We have a kiosk app where we would like to allow use of the Win + H hotkey to bring up Voice Typing, but still filter out other Win + ... hotkeys and the Win key by itself.
The hook is set with SetWindowsHookEx(WH_KEYBOARD_LL, callback, hInstance, 0);
Log from pressing Win + H:
// w = bool, GetAsyncKeyState for left and right windows keys
// h = bool, ...for "h" key
// key = KBDLLHOOKSTRUCY* pkh->vkCode, 72 = h, 91 = left Windows key
// flags = KBDLLHOOKSTRUCT* pkh->flags
// pressed Windows, then H, then released
w=0 h=0 key= 91 flags = 1
w=-1 h=0 key= 91 flags = 1
... repeats ....
w=-1 h=0 key= 91 flags = 1
w=-1 h=0 key= 72 flags = 0
w=-1 h=-1 key= 72 flags = 80
w=-1 h=0 key= 91 flags = 81
What I'm finding while trying different permutations of code in the callback is, either I get no keypress, or I get a plain h
(so Voice Typing is not launched), or all other Win + ... hotkeys get through not just Win + H.
This treats the press as a plain h
, so apparently at least some of the Win key events before the h
events must be allowed past the filter:
if (nCode == HC_ACTION)
{
BOOL bWinKeyDown = (GetAsyncKeyState(VK_LWIN) >> 15) | (GetAsyncKeyState(VK_RWIN) >> 15);
if (pkh->vkCode == 'H')
{
// w=-1 h=0 key= 72 flags = 0
// w=-1 h=-1 key= 72 flags = 80
return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);
}
else if ((pkh->vkCode == VK_LWIN || pkh->vkCode == VK_RWIN))
{
// also just "h" if we allow through the w=-1 h=0 key= 91 flags = 1 events
// if ((bWinKeyDown && (pkh->flags == 1)) )
// return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);
// else
return -1;
}
}
return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);
This lets all Win + ... hotkeys through, it seems like the first event acts as a "dead key" that gets applied to any next letter key:
if (nCode == HC_ACTION)
{
BOOL bWinKeyDown = (GetAsyncKeyState(VK_LWIN) >> 15) | (GetAsyncKeyState(VK_RWIN) >> 15);
if (pkh->vkCode == 'H')
{
// w=-1 h=0 key= 72 flags = 0
// w=-1 h=-1 key= 72 flags = 80
return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);
}
else if ((pkh->vkCode == VK_LWIN || pkh->vkCode == VK_RWIN))
{
if ((!bWinKeyDown && (pkh->flags == 1))) // // w=0 h=0 key= 91 flags = 1 - first event in log
return CallNextHookEx(g_hHookKbdLL, nCode, wp, lp);
else
return -1;
}
Is there any way to trap all Win + ... hotkey except for Win + H?
According to my test,
You can trap them at the second message. The following code which traps all
win+h
produces four messages, Index 1 to 4.Win+...
hotkey except forwin+h
works for me.Update:
Update 2: