I’m using the LoadKeyboardLayout function to load and activate the keyboard layout this way:
procedure TfrmMain.eSearchEnter(Sender: TObject);
begin
LoadKeyboardLayout('00000429', KLF_ACTIVATE);
end;
It works perfectly, but it freezes the active form for 1-2 seconds, since this change takes some time. For preventing this, I’ve moved this code to a background thread like this:
type
FLangChangeThread = class(TThread)
private
FLang: string;
protected
procedure Execute; override;
public
property Lang: string read FLang write FLang;
end;
implementation
procedure FLangChangeThread.Execute;
begin
if FLang = 'EN' then
LoadKeyboardLayout('00000409', KLF_ACTIVATE)
else
if FLang = 'FA' then
LoadKeyboardLayout('00000429', KLF_ACTIVATE);
end;
This background thread I’m then running this way:
procedure TfrmMain.ChangeWritingLanguage(ALang: string);
begin
with FLangChangeThread.Create(True) do
begin
FreeOnTerminate := True;
Lang := ALang;
Resume;
end;
end;
procedure TfrmMain.eSearchEnter(Sender: TObject);
begin
ChangeWritingLanguage('FA');
end;
The problem is, that it doesn’t change the keyboard layout as expected.
I’ve debugged the code and all lines were execeuted; just the LoadKeyboardLayout function hasn’t made its job.
How can I make the LoadKeyboardLayout function work from a background thread ?
First of all, you should check the result of the
LoadKeyboardLayoutfunction and if it fails, you should check the error returned by theGetLastErrorfunction to determine what is wrong.But even if this function call succeed, it will activate the input locale identifier, but for your worker thread. As the
LoadKeyboardLayoutreference states for theKLF_ACTIVATEflag (emphasized by me):Although, if you want to load and activate keyboard layout for the whole process, you may try to combine the
KLF_ACTIVATEflag with theKLF_SETFORPROCESSone: