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

📄 ch13.htm

📁 这是一本关于VC++自学教程的书籍 对于初学者以及编程有一定基础的人均有帮助
💻 HTM
📖 第 1 页 / 共 5 页
字号:
	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">			<H4>Name		</TD>		<TD ALIGN="LEFT">			<H4>Type		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">m_iCurPosition		</TD>		<TD ALIGN="LEFT">int		</TD>	</TR>	<TR ALIGN="LEFT" VALIGN="TOP">		<TD ALIGN="LEFT">m_oaPeople		</TD>		<TD ALIGN="LEFT">CObArray		</TD>	</TR></TABLE></P><P>The other thing that you need to do to the document class to provide support forthe record objects is make sure that the document knows about and understands therecord object that it will be holding. You do this by including the custom classheader file before the header file for the document class is included in the documentclass source code file. Because the document class needs to trigger actions in theview class, it's a good idea to also include the header file for the view class inthe document class.</P><P>To include these header files in your sample application, open the source-codefile for the document class and add the two #include statements as shown in Listing13.9.</P><P><H4>LISTING 13.9. INCLUDING THE CUSTOM AND VIEW CLASSES IN THE DOCUMENT CLASS IMPLEMENTATION.</H4><PRE> 1: // SerializeDoc.cpp : implementation of the CSerializeDoc class 2: // 3:  4: #include &quot;stdafx.h&quot; 5: #include &quot;Serialize.h&quot; 6:  7: #include &quot;Person.h&quot; 8: #include &quot;SerializeDoc.h&quot; 9: #include &quot;SerializeView.h&quot;10: 11: #ifdef _DEBUG12: #define new DEBUG_NEW13: #undef THIS_FILE14: static char THIS_FILE[] = __FILE__;15: #endif16: 17: //////////////////////////////////////////////////////////////////////18: // CSerializeDoc</PRE><P><H4>Adding New Records</H4><P>Before you can navigate the record set, you need to be able to add new recordsto the object array. If you add a private function for adding new records, you canadd new records to the set dynamically as new records are needed. Because new recordsshould be presenting the user with blank or empty data fields, you don't need toset any of the record variables when adding a new record to the object array, soyou can use the default constructor.</P><P>Following the same logic that you used to add new line records on Day 10, youshould add a new person record to the object array in your document class in today'ssample application. Once you add a new record, you can return a pointer to the newrecord so that the view class can directly update the variables in the record object.</P><P>Once the new record is added, you will want to set the current record positionmarker to the new record in the array. This way, the current record number can easilybe determined by checking the position counter.</P><P>If there are any problems in creating the new person record object, let the userknow that the application has run out of available memory and delete the allocatedobject, just as you did on Day 10.</P><P>To add this functionality to your sample application, add a new member functionto the document class. Specify the type as a pointer to your custom class. If younamed your custom class CPerson, the function type is CPerson*. This function needsno arguments. Give the function a name that reflects what it does, such as AddNewRecord.Specify the access for this function as private because it will only be accessedfrom other functions within the document class. You can edit the resulting function,adding the code in Listing 13.10.</P><P><H4>LISTING 13.10. THE CSerializeDoc.AddNewRecord FUNCTION.</H4><PRE> 1: CPerson * CSerializeDoc::AddNewRecord() 2: { 3:     // Create a new CPerson object 4:     CPerson *pPerson = new CPerson(); 5:     try 6:     { 7:         // Add the new person to the object array 8:         m_oaPeople.Add(pPerson); 9:         // Mark the document as dirty10:         SetModifiedFlag();11:         // Set the new position mark12:         m_iCurPosition = (m_oaPeople.GetSize() - 1);13:     }14:     // Did we run into a memory exception?15:     catch (CMemoryException* perr)16:     {17:         // Display a message for the user, giving them the18:         // bad news19:         AfxMessageBox(&quot;Out of memory&quot;, MB_ICONSTOP | MB_OK);20:         // Did we create a line object?21:         if (pPerson)22:         {23:             // Delete it24:             delete pPerson;25:             pPerson = NULL;26:         }27:         // Delete the exception object28:         perr-&gt;Delete();29:     }30:     return pPerson;31: }</PRE><P><H4>Getting the Current Position</H4><P>To aid the user in navigating the record set, it's always helpful to provide aguide about where the user is in the record set. To provide this information, youneed to be able to get the current record number and the total number of recordsfrom the document to display for the user.</P><P>The functions to provide this information are both fairly simple. For the totalnumber of records in the object array, all you need to do is get the size of thearray and return that to the caller.</P><P>For your sample application, add a new member function to the document class.Specify the function type as int, the function name as GetTotalRecords, and the accessas public. Once you add the function, edit it using the code in Listing 13.11.</P><P><H4>LISTING 13.11. THE CSerializeDoc.GetTotalRecords FUNCTION.</H4><PRE>1: int CSerializeDoc::GetTotalRecords()2: {3:     // Return the array count4:     return m_oaPeople.GetSize();5: }</PRE><P>Getting the current record number is almost just as simple. If you are maintaininga position counter in the document class, this variable contains the record numberthat the user is currently editing. As a result, all you need to do is return thevalue of this variable to the calling routine. Because the object array begins withposition 0, you probably need to add 1 to the current position before returning todisplay for the user.</P><P>To add this function to your sample application, add another new member functionto the document class. Specify the type as int, the function name as GetCurRecordNbr,and the access as public. Edit the function using the code in Listing 13.12.</P><P><H4>LISTING 13.12. THE CSerializeDoc.GetCurRecordNbr FUNCTION.</H4><PRE>1: int CSerializeDoc::GetCurRecordNbr()2: {3:     // Return the current position4:     return (m_iCurPosition + 1);5: }</PRE><P><H4>Navigating the Record Set</H4><P>To make your application really useful, you will need to provide the user withsome way of navigating the record set. A base set of functionality for performingthis navigation is a set of functions in the document class to get pointers to specificrecords in the record set. First is a function to get a pointer to the current record.Next are functions to get pointers to the first and last records in the set. Finally,you need functions to get the previous record in the set and the next record in theset. If the user is already editing the last record in the set and attempts to moveto the next record, you can automatically add a new record to the set and providethe user with this new, blank record.</P><P>To add all this functionality, start with the function to return the current record.This function needs to check the value in the position marker to make sure that thecurrent record is a valid array position. Once it has made sure that the currentposition is valid, the function can return a pointer to the current record in thearray.</P><P>To add this function to your sample application, add a new member function tothe document class. Specify the function type as CPerson* (a pointer to the customclass), the function name as GetCurRecord, and the access as public. Edit the function,adding the code in Listing 13.13.</P><P><H4>LISTING 13.13. THE CSerializeDoc.GetCurRecord FUNCTION.</H4><PRE> 1: CPerson* CSerializeDoc::GetCurRecord() 2: { 3:     // Are we editing a valid record number? 4:     if (m_iCurPosition &gt;= 0) 5:         // Yes, return the current record 6:         return (CPerson*)m_oaPeople[m_iCurPosition]; 7:     else 8:         // No, return NULL 9:         return NULL;10: }</PRE><P>The next function you might want to tackle is the function to return the firstrecord in the array. In this function, you need to first check to make sure thatthe array has records. If there are records in the array, set the current positionmarker to 0 and return a pointer to the first record in the array.</P><P>To add this function to your sample application, add a new member function tothe document class. Specify the function type as CPerson* (a pointer to the customclass), the function name as GetFirstRecord, and the access as public. Edit the function,adding the code in Listing 13.14.</P><P><H4>LISTING 13.14. THE CSerializeDoc.GetFirstRecord FUNCTION.</H4><PRE> 1: CPerson* CSerializeDoc::GetFirstRecord() 2: { 3:     // Are there any records in the array? 4:     if (m_oaPeople.GetSize() &gt; 0) 5:     { 6:         // Yes, move to position 0 7:         m_iCurPosition = 0; 8:         // Return the record in position 0 9:         return (CPerson*)m_oaPeople[0];10:     }11:     else12:         // No records, return NULL13:         return NULL;14: }</PRE><P>For the function to navigate to the next record in the set, you need to incrementthe current position marker and then check to see if you are past the end of thearray. If you are not past the end of the array, you need to return a pointer tothe current record in the array. If you are past the end of the array, you need toadd a new record to the end of the array.</P><P>To add this function to your sample application, add a new member function tothe document class. Specify the function type as CPerson* (a pointer to the customclass), the function name as GetNextRecord, and the access as public. Edit the function,adding the code in Listing 13.15.</P><P><H4>LISTING 13.15. THE CSerializeDoc.GetNextRecord FUNCTION.</H4><PRE> 1: CPerson * CSerializeDoc::GetNextRecord() 2: { 3:     // After incrementing the position marker, are we 4:     // past the end of the array? 5:     if (++m_iCurPosition &lt; m_oaPeople.GetSize()) 6:         // No, return the record at the new current position 7:         return (CPerson*)m_oaPeople[m_iCurPosition]; 8:     else 9:         // Yes, add a new record10:         return AddNewRecord();11: }</PRE><P>For the function to navigate to the previous record in the array, you need tomake several checks. First, you need to verify that the array has records. If thereare records in the array, you need to decrement the current position marker. If themarker is less than zero, you need to set the current position marker to equal zero,pointing at the first record in the array. Once you've made it through all of this,you can return a pointer to the current record in the array.</P><P>To add this function to your sample application, add a new member function tothe document class. Specify the function type as CPerson* (a pointer to the customclass), the function name as GetPrevRecord, and the access as public. Edit the function,adding the code in Listing 13.16.</P><P><H4>LISTING 13.16. THE CSerializeDoc.GetPrevRecord FUNCTION.</H4><PRE> 1: CPerson * CSerializeDoc::GetPrevRecord() 2: { 3:     // Are there any records in the array? 4:     if (m_oaPeople.GetSize() &gt; 0) 5:     { 6:         // Once we decrement the current position, 7:         // are we below position 0? 8:         if (--m_iCurPosition &lt; 0) 9:             // If so, set the record to position 010:             m_iCurPosition = 0;11:         // Return the record at the new current position12:         return (CPerson*)m_oaPeople[m_iCurPosition];13:     }14:     else15:         // No records, return NULL16:         return NULL;17: }</PRE><P>For the function that navigates to the last record in the array, you still needto check to make sure that there are records in the array. If the array does haverecords, you can get the current size of the array and set the current position markerto one less than the number of records in the array. This is actually the last recordin the array because the first record in the array is record 0. Once you set thecurrent position marker, you can return a pointer to the last record in the array.</P><P>To add this function to your sample application, add a new member function tothe document class. Specify the function type as CPerson* (a pointer to the customclass), the function name as GetLastRecord, and the access as public. Edit the function,adding the code in Listing 13.17.</P><P><H4>LISTING 13.17. THE CSerializeDoc.GetLastRecord FUNCTION.</H4><PRE> 1: CPerson * CSerializeDoc::GetLastRecord() 2: { 3:     // Are there any records in the array? 4:     if (m_oaPeople.GetSize() &gt; 0) 5:     { 6:         // Move to the last position in the array 7:         m_iCurPosition = (m_oaPeople.GetSize() - 1); 8:         // Return the record in this position 9:         return (CPerson*)m_oaPeople[m_iCurPosition];10:     }11:     else12:         // No records, return NULL13:         return NULL;14: }</PRE><P><H4>Serializing the Record Set</H4><P>When filling in the Serialize functionality in the document class, there's littleto do other than pass the CArchive object to the object array's Serialize function,just as you did on Day 10.</P><P>When reading data from the archive, the object array will query the CArchive objectto determine what object type it needs to create and how many it needs to create.The object array will then create each object in the array and call its Serializefunction, passing the CArchive object to each in turn. This enables the objects inthe object array to read their own variable values from the CArchive object in thesame order that they were written.</P><P>When writing data to the file archive, the object array will call each object'sSerialize function in order, passing the CArchive object (just as when reading fromthe archive). This allows each object in the array to write its own variables intothe archive as necessary.</P><P>For the sample application, edit the document class's Serialize function to passthe CArchive object to the object array's Serialize function, as in Listing 13.18.</P><P><H4>Listing 13.18. THE CSerializeDoc.Serialize FUNCTION.</H4>

⌨️ 快捷键说明

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