Special Edition Using Visual C++ 6

Previous chapterNext chapterContents


- E -

MFC Macros and Globals


When you're writing programs, you must use many types of data and operations again and again. Sometimes, you have to do something as simple as creating a portable integer data type. Other times, you need to do something a little more complex, such as extracting a word from a long word value or storing the position of the mouse pointer. As you might know, when you compile your program with Visual C++, many constants and variables are already defined. You can use these in your programs to save time writing code and to make your programs more portable and more readable for other programmers. In the following tables, you'll have a look at the most important of these globally available constants, macros, and variables.

Because there are so many constants, macros, and global variables, it is helpful to divide them into the following ten categories. The next sections describe each of these categories and the symbols they define:

Application Information and Management Functions

Because a typical Visual C++ application contains only one application object but many other objects created from other MFC classes, you frequently need to obtain information about the application in different places in a program. Visual C++ defines a set of global functions that return this information to any class in a program. These functions, listed in Table E.1, can be called from anywhere within an MFC program. For example, you frequently need to get a pointer to an application's main window. The following function call accomplishes that task:

CWnd* pWnd = AfxGetMainWnd();

Table E.1  Application Information and Management

Function Description
AfxBeginThread() Creates a new thread (see Chapter 27, "Multitasking with Windows Threads")
AfxEndThread() Terminates a thread
AfxGetApp() Gets the application's CWinApp pointer
AfxGetAppName() Gets the application's name
AfxGetInstanceHandle() Gets the application's instance handle
AfxGetMainWnd() Gets a pointer to the application's main window
AfxGetResourceHandle() Gets the application's resource handle
AfxGetThread() Gets a pointer to a CWinThread object
AfxRegisterClass() Registers a window class in an MFC DLL
AfxRegisterWndClass() Registers a Windows window class in an MFC application
AfxSetResourceHandle() Sets the instance handle that determines where to load the application's default resources
AfxSocketInit() Initializes Windows Sockets (see Chapter 18, "Sockets, MAPI, and the Internet")

ClassWizard Comment Delimiters

Visual C++ defines a number of delimiters that ClassWizard uses to keep track of what it's doing, as well as to locate specific areas of source code. Although you'll rarely, if ever, use these macros yourself, you will see them embedded in your AppWizard applications, so you might like to know exactly what they do. Table E.2 fills you in.

Table E.2  ClassWizard Delimiters

Delimiter Description
AFX_DATA Starts and ends member variable declarations in header files that are associated with dialog data exchange
AFX_DATA_INIT Starts and ends dialog data exchange variable initialization in a dialog class's constructor
AFX_DATA_MAP Starts and ends dialog data exchange function calls in a dialog class's DoDataExchange() function
AFX_DISP Starts and ends Automation declarations in header files
AFX_DISP_MAP Starts and ends Automation mapping in implementation files
AFX_EVENT Starts and ends ActiveX event declarations in header files
AFX_EVENT_MAP Starts and ends ActiveX events in implementation files
AFX_FIELD Starts and ends member variable declarations in header files that are associated with database record field exchange
AFX_FIELD_INIT Starts and ends record field exchange member variable initialization in a record set class's constructor
AFX_FIELD_MAP Starts and ends record field exchange function calls in a record set class's DoFieldExchange() function
AFX_MSG Starts and ends ClassWizard entries in header files for classes that use message maps
AFX_MSG_MAP Starts and ends message map entries
AFX_VIRTUAL Starts and ends virtual function overrides in header files

Collection Class Helper Functions

Because certain types of data structures are so commonly used in programming, MFC defines collection classes that enable you to get these common data structures initialized quickly and manipulated easily. MFC includes collection classes for arrays, linked lists, and mapping tables. (See Appendix F, "Useful Classes," for more on these constructs.) Each of these types of collections contains elements that represent the individual pieces of data that compose the collection. To make it easier to access these elements, MFC defines a set of functions created from templates (see Chapter 26, "Exceptions and Templates," for more on templates.) Table E.3 shows the functions, and you provide the implementation for each particular data type.

For example, if you want to keep a sorted list, the functions that insert new items into the list must be able to compare two Truck objects or two Employee objects to decide where to put a new Truck or Employee. You implement CompareElements() for the Truck class or Employee class, and then the collection class code can use this function to decide where to put new additions to the collection.

Table E.3  Collection Class Helper Functions

Function Description
CompareElements() Checks elements for equality
ConstructElements() Constructs new elements (works similar to a class constructor)
DestructElements() Destroys elements (works similar to a class destructor)
DumpElements() Provides diagnostic output in text form
HashKey() Calculates hashing keys
SerializeElements() Saves or loads elements to or from an archive

CString Formatting and Message-Box Display

