FunctionX - Practical Learning Logo

File Processing: Archiving

 

Introduction to File Processing

 

Overview

 

File processing is the ability to create, store, and/or retrieve the contents of a file from a medium such as a hard drive, a floppy disk, a CD-ROM, or a DVD-ROM, etc. One of the areas in which the MFC excels is file processing. MFC makes it particularly easy to perform most file related operations.

 

What to Process, When, and Where

Before creating a file, you should first plan your program since applications deal with different types of files. An application that manipulate pictures may need to save only one value for the whole file. Another application used for word processing may also need to save only one value but of a completely different kind. If an application is list-based, it may need to save various values that, when put together, constitute one file.

After deciding what type of file the user would be processing, you would also specify how and/or who would decide when to process a file. For example, if you create a certain application that allows a user to change the internal settings and store them in a file, you can process the file automatically and store it somewhere without asking the user to decide when, where, or how to save the file (some applications use the Registry to take care of this). For example, in tthe bits of data that are arranged in a particular way to produce a usable document. For easy storage, location, and management, the bits are stored on a medium such as a hard disc, a floppy disc, a compact disc, or any valid and support type of storage. When these bits belong to a single but common entity, the group is referred to as a file. For even greater management, files can be stored in a parent object called a directory or a folder. Since a file is a unit of storage and it stores information, it has a size which is the number of bits it contains. To manage it, a file also has a location also called a path that specifies where and/or how the file can be retrieved. Also, for better management, a file has attributes that indicate what can be done on a file or that provide specific information that the programmer or the operating system can use when dealing with the file.

For example, in Jasc Paint Shop Pro, users are allowed to create new customized gradients that were not installed with the application. Once a user clicks OK, the new gradient is saved:

Another way you can deal with this is to let a user decide when to save the file and where to save it. This is usually taken care of by providing the File Dialog to the user.

 

 

Archiving

 

Introduction

Most of the file processing in an MFC application is performed in conjunction with a class called CArchive. The CArchive class serves as a relay between the application and the medium used to either store data or make it available. The CArchive class is an accessory and not an end to itself. As such, it provides its services to the MFC class that need to perform file transfer.

Although used by MFC, the CArchive class is semi-independent. That is, it is not derived from CObject. It only provides its services to the MFC objects that need archiving. To provide this support, the parent class of MFC objects, CObject, is equipped with a method called Serialize(). The CObject::Serialize() method takes one argument, which is a CArchive reference variable. The syntax of the CObject::Serialize() method is:

virtual void Serialize(CArchive& ar);

This means that the MFC library already provides file processing at a very high level. This also implies that almost every MFC class is ready to save its value(s) from a medium or to retrieve existing (an) value(s) from a medium. This convenience is given at a very low price, as file processing is one of MFC strengths. Based on this, to provide file processing for an object in your application, you can simply override the Serialize() method.

 

The Process of Archiving

One of the most regular ways you will use the CArchive class consists of storing or retrieving values through their Serialize() method. To do this directly and easily in the class, the CArchive class overloads two operations: << and >>.

To store one or more values, the CArchive class provides the << operator. The values you can store are of MFC, BYTE, short, WORD, int, unsigned int, long, LONG, DWORD, float, or double types. The class also provides an exception handler for each kind. Therefore, the syntaxes for this operator are:

friend CArchive& operator <<( CArchive& ar, const CObject* pOb );
throw( CArchiveException, CFileException );
CArchive& operator <<( BYTE by );
throw( CArchiveException, CFileException );
CArchive& operator <<( WORD w );
throw( CArchiveException, CFileException );
CArchive& operator <<( int i );
throw( CArchiveException, CFileException );
CArchive& operator <<( LONG l );
throw( CArchiveException, CFileException );			
CArchive& operator <<( DWORD dw );
throw( CArchiveException, CFileException );
CArchive& operator <<( float f );
throw( CArchiveException, CFileException );
CArchive& operator <<( double d );
throw( CArchiveException, CFileException );

As you may have realized, there is only one version of the Serialize() method. That is, this member function is called once for both storing and retrieving. Therefore, when using it, you must specify what operation you want to perform. This checking process can be performed by calling the CArchive::IsStoring() Boolean method. Its syntax is:

BOOL IsStoring() const;

This method returns TRUE if you are storing data. If the answer is then TRUE, you can use the << operator to store each necessary value.

As opposed to storing value(s), to retrieve a value, the CArchive class provides the >> operator. It comes in the following syntaxes:

friend CArchive& operator >>( CArchive& ar, CObject *& pOb );
throw( CArchiveException, CFileException, CMemoryException );
friend CArchive& operator >>( CArchive& ar, const CObject *& pOb );
throw( CArchiveException, CFileException, CMemoryException );
CArchive& operator >>( BYTE& by );
throw( CArchiveException, CFileException );
CArchive& operator >>( WORD& w );
throw( CArchiveException, CFileException );
CArchive& operator >>( int& i );
throw( CArchiveException, CFileException );
CArchive& operator >>( LONG& l );
throw( CArchiveException, CFileException );
CArchive& operator >>( DWORD& dw );
throw( CArchiveException, CFileException );
CArchive& operator >>( float& f );
throw( CArchiveException, CFileException );
CArchive& operator >>( double& d );
throw( CArchiveException, CFileException );

