By analyzing the source code of MFC, we can get WM_COMMAND message response order as follows:
Multiple document frame, when there are open documents: View > Documents > Child Frames window > Applications > main frame window
Multiple frame when the document is not open, the order of the application and the main frame window is reversed: Main frame window > application
In a single-document framework application, because there are no child frame windows, the order should be: View > Document > Main frame window > application. The main frame window takes precedence over the application class, regardless of whether the document is open or not.
In fact, in a multi-document framework, the system automatically generates code that uses the CDocTemplate subclass CMultiDocTemplate. A code similar to the following can be found in the application class (multiple file application framework) InitInstance ():
// register the application's document template. Document templates // Connections between the composition document, frame window, and view CMultiDocTemplate* Pdoctemplate; pdoctemplate = new cmultidoctemplate (IDR_test3TYPE, runtime_class (Ctest3doc), runtime _class (cchildframe), // Custom MDI sub-frame runtime_class (Ctest3view)); if (!pdoctemplate) return FALSE; The CMultiDocTemplate class does not override the OnCmdMsg function, so it still does not affect the order in which the WM_COMMAND message responds. bool cdoctemplate::oncmdmsg (uint nid, int ncode, void* pextra, afx_cmdhandlerinfo* phandlerinfo) ... { bool breturn; ccmdtarget* pfactory = Dynamic_downcast (ccmdtarget, m_pattachedfactory); if (ncode == cn_ole_unregister && pfactory != null) breturn = pfactory->oncmdmsg (NID, nCode, pExtra, phandlerinfo); else breturn = CCmdTarget::OnCmdMsg (nid, ncode, pextra, phandlerinfo); return breturn;}
650) this.width=650; "align=" Top "src=" Http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif "/ >
Because the application does not develop a class that inherits directly from CDocTemplate, the application cannot use the CDocTemplate subclass to define the response function of the WM_COMMAND message. The ccmdtarget::oncmdmsg that the CDocTemplate class calls in the ONCMDMSG function implementation cannot implement any message delivery.
View CView > Document CDocument > Sub-frame cframe > Application CWinApp > main frame window CMDIFrameWnd
Then look at the implementation code for CDocument's oncmdmsg:
650) this.width=650; "align=" Top "src=" Http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif "/ >
The document class CDocument first finds its own response function (call ccmdtarget::oncmdmsg) and then has its members m_pdoctemplate to handle. m_pDocTemplate is a pointer to the document template class CDocTemplate, and the MFC framework uses document templates for automated document management. There is no programming for the document template class during application development. To view the implementation of OnCmdMsg in the CDocTemplate class:
BOOL cdocument::oncmdmsg (UINT nID, int nCode, void* Pextra, afx_cmdhandlerinfo* phandlerinfo) ... {if (CCmdTarget::OnCmdMsg (NID, NCode, Pextra, Phandlerinfo)) return TRUE; Otherwise check template if (m_pdoctemplate! = NULL && m_pdoctemplate->oncmdmsg (NID, NCode, Pextra, p Handlerinfo)) return TRUE; return FALSE;}
When there is an open view, the View CView > sub frame cframe > Application CWinApp > main frame window CMDIFrameWnd
Main frame window CMDIFrameWnd > Application CWinApp when no view is open
Then look at the view CView class for OnCmdMsg processing:
650) this.width=650; "align=" Top "src=" Http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif "/ >
Bool cview::oncmdmsg (uint nid, int ncode, void* pextra, Afx_cmdhandlerinfo* phandlerinfo) ... { // first pump through pane if (CWnd: : ONCMDMSG (nid, ncode, pextra, phandlerinfo)) return TRUE; // then pump through document if (m_pdocument != null)   ... { // special state for saving view Before routing to document cpushroutingview push ( this); return m_pdocument->oncmdmsg (nID, nCode, Pextra, phandlerinfo); } return false;}
The view class first finds its own message response table (called cwnd::oncmdmsg) and then has the CDocument class for the view to process the message. So it can be concluded as follows:
Child frame window CMDIChildWnd > main frame window CMDIFrameWnd
The CMDIChildWnd window does not overload the ONCMDMSG function, so use the ONCMDMSG function CFrameWnd the basic frame window: bool cframewnd::oncmdmsg (uint nid, Int ncode, void* pextra, afx_cmdhandlerinfo* phandlerinfo) ... { cpushroutingframe push (this); // pump Through current view first cview* pview = getactiveview () ; if (Pview != null && pview->oncmdmsg (nID, Ncode, pextra, phandlerinfo)) return TRUE; // then pump through frame if (Cwnd::o Ncmdmsg (nid, ncode, pextra, phandlerinfo)) return true; // last but not least, pump through app cwiNapp* papp = afxgetapp (); if (papp != null & & papp->oncmdmsg (nid, ncode, pextra, phandlerinfo)) return true; return false;}
650) this.width=650; "align=" Top "src=" Http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif "/ >
The basic frame window first makes the currently active view CView the response function, then finds its own message response table (called cwnd::oncmdmsg) and finally lets the application process the message. So the order is drawn:
Mfc:
Win32 Encapsulation, Window System cell, element sub-parent Draw relational system and message response mechanism, respectively, are the mutual plotting mechanism and
Message passing mechanism
In MFC-developed programs, menus, toolbar buttons, and so on will produce WM_COMMAND messages. In MFC's Document/view framework, there are many classes that can respond to WM_COMMAND messages, namely the Framework class: CFrameWnd,CMDIChildWnd,cmdiframewnd; application class CWinApp ; document class CDocument; and view class CView.
When the application main menu sends a WM_COMMAND message, the WM_COMMAND message is given an instance of the class in a certain order, and the first found response function is called. As an example of a multi-document view framework application, we can parse the source code of these classes in MFC and step through the sequence of responses to WM_COMMAND messages.
Because the frame window is the parent window of the menu, the message is first sent to an instance of the CMDIFrameWnd class (that is, the main frame window, usually CMainFrame). The oncmdmsg functions of the CMDIFrameWnd class are as follows:
650) this.width=650; "align=" Top "src=" Http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif "/ >
bool cmdiframewnd::oncmdmsg (Uint nid, int ncode, void* pextra, afx_cmdhandlerinfo* phandlerinfo) ... { cmdichildwnd* pactivechild = mdigetactive (); // pump through active child FIRST if (pactivechild != null) { cpushroutingframe push (this); if (Pactivechild->oncmdmsg (nid, ncode, pextra, phandlerinfo)) return TRUE; } // then pump through normal frame return cframewnd::oncmdmsg (Nid, ncode, pextra, phandlerinfo);}
The main frame window CMDIFrameWnd first finds the currently active child frame window CMDIChildWnd, gives it priority access, and then invokes the response function of the basic frame window CFrameWnd. So the response priority:
MFC window WM_COMMAND messages