Microsoft Foundation Class Library Development Guidelines

Microsoft Corporation

Updated March 31, 1997

Table of Contents

Overview

Design Goals of the MFC Class Library

Guidelines for Writing Class Library Extensions

Follow MFC’s Conventions

Make Your Classes Flexible

Use MFC to Create Your Classes

Write Thorough Documentation to Help Your Users

In Conclusion

Overview

This paper is intended for use by developers who want to create extensions for the Microsoft® Foundation Class Library and who want to ensure that their classes are "MFC-friendly"; that is, classes that will function well with MFC. This paper is also useful for anyone writing MFC applications who wants to know the philosophy and development practices used in the Library.

Design Goals of the MFC Class Library

The Microsoft Foundation Class Library, a C++ Windows® interface, is built on top of the C-language Windows application programming interface (API) to ensure long-term compatibility with the thousands of applications already written for Windows. MFC is a truly object-oriented interface designed with the following goals in mind:

The core of the Microsoft Foundation Class Library encapsulates a large portion of the Windows API in C++ form. Library classes represent windows, dialog boxes, device contexts, common GDI objects, and other standard Windows items. These classes provide a convenient C++ member function interface to the structures in Windows that they encapsulate. The Microsoft Foundation Class Library also supplies a layer of additional application functionality built on the C++ encapsulation of the Windows API. This layer is a working application framework for Windows that provides most of the common user interface expected of programs for Windows.

The single characteristic that sets the Microsoft Foundation Class Library apart from other class libraries for Windows is the close mapping to the Windows API written in the C language. You can generally mix calls to the class library freely with direct calls to the Windows API. However, the classes are not a complete replacement for that API. Developers must still occasionally make direct calls to some Windows functions (::GetSystemMetrics, for example). A Windows function is wrapped by a class member function only when there is a clear advantage to doing so.

Guidelines for Writing Class Library Extensions

The remainder of this paper outlines the practices that the MFC developers use when writing new classes for the Library. We recommend that you follow these same practices when writing classes that extend the MFC Library. For optimum performance and compatibility with the Library, we suggest that you:

Keep the classes simple.

Follow the conventions for naming classes, member functions, and data members.

Make your classes flexible.

Use MFC to write your classes.

Write thorough documentation to assist your users.

Keep Your Classes Simple

Classes you expose to the user should be as uncomplicated as you can make them. It is okay for your job as the class library designer to be difficult if doing so makes it easier for your users (in this case, other developers) to understand the classes you have written.

Use a safe subset of the C++ language features

MFC uses a safe subset of the C++ language features. This lowers the level of complexity in the Class Library, and ensures that the classes will be compatible with a wide range of uses. MFC uses C++ idioms in commonly accepted practices. Advanced issues such as copy construction, assignment operators, and correct object destruction are handled in a thorough and consistent manner. To make your classes MFC-friendly, we recommend that you follow these principles as you create your classes.

Limit the number of abstract base classes you write

MFC has a few abstract base classes that serve specific purposes, such as CObject and CCmdTarget. In general we advise developers to combine an abstract base class with a useful implementation if that is possible. CFile and CWnd are examples of classes that are used in both concrete and abstract forms.

Use //Implementation section instead of implementation classes

Creating a class that is for implementation purposes only, yet is visible to your users, is both confusing and frustrating. Instead, put implementation details below the //Implementation line in your header files. For more information, see "Limit the Use of ‘Private’ in Your Classes" elsewhere in this document, and also see "MFC: Using the MFC Source Files" in the Visual C++ Programmer’s Guide in the online documentation (MSDN Library, Developer Products, Visual C++).

Use single rather than multiple inheritance in your classes

Multiple inheritance adds a high degree of complexity to application development. The Microsoft Foundation Class Library does not use multiple inheritance in the design or implementation of any of its classes. While you can use multiple inheritance with MFC to write an application (see Technical Note 16 in the Microsoft Foundation Class Reference in the Visual C++® online documentation: MSDN Library, Developer Products, Visual C++, Microsoft Foundation Class Reference), we do not recommend using it in MFC-friendly classes.

Use templates as an advantage in your classes

Templates in C++ are relatively new to the language and rather complicated to implement. Templates allow your classes to be generic when necessary, but the level of complexity inherent to templates can negate this advantage. Templates are most useful when creating "collection" classes, or for providing type-safe wrappers on a non type-safe base implementation.

Use "Accessor" (Get/Set) functions when they add value

There is a philosophy of class design that suggests that all data members should be private or protected and that accessor functions should be used to change the values in those data members. MFC uses public data members instead, frequently offering both a public data member and an accessor function for use by the developer. For example, class CWnd provides both a public data member, CWnd::m_hWnd, and an accessor function, CWnd::GetSafeHwnd. Depending on the needs of a particular application, a developer might use the data member or the member function, or both.

More often, MFC uses accessor functions in significant operations such as setting and retrieving style settings, returning pointers, and obtaining values used in other operations. We encourage developers who are writing MFC-friendly classes to use public data members as often as possible, and reserve accessor functions for operations that do more than simply change values in a data member, such as incrementing a counter or updating another function.

Use a thin layer over the Windows API

Part of MFC’s success lies in the fact that the framework is a very thin layer over the Windows API. Most of the time MFC "wraps" the Windows functionality in C++ without adding functionality. In some cases (for example, dialog boxes), MFC greatly simplifies the Windows API by managing the details for you, but the general rule is to keep the layer as thin as possible. This principle also applies to the Windows Open Services Architecture (WOSA) APIs.

By keeping the framework layer very thin, developers can manipulate aspects of the Windows API more directly while still taking advantage of the power of C++. This layer can be especially helpful in HANDLE-based APIs such as the graphics device interface (GDI) HDCs and USER HWNDS.

To make your classes truly MFC-friendly, we recommend that you keep the encapsulation of any Windows API functions as simple as possible. Remember, however, to allow developers to call the Windows API directly whenever they need it.

Table 1 shows examples of the relationship between MFC and the Windows API, as well as common naming conventions used with these objects.

Table 1. Relationships Between MFC and Windows Handles, Controls, and Structures

Windows Type Example Variable MFC Class Example Object
HWND hWnd; CWnd* pWnd;
HDLG hDlg; CDialog* pDlg;
HDC hDC; CDC* pDC;
HGDIOBJ hGdiObj; CGdiObject* pGdiObj;
HPEN hPen; CPen* pPen;1
HBRUSH hBrush; CBrush* pBrush;1
HFONT hFont; CFont* pFont;1
HBITMAP hBitmap; CBitmap* pBitmap;1
HPALETTE hPalette; CPalette* pPalette;1
HRGN hRgn; CRgn* pRgn;1
HMENU hMenu; CMenu* pMenu;1
HWND hCtl; CStatic* pStatic;2
HWND hCtl; CButton* pBtn;2
HWND hCtl; CEdit* pEdit;2
HWND hCtl; CListBox* pListBox;2
HWND hCtl; CComboBox* pComboBox;2
HWND hCtl; CScrollBar* pScrollbar;2
HSZ hszStr; CString pStr;2
POINT pt; CPoint pt;
SIZE size; CSize size;
RECT rect; CRect rect;

* Most OLE data types are wrapped by the COleVariant class. Other MFC classes used with COleVariant include COleDateTime, COleDateTimeSpan, and COleCurrency.
1. Graphics device interface (GDI) objects typically are allocated as local variables on the stack frame. When allocated as such, the convention is to name them without a prefix, in lowercase characters; for example, CPen pen.
2. Controls typically are allocated at the same time the parent window is allocated, and usually are embedded by value in the parent window. For example, a CDialog that contains a CButton object will declare a member variable as CButton m_button.

Understand the Differences between Value and Framework Classes

MFC uses two types of classes as the basis for the class library: "value" classes and "framework" classes.

