📄 ch01.htm
字号:
<pre><font color="#008000">#ifndef test_h</font></pre>
<pre><font color="#008000">#include "test.h"</font></pre>
<pre><font color="#008000">#define test_h</font></pre>
<pre><font color="#008000">#endif</font></pre>
<P>This guarantees that the file test.h will never be included more than once. Including the same file more than once is quite likely in C++: imagine you define a class called Employee, and it uses a class called Manager. If the header files for both
Employee and Manager include, for example, BigCorp.h, you will get error messages from the compiler about "redefining" the symbols in BigCorp.h the second time it is included.</P>
<P>There is a problem with the approach above: if someone includes test.h but forgets to set test_h, your code will include test.h the second time. The solution is to put the test and the definition in the header file instead, so that test.h looks like
this:</P>
<pre><font color="#008000">#ifndef test_h</font></pre>
<pre><font color="#008000">... the entire header file</font></pre>
<pre><font color="#008000">#define test_h</font></pre>
<pre><font color="#008000">#endif</font></pre>
<P>All AppWizard did was generate a more complicated variable name than test_h (this wild name prevents problems when you have several files, in different folders and projects, with the same name) and use a slightly different syntax to check the variable.
The #pragma once code is also designed to prevent multiple definitions if this file is ever included twice.</P>
<P>The actual "meat" of the file is the definition of the class <font color="#008000">CFirstSDIApp</font>. This class inherits from <font color="#008000">CWinApp</font>, an MFC class that provides most of the functionality you need. AppWizard
has generated some functions for this class that override the ones inherited from the base class. The section of code that begins <font color="#008000">//Overrides</font> is for virtual function overrides. AppWizard generated the odd-looking comments that
surround the declaration of <font color="#008000">InitInstance()</font>: they will be used by ClassWizard to simplify the job of adding other overrides later if they are necessary. The next section of code is a message map and declares there is a function
called OnAppAbout. You can learn all about message maps 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."</P>
<P>AppWizard generated the code for the CFirstSDIApp constructor, InitInstance(), and OnAppAbout() in the file firstsdi.cpp. Here's the constructor, which initializes a CFirstSDIApp object as it is created:</P>
<pre><font color="#008000">CFirstSDIApp::CFirstSDIApp()</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> // TODO: add construction code here,</font></pre>
<pre><font color="#008000"> // Place all significant initialization in InitInstance</font></pre>
<pre><font color="#008000">}</font></pre>
<P>This is a typical Microsoft constructor. Because constructors don't return values, there's no easy way to indicate that there has been a problem with the initialization. There are several different ways to deal with this; Microsoft's approach is a
two-stage initialization, with a separate initializing function so that construction does no initialization . For an application, that function is called <font color="#008000">InitInstance()</font>, shown in Listing 1.2.</P>
<P><I>Listing 1.2—CFirstSDIApp::InitInstance()</I></P>
<pre><font color="#008000">BOOL CFirstSDIApp::InitInstance()</font></pre>
<pre><font color="#008000">{</font></pre>
<pre><font color="#008000"> AfxEnableControlContainer();</font></pre>
<pre><font color="#008000"> // Standard initialization</font></pre>
<pre><font color="#008000"> // If you are not using these features and wish to reduce the size</font></pre>
<pre><font color="#008000"> // of your final executable, you should remove from the following</font></pre>
<pre><font color="#008000"> // the specific initialization routines you do not need.</font></pre>
<pre><font color="#008000">#ifdef _AFXDLL</font></pre>
<pre><font color="#008000"> Enable3dControls(); // Call this when using MFC in a shared DLL</font></pre>
<pre><font color="#008000">#else</font></pre>
<pre><font color="#008000">> Enable3dControlsStatic(); // Call this when linking to MFC statically</font></pre>
<pre><font color="#008000">#endif</font></pre>
<pre><font color="#008000"> // Change the registry key under which our settings are stored.</font></pre>
<pre><font color="#008000"> // You should modify this string to be something appropriate</font></pre>
<pre><font color="#008000"> // such as the name of your company or organization.</font></pre>
<pre><font color="#008000"> SetRegistryKey(_T("Local AppWizard-Generated Applications"));</font></pre>
<pre><font color="#008000"> LoadStdProfileSettings(); // Load standard INI file options (including MRU)</font></pre>
<pre><font color="#008000"> // Register the application's document templates. Document templates</font></pre>
<pre><font color="#008000"> // serve as the connection between documents, frame windows and views.</font></pre>
<pre><font color="#008000"> CSingleDocTemplate* pDocTemplate;</font></pre>
<pre><font color="#008000"> pDocTemplate = new CSingleDocTemplate(</font></pre>
<pre><font color="#008000"> IDR_MAINFRAME,</font></pre>
<pre><font color="#008000"> RUNTIME_CLASS(CFirstSDIDoc),</font></pre>
<pre><font color="#008000"> RUNTIME_CLASS(CMainFrame), // main SDI frame window</font></pre>
<pre><font color="#008000"> RUNTIME_CLASS(CFirstSDIView));</font></pre>></P>
<pre><font color="#008000"> AddDocTemplate(pDocTemplate);</font></pre>
<pre><font color="#008000"> // Parse command line for standard shell commands, DDE, file open</font></pre>
<pre><font color="#008000"> CCommandLineInfo cmdInfo;</font></pre>
<pre><font color="#008000"> ParseCommandLine(cmdInfo);</font></pre>
<pre><font color="#008000"> // Dispatch commands specified on the command line</font></pre>
<pre><font color="#008000"> if (!ProcessShellCommand(cmdInfo))</font></pre>
<pre><font color="#008000"> return FALSE;</font></pre>
<pre><font color="#008000"> // The one and only window has been initialized, so show and update it.</font></pre>
<pre><font color="#008000"> m_pMainWnd->ShowWindow(SW_SHOW);</font></pre>
<pre><font color="#008000"> m_pMainWnd->UpdateWindow();</font></pre>
<pre><font color="#008000"> return TRUE;</font></pre>
<pre><font color="#008000">}</font></pre>
<P>InitInstance gets applications ready to go. This one starts by enabling the application to contain ActiveX controls with a call to AfxEnableControlContainer(), then turns on 3-D controls. It then sets up the Registry key under which this application
will be registered. (The Registry is introduced in <A HREF="index08.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index08.htm" target="text">Chapter 8</A>, "Persistence and File I/O." If you've never heard of it before, you can ignore it for now.)</P>
<p><font color="#008000">InitInstance()</font> goes on to register single document templates, which is what makes this an SDI application. Documents, views, frames, and document templates are all discussed in <A HREF="index05.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index05.htm" target="text">Chapter
5</A>, "Documents and Views."</P>
<P>Following the comment about parsing the command line, <font color="#008000">InitInstance()</font> sets up an empty <font color="#008000">CCommandLineInfo</font> object to hold any parameters that may have been passed to the application when it was run,
and calls <font color="#008000">ParseCommandLine()</font> to fill that. Finally, it calls <font color="#008000">ProcessShellCommand()</font> to do whatever those parameters requested. This means your application can support command line parameters to let
users save time and effort, without effort on your part. For example, if the user types at the command line <font color="#008000">FirstSDI fooble</font> then the application starts and opens the file called fooble. The command line parameters that <font
color="#008000">ProcessShellCommand()</font> supports are the following:</P>
<TABLE BORDER>
<TR>
<TD>
<P><B>Parameter</B></P>
<TD>
<P><B>Action</B></P>
<TR>
<TD>
<P>none</P>
<TD>
<P>Start app and open new file.</P>
<TR>
<TD>
<pre><font color="#008000">Filename</font></pre>
<TD>
<P>Start app and open file.</P>
<TR>
<TD>
<pre><font color="#008000">/p filename</font></pre>
<TD>
<P>Start app and print file to default printer.</P>
<TR>
<TD>
<pre><font color="#008000">/pt filename printer</font></pre>
<TD>
<P>Start app and print file to the </P>
<TR>
<TD>
<pre><font color="#008000">driver port</font></pre>
<TD>
<P>specified printer.</P>
<TR>
<TD>
<pre><font color="#008000">/dde</font></pre>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -