Windows Messaging Mechanism (MFC)

Source: Internet
Author: User

Windows Messaging Mechanism (MFC) message classification and Message Queuing

In Windows, messages use a uniform structure body (MSG) to hold information, where message indicates the specific type of messages,

And Wparam,lparam is the most flexible of the two variables, for different message types, the meaning of storing data is not the same.

Time indicates when the message was generated, and PT indicates the position of the mouse at the time the message was generated.

By type, Windows divides the message into:

(0) Message ID range

System-defined Message ID range: [0x0000, 0X03FF]
User-definable range of message IDs:
WM_USER:0X0400-0X7FFF (ex: WM_USER+10)
Wm_app (winver> 4.0): 0x8000-0xbfff (example: wm_app+4)
Registerwindowmessage:0xc000-0xffff "is used to communicate with other applications for the uniqueness of the ID, using:: RegisterWindowMessage to get the message ID of the range"

(1) Window messages: messages related to the internal workings of the window, such as creating Windows, drawing windows, destroying windows, etc.

It can be a normal window, a mainframe,dialog, a control, and so on.

such as: Wm_create, WM_PAINT, Wm_mousemove, Wm_ctlcolor, Wm_hscroll, etc.

(2) When the user selects a command item from the menu, presses a shortcut key, or clicks a button on the toolbar, the WM_COMMAND command message is sent.

LoWord (WParam) represents the ID of a menu item, toolbar button, or control, or, in the case of a control, HiWord (WParam) represents the control message type.

#define LOWORD (L) ((WORD) (L))

#define HIWORD (L) ((WORD) ((DWORD) (L) >>) & 0xFFFF)

(3) as the variety of controls becomes more and more complex (such as list controls, tree controls, and so on), just Wparam,lparam will be treated as a 32-bit unsigned integer, and there is not enough information to fit.

To send more information to the parent window, Microsoft defines a new WM_NOTIFY message to extend the WM_COMMAND message.

The WM_NOTIFY message still uses the MSG message structure, except that at this point the wparam is id,lparam as a NMHDR pointer to the control.

Different controls can augment NMHDR according to rules, so the amount of information wm_notify message delivery can be quite large.

Note: Window version 9x and subsequent new control notification messages are no longer transmitted via WM_COMMAND, but are transmitted via WM_NOTIFY.
However, the notification message for the old control, such as Cbn_selchange or WM_COMMAND message, is sent.

(4) Windwos also allows programmers to define their own messages, using SendMessage or PostMessage to send messages.

Windows messages can also be divided into:

(1) Queue message (Queued Messages)
The message is saved in the message queue, and the message loop takes the message out of the queue and distributes it to each window processing
such as: Wm_paint,wm_timer,wm_create,wm_quit, as well as mouse, keyboard messages and so on.
Where Wm_paint,wm_timer is processed only when there are no other messages in the queue,
WM_PAINT messages will also be merged to improve efficiency. All other messages are processed in first-in, in-and-out (FIFO) mode.

(2) Non-queue messages (nonqueued Messages)
Messages bypass system Message Queuing and thread Message Queuing and are sent directly to the window procedure for processing
such as: Wm_activate, Wm_setfocus, wm_setcursor,wm_windowposchanged

The entire messaging system of a Windows system is divided into 3 tiers:

System Message Queuing for the ①windows kernel

②app UI Thread Message Queuing

③ Form object for processing messages

The Windows kernel maintains a global system message queue, and messages in the system message queue are distributed to the message queue of the application's UI thread, depending on the thread;

Each UI thread of an application has its own message loop, and it continuously extracts messages from its own message queue and sends them to Windows Forms objects;

Each Form object uses a form procedure function (WindowProc) to handle the various messages that are received.

