【问题标题】:SetWindowsHookEx to determine when a window is deactivatedSetWindowsHookEx 确定窗口何时被停用
【发布时间】:2019-11-19 23:17:41
【问题描述】:

我有一个全局的WH_CBT 32 位钩子,我用它来确定何时将使用HCBT_ACTIVATE 激活窗口。

如何确定窗口何时将被停用? 有CBTACTIVATESTRUCThWndActive,但有时是0x0,当切换到64 位窗口时它不会工作。

没有HCBT_DEACTIVATE

【问题讨论】:

  • 使用 64 位挂钩会发生什么?
  • 我感兴趣的窗口是 32 位的,所以我正在从 32 位 exe 的 32 位 dll 中安装一个钩子。我真的不想生成 64 位 exe 来安装 64 位挂钩。
  • 有时您必须使用有效的方法而不是适合的方法
  • CBT 挂钩不会告诉您何时停用窗口(@98​​7654328@ 似乎也没有)。尝试使用消息挂钩并查找 WM_ACTIVATE 窗口消息。

标签: windows winapi hook setwindowshookex


【解决方案1】:

正如@Remy Lebeau 提到的,您可以使用WM_ACTIVATE 消息。此消息在窗口被激活或停用时发送。 设置一个WH_CALLWNDPROC 钩子来捕获停用的消息,它会在系统将它们发送到目标窗口过程之前获取这些消息。 更多详情:

将 DLL 中的函数用于非本地挂钩:

#include <Windows.h>
#include <stdio.h>

LRESULT CALLBACK wndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevinstance, PSTR szCmdLine, int iCmdShow) {
    HWND hwnd;
    //...

    DWORD threadID = GetWindowThreadProcessId(hwnd, NULL);
    HINSTANCE hinstDLL = LoadLibrary(TEXT("..\\Debug\\ProcHookDLL.dll"));
    void (*AttachHookProc)(DWORD);
    AttachHookProc = (void (*)(DWORD)) GetProcAddress(hinstDLL, "AttachHook");
    AttachHookProc(threadID);

    MSG msg = {};

    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
    //...
};

这是 DLL 的代码:

#include <Windows.h>
#include <stdio.h>

HMODULE thisModule;
HHOOK hook;
LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam);

#ifdef __cplusplus      // If used by C++ code, 
    extern "C" {        // we need to export the C interface
#endif
    __declspec(dllexport) void AttachHook(DWORD threadID) {
        hook = SetWindowsHookEx(WH_CALLWNDPROC, LaunchListener, thisModule, threadID);
    }
#ifdef __cplusplus
}
#endif
    LRESULT CALLBACK LaunchListener(int nCode, WPARAM wParam, LPARAM lParam) {
        // process event here
        if (nCode >= 0) {
            CWPSTRUCT* cwp = (CWPSTRUCT*)lParam;
            if (cwp->message == WM_ACTIVATE) {
                if (LOWORD(cwp->wParam) == WA_INACTIVE)
                {
                    //the window being deactivated
                }
                else
                {
                    //the window being activated
                }
            }
        }
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    }

【讨论】:

  • 很难找到正确的钩子。我试过WH_CBTWH_GETMESSAGE。这是我需要的WH_CALLWNDPROC 钩子。谢谢。
猜你喜欢
  • 2022-01-09
  • 2021-02-03
  • 2011-07-05
  • 1970-01-01
  • 2013-09-04
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
相关资源
最近更新 更多