delphi – 父窗口冻结时,子窗口冻结,虽然它是从另一个过程

前端之家收集整理的这篇文章主要介绍了delphi – 父窗口冻结时,子窗口冻结,虽然它是从另一个过程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
免责声明:我不熟悉Win32 API,尤其是Windows如何工作。此外,这是我的第一篇关于SO。这个问题可能是令人难以置信的愚蠢。

我想让一些进程的窗口是另一个进程的子窗口。这两个进程也是父级和子级。但我不认为重要。到目前为止,一切都像一个魅力 – 直到我冻结子窗口的主线程。

想象一下,一个“hosts”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,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指出:

Sent to both the window being activated and the window being deactivated. If the windows use the same input queue,the message is sent synchronously,first to the window procedure of the top-level window being deactivated,then to the window procedure of the top-level window being activated. If the windows use different input queues,the message is sent asynchronously,so the window is activated immediately.

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

总结:实际上可能托管另一个进程的窗口,并且当子窗口冻结时不冻结您自己的窗口?

解决方法

你不能期望阻塞任何进程的GUI线程。在你的场景中,事情有点复杂,因为有两个GUI线程。每个过程一个。

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

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

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

更新

OK,正如解释here当你从不同的线程关联窗口,你附加他们的消息队列彼此。所以如果你阻塞一个线程,你阻塞所有附加的线程。

所以,不要阻塞GUI线程。

原文链接:https://www.f2er.com/delphi/103591.html

猜你在找的Delphi相关文章