0

两个问题。

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 操作(恢复原始 wndprocs,见上文)之后才调用。

我在 WndProc 钩子中子类化窗口;所有接收消息且当前 wndproc 不是 dll 中的窗口的可见窗口都被子类化。

基本上所有(据我所知)应用程序在退出时都会崩溃,尽管 Windows 似乎确实将 wndproc 设置回它被替换时的状态。任何人都知道我可能做错了什么?

2)我需要这个来拦截 WM_MINMAXINFO 并在窗口最大化时修改窗口 maxsize。不幸的是,我不能在 dll 中执行此操作,但我必须与程序交谈以获取大小信息。那么,与那个窗口对话的最佳方式是什么?我需要它传回一些信息,以便我可以修改原始 WM_MINMAXINFO 消息附带的结构。WM_COPYDATA 中的结构是否会保留其数据,直到对 SendMessageTimeout 的调用返回?

谢谢

4

1 回答 1

0

这里有很多痛点。您假设没有其他代码将子类化该窗口。并且这样的代码将以正确的顺序取消子类化。没有正确的顺序,您的挂钩与程序的执行完全异步。

但是,解决方法很简单。您已经在使用 SetWindowsHookEx,不妨再做一次。WH_CALLWNDPROC 或 WH_CALLWNDPROCRET,取决于你想要做什么。

于 2010-10-16T18:00:43.490 回答