Discussion:
Z-Order of Topmost window (Multithreaded UI)
(too old to reply)
Denis Adamchuk
2008-12-17 19:15:01 UTC
Permalink
Hi everyone,

I see behavior which violates rules from the well-known article "Windows
Features"
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx

I have an MFC MDI application which is a bit different from a generated by
Visual Studio Wizard:
ChildFrames are not WS_CHILD but WS_POPUP. It allows to move MDI-childs out
of the MainFrame. Looks good!
Since ChildFrames are popup windows now, they are owned by the Mainframe.

On some user action I want to create a topmost window in a separate thread.
I design it to have WS_POPUP and WS_EX_TOPMOST styles and have the active
Child Frame as owner.

Then I start the application and open 2 child frames (A and B).
When the topmost window is created (say, with the child frame A as owner) -
appears the most weird Windows behavior I've ever seen:
If the topmost window is active now - a mouse click at the caption of the
child frame B brings this childframe to the bottom of Z-order, even behind
the Mainframe!

It's weird and it violates the rule from the "Windows Features":
"An owned window is always above its owner in the z-order."

Does anybody know what's wrong with TOPMOST windows in Win32?

Thanks a lot!
Drew
2008-12-17 19:58:21 UTC
Permalink
Secondary threads are not allowed to create windows and may not interact
with windows in the UI thread directly. Threads interact with main GUI
thread windows using PostMessage().

Drew
Post by Denis Adamchuk
Hi everyone,
I see behavior which violates rules from the well-known article "Windows
Features"
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx
I have an MFC MDI application which is a bit different from a generated by
ChildFrames are not WS_CHILD but WS_POPUP. It allows to move MDI-childs out
of the MainFrame. Looks good!
Since ChildFrames are popup windows now, they are owned by the Mainframe.
On some user action I want to create a topmost window in a separate thread.
I design it to have WS_POPUP and WS_EX_TOPMOST styles and have the active
Child Frame as owner.
Then I start the application and open 2 child frames (A and B).
When the topmost window is created (say, with the child frame A as owner) -
If the topmost window is active now - a mouse click at the caption of the
child frame B brings this childframe to the bottom of Z-order, even behind
the Mainframe!
"An owned window is always above its owner in the z-order."
Does anybody know what's wrong with TOPMOST windows in Win32?
Thanks a lot!
Joseph M. Newcomer
2008-12-17 20:59:51 UTC
Permalink
See below...

On Wed, 17 Dec 2008 11:15:01 -0800, Denis Adamchuk
Post by Denis Adamchuk
Hi everyone,
I see behavior which violates rules from the well-known article "Windows
Features"
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx
I have an MFC MDI application which is a bit different from a generated by
ChildFrames are not WS_CHILD but WS_POPUP. It allows to move MDI-childs out
of the MainFrame. Looks good!
Since ChildFrames are popup windows now, they are owned by the Mainframe.
On some user action I want to create a topmost window in a separate thread.
I design it to have WS_POPUP and WS_EX_TOPMOST styles and have the active
Child Frame as owner.
****
As soon as you say you want to create a window in a separate thread, you are entering
dangerous territory. Why? There is no reason to do so. All windows should be owned by
the main GUI thread.
****
Post by Denis Adamchuk
Then I start the application and open 2 child frames (A and B).
When the topmost window is created (say, with the child frame A as owner) -
****
As soon as you say you are creating windows owned by multiple threads, the above line is
the inevitable consequence. Which is why it is not a recommended practice. Because there
is no reason to create windows in secondary threads, it should not be done, because then
questions that start with that introduction never come up.
****
Post by Denis Adamchuk
If the topmost window is active now - a mouse click at the caption of the
child frame B brings this childframe to the bottom of Z-order, even behind
the Mainframe!
****
This may have nothing to do with multithreading, but I wouldn't even bother to answer such
a question until the windows were moved into the main GUI thread.
****
Post by Denis Adamchuk
"An owned window is always above its owner in the z-order."
Does anybody know what's wrong with TOPMOST windows in Win32?
****
Until all windows are in one thread, the question is not worth answering.

You are doing something that is so far out in the minefield that you should expect that
any step you take is going to blow up something.
joe
****
Post by Denis Adamchuk
Thanks a lot!
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Denis Adamchuk
2008-12-18 09:05:00 UTC
Permalink
Joseph,

I completely understand advantages of the single UI thread.
Ok, probably there is no reason to do so.
But why there are no "DON'T DO IT" neither in MSDN nor in OldNewThing?
Seems strange!
I cannot tell to the project architect that multithreaded UI is risky
because there are no facts at all...

The same scenario (popup MDI childs and topmost windows) works good when
everything belongs to the primary UI thread. Therefore I believe that my
issue has something to do with the multithreading.

I know that my design is risky and Windows behavior could be kind-of
unusual. But I cannot understand why the rule from MSDN is violated. I've
read all articles related to the Windows Management in the MSDN and have
found nothing about risks of multithreaded UI. Isn't it strange?
There are millions of software developers in the world and I cannot believe
that I'm the first one who face up with this issue.

