473,320 Members | 2,094 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Windows Form Message Loop

Would I be correct in saying that the only way to get a user message into a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian
Nov 16 '05 #1
8 16284
Depends on what you want the message to do and why you want it in the loop?

--
Patrik Löwendahl [C# MVP]
cshrp.net - 'Elegant code by witty programmers'
cornerstone.se 'IT Training for professionals'

Brian Keating EI9FXB wrote:
Would I be correct in saying that the only way to get a user message into a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian

Nov 16 '05 #2
the message basically is a string for the window to display,
I want to use the loop because in want to implement a prioritised message
loop, i.e., handle any windows message first then handle my user message.

Reason: My user messages will be coming v.fast, So I want to enforce
processing of any windows messages before processing my user message.

thanks
Brian

"Patrik Löwendahl [C# MVP]" wrote:
Depends on what you want the message to do and why you want it in the loop?

--
Patrik Löwendahl [C# MVP]
cshrp.net - 'Elegant code by witty programmers'
cornerstone.se 'IT Training for professionals'

Brian Keating EI9FXB wrote:
Would I be correct in saying that the only way to get a user message into a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian

Nov 16 '05 #3
Seems like you are not completely clear how windows messages are handled in
Windows (Win32) and as such Windows.Forms.

Consider the example you posted recently:
In this you have:
- a main thread handling the UI and,
- two worker threads (called workers), handling external communication and
dispatching messages (Text) to the UI thread.

Because the workers may not directly touch the UI thread affinitized window
handles, you correctly opted to use Control.Invoke to marshal the delegate
to the UI thread.
What basically happens when you call Invoke is :
- Put a Thread Method Entry object in a Linked list ( a queue), this TME
contains things like caller, target HWND, method delegate, arguments, the
compressed caller stack etc.
- Post a private USER Windows message (calling Win32 PostMessage) to the UI
thread application message queue.
- Wait for an Event that signals the end of the delegate method. (This is
what differentiates BeginInvoke from Invoke, in that BeginInvoke doesn't
wait but returns immediately)

When the UI thread message loop retrieves the private USER message from it's
application "message queue" in it's message handler, it also pulls the TME
from the linked list and executes the TME's method(function, eventhandler
etc..) on it's own thread (UI) using the arguments supplied and the
compressed caller stack. Whenever the method returns, the message handler
set's an Event signaling the caller that a method ran to completion. and
continues handling next application message.

If there's no further message in the UI thread's application message queue
(no further Posted messages), the Windows system will inspect the "input
message" queue and switch the message loop to this queue if there are input
messages (mouse, keyboard), however, as soon as there are new messages in
the application queue Windows will switch back to this queue for its message
processing. [note that not all input messages are placed in the input
queue!!]
What this all means is that Windows queues are prioritized by windows, that
means that posted messages have higher priority than input messages, and as
long as there are posted messages, no input messages (mouse clicks f.i) are
getting process. Worse, input messages are processed one at a time, that
means that a key-down event can be handled before a bunch of posted messages
followed by the handling of the key-up event.
To you it means that you should allow the message queue to drain at regular
intervals in order to allow input messages to be processed.
Now I still wonder why someone is placing all this stuff on the screen,
while I see hardly someone reading this at this speed.

Willy.
"Brian Keating EI9FXB" <csharp at briankeating.net> wrote in message
news:BC**********************************@microsof t.com...
Would I be correct in saying that the only way to get a user message into
a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian

Nov 16 '05 #4
Hi Willy,

I'd a look at the messages coming through the WndProc this morning and
noticed this user message in response to the Invoke.
Your explanation has cleared up what exactly happens in response to a
..Invokexxx,
Also you've really opened my eyes with the "Input quque" this explains why
my input message are not getting handled.

Also at the end of your post you wonder about how quick someone can read,
you are quite correct; but consider an applicationt that writes quite alot to
the screen for one minute then goes off and idles for a while, the user can
scroll back along the messages that were outputed to the screen to see what
exactly happened.

However I think I know what you are getting at, and as also suggested by Ian
Griffiths, it makes alot more sence to update the UI at a refresh interval,
and display any new messages.

Thanks for your reply, I'm starting to see things alot more clearly.
best regards
Brian.

"Willy Denoyette [MVP]" wrote:
Seems like you are not completely clear how windows messages are handled in
Windows (Win32) and as such Windows.Forms.

Consider the example you posted recently:
In this you have:
- a main thread handling the UI and,
- two worker threads (called workers), handling external communication and
dispatching messages (Text) to the UI thread.

Because the workers may not directly touch the UI thread affinitized window
handles, you correctly opted to use Control.Invoke to marshal the delegate
to the UI thread.
What basically happens when you call Invoke is :
- Put a Thread Method Entry object in a Linked list ( a queue), this TME
contains things like caller, target HWND, method delegate, arguments, the
compressed caller stack etc.
- Post a private USER Windows message (calling Win32 PostMessage) to the UI
thread application message queue.
- Wait for an Event that signals the end of the delegate method. (This is
what differentiates BeginInvoke from Invoke, in that BeginInvoke doesn't
wait but returns immediately)

When the UI thread message loop retrieves the private USER message from it's
application "message queue" in it's message handler, it also pulls the TME
from the linked list and executes the TME's method(function, eventhandler
etc..) on it's own thread (UI) using the arguments supplied and the
compressed caller stack. Whenever the method returns, the message handler
set's an Event signaling the caller that a method ran to completion. and
continues handling next application message.

If there's no further message in the UI thread's application message queue
(no further Posted messages), the Windows system will inspect the "input
message" queue and switch the message loop to this queue if there are input
messages (mouse, keyboard), however, as soon as there are new messages in
the application queue Windows will switch back to this queue for its message
processing. [note that not all input messages are placed in the input
queue!!]
What this all means is that Windows queues are prioritized by windows, that
means that posted messages have higher priority than input messages, and as
long as there are posted messages, no input messages (mouse clicks f.i) are
getting process. Worse, input messages are processed one at a time, that
means that a key-down event can be handled before a bunch of posted messages
followed by the handling of the key-up event.
To you it means that you should allow the message queue to drain at regular
intervals in order to allow input messages to be processed.
Now I still wonder why someone is placing all this stuff on the screen,
while I see hardly someone reading this at this speed.

Willy.
"Brian Keating EI9FXB" <csharp at briankeating.net> wrote in message
news:BC**********************************@microsof t.com...
Would I be correct in saying that the only way to get a user message into
a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian


Nov 16 '05 #5
> Would I be correct in saying that the only way to get a user message into a
Windows form would be to use P/Invoke with [Send/Post]Message?
Strictly, yes. Conceptually, no.
What I mean by "conceptually, no" is, if the thing emitting the 'message' is
part of the same .NET program as the windows form but in a different thread,
then the best way of getting a 'message' to the form is not to use an
*actual* message, but to use BeginInvoke, with a delegate, as I believe
others have pointed out. This is the recommended way of posting a 'message'
from a worker thread back to the user interface, and there will be lots of
examples of it, should you need them.
What I mean by "strictly, yes" is that if you're defining 'message' as an
*actual windows message*, i.e. WM_*, and the communication *must* be by this
means, then AFAIK the only way to get it to the form is to use PostMessage or
SendMessage.

Of is there some part of the .NET API that I am totally un aware of?
If you want to process custom messages, look into the following override,
that a form has:
public override bool PreProcessMessage(ref Message msg)

Thanks for any help
Brian

Nov 16 '05 #6
> the message basically is a string for the window to display,
I want to use the loop because in want to implement a prioritised message
loop, i.e., handle any windows message first then handle my user message.
If you really need this to happen, then I believe the only option will be to
rewrite the form in C, with a custom message pump. All windows have a message
pump that is basically similar to the following:

1 [start of loop] ) get the next message (using GetMessage) from the
operating system's queue for the application. If there aren't any messages,
the call blocks until there is one. If the message is WM_QUIT, quit the loop
and go to step 5.
2) "Translate" the message (using TranslateMessage), this 'translates' the
message (what it actually does I don't know, just know that you have to do
it). Also accelerator keys are translated into messages in this step.
3) Dispatch the message to the WndProc of the window it was intended for
(using DispatchMessage)
4) Go back to (1), the start of the loop
5) Return the wParam of the message as the return value of the function that
invoked the window

What this means essentially, is that a window's wndproc only gets messages
in sequence, it doesn't "prioritise" messages in any way or let you decide
which get processed first. The wndproc has no concept of what the next
message will be and no option of doing, either (or what the previous one was
come to that, unless it explicitly takes steps to remember it).
The bottom line is that if you want to prioritise messages, you will have to
cook up your own custom message pump, probably using PeekMessage and an array
of messages, but whether that's advisable / necessary, I wouldn't know.
It theoretically could be done - if you peek into the queue and there's one
of your custom messages there, then it stores it in an array until there
aren't any messages waiting (PeekMessage returns zero). If there *are* more
messages waiting, then you would Get them, and if they are your custom one,
store them in the array of waiting ones, and if they're not, then just
dispatch them as normal. When there's no more waiting, you dispatch any that
are in the array.
The only downside is that you *can't* do this in .NET!
You can subclass to take control of processing of messages, and replace the
wndproc's default handling of the message with your own, but you can't do
this with the message pump - it's too low-level, the fundamental basis of the
operation of the window. You've got to get your hands dirty and delve into
raw hardcore C.

