- ? Keyboard Hook (Combo-Keys, Owner Window)
- Posted by Alec S. on June 5th, 2008
Hi,
I'm trying to create a hotkey control that can detect any keys or combinations
(at least more than the standard one). I've modeled mine after XMPlay's shortcut
hotkey control: a button that you click which traps its next keyboard event.
It's coming along great. I've created the control, basing it on CButton, which
calls SetWindowsHookEx from OnBnClicked. I can trap the next key and call
UnhookWindowsHookEx in the hook proc. I've now run into two problems:
(1) I cannot figure out how to detect combinations (eg Ctrl+A, Shift+Win+F5,
etc.) The hook procedure triggers after any key, preventing combinations from
registering; ie, I get Ctrl by itself.
(1b) I need a way of interpreting the captured hotkey as a string.
(2) I need a way to call the (button) control's SetWindowText from the hook
procedure and to store the detected hotkey and its modifiers in the control.
I have no idea about problem (1). For problem (2), I have in the past worked
around similar situations by passing a pointer to the instance of the window to
the callback, but can't do that here. I have hacked a workaround by storing the
control's handle in a global static, HWND during its PreSubclassWindow. It seems
to work, but if I have more than one control in a dialog, won't they all use the
same HWND variable?
I can't seem to find any sample code that demonstrates anything like this.
How can I do this? Thanks a lot.
--
Alec S.
news/alec->synetech/cjb/net
- Posted by Christian ASTOR on June 6th, 2008
Alec S. wrote:
GetAsyncKeyState() (VK_CONTROL, etc...)
GetKeyNameText()
And if you have several buttons ? (then several Hook procecures)
(BTW, hotkeys are usually done with RegisterHotKey() or HOTKEY_CLASS
control)
- Posted by Alec S. on June 6th, 2008
"Christian ASTOR" <castorix@club-internet.fr> wrote in message
news:4848dc8e$0$21148$7a628cd7@news.club-internet.fr...
That’s what I’m using, but I need to specify Ctrl+, Alt+Shift+, etc. (I guess
this falls out of the solution to (1) which is why it’s 1b.)
But how do I store a pointer to the button? Each hook procedure needs to access
the button that created it.
Yes, but the hotkey control handles very few (no Win combos, no Enter, Esc,
Delete, etc.)
--
Alec S.
news/alec->synetech/cjb/net
- Posted by Alec S. on June 7th, 2008
"Christian ASTOR" <castorix@club-internet.fr> wrote in message
news:4848dc8e$0$21148$7a628cd7@news.club-internet.fr...
The keyboard hook triggers as soon as any key is pressed including the
modifiers, so it’s not possible to hold them down and press another. Should I
check each to see if it’s one of those and just exit the hook procedure?
Wouldn’t that mean that the hook procedure is stuck in a trigger-exit loop while
the user is holding down a modifier until they press something else?
--
Alec S.
news/alec->synetech/cjb/net
- Posted by Christian ASTOR on June 7th, 2008
Alec S. wrote:
You can distinguish modifiers keys by testing vkCode of KBDLLHOOKSTRUCT
with a function like IsModifierKey(DWORD vkCode) where you return
vkCode == VK_CONTROL || vkCode == VK_RCONTROL || vkCode == VK_LCONTROL
|| etc... (same for VK_SHIFT and VK_MENU)
then in the hook procedure :
KBDLLHOOKSTRUCT *pkbhs = (KBDLLHOOKSTRUCT *) lParam;
if(nCode == HC_ACTION && ( wParam == WM_KEYDOWN || wParam ==
WM_SYSKEYDOWN ) & !IsModifierKey(pkbhs->vkCode))
{
//...
// here you can test the state of these keys, like :
BOOL bAltGrDown = GetKeyState(VK_RMENU) & 0x8000;
BOOL bAltDown = GetKeyState(VK_LMENU) & 0x8000;
BOOL bCtrl = GetKeyState(VK_CONTROL) & 0x8000;
// etc...
}