处理来自其他进程的窗口消息
我正在开发一个 C# WPF 应用程序,该应用程序使用对 Win32 SetParent() 的调用来重新设置另一个应用程序的主窗口的父级。该进程外子窗口的句柄由派生自 HwndHost 的名为 FormHost 的类包装。一切都运行良好,除了一件事:重新设置父级的窗口的消息不会传递到 FormHost。 MSDN 文档明确指出 HwndHost 窗口过程 WndProc() 不能与进程外窗口一起使用。另一种方法 MessageHook 也不起作用。我还尝试调用 AttachThreadInput() 来合并两个窗口的输入处理。运气不好。有什么建议吗?
I'm developing a C# WPF application that reparents the main window of another application using a call to Win32 SetParent(). The handle to this out-of-process child window is wrapped by a class named FormHost which is derived from HwndHost. All is working well except for one thing: messages for the reparented window are not delivered to FormHost. MSDN documentation clearly states that the HwndHost window procedure WndProc() cannot be used with out-of-process windows. The alternative, MessageHook doesn't work either. I also tried calling AttachThreadInput() to combine the input processing of the two windows. No luck. Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
重新设置窗口父级的进程不能直接子类化进程外窗口的消息过程。它必须将自己的窗口过程代码注入到窗口所属进程的地址空间中,在该地址空间中对窗口进行子类化,然后最终使用您选择的 IPC 机制根据需要与重定父进程进行通信。
对于实际的注入,您可以:
1)将实际的窗口过程代码放入 DLL 中,使用 CreateRemoteThread() 将 DLL 加载到窗口所属进程中,然后让 DLL 的 DllEntryPoint() 子类化窗口(您将拥有将 HWND 句柄存储在全局内存中的某个位置,以便 DLL 可以找到它)。
2) 使用 VirtualAllocEx() 和 WriteProcessMemory() 将实际的窗口过程代码放入在窗口所属进程的地址空间内分配的内存块中,然后使用 CreateRemoteThread() 使用该内存块执行窗口的实际子类化作为窗口过程。
The process that is reparenting the window cannot directly subclass the message procedure of an out-of-process window. It would have to inject its own window procedure code into the address space of the window's owning process, subclass the window within that address space, and then finally use an IPC mechanism of your choosing to communicate back to the reparenting process as needed.
For the actual injection, you can either:
1) put the actual window procedure code into a DLL, use CreateRemoteThread() to load the DLL into the window's owning process, and then have the DLL's DllEntryPoint() subclass the window (you would have to store the HWND handle in global memory somewhere so the DLL can find it).
2) put the actual window procedure code into a block of memory allocated within the address space of the window's owning process by using VirtualAllocEx() and WriteProcessMemory(), then use CreateRemoteThread() to perform the actual subclass of the window using that memory block as the window procedure.