Deeply parse the message transmission mechanism in VC (I)

Source: Internet
Author: User
Abstract: Windows Programming and DOS programming, a big difference is that Windows programming is event-driven, message transmission. Therefore, to learn windows programming well, you must have a clear understanding of the message mechanism. This article hopes to make a comprehensive analysis of message transmission.
What is a message?

The message system is very important for a Win32 program. It is the source of motivation for running programs. A message is a 32-bit value defined by the system. It uniquely defines an event and sends a notification to Windows to tell the application that something has happened. For example, if you click the mouse, change the window size, or press a key on the keyboard, Windows will send a message to the application.

The message itself is passed to the application as a record, which contains the Message Type and other information. For example, for a message generated by clicking the mouse, this record contains the coordinates of the mouse. This record type is MSG. MSG contains message information from the Windows application message queue. It declares the following in Windows:

Typedef struct tagmsg
{
Hwnd; the window handle that receives the message
Uint message; the constant identifier of the message, which is the message number.
Wparam; a 32-bit additional message. The exact meaning depends on the message value.
Lparam; a 32-bit additional message. The exact meaning depends on the message value.
DWORD time; the time when the message was created
Point pt; cursor/cursor position in the screen coordinate system when a message is created
} MSG;

Messages can be generated by the system or application. The system generates a message when an input event occurs. For example, when you press the key, move the mouse or click the control. The system also generates messages to respond to changes caused by applications. For example, the application changes the system font and changes the form size. Applications can generate messages to execute tasks in the form or communicate with windows in other applications.

What are messages?

We have provided the above comments. Do we have a clear understanding of the message structure? If not, let's try again to explain the following:

Hwnd 32-bit window handle. Windows can be any type of screen objects, because Win32 can maintain the handles of most visual objects (Windows, dialog boxes, buttons, edit boxes, etc ).

Message is used to distinguish the constant values of other messages. These constants can be pre-defined constants in Windows units or custom constants. The message identifier indicates the meaning of a message in the form of a constant name. After a message is received in the window process, the message identifier is used to determine how to process the message. For example, wm_paint tells the window that the form customer area needs to be re-painted when it is changed. A symbolic constant specifies the type of the system message. Its prefix specifies the type of the form for processing the interpreted message.

Wparam is a message-related constant value, or a handle to a window or control.

Lparam is usually a pointer to data in the memory. Since wparam, lparam, and pointer are both 32-bit, they can be converted to each other.

Message Identifier value

