0

実行中のアプリケーションを表示するために SetWindowsHookEx を使用してキーボードをキャプチャしています。CTRL、ALT、SHIFT、および通常のキーを使用して組み合わせを作成できます。ただし、WINDOWS キーを使用して組み合わせを作成することはできません (たとえば、CTRL + WINDOWS + A)。

WINDOWS キーを単独でキャプチャする方法 (ゲームの実行中に Windows 8 のスタート画面が表示されないようにするなど) に関する記事を見たことがありますが、組み合わせを作成することはありません。

AutoHotKey などのソフトウェアが行うように、これらの組み合わせをキャプチャできることはわかっています。

SetWindowsHookEx はこれを行うには間違った方法ですか?

4

1 に答える 1

0

役立つ回答を含む同様の質問を見つけました。これにより、解決策への正しい道をたどることができました。

Keyboard.Modifiers は Windows キーを検出できないようです (少なくとも私の Win8 インスタンスでは)。

代わりに、Windows キーを別の方法で処理する必要がありましたKeyboard.IsKeyDown。これにより、押されたキー (LowLevelKeyboardProc から) と現在押されているモディファイア キーの組み合わせが、プロパティHotKeyとプロパティで定義されているキーとモディファイアと同じかどうかを確認するメソッドが作成されましたHotKeyModifiers

LowLevelKeyboardProc の C# は次のとおりです。

/// <summary>
/// Called by windows when a keypress occurs.
/// </summary>
/// <param name="nCode">A code the hook procedure uses to determine how to process the message. If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.</param>
/// <param name="wParam">The identifier of the keyboard message. This parameter can be one of the following messages: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP. </param>
/// <param name="lParam">A pointer to a KBDLLHOOKSTRUCT structure. </param>
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && (wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN))
    {
        int vkCode = Marshal.ReadInt32(lParam);
        var keyPressed = KeyInterop.KeyFromVirtualKey(vkCode);

        if (IsKeyCombinationPressed(keyPressed))
            OnKeyCombinationPressed(new EventArgs());
    }

    return CallNextHookEx(_hookId, nCode, wParam, lParam);
}

IsKeyCombinationPressed() メソッドの C#:

/// <summary>
/// Returns true if the registered key combination is pressed
/// </summary>
/// <remarks>
/// Keyboard.Modifiers doesn't pick up the windows key (at least on Windows 8) so we use Keyboard.IsKeyDown to detect it (if required).
/// </remarks>
bool IsKeyCombinationPressed(Key keyPressed)
{
    if (keyPressed != HotKey) return false;

    //Handle windows key
    bool isWindowsKeyRequired = (HotKeyModifiers & ModifierKeys.Windows) != 0;
    bool isWindowsKeyPressed = Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin);

    //Remove windows key from modifiers (if required)
    ModifierKeys myModifierKeys = isWindowsKeyRequired ? HotKeyModifiers ^ ModifierKeys.Windows : HotKeyModifiers;
    bool isModifierKeysPressed = Keyboard.Modifiers == myModifierKeys;

    return isWindowsKeyRequired
        ? isWindowsKeyPressed && isModifierKeysPressed
        : isModifierKeysPressed;
}
于 2013-11-12T07:35:54.590 に答える