Value classes are encapsulations of single structures that contain values such as a string or coordinates. The MFC value classes allow you to manipulate these values in an efficient manner. Some of the classes (for example, CPoint) add to the basic Windows functionality to make the classes easier to use.

Framework classes are derived from CObject. These classes provide the basic requirements of a Windows application and encapsulate much of the Windows interface. In some cases the framework classes are a very thin encapsulation of the Windows API, and in other cases the MFC classes add a lot of value to make the manipulation of Windows API details easy to manage.

Table 2 describes some of the characteristics of "value" and "framework" classes.

Table 2. Value and Framework Class Characteristics

Characteristics Value Framework
Has virtual functions? No Yes
Is a base class? No CObject derived
Is designed for direct usage? Yes Maybe
Is designed to be derived from? No Yes
Has an operator=? Usually No
Has a copy constructor? Usually No
Acts like built-in type? Usually No
Comparing values is meaningful? Usually No
Comparing address is meaningful? No Yes (address is identity)

Use const to Control Accessibility of Data Members

Using const in your code is a way to protect the accessibility of data. In general, developers could use const more often than they do, and in MFC const is used whenever feasible to make the data less vulnerable. We encourage you to apply const to your data members as often as possible as a guarantee to your users that your accessor functions do not have hidden side effects. This is particularly important because you will derive other classes and objects from the MFC-friendly classes that you write.

Passing Parameters

It is important to safeguard the data in your value classes by using the following principles:

To pass as an input parameter:

To determine return values:

Avoid Overloading operator = and Copy Constructors

The majority of the classes you will create as extensions to MFC will be framework-type classes. For those classes, you should keep to a safe subset of C++ functions. If you do create value classes, be sure to use all the advantages of the C++ language as MFC has done with its value classes. CString and CRect are good examples of classes to review for these features.

In general, framework objects do not behave like the types built-in to C++, so you cannot add them or assign them the way you would with value objects. Deciding what semantics the operator = would represent would be arbitrary, so avoid including this operator in your framework classes. In many such MFC classes provision is made for copying in such a way to protect the integrity of the data. For example, in the template collection classes, you cannot do the following:

CArray myarray1; 
CArray myarray2; 
... (insertion of data) 
myarray1=myarray2; 
You can, however, do this: 
CArray myarray1; 
CArray myarray2; 
... (insertion of data) 
myarray2.RemoveAll(); 
myarray2.Append(myarray1); 

For more information, see "General Rules for Operator Overloading" in the C++ Language Reference in the Visual C++ online documentation (MSDN Library, Developer Products, Visual C++).

Along the same lines, avoid overloading copy constructors in framework classes. The type of the copy constructor's argument should be "const classname&" whenever possible. This prevents the copy constructor from accidentally changing the object from which it is copying. It also allows copying from const objects.

Follow MFC's Conventions

MFC uses a set of conventions to make it easy to identify elements of the code. We recommend that you follow these simple conventions to leverage the ease-of-identification found in MFC.

Use the Windows API Data Types, API Names, and Message Names

MFC uses the Windows API types, API names, and message names whenever possible as the basis for naming classes and functions in the class library. This makes it easy to determine that the Windows API is encapsulated by an MFC member function. MFC’s member function names do not clash with those found in the Windows API because they operate within a class scope rather than a file scope. On occasion you might need to call a Windows API function instead of an MFC function, and you can do that using the global scoping operator (::). When you write MFC-friendly classes, we encourage you to follow the same conventions to make it easy for your users to understand your intentions.

Follow the MFC Conventions for Commenting Source Code

In both the MFC source files and the files that AppWizard creates, you will find comments like these within class declarations (usually in this order):

// Constructors

// Attributes

// Operations

// Overridables

// Implementation

MFC uses these commenting conventions to delineate the sections of the class declarations containing similar kinds of class members. Some classes omit some sections but all classes have at least the //Implementation section, and larger classes may have additional sections besides those listed above.

Following these and other conventions outlined in the article "MFC: Using the MFC Source Files" in the Visual C++ Programmer’s Guide found in the online documentation is optional, of course. However, doing so makes it easy for your users to find the functions they need in your header files.

Use Simplified Hungarian Notation

The following tables describe the subset of Hungarian notation used in MFC. Table 3 shows general prefix naming conventions. Note that all class names and structure names begin with the letter "C", and member variables are preceded by m_.

Table 3. General Prefix Naming Conventions

Prefix Type Example
C Class or structure CDocument, CPrintInfo
m_ Member variable m_pDoc, m_nCustomers

You may notice the absence of static member variables in Table 3. Static member variables are not really members of the object (that is to say, the instantiation of the class). Static member variables are global variables whose "namespace" is within the context of a class. Since global variables are not prefixed, static member variables are not prefixed.

Table 4 lists the prefixes MFC uses for naming variables. If you use these naming conventions in your MFC-friendly classes, users of your classes will appreciate the consistency between your code and MFC.

Table 4. Variable Prefix Naming Conventions

Prefix Type Description Example
ch char 8-bit character chGrade
ch TCHAR 16-bit character if _UNICODE is defined chName
b BOOL Boolean value bEnabled
n int Integer (size dependent on operating system) nLength
n UINT Unsigned value (size dependent on operating system) nLength
w WORD 16-bit unsigned value wPos
l LONG 32-bit signed integer lOffset
dw DWORD 32-bit unsigned integer dwRange
p * Pointer pDoc
lp FAR* Far pointer lpDoc
lpsz LPSTR 32-bit pointer to character string lpszName
lpsz LPCSTR 32-bit pointer to constant character string lpszName
lpsz LPCTSTR 32-bit pointer to constant character string if _UNICODE is defined lpszName
h handle Handle to Windows object hWnd
lpfn callback Far pointer to CALLBACK function lpfnAbort

Know and Use Other MFC Conventions

Consistency with MFC helps flatten the learning curve for your users since they will recognize the MFC conventions in your classes and already know what they mean.

Table 5 shows symbols generated and used by AppWizard and ClassWizard in MFC applications. You can also use these prefixes in classes and resource files in your MFC-friendly classes.

Table 5. Symbols Used by Applications

Prefix Type of Symbol Example Range
IDR_ Identification shared by multiple resources of different types. IDR_MAINFRAME 1 to 0x6FFF
IDD_ Dialog resource IDD_SPELL_CHECK 1 to 0x6FFF
HIDD_ Dialog-resource Help context HIDD_SPELL_CHECK 0x20001 to 0x26FF
IDB_ Bitmap resource IDB_COMPANY_LOGO 1 to 0x6FFF
IDC_ Cursor resource IDC_PENCIL 1 to 0x6FFF
IDI_ Icon resource IDI_NOTEPAD 1 to 0x6FFF
ID_ _ Command from menu item or toolbar ID_TOOLS_SPELLING 0x8000 to 0xDFFF
HID_ Command Help context HID_TOOLS_SPELLING 0x18000 to 0x1DFFF
IDP_ Message-box prompt IDP_INVALID_PARTNO 8 to 0xDFFF
HIDP_ Message-box Help context HIDP_INVALID_PARTNO 0x30008 to 0x3DFFF
IDS_ String resource IDS_COPYRIGHT 1 to 0x7FFF
IDC_ Control within dialog box IDC_RECALC 8 to 0xDFFF

Table 6 describes some macros used in the framework. For more information on the DEBUG macro, see the article "Diagnostics" in the Visual C++ Programmer’s Guide in the online documentation. The AFXAPI and CALLBACK macros mark specific types of MFC functions.

Table 6. Configuration Macros Used in MFC

Macro Name Type of Macro
_AFXDLL Stand-alone dynamic-link library (DLL) version
_ALPHA Compilation for the DEC Alpha processor only
_DEBUG Debug version including diagnostics
_MBCS Compilation for multi-byte character sets
_UNICODE Enables Unicode in an application
AFXAPI1 Function provided by MFC
CALLBACK Function called back via pointer

1. Reserved for use by MFC.

Make Your Classes Flexible

The classes you create should be flexible enough to be used in ways you did not originally intend for them to be used. Here are some guidelines for creating flexible classes.

Limit the Use of "Private" in Your Classes

It is important that your users be able to use your MFC-friendly classes in ways that you might not have originally intended. By keeping the majority of member functions, data members, and operators public, you allow for flexibility in their use. In MFC, even functions declared in the //Implementation section of a class are usually public or protected.

If you are concerned about future changes to functions within your classes that might break functionality, put those functions below the //Implementation line in your code (even if they are declared public). This will indicate that functions in this section should not be relied upon to remain the same in future versions of your classes.

Remember to Include Virtual Destructors for Your Class

Remember to declare virtual destructors for your classes if they include virtual functions. Using virtual destructors, you can destroy objects without knowing their type—the correct destructor for the object is invoked using the virtual function mechanism. For rules on declaring virtual destructors, see "Declaring Destructors" in the C++ Language Reference in the Visual C++ online documentation.

Allow for Unicode and ANSI Variants in Your Code

Portability makes your classes more appealing to other developers. Classes that you write as extensions of MFC should allow for Unicode and ANSI variants so that the code is easy to port to other platforms. By using TCHAR in your code, you have the flexibility of creating generic and Unicode-enabled builds with a few simple changes in the build definition.

Unicode is available only under Windows NT. For more information on Unicode, see the article "Unicode Programming Summary" in the Visual C++ Programmer’s Guide in the online documentation.

Make Your Code MBCS-Aware

MFC is also fully enabled for multibyte character sets (MBCS), specifically for double-byte character sets (DBCS). DBCS characters are composed of one or two bytes. Some ranges of bytes are set aside for use as "lead bytes." A lead byte specifies that it and the following "trail byte" comprise a single two-byte-wide character. You must keep track of which bytes are lead bytes.

MBCS is a good alternative to Unicode, and we encourage you to also MBCS-enable classes you write as extensions to MFC. For more information on MBCS, see "Support for Multibyte Character Sets (MBCS)" in the Visual C++ Programmer’s Guide in the online documentation.

Put Localizable Strings in an Included Resource File

If your classes contain strings that need to be localized (translated) because they appear in an interface, be sure to put the strings into your resource file rather than coding them elsewhere in an application. In your header and implementation files, use the functions in MFC that refer to localizable strings by ID number rather than, for example, supplying a caption as an argument in a function. It is much easier to maintain your resources by ID than referring to resources by their values.

Use MFC to Create Your Classes

Take advantage of the thousands of lines of pretested, versatile code included in the MFC sources to speed construction of your classes. You can leverage the carefully designed code in MFC to save yourself hundreds of hours of work. In addition, by following the recommendations outlined below, your code will be compatible with MFC.

Derive from Class CObject If Your Class Has Virtual Member Functions

If classes you write as extensions to MFC contain virtual functions, be sure to base them on CObject. If your class already has virtual functions, adding the CObject vtbl entries doesn’t add to the size of the object, since you already have the overhead of a vtbl pointer in your object. CObject provides a number of services including serialization, run-time class information, and object diagnostic output. The cost of deriving your class from CObject is minimal: your derived class will have the overhead of four virtual functions and a single CRuntimeClass object. Refer to Table 2 for more information.

Use Class CString for Manipulating Strings

Class CString is a robust, flexible, safe way to manipulate strings in your code. CString can store up to INT_MAX (2,145,483,647) characters, and has a built-in memory allocation feature that allows the CString object to grow if necessary. A CString object can also behave like a literal C-style string, and can be substituted for character pointers in function calls. Although class CString is not implemented as an MFC collection class, CString objects can be stored as elements of a collection. We recommend that you use CString in your MFC-friendly classes.

