Как использовать LoadKeyboardLayout в фоновом потоке?
Я использую LoadKeyboardLayout для загрузки и активации раскладки клавиатуры следующим образом:
procedure TfrmMain.eSearchEnter(Sender: TObject);
begin
LoadKeyboardLayout('00000429', KLF_ACTIVATE);
end;
Он работает отлично, но он замораживает активную форму на 1-2 секунды, так как это изменение занимает некоторое время. Чтобы предотвратить это, я переместил этот код в фоновый поток следующим образом:
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;
Этот фоновый поток я запускаю следующим образом:
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;
Проблема заключается в том, что она не меняет раскладку клавиатуры, как ожидалось.
Я отлаживал код, и все строки были execeuted; только функция LoadKeyboardLayout не выполнила свою работу.
Как я могу заставить LoadKeyboardLayout работать из фонового потока?
Ответы
Ответ 1
Прежде всего, вы должны проверить результат LoadKeyboardLayout
, и если это не удается, вы должны проверить ошибку, возвращаемую GetLastError
, чтобы определить, что не так.
Но даже если вызов этой функции будет успешным, он активирует идентификатор локали ввода, но для рабочего потока. Поскольку LoadKeyboardLayout
ссылается на KLF_ACTIVATE
флаг (подчеркнуто мной):
KLF_ACTIVATE
Если указанный идентификатор языка ввода еще не загружен, функция загружает и активирует идентификатор локали ввода для текущий поток.
Хотя, если вы хотите загрузить и активировать раскладку клавиатуры для всего процесса, вы можете попытаться объединить флаг KLF_ACTIVATE
с помощью KLF_SETFORPROCESS
one:
const
KLF_SETFORPROCESS = $00000100;
begin
if LoadKeyboardLayout('00000429', KLF_ACTIVATE or KLF_SETFORPROCESS) = 0 then
RaiseLastOSError;
end;