GetAsyncKeyState()函数
返回值 Long,自对GetAsyncKeyState函数的上一次调用以来,如键已被按过,则位0设为1;否则设为0。如键目前处于按下状态,则位15设为1;如抬起,则为0。微软的win32手册指出:倘若输入焦点从属于与调用函数的输入线程不同的另一个输入线程,则返回值为0(例如,一旦另一个程序拥有焦点,则它应返回零)。证据显示,函数实际是在整个系统的范围内工作的。在windows CE中无论输入焦点从不从属调用函数的输入线程,GetAsyncKeyState()都是可以正常返回的。
重点在这里:倘若输入焦点从属于与调用函数的输入线程不同的另一个输入线程,则返回值为0(例如,一旦另一个程序拥有焦点,则它应返回零)。
自己写了程序测试了下的确如此,但是在研究 录屏软件OBS代码 时却发现他们使用的也是GetAsyncKeyState函数却能正常工作,不知道为什么,哪位大神能解释一下吗??或者用什么方法让GetAsyncKeyState函数像在windowsCE中一样返回值??
OBS代码如下:
void OBSAPIInterface::HandleHotkeys()
{
List<DWORD> hitKeys;
static bool allow_other_hotkey_modifiers;
static bool uplay_overlay_compatibility;
static bool set_vars = false;
/* only query these config variables once */
if (!set_vars)
{
allow_other_hotkey_modifiers = !!GlobalConfig->GetInt(TEXT("General"), TEXT("AllowOtherHotkeyModifiers"), true);
uplay_overlay_compatibility = !!GlobalConfig->GetInt(L"General", L"UplayOverlayCompatibility", false);
set_vars = true;
}
DWORD modifiers = 0;
//这里试用了GetAsyncKeyState()
if(GetAsyncKeyState(VK_MENU) & 0x8000)
modifiers |= HOTKEYF_ALT;
if(GetAsyncKeyState(VK_CONTROL) & 0x8000)
modifiers |= HOTKEYF_CONTROL;
if (!uplay_overlay_compatibility)
if (GetAsyncKeyState(VK_SHIFT) & 0x8000)
modifiers |= HOTKEYF_SHIFT;
OSEnterMutex(App->hHotkeyMutex);
for(UINT i=0; i<hotkeys.Num(); i++)
{
HotkeyInfo &info = hotkeys[i];
DWORD hotkeyVK = LOBYTE(info.hotkey);
DWORD hotkeyModifiers = HIBYTE(info.hotkey);
DWORD xinputNum = LOWORD(info.hotkey);
DWORD xinputButton = HIWORD(info.hotkey);
hotkeyModifiers &= ~(HOTKEYF_EXT);
if(xinputButton)
{
XINPUT_STATE state = { 0 };
if(XInputGetState(xinputNum, &state) == ERROR_SUCCESS)
{
if(state.Gamepad.bLeftTrigger >= 85)
state.Gamepad.wButtons |= XINPUT_GAMEPAD_LEFT_TRIGGER;
if(state.Gamepad.bRightTrigger >= 85)
state.Gamepad.wButtons |= XINPUT_GAMEPAD_RIGHT_TRIGGER;
if((state.Gamepad.wButtons & xinputButton) != 0 && !info.bHotkeyDown)
{
PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID);
info.bDownSent = true;
info.bHotkeyDown = true;
}
}
info.bModifiersDown = 0;
}
else
{
bool bModifiersMatch = false;
if(allow_other_hotkey_modifiers)
bModifiersMatch = ((hotkeyModifiers & modifiers) == hotkeyModifiers); //allows other modifiers to be pressed
else
bModifiersMatch = (hotkeyModifiers == modifiers);
if(hotkeyModifiers && !hotkeyVK) //modifier-only hotkey
{
if((hotkeyModifiers & modifiers) == hotkeyModifiers)
{
if(!info.bHotkeyDown)
{
PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID);
info.bDownSent = true;
info.bHotkeyDown = true;
}
continue;
}
}
else
{
if (bModifiersMatch && !(uplay_overlay_compatibility && hotkeyVK == VK_F2))
{
//这里试用了GetAsyncKeyState()
short keyState = GetAsyncKeyState(hotkeyVK);
bool bDown = (keyState & 0x8000) != 0;
bool bWasPressed = (keyState & 0x1) != 0;
if(bDown || bWasPressed)
{
if(!info.bHotkeyDown && info.bModifiersDown) //only triggers the hotkey if the actual main key was pressed second
{
PostMessage(hwndMain, OBS_CALLHOTKEY, TRUE, info.hotkeyID);
info.bDownSent = true;
}
info.bHotkeyDown = true;
if(bDown)
continue;
}
}
}
info.bModifiersDown = bModifiersMatch;
}
if(info.bHotkeyDown) //key up
{
if(info.bDownSent)
{
PostMessage(hwndMain, OBS_CALLHOTKEY, FALSE, info.hotkeyID);
info.bDownSent = false;
}
info.bHotkeyDown = false;
}
}
OSLeaveMutex(App->hHotkeyMutex);
}