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!
Denis Adamchuk
2008-12-17 20:16:01 UTC
Permalink
Where does your information come from?
There are NO mentions in MSDN that multithreaded UI is not possible in
Windows.
Moreover, there is an article where described the opposite.
http://msdn.microsoft.com/en-us/library/ms810439.aspx

I have a big GUI part which is multithreaded and the problem appears with
topmost windows only.
BobF
2008-12-17 20:44:20 UTC
Permalink
Post by Denis Adamchuk
Where does your information come from?
There are NO mentions in MSDN that multithreaded UI is not possible in
Windows.
Moreover, there is an article where described the opposite.
http://msdn.microsoft.com/en-us/library/ms810439.aspx
I have a big GUI part which is multithreaded and the problem appears with
topmost windows only.
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.

Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.

Perhaps you are confronted with one of those rare cases where multiple
UI threads is the least of the possible evils you're faced with. If
that's the case, I do NOT envy your position and Good Luck.
David Ching
2008-12-17 20:56:11 UTC
Permalink
Post by BobF
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.
Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.
Perhaps you are confronted with one of those rare cases where multiple UI
threads is the least of the possible evils you're faced with. If that's
the case, I do NOT envy your position and Good Luck.
I agree it is easiest if all windows are created on the primary thread, but
it is not that hard to handle them being created on a secondary thread, as
long as you treat them just like you would windows belonging to another
process (i.e. only communicate via Post/Send message, etc.).

-- David
Joseph M. Newcomer
2008-12-17 21:11:01 UTC
Permalink
That article seems rather naive by today's standards. It was written for Windows NT 3.1,
and let's see, we've gone through Windows NT 3.5, Windows NT 3.51, Windows NT4, Windows
2000, Windows XP and Windows Vista, with Windows 7 on the horizon. Things Have Changed.

Reading an article like this is a bit like reading a diatribe about why women should not
be granted the vote. It represents a collection of attitudes which are now recognized as
inappropriate.

I agree completely: just because something looks like it might work is not an excuse to
use it, especially when the general view is that mostly it doesn't work and trying to make
it work is probably a Really Bad Idea.

But I find it hard to imagine that the situation is one in which multiple threads in the
user interface is the only alternative; years of programming without ever needing a
user-visible window in another thread has convinced me that there is no need for them.

I *can* imagine a situation in which a naive assumption that a multithreaded UI can make
sense leads to a design which requires it. Which suggests that the design must change.
joe
Post by BobF
Post by Denis Adamchuk
Where does your information come from?
There are NO mentions in MSDN that multithreaded UI is not possible in
Windows.
Moreover, there is an article where described the opposite.
http://msdn.microsoft.com/en-us/library/ms810439.aspx
I have a big GUI part which is multithreaded and the problem appears with
topmost windows only.
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.
Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.
Perhaps you are confronted with one of those rare cases where multiple
UI threads is the least of the possible evils you're faced with. If
that's the case, I do NOT envy your position and Good Luck.
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:16:01 UTC
Permalink
Bob,

The most obscure part of the multithreaded UI is a complete lack of facts!
I cannot find more than developer's opinions.
There are nothing about risks neither in the MSDN nor in the blog of Raymond
Chen (I consider it as a good source of Windows information).

Unfortunately, conventional wisdom is not a sufficient argument when dealing
with some kind of people...

Thank you for reply.
Post by BobF
Post by Denis Adamchuk
http://msdn.microsoft.com/en-us/library/ms810439.aspx
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.
Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.
Perhaps you are confronted with one of those rare cases where multiple
UI threads is the least of the possible evils you're faced with. If
that's the case, I do NOT envy your position and Good Luck.
BobF
2008-12-18 14:21:32 UTC
Permalink
Denis -

For as long as I've been doing Windows code, I've been amazed by the
lack of really good Windows programming docs from MS.

Like others, most of what I learned came from third-party books and peers.

As the third-party book sources have dried up, especially MFC books, we
have had to rely more and more on MSDN and peers. MSDN *has* been
improved over recent years, but it is still insufficient as a sole source.

I've found this particular ng to be an excellent resource. And NOT just
from the "celebrities" that generously donate their time and knowledge
here. This is one of the best, if not the best, online peer group I've
encountered.

What folks give here is based largely on experience. You will rarely be
able to "verify" what you're told here by confirming a MSDN reference.
The shortcomings of MSDN are at least partly responsible for the success
of this ng. OTOH, everyone here freely challenges each other and for
the most part reach mutual understanding through civilized discussion.

In the end, you'll have to make your own decisions about which pieces
fit with your own particular situation and which don't.

If you are working with (or for) someone else that will only accept a
MSDN reference ... sorry. In your reply to Joe, you confirmed multiple
UI threads were the source of your problems. Maybe you can present your
own argument, based on your own experience and desire to meet your own
requirements for simplicity, reliability and maintainability. Maybe not.

Best of Luck with your project!
Post by Denis Adamchuk
Bob,
The most obscure part of the multithreaded UI is a complete lack of facts!
I cannot find more than developer's opinions.
There are nothing about risks neither in the MSDN nor in the blog of Raymond
Chen (I consider it as a good source of Windows information).
Unfortunately, conventional wisdom is not a sufficient argument when dealing
with some kind of people...
Thank you for reply.
Post by BobF
Post by Denis Adamchuk
http://msdn.microsoft.com/en-us/library/ms810439.aspx
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.
Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.
Perhaps you are confronted with one of those rare cases where multiple
UI threads is the least of the possible evils you're faced with. If
that's the case, I do NOT envy your position and Good Luck.
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
Joseph M. Newcomer
2008-12-19 18:38:40 UTC
Permalink
See below...
On Thu, 18 Dec 2008 01:05:00 -0800, Denis Adamchuk
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!
****
It is strange.

You CAN do a multithreaded UI, but the problems are serious. You have to know all the
possible consequences, particularly of interthread SendMessage (which ARE documented), and
pretty much everything derives from that set of problems.
*****
Post by Denis Adamchuk
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.
****
So don't multithread.
****
Post by Denis Adamchuk
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.
*****
It isn't a "rule from MSDN". It is a consequence of understanding second-order and
third-order effects which *are* documented.

Generally, most people who face the issue end up in one of the following states:
(1) it works by sheer luck
(2) it works because the timing conditions that would cause failure
have not yet been hit
(3) it works because you have been EXTREMELY careful and avoided
all the possible failure modes
(4) it works because you started at state (3) and over the lifetime of
the app NEVER ONCE made a mistake that could cause
a failure
(5) it fails occasionally for reasons you don't understand
(6) it never works

Note that (3) is the low-probability model, (5) and (6) are the high-probability models.
That's why the people who have the most experience create situations in which none of
these scenarios are possible, because we avoid ever creating a multithreaded GUI. If you
achieve (3), then (4) is the nearly-inevitable consequence.

"A superior pilot is someone who uses his superior judgment to avoid getting into
situations in which his superior skill is required"
joe
Post by Denis Adamchuk
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
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Paul Nicholas
2011-06-21 11:17:45 UTC
Permalink
Hi,

I'm trying to do something very similar to the original poster; I have a pluggable C# application where each plug-in runs on it's own thread and creates it's own window, but gives the overall illusion of an MDI application.

For example, the windows are layed out in a Z-order like so:

MainHeaderForm
|
|-- PluginA_Form
|
|-- PluginB_Form
|
|-- PluginC_Form
|
|-- BackgroundForm

...where the MainHeaderForm is always at the top and the BackgroundForm must always be at the bottom of the pile.
However, there shouldn't be the possibility for other (external) Windows to appear within this application's Z-order (thus breaking the MDI illusion).

The reason I have the plugins on separate threads is so that they can be forcibly removed/killed, should they become unresponsive. As far as I know, this cannot be done on a single thread without bringing down ALL plug-ins.

But, like the OP, I'm having issues where (probably due to timing), sometimes Plugin windows are appearing behind the BackgroundForm and other oddities. I am maintaining the overall Z-order from the GUI thread and using "Invokes" to get the Windows to perform SetWindowPos. However, as mentioned above, this is probably doing a blocking call(?), which could account for some of the issues.

Otherwise, functionality is as desired - it's just the display issues.

If anyone has any additional guidance on how this could (or SHOULD) be done, it would be very much appreciated!

Thanks
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!
Post by Drew
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
Where does your information come from?
There are NO mentions in MSDN that multithreaded UI is not possible in
Windows.
Moreover, there is an article where described the opposite.
http://msdn.microsoft.com/en-us/library/ms810439.aspx
I have a big GUI part which is multithreaded and the problem appears with
topmost windows only.
Post by BobF
Since the time that article was published (1993, 15 years ago),
conventional wisdom has shifted to a single UI thread approach being
preferred.
Straightforwardness of design, simplicity of synchronization and
maintenance complexity are the priority criteria for decisions such as
this. The fact that something can be done does NOT imply that it should
done.
Perhaps you are confronted with one of those rare cases where multiple
UI threads is the least of the possible evils you're faced with. If
that's the case, I do NOT envy your position and Good Luck.
Post by David Ching
I agree it is easiest if all windows are created on the primary thread, but
it is not that hard to handle them being created on a secondary thread, as
long as you treat them just like you would windows belonging to another
process (i.e. only communicate via Post/Send message, etc.).
-- David
Post by Joseph M. Newcomer
See below...
On Wed, 17 Dec 2008 11:15:01 -0800, Denis Adamchuk
****
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.
****
****
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.
****
****
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.
****
****
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
****
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Post by Joseph M. Newcomer
That article seems rather naive by today's standards. It was written for Windows NT 3.1,
and let's see, we've gone through Windows NT 3.5, Windows NT 3.51, Windows NT4, Windows
2000, Windows XP and Windows Vista, with Windows 7 on the horizon. Things Have Changed.
Reading an article like this is a bit like reading a diatribe about why women should not
be granted the vote. It represents a collection of attitudes which are now recognized as
inappropriate.
I agree completely: just because something looks like it might work is not an excuse to
use it, especially when the general view is that mostly it doesn't work and trying to make
it work is probably a Really Bad Idea.
But I find it hard to imagine that the situation is one in which multiple threads in the
user interface is the only alternative; years of programming without ever needing a
user-visible window in another thread has convinced me that there is no need for them.
I *can* imagine a situation in which a naive assumption that a multithreaded UI can make
sense leads to a design which requires it. Which suggests that the design must change.
joe
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
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 Denis Adamchuk
Bob,
The most obscure part of the multithreaded UI is a complete lack of facts!
I cannot find more than developer's opinions.
There are nothing about risks neither in the MSDN nor in the blog of Raymond
Chen (I consider it as a good source of Windows information).
Unfortunately, conventional wisdom is not a sufficient argument when dealing
with some kind of people...
Thank you for reply.
Post by Scott McPhillips [MVP]
- 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]
Post by Alexander Grigoriev
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
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 Alexander Grigoriev
For best result, those windows should be completely unrelated.
Post by BobF
Denis -
For as long as I've been doing Windows code, I've been amazed by the
lack of really good Windows programming docs from MS.
Like others, most of what I learned came from third-party books and peers.
As the third-party book sources have dried up, especially MFC books, we
have had to rely more and more on MSDN and peers. MSDN *has* been
improved over recent years, but it is still insufficient as a sole source.
I've found this particular ng to be an excellent resource. And NOT just
from the "celebrities" that generously donate their time and knowledge
here. This is one of the best, if not the best, online peer group I've
encountered.
What folks give here is based largely on experience. You will rarely be
able to "verify" what you're told here by confirming a MSDN reference.
The shortcomings of MSDN are at least partly responsible for the success
of this ng. OTOH, everyone here freely challenges each other and for
the most part reach mutual understanding through civilized discussion.
In the end, you'll have to make your own decisions about which pieces
fit with your own particular situation and which don't.
If you are working with (or for) someone else that will only accept a
MSDN reference ... sorry. In your reply to Joe, you confirmed multiple
UI threads were the source of your problems. Maybe you can present your
own argument, based on your own experience and desire to meet your own
requirements for simplicity, reliability and maintainability. Maybe not.
Best of Luck with your project!
Post by Scott McPhillips [MVP]
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.
--
Scott McPhillips [VC++ MVP]
Post by Joseph M. Newcomer
See below...
On Thu, 18 Dec 2008 01:05:00 -0800, Denis Adamchuk
****
It is strange.
You CAN do a multithreaded UI, but the problems are serious. You have to know all the
possible consequences, particularly of interthread SendMessage (which ARE documented), and
pretty much everything derives from that set of problems.
*****
****
So don't multithread.
****
*****
It isn't a "rule from MSDN". It is a consequence of understanding second-order and
third-order effects which *are* documented.
(1) it works by sheer luck
(2) it works because the timing conditions that would cause failure
have not yet been hit
(3) it works because you have been EXTREMELY careful and avoided
all the possible failure modes
(4) it works because you started at state (3) and over the lifetime of
the app NEVER ONCE made a mistake that could cause
a failure
(5) it fails occasionally for reasons you don't understand
(6) it never works
Note that (3) is the low-probability model, (5) and (6) are the high-probability models.
That's why the people who have the most experience create situations in which none of
these scenarios are possible, because we avoid ever creating a multithreaded GUI. If you
achieve (3), then (4) is the nearly-inevitable consequence.
"A superior pilot is someone who uses his superior judgment to avoid getting into
situations in which his superior skill is required"
joe
Joseph M. Newcomer [MVP]
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
Joseph M. Newcomer
2011-06-21 14:06:31 UTC
Permalink
This post might be inappropriate. Click to display it.
David Webber
2011-06-21 17:20:43 UTC
Permalink
From: Paul Nicholas
Post by Paul Nicholas
I'm trying to do something very similar to the original poster; I have a
pluggable C# application where each plug-in runs on it's own thread and
creates it's own window, but gives the overall illusion of an MDI
application....
The thing about the MDI - multiple document interface - is that it is an
interface which manages multiple documents.

My feeling is that the sensible thing is to allow it to do it. You can
arrange that the document displayed in any given document window has its
client area wholly or partly looked after by a plug-in DLL if you like.
And your plug -in can supply menus and whatever as you like: but it should
do it in a way which is demanded by the MDI.

[I have plug-ins which read different formats and convert them to the native
document format of my application. So only the reading code depends on the
plug-in. But in principle other things (like drawing code) could do so
too.]

Dave

David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Joseph M. Newcomer
2011-06-21 20:10:25 UTC
Permalink
And there's nothing about MDI that insists on "mutliple documents", although that is one
of the side effects. It can also be treated as "multiple concurrent views of a single
document" and that is also a legitimate representation. So there may be a single
"document" but there are multiple views, each view managed by the main GUI thread but
whose data is prepared by some secondary thread. The secondary thread may be running in a
DLL, and the action of "load the plugin" may turn into "Create a view on the document,
load the DLL, and create a thread calling an entry point in the DLL". This still leaves
unresolved the concepts of "unresponsive" (whatever THAT means!) and "terminating the
thread" (which must be done properly to avoid disaster).
joe
Post by David Webber
From: Paul Nicholas
Post by Paul Nicholas
I'm trying to do something very similar to the original poster; I have a
pluggable C# application where each plug-in runs on it's own thread and
creates it's own window, but gives the overall illusion of an MDI
application....
The thing about the MDI - multiple document interface - is that it is an
interface which manages multiple documents.
My feeling is that the sensible thing is to allow it to do it. You can
arrange that the document displayed in any given document window has its
client area wholly or partly looked after by a plug-in DLL if you like.
And your plug -in can supply menus and whatever as you like: but it should
do it in a way which is demanded by the MDI.
[I have plug-ins which read different formats and convert them to the native
document format of my application. So only the reading code depends on the
plug-in. But in principle other things (like drawing code) could do so
too.]
Dave
David Webber
Mozart Music Software
http://www.mozart.co.uk
For discussion and support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
Joseph M. Newcomer [MVP]
email: ***@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

Loading...