Window message Overview:
The basic form of all window messages is the same. There are three parts: (1 ). an unsigned integer that contains the actual content of the message. (2) WPARAM, a 4-byte integer. (3) LPARAM, a 4-byte parameter. the number of unsigned messages is the actual message.
The core of any WINDOWS program, including MFC, is the message pump. the message pump is a loop that extracts messages and sends them to the appropriate window message processing function. the following is an example of a message pump:
While (GetMessage (& msg, NULL )){
TranslateMessage (& msg );
DispatchMessage (& msg );
}
Return msg. wParam;
When the program starts running, it calls RegisterClass () and uses a WNDCLASS structure to register at least one window class. WINDOWS calls the function specified by lpfnWndProc in WNDCLASS whenever there is a message in a window of this class.
In typical SDK programs, message processing functions are large and difficult to maintain switch statements. in C ++, virtual functions can be used to process each message. However, this method will incur excessive overhead due to the virtual table, and it is difficult to adapt to the increase or decrease of messages.
----------------------------
Csf-target and message ing table-two basic components of the Message Processing Structure of MFC
----------------------------
Message ing Table Data Structure
Struct AFX_MSGMAP_ENTRY {// actual entry of the message ing table.
UINT nMessage; // actual message
UINT nCode; // control code or notification code
UINT nID; // Control ID
UINT nLastID; // The maximum ID of the control.
UINT nSig; // signature of the Message Processing Function
AFX_PMSG pfn; // Message Processing Function
};
Struct AFX_MSGMAP {// The actual message ing table.
Const AFX_MSGMAP * pBaseMap; // message ing table of the base class.
Const AFX_MSGMAP_ENTRY * lpEntries; // array pointer of the message table entry.
}
Message ing macro:
# Define DECLARE_MESSAGE_MAP ()/
Private :/
Static const AFX_MSGMAP_ENTRY _ messageEntries [];/
Protected :/
Static AFX_DATA const AFX_MSGMAP messageMap ;/
Virtual const AFX_MSGMAP * GetMessageMap () const ;/
# Define BEGIN_MESSAGE_MAP (theClass, baseClass )/
Const AFX_MSGMAP * theClass: GetMessageMap () const/
{Return & theClass: messageMap ;}/
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP theClass: messageMap =/
{& BaseClass: messageMap, & theClass: _ messageEntries [0]};/
AFX_COMDAT const AFX_MSGMAP_ENTRY theClass: _ messageEntries [] =/
{/
# Define end_message_map ()/
{0, 0, 0, 0, afxsig_end, (afx_pmsg) 0 }/
};
Common Message table entry macros:
On_wm_xxxx: pre-defined window message
On_command: Command
On_update_command_ui: update command
On_xxxx: Control notification
On_message: custom message
On_registered_message: The registered window message.
On_command_range: Specifies the ID range command
On_update_command_ui_range: Specifies the update command for the ID range.
On_control_range: ID range control
On_notify: notification message
On_policy_range: indicates the notification message with the specified ID range.
...
Implementation example:
# Define on_command (ID, memberfxn )/
{Wm_command, cn_command, (Word) ID, (Word) ID, afxsig_vv, (afx_pmsg) & memberfxn },
// On_command (ID, onfoo) is the same
// On_control (0, ID, onfoo) or on_bn_clicked (0, ID, onfoo)
------------------------------
Use of message ing table
The message ing table can process two types of messages: common window messages (such as mouse messages) and command messages (such as menu messages ).
Association process between windows and AfxWndProc
In MFC, DefWindowProc is used as the message processing function for registration. when a new CWnd derived class is created (in CreateEx): createaappswex, AfxHookWindowCreate () is called to set HOOK: _ AfxCbtFilterHook () to process window activation and creation, destroys messages. _ AfxCbtFilterHook calls _ AfxStandardSubClass () when the HCBT_CREATEWND message arrives. It calls SetWindowLong () to put AfxWndProc () into a window, and AfxWndProc () processes the actual message. ---- MFC does not directly register AfxWndProc as a message processing function to support 3D controls. At this time, make sure that the processing process is called in the following order: AfxWndProc, WndProc of 3D controls, default DefWindowProc.
AfxWndProc Message Processing Process
1. when processing a message, AfxWndProc first checks whether it is WM_QUERYAFXWNDPROC. If yes, 1 is returned, indicating that the message ing System Using MFC is used.
2. call AfxCallWndProc. in the WM_INITDIALOG message, AfxCallWndProc calls _ AfxHandleInitDialog to center the dialog box. afxCallWndProc will also save the message pair in the thread state, and finally call the window process of the window object: WindowProc ();
3. CWnd: WindowProc call CWnd: OnWndMsg (). If FALSE is returned, call CWnd: DefWindowProc ();
4. CWnd: OnWndMsg () corresponds to the switch statement in the SDK program. first, it filters out special messages WM_COMMAN, WM_NOTIFY, WM_ACTIVATE, WM_SETCURSOR, and calls the special processing functions corresponding to the framework class. other messages enter the message ing table to find the processing function.
5. WM_COMMAND processing.
1 ). the first stop: the virtual function CWnd: OnCommand (); the message is generated by the framework class, so the OnCommand () implementation of the framework class is called. the OnCommand check indicates the LPARAM parameter of the Control. Messages generated by the control include the control window in the LPARAM. The close-up process is called for notification messages of the control. if a message is generated for a control, OnCommand will send the message directly to the control and return it; otherwise, it will ensure that the user interface elements that generate the command are not disabled, then ondomainmsg will be called.
2 ). CFrame: on1_msg (). it searches for processing functions in the message ing table in the following order: Activity view, activity view document, main window, and application. after finding it, call dispatch1_msg to execute the found processing function, and call DefWindowProc when it is not found.
3 ). static BOOL dispatch1_msg (): perform different operations according to the function signature (nSig variable in the message table entry. generally, the signature of the menu command is AfxSig_xx, which directly calls the processing function. Other signatures may need to pre-decompose the message parameters LPARAM and WPARAM;
Command route to the Framework Window: AfxWndProc -- AfxCallWndProc -- CWnd: WindowProc -- CFrameWnd: OnCommand -- CWnd: OnCommand -- CFrameWnd: on1_msg -- c1_target :: on‑msg -- dispatch‑msg -- CMainFrame class command processing
Command route to the document: AfxWndProc -- AfxCallWndProc -- CWnd: WindowProc -- CFrameWnd: OnCommand -- CWnd: OnCommand -- CFrameWnd: on1_msg -- CView: on1_msg -- CDocument :: on‑msg -- c‑target: on‑msg -- dispatch‑msg -- document-class command Handler
Command route to the view: AfxWndProc -- AfxCallWndProc -- CWnd: WindowProc -- CFrameWnd: OnCommand -- CWnd: OnCommand -- CFrameWnd: on1_msg -- CView: on1_msg -- c1_target :: on1_msg -- dispatch1_msg -- View class command processing function
Command route to the application class: AfxWndProc -- AfxCallWndProc -- CWnd: WindowProc -- CFrameWnd: OnCommand -- CWnd: OnCommand -- CFrameWnd: on1_msg -- c1_target :: on‑msg -- dispatch‑msg -- Application-class command Handler
Command route to the dialog box class: afxwndproc -- afxcallwndproc -- cwnd: windowproc -- cwnd: oncommand -- cwnd: on1_msg -- cdialog: on1_msg -- dispatch1_msg -- Dialog Box class command processing function
6. process common window messages: afxwndproc -- afxcallwndproc -- cwnd: windowproc -- cwnd: onwndmsg -- afxfindmessageentry -- actual processing function
7. Call member functions.
Function signature definition:
Union messagemapfunctions {
Afx_pmsg PFN; // General member function pointer.
Bool (afx_msg_call cwnd: * pfn_bd) (CDC *);
Bool (afx_msg_call cwnd: * pfn_bb (bool );
.......
};
In onwndmsg, the PFN in the Union is set as the address of the message processing function: MMF. PFN = lpentry-> PFN. At the same time, find the appropriate signature, extract necessary parameters from wparam and lparam, and call the processing function using a prototype consistent with the signature.
8. Other types of messages.
1). wm_policy.
Cwnd: onwndmsg () uses cwnd: onnotify () for processing. onnotify calls onchildnotify () to send the message to the control.
2). Message reflection.
Message macro reflection can be used to enable the control to process specific messages by itself.
3). wm_activate.
In onwndmsg (), call _ afxhandleactivate () to check whether the top layer is wm_activate. If yes, the wm_activatetoplevel message is sent to the top layer window.
4). WM_SETCURSOR.
Processing in _ AfxHandleSetCursor (). When you press the mouse, the last activity window is activated.
---------------------------------
PreTranslateMessage ---- message preprocessing
There are two portals in total: CWinApp: PreTranslateMessage, CWnd: PreTranslateMessage.
Before a message is processed by TranslateMessage () and DispatchMessage (), CWinApp: Run () calls CWinApp: PreTranslateMessage. Then, CWinApp :: preTranslateMessage calls the CWnd: Translatemessage () of each window from the message structure to the specified target window and the main window of the application ().
If TRUE is returned during preprocessing, the message is not processed subsequently.
This article from the CSDN blog, reproduced please indicate the source: http://blog.csdn.net/gxj1680/archive/2009/03/18/3998923.aspx