-1

I want to implement key strokes (CTRL + KEY) and therefore used SetWindowsHook (SetWindowsHook(WH_KEYBOARD, hookProcTest)) to "install" a hook.

Looking at the HOOKPROC

LRESULT CALLBACK hookProcTest(int code, WPARAM wParam, LPARAM lParam)

The code parameter seems to be always 0, wParam matches the virtual keycode, lParam is probably a pointer to a structure containing what key event it is.

When I press a key, realease a key, or press another key, the lParam shows drastic change.

I tried to cast it to LPCWPRETSTRUCT but that gave me a trash pointer (program crashed when accessing members).

So what structure is used?

Edit: This was on here: link

case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{
    WORD vkCode = LOWORD(wParam);                                       // virtual-key code

    BYTE scanCode = LOBYTE(HIWORD(lParam));                             // scan code
    BOOL scanCodeE0 = (HIWORD(lParam) & KF_EXTENDED) == KF_EXTENDED;    // extended-key flag, 1 if scancode has 0xE0 prefix

    BOOL upFlag = (HIWORD(lParam) & KF_UP) == KF_UP;                    // transition-state flag, 1 on keyup
    BOOL repeatFlag = (HIWORD(lParam) & KF_REPEAT) == KF_REPEAT;        // previous key-state flag, 1 on autorepeat
    WORD repeatCount = LOWORD(lParam);                                  // repeat count, > 0 if several keydown messages was combined into one message

    BOOL altDownFlag = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;     // ALT key was pressed

    BOOL dlgModeFlag = (HIWORD(lParam) & KF_DLGMODE) == KF_DLGMODE;     // dialog box is active
    BOOL menuModeFlag = (HIWORD(lParam) & KF_MENUMODE) == KF_MENUMODE;  // menu is active
    
    // ...
}
break;

The lParam wasn't a struct - a bunch of bit fields instead - as stated by Remy Lebeau in the comments.

Lost
  • 23
  • 1
  • 6
  • `LPCWPRETSTRUCT` is used with `WH_CALLWNDPROCRET`, not `WH_KEYBOARD`. The `lParam` for `WH_KEYBOARD` is not a (pointer to a) struct at all, it is a bunch of bitfields instead. – Remy Lebeau Jul 23 '21 at 15:05
  • Is this trying to reinvent [RegisterHotKey](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerhotkey)? – IInspectable Jul 26 '21 at 10:13
  • @IInspectable Thanks for adding that, it was really just for that; I just didn't know it existed. – Lost Jul 26 '21 at 14:37

1 Answers1

2

The lParam is described here in the KeyboardProc documentation. The lParam encodes the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag within its bits.

Bits Description
0-15 The repeat count. The value is the number of times the keystroke is repeated as a result of the user's holding down the key.
16-23 The scan code. The value depends on the OEM.
24 Indicates whether the key is an extended key, such as a function key or a key on the numeric keypad. The value is 1 if the key is an extended key; otherwise, it is 0.
25-28 Reserved.
29 The context code. The value is 1 if the ALT key is down; otherwise, it is 0.
30 The previous key state. The value is 1 if the key is down before the message is sent; it is 0 if the key is up.
31 The transition state. The value is 0 if the key is being pressed and 1 if it is being released.
  • @RemyLebeau: It's not a link-only answer. Even if the link breaks, I would know to read the documentation page on `KeyboardProc` (as opposed to `SetWindowsHook` which OP already mentioned) – Ben Voigt Jul 23 '21 at 15:08
  • I took the liberty of trying my hand at the new(?) table markdown, I hope you don't mind :) – Quentin Jul 23 '21 at 15:10
  • @Quentin Thank you very much. It looks nice. –  Jul 23 '21 at 15:10
  • @Lost Code like `lparam & 24` does *not* check if the 24th bit is set. Read this answer for more details: https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit – Daniel Kleinstein Jul 23 '21 at 15:25
  • @DanielKleinstein Yeah, I just noticed since 24 is 0b11000, so it checks for the 4th and 5th bit. – Lost Jul 23 '21 at 15:34
  • @user15284017 You pointed me to the right link, where I found the another link which is on my edited questions. I expected this to be a link-only answer; the terms I tried searching for weren't matching and I was impatient. But I think this is a good contribution to the StackOverflow archive anyways. – Lost Jul 23 '21 at 15:43
  • @BenVoigt "*It's not a link-only answer*" - it was at the time I wrote that comment. It has since been edited. – Remy Lebeau Jul 23 '21 at 18:05
  • @RemyLebeau: It was just the first sentence, which was already not a link-only answer. It was an answer only pointing to an off-site resource, but it did so via both link and by naming the exact documentation page. So it would still have been useful if the link broke. If you removed the link to have "The `lParam` is described in the `KeyboardProc` documentation" it is still an answer. – Ben Voigt Jul 23 '21 at 18:19