TJB replied to:
Willy... I am quite happy to use whatever terminology is accurate and
understandable. I am basing my terminology on the MSDN documentation.
"Windows Forms uses the single-threaded apartment (STA) model because
Windows Forms is based on native Win32 windows that are inherently
apartment-threaded."
Sometimes you have to take the documentation with a grain of salt.
The STA issue is a COM issue, not a native Windows one. STA says that
windows on two different threads can't talk to each other. For
example, you could not, in an STA view of things, have a window on one
thread set a property on another on another thread. However, the SDK
actually takes some steps to support this behavior in custom
applications.
Native SDK windows live on the same thread as the message pump that
services them. All things native Windows are handled by a message
procedure and this procedure is ultimately called in response to
SendMessage and PostMessage. While it is theoretically possible to call
a windows procedure directly and even from another thread, it is
incredibly inconsistent with sound design practice for native
applications. To talk to a window on another thread, one uses
PostMessage and SendMessage. Both of those calls ensure that the
message is sent properly synchronized from another thread to the gui
thread.
A native SDK application can actually have more than one GUI thread.
You can have 5 or 6 threads, each running their own message pump and
their own windows. I'm pretty sure IE does this for example. Each web
page is window is on a seperate top level thread. To synchronize data
between them, you could safely toss around a pointer using PostMessage
if you follow the paradigm of the caller doesn't look after PostMessage
is called, and the recipient deletes.
COM places some additional restrictions on that world though. For one,
you can't just toss a COM object from one thread to another because
Windows has to keep track of which thread the COM object is on, to
route events to it, from it, and also for basic bookkeeping. So the
simplest case of COM is a model where a control lives on one and only
one thread, even though Windows itself is actually a bit more flexibile
in this regard.
In the case of .NET, BeginInvoke on controls is required because .NET
places some data on top of what SendMessage does. Remember the note
about calling Windows procedures directly. Everything has to get
routed through the queue in order to talk between threads under Windows
and so they use BeginInvoke to put the information needed to make a
method call on the "Invokees" message queue.