父窗口在子窗口冻结时冻结,尽管它来自另一个进程 [英] Parent window freezes when child window freezes altough it's from another process

查看:25
本文介绍了父窗口在子窗口冻结时冻结,尽管它来自另一个进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Disclaimer: I'm not familiar with the Win32 API, especially how windows work.

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

I'd like to make the window of some process a child window of another process. The two processes are also parent and child. But I don't think that matters. So far, everything works like a charm - Until I freeze the main thread of the child window.

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

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

When I suspend the main thread of someApplication.exe for a few seconds, its window is frozen for that amount of time. That's perfectly understandable. But the window of container.exe will also hang for the same time. The child windows of other hosted processes (like notepad.exe) will continue to work fine.

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

I am using the SetParent command to make a regular non-child window a child of my container.exe:

SetParent(
    childProcess.HWND,
    myOwnHWND
);

在那之后,我使用 setWindowPos:

SetWindowPos(
    childProcess.HWND,
    HWND_TOP,
    someXPos,
    someYPos,
    0,
    0,
    SWP_FRAMECHANGED or SWP_NOSIZE or SWP_SHOWWINDOW
)

作为 MSDNSetParent 上的文章建议,我还清除了 WS_POPUP 样式属性并添加了 WS_CHILD 属性.由于这也无济于事,我还通过使用 SetWindowLongPtr 命令添加了 WS_EX_NOACTIVATE 扩展样式属性.最后,我尝试向两个窗口发送 WM_UPDATEUISTATEWM_CHANGEUISTATE 消息,但这也没有改变任何事情.

As the MSDN article on SetParent suggests, I also clear the WS_POPUP style attribute and add a WS_CHILD attribute. Since that didn't help either, I also added a WS_EX_NOACTIVATE extended style attribute, both by using the SetWindowLongPtr command. Finally, I tried sending both windows a WM_UPDATEUISTATE and then a WM_CHANGEUISTATE message but that also didn't change a thing.

让我困惑的是,父进程的窗口继续正常绘制,直到我触摸它.然后它完全冻结,直到子窗口解冻.我怀疑有一种叫做'输入队列'的东西.MSDN 文章 关于 WM_ACTIVATE 消息状态:

The thing that confuses me is that the window of the parent process continues to be drawn normally, until I touch it. Then it freezes completely until the child window unfreezes. I suspect something called an 'input queue'. The MSDN article about a WM_ACTIVATE message states:

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

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 扩展样式属性寄予厚望.

Because of that, I had high hopes for the WS_EX_NOACTIVATE extended style attribute.

总结一下:实际上有没有可能托管另一个进程的窗口而在子窗口冻结时不冻结自己的窗口?

To sum it up: Is actually possible to host the window of another process and to not freeze your own window when the child window freezes?

推荐答案

您不能期望阻塞任何进程的 GUI 线程.在您的场景中,事情稍微复杂一些,因为有两个 GUI 线程.每个进程一个.

You cannot expect to block the GUI thread of any process. In your scenario things are a little more complex because there are two GUI threads. One for each process.

然而,通过在这些进程的窗口之间建立父/子关系,您也引入了一个要求,即两个 GUI 线程都得到及时服务.

However, by establishing a parent/child relationship between windows of these processes you are also introducing a requirement that both GUI threads are serviced in good time.

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

Windows that are in a parent/child relationship will send each other messages. And if those messages are synchronous, that is sent rather than posted, then blocking one GUI thread will lead to the other being blocked.

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

The golden rule of GUI programming remains in force: do not block a GUI thread. If you have a long running task, then move it onto a background thread.

更新

好的,正如此处所解释的那样您将来自不同线程的窗口关联起来,并将它们的消息队列相互关联.因此,如果您阻止一个线程,就会阻止所有附加的线程.

OK, as explained here when you relate windows from different threads you attach their message queues to each other. And so if you block one thread, you block all of the attached threads.

所以,不要阻塞 GUI 线程.

So, don't block a GUI thread.

这篇关于父窗口在子窗口冻结时冻结,尽管它来自另一个进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