C++ 键盘挂钩问题

C++ 键盘挂钩问题,c++,winapi,input,keyboard,hook,C++,Winapi,Input,Keyboard,Hook,我正在做一个语音聊天应用程序,它使用按键通话键。我已经做了一个钩子,所以它也会注册应用程序外部的按键通话 HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)pushtotalk,0,0); LRESULT CALLBACK pushtotalk(int key, WPARAM wParam,LPARAM lParam) { if (key < 0) { return (CallNextHookEx(hook,key

我正在做一个语音聊天应用程序,它使用按键通话键。我已经做了一个钩子,所以它也会注册应用程序外部的按键通话

HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)pushtotalk,0,0);



LRESULT CALLBACK pushtotalk(int key, WPARAM wParam,LPARAM lParam) {
if (key < 0) {
    return (CallNextHookEx(hook,key,wParam,lParam));
}
else if (connected) {
    KBDLLHOOKSTRUCT* kbdll  = (KBDLLHOOKSTRUCT*)lParam;
    if (kbdll ->vkCode == 75 && wParam == WM_KEYDOWN) {
        MessageBox(mainhWnd,"KEYSTART","KEYSTART",0);
    }
    else if (kbdll ->vkCode == 75 && wParam == WM_KEYUP) {
        MessageBox(mainhWnd,"KEYSTOP","KEYSTOP",0);

    }
}

return (CallNextHookEx(hook,key,wParam,lParam));
}
其中sendEditProc是一个子类/超类,设计用于在编辑控件“send”内拦截“enter”键 这有用吗

这是消息循环;这是标准,所以没有什么幻想会出差错:)


你给CallNextHookEx打电话太多了。如果
键<0,则返回CallNextHookEx
,否则
返回0

您看到的问题与键盘重复和MessageBox或MessageBeep方法是非常非常昂贵的调用有关。尝试以下测试:

HHOOK hHook;
BOOL bTalkEnabled = FALSE;

LRESULT CALLBACK pushtotalk(int key, WPARAM wParam, LPARAM lParam)
{
    if (key < 0)
        return CallNextHookEx(hHook, key, wParam, lParam);

    KBDLLHOOKSTRUCT* kbdll  = (KBDLLHOOKSTRUCT*)lParam;
    if (kbdll->vkCode == VK_F11)
    {
        BOOL bStarted = FALSE;
        BOOL bStopped = FALSE;

        if (wParam == WM_KEYDOWN)
        {
            if (!bTalkEnabled)
            {
                bStarted = TRUE;
                bTalkEnabled = TRUE;
            }
        }
        else if (wParam == WM_KEYUP)
        {
            if (bTalkEnabled)
            {
                bStopped = TRUE;
                bTalkEnabled = FALSE;
            }
        }

        if (bStarted)
            OutputDebugString(L"Pushed\r\n");
        if (bStopped)
            OutputDebugString(L"Released\r\n");
    }

    return 0;
}
HHOOK-HHOOK;
BOOL bTalkEnabled=FALSE;
LRESULT回调pushtotalk(int键、WPARAM WPARAM、LPARAM LPARAM)
{
如果(键<0)
返回CallNextHookEx(hHook、key、wParam、lParam);
KBDLLHOOKSTRUCT*kbdll=(KBDLLHOOKSTRUCT*)LPRAM;
如果(kbdll->vkCode==VK_F11)
{
BOOL bStarted=FALSE;
boolbstopped=FALSE;
if(wParam==WM_KEYDOWN)
{
如果(!btalk已启用)
{
b开始=正确;
bTalkEnabled=TRUE;
}
}
else if(wParam==WM\u KEYUP)
{
如果(BTalk已启用)
{
bStopped=TRUE;
bTalkEnabled=FALSE;
}
}
如果(b开始)
OutputDebugString(L“Pushed\r\n”);
如果(b停止)
OutputDebugString(L“已发布\r\n”);
}
返回0;
}
您可以通过在调试器下运行应用程序(检查输出窗口)来监视调试字符串,也可以获取并观看


请注意,我没有像您那样检查连接的
。您不想在钩子中执行该检查,在钩子外部执行该检查,并且仅使用钩子来确定是否按下了键。

否,因为我使用的是WH_键盘,我会将该进程放在主应用程序中。如果您注释掉MessageBox调用(或者用MessageBeep之类的内容替换它),您仍然有相同的问题吗?是的,相同的问题再次出现请编辑您的问题,以包含应用程序的消息循环。(如果你没有,那可能是问题所在。)我没有看到你发布的代码中有任何东西跳出来——消息循环可能有助于重现问题。今天早上偶然发现——如果设置为false,我如何检查“已连接”而不使用钩子?你的意思是在连接时创建钩子,然后在断开连接时删除它吗?另外,如果我像您在过程结束时那样返回0,这不是“截获”按键消息并阻止它们发送到当前有焦点的应用程序吗?例如,如果我在程序运行时在文本编辑器中写入“k”,我想捕捉“k”,但也不想干扰文本编辑器的输出。CallNextHook将消息传递给它的目标用户,对吗?您需要知道按键通话键的状态(向下或向上)。像我在这里做的那样,在处理程序中这样做。您可能需要执行除
OutputDebugString
以外的操作来响应,并且该代码可以检查连接状态。至于
CallNextHookEx
,您是正确的。我弄糊涂了。你第一次做对了。我知道如果我长时间按下按钮,所有的MessageBox/MessageBeep都会变得昂贵并阻塞系统(因此使用了全局布尔变量,如您所述),但这并不能解释为什么第一次短按键会在系统中产生5秒的冻结。有什么想法吗?你的系统糟透了?这不会发生在我的身上。当钩子开始活动时,会有一个短暂的、明显的停顿,但这还不到5秒。
while (GetMessage(&msg, NULL,0,0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}
HHOOK hHook;
BOOL bTalkEnabled = FALSE;

LRESULT CALLBACK pushtotalk(int key, WPARAM wParam, LPARAM lParam)
{
    if (key < 0)
        return CallNextHookEx(hHook, key, wParam, lParam);

    KBDLLHOOKSTRUCT* kbdll  = (KBDLLHOOKSTRUCT*)lParam;
    if (kbdll->vkCode == VK_F11)
    {
        BOOL bStarted = FALSE;
        BOOL bStopped = FALSE;

        if (wParam == WM_KEYDOWN)
        {
            if (!bTalkEnabled)
            {
                bStarted = TRUE;
                bTalkEnabled = TRUE;
            }
        }
        else if (wParam == WM_KEYUP)
        {
            if (bTalkEnabled)
            {
                bStopped = TRUE;
                bTalkEnabled = FALSE;
            }
        }

        if (bStarted)
            OutputDebugString(L"Pushed\r\n");
        if (bStopped)
            OutputDebugString(L"Released\r\n");
    }

    return 0;
}