⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch08.htm

📁 VC使用大全。里面集合了VC使用的各种使用技巧。非常有用。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
string, as shown in Listing 8.5.</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 8.5&#151;One Possible Way to Save the New Class's Strings</I></P>

<pre><font color="#008000">void CFileDoc::Serialize(CArchive&amp; 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 &lt;&lt; m_messages.m_message1;</font></pre>

<pre><font color="#008000">        ar &lt;&lt; m_messages.m_message2;</font></pre>

<pre><font color="#008000">        ar &lt;&lt; m_messages.m_message3;</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 &gt;&gt; m_messages.m_message1;</font></pre>

<pre><font color="#008000">        ar &gt;&gt; m_messages.m_message2;</font></pre>

<pre><font color="#008000">        ar &gt;&gt; m_messages.m_message3;</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">}</font></pre>

<P>You can write the code in Listing 8.5 only if the three member variables of the <font color="#008000">CMessages</font> class are public and if you know the implementation of the class itself. Later, if the class is changed in any way, this code also 
has to be changed. It's more object-oriented to delegate the work of storing and loading to the <font color="#008000">CMessages</font> class itself. This requires some preparation. The basic steps to create a class that can serialize its member variables 
are the following:</P>

<ol>

<li><P> Derive the class from <font color="#008000">CObject</font>.</P>

<li><P> Place the <font color="#008000">DECLARE_SERIAL()</font> macro in the class's declaration.</P>

<li><P> Place the <font color="#008000">IMPLEMENT_SERIAL()</font> macro in the class's implementation.</P>

<li><P> Override the <font color="#008000">Serialize()</font> function in the class.</P>

<li><P> Provide an empty, default constructor for the class.</P>

</ol>

<P>In the following section, you explore an application that creates persistent objects exactly as described in the preceding steps.</P>

<P><A ID="I7" NAME="I7"><B>The File Demo 2 Application</B></A></P>

<P>The next sample application, File Demo 2, demonstrates the steps you take to create a class from which you can create persistent objects. When you run the application, you see the window shown in Figure 8.4. The program's window displays the three 
strings that make up the document's data. These three strings are contained in a custom class.</P>

<A HREF="Jfigs04.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch08/Jfigs04.gif"><b>Fig. 8.4</b></A>

<P><I>The three strings displayed in the window are data members of a custom class.</I></P>

<P>You can edit any of the three strings by choosing the <U>E</U>dit, <U>C</U>hange Messages command. When you do, the dialog box shown in Figure 8.5 appears. Type the new string or strings that you want to display in the window, and then click the OK 
button. The program displays the edited strings, and stores the new string values in the document object.</P>

<A HREF="Jfigs05.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch08/Jfigs05.gif"><b>Fig. 8.5</b></A>

<P><I>Use the Change Messages dialog box to edit the application's data.</I></P>

<P>The application's <U>F</U>ile menu contains the commands you need to save or load the contents of a document. If you save the changes you make before exiting the application, you can reload the document when you restart the application. In this case, 
unlike the first version of the program, the document class is using a persistent object&#151;an object that knows how to save and load its own state&#151;as the document's data.</P>

<P><A ID="I8" NAME="I8"><B>Looking at the CMessages Class</B></A></P>

<P>Before you can understand how the document class manages to save and load its contents successfully, you have to understand how the <font color="#008000">CMessages</font> class, of which the document class's <font color="#008000">m_messages</font> data 
member is an object, works. As you examine this class, you see how the aforementioned five steps for creating a persistent class have been implemented. Listing 8.6 shows the class's header file.</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 8.6&#151;</I>MESSAGES.H<I>&#151;The </I>CMessages<I> Class's Header File</I></P>

<pre><font color="#008000">// messages.h</font></pre>

<pre><font color="#008000">class CMessages : public CObject</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    DECLARE_SERIAL(CMessages)</font></pre>

<pre><font color="#008000">    CMessages(){};</font></pre>

<pre><font color="#008000">protected:</font></pre>

<pre><font color="#008000">    CString m_message1;</font></pre>

<pre><font color="#008000">    CString m_message2;</font></pre>

<pre><font color="#008000">    CString m_message3;</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">    void SetMessage(UINT msgNum, CString msg);</font></pre>

<pre><font color="#008000">    CString GetMessage(UINT msgNum);</font></pre>

<pre><font color="#008000">    void Serialize(CArchive&amp; ar);</font></pre>

<pre><font color="#008000">};</font></pre>

