TestKeyDownBit函数和SetKeyDownBit函数和ClearKeyDownBit函数分析
TestKeyDownBit函数和SetKeyDownBit函数和ClearKeyDownBit函数分析
第一部分:
/*
* Two bits per VK (down & toggle) so we can pack 4 VK keystates into 1 byte:
*
* Byte 0 Byte 1
* .---.---.---.---.---.---.---.---. .---.---.---.---.---.---.---.---. .-- -
* | T | D | T | D | T | D | T | D | | T | D | T | D | T | D | T | D | |
* `---'---'---'---'---'---'---'---' `---'---'---'---'---'---'---'---' `-- -
* : VK 3 : VK 2 : VK 1 : VK 0 : : VK 7 : VK 6 : VK 5 : VK 4 : :
*
* KEY_BYTE(pb, vk) identifies the byte containing the VK's state
* KEY_DOWN_BIT(vk) identifies the VK's down bit within a byte
* KEY_TOGGLE_BIT(vk) identifies the VK's toggle bit within a byte
*/
#define KEY_BYTE(pb, vk) pb[((BYTE)(vk)) >> 2]
#define KEY_DOWN_BIT(vk) (1 << ((((BYTE)(vk)) & 3) << 1))
#define KEY_TOGGLE_BIT(vk) (1 << (((((BYTE)(vk)) & 3) << 1) + 1))
#define TestKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) & KEY_DOWN_BIT(vk))
#define SetKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) |= KEY_DOWN_BIT(vk))
#define ClearKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) &= ~KEY_DOWN_BIT(vk))
#define TestKeyToggleBit(pb, vk) (KEY_BYTE(pb,vk) & KEY_TOGGLE_BIT(vk))
#define SetKeyToggleBit(pb, vk) (KEY_BYTE(pb,vk) |= KEY_TOGGLE_BIT(vk))
#define ClearKeyToggleBit(pb, vk) (KEY_BYTE(pb,vk) &= ~KEY_TOGGLE_BIT(vk))
#define ToggleKeyToggleBit(pb, vk) (KEY_BYTE(pb,vk) ^= KEY_TOGGLE_BIT(vk))
第二部分:
chenghao@chenghaodeiMac public % grep "KEY_DOWN_BIT" -nr
./internal/windows/inc/winuserp.h:2553: * KEY_DOWN_BIT(vk) identifies the VK's down bit within a byte
./internal/windows/inc/winuserp.h:2557:#define KEY_DOWN_BIT(vk) (1 << ((((BYTE)(vk)) & 3) << 1))
./internal/windows/inc/winuserp.h:2560:#define TestKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) & KEY_DOWN_BIT(vk))
./internal/windows/inc/winuserp.h:2561:#define SetKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) |= KEY_DOWN_BIT(vk))
./internal/windows/inc/winuserp.h:2562:#define ClearKeyDownBit(pb, vk) (KEY_BYTE(pb,vk) &= ~KEY_DOWN_BIT(vk))
#define VK_CLEAR 0x0C
#define VK_RETURN 0x0D
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12 10010
#define VK_PAUSE 0x13
#define VK_CAPITAL 0x14
#define KEY_BYTE(pb, vk) pb[((BYTE)(vk)) >> 2]
#define KEY_DOWN_BIT(vk) (1 << ((((BYTE)(vk)) & 3) << 1))
10000 100 0 0 0x1
10001 100 10 100 0x4
10010 100 100 10000 0x10
10011 100 110 1000000 040
#define VK_SHIFT 0x10
#define VK_CONTROL 0x11
#define VK_MENU 0x12 10010
#define VK_PAUSE 0x13
上面四个键可以共用1个字节,所以要除以4,也就是右移2位!!!: #define KEY_BYTE(pb, vk) pb[((BYTE)(vk)) >> 2]
VOID UpdateRawKeyState(
BYTE Vk,
BOOL fBreak)
{
CheckCritIn();
if (fBreak) {
ClearRawKeyDown(Vk);
} else {
/*
* This is a key make. If the key was not already down, update the
* physical toggle bit.
*/
if (!TestRawKeyDown(Vk)) {
ToggleRawKeyToggle(Vk);
}
/*
* This is a make, so turn on the physical key down bit.
*/
SetRawKeyDown(Vk);
}
}
VOID xxxProcessKeyEvent(
PKE pke,
ULONG_PTR ExtraInformation,
BOOL bInjected)
{
if (KOREAN_KBD_LAYOUT(GetActiveHKL())) {
if ((pke->usFlaggedVk & KBDBREAK) &&
!(pke->usFlaggedVk & KBDUNICODE) &&
(pke->bScanCode == 0xF1 || pke->bScanCode == 0xF2) &&
!TestRawKeyDown(Vk)) {
/*
* This is actually a keydown with a scancode of 0xF1 or 0xF2 from a
* Korean keyboard. Korean IMEs and apps want a WM_KEYDOWN with a
* scancode of 0xF1 or 0xF2. They don't mind not getting the WM_KEYUP.
* Don't update physical keystate to allow a real 0x71/0x72 keydown.
*/
pke->usFlaggedVk &= ~KBDBREAK;
} else {
UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK);
}
} else {
UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK);
}
/*
* Convert Left/Right Ctrl/Shift/Alt key to "unhanded" key.
* ie: if VK_LCONTROL or VK_RCONTROL, convert to VK_CONTROL etc.
*/
if ((Vk >= VK_LSHIFT) && (Vk <= VK_RMENU)) {
Vk = (BYTE)((Vk - VK_LSHIFT) / 2 + VK_SHIFT);
UpdateRawKeyState(Vk, pke->usFlaggedVk & KBDBREAK);
}
第三部分:
/public/sdk/inc/winuser.h
/*
* Virtual Keys, Standard Set
*/
#define VK_LBUTTON 0x01
#define VK_RBUTTON 0x02
#define VK_CANCEL 0x03
#define VK_MBUTTON 0x04 /* NOT contiguous with L & RBUTTON */
#if(_WIN32_WINNT >= 0x0500)
#define VK_XBUTTON1 0x05 /* NOT contiguous with L & RBUTTON */
#define VK_XBUTTON2 0x06 /* NOT contiguous with L & RBUTTON */
#endif /* _WIN32_WINNT >= 0x0500 */
/*
* 0x07 : unassigned
*/
#define VK_BACK 0x08
#define VK_TAB 0x09
/*
* 0x0A - 0x0B : reserved
*/