This indicates that you can retrieve an MFC object, a BYTE, a short, a WORD, an int, an unsigned int, a long, a LONG, a DWORD, a float, or a double value.

As mentioned above, the Serialize() method is used for both operations. Therefore, when using this method, you should first check what operation is being performed. This can be done by calling the IsLoading() method. Its syntax is:

BOOL IsLoading() const;

This method returns TRUE if you are retrieving a value or some values. If it is true, you can then use the >> operator to retrieve the value(s).

Practical Learning: Introducing File Processing

  1. If you want to follow this exercise, create a new application using MFC AppWizard (exe) or MFC Application
  2. Name it Palace Ice Cream
  3. Change the design of the IDR_MAINFRAME icon as follows:
     
     
  4. Design the dialog box as follows:
     
     
    Control ID Caption Additional Properties
    Static Text Static Text   First Name:  
    Edit Box IDC_FIRST_NAME    
    Static Text Static Text   Last Name:  
    Edit Box Edit Box IDC_LAST_NAME    
    Static Text Static Text   Address:  
    Edit Box IDC_ADDRESS    
    Static Text Static Text   City:  
    Edit Box IDC_CITY    
    Static Text Static Text   State:  
    Edit Box IDC_STATE  
    Static Text Static Text   ZIP Code:  
    Edit Box IDC_ZIP_CODE    
    Static Text Static Text   Hourly Salary:  
    Edit Box IDC_HOURLY_SALARY    
    Group Box   Employment Status  
    Radio Button Radio Button IDC_PART_TIME Part Time Group: True
    Left Text: True
    Radio Button Radio Button IDC_FULL_TIME Full Time Left Text: True
    Button Button IDOK    
    Button Button IDCANCEL    
  5. Using either the ClassWizard or the Add Member Variable Wizard, add the following member variables to the controls:
     
    Identifier Value Variable
    IDC_FIRST_NAME CString m_FirstName
    IDC_LAST_NAME CString m_LastName
    IDC_ADDRESS CString m_Address
    IDC_CITY CString m_City
    IDC_STATE CString m_State
    IDC_ZIP_CODE long m_ZIPCode
    IDC_HOURLY_SALARY double m_HourlySalary
    IDC_PART_TIME int m_EmploymentStatus
  6. Save everything 

 

MFC Support of File Processing

 

Introduction

MFC supports file processing at different levels. There is so much file processing that one of your biggest difficulties would consist of deciding what file processing system you want to use. MFC supports C, C++, Win32, and MFC file processing. Even if you select only one of these categories, some of them have other variances. For example, the C++ language provides more than one way to perform file processing. MFC itself is tremendously wide on this issue.

One of the classes used to perform file processing on MFC applications is CFile. Using this class, to create a file, you can first declare a variable of type CFile using one of its 3 constructors. They are;

CFile( );
CFile( int hFile );
CFile( LPCTSTR lpszFileName, UINT nOpenFlags );

The default constructor is used if you are not ready to specify the information needed to create the file.

The second constructor takes an argument that is a handle to a file created using the Win32's CreateFile() function.

The third constructor is used to create a file by specifying the file name and the flags that specify the operation to perform when saving or opening the file.

 

Automatic File Processing

Automatic File Processing consists of saving or opening a file with little to no intervention from the user. This technique is used to provide values that should be automatically provided to the user. This technique also allows the user to create or add a new value to a list that is deemed incomplete.

Practical Learning: Using the File Dialog Box

  1. Assuming that the user would have typed information about an employee, to automatically save the file, double-click the OK button
  2. Accept the suggested name of the event and implement it as follows:
     
    void CPalaceIceCreamDlg::OnOK() 
    {
    	// TODO: Add extra validation here
    	// TODO: Add your control notification handler code here
    	this->UpdateData();
    
    	CFile flEmployees;
    
    	flEmployees.Open("employees.mpl", CFile::modeCreate | CFile::modeWrite);
    	CArchive ar(&flEmployees, CArchive::store);
    
    	ar << m_FirstName << m_LastName << m_Address << m_City << m_State << m_ZIPCode << m_HourlySalary << m_EmploymentStatus;
    		
    	ar.Close();
    	flEmployees.Close();
    
    	CDialog::OnOK();
    }
  3. Execute the application and fill the dialog with some information
     
  4. Click OK to close the dialog box
  5. To automatically load the saved file when the dialog box comes up, generate the WM_CREATE message for the dialog box and implement its OnCreate event as follows:
     
    int CPalaceIceCreamDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    	if (CDialog::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	
    	// TODO: Add your specialized creation code here
    	CFile flEmployees;
    
    	flEmployees.Open("employees.mpl", CFile::modeRead);
    	CArchive ar(&flEmployees, CArchive::load);
    
    	ar >> m_FirstName >> m_LastName >> m_Address >> m_City >> m_State >> m_ZIPCode >> m_HourlySalary >> m_EmploymentStatus;
    	
    	ar.Close();
    	flEmployees.Close();
    
    	return 0;
    }
  6. Execute the application
  7. Close it
 

Copyright © 2004 FunctionX, Inc.