Understanding Message Loops
in order to write any even the simplest program, it is necessary to understand the message loop of Windows programs and the entire message sending structure. Now that we've tried a little bit of message processing, we should have a deeper understanding of the whole program, and if you don't understand how the message happens and how it works, then you're going to feel a lot of pain.
What is a message?
A message is an integer value, if you look up your header file (which is a good reference to the working practices of the API ) you will find something like this:
1 #define Wm_initdialog 0x01102#define wm_command 0x011134#define wm_ Lbuttondown 0x0201
There are a lot of things like that. In Windows Messaging is almost all communication applied at the basic level, if you want a window control (just a drawn window) to do something you need to send a message to it; the same if another window wants you to do something, it will send you a message If something like a user clicks on the keyboard, moves the mouse, clicks on a button, the corresponding message is sent to the affected window, and if you are one of the affected windows, you need to process the message and take action accordingly.
Each window message can have two parameters,WParamand theLParam, initiallyWParamis a -bit andLParamis a +bit, but inWin32all of them are +bit. Not every message needs to use these parameters, the use of the time is different, for instance,Wm_closeThe two parameters are not used in the message, and we can ignore both of them;Wm_commandThe two parameters are used at the same time,WParamcontains two values,HiWord(WParam) is a notification message (if available),LoWord(WParam) is a control or menu that sends a messageID.
LParam is the HWND(window handle) that controls the sending of a message or NULL(if the message is not from control)
HiWord ()and theLoWord ()wasWindowsmacro definition, both of these values areWindowsin the macro definition, a reference to the +Bits (0xffff0000) of High -bit(FFFF), a point +bit of low -bit(0000); inWin32in oneWORDindicates that the -bit, whileDWORD(Double Word) only to indicate +bit
You can passPostMessage ()orSendMessage ()both of these methods send messages. PostMessage ()inserts a message into the message queue and returns immediately, which means that even oncePostMessage ()when the call is completed, the message may not have been processed;SendMessage ()sends a message directly to the window and will not return immediately, knowing that the window has finished processing the message. If we want to close a window, we canPostMessage (hwnd, WM_CLOSE, 0, 0)Send aWm_closethe message, which we clicked on the top right of the windowXbuttons have the same effect, note theWm_closeThe corresponding processing of the message,WParamand theLParam's All0and that's because just mentioned in theWm_closeThese two parameters are not used in message processing.
dialog box
Once you start using dialog boxes, you will need to send messages to control in order to communicate with them. You can get the handle of the control by using GetDlgItem () by using the ID First and then use SendMessage (), or you can use the SendDlgItemMessage () , this method combines the two steps above. You give it a window handle and the child ID will get a child handle and then send a message to him. senddlgitemmessage () and similar apigetdlgitemtext () will work on all windows, not just dialogs.
What is Message Queuing?
Let's try to imagine when you're busy dealing with Wm_paint What happens when a user enters a bunch of things with the keyboard? When you draw the keyboard interrupt should be discarded? Of course not! Obviously it's not the right thing to abandon, so we have a message queue. A new POST message is added to the message queue, and the message is removed from the message queue when the message is processed, which ensures that you won't miss a message if you're working on a message, Then other messages will wait in the queue until you start processing them.
What is a message ring?
1 while 0 0 0 )2{3 translatemessage (&Msg); 4 DispatchMessage (&Msg); 5 }
1, in the message queue, the message ring call GetMessage () method, if your message queue is empty, then your program
will stop and wait for the message, which is equivalent to the suspended state
2, When an event occurs, will cause a message to join the message queue (such as the system registered a mouse click)
GetMessage () returns a positive value indicating that a message is to be processed and copied to the number of MSG we pass to it
according to the structure of the member, the method may also return 0 If the message is wm_quit, if the error occurs, the method will
returns a negative number.
3. we get the message (in the Msg variable) and pass it to translatemessage (), which produces a little extra
the process of translating a virtual keyboard click into a character message, this step is actually optional, if not needed
it will not happen.
4, Once the above steps are completed, we pass the message to DispatchMessage (),dispatchmessage () will do
The job is to get the message, check which window it is, and then find the corresponding window's message handler, then call
message handlers, and passes the window's handle, message,WParam, and lParam four parameters to it.
5, in your message handler, you will check the parameter message and then do anything you want to do, if you don't
has processed the specified message, the default is to invoke the DefWindowProc () method, the default action for this message processing,
It usually means doing nothing at all.
6, Once you have completed the message processing, your message handler will return,DispatchMessage () back, and then
we went back to where the ring began.
This is a very important concept in the window program, your message handlers are not magically called by the system, in fact you are indirectly through DispatchMessage () call. If you want, you can call the window handler directly in the window handle using GetWindowLong () .
1 while 0 0 0 )2{3 WNDPROC fwndproc = (WNDPROC) GetWindowLong (Msg.hwnd, GWL_WNDPROC) ; 4 Fwndproc (Msg.hwnd, Msg.message, Msg.wparam, Msg.lparam); 5 }
I tried to use the previous code, but it didn't work, because there were all kinds of problems like Unicode/ansi code translation, etc., call Timer callback method will not occupy, this may break our current all but insignificant program, so you can try, but in the actual code do not really do this :)
Note that we use GetWindowLong () to retrieve the window-related message handlers, why don't we call WndProc () directly ? Well, our message ring is for all the windows in our program, including buttons and list boxes with their own window procedures, so we should ensure that the correct window procedure is called, because multiple windows can use the same window procedure, so the first parameter (window handle) is used to tell the window which window the process message belongs to.
as you can see, your application spends most of its time executing this message loop, and you are able to happily send messages to a happy window that can handle them. But what do you do when you want to quit the program? Because we used awhile ()loops, ifGetMessage ()returned thefalse, the loop will end and reach USWinMain ()the end of the program is then exited. This isPostQuitMessage ()finished something that it putWm_quitmessage is placed in a queue instead of returning a positive value,GetMessage ()is populatedMSGthe contents of the data structure are then returned0, at this timeMSGof theWParamthe members contain what you pass on toPostQuitMessage ()the value, here you can ignore it, fromWinMain ()The return value will be used in the exit code for the end of the process.
Focus : Getmessgae () will return 1 If there is an error, be sure to remember this, or at some point you will have a sore egg ... Even if GetMessage () is defined to return a Boolean value, it can also return a value other than TRUE or FALSE , because BOOL is defined using a UINT(unsigned int). The following code example may work, but the condition will not be handled correctly:
1 while 0 0 ))23while 000)4 5 while 0 0) = = TRUE)
it's all wrong! As I just mentioned, it may be similar to the one I used in the first tutorial, as long as GetMessage () does not fail it will workplace well, even if your code is correct, this is not correct, But in many cases this code is wrong and does not work properly when GetMessage () fails! Here we solemnly explain and correct, please forgive me for missing some points.
1 while 0 0 0)
This is the right one!
I hope that now you have a better understanding of the window message loop, and if you don't understand it very well, don't be afraid, it will be much better once you use them for a period of time.
PS. due to my English proficiency limit, can only translate to this extent, there are flaws also hope to point out, attached to the translation of the original English course address:http://www.winprog.org/tutorial/message_loop.html
WIN32 Programming API Basics--4. Message loop translation According to English course