Thank you very much!
Post by Joseph M. Newcomer
See below...
On Wed, 17 Dec 2008 11:15:01 -0800, Denis Adamchuk
Post by Denis Adamchuk
Hi everyone,
I see behavior which violates rules from the well-known article "Windows
Features"
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx
I have an MFC MDI application which is a bit different from a generated by
ChildFrames are not WS_CHILD but WS_POPUP. It allows to move MDI-childs out
of the MainFrame. Looks good!
Since ChildFrames are popup windows now, they are owned by the Mainframe.
On some user action I want to create a topmost window in a separate thread.
I design it to have WS_POPUP and WS_EX_TOPMOST styles and have the active
Child Frame as owner.
****
As soon as you say you want to create a window in a separate thread, you are entering
dangerous territory. Why? There is no reason to do so. All windows should be owned by
the main GUI thread.
****
Post by Denis Adamchuk
Then I start the application and open 2 child frames (A and B).
When the topmost window is created (say, with the child frame A as owner) -
****
As soon as you say you are creating windows owned by multiple threads, the above line is
the inevitable consequence. Which is why it is not a recommended practice. Because there
is no reason to create windows in secondary threads, it should not be done, because then
questions that start with that introduction never come up.
****
Post by Denis Adamchuk
If the topmost window is active now - a mouse click at the caption of the
child frame B brings this childframe to the bottom of Z-order, even behind
the Mainframe!
****
This may have nothing to do with multithreading, but I wouldn't even bother to answer such
a question until the windows were moved into the main GUI thread.
****
Post by Denis Adamchuk
"An owned window is always above its owner in the z-order."
Does anybody know what's wrong with TOPMOST windows in Win32?
****
Until all windows are in one thread, the question is not worth answering.
You are doing something that is so far out in the minefield that you should expect that
any step you take is going to blow up something.
joe
****
Post by Denis Adamchuk
Thanks a lot!
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Scott McPhillips [MVP]
2008-12-18 13:42:37 UTC
Permalink
Post by Denis Adamchuk
Joseph,
I completely understand advantages of the single UI thread.
Ok, probably there is no reason to do so.
But why there are no "DON'T DO IT" neither in MSDN nor in OldNewThing?
Seems strange!
I cannot tell to the project architect that multithreaded UI is risky
because there are no facts at all...
Some facts demonstrating why multithreaded UI is risky:
- It is documented that most actions performed on windows are done with a
SendMessage call.
- It is documented that SendMessage blocks the calling thread until the
target thread handles it.
- Parent/Child windows, and Owner/Owned windows, have implementation-defined
communication between them that is hidden within the OS and undocumented.
- Therefore in a multithreaded UI with these window interrelationships we
have hidden, undocumented blocking calls and we don't even know what actions
trigger them.
- There's a big risk: Potentially blocking calls in your thread that you
cannot predict. That leaves you with unknown effect on performance, and of
course it introduces the possibility of deadlocks under unknown conditions.

Displaying a top level window in a secondary thread is not affected by this
line of reasoning, and indeed I've done it and it has worked OK for me. But
displaying windows with interrelationships in different threads has caused
many newsgroup posts, including yours, demonstrating that it has many
problems.
--
Scott McPhillips [VC++ MVP]
Denis Adamchuk
2008-12-18 13:57:37 UTC
Permalink
Scott,

You said that you did it and it worked?
Could you please describe briefly what kind of UI you had in separate threads?
Were there any relationships (parent/child or owner/owned) between your
windows or they were absolutely isolated?

