/_Ben Voigt [C++ MVP]_ a exposé/ :
[...]
SomeControl.BeginInvoke(SomeDelegate) would be equivalent to
PostMessage, not SendMessage, but I think it is the behavior you are
looking for.
thanks for the tip
but I really need an empty call stack when the actions are started
(well, I needed that for a lot of reasons with Delphi; even if some are
no more a problem with .net, I guess some are still)
Maybe you could describe your problem at a higher, more abstract level.
There's no such thing as "an empty call stack". By the time any of your
code gets to execute there is always at least a little bit of call stack,
and a GUI application is going to call as part of its first few actions a
..NET method that starts processing the window message queue (e.g.
Application.Run() for a Forms application), which will introduce even more
frames to the call stack.
The call stack also has very little to do with the message queue, and your
original post seemed to state you cared about the latter, not the former.
Also, your comments about SendMessage() are confusing, as SendMessage()
does not in any way guarantee that by the time the message sent is
actually processed that the window message queue is empty. In fact, a
message sent via SendMessage() doesn't go through the message queue at
all. If you call it from the thread that owns the window, it simply calls
the window class's window proc directly, and if from another thread the OS
simply ensures synchronization; it doesn't provide a guarantee that the
message queue is empty when the window class's window proc is actually
called.
Furthermore, there is no possible way to guarantee that the window message
queue is empty at the time that a particular message is handled, whether
that message was ever in the message queue or simply handled by a direct
call to the window proc. The instant that a particular thread might
_think_ that its message queue is empty, any code anywhere else could wind
up queuing a message to the queue, just as the particular thread was about
to start doing whatever "idle" processing is desired.
That's all a long way of saying that it is not literally possible to
accomplish what you seem to be saying you want to accomplish, and that
would be true for any Windows application.
Now, back to the basic things that _are_ possible:
-- In the unmanaged API there's SendMessage() and PostMessage().
SendMessage() being synchronous (doesn't return until the message is
processed) and PostMessage() being asynchronous (returns immediately, the
message to be processed later). In .NET, these are roughly equivalent to
Control.Invoke() and Control.BeginInvoke(), respectively. There are
obvious differences between the two paradigms, but in a very general sense
that would be the mapping.
-- In .NET, you can using the Application.Idle event
(
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.idle.aspx)
to detect when the message pump believes that the message queue is empty
and the application is about to enter an "idle" state. That event will
_not_ guarantee to you that there are in fact no messages in the queue
when your code executes, but then you never had that guarantee before. I
suspect that this event is the closest equivalent to what you were using
before, and would probably suffice for your purpose.
If the above doesn't help you, then you will probably have to provide a
more abstract, less implementation-specific description of what it is
you're really trying to accomplish. It's often difficult to provide good
advice when the question is presented as a specific implementation that
the questioner has already chosen, even if that implementation isn't
appropriate.
Pete