1 LRESULT CALLBACK WindowProc (HWND hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM) 2 {3     paintstruct PS; 4     HDC H dc 5  6     switch (message) 7     {8 case     wm_command:9         break;10 case     wm_paint:11         hdc = BeginPaint ( HWnd, &ps);         //TODO: Add any drawing code here ...         EndPaint (hWnd, &ps); break;15 case     wm_destroy:16         postquitmessage (0);     default:19         return DefWindowProc (hWnd, message, WParam, LParam);     }21     return 0;22}

If required, in WindowProc, you can use:: Getmessagetime to get the current message generation time,
Use:: Getmessagepos to get the position of the mouse cursor at the time the current message is generated.

(1) Each window message is received and processed by the WindowProc (virtual function) of each form (or control) itself.

(2) WM_COMMAND command Message unification is received by the WindowProc of the current active main window , and after the detour, it can be processed by other CCmdTarget objects .

(3) WM_COMMAND control notification unification is received and processed by the WindowProc of the parent window of the child window (control) , or it can be bypassed by other CCmdTarget objects .

(for example, CFormView has the condition to accept notifications for WM_COMMAND controls, and the ability to send WM_COMMAND messages to the associated Document object,

So the WM_COMMAND control notification to CFormView is a document object that can be processed. )

Additionally, theWM_COMMAND control notification invokes the REFLECTLASTMSG Reflection Notification Child window (control), and if the child window (control) processes the message and returns TRUE, the message stops distributing;

Otherwise, it will continue to call OnCmdMsg for command sending (as with the WM_COMMAND command message).

Note: The WM_COMMAND command message is similar to the WM_COMMAND control notification:
WM_COMMAND command messages and WM_COMMAND control notifications are handled by WindowProc to OnCommand.
OnCommand is a command message or notification message that is differentiated by wparam and lparam parameters and then sent to oncmdmsg processing.
In fact, the processing of the BN_CLICKED control notification message is identical to the processing of the WM_COMMAND command message.
Because the notification code for the message is 0,on_bn_clicked (id,memberfunction) and On_command (id,memberfunction) are equivalent.

(4) Thewm_notify message only extends the WM_COMMAND control notification , which has the same characteristics as the WM_COMMAND control notification.

SendMessage and PostMessage

PostMessage the message to the message queue and returns immediately;
SendMessage send the message directly to the window process processing, the processing is finished before returning.

GetMessage and PeekMessage

GetMessage has a message and the message is not wm_quit and returns True.
There is a message and the message is Wm_quit, which returns false.
When there is no message, the UI thread is suspended and control is returned to the system.
PeekMessage has a message that returns TRUE if no message returns false;
Whether to remove this message (Pm_remove) from the message queue, as specified by the function parameter.

To do some work without a message, you must use PeekMessage to crawl the message so that you can perform idle operations in OnIdle without the message (as follows):

1 while (TRUE)  2 {3     if (PeekMessage (&msg, NULL, 0, 0, pm_remove)  4     {5         if (msg.message = = Wm_quit ) 6 break             , 7         translatemessage (&msg), 8         dispatchmessage (&msg), 9     }10     Else,     {12         OnIdle ();     14}

For example, MFC uses the OnIdle function to clean up some temporary objects and unused dynamic-link libraries.

The program can continue to process user input only after OnIdle returns, so you should not perform longer tasks in OnIdle.

MFC Message Processing

In CWnd, MFC uses ONWNDMSG to process various messages separately:

If it is a WM_COMMAND message, give it to OnCommand and return.

If it is a WM_NOTIFY message, give it to onnotify and return.

If it is a wm_activate message, hand it over to _afxhandleactivate and proceed with the processing below.

If it is a wm_setcursor message, it is first handed to _afxhandlesetcursor and then returned.

If it is a different window message (including the wm_activate message), the

The message is first matched in the message buffer pool (a hash table, which is used to speed up the lookup of the message processing function).
If the match succeeds, the corresponding message handler function is called;
If it is not successful, a lookup match is made in the message map array of the message destination to see if it can handle the current message.
If the message target processes the message, it matches the message handler and invokes it for processing;

Otherwise, the message is not processed by the application and Onwndmsg returns FALSE.

MFC message Map

The message map is actually a message dispatch mechanism built in MFC.

Expand the Macros in MFC (below) to get a complete picture of the message map.

Note: Getmessagemap is a virtual function.
{0, 0, 0, 0, Afxsig_end, (afx_pmsg) 0}: End identity of the object message map table

window messages can only be handled by CWnd objects , and the corresponding message response function is processed by using the method of straight-forward to the base class .

Once the message response function is found (if there is a return value and true), it stops. As a result, we often see this code:

When adding a message handler to write our logic, MFC ClassWizard displays the function that calls its base class before or after the function, ensuring that the logic in the base class is executed.

The command message can be received and processed by the CCmdTarget object (OnCmdMsg is a virtual function), in addition to the base class straight way, there is also a command bypass mechanism (to prevent the formation of loops, dead loops).

To some extent, control notification messages are handled by Window objects as a habit and convention. However, a control notification message can also have a CCmdTarget object received and processed, and the command is bypassed .

Command message bypass route for MFC Classic Single Document View framework:

The function call procedure is as follows (if there is no object handling the WM_COMMAND message, it will end up being processed by::D Efwindowproc).

Message processing for a non-modal dialog box

1 static CAboutDlg aboutdlg;2 aboutdlg.create (Idd_aboutbox, this); 3 Aboutdlg.showwindow (sw_show);

The application has only one message loop.

For window messages, the Non-modal dialog box (and its child controls) and the parent window (and its child controls) are received and processed with their own WindowProc functions, and do not interfere with each other.

For a command message, received by the WindowProc of the currently active main window (for example: The current active main window is a non-modal dialog box, the command message is received by the Non-modal dialog box).

You can make a command detour in the oncmdmsg of the currently active main window, so that other CCmdTarget objects can also handle command messages.

For a control notification, the WindowProc of its parent window is received and processed, and the command bypass is generally handled by other CCmdTarget objects.

Message processing for modal dialog boxes

1 CAboutDlg aboutdlg;2 aboutdlg.domodal ();

(1) When the modal dialog box is bounced, the parent window is first invalidated so that it cannot accept the user's input (keyboard and mouse messages).

1 EnableWindow (hwndparent, FALSE);

(2) The parent window message loop is blocked (it will be stuck at DoModal, waiting to be returned), and the modal dialog's message loop will take over (so the whole program won't get stuck).

After the takeover, the modal dialog message loop will still send the window messages belonging to the parent window and its child controls (excluding window messages related to the keyboard mouse) to their respective WindowProc window functions for response processing.

(3) When the modal dialog is destroyed (click Idok or Idcancel), the parent window message loop is reactivated and the logic continues after the DoModal.

After activation, the parent window has input that can be re-accepted by the user (keyboard mouse message).

1 EnableWindow (hwndparent, TRUE);

From the above process, we can get the following conclusions:

For window messages, the modal dialog Box main window (and its child controls) and the parent window (and its child controls) are received and processed with their own WindowProc functions, with no interference.

Only the parent window (and its child controls) cannot accept window messages related to keyboard mouse messages.

For a command message, it is received by the WindowProc of the main window of the modal dialog box. You can make a command detour in the OnCmdMsg of the modal Dialog main window, so that other CCmdTarget objects can also handle command messages.

For a control notification, the WindowProc of its parent window is received and processed, and the command bypass is generally handled by other CCmdTarget objects.

Reference

"In Layman's MFC"-Houtie

MFC tutorial-Implementation of message maps

http://blog.csdn.net/kongfuxionghao/article/details/35882533

Windows Messaging Mechanism (MFC)

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.