5

のようなキーF12が押されたかどうかを常にチェックするアプリケーションがあります。アプリのメイン ウィンドウにフォーカスする必要はありません。私はこのコードを試しました:

public int a = 1;
    // DLL libraries used to manage hotkeys
    [DllImport("user32.dll")]
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
    [DllImport("user32.dll")]
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    const int MYACTION_HOTKEY_ID = 1;

    public Form1()
    {
        InitializeComponent();
        // Modifier keys codes: Alt = 1, Ctrl = 2, Shift = 4, Win = 8
        // Compute the addition of each combination of the keys you want to be pressed
        // ALT+CTRL = 1 + 2 = 3 , CTRL+SHIFT = 2 + 4 = 6...
        RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F12);
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID)
        {

            a++;
            MessageBox.Show(a.ToString());
        }
        base.WndProc(ref m);
    }

が押されたRegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, (int) Keys.F12);場合にのみキャプチャされるように、この行に 0 を入力します。F12

しかし、うまくいきませんでした。どうすればこれを解決できますか?

ここでは、次のようないくつかの行を理解できませんでした。

const int MYACTION_HOTKEY_ID = 1;
m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID
base.WndProc(ref m);

これらの行を理解するのを手伝ってくれる人はいますか?

4

4 に答える 4

2

しかし、うまくいきませんでした。どうすればこれを解決できますか?

「うまくいかなかった」とは?あなたの質問のコードは私には正しいようです。

機能しない唯一の理由は、RegisterHotKey関数がエラーを返し、それをチェックしていないためです。これを機能させるには、宣言にSetLastError属性を追加する必要があります。これにより、ランタイムは、設定した Win32 エラー コードをキャッシュします。これが完了したら、関数falseを呼び出して、(関数が を返した場合)GetLastWin32Errorそのエラー コードを確認できます。この関数の結果を使用して、 を生成してスローすることをお勧めしWin32Exceptionます。

の宣言をRegisterHotKey次のように変更します。

[DllImport("user32.dll", PreserveSig = false)]
public static extern bool RegisterHotKey(IntPtr hWnd,
                                         int id,
                                         uint fsModifiers,
                                         Keys key);

そして、次のように関数を呼び出します。

if (!RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, Keys.F12))
{
   throw new Win32Exception(Marshal.GetLastWin32Error());
}

それが完了すると、次のエラー メッセージとともに例外がスローされることがわかると思います。

ホットキーはすでに登録されています

そうですね、これで問題のデバッグがはるかに簡単になりますよね! RegisterHotKey関数のドキュメントで次のことが明示されているため、別のホット キーを選択する必要がある可能性があります。

このF12キーは常にデバッガで使用するために予約されているため、ホット キーとして登録しないでください。アプリケーションをデバッグしていないF12場合でも、カーネル モード デバッガーまたはジャスト イン タイム デバッガーが常駐している場合に備えて予約されています。

コードを実行しF11てホットキーとして登録すると、うまく機能します。


ここでは、次のようないくつかの行を理解できませんでした。

const int MYACTION_HOTKEY_ID = 1;
m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID
base.WndProc(ref m);

これらの行を理解するのを手伝ってくれる人はいますか?

もちろん:

  1. 最初の行は、関数を使用してインストールしたホットキーを一意に識別する定数値を宣言しRegisterHotKeyます。具体的にidは、関数のパラメータに相当します。最初の呼び出しでそれを渡しました。

  2. WndProcこれは、ウィンドウ プロシージャ ( ) で、処理中のメッセージ ( Msg) がメッセージかどうかをチェックしWM_HOTKEYます。機能に登録したホットキーが押されるたびに、WM_HOTKEYメッセージがウィンドウに自動的に投稿されますRegisterHotKey

    0x0312ただし、マジック ナンバーの意味を理解していないのはあなただけではないため、マジック ナンバーを直接使用するべきではありません。代わりに、定数を定義して代わりに使用します。

    const int WM_HOTKEY = 0x0312;
    m.Msg == WM_HOTKEY
    

    その条件テストの 2 番目の部分 ( の後の部分&&) では、メッセージのフィールドをチェックして、wParam押されたホット キーが登録したものであるかどうかを確認します。MYACTION_HOTKEY_IDこれは、ホット キーの一意の ID であることを忘れないでください。WM_HOTKEYメッセージのドキュメントには、wParamどのホット キーが押されたかを確認する方法が示されています。

  3. これにより、基本クラスのウィンドウ プロシージャが呼び出されます。つまり、仮想メソッドをオーバーライドして、追加WndProcのコードを追加できるようにします (の処理)。追加のロジックが完了したら、基本クラスのロジックを続行するため、メッセージを転送します。WM_HOTKEY

于 2013-03-15T10:21:56.933 に答える
1

あなたのコードには間違いはありません。ただし、 F12キーは予約されているため、ここでは機能しません。F10F11 などの別のキーを試してみてください。

于 2013-03-16T04:37:31.550 に答える
1

理由はわかりませんが、これはこの質問に関連しているように感じます...もう一度説明してみます。

const int MYACTION_HOTKEY_ID = 1;

ホットキーを識別するために使用される整数を保存する場所です。複数のホットキーを登録する必要がある場合は、他のホットキーを識別する他の整数フィールドを宣言する必要があります。

const int ANOTHER_ACTION_HOTKEY_ID = 2;
const int AND_ANOTHER_ACTION_HOTKEY_ID = 3;

それで、

m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID

ユーザーがどのホットキーを入力したかを知ることができる状態です。

0x0312(たとえば、ここWM_HOTKEYにあるドキュメントでも宣言されています)は、登録されたホットキーが押されたかどうかを知ることです:

キーが押されると、システムはすべてのホット キーとの一致を探します。一致が見つかると、システムは、ホット キーが関連付けられているウィンドウのメッセージ キューに WM_HOTKEY メッセージをポストします。ホット キーがウィンドウに関連付けられていない場合、WM_HOTKEY メッセージはホット キーに関連付けられたスレッドにポストされます。


ドキュメントによると、F12ホットキーは使用できません。

F12 キーは、デバッガーが常に使用するために予約されているため、ホット キーとして登録しないでください。アプリケーションをデバッグしていない場合でも、カーネル モード デバッガーまたはジャスト イン タイム デバッガーが常駐している場合に備えて、F12 キーは予約されています。

于 2013-03-15T09:31:23.513 に答える
1

同様のことを行うために、 を使用して低レベルのキーボード フックを実装しましたSetWindowsHookEx。これにより、Windows を通過するすべてのキーボード メッセージがトラップされ、それらを調べて、必要に応じてそれ以上進むのを防ぐことができます。

私のRocketLauncher GitHub 趣味プロジェクトの KeyboardHandling プロジェクトを見てください。そこから必要なものを直接取得できます。こちらも近々ナゲットパッケージにする予定です。

于 2013-03-15T09:25:26.850 に答える