Use CString for String Return Values

Using class CString for string return values in your classes instead of C-style strings gives you several advantages.

Provide CString Overloads When Advantageous

Make conversions between your own data types and class CString as easy as possible. Using CString parameters is often more convenient than using LPCTSTR. This is especially true if the parameter can contain embedded NUL characters, or if the function requires a separate length parameter. A good example for study is CDC::TextOut.

Use CDC* and CWnd* When Possible

Use pointers to the MFC CWnd and CDC objects rather than hWnd or hDC handles in Windows. MFC’s encapsulation of the Windows functionality in these classes provides some advantages to using these objects over the direct use of the equivalent Windows handles:

If a temporary C++ object is needed to encapsulate an hWnd or hDC, the object is created for you by MFC and destroyed automatically when the object goes out of scope.

CDC and CWnd present a simpler interface to most of the Windows APIs they encapsulate.

Create MFC Extension DLLs from Your Classes

The most effective way to make the classes you write available to users is to create an MFC Extension Dynamic Link Library (DLL). Extension DLLs can be prepared in a variety of formats. For example, you can create versions that are Unicode-enabled or not, debug or retail, and so on.

The Extension DLLs for MFC use the following naming conventions. The library names have the form

uAFXCWd.LIB

where the letters shown in italic lowercase are place holders for specifiers, as shown in Table 7.

Table 7. Library Naming Conventions

Specifier Values and Meaning
u ANSI (N) or Unicode (U)
d Debug or Release: D=Debug; omit specifier for Release

Table 8 shows examples of how static versions of the MFC libraries are prepared and named.

Table 8. Static Library Versions

Library Description
NAFXCWD.LIB Debug version: MFC Static Link Library
NAFXCW.LIB Release version: MFC Static Link Library
UAFXCWD.LIB Debug version: MFC Static Link Library with Unicode support
UAFXCW.LIB Release version: MFC Static Link Library with Unicode support

We recommend that you prepare your MFC-friendly classes as an MFC Extension Dynamic Link Library (DLL) or as a static library (LIB) using a variation of the naming scheme described above.

Table 9 describes the macros that are used in the creation of MFC Extension DLLs.

Table 9. Macros Used With Dynamic Link Libraries (DLLs)

Macro Name Type of Macro
_AFXDLL Stand-alone dynamic-link library (DLL) version
WINAPI Function provided by Windows

For more information on creating an MFC Extension DLL, see the article "DLLs: Building and Using an Extension DLL" in the Visual C++ Programmer’s Guide in the online documentation.

Use #pragma comment to Conditionally Include Your Classes

The #pragma directives offer a way for a compiler to offer machine- or operating system-specific features while retaining overall compatibility with the C++ language. MFC uses the #pragma comment preprocessor directive in AFX.H to determine which version of the MFC library to link with an application when it is compiled.

You can use the same method to assist your users in determining which version of your MFC Extension DLL the compiler should use.

For example, the following code fragment from the AFX.H header file instructs the linker to link in either the NAFXCWD.LIB or NAFXCW.LIB version of MFC, depending on whether you are using the debug version of MFC:

#ifndef _UNICODE 
#ifdef _DEBUG 
#pragma comment(lib, "nafxcwd.lib") 
#else 
#pragma comment(lib, "nafxcw.lib") 
#endif 
#else 
#ifdef _DEBUG 
#pragma comment(lib, "uafxcwd.lib") 
#else 
#pragma comment(lib, "uafxcw.lib") 
#endif 
#endif... 

For more information on the #pragma comment preprocessor directive, see "Pragma Directives" and "MFC Library Versions" in the Visual C++ Programmer’s Guide, both found in the online documentation (MSDN Library, Developer Products, Visual C++).

Write Thorough Documentation to Help Your Users