<P>First, notice that the <font color="#008000">CMessages</font> class is derived from MFC's <font color="#008000">CObject</font> class. Also, notice the <font color="#008000">DECLARE_SERIAL()</font> macro near the top of the class's declaration. This 
macro's single argument is the name of the class you're declaring. MFC uses this macro to provide the additional function and member variable declarations needed to implement object persistence.</P>

<P>Next, the class declares a default constructor that requires no arguments. This constructor is necessary because MFC needs to be able to create objects of the class when loading data from disk. If your class had no default constructor, MFC cannot 
create a blank object to fill from an archive.</P>

<P>After the default constructor comes the class's data members, which are three objects of the <font color="#008000">CString</font> class. Notice that they are protected member variables now. The public member functions are next. <font 
color="#008000">SetMessage()</font>, whose arguments are the index of the string to set and the string's new value, enables a program to change a data member. <font color="#008000">GetMessage()</font> is the complementary function, enabling a program to 
retrieve the current value of any of the strings. Its single argument is the number of the string to retrieve.</P>

<P>Finally, the class overrides the <font color="#008000">Serialize()</font> function, where all the data saving and loading takes place. The <font color="#008000">Serialize()</font> function is the heart of a persistent object, with each persistent class 
implementing it in a different way. Listing 8.7 is the class's implementation file, which defines the various member functions.</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 8.7&#151;</I>MESSAGES.CPP<I>&#151;The </I>CMessages<I> Class's Implementation </I><I>File</I></P>

<pre><font color="#008000">// messages.cpp</font></pre>

<pre><font color="#008000">#include &quot;stdafx.h&quot;</font></pre>

<pre><font color="#008000">#include &quot;messages.h&quot;</font></pre>

<pre><font color="#008000">IMPLEMENT_SERIAL(CMessages, CObject, 0)</font></pre>

<pre><font color="#008000">void CMessages::SetMessage(UINT msgNum, CString msg)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">     switch (msgNum)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">     case 1:</font></pre>

<pre><font color="#008000">          m_message1 = msg;</font></pre>

<pre><font color="#008000">          break;</font></pre>

<pre><font color="#008000">     case 2:</font></pre>

<pre><font color="#008000">        m_message2 = msg;</font></pre>

<pre><font color="#008000">          break; </font></pre>

<pre><font color="#008000">     case 3:</font></pre>

<pre><font color="#008000">        m_message3 = msg;</font></pre>

<pre><font color="#008000">          break;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">CString CMessages::GetMessage(UINT msgNum)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">   switch (msgNum)</font></pre>

<pre><font color="#008000">   {</font></pre>

<pre><font color="#008000">      case 1:</font></pre>

<pre><font color="#008000">         return m_message1;</font></pre>

<pre><font color="#008000">      case 2:</font></pre>

<pre><font color="#008000">         return m_message2;</font></pre>

<pre><font color="#008000">      case 3:</font></pre>

<pre><font color="#008000">         return m_message3;</font></pre>

<pre><font color="#008000">      default</font></pre>

<pre><font color="#008000">         return &quot;&quot;;</font></pre>

<pre><font color="#008000">   }</font></pre>

<pre><font color="#008000">}</font></pre>

<pre><font color="#008000">void CMessages::Serialize(CArchive&amp; ar)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">    CObject::Serialize(ar);</font></pre>