The system retains the message Identifier value in the 0x0000 range in 0x03ff (WM_USER-1. These values are used by system-defined messages. Applications cannot use these values for their own messages. The application uses the message range from wm_user (0x0400) to 0x7fff, or 0xc000 to 0 xFFFF; the message range from wm_user to 0x7fff is used by the application itself; messages in the range from 0xc000 to 0xffff are used to communicate with other applications. By the way, we have a symbolic message value:

Wm_null --- 0x0000 empty message.
0x0001 ---- 0x0087 is mainly a window message.
0x00a0 ---- 0x00a9 non-customer zone message
0x0100 ---- 0x0108 Keyboard Message
0x0111 ---- 0x0126 menu message
0x0132 ---- 0x0138 Color Control Message
0x0200 ---- 0x020a mouse message
0x0211 ---- 0x0213 menu cyclic message
0x0220 ---- 0x0230 multi-document message
0x03e0 ---- 0x03e8 DDE message
0x0400 wm_user
0x8000 wm_app
0x0400 ---- 0x7fff application custom private message

What is the message category?

In fact, there are many messages in windows, but the types are not complicated. There are generally three types: Window messages, command messages, and control notification messages.

Window messages are the most common messages in the system. They are the messages used by the operating system and windows that control other windows. For example, createwindow, destroywindow, and movewindow will trigger window messages, and the messages generated by clicking the mouse we have discussed above are also window messages.

Command message, which is a special window message. It is used to process user requests sent from one window to another. For example, if you press a button, it will send a command message to the main window.

A control notification message refers to a message in which a child control in a window has something to notify the parent window. The notification message is only applicable to standard window controls such as buttons, list boxes, Combo boxes, and edit boxes, as well as windows public controls such as tree views and list views. For example, clicking or double-clicking a control, selecting some text in the control, and the scroll bar of the operation control will generate a notification message. It is similar to a command message. When the user interacts with the control window, the control notification message is sent from the control window to its main window. However, this message does not exist to process user commands, but to enable the main window to change controls, such as loading and displaying data. For example, if you press a button, the message sent to the parent window can also be considered as a control notification message. The message generated by clicking the mouse can be processed directly by the main window and then handed over to the control window for processing.

The window messages and control notification messages are processed directly or indirectly by the cwnd class derived class. Compared with window messages and control notification messages, a command message can process a wide range of objects. It can be processed by window classes, document classes, document templates, and application classes.

Because the control notification message is very important and many people use it, but the specific meaning is often confusing for beginners, I decided to list the common ones for your reference:

Button Control

The bn_clicked user clicked the button.
Bn_disable button disabled
Bn_doubleclicked double-click the button
Bn_hilite user/user highlighted button
Bn_paint button should be repainted
Bn_unhilite should be removed

Combo Control

The list box of the cbn_closeup combo box is closed.
The cbn_dblclk user double-clicked a string.
The list box of the cbn_dropdown combo box is pulled out.
The cbn_editchange user modified the text in the editing box.
The text in the cbn_editupdate edit box is about to be updated.
The cbn_errspace combo box has insufficient memory.
The cbn_killfocus combo box loses the input focus.
Cbn_selchange
Cbn_selendcancel user selection should be canceled
Cbn_selendok users' selection is legal
Cbn_setfocus combo box to get the input focus

Edit box Control

The text in the en_change edit box has been updated.
The en_errspace editing box has insufficient memory.
The en_hscroll user clicked the horizontal scroll bar.
The en_killfocus edit box is missing the input focus.
The content inserted by en_maxtext is truncated.
En_setfocus edit box to get the input focus
The text in the en_update edit box will be updated.
The en_vscroll user clicks the vertical scroll bar message meaning

List box Control

Lbn_dblclk
Lbn_errspace: insufficient memory in the list box
The lbn_killfocus list box is missing the input focus.
Lbn_selcancel selected to be canceled
Lbn_selchange selects another item
Lbn_setfocus list box to get the input focus

Queue messages and non-queue messages

Messages can be divided into two types: queue messages and non-queue messages. Message queues can be divided into system message queues and thread message queues. The system message queue is maintained by windows, and the thread message queue is maintained by each GUI thread. To avoid creating a message queue for non-Gui, no message queue exists when all threads are generated, only when the thread calls the GDI function number system for the first time to create a message queue for the thread. The queue message is sent to the system message queue and then to the thread message queue. Non-queue messages are directly sent to the destination window.

For queue messages, the most common is the mouse and keyboard-triggered messages, such as wm_mousermove, wm_char, and other messages, such as wm_paint, wm_timer, and wm_quit. When a mouse or keyboard event is triggered, the corresponding mouse or keyboard driver converts the event to a message and then delivers it to the system message queue, it is handled by the Windows system. In Windows, a message is retrieved from the system message queue at an appropriate time. Based on the MSG message structure we mentioned earlier, the message is sent to that window, then, the retrieved message is sent to the corresponding queue of the thread that creates the window. The following is the concern of the thread message queue. Windows is busy with its own tasks. When a thread sees a message in its own message queue, it extracts it from the queue and sends it to a suitable window through the operating system for processing.

Generally, the system always posts messages to the end of the message queue. This ensures that the window receives messages in the FIFO order. However, wm_paint is an exception. Multiple wm_paint messages in the same window are merged into one wm_paint message, and all invalid areas are merged into one invalid area. The purpose of merging wm_pain is to reduce the number of refresh windows.

Non-queue messages will bypass system queues and message queues and directly send messages to the window ,. 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 system, wm_activate, wm_setfocus, and wm_setcursor are sent. These Message notification windows are activated. Non-queue messages can also be generated when the application calls system functions. For example, when the program calls the setwindowpos system to send the wm_windowposchanged message. Some functions also send non-queue messages, such as the functions we will talk about below.

Message sending

After understanding these basic theories, we can send and receive simple messages.

There are three ways to send a message to a window: sending, sending, and broadcasting.

The functions for sending messages include sendmessage, sendmessagecallback, sendnotifymessage, and sendmessagetimeout. The functions for sending messages include postmessage, postthreadmessage, and postquitmessage. I only know broadcastsystemmessage and broadcastsystemmessageex.

The prototype of sendmessage is as follows: lresult sendmessage (hwnd, uint MSG, wparam, lparam). This function sends a message to one or more windows, it will not be returned until the message is processed. However, if the receiving window is a part of the same application, the window function of this window will be called immediately as a sub-program; if the window for receiving messages is created by another thread, the window system switches to the corresponding thread and calls the corresponding window function. This message is not put into the target application queue. The Return Value of the function is returned by the window function of the window that receives the message. The returned value depends on the message to be sent.

The postmessage prototype is as follows: bool postmessage (hwnd, uint MSG, wparam, lparam). This function places a message in the message queue of the thread that creates the hwnd window, this function will immediately control the returned message without waiting for the message to be processed. Note that if the hwnd parameter is hwnd_broadcast, the message will be sent to all overlapping windows and pop-up windows in the system, but the subwindows will not receive the message; if the hwnd parameter is null, this function is similar to setting the dwthreadid parameter to the flag of the current thread to call the postthreadmessage function.

From the two representative functions above, we can see the difference between the message sending method and the sending method: whether the sent message is processed immediately, and whether the function returns immediately. The sent message is processed immediately, and the function returns the message after processing. The sent message is not processed immediately, and is placed in an FIFO queue, it will not be processed until the application is empty, but the function will return immediately after messages are placed.

In fact, there is no big difference between the process of sending a message to a window and the process of directly calling a window. The only difference is that you can ask the operating system to intercept all sent messages, however, direct calls to the window processing process cannot be intercepted.

Messages sent in sending mode usually correspond to user input events, because these events are not very urgent and can be buffered slowly. For example, the mouse and keyboard messages will be sent, the buttons and other messages will be sent.

Broadcast messages are rarely used. The broadcastsystemmessage function prototype is as follows:

Long broadcastsystemmessage (DWORD dwflags, lpdword lpdwrecipients, uint uimessage, wparam, lparam );

This function can send a message to a specified receiver, which can be an application, an installable driver, a network driver, a system-level device driver message, and any combination of them. Note that if the dwflags parameter is bsf_query and at least one receiver returns broadcast_query_deny, the return value is 0. If bsf_query is not specified, the function sends the message to all receivers, and ignore the returned value.

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.