Windows Programming _ sun Xin C ++ lesson13 documentation and serialization

Source: Internet
Author: User

Windows Programming _ sun Xin C ++ lesson13 documentation and serialization

Highlights of this section:
1. Understand the carchive class and serialized operations
2. Modify and obtain application-related fields
3. the breakpoint tracking method to understand the onfilenew and onfileopen execution processes of a single document
4. MFC Document Management (preliminary analysis, this part of content is relatively complex)
5. Programming Skills-Methods for copying Resources
6. Implementation of serialization of documents
7. Release of file memory space
//************************************** ************************************
1. Understand the carchive class and serialized operations
Carchive must be associated with a file. Open a file, construct a carchive object, and use this object to perform file operations.
In the document class, perform a preliminary test on serialization of the carchive class. The experiment code is as follows:
//************************************** ************************************
Void cgraphicdoc: serialize (carchive & AR)
{
If (AR. isstoring ())
{
// Todo: Add storing code here
Int I = 4;
Char CH = 'a ';
Float F = 1.4f;
Cstring STR = "carchive experiment ";
Ar <I <ch <F <STR;
}
Else
{
// Todo: Add loading code here
Int I;
Char ch;
Float F;
Cstring STR;
Ar> I> CH> F> STR;
Cstring MSG;
MSG. Format ("% d, % C, % F, % s", I, CH, F, STR );
Afxmessagebox (MSG );
}
}
//************************************** *************************************
2. Modify and obtain application-related fields
The cdocument class can be used to modify the window title:
Method 1: cgraphicdoc: onnewdocument () The function uses settitle to modify the title.
Method 2: Use the resource string to modify the title (other fields such as file type suffixes can also be modified). When loading a single document template with the idr_mainframe string, the resource includes a string,
You can modify the title of a startup interface by modifying the value of the corresponding field in the string.
In addition, the method getdocstring in the template class of the cdoctemplate document can find each substring in the idr_mainframe string.
The seven values that can be queried through this function correspond exactly to the content in the string resource, and the order is consistent. For example, cdoctemplate: windowtitle indicates the application window title.
3. the breakpoint tracking method to understand the onfilenew and onfileopen execution processes of a single document
//************************************** *********************************
// Onfilenew execution process of a single document
Cwinapp: onfilenew ()
Cdocmanager: onfilenew ()
{
Ptemplate-> opendocumentfile (null) // single-Document Template pointer
}
Csingledoctemplate-> openocumentfile ()
{
Pdocument-> createnewdocument ()
Pdocument-> createnewframe ()
Pdocument-> onnewdocument () // call onnewdocument by using the self-subclass pointer to call cgraphicdoc: onnewdocument ()
}
Cgraphicdoc: onfilenew ()
//************************************** *********************************
Onfileopen execution process of a single document
Cwinapp: onfileopen ()
Cdocmanager: onfileopen ()
{
Dopromptfilename () // select a file in the pop-up dialog box
Afxgetapp ()-> openocumentfile (newname)
}
Cwinapp: openocumentfile (newname );
Cdocmanager: openocumentfile ();
{
Cdocument * popendocument = NULL;
Cdoctemplate * pbesttemplate = NULL;
....
Cdoctemplate * ptemplate = (cdoctemplate *) m-templateList.GetNext (POS );
Ptemplate-> matchdoctype (szpath, popendocument );
// Key: Save the document and open the document if it has already been opened.
// Popendocument is no longer empty. Return popendocument and return directly without serialize of the subclass.
// If popendocument is empty, return pbesttemplate-> opendocumentfile (szpath );
}
Csingledoctemplate: opendocumentfile ()
Cdocument: onopendocument () construct cfile and carchive call virtual function serialize call serialize of subclass
Function.
Void cgraphicdoc: serialize (carchive & AR );
//************************************** *********************************
4. MFC Document Management (preliminary analysis, this part of content is relatively complex)
The framework, views, and documents of MFC actually divide file operations into different modules,
The View class is responsible for data display and user operations, and the document class is responsible for data storage and loading.
The new and open menu items are responded to in cwinapp. cwinapp has a member variable cdocmanager * m_pdocmanager pointing to cdocmanager,
The pointer linked list in the document manager saves the document template, which manages the document class, framework class, and view class.
For more information, see:

5. Programming Skills-Methods for copying Resources
To copy a menu resource from another project to the current project, you need to use the current project to open the previous project and copy its menu resource. Observe the ID and modify its ID if necessary.
6. Implementation of serialization of documents
(1) Understanding serialization
This topic will be devoted to a blog post later, in order to fully master serialization. I will not repeat it here.
(2) Communication Between document classes and visual classes:
A document object can be related to multiple object categories. A document object can only be related to one document object.
The document class of a single document finds the class pointer through getfirstviewposition and getnextview iteration. The class obtains the class pointer of the document through the function getdocument () generated by MFC.
As for the multi-document method, it is a little complicated, and it is not introduced here. For more information, see my post blog or go online.
(3) implement a serializable class:
Step: see the msdn serialization: Making a serializable class topic article.
Five main steps are required to make a class serializable.
Step1.eriving your class from cobject (or from some class derived from cobject ).
Step2.overriding the serialize member function.
Step3.using the declare_serial macro in the class declaration.
Step4.defining a constructor that takes no arguments.
Step5.using the implement_serial macro in the implementation file for your class.
The serial code of the cgraph class is as follows:
//************************************** *************************************
// Graph. h
Class cgraph: Public cobject // Step1 derives a class from cobject
{
Declare_serial (cgraph) // Step3 declares serialization
Public:
Cgraph ();
Cgraph (INT ndrawtype, cpoint ptorigin, cpoint ptend );
Virtual ~ Cgraph ();
Public:
Void draw (CDC * PDC );
Void serialize (carchive & archive); // step2 rewrite the serialize Function
Int m_ndrawtype;
Cpoint m_ptorigin;
Cpoint m_ptend;
};
// Graph. cpp
Implement_serial (cgraph, cobject, 1) // Step 5 use the implement_serial macro in the implementation file
Cgraph: cgraph () {}// step4 defines a constructor without Parameters
Cgraph: cgraph (INT ndrawtype, cpoint ptorigin, cpoint ptend)
{
M_ndrawtype = ndrawtype;
M_ptorigin = ptorigin;
M_ptend = ptend;
}
Cgraph ::~ Cgraph (){}
Void cgraph: serialize (carchive & archive)
{
Cobject: serialize (archive );

// Now do the stuff for our specific class
If (archive. isstoring ())
Archive <m_ndrawtype <m_ptorigin <m_ptend;
Else
Archive> m_ndrawtype> m_ptorigin> m_ptend;
}

Void cgraph: Draw (CDC * PDC)
{
Cbrush * pbrush = cbrush: fromhandle (hbrush) getstockobject (null_brush ));
Cbrush * poldbrush = PDC-> SelectObject (pbrush );
Switch (m_ndrawtype)
{
Case 0:
PDC-> setpixel (m_ptend.x, m_ptend.y, RGB (255, 0 ));
Break;
Case 1:
PDC-> moveTo (m_ptorigin.x, m_ptorigin.y );
PDC-> lineto (m_ptend.x, m_ptend.y );
Break;
Case 2:
PDC-> rectangle (crect (m_ptorigin, m_ptend ));
Break;
Case 3:
PDC-> ellipse (crect (m_ptorigin, m_ptend ));
Break;
Default:
Break;
}
PDC-> SelectObject (poldbrush );
}
//************************************** *************************************
(4) Save the image and operate it using the data structure cobarray.
Note that no matter whether graph is serialized in the cdoc class or cobarray is used for serialization, the underlying data storage work is completed by cgraph,
In addition, serialization always calls the serialize function implementation of the subclass, And the subclass should be responsible for the specific implementation of serialization.
The serial experiment code is as follows:
//************************************** *************************************
Void cgraphicdoc: serialize (carchive & AR)
{
/* The serialization method is complex.
Position Pos = getfirstviewposition ();
Cgraphicview * pview = (cgraphicview *) getnextview (POS); // get the Class Object Pointer
If (AR. isstoring ())
{
Int CNT = pview-> m_obrgraph.getsize ();
Int Index = 0;
Ar <CNT;
For (Index = 0; index <CNT; index ++)
Ar <pview-> m_obrgraph.getat (INDEX); // calls the serialize function implementation of the object.
}
Else
{
Int CNT;
Cgraph * pgrapg;
Int Index = 0;
Ar> CNT;
For (Index = 0; index <CNT; index ++)
{
Ar> pgrapg; // No need to construct an object to automatically construct the first address returned
Pview-> m_obrgraph.add (pgrapg );
}
}
*/
/* Serialization Method 2: simple serialization using the cobarray Structure
//// Cobarray m_obrgraph when defining the View class
Position Pos = getfirstviewposition ();
Cgraphicview * pview = (cgraphicview *) getnextview (POS); // get the Class Object Pointer
Pview-> m_obrgraph.serialize (AR );
*/
M_obrgraph.serialize (AR); // cobarray m_obrgraph is defined in the doc class
}
//************************************** *************************************
In fact, the code in method 1 is similar to that in cobarray. The cobarray serialization procedure is as follows:
Void cobarray: serialize (carchive & AR)
{
Assert_valid (this );

Cobject: serialize (AR );

If (AR. isstoring ())
{
Ar. writecount (m_nsize );
For (INT I = 0; I <m_nsize; I ++)
Ar <m_pdata [I];
}
Else
{
DWORD noldsize = ar. readcount ();
Setsize (noldsize );
For (INT I = 0; I <m_nsize; I ++)
Ar> m_pdata [I]; // cobject ** m_pdata;
}
}
//************************************** *************************************
7. Release of file memory space
(1) memory space release location
Cdocument: onnewdocument cdocument: onclosedocument cdocument: onopendocument
The same function must be called in all three functions. This function is cdocument: deletecontents,
This function clears the data of the document class. Therefore, the operation to release the memory space should be implemented in this function,
At the same time, this function is a virtual function. You can reload this function to clear the memory space.
(2) Clear cobarray data
Note: The removeat and removeall functions of the first cobarray only delete the pointer in the array,
Instead, the space of the object directed by the pointer is not released. This operation is done by the user;
Second, cobarray's removeat function has a special mechanism for deleting pointers. It will delete the elements referred to by the index,
At the same time, moving all the elements above the deleted element (the index is larger) down. If you do not notice this, an error will occur.
The experiment about cobarray: removeat function error is as follows:
//************************************** ***********************************
Void cgraphicdoc: deletecontents ()
{
// Todo: add your specialized code here and/or call the base class
Int ncnt = m_obrgraph.getsize ();
Int Index = 0;
For (Index = 0; index <ncnt; index ++)
{
Delete m_obrgraph.getat (INDEX );
M_obrgraph.removeat (INDEX); // Error
}
 
}
//************************************** ***********************************
Understanding about cobarray: removeat execution errors


When the loop is executed again, the element with Index = 2 cannot be deleted (an error occurs), and the element with Index = 0 cannot be deleted.
The deletion process is as follows:
{"Delete Index = 0, Info: TYPE = 1, ptorigin = 301, ptend = 65"} Delete obj1
{"Delete Index = 1, Info: TYPE = 1, ptorigin = 210, ptend = 122"} Delete obj3
{"Index = 0, Info: TYPE = 1, ptorigin = 539, ptend = 69"} obj2 is not deleted

Removeat error debugging program
Void cgraphicdoc: deletecontents ()
{
// Todo: add your specialized code here and/or call the base class
Int ncnt = m_obrgraph.getsize ();
Int Index = 0;
Cgraph * pgraph;
Cstring MSG;
// View m_obrgraph content
For (Index = 0; index <ncnt; index ++)
{
Pgraph = (cgraph *) m_obrgraph.getat (INDEX );
MSG. Format ("Index = % d, Info: TYPE = % d, ptorigin = % d, ptend = % d", index,
Pgraph-> m_ndrawtype, pgraph-> m_ptorigin, pgraph-> m_ptend );
Afxmessagebox (MSG );
}
// Observe the deletion Process
For (Index = 0; index <ncnt; index ++)
{
If (Index = 2) // The content of index 0 in m_obrgraph is not released for the third execution.
{
Pgraph = (cgraph *) m_obrgraph.getat (0 );
MSG. Format ("Index = % d, Info: TYPE = % d, ptorigin = % d, ptend = % d still remain! ",
0, pgraph-> m_ndrawtype, pgraph-> m_ptorigin, pgraph-> m_ptend );
Afxmessagebox (MSG );
}
Pgraph = (cgraph *) m_obrgraph.getat (INDEX );
MSG. Format ("delete Index = % d, Info: TYPE = % d, ptorigin = % d, ptend = % d ",
Index, pgraph-> m_ndrawtype, pgraph-> m_ptorigin, pgraph-> m_ptend );
Afxmessagebox (MSG );
Delete pgraph;
M_obrgraph.removeat (INDEX); // Error
}
Cdocument: deletecontents ();
}
//************************************** **************************************** **
There are two correct methods to release a space. The Code is as follows:
//************************************** *************************************
Void cgraphicdoc: deletecontents ()
{
// Todo: add your specialized code here and/or call the base class
Int ncnt = m_obrgraph.getsize ();
Int Index = 0;
// Method 1 Delete the pointer to the control and then delete the pointer in sequence
For (Index = 0; index <ncnt; index ++)
{
Delete m_obrgraph.getat (INDEX );
}
M_obrgraph.removeall ();
/*
// Method 2: delete from high sequence number
For (Index = nCnt-1; index> = 0; index --)
{
Delete m_obrgraph.getat (INDEX );
M_obrgraph.removeat (INDEX );
}
*/
Cdocument: deletecontents ();
}
//************************************** *************************************
Summary:
1. Master How To Make A class support serialization and use cobarray to quickly implement class serialization.
2. Understand the execution process of creating, opening, and saving an MFC single document and master the idea of breakpoint tracking.
3. Have a preliminary understanding of the management mechanism of the MFC Document.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.