Visual C++ / MFC - Common Guidelines

In developing MFC programs, you will find yourself repeatedly doing the same type of similar programming that you did in SDK programming (responding to messages in a switch statement). This document will attempt to describe the basic steps you do to implement an MFC program.


CDocument
The document class that AppWizard created for you is derived from the CDocument class (in SDI and MDI projects). This is the class where data is stored during runtime and it's primary task (that you must implement) is the saving and loading of that data to and from a disk file.

The CDocument (all CObject-derived classes, actually) have a Serialize function that is called by MFC to load and save a disk file. The Serialize function has the following basic format (as created by AppWizard):

void CAppNameDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here 
	}
}



The if test inside the function determines if you are being asked to save or load the data for the document. MFC will have already handled the File Open and Save menu choices, and opened the file by the time this function is called. The ar parameter represents the open file and is very similar to an ifstream object (you can use <<, >>, Read, and Write to store or load data).

The CArchive class provide a set of << and >> operators for fundamental data types, as well as many of the other MFC classes such as CString and CPoint, and even the collection classes like CObArray and CArray. In addition, since most of the collection classes also provide a Serialize routine, you can also those serialize routines, for those classes. The following are example is a Serialize routine for a CPoint object, called Point, that's a data member of the document class:

void CAppNameDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		ar << Point;
	}
	else
	{
		ar >> Point;
	}
}


The View Classes
The View classes represent the user interface to the document. There are two basic types of views you will be using: CView which is a view without controls, similar to SDK programming, and CFormView which is a view that is easy to place child controls on. The CView is the default view, but can be changed in the last dialog of AppWizard.


Data output (Drawing)
Your primary purpose in the view is to display data from the document to the user, and get user changes (in the form of events). These changes are given to the document. If you have a CView class, then you will be working with the OnDraw function of the view class:

void CAppNameView::OnDraw(CDC* pDC)
{
CHwDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
}

The CDC object is a 'wrapper' for the Windows HDC device context item. As a class, it has all the functions that work with a device context. For example, in the above code, you can do the following:

pDC->TextOut( 0, 0, "Hello World", 10 );

The first two lines of code in the function above, get a pointer to the document associated with the view. This pointer (pDoc) provides you with access to your document object to get data from for drawing. Your drawing code should appear after these two lines of code.

The OnDraw function is automatically called by MFC in response to a WM_PAINT message.


Data Input (User interaction)
In order to process user events, you add Message Maps using ClassWizard (the Message Maps tab). ClassWizard can be accessed from the View menu choice. In ClassWizard, you select the type of object from the Object IDs list, and the type of message from the Messages list. For Object IDs:

· Select the name of the view class to handle general window's messages, and special MFC functions (such as OnDraw).
· Select the ID of the menu item or control (if it's a CFormView view, and you added a control to the form for the view) to handle menu choices and control notifications.

Once you've selected the desired ID/Class, select the message you want to map. For menu items and controls, you will see a COMMAND choice, which means a WM_COMMAND message, or that the user has clicked that control (other controls like an edit box have more messages). Once you've selected the desired message, click the Add Function button.

MFC will then add a function to your view class definition and your .cpp file, and call that function when the previously selected message is sent to the selected object ID.




Helpful MFC classes
The following classes are basic helpful classes when writing MFC Windows programs:


Class Description

Serialize()
 CObject  Base class for most classes, helpful for collection classes and framework  Y
 CPoint  Point management  << and >>
 CRect  Rectangle management   << and >>
 CString  String management   << and >>
 CTime  Date and time management   << and >>
 CFile  File management  N
 CArchive  File management, similar to CFile, but supports other objects  N
 CStringArray  Collection of strings  Y
 CObArray  Collection of Cobjects pointers, or CObject-derived pointers  Y
 CPtrArray  Collection of pointers  N
 CDC  Wrapper class for Device Context  N
 CDatabase  A connection to a database (collection of data files)  N
 CRecordset  A query or table in a database. Works with a CDatabase  N

The Array classes above also have matching List and Map collection classes. While they are all collection classes, they differ in the following way:
· Arrays are implemented internally as an array, and are slower to insert than a list or map, searching speed is slower than a map and similar to list. Elements are accessed by an integer index.
· Lists are implemented internally as a linked list, and are fast to insert. Searching is slower than a map, and similar to an array. Elements are accessed sequentially.
· Maps are implemented as a look up table, and are fast to both insert and sort. Elements are accessed via a key value.

There are also template versions of the array, list, and map classes called CArray, CList, and CMap.