If you've done much Visual C++ programming, you know that MFC features a special string class, called CString, that makes string handling under C++ less cumbersome. CString objects are used extensively throughout MFC programs and are discussed in Appendix F. There are times when CString is not the right class, though, such as when dealing with strings in a resource's string table. These global functions, which replace format characters in string tables, provide the CString Format() capability for resource strings. There's also a global function for displaying a message box.

Table E.4  CString Formatting and Message-Box Functions

Function Description
AfxFormatString1() Replaces the format characters (such as %1) in a string resource with a given string
AfxFormatString2() Replaces the format characters %1 and %2 in a string resource with the given strings
AfxMessageBox() Displays a message box

Data Types

The most commonly used constants are those that define a portable set of data types. You've seen tons of these constants (named in all uppercase letters) used in Windows programs. You'll recognize many of these from the Windows SDK. Others are included only as part of Visual C++. You use these constants exactly as you would any other data type. For example, to declare an unsigned integer variable, you'd write something like this:

UINT flag;

Table E.5 lists the most commonly used data types defined by Visual C++ for Windows 95/98 and NT. Searching in the help index on any one of these types will lead you to a page in the online help that lists all the data types used in MFC and the Windows SDK.

Table E.5  Commonly Used Data Types

Data Type Description
BOOL Boolean value
BSTR 32-bit pointer to character data
BYTE 8-bit unsigned integer
COLORREF 32-bit color value
DWORD 32-bit unsigned integer
LONG 32-bit signed integer
LPARAM 32-bit window-procedure parameter
LPCRECT 32-bit constant RECT structure pointer
LPCSTR 32-bit string-constant pointer
LPSTR 32-bit string pointer
LPVOID 32-bit void pointer
LRESULT 32-bit window-procedure return value
POSITION The position of an element in a collection
UINT 32-bit unsigned integer
WNDPROC 32-bit window-procedure pointer
WORD 16-bit unsigned integer
WPARAM 32-bit window-procedure parameter

Diagnostic Services

When you have written your program, you're far from finished. Then comes the grueling task of testing, which means rolling up your sleeves, cranking up your debugger, and weeding out all the gotchas hiding in your code. Luckily, Visual C++ provides many macros, functions, and global variables for incorporating diagnostic abilities into your projects. By using these tools, you can print output to a debugging window, check the integrity of memory blocks, and much more. Table E.6 lists these valuable diagnostic macros, functions, and global variables. Many are discussed in Chapter 24, "Improving Your Application's Performance," and Appendix D, "Debugging."

Table E.6  Diagnostic Macros, Functions, and Global Variables

Symbol Description
AfxCheckMemory() Verifies the integrity of allocated memory.
AfxDoForAllClasses() Calls a given iteration function for all classes that are derived from CObject and that incorporate runtime type checking.
AfxDoForAllObjects() Calls a given iteration function for all objects derived from CObject and allocated with the new operator.
afxDump A global CDumpContext object that enables a program to send information to the debugger window.
AfxDump() Dumps an object's state during a debugging session.
AfxEnableMemoryTracking() Toggles memory tracking.
AfxIsMemoryBlock() Checks that memory allocation was successful.
AfxIsValidAddress() Checks that a memory address range is valid for the program.
AfxIsValidString() Checks string pointer validity.
afxMemDF A global variable that controls memory-allocation diagnostics. It can be set to allocMemDF, DelayFreeMemDF, or checkAlwaysMemDF.
AfxSetAllocHook() Sets a user-defined hook function that is called whenever memory allocation is performed.
afxTraceEnabled A global variable that enables or disables TRACE output.
afxTraceFlags A global variable that enables the MFC reporting features.
ASSERT Prints a message and exits the program if the ASSERT expression is FALSE (see Chapter 24).
ASSERT_VALID Validates an object by calling the object's AssertValid() function.
DEBUG_NEW Used in place of the new operator to trace memory-leak problems (see Chapter 23).
TRACE Creates formatted strings for debugging output (see Chapter 23).
TRACE0 Same as TRACE but requires no arguments in the format string.
TRACE1 Same as TRACE but requires one argument in the format string.
TRACE2 Same as TRACE but requires two arguments in the format string.
TRACE3 Same as TRACE but requires three arguments in the format string.
VERIFY Like ASSERT, but VERIFY evaluates the ASSERT expression in both the debug and release versions of MFC. If the assertion fails, a message is printed and the program is halted only in the debug version.

Exception Processing

Exceptions give a program greater control over how errors are handled (see Chapter 26). Before exceptions were part of the language, MFC developers used macros to achieve the same results. Now that exceptions are firmly established in Visual C++, a number of functions make it easier to throw exceptions of various types. These macros and functions are listed in Table E.7.

Table E.7  Exception Macros and Functions

