Windows message priority

Source: Internet
Author: User

The question may be a bit exaggerated, but there are some things you can't understand without looking into Windows messages. Such problems are not obvious errors and will not throw exceptions, but they are the most difficult problems, debugging is very troublesome, so I will sort out the actual problems as follows for reference.

 
I. Windows message and Message Processing Algorithm
Windows uses a message-driven approach, allowing the thread to respond to the outside by processing messages. Windows creates a Message Queue (including sending message queues, registering message queues, inputting message queues, and responding to message queues) for each thread that needs to receive and process messages ), the sending message queue stores the messages sent by other threads to the thread through sendmessage to establish a window, and the registration Message Queue stores the messages sent to the thread through postmessage or the thread creates a window, the input message queue stores the system input (including keyboard and mouse input). The Response Message Queue contains the information that the thread notifies the thread after the window function of the specified window is called sendmessage. In Windows, qs_sendmessage, qs_postmessage, qs_quit, qs_input, qs_paint, and qs_timer indicate whether messages are sent, registered, exited, input, repainted, and scheduled. The priority of a message is qs_sendmessage> qs_postmessage> qs_quit> qs_input> qs_paint> qs_timer.
Windows processes messages in the following way:
Message loop pseudo algorithm:
Bool Bret = false;
MSG;
While (Bret = getmessage (& MSG, null, 0, 0 ))){
If (Bret =-1) break; // on error exit the loop
Translatemessage (& MSG); // convert the message
Dispatchmessage (& MSG); // sends a message, which is actually a window function that calls a specified window.
}
 
The getmessage pseudo algorithm is as follows:
Bool getmessage (MSG * lpmsg, hwnd, uint wmsgfiltermin, uint wmsgfiltermax)
{
// View the qs_sendmessage flag. If yes, it is processed cyclically until no message location exists.
DWORD dwretval = 0;
Threadinfo;
 
Flag_sendprocloop:
Getthreadinfo (getcurrentthreadid (), & threadinfo );
While (threadinfo. qs_sendmessage = qs_signalset ){
// Obtain a message from the sending message queue
Dwreturnval = getmsgfromqueue (queue_send, lpmsg, hwnd, wmsgfiltermin, wmsgfiltermax );
// Determine whether the message is received. If yes, call the window function. If no message is received, the qs_sendmessage flag is returned.
If (dwreturnval = getmessage_hasmessage ){
// Call the window function of the specified window
Callwindowproc (hwnd, & threadinfo, lpmsg );
}
Else {
Qs_sendmessage = qs_signalreset;
Break;
}
}
// Check the sending message queue again before processing.
If (threadinfo. qs_sendmessage = qs_signalset) goto flag_sendprocloop;
// Check the sending message queue. If a message exists, take the sent message.
// Determine whether a message is sent. If no message is sent, reset the qs_postmessage flag.
If (threadinfo. qs_postmessage = qs_signalset ){
Dwreturnval = getmsgfromqueue (queue_post, lpmsg, hwnd, wmsgfiltermin, wmsgfiltermax );
If (dwreturnval = getmessage_lastmessage)
Threadinfo. qs_postmessage = qs_signalreset;

Return true;
}
 
// If the exit sign is set
If (threadinfo. qs_quit = qs_signalset ){
Threadinfo. qs_quit = qs_signalreset;
Fillmessage (lpmsg, message_quit );
Return false;
}
 
// Check the input message queue
If (threadinfo. qs_input = qs_signalset ){
DWORD dwretval = getmessagefromqueue (queue_input, lpmsg, hwnd, wmsgfiltermin, wmsgfiltermax );
// Check whether there is a keyboard or mouse message
If (test (dwretval, qs_key) = qs_lastmousekeymessage)
Threadinfo. qs_key = qs_signalreset;
If (test (dwretval, qs_mousebutton) = qs_lastmousemessage)
Threadinfo. qs_mousebutton = qs_signalreset;
 
Return true;
}
 
// Test qs_paint
If (threadinfo. qs_paint = qs_signalset ){
// Fill in MSG. If there is no window Confirmation window, reset the qs_paint flag.
//...
// Return true
Threadinfo. qs_paint = qs_signalreset;
Return true;
}
 
If (threadinfo. qs_timer = qs_signalset ){
// Fill in MSG. If no timer is reported, the qs_timer flag is reset.
//...
// Return true
Return true;
}
 
// Wait for a message to arrive
Dwretval = msgwaitformultipleobjectsex (...);
If (...)
Goto flag_sendprocloop;
 
// Wait for an error
Return false;
}
 
Note the priority order of various messages. When a message is sent in the sending queue, getmessage does not return until the message in the sending queue is processed, and qs_sendmessage is reset, when no message is sent, getmessage is used to view the registration message. If no registration message is sent, various messages are processed in order of priority from high to low. If a message with a low priority is found in this process, the getmessage is filled with a MSG and then returns. If qs_quit is set, getmessage returns false; otherwise, true. When getmessage returns false, the message loop ends. We can see from the message loop that when the message loop calls getmessage again, various messages are still processed in order of priority. Please note that the message sent from sendmessage to the Message Queue of the target thread is processed when the target thread calls getmessage, and getmessage is returned only when no message is sent. If a message is received, getmessage is returned, otherwise, the getmessage will cause the thread to fall into the idle state and be suspended. When a message arrives at the thread, the getmessage will be awakened and the message will be returned.
Ii. Windows message wm_timer
Wm_timer messages have the lowest priority. Therefore, if there are other messages, wm_timer messages cannot be processed. This is why I used settimer to register a callback function which has never been called. Because I used it in the UI environment, the UI re-painting is triggered when the wm_paint message is processed. As a result, the wm_paint message is always to be processed, and the wm_timer cannot be processed. Be careful when processing wm_paint messages. Otherwise, the program may consume a high CPU and the wm_timer lower than the wm_paint priority will not be processed.
Iii. sendmessagetimeout of Windows message-related functions
Sendmessagetimeout is a message that is returned when the message is processed or times out. However, I checked the msdn and Windows core programming and found no effect when the timeout value is set to 0. This value is set to 0 until the last message is broadcasted outside the service. After the service is started, sendmessagetimeout is called when the service status is not set to running, the timeout value is set to 0. It was originally thought that the function would return immediately, but the call caused the thread to be suspended. Since the other thread that processes the broadcast message has been waiting for the running state, and the service waits for the outside world to finish processing the message and then continues, this produces a deadlock. This is the consequence of setting the timeout value to 0. Now it seems that setting the timeout value to 0 is equivalent to calling sendmessage.
The preceding section does not analyze thread messages (messages sent through postthreadmessage). For more details about Windows messages and message processing mechanisms, see Chapter 26th of Windows core programming.

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/FreeWave/archive/2008/01/21/2056469.aspx

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.