Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
772 views
in Technique[技术] by (71.8m points)

delphi - Parent window freezes when child window freezes altough it's from another process

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.

Imagine a container.exe that 'hosts' notepad.exe and someApplication.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.

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

SetParent(
    childProcess.HWND,
    myOwnHWND
);

After that, I'm using setWindowPos:

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

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.

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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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 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.

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.

Update

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.

So, don't block a GUI thread.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...