(3) Documentation and view The connection between the view class has a protection data member: cdocument * m_pdocument; Class has a protective data member: cdocument * m_viewlist; it saves all pointers that are displaying the document, and the GetFirstViewPosition and GetNextView functions can be accessed by cdocument. When the view is created, the view and document occurred in the oncreate function: int CView :: OnCreate (LPCReateStruct LPCS) {if (CWnd :: Oncreate (LPCS) == -1) Return -1; ccreateContext * PContext = (CCreateContext *) lpcs-> lpCreateParams; if (!! pContext = NULL && pContext-> m_pCurrentDoc = NULL) {pContext-> m_pCurrentDoc-> addView (this); ASSERT (! m_pDocument = NULL);} else {TRACE0 ( " WARNING: CREANT./N ");} return 0;} This association is implemented by the addView function of the document class: void cdocument :: addView (cView * pView) {... m_viewlist.addtail (PVIEW) PView-> m_pdocument = this; onchangeDViewList ();} In this function, first add the added view pointer to its own view chain, then point to its own pointer to assume the M_PDocument added by the added view. member.
It is well known that documentation and view communicate ways to call the UpdateAllViews function of the document, thus call the view's onupdate function: void cdocument :: UpdateAllViews (CView * psenter, lparam lhint, cobject * phint) // Walk through all views {// view Lin tables cannot be empty and senders can't be empty assert (psenter == null ||! M_viewlist.isempty (); position pos = getfirstViewPosition (); while (pOS! = Null) {cView * pView = getNextView (POS); Assert_Valid (PView); // Does not call the sender's onupdate function if (pView! = Psenter) pView-> onupdate (psenter, lhint, phint);}} The default implementation in the ONUPDATE function in the view is only the notification view Painting: Invalidate (TRUE); We generally overload certain data of this update view or other operations, such as updating the scroll range of the view scroll bar.
(4) Frame window and documentation, the connection between the views is created in the frame window, create a view, the relevant functions are as follows: int CFrameWnd :: OnCreate (lpcreateStruct LPCS) {ccreateContext * PContext = (ccreatecontext *) LPCS > lpCreateParams; return OnCreateHelper (lpcs, pContext);} int CFrameWnd :: OnCreateHelper (LPCREATESTRUCT lpcs, CCreateContext * pContext) {if (CWnd :: OnCreate (lpcs) == -1) return -1; // create special children first (! OnCreateClient (lpcs, pContext)) if {TRACE0 ( "Failed to create client pane / view for frame./n"); return -1;} // post message for initial message string PostMessage (WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE); / / make sure the child windows have been properly sized RecalcLayout (); return 0; // create ok} BOOL CFrameWnd :: OnCreateClient (LPCREATESTRUCT, CCreateContext * pContext) {// default create client will create a view if asked for it if ( PCONText! = null &&pontext-> m_pnewviewclass! = nu LL) {if (CreateView (pContext, AFX_IDW_PANE_FIRST) == NULL) return FALSE;} return TRUE;} CWnd * CFrameWnd :: CreateView (CCreateContext * pContext, UINT nID) {CWnd * pView = (CWnd *) pContext-> m_pNewViewClass -> CreateObject (); if (pView == null) {return null;} assert_kindof (cwnd, pview); if (! PView-> Create (Null, Null, AFX_WS_DEFAULT_VIEW, CRECT (0, 0, 0, 0), THIS, NID, PCONText) {Return Null; // can't Continue without a view} IF (AfxData.bwin4 && (PView->
GetExStyle () & WS_EX_CLIENTEDGE)) {ModifyStyleEx (WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);} return pView;} in OpenDocumentFile function document template as a call has occurred: InitialUpdateFrame (pFrame, pDocument, bMakeVisible); implementation of this function document template is: pFrame-> InitialUpdateFrame (pDoc, bMakeVisible); actually called frame window function of the same name: void CFrameWnd :: InitialUpdateFrame (CDocument * pDoc, BOOL bMakeVisible) {CView * pView = NULL; if (GetActiveView () == NULL ) {// Take the main view CWnd * PWnd = getDescendantWindow (AFX_IDW_PANE_FIRST, TRUE); if (pWnd! = Null && pop-> iskindof (runtime_class (cView))) {// Main view exists and legal, put the current frontictive set active view pView = (CView *) pWnd; SetActiveView (pView, FALSE);}} if (bMakeVisible) {SendMessageToDescendants (WM_INITIALUPDATE, 0, 0, TRUE, TRUE); if (! pView = NULL) pView-> OnActivateFrame (Wa_INACTIVE, THIS) ; ...... ActivateFrame (nCmdShow); if (pView = NULL!) PView-> OnActivateView (TRUE, pView, pView);} // update frame counts and frame title (may already have been visible) if (! PDoc = NULL) PDOC-> UpdateFramecounts (); OnUpdateFrameTitle (TRUE);} The above function is mainly used to set the activity view with SetActiveView and call the onactivateframe function of the view.
CFrameWnd maintained in a protection member of the class: CView * m_pViewActive;, SetAcitveView main function is to operate it: void CFrameWnd :: SetActiveView (CView * pViewNew, BOOL bNotify) {CView * pViewOld = m_pViewActive; if (pViewNew == pViewOld ) return; // do not re-activate if SetActiveView called more than once m_pViewActive = NULL;! // no active for the following processing // deactivate the old one if (pViewOld = NULL) pViewOld-> OnActivateView (FALSE, pViewNew, pViewOld); if (m_pViewActive = NULL) return;! // already set m_pViewActive = pViewNew;! // activate if (pViewNew = NULL && bNotify) pViewNew-> OnActivateView (TRUE, pViewNew, pViewOld);} CFrameWnd yet another this function returns a member: CView * CFrameWnd :: GetActiveView () const {ASSERT (m_pViewActive == NULL || m_pViewActive-> IsKindOf (RUNTIME_CLASS (CView))); return m_pViewActive;} document CframeWnd there is a currently active function can be achieved , It is indirect through the activity view: cdocument * cframeWnd :: GetActiveDocument () {assert_valid (this); cView * pView = getActiveView (); if (pView! = Null) Return PView-> getDocument (); return null;} (5) Association between MDI main windows and sub-windows: when MDI child window is created, specifying the relationship between it and MDI: BOOL CMDIChildWnd :: create (LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT & rect, CMDIFrameWnd * pParentWnd, CCreateContext * pContext) {if (pParentWnd == NULL) {CWND * PMainWnd = AFXGETTHREAD () -> m_pmainwnd; assert (PMainWnd! = Null);