我使用SetWindowsHookEx捕獲鍵盤以顯示正在運行的應用程序。我可以使用CTRL,ALT,SHIFT和常規鍵創建組合。但是,我無法使用WINDOWS鍵創建組合(例如,CTRL + WINDOWS + A)。如何創建包含Windows密鑰的全局熱鍵組合?
我已經看到有關單獨捕獲WINDOWS鍵的文章(例如當遊戲運行時阻止Windows 8啓動屏幕),但從未創建組合。
我知道有可能將這些組合捕獲爲像AutoHotKey這樣的軟件。
SetWindowsHookEx是錯誤的方法嗎?
我使用SetWindowsHookEx捕獲鍵盤以顯示正在運行的應用程序。我可以使用CTRL,ALT,SHIFT和常規鍵創建組合。但是,我無法使用WINDOWS鍵創建組合(例如,CTRL + WINDOWS + A)。如何創建包含Windows密鑰的全局熱鍵組合?
我已經看到有關單獨捕獲WINDOWS鍵的文章(例如當遊戲運行時阻止Windows 8啓動屏幕),但從未創建組合。
我知道有可能將這些組合捕獲爲像AutoHotKey這樣的軟件。
SetWindowsHookEx是錯誤的方法嗎?
我發現了一個類似的問題,其中包含一個幫助here的答案。 這使我走上了解決問題的正確道路。
它出現Keyboard.Modifiers無法檢測到Windows鍵(至少在我的Win8實例)。
相反,我不得不以不同的方式使用Keyboard.IsKeyDown
來處理Windows密鑰。這導致構建一種方法來檢查按下(從我的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);
}
和C#的IsKeyCombinationPressed()方法:
/// <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;
}