免责声明 :我不熟悉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
扩展样式属性寄予厚望。
总结一下:实际上是否可以托管另一个进程的窗口,并在子窗口冻结时不冻结自己的窗口?
答案 0 :(得分:17)
您不能指望阻止任何进程的GUI线程。在您的场景中,事情有点复杂,因为有两个GUI线程。每个过程一个。
但是,通过在这些进程的窗口之间建立父/子关系,您还要求及时为两个GUI线程提供服务。
处于父/子关系的Windows将相互发送消息。如果这些消息是同步的,那就是发送而不是发布,那么阻止一个GUI线程将导致另一个被阻止。
GUI编程的黄金法则仍然有效:不要阻止GUI线程。如果您有一个长时间运行的任务,那么将其移动到后台线程。
<强>更新强>
好的,正如here所解释的那样,当您关联来自不同线程的窗口时,您将其消息队列相互附加。因此,如果您阻止一个线程,则会阻止所有连接的线程。
所以,不要阻止GUI线程。