Thanks!
Post by Scott McPhillips [MVP]
Post by Denis Adamchuk
Joseph,
I completely understand advantages of the single UI thread.
Ok, probably there is no reason to do so.
But why there are no "DON'T DO IT" neither in MSDN nor in OldNewThing?
Seems strange!
I cannot tell to the project architect that multithreaded UI is risky
because there are no facts at all...
- It is documented that most actions performed on windows are done with a
SendMessage call.
- It is documented that SendMessage blocks the calling thread until the
target thread handles it.
- Parent/Child windows, and Owner/Owned windows, have implementation-defined
communication between them that is hidden within the OS and undocumented.
- Therefore in a multithreaded UI with these window interrelationships we
have hidden, undocumented blocking calls and we don't even know what actions
trigger them.
- There's a big risk: Potentially blocking calls in your thread that you
cannot predict. That leaves you with unknown effect on performance, and of
course it introduces the possibility of deadlocks under unknown conditions.
Displaying a top level window in a secondary thread is not affected by this
line of reasoning, and indeed I've done it and it has worked OK for me. But
displaying windows with interrelationships in different threads has caused
many newsgroup posts, including yours, demonstrating that it has many
problems.
--
Scott McPhillips [VC++ MVP]
Alexander Grigoriev
2008-12-18 14:17:21 UTC
Permalink
For best result, those windows should be completely unrelated.
Post by Denis Adamchuk
Scott,
You said that you did it and it worked?
Could you please describe briefly what kind of UI you had in separate threads?
Were there any relationships (parent/child or owner/owned) between your
windows or they were absolutely isolated?
Thanks!
Post by Scott McPhillips [MVP]
Post by Denis Adamchuk
Joseph,
I completely understand advantages of the single UI thread.
Ok, probably there is no reason to do so.
But why there are no "DON'T DO IT" neither in MSDN nor in OldNewThing?
Seems strange!
I cannot tell to the project architect that multithreaded UI is risky
because there are no facts at all...
- It is documented that most actions performed on windows are done with a
SendMessage call.
- It is documented that SendMessage blocks the calling thread until the
target thread handles it.
- Parent/Child windows, and Owner/Owned windows, have
implementation-defined
communication between them that is hidden within the OS and undocumented.
- Therefore in a multithreaded UI with these window interrelationships we
have hidden, undocumented blocking calls and we don't even know what actions
trigger them.
- There's a big risk: Potentially blocking calls in your thread that you
cannot predict. That leaves you with unknown effect on performance, and of
course it introduces the possibility of deadlocks under unknown conditions.
Displaying a top level window in a secondary thread is not affected by this
line of reasoning, and indeed I've done it and it has worked OK for me.
But
displaying windows with interrelationships in different threads has caused
many newsgroup posts, including yours, demonstrating that it has many
problems.
--
Scott McPhillips [VC++ MVP]
Scott McPhillips [MVP]
2008-12-18 19:03:07 UTC
Permalink
I have created windows in secondary threads like a scrolling message monitor
in a com port or socket thread. In all cases the window's parent was set to
NULL. All of the thread's communication to other threads used PostMessage
to a window created by the other thread, which is a non-blocking call.
Post by Denis Adamchuk
Scott,
You said that you did it and it worked?
Could you please describe briefly what kind of UI you had in separate threads?
Were there any relationships (parent/child or owner/owned) between your
windows or they were absolutely isolated?
Thanks!
--
Scott McPhillips [VC++ MVP]
Alexander Grigoriev
2008-12-18 13:51:05 UTC
Permalink
In theory, you CAN create windows in different threads, and MFC supports
that, too. But in practice, you need to KNOW exactly what you're doing, and
what are the hazards of deadlocking. If you want to make your life easier,
use a single GUI thread.
Post by Denis Adamchuk
Joseph,
I completely understand advantages of the single UI thread.
Ok, probably there is no reason to do so.
But why there are no "DON'T DO IT" neither in MSDN nor in OldNewThing?
Seems strange!
I cannot tell to the project architect that multithreaded UI is risky
because there are no facts at all...
The same scenario (popup MDI childs and topmost windows) works good when
everything belongs to the primary UI thread. Therefore I believe that my
issue has something to do with the multithreading.
I know that my design is risky and Windows behavior could be kind-of
unusual. But I cannot understand why the rule from MSDN is violated. I've
read all articles related to the Windows Management in the MSDN and have
found nothing about risks of multithreaded UI. Isn't it strange?
There are millions of software developers in the world and I cannot believe
that I'm the first one who face up with this issue.
Thank you very much!
Post by Joseph M. Newcomer
See below...
On Wed, 17 Dec 2008 11:15:01 -0800, Denis Adamchuk
Post by Denis Adamchuk
Hi everyone,
I see behavior which violates rules from the well-known article "Windows
Features"
http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx
I have an MFC MDI application which is a bit different from a generated by
ChildFrames are not WS_CHILD but WS_POPUP. It allows to move MDI-childs out
of the MainFrame. Looks good!
Since ChildFrames are popup windows now, they are owned by the Mainframe.
On some user action I want to create a topmost window in a separate thread.
I design it to have WS_POPUP and WS_EX_TOPMOST styles and have the active
Child Frame as owner.
****
As soon as you say you want to create a window in a separate thread, you are entering
dangerous territory. Why? There is no reason to do so. All windows should be owned by
the main GUI thread.
****
Post by Denis Adamchuk
Then I start the application and open 2 child frames (A and B).
When the topmost window is created (say, with the child frame A as owner) -
****
As soon as you say you are creating windows owned by multiple threads, the above line is
the inevitable consequence. Which is why it is not a recommended
practice. Because there
is no reason to create windows in secondary threads, it should not be done, because then
questions that start with that introduction never come up.
****
Post by Denis Adamchuk
If the topmost window is active now - a mouse click at the caption of the
child frame B brings this childframe to the bottom of Z-order, even behind
the Mainframe!
****
This may have nothing to do with multithreading, but I wouldn't even
bother to answer such
a question until the windows were moved into the main GUI thread.
****
Post by Denis Adamchuk
"An owned window is always above its owner in the z-order."
Does anybody know what's wrong with TOPMOST windows in Win32?
****
Until all windows are in one thread, the question is not worth answering.
You are doing something that is so far out in the minefield that you should expect that
any step you take is going to blow up something.
joe
****
Post by Denis Adamchuk
Thanks a lot!
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Loading...