<pre><font color="#008000">    if (ar.IsStoring())</font></pre>

<pre><font color="#008000">    {</font></pre>

<pre><font color="#008000">        ar &lt;&lt; m_message1 &lt;&lt; m_message2 &lt;&lt; m_message3;</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 &gt;&gt; m_message1 &gt;&gt; m_message2 &gt;&gt; m_message3;</font></pre>

<pre><font color="#008000">    }</font></pre>

<pre><font color="#008000">}</font></pre>

<P>The <font color="#008000">IMPLEMENT_SERIAL()</font> macro is partner to the <font color="#008000">DECLARE_SERIAL()</font> macro, providing implementation for the functions that give the class its persistent capabilities. The macro's three arguments are 
the name of the class, the name of the immediate base class, and a schema number, which is like a version number. In most cases, you use 0 or 1 for the schema number.</P>

<P>There's nothing tricky about the <font color="#008000">SetMessage()</font> and <font color="#008000">GetMessage()</font> functions, which perform their assigned tasks straightforwardly. The <font color="#008000">Serialize()</font> function, however, 
may inspire a couple of questions. First, note that the first line of the body of the function calls the base class's <font color="#008000">Serialize()</font> function. This is a standard practice for many functions that override functions of a base class. 
In this case, the call to <font color="#008000">CObject::Serialize()</font> doesn't do much, since the <font color="#008000">CObject</font> class's <font color="#008000">Serialize()</font> function is empty. Still, calling the base class's <font 
color="#008000">Serialize()</font> function is a good habit to get into, because you may not always be working with classes derived directly from <font color="#008000">CObject</font>.</P>

<P>After calling the base class's version of the function, <font color="#008000">Serialize()</font> saves and loads its data in much the same way a document object does. Because the data members that must be serialized are <font 
color="#008000">CString</font> objects, the program can use the <font color="#008000">&gt;&gt;</font> and <font color="#008000">&lt;&lt;</font> operators to write the strings to the disk.</P>

<P><A ID="I9" NAME="I9"><B>Using the CMessages Class in the Program</B></A></P>

<P>Now that you know how the <font color="#008000">CMessages</font> class works, you can examine how it's used in the File Demo 2 application's document class. As you look over the document class, you see that the class uses the same steps to handle its 
data as the original File Demo application. The main difference is that it's now dealing with a custom class, rather than simple data types or classes defined by MFC. First, the object is declared in the document class's declaration, like this:</P>

<pre><font color="#008000">// Attributes</font></pre>

<pre><font color="#008000">public:</font></pre>

<pre><font color="#008000">    CMessages m_messages;</font></pre>

<P>Next, the program initializes the data object in the document class's <font color="#008000">OnNewDocument()</font> class, as seen in Listing 8.8.</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 8.8&#151;</I>FILE2DOC.CPP<I>&#151;Initializing the Data Object</I></P>

<pre><font color="#008000">BOOL CFile2Doc::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">    m_messages.SetMessage(1, &quot;Default Message 1&quot;);</font></pre>

<pre><font color="#008000">    m_messages.SetMessage(2, &quot;Default Message 2&quot;);</font></pre>

<pre><font color="#008000">    m_messages.SetMessage(3, &quot;Default Message 3&quot;);</font></pre>

<pre><font color="#008000">    return TRUE;</font></pre>

<pre><font color="#008000">}</font></pre>

<P>Because the document class cannot directly access the data object's data members, it must initialize each string by calling the <font color="#008000">CMessages</font> class's <font color="#008000">SetMessage()</font> member function. The view class 
must edit the data the same way, by calling the <font color="#008000">CMessages</font> object's member functions, as shown in Listing 8.9. The view class's <font color="#008000">OnDraw()</font> function also calls the <font 
color="#008000">GetMessage()</font> member function in order to access the <font color="#008000">CMessages</font> class's strings.</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -