Manually add a message Response Function
The most primitive method of the manual message response function is to add an appropriate message ing table item in the message ing table.
First, let's look at the message ing table items:
Struct afx_msgmap_entry <br/>{< br/> uint nmessage; // Windows message <br/> uint ncode; // control code or wm_policy Code <br/> uint NID; // Control ID (or 0 for Windows messages) <br/> uint nlastid; // used for entries specifying a range of Control ID's <br/> uint_ptr nsig; // signature type (action) or pointer to message # <br/> afx_pmsg PFN; // routine to call (or special value) <br/>}; <br/>
We can choose to fill in a table item so that the framework can find it and call the response function.
Determine nmessage.Of course it is a message to be processed.
Determine the response function.According to the nmessage, you can determine the specific meanings of wparam and lparam. Then, define the response function according to your own needs and set the appropriate parameters.
Determine nsig.The next step is to tell the framework how to pass parameters to the response function. for standard messages, wparam and lparam are formatted completely by nsig. for command messages and notification messages, the framework first analyzes wparam and lparam. at the end, nsig format is no longer for them.
For standard messages, see the naming rules of Enum afxsig for wparam and lparam formatting using nsig. The following is a snippet of afxmsg _. h:
// Naming scheme: <br/> // <signature>-> afxsig _ <returntype >_< wparamtype >_< lparamtype> <br/> // <returntype>-> B (bool) <br/> // H (handle) <br/> // v (void) <br/> // I (INT) <br/> // L (lresult) <br/> // <wparamtype>-> <br/> // naming scheme: <br/> // B-bool <br/> // D-CDC * <br/> // w-cwnd * <br/> // w-uint <br //> // H-handle <br/> // I-int <br/> // s-lptstr <br/> // v-void <br/> // l-lparam <br/> // M-cmenu * <br/> // P-cpoint <br/> // pos-windowpos * <br/> // calc- nccalcsize_params * <br/> // nmhdr-nmhdr * <br/> // helpinfo-helpinfo * <br/> // Sizing-lprect <br/> // cmdui-ccmdui * <br/> // CDS-copydatastruct * <br/> // s-short <br/>
After you have prepared the name, check whether the enum afxsig exists. Finally, check it in onwndmsg.
For command messages and notification messages. the framework finally calls _ afxdispatch1_msg for distribution. looking at its source code, you will find that there is no rule between nsig and the response function. no way. You can only check the source code of _ afxdispatch1_msg for nsig. It is not long anyway.
Determine NID and nlastid.Generally, the NID and nlastid values are the same, and they are the control or menu ID. The standard message must be 0. The value can be obtained from cwnd: onwndmsg.
The call to afxfindmessageentry shows that:
Bool cwnd: onwndmsg (uint message, wparam, lparam, lresult * presult) <br/>{< br/>... <br/> If (lpentry = afxfindmessageentry (pmessagemap-> lpentries, <br/> message, 0, 0 ))! = NULL) // The last two parameters are used to match ncode and NID. To match table items, you can only fill them with 0 <br/>{< br/> pmsgcache-> lpentry = lpentry; <br/> winmsglock. unlock (); <br/> goto ldispatch; // matched, ready for processing <br/>}< br/>... <br/>}< br/>
For command messages and notification messages, the programmer must specify the ID, which is NID.
Determine ncode.If the standard message ncode is 0, you can see the code above. For the Command Message ncode, it is not necessary to specify it, but the framework defaults to cn_command (the value is 0). In bool
Cwnd: oncommand (wparam
Wparam, lparam
You can find the answer in lparam:
Bool cwnd: oncommand (wparam, lparam) <br/>{< br/>... <br/> If (hwndctrl = NULL) <br/>{< br/>... <Br/> ncode = cn_command; // The ncode In the table item must be cn_commmand. <br/>... <br/>}< br/>... <br/> return on1_msg (NID, ncode, null, null); <br/>}< br/>
The ncode of the notification message must be specified, so it is settled. For the notification message with wm_notify headers, ncode is a bit strange. Let's take a look at the following code:
Bool cwnd: onnotify (wparam, lparam, lresult * presult) <br/>{< br/> assert (presult! = NULL); <br/> nmhdr * pnmhdr = (nmhdr *) lparam; <br/> hwnd hwndctrl = pnmhdr-> hwndfrom; <br/> uint_ptr nid = _ afxgetdlgctrlid (hwndctrl); <br/> int ncode = pnmhdr-> code; <br/>... <br/> // No. makelong (ncode, wm_notify) ncode and wm_notify are twisted into a group <br/> return on1_msg (uint) NID, makelong (ncode, wm_notify), ¬ ify, null); <br/>}< br/>
However, in cve-target: on1_msg, it is split again:
If (ncode! = Cn_update_command_ui) <br/>{< br/> nmsg = hiword (ncode); <br/> ncode = loword (ncode); <br/>}< br/>
Here, a problem occurs. The NID value is good, but how can we obtain the ncode value?
The general practice is to use msdn + Baidu + Google to search for the control and learn how to use it. However, sometimes it is difficult to find a suitable document. Even msdn is like this, I am helpless! It is not easy. In vs2005, you can do this:
Switch to resource editor-> select the control to be processed (the selected dialog box is also displayed)-> right-click and choose [properties]-> Find [control event] on the tab. ncode indicates the notification code. use msdn to search for these notification codes.
For manual filling, you can also refer to the Message ing macro of the Framework in afxmsg _. h.
Manual filling is clear but troublesome. and not everyone is like me. therefore, MFC provides a system message ing macro for ease of use. however, macros are too dead and function names are fixed and cannot be changed. for example, you can only use oncreate to respond to wm_create. You can see on_wm_create.