Microsoft Corporation
Updated March 31, 1997
Design Goals of the MFC Class Library
Guidelines for Writing Class Library Extensions
Use MFC to Create Your Classes
Write Thorough Documentation to Help Your Users
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.
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.
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.
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.
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.
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.
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++).
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.
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.
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.
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.
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) |
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.
It is important to safeguard the data in your value classes by using the following principles:
To pass as an input parameter:
void Do(CMyValue val);
void Do( const CMyValue& val );
// from the caller's perspective these look the same
void Do( const CMyView* pob );
To pass as an output parameter:
void GetSomething( CMyValue* pval );
void UpdateSomething( CMyView* pob );
Passing value objects as input/output parameters should be avoided. If you must, you can use a non-const pointer, or a non-const reference. Ideally, however, you should stay away from passing value objects in this manner.
void UpdateSomething( CMyView* pob );
To determine return values:
CMyValue GetCurrentValue();
CMyView* GetCurrentView();
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.
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.
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.
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.
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 |
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.
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.
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 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.
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.
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.
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.
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.
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.
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.
Using class CString for string return values in your classes instead of C-style strings gives you several advantages.
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 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.
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.
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++).
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. |
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.
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.
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).
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.
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.
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.
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.
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.
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.
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).
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.