Last time, we looked at how to distinguish the numeric keypad 0 and the top-row 0 in the WM_ message. We may as well look at the analogous table for WM_.
| Event | wParam | Extended? |
|---|---|---|
| Numpad0 with NumLock on | VK_0 | 0 |
| Numpad0 with NumLock off | (no WM_CHAR) |
|
| Ins key | (no WM_CHAR) |
|
| 0 on top row | VK_0 | 0 |
I got the name VK_0 from this comment block in winuser.h.
/* * VK_0 - VK_9 are the same as ASCII '0' - '9' (0x30 - 0x39) * 0x3A - 0x40 : unassigned * VK_A - VK_Z are the same as ASCII 'A' - 'Z' (0x41 - 0x5A) */
Uh-oh. The extended bit doesn’t distinguish between the two. They both show up as VK_0, non-extended.
What changes is something not in the above table: The scan code.
So let’s convert the scan code back to a virtual key.
auto vk_from_scan = MapVirtualKey((lParam >> 16) & 0xFF, MAPVK_VSC_TO_VK);
| Event | wParam | Extended? | vk_from_scan |
|---|---|---|---|
| Numpad0 with NumLock on | VK_0 | 0 | VK_INSERT |
| Numpad0 with NumLock off | (no WM_CHAR) |
||
| Ins key | (no WM_CHAR) |
||
| 0 on top row | VK_0 | 0 | VK_0 |
So we can infer which zero was pressed by taking the scan code, mapping it to a virtual key, and seeing whether it’s the Ins key (from the numeric keypad) or the 0 key (from the top row).
But wait, we’re not done yet.
There are ways to type the character 0 without using the numeric keypad or the top row. For example, you can hold the Alt key and then type 4,8 on the numeric keypad, and that will type a 0. I tried it out, and the vk_from_scan was VK_, which is the virtual key code for the Alt key. Another way of entering a 0 is by using an input method editor (IME). Or there might be a custom keyboard layout that generates a 0 through some wacky chord sequence.
Therefore, if the vk_ is neither VK_ nor VK_0, you have to conclude that the 0 was entered by some means other than the numeric keypad or the top row.
0 comments
Be the first to start the discussion.