折翅的飞蛾 2015-04-23 08:10 采纳率: 100%
浏览 2209

有关录屏软件OBS中GetAsyncKeyState()函数返回值得问题

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);
}
  • 写回答

1条回答

  • oyljerry 2015-04-24 07:39
    关注

    如果想要这些信息,做键盘hook钩子是比较全的

    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?