【发布时间】:2013-05-24 21:41:19
【问题描述】:
免责声明:我不熟悉 Win32 API,尤其是 windows 的工作原理。
我想让某个进程的窗口成为另一个进程的子窗口。这两个进程也是父进程和子进程。但我认为这并不重要。到目前为止,一切都像一个魅力 - 直到我冻结子窗口的主线程。
想象一个“托管”notepad.exe 和 someApplication.exe 的 container.exe
当我暂停 someApplication.exe 的主线程几秒钟时,它的窗口在这段时间内被冻结。这是完全可以理解的。但是container.exe的窗口也会同时挂起。其他托管进程(如 notepad.exe)的子窗口将继续正常工作。
我正在使用SetParent 命令将常规非子窗口作为我的 container.exe 的子窗口:
SetParent(
childProcess.HWND,
myOwnHWND
);
之后,我使用setWindowPos:
SetWindowPos(
childProcess.HWND,
HWND_TOP,
someXPos,
someYPos,
0,
0,
SWP_FRAMECHANGED or SWP_NOSIZE or SWP_SHOWWINDOW
)
正如MSDN article on SetParent 建议的那样,我还清除了WS_POPUP 样式属性并添加了WS_CHILD 属性。由于这也没有帮助,我还添加了一个WS_EX_NOACTIVATE 扩展样式属性,两者都使用SetWindowLongPtr 命令。最后,我尝试向两个窗口发送 WM_UPDATEUISTATE 和 WM_CHANGEUISTATE 消息,但这也没有改变。
让我感到困惑的是,父进程的窗口继续正常绘制,直到我触摸它。然后它完全冻结,直到子窗口解冻。我怀疑有一个叫做'输入队列'的东西。关于WM_ACTIVATE 消息的MSDN article 声明:
发送到正在激活的窗口和正在停用的窗口。如果窗口使用相同的输入队列,则消息同步发送,首先发送到被停用的顶层窗口的窗口过程,然后发送到顶层窗口的窗口过程顶层窗口被激活。如果窗口使用不同的输入队列,消息是异步发送的,所以窗口立即被激活。
因此,我对 WS_EX_NOACTIVATE 扩展样式属性寄予厚望。
总结一下:实际上是否可以托管另一个进程的窗口,并且在子窗口冻结时不冻结自己的窗口?
【问题讨论】:
-
+1 这个问题非常彻底。
-
为什么你需要这样做?我相信有更好更简单的方法来实现你的实际目的。不要陷入 XY 问题陷阱。
-
@GSerg:正是我想发布的链接。通过以父/子方式从两个或多个进程绑定 Windows,您可以绑定它们的输入队列。如果您随后阻止任何输入队列,则所有 Windows 都会被阻止。