When you finish writing your classes, make sure that users understand and can use the full potential of your work by documenting the classes thoroughly. Writing good reference documentation is important, but you can also write encyclopedia articles, technical notes, and samples help that explain how to use the classes. The MFC documentation has a consistent and accessible style that we describe in the remaining sections of this paper.

The documentation included with the Microsoft Foundation Class Library consists of the Class Library Reference, the MFC Technical Notes, MFC-specific articles in the Visual C++ Programmer’s Guide, the sample abstracts that accompany the MFC Samples, and tutorials found in the Visual C++ Tutorials. The MFC documentation in general has a clear, friendly style that avoids the use of jargon and obscure terms.

The Visual C++ documentation uses a common set of conventions that assist readers in identifying elements of documentation such as code, keyboard key names, procedures, and so on. We suggest that you follow these conventions as you prepare documentation for the classes you write as extensions to MFC. Here are the Documentation Conventions used in the Visual C++ online documentation.

Example Description
STDIO.H Uppercase letters indicate filenames, segment names, registers, and terms used at the operating-system command level.
expression Words in italics indicate placeholders for information you must supply, such as a filename. Italic type is also occasionally used for emphasis in the text.
char, _setcolor, _ _far Bold type indicates keywords, operators, language-specific characters, and library routines. Within discussions of syntax, bold type indicates the text must be entered exactly as shown.
    Many functions and constants begin with either a single or double underscore. These are part of the name and are mandatory. For example, to have the _ _cplusplus manifest constant be recognized by the compiler, you must enter the leading double underscore.
[option] Items inside square brackets are optional.
#pragma pack {1 | 2} Braces and a vertical bar indicate a choice among two or more items. You must choose one of these items unless square brackets surround the braces: [ { | } ].
#include <io.h> This font is used for examples, user input, program output, and error messages in text.
CL [option...] file... Three dots (an ellipsis) following an item indicate that more items having the same form can appear.
while()
.
.
.
}
A column or row of three dots tells you that part of an example program has been intentionally omitted.
CTRL+ENTER Small capital letters are used to indicate the names of keys on the keyboard. When you see a plus sign (+) between two key names, you should hold down the first key while pressing the second.
    The carriage-return key, sometimes marked as a bent arrow on the keyboard, is called ENTER.
"argument" Quotation marks enclose a new term the first time it is defined in text.
"C string" Some C constructs, such as strings, require quotation marks.
Color/Graphics Adapter (CGA) The first time an acronym is used, it is usually spelled out.

Match the Structure and Conventions of the MFC Reference

The Class Library Reference is the cornerstone of the MFC documentation. This volume contains descriptions of all of the class members in the Library that appear above the //Implementation line in the MFC source code. Each class has a corresponding Overview, Member Functions list, and individual descriptions of the member functions, data members, and operators in each class. We recommend that you follow this structure and the conventions in this book to make it easy for your users to find the information they need.

Write Class Overviews and Member Function Lists

The individual class Overviews describe the class in just enough detail to help developers decide whether this is the class they want. The Overview points readers to articles in the Visual C++ Programmer’s Guide for details. Here’s what a class overview should do:

The Member Functions list in each class corresponds to sections that appear in MFC source code. In some classes, additional sections in the Class Library Reference further categorize the member functions to make them easy to locate. Each member function, data member, and operator in a class should have an entry in the list, along with a one or two sentence description.

Write Detailed Member Function Descriptions

Each member function, data member, and operator that appears above the //Implementation line in the class has an individual description. Each description has one or more of the following six sections that appear in a specific order:

When viewed online, the See Also entries include hypertext jumps to the individual class Overview, the list of Class Member functions, and the Hierarchy Chart that applies to the class, as well as cross references to other member functions in that class.

Note carefully the use of bold, italics, and alternate fonts in the documentation. These help readers distinguish between example code, syntax, and parameters. Whenever the Windows API functions are cited, they are preceded with the global scoping operator ( for example, ::GetSystemMetrics).

Write Encyclopedia Articles for Your Classes (Optional)

