在WinApi中捕获窗口的关闭事件

时间:2018-03-23 11:39:25

标签: windows winapi events hook user32

基本上,我想在用户点击X(关闭)特定窗口后做一些事情。

这是我的方法:

HWND handle;

LRESULT WINAPI procedure(int code, WPARAM wParam, LPARAM, lParam){
    CWPSTRUCT* j = (CWPSTRUCT*) lParam;
    WPSTRUCT* w = (CWPSTRUCT*) wParam;

    if(w->message == WM_SYSCOMMAND && j->message == SC_CLOSE){
        //do something
    }
}

Void doSomething(){
    HINSTANCE hDLL = LoadLibrary("User32.dll");
    HWND WINAPI FindWindow(_In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowName);
    HHOOK WINAPI SetWindowsHookEx(_In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId);

    handle = FindWindow("Notepad", NULL) //for example
    DWORD threadId = GetWindowThreadProcessId(handle, NULL);
    HHOOK hhook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC) &procedure, (HINSTANCE) NULL, threadId);
    return;
}

这不起作用,因为应用程序永远不会进入 过程()

修改:在 -RbMm 提出建议后,我从句柄中找到 threadId 。谢谢。

 DWORD threadId = GetWindowThreadProcessId(handle, NULL);
 HHOOK hhook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC) &procedure, (HINSTANCE) NULL, threadId);

1 个答案:

答案 0 :(得分:1)

您必须在挂钩后抽取消息,而您的示例不会这样做。

其他应用程序中的线程的钩子程序必须在.DLL中:

  

仅在关联线程的上下文中调用特定于线程的挂钩过程。如果应用程序为其自己的一个线程安装了一个钩子过程,那么钩子过程可以与应用程序代码的其余部分在一个模块中,也可以在DLL中。如果应用程序为不同应用程序的线程安装了一个钩子过程,则该过程必须位于DLL中。

WH_CBTWH_SHELL挂钩可能更适合您尝试的操作。

或者您可以尝试使用event hook抓取EVENT_OBJECT_DESTROY。事件挂钩明确支持超出上下文的挂钩。