Understanding Windows message loop

Source: Internet
Author: User
Understanding the message loop and the entire message transmission mechanism is very important for Windows programming. If you do not know the entire process of message processing, you may encounter many puzzles in Windows programming.

What is a message)

Each message is an integer value. If you look at the header file (it is a good habit and common practice to view the header file to understand the API), you can find the following macro definitions:# DefineWm_initdialog 0x0110
# DefineWm_command 0x0111

# DefineWm_lbuttondown 0x0201
//...

In Windows communications, at least some basic Windows communications require almost all messages. If you want a window or control (essentially, a control is a special window) to perform what action, you should send a message to it; if another window wants you to perform what action, it can send you a message. If an event, such as hitting the keyboard, moving the mouse, or clicking a button, is sent to a window, if you are one of these windows, you will receive the message and perform corresponding operations.

Each Windows message has two parameters: wparam and lparam. Initially, wparam was a 16-bit (Win16 era), and lparam was a 32-bit. In Win32, both parameters are 32-bit. Not all messages use these two parameters, and each message uses different methods. If the wm_close message ignores the preceding two parameters, for example, if the wm_command message uses the preceding two parameters, wparam contains "two" values, and hiword (wparam) is the notification information (if available ), loword (wparam) is the control for sending messages or the menu ID. lparam is the hwnd (window handle) of the Control for sending messages. If this value is null, indicates that the message is not sent by the control.

Hiword () and loword () are windows-defined macros, which take out a 32-bit integer value of high and low. In Win32, a "word" is a 16-bit integer, and DWORD (double word) is a 32-bit integer.

You can use postmessage () or sendmessage () to send messages. Postmessage () puts a message into the message queue and returns immediately. That is, when postmessage () is called, the message may not be processed after the function is executed. Sendmessage () directly sends the message to the window until the message is processed completely. To close a window, you can send it a wm_close message, such as postmessage (hwnd, wm_close, 0, 0). The effect is the same as clicking the (close) button in the upper-right corner of the window. Note that the values of wparam and lparam are both 0, because the preceding two parameters are ignored in the wm_close message.

Dialog Box (dialogs)

If you use the dialog box to communicate with the control, you need to send a message to the control. You can also use the getdlgitem () function to obtain the control handle Based on the Control ID, and then call the sendmessage () function to send messages; or use senddlgitemmessage () to combine the preceding steps. You can pass in a window handle and the Child Control ID to obtain the child control handle and use this handle to send messages. APIS similar to senddlgitemmessage (), such as getdlgitemtext (), can operate on all windows, not just dialogs.

What is message queue)

Assume that the system is processing the wm_paint message. Then, the user clicks some buttons on the keyboard. What will happen? Should the system interrupt the Drawing operation and process the button message or discard the button message? Obviously, these are unreasonable. Therefore, we have introduced a message queue. When a message is sent, it is added to the Message Queue. When a message is processed, it is removed from the message queue. This ensures that messages are not lost. When you are processing a message, other incoming messages can be added to the message queue until they are processed.

What is message loop)

While (Getmessage ( & MSG, null, 0 , 0 ) > 0 )
{
Translatemessage ( & MSG );
Dispatchmessage ( & MSG );
}

AboveCodeThe execution process is as follows:
1. Call getmessage () to find and process messages from the Message Queue cyclically. If the message queue is empty,ProgramStops execution and waits (Program blocking ).
2. when an event occurs, a message is added to the Message Queue (for example, if the system registers a mouse click event). getmessage () returns a positive value, indicating that a message needs to be processed, the message has been filled in the input msg parameter; 0 is returned when the wm_quit message is passed in; if the returned value is negative, an error occurs.
3. Retrieve the message (in the MSG variable) and pass it to the translatemessage () function. This function performs some additional processing: converts the virtual key value information to the character information. This step is actually optional, but needs to be used in some places.
4. After the preceding steps are completed, the message is passed to the dispatchmessage () function. The dispatchmessage () function distributes messages to the target window of the message, finds the process function of the target window, transmits window handle, message, wparam, lparam, and other parameters to the window process function, and then calls this function.
5. Check the message and other parameters in the window procedure function. You can use it to implement the operation you want. If you do not want to process some special messages, you should always call the defwindowproc () function, and the system will process these messages in the default way (usually not doing any operation ).
6. Once a message is processed, the window process function returns, the dispatchmessage () function returns, and the next message continues to be processed cyclically.

Message loop is a very important concept for Windows programming. Window procedure functions are not automatically called by the system, but indirectly called by developers by calling dispatchmessage. If you want to, you can call the getwindowlong () function to find the window procedure function through the window handle and call it directly to process the message.

While (Getmessage ( & MSG, null, 0 , 0 ) > 0 )
{
Wndproc fwndproc = (Wndproc) getwindowlong (msg. hwnd, gwl_wndproc );
Fwndproc (msg. hwnd, MSG. Message, MSG. wparam, MSG. lparam );
}

I tried to write the above Code and it does work, but there are various problems here, such as Unicode/ANSI encoding conversion, Timer callback, and so on, and may cause many interruptions to the normal operation of many programs. Therefore, such code is only a test, and such Code cannot be written in real projects.

Note that getwindowlong () is used to obtain the window procedure functions of related windows. Why don't we directly call the wndproc () function? A message loop processes messages in all windows in the program, including buttons, list boxes, and other controls with their own window procedure functions. Therefore, we must ensure that the correct window procedure functions are called. Although several windows call the same window procedure function, the first parameter (window handle) of the function is usually used to tell the window procedure function that is the message sent by that window.

The Code shows that the program processes the message loop most of the time. The window will continuously process sent messages. But what should I do if I want to exit the program? Because we use a while () loop, if getmessage () returns false (0), it will exit the loop, and the program can be executed to the end of winmain (), that is, the program exits: this is exactly the work completed by the postquitmessage () function, which adds the wm_quit message to the end of the message queue. getmessage () extracts the wm_quit message from the message queue and fills in the MSG structure, returns 0 instead of a positive number. At the same time, the value of wparam, a member of the MSG structure, is set as the value passed to the postquitmessage () function parameter. You can ignore it or use it as the value of winmain () the Return Value of the function is the exit code of the process ).

Note: if an error occurs, the getmessage () function returns-1. You should remember this, maybe your program will make an error. Although the return value of getmessage () is bool, it can return values other than true or false because bool is defined as uint (unsigned INT ). The following program seems to work normally, but sometimes it cannot work normally.

While (Getmessage ( & MSG, null, 0 , 0 ))

While(Getmessage (&MSG, null,0,0)! = 0)

While(Getmessage (&MSG, null,0,0)=True)

The above code is all wrong! In some programs, you will see that the first method is used. To use this method, you must ensure that getmessage () is always executed successfully. Otherwise, you should use the following code:While(Getmessage (&MSG, null,0,0)> 0)

I hope you can have a good understanding of Windows message loop. If you haven't, you will gradually understand it during usage.

Http://winprog.org/tutorial/message_loop.html.

Note: Feel this articleArticleThe message loop is well described. If there are any omissions in translation, please point out.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.