Symbol Description
AfxAbort() Terminates an application upon a fatal error
AfxThrowArchiveException() Throws an archive exception
AfxThrowDAOException() Throws a CDAOException
AfxThrowDBException() Throws a CDBException
AfxThrowFileException() Throws a file exception
AfxThrowMemoryException() Throws a memory exception
AfxThrowNotSupportedException() Throws a not-supported exception
AfxThrowOleDispatchException() Throws an OLE automation exception
AfxThrowOleException() Throws an OLE exception
AfxThrowResourceException() Throws a resource-not-found exception
AfxThrowUserException() Throws an end user exception
AND_CATCH Begins code that will catch specified exceptions not caught in the preceding TRY block
AND_CATCH_ALL Begins code that will catch all exceptions not caught in the preceding TRY block
CATCH Begins code for catching an exception
CATCH_ALL Begins code for catching all exceptions
END_CATCH Ends CATCH or AND_CATCH code blocks
END_CATCH_ALL Ends CATCH_ALL code blocks
THROW Throws a given exception
THROW_LAST Throws the most recent exception to the next handler
TRY Starts code that will accommodate exception handling

Message-Map Macros

Windows is an event-driven operating system, which means that every Windows application must handle a flood of messages that flow between an application and the system. MFC does away with the clunky switch statements that early Windows programmers had to construct to handle messages and replaces those statements with a message map. A message map is nothing more than a table that matches a message with its message handler (see Chapter 3, "Messages and Commands"). To simplify the declaration and definition of these tables, Visual C++ defines a set of message-map macros. Many of these macros, which are listed in Table E.8, will already be familiar to experienced MFC programmers.

Table E.8  Message-Map Macros

Macro Description
BEGIN_MESSAGE_MAP Begins a message-map definition
DECLARE_MESSAGE_MAP Starts a message-map declaration
END_MESSAGE_MAP Ends a message-map definition
ON_COMMAND Begins a command-message message-map entry
ON_COMMAND_RANGE Begins a command-message message-map entry that maps multiple messages to a single handler
ON_CONTROL Begins a control-notification message-map entry
ON_CONTROL_RANGE Begins a control-notification message-map entry that maps multiple control IDs to a single handler
ON_MESSAGE Begins a user-message message-map entry
ON_REGISTERED_MESSAGE Begins a registered user-message message-map entry
ON_UPDATE_COMMAND_UI Begins a command-update message-map entry
ON_UPDATE_COMMAND_UI_RANGE Begins a command-update message-map entry that maps multiple command-update messages to a single handler

Runtime Object Model Services

Frequently in your programs, you need access to information about classes at runtime. MFC supplies a macro for obtaining this type of information in a CRuntimeClass structure. In addition, the MFC application framework relies on a set of macros to declare and define runtime abilities (such as object serialization and dynamic object creation). If you've used AppWizard at all, you've seen these macros in the generated source-code files. If you're an advanced MFC programmer, you might have even used these macros yourself. Table E.9 lists the runtime macros and their descriptions.

Table E.9  Runtime Services Macros

Macro File Description
DECLARE_DYNAMIC Class declaration(.h) Enables runtime class information access
DECLARE_DYNCREATE Class declaration(.h) Enables the class (derived from CObject) to be created dynamically and also enables runtime class information access
DECLARE_OLECREATE Class declaration (.h) Enables object creation with OLE automation
DECLARE_SERIAL Class declaration (.h) Enables object serialization, as well as runtime class information access
IMPLEMENT_DYNAMIC Class implementation (.cpp) Enables runtime class information access
IMPLEMENT_DYNCREATE Class implementation (.cpp) Enables dynamic creation of the object and runtime information access
IMPLEMENT_OLECREATE Class implementation (.cpp) Enables object creation with OLE
IMPLEMENT_SERIAL Class implementation (.cpp) Enables object serialization and runtime class information access
RUNTIME_CLASS Returns a CRuntimeClass structure for the given class

Standard Command and Window IDs

A Windows application user can generate myriad standard messages. For example, whenever the user selects a menu command from a standard menu like File or Edit, the program sends a message. Each standard command is represented by an ID. To relieve the programmer of having to define the dozens of IDs often used in a Windows application, Visual C++ defines these symbols in a file called AFXRES.H. Some of these IDs have obvious purposes (for example, ID_FILE_OPEN), but many others are used internally by MFC for everything from mapping standard Windows messages to their handlers, to defining string-table IDs, to assigning IDs to toolbar and status bar styles.

There are far too many of these identifiers to list here. However, if you're interested in seeing them, just open the AFXRES.H file from your Visual C++ installation folder.


Previous chapterNext chapterContents

© Copyright, Macmillan Computer Publishing. All rights reserved.