简体   繁体   English

“跨过程子类化”的问题

[英]Problems with 'cross process subclassing'

Two questions. 两个问题。

1) I understand this must be an expected outcome but maybe someone can tell me what I'm doing wrong; 1)我知道这一定是预期的结果,但也许有人可以告诉我我做错了什么; I'm trying to subclass all window classes in a global hook and it works except that I'm not able to close shop as I should and when the program initially registering the hook unregisters the hook and exits, subclassed applications start crashing. 我试图在全局钩子中对所有窗口类进行子类化,并且它的工作原理是,我无法按照应有的方式关闭商店,并且当程序最初注册钩子时取消注册钩子并退出时,子类化的应用程序开始崩溃。

Here's how I'm trying to do it.. 这是我正在尝试的方法。

// 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;
}

In DllMain I don't do anything on DLL_PROCESS_DETACH. 在DllMain中,我对DLL_PROCESS_DETACH不执行任何操作。 Instead, ClearHooks() is called from the program originally registering the hooks and there only after the hook has sent a message signalling that it has executed the EnumWindows operation (restores original wndprocs, see above). 而是从最初注册该钩子的程序中调用ClearHooks(),并且仅在该钩子发送了表示已执行EnumWindows操作的消息(还原原始wndprocs,请参见上文)之后,才在该钩子中进行调用。

I subclass windows in a WndProc hook; 我将Windows放在WndProc挂钩中; all visible windows that receive a message and whose current wndproc is not the one in the dll, are subclassed. 所有可见消息且当前wndproc不是dll中的窗口的可见窗口都是子类。

Basically all (as far as I can tell) applications crash on exit despite the fact that windows do seem to get the wndproc set back to what it was when it was replaced. 基本上所有(据我所知)应用程序都在退出时崩溃,尽管Windows似乎确实将wndproc设置恢复为替换时的状态。 Anyone have a clue what I might be doing wrong? 有人知道我可能做错了什么吗?

2) I need this to intercept WM_MINMAXINFO and modify window maxsize whenever a window is maximized. 2)每当窗口最大化时,我需要它来拦截WM_MINMAXINFO并修改窗口maxsize。 Unfortunately I can't do this in the dll but I have to talk with a program to get the size info. 不幸的是,我无法在dll中执行此操作,但是我必须与程序进行交谈才能获取大小信息。 So, what's the best way to talk to that window; 因此,与该窗口对话的最佳方式是什么? I need it to pass back some info so I can modify the structure that came with the original WM_MINMAXINFO message. 我需要它来传递一些信息,以便可以修改原始WM_MINMAXINFO消息附带的结构。 Will a structure in WM_COPYDATA preserve it's data until the call to SendMessageTimeout returns? WM_COPYDATA中的结构是否会保留其数据,直到对SendMessageTimeout的调用返回?

Thanks 谢谢

There are plenty of pain points here. 这里有很多痛点。 You assume that no other code will subclass the window. 您假定没有其他代码可以将窗口作为子类。 And that such code will un-subclass it in the right order. 这样的代码将以正确的顺序取消子类化。 There is no right order, your hooking is quite asynchronous from the program's execution. 没有正确的顺序,您的钩子与程序的执行是完全异步的。

But, the workaround is simple enough. 但是,解决方法非常简单。 You are already hooking with SetWindowsHookEx, might as well do one more. 您已经迷上了SetWindowsHookEx,不妨再做一遍。 WH_CALLWNDPROC or WH_CALLWNDPROCRET, depending on what you want to do. WH_CALLWNDPROC或WH_CALLWNDPROCRET,具体取决于您要执行的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM