1

キーボード フック内のキーボード レイアウトの変更に問題があります。この単純なコードでは、「A」キーを押すと、言語を変更するのに多くの時間がかかり、より複雑なケースでは、アプリケーションが間違ったことをします..

アプリケーションはトレイで動作するため、フックを使用しました。私のコードの何が問題なのですか? )) または、フックでうまく機能するキーボードレイアウトを変更する別の方法があるのでしょうか? 回答ありがとうございます。

private static bool nextKey = false;

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
    uint tpid = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
    ushort currentLayout = GetKeyboardLayout(tpid);

    if (nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN) {
        if (nextKey) {
            Console.WriteLine("changing to english...");
            PostMessage(GetForegroundWindow(), 0x0050, 0, (int) LoadKeyboardLayout("00000409", 0x00000001));
            nextKey = false;
        }

        int vkCode = Marshal.ReadInt32(lParam);

        if (vkCode == 0x41 && currentLayout == 0x409) { // if language is rus and 'A' pressed
            Console.WriteLine("changing to russian...");
            PostMessage(GetForegroundWindow(), 0x0050, 0, (int) LoadKeyboardLayout("00000419", 0x00000001));
            nextKey = true;
        }
    }
    return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
4

1 に答える 1

0

このコードを修正しようとする前に、いくつかばかげた質問をする必要があります。

  1. なぜフック内でこれを行う必要があるのですか?
  2. なぜこれを行う必要があるのですか?ホットキーを指定して、キーボード コントロール パネルで入力言語を選択できます ([地域と言語] → [キーボードと言語] → [キーボードの変更] → [高度なキー設定])。また、複数の入力言語を有効にすると、タスク バーにアイコンが既に配置されています。これらのことを行うために独自のアプリを作成する必要はありません。

ここで、具体的にコードを見ると、WM_INPUTLANGCHANGEREQUESTメッセージをフォアグラウンド ウィンドウにポストしています。しかし、このメッセージは通知です。ユーザーが入力言語の変更を要求したことをプログラムに通知します。プログラムが他のプログラムに入力言語を変更するよう要求できるようには設計されていません。

プログラムが独自のキーボード レイアウトを変更する場合は、ActivateKeyboardLayout関数を呼び出します。ただし、.NET アプリケーションからこの関数を p/invoke する必要はありません。InputLanguageフレームワークはすでにこれらすべてをクラスにラップしています。強くお勧めします。

それとは別に、表示されていないコード、他のアプリケーションに属するコードには、他の問題が必然的に存在します。メッセージを投稿するフォアグラウンド ウィンドウにWM_INPUTLANGCHANGEREQUESTは、メッセージを に渡して変更を受け入れるかDefWindowProc、応答で 0 を返して変更を拒否するかのオプションがあります。壊れたアプリケーションが、明示的に処理しないすべてのメッセージに対して0 を返すだけの場合、正しく動作しません。または、アプリケーションが要求を明示的に拒否するように作成されている場合、WM_INPUTLANGCHANGEREQUEST期待どおりに動作しません。等々。これらのことを制御することはできません。WM_INPUTLANGCHANGEREQUEST単なる要求であることを忘れないでください。

速度の問題 (「言語を変更するには多くの時間がかかる」) に関しては、初めて入力言語をロードする操作が超高速であるとは限りません。通常のメカニズムを使用しているマシンでは、約 0.5 秒の遅延が見られます。通常は大きなボトルネックにはなりません。ほとんどの人は、それほど何度も切り替えることはありません。これを本当に高速化する必要がある場合は、LoadKeyboardLayout関数の戻り値をキャッシュすることを検討してください。

于 2013-05-26T08:53:48.347 に答える