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 LoadKeyboardLayout
function and if it fails, you should check the error returned by the GetLastError
function 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 LoadKeyboardLayout
reference states for the KLF_ACTIVATE
flag (emphasized by me):
KLF_ACTIVATE
If the specified input locale identifier is not already loaded, the function loads and activates the input locale identifier for the current thread.
Although, if you want to load and activate keyboard layout for the whole process, you may try to combine the KLF_ACTIVATE
flag with the KLF_SETFORPROCESS
one:
const
KLF_SETFORPROCESS = $00000100;
begin
if LoadKeyboardLayout('00000429', KLF_ACTIVATE or KLF_SETFORPROCESS) = 0 then
RaiseLastOSError;
end;