Reason: My user messages will be coming v.fast, So I want to enforce
processing of any windows messages before processing my user message.

thanks
Brian

"Patrik Löwendahl [C# MVP]" wrote:
Depends on what you want the message to do and why you want it in the loop?

--
Patrik Löwendahl [C# MVP]
cshrp.net - 'Elegant code by witty programmers'
cornerstone.se 'IT Training for professionals'

Brian Keating EI9FXB wrote:
Would I be correct in saying that the only way to get a user message into a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian

Nov 16 '05 #7
> Now I still wonder why someone is placing all this stuff on the screen,
while I see hardly someone reading this at this speed.
I can think of several reasons:
a) programs that constantly spool a load of text, fast, look *cool*.
b) if it constantly spools a load of text there can be no doubt that it's
doing stuff.
c) you can read it faster if you know what it's likely to say. i.e, you
don't actually have to read it, so much as 'recognize' general textual
patterns.
d) if management walk over and see your screen while its running, it tends
to look like you've automated something off your own bat to happen really
fast that you would otherwise be doing manually slowly.


Willy.
"Brian Keating EI9FXB" <csharp at briankeating.net> wrote in message
news:BC**********************************@microsof t.com...
Would I be correct in saying that the only way to get a user message into
a
Windows form would be to use P/Invoke with [Send/Post]Message?

Of is there some part of the .NET API that I am totally un aware of?

Thanks for any help
Brian


Nov 16 '05 #8
> a) programs that constantly spool a load of text, fast, look *cool*.

This is true. However, you don't need to post hundreds of messages across
threads every second to make this happen.

In fact it's better if you don't.

You tend to get better results if you have as few transitions between the
worker thread and the UI thread as possible. If you throttle it to, say, 10
a second, and batch your updates, you can still scroll vast amounts of text
past the user, but you'll get your actual work done a lot faster.
--
Ian Griffiths - http://www.interact-sw.co.uk/iangblog/
DevelopMentor - http://www.develop.com/

"Bonj" <Bo**@discussions.microsoft.com> wrote in message
news:39**********************************@microsof t.com...
Now I still wonder why someone is placing all this stuff on the screen,
while I see hardly someone reading this at this speed.


I can think of several reasons:
a) programs that constantly spool a load of text, fast, look *cool*.
b) if it constantly spools a load of text there can be no doubt that it's
doing stuff.
c) you can read it faster if you know what it's likely to say. i.e, you
don't actually have to read it, so much as 'recognize' general textual
patterns.
d) if management walk over and see your screen while its running, it tends
to look like you've automated something off your own bat to happen really
fast that you would otherwise be doing manually slowly.


Willy.
"Brian Keating EI9FXB" <csharp at briankeating.net> wrote in message
news:BC**********************************@microsof t.com...
> Would I be correct in saying that the only way to get a user message
> into
> a
> Windows form would be to use P/Invoke with [Send/Post]Message?
>
> Of is there some part of the .NET API that I am totally un aware of?
>
> Thanks for any help
> Brian


Nov 16 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Jon Hyland | last post by:
Ok, I'm a little rusty on this, it should be a simple problem but I can't figure it out. How can I handle form events in my main code page?? I'm creating a Windows App in C#. Rather than make...
5
by: Dave | last post by:
How do I check in a Windows Forms app if any controls have changed? I have a form that collects data, and I want to prompt the user if they try to exit the app, or load a new file, without saving...
3
by: Brian Keating EI9FXB | last post by:
Hello again, I've already placed a few posts on this topic. This time i've a simple application that exhibits my problem, I've placed sample solution 8k on my website should anyone be interested...
6
by: billr | last post by:
I have developed a small API for taking care of a lot of boiler plate stuff in a multi formed windows application, for example setting up a messaging thread framework. New Forms, in the...
14
by: | last post by:
Hi All, I am little confused here, hope you can help me. While processing WM_POWERBROADCAST (wParam=PBT_APMQUERYSUSPEND), I MUST to do some lengthy operation(30 sec) before system Suspends or...
3
by: Neal | last post by:
managed C++ VS 2003 I have a beginner question about windows forms.... I need to call a function when a certain limit has been reached, now with the way VS sets up the .NET windows Form I get...
3
by: RBarryYoung | last post by:
How can I get the following two features in the same program in VS2005?: 1) Access to the command-line arguments (cmdArgs()) that started my App. 2) Shutdown Mode = "When last Form exits". ...
28
by: | last post by:
I have a multi threaded windows form application that runs great after calling Application.Run(). Application.Run is required for a COM component I a using in the app (required for message loop). ...
21
by: Dan Tallent | last post by:
In my application I have a form (Customer) that I want to be able to open multiple copies at once. Within this form I have other forms that can be opened. Example: ZipCode. When the user enters...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.