?? ch23.htm
字號:
</TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>ID_WINDOW_FORM</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">&Form View</TD> <TD ALIGN="LEFT" VALIGN="TOP"><TT>COMMAND</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP"><TT>OnWindowForm</TT></TD> </TR></TABLE><BLOCKQUOTE> <P><HR><B> </B><FONT COLOR="#000077"><B>CAUTION:</B></FONT><B> </B>You must add the new menu items to both the <TT>IDR_DISPLAYTYPE</TT> and <TT>IDR_DVTESTTYPE</TT> menus. If you don't, you won't be able to access the new menu items when either view is active. <HR></BLOCKQUOTE><P>Listing 23.9 provides the source code for the message-handling functions.<H4><FONT COLOR="#000077">TYPE: Listing 23.9. CMainFrame member functions used tocreate new views.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CMainFrame::OnWindowForm()</TT><TT>{</TT><TT> CMDIChildWnd* pActiveChild = MDIGetActive();</TT><TT> if( pActiveChild != 0 )</TT><TT> {</TT><TT> CDocument* pDocument = pActiveChild->GetActiveDocument();</TT><TT> if( pDocument != 0 )</TT><TT> {</TT><TT> CDVTestApp* pApp = (CDVTestApp*)AfxGetApp();</TT><TT> CDocTemplate* pTemp;</TT><TT> CFrameWnd* pFrame;</TT><TT> pTemp = pApp->GetFormTemplate();</TT><TT> pFrame = pTemp->CreateNewFrame(pDocument,pActiveChild);</TT><TT> if( pFrame != 0 )</TT><TT> {</TT><TT> pTemp->InitialUpdateFrame(pFrame, pDocument);</TT><TT> }</TT><TT> }</TT><TT> }</TT><TT>}</TT><TT>void CMainFrame::OnWindowDisplay()</TT><TT>{</TT><TT> CMDIChildWnd* pActiveChild = MDIGetActive();</TT><TT> if( pActiveChild != 0 )</TT><TT> {</TT><TT> CDocument* pDocument = pActiveChild->GetActiveDocument();</TT><TT> if( pDocument != 0 )</TT><TT> {</TT><TT> CDVTestApp* pApp = (CDVTestApp*)AfxGetApp();</TT><TT> CDocTemplate* pTemp;</TT><TT> CFrameWnd* pFrame;</TT><TT> pTemp = pApp->GetDisplayTemplate();</TT><TT> pFrame = pTemp->CreateNewFrame(pDocument,pActiveChild);</TT><TT> if( pFrame != 0 )</TT><TT> {</TT><TT> pTemp->InitialUpdateFrame(pFrame, pDocument);</TT><TT> }</TT><TT> }</TT><TT> }</TT></FONT></PRE><P><TT>}</TT> These functions are nearly identical: the only difference between themis the call to either <TT>GetDisplayTemplate</TT> or <TT>GetFormTemplate</TT>. Thefunctions provided in Listing 23.9 follow these steps when creating a new view:<DL> <DD>1. Get a pointer to the active child window.<BR> <BR> 2. Get a pointer to the active document.<BR> <BR> 3. Get a pointer to the application.<BR> <BR> 4. Using the application pointer, get the document template for the new view.<BR> <BR> 5. Using the document template, create a new frame associated with the active frame from step 1 and the document pointer from step 2.<BR> <BR> 6. Update the frame.</DL><P>These basic steps can be followed no matter what classes are involved or how manyviews and documents are being managed by the application.<H3><FONT COLOR="#000077"><B>Updating Multiple Views</B></FONT></H3><P>One of the most important issues when a document has more than one view is ensuringthat each view is accurate. If one view changes data loaded in the document, allviews must be notified about the change; otherwise, they will present out-of-dateinformation. The mechanism used by Document/View applications to keep documents andviews synchronized is shown in Figure 23.6.</P><P><A NAME="06"></A><A HREF="06.htm"><B>Figure 23.6.</B></A> <BR><I>The document class controls the updating of all views.</I></P><P>Every document should provide updates to its associated views by calling the <TT>UpdateAllViews</TT>function when data contained by the document has been changed. To update all viewsassociated with a document, you can use a line like this:</P><PRE><FONT COLOR="#0066FF"><TT>UpdateAllViews( NULL );</TT></FONT></PRE><P>The default implementation of <TT>UpdateAllViews</TT> notifies every view thatthe document has been changed by calling each view object's <TT>OnUpdate</TT> memberfunction. The <TT>NULL</TT> parameter causes all views to be updated. If a view pointeris passed as a parameter, that view is not updated. Listing 23.10 provides the newsource code for the <TT>CDVTestDoc::AddName</TT> function.<H4><FONT COLOR="#000077">TYPE: Listing 23.10. A new version of CDVTestDoc::AddNamethat causes views to be updated.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>int CDVTestDoc::AddName( const CString& szName )</TT><TT>{</TT><TT> TRACE("CDVTestDoc::AddName, string = %s\n", (LPCSTR)szName);</TT><TT> int nPosition = m_arNames.Add( szName );</TT><TT> UpdateAllViews( NULL );</TT><TT> return nPosition;</TT><TT>}</TT></FONT></PRE><H3><FONT COLOR="#000077"><B>Adding the <TT>OnInitialUpdate</TT> and <TT>OnUpdate</TT>Member Functions</B></FONT></H3><P>The <TT>OnInitialUpdate</TT> and <TT>OnUpdate</TT> member functions for <TT>CDisplayView</TT>invalidate the view area, causing the view to be repainted. When Windows sends a<TT>WM_PAINT</TT> message to the view, the <TT>OnDraw</TT> member function is called,redrawing the view with the new contents. Edit the <TT>OnInitialUpdate</TT> and <TT>OnUpdate</TT>functions as shown in Listing 23.11.<H4><FONT COLOR="#000077">TYPE: Listing 23.11. Source code the CDisplayView updatefunctions.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CDisplayView::OnInitialUpdate()</TT><TT>{</TT><TT> CView::OnInitialUpdate();</TT><TT> InvalidateRect( NULL );</TT><TT>}</TT><TT>void CDisplayView::OnUpdate(CView* pSender, LPARAM lHint,</TT><TT> CObject* pHint)</TT><TT>{</TT><TT> InvalidateRect( NULL );</TT><TT>}</TT> </FONT></PRE><P>All view classes should provide <TT>OnUpdate</TT> member functions that are calledby the MFC framework after the document class calls <TT>UpdateAllViews</TT>. Notethat the entire view is redrawn whenever the document has been updated.</P><P>The current view, <TT>CFormTest</TT>, must also support <TT>OnUpdate</TT>. Addthe <TT>OnUpdate</TT> function to the <TT>CFormTest</TT> class using ClassWizard.Listing 23.12 provides the source code for <TT>CFormTest::OnUpdate</TT>.<H4><FONT COLOR="#000077">TYPE: Listing 23.12. Source code for the CFormTest::OnUpdatefunction.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CFormTest::OnUpdate(CView* pSender, LPARAM lHint,</TT><TT> CObject* pHint)</TT><TT>{</TT><TT> CDVTestDoc* pDoc = (CDVTestDoc*)GetDocument();</TT><TT> ASSERT_VALID(pDoc);</TT><TT> m_lbNames.ResetContent();</TT><TT> for( int nIndex = 0; nIndex < pDoc->GetCount(); nIndex++ )</TT><TT> {</TT><TT> CString szName = pDoc->GetName( nIndex );</TT><TT> m_lbNames.AddString( szName );</TT><TT> }</TT><TT>}</TT> </FONT></PRE><P>Now that you have implemented <TT>OnUpdate</TT>, change the <TT>OnInitialUpdate</TT>member function so that it performs only work that must be done when the view isinitially displayed. Remove source code from <TT>CFormTest::OnInitialUpdate</TT>so it looks like the function provided in Listing 23.13.<H4><FONT COLOR="#000077">TYPE: Listing 23.13. CFormTest::OnInitialUpdate after removingunnecessary code.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CFormTest::OnInitialUpdate()</TT><TT>{</TT><TT> CFormView::OnInitialUpdate();</TT><TT> ResizeParentToFit( FALSE );</TT><TT> ResizeParentToFit();</TT><TT>}</TT> </FONT></PRE><P>Because <TT>OnUpdate</TT> handles the insertion of new items into the list box,you should change the <TT>OnApply</TT> member function so that it does not add stringsto the list box. Edit the <TT>OnApply</TT> member function so it looks like the codein Listing 23.14.<H4><FONT COLOR="#000077">TYPE: Listing 23.14. CFormTest::OnApply after removinglist box AddString code.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CFormTest::OnApply()</TT><TT>{</TT><TT> CDVTestDoc* pDoc = (CDVTestDoc*)GetDocument();</TT><TT> ASSERT_VALID(pDoc);</TT><TT> CString szName;</TT><TT> m_edNames.GetWindowText( szName );</TT><TT> m_edNames.SetWindowText( "" );</TT><TT> m_edNames.SetFocus();</TT><TT> if( szName.GetLength() > 0 )</TT><TT> {</TT><TT> pDoc->AddName( szName );</TT><TT> }</TT><TT>}</TT> </FONT></PRE><P>Compile and run the DVTest project. Figure 23.7 shows DVTest with new names addedto the document, and multiple open views.</P><P><A NAME="07"></A><A HREF="07.htm"><B>Figure 23.7.</B></A> <I><BR>DVTest after adding the display view.</I><H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2><P>In this hour you learned about using form views in place of standard views ordialog boxes. Form views enable you to easily use controls in a view, just as theyare used in dialog boxes. You also learned about associating multiple views witha document class. The DVTest program from Hour 9 was modified to take advantage ofform views and multiple views.<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2><DL> <DD><B>Q I have a view that must populate the menu with different menu items than other views. How should I handle the different menu choices?</B><BR> <BR> <B>A</B> There is no requirement that all view menus have the same items; each view menu can be customized to suit the needs of each view. You should give each menu item a unique identifier--two menu items that perform different tasks should have different identifiers, even if they have the same names.<BR> <BR> <B>Q Why is it useful to pass a <TT>CView</TT> pointer as a parameter in <TT>UpdateAllViews</TT> and prevent that view from receiving an <TT>OnUpdate</TT> notification?</B><BR> <BR> <B>A</B> Often, a view that causes a document to be updated can efficiently update its own view. In this case, there is no need for that particular view to be updated.</DL><H2><FONT COLOR="#000077"><B>Workshop</B></FONT></H2><P>The Workshop is designed to help you anticipate possible questions, review whatyou've learned, and begin thinking ahead to putting your knowledge into practice.The answers to the quiz are in Appendix B, "Quiz Answers."<H3><FONT COLOR="#000077"><B>Quiz</B></FONT></H3><DL> <DD>1. What are some differences between a form view and a dialog box?<BR> <BR> 2. What are the special requirements for dialog box resources used in a form view?<BR> <BR> 3. How do you size the frame of a form view so that it is the same size as its dialog box resource?<BR> <BR> 4. What is the difference between <TT>OnInitialUpdate</TT> and <TT>OnUpdate</TT>?<BR> <BR> 5. How do you prevent an MDI child window from being resized?<BR> <BR> 6. What function is called by a document class to notify views that the document has been changed?<BR> <BR> 7. What resources are identified through a shared resource identifier?<BR> <BR> 8. What view class enables you to use an edit control as a view?<BR> <BR> 9. What view class enables your view to have a large virtual area that is seen through a smaller scrolling viewport?<BR> <BR> 10. What class is used in an MDI application to associate a view class and a document class?</DL><H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3><DL> <DD>1. Because the <TT>CChildFrame</TT> class was modified to prevent resizing, the instances of the <TT>CDisplayView</TT> class cannot be resized. Modify DVTest so that display views can be resized and form views cannot be resized.<BR> <BR> 2. Modify the form view in DVTest so that it displays the number of items stored in the document.<FONT COLOR="#000077"></FONT></DL><CENTER><P><HR><A HREF="../ch22/ch22.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch24/ch24.htm"><IMGSRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR><BR><BR><IMG SRC="../button/corp.gif" WIDTH="284" HEIGHT="45" ALIGN="BOTTOM" ALT="Macmillan Computer Publishing USA"BORDER="0"></P><P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. Allrights reserved.</CENTER></BODY></HTML>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -