📄 ch13.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><HTML><HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1"><SCRIPT LANGUAGE="JavaScript"><!--function popUp(pPage) { var fullURL = document.location; var textURL = fullURL.toString(); var URLlen = textURL.length; var lenMinusPage = textURL.lastIndexOf("/"); lenMinusPage += 1; var fullPath = textURL.substring(0,lenMinusPage); popUpWin = window.open('','popWin','resizable=yes,scrollbars=no,width=525,height=394'); figDoc= popUpWin.document; zhtm= '<HTML><HEAD><TITLE>' + pPage + '</TITLE>'; zhtm += '</head>'; zhtm += '<BODY bgcolor="#FFFFFF">'; zhtm += '<IMG SRC="' + fullPath + pPage + '">'; zhtm += '<P><B>' + pPage + '</B>'; zhtm += '</BODY></HTML>'; window.popUpWin.document.write(zhtm); window.popUpWin.document.close(); // Johnny Jackson 4/28/98 }//--> </SCRIPT><link rel="stylesheet" href="/includes/stylesheets/ebooks.css"> <META NAME="GENERATOR" Content="Symantec Visual Page Mac 1.1.1"> <TITLE>Teach Yourself Visual C++ 6 in 21 Days -- Ch 13 -- Saving and Restoring Work--File Access</TITLE></HEAD><BODY TEXT="#000000" BGCOLOR="#FFFFFF"><H1 ALIGN="CENTER"><IMG SRC="../button/sams.gif" WIDTH="171" HEIGHT="66" ALIGN="BOTTOM"BORDER="0"><BR>Teach Yourself Visual C++ 6 in 21 Days</H1><CENTER><P><A HREF="../ch12/ch12.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch14/ch14.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> <HR></CENTER><H1 ALIGN="CENTER">- 13 -<BR>Saving and Restoring Work--File Access</H1><H1></H1><UL> <LI><A HREF="#Heading1">Serialization</A> <UL> <LI><A HREF="#Heading2">The CArchive and CFile Classes</A> <LI><A HREF="#Heading3">The Serialize Function</A> <LI><A HREF="#Heading4">Making Objects Serializable</A> <LI><A HREF="#Heading5">Listing 13.3. Including the IMPLEMENT_SERIAL macro in the class implementation.</A> </UL> <LI><A HREF="#Heading6">Implementing a Serializable Class</A> <UL> <LI><A HREF="#Heading7">Creating a Serialized Application</A> <LI><A HREF="#Heading8">Creating a Serializable Class</A> <LI><A HREF="#Heading9">Building Support in the Document Class</A> <LI><A HREF="#Heading10">Adding Navigating and Editing Support in the View Class</A> </UL> <LI><A HREF="#Heading11">Summary</A> <LI><A HREF="#Heading12">Q&A</A> <LI><A HREF="#Heading13">Workshop</A> <UL> <LI><A HREF="#Heading14">Quiz</A> </UL></UL><P><HR SIZE="4"><BR>Most applications provide the user the option of saving what has been created. Thecreation can be a word-processing document, a spreadsheet, a drawing, or a set ofdata records. Today, you will explore how Visual C++ provides you with the meansto implement this functionality easily. Today, you will learn</P><P><UL> <LI>How Visual C++ uses C++ streams to save information about your application <P> <LI>How to store your application data in binary files <P> <LI>How to make your application objects serializable <P> <LI>How you can store variables of differing data types into a single file</UL><H2><A NAME="Heading1"></A>Serialization</H2><P>There are two parts of serialization. When application data is stored on the systemdrive in the form of a file, it is called serialization. When the application stateis restored from the file, it is called deserialization. The combination of thesetwo parts makes up the serialization of application objects in Visual C++.</P><P><H3><A NAME="Heading2"></A>The CArchive and CFile Classes</H3><P>Serialization in Visual C++ applications is accomplished through the CArchiveclass. The CArchive class is designed to act as an input/output (I/O) stream fora CFile object, as shown in Figure 13.1. It uses C++ streams to enable efficientdata flow to and from the file that is the storage of the application data. The CArchiveclass cannot exist without a CFile class object to which it is attached.</P><P><A HREF="javascript:popUp('13fig01.gif')"><B>FIGURE 13.1.</B></A><B> </B><I>TheCArchive class stores application data in a CFile object.</I></P><P>The CArchive class can store data in a number of types of files, all of whichare descendants of the CFile class. By default, the AppWizard includes all the functionalityto create and open regular CFile objects for use with CArchive. If you want or needto work with one of these other file types, you might need to add additional codeto your application to enable the use of these different file types.</P><P><H3><A NAME="Heading3"></A>The Serialize Function</H3><P>The CArchive class is used in the Serialize function on the document and dataobjects in Visual C++ applications. When an application is reading or writing a file,the document object's Serialize function is called, passing the CArchive object thatis used to write to or read from the file. In the Serialize function, the typicallogic to follow is to determine whether the archive is being written to or read fromby calling the CArchive IsStoring or IsLoading functions. The return value from eitherof these two functions determines if your application needs to be writing to or readingfrom the CArchive class's I/O stream. A typical Serialize function in the view classlooks like Listing 13.1.</P><P><H4>LISTING 13.1. A TYPICAL Serialize FUNCTION.</H4><PRE> 1: void CAppDoc::Serialize(CArchive& ar) 2: { 3: // Is the archive being written to? 4: if (ar.IsStoring()) 5: { 6: // Yes, write my variable 7: ar << m_MyVar; 8: } 9: else10: {11: // No, read my variable12: ar >> m_MyVar;13: }14: }</PRE><P>You can place a Serialize function in any classes you create so that you can calltheir Serialize function from the document Serialize function. If you place yourcustom objects into an object array, such as the CObArray that you used in your drawingapplication for the past three days, you can call the array's Serialize functionfrom the document's Serialize function. The object array will, in turn, call theSerialize function of any objects that have been stored in the array.</P><P><H3><A NAME="Heading4"></A>Making Objects Serializable</H3><P>When you created the CLine class on Day 10, "Creating Single Document InterfaceApplications," you had to add two macros before you could save and restore yourdrawings. These two macros, DECLARE_SERIAL and IMPLEMENT_SERIAL, include functionalityin your classes that are necessary for the Serialize function to work correctly.</P><P><H4>Including the DECLARE_SERIAL Macro</H4><P>You must include the DECLARE_SERIAL macro in your class declaration, as shownin Listing 13.2. The DECLARE_SERIAL macro takes a single argument, the class name.This macro automatically adds to your class some standard function and operator declarationsthat are necessary for serialization to work correctly.</P><P><H4>LISTING 13.2. INCLUDING THE DECLARE_SERIAL MACRO IN THE CLASS DECLARATION.</H4><PRE>1: class CMyClass : public CObject2: {3: DECLARE_SERIAL (CMyClass)4: public:5: virtual void Serialize(CArchive &ar);6: CMyClass();7: virtual ~CMyClass();</PRE><PRE>8: };</PRE><P><H4>Including the IMPLEMENT_SERIAL Macro</H4><P>You need to add the IMPLEMENT_SERIAL macro to the implementation of your class.This macro needs to appear outside any other class functions because it adds thecode for the class functions that were declared with the DECLARE_SERIAL macro.</P><P>The IMPLEMENT_SERIAL macro takes three arguments. The first argument is the classname, as in the DECLARE_SERIAL macro. The second argument is the name of the baseclass, from which your class is inherited. The third argument is a version numberthat can be used to determine whether a file is the correct version for reading intoyour application. The version number, which must be a positive number, should beincremented each time the serialization method of the class is changed in any waythat alters the data being written to or read from a file. A typical usage of theIMPLEMENT_SERIAL macro is provided in Listing 13.3.</P><P><H3><A NAME="Heading5"></A>Listing 13.3. Including the IMPLEMENT_SERIAL macro inthe class implementation.</H3><PRE> 1: // MyClass.cpp: implementation of the CMyClass class. 2: // 3: ////////////////////////////////////////////////////////////////////// 4: 5: #include "stdafx.h" 6: #include "MyClass.h" 7: 8: #ifdef _DEBUG 9: #undef THIS_FILE10: static char THIS_FILE[]=__FILE__;11: #define new DEBUG_NEW12: #endif13: 14: IMPLEMENT_SERIAL (CMyClass, CObject, 1)15: //////////////////////////////////////////////////////////////////////16: // Construction/Destruction17: //////////////////////////////////////////////////////////////////////18: 19: CMyClass::CMyClass()20: {21: }22: 23: CMyClass::~CMyClass()24: {</PRE><PRE>25: }</PRE><P><H4>Defining the Serialize Function</H4><P>Along with the two macros, you need to include a Serialize function in your class.This function should be declared as a void function with a single argument (CArchive&ar), public access, and the virtual check box selected--producing the functiondeclaration in Listing 13.2. When you implement the Serialize function for your class,you typically use the same approach as that used in the document class, shown inListing 13.1, where you check to determine whether the file is being written to orread from.</P><P><H2><A NAME="Heading6"></A>Implementing a Serializable Class</H2><P>When you begin designing a new application, one of the first things you need todesign is how to store the data in the document class that your application willcreate and operate on. If you are creating a data-oriented application that collectssets of data from the user, much like a contact database application, how are yougoing to hold that data in the application memory? What if you are building a wordprocessor application--how are you going to hold the document being written in theapplication memory? Or a spreadsheet? Or a painting program? Or...you get the idea.</P><P>Once you determine how you are going to design the data structures on which yourapplication will operate, then you can determine how best to serialize your applicationand classes. If you are going to hold all data directly in the document class, allyou need to worry about is writing the data to and reading the data from the CArchiveobject in the document's Serialize function. If you are going to create your ownclass to hold your application data, you need to add the serialization functionalityto your data classes so that they can save and restore themselves.</P><P>In the application that you are going to build today, you will create a simple,flat-file database application that illustrates how you can combine a mixture ofdata types into a single data stream in the application serialization. Your applicationwill display a few fields of data, some of which are variable-length strings, andothers that are integer or boolean, and will save and restore them in a single datastream to and from the CArchive object.</P><P><H3><A NAME="Heading7"></A>Creating a Serialized Application</H3><P>You can create your own classes, which can also be serialized, for use in an SDIor MDI application. In short, any application that works with any sort of data, whethera database or a document, can be serialized. Now you will create a simple, flat-filedatabase application that you will serialize.</P><BLOCKQUOTE> <P><HR><STRONG>NOTE:</STRONG> A flat-file database is one of the original types of databases. It is a simple file-based database, with the records sequentially appended to the end of the previous record. It has none of the fancy relational functionality that is standard in most databases today. The database that you will build today is closer to an old dBASE or Paradox database, without any indexes, than to databases such as Access or SQL Server.<HR></BLOCKQUOTE><H4>Creating the Application Shell</H4><P>To get your application started, create a new AppWizard application. Give yourapplication a name, such as Serialize, and click OK to start the AppWizard.</P><P>In the AppWizard, select to create a single document style application using theDocument/View architecture. You can choose to include support for ActiveX controlsin the third AppWizard step, although it's not really necessary for the example thatyou will build.</P><P>In the fourth step, be sure to specify the file extension for the files that yourapplication will create and read. An example of a file extension that you might wantto use is ser for serialize or fdb for flat-file database.</P><P>In the sixth AppWizard step, you need to specify which base class to use for theapplication view class. For a description of the different base classes availablefor inheriting the view class from, refer to Day 10 in the section "The Document/ViewArchitecture." For the sample application you are building, because it willbe a database application, you'll find it easiest to use CFormView as the base classfrom which your view class will be inherited. This enables you to use the dialogdesigner for your application view.</P><P>Once you finish making your way through the AppWizard and let the AppWizard createyour application shell, you will see a large window canvas in the dialog designeras if you had created a dialog-style application, only without the OK and Cancel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -