📄 ch23.htm
字号:
new interfaces:
<UL>
<LI><TT>OnInitialUpdate</TT>, called when the view is first created<BR>
<BR>
<LI><TT>OnUpdate</TT>, called when the document updates its views
</UL>
<P>To create a new view to add to the CDVTest project, follow these steps:
<DL>
<DD>1. Open ClassWizard.<BR>
<BR>
2. Press the button labeled Add Class and select the New option from the drop-down
menu.<BR>
<BR>
3. Use the values from Table 23.6 to fill in the Add Class dialog box.<BR>
<BR>
4. Click OK and close ClassWizard.
</DL>
<H4><FONT COLOR="#000077">Table 23.6. Values used to add the CDisplayView class.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Control</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Value</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Name</TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDisplayView</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Base Class</TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CView</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">OLE Automation</TD>
<TD ALIGN="LEFT" VALIGN="TOP">None</TD>
</TR>
</TABLE>
</P>
<P>ClassWizard adds the new view to the project and creates some default initialization
functions. However, the view class isn't useful until you do some additional work
to associate it with the document class and define how it displays information.</P>
<P>When you create a new view using ClassWizard, you must add functions to handle
the Document/View interfaces; they aren't automatically created as they are for views
created by AppWizard when a new project is created. Using ClassWizard, add two message-handling
functions to the <TT>CDisplayView</TT> class using the values from Table 23.7.
<H4><FONT COLOR="#000077">Table 23.7. New member functions for the CDisplayView class.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Class Name</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Object ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Message</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDisplayView</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDisplayView</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnInitialUpdate</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDisplayView</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CDisplayView</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnUpdate</TT></TD>
</TR>
</TABLE>
<H3><FONT COLOR="#000077"><B>Modifying the <TT>OnDraw</TT> Function</B></FONT></H3>
<P>As discussed earlier, when you complete it, the <TT>CDisplayView</TT> class will
list the names contained in the <TT>CDVTestDoc</TT> document class. Like other <TT>OnDraw</TT>
functions, <TT>CDisplayView::OnDraw</TT> retrieves a pointer to the document class
and collects information about the items to be displayed in the view. The source
code for <TT>CDisplayView::OnDraw</TT> is provided in Listing 23.5.
<H4><FONT COLOR="#000077">TYPE: Listing 23.5. Source code for CDisplayView::OnDraw.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CDisplayView::OnDraw(CDC* pDC)</TT>
<TT>{</TT>
<TT> CDVTestDoc* pDoc = (CDVTestDoc*)GetDocument();</TT>
<TT> ASSERT_VALID(pDoc);</TT>
<TT> // Calculate the space required for a single</TT>
<TT> // line of text, including the inter-line area.</TT>
<TT> TEXTMETRIC tm;</TT>
<TT> pDC->GetTextMetrics( &tm );</TT>
<TT> int nLineHeight = tm.tmHeight + tm.tmExternalLeading;</TT>
<TT> CPoint ptText( 0, 0 );</TT>
<TT> for( int nIndex = 0; nIndex < pDoc->GetCount(); nIndex++ )</TT>
<TT> {</TT>
<TT> CString szName = pDoc->GetName( nIndex );</TT>
<TT> pDC->TextOut( ptText.x, ptText.y, szName );</TT>
<TT> ptText.y += nLineHeight;</TT>
<TT> }</TT>
</FONT></PRE>
<P><TT>}</TT> Notice that the <TT>OnDraw</TT> function used in <TT>CDisplayView</TT>
is the same as the <TT>CDVTestView::OnDraw</TT> function in Listing 9.14. Although
that view had exclusive access to its document, the same source code works when the
document is shared by multiple views. You add the code for the <TT>OnInitialUpdate</TT>
and <TT>OnUpdate</TT> member functions later, in the section "Adding the <TT>OnInitialUpdate</TT>
and <TT>OnUpdate</TT> Member Functions."</P>
<P>Because the <TT>OnDraw</TT> function must access the <TT>CDVTestDoc</TT> class,
add this <TT>#include</TT> directive for the <TT>CDVTestDoc</TT> class:</P>
<PRE><FONT COLOR="#0066FF"><TT>#include "DVTestDoc.h"</TT>
</FONT></PRE>
<P>Add this include statement after the other include statements near the beginning
of the <TT>DisplayView.cpp</TT> source file.
<H3><FONT COLOR="#000077"><B>Creating and Maintaining Multiple Document Templates</B></FONT></H3>
<P>When a single view and document are associated with each other, a <TT>CMultiDocTemplate</TT>
is passed to the MFC framework, and the application never sees it again. When multiple
views are created, the application class must keep track of the document templates
used for the document and view associations. The application class stores these pointers
and provides them to the <TT>CMainFrame</TT> class when needed. Add the source code
in Listing 23.6 to the implementation section of the <TT>CDVTestApp</TT> class declaration.
These additions declare two member variables that are used to cache pointers to the
document templates and two member functions used to get access to the pointers.
<H4><FONT COLOR="#000077">TYPE: Listing 23.6. Changes to the CDVTestApp class declaration.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>public:</TT>
<TT> CDocTemplate* GetDisplayTemplate() const;</TT>
<TT> CDocTemplate* GetFormTemplate() const;</TT>
<TT>private:</TT>
<TT> CDocTemplate* m_pDisplayTemplate;</TT>
</FONT></PRE>
<P><TT>CDocTemplate* m_pFormTemplate;</TT> The two document template pointers are
set during the <TT>CDVTestApp::InitInstance</TT> member function. Instead of creating
a <TT>CMultiDocTemplate</TT> object and passing it immediately to the <TT>AddDocTemplate</TT>
function, <TT>CMultiDocTemplate</TT> objects are created, and their pointers are
stored in the new member variables. Replace the current code used to create the document
templates in <TT>CDVTestApp::InitInstance</TT> with the source code provided in Listing
23.7.
<H4><FONT COLOR="#000077">TYPE: Listing 23.7. Changes to CDVTestApp::InitInstance
creating two document templates.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>m_pFormTemplate = new CMultiDocTemplate(</TT>
<TT> IDR_DVTESTTYPE,</TT>
<TT> RUNTIME_CLASS(CDVTestDoc),</TT>
<TT> RUNTIME_CLASS(CChildFrame),</TT>
<TT> RUNTIME_CLASS(CFormTest) );</TT>
<TT> m_pDisplayTemplate = new CMultiDocTemplate(</TT>
<TT> IDR_DISPLAYTYPE,</TT>
<TT> RUNTIME_CLASS(CDVTestDoc),</TT>
<TT> RUNTIME_CLASS(CChildFrame),</TT>
<TT> RUNTIME_CLASS(CDisplayView) );</TT>
</FONT></PRE>
<P><TT>AddDocTemplate( m_pFormTemplate );</TT> Each of the document templates created
in Listing 23.7 describes views associated with the <TT>CDVTestDoc</TT> class. One
of the document templates uses the <TT>CFormTest</TT> class from earlier this hour,
whereas the other template uses the <TT>CDisplayView</TT> class. Because this class
is new to the <TT>DVTest.cpp</TT> file, add an <TT>#include</TT> directive for the
<TT>CDisplayView</TT> class:</P>
<PRE><FONT COLOR="#0066FF"><TT>#include "DisplayView.h"</TT>
</FONT></PRE>
<P>Listing 23.8 contains the source for the new <TT>CDVTestApp</TT> functions that
return pointers to the <TT>CDocTemplate</TT> pointers created during <TT>CDVTest::OnInitInstance</TT>.
The <TT>CMainFrame</TT> class uses these pointers when creating new views. Add the
source code in Listing 23.8 to the <TT>DVTest.cpp</TT> file.
<H4><FONT COLOR="#000077">TYPE: Listing 23.8. CDVTestApp functions used to return
pointers to the document templates.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>CDocTemplate* CDVTestApp::GetDisplayTemplate() const</TT>
<TT>{</TT>
<TT> return m_pDisplayTemplate;</TT>
<TT>}</TT>
<TT>CDocTemplate* CDVTestApp::GetFormTemplate() const</TT>
<TT>{</TT>
<TT> return m_pFormTemplate;</TT>
<TT>}</TT></FONT></PRE>
<H3><FONT COLOR="#000077"><B>Adding Shared Resources</B></FONT></H3>
<P>One of the parameters used when creating a document template is the <I>shared-resource
identifier</I>. This resource ID is used to identify several different resources
used by the view:
<UL>
<LI>A resource string; specifying the file type, file extension, and document name
for the document template<BR>
<BR>
<LI>An icon for the view<BR>
<BR>
<LI>A menu used when the view is active
</UL>
<P>Each of these resources must be created for a new view. Although sharing an existing
resource ID is possible, providing at least a customized icon for the new view is
a much better practice. The name of the current shared resource ID is <TT>IDR_DVTESTTYPE</TT>;
for the new view, you will create a shared resource ID named <TT>IDR_DISPLAYTYPE</TT>.
<H4><FONT COLOR="#000077">Creating a Menu for the New View</FONT></H4>
<P>Click the <TT>IDR_DVTESTTYPE</TT> menu item, and use Copy and Paste to create
a new menu item. Rename the new item as <TT>IDR_DISPLAYTYPE</TT>; you can open the
property page by right-clicking the icon and selecting Properties from the pop-up
menu.
<H4><FONT COLOR="#000077">Creating an Icon for the New View</FONT></H4>
<P>Create an <TT>IDR_DISPLAYTYPE</TT> icon by opening the Icon folder on the resource
tree. Create a copy of the existing <TT>IDR_DVTESTTYPE</TT> icon by using the Edit
menu to copy and paste the icon, or by pressing Ctrl+C, then Ctrl+V.
<H4><FONT COLOR="#000077">Using a Resource String</FONT></H4>
<P>The resource string for each document template is stored in a String Table resource.
Go to the ResourceView window and click the String Table icon. In the DVTest project,
the resource string for the current document template is stored under the name <TT>IDR_DVTESTTYPE</TT>.
You can add a new string to the String Table by pressing the Insert key on the keyboard.
Create a new string resource named <TT>IDR_DISPLAYTYPE</TT> with the following string
value:</P>
<PRE><FONT COLOR="#0066FF"><TT>\nDVTest\n\n\n\nDVTest.Document\nDVTest Document</TT>
</FONT></PRE>
<P>The contents of the resource string are split into seven sections, and each section
is separated by <TT>\n</TT>. Each of the seven sections has a particular purpose,
as shown in Table 23.8.
<H4><FONT COLOR="#000077">Table 23.8. Values for subsections of resource strings
used in DVTest.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Section</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDR_DVTEST</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDR_DISPLAYTYPE</TT></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Title</TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Document Name</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">New File Name</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest</TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Filter Name</TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Filter Extension</TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
<TD ALIGN="LEFT" VALIGN="TOP"></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Type ID</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest.Document</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest.Document</TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP">Type Name</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest Document</TD>
<TD ALIGN="LEFT" VALIGN="TOP">DVTest Document</TD>
</TR>
</TABLE>
</P>
<P>The new resource string is almost the same as the original string. The only difference
is that there is no entry for the section marked New File Name. This is a clue to
the MFC framework that this document template is not used to create new documents;
instead, it is used only to open a new view on an existing document. You don't have
to worry too much about the purpose of each segment. The MFC framework uses these
segments when registering your application with Windows, and when opening new views
and documents.
<H3><FONT COLOR="#000077"><B>Adding Menu Items for New Views</B></FONT></H3>
<P>You add new views by selecting a menu item from the Window menu. Add the menu
items using the Developer Studio resource editor, as you learned in Hour 10, "Menus."
Use the values from Table 23.9 to add the menu items to the <TT>IDR_DISPLAYTYPE</TT>
and <TT>IDR_DVTESTTYPE</TT> menus, and to add message-handling functions to the <TT>CMainFrame</TT>
class.
<H4><FONT COLOR="#000077">Table 23.9. New member functions for the CMainFrame class.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Menu ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Caption</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Event</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Function Name</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>ID_WINDOW_DISPLAY</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP">&Display View</TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>COMMAND</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnWindowDisplay</TT></TD>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -