This post shows you how to utilize the built-in file handling capabilities that MFC has in order to serialize your data, that is, how to read from or write to a disk.
Using the MFC document object
One way is to use the MFC document object to do the serializing for you. This will be demonstrated by creating a simple SDI (single document interface) using the AppWizard.
Select File > New > Project and select the Visual C++ > MFC Application as the choice of installed template:
In the Application Type, select Single Document:
In the Advanced Features section, uncheck the Advanced frame panes:
For this example, we will let the program accept and display input from the keyboard.
The first bit of coding is to store the characters that the user types in using a CString
object, m_strData
in the document class that is created in SerializeSDIexampleDoc.h
:
class CSerializeSDIexampleDoc : public CDocument { protected: // create from serialization only CSerializeSDIexampleDoc(); DECLARE_DYNCREATE(CSerializeSDIexampleDoc) // Attributes public: CString m_strData; ...
And initialise the value of m_strData in the document’s constructor:
CSerializeSDIexampleDoc::CSerializeSDIexampleDoc() { m_strData = ""; }
We then write code to handle the WM_CHAR
Windows messages that are received when the user inputs characters from the keyboard. You can either just write this code yourself, or use the ClassWizard.
To use the ClassWizard, right-click the project folder and select Class Wizard… Ensure the CSerializeSDIexampleView
class name is selected. Select the Message tab and then select the ‘Add Handler…’ button.
Then press Apply. Click Edit Code so that we can write code to store the characters the user types in. In addition this handler checks to see if the user has entered backspace, in which case it deletes the last character by shortening the string data member by 1:
void CSerializeSDIexampleView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CSerializeSDIexampleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if ( nChar == 8 ) { int length = pDoc->m_strData.GetLength(); CString str = pDoc->m_strData.Left( length - 1 ); pDoc->m_strData = str; } else { CString str; str.Format( TEXT( "%c" ), nChar ); pDoc->m_strData += str; } Invalidate(); CView::OnChar(nChar, nRepCnt, nFlags); }
Invalidate()
is used to invalidate the view when the user types a new character.
We then add an message handler to display the new text string in OnDraw()
method inside CSerializeSDIexampleView
, which is automatically created.
Uncomment CDC* /*pDC*/
and add the code to display the text
void CSerializeSDIexampleView::OnDraw(CDC* pDC) { CSerializeSDIexampleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; pDC->TextOut( 0, 0, pDoc->m_strData ); }
Notice that the CSerializeSDIexampleDoc
class already has a Serialize()
method. This is where we serialize the m_strData
string. Use the CArchive
reference passed to it in the same as you would use std::cout
or std::cin
to read and write to the disk respectively:
void CSerializeSDIexampleDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar << m_strData; } else { ar >> m_strData; } }
One last modification we make to the project is to let the application remember when the user has added more data to the m_strData
object, so that when the user exits the application, before saving the changes, the application will prompt the user with a “Save changes to document” message.
In CSerializeSDIexampleView::OnChar
indicate that the document has changed by setting the modified flag:
void CSerializeSDIexampleView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default CSerializeSDIexampleDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if ( nChar == 8 ) { int length = pDoc->m_strData.GetLength(); CString str = pDoc->m_strData.Left( length - 1 ); pDoc->m_strData = str; } else { CString str; str.Format( TEXT( "%c" ), nChar ); pDoc->m_strData += str; } Invalidate(); pDoc->SetModifiedFlag(); CView::OnChar(nChar, nRepCnt, nFlags); }
Running the program, we can enter characters or delete them using the backspace:
Now try closing the application without saving the text, so that you are prompted if you wish to save:
Give the file a name and then save:
Now restart the application, open the file Serialize1.txt
in order to re-open:
Download Visual Studio project from here:
Serializing data in MFC / Visual C++.
Related post: