0

I did this in the top of my Form1:

globalKeyboardHook gkh;

In the Load event:

private void Form1_Load(object sender, EventArgs e)
{
    gkh = new globalKeyboardHook();
    gkh.HookedKeys.Add(Keys.M);
    gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
    gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
}

Then in the bottom:

void gkh_KeyDown(object sender, KeyEventArgs e)
{
    // e.KeyCode.ToString() is the KeyCode of the pressed key
    e.Handled = true;
    if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
    {
        controlDown = true;
    }

    if (e.KeyCode == System.Windows.Forms.Keys.M && controlDown)
    {
        // Do CTRL-M action
        if (mf == null)
        {
            //mf = new MagnifierMainForm();
            mf = new MagnifierMainForm(false);
            mf.StartPosition = FormStartPosition.Manual;
            mf.Location = Control.MousePosition;
            //mf.Show();

            this.Select();
        }
        else if (mf.IsDisposed)
        {
            mf = new MagnifierMainForm(false);
            mf.StartPosition = FormStartPosition.Manual;
            mf.Location = Control.MousePosition;
            //mf.Show();
        }
        else
        {
            mf.Close();
            mf = null;
        }
    }
}

        void gkh_KeyUp(object sender, KeyEventArgs e)
        {
            controlDown = false;
        }

たとえば、アプリケーションを実行してプロンプトコマンドウィンドウをクリックすると、CTRL + Mをクリックするか、数秒後に何もクリックせずに例外が発生します。

CallbackOnCollectedDelegate タイプ 'ScreenVideoRecorder!Utilities.globalKeyboardHook+keyboardHookProc::Invoke' のガベージ コレクション デリゲートでコールバックが行われました。これにより、アプリケーションのクラッシュ、破損、データ損失が発生する可能性があります。デリゲートをアンマネージ コードに渡すときは、デリゲートが決して渡されないことが保証されるまで、マネージ アプリケーションによって有効にしておく必要があります。

CallbackOnCollectedDelegate が検出されました メッセージ: タイプ 'ScreenVideoRecorder!Utilities.globalKeyboardHook+keyboardHookProc::Invoke' のガベージ コレクション デリゲートでコールバックが行われました。これにより、アプリケーションのクラッシュ、破損、データ損失が発生する可能性があります。デリゲートをアンマネージ コードに渡す場合、デリゲートが呼び出されないことが保証されるまで、マネージ アプリケーションによって保持される必要があります。

4

1 に答える 1

1

グローバルキーボードフックを探していると思います。C#の簡単な使用例を次に示します。

上記の例のクラスを使用する場合globalKeyboardHook、次の 4 つのことを行う必要があります。

最初に、自己タイトルの .cs ファイルをプロジェクトに追加します (そのコードにはバグがあるため、少なくとも 2007 年 5 月 30 日以降のバージョンでは、次のように変更します - メンバー 4120854 のコメントによると):

線の下

public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);

この行を追加

private keyboardHookProc _keyboardHookProc;

フック メソッドを次のように変更します。

public void hook()
{
    IntPtr hInstance = LoadLibrary("User32");
    _keyboardHookProc = new keyboardHookProc(hookProc);
    hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _keyboardHookProc, hInstance, 0);
}

次に、 Form クラスに次のようなプライベートメンバー変数を追加します

globalKeyboardHook gkh = new globalKeyboardHook();

3 番目に、Form_Load (またはキーのフックを開始する他の場所) で、必要なキーを gkh クラスの HookedKeys コレクション プロパティに追加し、gkh クラスの KeyDown および/または KeyUp イベントをサブスクライブします。これ:

private void Form1_Load(object sender, EventArgs e) {
    gkh.HookedKeys.Add(Keys.LControlKey);
    gkh.HookedKeys.Add(Keys.RControlKey);
    gkh.HookedKeys.Add(Keys.M);
    gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
    gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
}

4 番目に、次のように、KeyUp または KeyDown ハンドラーで必要なことを行うことができます。e.Handled を true に設定して、システム上でのキー イベントの伝播を停止します。

void gkh_KeyUp(object sender, KeyEventArgs e) { // e.KeyCode.ToString() は解放されたキーの KeyCode e.Handled = true; }

    void gkh_KeyDown(object sender, KeyEventArgs e) {
        // e.KeyCode.ToString() is the KeyCode of the pressed key
        e.Handled = true;
    }

特定のキーの組み合わせで何かを行うには、キーの状態を変数に記録し、KeyDown 時に両方 (またはすべて) のキーが押されているかどうかを確認する必要があります。したがって、「CTRL-M」の場合、メンバー変数を追加します

bool controlDown = false;

次に、このコードを KeyDown イベント ハンドラーに追加します。

if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
{
    controlDown = true;
}

if (e.KeyCode == System.Windows.Forms.Keys.M && controlDown)
{
    // Do CTRL-M action
}

KeyUpイベントハンドラーでこれを追加する必要があります

if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
{
    controlDown = false;
}
于 2013-05-26T16:40:17.193 に答える