MFC Tutorial PDF
MFC Tutorial PDF
The Microsoft Foundation Class (MFC) Library provides an object-oriented wrapper over much of the Win32 and
COM APIs. Although it can be used to create very simple desktop applications, it is most useful when you need to
develop more complex user interfaces with multiple controls. You can use MFC to create applications with Office-
style user interfaces. For documentation on the Windows platform itself, see Windows documentation. For
information on building Windows applications in C++ without MFC, see Build desktop Windows apps using the
Win32 API.
The MFC Reference covers the classes, global functions, global variables, and macros that make up the Microsoft
Foundation Class Library.
The individual hierarchy charts included with each class are useful for locating base classes. The MFC Reference
usually does not describe inherited member functions or inherited operators. For information on these functions,
refer to the base classes depicted in the hierarchy diagrams.
The documentation for each class includes a class overview, a member summary by category, and topics for the
member functions, overloaded operators, and data members.
Public and protected class members are documented only when they are normally used in application programs
or derived classes. See the class header files for a complete listing of class members.
IMPORTANT
The MFC classes and their members cannot be used in applications that execute in the Windows Runtime environment.
MFC libraries (DLLs) for multibyte character encoding (MBCS) are no longer included in Visual Studio, but are available as a
Visual Studio add-on. For more information, see MFC MBCS DLL Add-on.
In This Section
Concepts
Conceptual articles on MFC topics.
Hierarchy Chart
Visually details the class relationships in the class library.
Class Overview
Lists the classes in the MFC Library according to category.
Walkthroughs
Contains articles that walk you through various tasks associated with MFC library features.
Technical Notes
Provides links to specialized topics, written by the MFC development team, on the class library.
Customization for MFC
Provides some tips for customizing your MFC application.
Classes
Provides links to and header file information for the MFC classes.
Internal Classes
Used internally in MFC. For completeness, this section describes these internal classes, but they are not intended
to be used directly in your code.
Macros and Globals
Provides links to the macros and global functions in the MFC Library.
Structures, Styles, Callbacks, and Message Maps
Provides links to the structures, styles, callbacks, and message maps used by the MFC Library.
MFC Wizards and Dialog Boxes
A guide to the features in Visual Studio for creating MFC applications.
Working with Resource Files
How to use resource files to manage static user interface data such as UI strings and dialog box layout.
Related Sections
Hierarchy Chart Categories
Describes the MFC hierarchy chart by category.
ATL/MFC Shared Classes
Provides links to classes that are shared between MFC and ATL.
MFC Samples
Provides links to samples that demonstrate how to use MFC.
Visual C++ Libraries Reference
Provides links to the various libraries provided with Visual C++, including ATL, MFC, OLE DB Templates, the C run-
time library, and the C++ Standard Library.
Debugging in Visual Studio
Provides links to using the Visual Studio debugger to correct logic errors in your application or stored procedures.
See also
MFC and ATL
MFC Concepts
3/24/2020 • 2 minutes to read • Edit Online
This section provides conceptual and task-based topics to help you program using the Microsoft Foundation Class
(MFC) Library.
In This Section
General MFC Topics
Discusses the technical details of the MFC Library.
Using CObject
Provides links to using CObject , the base class for most classes in MFC.
Collections
Discusses collection classes created from and not created from C++ templates.
Date and Time
Provides links to topics discussing using date and time with MFC.
Files
Discusses CFile and how to handle files in MFC.
Memory Management (MFC)
Describes how to take advantage of the general-purpose services related to memory management.
Message Handling and Mapping
Describes how messages and commands are processed by the MFC framework and how to connect them to their
handler functions.
Serialization
Explains the serialization mechanism provided to allow objects to persist between runs of your program.
Related Sections
Exception Handling (MFC)
Explains the exception-handling mechanisms available in MFC.
MFC Internet Programming Basics
Discusses the MFC classes that support Internet programming.
MFC Internet Programming Tasks
Discusses how to add Internet support to your applications.
Unicode and Multibyte Character Set (MBCS) Support
Explains how to use MFC and ATL support for Unicode and multibyte character sets.
MFC COM
Discusses a subset of MFC, which is designed to support COM, while most of the Active Template Library (ATL) is
designed for COM programming.
Multithreading with C++ and MFC
Describes what processes and threads are and discusses the MFC approach to multithreading.
Windows Sockets in MFC
Covers the MFC implementation of Windows Sockets.
MFC Reference
Provides reference material for the MFC Library, a set of classes that constitute an application framework, which is
the framework of an application written for the Windows API.
MFC Samples
Provides links to samples that show how to use MFC in desktop applications, DLLs, database applications,
controls, Web applications, and more.
General MFC Topics
3/24/2020 • 2 minutes to read • Edit Online
This family of articles includes technical details about the Microsoft Foundation Class (MFC) Library and provides
an overview of the MFC framework and its key components and subsystems.
The Microsoft Foundation Class Library is an application framework for programming in Microsoft Windows.
Written in C++, MFC provides much of the code necessary for managing windows, menus, and dialog boxes;
performing basic input/output; storing collections of data objects; and so on. All you need to do is add your
application-specific code into this framework. Given the nature of C++ class programming, it is easy to extend or
override the basic functionality that the MFC framework supplies.
The MFC framework is a powerful approach that lets you build upon the work of expert programmers for
Windows. MFC shortens development time; makes code more portable; provides tremendous support without
reducing programming freedom and flexibility; and gives easy access to "hard to program" user-interface
elements and technologies, like Active technology, OLE, and Internet programming. Furthermore, MFC simplifies
database programming through Data Access Objects (DAO) (now obsolete) and Open Database Connectivity
(ODBC), and network programming through Windows Sockets. MFC makes it easy to program features like
property sheets ("tab dialogs"), print preview, and floating, customizable toolbars.
In This Section
MFC Samples
Using the MFC Source Files
MFC Library Versions
Using the Classes to Write Applications for Windows
Building on the Framework
CWinApp: The Application Class
Document Templates and the Document/View Creation Process
Managing the State Data of MFC Modules
Idle Loop Processing
Support for Activation Contexts in the MFC Module State
Isolation of the MFC Common Controls Library
Build Requirements for Windows Vista Common Controls
How to: Add Restart Manager Support
Dynamic Layout
For an overview of the MFC reference documentation, see Microsoft Foundation Class Library.
For information about ATL, see Active Template Library Reference.
See also
Working with Window Objects
Using the MFC source files
8/20/2019 • 5 minutes to read • Edit Online
The Microsoft Foundation Class (MFC) Library supplies full source code. Header files (.h) are in the \atlmfc\include
directory. Implementation files (.cpp) are in the \atlmfc\src\mfc directory.
This article explains the conventions that MFC uses to comment the various parts of each class, what these
comments mean, and what you should expect to find in each section. The Visual Studio wizards use similar
conventions for the classes that they create for you, and you'll probably find these conventions useful for your own
code.
You might be familiar with the public , protected , and private C++ keywords. In the MFC header files, you'll find
each class may have several of each of them. For example, public member variables and functions might be under
more than one public keyword. It's because MFC separates member variables and functions based on their use,
not by the type of access allowed. MFC uses private sparingly. Even items considered implementation details are
often protected , and many times are public . Although access to the implementation details is discouraged, MFC
leaves the decision to you.
In both the MFC source files and the header files that the MFC Application Wizard creates, you'll find comments like
these ones within class declarations (usually in this order):
// Constructors
// Attributes
// Operations
// Overridables
// Implementation
public:
// Constructors
CStdioFile();
// . . .
// Attributes
FILE* m_pStream; // stdio FILE
// m_hFile from base class is _fileno(m_pStream)
// Operations
// reading and writing strings
virtual void WriteString(LPCTSTR lpsz);
virtual LPTSTR ReadString(_Out_writes_z_(nMax) LPTSTR lpsz, _In_ UINT nMax);
virtual BOOL ReadString(CString& rString);
// Implementation
public:
virtual ~CStdioFile();
#ifdef _DEBUG
void Dump(CDumpContext& dc) const;
#endif
virtual ULONGLONG GetPosition() const;
virtual ULONGLONG GetLength() const;
virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL);
// . . .
protected:
void CommonBaseInit(FILE* pOpenStream, CAtlTransactionManager* pTM);
void CommonInit(LPCTSTR lpszFileName, UINT nOpenFlags, CAtlTransactionManager* pTM);
};
These comments consistently mark sections of the class declaration that contain similar kinds of class members.
Keep in mind that they're MFC conventions, not set rules.
// Constructors comment
The // Constructors section of an MFC class declaration declares constructors (in the C++ sense) and any
initialization functions required to really use the object. For example, CWnd::Create is in the constructors section
because before you use the CWnd object, it must be "fully constructed" by first calling the C++ constructor and
then calling the Create function. Typically, these members are public.
For example, class CStdioFile has five constructors, one of which is shown in the listing under An example of the
comments.
// Attributes comment
The // Attributes section of an MFC class declaration contains the public attributes (or properties) of the object.
Typically the attributes are member variables, or Get/Set functions. The "Get" and "Set" functions may or may not
be virtual. The "Get" functions are often const , because in most cases they don't have side effects. These members
are normally public. Protected and private attributes are typically found in the implementation section.
In the sample listing from class CStdioFile , under An example of the comments, the list includes one member
variable, m_pStream. Class CDC lists nearly 20 members under this comment.
NOTE
Large classes, such as CDC and CWnd , may have so many members that simply listing all the attributes in one group would
not add much to clarity. In such cases, the class library uses other comments as headings to further delineate the members.
For example, CDC uses // Device-Context Functions , // Drawing Tool Functions ,
// Drawing Attribute Functions , and more. Groups that represent attributes will follow the usual syntax described
above. Many OLE classes have an implementation section called // Interface Maps .
// Operations comment
The // Operations section of an MFC class declaration contains member functions that you can call on the object
to make it do things or take actions (perform operations). These functions are typically non-const because they
usually have side effects. They may be virtual or nonvirtual depending on the needs of the class. Typically, these
members are public.
In the sample listing from class CStdioFile , in An example of the comments, the list includes three member
functions under this comment: WriteString and two overloads of ReadString .
// Overridables comment
The // Overridables section of an MFC class declaration contains virtual functions that you can override in a
derived class when you need to modify the base class behavior. They're typically named starting with "On",
although it's not strictly necessary. Functions here are designed to be overridden, and often implement or provide
some sort of "callback" or "hook." Typically, these members are protected.
In MFC itself, pure virtual functions are always placed in this section. A pure virtual function in C++ takes the form:
virtual void OnDraw( ) = 0;
In the sample listing from class CStdioFile , in An example of the comments, the list includes no overridables
section. Class CDocument , on the other hand, lists approximately 10 overridable member functions.
In some classes, you may also see the comment // Advanced Overridables . These functions are ones that only
advanced programmers should attempt to override. You'll probably never need to override them.
NOTE
The conventions described in this article also work well, in general, for Automation (formerly known as OLE Automation)
methods and properties. Automation methods are similar to MFC operations. Automation properties are similar to MFC
attributes. Automation events (supported for ActiveX controls, formerly known as OLE controls) are similar to MFC
overridable member functions.
// Implementation comment
The // Implementation section is the most important part of any MFC class declaration.
This section houses all implementation details. Both member variables and member functions can appear in this
section. Everything below this line could change in a future release of MFC. Unless you can't avoid it, you shouldn't
rely on details below the // Implementation line. In addition, members declared below the implementation line are
undocumented, although some implementation is discussed in technical notes. Overrides of virtual functions in the
base class reside in this section, regardless of which section the base class function is defined in. When a function
overrides the base class implementation, it's considered an implementation detail. Typically, these members are
protected, but not always.
In the CStdioFile listing under An example of the comments, members declared below the // Implementation
comment may be declared as public , protected , or private . Only use these members with caution, because they
may change in the future. Declaring a group of members as public may be necessary for the class library
implementation to work correctly. However, it doesn't mean that you may safely use the members so declared.
NOTE
You may find comments of the remaining types either above or below the // Implementation comment. In either case,
they describe the kinds of members declared below them. If they occur below the // Implementation comment, you
should assume that the members may change in future versions of MFC.
See also
General MFC Topics
MFC Library Versions
5/10/2019 • 5 minutes to read • Edit Online
The MFC Library is available in versions that support ANSI single-byte and multibyte character set (MBCS) code, as
well as versions that support Unicode (encoded as UTF-16LE, the Windows-native character set). Each MFC version
is available as a static library or as a shared DLL. There is also a smaller MFC static library version that leaves out
MFC controls for dialogs, for applications that are very sensitive to size and don't need those controls. The MFC
libraries are available in both debug and release versions for supported architectures that include x86, x64, and
ARM processors. You can create both applications (.exe files) and DLLs with any version of the MFC libraries. There
is also a set of MFC libraries compiled for interfacing with managed code. The MFC shared DLLs include a version
number to indicate library binary compatibility.
MFC header files also include directives to link in all required libraries, including MFC libraries, Win32 libraries, OLE
libraries, OLE libraries built from samples, ODBC libraries, and so on.
uAFXcd.LIB
where the letters shown in italic lowercase are placeholders for specifiers whose meanings are shown in the
following table:
SP EC IF IER VA L UES A N D M EA N IN GS
All libraries listed in the following table are included prebuilt in the \atlmfc\lib directory for supported build
architectures.
L IB RA RY DESC RIP T IO N
Debugger files that have the same base name and a .pdb extension are also available for each of the static libraries.
DL L DESC RIP T IO N
MFCMversionD.DLL MFC DLL with Windows Forms controls, ANSI or MBCS Debug
version
The import libraries needed to build applications or MFC extension DLLs that use these shared DLLs have the same
base name as the DLL but have a .lib file name extension. When you use the shared DLLs, a small static library
must still be linked with your code; this library is named MFCS version{U}{D}.lib.
If you are dynamically linking to the shared DLL version of MFC, whether it is from an application or from an MFC
extension DLL, you must include the matching MFCversion.DLL or MFCversionU.DLL when you deploy your
product.
For a list of Visual C++ DLLs that can be distributed with your applications, see Distributable Code for Microsoft
Visual Studio 2017 and Microsoft Visual Studio 2017 SDK (Includes Utilities and BuildServer Files) or Distributable
Code for Visual Studio 2019.
For more information on MBCS and Unicode support in MFC, see Unicode and Multibyte Character Set (MBCS)
Support.
See also
General MFC Topics
MFC MBCS DLL Add-on
12/4/2019 • 2 minutes to read • Edit Online
Support for MFC and its multibyte character set (MBCS) libraries requires an additional step during Visual Studio
installation in Visual Studio 2013 and later.
Visual Studio 2013 : By default, the MFC libraries installed in Visual Studio 2013 only support Unicode
development. You need the MBCS DLLs in order to build an MFC project in Visual Studio 2013 that has the
Character Set property set to Use Multi-Byte Character Set or Not Set . Download the DLL at Multibyte MFC
Library for Visual Studio 2013.
Visual Studio 2015 : Both Unicode and MBCS MFC DLLs are included in the Visual C++ setup components, but
support for MFC is not installed by default. Visual C++ and MFC are optional install configurations in Visual Studio
setup. To make sure that MFC is installed, choose Custom in setup, and under Programming Languages , make
sure that Visual C++ and Microsoft Foundation Classes for C++ are selected. If you have already installed
Visual Studio, you will be prompted to install Visual C++ and/or MFC when you attempt to create an MFC project.
Visual Studio 2017 and later : The Unicode and MBCS MFC DLLs are installed with the Desktop development
with C++ workload when you select MFC and ATL suppor t from the Optional Components pane in the
Visual Studio Installer program. If your installation does not include these components, navigate to the File | New
Projects dialog and click the Open Visual Studio Installer link. For more information, see Install Visual Studio.
See also
MFC Library Versions
Using the Classes to Write Applications for Windows
3/4/2019 • 2 minutes to read • Edit Online
Taken together, the classes in the Microsoft Foundation Class (MFC) Library make up an "application framework,"
on which you build an application for the Windows operating system. At a very general level, the framework
defines the skeleton of an application and supplies standard user-interface implementations that can be placed
onto the skeleton. Your job as programmer is to fill in the rest of the skeleton, which are those things that are
specific to your application. You can get a head start by using the MFC Application Wizard to create the files for a
very thorough starter application. You use the Microsoft Visual C++ resource editors to design your user-interface
elements visually, Class View commands to connect those elements to code, and the class library to implement
your application-specific logic.
Version 3.0 and later of the MFC framework supports programming for Win32 platforms, including Microsoft
Windows 95 and later, and Windows NT versions 3.51 and later. MFC Win32 support includes multithreading. Use
version 1.5x if you need to do 16-bit programming.
This family of articles presents a broad overview of the application framework. It also explores the major objects
that make up your application and how they are created. Among the topics covered in these articles are the
following:
The framework.
Division of labor between the framework and your code, as described in Building on the Framework.
The application class, which encapsulates application-level functionality.
How document templates create and manage documents and their associated views and frame windows.
Class CWnd, the root base class of all windows.
Graphic objects, such as pens and brushes.
Other parts of the framework include:
Window Objects: Overview
Message handling and mapping
CObject, The Root Base Class in MFC
Document/View Architecture
Dialog Boxes
Controls
Control Bars
OLE
Memory Management
Besides giving you an advantage in writing applications for the Windows operating system, MFC also
makes it much easier to write applications that specifically use OLE linking and embedding technology. You
can make your application an OLE visual editing container, an OLE visual editing server, or both, and you
can add Automation so that other applications can use objects from your application or even drive it
remotely.
MFC ActiveX Controls
The OLE control development kit (CDK) is now fully integrated with the framework. This article family
supplies an overview of ActiveX control development with MFC. (ActiveX controls were formerly known as
OLE controls.)
Database Programming
MFC also supplies two sets of database classes that simplify writing data-access applications. Using the
ODBC database classes, you can connect to databases through an Open Database Connectivity (ODBC)
driver, select records from tables, and display record information in an on-screen form. Using the Data
Access Object (DAO) classes, you can work with databases through the Microsoft Jet database engine or
external (non-Jet) data sources, including ODBC data sources.
In addition, MFC is fully enabled for writing applications that use Unicode and multibyte character sets
(MBCS), specifically double-byte character sets (DBCS).
For a general guide to MFC documentation, see General MFC Topics.
See also
General MFC Topics
Framework (MFC)
11/21/2019 • 2 minutes to read • Edit Online
Your work with the Microsoft Foundation Class (MFC) Library framework is based largely on a few major classes
and several Visual C++ tools. Some classes encapsulate a large portion of the Win32 application programming
interface (API). Other classes encapsulate application concepts such as documents, views, and the application itself.
Still others encapsulate OLE features and ODBC and DAO data-access functionality. (DAO is supported through
Office 2013. DAO 3.6 is the final version, and it is considered obsolete.)
For example, Win32's concept of window is encapsulated by MFC class CWnd . That is, a C++ class called CWnd
encapsulates or "wraps" the HWND handle that represents a Windows window. Likewise, class CDialog
encapsulates Win32 dialog boxes.
Encapsulation means that the C++ class CWnd , for example, contains a member variable of type HWND , and the
class's member functions encapsulate calls to Win32 functions that take an HWND as a parameter. The class
member functions typically have the same name as the Win32 function they encapsulate.
In This Section
SDI and MDI
Documents, Views, and the Framework
Wizards and Resource Editors
In Related Sections
Building on the Framework
How the Framework Calls Your Code
CWinApp: The Application Class
Document Templates and the Document/View Creation Process
Message Handling and Mapping
Window Objects
See also
Using the Classes to Write Applications for Windows
SDI and MDI
3/27/2020 • 2 minutes to read • Edit Online
MFC makes it easy to work with both single-document interface (SDI) and multiple-document interface (MDI)
applications.
SDI applications allow only one open document frame window at a time. MDI applications allow multiple
document frame windows to be open in the same instance of an application. An MDI application has a window
within which multiple MDI child windows, which are frame windows themselves, can be opened, each containing a
separate document. In some applications, the child windows can be of different types, such as chart windows and
spreadsheet windows. In that case, the menu bar can change as MDI child windows of different types are activated.
NOTE
Under Windows 95 and later, applications are commonly SDI because the operating system has adopted a "document-
centered" view.
See also
Using the Classes to Write Applications for Windows
Documents, Views, and the Framework
3/4/2019 • 3 minutes to read • Edit Online
At the heart of the MFC framework are the concepts of document and view. A document is a data object with
which the user interacts in an editing session. It is created by the New or Open command on the File menu and is
typically saved in a file. (Standard MFC documents, derived from class CDocument , are different from Active
documents and OLE compound documents.) A view is a window object through which the user interacts with a
document.
The key objects in a running application are:
The document or documents.
Your document class (derived from CDocument) specifies your application's data.
If you want OLE functionality in your application, derive your document class from COleDocument or one of
its derived classes, depending on the type of functionality you need.
The view or views.
Your view class (derived from CView) is the user's "window on the data." The view class controls how the
user sees your document's data and interacts with it. In some cases, you may want a document to have
multiple views of the data.
If you need scrolling, derive from CScrollView. If your view has a user interface that is laid out in a dialog-
template resource, derive from CFormView. For simple text data, use or derive from CEditView. For a form-
based data-access application, such as a data-entry program, derive from CRecordView (for ODBC). Also
available are classes CTreeView, CListView, and CRichEditView.
The frame windows
Views are displayed inside "document frame windows." In an SDI application, the document frame window
is also the "main frame window" for the application. In an MDI application, document windows are child
windows displayed inside a main frame window. Your derived main frame-window class specifies the styles
and other characteristics of the frame windows that contain your views. If you need to customize frame
windows, derive from CFrameWnd to customize the document frame window for SDI applications. Derive
from CMDIFrameWnd to customize the main frame window for MDI applications. Also derive a class from
CMDIChildWnd to customize each distinct kind of MDI document frame windows that your application
supports.
The document template or templates
A document template orchestrates the creation of documents, views, and frame windows. A particular
document-template class, derived from class CDocTemplate, creates and manages all open documents of
one type. Applications that support more than one type of document have multiple document templates.
Use class CSingleDocTemplate for SDI applications, or use class CMultiDocTemplate for MDI applications.
The application object
Your application class (derived from CWinApp) controls all of the objects above and specifies application
behavior such as initialization and cleanup. The application's one and only application object creates and
manages the document templates for any document types the application supports.
Thread objects
If your application creates separate threads of execution — for example, to perform calculations in the
background — you'll use classes derived from CWinThread. CWinApp itself is derived from CWinThread and
represents the primary thread of execution (or the main process) in your application. You can also use MFC
in secondary threads.
In a running application, these objects cooperatively respond to user actions, bound together by commands and
other messages. A single application object manages one or more document templates. Each document template
creates and manages one or more documents (depending on whether the application is SDI or MDI). The user
views and manipulates a document through a view contained inside a frame window. The following figure shows
the relationships among these objects for an SDI application.
See also
Using the Classes to Write Applications for Windows
Wizards and the Resource Editors
3/27/2020 • 2 minutes to read • Edit Online
Visual C++ includes several wizards for use in MFC programming, along with many integrated resource editors.
For ActiveX controls programming, the ActiveX Control Wizard serves a purpose much like that of the MFC
Application Wizard. While you can write MFC applications without most of these tools, the tools greatly simplify
and speed your work.
NOTE
Class View also helps you to override virtual functions in the MFC classes. Select the class and the virtual function to
override. The rest of the process is similar to message handling, as described in the following paragraphs.
Applications running under Windows are message driven. User actions and other events that occur in the running
program cause Windows to send messages to the windows in the program. For example, if the user clicks the
mouse in a window, Windows sends a WM_LBUTTONDOWN message when the left mouse button is pressed and a
WM_LBUTTONUP message when the button is released. Windows also sends WM_COMMAND messages when the
user selects commands from the menu bar.
In the MFC framework, various objects, such as documents, views, frame windows, document templates, and the
application object, can "handle" messages. Such an object provides a "handler function" as one of its member
functions, and the framework maps the incoming message to its handler.
A large part of your programming task is choosing which messages to map to which objects and then
implementing that mapping. To do so, you use Class View and the Class Wizard.
The Class Wizard will create empty message-handler member functions, and you use the source code editor to
implement the body of the handler. You can also create or edit classes (including classes of your own, not derived
from MFC classes) and their members with Class View. For more information on using Class View and about
wizards that add code to a project, see Adding Functionality with Code Wizards.
See also
Using the Classes to Write Applications for Windows
Building on the Framework
3/4/2019 • 2 minutes to read • Edit Online
Your role in configuring an application with the MFC framework is to supply the application-specific source code
and to connect the components by defining what messages and commands to which they respond. You use the
C++ language and standard C++ techniques to derive your own application-specific classes from those supplied
by the class library and to override and augment the base class's behavior.
In related topics, the following tables describe the general sequence of operations you will typically follow and
your responsibilities versus the framework's responsibilities:
Sequence for Building an Application with the Framework
Sequence of Operations for Creating OLE Applications
Sequence of Operations for Creating ActiveX Controls
Sequence of Operations for Creating Database Applications
For the most part, you can follow these tables as a sequence of steps for creating an MFC application, although
some of the steps are alternative options. For example, most applications use one type of view class from the
several types available.
See also
General MFC Topics
Sequence of Operations for Building MFC
Applications
9/11/2019 • 6 minutes to read • Edit Online
The following table explains the general sequence you might typically follow as you develop your MFC application.
Sequence for Building an Application with the Framework
TA SK Y O U DO T H E F RA M EW O RK DO ES
Create a skeleton application. Run the MFC Application Wizard. The MFC Application Wizard creates the
Specify the options you want in the files for a skeleton application, including
options pages. Options include making source files for your application,
the application a COM component, document, view, and frame windows; a
container, or both; adding Automation; resource file; a project file; and others,
and making the application database- all tailored to your specifications.
aware.
See what the framework and the MFC Build the skeleton application and run it The running skeleton application
Application Wizard offer without adding in Visual C++. derives many standard File , Edit , View ,
a line of your own code. and Help menu commands from the
framework. For MDI applications, you
also get a fully functional Windows
menu, and the framework manages
creation, arrangement, and destruction
of MDI child windows.
Construct your application's user Use the Visual C++ resource editors to The default resource file created by the
interface. visually edit the application's user MFC Application Wizard supplies many
interface: of the resources you need. Visual C++
lets you edit existing resources and add
- Create menus. new resources easily and visually.
- Define accelerators.
- Create dialog boxes.
- Create and edit bitmaps, icons, and
cursors.
- Edit the toolbar created for you by
the MFC Application Wizard.
- Create and edit other resources.
Map menus to handler functions. Use the Events button in the These tools insert message-map entries
Proper ties window in Class View (or and empty function templates into the
the Commands tab in Class Wizard) to source files you specify and manages
connect menus and accelerators to many manual coding tasks.
handler functions in your code.
TA SK Y O U DO T H E F RA M EW O RK DO ES
Write your handler code. Use Class View to jump directly to the Class View opens the editor, scrolls to
code in the source code editor. Fill in the empty function template and
the code for your handler functions. For positions the cursor for you.
more information on using Class View
and about wizards that add code to a
project, see Adding Functionality with
Code Wizards.
Map toolbar buttons to commands. Map each button on your toolbar to a The framework controls the drawing,
menu or accelerator command by enabling, disabling, checking, and other
assigning the button the appropriate visual aspects of the toolbar buttons.
command ID.
Test your handler functions. Rebuild the program and use the built- You can step or trace through the code
in debugging tools to test that your to see how your handlers are called. If
handlers work correctly. you have filled out the handler code,
the handlers carry out commands. The
framework will automatically disable
menu items and toolbar buttons that
are not handled.
Add dialog boxes. Design dialog-template resources with The framework manages the dialog box
the dialog editor. Then create a dialog and facilitates retrieving information
class and the code that handles the entered by the user.
dialog box.
Initialize, validate, and retrieve dialog- You can also define how the dialog The framework manages dialog-box
box data. box's controls are to be initialized and initialization and validation. If the user
validated. Use Visual Studio to add enters invalid information, the
member variables to the dialog class framework displays a message box and
and map them to dialog controls. lets the user reenter the data.
Specify validation rules to be applied to
each control as the user enters data.
Provide your own custom validations if
you wish.
Create additional classes. Use Class View to create additional Class View adds these classes to your
document, view, and frame-window source files and helps you define their
classes beyond those created connections to any commands they
automatically by the MFC Application handle.
Wizard. You can create additional
database recordset classes, dialog
classes, and so on. (With Class View,
you can create classes not derived from
MFC classes.)
Add ready-to-use components to your Use the New Item dialog box to add These items are easy to integrate into
application. a variety of items. your application and save you a great
deal of work.
Implement your document class. Implement your application-specific The framework already knows how to
document class or classes. Add member interact with document data files. It can
variables to hold data structures. Add open and close document files, read
member functions to provide an and write the document's data, and
interface to the data. handle other user interfaces. You can
focus on how the document's data is
manipulated.
TA SK Y O U DO T H E F RA M EW O RK DO ES
Implement Open, Save, and Save As Write code for the document's The framework displays dialog boxes for
commands. Serialize member function. the Open , Save , and Save As
commands on the File menu. It writes
and reads back a document using the
data format specified in your
Serialize member function.
Implement your view class. Implement one or more view classes The framework manages most of the
corresponding to your documents. relationship between a document and
Implement the view's member functions its view. The view's member functions
that you mapped to the user interface access the view's document to render
with Class View. A variety of CView- its image on the screen or printed page
derived classes are available, including and to update the document's data
CListView and CTreeView. structures in response to user editing
commands.
Enhance default printing. If you need to support multipage The framework supports the Print ,
printing, override view member Page Setup , and Print Preview
functions. commands on the File menu. You must
tell it how to break your document into
multiple pages.
Add scrolling. If you need to support scrolling, derive The view automatically adds scroll bars
your view class or classes from when the view window becomes too
CScrollView. small.
Create form views. If you want to base your views on The view uses the dialog-template
dialog-template resources, derive your resource to display controls. The user
view class or classes from CFormView. can tab from control to control in the
view.
Create database forms. If you want a form-based data-access The view works like a form view, but its
application, derive your view class from controls are connected to the fields of a
CRecordView (for ODBC programming). CRecordset object representing a
database table. MFC moves data
between the controls and the recordset
for you.
Create a simple text editor. If you want your view to be a simple The view provides editing functions,
text editor, derive your view class or Clipboard support, and file
classes from CEditView or input/output. CRichEditView provides
CRichEditView. styled text.
Add splitter windows. If you want to support window The framework supplies splitter-box
splitting, add a CSplitterWnd object to controls next to the scroll bars and
your SDI frame window or MDI child manages splitting your view into
window and hook it up in the window's multiple panes. If the user splits a
OnCreateClient member function. window, the framework creates and
attaches additional view objects to the
document.
Build, test, and debug your application. Use the facilities of Visual C++ to build, Visual C++ lets you adjust compile, link,
test, and debug your application. and other options. It also lets you
browse your source code and class
structure.
See also
Sequence of Operations for Creating OLE Applications
Sequence of Operations for Creating ActiveX Controls
Sequence of Operations for Creating Database Applications
Building on the Framework
Sequence of Operations for Creating OLE
Applications
3/4/2019 • 2 minutes to read • Edit Online
The following table shows your role and the framework's role in creating OLE linking and embedding applications.
These represent options available rather than a sequence of steps to perform.
Creating OLE Applications
TA SK Y O U DO T H E F RA M EW O RK DO ES
Create a COM component. Run the MFC Application Wizard. The framework generates a skeleton
Choose Full-ser ver or Mini-ser ver in application with COM component
the Compound Document Suppor t capability enabled. All of the COM
tab. capability can be transferred to your
existing application with only slight
modification.
Create a container application from Run the MFC Application Wizard. The framework generates a skeleton
scratch. Choose Container in the Compound application that can insert COM objects
Document Suppor t tab. Using Class created by COM component (server)
View, go to the source code editor. Fill applications.
in code for your COM handler
functions.
Create an application that supports Run the MFC Application Wizard. The framework generates a skeleton
Automation from scratch. Choose Automation from the application that can be activated and
Advanced Features tab. Use Class automated by other applications.
View to expose methods and properties
in your application for automation.
See also
Building on the Framework
Sequence of Operations for Building MFC Applications
Sequence of Operations for Creating ActiveX Controls
Sequence of Operations for Creating Database Applications
Sequence of Operations for Creating ActiveX
Controls
4/1/2019 • 2 minutes to read • Edit Online
The following table shows your role and the framework's role in creating ActiveX controls (formerly known as OLE
controls).
Creating ActiveX Controls
TA SK Y O U DO T H E F RA M EW O RK DO ES
Create an ActiveX control framework. Run the MFC ActiveX Control Wizard to The MFC ActiveX Control Wizard
create your control. Specify the options creates the files for an ActiveX control
you want in the options pages. Options with basic functionality, including source
include the type and name of the files for your application, control, and
control in the project, licensing, property page or pages; a resource file;
subclassing, and an About Box method. a project file; and others, all tailored to
your specifications.
See what the control and the ActiveX Build the ActiveX control and test it The running control has the ability to
Control Wizard offer without adding a with Internet Explorer or the TSTCON be resized and moved. It also has an
line of your own code. sample. About Box method (if chosen) that
can be invoked.
Implement the control's methods and Implement your control-specific The framework has already defined a
properties. methods and properties by adding map to support the control's events,
member functions to provide an properties, and methods, leaving you
exposed interface to the control's data. to focus on how the properties and
Add member variables to hold data methods are implemented. The default
structures and use event handlers to property page is viewable and a default
fire events when you determine. About Box method is supplied.
Construct the control's property page Use the Visual C++ resource editors to The default resource file created by the
or pages. visually edit the control's property page MFC Application Wizard supplies many
interface: of the resources you need. Visual C++
lets you edit existing resources and add
- Create additional property pages. new resources easily and visually.
- Create and edit bitmaps, icons, and
cursors.
Test the control's events, methods, and Rebuild the control and use Test You can invoke the control's methods
properties. Container to test that your handlers and manipulate its properties through
work correctly. the property page interface or through
Test Container. In addition, use Test
Container to track events fired from the
control and notifications received by
the control's container.
See also
Building on the Framework
Sequence of Operations for Building MFC Applications
Sequence of Operations for Creating OLE Applications
Sequence of Operations for Creating Database Applications
Sequence of Operations for Creating Database
Applications
3/27/2020 • 2 minutes to read • Edit Online
The following table shows your role and the framework's role in writing database applications.
NOTE
The Visual C++ environment and wizards do not support DAO (although the DAO classes are included and you can still use
them). Microsoft recommends that you use ODBC for new MFC projects. You should only use DAO in maintaining existing
applications.
Decide whether to use the MFC ODBC Use ODBC for new MFC projects. Use The framework supplies classes that
or DAO classes. DAO only to maintain existing support database access.
applications. For general information,
see the article Data Access
Programming.
Create your skeleton application with Run the MFC Application Wizard. Select The MFC Application Wizard creates
database options. options on the Database Support page. files and specifies the necessary
If you choose an option that creates a includes. Depending on the options you
record view, also specify: specify, the files can include a recordset
class.
- Data source and table name or names
- Query name or names.
Design your database form or forms. Use the Visual C++ dialog editor to The MFC Application Wizard creates an
place controls on the dialog template empty dialog template resource for you
resources for your record view classes. to fill in.
Create additional record view and Use Class View to create the classes Class View creates additional files for
recordset classes as needed. and the dialog editor to design the your new classes.
views.
Create recordset objects as needed in Your recordsets are based on the ODBC uses record field exchange (RFX)
your code. Use each recordset to classes derived from CRecordset with to exchange data between the database
manipulate records... the wizards. and your recordset's field data
members. If you are using a record
view, dialog data exchange (DDX)
exchanges data between the recordset
and the controls on the record view.
...or create an explicit CDatabase in Base your recordset objects on the The database object provides an
your code for each database you want database objects. interface to the data source.
to open.
TA SK Y O U DO T H E F RA M EW O RK DO ES
Bind data columns to your recordset In ODBC, add code to your derived
dynamically. recordset class to manage the binding.
See the article Recordset: Dynamically
Binding Data Columns (ODBC).
See also
Building on the Framework
Sequence of Operations for Building MFC Applications
Sequence of Operations for Creating OLE Applications
Sequence of Operations for Creating ActiveX Controls
How the Framework Calls Your Code
3/4/2019 • 2 minutes to read • Edit Online
It is crucial to understand the relationship between your source code and the code in the MFC framework. When
your application runs, most of the flow of control resides in the framework's code. The framework manages the
message loop that gets messages from Windows as the user chooses commands and edits data in a view. Events
that the framework can handle by itself do not rely on your code at all. For example, the framework knows how to
close windows and how to exit the application in response to user commands. As it handles these tasks, the
framework uses message handlers and C++ virtual functions to give you opportunities to respond to these events
as well. Your code is not in control, however; the framework is.
The framework calls your code for application-specific events. For example, when the user chooses a menu
command, the framework routes the command along a sequence of C++ objects: the current view and frame
window, the document associated with the view, the document's document template, and the application object. If
one of these objects can handle the command, it does so, calling the appropriate message-handler function. For
any given command, the code called may be yours or it may be the framework's.
This arrangement is somewhat familiar to programmers experienced with traditional programming for Windows
or event-driven programming.
In related topics, you will read what the framework does as it initializes and runs the application and then cleans up
as the application terminates. You will also understand where the code you write fits in.
For more information, see Class CWinApp: The Application Class and Document Templates and the Document/View
Creation Process.
See also
Building on the Framework
CWinApp: The Application Class
3/27/2020 • 2 minutes to read • Edit Online
The main application class in MFC encapsulates the initialization, running, and termination of an application for
the Windows operating system. An application built on the framework must have one and only one object of a
class derived from CWinApp. This object is constructed before windows are created.
CWinApp is derived from CWinThread , which represents the main thread of execution for your application, which
might have one or more threads. In recent versions of MFC, the InitInstance , Run , ExitInstance , and OnIdle
member functions are actually in class CWinThread . These functions are discussed here as if they were CWinApp
members instead, because the discussion concerns the object's role as application object rather than as primary
thread.
NOTE
Your application class constitutes your application's primary thread of execution. Using Win32 API functions, you can also
create secondary threads of execution. These threads can use the MFC Library. For more information, see Multithreading.
Like any program for the Windows operating system, your framework application has a WinMain function. In a
framework application, however, you do not write WinMain . It is supplied by the class library and is called when
the application starts up. WinMain performs standard services such as registering window classes. It then calls
member functions of the application object to initialize and run the application. (You can customize WinMain by
overriding the CWinApp member functions that WinMain calls.)
To initialize the application, WinMain calls your application object's InitApplication and InitInstance member
functions. To run the application's message loop, WinMain calls the Run member function. On termination,
WinMain calls the application object's ExitInstance member function.
NOTE
Names shown in bold in this documentation indicate elements supplied by the Microsoft Foundation Class Library and
Visual C++. Names shown in monospaced type indicate elements that you create or override.
See also
General MFC Topics
CWinApp and the MFC Application Wizard
Overridable CWinApp Member Functions
Special CWinApp Services
CWinApp and the MFC Application Wizard
3/16/2020 • 2 minutes to read • Edit Online
When it creates a skeleton application, the MFC Application Wizard declares an application class derived from
CWinApp. The MFC Application Wizard also generates an implementation file that contains the following items:
A message map for the application class.
An empty class constructor.
A variable that declares the one and only object of the class.
A standard implementation of your InitInstance member function.
The application class is placed in the project header and main source files. The names of the class and files created
are based on the project name you supply in the MFC Application Wizard. The easiest way to view the code for
these classes is through Class View.
The standard implementations and message map supplied are adequate for many purposes, but you can modify
them as needed. The most interesting of these implementations is the InitInstance member function. Typically,
you will add code to the skeletal implementation of InitInstance .
See also
CWinApp: The Application Class
Overridable CWinApp Member Functions
Special CWinApp Services
Overridable CWinApp Member Functions
3/16/2020 • 2 minutes to read • Edit Online
CWinApp provides several key overridable member functions ( CWinApp overrides these members from class
CWinThread, from which CWinApp derives):
InitInstance
Run
ExitInstance
OnIdle
The only CWinApp member function that you must override is InitInstance .
See also
CWinApp: The Application Class
InitInstance Member Function
3/27/2020 • 2 minutes to read • Edit Online
The Windows operating system allows you to run more than one copy, or "instance," of the same application.
WinMain calls InitInstance every time a new instance of the application starts.
The standard InitInstance implementation created by the MFC Application Wizard performs the following tasks:
As its central action, creates the document templates that in turn create documents, views, and frame
windows. For a description of this process, see Document Template Creation.
Loads standard file options from an .ini file or the Windows registry, including the names of the most
recently used files.
Registers one or more document templates.
For an MDI application, creates a main frame window.
Processes the command line to open a document specified on the command line or to open a new, empty
document.
You can add your own initialization code or modify the code written by the wizard.
NOTE
MFC applications must be initialized as single threaded apartment (STA). If you call CoInitializeEx in your InitInstance
override, specify COINIT_APARTMENTTHREADED (rather than COINIT_MULTITHREADED).
See also
CWinApp: The Application Class
Run Member Function
3/4/2019 • 2 minutes to read • Edit Online
A framework application spends most of its time in the Run member function of class CWinApp. After initialization,
WinMain calls Run to process the message loop.
Run cycles through a message loop, checking the message queue for available messages. If a message is available,
Run dispatches it for action. If no messages are available, which is often true, Run calls OnIdle to do any idle-
time processing that you or the framework may need done. If there are no messages and no idle processing to do,
the application waits until something happens. When the application terminates, Run calls ExitInstance . The
figure in OnIdle Member Function shows the sequence of actions in the message loop.
Message dispatching depends on the kind of message. For more information, see Messages and Commands in the
Framework.
See also
CWinApp: The Application Class
ExitInstance Member Function
3/4/2019 • 2 minutes to read • Edit Online
The ExitInstance member function of class CWinApp is called each time a copy of your application terminates,
usually as a result of the user quitting the application.
Override ExitInstance if you need special cleanup processing, such as freeing graphics device interface (GDI)
resources or deallocating memory used during program execution. Cleanup of standard items such as documents
and views, however, is provided by the framework, with other overridable functions for doing special cleanup
specific to those objects.
See also
CWinApp: The Application Class
OnIdle Member Function
3/4/2019 • 2 minutes to read • Edit Online
When no Windows messages are being processed, the framework calls the CWinApp member function OnIdle
(described in the MFC Library Reference).
Override OnIdle to perform background tasks. The default version updates the state of user-interface objects such
as toolbar buttons and performs cleanup of temporary objects created by the framework in the course of its
operations. The following figure illustrates how the message loop calls OnIdle when there are no messages in the
queue.
See also
CWinApp: The Application Class
Special CWinApp Services
3/27/2020 • 3 minutes to read • Edit Online
Besides running the message loop and giving you an opportunity to initialize the application and clean up after it,
CWinApp provides several other services.
Shell Registration
By default, the MFC Application Wizard makes it possible for the user to open data files that your application has
created by double-clicking them in File Explorer or File Manager. If your application is an MDI application and you
specify an extension for the files your application creates, the MFC Application Wizard adds calls to the
RegisterShellFileTypes and EnableShellOpen member functions of CWinApp to the InitInstance override that it
writes for you.
RegisterShellFileTypes registers your application's document types with File Explorer or File Manager. The
function adds entries to the registration database that Windows maintains. The entries register each document
type, associate a file extension with the file type, specify a command line to open the application, and specify a
dynamic data exchange (DDE) command to open a document of that type.
EnableShellOpen completes the process by allowing your application to receive DDE commands from File Explorer
or File Manager to open the file chosen by the user.
This automatic registration support in CWinApp eliminates the need to ship a .reg file with your application or to
do special installation work.
If you want to initialize GDI+ for your application (by calling GdiplusStartup in your InitInstance function), you
have to suppress the GDI+ background thread.
You can do this by setting the SuppressBackgroundThread member of the GdiplusStartupInput structure to TRUE .
When suppressing the GDI+ background thread, the NotificationHook and NotificationUnhook calls should be
made just prior to entering and exiting the application's message loop. For more information on these calls, see
GdiplusStartupOutput. Therefore, a good place to call GdiplusStartup and the hook notification functions would
be in an override of the virtual function CWinApp::Run, as shown below:
int CMyWinApp::Run()
{
GdiplusStartupInput gdiSI;
GdiplusStartupOutput gdiSO;
ULONG_PTR gdiToken;
ULONG_PTR gdiHookToken;
gdiSI.SuppressBackgroundThread = TRUE;
GdiplusStartup(&gdiToken, &gdiSI, &gdiSO);
gdiSO.NotificationHook(&gdiHookToken);
int nRet = CWinApp::Run();
gdiSO.NotificationUnhook(gdiHookToken);
GdiplusShutdown(gdiToken);
return nRet;
}
If you do not suppress the background GDI+ thread, DDE commands can be prematurely issued to the application
before its main window has been created. The DDE commands issued by the shell can be prematurely aborted,
resulting in error messages.
NOTE
You can also implement more general drag-and-drop capabilities—dragging data between or within documents—with OLE.
For information, see the article OLE drag and drop.
See also
CWinApp: The Application Class
Document Templates and the Document/View
Creation Process
3/4/2019 • 2 minutes to read • Edit Online
To manage the complex process of creating documents with their associated views and frame windows, the
framework uses two document template classes: CSingleDocTemplate for SDI applications and
CMultiDocTemplate for MDI applications. A CSingleDocTemplate can create and store one document of one type
at a time. A CMultiDocTemplate keeps a list of many open documents of one type.
Some applications support multiple document types. For example, an application might support text documents
and graphics documents. In such an application, when the user chooses the New command on the File menu, a
dialog box shows a list of possible new document types to open. For each supported document type, the
application uses a distinct document template object. The following figure illustrates the configuration of an MDI
application that supports two document types and shows several open documents.
See also
General MFC Topics
Document Template Creation
Document/View Creation
Relationships Among MFC Objects
Creating New Documents, Windows, and Views
Document Template Creation
3/4/2019 • 2 minutes to read • Edit Online
When creating a new document in response to a New or Open command from the File menu, the document
template also creates a new frame window through which to view the document.
The document-template constructor specifies what types of documents, windows, and views the template will be
able to create. This is determined by the arguments you pass to the document-template constructor. The following
code illustrates creation of a CMultiDocTemplate for a sample application:
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_CMyDocTypeTYPE,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CMyView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
The pointer to a new CMultiDocTemplate object is used as an argument to AddDocTemplate. Arguments to the
CMultiDocTemplate constructor include the resource ID associated with the document type's menus and
accelerators, and three uses of the RUNTIME_CLASS macro. RUNTIME_CLASS returns the CRuntimeClass object for
the C++ class named as its argument. The three CRuntimeClass objects passed to the document-template
constructor supply the information needed to create new objects of the specified classes during the document
creation process. The example shows creation of a document template that creates CScribDoc objects with
CScribView objects attached. The views are framed by standard MDI child frame windows.
See also
Document Templates and the Document/View Creation Process
Document/View Creation
Relationships Among MFC Objects
Creating New Documents, Windows, and Views
Document/View Creation
3/4/2019 • 2 minutes to read • Edit Online
The framework supplies implementations of the New and Open commands (among others) on the File menu.
Creation of a new document and its associated view and frame window is a cooperative effort among the
application object, a document template, the newly created document, and the newly created frame window. The
following table summarizes which objects create what.
Object Creators
C REATO R C REAT ES
See also
Document Templates and the Document/View Creation Process
Document Template Creation
Relationships Among MFC Objects
Creating New Documents, Windows, and Views
Relationships Among MFC Objects
3/27/2020 • 2 minutes to read • Edit Online
To help put the document/view creation process in perspective, consider a running program: a document, the
frame window used to contain the view, and the view associated with the document.
A document keeps a list of the views of that document and a pointer to the document template that created
the document.
A view keeps a pointer to its document and is a child of its parent frame window.
A document frame window keeps a pointer to its current active view.
A document template keeps a list of its open documents.
The application keeps a list of its document templates.
Windows keeps track of all open windows so it can send messages to them.
These relationships are established during document/view creation. The following table shows how objects in a
running program can access other objects. Any object can obtain a pointer to the application object by calling the
global function AfxGetApp.
Gaining Access to Other Objects in Your Application
F RO M O B JEC T H O W TO A C C ESS OT H ER O B JEC T S
MDI frame window Call MDIGetActive to get the currently active CMDIChildWnd.
Typically, a frame window has one view, but sometimes, as in splitter windows, the same frame window contains
multiple views. The frame window keeps a pointer to the currently active view; the pointer is updated any time
another view is activated.
NOTE
A pointer to the main frame window is stored in the m_pMainWnd member variable of the application object. A call to
OnFileNew in your override of the InitInstance member function of CWinApp sets m_pMainWnd for you. If you do not
call OnFileNew , you must set the variable's value in InitInstance yourself. (SDI COM component (server) applications
may not set the variable if /Embedding is on the command line.) Note that m_pMainWnd is now a member of class
CWinThread rather than CWinApp .
See also
Document Templates and the Document/View Creation Process
Document Template Creation
Document/View Creation
Creating New Documents, Windows, and Views
Creating New Documents, Windows, and Views
3/27/2020 • 2 minutes to read • Edit Online
The following figures give an overview of the creation process for documents, views, and frame windows. Other
articles that focus on the participating objects provide further details.
Upon completion of this process, the cooperating objects exist and store pointers to each other. The following
figures show the sequence in which objects are created. You can follow the sequence from figure to figure.
See also
Document Templates and the Document/View Creation Process
Document Template Creation
Document/View Creation
Relationships Among MFC Objects
Managing the State Data of MFC Modules
3/27/2020 • 2 minutes to read • Edit Online
This article discusses the state data of MFC modules and how this state is updated when the flow of execution (the
path code takes through an application when executing) enters and leaves a module. Switching module states with
the AFX_MANAGE_STATE and METHOD_PROLOGUE macros is also discussed.
NOTE
The term "module" here refers to an executable program, or to a DLL (or set of DLLs) that operate independently of the rest
of the application, but uses a shared copy of the MFC DLL. An ActiveX control is a typical example of a module.
As shown in the following figure, MFC has state data for each module used in an application. Examples of this data
include Windows instance handles (used for loading resources), pointers to the current CWinApp and CWinThread
objects of an application, OLE module reference counts, and a variety of maps that maintain the connections
between Windows object handles and corresponding instances of MFC objects. However, when an application uses
multiple modules, the state data of each module is not application wide. Rather, each module has its own private
copy of the MFC's state data.
See also
General MFC Topics
Exported DLL Function Entry Points
3/4/2019 • 2 minutes to read • Edit Online
For exported functions of a DLL, use the AFX_MANAGE_STATE macro to maintain the proper global state when
switching from the DLL module to the calling application's DLL.
When called, this macro sets pModuleState , a pointer to an AFX_MODULE_STATE structure containing global data for
the module, as the effective module state for the remainder of the containing scope of the function. Upon leaving
the scope containing the macro, the previous effective module state is automatically restored.
This switching is achieved by constructing an instance of an AFX_MODULE_STATE class on the stack. In its constructor,
this class obtains a pointer to the current module state and stores it in a member variable, and then sets
pModuleState as the new effective module state. In its destructor, this class restores the pointer stored in its
member variable as the effective module state.
If you have an exported function, such as one that launches a dialog box in your DLL, you need to add the following
code to the beginning of the function:
AFX_MANAGE_STATE(AfxGetStaticModuleState())
This swaps the current module state with the state returned from AfxGetStaticModuleState until the end of the
current scope.
Problems with resources in DLLs will occur if the AFX_MANAGE_STATE macro is not used. By default, MFC uses the
resource handle of the main application to load the resource template. This template is actually stored in the DLL.
The root cause is that MFC's module state information has not been switched by the AFX_MANAGE_STATE macro. The
resource handle is recovered from MFC's module state. Not switching the module state causes the wrong resource
handle to be used.
AFX_MANAGE_STATE does not need to be put into every function in the DLL. For example, InitInstance can be called
by the MFC code in the application without AFX_MANAGE_STATE because MFC automatically shifts the module state
before InitInstance and then switches it back after InitInstance returns. The same is true for all message-map
handlers. Regular MFC DLLs actually have a special master window procedure that automatically switches the
module state before routing any message.
See also
Managing the State Data of MFC Modules
COM Interface Entry Points
3/28/2019 • 2 minutes to read • Edit Online
For member functions of a COM interface, use the METHOD_PROLOGUE macro to maintain the proper global state
when calling methods of an exported interface.
Typically, member functions of interfaces implemented by CCmdTarget -derived objects already use this macro to
provide automatic initialization of the pThis pointer. For example:
STDMETHODIMP_(ULONG) CMySink::XSinky::AddRef()
{
METHOD_PROLOGUE(CMySink, Sinky);
return pThis->InternalAddRef();
}
The portion of the macro concerned with managing the global state is:
AFX_MANAGE_STATE( pThis->m_pModuleState )
In this expression, m_pModuleState is assumed to be a member variable of the containing object. It is implemented
by the CCmdTarget base class and is initialized to the appropriate value by COleObjectFactory , when the object is
instantiated.
See also
Managing the State Data of MFC Modules
Window Procedure Entry Points
3/4/2019 • 2 minutes to read • Edit Online
To protect MFC window procedures, a module static links with a special window procedure implementation. The
linkage occurs automatically when the module is linked with MFC. This window procedure uses the
AFX_MANAGE_STATE macro to properly set the effective module state, then it calls AfxWndProc , which in turn
delegates to the WindowProc member function of the appropriate CWnd -derived object.
See also
Managing the State Data of MFC Modules
Idle Loop Processing
3/27/2020 • 2 minutes to read • Edit Online
Many applications perform lengthy processing "in the background." Sometimes performance considerations
dictate using multithreading for such work. Threads involve extra development overhead, so they are not
recommended for simple tasks like the idle-time work that MFC does in the OnIdle function. This article focuses on
idle processing. For more information about multithreading, see Multithreading Topics.
Some kinds of background processing are appropriately done during intervals that the user is not otherwise
interacting with the application. In an application developed for the Microsoft Windows operating system, an
application can perform idle-time processing by splitting a lengthy process into many small fragments. After
processing each fragment, the application yields execution control to Windows using a PeekMessage loop.
This article explains two ways to do idle processing in your application:
Using PeekMessage in MFC's main message loop.
Embedding another PeekMessage loop somewhere else in the application.
NOTE
Run , OnIdle , and certain other member functions are now members of class CWinThread rather than of class CWinApp .
CWinApp is derived from CWinThread .
For more information about performing idle processing, see OnIdle in the MFC Reference.
This code, embedded in a function, loops as long as there is idle processing to do. Within that loop, a nested loop
repeatedly calls PeekMessage . As long as that call returns a nonzero value, the loop calls CWinThread::PumpMessage
to perform normal message translation and dispatching. Although PumpMessage is undocumented, you can
examine its source code in the ThrdCore.Cpp file in the \atlmfc\src\mfc directory of your Visual C++ installation.
Once the inner loop ends, the outer loop performs idle processing with one or more calls to OnIdle . The first call
is for MFC's purposes. You can make additional calls to OnIdle to do your own background work.
For more information about performing idle processing, see OnIdle in the MFC Library Reference.
See also
General MFC Topics
Support for Activation Contexts in the MFC Module
State
8/15/2019 • 2 minutes to read • Edit Online
MFC creates an activation context using a manifest resource provided by the user module. For more information
on how activation contexts are created, see the following topics:
Activation Contexts
Application Manifests
Assembly Manifests
Remarks
When reading these Windows SDK topics, note that the MFC activation context mechanism resembles the
Windows SDK activation context except that MFC does not use the Windows SDK Activation Context API.
Activation context works in MFC applications, user DLLs, and MFC extension DLLs in the following ways:
MFC applications use resource ID 1 for their manifest resource. In this case, the MFC does not create its own
activation context, but uses the default application context.
MFC user DLLs use resource ID 2 for their manifest resource. Here, MFC creates an activation context for
each User DLL, so different user DLLs can use different versions of the same libraries (for example, the
Common Controls library).
MFC extension DLLs rely on their hosting applications or user DLLs to establish their activation context.
Although the activation context state can be modified using the processes described under Using the Activation
Context API, using the MFC activation context mechanism can be useful when developing DLL-based plug-in
architectures where it is not easy (or not possible) to manually switch activation state before and after individual
calls to external plug-ins.
The activation context is created in AfxWinInit. It is destroyed in the AFX_MODULE_STATE destructor. An activation
context handle is kept in AFX_MODULE_STATE . ( AFX_MODULE_STATE is described in AfxGetStaticModuleState.)
The AFX_MANAGE_STATE macro activates and deactivates the activation context. AFX_MANAGE_STATE is enabled for
static MFC libraries, as well as MFC DLLs, to allow MFC code to execute in the proper activation context selected by
the User DLL.
See also
Activation Contexts
Application Manifests
Assembly Manifests
AfxWinInit
AfxGetStaticModuleState
AFX_MANAGE_STATE
Isolation of the MFC Common Controls Library
3/4/2019 • 2 minutes to read • Edit Online
The Common Controls library is now isolated within MFC, allowing different modules (such as user DLLs) to use
different versions of the Common Controls library by specifying the version in their manifests.
An MFC application (or user code called by MFC) makes calls to Common Controls library APIs through wrapper
functions named Afx FunctionName, where FunctionName is the name of a Common Controls API. Those wrapper
functions are defined in afxcomctl32.h and afxcomctl32.inl.
You can use the AFX_COMCTL32_IF_EXISTS and AFX_COMCTL32_IF_EXISTS2 macros (defined in afxcomctl32.h) to
determine whether the Common Controls library implements a certain API instead of calling GetProcAddress.
Technically, you make calls to Common Controls Library APIs through a wrapper class, CComCtlWrapper (defined in
afxcomctl32.h). CComCtlWrapper is also responsible for the loading and unloading of comctl32.dll. The MFC Module
State contains a pointer to an instance of CComCtlWrapper . You can access the wrapper class using the
afxComCtlWrapper macro.
Note that calling Common Controls API directly (not using the MFC wrapper functions) from an MFC application or
user DLL will work in most cases, because the MFC application or user DLL is bound to the Common Controls
library it requested in its manifest). However, the MFC code itself has to use the wrappers, because MFC code might
be called from user DLLs with different Common Controls library versions.
Build Requirements for Windows Common Controls
8/20/2019 • 2 minutes to read • Edit Online
The Microsoft Foundation Class (MFC) library supports Windows Common Controls. The Common Controls are
included in Windows and the library is included in Visual Studio. The MFC library provides new methods that
enhance existing classes, and additional classes and methods that support Windows Common Controls. When you
build your application, you should follow the compilation and migration requirements that are described in the
following sections.
Compilation Requirements
Supported Versions
MFC supports all versions of the Common Controls. For information about Windows Common Controls versions,
see Common Control Versions.
Supported Character Sets
The Windows Common Controls support only the Unicode character set, and not the ANSI character set. If you
build your application on the command line, use both of the following define (/D) compiler options to specify
Unicode as the underlying character set:
/D_UNICODE /DUNICODE
If you build your application in the Visual Studio integrated development environment (IDE), specify the Unicode
Character Set option of the Character Set property in the General node of the project properties.
Migration Requirements
If you use the Visual Studio IDE to build a new MFC application that uses Windows Common Controls, the IDE
automatically declares an appropriate manifest. However, if you migrate an existing MFC application from Visual
Studio 2005 or earlier and you want to use the Common Controls, the IDE does not automatically provide manifest
information to upgrade your application. Instead, you must manually insert the following source code in your
precompiled header file:
#ifdef UNICODE
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls'
version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls'
version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls'
version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls'
version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#endif
See also
General MFC Topics
Hierarchy Chart
Deprecated ANSI APIs
Deprecated ANSI APIs
3/4/2019 • 2 minutes to read • Edit Online
The Microsoft Foundation Class (MFC) library is migrating toward classes and methods that are based on the
Unicode character set. Consequently, the ANSI versions of several MFC methods are deprecated. Use the Unicode
versions of these methods in your future applications.
Starting with Windows Common Controls version 6.1, which ships in Windows Vista, the following ANSI methods
are deprecated.
CButton class
AFX_ANSI_DEPRECATED BOOL GetIdealSize(LPSIZE psize) const;
CComboBoxEx class
AFX_ANSI_DEPRECATED HRESULT SetWindowTheme(LPCWSTR pszSubAppName);
CEdit class
AFX_ANSI_DEPRECATED BOOL GetCueBanner(LPWSTR lpszText,
int cchText) const;
CLinkCtrl class
The entire class is deprecated.
CListCtrl class
AFX_ANSI_DEPRECATED void CancelEditLabel();
CReBarCtrl class
AFX_ANSI_DEPRECATED void GetBandMargins(PMARGINS pMargins) const;
CToolBarCtrl class
AFX_ANSI_DEPRECATED void GetMetrics(LPTBMETRICS ptbm) const;
CToolTipCtrl class
AFX_ANSI_DEPRECATED HRESULT SetWindowTheme(LPCWSTR pszSubAppName);
See also
Build Requirements for Windows Vista Common Controls
How to: Add Restart Manager Support
3/27/2020 • 2 minutes to read • Edit Online
The restart manager is a feature added to Visual Studio for Windows Vista or later operating systems. The restart
manager adds support for your application if it unexpectedly closes or restarts. The behavior of the restart
manager depends on the type of your application. If your application is a document editor, the restart manager
enabled your application to automatically save the state and content of any open documents and restarts your
application after an unexpected closure. If your application is not a document editor, the restart manager will
restart the application, but it cannot save the state of the application by default.
After restart, the application displays a task dialog box if the application is Unicode. If it is an ANSI application, the
application displays a Windows Message box. At this point, the user chooses whether to restore the automatically
saved documents. If the user does not restore the automatically saved documents, the restart manager discards
the temporary files.
NOTE
You can override the default behavior of the restart manager for saving data and restarting the application.
By default, MFC applications created by using the project wizard in Visual Studio support the restart manager
when the applications are run on a computer that has a Windows Vista or later operating system. If you do not
want your application to support the restart manager, you can disable the restart manager in the new project
wizard.
To Add Support For the Restart Manager to an Existing Application
1. Open an existing MFC application in Visual Studio.
2. Open the source file for your main application. By default this is the .cpp file that has the same name as
your application. For example, the main application source file for MyProject is MyProject.cpp.
3. Find the constructor for your main application. For example, if your project is MyProject, the constructor is
CMyProjectApp::CMyProjectApp() .
m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
1. Make sure the InitInstance method of your application calls its parent InitInstance method:
CWinApp::InitInstance or CWinAppEx::InitInstance . The InitInstance method is responsible for checking
the m_dwRestartManagerSupportFlags parameter.
2. Compile and run your application.
See also
CDataRecoveryHandler Class
CWinApp::m_dwRestartManagerSupportFlags
CWinApp Class
CWinApp::m_nAutosaveInterval
CDocument::OnDocumentEvent
Dynamic Layout
9/11/2019 • 5 minutes to read • Edit Online
With MFC in Visual Studio 2015, you can create dialogs that the user can resize, and you can control the way the
layout adjusts to the change in size. For example, you can attach buttons at the bottom of a dialog to the bottom
edge so they always stay at the bottom. You can also set up certain controls such as listboxes, editboxes, and text
fields to expand as the user expands the dialog.
After being resized, the listbox area is increased to show more items, and the buttons are moved along with the
bottom right corner:
You can control dynamic layout by specifying the details for each control in the Resource Editor in the IDE, or you
can do so programmatically by accessing the CMFCDynamicLayout object for a particular control and setting the
properties.
Setting dynamic layout properties in the resource editor
You can set the dynamic layout behavior for a dialog box without having to write any code, by using the resource
editor.
To set dynamic layout properties in the resource editor
1. With an MFC project open, open the dialog you want to work with in the dialog editor.
2. Select a control and in the Proper ties window (in Class View ), set its dynamic layout properties. The
Dynamic Layout section in the Proper ties window contains the properties Moving Type , Sizing Type ,
and, depending on the values selected for those properties, specific properties that define how much
controls move or change size. Moving Type determines how a control is moved as the size of the dialog is
changed; Sizing Type determines how a control is resized as the size of the dialog is changed. Moving
Type and Sizing Type may be Horizontal , Ver tical , Both , or None depending on the dimensions that
you want to change dynamically. Horizontal is the X dimension; Vertical is the Y direction.
3. If you want a control such as a button to be at a fixed size and stay in place at the bottom right, as is
common for the OK or Cancel buttons, set the Sizing Type to None , and set the Moving Type to Both .
For the Moving X and Moving Y values under Moving Type , set 100% to cause the control to stay a fixed
distance from the bottom right corner.
4. Suppose you also have a control that you want to expand as the dialog expands. Typically, a user might
expand a dialog in order to expand a multiline editbox to increase the size of the text area, or they might
expand a list control to see more data. For this case, set the Sizing Type to Both, and set the Moving Type
to none. Then, set the Sizing X and Sizing Y values to 100.
5. Experiment with other values that might make sense for your controls. A dialog with a one-line textbox
might have the Sizing Type set to Horizontal only, for example.
Setting dynamic layout properties programmatically
The previous procedure is useful for specifying dynamic layout properties for a dialog at design time, but if you
want to control the dynamic layout at runtime, you can set dynamic layout properties programmatically.
To set dynamic layout properties programmatically
1. Find or create a place in your dialog class's implementation code where you want to specify the dynamic
layout for the dialog. For example, you might want to add a method such as AdjustLayout in your dialog,
and call it from places where the layout needs to be changed. You might first call this from the constructor,
or after making changes to the dialog.
2. For the dialog, call GetDynamicLayout, a method of the CWnd class. GetDynamicLayout returns a pointer to a
CMFCDynamicLayout object.
3. For the first control to which you want to add dynamic behavior, use the static methods on the dynamic
layout class to create the MoveSettings structure that encodes the way the control should be adjusted. You
do this by first choosing the appropriate static method: CMFCDynamicLayout::MoveHorizontal,
CMFCDynamicLayout::MoveVertical, CMFCDynamicLayout::MoveNone, or
CMFCDynamicLayout::MoveHorizontalAndVertical. You pass in a percentage for the horizontal and/or
vertical aspects of the move. These static methods all return a newly created MoveSettings object that you
can use to specify a control's move behavior.
Keep in mind that 100 means move exactly as much as the dialog changes size, which causes a control's
edge to stay a fixed distance from the new border.
4. Do the same thing for the size behavior, which uses the SizeSettings type. For example, to specify that a
control does not change size when the dialog resizes, use the following code:
5. Add the control to the dynamic layout manager using the CMFCDynamicLayout::AddItem method. There are
two overloads for different ways of specifying the desired control. One takes the control's window handle
(HWND), and the other takes the control ID.
dynamicLayout->AddItem(hWndControl,
moveSettings,
sizeSettings);
pDialog->EnableDynamicLayout(TRUE);
9. The next time the user resizes the dialog, the CMFCDynamicLayout::Adjust method is called which actually
applies the settings.
10. If you want to disable dynamic layout, call CWnd::EnableDynamicLayout with FALSE as for the bEnabled
parameter.
pDialog->EnableDynamicLayout(FALSE);
dynamicLayout->LoadResource("IDD_DIALOG1");
The named resource must reference a dialog that contains layout information in the form of an
AFX_DIALOG_L AYOUT entry in the resource file, as in the following example:
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MFCAPPLICATION1_DIALOG AFX_DIALOG_LAYOUT
BEGIN
0x0000,
0x6400,
0x0028,
0x643c,
0x0028
END
IDD_DIALOG1 AFX_DIALOG_LAYOUT
BEGIN
0x0000,
0x6464,
0x0000,
0x6464,
0x0000,
0x0000,
0x6464,
0x0000,
0x0000
END
See also
CMFCDynamicLayout Class
Control Classes
Dialog Box Classes
Dialog Editor
Dynamic Dialog Layout for MFC in Visual C++ 2015
Using CObject
3/16/2020 • 2 minutes to read • Edit Online
CObject is the root base class for most of the Microsoft Foundation Class Library (MFC). The CObject class
contains many useful features that you may want to incorporate into your own program objects, including
serialization support, run-time class information, and object diagnostic output. If you derive your class from
CObject , your class can exploit these CObject features.
See also
Concepts
General MFC Topics
CRuntimeClass Structure
Files
Serialization
Deriving a Class from CObject
3/16/2020 • 2 minutes to read • Edit Online
This article describes the minimum steps necessary to derive a class from CObject. Other CObject class articles
describe the steps needed to take advantage of specific CObject features, such as serialization and diagnostic
debugging support.
In the discussions of CObject , the terms "interface file" and "implementation file" are used frequently. The
interface file (often called the header file, or .H file) contains the class declaration and any other information
needed to use the class. The implementation file (or .CPP file) contains the class definition as well as the code that
implements the class member functions. For example, for a class named CPerson , you would typically create an
interface file named PERSON.H and an implementation file named PERSON.CPP. However, for some small classes
that will not be shared among applications, it is sometimes easier to combine the interface and implementation
into a single .CPP file.
You can choose from four levels of functionality when deriving a class from CObject :
Basic functionality: No support for run-time class information or serialization but includes diagnostic
memory management.
Basic functionality plus support for run-time class information.
Basic functionality plus support for run-time class information and dynamic creation.
Basic functionality plus support for run-time class information, dynamic creation, and serialization.
Classes designed for reuse (those that will later serve as base classes) should at least include run-time class
support and serialization support, if any future serialization need is anticipated.
You choose the level of functionality by using specific declaration and implementation macros in the declaration
and implementation of the classes you derive from CObject .
The following table shows the relationship among the macros used to support serialization and run-time
information.
Macros Used for Serialization and Run-Time Information
C RUN T IM EC L A SS: : C A RC H IVE: : O P ERATO R>>
DECLARE_DYNAMIC Yes No No
Normally, however, you may want to override some of CObject 's member functions to handle the specifics of
your new class. For example, you may usually want to override the Dump function of CObject to provide
debugging output for the contents of your class. For details on how to override Dump , see the article Object Dump
Customization. You may also want to override the AssertValid function of CObject to provide customized testing
to validate the consistency of the data members of class objects. For a description of how to override AssertValid ,
see MFC ASSERT_VALID and CObject::AssertValid.
The article Specifying Levels of Functionality describes how to specify other levels of functionality, including run-
time class information, dynamic object creation, and serialization.
See also
Using CObject
Specifying Levels of Functionality
3/4/2019 • 2 minutes to read • Edit Online
This article describes how to add the following levels of functionality to your CObject-derived class:
Run-time class information
Dynamic creation support
Serialization support
For a general description of CObject functionality, see the article Deriving a Class from CObject.
// other declarations
};
3. Use the IMPLEMENT_DYNAMIC macro in the implementation file (.CPP) of your class. This macro takes as
arguments the name of the class and its base class, as follows:
IMPLEMENT_DYNAMIC(CPerson, CObject)
NOTE
Always put IMPLEMENT_DYNAMIC in the implementation file (.CPP) for your class. The IMPLEMENT_DYNAMIC macro
should be evaluated only once during a compilation and therefore should not be used in an interface file (.H) that could
potentially be included in more than one file.
NOTE
A "polymorphic pointer" points to an object of a class (call it A) or to an object of any class derived from A (say, B). To serialize
through a polymorphic pointer, the framework must determine the run-time class of the object it is serializing (B), since it
might be an object of any class derived from some base class (A).
For more details on how to enable serialization when you derive your class from CObject , see the articles Files in
MFC and Serialization.
See also
Deriving a Class from CObject
Accessing Run-Time Class Information
3/27/2020 • 2 minutes to read • Edit Online
This article explains how to access information about the class of an object at run time.
NOTE
MFC does not use the Run-Time Type Information (RTTI) support introduced in Visual C++ 4.0.
If you have derived your class from CObject and used the DECL ARE _DYNAMIC and IMPLEMENT_DYNAMIC , the
DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE , or the DECLARE_SERIAL and IMPLEMENT_SERIAL macros explained in
the article Deriving a Class from CObject, the CObject class has the ability to determine the exact class of an
object at run time.
This ability is most useful when extra type checking of function arguments is needed and when you must write
special-purpose code based on the class of an object. However, this practice is not usually recommended because
it duplicates the functionality of virtual functions.
The CObject member function IsKindOf can be used to determine if a particular object belongs to a specified
class or if it is derived from a specific class. The argument to IsKindOf is a CRuntimeClass object, which you can
get using the RUNTIME_CLASS macro with the name of the class.
To use the RUNTIME_CLASS macro
1. Use RUNTIME_CLASS with the name of the class, as shown here for the class CObject :
You will rarely need to access the run-time class object directly. A more common use is to pass the run-time class
object to the IsKindOf function, as shown in the next procedure. The IsKindOf function tests an object to see if it
belongs to a particular class.
To use the IsKindOf function
1. Make sure the class has run-time class support. That is, the class must have been derived directly or
indirectly from CObject and used the DECL ARE _DYNAMIC and IMPLEMENT_DYNAMIC , the
DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE , or the DECLARE_SERIAL and IMPLEMENT_SERIAL macros
explained in the article Deriving a Class from CObject.
2. Call the IsKindOf member function for objects of that class, using the RUNTIME_CLASS macro to generate
the CRuntimeClass argument, as shown here:
// other declarations
};
IMPLEMENT_DYNAMIC(CPerson, CObject)
IMPLEMENT_DYNCREATE(CMyDynCreateObj, CObject)
void SomeFunction(void)
{
CObject *pMyObject = new CPerson;
delete pMyObject;
}
NOTE
IsKindOf returns TRUE if the object is a member of the specified class or of a class derived from the specified class.
IsKindOf does not support multiple inheritance or virtual base classes, although you can use multiple inheritance
for your derived Microsoft Foundation classes if necessary.
One use of run-time class information is in the dynamic creation of objects. This process is discussed in the article
Dynamic Object Creation.
For more detailed information on serialization and run-time class information, see the articles Files in MFC and
Serialization.
See also
Using CObject
Dynamic Object Creation
3/30/2020 • 2 minutes to read • Edit Online
This article explains how to create an object dynamically at run time. The procedure uses run-time class
information, as discussed in the article Accessing Run-Time Class Information.
Dynamically create an object given its run-time class
1. Use the following code to dynamically create an object using the CreateObject function of the
CRuntimeClass . On failure, CreateObject returns NULL instead of raising an exception:
See also
Destroying Window Objects Using CObject
CObject Class: Frequently Asked Questions
3/16/2020 • 2 minutes to read • Edit Online
See also
Using CObject
Do I Have to Derive New Classes from CObject?
3/16/2020 • 2 minutes to read • Edit Online
See also
CObject Class: Frequently Asked Questions
What Does it Cost me to Derive a Class from
CObject?
3/16/2020 • 2 minutes to read • Edit Online
The overhead in deriving from class CObject is minimal. Your derived class inherits only four virtual functions and a
single CRuntimeClass object.
See also
CObject Class: Frequently Asked Questions
Collections
3/27/2020 • 2 minutes to read • Edit Online
The Microsoft Foundation Class Library provides collection classes to manage groups of objects. These classes
are of two types:
Collection classes created from C++ templates
Collection classes not created from templates
NOTE
If your code already uses nontemplate collection classes, you can continue to use them. If you write new type-safe
collection classes for your own data types, we recommend that you use the newer template-based classes.
Collection Shapes
A collection class is characterized by its "shape" and by the types of its elements. The shape refers to the way
the objects are organized and stored by the collection. MFC provides three basic collection shapes: lists, arrays,
and maps (also known as dictionaries). You can pick the collection shape that is most suited to your particular
programming problem.
Each of the three provided collection shapes is described briefly later in this topic. To compare the features of
the shapes to help you decide which is best for your program, see Recommendations for Choosing a Collection
Class.
List
The list class provides an ordered, nonindexed list of elements, implemented as a doubly linked list. A list
has a "head" and a "tail," and adding or removing elements from the head or tail, or inserting or deleting
elements in the middle, is very fast.
Array
The array class provides a dynamically sized, ordered, and integer-indexed array of objects.
Map (also known as a dictionary)
A map is a collection that associates a key object with a value object.
CPtrArray CMapStringToPtr
CStringArray CMapStringToString
CWordArray CMapWordToOb
CUIntArray CMapWordToPtr
The Characteristics of MFC Collection Classes table in Recommendations for Choosing a Collection Class
describes the MFC collection classes in terms of these characteristics (other than shape):
Whether the class uses C++ templates
Whether the elements stored in the collection can be serialized
Whether the elements stored in the collection can be dumped for diagnostics
Whether the collection is type-safe
What do you want to do
General Collection-Class Tasks
Recommendations for Choosing a Collection Class
How to: Make a Type-Safe Collection
Creating Stack and Queue Collections
CArray::Add
Template-Based Collection-Class Tasks
Template-Based Classes
Accessing the Members of a Collection (Template-Based or Not)
Accessing All Members of a Collection
Deleting All Objects in a CObject Collection
See also
Concepts
General MFC Topics
Recommendations for Choosing a Collection Class
3/27/2020 • 3 minutes to read • Edit Online
This article contains detailed information designed to help you choose a collection class for your particular
application needs.
Your choice of a collection class depends on a number of factors, including:
The features of the class shape: order, indexing, and performance, as shown in the Collection Shape Features
table later in this topic
Whether the class uses C++ templates
Whether the elements stored in the collection can be serialized
Whether the elements stored in the collection can be dumped for diagnostics
Whether the collection is type-safe
The following table, Collection Shape Features, summarizes the characteristics of the available collection shapes.
Columns 2 and 3 describe each shape's ordering and access characteristics. In the table, the term "ordered"
means that the order in which items are inserted and deleted determines their order in the collection; it
does not mean the items are sorted on their contents. The term "indexed" means that the items in the
collection can be retrieved by an integer index, much like items in a typical array.
Columns 4 and 5 describe each shape's performance. In applications that require many insertions into the
collection, insertion speed might be especially important; for other applications, lookup speed may be more
important.
Column 6 describes whether each shape allows duplicate elements.
Collection Shape Features
SEA RC H F O R
IN SERT A N SP EC IF IED DUP L IC AT E
SH A P E O RDERED IN DEXED EL EM EN T EL EM EN T EL EM EN T S
The following table, Characteristics of MFC Collection Classes, summarizes other important characteristics of
specific MFC collection classes as a guide to selection. Your choice may depend on whether the class is based on
C++ templates, whether its elements can be serialized via MFC's document serialization mechanism, whether its
elements can be dumped via MFC's diagnostic dumping mechanism, or whether the class is type-safe — that is,
whether you can guarantee the type of elements stored in and retrieved from a collection based on the class.
Characteristics of MFC Collection Classes
USES C ++ C AN BE C AN BE IS
C L A SS T EM P L AT ES SERIA L IZ ED DUM P ED T Y P E- SA F E
CMapPtrToPtr No No Yes No
CMapPtrToWord No No Yes No
CMapStringToPtr No No Yes No
CMapWordToPtr No No Yes No
CPtrArray No No Yes No
CPtrList No No Yes No
1. To serialize, you must explicitly call the collection object's Serialize function; to dump, you must explicitly
call its Dump function. You cannot use the form ar << collObj to serialize or the form dmp << collObj to
dump.
2. Serializability depends on the underlying collection type. For example, if a typed pointer array is based on
CObArray , it is serializable; if based on CPtrArray , it is not serializable. In general, the "Ptr" classes cannot
be serialized.
3. If marked Yes in this column, a nontemplate collection class is type-safe provided you use it as intended. For
example, if you store bytes in a CByteArray , the array is type-safe. But if you use it to store characters, its
type safety is less certain.
See also
Collections
Template-Based Classes
How to: Make a Type-Safe Collection
Accessing All Members of a Collection
Template-Based Classes
3/27/2020 • 5 minutes to read • Edit Online
This article explains the type-safe template-based collection classes in MFC version 3.0 and later. Using these
templates to create type-safe collections is more convenient and helps provide type safety more effectively than
using the collection classes not based on templates.
MFC predefines two categories of template-based collections:
Simple array, list, and map classes
CArray , CList , CMap
The simple collection classes are all derived from class CObject , so they inherit the serialization, dynamic creation,
and other properties of CObject . The typed pointer collection classes require you to specify the class you derive
from — which must be one of the nontemplate pointer collections predefined by MFC, such as CPtrList or
CPtrArray . Your new collection class inherits from the specified base class, and the new class's member functions
use encapsulated calls to the base class members to enforce type safety.
For more information about C++ templates, see Templates in the C++ Language Reference.
The first example declares an array collection, myArray , that contains int s. The second example declares a list
collection, myList , that stores CPerson objects. Certain member functions of the collection classes take
arguments whose type is specified by the ARG_TYPE template parameter. For example, the Add member function
of class CArray takes an ARG_TYPE argument:
CArray<CPerson, CPerson &> personArr;
CPerson person;
personArr.Add(person);
The first example stores MY_STRUCT values, accesses them by int keys, and returns accessed MY_STRUCT items by
reference. The second example stores CPerson values, accesses them by CString keys, and returns references to
accessed items. This example might represent a simple address book, in which you look up persons by last name.
Because the KEY parameter is of type CString and the KEY_TYPE parameter is of type LPCSTR , the keys are stored
in the map as items of type CString but are referenced in functions such as SetAt through pointers of type
LPCSTR . For example:
The first example declares a typed-pointer array, myArray , derived from CObArray . The array stores and returns
pointers to CPerson objects (where CPerson is a class derived from CObject ). You can call any CObArray member
function, or you can call the new type-safe GetAt and ElementAt functions or use the type-safe [ ] operator.
The second example declares a typed-pointer list, myList , derived from CPtrList . The list stores and returns
pointers to MY_STRUCT objects. A class based on CPtrList is used for storing pointers to objects not derived from
CObject . CTypedPtrList has a number of type-safe member functions: GetHead , GetTail , RemoveHead ,
RemoveTail , GetNext , GetPrev , and GetAt .
The first example is a map based on CMapPtrToPtr — it uses CString keys mapped to pointers to MY_STRUCT . You
can look up a stored pointer by calling a type-safe Lookup member function. You can use the [ ] operator to look
up a stored pointer and add it if not found. And you can iterate the map using the type-safe GetNextAssoc
function. You can also call other member functions of class CMapPtrToPtr .
The second example is a map based on CMapStringToOb — it uses string keys mapped to stored pointers to
CMyObject objects. You can use the same type-safe members described in the previous paragraph, or you can call
members of class CMapStringToOb .
NOTE
If you specify a class or struct type for the VALUE parameter, rather than a pointer or reference to the type, the class or
structure must have a copy constructor.
See also
Collections
How to: Make a Type-Safe Collection
3/27/2020 • 4 minutes to read • Edit Online
This article explains how to make type-safe collections for your own data types. Topics include:
Using template-based classes for type safety
Implementing helper functions
Using nontemplate collection classes
The Microsoft Foundation Class Library provides predefined type-safe collections based on C++ templates.
Because they are templates, these classes help provide type safety and ease of use without the type-casting and
other extra work involved in using a nontemplate class for this purpose. The MFC sample COLLECT demonstrates
the use of template-based collection classes in an MFC application. In general, use these classes any time you
write new collections code.
m_intList.AddTail(100);
m_intList.RemoveAll();
3. If necessary, implement the helper functions and SerializeElements. For information on implementing
these functions, see Implementing Helper Functions.
This example shows the declaration of a list of integers. The first parameter in step 1 is the type of data stored as
elements of the list. The second parameter specifies how the data is to be passed to and returned from member
functions of the collection class, such as Add and GetAt .
The overloaded insertion operators for CArchive call CObject::Serialize (or an override of that function) for
each CPerson object.
This technique of using a predefined collection type and casting as necessary may be adequate for many of
your collection needs. If you need further functionality or more type safety, use a template-based class, or
follow the next procedure.
To derive and extend a nontemplate type-safe collection
1. Derive your own collection class from one of the predefined nontemplate classes.
When you derive your class, you can add type-safe wrapper functions to provide a type-safe interface to
existing functions.
For example, if you derived a list from CObList to hold CPerson objects, you might add the wrapper
functions AddHeadPerson and GetHeadPerson , as shown below.
These wrapper functions provide a type-safe way to add and retrieve CPerson objects from the derived list.
You can see that for the GetHeadPerson function, you are simply encapsulating the type casting.
You can also add new functionality by defining new functions that extend the capabilities of the collection
rather than just wrapping existing functionality in type-safe wrappers. For example, the article Deleting All
Objects in a CObject Collection describes a function to delete all the objects contained in a list. This function
could be added to the derived class as a member function.
See also
Collections
Accessing All Members of a Collection
3/4/2019 • 3 minutes to read • Edit Online
The MFC array collection classes — both template-based and not — use indexes to access their elements. The MFC
list and map collection classes — both template-based and not — use an indicator of type POSITION to describe
a given position within the collection. To access one or more members of these collections, you first initialize the
position indicator and then repeatedly pass that position to the collection and ask it to return the next element. The
collection is not responsible for maintaining state information about the progress of the iteration. That information
is kept in the position indicator. But, given a particular position, the collection is responsible for returning the next
element.
The following procedures show how to iterate over the three main types of collections provided with MFC:
Iterating an array
Iterating a list
Iterating a map
To iterate an array
1. Use sequential index numbers with the GetAt member function:
myArray.Add(new CPerson());
for (int i = 0; i < myArray.GetSize(); i++)
{
CPerson *thePerson = myArray.GetAt(i);
thePerson->AssertValid();
}
This example uses a typed pointer array that contains pointers to CPerson objects. The array is derived
from class CObArray , one of the nontemplate predefined classes. GetAt returns a pointer to a CPerson
object. For typed pointer collection classes — arrays or lists — the first parameter specifies the base class;
the second parameter specifies the type to store.
The CTypedPtrArray class also overloads the [ ] operator so that you can use the customary array-subscript
syntax to access elements of an array. An alternative to the statement in the body of the for loop above is
This operator exists in both const and non-const versions. The const version, which is invoked for const
arrays, can appear only on the right side of an assignment statement.
To iterate a list
1. Use the member functions GetHeadPosition and GetNext to work your way through the list:
CTypedPtrList<CObList, CPerson *> myList;
myList.AddHead(new CPerson());
POSITION pos = myList.GetHeadPosition();
while (pos != NULL)
{
CPerson *thePerson = myList.GetNext(pos);
thePerson->AssertValid();
}
This example uses a typed pointer list to contain pointers to CPerson objects. The list declaration resembles
the one for the array in the procedure To iterate an array but is derived from class CObList . GetNext
returns a pointer to a CPerson object.
To iterate a map
1. Use GetStartPosition to get to the beginning of the map and GetNextAssoc to repeatedly get the next key
and value from the map, as shown by the following example:
myMap.SetAt(_T("Bill"), &myPerson);
POSITION pos = myMap.GetStartPosition();
while (pos != NULL)
{
CPerson *pPerson;
CString string;
// Get key (string) and value (pPerson)
myMap.GetNextAssoc(pos, string, pPerson);
// Use string and pPerson
}
This example uses a simple map template (rather than a typed pointer collection) that uses CString keys
and stores pointers to CPerson objects. When you use access functions such as GetNextAssoc , the class
provides pointers to CPerson objects. If you use one of the nontemplate map collections instead, you must
cast the returned CObject pointer to a pointer to a CPerson .
NOTE
For nontemplate maps, the compiler requires a reference to a CObject pointer in the last parameter to
GetNextAssoc . On input, you must cast your pointers to that type, as shown in the next example.
The template solution is simpler and helps provide better type safety. The nontemplate code is more
complicated, as you can see here:
CMapStringToOb myMap; // A nontemplate collection class
CPerson myPerson;
myMap.SetAt(_T("Bill"), &myPerson);
See also
Collections
Deleting All Objects in a CObject Collection
3/27/2020 • 3 minutes to read • Edit Online
This article explains how to delete all objects in a collection (without deleting the collection object itself).
To delete all the objects in a collection of CObject s (or of objects derived from CObject ), you use one of the
iteration techniques described in the article Accessing All Members of a Collection to delete each object in turn.
Cau t i on
Objects in collections can be shared. That is, the collection keeps a pointer to the object, but other parts of the
program may also have pointers to the same object. You must be careful not to delete an object that is shared until
all the parts have finished using the object.
This article shows you how to delete the objects in:
A list
An array
A map
To delete all objects in a list of pointers to CObject
1. Use GetHeadPosition and GetNext to iterate through the list.
2. Use the delete operator to delete each object as it is encountered in the iteration.
3. Call the RemoveAll function to remove all elements from the list after the objects associated with those
elements have been deleted.
The following example shows how to delete all objects from a list of CPerson objects. Each object in the list is a
pointer to a CPerson object that was originally allocated on the heap.
The last function call, RemoveAll , is a list member function that removes all elements from the list. The member
function RemoveAt removes a single element.
Notice the difference between deleting an element's object and removing the element itself. Removing an element
from the list merely removes the list's reference to the object. The object still exists in memory. When you delete
an object, it ceases to exist and its memory is reclaimed. Thus, it is important to remove an element immediately
after the element's object has been deleted so that the list won't try to access objects that no longer exist.
To delete all elements in an array
1. Use GetSize and integer index values to iterate through the array.
2. Use the delete operator to delete each element as it is encountered in the iteration.
3. Call the RemoveAll function to remove all elements from the array after they have been deleted.
The code for deleting all elements of an array is as follows:
int i = 0;
while (i < myArray.GetSize())
{
delete myArray.GetAt(i++);
}
myArray.RemoveAll();
As with the list example above, you can call RemoveAll to remove all elements in an array or RemoveAt to remove
an individual element.
To delete all elements in a map
1. Use GetStartPosition and GetNextAssoc to iterate through the array.
2. Use the delete operator to delete the key and/or value for each map element as it is encountered in the
iteration.
3. Call the RemoveAll function to remove all elements from the map after they have been deleted.
The code for deleting all elements of a CMap collection is as follows. Each element in the map has a string
as the key and a CPerson object (derived from CObject ) as the value.
You can call RemoveAll to remove all elements in a map or RemoveKey to remove an individual element with the
specified key.
See also
Accessing All Members of a Collection
Creating Stack and Queue Collections
3/27/2020 • 2 minutes to read • Edit Online
This article explains how to create other data structures, such as stacks and queues, from MFC list classes. The
examples use classes derived from CList , but you can use CList directly unless you need to add functionality.
Stacks
Because the standard list collection has both a head and a tail, it is easy to create a derived list collection that
mimics the behavior of a last-in-first-out stack. A stack is like a stack of trays in a cafeteria. As trays are added to the
stack, they go on top of the stack. The last tray added is the first to be removed. The list collection member
functions AddHead and RemoveHead can be used to add and remove elements specifically from the head of the list;
thus, the most recently added element is the first to be removed.
To create a stack collection
1. Derive a new list class from one of the existing MFC list classes and add more member functions to support
the functionality of stack operations.
The following example shows how to add member functions to push elements on to the stack, peek at the
top element of the stack, and pop the top element from the stack:
Note that this approach exposes the underlying CObList class. The user can call any CObList member function,
whether it makes sense for a stack or not.
Queues
Because the standard list collection has both a head and a tail, it is also easy to create a derived list collection that
mimics the behavior of a first-in-first-out queue. A queue is like a line of people in a cafeteria. The first person in
line is the first to be served. As more people come, they go to the end of the line to wait their turn. The list
collection member functions AddTail and RemoveHead can be used to add and remove elements specifically from
the head or tail of the list; thus, the most recently added element is always the last to be removed.
To create a queue collection
1. Derive a new list class from one of the predefined list classes provided with the Microsoft Foundation Class
Library and add more member functions to support the semantics of queue operations.
The following example shows how you can append member functions to add an element to the end of the
queue and get the element from the front of the queue.
See also
Collections
Exception Handling in MFC
3/27/2020 • 4 minutes to read • Edit Online
This article explains the exception-handling mechanisms available in MFC. Two mechanisms are available:
C++ exceptions, available in MFC version 3.0 and later
The MFC exception macros, available in MFC versions 1.0 and later
If you're writing a new application using MFC, you should use the C++ mechanism. You can use the macro-
based mechanism if your existing application already uses that mechanism extensively.
You can readily convert existing code to use C++ exceptions instead of the MFC exception macros.
Advantages of converting your code and guidelines for doing so are described in the article Exceptions:
Converting from MFC Exception Macros.
If you have already developed an application using the MFC exception macros, you can continue using these
macros in your existing code, while using C++ exceptions in your new code. The article Exceptions: Changes
to Exception Macros in Version 3.0 gives guidelines for doing so.
NOTE
To enable C++ exception handling in your code, select Enable C++ Exceptions on the Code Generation page in the
C/C++ folder of the project's Property Pages dialog box, or use the /EHsc compiler option.
EXC EP T IO N C L A SS M EA N IN G
CUserException Class Exception that alerts the user with a message box, then
throws a generic CException Class
Since version 3.0, MFC has used C++ exceptions but still supports its older exception handling macros, which
are similar to C++ exceptions in form. Although these macros are not recommended for new programming,
they are still supported for backward compatibility. In programs that already use the macros, you can freely
use C++ exceptions as well. During preprocessing, the macros evaluate to the exception handling keywords
defined in the MSVC implementation of the C++ language as of Visual C++ version 2.0. You can leave
existing exception macros in place while you begin to use C++ exceptions. For information on mixing macros
and C++ exception handling and on converting old code to use the new mechanism, see the articles
Exceptions: Using MFC Macros and C++ Exceptions and Exceptions: Converting from MFC Exception Macros.
The older MFC exception macros, if you still use them, evaluate to C++ exception keywords. See Exceptions:
Changes to Exception Macros in Version 3.0. MFC does not directly support Windows NT structured exception
handlers (SEH), as discussed in Structured Exception Handling.
See also
Modern C++ best practices for exceptions and error handling
How Do I: Create my Own Custom Exception Classes
Exceptions: Changes to Exception Macros in Version
3.0
3/27/2020 • 2 minutes to read • Edit Online
TRY
{
THROW((CException*) new CCustomException());
}
CATCH(CCustomException, e)
{
TRACE("MFC 2.x will land here\n");
}
AND_CATCH(CException, e)
{
TRACE("MFC 3.0 will land here\n");
}
END_CATCH
This code behaves differently in version 3.0 because control always passes to the first catch block with a matching
exception-declaration. The result of the throw expression
is thrown as a CException* , even though it is constructed as a CCustomException . The CATCH macro in MFC
versions 2.5 and earlier uses CObject::IsKindOf to test the type at run time. Because the expression
e->IsKindOf(RUNTIME_CLASS(CException));
is true, the first catch block catches the exception. In version 3.0, which uses C++ exceptions to implement many of
the exception-handling macros, the second catch block matches the thrown CException .
Code like this is uncommon. It usually appears when an exception object is passed to another function that accepts
a generic CException* , performs "pre-throw" processing, and finally throws the exception.
To work around this problem, move the throw expression from the function to the calling code and throw an
exception of the actual type known to the compiler at the time the exception is generated.
Re-Throwing Exceptions
A catch block cannot throw the same exception pointer that it caught.
For example, this code was valid in previous versions, but will have unexpected results with version 3.0:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
THROW(e); // Wrong. Use THROW_LAST() instead
}
END_CATCH
}
Using THROW in the catch block causes the pointer e to be deleted, so that the outer catch site will receive an
invalid pointer. Use THROW_L AST to re-throw e .
For more information, see Exceptions: Catching and Deleting Exceptions.
See also
Exception Handling
Exceptions: Catching and Deleting Exceptions
3/27/2020 • 2 minutes to read • Edit Online
The following instructions and examples show you how to catch and delete exceptions. For more information on
the tr y , catch , and throw keywords, see Modern C++ best practices for exceptions and error handling.
Your exception handlers must delete exception objects they handle, because failure to delete the exception causes
a memory leak whenever that code catches an exception.
Your catch block must delete an exception when:
The catch block throws a new exception.
Of course, you must not delete the exception if you throw the same exception again:
catch (CException* e)
{
if (m_bThrowExceptionAgain)
throw; // Do not delete e
else
e->Delete();
}
NOTE
When deleting a CException , use the Delete member function to delete the exception. Do not use the delete keyword,
because it can fail if the exception is not on the heap.
try
{
// Execute some code that might throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
// Handle the exception here.
// "e" contains information about the exception.
e->Delete();
}
When an exception is thrown, control passes to the first catch block whose exception-declaration matches
the type of the exception. You can selectively handle different types of exceptions with sequential catch
blocks as listed below:
try
{
// Execute some code that might throw an exception.
AfxThrowUserException();
}
catch (CMemoryException* e)
{
// Handle the out-of-memory exception here.
e->Delete();
}
catch (CFileException* e)
{
// Handle the file exceptions here.
e->Delete();
}
catch (CException* e)
{
// Handle all other types of exceptions here.
e->Delete();
}
For more information, see Exceptions: Converting from MFC Exception Macros.
See also
Exception Handling
Exceptions: Converting from MFC Exception Macros
3/27/2020 • 3 minutes to read • Edit Online
Advantages of Converting
You probably do not need to convert existing code, although you should be aware of differences between the
macro implementations in MFC version 3.0 and the implementations in earlier versions. These differences and
subsequent changes in code behavior are discussed in Exceptions: Changes to Exception Macros in Version 3.0.
The principal advantages of converting are:
Code that uses the C++ exception-handling keywords compiles to a slightly smaller .EXE or .DLL.
The C++ exception-handling keywords are more versatile: They can handle exceptions of any data type that
can be copied (int , float , char , and so on), whereas the macros handle exceptions only of class CException
and classes derived from it.
The major difference between the macros and the keywords is that code using the macros "automatically" deletes
a caught exception when the exception goes out of scope. Code using the keywords does not, so you must
explicitly delete a caught exception. For more information, see the article Exceptions: Catching and Deleting
Exceptions.
Another difference is syntax. The syntax for macros and keywords differs in three respects:
1. Macro arguments and exception declarations:
A CATCH macro invocation has the following syntax:
CATCH( exception_class, exception_object_pointer_name )
Notice the comma between the class name and the object pointer name.
The exception declaration for the catch keyword uses this syntax:
catch( exception_type exception_name )
This exception declaration statement indicates the type of exception the catch block handles.
2. Delimitation of catch blocks:
With the macros, the CATCH macro (with its arguments) begins the first catch block; the AND_CATCH
macro begins subsequent catch blocks, and the END_CATCH macro terminates the sequence of catch
blocks.
With the keywords, the catch keyword (with its exception declaration) begins each catch block. There is no
counterpart to the END_CATCH macro; the catch block ends with its closing brace.
3. The throw expression:
The macros use THROW_L AST to re-throw the current exception. The throw keyword, with no argument,
has the same effect.
CATCH(CException, e)
to
catch (CException* e)
4. Modify the code in the catch blocks so that it deletes exception objects as necessary. For more information,
see the article Exceptions: Catching and Deleting Exceptions.
Here is an example of exception-handling code using MFC exception macros. Note that because the code in the
following example uses the macros, the exception e is deleted automatically:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
The code in the next example uses the C++ exception keywords, so the exception must be explicitly deleted:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch (CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
For more information, see Exceptions: Using MFC Macros and C++ Exceptions.
See also
Exception Handling
Exceptions: Using MFC Macros and C++ Exceptions
3/27/2020 • 2 minutes to read • Edit Online
This article discusses considerations for writing code that uses both the MFC exception-handling macros and the
C++ exception-handling keywords.
This article covers the following topics:
Mixing exception keywords and macros
Try blocks inside catch blocks
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
throw; // Invalid attempt to throw exception
// to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is invalid because
// it was deleted in the inner catch block.
}
END_CATCH
The problem occurs because e is deleted when execution passes out of the "inner" CATCH block. Using the
THROW_L AST macro instead of the THROW statement will cause the "outer" CATCH block to receive a valid
pointer:
TRY
{
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e) // The "inner" catch block
{
THROW_LAST(); // Throw exception to the outer catch block below.
}
END_CATCH
}
CATCH(CException, e) // The "outer" catch block
{
// Pointer e is valid because
// THROW_LAST() was used.
}
END_CATCH
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
try
{
throw; // Wrong. Causes e (the exception
// being thrown) to be deleted.
}
catch (CException* exception)
{
exception->ReportError();
}
}
END_CATCH
See also
Exception Handling
Exceptions: Examining Exception Contents
3/4/2019 • 2 minutes to read • Edit Online
Although a catch block's argument can be of almost any data type, the MFC functions throw exceptions of types
derived from the class CException . To catch an exception thrown by an MFC function, then, you write a catch block
whose argument is a pointer to a CException object (or an object derived from CException , such as
CMemoryException ). Depending on the exact type of the exception, you can examine the data members of the
exception object to gather information about the specific cause of the exception.
For example, the CFileException type has the m_cause data member, which contains an enumerated type that
specifies the cause of the file exception. Some examples of the possible return values are
CFileException::fileNotFound and CFileException::readOnly .
The following example shows how to examine the contents of a CFileException . Other exception types can be
examined similarly.
try
{
CFile file(_T("\\this_file_should_not_exist.dat"), CFile::modeRead);
}
catch (CFileException* theException)
{
if (theException->m_cause == CFileException::fileNotFound)
TRACE("File not found\n");
theException->Delete();
}
For more information, see Exceptions: Freeing Objects in Exceptions and Exceptions: Catching and Deleting
Exceptions.
See also
Exception Handling
Exceptions: Freeing Objects in Exceptions
3/27/2020 • 3 minutes to read • Edit Online
This article explains the need and the method of freeing objects when an exception occurs. Topics include:
Handling the exception locally
Throwing exceptions after destroying objects
Exceptions thrown by the framework or by your application interrupt normal program flow. Thus, it is very
important to keep close track of objects so that you can properly dispose of them in case an exception is thrown.
There are two primary methods to do this.
Handle exceptions locally using the tr y and catch keywords, then destroy all objects with one statement.
Destroy any object in the catch block before throwing the exception outside the block for further handling.
These two approaches are illustrated below as solutions to the following problematic example:
As written above, myPerson will not be deleted if an exception is thrown by SomeFunc . Execution jumps directly to
the next outer exception handler, bypassing the normal function exit and the code that deletes the object. The
pointer to the object goes out of scope when the exception leaves the function, and the memory occupied by the
object will never be recovered as long as the program is running. This is a memory leak; it would be detected by
using the memory diagnostics.
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
// Handle the exception locally
e->Delete();
}
This new example sets up an exception handler to catch the exception and handle it locally. It then exits the function
normally and destroys the object. The important aspect of this example is that a context to catch the exception is
established with the tr y/catch blocks. Without a local exception frame, the function would never know that an
exception had been thrown and would not have the chance to exit normally and destroy the object.
void SomeFunc()
{
CPerson* myPerson = new CPerson;
try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
e->ReportError();
// Destroy the object before passing exception on.
delete myPerson;
// Throw the exception to the next handler.
throw;
}
The exception mechanism automatically deallocates frame objects; the destructor of the frame object is also called.
If you call functions that can throw exceptions, you can use tr y/catch blocks to make sure that you catch the
exceptions and have a chance to destroy any objects you have created. In particular, be aware that many MFC
functions can throw exceptions.
For more information, see Exceptions: Catching and Deleting Exceptions.
See also
Exception Handling
Exceptions: Throwing Exceptions from Your Own
Functions
3/27/2020 • 2 minutes to read • Edit Online
It is possible to use the MFC exception-handling paradigm solely to catch exceptions thrown by functions in MFC
or other libraries. In addition to catching exceptions thrown by library code, you can throw exceptions from your
own code if you are writing functions that can encounter exceptional conditions.
When an exception is thrown, execution of the current function is stopped and jumps directly to the catch block of
the innermost exception frame. The exception mechanism bypasses the normal exit path from a function.
Therefore, you must be sure to delete those memory blocks that would be deleted in a normal exit.
To throw an exception
1. Use one of the MFC helper functions, such as AfxThrowMemoryException . These functions throw a
preallocated exception object of the appropriate type.
In the following example, a function tries to allocate two memory blocks and throws an exception if either
allocation fails:
{
char* p1 = (char*)malloc(SIZE_FIRST);
if (p1 == NULL)
AfxThrowMemoryException();
char* p2 = (char*)malloc(SIZE_SECOND);
if (p2 == NULL)
{
free(p1);
AfxThrowMemoryException();
}
If the first allocation fails, you can simply throw the memory exception. If the first allocation is successful but
the second one fails, you must free the first allocation block before throwing the exception. If both
allocations succeed, you can proceed normally and free the blocks when exiting the function.
or -
2. Use a user-defined exception to indicate a problem condition. You can throw an item of any type, even an
entire class, as your exception.
The following example attempts to play a sound through a wave device and throws an exception if there is a
failure.
#define WAVE_ERROR -5
{
// This Win32 API returns 0 if the sound cannot be played.
// Throw an integer constant if it fails.
if (!PlaySound(_T("SIREN.WAV"), NULL, SND_ASYNC))
throw WAVE_ERROR;
}
NOTE
MFC's default handling of exceptions applies only to pointers to CException objects (and objects of CException -derived
classes). The example above bypasses MFC's exception mechanism.
See also
Exception Handling
Exceptions: Exceptions in Constructors
3/4/2019 • 2 minutes to read • Edit Online
When throwing an exception in a constructor, clean up whatever objects and memory allocations you have made
prior to throwing the exception, as explained in Exceptions: Throwing Exceptions from Your Own Functions.
When throwing an exception in a constructor, the memory for the object itself has already been allocated by the
time the constructor is called. So, the compiler will automatically deallocate the memory occupied by the object
after the exception is thrown.
For more information, see Exceptions: Freeing Objects in Exceptions.
See also
Exception Handling
Exceptions: Database Exceptions
3/27/2020 • 3 minutes to read • Edit Online
This article explains how to handle database exceptions. Most of the material in this article applies whether you
are working with the MFC classes for Open Database Connectivity (ODBC) or the MFC classes for Data Access
Objects (DAO). Material specific to one or the other model is explicitly marked. Topics include:
Approaches to exception handling
A database exception-handling example
m_scode contains an OLE SCODE from DAO, if applicable. You'll seldom need to work with this error code,
however. Usually more information is available in the other two data members. See the data member for
more about SCODE values.
Additional information about DAO errors, the DAO Error object type, and the DAO Errors collection is available
under class CDaoException.
CRecordset* CMyDatabaseDoc::GetRecordset()
{
CCourses* pSet = new CCourses(&m_dbCust);
try
{
pSet->Open();
}
catch (CDBException* e)
{
AfxMessageBox(e->m_strError, MB_ICONEXCLAMATION);
// Delete the incomplete recordset object
delete pSet;
pSet = NULL;
e->Delete();
}
return pSet;
}
CDaoRecordset* CMyDaoDatabaseDoc::GetRecordset()
{
CDaoRecordset* pSet = new CCustSet(&m_db);
try
{
pSet->Open();
}
catch (CDaoException* pe)
{
AfxMessageBox(pe->m_pErrorInfo->m_strDescription, MB_ICONEXCLAMATION);
// Delete the incomplete recordset object
delete pSet;
pSet = NULL;
pe->Delete();
}
return pSet;
}
This code gets an error message string from the m_pErrorInfo member of the exception object. MFC fills this
member when it throws the exception.
For a discussion of the error information returned by a CDaoException object, see classes CDaoException and
CDaoErrorInfo.
When you are working with Microsoft Jet (.mdb) databases, and in most cases when you are working with ODBC,
there will be only one error object. In the rare case when you are using an ODBC data source and there are
multiple errors, you can loop through DAO's Errors collection based on the number of errors returned by
CDaoException::GetErrorCount. Each time through the loop, call CDaoException::GetErrorInfo to refill the
m_pErrorInfo data member.
See also
Exception Handling
Exceptions: OLE Exceptions
11/20/2019 • 2 minutes to read • Edit Online
The techniques and facilities for handling exceptions in OLE are the same as those for handling other exceptions.
For further information on exception handling, see the article Modern C++ best practices for exceptions and error
handling.
All exception objects are derived from the abstract base class CException . MFC provides two classes for handling
OLE exceptions:
COleException For handling general OLE exceptions.
COleDispatchException For generating and handling OLE dispatch (automation) exceptions.
The difference between these two classes is the amount of information they provide and where they are used.
COleException has a public data member that contains the OLE status code for the exception.
COleDispatchException supplies more information, including the following:
See also
Exception Handling
Files in MFC
3/27/2020 • 2 minutes to read • Edit Online
In the Microsoft Foundation Class Library (MFC), class CFile handles normal file I/O operations. This family of
articles explains how to open and close files as well as read and write data to those files. It also discusses file
status operations. For a description of how to use the object-based serialization features of MFC as an alternative
way of reading and writing data in files, see the article Serialization.
NOTE
When you use MFC CDocument objects, the framework does much of the serialization work for you. In particular, the
framework creates and uses the CFile object. You only have to write code in your override of the Serialize member
function of class CDocument .
The CFile class provides an interface for general-purpose binary file operations. The CStdioFile and CMemFile
classes derived from CFile and the CSharedFile class derived from CMemFile supply more specialized file
services.
For more information about alternatives to MFC file handling, see File Handling in the Run-Time Library
Reference.
For information about derived CFile classes, see the MFC hierarchy chart.
See also
Concepts
General MFC Topics
CArchive Class
CObject Class
Opening Files
3/27/2020 • 2 minutes to read • Edit Online
The open flags specify which permissions, such as read-only, you want for the file. The possible flag values
are defined as enumerated constants within the CFile class, so they are qualified with " CFile:: " as in
CFile::modeRead . Use the CFile::modeCreate flag if you want to create the file.
The following example shows how to create a new file with read/write permission (replacing any previous file with
the same path):
NOTE
This example creates and opens a file. If there are problems, the Open call can return a CFileException object in its last
parameter, as shown here. The TRACE macro prints both the file name and a code indicating the reason for failure. You can
call the AfxThrowFileException function if you require more detailed error reporting.
See also
CFile Class
CFile::Open
Files
Reading and Writing Files
3/27/2020 • 2 minutes to read • Edit Online
If you've used the C run-time library file-handling functions, MFC reading and writing operations will appear
familiar. This article describes reading directly from and writing directly to a CFile object. You can also do buffered
file I/O with the CArchive class.
To read from and write to the file
1. Use the Read and Write member functions to read and write data in the file.
-or-
2. The Seek member function is also available for moving to a specific offset within the file.
Read takes a pointer to a buffer and the number of bytes to read and returns the actual number of bytes that were
read. If the required number of bytes could not be read because end-of-file (EOF) is reached, the actual number of
bytes read is returned. If any read error occurs, an exception is thrown. Write is similar to Read , but the number
of bytes written is not returned. If a write error occurs, including not writing all the bytes specified, an exception is
thrown. If you have a valid CFile object, you can read from it or write to it as shown in the following example:
TCHAR szBuffer[256];
UINT nActual = 0;
CFile myFile;
NOTE
You should normally carry out input/output operations within a tr y /catch exception handling block. For more information,
see Exception Handling (MFC).
See also
Files
Closing Files
3/4/2019 • 2 minutes to read • Edit Online
As usual in I/O operations, once you finish with a file, you must close it.
To close a file
1. Use the Close member function. This function closes the file-system file and flushes buffers if necessary.
If you allocated the CFile object on the frame (as in the example shown in Opening Files), the object will
automatically be closed and then destroyed when it goes out of scope. Note that deleting the CFile object does
not delete the physical file in the file system.
See also
Files
Accessing File Status
3/4/2019 • 2 minutes to read • Edit Online
CFile also supports getting file status, including whether the file exists, creation and modification dates and times,
logical size, and path.
To get file status
1. Use the CFile class to get and set information about a file. One useful application is to use the CFile static
member function GetStatus to determine if a file exists. GetStatus returns 0 if the specified file does not exist.
Thus, you could use the result of GetStatus to determine whether to use the CFile::modeCreate flag when
opening a file, as shown by the following example:
CFile theFile;
TCHAR* szFileName = _T("c:\\test\\myfile.dat");
BOOL bOpenOK;
CFileStatus status;
if( CFile::GetStatus( szFileName, status ) )
{
// Open the file without the Create flag
bOpenOK = theFile.Open( szFileName,
CFile::modeWrite );
}
else
{
// Open the file with the Create flag
bOpenOK = theFile.Open( szFileName,
CFile::modeCreate | CFile::modeWrite );
}
See also
Files
Interface Elements
3/4/2019 • 4 minutes to read • Edit Online
This document describes interface elements that were introduced in Visual Studio 2008 SP1, and also describes
differences with the earlier version of the library.
The following illustration shows an application that was built by using the new interface elements.
Window Docking
Window docking functionality resembles the window docking that the Visual Studio graphical user interface uses.
Dock Site
The dock site (or main frame window) owns all panes and mini-frame windows in an application. The dock site
contains a CDockingManager member. This member maintains a list of all panes that belong to the dock site. The
list is ordered so that the panes created at the outer edges of the dock site are positioned at the start of the list.
When the framework redraws the dock site, it loops over this list and adjusts the layout of each pane to include the
current bounding rectangle of the dock site. You can call AdjustDockingLayout or RecalcLayout when you have to
adjust the docking layout, and the framework redirects this call to the docking manager.
Dock Bars
Each main frame window can position dock bars along its borders. A dock bar is a pane that belongs to a CDockSite
Class. Dock bars can accept objects derived from CPane, such as toolbars. To create dock bars when the main frame
window is initialized, call EnableDocking . To enable auto hide bars, call EnableAutoHideBars . EnableAutoHideBars
creates CAutoHideDockSite objects, and positions them next to each dock bar.
Each dock bar is divided into dock rows. Dock rows are represented by the CDockingPanesRow Class. Each dock
row contains a list of toolbars. If a user docks a toolbar or moves the toolbar from one row to another within the
same dock bar, the framework either creates a new row and resizes the dock bar accordingly, or it positions the
toolbar on an existing row.
Mini-frame Windows
A floating pane resides in a mini-frame window. Mini-frame windows are represented by two classes: CMDITabInfo
Class (which can contain only one pane) and CMultiPaneFrameWnd Class (which can contain several panes). To
float a pane in your code, call CBasePane::FloatPane. After a pane floats, the framework automatically creates a
mini-frame window and that mini-frame window becomes the floating pane's parent. When the floating pane
docks, the framework resets its parent, and the floating pane becomes a dock bar (for toolbars) or a dock site (for
resizable panes).
Pane Dividers
Pane dividers (also named sliders or splitters) are represented by the CPaneDivider Class. When a user docks a
pane, the framework creates pane dividers, regardless of whether the pane is docked at the dock site or at another
pane. When a pane docks to the dock site, the pane divider is called the default pane divider. The default pane
divider is responsible for the layout of all the docking panes in the dock site. The dock manager maintains a list of
default pane dividers, and a list of panes. Dock managers are responsible for the layout of all the docking panes.
Containers
All resizable panes, when docked to each other, are maintained in containers. Containers are represented by the
CPaneContainer Class. Each container has pointers to its left pane, right pane, left sub-container, right sub-container,
and the splitter between the left and right parts. (Left and right do not refer to physical sides but rather identify the
branches of a tree structure.) In this manner we can build a tree of panes and splitters and therefore achieve
complex layouts of panes that can be resized together. The CPaneContainer class maintains the tree of containers; it
also maintains two lists of panes and sliders that reside in this tree. Pane container managers are usually embedded
into default sliders and mini-frame windows that carry multiple panes.
See also
Concepts
MAPI
3/4/2019 • 2 minutes to read • Edit Online
This article describes the Microsoft Messaging Application Programming Interface (MAPI) for client message
application developers. MFC supplies support for a subset of MAPI in class CDocument but does not encapsulate
the entire API. For more information, see MAPI Support in MFC.
MAPI is a set of functions that mail-enabled and mail-aware applications use to create, manipulate, transfer, and
store mail messages. It gives application developers the tools to define the purpose and content of mail messages
and gives them flexibility in their management of stored mail messages. MAPI also provides a common interface
that application developers can use to create mail-enabled and mail-aware applications independent of the
underlying messaging system.
Messaging clients provide a human interface for interaction with the Microsoft Windows Messaging System
(WMS). This interaction typically includes requesting services from MAPI-compliant providers such as message
stores and address books.
For more information about MAPI, see the articles under Guide in Win32 Messaging (MAPI) of the Windows SDK.
In This Section
MAPI Support in MFC
See also
CDocument::OnFileSendMail
CDocument::OnUpdateFileSendMail
COleDocument::OnFileSendMail
MAPI Support in MFC
3/27/2020 • 2 minutes to read • Edit Online
MFC supplies support for a subset of the Microsoft Messaging Application Program Interface (MAPI) in class
CDocument . Specifically, CDocument has member functions that determine whether mail support is present on the
end-user's machine and, if so, enable a Send Mail command whose standard command ID is ID_FILE_SEND_MAIL.
The MFC handler function for this command allows the user to send a document through electronic mail.
TIP
Although MFC does not encapsulate the entire MAPI function set, you can still call MAPI functions directly, just as you can
call Win32 API functions directly from MFC programs.
Providing the Send Mail command in your application is very easy. MFC provides the implementation to package
a document (that is, a CDocument -derived object) as an attachment and send it as mail. This attachment is
equivalent to a File Save command that saves (serializes) the document's contents to the mail message. This
implementation calls upon the mail client on the user's machine to give the user the opportunity to address the
mail and to add subject and message text to the mail message. Users see their familiar mail application's user
interface. This functionality is supplied by two CDocument member functions: OnFileSendMail and
OnUpdateFileSendMail .
MAPI needs to read the file to send the attachment. If the application keeps its data file open during an
OnFileSendMail function call, the file needs to be opened with a share mode that allows multiple processes to
access the file.
NOTE
An overriding version of OnFileSendMail for class COleDocument correctly handles compound documents.
ON_COMMAND(ID_FILE_SENDMAIL, &CMyDoc::OnFileSendMail)
ON_UPDATE_COMMAND_UI(ID_FILE_SENDMAIL, &CMyDoc::OnUpdateFileSendMail)
NOTE
This message map works for a document derived from either CDocument or COleDocument — it picks up the
correct base class in either case, even though the message map is in your derived document class.
TIP
Rather than manually adding message map entries as previously described, you can use the class Class Wizard to map
messages to functions. For more information, see Mapping Messages to Functions.
See also
MAPI
MAPI Samples
4/1/2019 • 2 minutes to read • Edit Online
See the following sample programs that illustrate Microsoft Messaging Application Programming Interface (MAPI)
functionality:
NPP
DRAWCLI
See also
MAPI
Memory Management
8/15/2019 • 2 minutes to read • Edit Online
This group of articles describes how to take advantage of the general-purpose services of the Microsoft
Foundation Class Library (MFC) related to memory management. Memory allocation can be divided into two main
categories: frame allocations and heap allocations.
One main difference between the two allocation techniques is that with frame allocation you typically work with
the actual memory block itself, while with heap allocation you are always given a pointer to the memory block.
Another major difference between the two schemes is that frame objects are automatically deleted, while heap
objects must be explicitly deleted by the programmer.
For non-MFC information about memory management in programs for Windows, see Memory Management in
the Windows SDK.
See also
Concepts
General MFC Topics
Memory Management: Frame Allocation
3/21/2019 • 2 minutes to read • Edit Online
Allocation on the frame takes its name from the "stack frame" that is set up whenever a function is called. The stack
frame is an area of memory that temporarily holds the arguments to the function as well as any variables that are
defined local to the function. Frame variables are often called "automatic" variables because the compiler
automatically allocates the space for them.
There are two key characteristics of frame allocations. First, when you define a local variable, enough space is
allocated on the stack frame to hold the entire variable, even if it is a large array or data structure. Second, frame
variables are automatically deleted when they go out of scope:
void MyFunction()
{
// Local object created on the stack
CString strName;
// Object goes out of scope and is deleted as function ends
}
For local function variables, this scope transition happens when the function exits, but the scope of a frame variable
can be smaller than a function if nested braces are used. This automatic deletion of frame variables is very
important. In the case of simple primitive types (such as int or byte ), arrays, or data structures, the automatic
deletion simply reclaims the memory used by the variable. Since the variable has gone out of scope, it cannot be
accessed anyway. In the case of C++ objects, however, the process of automatic deletion is a bit more complicated.
When an object is defined as a frame variable, its constructor is automatically invoked at the point where the
definition is encountered. When the object goes out of scope, its destructor is automatically invoked before the
memory for the object is reclaimed. This automatic construction and destruction can be very handy, but you must
be aware of the automatic calls, especially to the destructor.
The key advantage of allocating objects on the frame is that they are automatically deleted. When you allocate your
objects on the frame, you don't have to worry about forgotten objects causing memory leaks. (For details on
memory leaks, see the article Detecting Memory Leaks in MFC.) A disadvantage of frame allocation is that frame
variables cannot be used outside their scope. Another factor in choosing frame allocation versus heap allocation is
that for large structures and objects, it is often better to use the heap instead of the stack for storage since stack
space is often limited.
See also
Memory Management
Memory Management: Heap Allocation
3/4/2019 • 2 minutes to read • Edit Online
The heap is reserved for the memory allocation needs of the program. It is an area apart from the program code
and the stack. Typical C programs use the functions malloc and free to allocate and deallocate heap memory. The
Debug version of MFC provides modified versions of the C++ built-in operators new and delete to allocate and
deallocate objects in heap memory.
When you use new and delete instead of malloc and free , you are able to take advantage of the class library's
memory-management debugging enhancements, which can be useful in detecting memory leaks. When you build
your program with the Release version of MFC, the standard versions of the new and delete operators provide an
efficient way to allocate and deallocate memory (the Release version of MFC does not provide modified versions of
these operators).
Note that the total size of objects allocated on the heap is limited only by your system's available virtual memory.
See also
Memory Management
Memory Management: Examples
3/27/2020 • 2 minutes to read • Edit Online
This article describes how MFC performs frame allocations and heap allocations for each of the three typical kinds
of memory allocations:
An array of bytes
A data structure
An object
{
const int BUFF_SIZE = 128;
To allocate an array of bytes (or any primitive data type) on the heap
1. Use the new operator with the array syntax shown in this example:
delete[] myCharArray;
delete[] myIntArray;
The memory occupied by the structure is reclaimed when it exits its scope.
To allocate data structures on the heap
1. Use new to allocate data structures on the heap and delete to deallocate them, as shown by the following
examples:
// Heap allocation
MyStructType* myStruct = new MyStructType;
delete myStruct;
Allocation of an Object
To allocate an object on the frame
1. Declare the object as follows:
{
CMyClass myClass; // Automatic constructor call here
The destructor for the object is automatically invoked when the object exits its scope.
To allocate an object on the heap
1. Use the new operator, which returns a pointer to the object, to allocate objects on the heap. Use the delete
operator to delete them.
The following heap and frame examples assume that the CPerson constructor takes no arguments.
If the argument for the CPerson constructor is a pointer to char , the statement for frame allocation is:
See also
Memory Management: Heap Allocation
Memory Management: Resizable Memory Blocks
3/27/2020 • 2 minutes to read • Edit Online
The new and delete operators, described in the article Memory Management: Examples, are good for allocating
and deallocating fixed-size memory blocks and objects. Occasionally, your application may need resizable memory
blocks. You must use the standard C run-time library functions malloc, realloc, and free to manage resizable
memory blocks on the heap.
IMPORTANT
Mixing the new and delete operators with the resizable memory-allocation functions on the same memory block will result
in corrupted memory in the Debug version of MFC. You should not use realloc on a memory block allocated with new .
Likewise, you should not allocate a memory block with the new operator and delete it with free , or use the delete operator
on a block of memory allocated with malloc.
See also
Memory Management: Heap Allocation
Message Handling and Mapping
8/15/2019 • 2 minutes to read • Edit Online
This article family describes how messages and commands are processed by the MFC framework and how you
connect them to their handler functions.
In traditional programs for Windows, Windows messages are handled in a large switch statement in a window
procedure. MFC instead uses message maps to map direct messages to distinct class member functions.
Message maps are more efficient than virtual functions for this purpose, and they allow messages to be
handled by the most appropriate C++ object — application, document, view, and so on. You can map a single
message or a range of messages, command IDs, or control IDs.
WM_COMMAND messages — usually generated by menus, toolbar buttons, or accelerators — also use the
message-map mechanism. MFC defines a standard routing of command messages among the application,
frame window, view, and Active documents in your program. You can override this routing if you need to.
Message maps also supply a way to update user-interface objects (such as menus and toolbar buttons),
enabling or disabling them to suit the current context.
For general information about messages and message queues in Windows, see Messages and Message Queues
in the Windows SDK.
See also
Concepts
General MFC Topics
CWnd Class
CCmdTarget Class
Messages and Commands in the Framework
3/4/2019 • 2 minutes to read • Edit Online
Applications written for Microsoft Windows are "message driven." In response to events such as mouse clicks,
keystrokes, window movements, and so on, Windows sends messages to the proper window. Framework
applications process Windows messages like any other application for Windows. But the framework also provides
some enhancements that make processing messages easier, more maintainable, and better encapsulated.
The following topics introduce the key terms used in the rest of the article family to discuss messages and
commands:
Messages
Message handlers
Message categories
Windows messages and control-notification messages
Command messages
Message maps
User-interface objects and command IDs
Command targets
See also
Message Handling and Mapping
Messages
3/4/2019 • 2 minutes to read • Edit Online
The message loop in the Run member function of class CWinApp retrieves queued messages generated by various
events. For example, when the user clicks the mouse, Windows sends several mouse-related messages, such as
WM_LBUTTONDOWN when the left mouse button is pressed and WM_LBUTTONUP when the left mouse button is
released. The framework's implementation of the application message loop dispatches the message to the
appropriate window.
The important categories of messages are described in Message Categories.
See also
Messages and Commands in the Framework
Message Handlers
9/11/2019 • 2 minutes to read • Edit Online
In MFC, a dedicated handler function processes each separate message. Message-handler functions are member
functions of a class. This documentation uses the terms message-handler member function, message-handler
function, message handler, and handler interchangeably. Some kinds of message handlers are also called
"command handlers."
Writing message handlers accounts for a large proportion of your work in writing a framework application. This
article family describes how the message-processing mechanism works.
What does the handler for a message do It does whatever you want done in response to that message. You can
create the handlers by using the Class Wizard of the class, and then fill in the handler's code using the source code
editor.
You can use all of the facilities of Microsoft Visual C++ and MFC to write your handlers. For a list of all classes, see
Class Library Overview in the MFC Reference.
See also
Messages and Commands in the Framework
Message Categories
3/27/2020 • 2 minutes to read • Edit Online
What kinds of messages do you write handlers for There are three main categories:
1. Windows messages
This includes primarily those messages beginning with the WM_ prefix, except for WM_COMMAND.
Windows messages are handled by windows and views. These messages often have parameters that are
used in determining how to handle the message.
2. Control notifications
This includes WM_COMMAND notification messages from controls and other child windows to their
parent windows. For example, an edit control sends its parent a WM_COMMAND message containing the
EN_CHANGE control-notification code when the user has taken an action that may have altered text in the
edit control. The window's handler for the message responds to the notification message in some
appropriate way, such as retrieving the text in the control.
The framework routes control-notification messages like other WM_ messages. One exception, however, is
the BN_CLICKED control-notification message sent by buttons when the user clicks them. This message is
treated specially as a command message and routed like other commands.
3. Command messages
This includes WM_COMMAND notification messages from user-interface objects: menus, toolbar buttons,
and accelerator keys. The framework processes commands differently from other messages, and they can
be handled by more kinds of objects, as explained in Command Targets.
Command Messages
Messages in category 3 — commands — can be handled by a wider variety of objects: documents, document
templates, and the application object itself in addition to windows and views. When a command directly affects
some particular object, it makes sense to have that object handle the command. For example, the Open command
on the File menu is logically associated with the application: the application opens a specified document upon
receiving the command. So the handler for the Open command is a member function of the application class. For
more about commands and how they are routed to objects, see How the Framework Calls a Handler.
See also
Messages and Commands in the Framework
Mapping Messages
3/4/2019 • 2 minutes to read • Edit Online
Each framework class that can receive messages or commands has its own "message map." The framework uses
message maps to connect messages and commands to their handler functions. Any class derived from class
CCmdTarget can have a message map. Other articles explain message maps in detail and describe how to use
them.
In spite of the name "message map," message maps handle both messages and commands — all three categories
of messages listed in Message Categories.
See also
Messages and Commands in the Framework
User-Interface Objects and Command IDs
3/4/2019 • 2 minutes to read • Edit Online
Menu items, toolbar buttons, and accelerator keys are "user-interface objects" capable of generating commands.
Each such user-interface object has an ID. You associate a user-interface object with a command by assigning the
same ID to the object and the command. As explained in Messages, commands are implemented as special
messages. The figure "Commands in the Framework" below shows how the framework manages commands.
When a user-interface object generates a command, such as ID_EDIT_CLEAR_ALL , one of the objects in your
application handles the command — in the figure below, the document object's OnEditClearAll function is called
via the document's message map.
See also
Messages and Commands in the Framework
Command IDs
3/4/2019 • 2 minutes to read • Edit Online
A command is fully described by its command ID alone (encoded in the WM_COMMAND message). This ID is
assigned to the user-interface object that generates the command. Typically, IDs are named for the functionality of
the user-interface object they are assigned to.
For example, a Clear All item in the Edit menu might be assigned an ID such as ID_EDIT_CLEAR_ALL . The class
library predefines some IDs, particularly for commands that the framework handles itself, such as
ID_EDIT_CLEAR_ALL or ID_FILE_OPEN . You will create other command IDs yourself.
When you create your own menus in the Visual C++ menu editor, it is a good idea to follow the class library's
naming convention as illustrated by ID_FILE_OPEN . Standard Commands explains the standard commands
defined by the class library.
See also
User-Interface Objects and Command IDs
Standard Commands
3/4/2019 • 2 minutes to read • Edit Online
The framework defines many standard command messages. The IDs for these commands typically take the form:
ID_ Source_Item
where Source is usually a menu name and Item is a menu item. For example, the command ID for the New
command on the File menu is ID_FILE_NEW. Standard command IDs are shown in bold type in the documentation.
Programmer-defined IDs are shown in a font that is different from the surrounding text.
The following is a list of some of the most important commands supported:
File Menu Commands
New, Open, Close, Save, Save As, Page Setup, Print Setup, Print, Print Preview, Exit, and most-recently-used files.
Edit Menu Commands
Clear, Clear All, Copy, Cut, Find, Paste, Repeat, Replace, Select All, Undo, and Redo.
View Menu Commands
Toolbar and Status Bar.
Window Menu Commands
New, Arrange, Cascade, Tile Horizontal, Tile Vertical, and Split.
Help Menu Commands
Index, Using Help, and About.
OLE Commands (Edit Menu)
Insert New Object, Edit Links, Paste Link, Paste Special, and typename Object (verb commands).
The framework provides varying levels of support for these commands. Some commands are supported only as
defined command IDs, while others are supported with thorough implementations. For example, the framework
implements the Open command on the File menu by creating a new document object, displaying an Open dialog
box, and opening and reading the file. In contrast, you must implement commands on the Edit menu yourself, since
commands like ID_EDIT_COPY depend on the nature of the data you are copying.
For more information about the commands supported and the level of implementation provided, see Technical
Note 22. The standard commands are defined in the file AFXRES.H.
See also
User-Interface Objects and Command IDs
Command Targets
3/4/2019 • 2 minutes to read • Edit Online
The figure Commands in the Framework shows the connection between a user-interface object, such as a menu
item, and the handler function that the framework calls to carry out the resulting command when the object is
clicked.
Windows sends messages that are not command messages directly to a window whose handler for the message is
then called. However, the framework routes commands to a number of candidate objects — called "command
targets" — one of which normally invokes a handler for the command. The handler functions work the same way
for both commands and standard Windows messages, but the mechanisms by which they are called are different,
as explained in How the Framework Calls a Handler.
See also
Messages and Commands in the Framework
How the Framework Calls a Handler
3/4/2019 • 2 minutes to read • Edit Online
The following topics first examine how the framework routes commands, then examine how other messages and
control notifications are sent to windows:
Message sending and receiving
How noncommand messages reach their handlers
Command routing
Command Routing Illustration
The OnCmdMsg Handler
Overriding the Standard Command Routing
See also
Message Handling and Mapping
Message Sending and Receiving
3/4/2019 • 2 minutes to read • Edit Online
Consider the sending part of the process and how the framework responds.
Most messages result from user interaction with the program. Commands are generated by mouse clicks in menu
items or toolbar buttons or by accelerator keystrokes. The user also generates Windows messages by, for example,
moving or resizing a window. Other Windows messages are sent when events such as program startup or
termination occur, as windows get or lose the focus, and so on. Control-notification messages are generated by
mouse clicks or other user interactions with a control, such as a button or list-box control in a dialog box.
The Run member function of class CWinApp retrieves messages and dispatches them to the appropriate window.
Most command messages are sent to the main frame window of the application. The WindowProc predefined by the
class library gets the messages and routes them differently, depending on the category of message received.
Now consider the receiving part of the process.
The initial receiver of a message must be a window object. Windows messages are usually handled directly by that
window object. Command messages, usually originating in the application's main frame window, get routed to the
command-target chain described in Command Routing.
Each object capable of receiving messages or commands has its own message map that pairs a message or
command with the name of its handler.
When a command-target object receives a message or command, it searches its message map for a match. If it
finds a handler for the message, it calls the handler. For more information about how message maps are searched,
see How the Framework Searches Message Maps. Refer again to the figure Commands in the Framework.
See also
How the Framework Calls a Handler
How Noncommand Messages Reach Their Handlers
3/4/2019 • 2 minutes to read • Edit Online
Unlike commands, standard Windows messages do not get routed through a chain of command targets but are
usually handled by the window to which Windows sends the message. The window might be a main frame
window, an MDI child window, a standard control, a dialog box, a view, or some other kind of child window.
At run time, each Windows window is attached to a window object (derived directly or indirectly from CWnd ) that
has its own associated message map and handler functions. The framework uses the message map — as for a
command — to map incoming messages to handlers.
See also
How the Framework Calls a Handler
Command Routing
9/11/2019 • 2 minutes to read • Edit Online
Your responsibility in working with commands is limited to making message-map connections between
commands and their handler functions, a task for which you use the MFC Class Wizard. You must also write the
code for the command handlers.
Windows messages are usually sent to the main frame window, but command messages are then routed to other
objects. The framework routes commands through a standard sequence of command-target objects, one of which
is expected to have a handler for the command. Each command-target object checks its message map to see if it
can handle the incoming message.
Different command-target classes check their own message maps at different times. Typically, a class routes the
command to certain other objects to give them first chance at the command. If none of those objects handles the
command, the original class checks its own message map. Then, if it can't supply a handler itself, it may route the
command to yet more command targets. The table Standard Command Route below shows how each of the
classes structures this sequence. The general order in which a command target routes a command is:
1. To its currently active child command-target object.
2. To itself.
3. To other command targets.
How expensive is this routing mechanism Compared to what your handler does in response to a command, the
cost of the routing is low. Bear in mind that the framework generates commands only when the user interacts
with a user-interface object.
Standard Command Route
IT GIVES IT SEL F A N D OT H ER C O M M A N D- TA RGET O B JEC T S A
W H EN A N O B JEC T O F T H IS T Y P E REC EIVES A C O M M A N D . . . C H A N C E TO H A N DL E T H E C O M M A N D IN T H IS O RDER:
Where numbered entries in the second column of the preceding table mention other objects, such as a document,
see the corresponding item in the first column. For instance, when you read in the second column that the view
forwards a command to its document, see the "Document" entry in the first column to follow the routing further.
See also
How the Framework Calls a Handler
Command Routing Illustration
3/4/2019 • 2 minutes to read • Edit Online
To illustrate, consider a command message from a Clear All menu item in an MDI application's Edit menu. Suppose
the handler function for this command happens to be a member function of the application's document class.
Here's how that command reaches its handler after the user chooses the menu item:
1. The main frame window receives the command message first.
2. The main MDI frame window gives the currently active MDI child window a chance to handle the command.
3. The standard routing of an MDI child frame window gives its view a chance at the command before
checking its own message map.
4. The view checks its own message map first and, finding no handler, next routes the command to its
associated document.
5. The document checks its message map and finds a handler. This document member function is called and
the routing stops.
If the document did not have a handler, it would next route the command to its document template. Then the
command would return to the view and then the frame window. Finally, the frame window would check its
message map. If that check failed as well, the command would be routed back to the main MDI frame window and
then to the application object — the ultimate destination of unhandled commands.
See also
How the Framework Calls a Handler
OnCmdMsg Handler
3/4/2019 • 2 minutes to read • Edit Online
To accomplish the routing of commands, each command target calls the OnCmdMsg member function of the next
command target in the sequence. Command targets use OnCmdMsg to determine whether they can handle a
command and to route it to another command target if they cannot handle it.
Each command-target class may override the OnCmdMsg member function. The overrides let each class route
commands to a particular next target. A frame window, for example, always routes commands to its current child
window or view, as shown in the table Standard Command Route.
The default CCmdTarget implementation of OnCmdMsg uses the message map of the command-target class to
search for a handler function for each command message it receives — in the same way that standard messages
are searched. If it finds a match, it calls the handler. Message-map searching is explained in How the Framework
Searches Message Maps.
See also
How the Framework Calls a Handler
Overriding the Standard Command Routing
3/4/2019 • 2 minutes to read • Edit Online
In rare cases when you must implement some variation of the standard framework routing, you can override it. The
idea is to change the routing in one or more classes by overriding OnCmdMsg in those classes. Do so:
In the class that breaks the order to pass to a nondefault object.
In the new nondefault object or in command targets it might in turn pass commands to.
If you insert some new object into the routing, its class must be a command-target class. In your overriding
versions of OnCmdMsg , be sure to call the version that you're overriding. See the OnCmdMsg member function of
class CCmdTarget in the MFC Reference and the versions in such classes as CView and CDocument in the supplied
source code for examples.
See also
How the Framework Calls a Handler
How the Framework Searches Message Maps
3/4/2019 • 2 minutes to read • Edit Online
The framework searches the message-map table for matches with incoming messages. Once you write a
message-map entry for each message you want a class to handle and write the corresponding handlers, the
framework calls your handlers automatically. The following topics explain message-map searching:
Where to find message maps
Derived message maps
Mapping ranges of messages, command IDs, or control IDs to one handler
See also
Message Handling and Mapping
Where to Find Message Maps
3/27/2020 • 2 minutes to read • Edit Online
When you create a new skeleton application with the Application Wizard, the Application Wizard writes a message
map for each command-target class it creates for you. This includes your derived application, document, view, and
frame-window classes. Some of these message maps already have the entries supplied by the Application Wizard
for certain messages and predefined commands, and some are just placeholders for handlers that you will add.
A class's message map is located in the .CPP file for the class. Working with the basic message maps that the
Application Wizard creates, you use the Class Wizard to add entries for the messages and commands that each
class will handle. A typical message map might look like the following after you add some entries:
BEGIN_MESSAGE_MAP(CMyView, CFormView)
ON_WM_MOUSEACTIVATE()
ON_COMMAND(ID_EDIT_CUT, &CMyView::OnEditCut)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, &CMyView::OnUpdateEditCut)
ON_BN_CLICKED(IDC_MYBUTTON, &CMyView::OnBnClickedMybutton)
ON_WM_CREATE()
END_MESSAGE_MAP()
The message map consists of a collection of macros. Two macros, BEGIN_MESSAGE_MAP and
END_MESSAGE_MAP, bracket the message map. Other macros, such as ON_COMMAND , fill in the message map's
contents.
NOTE
The message-map macros are not followed by semicolons.
When you use the Add Class wizard to create a new class, it provides a message map for the class. Alternatively,
you can create a message map manually using the source code editor.
See also
How the Framework Searches Message Maps
Derived Message Maps
3/4/2019 • 2 minutes to read • Edit Online
During message handling, checking a class's own message map is not the end of the message-map story. What
happens if class CMyView (derived from CView ) has no matching entry for a message
Keep in mind that CView , the base class of CMyView , is derived in turn from CWnd . Thus CMyView is a CView and is
a CWnd . Each of those classes has its own message map. The figure "A View Hierarchy" below shows the
hierarchical relationship of the classes, but keep in mind that a CMyView object is a single object that has the
characteristics of all three classes.
A View Hierarchy
So if a message can't be matched in class CMyView 's message map, the framework also searches the message map
of its immediate base class. The BEGIN_MESSAGE_MAP macro at the start of the message map specifies two class
names as its arguments:
BEGIN_MESSAGE_MAP(CMyView, CFormView)
The first argument names the class to which the message map belongs. The second argument provides a
connection with the immediate base class — CView here — so the framework can search its message map, too.
The message handlers provided in a base class are thus inherited by the derived class. This is very similar to
normal virtual member functions without needing to make all handler member functions virtual.
If no handler is found in any of the base-class message maps, default processing of the message is performed. If
the message is a command, the framework routes it to the next command target. If it is a standard Windows
message, the message is passed to the appropriate default window procedure.
To speed message-map matching, the framework caches recent matches on the likelihood that it will receive the
same message again. One consequence of this is that the framework processes unhandled messages quite
efficiently. Message maps are also more space-efficient than implementations that use virtual functions.
See also
How the Framework Searches Message Maps
Declaring Message Handler Functions
3/4/2019 • 2 minutes to read • Edit Online
Certain rules and conventions govern the names of your message-handler functions. These depend on the
message category, as described in the following topics:
Handlers for standard Windows messages
Handlers for commands and control notifications
Handlers for ranges of messages
Handling reflected messages
See also
Message Handling and Mapping
Handlers for Standard Windows Messages
3/27/2020 • 2 minutes to read • Edit Online
Default handlers for standard Windows messages (WM_ ) are predefined in class CWnd . The class library bases
names for these handlers on the message name. For example, the handler for the WM_PAINT message is declared
in CWnd as:
afx_msg void OnPaint();
The afx_msg keyword suggests the effect of the C++ vir tual keyword by distinguishing the handlers from other
CWnd member functions. Note, however, that these functions are not actually virtual; they are instead implemented
through message maps. Message maps depend solely on standard preprocessor macros, not on any extensions to
the C++ language. The afx_msg keyword resolves to white space after preprocessing.
To override a handler defined in a base class, simply define a function with the same prototype in your derived
class and to make a message-map entry for the handler. Your handler "overrides" any handler of the same name in
any of your class's base classes.
In some cases, your handler should call the overridden handler in the base class so the base class(es) and Windows
can operate on the message. Where you call the base-class handler in your override depends on the circumstances.
Sometimes you must call the base-class handler first and sometimes last. Sometimes you call the base-class
handler conditionally, if you choose not to handle the message yourself. Sometimes you should call the base-class
handler, then conditionally execute your own handler code, depending on the value or state returned by the base-
class handler.
Cau t i on
It is not safe to modify the arguments passed into a handler if you intend to pass them to a base-class handler. For
example, you might be tempted to modify the nChar argument of the OnChar handler (to convert to uppercase, for
example). This behavior is fairly obscure, but if you need to accomplish this effect, use the CWnd member function
SendMessage instead.
How do you determine the proper way to override a given message When the Class Wizard writes the skeleton of
the handler function for a given message — an OnCreate handler for WM_CREATE , for example — it sketches in
the form of the recommended overridden member function. The following example recommends that the handler
first call the base-class handler and proceed only on condition that it does not return -1.
return 0;
}
By convention, the names of these handlers begin with the prefix "On." Some of these handlers take no arguments,
while others take several. Some also have a return type other than void . The default handlers for all WM_
messages are documented in the MFC Reference as member functions of class CWnd whose names begin with
"On." The member function declarations in CWnd are prefixed with afx_msg .
See also
Declaring Message Handler Functions
Handlers for Commands and Control Notifications
9/11/2019 • 2 minutes to read • Edit Online
There are no default handlers for commands or control-notification messages. Therefore, you are bound only by
convention in naming your handlers for these categories of messages. When you map the command or control
notification to a handler, the Class Wizard proposes a name based on the command ID or control-notification code.
You can accept the proposed name, change it, or replace it.
Convention suggests that you name handlers in both categories for the user-interface object they represent. Thus a
handler for the Cut command on the Edit menu might be named
Because the Cut command is so commonly implemented in applications, the framework predefines the command
ID for the Cut command as ID_EDIT_CUT . For a list of all predefined command IDs, see the file AFXRES.H. For
more information, see Standard Commands.
In addition, convention suggests a handler for the BN_CLICKED notification message from a button labeled "My
Button" might be named
See also
Declaring Message Handler Functions
Handlers for Message-Map Ranges
3/27/2020 • 3 minutes to read • Edit Online
This article explains how to map a range of messages to a single message handler function (instead of mapping
one message to only one function).
There are times when you need to process more than one message or control notification in exactly the same way.
At such times, you might wish to map all of the messages to a single handler function. Message-map ranges allow
you to do this for a contiguous range of messages:
You can map ranges of command IDs to:
A command handler function.
A command update handler function.
You can map control-notification messages for a range of control IDs to a message handler function.
Topics covered in this article include:
Writing the message-map entry
Declaring the handler function
Example for a range of command IDs
Example for a range of control IDs
public:
afx_msg void OnDoSomething(UINT nID);
Handler functions for single commands normally take no parameters. With the exception of update handler
functions, handler functions for message-map ranges require an extra parameter, nID, of type UINT . This
parameter is the first parameter. The extra parameter accommodates the extra command ID needed to specify
which command the user actually chose.
For more information about parameter requirements for updating handler functions, see Example for a Range of
Command IDs.
public:
afx_msg void OnZoom(UINT nID);
The case of update handler functions is similar, and likely to be more widely useful. It's quite common to write
ON_UPDATE_COMMAND_UI handlers for a number of commands and find yourself writing, or copying, the same code
over and over. The solution is to map a range of command IDs to one update handler function using the
ON_UPDATE_COMMAND_UI_RANGE macro. The command IDs must form a contiguous range. For an example, see the
OnUpdateZoom handler and its ON_UPDATE_COMMAND_UI_RANGE message-map entry in the HIERSVR sample's view
class.
Update handler functions for single commands normally take a single parameter, pCmdUI, of type CCmdUI* . Unlike
handler functions, update handler functions for message-map ranges do not require an extra parameter, nID, of
type UINT . The command ID, which is needed to specify which command the user actually chose, is found in the
CCmdUI object.
When you write the ON_CONTROL_RANGE macro in your message map, you specify:
A particular control-notification message.
Here it's BN_CLICKED .
The control ID values associated with the contiguous range of controls.
Here these are IDC_BUTTON1 and IDC_BUTTON10 .
The name of the message handler function.
Here it's OnButtonClicked .
When you write the handler function, specify the extra UINT parameter, as shown in the following:
The OnButtonClicked handler for a single BN_CLICKED message takes no parameters. The same handler for a
range of buttons takes one UINT . The extra parameter allows for identifying the particular control responsible for
generating the BN_CLICKED message.
The code shown in the example is typical: converting the value passed to an int within the message range and
asserting that this is the case. Then you might take some different action depending on which button was clicked.
See also
Declaring Message Handler Functions
Handling Reflected Messages
3/4/2019 • 2 minutes to read • Edit Online
Message reflection lets you handle messages for a control, such as WM_CTLCOLOR , WM_COMMAND , and
WM_NOTIFY , within the control itself. This makes the control more self-contained and portable. The mechanism
works with Windows common controls as well as with ActiveX controls (formerly called OLE controls).
Message reflection lets you reuse your CWnd -derived classes more readily. Message reflection works via
CWnd::OnChildNotify, using special ON_XXX_REFLECT message map entries: for example,
ON_CTLCOLOR_REFLECT and ON_CONTROL_REFLECT . Technical Note 62 explains message reflection in
more detail.
See also
Declaring Message Handler Functions
How to: Display Command Information in the Status
Bar
3/4/2019 • 2 minutes to read • Edit Online
When you run the Application Wizard to create the skeleton of your application, you can support a toolbar and a
status bar. Just one option in the Application Wizard supports both. When a status bar is present, the application
automatically provides helpful feedback as the user moves the pointer over items on the menus. The application
automatically displays a prompt string in the status bar when the menu item is highlighted. For example, when the
user moves the pointer over the Cut command on the Edit menu, the status bar might display "Cuts the selection
and puts it on the Clipboard" in the message area of the status bar. The prompt helps the user understand the
purpose of the menu item. This also works when the user clicks a toolbar button.
You can add to this status-bar help by defining prompt strings for menu items that you add to the program. To do
this, provide the prompt strings when you edit the properties of the menu item in the menu editor. The strings you
define are stored in the application resource file; they have the same IDs as the commands they explain.
By default, the Application Wizard adds AFX_IDS_IDLEMESSAGE , the ID for a standard "Ready" message, which is
displayed when the program is waiting for new messages. If you specify the Context-Sensitive Help option in the
Application Wizard, the message is changed to "For Help, press F1."
See also
Message Handling and Mapping
How to: Create a Message Map for a Template Class
3/4/2019 • 3 minutes to read • Edit Online
Message mapping in MFC provides an efficient way to direct Windows messages to an appropriate C++ object
instance. Examples of MFC message map targets include application classes, document and view classes, control
classes, and so on.
Traditional MFC message maps are declared using the BEGIN_MESSAGE_MAP macro to declare the start of the
message map, a macro entry for each message-handler class method, and finally the END_MESSAGE_MAP macro
to declare the end of the message map.
One limitation with the BEGIN_MESSAGE_MAP macro occurs when it is used in conjunction with a class containing
template arguments. When used with a template class, this macro will cause a compile-time error due to the
missing template parameters during macro expansion. The BEGIN_TEMPLATE_MESSAGE_MAP macro was
designed to allow classes containing a single template argument to declare their own message maps.
Example
Consider an example where the MFC CListBox class is extended to provide synchronization with an external data
source. The fictitious CSyncListBox class is declared as follows:
The CSyncListBox class is templated on a single type that describes the data source it will synchronize with. It also
declares three methods that will participate in the message map of the class: OnPaint , OnDestroy , and
OnSynchronize . The OnSynchronize method is implemented as follows:
template <class CollectionT>
LRESULT CSyncListBox<CollectionT>::OnSynchronize(WPARAM, LPARAM lParam)
{
CollectionT* pCollection = (CollectionT*)(lParam);
ResetContent();
if (pCollection != NULL)
{
INT nCount = (INT)pCollection->GetCount();
for (INT n = 0; n < nCount; n++)
{
CString s = StringizeElement(pCollection, n);
AddString(s);
}
}
return 0L;
}
The above implementation allows the CSyncListBox class to be specialized on any class type that implements the
GetCount method, such as CArray , CList , and CMap . The StringizeElement function is a template function
prototyped by the following:
Normally, the message map for this class would be defined as:
BEGIN_MESSAGE_MAP(CSyncListBox, CListBox)
ON_WM_PAINT()
ON_WM_DESTROY()
ON_MESSAGE(LBN_SYNCHRONIZE, OnSynchronize)
END_MESSAGE_MAP()
where LBN_SYNCHRONIZE is a custom user message defined by the application, such as:
The above macro map will not compile, due to the fact that the template specification for the CSyncListBox class
will be missing during macro expansion. The BEGIN_TEMPL ATE_MESSAGE_MAP macro solves this by
incorporating the specified template parameter into the expanded macro map. The message map for this class
becomes:
The following demonstrates sample usage of the CSyncListBox class using a CStringList object:
void CSyncListBox_Test(CWnd* pParentWnd)
{
CSyncListBox<CStringList> ctlStringLB;
ctlStringLB.Create(WS_CHILD | WS_VISIBLE | LBS_STANDARD | WS_HSCROLL,
CRect(10, 10, 200, 200), pParentWnd, IDC_MYSYNCLISTBOX);
// Verify the contents of the list box by printing out its contents
INT nCount = ctlStringLB.GetCount();
for (INT n = 0; n < nCount; n++)
{
TCHAR szText[256];
ctlStringLB.GetText(n, szText);
TRACE(_T("%s\n"), szText);
}
}
To complete the test, the StringizeElement function must be specialized to work with the CStringList class:
template<>
CString StringizeElement(CStringList* pStringList, INT iIndex)
{
if (pStringList != NULL && iIndex < pStringList->GetCount())
{
POSITION pos = pStringList->GetHeadPosition();
for (INT i = 0; i < iIndex; i++)
{
pStringList->GetNext(pos);
}
return pStringList->GetAt(pos);
}
return CString(); // or throw, depending on application requirements
}
See also
BEGIN_TEMPLATE_MESSAGE_MAP
Message Handling and Mapping
MFC COM
3/27/2020 • 2 minutes to read • Edit Online
A subset of MFC is designed to support COM, while most of the Active Template Library (ATL) is designed for COM
programming. This section of topics describes MFC's support for COM.
Active technologies (such as ActiveX controls, Active document containment, OLE, and so on) use the Component
Object Model (COM) to enable software components to interact with one another in a networked environment,
regardless of the language with which they were created. Active technologies can be used to create applications
that run on the desktop or the Internet. For more information see Introduction to COM or The Component Object
Model.
Active technologies include both client and server technologies, including the following:
ActiveX controls are interactive objects that can be used in containers such as a Web site. For more
information on ActiveX controls, see:
MFC ActiveX Controls
ActiveX Controls on the Internet
Overview: Internet
Upgrade an Existing ActiveX Control to be Used on the Internet
Debugging an ActiveX Control
Active scripting controls the integrated behavior of one or more ActiveX controls from a browser or server.
For more information on active scripting, see Active Technology on the Internet.
Automation (formerly known as OLE Automation) makes it possible for one application to manipulate
objects implemented in another application, or to "expose" objects so they can be manipulated.
The automated object might be local or remote (on another machine accessible across a network).
Automation is available for both OLE and COM objects.
This section also provides information on how to write COM components using MFC, for example, in
Connection Points.
For a discussion of what is still called OLE versus what is now called active technology, see the topics on OLE.
In This Section
Active Document Containment
Automation
Connection Points
MFC ActiveX Controls
See also
Concepts
Active Document Containment
4/1/2019 • 2 minutes to read • Edit Online
Active document containment is a technology that provides a single frame in which to work with documents,
instead of forcing you to create and use multiple application frames for each document type. It differs from basic
OLE technology in that OLE works with embedded objects within a compound document in which only a single
piece of content can be active. With active document containment, you activate an entire document (that is, an
entire application, including associated menus, toolbars, and so on) within the context of a single frame.
The active document containment technology was originally developed for Microsoft Office to implement Office
Binder. However, the technology is flexible enough to support active document containers other than Office Binder
and can support document servers other than Office and Office-compatible applications.
The application that hosts active documents is called an active document container. Examples of such containers
are the Microsoft Office Binder or Microsoft Internet Explorer.
Active document containment is implemented as a set of extensions to OLE documents, the compound document
technology of OLE. The extensions are additional interfaces that allow an embeddable, in-place object to represent
an entire document instead of a single piece of embedded content. As with OLE documents, active document
containment uses a container that provides the display space for active documents, and servers that provide the
user interface and manipulation capabilities for the active documents themselves.
An active document server is an application (such as Word, Excel, or PowerPoint) that supports one or more active
document classes, where each object itself supports the extension interfaces that allow the object to be activated
in a suitable container.
An active document (provided from an active document server such as Word or Excel) is essentially a full-scale,
conventional document that is embedded as an object within another active document container. Unlike
embedded objects, active documents have complete control over their pages, and the full interface of the
application (with all its underlying commands and tools) is available to the user to edit them.
An active document is best understood by distinguishing it from a standard OLE embedded object. Following the
OLE convention, an embedded object is one that is displayed within the page of the document that owns it, and
the document is managed by an OLE container. The container stores the embedded object's data with the rest of
the document. However, embedded objects are limited in that they do not control the page on which they appear.
Users of an active document container application can create active documents (called sections in Office Binder)
using their favorite applications (provided these applications are active document enabled), yet the users can
manage the resulting project as a single entity, which can be uniquely named, saved, printed, and so on. In the
same way, a user of an Internet browser can treat the entire network, as well as local file systems, as a single
document storage entity with the ability to browse the documents in that storage from a single location.
Sample Programs
The MFCBIND sample illustrates the implementation of an active document container application.
See also
MFC COM
Example of Active Document Containment: Office
Binder
3/4/2019 • 2 minutes to read • Edit Online
The Microsoft Office Binder is an example of an active document container. An Office Binder includes two primary
panes, as containers typically do. The left pane contains icons that correspond to active documents in the Binder.
Each document is called a section within the Binder. For example, a Binder can contain Word documents,
PowerPoint files, Excel spreadsheets, and so on.
Clicking an icon in the left pane activates the corresponding active document. The right pane of the Binder then
displays the contents of the currently selected active document.
If you open and activate a Word document in a Binder, the Word menu bar and toolbars appear at the top of the
view frame, and you can edit the document's contents using any Word command or tool. However, the menu bar is
a combination of both the Binder's and Word's menu bars. Because both Binder and Word have Help menus, the
contents of the respective menus are merged. Active document containers such as Office Binder automatically
provide Help menu merging; for more information, see Help Menu Merging.
When you select an active document of another application type, the Binder's interface changes to accommodate
that of the active document's application type. For example, if a Binder contains an Excel spreadsheet, you will
observe that the menus in the Binder change when you select the Excel spreadsheet section.
There are, of course, other possible types of containers beside Binders. File Explorer uses the typical dual-pane
interface in which the left pane uses a tree control to display a hierarchical list of directories in a drive or network,
while the right pane displays the files contained in the currently selected directory. An Internet browser-type of
container (such as Microsoft Internet Explorer), rather than using a dual-pane interface, usually has a single frame
and provides navigation using hyperlinks.
See also
Active Document Containment
Creating an Active Document Container Application
3/4/2019 • 2 minutes to read • Edit Online
The simplest and most recommended way to create an active document container application is to create an MFC
EXE container application using the MFC Application Wizard, then modify the application to support active
document containment.
To create an active document container application
1. From the File menu, click Project from the New submenu.
2. From the left pane, click Visual C++ project type.
3. Select MFC Application from the right pane.
4. Name the project MyProj, click OK .
5. Select the Compound Document Suppor t page.
6. Select the Container or Container/Full-ser ver option.
7. Select the Active document container check box.
8. Click Finish .
9. When the MFC Application Wizard finishes generating the application, open the following files using
Solution Explorer:
MyProjview.cpp
10. In MyProjview.cpp, make the following changes:
In CMyProjView::OnPreparePrinting , replace the function contents with the following code:
if (!CView::OnPreparePrinting(pInfo))
return FALSE;
if (!COleDocObjectItem::OnPreparePrinting(this, pInfo))
return FALSE;
return TRUE;
OnPreparePrinting provides printing support. This code replaces DoPreparePrinting , which is the default
print preparation.
Active document containment provides an improved printing scheme:
You can first call the active document through its IPrint interface and tell it to print itself. This is
different from previous OLE containment, in which the container had to render an image of the
contained item onto the printer CDC object.
If that fails, tell the contained item to print itself through its IOleCommandTarget interface
If that fails, make your own rendering of the item.
The static member functions COleDocObjectItem::OnPrint and COleDocObjectItem::OnPreparePrinting , as
implemented in the previous code, handle this improved printing scheme.
11. Add any implementation of your own and build the application.
See also
Active Document Containment
Active Document Containers
3/27/2020 • 4 minutes to read • Edit Online
An active document container, such as Microsoft Office Binder or Internet Explorer, allows you to work with several
documents of different application types within a single frame (instead of forcing you to create and use multiple
application frames for each document type).
MFC provides full support for active document containers in the COleDocObjectItem class. You can use the MFC
Application Wizard to create an active document container by selecting the Active document container check
box on the Compound Document Suppor t page of the MFC Application Wizard. For more information, see
Creating an Active Document Container Application.
For more information about active document containers, see:
Container Requirements
Document Site Objects
View Site Objects
Frame Object
Help Menu Merging
Programmatic Printing
Command Targets
Container Requirements
Active document support in an active document container implies more than just interface implementations: it also
requires knowledge of using the interfaces of a contained object. The same applies to active document extensions,
where the container must also know how to use those extension interfaces on the active documents themselves.
An active document container that integrates active documents must:
Be capable of handling object storage through the IPersistStorage interface, that is, it must provide an
IStorage instance to each active document.
Support the basic embedding features of OLE documents, necessitating "site" objects (one per document or
embedding) that implement IOleClientSite and IAdviseSink .
Support in-place activation of embedded objects or active documents. The container's site objects must
implement IOleInPlaceSite and the container's frame object must provide IOleInPlaceFrame .
Support the active documents' extensions by implementing IOleDocumentSite to provide the mechanism
for the container to talk to the document. Optionally, the container can implement the active document
interfaces IOleCommandTarget and IContinueCallback to pick up simple commands such as printing or
saving.
The frame object, the view objects, and the container object can optionally implement IOleCommandTarget to
support the dispatch of certain commands, as discussed in Command Targets. View and container objects can also
optionally implement IPrint and IContinueCallback , to support programmatic printing, as discussed in
Programmatic Printing.
The following figure shows the conceptual relationships between a container and its components (at left), and the
active document and its views (at right). The active document manages storage and data, and the view displays or
optionally prints that data. Interfaces in bold are those required for active document participation; those bold and
italic are optional. All other interfaces are required.
A document that supports only a single view can implement both the view and document components (that is,
their corresponding interfaces) on a single concrete class. In addition, a container site that only supports one view
at a time can combine the document site and the view site into a single concrete site class. The container's frame
object, however, must remain distinct, and the container's document component is merely included here to give a
complete picture of the architecture; it is not affected by the active document containment architecture.
The document site is conceptually the container for one or more "view site" objects. Each view site object is
associated with individual view objects of the document managed by the document site. If the container only
supports a single view per document site, then it can implement the document site and the view site with a single
concrete class.
Frame Object
The container's frame object is, for the most part, the same frame that is used for in-place activation in OLE
Documents, that is, the one that handles menu and toolbar negotiation. A view object has access to this frame
object through IOleInPlaceSite::GetWindowContext , which also provides access to the container object representing
the container document (which can handle pane-level toolbar negotiation and contained object enumeration).
An active document container can augment the frame by adding IOleCommandTarget . This allows it to receive
commands that originate in the active document's user interface in the same way that this interface can allow a
container to send the same commands (such as File New , Open , Save As , Print ; Edit Copy , Paste , Undo , and
others) to an active document. For more information, see Command Targets.
See also
Active Document Containment
Help Menu Merging
3/4/2019 • 4 minutes to read • Edit Online
When an object is active within a container, the menu merging protocol of OLE Documents gives the object
complete control of the Help menu. As a result, the container's Help topics are not available unless the user
deactivates the object. The active document containment architecture expands on the rules for in-place menu
merging to allow both the container and an active document that is active to share the menu. The new rules are
simply additional conventions about what component owns what part of the menu and how the shared menu is
constructed.
The new convention is simple. In active documents, the Help menu has two top-level menu items organized as
follows:
Help
For example, when a Word section is active in the Office Binder, then the Help menu would appear as follows:
Help
Both menu items are cascading menus under which any additional menu items specific to the container and the
object are provided to the user. What items appear here will vary with the container and objects involved.
To construct this merged Help menu, the active document containment architecture modifies the normal OLE
Documents procedure. According to OLE Documents, the merged menu bar can have six groups of menus, namely
File , Edit , Container , Object , Window , Help , in that order. In each group, there can be zero or more menus. The
groups File , Container , and Window belong to the container and the groups Edit , Object, and Help belong to
the object. When the object wants to do menu merging, it creates a blank menu bar and passes it to the container.
The container then inserts its menus, by calling IOleInPlaceFrame::InsertMenus . The object also passes a structure
that is an array of six LONG values (OLEMENUGROUPWIDTHS ). After inserting the menus, the container marks
how many menus it added in each one of its groups, and then returns. Then the object inserts its menus, paying
attention to the count of menus in each container group. Finally, the object passes the merged menu bar and the
array (which contains the count of menus in each group) to OLE, which returns an opaque "menu descriptor"
handle. Later the object passes that handle and the merged menu bar to the container, via
IOleInPlaceFrame::SetMenu . At this time, the container displays the merged menu bar and also passes the handle to
OLE, so that OLE can do proper dispatching of menu messages.
In the modified active document procedure, the object must first initialize the OLEMENUGROUPWIDTHS
elements to zero before passing it to the container. Then the container performs a normal menu insertion with one
exception: The container inserts a Help menu as the last item and stores a value of 1 in the last (sixth) entry of the
OLEMENUGROUPWIDTHS array (that is, width[5], which belongs to the object's Help group). This Help menu
will have only one item which is a submenu, the "Container Help >" cascade menu as previously described.
The object then executes its normal menu insertion code, except that before inserting its Help menu, it checks the
sixth entry of the OLEMENUGROUPWIDTHS array. If the value is 1 and the name of the last menu is Help (or the
appropriate localized string), then the object inserts its Help menu as submenu of the container's Help menu.
The object then sets the sixth element of OLEMENUGROUPWIDTHS to zero and increments the fifth element by
one. This lets OLE know that the Help menu belongs to the container and the menu messages corresponding to
that menu (and its submenus) should be routed to the container. It is then the container's responsibility to forward
WM_INITMENUPOPUP , WM_SELECT , WM_COMMAND , and other menu-related messages that belong to the
object's portion of the Help menu. This is accomplished by using WM_INITMENU to clear a flag that tells the
container whether the user has navigated into the object's Help menu. The container then watches
WM_MENUSELECT for entry into or exit from any item on the Help menu that the container did not add itself.
On entry, it means the user has navigated into an object menu, so the container sets the "in object Help menu" flag
and uses the state of that flag to forward any WM_MENUSELECT , WM_INITMENUPOPUP , and
WM_COMMAND messages, as a minimum, to the object window. (On exit, the container clears the flag and then
processes these same messages itself.) The container should use the window returned from the object's
IOleInPlaceActiveObejct::GetWindow function as the destination for these messages.
If the object detects a zero in the sixth element of OLEMENUGROUPWIDTHS , it proceeds according to the
normal OLE Documents rules. This procedure covers containers that do participate in Help menu merging as well
as those that do not.
When the object calls IOleInPlaceFrame::SetMenu , before displaying the merged menu bar, the container checks
whether the Help menu has an additional submenu, in addition to what the container has inserted. If so, the
container leaves its Help menu in the merged menu bar. If the Help menu does not have an additional submenu,
the container will remove its Help menu from the merged menu bar. This procedure covers objects that participate
in Help menu merging as well as those that do not.
Finally, when it is time to disassemble the menu, the object removes the inserted Help menu in addition to
removing the other inserted menus. When the container removes its menus, it will remove its Help menu in
addition to the other menus that it has inserted.
See also
Active Document Containers
Programmatic Printing
3/4/2019 • 2 minutes to read • Edit Online
OLE provided the means to uniquely identify persistent documents ( GetClassFile ) and load them into their
associated code ( CoCreateInstance , QueryInterface(IID_IPersistFile) , QueryInterface(IID_IPersistStorage) ,
IPersistFile::Load , and IPersistStorage::Load ). To further enable printing documents, active document
containment (using an existing OLE design not shipped with OLE 2.0 originally) introduces a base-standard
printing interface, IPrint , generally available through any object that can load the persistent state of the
document type. Each view of an active document can optionally support the IPrint interface to provide these
capabilities.
The IPrint interface is defined as follows:
Clients and containers simply use IPrint::Print to instruct the document to print itself once that document is
loaded, specifying printing control flags, the target device, the pages to print, and additional options. The client can
also control the continuation of printing through the interface IContinueCallback (see below).
In addition, IPrint::SetInitialPageNum supports the ability to print a series of documents as one by numbering
pages seamlessly, obviously a benefit for active document containers like Office Binder. IPrint::GetPageInfo
makes displaying pagination information simple by allowing the caller to retrieve the starting page number
previously passed to SetInitialPageNum (or the document's internal default starting page number) and the
number of pages in the document.
Objects that support IPrint are marked in the registry with the "Printable" key stored under the object's CLSID:
HKEY_CLASSES_ROOT\CLSID\{...}\Printable
IPrint is usually implemented on the same object that supports either IPersistFile or IPersistStorage . Callers
note the capability to programmatically print the persistent state of some class by looking in the registry for the
"Printable" key. Currently, "Printable" indicates support for at least IPrint ; other interfaces may be defined in the
future which would then be available through QueryInterface where IPrint simply represents the base level of
support.
During a print procedure, you may want the client or container that initiated the printing to control whether or not
the printing should continue. For example, the container may support a "Stop Print" command that should
terminate the print job as soon as possible. To support this capability, the client of a printable object can implement
a small notification sink object with the interface IContinueCallback :
interface IContinueCallback : IUnknown
{
HRESULT FContinue(void);
HRESULT FContinuePrinting(
[in] LONG cPagesPrinted,
[in] LONG nCurrentPage,
[in] LPOLESTR pszPrintStatus);
};
This interface is designed to be useful as a generic continuation callback function that takes the place of the various
continuation procedures in the Win32 API (such as the AbortProc for printing and the EnumMetafileProc for
metafile enumeration). Thus this interface design is useful in a wide variety of time-consuming processes.
In the most generic cases, the IContinueCallback::FContinue function is called periodically by any lengthy process.
The sink object returns S_OK to continue the operation, and S_FALSE to stop the procedure as soon as possible.
FContinue , however, is not used in the context of IPrint::Print ; rather, printing uses
IContinueCallback::FContinuePrint . Any printing object should periodically call FContinuePrinting passing the
number of pages that have been printing, the number of the page being printed, and an additional string
describing the print status that the client may choose to display to the user (such as "Page 5 of 19").
See also
Active Document Containers
Message Handling and Command Targets
3/4/2019 • 2 minutes to read • Edit Online
The command dispatch interface IOleCommandTarget defines a simple and extensible mechanism to query and
execute commands. This mechanism is simpler than Automation's IDispatch because it relies entirely on a
standard set of commands; commands rarely have arguments, and no type information is involved (type safety is
diminished for command arguments as well).
In the command dispatch interface design, each command belongs to a "command group" which is itself identified
with a GUID . Therefore, anyone can define a new group and define all the commands within that group without
any need to coordinate with Microsoft or any other vendor. (This is essentially the same means of definition as a
dispinterface plus dispIDs in Automation. There is overlap here, although this command routing mechanism is
only for command routing and not for scripting/programmability on a large scale as Automation handles.)
IOleCommandTarget handles the following scenarios:
When an object is in-place activated, only the object's toolbars are typically displayed and the object's
toolbars may have buttons for some of the container commands like Print , Print Preview , Save , New ,
Zoom , and others. (In-place activation standards recommend that objects remove such buttons from their
toolbars, or at least disable them. This design allows those commands to be enabled and yet routed to the
right handler.) Currently, there is no mechanism for the object to dispatch these commands to the container.
When an active document is embedded in an active document container (such as Office Binder), the
container may need to send commands such Print , Page Setup , Proper ties , and others to the contained
active document.
This simple command routing could be handled through existing Automation standards and IDispatch . However,
the overhead involved with IDispatch is more than is necessary here, so IOleCommandTarget provides a simpler
means to achieve the same ends:
The QueryStatus method here tests whether a particular set of commands, the set being identified with a GUID , is
supported. This call fills an array of OLECMD values (structures) with the supported list of commands as well as
returning text describing the name of a command and/or status information. When the caller wishes to invoke a
command, it can pass the command (and the set GUID ) to Exec along with options and arguments, getting back
a return value.
See also
Active Document Containers
Active Document Servers
3/4/2019 • 2 minutes to read • Edit Online
Active document servers such as Word, Excel, or PowerPoint host documents of other application types called
active documents. Unlike OLE embedded objects (which are simply displayed within the page of another
document), Active documents provide the full interface and complete native functionality of the server application
that creates them. Users can create documents using the full power of their favorite applications (if they are active
document enabled), yet can treat the resulting project as a single entity.
Active documents can have more than one page and are always in-place active. Active documents control part of
the user interface, merging their menus with the File and Help menus of the container. They occupy the entire
editing area of the container and control the views and the layout of the printer page (margins, footers, and so on).
MFC implements active document servers with document/view interfaces, command dispatch maps, printing,
menu management, and registry management. Specific programming requirements are discussed in active
documents.
MFC supports active documents with the CDocObjectServer class, derived from CCmdTarget, and
CDocObjectServerItem, derived from COleServerItem. MFC supports active document containers with the
COleDocObjectItem class, derived from COleClientItem.
CDocObjectServer maps the active document interfaces and initializes and activates an active document. MFC also
provides macros to handle command routing in ACTIVE documents. To use active documents in your application,
include AfxDocOb.h in your StdAfx.h file.
A regular MFC server hooks up its own COleServerItem -derived class. The MFC Application Wizard generates this
class for you if you select the Mini-ser ver or Full-ser ver check box to give your application server compound
document support. If you also select the Active document ser ver check box, the MFC Application Wizard
generates a class derived from CDocObjectServerItem instead.
The COleDocObjectItem class allows an OLE container to become an active document container. You can use the
MFC Application Wizard to create an active document container by selecting the Active document container
checkbox in the Compound Document Support page of the MFC Application Wizard. For more information, see
Creating an Active Document Container Application.
See also
Active Document Containment
Active Documents
3/27/2020 • 4 minutes to read • Edit Online
Active documents extend the compound document technology of OLE. These extensions are provided in the form
of additional interfaces that manage views, so that objects can function within containers and yet retain control
over their display and printing functions. This process makes it possible to display documents both in foreign
frames (such as the Microsoft Office Binder or Microsoft Internet Explorer) and in native frames (such as the
product's own view ports).
This section describes the functional requirements for active documents. The active document owns a set of data
and has access to storage where the data can be saved and retrieved. It can create and manage one or more views
on its data. In addition to supporting the usual embedding and in-place activation interfaces of OLE documents,
the active document communicates its ability to create views through IOleDocument . Through this interface, the
container can ask to create (and possibly enumerate) the views that the active document can display. Through this
interface, the active document can also provide miscellaneous information about itself, such as whether it supports
multiple views or complex rectangles.
The following is the IOleDocument interface. Note that the IEnumOleDocumentViews interface is a standard OLE
enumerator for IOleDocumentView* types.
HRESULT EnumViews(
[out] IEnumOleDocumentViews **ppEnum,
[out] IOleDocumentView **ppView);
}
Every active document must have a view frame provider with this interface. If the document is not embedded
within a container, the active document server itself must provide the view frame. However, when the active
document is embedded in an active document container, the container provides the view frame.
An active document can create one or more types of views of its data (for example, normal, outline, page layout,
and so on). Views act like filters through which the data can be seen. Even if the document has only one type of
view, you may still want to support multiple views as a means of supporting new window functionality (for
example, the New Window item on the Window menu in Office applications).
To be represented within an active document container, a view component must support IOleInPlaceObject and
IOleInPlaceActiveObject in addition to IOleDocumentView :
Every view has an associated view site, which encapsulates the view frame and the view port (HWND and a
rectangular area in that window). The site exposes this functionality though the standard IOleInPlaceSite
interface. Note that it is possible to have more than one view port on a single HWND.
Typically, each type of view has a different printed representation. Hence views and the corresponding view sites
should implement the printing interfaces if IPrint and IContinueCallback , respectively. The view frame must
negotiate with the view provider through IPrint when printing begins, so that headers, footers, margins, and
related elements are printed correctly. The view provider notifies the frame of printing-related events through
IContinueCallback . For more information on the use of these interfaces, see Programmatic Printing.
Note that if an active document only supports a single view, then the active document and that single view can be
implemented using a single concrete class. IOleDocument::CreateView simply returns the same object's
IOleDocumentView interface pointer. In short, it is not necessary that there be two separate object instances when
only one view is required.
A view object can also be a command target. By implementing IOleCommandTarget a view can receive commands
that originate in the container's user interface (such as New , Open , Save As , Print on the File menu; and Copy ,
Paste , Undo on the Edit menu). For more information, see Message Handling and Command Targets.
See also
Active Document Containment
Automation
3/27/2020 • 2 minutes to read • Edit Online
Automation (formerly known as OLE Automation) makes it possible for one application to manipulate objects
implemented in another application, or to expose objects so they can be manipulated.
An Automation server is an application (a type of COM server) that exposes its functionality through COM
interfaces to other applications, called Automation clients. The exposure enables Automation clients to automate
certain functions by directly accessing objects and using the services they provide.
Automation servers and clients use COM interfaces that are always derived from IDispatch and take and return a
specific set of data types called Automation types. You can automate any object that exposes an Automation
interface, providing methods and properties that you can access from other applications. Automation is available
for both OLE and COM objects. The automated object might be local or remote (on another machine accessible
across a network); therefore there are two categories of automation:
Automation (local).
Remote Automation (over a network, using Distributed COM, or DCOM).
Exposing objects is beneficial when applications provide functionality useful to other applications. For example, an
ActiveX control is a type of Automation server; the application hosting the ActiveX control is the automation client
of that control.
As another example, a word processor might expose its spell-checking functionality to other programs. Exposure
of objects enables vendors to improve their applications by using the ready-made functionality of other
applications. In this way, Automation applies some of the principles of object-oriented programming, such as
reusability and encapsulation, at the level of applications themselves.
More important is the support Automation provides to users and solution providers. By exposing application
functionality through a common, well-defined interface, Automation makes it possible to build comprehensive
solutions in a single general programming language, such as Microsoft Visual Basic, instead of in diverse
application-specific macro languages.
Many commercial applications, such as Microsoft Excel and Microsoft Visual C++, allow you to automate much of
their functionality. For example, in Visual C++, you can write VBScript macros to automate builds, aspects of code
editing, or debugging tasks.
Automation Samples
AUTOCLIK Use this sample to learn Automation techniques and as a foundation for learning Remote
Automation.
ACDUAL Adds dual interfaces to an Automation server application.
CALCDRIV Automation client application driving MFCCALC.
INPROC Demonstrates an In-Process Automation server application.
IPDRIVE Automation client application driving INPROC.
MFCCALC Demonstrates an Automation client application.
See also
MFC COM
Automation Clients
3/4/2019 • 2 minutes to read • Edit Online
Automation makes it possible for your application to manipulate objects implemented in another application, or
to expose objects so they can be manipulated. An Automation client is an application that can manipulate exposed
objects belonging to another application. The application that exposes the objects is called the Automation server.
The client manipulates the server application's objects by accessing those objects' properties and functions.
Types of Automation Clients
There are two types of Automation clients:
Clients that dynamically (at run time) acquire information about the properties and operations of the
server.
Clients that possess static information (provided at compile time) that specifies the properties and
operations of the server.
Clients of the first kind acquire information about the server's methods and properties by querying the OLE
system's IDispatch mechanism. Although it is adequate to use for dynamic clients, IDispatch is difficult to use
for static clients, where the objects being driven must be known at compile time. For static bound clients, the
Microsoft Foundation classes provide the COleDispatchDriver class.
Static bound clients use a proxy class that is statically linked with the client application. This class provides a type-
safe C++ encapsulation of the server application's properties and operations.
The class COleDispatchDriver provides the principal support for the client side of Automation. Using the Add
New Item dialog box, you create a class derived from COleDispatchDriver .
You then specify the type-library file describing the properties and functions of the server application's object. The
Add Item dialog box reads this file and creates the COleDispatchDriver -derived class, with member functions that
your application can call to access the server application's objects in C++ in a type-safe manner. Additional
functionality inherited from COleDispatchDriver simplifies the process of calling the proper Automation server.
Handling Events in Automation Clients
If you want to handle events in your automation client, you need to add a sink interface. MFC provides wizard
support to add sink interfaces for ActiveX controls, but not support for other COM servers.
See also
Automation Clients: Using Type Libraries
Automation
MFC Application Wizard
Automation Clients: Using Type Libraries
8/15/2019 • 2 minutes to read • Edit Online
Automation clients must have information about server objects' properties and methods if the clients are to
manipulate the servers' objects. Properties have data types; methods often return values and accept parameters.
The client requires information about the data types of all of these in order to statically bind to the server object
type.
This type information can be made known in several ways. The recommended way is to create a type library.
For information on MkTypLib, see the Windows SDK.
Visual C++ can read a type-library file and create a dispatch class derived from COleDispatchDriver. An object of
that class has properties and operations duplicating those of the server object. Your application calls this object's
properties and operations, and functionality inherited from COleDispatchDriver routes these calls to the OLE
system, which in turn routes them to the server object.
Visual C++ automatically maintains this type-library file for you if you chose to include Automation when the
project was created. As part of each build, the .tlb file will be built with MkTypLib.
To create a dispatch class from a type -library (.tlb) file
1. In either Class View or Solution Explorer, right-click the project and click Add and then click Add Class on
the shortcut menu.
2. In the Add Class dialog box, select the Visual C++/MFC folder in the left pane. Select the MFC Class
From TypeLib icon from the right pane and click Open .
3. In the Add Class From Typelib Wizard dialog box, select a type library from the Available type
libraries drop-down list. The Interfaces box displays the interfaces available for the selected type library.
NOTE
You can select interfaces from more than one type library.
To select interfaces, double-click them or click the Add button. When you do so, names for the dispatch
classes will appear in the Generated classes box. You can edit the class names in the Class box.
The File box displays the file in which the class will be declared. (you can edit this file name as well). You can
also use the browse button to select other files, if you prefer to have the header and implementation
information written in existing files or in a directory other than the project directory.
NOTE
All the dispatch classes for the selected interfaces will be put into the file specified here. If you want the interfaces to
be declared in separate headers, you must run this wizard for each header file you want to create.
NOTE
Some type library information may be stored in files with .DLL, .OCX, or .OLB file extensions.
4. Click Finish .
The wizard will then write the code for your dispatch classes using the specified class and file names.
See also
Automation Clients
Automation Servers
3/27/2020 • 2 minutes to read • Edit Online
Automation makes it possible for your application to manipulate objects implemented in another application, or
to expose objects so they can be manipulated. An Automation server is an application that exposes
programmable objects (called Automation objects) to other applications (called Automation clients). Automation
servers are sometimes called Automation components.
Exposing Automation objects enables clients to automate certain procedures by directly accessing the objects
and functionality the server makes available. Exposing objects this way is beneficial when applications provide
functionality that is useful for other applications. For example, a word processor might expose its spell-checking
functionality so that other programs can use it. Exposure of objects thus enables vendors to improve their
applications' functionality by using the ready-made functionality of other applications.
These Automation objects have properties and methods as their external interface. Properties are named
attributes of the Automation object. Properties are like the data members of a C++ class. Methods are functions
that work on Automation objects. Methods are like the public member functions of a C++ class.
NOTE
Although properties are like C++ data members, they are not directly accessible. To provide transparent access, set up an
internal variable in the Automation object with a pair of get/set member functions to access them.
By exposing application functionality through a common, well-defined interface, Automation makes it possible to
build applications in a single general programming language like Microsoft Visual Basic instead of in diverse,
application-specific macro languages.
BEGIN_DISPATCH_MAP(CMyServerDoc, COleServerDoc)
DISP_PROPERTY(CMyServerDoc, "Msg", m_strMsg, VT_BSTR)
DISP_FUNCTION(CMyServerDoc, "SetDirty", SetDirty, VT_EMPTY, VTS_I4)
END_DISPATCH_MAP()
The Class Wizard and Class View assist in maintaining dispatch maps. When you add a new method or property
to a class, Visual Studio adds a corresponding DISP_FUNCTION or DISP_PROPERTY macro with parameters
indicating the class name, external and internal names of the method or property, and data types.
The Add Class dialog box also simplifies the declaration of Automation classes and the management of their
properties and operations. When you use the Add Class dialog box to add a class to your project, you specify its
base class. If the base class allows Automation, the Add Class dialog box displays controls you use to specify
whether the new class should support Automation, whether it is "OLE creatable" (that is, whether objects of the
class can be created on a request from a COM client), and the external name for the COM client to use.
The Add Class dialog box then creates a class declaration, including the appropriate macros for the OLE features
you have specified. It also adds the skeleton code for implementation of your class's member functions.
The MFC Application Wizard simplifies the steps involved in getting your automation server application off the
ground. If you select the Automation check box from the Advanced Features page, the MFC Application
Wizard adds to your application's InitInstance function the calls required to register your Automation objects
and run your application as an Automation server.
What do you want to do
Learn about Automation clients
Learn more about class CCmdTarget
Learn more about class COleDispatchDriver
See also
Automation
MFC Application Wizard
Automation Servers: Object-Lifetime Issues
8/15/2019 • 2 minutes to read • Edit Online
When an Automation client creates or activates an OLE item, the server passes the client a pointer to that object.
The client establishes a reference to the object through a call to the OLE function IUnknown::AddRef. This reference
is in effect until the client calls IUnknown::Release. (Client applications written with the Microsoft Foundation Class
Library's OLE classes need not make these calls; the framework does so.) The OLE system and the server itself may
establish references to the object. A server should not destroy an object as long as external references to the object
remain in effect.
The framework maintains an internal count of the number of references to any server object derived from
CCmdTarget. This count is updated when an Automation client or other entity adds or releases a reference to the
object.
When the reference count becomes 0, the framework calls the virtual function CCmdTarget::OnFinalRelease. The
default implementation of this function calls the delete operator to delete this object.
The Microsoft Foundation Class Library provides additional facilities for controlling application behavior when
external clients have references to the application's objects. Besides maintaining a count of references to each
object, servers maintain a global count of active objects. The global functions AfxOleLockApp and AfxOleUnlockApp
update the application's count of active objects. If this count is nonzero, the application does not terminate when the
user chooses Close from the system menu or Exit from the File menu. Instead, the application's main window is
hidden (but not destroyed) until all pending client requests have been completed. Typically, AfxOleLockApp and
AfxOleUnlockApp are called in the constructors and destructors, respectively, of classes that support Automation.
Sometimes circumstances force the server to terminate while a client still has a reference to an object. For example,
a resource on which the server depends may become unavailable, causing the server to encounter an error. The
user may also close a server document that contains objects to which other applications have references.
In the Windows SDK, see IUnknown::AddRef and IUnknown::Release .
See also
Automation Servers
AfxOleCanExitApp
Connection Points
3/4/2019 • 3 minutes to read • Edit Online
This article explains how to implement connection points (formerly known as OLE connection points) using the
MFC classes CCmdTarget and CConnectionPoint .
In the past, the Component Object Model (COM) defined a general mechanism ( IUnknown::QueryInterface *) that
allowed objects to implement and expose functionality in interfaces. However, a corresponding mechanism that
allowed objects to expose their capability to call specific interfaces was not defined. That is, COM defined how
incoming pointers to objects (pointers to that object's interfaces) were handled, but it did not have an explicit
model for outgoing interfaces (pointers the object holds to other objects' interfaces). COM now has a model, called
connection points, that supports this functionality.
A connection has two parts: the object calling the interface, called the source, and the object implementing the
interface, called the sink. A connection point is the interface exposed by the source. By exposing a connection point,
a source allows sinks to establish connections to itself (the source). Through the connection point mechanism (the
IConnectionPoint interface), a pointer to the sink interface is passed to the source object. This pointer provides the
source with access to the sink's implementation of a set of member functions. For example, to fire an event
implemented by the sink, the source can call the appropriate method of the sink's implementation. The following
figure demonstrates the connection point just described.
DECLARE_CONNECTION_MAP()
BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()
If your class has more than one connection point, insert additional CONNECTION_PART macros between the
BEGIN_CONNECTION_MAP and END_CONNECTION_MAP macros.
Finally, add a call to EnableConnections in the class's constructor. For example:
CMyClass::CMyClass()
{
EnableConnections();
}
Once this code has been inserted, your CCmdTarget -derived class exposes a connection point for the ISampleSink
interface. The following figure illustrates this example.
void CMyClass::CallSinkFunc()
{
POSITION pos = m_xSampleConnPt.GetStartPosition();
ISampleSink* pSampleSink;
while (pos != NULL)
{
pSampleSink = (ISampleSink*)(m_xSampleConnPt.GetNextConnection(pos));
if (pSampleSink != NULL)
pSampleSink->SinkFunc();
}
}
This example retrieves the current set of connections on the SampleConnPt connection point with a call to
CConnectionPoint::GetConnections . It then iterates through the connections and calls ISampleSink::SinkFunc on
every active connection.
See also
MFC COM
MFC Internet Programming Basics
3/27/2020 • 2 minutes to read • Edit Online
Microsoft provides many APIs for programming both client and server applications. Many new applications are
being written for the Internet, and as technologies, browser capabilities, and security options change, new types
of applications will be written. Browsers run on client computers, providing access to the World Wide Web and
displaying HTML pages that contain text, graphics, ActiveX controls, and documents. Servers provide FTP, HTTP,
and gopher services, and run server extension applications using CGI. Your custom application can retrieve
information and provide data on the Internet.
IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information, see ActiveX Controls.
MFC provides classes that support Internet programming. You can use COleControl and CDocObjectServer and
related MFC classes to write ActiveX controls and Active documents. You can use MFC classes such as
CInternetSession, CFtpConnection, and CAsyncMonikerFile to retrieve files and information using Internet
protocols such as FTP, HTTP, and gopher.
In This Section
Internet-Related MFC Classes
Internet Information by Topic
Internet Information by Task
Active Technology on the Internet
WinInet Basics
HTML Basics
Related Sections
ActiveX Controls on the Internet
Asynchronous Monikers on the Internet
Win32 Internet Extensions (WinInet)
MFC Internet Programming Tasks
Application Design Choices
Writing MFC Applications
Testing Internet Applications
Internet Security
ATL Support for DHTML Controls
Global functions
AfxParseURL
AfxGetInternetHandleType
WinInet classes
CInternetSession
CInternetConnection
CFtpConnection
CGopherConnection
CHttpConnection
CInternetFile
CGopherFile
CHttpFile
CFileFind
CFtpFileFind
CGopherFileFind
CGopherLocator
CInternetException
See also
MFC Internet Programming Basics
Internet Information by Topic
3/4/2019 • 2 minutes to read • Edit Online
WinInet Basics
See also
MFC Internet Programming Basics
Internet Information by Task
3/27/2020 • 2 minutes to read • Edit Online
The tasks listed in this topic are sorted based on the task you want to accomplish.
IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information about modern
technologies that supersede ActiveX, see ActiveX Controls.
See also
MFC Internet Programming Basics
Active Technology on the Internet
3/4/2019 • 2 minutes to read • Edit Online
Active technology is an open platform that lets developers create exciting, dynamic content and applications for the
global Internet, or for a company's internal network, known as an intranet. The major technologies provided by
Microsoft for Internet programming are described below.
IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information about modern
technologies that supersede ActiveX, see ActiveX Controls.
ActiveX Controls
ActiveX controls (formerly OLE controls) are objects that can be inserted into Web pages or any other application
that is an ActiveX control container. Examples include buttons, stock tickers, and chart controls. For more
information, see ActiveX Controls on the Internet.
Active Scripts
VBScript and other scripting languages connect controls and add interactive functionality to Web pages. Scripting
moves processing from the server to the client. For example, form entries can be validated on the client and then
sent to the server.
HTML Extensions
HTML extensions, such as the object tag, have been added to support controls and scripting.
See also
MFC Internet Programming Basics
ActiveX Controls on the Internet
Win32 Internet Extensions (WinInet)
WinInet Basics
3/27/2020 • 3 minutes to read • Edit Online
You can use WinInet to add FTP support to download and upload files from within your application. You can
override OnStatusCallback and use the dwContext parameter to provide progress information to users as you
search for and download files.
This article contains the following topics:
Create a Very Simple Browser
Download a Web Page
FTP a File
Retrieve a Gopher Directory
Display Progress Information While Transferring Files
The code excerpts below demonstrate how to create a simple browser, download a Web page, FTP a file, and
search for a gopher file. They are not meant as complete examples and not all contain exception handling.
For additional information on WinInet, see Win32 Internet Extensions (WinInet).
if (dwRet == HTTP_STATUS_OK)
{
CHAR szBuff[1024];
while (pFile->Read(szBuff, 1024) > 0)
{
printf_s("%1023s", szBuff);
}
}
delete pFile;
delete pServer;
}
catch (CInternetException *pEx)
{
//catch errors from WinInet
TCHAR pszError[64];
pEx->GetErrorMessage(pszError, 64);
_tprintf_s(_T("%63s"), pszError);
}
session.Close();
}
FTP a File
#include <afxinet.h>
pConn = session.GetFtpConnection(pszServerName);
//get the file
if (!pConn->GetFile(pszRemoteFile, pszLocalFile))
{
//display an error
}
delete pConn;
session.Close();
}
pConn = session.GetGopherConnection(pszGopherSite);
pFile = new CGopherFileFind(pConn);
BOOL bFound = pFile->FindFile(pszFile);
while (bFound)
{
//retrieve attributes of found file
bFound = pFile->FindNextFile();
}
delete pFile;
delete pConn;
session.Close();
}
Use OnStatusCallback
When using the WinInet classes, you can use the OnStatusCallback member of your application's
CInternetSession object to retrieve status information. If you derive your own CInternetSession object, override
OnStatusCallback , and enable status callbacks, MFC will call your OnStatusCallback function with progress
information about all the activity in that Internet session.
Because a single session might support several connections (which, over their lifetime, might perform many
different distinct operations), OnStatusCallback needs a mechanism to identify each status change with a
particular connection or transaction. That mechanism is provided by the context ID parameter given to many of
the member functions in the WinInet support classes. This parameter is always of type DWORD and is always
named dwContext.
The context assigned to a particular Internet object is used only to identify the activity the object causes in the
OnStatusCallback member of the CInternetSession object. The call to OnStatusCallback receives several
parameters; these parameters work together to tell your application what progress has been made for which
transaction and connection.
When you create a CInternetSession object, you can specify a dwContext parameter to the constructor.
CInternetSession itself doesn't use the context ID; instead, it passes the context ID on to any
InternetConnection -derived objects that don't explicitly get a context ID of their own. In turn, those
CInternetConnection objects will pass the context ID along to CInternetFile objects they create if you don't
explicitly specify a different context ID. If, on the other hand, you do specify a specific context ID of your own, the
object and any work it does will be associated with that context ID. You can use the context IDs to identify what
status information is being given to you in your OnStatusCallback function.
Most browsers have the capability of examining the HTML source of the pages you browse. When you view the
source you will see a number of HTML (Hypertext markup language) tags, surrounded by angle brackets(<>),
interspersed with text.
The steps below use HTML tags to build a simple Web page. In these steps, you'll type plain text into a file in
Notepad, make a few changes, save the file, and reload your page in the browser to see your changes.
To create an HTML file
1. Open Notepad or any plain text editor.
2. From the File menu, choose New .
3. Type the following lines:
<HTML>
<HEAD>
<TITLE>Top HTML Tags</TITLE>
</HEAD>
</HTML>
4. From the File menu, choose Save , and save the file as c:\webpages\First.htm. Leave the file open in the
editor.
5. Switch to your browser, and from the File menu, choose Open , or type file://C:/webpages/first.htm in the
browser's URL edit box. You should see a blank page with the window caption "Top HTML Tags."
Notice the tags are paired and are included in angle brackets. Tags are not case-sensitive, but capitalization is
often used to make tags stand out.
The tag <HTML> starts the document, and the tag </HTML> ends it. Ending tags (not always required) are
the same as the starting tag, but have a forward slash (/) in front of the tag. There should be no spaces
between the angle bracket (<) and the start of your tag.
6. Switch back to Notepad, and after the </HEAD> line, type:
<BODY>
HTML is swell.
Life is good.
</BODY>
10. Add an image, using a .gif file saved in the same directory as your page:
<IMG src="yourfile.gif">
12. To number the list instead, use paired <OL> and </OL> tags in place of the <UL> and </UL> tags.
That should get you started. If you see a great feature on a Web page, you can find out how it was created by
examining the HTML source. HTML editors such as Microsoft Front Page can be used to create both simple and
advanced pages.
Here's the entire HTML source for the file you've been building:
<HTML>
<HEAD>
<TITLE>Top HTML Tags</TITLE>
</HEAD>
<BODY>
HTML is swell.<BR>
Life is good.
<H3>Here's the big picture</H3>
<IMG src="yourfile.gif">
<UL>Make me an unordered list.
<LI>One programmer</LI>
<LI>Ten SDKs</LI>
<LI>Great Internet Apps</LI>
</UL>
</BODY>
</HTML>
For a complete description of tags, attributes, and extensions, see the Hypertext Markup Language (HTML)
specification:
Latest published version of HTML at W3C.org.
See also
MFC Internet Programming Basics
MFC Internet Programming Tasks
3/4/2019 • 2 minutes to read • Edit Online
This section contains detailed steps for adding Internet support to your applications. Topics include how to use the
MFC classes to Internet-enable your existing applications, and how to add Active document support to your
existing COM component. Do you want to create a document with up-to-the-minute stock quotes, Pittsburgh's
football scores, and the latest temperature in Antarctica Microsoft provides a number of technologies to help you
do that over the Internet.
Active technologies include ActiveX controls (formerly OLE controls) and Active documents; WinInet for easily
retrieving and saving files across the Internet; and asynchronous monikers for efficient data downloading. Visual
C++ provides wizards to help you get started quickly with a starter application. For an introduction to these
technologies, see MFC Internet Programming Basics and MFC COM.
Have you always wanted to FTP a file but haven't learned WinSock and network programming protocols WinInet
classes encapsulate these protocols, providing you with a simple set of functions you can use to write a client
application on the Internet to download files using HTTP, FTP, and gopher. You can use WinInet to search
directories on your hard drive or around the world. You can transparently collect data of several different types,
and present it to the user in an integrated interface.
Do you have large amounts of data to download Asynchronous monikers provide a COM (Component Object
Model) solution for progressive rendering of large objects. WinInet can also be used asynchronously.
The following table describes a few of the things you can do with these technologies.
Y O U H AVE Y O U WA N T TO Y O U SH O UL D
A Web server. Track logons and detailed information Write a filter, request notifications for
about URL requests. logon events and URL mapping.
A Web browser. Provide dynamic content. Create ActiveX controls and Active
documents.
See also
MFC Internet Programming Basics
Internet Information by Task
Application Design Choices
3/27/2020 • 3 minutes to read • Edit Online
This article discusses some of the design issues to consider when programming for the Internet.
Topics covered in this article include:
Intranet Versus Internet
Client or Server Application
The Web Page
Browser or Stand-Alone Application
COM on the Internet
Client Data Download Services
If you are ready to start writing your program now, see Writing MFC Applications.
IN T ERN ET IN T RA N ET
Reduced security of data and systems Controlled access to data and systems
Internet Downloading Using For asynchronous transfer using COM, CAsyncMonikerFile, CDataPathProperty
Asynchronous Monikers ActiveX controls, and any Internet
protocol.
WinInet For Internet protocols for HTTP, FTP, and CInternetSession, CFtpFileFind,
gopher. Data can be transferred CGopherFileFind, and many more.
synchronously or asynchronously and is
stored in a system-wide cache.
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
Win32 Internet Extensions (WinInet)
Asynchronous Monikers on the Internet
Writing MFC Applications
3/4/2019 • 2 minutes to read • Edit Online
This article explains the initial steps you take to develop your application. First, you must decide what kind of
application you are writing. Several of the choices were discussed in Application Design Choices. Will your
application be:
Running on the Internet or an intranet
Running on a client or on a server
Running in a browser or as a stand-alone application
Using COM or Active technology
Downloading data using WinInet or asynchronous monikers
Your decisions determine which classes are appropriate for your application. Your answers also help determine the
selections you make when you run the Application Wizard to begin constructing your application.
After you've made your initial design decisions about your Internet application, you can use the Application Wizard
to get started. Use the Application Wizard to create a skeleton application and modify the code as described in the
following articles:
For an ActiveX control, see ActiveX Controls on the Internet.
The following articles also provide instructions to help you start your programming tasks:
Application Design Choices
Asynchronous Monikers on the Internet
WinInet Basics
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
ActiveX Controls on the Internet
5/8/2019 • 7 minutes to read • Edit Online
ActiveX controls are the updated version of the OLE control specification.
IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information, see ActiveX Controls.
Controls are a primary architecture for developing programmable software components that can be used in a
variety of different containers, including COM-aware Web browsers on the Internet. Any ActiveX control can be
an Internet control and can add its functionality to an Active document or be part of a Web page. Controls on a
Web page can communicate with each other using scripting.
ActiveX controls are not limited to the Internet. An ActiveX control can also be used in any container, as long as
the control supports the interfaces required by that container.
ActiveX controls have several advantages, including:
Fewer required interfaces than previous OLE controls.
The ability to be windowless and always in-place active.
In order to be an ActiveX control, a control must:
Support the IUnknown interface.
Be a COM object.
Export DLLRegisterSer ver and DLLUnRegisterSer ver .
Support additional interfaces as needed for functionality.
if (dwSize > 0)
{
CString string;
LPTSTR str = string.GetBuffer(dwSize);
UINT nBytesRead = Read(str, dwSize);
if (nBytesRead > 0)
{
string.ReleaseBuffer(nBytesRead);
edit->SetSel(-1, -1);
edit->ReplaceSel(string);
}
}
}
Note that you must include AFXCMN.H to use the CListCtrl class.
4. When your control's overall state changes (for example, from loading to initialized or user interactive), call
COleControl::InternalSetReadyState . If your control has only one data path property, you can add code on
BSCF_L ASTDATANOTIFICATION to notify the container that your download is complete. For example:
5. Override OnProgress . In OnProgress , you are passed a number showing the maximum range and a
number showing how far along the current download is. You can use these numbers to display status
such as percent complete to the user.
The next procedure adds a property to the control to use the class just derived.
To add a property
1. In Class View , right-click the interface underneath the library node and select Add , then Add Proper ty .
This will start the Add Proper ty Wizard .
2. In the Add Proper ty Wizard , select the Set/Get Methods radio button, type the Proper ty Name , for
example, EditControlText, and select BSTR as the Proper ty type .
3. Click Finish .
4. Declare a member variable of your CDataPathProperty -derived class to your ActiveX control class.
CMyDataPathProperty EditControlText;
5. Implement the Get/Set methods. For Get , return the string. For Set , load the property and call
SetModifiedFlag .
BSTR CMFCActiveXControlCtrl::GetEditControlText(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString strResult;
strResult = EditControlText.GetPath();
return strResult.AllocSysString();
}
Load(newVal, EditControlText);
SetModifiedFlag();
}
7. Override ResetData to notify the property to reset its control by adding this line:
EditControlText.ResetData();
In your ActiveX control class, you can use this memory mapped file in OnDraw to display the data. In your ActiveX
control CCachedDataPathProperty -derived class, override the member function OnDataAvailable and invalidate
the control, after calling the base class implementation.
<OBJECT
CLASSID="clsid:FC25B780-75BE-11CF-8B01-444553540000"
CODEBASE="/ie/download/activex/iechart.ocx"
ID=chart1
WIDTH=400
HEIGHT=200
ALIGN=center
HSPACE=0
VSPACE=0>
<PARAM NAME="BackColor" value="#ffffff"/>
<PARAM NAME="ForeColor" value="#0000ff"/>
<PARAM NAME="url" VALUE="/ie/controls/chart/mychart.txt"/>
</OBJECT>
m_lReadyState = READYSTATE_LOADING;
You will update the ready state as your code is downloaded by calling COleControl::InternalSetReadyState. One
place you could call InternalSetReadyState is from the OnProgress override of CDataPathProperty -derived class.
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
Upgrading an Existing ActiveX Control
4/21/2020 • 10 minutes to read • Edit Online
Existing ActiveX controls (formerly OLE controls) can be used on the Internet without modification. However, you
may want to modify controls to improve their performance.
IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information about modern
technologies that supersede ActiveX, see ActiveX Controls.
When using your control on a Web page, there are additional considerations. The .ocx file and all supporting files
must be on the target machine or be downloaded across the Internet. This makes code size and download time an
important consideration. Downloads can be packaged in a signed .cab file. You can mark your control as safe for
scripting, and as safe for initializing.
This article discusses the following topics:
Packaging Code for Downloading
Marking a Control Safe for Scripting and Initializing
Licensing Issues
Signing Code
Managing the Palette
Internet Explorer Browser Safety Levels and Control Behavior
You can also add optimizations, as described in ActiveX Controls: Optimization. Monikers can be used to download
properties and large BLOBs asynchronously, as described in ActiveX Controls on the Internet.
CODEBASE="http://example.microsoft.com/mycontrol.ocx#version=4,
70,
0,
1086"
This solution downloads only the control's .ocx file, and requires any supporting DLLs to already be installed on
the client machine. This will work for Internet Explorer and MFC ActiveX controls built with Visual C++, because
Internet Explorer ships with the supporting DLLs for Visual C++ controls. If another Internet browser that is
ActiveX control-capable is used to view this control, this solution will not work.
Using the CODEBASE Tag with an INF File
CODEBASE="http://example.microsoft.com/trustme.inf"
An .inf file will control the installation of an .ocx and its supporting files. This method is not recommended because
it is not possible to sign an .inf file (see Signing Code for pointers on code signing).
Using the CODEBASE Tag with a CAB File
CODEBASE="http://example.microsoft.com/acontrol.cab#version=1,
2,
0,
0"
Cabinet files are the recommended way to package ActiveX controls that use MFC. Packaging an MFC ActiveX
control in a cabinet file allows an .inf file to be included to control installation of the ActiveX control and any
dependent DLLs (such as the MFC DLLs). Using a CAB file automatically compresses the code for quicker
download. If you are using a .cab file for component download, it is faster to sign the entire .cab file than each
individual component.
Creating CAB Files
Tools to create cabinet files are now part of the Windows 10 SDK.
The cabinet file pointed to by CODEBASE should contain the .ocx file for your ActiveX control and an .inf file to
control its installation. You create the cabinet file by specifying the name of your control file and an .inf file. Do not
include dependent DLLs that may already exist on the system in this cabinet file. For example, the MFC DLLs are
packaged in a separate cabinet file and referred to by the controlling .inf file.
For details on how to create a CAB file, see Creating a CAB File.
The INF File
The following example, spindial.inf, lists the supporting files and the version information needed for the MFC
Spindial control. Notice the location for the MFC DLLs is a Microsoft Web site. The mfc42.cab is provided and
signed by Microsoft.
Contents of spindial.inf:
[mfc42installer]
file-win32-x86=http://activex.microsoft.com/controls/vc/mfc42.cab
[Olepro32.dll] - FileVersion=5,
0,
4261,
0
[Mfc42.dll] - FileVersion=6,
0,
8168,
0
[Msvcrt.dll] - FileVersion=6,
0,
8168,
0
In this case, spindial.cab will contain two files, spindial.ocx and spindial.inf. The following command will build the
cabinet file:
The -s 6144 parameter reserves space in the cabinet for code signing.
The Version Tag
Note here that the #Version information specified with a CAB file applies to the control specified by the CLASSID
parameter of the <OBJECT> tag.
Depending on the version specified, you can force download of your control. For complete specifications of the
OBJECT tag including the CODEBASE parameter, see the W3C reference.
HKEY_CLASSES_ROOT\Component Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
Controls that can be safely initialized from persistent data are marked safe for persistence with a registry entry
similar to:
HKEY_CLASSES_ROOT\Component Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
Add entries similar to the following (substituting your control's class ID in place of
{06889605-B8D0-101A-91F1-00608CEAD5B3} ) to associate your keys with the following class ID:
HKEY_CLASSES_ROOT\CLSID\{06889605-B8D0-101A-91F1-00608CEAD5B3}\Implemented Categories\{7DD95801-9882-11CF-
9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{06889605-B8D0-101A-91F1-00608CEAD5B3}\Implemented Categories\{7DD95802-9882-11CF-
9FA9-00AA006C42C4}
Licensing Issues
If you want to use a licensed control on a Web page, you must verify that the license agreement allows its use on
the Internet and create a license package file (LPK) for it.
A licensed ActiveX control will not load properly in an HTML page if the computer running Internet Explorer is not
licensed to use the control. For example, if a licensed control was built using Visual C++, the HTML page using the
control will load properly on the computer where the control was built, but it will not load on a different computer
unless licensing information is included.
To use a licensed ActiveX control in Internet Explorer, you must check the vendor's license agreement to verify that
the license for the control permits:
Redistribution
Use of the control on the Internet
Use of the Codebase parameter
To use a licensed control in an HTML page on a nonlicensed machine, you must generate a license package file
(LPK). The LPK file contains run-time licenses for licensed controls in the HTML page. This file is generated via
LPK_TOOL.EXE which comes with the ActiveX SDK.
To create an LPK file
1. Run LPK_TOOL.EXE on a computer that is licensed to use the control.
2. In the License Package Authoring Tool dialog box, in the Available Controls list box, select each
licensed ActiveX control that will be used on the HTML page and click Add .
3. Click Save & Exit and type a name for the LPK file. This will create the LPK file and close the application.
To embed a licensed control on an HTML page
1. Edit your HTML page. In the HTML page, insert an <OBJECT> tag for the License Manager object before any
other <OBJECT> tags. The License Manager is an ActiveX control that is installed with Internet Explorer. Its class
ID is shown below. Set the LPKPath property of the License Manager object to the path and name of the LPK
file. You can have only one LPK file per HTML page.
1. Insert the <OBJECT> tag for your licensed control after the License Manager tag.
For example, an HTML page that displays the Microsoft Masked Edit control is shown below. The first class
ID is for the License Manager control, the second class ID is for the Masked Edit control. Change the tags to
point to the relative path of the .lpk file you created earlier, and add an object tag including the class ID for
your control.
2. Insert the <EMBED> attribute for your LPK file, if using the NCompass ActiveX plug-in.
If your control may be viewed on other Active enabled browsers — for example, Netscape using the
NCompass ActiveX plug-in — you must add the <EMBED> syntax as shown below.
<OBJECT CLASSID="clsid:5220cb21-c88d-11cf-b347-00aa00a28331">
<PARAM NAME="LPKPath" VALUE="maskedit.lpk">
</OBJECT>
<OBJECT CLASSID="clsid:C932BA85-4374-101B-A56C-00AA003668DC" WIDTH=100 HEIGHT=25>
</OBJECT>
For more information about control licensing, see ActiveX Controls: Licensing an ActiveX Control.
Signing Code
Code signing is designed to identify the source of code, and to guarantee that the code has not changed since it
was signed. Depending on browser safety settings, users may be warned before the code is downloaded. Users
may choose to trust certain certificate owners or companies, in which case code signed by those trusted will be
downloaded without warning. Code is digitally signed to avoid tampering.
Make sure your final code is signed so that your control can be automatically downloaded without displaying trust
warning messages. For details on how to sign code, check the documentation on Authenticode in the ActiveX SDK
and see Signing a CAB File.
Depending on trust and browser safety level settings, a certificate may be displayed to identify the signing person
or company. If the safety level is none, or if the signed control's certificate owner is trusted, a certificate will not be
displayed. See Internet Explorer Browser Safety Levels and Control Behavior for details on how the browser safety
setting will determine whether your control is downloaded and a certificate displayed.
Digital signing guarantees code has not changed since it's been signed. A hash of the code is taken and embedded
in the certificate. This hash is later compared with a hash of the code taken after the code is downloaded but
before it runs. Companies such as Verisign can supply private and public keys needed to sign code. The ActiveX
SDK ships with MakeCert, a utility for creating test certificates.
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
MFC ActiveX Controls: Licensing an ActiveX Control
Asynchronous Monikers on the Internet
3/4/2019 • 2 minutes to read • Edit Online
The Internet requires new approaches to application design because of its slow network access. Applications
should perform network access asynchronously to avoid stalling the user interface. The MFC class
CAsyncMonikerFile provides asynchronous support for downloading files.
With asynchronous monikers, you can extend your COM application to download asynchronously across the
Internet and to provide progressive rendering of large objects such as bitmaps and VRML objects. Asynchronous
monikers enable an ActiveX control property or a file on the Internet to be downloaded without blocking the
response of the user interface.
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
Testing Internet Applications
3/4/2019 • 2 minutes to read • Edit Online
There are some unique testing challenges on the Internet, especially for applications running on a Web server. Your
initial testing will probably be done using a single-user client connecting to a test server. This will be useful for
debugging your code.
You will also want to test under real conditions: with multiple clients connected over high-speed connections as
well as low-speed serial lines, including modem connections. It can be difficult to simulate real conditions, but it is
certainly worth spending time designing possible scenarios and executing them. If possible, you will also want to
use tools to do capacity and stress testing. Certain classes of bugs, such as timing bugs, are difficult to find and to
reproduce.
One of the challenges of Internet programming is its visibility. Many accesses to your site may slow down your
server. You want your server to degrade gracefully. You want to prevent anything that could be destructive to a
user's computer if your application fails (for example, corruption of data while writing to the registry or while
writing cookies on the client).
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
Internet Security (C++)
3/4/2019 • 2 minutes to read • Edit Online
Code safety is a major issue for developers and for users of Internet applications. There are risks: malicious code,
code that has been tampered with, and code from unknown sites or authors.
There are two basic approaches to security when developing for the Internet. The first is called "sandboxing." In this
approach, an application is restricted to a particular set of APIs, and excluded from potentially dangerous ones
such as file I/O where a program could destroy data on a user's computer. The second is implemented using digital
signatures. This approach is referred to as "shrinkwrap" for the Internet. Code is verified and signed using private
key/public key technology. Before the code is run, its digital signature is verified to ensure that the code is from a
known authenticated source, and that the code has not been altered since it has been signed.
In the first case, you trust that the application will not do any harm and you trust the origin of the application. In
the second, digital signatures are used to verify authenticity. Digital signing is an industry standard used to identify
and provide details about the publisher of the code. Its technology is based on standards, including RSA and X.509.
Browsers typically allow users to choose if they want to download and run code of unknown origin.
See also
MFC Internet Programming Tasks
MFC Internet Programming Basics
OLE in MFC
3/27/2020 • 2 minutes to read • Edit Online
These articles explain the fundamentals of OLE programming using MFC. MFC provides the easiest way to write
programs that use OLE:
To use OLE visual editing (in-place activation).
To work as OLE containers or servers.
To implement drag-and-drop functionality.
To work with date and time data.
To manage the state data of MFC modules, including exported DLL function entry points, OLE/COM
interface entry points, and window procedure entry points.
You can also use Automation.
NOTE
The term OLE denotes the technologies associated with linking and embedding, including OLE containers, OLE servers,
OLE items, in-place activation (or visual editing), trackers, drag and drop, and menu merging. The term Active applies to
the Component Object Model (COM) and COM-based objects such as ActiveX controls. OLE Automation is now called
Automation.
In This Section
OLE Background
Discusses OLE and provides conceptual information about how it works.
Activation
Describes the role of activation in editing OLE items.
Containers
Provides links to using containers in OLE.
Data Objects and Data Sources
Provides links to topics discussing the use of the COleDataObject and COleDataSource classes.
Drag and Drop
Discusses using copying and pasting with OLE.
OLE Menus and Resources
Explains the use of menus and resources in MFC OLE document applications.
Registration
Discusses server installation and initialization.
Servers
Describes how to create OLE items (or components) for use by container applications.
Trackers
Provides information about the CRectTracker class, which provides a graphical interface to enable users to
interact with OLE client items.
Related Sections
Connection Points
Explains how to implement connection points (formerly known as OLE connection points) using the MFC classes
CCmdTarget and CConnectionPoint .
See also
Concepts
OLE Background
3/27/2020 • 3 minutes to read • Edit Online
OLE is a mechanism that allows users to create and edit documents containing items or "objects" created by
multiple applications.
NOTE
OLE was originally an acronym for Object Linking and Embedding. However, it is now referred to as OLE. Parts of OLE not
related to linking and embedding are now part of Active technology.
OLE documents, historically called compound documents, seamlessly integrate various types of data, or
components. Sound clips, spreadsheets, and bitmaps are typical examples of components found in OLE
documents. Supporting OLE in your application allows your users to use OLE documents without worrying about
switching between the different applications; OLE does the switching for you.
You use a container application to create compound documents and a server application or component
application to create the items within the container document. Any application you write can be a container, a
server, or both.
OLE incorporates many different concepts that all work toward the goal of seamless interaction between
applications. These areas include the following:
Linking and Embedding
Linking and embedding are the two methods for storing items created inside an OLE document that were
created in another application. For general information on the differences between the two, see the article
OLE Background: Linking and Embedding. For more detailed information, see the articles Containers and
Servers.
In-Place Activation (Visual Editing)
Activating an embedded item in the context of the container document is called in-place activation or visual
editing. The container application's interface changes to incorporate the features of the component
application that created the embedded item. Linked items are never activated in place because the actual
data for the item is contained in a separate file, out of the context of the application containing the link. For
more information on in-place activation, see the article Activation.
NOTE
Linking and embedding and in-place activation provide the main features of OLE visual editing.
Automation Automation allows one application to drive another application. The driving application is
known as an automation client, and the application being driven is known as an automation server or
automation component. For more information on automation, see the articles Automation Clients and
Automation Servers.
NOTE
Automation works in both OLE and Active technology contexts. You can automate any object based on COM.
Compound Files
Compound files provide a standard file format that simplifies structured storing of compound documents
for OLE applications. Within a compound file, storages have many features of directories and streams have
many features of files. This technology is also called structured storage. For more information on
compound files, see the article Containers: Compound Files.
Uniform Data Transfer
Uniform Data Transfer (UDT) is a set of interfaces that allow data to be sent and received in a standard
fashion, regardless of the actual method chosen to transfer the data. UDT forms the basis for data transfers
by drag and drop. UDT now serves as the basis for existing Windows data transfer, such as the Clipboard
and dynamic data exchange (DDE). For more information on UDT, see the article Data Objects and Data
Sources (OLE).
Drag and Drop
Drag and drop is an easy-to-use, direct-manipulation technique to transfer data among applications,
among windows within an application, or even within a single window in an application. The data to be
transferred is selected and dragged to the desired destination. Drag and drop is based on uniform data
transfer. For more information on drag and drop, see the article Drag and Drop.
Component Object Model
The Component Object Model (COM) provides the infrastructure used when OLE objects communicate with
each other. The MFC OLE classes simplify COM for the programmer. COM is part of Active technology,
because COM objects underlie both OLE and Active technology. For more information about COM, see the
Active Template Library (ATL) topics.
Some of the more important OLE topics are covered in the following articles:
OLE Background: Linking and Embedding
OLE Background: Containers and Servers
OLE Background: Implementation Strategies
OLE Background: MFC Implementation
For general OLE information not found in the above articles, search for OLE in MSDN.
See also
OLE
OLE Background: Linking and Embedding
3/4/2019 • 2 minutes to read • Edit Online
Using the Paste command in a container application can create an embedded component, or embedded item. The
source data for an embedded item is stored as part of the OLE document that contains it. In this way, a document
file for a word processor document can contain text and also can contain bitmaps, graphs, formulas, or any other
type of data.
OLE provides another way to incorporate data from another application: creating a linked component, or linked
item, or a link. The steps for creating a linked item are similar to those for creating an embedded item, except that
you use the Paste Link command instead of the Paste command. Unlike an embedded component, a linked
component stores a path to the original data, which is often in a separate file.
For example, if you are working in a word processor document and create a linked item to some spreadsheet cells,
the data for the linked item is stored in the original spreadsheet document. The word processor document contains
only the information specifying where the item can be found, that is, it contains a link to the original spreadsheet
document. When you double-click the cells, the spreadsheet application is launched and the original spreadsheet
document is loaded from where it was stored.
Every OLE item, whether embedded or linked, has a type associated with it based on the application that created it.
For example, a Microsoft Paintbrush item is one type of item, and a Microsoft Excel item is another type. Some
applications, however, can create more than one item type. For example, Microsoft Excel can create worksheet
items, chart items, and macrosheet items. Each of these items can be uniquely identified by the system using a
Class Identifier or CLSID .
See also
OLE Background
OLE Background: Containers and Servers
Containers: Client Items
Servers: Server Items
OLE Background: Containers and Servers
3/4/2019 • 2 minutes to read • Edit Online
A container application is an application that can incorporate embedded or linked items into its own documents.
The documents managed by a container application must be able to store and display OLE document components
as well as the data created by the application itself. A container application must also allow users to insert new
items or edit existing items by activating server applications when necessary. The user-interface requirements of a
container application are listed in the article Containers: User-Interface Issues.
A server application or component application is an application that can create OLE document components for use
by container applications. Server applications usually support drag and drop or copying their data to the Clipboard
so that a container application can insert the data as an embedded or linked item. An application can be both a
container and a server.
Most servers are stand-alone applications or full servers; they can either be run as stand-alone applications or can
be launched by a container application. A miniserver is a special type of server application that can be launched
only by a container. It cannot be run as a stand-alone application. Microsoft Draw and Microsoft Graph servers are
examples of miniservers.
Containers and servers do not communicate directly. Instead, they communicate through the OLE system dynamic-
link libraries (DLL). These DLLs provide functions that containers and servers call, and the containers and servers
provide callback functions that the DLLs call.
Using this means of communication, a container does not need to know the implementation details of the server
application. It allows a container to accept items created by any server without having to define the types of
servers with which it can work. As a result, the user of a container application can take advantage of future
applications and data formats. If these new applications are OLE components, then a compound document will be
able to incorporate items created by those applications.
See also
OLE Background
OLE Background: MFC Implementation
Containers
Servers
Containers: Client Items
Servers: Server Items
OLE Background: Implementation Strategies
4/1/2019 • 2 minutes to read • Edit Online
Depending on your application, there are four possible implementation strategies for adding OLE support:
You are writing a new application.
This situation usually requires the least work. You run the MFC Application Wizard and select either
Advanced Features or Compound Document Support to create a skeleton application. For information on
these options and what they do, see the article Creating an MFC EXE Program.
You have a program written with the Microsoft Foundation Class Library version 2.0 or higher that does not
support OLE.
Create a new application with the MFC Application Wizard as previously mentioned, and then copy and
paste the code from the new application into your existing application. This will work for servers, containers,
or automated applications. See the MFC SCRIBBLE sample for an example of this strategy.
You have a Microsoft Foundation Class Library program that implements OLE version 1.0 support.
See MFC Technical Note 41 for this conversion strategy.
You have an application that was not written using the Microsoft Foundation Classes and that may or may
not have implemented OLE support.
This situation requires the most work. One approach is to create a new application, as in the first strategy,
and then copy and paste your existing code into it. If your existing code is written in C, then you may need to
modify it so it can compile as C++ code. If your C code calls the Windows API, then you do not have to
change it to use the Microsoft Foundation classes. This approach likely will require some restructuring of
your program to support the document/view architecture used by versions 2.0 and higher of the Microsoft
Foundation Classes. For more information on this architecture, see Technical Note 25.
Once you have decided on a strategy, you should either read the Containers or Servers articles (depending on the
type of application you are writing) or examine the sample programs, or both. The MFC OLE samples OCLIENT and
HIERSVR show how to implement the various aspects of containers and servers, respectively. At various points
throughout these articles, you will be referred to certain functions in these samples as examples of the techniques
being discussed.
See also
OLE Background
Containers: Implementing a Container
Servers: Implementing a Server
MFC Application Wizard
OLE Background: MFC Implementation
3/27/2020 • 2 minutes to read • Edit Online
Because of the size and complexity of the raw OLE API, calling it directly to write OLE applications can be very time
consuming. The goal of the Microsoft Foundation Class Library implementation of OLE is to reduce the amount of
work you have to do to write full-featured, OLE-capable applications.
This article explains the parts of the OLE API that have not been implemented inside MFC. The discussion also
explains how what is implemented maps to the OLE section of the Windows SDK.
TIP
The easiest way to implement an Automation server is to place it in a DLL. MFC supports this approach.
For more information on how the Microsoft Foundation OLE classes implement OLE interfaces, see MFC Technical
Notes 38, 39, and 40.
See also
OLE Background
OLE Background: Implementation Strategies
Activation (C++)
3/27/2020 • 2 minutes to read • Edit Online
This article explains the role of activation in the visual editing of OLE items. After a user has embedded an OLE
item in a container document, it may need to be used. To do this, the user double-clicks the item, which activates
that item. The most frequent activity for activation is editing. Many current OLE items, when activated for editing,
cause the menus and toolbars in the current frame window to change to reflect those belonging to the server
application that created the item. This behavior, known as in-place activation, allows the user to edit any
embedded item in a compound document without leaving the container document's window.
It is also possible to edit embedded OLE items in a separate window. This will happen if either the container or
server application does not support in-place activation. In this case, when the user double-clicks an embedded
item, the server application is launched in a separate window and the embedded item appears as its own
document. The user edits the item in this window. When editing is complete, the user closes the server
application and returns to the container application.
As an alternative, the user can choose "open editing" with the <object> Open command on the Edit menu. This
opens the object in a separate window.
NOTE
Editing embedded items in a separate window was standard behavior in version 1 of OLE, and some OLE applications may
support only this style of editing.
In-place activation promotes a document-centric approach to document creation. The user can treat a compound
document as a single entity, working on it without switching between applications. However, in-place activation is
used only for embedded items, not for linked items: they must be edited in a separate window. This is because a
linked item is actually stored in a different place. The editing of a linked item takes place within the actual context
of the data, that is, where the data is stored. Editing a linked item in a separate window reminds the user that the
data belongs to another document.
MFC does not support nested in-place activation. If you build a container/server application, and that
container/server is embedded in another container and in-place activated, it cannot in-place activate objects
embedded inside it.
What happens to an embedded item when the user double-clicks it depends on the verbs defined for the item.
For information, see Activation: Verbs.
See also
OLE
Containers
Servers
Activation: Verbs
3/4/2019 • 2 minutes to read • Edit Online
This article explains the role primary and secondary verbs play in OLE activation.
Usually, double-clicking an embedded item allows the user to edit it. However, certain items do not behave this
way. For example, double-clicking an item created with the Sound Recorder application does not open the server in
a separate window; instead, it plays the sound.
The reason for this behavior difference is that Sound Recorder items have a different "primary verb." The primary
verb is the action performed when the user double-clicks an OLE item. For most types of OLE items, the primary
verb is Edit, which launches the server that created the item. For some types of items, such as Sound Recorder
items, the primary verb is Play.
Many types of OLE items support only one verb, and Edit is the most common one. However, some types of items
support multiple verbs. For example, Sound Recorder items support Edit as a secondary verb.
Another verb used frequently is Open. The Open verb is identical to Edit, except the server application is launched
in a separate window. This verb should be used when either the container application or the server application
does not support in-place activation.
Any verbs other than the primary verb must be invoked through a submenu command when the item is selected.
This submenu contains all the verbs supported by the item and is usually reached by the typename Object
command on the Edit menu. For information on the typename Object command, see the article Menus and
Resources: Container Additions.
The verbs a server application supports are listed in the Windows registration database. If your server application
is written with the Microsoft Foundation Class Library, it will automatically register all verbs when the server is
started. If not, you should register them during the server application's initialization phase. For more information,
see the article Registration.
See also
Activation
Containers
Servers
Containers
3/4/2019 • 2 minutes to read • Edit Online
A container application is an application that can incorporate embedded or linked items into its own documents.
The documents managed by a container application must be able to store and display OLE compound document
components as well as data created by the application itself. A container application must also allow users to
insert new items or edit existing items.
In This Section
Implement a Container
Container Client Items
Use Compound Files
Container User-Interface Issues
Advanced Features of Containers
See also
OLE
Servers
Activation
Menus and Resources (OLE)
Containers: Implementing a Container
2/10/2020 • 2 minutes to read • Edit Online
This article summarizes the procedure for implementing a container and points you to other articles that provide
more detailed explanations about implementing containers. It also lists some optional OLE features you may want
to implement and the articles describing these features.
To prepare your CWinApp-derived class
1. Initialize the OLE libraries by calling AfxOleInit in the InitInstance member function.
2. Call CDocTemplate::SetContainerInfo in InitInstance to assign the menu and accelerator resources used
when an embedded item is activated in-place. For more information on this topic, see Activation.
These features are provided for you automatically when you use the MFC Application Wizard to create a container
application. See Creating an MFC EXE Program.
To prepare your view class
1. Keep track of selected items by maintaining a pointer, or list of pointers if you support multiple selection, to
the selected items. Your OnDraw function must draw all OLE items.
2. Override IsSelected to check whether the item passed to it is currently selected.
3. Implement an OnInsertObject message handler to display the Inser t Object dialog box.
4. Implement an OnSetFocus message handler to transfer focus from the view to an in-place active OLE
embedded item.
5. Implement an OnSize message handler to inform an OLE embedded item that it needs to change its
rectangle to reflect the change in size of its containing view.
Because the implementation of these features varies dramatically from one application to the next, the application
wizard provides only a basic implementation. You will likely have to customize these functions to get your
application to function properly. For an example of this, see the CONTAINER sample.
To handle embedded and linked items
1. Derive a class from COleClientItem. Objects of this class represent items that have been embedded in or
linked to your OLE document.
2. Override OnChange , OnChangeItemPosition , and OnGetItemPosition . These functions handle sizing,
positioning, and modifying embedded and linked items.
The application wizard will derive the class for you, but you will likely need to override OnChange and the other
functions listed with it in step 2 in the preceding procedure. The skeleton implementations need to be customized
for most applications, because these functions are implemented differently from one application to the next. For
examples of this, see the MFC samples DRAWCLI and CONTAINER.
You must add a number of items to the container application's menu structure to support OLE. For more
information on these, see Menus and Resources: Container Additions.
You may also want to support some of the following features in your container application:
In-place activation when editing an embedded item.
For more information, see Activation.
Creation of OLE items by dragging and dropping a selection from a server application.
For more information, see OLE drag and drop.
Links to embedded objects or combination container/server applications.
For more information, see Containers: Advanced Features.
See also
Containers
Containers: Client Items
Containers: Client Items
3/4/2019 • 2 minutes to read • Edit Online
This article explains what client items are and from what classes your application should derive its client items.
Client items are data items belonging to another application that are either contained in or referenced by an OLE
container application's document. Client items whose data is contained within the document are embedded; those
whose data is stored in another location referenced by the container document are linked.
The document class in an OLE application is derived from the class COleDocument rather than from CDocument .
The COleDocument class inherits from CDocument all the functionality necessary for using the document/view
architecture on which MFC applications are based. COleDocument also defines an interface that treats a document
as a collection of CDocItem objects. Several COleDocument member functions are provided for adding, retrieving,
and deleting elements of that collection.
Every container application should derive at least one class from COleClientItem . Objects of this class represent
items, embedded or linked, in the OLE document. These objects exist for the life of the document containing them,
unless they are deleted from the document.
CDocItem is the base class for COleClientItem and COleServerItem . Objects of classes derived from these two act
as intermediaries between the OLE item and the client and server applications, respectively. Each time a new OLE
item is added to the document, the MFC framework adds a new object of your client application's COleClientItem -
derived class to the document's collection of CDocItem objects.
See also
Containers
Containers: Compound Files
Containers: User-Interface Issues
Containers: Advanced Features
COleClientItem Class
COleServerItem Class
Containers: Client-Item Notifications
3/4/2019 • 2 minutes to read • Edit Online
This article discusses the overridable functions that the MFC framework calls when server applications modify
items in your client application's document.
COleClientItem defines several overridable functions that are called in response to requests from the component
application, which is also called the server application. These overridables usually act as notifications. They inform
the container application of various events, such as scrolling, activation, or a change of position, and of changes
that the user makes when editing or otherwise manipulating the item.
The framework notifies your container application of changes through a call to COleClientItem::OnChange , an
overridable function whose implementation is required. This protected function receives two arguments. The first
specifies the reason the server changed the item:
N OT IF IC AT IO N M EA N IN G
OLE_RENAMED The server document containing the OLE item has been
renamed.
OLE_CHANGED_STATE The OLE item has changed from one state to another.
OLE_CHANGED_ASPECT The OLE item's draw aspect has been changed by the
framework.
These values are from the OLE_NOTIFICATION enumeration, which is defined in AFXOLE.H.
The second argument to this function specifies how the item has changed or what state it has entered:
OLE_CHANGED Specifies the aspect of the OLE item that has changed.
For more information about the states a client item can assume, see Containers: Client-Item States.
The framework calls COleClientItem::OnGetItemPosition when an item is being activated for in-place editing.
Implementation is required for applications that support in-place editing. The MFC Application Wizard provides a
basic implementation, which assigns the item's coordinates to the CRect object that is passed as an argument to
OnGetItemPosition .
If an OLE item's position or size changes during in-place editing, the container's information about the item's
position and clipping rectangles must be updated and the server must receive information about the changes. The
framework calls COleClientItem::OnChangeItemPosition for this purpose. The MFC Application Wizard provides an
override that calls the base class's function. You should edit the function that the application wizard writes for your
COleClientItem -derived class so that the function updates any information retained by your client-item object.
See also
Containers
Containers: Client-Item States
COleClientItem::OnChangeItemPosition
Containers: Client-Item States
3/4/2019 • 2 minutes to read • Edit Online
This article explains the different states a client item passes through in its lifetime.
A client item passes through several states as it is created, activated, modified, and saved. Each time the item's
state changes, the framework calls COleClientItem::OnChange with the OLE_CHANGED_STATE notification. The
second parameter is a value from the COleClientItem::ItemState enumeration. It can be one of the following:
COleClientItem::emptyState
COleClientItem::loadedState
COleClientItem::openState
COleClientItem::activeState
COleClientItem::activeUIState
In the empty state, a client item is not yet completely an item. Memory has been allocated for it, but it has not yet
been initialized with the OLE item's data. This is the state a client item is in when it has been created through a call
to new but has not yet undergone the second step of the typical two-step creation.
In the second step, performed through a call to COleClientItem::CreateFromFile or another CreateFrom xxxx
function, the item is completely created. The OLE data (from a file or some other source, such as the Clipboard) has
been associated with the COleClientItem -derived object. Now the item is in the loaded state.
When an item has been opened in the server's window rather than opened in place in the container's document, it
is in the open (or fully open) state. In this state, a cross-hatch usually is drawn over the representation of the item
in the container's window to indicate that the item is active elsewhere.
When an item has been activated in place, it passes, usually only briefly, through the active state. It then enters the
UI active state, in which the server has merged its menus, toolbars, and other user-interface components with
those of the container. The presence of these user-interface components distinguishes the UI active state from the
active state. Otherwise, the active state resembles the UI active state. If the server supports Undo, the server is
required to retain the OLE item's undo-state information until it reaches the loaded or open state.
See also
Containers
Activation
Containers: Client-Item Notifications
Trackers
CRectTracker Class
Containers: Compound Files
3/27/2020 • 3 minutes to read • Edit Online
This article explains the components and implementation of compound files and the advantages and
disadvantages of using compound files in your OLE applications.
Compound files are an integral part of OLE. They are used to facilitate data transfer and OLE document storage.
Compound files are an implementation of the Active structured storage model. Consistent interfaces exist that
support serialization to a storage, a stream, or a file object. Compound files are supported in the Microsoft
Foundation Class Library by the classes COleStreamFile and COleDocument .
NOTE
Using a compound file does not imply that the information comes from an OLE document or a compound document.
Compound files are just one of the ways to store compound documents, OLE documents, and other data.
See also
Containers
Containers: User-Interface Issues
COleStreamFile Class
COleDocument Class
Containers: User-Interface Issues
4/1/2019 • 2 minutes to read • Edit Online
You must add a number of features to a container application's user interface to adequately manage linked and
embedded items. These features involve changes to the menu structure and to the events that the application
handles. For detailed information about them, see the following articles:
F O R IN F O RM AT IO N O N SEE
See also
Containers
Containers: Advanced Features
Menus and Resources (OLE)
Containers: Advanced Features
3/27/2020 • 3 minutes to read • Edit Online
This article describes the steps necessary to incorporate optional advanced features into existing container
applications. These features are:
An application that is both a container and a server
An OLE link to an embedded object
See also
Containers
Servers
Data Objects and Data Sources (OLE)
3/4/2019 • 2 minutes to read • Edit Online
When you perform a data transfer, either by using the Clipboard or drag and drop, the data has a source and a
destination. One application provides the data for copying and another application accepts it for pasting. Each
side of the transfer needs to perform different operations on the same data for the transfer to succeed. The
Microsoft Foundation Class (MFC) Library provides two classes that represent each side of this transfer:
Data sources (as implemented by COleDataSource objects) represent the source side of the data transfer.
They are created by the source application when data is to be copied to the Clipboard, or when data is
provided for a drag-and-drop operation.
Data objects (as implemented by COleDataObject objects) represent the destination side of the data
transfer. They are created when the destination application has data dropped into it, or when it is asked to
perform a paste operation from the Clipboard.
The following articles explain how to use data objects and data sources in your applications. This information
applies to both container and server applications, because both may be called upon to copy and paste data.
Data Objects and Data Sources: Creation and Destruction
Data Objects and Data Sources: Manipulation
In This Section
Drag and Drop
Clipboard
See also
OLE
COleDataObject Class
COleDataSource Class
Data Objects and Data Sources: Creation and
Destruction
3/27/2020 • 3 minutes to read • Edit Online
As explained in the article Data Objects and Data Sources (OLE), data objects and data sources represent both
sides of a data transfer. This article explains when to create and destroy these objects and sources to perform your
data transfers properly, including:
Creating data objects
Destroying data objects
Creating data sources
Destroying data sources
5. The application calls the SetClipboard member function (or the DoDragDrop member function if this is a
drag-and-drop operation) belonging to the object created in step 3.
6. If this is a Cut operation or DoDragDrop returns DROPEFFECT_MOVE , the data selected in step 1 is deleted
from the document.
This scenario is implemented by the MFC OLE samples OCLIENT and HIERSVR. Look at the source for each
application's CView -derived class for all but the GetClipboardData and OnGetClipboardData functions. These two
functions are in either the COleClientItem or COleServerItem -derived class implementations. These sample
programs provide a good example of how to implement these concepts.
One other situation in which you might want to create a COleDataSource object occurs if you are modifying the
default behavior of a drag-and-drop operation. For more information, see the OLE Drag and drop: Customize drag
and drop article.
If you have not handed your data source to OLE, then you are responsible for destroying it, as with any typical
C++ object.
For more information, see Drag and Drop, Clipboard, and Manipulating Data Objects and Data Sources.
See also
Data Objects and Data Sources (OLE)
COleDataObject Class
COleDataSource Class
Data Objects and Data Sources: Manipulation
3/27/2020 • 3 minutes to read • Edit Online
After a data object or data source has been created, you can perform a number of common operations on the
data, such as inserting and removing data, enumerating the formats the data is in, and more. This article
describes the techniques necessary to complete the most common operations. Topics include:
Inserting data into a data source
Determining the formats available in a data object
Retrieving data from a data object
M EDIUM F UN C T IO N TO C A L L
Commonly, the medium will be specified along with its Clipboard format. For example, a
CF_EMBEDDEDSTRUCT object is always in an IStorage medium that requires an STGMEDIUM structure.
Therefore, you would use GetData because it is the only one of these functions that can accept an STGMEDIUM
structure.
For cases where the Clipboard format is in an IStream or HGLOBAL medium, the framework can provide a CFile
pointer that references the data. The application can then use file read to get the data in much the same way as it
might import data from a file. Essentially, this is the client-side interface to the OnRenderData and
OnRenderFileData routines in the data source.
The user can now insert data into the document just like for any other data in the same format.
What do you want to know more about
Drag and drop
Clipboard
See also
Data Objects and Data Sources (OLE)
COleDataObject Class
COleDataSource Class
OLE drag and drop
2/10/2020 • 5 minutes to read • Edit Online
The drag-and-drop feature of OLE is primarily a shortcut for copying and pasting data. When you use the
Clipboard to copy or paste data, a number of steps are required. You select the data, and choose Cut or Copy
from the Edit menu. Then you move to the destination app or window, and place the cursor in the target
location. Finally, you choose Edit > Paste from the menu.
The OLE drag-and-drop feature is different from the File Manager drag-and-drop mechanism. The File Manager
can only handle filenames, and is designed specifically to pass filenames to applications. Drag and drop in OLE
is much more general. It allows you to drag and drop any data that could also be placed on the Clipboard.
When you use OLE drag and drop, you remove two steps from the process. You select the data from the source
window (the "drop source"), then you drag it to the destination (the "drop target"). You drop it by releasing the
mouse button. The operation eliminates the need for menus, and it's quicker than the copy/paste sequence.
There's only one requirement: Both the drop source and drop target must be open, and at least partially visible
on the screen.
Using OLE drag and drop, data can be transferred easily from one location to another: Within a document,
between different documents, or between applications. It may be implemented in either a container or a server
application. Any application could be a drop source, a drop target, or both. If an application implements both
drop-source and drop-target support, you can drag and drop between child windows, or within one window.
This feature makes your application much easier to use.
The Data objects and data sources (OLE) articles explain how to implement data transfer in your applications. It's
also helpful to examine the MFC OLE samples OCLIENT and HIERSVR.
O VERRIDE TO A L LO W
See the MAINVIEW.CPP file that is part of the MFC OLE sample OCLIENT for an example of how these functions
work together.
For more information, see OLE data objects and data sources: Creation and destruction and OLE data objects
and data sources: Manipulation.
OnBeginDrag How the drag operation begins after you call DoDragDrop .
See also
OLE
OLE Data objects and data sources
OLE data objects and data sources: Creation and destruction
OLE data objects and data sources: Manipulation
COleClientItem::DoDragDrop
COleDataSource class
COleDataSource::DoDragDrop
COleDropSource class
COleDropTarget class
CView::OnDragLeave
Menus and Resources (OLE)
3/4/2019 • 2 minutes to read • Edit Online
This group of articles explains the use of menus and resources in MFC OLE document applications.
OLE visual editing places additional requirements on the menu and other resources provided by OLE document
applications because there are a number of modes in which both container and server (component) applications
can be started and used. For example, a full-server application can run in any of these three modes:
Stand alone.
In place, for editing an item within the context of a container.
Open, for editing an item outside the context of its container, often in a separate window.
This requires three separate menu layouts, one for each possible mode of the application. Accelerator tables are
also necessary for each new mode. A container application may or may not support in-place activation; if it does,
it needs a new menu structure and associated accelerator tables.
In-place activation requires that the container and server applications must negotiate for menu, toolbar, and
status bar space. All resources must be designed with this in mind. The article Menus and Resources: Menu
Merging covers this topic in detail.
Because of these issues, OLE document applications created with the application wizard can have up to four
separate menus and accelerator table resources. These are used for the following reasons:
Each of these resource names represents a menu and, usually, an accelerator table. A similar scheme should be
used in MFC applications that are not created with the application wizard.
The following articles discuss topics related to containers, servers, and the menu merging necessary to
implement in-place activation:
Menus and Resources: Container Additions
Menus and Resources: Server Additions
Menus and Resources: Menu Merging
See also
OLE
Menus and Resources: Container Additions
3/27/2020 • 2 minutes to read • Edit Online
This article explains the changes that need to be made to the menus and other resources in a visual editing
container application.
In container applications, two types of changes need to be made: modifications to existing resources to support
OLE visual editing and addition of new resources used for in-place activation. If you use the application wizard to
create your container application, these steps will be done for you, but they may require some customization.
If you do not use the application wizard, you may want to look at OCLIENT.RC, the resource script for the OCLIENT
sample application, to see how these changes are implemented. See the MFC OLE sample OCLIENT.
Topics covered in this article include:
Container Menu Additions
Accelerator Table Additions
String Table Additions
IT EM P URP O SE
Inser t New Object Opens the OLE Insert Object dialog box to insert a linked or
embedded item into the document.
Paste Link Pastes a link to the item on the Clipboard into the document.
OLE Verb Calls the selected item's primary verb. The text of this menu
item changes to reflect the primary verb of the selected item.
Links Opens the OLE Edit Links dialog box to change existing linked
items.
In addition to the changes listed in this article, your source file must include AFXOLECL.RC, which is required for
the Microsoft Foundation Class Library implementation. Insert New Object is the only required menu addition.
Other items can be added, but those listed here are the most common.
You must create a new menu for your container application if you want to support in-place activation of
contained items. This menu consists of the same File menu and Window pop-up menus used when files are open,
but it has two separators placed between them. These separators are used to indicate where the server
(component) item (application) should place its menus when activated in place. For more information on this
menu-merging technique, see Menus and Resources: Menu Merging.
The second change is to create a new accelerator table that corresponds to the new menu resource created for in-
place activation. This table has entries for the File and Window menus in addition to the VK_ESCAPE entry above.
The following example is the accelerator table created for in-place activation in the MFC sample CONTAINER:
ID K EY TYPE
ID ST RIN G
IDP_OLE_INIT_FAILED OLE initialization failed. Make sure that the OLE libraries are
the correct version.
IDP_FAILED_TO_CREATE Failed to create object. Make sure that the object is entered in
the system registry.
See also
Menus and Resources (OLE)
Menus and Resources: Server Additions
Menus and Resources: Server Additions
3/27/2020 • 3 minutes to read • Edit Online
This article explains the changes that need to be made to the menus and other resources in a visual editing server
(component) application. A server application requires many additions to the menu structure and other resources
because it can be started in one of three modes: stand alone, embedded, or in place. As described in the Menus
and Resources (OLE) article, there are a maximum of four sets of menus. All four are used for an MDI full-server
application, while only three are used for a miniserver. The application wizard will create the menu layout
necessary for the type of server you want. Some customization may be necessary.
If you do not use the application wizard, you may want to look at HIERSVR.RC, the resource script for the MFC
sample application HIERSVR, to see how these changes are implemented.
Topics covered in this article include:
Server Menu Additions
Accelerator Table Additions
String Table Additions
Miniserver Additions
ID ST RIN G
IDP_OLE_INIT_FAILED OLE initialization failed. Make sure that the OLE libraries are
the correct version.
Miniserver Additions
The same additions apply for miniservers as those listed above for full-servers. Because a miniserver cannot be
run in stand-alone mode, its main menu is much smaller. The main menu created by the application wizard has
only a File menu, containing only the items Exit and About. Embedded and in-place menus and accelerators for
miniservers are the same as those for full-servers.
See also
Menus and Resources (OLE)
Menus and Resources: Menu Merging
Menus and Resources: Menu Merging
3/27/2020 • 3 minutes to read • Edit Online
This article details the steps necessary for OLE document applications to handle visual editing and in-place
activation properly. In-place activation poses a challenge for both container and server (component) applications.
The user remains in the same frame window (within the context of the container document) but is actually
running another application (the server). This requires coordination between the resources of the container and
server applications.
Topics covered in this article include:
Menu Layouts
Toolbars and Status Bars
Menu Layouts
The first step is to coordinate menu layouts. Container applications should create a new menu to be used only
when embedded items are activated in place. At the minimum, this menu should consist of the following, in the
order listed:
1. File menu identical to the one used when files are open. (Usually no other menu items are placed before
the next item.)
2. Two consecutive separators.
3. Window menu identical to the one used when files are open (only if the container application in an MDI
application). Some applications may have other menus, such as an Options menu, that belong in this
group, which remains on the menu when an embedded item is activated in place.
NOTE
There may be other menus that affect the view of the container document, such as Zoom. These container menus
appear between the two separators in this menu resource.
Server (component) applications should also create a new menu specifically for in-place activation. It should be
like the menu used when files are open, but without menu items, such as File and Window that manipulate the
server document instead of the data. Typically, this menu consists of the following:
1. Edit menu identical to the one used when files are open.
2. Separator.
3. Object editing menus, such as the Pen menu in the Scribble sample application.
4. Separator.
5. Help menu.
For an example, look at the layout of some sample in-place menus for a container and a server. The details of each
menu item have been removed to make the example clearer. The container's in-place menu has the following
entries:
IDR_CONTAINERTYPE_CNTR_IP MENU PRELOAD DISCARDABLE
BEGIN
POPUP "&File C1"
MENUITEM SEPARATOR
POPUP "&Zoom C2"
MENUITEM SEPARATOR
POPUP "&Options C3"
POPUP "&Window C3"
END
The consecutive separators indicate where the first part of the server's menu should go. Now look at the server's
in-place menu:
The separators here indicate where the second group of container menu items should go. The resulting menu
structure when an object from this server is activated in place inside this container looks like this:
BEGIN
POPUP "&File C1"
POPUP "&Edit S1"
POPUP "&Zoom C2"
POPUP "&Format S2"
POPUP "&Options C3
POPUP "&Window C3"
POPUP "&Help S3"
END
As you can see, the separators have been replaced with the different groups of each application's menu.
Accelerator tables associated with the in-place menu should also be supplied by the server application. The
container will incorporate them into its own accelerator tables.
When an embedded item is activated in place, the framework loads the in-place menu. It then asks the server
application for its menu for in-place activation and inserts it where the separators are. This is how the menus
combine. You get menus from the container for operating on the file and window placement, and you get menus
from the server for operating on the item.
See also
Menus and Resources (OLE)
Activation
Servers
Containers
Registration
3/27/2020 • 3 minutes to read • Edit Online
When a user wants to insert an OLE item into an application, OLE presents a list of object types to choose from.
OLE gets this list from the system registration database, which contains information provided by all server
applications. When a server registers itself, the entries it puts into the system registration database (the Registry)
describe each type of object it supplies, file extensions, and the path to itself, among other information.
The framework and the OLE system dynamic-link libraries (DLL) use this registry to determine what types of OLE
items are available on the system. The OLE system DLLs also use this registry to determine how to launch a server
application when a linked or embedded object is activated.
This article describes what each server application needs to do when it is installed and each time it is executed.
For detailed information about the system registration database and the format of the .reg files used to update it,
see the OLE Programmer's Reference.
Server Installation
When you first install your server application, it should register all the types of OLE items that it supports. You can
also have the server update the system registration database every time it executes as a stand-alone application.
This keeps the registration database up-to-date if the server's executable file is moved.
NOTE
MFC applications generated by the application wizard automatically register themselves when they are run as stand-alone
applications.
If you want to register your application during installation, use the RegEdit.exe program. If you include a setup
program with your application, have the setup program run "RegEdit /S appname.reg". (The /S flag indicates silent
operation, that is, it does not display the dialog box reporting successful completion of the command.) Otherwise,
instruct the user to run RegEdit manually.
NOTE
The .reg file created by the application wizard does not include the complete path for the executable. Your installation
program must either modify the .reg file to include the complete path to the executable or modify the PATH environment
variable to include the installation directory.
RegEdit merges t