The Visual C++ Programmer’s Guide is a procedural and encyclopedic manual that contains articles that describe aspects of programming with C++ and MFC. The articles in this book offer both an overview and procedures you can use in specific situations by functional area. Table 10 describes characteristics of the sections of the Visual C++ Programmer’s Guide.

Table 10. Articles in the Visual C++ Programmer’s Guide

Purpose Description Level of Information
Overview Descriptions of the topic with links to further information High-level overviews, e.g. "Database Overview"
How Do I? Lists of tasks with links to further information Lists of possible tasks
Frequently Asked Questions Short answers to common questions with links to other information. Easy to find information
Details Procedural articles and sub-articles In-depth conceptual and procedural information

Including encyclopedic articles with your MFC-friendly class documentation is optional. Nevertheless, we encourage you to at least include a conceptual overview of the uses of your classes (in addition to the one in the Reference section) so that developers can take full advantage of the power and flexibility in your classes. By providing adequate documentation up front, you can avoid or reduce costly product support calls, and ensure customer satisfaction both now and in the future.

Balance Conceptual Information Between Overviews and Articles

Ideally, a class overview included with reference material should contain a short description of the class, a set of high-level procedures for using the class, and cross-references to similar or related classes. The class overview should serve as a quick summary that a developer can read to decide whether the class you have written is the appropriate class for their need. Save any lengthy or detailed descriptions of the class usage for encyclopedic articles.

Prepare Technical Notes (Optional)

The MFC Technical Notes "are written by developers for developers." The Technical Notes cover advanced techniques in specific areas, and offer a level of technical detail that average developers don’t normally require to do their work.

Writing technical notes for your MFC-friendly classes is optional. When used sparingly and for very specific situations, technical notes can be an invaluable resource for unusual situations. Review the MFC Technical Notes for ideas on how you can write your own to your best advantage.

Write Help Files for Your MFC Samples

Sample code is an essential part of any documentation, and providing sample applications for your users is the best way for them to understand the intent and usage of your MFC-friendly classes. MFC provides a substantial number of samples as part of their documentation, and abstracts of each MFC sample appear in Visual C++ Samples, MFC Samples, in the online documentation.

The MFC Samples abstracts contain individual descriptions of the features of the sample. You can find an alphabetical list of samples and a cross-reference index by subject under "MFC Samples Index" in Visual C++ Samples in the online documentation.

We highly recommend that you document your samples in a similar help file. Developers can refer again and again to these descriptions to help them locate code they can use in their own applications.

In Conclusion

We have covered general principles for developing "MFC-friendly" classes, given examples of how to make your classes robust as well as practical, and outlined methods for documenting your work. We encourage you to follow up on references to the documentation for more information on these principles. You can also get help in class design from the sources listed below.

CompuServe Forums

Developer forums

These forums cover developer-specific information on the Windows operating system, languages, tools, and utilities. (For example, you can find forums on development products by typing GO MSDEVPROD.) You can use these forums to exchange messages with experienced users of Microsoft development products. Microsoft support engineers act as section leaders and monitor the forums to ensure complete and accurate information flow and to provide general technical information on Microsoft development products.

Developer Knowledge Base

This comprehensive database contains more than 40,000 detailed articles with technical information about Microsoft development products, bug lists, fix lists, documentation errors, and answers to common technical support questions. The Knowledge Base is a primary Microsoft product information source used daily by Microsoft support engineers. You can search the Knowledge Base by keyword, and files can be downloaded for local use. Many Microsoft Knowledge Base articles have associated Software Library items (MSDN Library, Knowledge Base).

Software Library

This Library contains sample programs, device drivers, patches, software updates, programming aids, and downloadable application notes and white papers. The entire library can be searched by keyword, and the files can be downloaded for local use. To help you quickly evaluate items, a brief text description is displayed when you view each item. Additionally, many Software Library items have associated Microsoft Knowledge Base articles that more fully discuss the subject. For the Software Library, type GO MSL.