Windows is a message-driven system. Windows messages provide a means of communicating between applications and between applications and Windows systems. The functionality the application wants to implement is triggered by the message, and is done by responding to and processing the message. It must be noted that the message is not preemptive, regardless of the urgency of the event, always follow the arrival of the party, in turn (some system messages excepted), which may cause some real-time external events can not be processed in time.
Windows applications typically include Windows, which primarily provide a visual way for users to interact, and windows are always created within a thread. Windows systems manage interactions through messaging mechanisms, messages are sent, saved, processed, and a thread maintains its own set of message queues (messages queue) to maintain exclusivity among threads. The characteristics of the queue are nothing more than FIFO, which can implement an asynchronous demand response process.
2. Message type
3. Message Queuing (msg Queues)
4. Queue messages (Queued Messages) and non-queue messages (non-queued Messages)
5, PostMessage (postthreadmessage), SendMessage
6, GetMessage, PeekMessage
7, TranslateMessage, TranslateAccelerator
8, (Message deadlocks)
10. Handling of messages
11, MFC's message map
12. Message Reflection mechanism1. Message
The message system is very important for a Win32 program, which is a source of power for a program to run. A message is a system-defined 32-bit value that uniquely defines an event that sends a notification to Windows informing the application that something has happened. For example, click the mouse, change the window size, press a key on the keyboard
will cause Windows to send a message to the application.
The message itself is passed to the application as a record that contains the type of message and other information. For example, for a message that is generated by clicking the mouse,
said that this record contains the coordinates when the mouse is clicked. This record type, called MSG,MSG, contains message information from the Windows Application Message queue, which is
Windows declares the following:
typedef struct TAGMSG
HWND hwnd; The window handle that accepts the message
UINT message; The message constant identifier, which is what we usually call the message number
WPARAM WPARAM; Specific additional information for a 32-bit message, which means that the exact meaning depends on the message value
LPARAM LPARAM; Specific additional information for a 32-bit message, which means that the exact meaning depends on the message value
DWORD time; Time when the message was created
Point pt; The position of the mouse/cursor in the screen coordinate system when the message was created
Messages can be generated by a system or application. The system generates a message when an input event occurs. For example, when the user strikes a key, move the mouse or click the control. The system also generates messages in response to changes made by the application, such as the application changing the system font and changing the size of the form. An application can generate messages to make a form perform tasks or communicate with a window in another application.
1) System Definition message (system-defined Messages)
Pre-defined messages in the SDK, which are not user-defined, range between [0x0000, 0x03ff] and can be divided into the following three categories:
1> window messages (Windows message)
Related to the internal workings of the window, such as creating Windows, drawing windows, destroying windows, etc. It can be a normal window, a dialog, a control, and so on.
such as: Wm_create, WM_PAINT, Wm_mousemove, Wm_ctlcolor, Wm_hscroll ...
2> Command Message
A command message is generated when a user request is processed, such as when a menu item or toolbar or control is clicked.
WM_COMMAND, LoWord (WParam) represents the ID of a menu item, toolbar button, or control. If it is a control, HiWord (WParam) represents the control message type
3> Control Notification (Notify Message)
The control notifies the message, which is the most flexible message format, with its messages, WParam, LPARAM, respectively: WM_NOTIFY, control ID, pointer to NMHDR. NMHDR contains the contents of the control notification and can be arbitrarily extended.
2) Program definition message (application-defined Messages)
User-defined messages have the following provisions for their scope:
Wm_user:0x0400-0x7fff (ex. wm_user+10)
Wm_app (winver> 4.0): 0x8000-0xbfff (ex. WM_APP+4)
There are two types of Message Queuing in Windows
1) System Message Queuing (systems messages queue)
This is a system-unique queue where the device driver (mouse, keyboard) translates the operation input into a message that exists in the system queue, which is then placed in the message queue of the thread on which the target window is located (thread-specific-message queues) Waiting for processing in
2) thread Message Queuing (thread-specific message queue)
Each GUI thread maintains such a thread message queue. (This queue is created only when the thread calls the GDI function and is not created by default). The message in the thread message queue is then sent to the appropriate window procedure (WNDPROC) for processing.
Note: In thread Message Queuing, Wm_paint,wm_timer is processed only when there are no other messages in the queue, and WM_PAINT messages are merged to improve efficiency. All other messages are processed in first-in, in-and-out (FIFO) mode.
1) Queue messages (Queued Messages)
messages are saved in the message queue first, the message loop takes messages from this queue and distributes them to each window processing , such as mouse, keyboard messages.
2) Non-queue messages (nonqueued Messages)
messages bypass system Message Queuing and thread Message Queuing send directly to a window procedure is processed such as: Wm_activate, Wm_setfocus, Wm_setcursor, wm_windowposchanged
Note: The message sent by PostMessage is a queue message. It will post the message to the message queue, and the message sent by SendMessage is sent to the window process directly.
Differences between queue messages and non-queue messages
From the way messages are sent, messages can be divided into 2 types: Queue messages and non-queue messages. Message Queuing can be divided into system Message Queuing and thread Message Queuing. System Message Queuing is maintained by Windows, thread Message Queuing is maintained by each GUI thread itself, to avoid creating message queues for Non-gui, all threads are generated without Message Queuing, and the system creates a message queue for the thread the first time the GDI function is called. Queue messages are sent to the system message queue and then to the thread message queue, and non-queue messages are sent directly to the destination window procedure.
For queue messages, the most common messages that are triggered by the mouse and keyboard, such as Wm_mousermove,wm_char, are other messages, such as WM_PAINT, Wm_timer, and Wm_quit. When the mouse, keyboard events are triggered, the corresponding mouse or keyboard driver will convert these events into corresponding messages, and then sent to the system message queue, by the Windows system to process. The Windows system takes a message from the system message queue at the appropriate time, determines that the message is to be sent to that window, according to the structure of the MSG message, and then takes the extracted message to the appropriate queue of the thread that created the window, and the following is what the thread message queue is about. Windows started to get busy with their own things. When a thread sees a message in its own message queue, it takes it out of the queue and sends it to the appropriate window process via the operating system.
In general, the system always posts the message at the end of the message queue. This ensures that the window receives the message in FIFO order. However, WM_PAINT is an exception, and multiple wm_paint of the same window are merged into a WM_PAINT message, merging all invalid areas into an invalid zone. The purpose of merging Wm_pain is to reduce the number of times the window is refreshed.
Non-queue messages will bypass system queues and message queues, sending messages directly to the window procedure. The system sends a non-queue message Notification window and the system sends a message notification window. For example, when a user activates a window The system sends Wm_activate, Wm_setfocus, and Wm_setcursor. These messages notify the window that it was activated. Non-queue messages can also be generated by system functions when the application calls. For example, when the program calls the SetWindowPos system, the wm_windowposchanged message is sent. Some functions also send non-queue messages, such as the ones we're going to talk about below.
5, PostMessage (postthreadmessage), SendMessage
PostMessage: Returns the message immediately after it is placed in the thread message queue where the specified window is located. PostThreadMessage: Returns the message immediately after it is placed in the message queue of the specified thread.
SendMessage: The message is sent directly to the window process processing, the process is finished before returning.
The difference between PostMessage (asynchronous) and SendMessage (synchronous)
A, PostMessage is asynchronous, SendMessage is synchronous.
PostMessage only puts the message in the queue, regardless of whether the message is processed or returned, the message may not be processed;
SendMessage waits for the message to be processed before returning, and if the message is not processed, the thread that sent the message will remain in a blocked state waiting for the message to be returned.
b, the same line range:
When SendMessage sends a message, the USER32.DLL module invokes the message handler of the target window and returns the result, SendMessage sends a message inside the same thread does not enter the thread message queue, and the message sent by the PostMessage is first placed in the message queue. The message loop is then dispatched to the target window (dispatchmessage).
C, Different threads:
SendMessage sends a message to the destination window of the message queue, and then sends the message to the thread in USER32. The DLL module monitors and waits for messages to be processed until the target window is processed back, and SendMessage needs to do a lot of work before returning, such as responding to a SendMessage () sent to it by another thread. It is best to use PostThreadMessage instead when Postmessge () to other threads. The HWND parameter of PostMessage () can be null, which is equivalent to PostThreadMessage () + Getcrrentthreadid.
D, the system processes the message.
The system only processes (marshal) system messages (0--wm_user), and users are required to process them themselves when sending user messages (defined by the user).
When sending a system message using an asynchronous function such as Postmessage,sendnotifymessage,sendmessagecallback, the parameter cannot use a pointer because the sender does not wait for the message to be processed and the receiver has not been processed, and the pointer may be released. , or the content changes.
E, in Windows 2000/XP, each message queue can hold up to a certain number of messages, more than will not be processed and discarded. The system defaults to 10000;:[hkey_local_machine\software\microsoft\windows NT\CurrentVersion\Windows] USERPostMessageLimit
6, GetMessage, PeekMessage
PeekMessage will return immediately to keep the message
GetMessage returns a message when there is a message
The main differences between the PeekMessage and GetMessage functions are:
A. The primary function of GetMessage is to "take out" messages from the message queue, remove them from the message queue after the message is taken out, and PeekMessage's primary function is to "peek" the message and return True if there is a message, otherwise false. You can also use PeekMessage to remove a message from the message queue, which uses one of its parameters (UINT wremovemsg), and if set to Pm_remove, the message is fetched and removed from the message queue, and if set to Pm_noremove, The message is not removed from the message queue.
B. If getmessage does not get a message from the message queue, the thread is suspended by the operating system, and when the OS re-dispatches the thread, the nature of the two is different: the use of the getmessage thread will still be suspended, and using the PeekMessage thread would give the CPU control. Run for some time.
C, GetMessage waits for a message each time, until the message is returned, and PeekMessage simply queries the message queue, returns without a message, and determines whether the message was taken from the return value.
We can also say that PeekMessage is a function with thread-asynchronous behavior, and the function returns immediately regardless of whether there is a message in the message queue. The GetMessage is a function that has thread synchronization behavior, and if there is no message in the message queue, the function waits until at least one message in the message queue is returned.
If there is no message in the message queue, PeekMessage can always return, which is equivalent to executing a loop, which enters a dead loop if the message queue is always empty. GetMessage is unlikely to enter a dead loop because the message queue is empty.
Inside windows, GetMessage and PeekMessage execute the same code, and both PeekMessage and getmessage get messages to the system's message queue and place them in the specified structure.
PeekMessage: Returns True when there is a message, no message returns false
GetMessage: Returns True if there is a message and the message is not wm_quit, if there is a message and returns false for Wm_quit, no message is returned.
GetMessage: After getting the message, delete the message except the WM_PAINT message.
PeekMessage: After getting the message, determine whether to delete the message according to the WREMOVEMSG parameter. Pm_remove is deleted, Pm_noremove is not deleted.
The PeekMessage function normally does not remove WM_PAINT messages from the queue. WM_PAINT messages remain in the queue until they is processed. However, if a WM_PAINT message has a null update region, PeekMessage does remove it from the queue.
You cannot delete a WM_PAINT message from a message queue by using PeekMessage, removing the WM_PAINT message from the queue can make the invalidated area of the window's display area effective (refreshing the window), and if the queue contains a WM_PAINT message program, it will always be the while loop.
7, TranslateMessage, TranslateAccelerator
TranslateMessage: Converts a virtual-key message into a character message (character message) and puts it into the message queue of the current thread, and the next fetch of the message loop.
TranslateAccelerator: The shortcut key corresponds to the corresponding menu command. It transforms the Wm_keydown or wm_syskeydown into the corresponding WM_COMMAND or Wm_syscommand message in the accelerator table, and then sends the converted WM_COMMAND or Wm_syscommand directly to the window process, It will not be returned until the processing is finished.
8, (message deadlocks)
Assuming the threads A and B, now have the following steps
1) thread A sendmessage to thread B, a waits for the message to be returned after process B is processed
2) thread B receives a message from thread A and processes it, B also sendmessgae to thread a during processing, and waits for a return from a. Because at this point, thread A is waiting to be returned from thread B, unable to process the message from B, which causes the thread A, b to wait for each other to form a deadlock. Multiple threads can also form ring deadlocks.
You can use SendNotifyMessage or sendmessagetimeout to avoid deadlocks.
We generally contact the message is sent to the window, in fact, the recipient of the message can be a variety of, it can be an application (applications), can install the driver (installable drivers), network equipment (networks drivers), System-Level device drivers (System-level devices drivers), etc.,
Broadcastsystemmessage This API can send messages to the above system components.
10. Handling of Messages
Next we talk about the processing of the message, first we look at the VC in the message pump:
while (GetMessage (&msg, NULL, 0, 0))
if (! TranslateAccelerator (Msg.hwnd, hacceltable, &msg))
TranslateMessage (Conversion message):
Used to convert a virtual key message to a character message. Because Windows uses a virtual key definition for all keyboard encodings, it is not a character message when the key is pressed, and a message that requires a keyboard mapping to convert to characters.
Used to convert a virtual key message to a character message. The character message is posted to the calling thread's message queue and is removed the next time the GetMessage function is called. When we hit a character key on the keyboard, the system generates WM_KEYDOWN and WM_KEYUP messages. The additional parameters of these two messages (WPARAM and lparam) contain information such as the virtual key code and the scan code, and we often need to get the ASCII code of a character in the program, translatemessage this function can be wm_keydown and wm_ The combination of the KeyUp messages is converted to a WM_CHAR message (the wparam attached parameter of the message contains the ASCII code of the character) and the converted new message is posted to the calling thread's message queue. Note that the TranslateMessage function does not modify the original message, it simply generates a new message and posts it to the message queue.
That is to say, TranslateMessage will find the message there is a character key message, if there is a character key message, will produce a WM_CHAR message, if there is no message will be generated.
DispatchMessage (Dispatch message):
Sends the message of the TranslateMessage transformation to the window's message handler function, which was specified when the window was registered.First, GetMessage gets a message from the message queue of the main thread of the process and copies it to the MSG structure, and if there is no message in the queue, the GetMessage function waits for a message to come back. If you pass a window handle to GetMessage as the second argument, only the message for the specified window can be obtained from the queue. GetMessage can also filter messages from the message queue to accept only messages that fall within the scope of the message queue. This is the time to use Getmessage/peekmessage to specify a message filter. This filter is a range of message identifiers or a form handle, or both. It is useful when an application is looking for a post-incoming message queue message. The Wm_keyfirst and Wm_keylast constants are used to accept all keyboard messages. The Wm_mousefirst and Wm_mouselast constants are used to accept all mouse messages.
Lin Bingwen Evankaka Original works. Reprint please specify the source Http://blog.csdn.net/evankaka
A detailed description of the Windows message delivery mechanism