C++ 在活动窗口更改时获取通知

C++ 在活动窗口更改时获取通知,c++,windows,winapi,hook,C++,Windows,Winapi,Hook,我试图让我的程序在焦点改变时获取当前活动窗口标题。我收到以下回电: LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam) { if (wParam == HCBT_SETFOCUS || lParam == HCBT_SETFOCUS) cout << GetActiveWindowTitle(); return(CallNextHookEx(NULL,

我试图让我的程序在焦点改变时获取当前活动窗口标题。我收到以下回电:

LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (wParam == HCBT_SETFOCUS || lParam == HCBT_SETFOCUS)
        cout << GetActiveWindowTitle();

    return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
也许我很愚蠢,但它并没有按预期的那样工作,有人知道为什么吗

编辑: 看起来程序根本没有检测到窗口的变化,我尝试过将代码改成这样,但没有效果:

LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS)
        cout << "TEST";

    return(CallNextHookEx(NULL, nCode, wParam, lParam));
}
LRESULT回调windowChangeHook(int-nCode、WPARAM-WPARAM、LPARAM-LPARAM)
{
如果(nCode==HCBT_激活| | nCode==HCBT_设置焦点)
cout
  • 您没有检查
    SetWindowsHookEx
    中的返回值

  • windowChangeHook
    需要与
    hMod
    参数中的
    HMODULE
    一起位于DLL中

  • HCBT.*
    值在
    nCode
    参数中传递

您也可以尝试使用…

  • 您没有检查
    SetWindowsHookEx
    中的返回值

  • windowChangeHook
    需要与
    hMod
    参数中的
    HMODULE
    一起位于DLL中

  • HCBT.*
    值在
    nCode
    参数中传递


您也可以尝试改用…

您没有正确处理
WH\u CBT
回调

根据文件:

LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_SETFOCUS)
    {
        HWND hwnd = (HWND) wParam;
        // retreive and use the title of hwnd as needed...
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
nCode[in]
类型:int

钩子过程用于确定如何处理消息的代码。如果
nCode
小于零,钩子过程必须将消息传递给
CallNextHookEx
函数,而无需进一步处理,并应返回
CallNextHookEx
返回的值。此参数可以是下面的值

HCBT_设置焦点
9
一个窗口即将接收键盘焦点

wParam[in]
类型:WPARAM

取决于
nCode
参数。有关详细信息,请参阅以下备注部分

lParam[in]
类型:LPRAM

取决于
nCode
参数。有关详细信息,请参阅以下备注部分

下表描述了每个
HCBT\uucode>hook代码的
wParam
lParam
参数

HCBT_设置焦点
wParam:指定获得键盘焦点的窗口句柄。
lParam:指定丢失键盘焦点的窗口句柄

您正在错误的参数中查找
HCBT_SETFOCUS
值。您还检索了错误窗口的标题,因为输入焦点尚未实际切换窗口

您的回调应该更像这样(假设您的回调是在DLL中实现的,这是检测全局事件所必需的,这也意味着您在64位系统上需要单独的32位和64位DLL。文档中对此进行了解释):

所说的,你应该考虑使用,如果你使用钩子“脱离上下文”,则不需要DLL要求:

回调函数未映射到生成事件的进程的地址空间。由于钩子函数是跨进程边界调用的,因此系统必须对事件排队。尽管此方法是异步的,但事件保证按顺序排列。有关详细信息,请参阅

事件\对象\焦点
0x8005

对象已收到键盘焦点。系统为以下用户界面元素发送此事件:列表视图控件、菜单栏、弹出菜单、切换窗口、选项卡控件、树视图控件和窗口对象。服务器应用程序为其可访问对象发送此事件

调用函数
WinEventProc
hwnd
参数标识接收键盘焦点的窗口

例如:

void CALLBACK windowChangeHook(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime)
{
    // retreive and use the title of hwnd as needed...
}

HWINEVENTHOOK hEventHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_FOCUS, NULL, &windowChangeHook, 0, 0, WINEVENT_OUTOFCONTEXT);
...
UnhookWinEvent(hEventHook);

您没有正确处理
WH\u CBT
回调

根据文件:

LRESULT CALLBACK windowChangeHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_SETFOCUS)
    {
        HWND hwnd = (HWND) wParam;
        // retreive and use the title of hwnd as needed...
    }

    return CallNextHookEx(NULL, nCode, wParam, lParam);
}
nCode[in]
类型:int

钩子过程用于确定如何处理消息的代码。如果
nCode
小于零,钩子过程必须将消息传递给
CallNextHookEx
函数,而无需进一步处理,并应返回
CallNextHookEx
返回的值。此参数可以是下面的值

HCBT_设置焦点
9
一个窗口即将接收键盘焦点

wParam[in]
类型:WPARAM

取决于
nCode
参数。有关详细信息,请参阅以下备注部分

lParam[in]
类型:LPRAM

取决于
nCode
参数。有关详细信息,请参阅以下备注部分

下表描述了每个
HCBT\uucode>hook代码的
wParam
lParam
参数

HCBT_设置焦点
wParam:指定获得键盘焦点的窗口句柄。
lParam:指定丢失键盘焦点的窗口句柄

您正在错误的参数中查找
HCBT_SETFOCUS
值。您还检索了错误窗口的标题,因为输入焦点尚未实际切换窗口

您的回调应该更像这样(假设您的回调是在DLL中实现的,这是检测全局事件所必需的,这也意味着您在64位系统上需要单独的32位和64位DLL。文档中对此进行了解释):

所说的,您应该考虑使用,而不需要DLL要求。