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 に答える