to blog CTabCtrl as described in, Add a child dialog box to the tab to display the tab content. So what if this child dialog contains a CTreeCtrl control with a button control and I want to simulate sending messages to both controls? It is useless to give the control's message directly to the control container (the parent window of the control). Why is it? The first thing to know about Windows message Classification :
Classification of Windows messages
1. Standard message (Queue message)
All messages beginning with wm_ , except wm_command , are standard messages, such as Wm_mousemove, Wm_lbuttonup, WM_KEYDOWN, and WM_CHAR.
Classes derived from CWnd can receive this type of message.
Each time Windows removes a message from the system message queue, determines which window it is sent to and which thread created it, and then puts it into the window to create the thread's thread message queue. Thread Message Queuing receives a message to the window created by the thread. The thread takes the message out of the message queue and sends it through windows to the appropriate window procedure to handle it. In addition to keyboard and mouse messages, queue messages include WM_PAINT, Wm_timer, and Wm_quit.
Note: The standard message does not require that we specify the handler name, which is the default correspondence.
For example:
macro names correspond to message message handler functions
On_wm_char WM_CHAR OnChar
On_wm_close Wm_close OnClose
On_wm_create wm_create OnCreate
On_wm_destroy Wm_destroy OnDestroy
On_wm_lbuttondo Wm_lbuttondown OnLButtonDown
On_wm_lbuttonup Wm_lbuttonup OnLButtonUp
On_wm_mousemove Wm_mousemove OnMouseMove
On_wm_paint WM_PAINT OnPaint
......... ............ .......
2. Command messages
Messages from menus, accelerator keys, or toolbar buttons are command messages.
This type of message is presented in wm_command form. In MFC, different command messages are distinguished by the identification (ID) of the menu item, and in the SDK, the wParam parameter of the message is identified. A class derived from CCmdTarget can receive such a message, and its wParam records which menu item the message came from.
Example : On_command (idm_about, Onabout)
On_command (Idm_filenew, OnFileNew)
On_command (Idm_fileopen, OnFileOpen)
On_command (Idm_filesave, OnFileSave)
...........
3. Notification message
Messages generated by controls, such as buttons, selection of list boxes, and so on, generate advertisement messages in order to notify their parent window (usually a dialog box) of the occurrence of an event.
This type of message is presented in the form of wm_command or wm_notify . Classes derived from CCmdTarget, such as CDocument can accept command messages and advertise messages, but cannot receive standard messages (queue messages), can receive such messages.
Note: Since the CWnd class derives from the CCmdTarget class, all classes derived from CWnd can receive both standard messages and command messages and advertisement messages. For classes derived from the CCmdTarget class, you can only receive command messages and advertisement messages, and you cannot accept standard messages.
For example : Control macro Message Handler function
Button on_bn_clicked (<id>,<memberFxn>) memberfxn
ComboBox on_cbn_dblclk (<id>,<memberFxn>) memberfxn
Edit On_en_setfocus (<id>,<memberFxn>) memberfxn
ListBox on_lbn_dblclk (<id>,<memberFxn>) memberfxn
......... ...................... ...........
Distinction between standard and non-standard messages:
Standard message: Generation of post-control follow-up operations;
Non-standard message: Just a simple hint.
Routing of MFC Command messages:
AfxWndProc (Replaces the window procedure function)->afxcallwndproc->windowproc->onwnddmsg-> (if the command message is called OnCommand; Call OnNotify If it is a notification message)->oncmdmsg
So is it wm_command or wm_notify to announce the message ?
Explanation One:wm_notify is more powerful than Wm_command and can store some extra information,WM_COMMAND not supported by all controls.
Explanation II: Edit,button,listbox, such as sending wm_command messages, Listview,toolbar,tree and other compile-time if not joined Comctl32.lib will not pass. Common,controls sends wm_notify messages Because more information is needed.
To send a message to a control in a dialog box:
You want to send a tcn_selchange message to the CTreeCtrl control simulation.
You want to send a bn_clicked message to the CButton control simulation.
★ From the face of Windows message classification, we know that these two messages are notification messages. Is that for wm_command or wm_notify ?
According to the above explanation, we use tcn_selchange-wm_notify ,bn_clicked-wm_command.
Isn't that so? Let's see MSDN:
Tcn_selchange
Tcn_selchange
LPNMHDR = (LPNMHDR) LParam;
Notifies a tab control ' s parent window, the currently selected tab has changed. This message was sent in the form of a WM_NOTIFY message.
-
Lpnmhdr
-
Address of an NMHDR structure. The
hwndfrom member is the handle to the tab control. The
idfrommember is the child window identifier of the tab control. The
code member is tcn_selchange.
It is seen that Tcn_selchange is indeed rendered as wm_notify , which contains the form of a struct pointer contained in LParam .
typedef struct TAGNMHDR {HWND hwndfrom; UINT Idfrom; UINT Code; } NMHDR;
Contains information about a notification message.
-
Hwndfrom
-
Window handle to the control sending a message.
-
Idfrom
-
Identifier of the control sending a message.
-
Code
-
Notification Code. This member can is a CONTROL-SPECIFIC notification code or it can be one of the common notification codes.
Bn_clicked
The BN_CLICKED notification message is sent when the user clicks a button. The parent window of the button receives this notification message through the wm_command message.
BN_CLICKED idButton = (int) LOWORD(wParam); // identifier of button hwndButton = (HWND) lParam; // handle to button
It is evident from the above that bn_clicked is indeed contained in the wm_command .
★ How to dissolve the announcement message into wm_command and wm_notify ?
Wm_notify
Idctrl = (int) WParam;
PNMH = (LPNMHDR) LParam;
-
Idctrl
-
Identifier of the common control sending the message.
-
Pnmh
-
Address of an NMHDR structure that contains the notification code and additional information.
-
Wm_command
wNotifyCode = HiWord (WParam); Notification code
WID = LoWord (WParam); Item, control, or accelerator identifier
hWndCtl = (HWND) LParam; Handle of control
Assembly Parameters:
LPARAM Makelparam (
Word wlow, //Low-order Word
WORD Whigh //High-order Word
);
Or
DWORD Makelong (
Word wlow, //Low-order Word of Long value
WORD Whigh //High-order Word of Long value );
★ Send a message to the control we can use the following two methods:
LONG senddlgitemmessage (
hwnd hdlg , &NBSP;&NBSP //Handle of dialog box
int Niddlgitem , //identifier of control
uint Msg , &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP //message to send
wparam wParam , //First message parameter
lparam lParam //Second message parameter
);
or
LRESULT SendMessage (
HWND hwnd, //Handle of destination window
UINT MSG , //message to send
WPARAM WParam , //First message parameter
LPARAM LParam //second message parameter
);
★ example, verify success:
Simulate sending Tcn_selchange messages
NMHDR NMHDR;
Nmhdr.code = Tcn_selchange;
Nmhdr.hwndfrom = G_pmaindlg->m_tabctrl.getsafehwnd ();
Nmhdr.idfrom= G_pmaindlg->m_tabctrl.getdlgctrlid ();
:: SendDlgItemMessage (G_pmaindlg->m_hwnd,idc_tab1,wm_notify,makelong (tcn_selchange,0), (LPARAM) (&NMHDR));
Send bn_clicked message
:: SendMessage (G_pmaindlg->m_vnonline.m_hwnd,wm_command,makelparam (idc_rang_off,bn_clicked), (LPARAM) (:: GetDlgItem (G_pmaindlg->m_vnonline.m_hwnd,idc_rang_off));
How do I send a message to a control in a dialog box? Windows message Classification