当子窗口从另一个进程冻结时,父窗口会冻结

Gün*_*ful 25 delphi winapi window

免责声明:我不熟悉Win32 API,尤其是Windows的工作方式.

我想让某个进程的窗口成为另一个进程的子窗口.这两个过程也是父母和孩子.但我认为不重要.到目前为止,一切都像魅力一样 - 直到我冻结子窗口的主线程.

想象一下一个"托管"notepad.exe和someApplication.exe的container.exe

当我暂停someApplication.exe的主线程几秒钟时,它的窗口会被冻结一段时间.这完全可以理解.但是container.exe的窗口也会同时挂起.其他托管进程(如notepad.exe)的子窗口将继续正常工作.

我正在使用该SetParent命令使常规非子窗口成为我的container.exe的子项:

SetParent(
    childProcess.HWND,
    myOwnHWND
);
Run Code Online (Sandbox Code Playgroud)

在那之后,我正在使用setWindowPos:

SetWindowPos(
    childProcess.HWND,
    HWND_TOP,
    someXPos,
    someYPos,
    0,
    0,
    SWP_FRAMECHANGED or SWP_NOSIZE or SWP_SHOWWINDOW
)
Run Code Online (Sandbox Code Playgroud)

正如关于SetParentMSDN文章所示,我还清除了WS_POPUPstyle属性并添加了一个WS_CHILD属性.由于这也没有帮助,我还WS_EX_NOACTIVATE通过使用SetWindowLongPtr命令添加了扩展样式属性.最后,我尝试发送两个窗口WM_UPDATEUISTATE然后WM_CHANGEUISTATE发送消息,但这也没有改变一件事.

令我困惑的是,父进程的窗口继续正常绘制,直到我触摸它.然后它完全冻结,直到子窗口解冻.我怀疑称为"输入队列"的东西.有关消息的MSDN文章WM_ACTIVATE指出:

发送到正在激活的窗口和停用的窗口.如果窗口使用相同的输入队列,则同步发送消息,首先发送到被停用的顶级窗口的窗口过程,然后发送到被激活的顶级窗口的窗口过程.如果窗口使用不同的输入队列,则会异步发送消息,因此会立即激活窗口.

因此,我对WS_EX_NOACTIVATE扩展样式属性寄予厚望.

总结一下:实际上可以托管另一个进程的窗口,并在子窗口冻结时不冻结自己的窗口吗?

Dav*_*nan 17

您不能指望阻止任何进程的GUI线程.在您的场景中,事情有点复杂,因为有两个GUI线程.每个过程一个.

但是,通过在这些进程的窗口之间建立父/子关系,您还要求及时为两个GUI线程提供服务.

处于父/子关系的Windows将相互发送消息.如果这些消息是同步的,那就是发送而不是发布,那么阻塞一个GUI线程将导致另一个被阻止.

GUI编程的黄金法则仍然有效:不要阻止GUI线程.如果您有一个长时间运行的任务,然后将其移动到后台线程.

更新

好的,正如您在解释来自不同线程的窗口时所解释的那样,您将其消息队列相互附加.因此,如果您阻止一个线程,则会阻止所有连接的线程.

所以,不要阻止GUI线程.

  • 所以关键是两个窗口现在都使用相同的_input queue_.核心问题在于将"WM_ACTIVATE"消息同步**发送到冻结窗口.这是另一篇新闻组帖子,涵盖了完全相同的主题:[链接](http://narkive.com/YmRDFrDR).因为我不希望能够使用类似`AttachThreadInput`命令的子窗口_input queue_分离,所以我接受这个作为答案,并且在没有父/子窗口关系的情况下过上幸福的生活.非常感谢! (2认同)