10

我正在使用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;

问题是,它没有按预期改变键盘布局。我已经调试了代码并且所有的行都被执行了;只是LoadKeyboardLayout功能还没有发挥作用。

如何使LoadKeyboardLayout函数从后台线程工作?

4

1 回答 1

8

首先,您应该检查LoadKeyboardLayout函数的结果,如果失败,您应该检查GetLastError函数返回的错误以确定错误所在。

但是即使这个函数调用成功,它也会激活输入的语言环境标识符,但是对于你的工作线程。作为标志的LoadKeyboardLayout参考状态KLF_ACTIVATE(由我强调):

KLF_ACTIVATE

如果指定的输入语言环境标识符尚未加载,则该函数加载并激活当前线程的输入语言环境标识符。


虽然,如果您想为整个过程加载和激活键盘布局,您可以尝试将KLF_ACTIVATE标志与以下标志结合起来KLF_SETFORPROCESS

const
  KLF_SETFORPROCESS = $00000100;
begin
  if LoadKeyboardLayout('00000429', KLF_ACTIVATE or KLF_SETFORPROCESS) = 0 then
    RaiseLastOSError;
end;
于 2012-12-09T06:04:18.473 回答