两个问题。
1)我明白这一定是预期的结果,但也许有人可以告诉我我做错了什么;我正在尝试将所有窗口类子类化为全局钩子并且它工作,除了我无法按照我应该关闭商店,当程序最初注册钩子时注销钩子并退出,子类应用程序开始崩溃。
以下是我试图做的事情..
// stores original wndprocs. In the hook dll, outside the shared memory.
map<HWND, WNDPROC> origWndProcs;
// in an EnumWindows callback, executed for all HWND's, also in the hook dll (UWM_REMOVE_HOOK is a registered unique message)
SendMessageTimeout(hWnd, UWM_REMOVE_HOOK, 0, 0, SMTO_ABORTIFHUNG | SMTO_NORMAL, 15000, res);
// Still in the same hook, in the subclassing wndproc..
if (msg == UWM_REMOVE_HOOK) {
if (origWndProcs.find(hwnd) != origWndProcs.end()) {
SetWindowLongPtr(hwnd, GWL_WNDPROC, (LONG_PTR)origWndProcs[hwnd]);
}
}
// clears the hook..
__declspec(dllexport) BOOL ClearHooks(HWND hWnd) {
BOOL unhooked = UnhookWindowsHookEx(hook) &&
UnhookWindowsHookEx(kb_hook) &&
UnhookWindowsHookEx(mouse_hook) &&
UnhookWindowsHookEx(cbt_hook);
if(unhooked)
hWndServer = NULL;
return unhooked;
}
在DllMain中,我没有对DLL_PROCESS_DETACH做任何事情。相反,ClearHooks()是从最初注册钩子的程序中调用的,只有在钩子发送了一条消息后才发出信号表明它已经执行了EnumWindows操作(恢复原始的wndproc,见上文)。
我在WndProc钩子中子类化窗口;接收消息并且当前wndproc不是dll中的所有可见窗口都是子类。
基本上所有(据我所知)应用程序在退出时崩溃,尽管windows似乎确实将wndproc设置恢复到更换时的状态。任何人都知道我可能做错了什么?
2)我需要这个来拦截WM_MINMAXINFO并在窗口最大化时修改窗口maxsize。不幸的是我不能在dll中这样做,但我必须与程序交谈以获取大小信息。那么,与窗口交谈的最佳方式是什么?我需要它传回一些信息,以便我可以修改原始WM_MINMAXINFO消息附带的结构。在调用SendMessageTimeout之前,WM_COPYDATA中的结构是否会保留它的数据?
由于
答案 0 :(得分:0)
这里有很多痛点。您假设没有其他代码将子类化窗口。并且这样的代码将以正确的顺序对其进行非子类化。没有正确的顺序,你的挂钩与程序的执行非常不同。
但是,解决方法很简单。您已经使用SetWindowsHookEx挂钩了,不妨再做一次。 WH_CALLWNDPROC或WH_CALLWNDPROCRET,取决于您想要做什么。