基本上,我想在用户点击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);
答案 0 :(得分:1)
您必须在挂钩后抽取消息,而您的示例不会这样做。
其他应用程序中的线程的钩子程序必须在.DLL中:
仅在关联线程的上下文中调用特定于线程的挂钩过程。如果应用程序为其自己的一个线程安装了一个钩子过程,那么钩子过程可以与应用程序代码的其余部分在一个模块中,也可以在DLL中。如果应用程序为不同应用程序的线程安装了一个钩子过程,则该过程必须位于DLL中。
WH_CBT
或WH_SHELL
挂钩可能更适合您尝试的操作。
或者您可以尝试使用event hook抓取EVENT_OBJECT_DESTROY
。事件挂钩明确支持超出上下文的挂钩。