📄 ch09.htm
字号:
<HTML>
<HEAD>
<TITLE>Special Edition Using Visual C++ 5 - Chapter 9</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H2><B>Chapter </B><B>9</B></H2>
<H2><A ID="I1" NAME="I1"><B>Building a Complete Application: ShowString</B></A></H2>
<hr>
<ul>
<li> <B>The ShowString application</B></P>
<P> A variation on the traditional C "Hello, world!" program, ShowString displays a string and allows the user to control the display.</P>
<li> <B>Adding menu items</B></P>
<P> You use the ResourceView of Developer Studio to add a menu of items to an application, or to add an item to a menu.</P>
<li> <B>Adding a dialog box</B></P>
<P> Building dialog boxes in Developer Studio is what earned Visual C++ its name. Drag, drop, and click your way to a custom interface.</P>
<li> <B>Connecting menus to code</B></P>
<P> ClassWizard simplifies message handling and makes menus intuitive.</P>
<li> <B>Connecting the dialog box to code</B></P>
<P> ClassWizard handles dialog boxes almost as easily as it does menus.</P>
<li> <B>Changing the appearance of the view</B></P>
<P> The control over the display is added in this section. Users can set the color and centering of the text after you change the dialog box and drawing code.</P>
</ul>
<P>In this chapter you pull together the concepts demonstrated in previous chapters to create an application that really does something. You add a menu, a menu item, a dialog box, and persistence to an application that draws output based on user settings.
In subsequent chapters this application serves as a base for more advanced work.</P>
<H3><A ID="I2" NAME="I2"><B>Building an Application That Displays a String</B></A></H3>
<P>In this chapter you see how to develop an application very much like the traditional "Hello, world!" of C programming. The application simply displays a text string in the main window. The <I>document </I>(what you save in a file) contains
the string and a few settings. There is a new menu item to bring up a dialog box to change the string and the settings, which control the appearance of the string. This is a deliberately simple application so that the concepts of adding menu items and
adding dialogs are not obscured by trying to understand the actual brains of the application. So bring up Developer Studio and follow along.</P>
<P><A ID="I3" NAME="I3"><B>Creating an Empty Shell with AppWizard</B></A></P>
<P>First, use AppWizard to create the starter application. (<A HREF="index01.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index01.htm" target="text">Chapter 1</A>, "Building Your First Application," covers AppWizard and creating starter applications.) Choose <U>F</U>ile, <U>N</U>ew and the Project
tab. Name the project ShowString so that your class names will match those shown throughout this chapter. Click OK.</P>
<P>In Step 1 of AppWizard, it doesn't matter much whether you choose SDI or MDI, but MDI will allow you to see for yourself how little effort is required to have multiple documents open at once, so choose MDI. Choose US English, and then click
<U>N</U>ext.</P>
<P>The ShowString application needs no database support and no compound document support, so click <U>N</U>ext on Step 2 and Step 3 without changing anything. In AppWizard's Step 4 dialog box, set to work selecting a docking toolbar, status bar, printing
and print preview, context-sensitive help, and 3-D controls, and then click <U>N</U>ext. Choose source-file comments and shared DLL, and then click <U>N</U>ext. The class names and file names are all fine, so click <U>F</U>inish. Figure 9.1 shows the final
confirmation dialog box. Click OK.</P>
<A HREF="Kfigs01.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch09/Kfigs01.gif"><b>Fig. 9.1</b></A>
<P><I>AppWizard summarizes the design choices for ShowString.</I></P>
<P><A ID="I4" NAME="I4"><B>Displaying a String</B></A></P>
<P>The ShowString application displays a string that will be kept in the document. You need to add a member variable to the document class, <font color="#008000">CShowStringDoc</font>, and add loading and saving code to the <font
color="#008000">Serialize()</font> function. You can initialize the string by adding code to <font color="#008000">OnNewDocument()</font> for the document and, in order to actually display it, override <font color="#008000">OnDraw()</font> for the view.
Documents and views were introduced in <A HREF="index06.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index06.htm" target="text">Chapter 6</A>, "Documents and Views."</P>
<P><A ID="I5" NAME="I5">Member Variable and Serialization</A></P>
<P>Add a private variable to the document and a public function to get the value, by adding these lines to <font color="#008000">ShowStringDoc.h</font>:</P>
<pre><font color="#008000">private:</font></pre>
<pre><font color="#008000"> CString string;</font></pre>
<pre><font color="#008000">public:</font></pre>
<pre><font color="#008000"> CString GetString() {return string;}</font></pre>
<P>The inline function gives other parts of your application a copy of the string to use whenever necessary but makes it impossible for other parts to change the string.</P>
<P>Next, change the skeleton <font color="#008000">CShowStringDoc::Serialize()</font> function provided by AppWizard to look like Listing 9.1. (Expand <font color="#008000">CShowStringDoc</font> in ClassView and double-click <font
color="#008000">Serialize()</font> to edit the code.) Since you used the MFC <font color="#008000">CString</font> class, the archive has operators <font color="#008000"><<</font> and <font color="#008000">>></font> already defined, so this is a
simple function to write. It fills the archive from the string when you are saving the document and fills the string from the archive when you are loading the document from a file. <A HREF="index09.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index09.htm" target="text">Chapter 9</A>, "Persistence and
File I/O," introduces serialization.</P>
<p><img src="cd_rom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/cd_rom.gif" hspace=10>
<P><I>Listing </I><I>9</I><I>.1—</I>SHOWSTRINGDOC.CPP<I>—</I><font color="#008000">CShowStringDoc::Serialize()</font></pre>
<pre><font color="#008000">void CShowStringDoc::Serialize(CArchive& ar)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> if (ar.IsStoring())</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> ar << string;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000"> else</font></pre>
<pre><font color="#008000"> {</font></pre>
<pre><font color="#008000"> ar >> string;</font></pre>
<pre><font color="#008000"> }</font></pre>
<pre><font color="#008000">}</font></pre>
<P><A ID="I6" NAME="I6">Initializing the String</A></P>
<P>Whenever a new document is created, you want your application to initialize <font color="#008000">string</font> to "Hello, world!" A new document is created when the user chooses <U>F</U>ile, <U>N</U>ew. This message is caught by <font
color="#008000">CShowStringApp</font> (the message map is shown in Listing 9.2) and handled by <font color="#008000">CWinApp::OnFileNew()</font>. (Message maps and message handlers and discussed in <A HREF="index04.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index04.htm" target="text">Chapter 4</A>,
"Messages and Commands.") Starter applications generated by AppWizard call <font color="#008000">OnFileNew()</font>_to create a blank document when they run. <font color="#008000">OnFileNew()</font> calls the document's <font
color="#008000">OnNewDocument()</font>, which actually initializes the member variables of the document.</P>
<p><img src="cd_rom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/cd_rom.gif" hspace=10>
<P><I>Listing </I><I>9</I><I>.2—</I>SHOWSTRING.CPP<I>—Message Map</I></P>
<pre><font color="#008000">BEGIN_MESSAGE_MAP(CShowStringApp, CWinApp)</font></pre>
<pre><font color="#008000"> //{{AFX_MSG_MAP(CShowStringApp)</font></pre>
<pre><font color="#008000"> ON_COMMAND(ID_APP_ABOUT, OnAppAbout)</font></pre>
<pre><font color="#008000"> // NOTE - the ClassWizard will add and remove mapping macros here.</font></pre>
<pre><font color="#008000"> // DO NOT EDIT what you see in these blocks of generated code!</font></pre>
<pre><font color="#008000"> //}}AFX_MSG_MAP</font></pre>
<pre><font color="#008000"> // Standard file based document commands</font></pre>
<pre><font color="#008000"> ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)</font></pre>
<pre><font color="#008000"> ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)</font></pre>
<pre><font color="#008000"> // Standard print setup command</font></pre>
<pre><font color="#008000"> ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)</font></pre>
<pre><font color="#008000">END_MESSAGE_MAP()</font></pre>
<P>AppWizard gives you the simple <font color="#008000">OnNewDocument()</font> shown in Listing 9.3.</P>
<p><img src="cd_rom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/cd_rom.gif" hspace=10>
<P><I>Listing </I><I>9</I><I>.3—</I>SHOWSTRINGDOC.CPP<I>—</I>CShowStringDoc::OnNewDocument()</P>
<pre><font color="#008000">BOOL CShowStringDoc::OnNewDocument()</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> if (!CDocument::OnNewDocument())</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> // TODO: add reinitialization code here</font></pre>
<pre><font color="#008000"> // (SDI documents will reuse this document)</font></pre>
<pre><font color="#008000"> return TRUE;</font></pre>
<pre><font color="#008000">}</font></pre>
<P>Take away the comments and add this line in their place:</P>
<pre><font color="#008000"> string = "Hello, world!";</font></pre>
<P>(What else could it say, after all?) Leave the call to <font color="#008000">CDocument::OnNewDocument()</font> because that will handle all the other work involved in making a new document.</P>
<P><A ID="I7" NAME="I7">Getting the String on the Screen</A></P>
<P>As you learned in <A HREF="index07.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index07.htm" target="text">Chapter 7</A>, "Drawing on the Screen," a view's <font color="#008000">OnDraw()</font> function is called whenever that view needs to be drawn, such as when your application is first
started, resized, or restored, or when a window that had been covering it is taken away. AppWizard has provided a skeleton, shown in Listing 9.4. To edit this function, expand <font color="#008000">CShowStringView</font> in ClassView and then double-click
<font color="#008000">OnDraw()</font>.</P>
<p><img src="cd_rom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/cd_rom.gif" hspace=10>
<P><I>Listing </I><I>9</I><I>.4—</I>SHOWSTRINGVIEW.CPP<I>—</I>CShowStringView::OnDraw()</P>
<pre><font color="#008000">void CShowStringView::OnDraw(CDC* pDC)</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> CShowStringDoc* pDoc = GetDocument();</font></pre>
<pre><font color="#008000"> ASSERT_VALID(pDoc);</font></pre>
<pre><font color="#008000"> // TODO: add draw code for native data here</font></pre>
<pre><font color="#008000">}</font></pre>
<p><font color="#008000">OnDraw()</font> takes a pointer to a device context, as discussed in <A HREF="index07.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index07.htm" target="text">Chapter 7</A>, "Drawing on the Screen." The device context class, <font color="#008000">CDC</font>, has a member
function called <font color="#008000">DrawText()</font> that draws text on the screen. It is declared like this:</P>
<pre><font color="#008000">int DrawText( const CString& </font><I><font color="#008000">str</font></I><font color="#008000">, LPRECT </font><I><font color="#008000">lpRect</font></I><font color="#008000">, UINT </font><I><font
color="#008000">nFormat</font></I><font color="#008000"> )</font></pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -