Sie sind auf Seite 1von 6778

Contents

MFC desktop applications


MFC concepts
MFC concepts
General MFC topics
General MFC topics
Using the MFC source files
MFC library versions
MFC library versions
MFC MBCS DLL add-on
Using the classes to write applications for Windows
Using the classes to write applications for Windows
Framework (MFC)
SDI and MDI
Documents, views, and the framework
Wizards and the resource editors
Building on the framework
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
Sequence of operations for creating database applications
How the framework calls your code
CWinApp: The Application class
CWinApp: The Application class
CWinApp and the MFC Application wizard
Overridable CWinApp member functions
InitInstance member function
Run member function
ExitInstance member function
OnIdle member function
Special CWinApp services
Document templates and the document-view creation process
Document templates and the document-view creation process
Document template creation
Document-view creation
Relationships among MFC objects
Creating new documents, windows, and views
Managing the state data of MFC modules
Managing the state data of MFC modules
Exported DLL function entry points
COM interface entry points
Window procedure entry points
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
Build requirements for Windows Vista common controls
Deprecated ANSI APIs
How to: Add restart manager support
Dynamic layout
Using CObject
Using CObject
Deriving a class from CObject
Deriving a class from CObject
Specifying levels of functionality
Accessing run-time class information
Dynamic object creation
CObject class: Frequently asked questions
CObject class: Frequently asked questions
Do I have to derive new classes from CObject?
What does it cost me to derive a class from CObject?
Collections
Collections
Recommendations for choosing a collection class
Template-based classes
How to: Make a type-safe collection
Accessing all members of a collection
Accessing all members of a collection
Deleting all objects in a CObject collection
Creating stack and queue collections
Exception handling in MFC
Exception handling in MFC
Exceptions: Changes to exception macros in version 3.0
Exceptions: Catching and deleting exceptions
Exceptions: Converting from MFC exception macros
Exceptions: Using MFC macros and C++ exceptions
Exceptions: Examining exception contents
Exceptions: Freeing objects in exceptions
Exceptions: Throwing exceptions from your own functions
Exceptions: Exceptions in constructors
Exceptions: Database exceptions
Exceptions: OLE exceptions
Files in MFC
Files in MFC
Opening files
Reading and writing files
Closing files
Accessing file status
Interface elements
MAPI
MAPI
MAPI support in MFC
MAPI samples
Memory management
Memory management
Memory management: Frame allocation
Memory management: Heap allocation
Memory management: Heap allocation
Memory management: Examples
Memory management: Resizable memory blocks
Message handling and mapping
Message handling and mapping
Messages and commands in the framework
Messages and commands in the framework
Messages
Message handlers
Message categories
Mapping messages
User-interface objects and command IDs
User-interface objects and command IDs
Command IDs
Standard commands
Command targets
How the framework calls a handler
How the framework calls a handler
Message sending and receiving
How noncommand messages reach their handlers
Command routing
Command routing illustration
OnCmdMsg handler
Overriding the standard command routing
How the framework searches message maps
How the framework searches message maps
Where to find message maps
Derived message maps
Declaring message handler functions
Declaring message handler functions
Handlers for standard Windows messages
Handlers for commands and control notifications
Handlers for message-map ranges
Handling reflected messages
How to: Display command information in the status bar
How to: Create a message map for a template class
MFC COM
MFC COM
Active document containment
Active document containment
Example of active document containment: Office binder
Creating an active document container application
Active document containers
Active document containers
Help menu merging
Programmatic printing
Message handling and command targets
Active document servers
Active documents
Automation
Automation
Automation clients
Automation clients
Automation clients: Using type libraries
Automation servers
Automation servers
Automation servers: Object-lifetime issues
Connection points
MFC internet programming basics
MFC internet programming basics
Internet-related MFC classes
Internet information by topic
Internet information by task
Active technology on the internet
WinInet basics
HTML basics
MFC internet programming tasks
MFC internet programming tasks
Application design choices
Writing MFC applications
ActiveX controls on the internet
Upgrading an existing ActiveX control
Asynchronous monikers on the internet
Testing internet applications
Internet security (C++)
OLE in MFC
OLE in MFC
OLE background
OLE background
OLE background: Linking and embedding
OLE background: Containers and servers
OLE background: Implementation strategies
OLE background: MFC implementation
Activation (C++)
Activation (C++)
Activation: Verbs
Containers
Containers
Containers: Implementing a container
Containers: Client items
Containers: Client-item notifications
Containers: Client-item states
Containers: Compound files
Containers: User-interface issues
Containers: Advanced features
Data objects and data sources (OLE)
Data objects and data sources (OLE)
Data objects and data sources: Creation and destruction
Data objects and data sources: Manipulation
OLE drag and drop
Menus and resources (OLE)
Menus and resources (OLE)
Menus and resources: Container additions
Menus and resources: Server additions
Menus and resources: Menu merging
Registration
Servers
Servers
Servers: Implementing a server
Servers: Implementing server documents
Servers: Implementing in-place frame windows
Servers: Server items
Servers: User-interface issues
Trackers
Trackers
Trackers: Implementing trackers in your OLE application
Trackers: Implementing trackers in your OLE application
How to: Implement tracking in your code
Rubber-banding and trackers
Serialization in MFC
Serialization in MFC
Serialization: Making a serializable class
Serialization: Serializing an object
Serialization: Serializing an object
What is a CArchive object
Two ways to create a CArchive object
Using the CArchive << and >> operators
Storing and loading CObjects via an archive
Serialization: Serialization vs. database input-output
Serialization: Serialization vs. database input-output
Recommendations for handling input-output
File menu in an MFC database application
User interface elements (MFC)
User interface elements (MFC)
ActiveX controls
ActiveX controls
MFC ActiveX controls
MFC ActiveX controls
MFC ActiveX controls: Optimization
MFC ActiveX controls: Optimization
Optimizing persistence and initialization
Providing windowless activation
Turning off the activate when visible option
Providing mouse interaction while inactive
Providing flicker-free activation
Using an unclipped device context
Optimizing control drawing
MFC ActiveX controls: Painting an ActiveX control
MFC ActiveX controls: Events
MFC ActiveX controls: Adding stock events to an ActiveX control
MFC ActiveX controls: Adding custom events
MFC ActiveX controls: Methods
MFC ActiveX controls: Adding stock methods
MFC ActiveX controls: Adding custom methods
MFC ActiveX controls: Returning error codes from a method
MFC ActiveX controls: Properties
MFC ActiveX controls: Adding stock properties
MFC ActiveX controls: Adding custom properties
MFC ActiveX controls: Advanced property implementation
MFC ActiveX controls: Accessing ambient properties
MFC ActiveX controls: Property pages
MFC ActiveX controls: Adding another custom property page
MFC ActiveX controls: Using stock property pages
MFC ActiveX controls: Creating an automation server
MFC ActiveX controls: Using fonts
MFC ActiveX controls: Using pictures in an ActiveX control
MFC ActiveX controls: Advanced topics
MFC ActiveX controls: Distributing ActiveX controls
MFC ActiveX controls: Licensing an ActiveX control
MFC ActiveX controls: Localizing an ActiveX control
MFC ActiveX controls: Serializing
MFC ActiveX controls: Subclassing a Windows control
MFC ActiveX controls: Subclassing a Windows control
Reflected window message IDs
MFC ActiveX controls: Using data binding in an ActiveX control
ActiveX control containers
ActiveX control containers
Containers for ActiveX controls
ActiveX control containers: Manually enabling ActiveX control containment
ActiveX control containers: Inserting a control into a control container application
ActiveX control containers: Connecting an ActiveX control to a member variable
ActiveX control containers: Handling events from an ActiveX control
ActiveX control containers: Viewing and modifying control properties
ActiveX control containers: Programming ActiveX controls in an ActiveX control
container
ActiveX control containers: Using controls in a non-dialog container
Testing properties and events with Test Container
Clipboard
Clipboard
Clipboard: When to use each clipboard mechanism
Clipboard: Using the Windows clipboard
Clipboard: Using the OLE clipboard mechanism
Clipboard: Using the OLE clipboard mechanism
Clipboard: Copying and pasting data
Clipboard: Adding other formats
Controls (MFC)
Controls (MFC)
Common control sample list
Making and using controls
Making and using controls
Using common controls in a dialog box
Using the Dialog editor to add controls
Adding controls by hand
Deriving controls from a standard control
Using a common control as a child window
Receiving notification from common controls
Using CAnimateCtrl
Using CAnimateCtrl
Using an animation control
Notifications sent by animation controls
Using CDateTimeCtrl
Using CDateTimeCtrl
Creating the Date and Time Picker control
Date and Time Picker control examples
Accessing the embedded Month calendar control
Using custom format strings in a Date and Time Picker control
Using callback fields in a Date and Time Picker control
Processing notification messages in Date and Time Picker controls
Using CComboBoxEx
Using CComboBoxEx
Creating an extended combo box control
Using image lists in an extended combo box control
Setting the images for an individual item
Processing notification messages in extended combo box controls
Using CHeaderCtrl
Using CHeaderCtrl
Header control and list control
Header control examples
Header items in a header control
Customizing the header item's appearance
Providing drag-and-drop support for header items
Using image lists with header controls
Making owner-drawn header controls
Working with a header control
Creating the header control
Adding items to the header control
Ordering items in the header control
Processing header-control notifications
Using CHotKeyCtrl
Using CHotKeyCtrl
Using a hot key control
Setting a hot key
Global hot keys
Thread-specific hot keys
Using CImageList
Using CImageList
Types of image lists
Using an image list
Manipulating image lists
Drawing images from an image list
Image overlays in image lists
Dragging images from an image list
Image information in image lists
Using CListCtrl
Using CListCtrl
List control and list view
List items and image lists
Callback items and the callback mask
Creating the list control
Creating the image lists
Adding columns to the control (Report view)
Adding items to the control
Scrolling, arranging, sorting, and finding in list controls
Implementing working areas in list controls
Processing notification messages in list controls
Changing list control styles
Virtual list controls
Destroying the list control
Using CMonthCalCtrl
Using CMonthCalCtrl
Creating the Month calendar control
Month calendar control examples
Processing notification messages in Month calendar controls
Setting the Day state of a Month calendar control
Using CProgressCtrl
Using CProgressCtrl
Styles for the progress control
Settings for the progress control
Manipulating the progress control
Using CReBarCtrl
Using CReBarCtrl
CReBar vs. CReBarCtrl
Creating a rebar control
Rebar controls and bands
Using an image list with a rebar control
Using a dialog bar with a rebar control
Processing notification messages in a rebar control
Using CRichEditCtrl
Using CRichEditCtrl
Overview of the Rich Edit control
Classes related to Rich Edit controls
Rich Edit control examples
Character formatting in Rich Edit controls
Paragraph formatting in Rich Edit controls
Current selection in a Rich Edit control
Word breaks in Rich Edit controls
Clipboard operations in Rich Edit controls
Stream operations in Rich Edit controls
Printing in Rich Edit controls
Bottomless Rich Edit controls
Notifications from a Rich Edit control
Using CSliderCtrl
Using CSliderCtrl
Using slider controls
Slider control styles
Slider control member functions
Slider notification messages
Using CSpinButtonCtrl
Using CSpinButtonCtrl
Spin button styles
Spin button member functions
Using CStatusBarCtrl
Using CStatusBarCtrl
Methods of creating a status bar
Settings for the CStatusBarCtrl
Using CStatusBarCtrl to create a CStatusBarCtrl object
Setting the mode of a CStatusBarCtrl object
Initializing the parts of a CStatusBarCtrl object
Using tooltips in a CStatusBarCtrl object
Using CTabCtrl
Using CTabCtrl
Tab controls and property sheets
Tabs and tab control attributes
Making owner-drawn tabs
Working with a tab control
Creating the tab control
Adding tabs to a tab control
Processing tab control notification messages
Using CToolBarCtrl
Using CToolBarCtrl
Methods of creating a toolbar
Settings for the toolbar control
Creating a CToolBarCtrl object
Using image lists in a toolbar control
Using drop-down buttons in a toolbar control
Customizing the appearance of a toolbar control
Handling tool tip notifications
Handling customization notifications
Using CToolTipCtrl
Using CToolTipCtrl
Methods of creating tool tips
Settings for the tool tip control
Using CToolTipCtrl to create and manipulate a CToolTipCtrl object
Manipulating the tool tip control
Using CTreeCtrl
Using CTreeCtrl
CTreeCtrl vs. CTreeView
Using tree controls
Communicating with a tree control
Tree control styles
Tree control parent and child items
Tree control item position
Tree control item labels
Tree control label editing
Tree control item states overview
Tree control image lists
Tree control item selection
Tree control drag-and-drop operations
Tree control item information
Tree control notification messages
Control bars
Dialog bars
Dialog boxes
Dialog boxes
Example: Displaying a dialog box via a menu command
Dialog sample list
Dialog-box components in the framework
Modal and modeless dialog boxes
Property sheets and property pages (MFC)
Creating the dialog resource
Creating a dialog class with code wizards
Creating a dialog class with code wizards
Creating your dialog class
Life cycle of a dialog box
Working with Dialog Boxes in MFC
Creating and displaying dialog boxes
Creating modal dialog boxes
Creating modeless dialog boxes
Using a dialog template in memory
Setting the dialog box’s background color
Initializing the dialog box
Handling Windows messages in your dialog box
Retrieving data from the dialog object
Closing the dialog box
Destroying the dialog box
Dialog Data Exchange and validation
Dialog Data Exchange and validation
Dialog Data Exchange
Dialog data validation
Type-safe access to controls in a dialog box
Type-safe access to controls in a dialog box
Type-safe access to controls without code wizards
Type-safe access to controls with code wizards
Mapping Windows messages to your class
Commonly overridden member functions
Commonly added member functions
Common dialog classes
Dialog boxes in OLE
Walkthrough: Adding a CTaskDialog to an application
Document-view architecture
Document-view architecture
Document-view sample list
A portrait of the document-view architecture
Advantages of the document-view architecture
Document and view classes created by the MFC application wizard
Alternatives to the document-view architecture
Using documents
Using documents
Deriving a document class from CDocument
Managing data with document data variables
Serializing data to and from files
Bypassing the serialization mechanism
Handling commands in the document
Using views
Using views
Derived view classes available in MFC
Drawing in a view
Interpreting user input through a view
Role of the view in printing
Scrolling and scaling views
Multiple document types, views, and frame windows
Initializing and cleaning up documents and views
Initializing and cleaning up documents and views
Initializing documents and views
Cleaning up documents and views
Adding multiple views to a single document
Form views (MFC)
Form views (MFC)
Inserting a form into a project
HTML Help: Context-sensitive help for your programs
MDI tabbed groups
Menus (MFC)
Menus (MFC)
Menu sample list
Manipulating menus during program execution
How to: Update user-interface objects
How to: Update user-interface objects
When update handlers are called
ON_UPDATE_COMMAND_UI macro
The CCmdUI class
OLE (MFC)
Printing and print preview
Printing and print preview
Printing
Printing
How default printing is done
Multipage documents
Headers and footers
Allocating GDI resources
Print preview architecture
Property sheets (MFC)
Property sheets (MFC)
Property sheets and property pages in MFC
Using property sheets in your application
Adding controls to a property sheet
Exchanging data
Creating a modeless property sheet
Handling the Apply button
Property sheets as wizards
Ribbon designer (MFC)
Ribbon designer (MFC)
How to: Convert an existing MFC ribbon to a ribbon resource
How to: Customize the application button
How to: Customize the Quick Access toolbar
How to: Add ribbon controls and event handlers
How to: Load a ribbon resource from an MFC application
Walkthrough: Creating a ribbon application by using MFC
Walkthrough: Updating the MFC Scribble application (Part 1)
Walkthrough: Updating the MFC Scribble application (Part 2)
Status bars
Status bars
Status bar implementation in MFC
Status bar implementation in MFC
Updating the text of a status-bar pane
Tool tips
Tool tips
Tool tips in windows not derived from CFrameWnd
Tool tips in windows not derived from CFrameWnd
Enabling tool tips
Handling TTN_NEEDTEXT notification for tool tips
TOOLTIPTEXT structure
Toolbars
Toolbars
Toolbar sample list
MFC toolbar implementation
MFC toolbar implementation
Toolbar fundamentals
Docking and floating toolbars
Toolbar tool tips
Working with the toolbar control
Using your old toolbars
Visualization manager
Windows
Windows
Window objects
Window objects
Relationship between a C++ window object and an HWND
Derived window classes
Creating windows
Creating windows
Registering window classes
General window creation sequence
Destroying window objects
Destroying window objects
Window destruction sequence
Allocating and deallocating window memory
Detaching a CWnd from its HWND
Working with window objects
Device contexts
Graphic objects
Graphic objects
One-stage and two-stage construction of objects
Selecting a graphic object into a device context
Frame windows
Frame windows
Frame-window classes
Frame-window classes
Frame-window classes created by the application wizard
Frame-window styles (C++)
Frame-window styles (C++)
Changing the styles of a window created by MFC
What frame windows do
Using frame windows
Using frame windows
Creating document frame windows
When to initialize CWnd objects
Destroying frame windows
Managing MDI child windows
Managing the current view
Managing menus, control bars, and accelerators
Dragging and dropping files in a frame window
Responding to Dynamic Data Exchange (DDE)
Orchestrating other window actions
Windows Sockets
Windows Sockets
Windows Sockets in MFC
Windows Sockets in MFC
Windows Sockets: Background
Windows Sockets: Stream sockets
Windows Sockets: Datagram sockets
Windows Sockets: Using sockets with archives
Windows Sockets: Sequence of operations
Windows Sockets: Example of sockets using archives
Windows Sockets: How sockets with archives work
Windows Sockets: Using class CAsyncSocket
Windows Sockets: Deriving from socket classes
Windows Sockets: Socket notifications
Windows Sockets: Blocking
Windows Sockets: Byte ordering
Windows Sockets: Converting strings
Windows Sockets: Ports and socket addresses
Win32 internet extensions (WinInet)
Win32 internet extensions (WinInet)
How WinInet makes it easier to create internet client applications
How MFC makes it easier to create internet client applications
MFC classes for creating internet client applications
Prerequisites for internet client classes
Writing an internet client application using MFC WinInet classes
Steps in a typical internet client application
Steps in a typical FTP client application
Steps in a typical FTP client application to delete a file
Steps in a typical Gopher client application
Steps in a typical HTTP client application
Hierarchy chart
Hierarchy chart
Hierarchy chart categories
Customization for MFC
Customization for MFC
Keyboard and mouse customization
User-defined tools
Security implications of customization
MFC Technical Notes
MFC Technical Notes
Technical Notes by category
Technical Notes by number
TN001: Window class registration
TN002: Persistent object data format
TN003: Mapping of Windows handles to objects
TN006: Message maps
TN011: Using MFC as part of a DLL
TN014: Custom controls
TN016: Using C++ multiple inheritance with MFC
TN017: Destroying window objects
TN020: ID naming and numbering conventions
TN021: Command and message routing
TN022: Standard commands implementation
TN023: Standard MFC resources
TN024: MFC-defined messages and resources
TN025: Document, view, and frame creation
TN026: DDX and DDV routines
TN028: Context-sensitive help support
TN029: Splitter windows
TN030: Customizing printing and print preview
TN031: Control bars
TN032: MFC exception mechanism
TN033: DLL version of MFC
TN035: Using multiple resource files and header files with Visual C++
TN036: Using CFormView with AppWizard and ClassWizard
TN037: Multithreaded MFC 2.1 applications
TN038: MFC-OLE IUnknown implementation
TN039: MFC-OLE automation implementation
TN040: MFC-OLE in-place resizing and zooming
TN041: MFC-OLE1 migration to MFC-OLE 2
TN042: ODBC driver developer recommendations
TN043: RFX routines
TN044: MFC support for DBCS
TN045: MFC-database support for long varchar-varbinary
TN046: Commenting conventions for the MFC classes
TN047: Relaxing database transaction requirements
TN048: Writing ODBC setup and administration programs for MFC database
applications
TN049: MFC-OLE MBCS to Unicode translation layer (MFCANS32)
TN050: MFC-OLE common dialogs (MFCUIx32)
TN051: Using CTL3D now and in the future
TN053: Custom DFX routines for DAO database classes
TN054: Calling DAO directly while using MFC DAO classes
TN055: Migrating MFC ODBC database class applications to MFC DAO classes
TN056: Installation of localized MFC components
TN057: Localization of MFC components
TN058: MFC module state implementation
TN059: Using MFC MBCS-Unicode conversion macros
TN060: The new Windows common controls
TN061: ON_NOTIFY and WM_NOTIFY messages
TN062: Message reflection for Windows controls
TN063: Debugging internet MFC extension DLLs
TN064: Apartment-model threading in ActiveX controls
TN065: Dual-interface support for OLE automation servers
TN066: Common MFC 3.x to 4.0 porting issues
TN068: Performing transactions with the Microsoft access 7 ODBC driver
TN070: MFC window class names
TN071: MFC IOleCommandTarget implementation
Class library overview
Class library overview
General class design philosophy
General class design philosophy
Application framework
Relationship to the C-language API
Root class: CObject
MFC application architecture classes
MFC application architecture classes
Application and thread support classes
Command routing classes
Document classes
View classes (Architecture)
Frame window classes (Architecture)
Document-template classes
Window, dialog, and control classes
Window, dialog, and control classes
Frame window classes (Windows)
View classes (Windows)
Dialog box classes
Control classes
Control bar classes
Drawing and printing classes
Drawing and printing classes
Output (Device context) classes
Drawing tool classes
Simple data type classes
Array, list, and map classes
Array, list, and map classes
Template classes for arrays, lists, and maps
Ready-to-use array classes
Ready-to-use list classes
Ready-to-use map classes
File and database classes
File and database classes
File I-O classes
OLE DB classes
DAO classes
ODBC classes
Internet and networking classes
Internet and networking classes
Windows Sockets classes
Win32 internet classes
OLE classes
OLE classes
OLE container classes
OLE server classes
OLE drag-and-drop and data transfer classes
OLE common dialog classes
OLE automation classes
OLE control classes
Active document classes
OLE-related classes
Debugging and exception classes
Debugging and exception classes
Debugging support classes
Exception classes
Walkthroughs (MFC)
Walkthroughs (MFC)
Walkthrough: Using the new MFC shell controls
Walkthrough: Putting controls on toolbars
Walkthrough: Adding a D2D object to an MFC project
Walkthrough: Adding animation to an MFC project
MFC API Reference
MFC classes
MFC classes
CAccelerateDecelerateTransition class
CAnimateCtrl class
CAnimationBaseObject class
CAnimationColor class
CAnimationController class
CAnimationGroup class
CAnimationManagerEventHandler class
CAnimationPoint class
CAnimationRect class
CAnimationSize class
CAnimationStoryboardEventHandler class
CAnimationTimerEventHandler class
CAnimationValue class
CAnimationVariable class
CAnimationVariableChangeHandler class
CAnimationVariableIntegerChangeHandler class
CArchive class
CArchiveException class
CArray class
CAsyncMonikerFile class
CAsyncSocket class
CAutoHideDockSite class
CBaseKeyFrame class
CBasePane class
CBaseTabbedPane class
CBaseTransition class
CBitmap class
CBitmapButton class
CBitmapRenderTarget class
CBrush class
CButton class
CByteArray class
CCachedDataPathProperty class
CCheckListBox class
CClientDC class
CCmdTarget class
CCmdUI class
CColorDialog class
CComboBox class
CComboBoxEx class
CCommandLineInfo class
CCommonDialog class
CConnectionPoint class
CConstantTransition class
CContextMenuManager class
CControlBar class
CCreateContext structure
CCriticalSection class
CCtrlView class
CCubicTransition class
CCustomInterpolator class
CCustomTransition class
CD2DBitmap class
CD2DBitmapBrush class
CD2DBrush class
CD2DBrushProperties class
CD2DEllipse class
CD2DGeometry class
CD2DGeometrySink class
CD2DGradientBrush class
CD2DLayer class
CD2DLinearGradientBrush class
CD2DMesh class
CD2DPathGeometry class
CD2DPointF class
CD2DPointU class
CD2DRadialGradientBrush class
CD2DRectF class
CD2DRectU class
CD2DResource class
CD2DRoundedRect class
CD2DSizeF class
CD2DSizeU class
CD2DSolidColorBrush class
CD2DTextFormat class
CD2DTextLayout class
CDaoDatabase class
CDaoException class
CDaoFieldExchange class
CDaoQueryDef class
CDaoRecordset class
CDaoRecordView class
CDaoTableDef class
CDaoWorkspace class
CDatabase class
CDataExchange class
CDataPathProperty class
CDataRecoveryHandler class
CDateTimeCtrl class
CDBException class
CDBVariant class
CDC class
CDCRenderTarget class
CDHtmlDialog class
CDHtmlDialog class
DDX_DHtml helper macros
CDialog class
CDialogBar class
CDialogEx class
CDiscreteTransition class
CDocItem class
CDockablePane class
CDockablePaneAdapter class
CDockingManager class
CDockingPanesRow class
CDockSite class
CDockState class
CDocObjectServer class
CDocObjectServerItem class
CDocTemplate class
CDocument class
CDragListBox class
CDrawingManager class
CDumpContext class
CDWordArray class
CEdit class
CEditView class
CEvent class
CException class
CFieldExchange class
CFile class
CFileDialog class
CFileException class
CFileFind class
CFindReplaceDialog class
CFolderPickerDialog class
CFont class
CFontDialog class
CFontHolder class
CFormView class
CFrameWnd class
CFrameWndEx class
CFtpConnection class
CFtpFileFind class
CGdiObject class
CGlobalUtils class
CGopherConnection class
CGopherFile class
CGopherFileFind class
CGopherLocator class
CHeaderCtrl class
CHotKeyCtrl class
CHtmlEditCtrl class
CHtmlEditCtrlBase class
CHtmlEditDoc class
CHtmlEditView class
CHtmlView class
CHttpConnection class
CHttpFile class
CHwndRenderTarget class
CImageList class
CInstantaneousTransition class
CInternetConnection class
CInternetException class
CInternetFile class
CInternetSession class
CInterpolatorBase class
CInvalidArgException class
CIPAddressCtrl class
CJumpList class
CKeyboardManager class
CKeyFrame class
CLinearTransition class
CLinearTransitionFromSpeed class
CLinkCtrl class
CList class
CListBox class
CListCtrl class
CListView class
CLongBinary class
CMap class
CMapPtrToPtr class
CMapPtrToWord class
CMapStringToOb class
CMapStringToPtr class
CMapStringToString class
CMapWordToOb class
CMapWordToPtr class
CMDIChildWnd class
CMDIChildWndEx class
CMDIFrameWnd class
CMDIFrameWndEx class
CMDITabInfo class
CMemFile class
CMemoryException class
CMemoryState structure
CMenu class
CMenuTearOffManager class
CMetaFileDC class
CMFCAcceleratorKey class
CMFCAcceleratorKeyAssignCtrl class
CMFCAutoHideBar class
CMFCAutoHideButton class
CMFCBaseTabCtrl class
CMFCBaseToolBar class
CMFCBaseVisualManager class
CMFCButton class
CMFCCaptionBar class
CMFCCaptionButton class
CMFCCmdUsageCount class
CMFCColorBar class
CMFCColorButton class
CMFCColorDialog class
CMFCColorMenuButton class
CMFCColorPickerCtrl class
CMFCColorPopupMenu class
CMFCCustomColorsPropertyPage class
CMFCDesktopAlertDialog class
CMFCDesktopAlertWnd class
CMFCDesktopAlertWndButton class
CMFCDesktopAlertWndInfo class
CMFCDisableMenuAnimation class
CMFCDragFrameImpl class
CMFCDropDownFrame class
CMFCDropDownToolBar class
CMFCDropDownToolbarButton class
CMFCDynamicLayout class
CMFCEditBrowseCtrl class
CMFCFilterChunkValueImpl class
CMFCFontComboBox class
CMFCFontInfo class
CMFCHeaderCtrl class
CMFCImageEditorDialog class
CMFCImageEditorPaletteBar class
CMFCImagePaintArea class
CMFCKeyMapDialog class
CMFCLinkCtrl class
CMFCListCtrl class
CMFCMaskedEdit class
CMFCMenuBar class
CMFCMenuButton class
CMFCOutlookBar class
CMFCOutlookBarPane class
CMFCOutlookBarTabCtrl class
CMFCPopupMenu class
CMFCPopupMenuBar class
CMFCPreviewCtrlImpl class
CMFCPrintPreviewToolBar class
CMFCPropertyGridColorProperty class
CMFCPropertyGridCtrl class
CMFCPropertyGridFileProperty class
CMFCPropertyGridFontProperty class
CMFCPropertyGridProperty class
CMFCPropertyGridToolTipCtrl class
CMFCPropertyPage class
CMFCPropertySheet class
CMFCReBar class
CMFCRibbonApplicationButton class
CMFCRibbonBar class
CMFCRibbonBaseElement class
CMFCRibbonButton class
CMFCRibbonButtonsGroup class
CMFCRibbonCategory class
CMFCRibbonCheckBox class
CMFCRibbonColorButton class
CMFCRibbonComboBox class
CMFCRibbonContextCaption class
CMFCRibbonCustomizeDialog class
CMFCRibbonCustomizePropertyPage class
CMFCRibbonEdit class
CMFCRibbonFontComboBox class
CMFCRibbonGallery class
CMFCRibbonGalleryMenuButton class
CMFCRibbonLabel class
CMFCRibbonLinkCtrl class
CMFCRibbonMainPanel class
CMFCRibbonMiniToolBar class
CMFCRibbonPanel class
CMFCRibbonProgressBar class
CMFCRibbonQuickAccessToolBarDefaultState class
CMFCRibbonSeparator class
CMFCRibbonSlider class
CMFCRibbonStatusBar class
CMFCRibbonStatusBarPane class
CMFCRibbonUndoButton class
CMFCShellListCtrl class
CMFCShellTreeCtrl class
CMFCSpinButtonCtrl class
CMFCStandardColorsPropertyPage class
CMFCStatusBar class
CMFCTabCtrl class
CMFCTabDropTarget class
CMFCTabToolTipInfo structure
CMFCTasksPane class
CMFCTasksPaneTask class
CMFCTasksPaneTaskGroup class
CMFCToolBar class
CMFCToolBarButton class
CMFCToolBarComboBoxButton class
CMFCToolBarComboBoxEdit class
CMFCToolBarDateTimeCtrl class
CMFCToolBarEditBoxButton class
CMFCToolBarFontComboBox class
CMFCToolBarFontSizeComboBox class
CMFCToolBarImages class
CMFCToolBarMenuButton class
CMFCToolBarInfo class
CMFCToolBarsCustomizeDialog class
CMFCToolTipCtrl class
CMFCToolTipInfo class
CMFCVisualManager class
CMFCVisualManagerOffice2003 class
CMFCVisualManagerOffice2007 class
CMFCVisualManagerOfficeXP class
CMFCVisualManagerVS2005 class
CMFCVisualManagerWindows class
CMFCVisualManagerWindows7 class
CMFCWindowsManagerDialog class
CMiniFrameWnd class
CMonikerFile class
CMonthCalCtrl class
CMouseManager class
CMultiDocTemplate class
CMultiLock class
CMultiPageDHtmlDialog class
CMultiPaneFrameWnd class
CMutex class
CNetAddressCtrl class
CNotSupportedException class
CObArray class
CObject class
CObList class
COccManager class
COleBusyDialog class
COleChangeIconDialog class
COleChangeSourceDialog class
COleClientItem class
COleCmdUI class
COleControl class
COleControlContainer class
COleControlModule class
COleControlSite class
COleConvertDialog class
COleCurrency class
COleDataObject class
COleDataSource class
COleDBRecordView class
COleDialog class
COleDispatchDriver class
COleDispatchException class
COleDocObjectItem class
COleDocument class
COleDropSource class
COleDropTarget class
COleException class
COleInsertDialog class
COleIPFrameWnd class
COleIPFrameWndEx class
COleLinkingDoc class
COleLinksDialog class
COleMessageFilter class
COleObjectFactory class
COlePasteSpecialDialog class
COlePropertiesDialog class
COlePropertyPage class
COleResizeBar class
COleSafeArray class
COleServerDoc class
COleServerItem class
COleStreamFile class
COleTemplateServer class
COleUpdateDialog class
COleVariant class
CPagerCtrl class
CPageSetupDialog class
CPaintDC class
CPalette class
CPane class
CPaneContainer class
CPaneContainerManager class
CPaneDialog class
CPaneDivider class
CPaneFrameWnd class
CParabolicTransitionFromAcceleration class
CPen class
CPictureHolder class
CPrintDialog class
CPrintDialogEx class
CPrintInfo structure
CProgressCtrl class
CPropertyPage class
CPropertySheet class
CPropExchange class
CPtrArray class
CPtrList class
CReBar class
CReBarCtrl class
CRecentDockSiteInfo class
CRecentFileList class
CRecordset class
CRecordView class
CRectTracker class
CRenderTarget class
CResourceException class
CReversalTransition class
CRgn class
CRichEditCntrItem class
CRichEditCtrl class
CRichEditDoc class
CRichEditView class
CRuntimeClass structure
CScrollBar class
CScrollView class
CSemaphore class
CSettingsStore class
CSettingsStoreSP class
CSharedFile class
CShellManager class
CSimpleException class
CSingleDocTemplate class
CSingleLock class
CSinusoidalTransitionFromRange class
CSinusoidalTransitionFromVelocity class
CSliderCtrl class
CSmartDockingInfo class
CSmoothStopTransition class
CSocket class
CSocketFile class
CSpinButtonCtrl class
CSplitButton class
CSplitterWnd class
CSplitterWndEx class
CStatic class
CStatusBar class
CStatusBarCtrl class
CStdioFile class
CStringArray class
CStringList class
CSyncObject class
CTabCtrl class
CTabbedPane class
CTabView class
CTaskDialog class
CToolBar class
CToolBarCtrl class
CToolTipCtrl class
CTooltipManager class
CTreeCtrl class
CTreeView class
CTypedPtrArray class
CTypedPtrList class
CTypedPtrMap class
CUIntArray class
CUserException class
CUserTool class
CUserToolsManager class
CView class
CVSListBox class
CWaitCursor class
CWinApp class
CWinAppEx class
CWindowDC class
CWinFormsControl class
CWinFormsDialog class
CWinFormsView class
CWinThread class
CWnd class
CWordArray class
ICommandSource interface
ICommandTarget interface
ICommandUI interface
IView interface
Internal classes
MFC macros and globals
MFC macros and globals
Data types (MFC)
Type casting of MFC class objects
Run-time object model services
Diagnostic services
Modules and DLLs
Exception processing
CString formatting and message-box display
Application information and management
Standard command and window IDs
Collection class helpers
Gray and dithered bitmap functions
Record Field Exchange functions
Dialog Data Exchange functions for CRecordView and CDaoRecordView
Dialog Data Exchange functions for OLE controls
Database macros and globals
DAO database engine initialization and termination
OLE initialization
Application control
Dispatch maps
Variant parameter type constants
Type library access
Property pages (MFC)
Event maps
Event sink maps
Connection maps
Registering OLE controls
Class factories and licensing
Persistence of OLE controls
Internet URL parsing globals
DHTML event maps
DHTML editing command maps
Standard Dialog Data Exchange routines
Standard Dialog data validation routines
AFX messages
ToolBar control styles
CMFCImagePaintArea::IMAGE_EDIT_MODE enumeration
UICheckState enumeration
Structures, styles, callbacks, and message maps
Structures, styles, callbacks, and message maps
Structures used by MFC
Structures used by MFC
AFX_EXTENSION_MODULE structure
AFX_GLOBAL_DATA structure
CDaoDatabaseInfo structure
CDaoErrorInfo structure
CDaoFieldInfo structure
CDaoIndexInfo structure
CDaoIndexFieldInfo structure
CDaoParameterInfo structure
CDaoQueryDefInfo structure
CDaoRelationInfo structure
CDaoRelationFieldInfo structure
CDaoTableDefInfo structure
CDaoWorkspaceInfo structure
CODBCFieldInfo structure
DHtmlUrlEventMapEntry structure
HSE_VERSION_INFO structure
Styles used by MFC
Callback functions used by MFC
Message maps (MFC)
Message maps (MFC)
Message map macros (MFC)
Delegate and interface map macros
How to: Use the message-map cross-reference
Child window notification message handlers
Generic control handler
User button handlers
Combo box handlers
Edit control handlers
List box handlers
Handlers for WM_ messages
WM_ message handlers: A - C
WM_ message handlers: D - E
WM_ message handlers: F - K
WM_ message handlers: L - M
WM_ message handlers: N - O
WM_ messages: P - R
WM_ messages: S
WM_ messages: T - Z
User-defined handlers
MFC wizards and dialog boxes
MFC wizards and dialog boxes
Creating an MFC DLL project
Creating an MFC DLL project
MFC DLL wizard
MFC DLL wizard
Application settings, MFC DLL wizard
Classes and functions generated by the MFC DLL wizard
Creating an MFC application
Creating an MFC application
MFC application wizard
MFC application wizard
Application type, MFC application wizard
Compound document support, MFC application wizard
Database support, MFC application wizard
User interface features, MFC application wizard
Advanced features, MFC application wizard
Generated classes, MFC application wizard
Creating a forms-based MFC application
Creating a File Explorer-style MFC application
Creating a web browser-style MFC application
Creating an MFC ActiveX control container
Creating an MFC ActiveX control
Creating an MFC ActiveX control
MFC ActiveX control wizard
MFC ActiveX control wizard
Application settings, MFC ActiveX control wizard
Control names, MFC ActiveX control wizard
Control settings, MFC ActiveX control wizard
Adding an MFC class
Adding an MFC class
MFC Add class wizard
MFC Add class wizard
Adding an MFC class from a type library
Adding an MFC class from a type library
Add class from typelib wizard
Adding an MFC message handler
Adding an MFC message handler
Mapping messages to functions
Mapping messages to functions
Message types associated with user-interface objects
Editing a message handler
Defining a message handler for a reflected message
Declaring a variable based on your new control class
Adding an MFC ODBC consumer
Adding an MFC ODBC consumer
MFC ODBC consumer wizard
Adding ATL support to your MFC project
Adding ATL support to your MFC project
Details of ATL support added by the ATL wizard
MFC class wizard
MFC Desktop Applications
3/30/2020 • 2 minutes to read • Edit Online

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

An example of the comments


The following partial listing of class CStdioFile uses most of the standard comments that MFC employs in its
classes to divide class members by the ways they're used:
/*============================================================================*/
// STDIO file implementation

class CStdioFile : public CFile


{
DECLARE_DYNAMIC(CStdioFile)

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 .

As with attributes, operations can be further subdivided.

// 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.

Automatic linking of MFC library versions


The MFC header files automatically determine the correct version of the MFC library to link, based on values
defined in your build environment. The MFC header files add compiler directives instructing the linker to link in a
specific version of the MFC library.
For example, the AFX.H header file instructs the linker to link in the full static, limited static, or shared DLL version
of MFC; ANSI/MBCS or Unicode version; and debug or retail version, depending on your build configuration:
#ifndef _AFXDLL
#ifdef _AFX_NO_MFC_CONTROLS_IN_DIALOGS
#ifdef _DEBUG
#pragma comment(lib, "afxnmcdd.lib")
#else
#pragma comment(lib, "afxnmcd.lib")
#endif
#pragma comment(linker, "/include:__afxNoMFCControlSupportInDialogs")
#pragma comment(linker, "/include:__afxNoMFCControlContainerInDialogs")
#endif
#ifndef _UNICODE
#ifdef _DEBUG
#pragma comment(lib, "nafxcwd.lib")
#else
#pragma comment(lib, "nafxcw.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "uafxcwd.lib")
#else
#pragma comment(lib, "uafxcw.lib")
#endif
#endif
#else
#ifndef _UNICODE
#ifdef _DEBUG
#pragma comment(lib, "mfc" _MFC_FILENAME_VER "d.lib")
#pragma comment(lib, "mfcs" _MFC_FILENAME_VER "d.lib")
#else
#pragma comment(lib, "mfc" _MFC_FILENAME_VER ".lib")
#pragma comment(lib, "mfcs" _MFC_FILENAME_VER ".lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "mfc" _MFC_FILENAME_VER "ud.lib")
#pragma comment(lib, "mfcs" _MFC_FILENAME_VER "ud.lib")
#else
#pragma comment(lib, "mfc" _MFC_FILENAME_VER "u.lib")
#pragma comment(lib, "mfcs" _MFC_FILENAME_VER "u.lib")
#endif
#endif
#endif

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.

ANSI, MBCS, and Unicode


The MFC ANSI/MBCS library versions support both single-byte character sets such as ASCII, and multibyte
character sets such as Shift-JIS. The MFC Unicode library versions support Unicode in its UTF-16LE wide-character
encoded form. Use the ANSI/MBCS library versions of MFC for UTF-8 encoded Unicode support.
To set your project configuration to use single-byte, multibyte, or wide-character Unicode string and character
support in the IDE, use the Project Proper ties dialog. In the Configuration Proper ties > General page, set the
Character Set property to Not Set to use a single-byte character set. Set the property to Use Multi-Byte
Character Set to use a multibyte character set, or to Use Unicode Character Set to use Unicode encoded as
UTF-16.
MFC projects use the preprocessor symbol _UNICODE to indicate UTF-16 wide-character Unicode support, and
_MBCS to indicate MBCS support. These options are mutually exclusive in a project.

MFC static library naming conventions


Static libraries for MFC use the following naming conventions. The library names have the form

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

u ANSI/MBCS (N) or Unicode (U); omit for version without MFC


controls in dialogs

c Version with MFC controls in dialogs (CW) or without (NMCD)

d Debug or Release: D=Debug; omit specifier for Release

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

NAFXCW.LIB MFC Static-Link Library, Release version

NAFXCWD.LIB MFC Static-Link Library, Debug version

UAFXCW.LIB MFC Static-Link Library with Unicode support, Release version

UAFXCWD.LIB MFC Static-Link Library with Unicode support, Debug version

AFXNMCD.LIB MFC Static-Link Library without MFC dialog controls, Release


version

AFXNMCDD.LIB MFC Static-Link Library without MFC dialog controls, Debug


version

Debugger files that have the same base name and a .pdb extension are also available for each of the static libraries.

MFC shared DLL naming conventions


The MFC shared DLLs also follow a structured naming convention. This makes it easier to know which DLL or
library you should be using for which purpose.
The MFC DLLs have version numbers that indicate binary compatibility. Use MFC DLLs that have the same version
as your other libraries and compiler toolset to guarantee compatibility within a project.

DL L DESC RIP T IO N

MFCversion.DLL MFC DLL, ANSI or MBCS Release version

MFCversionU.DLL MFC DLL, Unicode Release version

MFCversionD.DLL MFC DLL, ANSI or MBCS Debug version

MFCversionUD.DLL MFC DLL, Unicode Debug version


DL L DESC RIP T IO N

MFCMversion.DLL MFC DLL with Windows Forms controls, ANSI or MBCS


Release version

MFCMversionU.DLL MFC DLL with Windows Forms controls, Unicode Release


version

MFCMversionD.DLL MFC DLL with Windows Forms controls, ANSI or MBCS Debug
version

MFCMversionUD.DLL MFC DLL with Windows Forms controls, Unicode 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.

Dynamic-link library support


You can use either the static or shared dynamic MFC libraries to create DLLs that can be used by both MFC and
non-MFC executables. These are called "regular DLLs" or "regular MFC DLLs", to distinguish them from MFC
extension DLLs that can only be used by MFC apps and MFC DLLs. A DLL built by using the MFC static libraries is
sometimes called a USRDLL in older references, because MFC DLL projects define the preprocessor symbol
_USRDLL . A DLL that uses the MFC shared DLLs is sometimes called an AFXDLL in older references, because it
defines the preprocessor symbol _AFXDLL .
When you create your DLL project by linking to the MFC static libraries, your DLL can be deployed without the MFC
shared DLLs. When your DLL project links to the import libraries MFCversion.LIB or MFCversionU.LIB, you must
deploy the matching MFC shared DLL MFCversion.DLL or MFCversionU.DLL together with your DLL. For more
information, see DLLs.

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.

For more information, see Documents, Views, and the Framework.

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.

Objects in a Running SDI Application


The rest of this family of articles explains how the framework tools, the MFC Application Wizard, and the resource
editors, create these objects, how they work together, and how you use them in your programming. Documents,
views, and frame windows are discussed in more detail in Window Objects and Document/View Architecture.

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.

Use the MFC Application Wizard to Create an MFC Application


Use the MFC Application Wizard to create an MFC project in Visual C++, which can include OLE and database
support. Files in the project contain your application, document, view, and frame-window classes; standard
resources, including menus and an optional toolbar; other required Windows files; and optional .rtf files containing
standard Windows Help topics that you can revise and augment to create your program's help file.

Use Class View to Manage Classes and Windows Messages


Class View helps you create handler functions for Windows messages and commands, create and manage classes,
create class member variables, create Automation methods and properties, create database classes, and more.

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.

Use the Resource Editors to Create and Edit Resources


Use the Visual C++ resource editors to create and edit menus, dialog boxes, custom controls, accelerator keys,
bitmaps, icons, cursors, strings, and version resources. As of Visual C++ version 4.0, a toolbar editor makes
creating toolbars much easier.
To help you even more, the Microsoft Foundation Class Library provides a file called COMMON.RES, which
contains "clip art" resources that you can copy from COMMON.RES and paste into your own resource file.
COMMON.RES includes toolbar buttons, common cursors, icons, and more. You can use, modify, and redistribute
these resources in your application. For more information about COMMON.RES, see the Clipart sample.
The MFC Application Wizard, the Visual C++ wizards, resource editors, and the MFC framework do a lot of work for
you and make managing your code much easier. The bulk of your application-specific code is in your document
and view classes.

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.

You can also test the dialog boxes in


the dialog editor.

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.

You can also test the property page(s)


in the dialog editor.

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.

Creating Database Applications


TA SK Y O U DO T H E F RA M EW O RK DO ES

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.

The Message Loop


For more information about what you can do in the idle loop, see Idle Loop Processing.

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.

File Manager Drag and Drop


Files can be dragged from the file view window in File Manager or File Explorer to a window in your application.
You might, for example, enable one or more files to be dragged to an MDI application's main window, where the
application could retrieve the file names and open MDI child windows for those files.
To enable file drag and drop in your application, the MFC Application Wizard writes a call to the CWnd member
function DragAcceptFiles for your main frame window in your InitInstance . You can remove that call if you do
not want to implement the drag-and-drop feature.

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.

Keeping Track of the Most Recently Used Documents


As the user opens and closes files, the application object keeps track of the four most recently used files. The
names of these files are added to the File menu and updated when they change. The framework stores these file
names in either the registry or in the .ini file, with the same name as your project and reads them from the file
when your application starts up. The InitInstance override that the MFC Application Wizard creates for you
includes a call to the CWinApp member function LoadStdProfileSettings, which loads information from the
registry or .ini file, including the most recently used file names.
These entries are stored as follows:
In Windows NT, Windows 2000, and later, the value is stored to a registry key.
In Windows 3.x, the value is stored in the WIN.INI file.
In Windows 95 and later, the value is stored in a cached version of WIN.INI.

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.

An MDI Application with Two Document Types


Document templates are created and maintained by the application object. One of the key tasks performed
during your application's InitInstance function is to construct one or more document templates of the
appropriate kind. This feature is described in Document Template Creation. The application object stores a pointer
to each document template in its template list and provides an interface for adding document templates.
If you need to support two or more document types, you must add an extra call to AddDocTemplate for each
document type.
An icon is registered for each document template based on its position in the application's list of document
templates. The order of the document templates is determined by the order they are added with calls to
AddDocTemplate . MFC assumes that the first Icon resource in the application is the application icon, the next Icon
resource is the first document icon, and so on.
For example, a document template is the third of three for the application. If there is an Icon resource in the
application at index 3, that icon is used for the document template. If not, the icon at index 0 is used as a default.

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

Application object Document template

Document template Document

Document template Frame window

Frame window View

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

Document Use GetFirstViewPosition and GetNextView to access the


document's view list.

Call GetDocTemplate to get the document template.

View Call GetDocument to get the document.

Call GetParentFrame to get the frame window.

Document frame window Call GetActiveView to get the current view.

Call GetActiveDocument to get the document attached to the


current view.

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.

Sequence in Creating a Document

Sequence in Creating a Frame Window


Sequence in Creating a View
For information about how the framework initializes the new document, view, and frame-window objects, see
classes CDocument, CView, CFrameWnd, CMDIFrameWnd, and CMDIChildWnd in the MFC Library Reference.
Also see Technical Note 22, which explains the creation and initialization processes further under its discussion of
the framework's standard commands for the New and Open items on the File menu.

Initializing Your Own Additions to These Classes


The preceding figures also suggest the points at which you can override member functions to initialize your
application's objects. An override of OnInitialUpdate in your view class is the best place to initialize the view. The
OnInitialUpdate call occurs immediately after the frame window is created and the view within the frame
window is attached to its document. For example, if your view is a scroll view (derived from CScrollView rather
than CView ), you should set the view size based on the document size in your OnInitialUpdate override. (This
process is described in the description of class CScrollView.) You can override the CDocument member functions
OnNewDocument and OnOpenDocument to provide application-specific initialization of the document. Typically, you
must override both since a document can be created in two ways.
In most cases, your override should call the base class version. For more information, see the named member
functions of classes CDocument, CView, CFrameWnd, and CWinApp in the MFC Library Reference.

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.

State Data of a Single Module (Application)


A module's state data is contained in a structure and is always available via a pointer to that structure. When the
flow of execution enters a particular module, as shown in the following figure, that module's state must be the
"current" or "effective" state. Therefore, each thread object has a pointer to the effective state structure of that
application. Keeping this pointer updated at all times is vital to managing the application's global state and
maintaining the integrity of each module's state. Incorrect management of the global state can lead to
unpredictable application behavior.

State Data of Multiple Modules


In other words, each module is responsible for correctly switching between module states at all of its entry points.
An "entry point" is any place where the flow of execution can enter the module's code. Entry points include:
Exported functions in a DLL
Member functions of COM interfaces
Window procedures

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();
}

For additional information, see Technical Note 38 on MFC/OLE IUnknown implementation.


The METHOD_PROLOGUE macro is defined as:

#define METHOD_PROLOGUE(theClass, localClass) \


theClass* pThis = \
((theClass*)((BYTE*)this - offsetof(theClass, m_x##localClass))); \
AFX_MANAGE_STATE(pThis->m_pModuleState) \

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.

PeekMessage in the MFC Message Loop


In an application developed with MFC, the main message loop in the CWinThread class contains a message loop
that calls the PeekMessage Win32 API. This loop also calls the OnIdle member function of CWinThread between
messages. An application can process messages in this idle time by overriding the OnIdle function.

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.

PeekMessage Elsewhere in Your Application


Another method for performing idle processing in an application involves embedding a message loop in one of
your functions. This message loop is very similar to MFC's main message loop, found in CWinThread::Run. That
means such a loop in an application developed with MFC must perform many of the same functions as the main
message loop. The following code fragment demonstrates writing a message loop that is compatible with MFC:
BOOL bDoingBackgroundProcessing = TRUE;
while (bDoingBackgroundProcessing)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!AfxGetApp()->PumpMessage())
{
bDoingBackgroundProcessing = FALSE;
::PostQuitMessage(0);
break;
}
}
// let MFC do its idle processing
LONG lIdle = 0;
while (AfxGetApp()->OnIdle(lIdle++))
;
// Perform some background processing here
// using another call to OnIdle
}

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;

AFX_ANSI_DEPRECATED BOOL GetImageList(PBUTTON_IMAGELIST pbuttonImagelist) const;

AFX_ANSI_DEPRECATED BOOL GetTextMargin(LPRECT pmargin) const;

AFX_ANSI_DEPRECATED BOOL SetImageList(PBUTTON_IMAGELIST pbuttonImagelist);

AFX_ANSI_DEPRECATED BOOL SetTextMargin(LPRECT pmargin);

CComboBoxEx class
AFX_ANSI_DEPRECATED HRESULT SetWindowTheme(LPCWSTR pszSubAppName);

CEdit class
AFX_ANSI_DEPRECATED BOOL GetCueBanner(LPWSTR lpszText,
int cchText) const;

AFX_ANSI_DEPRECATED BOOL SetCueBanner(LPCWSTR lpszText,


BOOL fDrawIfFocused = FALSE);

CLinkCtrl class
The entire class is deprecated.

CListCtrl class
AFX_ANSI_DEPRECATED void CancelEditLabel();

AFX_ANSI_DEPRECATED int EnableGroupView(BOOL fEnable);

AFX_ANSI_DEPRECATED int GetGroupInfo(int iGroupId,


PLVGROUP pgrp) const;

AFX_ANSI_DEPRECATED void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const;

AFX_ANSI_DEPRECATED BOOL GetInsertMark(LPLVINSERTMARK lvim) const;


AFX_ANSI_DEPRECATED COLORREF GetInsertMarkColor() const;

AFX_ANSI_DEPRECATED int GetInsertMarkRect(LPRECT pRect) const;

AFX_ANSI_DEPRECATED COLORREF GetOutlineColor() const;

AFX_ANSI_DEPRECATED UINT GetSelectedColumn() const;

AFX_ANSI_DEPRECATED BOOL GetTileInfo(PLVTILEINFO pti) const;

AFX_ANSI_DEPRECATED BOOL GetTileViewInfo(PLVTILEVIEWINFO ptvi) const;

AFX_ANSI_DEPRECATED DWORD GetView() const;

AFX_ANSI_DEPRECATED BOOL HasGroup(int iGroupId) const;

AFX_ANSI_DEPRECATED int InsertGroup(int index,


PLVGROUP pgrp);

AFX_ANSI_DEPRECATED void InsertGroupSorted(PLVINSERTGROUPSORTED pStructInsert);

AFX_ANSI_DEPRECATED int InsertMarkHitTest(LPPOINT pPoint,


LPLVINSERTMARK lvim) const;

AFX_ANSI_DEPRECATED BOOL IsGroupViewEnabled() const;

AFX_ANSI_DEPRECATED void MoveGroup(int iGroupId,


int toIndex);

AFX_ANSI_DEPRECATED void MoveItemToGroup(int idItemFrom,


int idGroupTo);

AFX_ANSI_DEPRECATED void RemoveAllGroups();

AFX_ANSI_DEPRECATED int RemoveGroup(int iGroupId);

AFX_ANSI_DEPRECATED BOOL SetGroupInfo(int iGroupId,


PLVGROUP pGroup);

AFX_ANSI_DEPRECATED void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics);

AFX_ANSI_DEPRECATED BOOL SetInfoTip(PLVSETINFOTIP plvInfoTip);

AFX_ANSI_DEPRECATED BOOL SetInsertMark(LPLVINSERTMARK lvim);

AFX_ANSI_DEPRECATED COLORREF SetInsertMarkColor(COLORREF color);

AFX_ANSI_DEPRECATED COLORREF SetOutlineColor(COLORREF color);

AFX_ANSI_DEPRECATED void SetSelectedColumn(int iCol);

AFX_ANSI_DEPRECATED BOOL SetTileInfo(PLVTILEINFO pti);

AFX_ANSI_DEPRECATED BOOL SetTileViewInfo(PLVTILEVIEWINFO ptvi);

AFX_ANSI_DEPRECATED DWORD SetView(int iView);

AFX_ANSI_DEPRECATED BOOL SortGroups(PFNLVGROUPCOMPARE _pfnGroupCompare,


LPVOID _plv);

CReBarCtrl class
AFX_ANSI_DEPRECATED void GetBandMargins(PMARGINS pMargins) const;

AFX_ANSI_DEPRECATED HRESULT SetWindowTheme(LPCWSTR pszSubAppName);

CToolBarCtrl class
AFX_ANSI_DEPRECATED void GetMetrics(LPTBMETRICS ptbm) const;

AFX_ANSI_DEPRECATED void SetMetrics(LPTBMETRICS ptbm);

AFX_ANSI_DEPRECATED HRESULT SetWindowTheme(LPCWSTR pszSubAppName);

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() .

4. Add the following line of code to your constructor.

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.

Specifying dynamic layout settings for an MFC dialog box


When the user resizes a dialog, the controls in the dialog can resize or move in the X and Y directions. The change
in size or position of a control when the user resizes a dialog is called dynamic layout. For example, the following is
a dialog before being resized:

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.

CMFCDynamicLayout* dynamicLayout = pDialog->GetDynamicLayout();

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.

MoveSettings moveSettings = CMFCDynamicLayout::MoveHorizontal(100);

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:

SizeSettings sizeSettings = CMFCDynamicLayout::SizeNone();

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);

6. Repeat for each control that needs to be moved or resized.


7. If necessary, can use the CMFCDynamicLayout::HasItem method to determine if a control is already on the
list of controls subjected to dynamic layout changes, or the CMFCDynamicLayout::IsEmpty method to
determine if there are any controls that are subject to changes.
8. To enable dialog layout, call the CWnd::EnableDynamicLayout method.

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);

To set the dynamic layout programmatically from a resource file


1. Use the CMFCDynamicLayout::MoveHorizontalAndVertical method to specify a resource name in the
relevant resource script file (.rc file) that specifies dynamic layout information, as in the following example:

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.

What do you want to do


Derive a class from CObject
Add support for run-time class information, dynamic creation, and serialization to my derived class
Access run-time class information
Create objects dynamically
Dump the object's data for diagnostic purposes
Validate the object's internal state (see MFC ASSERT_VALID and CObject::AssertValid)
Have the class serialize itself to persistent storage
See a list of CObject Frequently Asked Questions

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>>

M A C RO USED C O B JEC T : : ISK IN DO F C REAT EO B JEC T C A RC H IVE: : O P ERATO R<<

Basic CObject functionality No No No

DECLARE_DYNAMIC Yes No No

DECLARE_DYNCREATE Yes Yes No

DECLARE_SERIAL Yes Yes Yes

To use basic CObject functionality


1. Use the normal C++ syntax to derive your class from CObject (or from a class derived from CObject ).
The following example shows the simplest case, the derivation of a class from CObject :
class CSimple : public CObject
{
// add CSimple-specific members and functions...
};

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.

To add run-time class information


1. Derive your class from CObject , as described in the Deriving a Class from CObject article.
2. Use the DECLARE_DYNAMIC macro in your class declaration, as shown here:

class CPerson : public CObject


{
DECLARE_DYNAMIC(CPerson)

// 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.

To add dynamic creation support


1. Derive your class from CObject .
2. Use the DECLARE_DYNCREATE macro in the class declaration.
3. Define a constructor with no arguments (a default constructor).
4. Use the IMPLEMENT_DYNCREATE macro in the class implementation file.

To add serialization support


1. Derive your class from CObject .
2. Override the Serialize member function.
NOTE
If you call Serialize directly, that is, you do not want to serialize the object through a polymorphic pointer, omit
steps 3 through 5.

3. Use the DECLARE_SERIAL macro in the class declaration.


4. Define a constructor with no arguments (a default constructor).
5. Use the IMPLEMENT_SERIAL macro in the class implementation 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 :

CRuntimeClass *pClass = RUNTIME_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:

class CPerson : public CObject


{
DECLARE_DYNAMIC(CPerson)

// other declarations
};
IMPLEMENT_DYNAMIC(CPerson, CObject)

IMPLEMENT_DYNCREATE(CMyDynCreateObj, CObject)

void MemoryCorruptingSnippet(bool bCorrupt)


{
if (bCorrupt)
{
CAge *pcage = new CAge(21); // CAge is derived from CObject.
Age *page = new Age(22); // Age is NOT derived from CObject.
*(((char *)pcage) - 1) = 99; // Corrupt preceding guard byte
*(((char *)page) - 1) = 99; // Corrupt preceding guard byte
AfxCheckMemory();
}
}

void SomeFunction(void)
{
CObject *pMyObject = new CPerson;

if (NULL != pMyObject &&


pMyObject->IsKindOf(RUNTIME_CLASS(CPerson)))
{
//if IsKindOf is true, then cast is all right
CPerson *pmyPerson = (CPerson *)pMyObject;
pmyPerson->AssertValid();
// other code goes here...
}

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:

CRuntimeClass* pRuntimeClass = RUNTIME_CLASS(CMyClass);


CObject* pObject = pRuntimeClass->CreateObject();
ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CMyClass)));

See also
Destroying Window Objects Using CObject
CObject Class: Frequently Asked Questions
3/16/2020 • 2 minutes to read • Edit Online

This section covers questions on class CObject .

What do you want to know more about


Do I have to derive new classes from CObject
What does it cost me to derive a class from CObject

See also
Using CObject
Do I Have to Derive New Classes from CObject?
3/16/2020 • 2 minutes to read • Edit Online

No, you don't.


Derive a class from CObject when you need the facilities it provides, such as serialization or dynamic creatability.
Many data classes need to be serialized to files, so it's often a good idea to derive them from CObject . For an
example of a class derived from CObject , see the Scribble sample.

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.

The Template-Based Collection Classes


The easiest way to implement a type-safe collection that contains objects of any type is to use one of the MFC
template-based classes. For examples of these classes, see the MFC sample COLLECT.
The following table lists the MFC template-based collection classes.
Collection Template Classes
C O L L EC T IO N C O N T EN T S A RRAY S L IST S MAPS

Collections of objects of CArray CList CMap


any type
C O L L EC T IO N C O N T EN T S A RRAY S L IST S MAPS

Collections of pointers to CTypedPtrArray CTypedPtrList CTypedPtrMap


objects of any type

The Collection Classes Not Based on Templates


If your application already uses MFC nontemplate classes, you can continue to use them. However, for new
collections, we recommend that you use the template-based classes. The following table lists the MFC
collection classes that are not based on templates.
Nontemplate Collection Classes
A RRAY S L IST S MAPS

CObArray CObList CMapPtrToWord

CByteArray CPtrList CMapPtrToPtr

CDWordArray CStringList CMapStringToOb

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

List Yes No Fast Slow Yes

Array Yes By int Slow Slow Yes

Map No By key Fast Fast No (keys) Yes


(values)

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

CArray Yes Yes 1 Yes 1 No

CByteArray No Yes Yes Yes 3

CDWordArray No Yes Yes Yes 3

CList Yes Yes 1 Yes 1 No

CMap Yes Yes 1 Yes 1 No

CMapPtrToPtr No No Yes No

CMapPtrToWord No No Yes No

CMapStringToOb No Yes Yes No

CMapStringToPtr No No Yes No

CMapStringToString No Yes Yes Yes 3

CMapWordToOb No Yes Yes No

CMapWordToPtr No No Yes No

CObArray No Yes Yes No

CObList No Yes Yes No

CPtrArray No No Yes No

CPtrList No No Yes No

CStringArray No Yes Yes Yes 3

CStringList No Yes Yes Yes 3

CTypedPtrArray Yes Depends 2 Yes Yes

CTypedPtrList Yes Depends 2 Yes Yes

CTypedPtrMap Yes Depends 2 Yes Yes

CUIntArray No No Yes Yes 3

CWordArray No Yes Yes Yes 3

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

Arrays, lists, and maps of typed pointers


CTypedPtrArray , CTypedPtrList , CTypedPtrMap

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.

Using Simple Array, List, and Map Templates


To use the simple collection templates, you need to know what kind of data you can store in these collections and
what parameters to use in your collection declarations.
Simple Array and List Usage
The simple array and list classes, CArray and CList, take two parameters: TYPE and ARG_TYPE . These classes can
store any data type, which you specify in the TYPE parameter:
Fundamental C++ data types, such as int , char , and float
C++ structures and classes
Other types that you define
For convenience and efficiency, you can use the ARG_TYPE parameter to specify the type of function arguments.
Typically, you specify ARG_TYPE as a reference to the type you named in the TYPE parameter. For example:

CArray<int, int> myArray;


CList<CPerson, CPerson &> myList;

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);

Simple Map Usage


The simple map class, CMap, takes four parameters: KEY, ARG_KEY, VALUE, and ARG_VALUE. Like the array and list
classes, the map classes can store any data type. Unlike arrays and lists, which index and order the data they store,
maps associate keys and values: You access a value stored in a map by specifying the value's associated key. The
KEY parameter specifies the data type of the keys used to access data stored in the map. If the type of KEY is a
structure or class, the ARG_KEY parameter is typically a reference to the type specified in KEY. The VALUE
parameter specifies the type of the items stored in the map. If the type of ARG_VALUE is a structure or class, the
ARG_VALUE parameter is typically a reference to the type specified in VALUE. For example:

CMap<int, int, MY_STRUCT, MY_STRUCT &> myMap1;


CMap<CString, LPCTSTR, CPerson, CPerson &> myMap2;

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:

CMap<CString, LPCTSTR, CPerson, CPerson &> myMap;


CPerson person;
LPCTSTR lpstrName = _T("Jones");
myMap.SetAt(lpstrName, person);

Using Typed-Pointer Collection Templates


To use the typed-pointer collection templates, you need to know what kinds of data you can store in these
collections and what parameters to use in your collection declarations.
Typed-Pointer Array and List Usage
The typed-pointer array and list classes, CTypedPtrArray and CTypedPtrList, take two parameters: BASE_CLASS and
TYPE. These classes can store any data type, which you specify in the TYPE parameter. They are derived from one of
the nontemplate collection classes that stores pointers; you specify this base class in BASE_CLASS . For arrays, use
either CObArray or CPtrArray . For lists, use either CObList or CPtrList .
In effect, when you declare a collection based on, say CObList , the new class not only inherits the members of its
base class, but it also declares a number of additional type-safe member functions and operators that help provide
type safety by encapsulating calls to the base class members. These encapsulations manage all necessary type
conversion. For example:

CTypedPtrArray<CObArray, CPerson *> myArray;


CTypedPtrList<CPtrList, MY_STRUCT *> myList;

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 .

Typed-Pointer Map Usage


The typed-pointer map class, CTypedPtrMap, takes three parameters: BASE_CLASS , KEY, and VALUE. The
BASE_CLASS parameter specifies the class from which to derive the new class: CMapPtrToWord , CMapPtrToPtr ,
CMapStringToPtr , CMapWordToPtr , CMapStringToOb , and so on. KEY is analogous to KEY in CMap : It specifies the type
of the key used for lookups. VALUE is analogous to VALUE in CMap : It specifies the type of object stored in the
map. For example:

CTypedPtrMap<CMapPtrToPtr, CString, MY_STRUCT*> myPtrMap;


CTypedPtrMap<CMapStringToOb, CString, CPerson*> myPersonMap;

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.

For more information, see How to Make a Type-Safe Collection.

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.

Using Template-Based Classes for Type Safety


To use template-based classes
1. Declare a variable of the collection class type. For example:

CList<int, int> m_intList;

2. Call the member functions of the collection object. For example:

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 .

Implementing Helper Functions


The template-based collection classes CArray , CList , and CMap use five global helper functions that you can
customize as needed for your derived collection class. For information on these helper functions, see Collection
Class Helpers in the MFC Reference. Implementation of the serialization function is necessary for most uses of the
template-based collection classes.
Serializing Elements
The CArray , CList , and CMap classes call SerializeElements to store collection elements to or read them from
an archive.
The default implementation of the SerializeElements helper function does a bitwise write from the objects to the
archive, or a bitwise read from the archive to the objects, depending on whether the objects are being stored in or
retrieved from the archive. Override SerializeElements if this action is not appropriate.
If your collection stores objects derived from CObject and you use the IMPLEMENT_SERIAL macro in the
implementation of the collection element class, you can take advantage of the serialization functionality built into
CArchive and CObject :

CArray< CPerson, CPerson& > personArray;

template <> void AFXAPI SerializeElements <CPerson>(CArchive& ar,


CPerson* pNewPersons, INT_PTR nCount)
{
for (int i = 0; i < nCount; i++, pNewPersons++)
{
// Serialize each CPerson object
pNewPersons->Serialize(ar);
}
}

The overloaded insertion operators for CArchive call CObject::Serialize (or an override of that function) for
each CPerson object.

Using Nontemplate Collection Classes


MFC also supports the collection classes introduced with MFC version 1.0. These classes are not based on
templates. They can be used to contain data of the supported types CObject* , UINT , DWORD , and CString . You
can use these predefined collections (such as CObList ) to hold collections of any objects derived from CObject .
MFC also provides other predefined collections to hold primitive types such as UINT and void pointers ( void *).
In general, however, it is often useful to define your own type-safe collections to hold objects of a more specific
class and its derivatives. Note that doing so with the collection classes not based on templates is more work than
using the template-based classes.
There are two ways to create type-safe collections with the nontemplate collections:
1. Use the nontemplate collections, with type casting if necessary. This is the easier approach.
2. Derive from and extend a nontemplate type-safe collection.
To use the nontemplate collections with type casting
1. Use one of the nontemplate classes, such as CWordArray , directly.
For example, you can create a CWordArray and add any 32-bit values to it, then retrieve them. There is
nothing more to do. You just use the predefined functionality.
You can also use a predefined collection, such as CObList , to hold any objects derived from CObject . A
CObList collection is defined to hold pointers to CObject . When you retrieve an object from the list, you
may have to cast the result to the proper type since the CObList functions return pointers to CObject . For
example, if you store CPerson objects in a CObList collection, you have to cast a retrieved element to be a
pointer to a CPerson object. The following example uses a CObList collection to hold CPerson objects:

CPerson* p1 = new CPerson();


CObList myList;

myList.AddHead(p1); // No cast needed


CPerson* p2 = (CPerson*)myList.GetHead();

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.

class CPersonList : public CObList


{
public:
void AddHeadPerson(CPerson* person)
{
AddHead(person);
}

const CPerson* GetHeadPerson()


{
return (CPerson*)GetHead();
}
};

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:

CTypedPtrArray<CObArray, CPerson *> myArray;

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

CPerson *thePerson = myArray[i];

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:

CMap<CString, LPCTSTR, CPerson *, CPerson *> myMap;


CPerson myPerson;

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);

POSITION pos = myMap.GetStartPosition();


while (pos != NULL)
{
CPerson *pPerson;
CString string;
// Gets key (string) and value (pPerson)
myMap.GetNextAssoc(pos, string, (CObject *&)pPerson);
ASSERT(pPerson->IsKindOf(RUNTIME_CLASS(CPerson)));
// Use string and pPerson ...
}

For more information, see Deleting All Objects in a CObject Collection.

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.

CTypedPtrList<CObList, CPerson*> myList;


CPerson* pPerson = new CPerson();
myList.AddHead(pPerson);
POSITION pos = myList.GetHeadPosition();

while (pos != NULL)


{
delete myList.GetNext(pos);
}
myList.RemoveAll();

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:

CArray<CPerson*, CPerson*> myArray;

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.

CMap<CString, LPCTSTR, CPerson*, CPerson*> myMap;


// ... Add some key-value elements ...
// Now delete the elements
POSITION pos = myMap.GetStartPosition();
while (pos != NULL)
{
CPerson* pPerson;
CString string;
// Gets key (string) and value (pPerson)
myMap.GetNextAssoc(pos, string, pPerson);
delete pPerson;
}
// RemoveAll deletes the keys
myMap.RemoveAll();

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:

class CTray : public CObject { };

class CStack : public CTypedPtrList< CObList, CTray* >


{
public:
// Add element to top of stack
void Push(CTray* newTray)
{
AddHead(newTray);
}

// Peek at top element of stack


CTray* Peek()
{
return IsEmpty() ? NULL : GetHead();
}

// Pop top element off stack


CTray* Pop()
{
return RemoveHead();
}
};

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.

class CQueue : public CTypedPtrList< CObList, CPerson* >


{
public:
// Go to the end of the line
void AddToEnd(CPerson* newPerson)
{
AddTail(newPerson);
} // End of the queue

// Get first element in line


CPerson* GetFromFront()
{
return IsEmpty() ? NULL : RemoveHead();
}
};

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.

This article covers the following topics:


When to use exceptions
MFC exception support
Further reading about exceptions

When to Use Exceptions


Three categories of outcomes can occur when a function is called during program execution: normal
execution, erroneous execution, or abnormal execution. Each category is described below.
Normal execution
The function may execute normally and return. Some functions return a result code to the caller, which
indicates the outcome of the function. The possible result codes are strictly defined for the function and
represent the range of possible outcomes of the function. The result code can indicate success or
failure or can even indicate a particular type of failure that is within the normal range of expectations.
For example, a file-status function can return a code that indicates that the file does not exist. Note that
the term "error code" is not used because a result code represents one of many expected outcomes.
Erroneous execution
The caller makes some mistake in passing arguments to the function or calls the function in an
inappropriate context. This situation causes an error, and it should be detected by an assertion during
program development. (For more information on assertions, see C/C++ Assertions.)
Abnormal execution
Abnormal execution includes situations where conditions outside the program's control, such as low
memory or I/O errors, are influencing the outcome of the function. Abnormal situations should be
handled by catching and throwing exceptions.
Using exceptions is especially appropriate for abnormal execution.

MFC Exception Support


Whether you use the C++ exceptions directly or use the MFC exception macros, you will use CException Class
or CException -derived objects that may be thrown by the framework or by your application.
The following table shows the predefined exceptions provided by MFC.

EXC EP T IO N C L A SS M EA N IN G

CMemoryException Class Out-of-memory

CFileException Class File exception

CArchiveException Class Archive/Serialization exception

CNotSupportedException Class Response to request for unsupported service

CResourceException Class Windows resource allocation exception

CDaoException Class Database exceptions (DAO classes)

CDBException Class Database exceptions (ODBC classes)

COleException Class OLE exceptions

COleDispatchException Class Dispatch (automation) exceptions

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.

Further Reading About Exceptions


The following articles explain using the MFC library for exception handing:
Exceptions: Catching and Deleting Exceptions
Exceptions: Examining Exception Contents
Exceptions: Freeing Objects in Exceptions
Exceptions: Throwing Exceptions from Your Own Functions
Exceptions: Database Exceptions
Exceptions: OLE Exceptions
The following articles compare the MFC exception macros with the C++ exception keywords and explain how
you can adapt your code:
Exceptions: Changes to Exception Macros in Version 3.0
Exceptions: Converting from MFC Exception Macros
Exceptions: Using MFC Macros and C++ Exceptions

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

This is an advanced topic.


In MFC version 3.0 and later, the exception-handling macros have been changed to use C++ exceptions. This
article tells how those changes can affect the behavior of existing code that uses the macros.
This article covers the following topics:
Exception types and the CATCH macro
Re-throwing exceptions

Exception Types and the CATCH Macro


In earlier versions of MFC, the CATCH macro used MFC run-time type information to determine an exception's
type; the exception's type is determined, in other words, at the catch site. With C++ exceptions, however, the
exception's type is always determined at the throw site by the type of the exception object that is thrown. This will
cause incompatibilities in the rare case where the type of the pointer to the thrown object differs from the type of
the thrown object.
The following example illustrates the consequence of this difference between MFC version 3.0 and earlier versions:

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

THROW((CException*) new CCustomException());

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();
}

Execution returns from within the catch block.

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.

To catch and delete exceptions


1. Use the tr y keyword to set up a tr y block. Execute any program statements that might throw an exception
within a tr y block.
Use the catch keyword to set up a catch block. Place exception-handling code in a catch block. The code
in the catch block is executed only if the code within the tr y block throws an exception of the type
specified in the catch statement.
The following skeleton shows how tr y and catch blocks are normally arranged:

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

This is an advanced topic.


This article explains how to convert existing code written with Microsoft Foundation Class macros — TRY , CATCH ,
THROW , and so on — to use the C++ exception-handling keywords tr y , catch , and throw . Topics include:
Conversion advantages
Converting code with exception macros to use C++ exceptions

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.

Doing the Conversion


To convert code using macros to use the C++ exception-handling keywords
1. Locate all occurrences of the MFC macros TRY , CATCH , AND_CATCH , END_CATCH , THROW , and
THROW_L AST .
2. Replace or delete all occurrences of the following macros:
TRY (Replace it with tr y )
CATCH (Replace it with catch )
AND_CATCH (Replace it with catch )
END_CATCH (Delete it)
THROW (Replace it with throw )
THROW_L AST (Replace it with throw )
3. Modify the macro arguments so that they form valid exception declarations.
For example, change

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;

// Not necessary to delete the exception e.


}
END_CATCH

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

Mixing Exception Keywords and Macros


You can mix MFC exception macros and C++ exception keywords in the same program. But you cannot mix MFC
macros with C++ exception keywords in the same block because the macros delete exception objects
automatically when they go out of scope, whereas code using the exception-handling keywords does not. For
more information, see the article Exceptions: Catching and Deleting Exceptions.
The main difference between the macros and the keywords is that the macros "automatically" delete a caught
exception when the exception goes out of scope. Code using the keywords does not; exceptions caught in a catch
block must be explicitly deleted. Mixing macros and C++ exception keywords can cause memory leaks when an
exception object is not deleted, or heap corruption when an exception is deleted twice.
The following code, for example, invalidates the exception pointer:

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 Blocks Inside Catch Blocks


You cannot re-throw the current exception from within a tr y block that is inside a CATCH block. The following
example is invalid:

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

For more information, see Exceptions: Examining Exception Contents.

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:

void SomeFunc() // Problematic code


{
CPerson* myPerson = new CPerson;

// Do something that might throw an exception.


myPerson->SomeFunc();

// Now destroy the object before exiting.


// If SomeFunc above throws an exception this code will
// not be reached and myPerson will not be deleted.
delete myPerson;
}

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.

Handling the Exception Locally


The tr y/catch paradigm provides a defensive programming method for avoiding memory leaks and ensuring
that your objects are destroyed when exceptions occur. For instance, the example shown earlier in this article could
be rewritten as follows:
void SomeFunc()
{
CPerson* myPerson = new CPerson;

try
{
// Do something that might throw an exception.
myPerson->SomeFunc();
}
catch (CException* e)
{
// Handle the exception locally
e->Delete();
}

// Now destroy the object before exiting.


delete myPerson;
}

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.

Throwing Exceptions After Destroying Objects


Another way to handle exceptions is to pass them on to the next outer exception-handling context. In your catch
block, you can do some cleanup of your locally allocated objects and then throw the exception on for further
processing.
The throwing function may or may not need to deallocate heap objects. If the function always deallocates the heap
object before returning in the normal case, then the function should also deallocate the heap object before
throwing the exception. On the other hand, if the function does not normally deallocate the object before returning
in the normal case, then you must decide on a case-by-case basis whether the heap object should be deallocated.
The following example shows how locally allocated objects can be cleaned up:

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;
}

// On normal exits, destroy the object.


delete myPerson;
}

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();
}

// ... Do something with allocated blocks ...

// In normal exit, both blocks are deleted.


free(p1);
free(p2);
}

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

Approaches to Exception Handling


The approach is the same whether you are working with DAO (obsolete) or ODBC.
You should always write exception handlers to handle exceptional conditions.
The most pragmatic approach to catching database exceptions is to test your application with exception scenarios.
Determine the likely exceptions that might occur for an operation in your code, and force the exception to occur.
Then examine the trace output to see what exception is thrown, or examine the returned error information in the
debugger. This lets you know which return codes you'll see for the exception scenarios you are using.
Error Codes Used for ODBC Exceptions
In addition to return codes defined by the framework, which have names of the form AFX_SQL_ERROR_XXX ,
some CDBExceptions are based on ODBC return codes. The return codes for such exceptions have names of the
form SQL_ERROR_XXX .
The return codes — both framework-defined and ODBC-defined — that the database classes can return are
documented under the m_nRetCode data member of class CDBException . Additional information about return
codes defined by ODBC is available in the ODBC SDK Programmer's Reference in the MSDN Library.
Error Codes Used for DAO Exceptions
For DAO exceptions, more information is typically available. You can access error information through three data
members of a caught CDaoException object:
m_pErrorInfo contains a pointer to a CDaoErrorInfo object that encapsulates error information in DAO's
collection of error objects associated with the database.
m_nAfxDaoError contains an extended error code from the MFC DAO classes. These error codes, which
have names of the form AFX_DAO_ERROR_XXX , are documented under the data member in
CDaoException .

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.

A Database Exception-Handling Example


The following example attempts to construct a CRecordset-derived object on the heap with the new operator, and
then open the recordset (for an ODBC data source). For a similar example for the DAO classes, see "DAO Exception
Example" below.
ODBC Exception Example
The Open member function could throw an exception (of type CDBException for the ODBC classes), so this code
brackets the Open call with a tr y block. The subsequent catch block will catch a CDBException . You could examine
the exception object itself, called e , but in this case it is enough to know that the attempt to create a recordset has
failed. The catch block displays a message box and cleans up by deleting the recordset object.

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;
}

DAO Exception Example


The DAO example is similar to the example for ODBC, but you can typically retrieve more kinds of information. The
following code also attempts to open a recordset. If that attempt throws an exception, you can examine a data
member of the exception object for error information. As with the previous ODBC example, it is probably enough
to know that the attempt to create a recordset failed.

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:

An application-specific error code


An error description, such as "Disk full"
A Help context that your application can use to provide additional information for the user
The name of your application's Help file
The name of the application that generated the exception
COleDispatchException provides more information so that it can be used with products like Microsoft Visual Basic.
The verbal error description can be used in a message box or other notification; the Help information can be used
to help the user respond to the conditions that caused the exception.
Two global functions correspond to the two OLE exception classes: AfxThrowOleException and
AfxThrowOleDispatchException. Use them to throw general OLE exceptions and OLE dispatch exceptions,
respectively.

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.

What do you want to do


Use CFile
Open a file with CFile
Read and write a file with CFile
Close a file with CFile
Access file status with CFile
Use MFC Serialization (Object Persistence)
Create a serializable class
Serialize an object via a CArchive object
Create a CArchive object
Use CArchive << and >> operators
Store and load CObjects and CObject-derived objects via an archive

See also
Concepts
General MFC Topics
CArchive Class
CObject Class
Opening Files
3/27/2020 • 2 minutes to read • Edit Online

In MFC, the most common way to open a file is a two-stage process.


To open a file
1. Create the file object without specifying a path or permission flags.
You usually create a file object by declaring a CFile variable on the stack frame.
2. Call the Open member function for the file object, supplying a path and permission flags.
The return value for Open will be nonzero if the file was opened successfully or 0 if the specified file could
not be opened. The Open member function is prototyped as follows:
virtual BOOL Open( LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError = NULL );

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):

TCHAR* pszFileName = _T("c:\\test\\myfile.dat");


CFile myFile;
CFileException fileException;

if ( !myFile.Open( pszFileName, CFile::modeCreate |


CFile::modeReadWrite, &fileException ) )
{
TRACE( _T("Can't open file %s, error = %u\n"),
pszFileName, fileException.m_cause );
}

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;

if ( myFile.Open( _T("c:\\test\\myfile.dat"), CFile::modeCreate |


CFile::modeReadWrite ) )
{
myFile.Write( szBuffer, sizeof( szBuffer ) );
myFile.Flush();
myFile.Seek( 0, CFile::begin );
nActual = myFile.Read( szBuffer, sizeof( szBuffer ) );
}

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 );
}

For related information, see Serialization.

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.

Control Bars are Now Panes


Control bars are now known as panes and are derived from CBasePane Class. In earlier versions of MFC, the base
class of control bars was CControlBar .
The application main frame window is usually represented by the CFrameWndEx Class or the CMDIFrameWndEx
Class. The main frame is called the dock site. Panes can have one of three types of parents: a dock site, a dock bar, or
a mini-frame window.
There are two types of panes: non-resizable and resizable. Resizable panes, such as status bars and toolbars, can be
resized by using splitters or sliders. Resizable panes can form containers (one pane can be docked to another pane,
creating a splitter between them). However, resizable panes cannot be attached (docked) to dock bars.
If your application uses non-resizable panes, derive them from CPane Class. If your application uses resizable
panes, derive them from CDockablePane Class

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.

Auto-hide Control Bars


By default, each CDockablePane supports the auto-hide feature. When a user clicks the pin button on the caption of
the CDockablePane , the framework switches the pane to auto-hide mode. To handle the click, the framework creates
a CMFCAutoHideBar Class and a CMFCAutoHideButton Class associated with the CMFCAutoHideBar object. The
framework puts the new CMFCAutoHideBar on the CAutoHideDockSite. The framework also attaches the
CMFCAutoHideButton to the toolbar. The CDockingManager Class maintains the CDockablePane .

Tabbed Control Bars and Outlook Bars


The CMFCBaseTabCtrl Class implements the base functionality of a tabbed window with detachable tabs. To use a
CMFCBaseTabCtrl object, initialize a CBaseTabbedPane Class in your application. CBaseTabbedPane is derived from
CDockablePane and maintains a pointer to a CMFCBaseTabCtrl object. The CBaseTabbedPane enables users to dock
and resize tabbed control bars. Use CDockablePane::AttachToTabWnd to dynamically create control bars that are
docked and tabbed.
The Outlook bar control is also based on tabbed bars. The CMFCOutlookBar Class is derived from CBaseTabbedPane .
For more information about how to use Outlook bar, see CMFCOutlookBar Class.

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.

To implement a Send Mail command with MFC


1. Use the Visual C++ menu editor to add a menu item whose command ID is ID_FILE_SEND_MAIL.
This command ID is provided by the framework in AFXRES.H. The command can be added to any menu, but
it is usually added to the File menu.
2. Manually add the following to your document's message map:

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.

3. Build your application.


If mail support is available, MFC enables your menu item with OnUpdateFileSendMail and subsequently processes
the command with OnFileSendMail . If mail support is not available, MFC automatically removes your menu item
so the user will not see it.

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.

For related information, see the MAPI overview.


For more information about the CDocument member functions that enable MAPI, see:
CDocument::OnFileSendMail
CDocument::OnUpdateFileSendMail
COleDocument::OnFileSendMail

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.

What do you want to know more about


Frame allocation
Heap allocation
Allocating memory for an array
Deallocating memory for an array from the heap
Allocating memory for a data structure
Allocating memory for an object
Resizable memory blocks

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

Allocation of an Array of Bytes


To allocate an array of bytes on the frame
1. Define the array as shown by the following code. The array is automatically deleted and its memory
reclaimed when the array variable exits its scope.

{
const int BUFF_SIZE = 128;

// Allocate on the frame


char myCharArray[BUFF_SIZE];
int myIntArray[BUFF_SIZE];
// Reclaimed when exiting scope
}

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:

const int BUFF_SIZE = 128;

// Allocate on the heap


char* myCharArray = new char[BUFF_SIZE];
int* myIntArray = new int[BUFF_SIZE];

To deallocate the arrays from the heap


1. Use the delete operator as follows:

delete[] myCharArray;
delete[] myIntArray;

Allocation of a Data Structure


To allocate a data structure on the frame
1. Define the structure variable as follows:
struct MyStructType { int topScore; };
void MyFunc()
{
// Frame allocation
MyStructType myStruct;

// Use the struct


myStruct.topScore = 297;

// Reclaimed when exiting scope


}

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;

// Use the struct through the pointer ...


myStruct->topScore = 297;

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

myClass.SomeMemberFunction(); // Use the object


}

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.

// Automatic constructor call here


CMyClass* myClass = new CMyClass;

myClass->SomeMemberFunction(); // Use the object

delete myClass; // Destructor invoked during delete

If the argument for the CPerson constructor is a pointer to char , the statement for frame allocation is:

CMyClass myClass("Joe Smith");

The statement for heap allocation is:


CMyClass* myClass = new CMyClass("Joe Smith");

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.

What do you want to know more about


Messages and Commands in the Framework
How the framework calls a message handler
How the Framework Searches Message Maps
Declaring Message Handler Functions
Mapping Messages to Functions
How to Display Command Information in the Status Bar
Dynamic update of user-interface objects
How to: Create a Message Map for a Template Class

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.

Windows Messages and Control-Notification Messages


Messages in categories 1 and 2 — Windows messages and control notifications — are handled by windows:
objects of classes derived from class CWnd . This includes CFrameWnd , CMDIFrameWnd , CMDIChildWnd , CView ,
CDialog , and your own classes derived from these base classes. Such objects encapsulate an HWND , a handle to a
Windows window.

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.

Commands in the Framework


The figure "Command Updating in the Framework" below shows how MFC updates user-interface objects such as
menu items and toolbar buttons. Before a menu drops down, or during the idle loop in the case of toolbar buttons,
MFC routes an update command. In the figure below, the document object calls its update command handler,
OnUpdateEditClearAll , to enable or disable the user-interface object.

Command Updating in the Framework

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:

MDI frame window ( CMDIFrameWnd ) 1. Active CMDIChildWnd


2. This frame window
3. Application ( CWinApp object)

Document frame window ( CFrameWnd , CMDIChildWnd ) 1. Active view


2. This frame window
3. Application ( CWinApp object)

View 1. This view


2. Document attached to the view

Document 1. This document


2. Document template attached to the document

Dialog box 1. This dialog box


2. Window that owns the dialog box
3. Application ( CWinApp object)

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.

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)


{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here

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

afx_msg void OnEditCut();

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

afx_msg void OnBnClickedMybutton();

You might assign this command an ID of IDC_MY_BUTTON because it is equivalent to an application-specific


user-interface object.
Both categories of messages take no arguments and return no value.

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

Writing the Message-Map Entry


In the .CPP file, add your message-map entry, as shown in the following example:

ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, &OnDoSomething)

The message-map entry consists of the following items:


The message-map range macro:
ON_COMMAND_RANGE
ON_UPDATE_COMMAND_UI_RANGE
ON_CONTROL_RANGE
Parameters to the macro:
The first two macros take three parameters:
The command ID that starts the range
The command ID that ends the range
The name of the message handler function
The range of command IDs must be contiguous.
The third macro, ON_CONTROL_RANGE , takes an additional first parameter: a control-notification message, such
as EN_CHANGE .

Declaring the Handler Function


Add your handler function declaration in the .H file. The following code shows how this might look, as shown
below:

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.

Example for a Range of Command IDs


When might you use ranges One example is in handling commands like the Zoom command in the MFC sample
HIERSVR. This command zooms the view, scaling it between 25% and 300% of its normal size. HIERSVR's view
class uses a range to handle the Zoom commands with a message-map entry resembling this:

ON_COMMAND_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, &OnZoom)

When you write the message-map entry, you specify:


Two command IDs, beginning and ending a contiguous range.
Here they are ID_VIEW_ZOOM25 and ID_VIEW_ZOOM300 .
The name of the handler function for the commands.
Here it's OnZoom .
The function declaration would resemble this:

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.

Example for a Range of Control IDs


Another interesting case is mapping control-notification messages for a range of control IDs to a single handler.
Suppose the user can click any of 10 buttons. To map all 10 buttons to one handler, your message-map entry
would look like this:

ON_CONTROL_RANGE(BN_CLICKED, IDC_BUTTON1, IDC_BUTTON10, OnButtonClicked)

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:

void CRangesView::OnButtonClicked(UINT nID)


{
int nButton = nID - IDC_BUTTON1;
ASSERT(nButton >= 0 && nButton < 10);
// ...
}

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.

What do you want to do


Learn more about message reflection
Implement message reflection for a common control
Implement message reflection for an ActiveX control

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:

// Extends the CListBox class to provide synchronization with


// an external data source
template <typename CollectionT>
class CSyncListBox : public CListBox
{
public:
CSyncListBox();
virtual ~CSyncListBox();

afx_msg void OnPaint();


afx_msg void OnDestroy();
afx_msg LRESULT OnSynchronize(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()

// ...additional functionality as needed


};

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:

// Template function for converting an element within a collection


// to a CString object
template<typename CollectionT>
CString StringizeElement(CollectionT* pCollection, INT iIndex);

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:

#define LBN_SYNCHRONIZE (WM_USER + 1)

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:

BEGIN_TEMPLATE_MESSAGE_MAP(CSyncListBox, CollectionT, CListBox)


ON_WM_PAINT()
ON_WM_DESTROY()
ON_MESSAGE(LBN_SYNCHRONIZE, OnSynchronize)
END_MESSAGE_MAP()

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);

// Create a CStringList object and add a few strings


CStringList stringList;
stringList.AddTail(_T("A"));
stringList.AddTail(_T("B"));
stringList.AddTail(_T("C"));

// Send a message to the list box control to synchronize its


// contents with the string list
ctlStringLB.SendMessage(LBN_SYNCHRONIZE, 0, (LPARAM)& stringList);

// 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.

Document Site Objects


In the active document containment architecture, a document site is the same as a client site object in OLE
Documents with the addition of the IOleDocument interface:

interface IOleDocumentSite : IUnknown


{
HRESULT ActivateMe(IOleDocumentView *pViewToActivate);
}

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.

View Site Objects


A container's view site object manages the display space for a particular view of a document. In addition to
supporting the standard IOleInPlaceSite interface, a view site also generally implements IContinueCallback for
programmatic printing control. (Note that the view object never queries for IContinueCallback so it can actually be
implemented on any object the container desires.)
A container that supports multiple views must be able to create multiple view site objects within the document
site. This provides each view with separate activation and deactivation services as provided through
IOleInPlaceSite .

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

Container Help >

Object Help >

For example, when a Word section is active in the Office Binder, then the Help menu would appear as follows:
Help

Binder Help >

Word 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:

interface IPrint : IUnknown


{
HRESULT SetInitialPageNum([in] LONG nFirstPage);
HRESULT GetPageInfo(
[out] LONG *pnFirstPage,
[out] LONG *pcPages);
HRESULT Print(
[in] DWORD grfFlags,
[in,out] DVTARGETDEVICE **pptd,
[in,out] PAGESET ** ppPageSet,
[in,out] STGMEDIUM **ppstgmOptions,
[in] IContinueCallback* pCallback,
[in] LONG nFirstPage,
[out] LONG *pcPagesPrinted,
[out] LONG *pnPageLast);
};

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:

interface IOleCommandTarget : IUnknown


{
HRESULT QueryStatus(
[in] GUID *pguidCmdGroup,
[in] ULONG cCmds,
[in,out][size_is(cCmds)] OLECMD *prgCmds,
[in,out] OLECMDTEXT *pCmdText);
HRESULT Exec(
[in] GUID *pguidCmdGroup,
[in] DWORD nCmdID,
[in] DWORD nCmdExecOpt,
[in] VARIANTARG *pvaIn,
[in,out] VARIANTARG *pvaOut);
}

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.

interface IOleDocument : IUnknown


{
HRESULT CreateView(
[in] IOleInPlaceSite *pIPSite,
[in] IStream *pstm,
[in] DWORD dwReserved,
[out] IOleDocumentView **ppView);

HRESULT GetDocMiscStatus([out] DWORD *pdwStatus);

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).

Requirements for Active Documents


An active document that can be displayed in an active document container must:
Use OLE's Compound Files as its storage mechanism by implementing IPersistStorage .
Support the basic embedding features of OLE Documents, including Create From File . This necessitates
the interfaces IPersistFile , IOleObject , and IDataObject .
Support one or more views, each of which is capable of in-place activation. That is, the views must support
the interface IOleDocumentView as well as the interfaces IOleInPlaceObject and IOleInPlaceActiveObject
(using the container's IOleInPlaceSite and IOleInPlaceFrame interfaces).
Support the standard active document interfaces IOleDocument , IOleCommandTarget , and IPrint .
Knowledge of when and how to use the container-side interfaces is implied in these requirements.

Requirements for View Objects


An active document can create one or more views of its data. Functionally, these views are like ports onto a
particular method for displaying the data. If an active document only supports a single view, the active document
and that single view can be implemented using a single class. IOleDocument::CreateView returns the same object's
IOleDocumentView interface pointer.

To be represented within an active document container, a view component must support IOleInPlaceObject and
IOleInPlaceActiveObject in addition to IOleDocumentView :

interface IOleDocumentView : IUnknown


{
HRESULT SetInPlaceSite([in] IOleInPlaceSite *pIPSite);
HRESULT GetInPlaceSite([out] IOleInPlaceSite **ppIPSite);
HRESULT GetDocument([out] IUnknown **ppunk);
[input_sync] HRESULT SetRect([in] LPRECT prcView);
HRESULT GetRect([in] LPRECT prcView);
[input_sync] HRESULT SetRectComplex(
[in] LPRECT prcView,
[in] LPRECT prcHScroll,
[in] LPRECT prcVScroll,
[in] LPRECT prcSizeBox);
HRESULT Show([in] BOOL fShow);
HRESULT UIActivate([in] BOOL fUIActivate);
HRESULT Open(void);
HRESULT CloseView([in] DWORD dwReserved);
HRESULT SaveViewState([in] IStream *pstm);
HRESULT ApplyViewState([in] IStream *pstm);
HRESULT Clone(
[in] IOleInPlaceSite *pIPSiteNew,
[out] IOleDocumentView **ppViewNew);
}

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.

Passing Parameters in Automation


One difficulty in creating Automation methods is helping to provide a uniform "safe" mechanism to pass data
between automation servers and clients. Automation uses the VARIANT type to pass data. The VARIANT type is
a tagged union. It has a data member for the value (this is an anonymous C++ union) and a data member
indicating the type of information stored in the union. The VARIANT type supports a number of standard data
types: 2- and 4-byte integers, 4- and 8-byte floating-point numbers, strings, and Boolean values. In addition, it
supports the HRESULT (OLE error codes), CURRENCY (a fixed-point numeric type), and DATE (absolute date
and time) types, as well as pointers to IUnknown and IDispatch interfaces.
The VARIANT type is encapsulated in the COleVariant class. The supporting CURRENCY and DATE classes are
encapsulated in the COleCurrency and COleDateTime classes.

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.

What do you want to know more about


Automation Clients
Automation Servers
OLE
Active Technology

What do you want to do


Add an Automation class
Use type libraries
Access automation servers
Write automation clients in C++

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.

Support for Automation Servers


Visual C++ and the MFC framework provide extensive support for Automation servers. They handle much of the
overhead involved in making an Automation server, so you can focus your efforts on the functionality of your
application.
The framework's principal mechanism for supporting Automation is the dispatch map, a set of macros that
expands into the declarations and calls needed to expose methods and properties for OLE. A typical dispatch
map looks like this:

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.

An Implemented Connection Point


MFC implements this model in the CConnectionPoint and CCmdTarget classes. Classes derived from
CConnectionPoint implement the IConnectionPoint interface, used to expose connection points to other objects.
Classes derived from CCmdTarget implement the IConnectionPointContainer interface, which can enumerate all of
an object's available connection points or find a specific connection point.
For each connection point implemented in your class, you must declare a connection part that implements the
connection point. If you implement one or more connection points, you must also declare a single connection map
in your class. A connection map is a table of connection points supported by the ActiveX control.
The following examples demonstrate a simple connection map and one connection point. The first example
declares the connection map and point; the second example implements the map and point. Note that CMyClass
must be a CCmdTarget -derived class. In the first example, code is inserted in the class declaration, under the
protected section:

class CMyClass : public CCmdTarget


{
protected:
// Connection point for ISample interface
BEGIN_CONNECTION_PART(CMyClass, SampleConnPt)
CONNECTION_IID(IID_ISampleSink)
END_CONNECTION_PART(SampleConnPt)

DECLARE_CONNECTION_MAP()

The BEGIN_CONNECTION_PART and END_CONNECTION_PART macros declare an embedded class,


XSampleConnPt (derived from CConnectionPoint ), that implements this particular connection point. If you want to
override any CConnectionPoint member functions or add member functions of your own, declare them between
these two macros. For example, the CONNECTION_IID macro overrides the CConnectionPoint::GetIID member
function when placed between these two macros.
In the second example, code is inserted in the control's implementation file (.cpp file). This code implements the
connection map, which includes the connection point, SampleConnPt :

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.

A Connection Point Implemented with MFC


Usually, connection points support "multicasting" — the ability to broadcast to multiple sinks connected to the
same interface. The following example fragment demonstrates how to multicast by iterating through each sink on
a connection point:

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

Web Sites for More Information


For additional information about Microsoft Internet technology, see the Microsoft Developer Network (MSDN)
Web site. (Links may change without notice.)
This Web site for developers contains information on using Microsoft development tools and technologies, and
top stories about recent and upcoming conferences. From this page, you can jump to many related developer
sites, including the .NET, and XML Developer Centers. You can also download beta SDKs and samples.
The World Wide Web Consortium (W3C) publishes specifications for HTML, HTTP, CGI, and other World Wide
Web technologies.

More Internet Help


The OLE section of the Windows SDK contains additional information about OLE programming. This information
provides details about using the Win32 WinInet functions directly, rather than through the MFC classes. It also
contains overview information about Internet technologies.
Internet-Related MFC Classes
3/4/2019 • 2 minutes to read • Edit Online

For information about Internet-related classes and functions, see:

Global functions
AfxParseURL
AfxGetInternetHandleType

ActiveX control classes


COleControl

Active document classes


CDocObjectServer
CDocObjectServerItem

Asynchronous moniker classes


CAsyncMonikerFile
CDataPathProperty

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

For information on programming with a specific Internet technology, see:


WinInet

Overviews WinInet (HTTP, FTP, Gopher)

WinInet Basics

Win32 Internet Extensions (WinInet)

How WinInet Makes It Easier to Create Internet Client


Applications

How MFC Makes It Easier to Create Internet Client


Applications

Steps in creating WinInet applications Prerequisites for Internet Client Classes

Writing an Internet Client Application Using MFC WinInet


Classes

Steps in a Typical Internet Client Application

Steps in a Typical FTP Client Application

Steps in a Typical HTTP Client Application

Steps in a Typical Gopher Client Application

Steps in a Typical HTTP Client Application

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.

The following categories of tasks are listed in this topic:


ActiveX Controls, Documents and Asynchronous Moniker Tasks
WinInet Tasks

What do you want to do


ActiveX Controls, Documents and Asynchronous Moniker Tasks
Learn about Asynchronous Monikers
Learn about ActiveX controls in the Internet context
Optimize an ActiveX control
WinInet Tasks
Learn about WinInet, the Win32 API functions for Internet access
Review what's involved with WinInet programming
Write an Internet client application, using MFC WinInet classes
Write an FTP client application
Write an HTTP client application
Write a Gopher client application

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.

Internet Data Download Services


Data can be downloaded over the Internet using common protocols: HTTP, FTP, and gopher. The MFC WinInet
classes make it easy to transfer data using HTTP, FTP, and gopher protocols by abstracting the TCP/IP and WinSock
protocols. The MFC asynchronous moniker classes provide a way to download files without blocking and to render
large objects asynchronously. For more information, see Win32 Internet Extensions (WinInet).

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).

Create a Very Simple Browser


#include <afxinet.h>

void DisplayPage(LPCTSTR pszURL)


{
CInternetSession session(_T("My Session"));
CStdioFile *pFile = NULL;
CHAR szBuff[1024];
//use a URL and print a Web page to the console
pFile = session.OpenURL(pszURL);
while (pFile->Read(szBuff, 1024) > 0)
{
printf_s("%1023s", szBuff);
}
delete pFile;
session.Close();
}

Download a Web Page


//this code excerpt also demonstrates try/catch exception handling
#include <afxinet.h>

void DisplayHttpPage(LPCTSTR pszServerName, LPCTSTR pszFileName)


{
CInternetSession session(_T("My Session"));
CHttpConnection *pServer = NULL;
CHttpFile *pFile = NULL;
try
{
CString strServerName;
INTERNET_PORT nPort = 80;
DWORD dwRet = 0;

pServer = session.GetHttpConnection(pszServerName, nPort);


pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, pszFileName);
pFile->SendRequest();
pFile->QueryInfoStatusCode(dwRet);

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>

void GetFtpFile(LPCTSTR pszServerName, LPCTSTR pszRemoteFile, LPCTSTR pszLocalFile)


{
CInternetSession session(_T("My FTP Session"));
CFtpConnection *pConn = NULL;

pConn = session.GetFtpConnection(pszServerName);
//get the file
if (!pConn->GetFile(pszRemoteFile, pszLocalFile))
{
//display an error
}
delete pConn;
session.Close();
}

Retrieve a Gopher Directory


#include <afxinet.h>

void RetrieveGopherFile(LPCTSTR pszGopherSite, LPCTSTR pszFile)


{
CInternetSession session(_T("My Gopher Session"));
CGopherConnection *pConn = NULL;
CGopherFileFind *pFile;

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.

Display Progress Information While Transferring Files


For example, if you write an application that creates a connection with an FTP server to read a file and also
connects to an HTTP server to get a Web page, you'll have a CInternetSession object, two CInternetConnection
objects (one would be a CFtpSession and the other would be a CHttpSession ), and two CInternetFile objects
(one for each connection). If you used default values for the dwContext parameters, you would not be able to
distinguish between the OnStatusCallback invocations that indicate progress for the FTP connection and the
invocations that indicate progress for the HTTP connection. If you specify a dwContext ID, which you can later
test for in OnStatusCallback , you will know which operation generated the callback.
See also
MFC Internet Programming Basics
Win32 Internet Extensions (WinInet)
HTML Basics
3/31/2020 • 2 minutes to read • Edit Online

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>

7. From the File menu, choose Save .


8. Switch back to your browser and refresh the page.
The words will appear in the client area of your browser's window. Notice that your carriage return is
ignored. If you want to have a line break, you must include a <BR> tag after the first line.
For all the steps that follow, insert the text anywhere between <BODY> and </BODY> to add to the body of
your document.
9. Add a header:
<H3>Here's the big picture</H3>

10. Add an image, using a .gif file saved in the same directory as your page:

<IMG src="yourfile.gif">

11. Add a list:

<UL>Make me an unordered list.


<LI>One programmer</LI>
<LI>Ten SDKs</LI>
<LI>Great Internet Apps</LI>
</UL>

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.

A document-based application. Add support to FTP a file. Use WinInet or asynchronous


monikers.

See the following topics for details to get you started:


Application Design Choices
Writing MFC Applications
ActiveX Controls on the Internet
Upgrading an Existing ActiveX Control
Asynchronous Monikers on the Internet
Testing Internet Applications
Internet Security

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.

Intranet Versus Internet


Many applications run on the Internet and are accessible to anyone with a browser and Internet access. Businesses
are also implementing intranets, which are company-wide networks using TCP/IP protocols and Web browsers.
Intranets offer an easily upgradeable, central source for company-wide information. They can be used for
upgrading software, for delivering and tabulating surveys, for customer support, and for information delivery. The
following table compares features of the Internet and intranets.

IN T ERN ET IN T RA N ET

Low bandwidth High bandwidth

Reduced security of data and systems Controlled access to data and systems

Minimal control of content High control of content

Client or Server Application


Your application may run on a client computer or on a server computer. Your application may also be stored on a
server, and then downloaded across the Internet and run on a client computer. MFC WinInet classes are used for
client applications to download files. MFC and asynchronous moniker classes are used to download files and
control properties. Classes for ActiveX controls and Active documents are used for client applications and for
applications that are downloaded from the server to run on a client.

The Web Page: HTML, Active Documents, ActiveX Controls


Microsoft offers several ways of providing content on a Web page. Web pages can use standard HTML or HTML
extensions, such as the object tag, to provide dynamic content such as ActiveX controls.
Web browsers typically display HTML pages. Active documents can also display your application's data in the
simple point-and-click interface of a COM-enabled browser. Your Active document server can display your
document, full frame in the entire client area, with its own menus and toolbars.
ActiveX controls you write can be downloaded asynchronously from the server and displayed on a Web page. You
can use a scripting language such as VBScript to perform client-side validation before sending information to the
server.

Browser or Stand-Alone Application


You can write ActiveX controls that are embedded in an HTML page and Active document servers that are viewed
in a browser. You can write HTML pages that contain a button to submit a request to run your ISAPI application on
a Web server. You can write a stand-alone application that uses Internet protocols to download files and display
the information to your user, without ever using a browser application.

COM on the Internet


ActiveX controls, Active documents, and asynchronous monikers all use COM (Component Object Model)
technologies.
ActiveX controls provide dynamic content to documents and pages on Internet sites. With COM, you can build
ActiveX controls and full-frame documents using Active documents.
Asynchronous monikers provide features to enable a control to perform well in an Internet environment, including
an incremental or progressive means to download data. Controls must also work well with other controls that may
also be retrieving their data asynchronously at the same time.

Client Data Download Services


Two sets of APIs that will help transfer data to your client are WinInet and asynchronous monikers. If you have
large .gif and .avi files and ActiveX controls on your HTML page, you can increase the responsiveness to the user
by downloading asynchronously, either by using asynchronous monikers or using WinInet asynchronously.
A common task on the Internet is transferring data. If you are already using Active technology (for example, if you
have an ActiveX control), you can use asynchronous monikers to progressively render data as it downloads. You
can use WinInet to transfer data using common Internet protocols like HTTP, FTP, and gopher. Both methods
provide protocol independence, and provide an abstract layer to using WinSock and TCP/IP. You can still use
WinSock directly.
The following table summarizes several ways of using MFC to transfer data across the Internet.

USE T H IS P ROTO C O L UN DER T H ESE C O N DIT IO N S USIN G T H ESE C L A SSES

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.

WinSock For maximum efficiency and control. CSocket, CAsyncSocket


Requires understanding of sockets and
TCP/IP protocols.

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.

Making Your Existing Controls Internet-Friendly


Designing a control that will work well in an Internet environment requires consideration for the relatively low
transmission rates on the Internet. You can use your existing controls; however, there are steps you should take
to make your code size smaller and to make your control properties download asynchronously.
To improve performance of your controls, follow these tips on efficiency considerations:
Implement the techniques described in the article ActiveX Controls: Optimization.
Consider how a control is instantiated.
Be asynchronous; don't hold up other programs.
Download data in small blocks.
When downloading large streams such as bitmaps or video data, access a control's data asynchronously
in cooperation with the container. Retrieve the data in an incremental or progressive fashion, working
cooperatively with other controls that may also be retrieving data. Code can also be downloading
asynchronously.
Download code and properties in the background.
Become user-interface active as quickly as possible.
Consider how persistent data is stored, both properties and large data BLOBs (such as a bitmap image or
video data).
Controls with significant amounts of persistent data, such as large bitmaps or AVI files, require careful
attention to downloading method. A document or page can become visible as soon as possible, and allow
the user to interact with the page while controls retrieve data in the background.
Write efficient routines to keep code size and run time down.
Small button and label controls, with only a few bytes of persistent data, are suitable for use in the
Internet environment and work well inside browsers.
Consider progress is communicated to the container.
Notify the container of progress in the asynchronous download, including when the user can start to
interact with a page, and when the download is complete. The container can display progress (such as
percent complete) to the user.
Consider how controls are registered on the client computer.

Creating a New ActiveX Control


When creating a new control using the Application Wizard, you can choose to enable support for asynchronous
monikers as well as other optimizations. To add support to download control properties asynchronously, follow
these steps:
To create your project using the MFC ActiveX Control Wizard
1. Click New on the File menu.
2. Select MFC ActiveX Control Wizard from the Visual Studio C++ projects and name your project.
3. On the Control Settings page, select Loads proper ties asynchronously . Selecting this option sets up
the ready state property and the ready state changed event for you.
You can also select other optimizations, such as Windowless activation , which is described in ActiveX
Controls: Optimization.
4. Choose Finish to create the project.
To create a class derived from CDataPathProperty
1. Create a class derived from CDataPathProperty .
2. In each of your source files that includes the header file for your control, add the header file for this class
before it.
3. In this class, override OnDataAvailable . This function is called whenever data is available for display. As
data becomes available, you can handle it any way you choose, for example by progressively rendering it.
The code excerpt below is a simple example of progressively displaying data in an edit control. Note the
use of flag BSCF_FIRSTDATANOTIFICATION to clear the edit control.
void CMyDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
CListCtrl list_ctrl;
CEdit *edit = list_ctrl.GetEditControl();
if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) && edit->m_hWnd)
{
edit->SetSel(0, -1);
edit->Clear();
}

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:

if (bscfFlag & BSCF_LASTDATANOTIFICATION)


{
GetControl()->InternalSetReadyState(READYSTATE_COMPLETE);
}

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();
}

void CMFCActiveXControlCtrl::SetEditControlText(LPCTSTR newVal)


{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

Load(newVal, EditControlText);
SetModifiedFlag();
}

6. In DoPropExchange, add the following line:

PX_DataPath(pPX, _T("DataPath"), EditControlText);

7. Override ResetData to notify the property to reset its control by adding this line:

EditControlText.ResetData();

Deciding Whether to Derive from CDataPathProperty or


CCachedDataPathProperty
The previous example describes steps for deriving your control's property from CDataPathProperty . This is a
good choice if you are downloading real-time data that frequently changes, and for which you do not need to
keep all the data, but only the current value. An example is a stock ticker control.
You can also derive from CCachedDataPathProperty . In this case, the downloaded data is cached in a memory file.
This is a good choice if you need to keep all the downloaded data — for example, a control that progressively
renders a bitmap. In this case, the class has a member variable containing your data:
CMemFile m_Cache;

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.

void CMyCachedDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)


{
CCachedDataPathProperty::OnDataAvailable(dwSize, bscfFlag);
GetControl()->InvalidateControl();
}

Downloading Data Asynchronously Using ActiveX Controls


Downloading data over a network should be done asynchronously. The advantage of doing so is that if a large
amount of data is transferred or if the connection is slow, the download process will not block other processes
on the client.
Asynchronous monikers provide a way to download data asynchronously over a network. A Read operation on
an Asynchronous moniker returns immediately, even if the operation has not been completed.
For example, if only 10 bytes are available and Read is called asynchronously on a 1K file, Read does not block,
but returns with the currently available 10 bytes.
You implement asynchronous monikers using the CAsyncMonikerFile class. However, ActiveX controls can use
the CDataPathProperty class, which is derived from CAsyncMonikerFile , to help implement asynchronous control
properties.

Displaying a Control on a Web Page


Here is an example of an object tag and attributes for inserting a control on a Web page.

<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>

Updating an Existing OLE Control to Use New ActiveX Control


Features
If your OLE control was created with a version of Visual C++ prior to 4.2, there are steps you can take to improve
its performance and enhance its functionality. For a detailed discussion of these changes, see ActiveX Controls:
Optimization.
If you are adding asynchronous property support to an existing control, you will need to add the ready state
property and the ReadyStateChange event yourself. In the constructor for your control, add:

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.

Packaging Code for Downloading


For more information on this subject, see Packaging ActiveX Controls.
The CODEBASE Tag
ActiveX controls are embedded in Web pages using the <OBJECT> tag. The CODEBASE parameter of the <OBJECT>
tag specifies the location from which to download the control. CODEBASE can point at a number of different file
types successfully.
Using the CODEBASE Tag with an OCX File

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

The <OBJECT> Tag


The following example illustrates using the <OBJECT> tag to package the MFC Spindial sample control.
<OBJECT ID="Spindial1" WIDTH=100 HEIGHT=51
CLASSID="CLSID:06889605-B8D0-101A-91F1-00608CEAD5B3"
CODEBASE="http://example.microsoft.com/spindial.cab#Version=1,0,0,001">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2646">
<PARAM NAME="_ExtentY" VALUE="1323">
<PARAM NAME="_StockProps" VALUE="0">
<PARAM NAME="NeedlePosition" VALUE="2">
</OBJECT>

In this case, spindial.cab will contain two files, spindial.ocx and spindial.inf. The following command will build the
cabinet file:

C:\CabDevKit\cabarc.exe -s 6144 N spindial.cab spindial.ocx spindial.inf

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.

Marking a Control Safe for Scripting and Initializing


ActiveX controls used in Web pages should be marked as safe for scripting and safe for initializing if they are in
fact safe. A safe control will not perform disk IO or access the memory or registers of a machine directly.
Controls can be marked as safe for scripting and safe for initializing via the registry. Modify DllRegisterServer to
add entries similar to the following to mark the control as safe for scripting and persistence in the registry. An
alternative method is to implement IObjectSafety .
You will define GUIDs (Globally Unique Identifiers) for your control to mark it safe for scripting and for persistence.
Controls that can be safely scripted will contain a registry entry similar to the following:

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.

<OBJECT CLASSID = "clsid:5220cb21-c88d-11cf-b347-00aa00a28331">


<PARAM NAME="LPKPath" VALUE="relative URL to .LPK file">
</OBJECT>

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">

<EMBED SRC = "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.

Managing the Palette


Containers determine the palette and make it available as an ambient property, DISPID_AMBIENT_PALETTE . A
container (for example, Internet Explorer) chooses a palette that is used by all ActiveX controls on a page to
determine their own palette. This prevents display flickering and presents a consistent appearance.
A control can override OnAmbientPropertyChange to handle notification of changes to the palette.
A control can override OnGetColorSet to return a color set to draw the palette. Containers use the return value to
determine if a control is palette-aware.
Under OCX 96 guidelines, a control must always realize its palette in the background.
Older containers that do not use the ambient palette property will send WM_QUERYNEWPALETTE and
WM_PALETTECHANGED messages. A control can override OnQueryNewPalette and OnPaletteChanged to handle
these messages.

Internet Explorer Browser Safety Levels and Control Behavior


A browser has options for safety level, configurable by the user. Because Web pages can contain active content that
might potentially harm a user's computer, browsers allow the user to select options for safety level. Depending on
the way a browser implements safety levels, a control may not be downloaded at all, or will display a certificate or
a warning message to allow the user to choose at run time whether or not to download the control. The behavior
of ActiveX controls under high, medium, and low safety levels on Internet Explorer is listed below.
High Safety Mode
Unsigned controls will not be downloaded.
Signed controls will display a certificate if untrusted (a user can choose an option to always trust code from
this certificate owner from now on).
Only controls marked as safe will have persistent data and/or be scriptable.
Medium Safety Mode
Unsigned controls will display a warning before downloading.
Signed controls will display a certificate if untrusted.
Controls not marked as safe will display a warning.
Low Safety Mode
Controls are downloaded without warning.
Scripting and persistence occur without warning.

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.

Advantages of Asynchronous Monikers


You can use asynchronous monikers to:
Download code and files without blocking.
Download properties in ActiveX controls without blocking.
Receive notifications of downloading progress.
Track progress and ready state information.
Provide status information to the user about progress.
Allow the user to cancel a download at any time.

MFC Classes for Asynchronous Monikers


CAsyncMonikerFile is derived from CMonikerFile, which in turn is derived from COleStreamFile. A
COleStreamFile object represents a stream of data; a CMonikerFile object uses an IMoniker to obtain the data,
and a CAsyncMonikerFile object does so asynchronously.
Asynchronous monikers are used primarily in Internet-enabled applications and ActiveX controls to provide a
responsive user interface during file transfers. A prime example of this is the use of CDataPathProperty to
provide asynchronous properties for ActiveX controls.

MFC Classes for Data Paths in ActiveX Controls


The MFC classes CDataPathProperty and CCachedDataPathProperty implement ActiveX control properties that
can be loaded asynchronously. Asynchronous properties are loaded after synchronous initiation. Asynchronous
ActiveX controls repeatedly invoke a callback to indicate availability of new data during a lengthy property
exchange process.
CDataPathProperty is derived from CAsyncMonikerFile . CCachedDataPathProperty is derived from
CDataPathProperty . To implement asynchronous properties in your ActiveX controls, derive a class from
CDataPathProperty or CCachedDataPathProperty , and override OnDataAvailable and other notifications you wish
to receive.
To download a file using asynchronous monikers
1. Declare a class derived from CAsyncMonikerFile.
2. Override OnDataAvailable to display the data.
3. Override other member functions, including OnProgress, OnStartBinding, and OnStopBinding.
4. Declare an instance of this class and use it to open URLs.
For information about downloading asynchronously in an ActiveX control, see ActiveX Controls on the Internet.

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 .

Container/Server COM Components


Describes the steps necessary to incorporate optional advanced features into existing container applications.
The Component Object Model
Describes using OLE without MFC.

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.

Portions of OLE Not Implemented by the Class Library


A few interfaces and features of OLE are not directly provided by MFC. If you want to use these features, you can
call the OLE API directly.
IMoniker Interface The IMoniker interface is implemented by the class library (for example, the COleServerItem
class) but has not previously been exposed to the programmer. For more information about this interface, see OLE
Moniker Implementations in the OLE section of the Windows SDK. However, see also class CMonikerFile and
CAsyncMonikerFile.
IUnknown and IMarshal Interfaces The IUnknown interface is implemented by the class library but is not exposed
to the programmer. The IMarshal interface is not implemented by the class library but is used internally.
Automation servers built using the class library already have marshaling capabilities built in.
Docfiles (Compound Files) Compound files are partially supported by the class library. None of the functions that
directly manipulate compound files beyond creation are supported. MFC uses class COleFileStream to support
manipulation of streams with standard file functions. For more information, see the article Containers: Compound
Files.
In-Process Servers and Object Handlers In-process servers and object handlers allow implementation of visual
editing data or full Component Object Model (COM) objects in a dynamic-link library (DLL). To do this, you can
implement your DLL by calling the OLE API directly. However, if you are writing an Automation server and your
server has no user interface, you can use AppWizard to make your server an in-process server and put it
completely into a DLL. For more information about these topics, see Automation Servers.

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_CHANGED The OLE item's appearance has changed.

OLE_SAVED The OLE item has been saved.

OLE_CLOSED The OLE item has been closed.

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:

W H EN F IRST A RGUM EN T IS SEC O N D A RGUM EN T

OLE_SAVED or OLE_CLOSED Is not used.

OLE_CHANGED Specifies the aspect of the OLE item that has changed.

OLE_CHANGED_STATE Describes the state being entered (emptyState, loadedState,


openState, activeState, or activeUIState).

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.

Components of a Compound File


The OLE implementation of compound files uses three object types: stream objects, storage objects, and
ILockBytes objects. These objects are similar to the components of a standard file system in the following ways:

Stream objects, like files, store data of any type.


Storage objects, like directories, can contain other storage and stream objects.
LockBytes objects represent the interface between the storage objects and the physical hardware. They
determine how the actual bytes are written to whatever storage device the LockBytes object is accessing,
such as a hard drive or an area of global memory. For more information about LockBytes objects and the
ILockBytes interface, see the OLE Programmer's Reference.

Advantages and Disadvantages of Compound Files


Compound files provide benefits not available with earlier methods of file storage. They include:
Incremental file accessing.
File access modes.
Standardization of file structure.
The potential disadvantages of compound files — large size and performance issues relating to storage on floppy
discs — should be considered when deciding whether to use them in your application.
Incremental Access to Files
Incremental access to files is an automatic benefit of using compound files. Because a compound file can be
viewed as a "file system within a file," individual object types, such as stream or storage, can be accessed without
the need to load the entire file. This can dramatically decrease the time an application needs to access new objects
for editing by the user. Incremental updating, based on the same concept, offers similar benefits. Instead of saving
the entire file just to save the changes made to one object, OLE saves only the stream or storage object edited by
the user.
File Access Modes
Being able to determine when changes to objects in a compound file are committed to disk is another benefit of
using compound files. The mode in which files are accessed, either transacted or direct, determines when changes
are committed.
Transacted mode uses a two-phase commit operation to make changes to objects in a compound file,
thereby keeping both the old and the new copies of the document available until the user chooses to either
save or undo the changes.
Direct mode incorporates changes to the document as they are made, without the ability to later undo
them.
For more information about access modes, see the OLE Programmer's Reference.
Standardization
The standardized structure of compound files allows different OLE applications to browse through compound files
created by your OLE application with no knowledge of the application that actually created the file.
Size and Performance Considerations
Because of the complexity of the compound file storage structure and the ability to save data incrementally, files
using this format tend to be larger than other files using unstructured or "flat file" storage. If your application
frequently loads and saves files, using compound files can cause the file size to increase much more quickly than
noncompound files. Because compound files can get large, the access time for files stored on and loaded from
floppy disks can also be affected, resulting in slower access to files.
Another issue that affects performance is compound-file fragmentation. The size of a compound file is determined
by the difference between the first and last disk sectors used by the file. A fragmented file can contain many areas
of free space that do not contain data, but are counted when calculating the size. During the lifetime of a
compound file, these areas are created by the insertion or deletion of storage objects.

Using Compound Files Format for Your Data


After successfully creating an application that has a document class derived from COleDocument , ensure that your
main document constructor calls EnableCompoundFile . When the application wizard creates OLE container
applications, this call is inserted for you.
In the OLE Programmer's Reference, see IStream, IStorage, and ILockBytes.

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

Menu additions for containers Menus and Resources: Container Additions

Additional resources for containers Menus and Resources: Container Additions

Painting linked or embedded items Container sample

New dialog boxes for containers Dialog Boxes in OLE

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

Creating a Container/Server Application


A container/server application is an application that acts as both a container and a server. Microsoft Word for
Windows is an example of this. You can embed Word for Windows documents in other applications, and you can
also embed items in Word for Windows documents. The process for modifying your container application to be
both a container and a full server (you cannot create a combination container/miniserver application) is similar to
the process for creating a full server.
The article Servers: Implementing a Server lists a number of tasks required to implement a server application. If
you convert a container application to a container/server application, then you need to perform some of those
same tasks, adding code to the container. The following lists the important things to consider:
The container code created by the application wizard already initializes the OLE subsystem. You will not
need to change or add anything for that support.
Wherever the base class of a document class is COleDocument , change the base class to COleServerDoc .
Override COleClientItem::CanActivate to avoid editing items in place while the server itself is being used
to edit in place.
For example, the MFC OLE sample OCLIENT has embedded an item created by your container/server
application. You open the OCLIENT application and in-place edit the item created by your container/server
application. While editing your application's item, you decide you want to embed an item created by the
MFC OLE sample HIERSVR. To do this, you cannot use in-place activation. You must fully open HIERSVR to
activate this item. Because the Microsoft Foundation Class Library does not support this OLE feature,
overriding COleClientItem::CanActivate allows you to check for this situation and prevent a possible run-
time error in your application.
If you are creating a new application and want it to function as a container/server application, choose that option
in the OLE Options dialog box in the application wizard and this support will be created automatically. For more
information, see the article Overview: Creating an ActiveX Control Container. For information about MFC
samples, see MFC Samples.
Note that you cannot insert an MDI application into itself. An application that is a container/server cannot be
inserted into itself unless it is an SDI application.

Links to Embedded Objects


The Links to Embedded Objects feature enables a user to create a document with an OLE link to an embedded
object inside your container application. For example, create a document in a word processor containing an
embedded spreadsheet. If your application supports links to embedded objects, it could paste a link to the
spreadsheet contained in the word processor's document. This feature allows your application to use the
information contained in the spreadsheet without knowing where the word processor originally got it.
To link to embedded objects in your application
1. Derive your document class from COleLinkingDoc instead of COleDocument .
2. Create an OLE class ID (CLSID ) for your application by using the Class ID Generator included with the OLE
Development Tools.
3. Register the application with OLE.
4. Create a COleTemplateServer object as a member of your application class.
5. In your application class's InitInstance member function, do the following:
Connect your COleTemplateServerobject to your document templates by calling the object's
ConnectTemplate member function.
Call the COleTemplateServer::RegisterAll member function to register all class objects with the OLE
system.
Call COleTemplateServer::UpdateRegistry . The only parameter to UpdateRegistry should be
OAT_CONTAINER if the application is not launched with the "/Embedded" switch. This registers the
application as a container that can support links to embedded objects.
If the application is launched with the "/Embedded" switch, it should not show its main window,
similar to a server application.
The MFC OLE sample OCLIENT implements this feature. For an example of how this is done, see the InitInstance
function in the OCLIENT.CPP file of this sample application.

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

Creating Data Objects


Data objects are used by the destination application — either the client or the server. A data object in the
destination application is one end of a connection between the source application and the destination application.
A data object in the destination application is used to access and interact with the data in the data source.
There are two common situations where a data object is needed. The first situation is when data is dropped in your
application using drag and drop. The second situation is when Paste or Paste Special is chosen from the Edit menu.
In a drag-and-drop situation, you do not need to create a data object. A pointer to an existing data object will be
passed to your OnDrop function. This data object is created by the framework as part of the drag-and-drop
operation and will also be destroyed by it. This is not always the case when pasting is done by another method. For
more information, see Destroying Data Objects.
If the application is performing a paste or paste special operation, you should create a COleDataObject object and
call its AttachClipboard member function. This associates the data object with the data on the Clipboard. You can
then use this data object in your paste function.

Destroying Data Objects


If you follow the scheme described in Creating Data Objects, destroying data objects is a trivial aspect of data
transfers. The data object that was created in your paste function will be destroyed by MFC when your paste
function returns.
If you follow another method of handling paste operations, make sure the data object is destroyed after your paste
operation is complete. Until the data object is destroyed, it will be impossible for any application to successfully
copy data to the Clipboard.

Creating Data Sources


Data sources are used by the source of the data transfer, which can be either the client or the server side of the
data transfer. A data source in the source application is one end of a connection between the source application
and the destination application. A data object in the destination application is used to interact with the data in the
data source.
Data sources are created when an application needs to copy data to the Clipboard. A typical scenario runs like this:
1. The user selects some data.
2. The user chooses Copy (or Cut ) from the Edit menu or begins a drag-and-drop operation.
3. Depending on the design of the program, the application creates either a COleDataSource object or an
object from a class derived from COleDataSource .
4. The selected data is inserted into the data source by calling one of the functions in the
COleDataSource::CacheData or COleDataSource::DelayRenderData groups.

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.

Destroying Data Sources


Data sources must be destroyed by the application currently responsible for them. In situations where you hand
the data source to OLE, such as calling COleDataSource::DoDragDrop, you need to call pDataSrc->InternalRelease .
For example:

void CMyListView::OnLvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)


{
UNREFERENCED_PARAMETER(pResult);

LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);

CMyDataSource* pDataSrc = new CMyDataSource();


if (NULL != pDataSrc)
{
pDataSrc->Initialize(pNMLV, this);
pDataSrc->DelayRenderData((CLIPFORMAT)RegisterClipboardFormat(_T("TIGroupFiles")));
pDataSrc->DoDragDrop();
pDataSrc->InternalRelease();
}
}

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

Inserting Data into a Data Source


How data is inserted into a data source depends on whether the data is supplied immediately or on demand, and
in which medium it is supplied. The possibilities are as follows.
Supplying Data Immediately (Immediate Rendering)
Call COleDataSource::CacheGlobalData repeatedly for every Clipboard format in which you are supplying
data. Pass the Clipboard format to be used, a handle to the memory containing the data and, optionally, a
FORMATETC structure describing the data.
-or-
If you want to work directly with STGMEDIUM structures, you call COleDataSource::CacheData instead of
COleDataSource::CacheGlobalData in the option above.

Supplying Data on Demand (Delayed Rendering)


This is an advanced topic.
Call COleDataSource::DelayRenderData repeatedly for every Clipboard format in which you are supplying
data. Pass the Clipboard format to be used and, optionally, a FORMATETC structure describing the data.
When the data is requested, the framework will call COleDataSource::OnRenderData , which you must
override.
-or-
If you use a object to supply the data, call COleDataSource::DelayRenderFileData instead of
CFile
COleDataSource::DelayRenderData in the previous option. When the data is requested, the framework will
call COleDataSource::OnRenderFileData , which you must override.

Determining the Formats Available in a Data Object


Before an application allows the user to paste data into it, it needs to know if there are formats on the Clipboard
that it can handle. To do this, your application should do the following:
1. Create a COleDataObject object and a FORMATETC structure.
2. Call the data object's AttachClipboard member function to associate the data object with the data on the
Clipboard.
3. Do one of the following:
Call the data object's IsDataAvailable member function if there are only one or two formats you
need. This will save you time in cases where the data on the Clipboard supports significantly more
formats than your application.
-or-
Call the data object's BeginEnumFormats member function to start enumerating the formats
available on the Clipboard. Then call GetNextFormat until the Clipboard returns a format your
application supports or there are no more formats.
If you are using ON_UPDATE_COMMAND_UI , you can now enable the Paste and, possibly, Paste Special items
on the Edit menu. To do this, call either CMenu::EnableMenuItem or CCmdUI::Enable . For more information about
what container applications should do with menu items and when, see Menus and Resources: Container
Additions.

Retrieving Data from a Data Object


Once you have decided on a data format, all that remains is to retrieve the data from the data object. To do this,
the user decides where to put the data, and the application calls the appropriate function. The data will be
available in one of the following mediums:

M EDIUM F UN C T IO N TO C A L L

Global Memory ( HGLOBAL ) COleDataObject::GetGlobalData

File ( CFile ) COleDataObject::GetFileData

STGMEDIUM structure ( IStorage ) COleDataObject::GetData

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.

Implement a drop source


To get your application to provide data to a drag-and-drop operation, you implement a drop source. Basic
implementation of a drop source is relatively simple. The first step is to determine what events begin a drag
operation. Recommended user interface guidelines define the beginning of a drag operation as when a
WM_LBUTTONDOWN event occurs on a point inside some selected data. The MFC OLE samples OCLIENT and
HIERSVR follow these guidelines.
If your application is a container and the selected data is a linked or an embedded object of type
COleClientItem , call its DoDragDrop member function. Otherwise, construct a COleDataSource object, initialize it
with the selection, and call the data source object's DoDragDrop member function. If your application is a server,
use COleServerItem::DoDragDrop . For information about customizing standard drag-and-drop behavior, see the
section Customize drag and drop.
If DoDragDrop returns DROPEFFECT_MOVE , delete the source data from the source document immediately.
No other return value from DoDragDrop has any effect on a drop source.
For more information, see OLE data objects and data sources: Creation and destruction and OLE data objects
and data sources: Manipulation.

Implement a drop target


It takes slightly more work to implement a drop target than a drop source, but it's still relatively simple.
To implement an OLE drop target
1. If it isn't already there, add a call to AfxOleInit in your application's InitInstance member function. This
call is required to initialize the OLE libraries.
2. Add a member variable to each view in the application that you want to be a drop target. This member
variable must be of type COleDropTarget or a class derived from it.
3. From your view class's function that handles the WM_CREATE message (typically OnCreate ), call the
new member variable's Register member function. Revoke will be called automatically for you when
your view is destroyed.
4. Override the following functions. If you want the same behavior throughout your application, override
these functions in your view class. If you want to modify behavior in isolated cases or want to enable
dropping on non- CView windows, override these functions in your COleDropTarget -derived class.

O VERRIDE TO A L LO W

OnDragEnter Drop operations to occur in the window. Called when the


cursor first enters the window.

OnDragLeave Special behavior when the drag operation leaves the


specified window.

OnDragOver Drop operations to occur in the window. Called when the


cursor is being dragged across the window.

OnDrop Handling of data being dropped into the specified


window.

OnScrollBy Special behavior for when scrolling is necessary in the


target window.

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.

Customize drag and drop


The default implementation of the drag-and-drop feature is sufficient for most applications. However, some
applications may require you to change this standard behavior. This section explains the steps necessary to
change these defaults. You can use this technique to make applications that don't support compound
documents into drop sources.
If you're customizing standard OLE drag-and-drop behavior, or you have a non-OLE application, you must
create a COleDataSource object to contain the data. When the user starts a drag-and-drop operation, your code
should call the DoDragDrop function from this object instead of from other classes that support drag-and-drop
operations.
Optionally, you can create a COleDropSource object to control the drop and override some of its functions
depending on the type of behavior you want to change. This drop-source object is then passed to
COleDataSource::DoDragDrop to change the default behavior of these functions. These different options allow a
great deal of flexibility in how you support drag-and-drop operations in your application. For more information
about data sources, see the article Data Objects and Data Sources (OLE).
You can override the following functions to customize drag-and-drop operations:
O VERRIDE TO C USTO M IZ E

OnBeginDrag How the drag operation begins after you call DoDragDrop .

GiveFeedback Visual feedback, such as cursor appearance, for different


drop results.

QueryContinueDrag The termination of a drag-and-drop operation. This function


enables you to check modifier key states during the drag
operation.

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:

RESO URC E N A M E USE

IDR_MAINFRAME Used in an MDI application if no file is open, or in an SDI


application regardless of open files. This is the standard menu
used in non-OLE applications.

IDR_<project>TYPE Used in an MDI application if files are open. Used when an


application is running stand-alone. This is the standard menu
used in non-OLE applications.

IDR_<project>TYPE_SRVR_IP Used by the server or container when an object is open in


place.

IDR_<project>TYPE_SRVR_EMB Used by a server application if an object is opened without


using in-place activation.

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

Container Menu Additions


You must add the following items to the Edit menu:

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.

Container Application Accelerator Table Additions


Small changes to a container application's accelerator table resources are necessary if you are supporting in-place
activation. The first change allows the user to press the escape key (ESC) to cancel the in-place editing mode. Add
the following entry to the main accelerator table:
ID K EY TYPE

ID_CANCEL_EDIT_CNTR VK_ESCAPE VIRTKEY

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_FILE_NEW CTRL+N VIRTKEY

ID_FILE_OPEN CTRL+O VIRTKEY

ID_FILE_SAVE CTRL+S VIRTKEY

ID_FILE_PRINT CTRL+P VIRTKEY

ID_NEXT_PANE VK_F6 VIRTKEY

ID_PREV_PANE SHIFT+VK_F6 VIRTKEY

ID_CANCEL_EDIT_CNTR VK_ESCAPE VIRTKEY

String Table Additions for Container Applications


Most of the changes to string tables for container applications correspond to the additional menu items
mentioned in Container Menu Additions. They supply the text displayed in the status bar when each menu item is
displayed. As an example, here are the string-table entries the application wizard generates:

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

Server Menu Additions


Server (component) applications must have menu resources added to support OLE visual editing. The menus used
when the application is run in stand-alone mode do not have to be changed, but you must add two new menu
resources before building the application: one to support in-place activation and one to support the server being
fully open. Both menu resources are used by full- and miniserver applications.
To support in-place activation, you must create a menu resource that is very similar to the menu resource
used when run in stand-alone mode. The difference in this menu is that the File and Window items (and any
other menu items that deal with the application, and not the data) are missing. The container application
will supply these menu items. For more information on, and an example of, this menu-merging technique,
see the article Menus and Resources: Menu Merging.
To support fully open activation, you must create a menu resource nearly identical to the menu resource
used when run in stand-alone mode. The only modification to this menu resource is that some items are
reworded to reflect the fact that the server is operating on an item embedded in a compound document.
In addition to the changes listed in this article, your resource file needs to include AFXOLESV.RC, which is required
for the Microsoft Foundation Class Library implementation. This file is in the MFC\Include subdirectory.

Server Application Accelerator Table Additions


Two new accelerator table resources must be added to server applications; they correspond directly to the new
menu resources previously described. The first accelerator table is used when the server application is activated in
place. It consists of all the entries in the view's accelerator table except those tied to the File and Window menus.
The second table is nearly an exact copy of the view's accelerator table. Any differences parallel changes made in
the fully open menu mentioned in Server Menu Additions.
For an example of these accelerator table changes, compare the IDR_HIERSVRTYPE_SRVR_IP and
IDR_HIERSVRTYPE_SRVR_EMB accelerator tables with IDR_MAINFRAME in the HIERSVR.RC file included in the
MFC OLE sample HIERSVR. The File and Window accelerators are missing from the in-place table and exact copies
of them are in the embedded table.

String Table Additions for Server Applications


Only one string table addition is necessary in a server application — a string to signify that the OLE initialization
failed. As an example, here is the string-table entry that the application wizard generates:

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:

IDR_SERVERTYPE_SRVR_IP MENU PRELOAD DISCARDABLE


BEGIN
POPUP "&Edit S1"
MENUITEM SEPARATOR
POPUP "&Format S2"
MENUITEM SEPARATOR
POPUP "&Help S3"
END

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.

Toolbars and Status Bars


Server applications should create a new toolbar and store its bitmap in a separate file. The application wizard-
generated applications store this bitmap in a file called ITOOLBAR.BMP. The new toolbar replaces the container
application's toolbar when your server's item is activated in place, and should contain the same items as your
normal toolbar, but remove icons representing items on the File and Window menus.
This toolbar is loaded in your COleIPFrameWnd -derived class, created for you by the application wizard. The status
bar is handled by the container application. For more information on the implementation of in-place frame
windows, see Servers: Implementing a Server.

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 the contents of the .reg text file into the registration database. To verify the database or to repair it,
use the registry editor. Take care to avoid deleting essential OLE entries.

Server Initialization
When you create a server application with the application wizard, the wizard completes all initialization tasks for
you automatically. This section describes what you must do if you write a server application manually.
When a server application is launched by a container application, the OLE system DLLs add the "/Embedding"
option to the server's command line. A server application's behavior differs depending on whether it was launched
by a container, so the first thing an application should do when it begins execution is check for the "/Embedding"
or "-Embedding" option on the command line. If this switch exists, load a different set of resources that show the
server as being either in-place active or fully open. For more information, see Menus and Resources: Server
Additions.
Your server application should also call its CWinApp::RunEmbedded function to parse the command line. If it returns
a nonzero value, the application should not show its window because it has been run from a container application,
not as a stand-alone application. This function updates the server's entry in the system registration database and
calls the RegisterAll member function for you, performing instance registration.
When your server application is starting, you must ensure that it can perform instance registration. Instance
registration informs the OLE system DLLs that the server is active and ready to receive requests from containers. It
does not add an entry to the registration database. Perform instance registration of the server by calling the
ConnectTemplate member function defined by COleTemplateServer . This connects the CDocTemplate object to the
COleTemplateServer object.

The ConnectTemplate function takes three parameters: the server's CLSID, a pointer to the CDocTemplate object,
and a flag indicating whether the server supports multiple instances. A miniserver must be able to support
multiple instances, that is, it must be possible for multiple instances of the server to run simultaneously, one for
each container. Consequently, pass TRUE for this flag when launching a miniserver.
If you are writing a miniserver, by definition it will always be launched by a container. You should still parse the
command line to check for the "/Embedding" option. The absence of this option on the command line means that
the user has tried to launch the miniserver as a stand-alone application. If this occurs, register the server with the
system registration database and then display a message box informing the user to launch the miniserver from a
container application.

See also
OLE
Servers
CWinApp::RunAutomated
CWinApp::RunEmbedded
COleTemplateServer Class
Servers
3/4/2019 • 2 minutes to read • Edit Online

A server application (or component application) creates OLE items (or components) for use by container
applications. A visual editing server application also supports visual editing or in-place activation. Another form
of OLE server is an automation server. Some server applications support only the creation of embedded items;
others support the creation of both embedded and linked items. Some support linking only, although this is
rare. All server applications must support activation by container applications when the user wants to edit an
item. An application can be both a container and a server. In other words, it can both incorporate data into its
documents, and create data that can be incorporated as items into other applications' documents.
A miniserver is a special type of server application that can only be launched by a container. Microsoft Draw and
Microsoft Graph are examples of miniservers. A miniserver does not store documents as files on disk. Instead, it
reads its documents from and writes them to items in documents belonging to containers. As a result, a
miniserver supports embedding only, not linking.
A full server can be run either as a stand-alone application or launched by a container application. A full server
can store documents as files on disk. It can support embedding only, both embedding and linking, or linking
only. The user of a container application can create an embedded item by choosing the Cut or Copy command in
the server and the Paste command in the container. A linked item is created by choosing the Copy command in
the server and the Paste Link command in the container. Alternatively, the user can create an embedded or
linked item using the Insert Object dialog box.
The following table summarizes characteristics of different types of servers:
Server Characteristics
SUP P O RT S M ULT IP L E DO C UM EN T S P ER
T Y P E O F SERVER IN STA N C ES IT EM S P ER DO C UM EN T IN STA N C E

Miniserver Yes 1 1

SDI full server Yes 1 (if linking is supported, 1 1


or more)

MDI full server No (not required) 1 (if linking is supported, 1 0 or more


or more)

A server application should support multiple containers simultaneously, in the event that more than one
container will be used to edit an embedded or linked item. If the server is an SDI application (or a miniserver
with a dialog box interface), multiple instances of the server must be able to run simultaneously. This allows a
separate instance of the application to handle each container request.
If the server is an MDI application, it can create a new MDI child window each time a container needs to edit an
item. In this way, a single instance of the application can support multiple containers.
Your server application must tell the OLE system DLLs what to do if one instance of the server is already
running when another container requests its services: whether it should launch a new instance of the server or
direct all containers' requests to one instance of the server.
For more details on servers, see:
Servers: Implementing a Server
Servers: Implementing Server Documents
Servers: Implementing In-Place Frame Windows
Servers: Server Items
Servers: User-Interface Issues

See also
OLE
Containers
Containers: Advanced Features
Menus and Resources (OLE)
Registration
Automation Servers
Servers: Implementing a Server
3/4/2019 • 2 minutes to read • Edit Online

This article explains the code the MFC Application Wizard creates for a visual editing server application. If you are
not using the application wizard, this article lists the areas where you must write code to implement a server
application.
If you are using the application wizard to create a new server application, it provides a significant amount of
server-specific code for you. If you are adding visual editing server functionality to an existing application, you
must duplicate the code that the application wizard would have provided before adding the rest of the necessary
server code.
The server code that the application wizard provides falls into several categories:
Defining server resources:
The menu resource used when the server is editing an embedded item in its own window.
The menu and toolbar resources used when the server is active in place.
For more information on these resources, see Menus and Resources: Server Additions.
Defining an item class derived from COleServerItem . For further details on server items, see Servers:
Server Items.
Changing the base class of the document class to COleServerDoc . For further details, see Servers:
Implementing Server Documents.
Defining a frame-window class derived from COleIPFrameWnd . For further details, see Servers:
Implementing In-Place Frame Windows.
Creating an entry for the server application in the Windows registration database and registering the new
instance of the server with the OLE system. For information on this topic, see Registration.
Initializing and launching the server application. For information on this topic, see Registration.
For more information, see COleServerItem, COleServerDoc, and COleIPFrameWnd in the Class Library Reference.

See also
Servers
Containers
Menus and Resources (OLE)
Registration
Servers: Implementing Server Documents
3/4/2019 • 2 minutes to read • Edit Online

This article explains the steps you must take to successfully implement a server document if you did not specify
the OLE Server option in the application wizard.
To define a server document class
1. Derive your document class from COleServerDoc instead of CDocument .
2. Create a server item class derived from COleServerItem .
3. Implement the OnGetEmbeddedItem member function of your server document class.
OnGetEmbeddedItem is called when the user of a container application creates or edits an embedded item. It
should return an item representing the entire document. This should be an object of your COleServerItem -
derived class.
4. Override the Serialize member function to serialize the contents of the document. You do not need to
serialize the list of server items unless you are using them to represent the native data in your document.
For more information, see Implementing Server Items in the article Servers: Server Items.
When a server document is created, the framework automatically registers the document with the OLE system
DLLs. This allows the DLLs to identify the server documents.
For more information, see COleServerItem and COleServerDoc in the Class Library Reference.

See also
Servers
Servers: Server Items
Servers: Implementing a Server
Servers: Implementing In-Place Frame Windows
Servers: Implementing In-Place Frame Windows
9/11/2019 • 2 minutes to read • Edit Online

This article explains what you must do to implement in-place frame windows in your visual editing server
application if you do not use the application wizard to create your server application. In place of following the
procedure outlined in this article, you could use an existing in-place frame-window class from either an application
wizard-generated application or a sample provided with Visual C++.
To declare an in-place frame-window class
1. Derive an in-place frame-window class from COleIPFrameWnd .
Use the DECLARE_DYNCREATE macro in your class header file.
Use the IMPLEMENT_DYNCREATE macro in your class implementation (.cpp) file. This allows objects
of this class to be created by the framework.
2. Declare a COleResizeBar member in the frame-window class. This is needed if you want to support in-place
resizing in server applications.
Declare an OnCreate message handler (using the Class Wizard), and call Create for your COleResizeBar
member, if you've defined it.
3. If you have a toolbar, declare a CToolBar member in the frame-window class.
Override the OnCreateControlBars member function to create a toolbar when the server is active in place.
For example:

BOOL CInPlaceFrame::OnCreateControlBars(CFrameWnd* pWndFrame, CFrameWnd* pWndDoc)


{
UNREFERENCED_PARAMETER(pWndDoc);

// Set owner to this window, so messages are delivered to correct app


m_wndToolBar.SetOwner(this);

// Create toolbar on client's frame window


if (!m_wndToolBar.CreateEx(pWndFrame, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_SRVR_INPLACE))
{
TRACE0("Failed to create toolbar\n");
return FALSE;
}

// TODO: Delete these three lines if you don't want the toolbar to be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
pWndFrame->EnableDocking(CBRS_ALIGN_ANY);
pWndFrame->DockControlBar(&m_wndToolBar);

return TRUE;
}

See the discussion of this code following step 5.


4. Include the header file for this in-place frame-window class in your main .cpp file.
5. In InitInstance for your application class, call the SetServerInfo function of the document template object
to specify the resources and in-place frame window to be used in open and in-place editing.
The series of function calls in the if statement creates the toolbar from the resources the server provided. At this
point, the toolbar is part of the container's window hierarchy. Because this toolbar is derived from CToolBar , it will
pass its messages to its owner, the container application's frame window, unless you change the owner. That is why
the call to SetOwner is necessary. This call changes the window where commands are sent to be the server's in-
place frame window, causing the messages to be passed to the server. This allows the server to react to operations
on the toolbar that it provides.
The ID for the toolbar bitmap should be the same as the other in-place resources defined in your server
application. See Menus and Resources: Server Additions for details.
For more information, see COleIPFrameWnd, COleResizeBar, and CDocTemplate::SetServerInfo in the Class Library
Reference.

See also
Servers
Servers: Implementing a Server
Servers: Implementing Server Documents
Servers: Server Items
Servers: Server Items
3/27/2020 • 2 minutes to read • Edit Online

When a container launches a server so that a user can edit an embedded or linked OLE item, the server
application creates a "server item." The server item, which is an object of a class derived from COleServerItem ,
provides an interface between the server document and the container application.
The COleServerItem class defines several overridable member functions that are called by OLE, usually in
response to requests from the container. Server items can represent part of the server document or the entire
document. When an OLE item is embedded in the container document, the server item represents the entire
server document. When the OLE item is linked, the server item can represent a part of the server document or
the whole document, depending on whether the link is to a part or to the whole.
In the HIERSVR sample, for example, the server-item class, CServerItem , has a member that is a pointer to an
object of the class CServerNode . The CServerNode object is a node in the HIERSVR application's document, which
is a tree. When the CServerNode object is the root node, the CServerItem object represents the whole document.
When the CServerNode object is a child node, the CServerItem object represents a part of the document. See the
MFC OLE sample HIERSVR for an example of this interaction.

Implementing Server Items


If you use the application wizard to produce "starter" code for your application, all you have to do to include
server items in your starter code is to choose one of the server options from the OLE Options page. If you are
adding server items to an existing application, perform the following steps:
To implement a server item
1. Derive a class from COleServerItem .
2. In your derived class, override the OnDraw member function.
The framework calls OnDraw to render the OLE item into a metafile. The container application uses this
metafile to render the item. Your application's view class also has an OnDraw member function, which is
used to render the item when the server application is active.
3. Implement an override of OnGetEmbeddedItem for your server-document class. For further information, see
the article Servers: Implementing Server Documents and the MFC OLE sample HIERSVR.
4. Implement your server-item class's OnGetExtent member function. The framework calls this function to
retrieve the size of the item. The default implementation does nothing.

A Tip for Server-Item Architecture


As noted in Implementing Server Items, server applications must be able to render items both in the server's
view and in a metafile used by the container application. In the Microsoft Foundation Class Library's application
architecture, the view class's OnDraw member function renders the item when it is being edited (see
CView::OnDraw in the Class Library Reference). The server item's OnDraw renders the item into a metafile in all
other cases (see COleServerItem::OnDraw).
You can avoid duplication of code by writing helper functions in your server-document class and calling them
from the OnDraw functions in your view and server-item classes. The MFC OLE sample HIERSVR uses this
strategy: the functions CServerView::OnDraw and CServerItem::OnDraw both call CServerDoc::DrawTree to render
the item.
The view and the item both have OnDraw member functions because they draw under different conditions. The
view must take into account such factors as zooming, selection size and extent, clipping, and user-interface
elements such as scroll bars. The server item, on the other hand, always draws the entire OLE object.
For more information, see CView::OnDraw, COleServerItem, COleServerItem::OnDraw, and
COleServerDoc::OnGetEmbeddedItem in the Class Library Reference.

See also
Servers
Servers: User-Interface Issues
3/4/2019 • 2 minutes to read • Edit Online

A server application has a number of features that must be added to the user interface to supply OLE items to
container applications. For further information on the menus and additional resources that need to be added to a
server application, see Menus and Resources: Server Additions.

See also
Servers
Menus and Resources (OLE)
Trackers
4/1/2019 • 2 minutes to read • Edit Online

The CRectTracker class provides a user interface between rectangular items in your application and your user by
providing a variety of display styles. These styles include solid, hatched, or dashed borders; a hatched pattern that
covers the item; and resize handles that can be located on the outside or inside of a border. Trackers are often used
in conjunction with OLE items, that is, objects derived from COleClientItem . The tracker rectangles give visual cues
on the current status of the item.
The MFC OLE sample OCLIENT demonstrates a common interface using trackers and OLE client items from the
viewpoint of a container application. For a demonstration of the different styles and abilities of a tracker object, see
the MFC general sample TRACKER.
For more information on implementing trackers in your OLE application, see Trackers: Implementing Trackers in
Your OLE Application

See also
OLE
COleClientItem Class
Trackers: Implementing Trackers in Your OLE
Application
4/1/2019 • 2 minutes to read • Edit Online

Trackers provide a graphical interface to enable users to interact with OLE client items. By using different tracker
styles, OLE client items can be displayed with hatched borders, resize handles, or a variety of other visual effects.
This article describes:
How to Implement Tracking in Your Code.
Rubber-Banding and Trackers.
The article also covers the use of styles with trackers. In addition, it makes several references to the MFC OLE
sample OCLIENT.

See also
Trackers
How to: Implement Tracking in Your Code
4/1/2019 • 3 minutes to read • Edit Online

To track an OLE item, you must handle certain events related to the item, such as clicking the item or updating the
view of the document. In all cases, it is sufficient to declare a temporary CRectTracker object and manipulate the
item by means of this object.
When a user selects an item or inserts an object with a menu command, you must initialize the tracker with the
proper styles to represent the state of the OLE item. The following table outlines the conventions used by the
OCLIENT sample. For more information on these styles, see CRectTracker .
Container Styles and States of the OLE Item
ST Y L E DISP L AY ED STAT E O F O L E IT EM

Dotted border Item is linked

Solid border Item is embedded in your document

Resize handles Item is currently selected

Hatched border Item is currently in-place active

Hatching pattern overlays item Item's server is open

You can handle this initialization easily using a procedure that checks the state of the OLE item and sets the
appropriate styles. The SetupTracker function found in the OCLIENT sample demonstrates tracker initialization.
The parameters for this function are the address of the tracker, pTracker; a pointer to the client item that is related
to the tracker, pItem; and a pointer to a rectangle, pTrueRect. For a more complete example of this function, see the
MFC OLE sample OCLIENT.
The SetupTracker code example presents a single function; lines of the function are interspersed with discussion
of the function's features:

void CMainView::SetupTracker(CRectTracker* pTracker, CRectItem* pItem,


CRect* pTrueRect)

The tracker is initialized by setting the minimum size and clearing the style of the tracker.

// set minimum size for our OLE items


pTracker->m_sizeMin.cx = 8;
pTracker->m_sizeMin.cy = 8;

pTracker->m_nStyle = 0;

The following lines check to see whether the item is currently selected and whether the item is linked to the
document or embedded in it. Resize handles located on the inside of the border are added to the style, indicating
that the item is currently selected. If the item is linked to your document, the dotted border style is used. A solid
border is used if the item is embedded.
// setup resize handles if item is selected
if (pItem == m_pSelection)
pTracker->m_nStyle |= CRectTracker::resizeInside;

// put correct border depending on item type


if (pItem->GetType() == OT_LINK)
pTracker->m_nStyle |= CRectTracker::dottedLine;
else
pTracker->m_nStyle |= CRectTracker::solidLine;

The following code overlays the item with a hatched pattern if the item is currently open.

// put hatching over the item if it is currently open


if (pItem->GetItemState() == COleClientItem::openState ||
pItem->GetItemState() == COleClientItem::activeUIState)
{
pTracker->m_nStyle |= CRectTracker::hatchInside;
}

You can then call this function whenever the tracker has to be displayed. For example, call this function from the
OnDraw function of your view class. This updates the tracker's appearance whenever the view is repainted. For a
complete example, see the CMainView::OnDraw function of the MFC OLE sample OCLIENT.
In your application, events that require tracker code, such as resizing, moving, or hit detecting, will occur. These
actions usually indicate that an attempt is being made to grab or move the item. In these cases, you will need to
decide what was grabbed: a resize handle or a portion of the border between resize handles. The OnLButtonDown
message handler is a good place to test the position of the mouse in relation to the item. Make a call to
CRectTracker::HitTest . If the test returns something besides CRectTracker::hitOutside , the item is being resized
or moved. Therefore, you should make a call to the Track member function. See the CMainView::OnLButtonDown
function located in the MFC OLE sample OCLIENT for a complete example.
The CRectTracker class provides several different cursor shapes used to indicate whether a move, resize, or drag
operation is taking place. To handle this event, check to see whether the item currently under the mouse is selected.
If it is, make a call to CRectTracker::SetCursor , or call the default handler. The following example is from the MFC
OLE sample OCLIENT:

BOOL CMainView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)


{
if (pWnd == this && m_pSelection != NULL)
{
// give the tracker for the selection a chance
CRectTracker tracker;
SetupTracker(&tracker, m_pSelection);
if (tracker.SetCursor(this, nHitTest))
return TRUE;
}
return CScrollView::OnSetCursor(pWnd, nHitTest, message);
}

See also
Trackers: Implementing Trackers in Your OLE Application
Rubber-Banding and Trackers
2/10/2020 • 2 minutes to read • Edit Online

Another feature supplied with trackers is the "rubber-band" selection, which allows a user to select multiple OLE
items by dragging a sizing rectangle around the items to be selected. When the user releases the left mouse button,
items within the region selected by the user are selected and can be manipulated by the user. For instance, the user
might drag the selection into another container application.
Implementing this feature requires some additional code in your application's WM_LBUTTONDOWN handler
function.
The following code sample implements rubber-band selection and additional features.

else if (m_Tracker.HitTest(point) < 0)


{
// just to demonstrate CRectTracker::TrackRubberBand
CRectTracker trackerRubber;
if (trackerRubber.TrackRubberBand(this, point, TRUE))
{
MessageBeep(0); // beep indicates TRUE

// See if rubber band intersects


// with the doc's tracker
CRect rectT;
// so intersect rect works
trackerRubber.m_rect.NormalizeRect();
if (rectT.IntersectRect(trackerRubber.m_rect, m_Tracker.m_rect))
{
// If so, put resize handles on it (i.e. select it)
if (m_Tracker.m_nStyle & CRectTracker::resizeInside)
{
// swap from resize inside to resize outside for effect
m_Tracker.m_nStyle &= ~CRectTracker::resizeInside;
m_Tracker.m_nStyle |= CRectTracker::resizeOutside;
}
else
{
// Just use inside resize handles on first time
m_Tracker.m_nStyle &= ~CRectTracker::resizeOutside;
m_Tracker.m_nStyle |= CRectTracker::resizeInside;
}
GetDocument()->SetModifiedFlag();
GetDocument()->UpdateAllViews(NULL);
}
}
}

If you want to allow reversible orientation of the tracker during rubber-banding, you should call
CRectTracker::TrackRubberBand with the third parameter set to TRUE . Remember that allowing reversible
orientation will sometimes cause CRectTracker::m_rect to become inverted. This can be corrected by a call to
CRect::NormalizeRect.
For more information, see Container Client Items and OLE drag and drop: Customize drag and drop.

See also
Trackers: Implementing Trackers in Your OLE Application
CRectTracker Class
Serialization in MFC
3/27/2020 • 2 minutes to read • Edit Online

This article explains the serialization mechanism provided in the Microsoft Foundation Class Library (MFC) to
allow objects to persist between runs of your program.
Serialization is the process of writing or reading an object to or from a persistent storage medium such as a disk
file. Serialization is ideal for situations where it is desired to maintain the state of structured data (such as C++
classes or structures) during or after execution of a program. Using the serialization objects provided by MFC
allows this to occur in a standard and consistent manner, relieving the user from the need to perform file
operations by hand.
MFC supplies built-in support for serialization in the class CObject . Thus, all classes derived from CObject can
take advantage of CObject 's serialization protocol.
The basic idea of serialization is that an object should be able to write its current state, usually indicated by the
value of its member variables, to persistent storage. Later, the object can be re-created by reading, or
deserializing, the object's state from the storage. Serialization handles all the details of object pointers and
circular references to objects that are used when you serialize an object. A key point is that the object itself is
responsible for reading and writing its own state. Thus, for a class to be serializable, it must implement the basic
serialization operations. As shown in the Serialization group of articles, it is easy to add this functionality to a
class.
MFC uses an object of the CArchive class as an intermediary between the object to be serialized and the
storage medium. This object is always associated with a CFile object, from which it obtains the necessary
information for serialization, including the file name and whether the requested operation is a read or write. The
object that performs a serialization operation can use the CArchive object without regard to the nature of the
storage medium.
A CArchive object uses overloaded insertion (<< ) and extraction (>> ) operators to perform writing and
reading operations. For more information, see Storing and Loading CObjects via an Archive in the article
Serialization: Serializing an Object.

NOTE
Do not confuse the CArchive class with general-purpose iostream classes, which are for formatted text only. The
CArchive class is for binary-format serialized objects.

If you want, you can bypass MFC serialization to create your own mechanism for persistent data storage. You
will need to override the class member functions that initiate serialization at the user's command. See the
discussion in Technical Note 22 of the ID_FILE_OPEN, ID_FILE_SAVE, and ID_FILE_SAVE_AS standard commands.
The following articles cover the two main tasks required for serialization:
Serialization: Making a Serializable Class
Serialization: Serializing an Object
The article Serialization: Serialization vs. Database Input/Output describes when serialization is an appropriate
input/output technique in database applications.
See also
Concepts
General MFC Topics
CArchive Class
CObject Class
CDocument Class
CFile Class
Serialization: Making a Serializable Class
3/27/2020 • 4 minutes to read • Edit Online

Five main steps are required to make a class serializable. They are listed below and explained in the following
sections:
1. Deriving your class from CObject (or from some class derived from CObject ).
2. Overriding the Serialize member function.
3. Using the DECLARE_SERIAL macro in the class declaration.
4. Defining a constructor that takes no arguments.
5. Using the IMPLEMENT_SERIAL macro in the implementation file for your class.
If you call Serialize directly rather than through the >> and << operators of CArchive, the last three steps are
not required for serialization.

Deriving Your Class from CObject


The basic serialization protocol and functionality are defined in the CObject class. By deriving your class from
CObject (or from a class derived from CObject ), as shown in the following declaration of class CPerson , you gain
access to the serialization protocol and functionality of CObject .

Overriding the Serialize Member Function


The Serialize member function, which is defined in the CObject class, is responsible for actually serializing the
data necessary to capture an object's current state. The Serialize function has a CArchive argument that it uses
to read and write the object data. The CArchive object has a member function, IsStoring , which indicates whether
Serialize is storing (writing data) or loading (reading data). Using the results of IsStoring as a guide, you either
insert your object's data in the CArchive object with the insertion operator (<< ) or extract data with the extraction
operator (>> ).
Consider a class that is derived from CObject and has two new member variables, of types CString and WORD .
The following class declaration fragment shows the new member variables and the declaration for the overridden
Serialize member function:

class CPerson : public CObject


{
public:
DECLARE_SERIAL(CPerson)
// empty constructor is necessary
CPerson();
virtual ~CPerson();

CString m_name;
WORD m_number;

void Serialize(CArchive& archive);


};

To override the Serialize member function


1. Call your base class version of Serialize to make sure that the inherited portion of the object is serialized.
2. Insert or extract the member variables specific to your class.
The insertion and extraction operators interact with the archive class to read and write the data. The
following example shows how to implement Serialize for the CPerson class declared above:

void CPerson::Serialize(CArchive& archive)


{
// call base class function first
// base class is CObject in this case
CObject::Serialize(archive);

// now do the stuff for our specific class


if (archive.IsStoring())
archive << m_name << m_number;
else
archive >> m_name >> m_number;
}

You can also use the CArchive::Read and CArchive::Write member functions to read and write large amounts of
untyped data.

Using the DECLARE_SERIAL Macro


The DECLARE_SERIAL macro is required in the declaration of classes that will support serialization, as shown here:

class CPerson : public CObject


{
public:
DECLARE_SERIAL(CPerson)

Defining a Constructor with No Arguments


MFC requires a default constructor when it re-creates your objects as they are deserialized (loaded from disk). The
deserialization process will fill in all member variables with the values required to re-create the object.
This constructor can be declared public, protected, or private. If you make it protected or private, you help make
sure that it will only be used by the serialization functions. The constructor must put the object in a state that
allows it to be deleted if necessary.

NOTE
If you forget to define a constructor with no arguments in a class that uses the DECLARE_SERIAL and IMPLEMENT_SERIAL
macros, you will get a "no default constructor available" compiler warning on the line where the IMPLEMENT_SERIAL macro
is used.

Using the IMPLEMENT_SERIAL Macro in the Implementation File


The IMPLEMENT_SERIAL macro is used to define the various functions needed when you derive a serializable class
from CObject . You use this macro in the implementation file (.CPP) for your class. The first two arguments to the
macro are the name of the class and the name of its immediate base class.
The third argument to this macro is a schema number. The schema number is essentially a version number for
objects of the class. Use an integer greater than or equal to 0 for the schema number. (Don't confuse this schema
number with database terminology.)
The MFC serialization code checks the schema number when reading objects into memory. If the schema number
of the object on disk does not match the schema number of the class in memory, the library will throw a
CArchiveException , preventing your program from reading an incorrect version of the object.

If you want your Serialize member function to be able to read multiple versions — that is, files written with
different versions of the application — you can use the value VERSIONABLE_SCHEMA as an argument to the
IMPLEMENT_SERIAL macro. For usage information and an example, see the GetObjectSchema member function of
class CArchive .
The following example shows how to use IMPLEMENT_SERIAL for a class, CPerson , that is derived from CObject :

IMPLEMENT_SERIAL(CPerson, CObject, 1)

Once you have a serializable class, you can serialize objects of the class, as discussed in the article Serialization:
Serializing an Object.

See also
Serialization
Serialization: Serializing an Object
3/4/2019 • 2 minutes to read • Edit Online

The article Serialization: Making a Serializable Class shows how to make a class serializable. Once you have a
serializable class, you can serialize objects of that class to and from a file via a CArchive object. This article
explains:
What a CArchive object is.
Two ways to create a CArchive.
How to use the CArchive << and >> operators.
Storing and loading CObjects via an archive.
You can let the framework create the archive for your serializable document or explicitly create the CArchive
object yourself. You can transfer data between a file and your serializable object by using the << and >>
operators for CArchive or, in some cases, by calling the Serialize function of a CObject -derived class.

See also
Serialization
What Is a CArchive Object
3/16/2020 • 2 minutes to read • Edit Online

A CArchive object provides a type-safe buffering mechanism for writing or reading serializable objects to or from
a CFile object. Usually the CFile object represents a disk file; however, it can also be a memory file ( CSharedFile
object), perhaps representing the Clipboard.
A given CArchive object either stores (writes, serializes) data or loads (reads, deserializes) data, but never both. The
life of a CArchive object is limited to one pass through writing objects to a file or reading objects from a file. Thus,
two successively created CArchive objects are required to serialize data to a file and then deserialize it back from
the file.
When an archive stores objects to a file, the archive attaches the CRuntimeClass name to the objects. Then, when
another archive loads objects from a file to memory, the CObject -derived objects are dynamically reconstructed
based on the CRuntimeClass of the objects. A given object may be referenced more than once as it is written to the
file by the storing archive. The loading archive, however, will reconstruct the object only once. The details about
how an archive attaches CRuntimeClass information to objects and reconstructs objects, taking into account
possible multiple references, are described in Technical Note 2.
As data is serialized to an archive, the archive accumulates the data until its buffer is full. Then the archive writes its
buffer to the CFile object pointed to by the CArchive object. Similarly, as you read data from an archive, it reads
data from the file to its buffer and then from the buffer to your deserialized object. This buffering reduces the
number of times a hard disk is physically read, thus improving your application's performance.

See also
Serialization: Serializing an Object
Two Ways to Create a CArchive Object
3/27/2020 • 2 minutes to read • Edit Online

There are two ways to create a CArchive object:


Implicit creation of a CArchive object via the framework
Explicit creation of a CArchive object

Implicit Creation of a CArchive Object via the Framework


The most common, and easiest, way is to let the framework create a CArchive object for your document on behalf
of the Save, Save As, and Open commands on the File menu.
Here is what the framework does when the user of your application issues the Save As command from the File
menu:
1. Presents the Save As dialog box and gets the filename from the user.
2. Opens the file named by the user as a CFile object.
3. Creates a CArchive object that points to this CFile object. In creating the CArchive object, the framework
sets the mode to "store" (write, serialize), as opposed to "load" (read, deserialize).
4. Calls the Serialize function defined in your CDocument -derived class, passing it a reference to the
CArchive object.
Your document's Serialize function then writes data to the CArchive object, as explained shortly. Upon return
from your Serialize function, the framework destroys the CArchive object and then the CFile object.
Thus, if you let the framework create the CArchive object for your document, all you have to do is implement the
document's Serialize function that writes and reads to and from the archive. You also have to implement
Serialize for any CObject -derived objects that the document's Serialize function in turn serializes directly or
indirectly.

Explicit Creation of a CArchive Object


Besides serializing a document via the framework, there are other occasions when you may need a CArchive
object. For example, you might want to serialize data to and from the Clipboard, represented by a CSharedFile
object. Or, you may want to use a user interface for saving a file that is different from the one offered by the
framework. In this case, you can explicitly create a CArchive object. You do this the same way the framework does,
using the following procedure.
To explicitly create a CArchive object
1. Construct a CFile object or an object derived from CFile .
2. Pass the CFile object to the constructor for CArchive , as shown in the following example:

CFile theFile;
theFile.Open(_T("CArchive__Test.txt"), CFile::modeCreate | CFile::modeWrite);
CArchive archive(&theFile, CArchive::store);

The second argument to the CArchive constructor is an enumerated value that specifies whether the
archive will be used for storing or loading data to or from the file. The Serialize function of an object
checks this state by calling the IsStoring function for the archive object.
When you are finished storing or loading data to or from the CArchive object, close it. Although the CArchive
(and CFile ) objects will automatically close the archive (and file), it is good practice to explicitly do so since it
makes recovery from errors easier. For more information about error handling, see the article Exceptions: Catching
and Deleting Exceptions.
To close the CArchive object
1. The following example illustrates how to close the CArchive object:

archive.Close();
theFile.Close();

See also
Serialization: Serializing an Object
Using the CArchive << and >> Operators
3/27/2020 • 2 minutes to read • Edit Online

CArchive provides << and >> operators for writing and reading simple data types as well as CObject s to and
from a file.
To store an object in a file via an archive
1. The following example shows how to store an object in a file via an archive:

CArchive ar(&theFile, CArchive::store);


WORD wEmployeeID = 78;
ar << wEmployeeID;

To load an object from a value previously stored in a file


1. The following example shows how to load an object from a value previously stored in a file:

CArchive ar(&theFile, CArchive::load);


WORD wEmployeeID;
ar >> wEmployeeID;

Usually, you store and load data to and from a file via an archive in the Serialize functions of CObject -derived
classes, which you must have declared with the DECLARE_SERIALIZE macro. A reference to a CArchive object is
passed to your Serialize function. You call the IsLoading function of the CArchive object to determine whether
the Serialize function has been called to load data from the file or store data to the file.
The Serialize function of a serializable CObject -derived class typically has the following form:

void CSerializableObj::Serialize(CArchive &archive)


{
// call base class function first
// base class is CObject in this case
CObject::Serialize(archive);

// now do the stuff for our specific class


if (archive.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add storing code here
}
}

The above code template is exactly the same as the one AppWizard creates for the Serialize function of the
document (a class derived from CDocument ). This code template helps you write code that is easier to review,
because the storing code and the loading code should always be parallel, as in the following example:
void CEmployee::Serialize(CArchive &archive)
{
// call base class function first
// base class is CObject in this case
CObject::Serialize(archive);

// now do the stuff for our specific class


if (archive.IsStoring())
archive << m_strName << m_wAge;
else
archive >> m_strName >> m_wAge;
}

The library defines << and >> operators for CArchive as the first operand and the following data types and class
types as the second operand:

CObject* SIZE and CSize float

WORD CString POINT and CPoint

DWORD BYTE RECT and CRect

Double LONG CTime and CTimeSpan

Int COleCurrency COleVariant

COleDateTime COleDateTimeSpan

NOTE
Storing and loading CObject s via an archive requires extra consideration. For more information, see Storing and Loading
CObjects via an Archive.

The CArchive << and >> operators always return a reference to the CArchive object, which is the first operand.
This enables you to chain the operators, as illustrated below:

archive << m_strName << m_wAge;

See also
Serialization: Serializing an Object
Storing and Loading CObjects via an Archive
3/27/2020 • 2 minutes to read • Edit Online

Storing and loading CObject s via an archive requires extra consideration. In certain cases, you should call the
Serialize function of the object, where the CArchive object is a parameter of the Serialize call, as opposed to
using the << or >> operator of the CArchive . The important fact to keep in mind is that the CArchive >>
operator constructs the CObject in memory based on CRuntimeClass information previously written to the file by
the storing archive.
Therefore, whether you use the CArchive << and >> operators, versus calling Serialize , depends on whether
you need the loading archive to dynamically reconstruct the object based on previously stored CRuntimeClass
information. Use the Serialize function in the following cases:
When deserializing the object, you know the exact class of the object beforehand.
When deserializing the object, you already have memory allocated for it.
Cau t i on

If you load the object using the Serialize function, you must also store the object using the Serialize function.
Don't store using the CArchive << operator and then load using the Serialize function, or store using the
Serialize function and then load using CArchive >> operator.

The following example illustrates the cases:


class CMyObject : public CObject
{
// ...Member functions
public:
CMyObject() {}
virtual void Serialize(CArchive &ar);

// Implementation
protected:
DECLARE_SERIAL(CMyObject)
};

class COtherObject : public CObject


{
// ...Member functions
public:
COtherObject() {}
virtual void Serialize(CArchive &ar);

// Implementation
protected:
DECLARE_SERIAL(COtherObject)
};

class CCompoundObject : public CObject


{
// ...Member functions
public:
CCompoundObject();
~CCompoundObject();
virtual void Serialize(CArchive &ar);

// Implementation
protected:
CMyObject m_myob; // Embedded object
COtherObject *m_pOther; // Object allocated in constructor
CObject *m_pObDyn; // Dynamically allocated object
//..Other member data and implementation

DECLARE_SERIAL(CCompoundObject)
};
IMPLEMENT_SERIAL(CMyObject, CObject, 1)
IMPLEMENT_SERIAL(COtherObject, CObject, 1)
IMPLEMENT_SERIAL(CCompoundObject, CObject, 1)

CCompoundObject::CCompoundObject()
{
m_pOther = new COtherObject; // Exact type known and object already
//allocated.
m_pObDyn = NULL; // Will be allocated in another member function
// if needed, could be a derived class object.
}

CCompoundObject::~CCompoundObject()
{
delete m_pOther;
}

void CCompoundObject::Serialize(CArchive &ar)


{
CObject::Serialize(ar); // Always call base class Serialize.
m_myob.Serialize(ar); // Call Serialize on embedded member.
m_pOther->Serialize(ar); // Call Serialize on objects of known exact type.

// Serialize dynamic members and other raw data


if (ar.IsStoring())
{
ar << m_pObDyn;
// Store other members
}
else
{
ar >> m_pObDyn; // Polymorphic reconstruction of persistent object
//load other members
}
}

In summary, if your serializable class defines an embedded CObject as a member, you should not use the
CArchive << and >> operators for that object, but should call the Serialize function instead. Also, if your
serializable class defines a pointer to a CObject (or an object derived from CObject ) as a member, but constructs
this other object in its own constructor, you should also call Serialize .

See also
Serialization: Serializing an Object
Serialization: Serialization vs. Database Input/Output
3/4/2019 • 2 minutes to read • Edit Online

This article explains when to use document objects and serialization for file-based input/output (I/O) and when
other I/O techniques are appropriate — because the application reads and writes data on a per-transaction basis,
as in database applications. If you don't use serialization, you also won't need the File Open, Save, and Save As
commands. Topics covered include:
Recommendations for handling input/output
Handling the File menu in database applications

See also
Serialization
Recommendations for Handling Input/Output
3/27/2020 • 2 minutes to read • Edit Online

Whether you use file-based I/O or not depends on how you respond to the questions in the following decision tree:
Does the primar y data in your application reside in a disk file
Yes, the primary data resides in a disk file:
Does the application read the whole file into memor y on File Open and write the whole file
back to disk on File Save
Yes: This is the default MFC document case. Use CDocument serialization.
No: This is typically the case of transaction-based updating of the file. You update the file on a per-
transaction basis and don't need CDocument serialization.
No, the primary data doesn't reside in a disk file:
Does the data reside in an ODBC data source
Yes, the data resides in an ODBC data source:
Use MFC's database support. The standard MFC implementation for this case includes a CDatabase
object, as discussed in the article MFC: Using Database Classes with Documents and Views. The
application might also read and write an auxiliary file — the purpose of the application wizard "both a
database view and file support" option. In this case, you'd use serialization for the auxiliary file.
No, the data doesn't reside in an ODBC data source.
Examples of this case: the data resides in a non-ODBC DBMS; the data is read via some other
mechanism, such as OLE or DDE.
In such cases, you won't use serialization, and your application won't have Open and Save menu
items. You might still want to use a CDocument as a home base, just as an MFC ODBC application uses
the document to store CRecordset objects. But you won't use the framework's default File Open/Save
document serialization.
To support the Open, Save, and Save As commands on the File menu, the framework provides document
serialization. Serialization reads and writes data, including objects derived from class CObject , to permanent
storage, normally a disk file. Serialization is easy to use and serves many of your needs, but it may be inappropriate
in many data-access applications. Data-access applications typically update data on a per-transaction basis. They
update the records affected by the transaction rather than reading and writing a whole data file at once.
For information about serialization, see Serialization.

See also
Serialization: Serialization vs. Database Input/Output
File Menu in an MFC Database Application
3/4/2019 • 2 minutes to read • Edit Online

If you create an MFC database application and don't use serialization, how should you interpret the Open, Close,
Save, and Save As commands on the File menu While there are no style guidelines for this question, here are a few
suggestions:
Eliminate the File menu's Open command entirely.
Interpret the Open command as "open database" and show the user a list of data sources your application
recognizes.
Interpret the Open command as, perhaps, "open profile." Retain Open for opening a serialized file, but use
the file to store a serialized document containing "user profile" information, such as the user's preferences,
including his or her login ID (optionally excluding the password) and the data source he or she most recently
worked with.
The MFC Application Wizard supports creating an application with no document-related File menu commands.
Select the Database view without file suppor t option on the Database Suppor t page.
To interpret a File menu command in a special way, you must override one or more command handlers, mostly in
your CWinApp -derived class. For example, if you completely override OnFileOpen (which implements the
ID_FILE_OPEN command) to mean "open database:"

Don't call the base class version of OnFileOpen , since you're completely replacing the framework's default
implementation of the command.
Use the handler instead to display a dialog box listing data sources. You can display such a dialog by calling
CDatabase::OpenEx or CDatabase::Open with the parameter NULL . This opens an ODBC dialog box that
displays all available data sources on the user's machine.
Because database applications typically don't save a whole document, you'll probably want to remove the
Save and Save As implementations unless you use a serialized document to store profile information.
Otherwise, you might implement the Save command as, for example, "commit transaction." See Technical
Note 22 for more information about overriding these commands.

See also
Serialization: Serialization vs. Database Input/Output
User Interface Elements (MFC)
3/4/2019 • 2 minutes to read • Edit Online

For information about how to create the user interface for your application by using the Microsoft Foundation
Class (MFC) Library, see the following topics.

In This Section
ActiveX Controls
Describes how to use reusable software component based on the Component Object Model (COM), which
supports a wide variety of OLE functionality and can be customized to fit many software needs
Clipboard
Describes how to implement support for the Windows Clipboard in MFC applications.
Controls
Describes Windows common controls, including owner-drawn controls, ActiveX controls, and other control
classes supplied by the MFC Library.
Control Bars
Describes functionality of toolbars, status bars, and dialog bars.
Dialog Bars
Describes a kind of control bar that can contain any kind of control.
Dialog Boxes
Describes how to create dialog boxes by using the editors and code wizards.
Document/View Architecture
Describes data management in MFC.
Form Views
Describes how to add forms support to your application.
HTML Help: Context-Sensitive Help for Your Programs
Describes how to add context-sensitive help to your applications by using HTML Help.
MDI Tabbed Groups
Enables multiple document interface (MDI) applications to display one or more tabbed windows (or groups of
tabbed windows, which are known as tabbed groups) in the MDI client area.
Menus
Describes how to add menus to your user interface.
OLE
Provides links to topics that discuss object linking and embedding.
Printing and Print Preview
Describes MFC support for printing and print preview from your applications.
Property Sheets
Describes how to use property sheets to manage large numbers of control in a dialog box.
Ribbon Designer (MFC)
Describes MFC support for creating and modifying ribbon UI resources.
Status Bars
Describes how to use status bars in your applications.
Tool Tips
Describes how to implement tool tips to assist users in using your applications.
Toolbars
Describes the fundamentals about how to use toolbars in MFC.
Visualization Manager
Acts as one class where you can put all the drawing code for your application.
Windows
Describes the fundamentals about how to use windows in MFC.

Related Sections
MFC Desktop Applications
Provides reference material for the MFC Library. MFC is a set of classes that constitute an application framework,
which is the framework of an application written for the Windows API.
ActiveX Controls
3/4/2019 • 2 minutes to read • Edit Online

In Visual C++ you can create ActiveX controls using MFC or ATL.

IMPORTANT
ActiveX is a legacy technology that should not be used for new development. Many capabilities of ActiveX controls can
be performed in a simpler and much more secure way with modern technologies such as HTML5 and JavaScript,
modern browser extensions, or WebAssembly modules. For more information, see A break from the past, part 2: Saying
goodbye to ActiveX, VBScript, attachEvent… and Native Messaging and Microsoft Edge extensions and WebAssembly.

MFC ActiveX Controls


ATL

See also
User Interface Elements
MFC ActiveX Controls
3/27/2020 • 6 minutes to read • Edit Online

An ActiveX control is a reusable software component based on the Component Object Model (COM) that
supports a wide variety of OLE functionality and can be customized to fit many software needs.

IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information, see ActiveX
Controls.

ActiveX controls are designed for use both in ordinary ActiveX control containers and on the Internet, in
World Wide Web pages. You can create ActiveX controls either with MFC, described here, or with the Active
Template Library (ATL).
An ActiveX control can draw itself in its own window, respond to events (such as mouse clicks), and be
managed through an interface that includes properties and methods similar to those in Automation objects.
These controls can be developed for many uses, such as database access, data monitoring, or graphing.
Besides their portability, ActiveX controls support features previously not available to ActiveX controls, such
as compatibility with existing OLE containers and the ability to integrate their menus with the OLE container
menus. In addition, an ActiveX control fully supports Automation, which allows the control to expose
read\write properties and a set of methods that can be called by the control user.
You can create windowless ActiveX controls and controls that only create a window when they become active.
Windowless controls speed up the display of your application and make it possible to have transparent and
nonrectangular controls. You can also load ActiveX control properties asynchronously.
An ActiveX control is implemented as an in-process server (typically a small object) that can be used in any
OLE container. Note that the full functionality of an ActiveX control is available only when used within an OLE
container designed to be aware of ActiveX controls. See Port ActiveX Controls to Other Applications for a list
of containers that support ActiveX controls. This container type, hereafter called a "control container," can
operate an ActiveX control by using the control's properties and methods, and receives notifications from the
ActiveX control in the form of events. The following figure demonstrates this interaction.

Interaction Between an ActiveX Control Container and a Windowed ActiveX Control


For some recent information on optimizing your ActiveX controls, see MFC ActiveX Controls: Optimization.
To create an MFC ActiveX control, see Create an ActiveX control project.
For more information, see:
ActiveX Control Containers
Active Documents
Understanding ActiveX Controls
Upgrading an Existing ActiveX Control to be Used on the Internet
Basic Components of an ActiveX Control
An ActiveX control uses several programmatic elements to interact efficiently with a control container and
with the user. These are class COleControl, a set of event-firing functions, and a dispatch map.
Every ActiveX control object you develop inherits a powerful set of features from its MFC base class,
COleControl . These features include in-place activation, and Automation logic. COleControl can provide the
control object with the same functionality as an MFC window object, plus the ability to fire events.
COleControl can also provide windowless controls, which rely on their container for help with some of the
functionality a window provides (mouse capture, keyboard focus, scrolling), but offer much faster display.
Because the control class derives from COleControl , it inherits the capability to send, or "fire," messages,
called events, to the control container when certain conditions are met. These events are used to notify the
control container when something important happens in the control. You can send additional information
about an event to the control container by attaching parameters to the event. For more information about
ActiveX control events, see the article MFC ActiveX Controls: Events.
The final element is a dispatch map, which is used to expose a set of functions (called methods) and
attributes (called properties) to the control user. Properties allow the control container or the control user to
manipulate the control in various ways. The user can change the appearance of the control, change certain
values of the control, or make requests of the control, such as accessing a specific piece of data that the
control maintains. This interface is determined by the control developer and is defined using Class View . For
more information on ActiveX control methods and properties, see the articles MFC ActiveX Controls:
Methods and Properties.

Interaction Between Controls with Windows and ActiveX Control


Containers
When a control is used within a control container, it uses two mechanisms to communicate: it exposes
properties and methods, and it fires events. The following figure demonstrates how these two mechanisms
are implemented.

Communication Between an ActiveX Control Container and an ActiveX Control


The previous figure also illustrates how other OLE interfaces (besides automation and events) are handled by
controls.
All of a control's communication with the container is performed by COleControl . To handle some of the
container's requests, COleControl will call member functions that are implemented in the control class. All
methods and some properties are handled in this way. Your control's class can also initiate communication
with the container by calling member functions of COleControl . Events are fired in this manner.

Active and Inactive States of an ActiveX Control


A control has two basic states: active and inactive. Traditionally, these states were distinguished by whether
the control had a window. An active control had a window; an inactive control did not. With the introduction
of windowless activation, this distinction is no longer universal, but still applies to many controls.
When a windowless control goes active, it invokes mouse capture, keyboard focus, scrolling, and other
window services from its container. You can also provide mouse interaction to inactive controls, as well as
create controls that wait until activated to create a window.
When a control with a window becomes active, it is able to interact fully with the control container, the user,
and Windows. The figure below demonstrates the paths of communication between the ActiveX control, the
control container, and the operating system.

Windows Message Processing in a Windowed ActiveX Control (When Active)

Serialization
The ability to serialize data, sometimes referred to as persistence, allows the control to write the value of its
properties to persistent storage. Controls can then be recreated by reading the object's state from the
storage.
Note that a control is not responsible for obtaining access to the storage medium. Instead, the control's
container is responsible for providing the control with a storage medium to use at the appropriate times. For
more information on serialization, see the article MFC ActiveX Controls: Serializing. For information on
optimizing serialization, see Optimizing Persistence and Initialization in ActiveX Controls: Optimization.

Installing ActiveX Control Classes and Tools


When you install Visual C++, the MFC ActiveX control classes and retail and debug ActiveX control run-time
DLLs are automatically installed if ActiveX controls are selected in Setup (they are selected by default).
By default, the ActiveX control classes and tools are installed in the following subdirectories under \Program
Files\Microsoft Visual Studio .NET:
\Common7\Tools
Contains the Test Container files (TstCon32.exe, as well as its Help files).
\Vc7\atlmfc\include
Contains the include files needed to develop ActiveX controls with MFC
\Vc7\atlmfc\src\mfc
Contains the source code for specific ActiveX control classes in MFC
\Vc7\atlmfc\lib
Contains the libraries required to develop ActiveX controls with MFC
There are also samples for MFC ActiveX controls. For more information about these samples, see Controls
Samples: MFC-Based ActiveX Controls

See also
User Interface Elements
MFC ActiveX Controls: Optimization
3/4/2019 • 2 minutes to read • Edit Online

This article explains techniques you can use to optimize your ActiveX controls for better 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.

The topics Turning Off the Activate When Visible Option and Providing Mouse Interaction While Inactive discuss
controls that don't create a window until activated. The topic Providing Windowless Activation discusses
controls that never create a window, even when they are activated.
Windows have two major drawbacks for OLE objects: they prevent objects from being transparent or
nonrectangular when active, and they add a large overhead to the instantiation and display of controls.
Typically, creating a window takes 60 percent of a control's creation time. With a single shared window (usually
the container's) and some dispatching code, a control receives the same window services, generally without a
loss of performance. Having a window is mostly unnecessary overhead for the object.
Some optimizations do not necessarily improve performance when your control is used in certain containers.
For example, containers released prior to 1996 did not support windowless activation, so implementing this
feature will not provide a benefit in older containers. However, nearly every container supports persistence, so
optimizing your control's persistence code will likely improve its performance in any container. If your control is
specifically intended to be used with one particular type of container, you may want to research which of these
optimizations is supported by that container. In general, however, you should try to implement as many of these
techniques as are applicable to your particular control to ensure your control performs as well as it possibly can
in a wide array of containers.
You can implement many of these optimizations through the MFC ActiveX Control Wizard, on the Control
Settings page.
MFC ActiveX Control Wizard OLE Optimization Options
C O N T RO L SET T IN G IN T H E M F C
A C T IVEX C O N T RO L W IZ A RD A C T IO N M O RE IN F O RM AT IO N

Activate when visible check box Clear Turning Off the Activate When Visible
Option

Windowless activation check box Select Providing Windowless Activation

Unclipped device context check Select Using an Unclipped Device Context


box

Flicker-free activation check box Select Providing Flicker-Free Activation

Mouse pointer notifications when Select Providing Mouse Interaction While


inactive check box Inactive

Optimized drawing code check box Select Optimizing Control Drawing


For detailed information about the member functions that implement these optimizations, see COleControl.
For more information, see:
Optimizing Persistence and Initialization
Providing Windowless Activation
Turning Off the Activate When Visible Option
Providing Mouse Interaction While Inactive
Providing Flicker-Free Activation
Using an Unclipped Device Context
Optimizing Control Drawing

See also
MFC ActiveX Controls
Optimizing Persistence and Initialization
3/4/2019 • 2 minutes to read • Edit Online

By default, persistence and initialization in a control are handled by the DoPropExchange member function. In a
typical control, this function contains calls to several PX_ functions ( PX_Color , PX_Font , and so on), one for each
property.
This approach has the advantage that a single DoPropExchange implementation can be used for initialization, for
persistence in binary format, and for persistence in the so-called "property-bag" format used by some containers.
This one function provides all information about the properties and their default values in one convenient place.
However, this generality comes at the expense of efficiency. The PX_ functions get their flexibility through
multilayered implementations that are inherently less efficient than more direct, but less flexible, approaches.
Furthermore, if a control passes a default value to a PX_ function, that default value must be provided every time,
even in situations when the default value may not necessarily be used. If generating the default value is a nontrivial
task (for example, when the value is obtained from an ambient property), then extra, unnecessary work is done in
cases where the default value is not used.
You can improve your control's binary persistence performance by overriding your control's Serialize function.
The default implementation of this member function makes a call to your DoPropExchange function. By overriding
it, you can provide a more direct implementation for binary persistence. For example, consider this DoPropExchange
function:

void CMyAxOptCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

PX_Bool(pPX, _T("BoolProp"), m_BoolProp, TRUE);


PX_Short(pPX, _T("ShortProp"), m_ShortProp, 0);
PX_Color(pPX, _T("ColorProp"), m_ColorProp, RGB(0xFF, 0x00, 0x00));
PX_String(pPX, _T("StringProp"), m_StringProp, _T(""));
}

To improve the performance of this control's binary persistence, you can override the Serialize function as
follows:
void CMyAxOptCtrl::Serialize(CArchive& ar)
{
SerializeVersion(ar, MAKELONG(_wVerMinor, _wVerMajor));
SerializeExtent(ar);
SerializeStockProps(ar);

if (ar.IsLoading())
{
ar >> m_BoolProp;
ar >> m_ShortProp;
ar >> m_ColorProp;
ar >> m_StringProp;
}
else
{
ar << m_BoolProp;
ar << m_ShortProp;
ar << m_ColorProp;
ar << m_StringProp;
}
}

The dwVersion local variable can be used to detect the version of the control's persistent state being loaded or
saved. You can use this variable instead of calling CPropExchange::GetVersion.
To save a little space in the persistent format for a BOOL property (and to keep it compatible with the format
produced by PX_Bool ), you can store the property as a BYTE , as follows:

if (ar.IsLoading())
{
BYTE bTmp;
ar >> bTmp;
m_BoolProp = (BOOL)bTmp;
// other properties...
}
else
{
ar << (BYTE)m_BoolProp;
// other properties...
}

Note that in the load case, a temporary variable is used and then its value is assigned, rather than casting
m_boolProp to a BYTE reference. The casting technique would result in only one byte of m_boolProp being
modified, leaving the remaining bytes uninitialized.
For the same control, you can optimize the control's initialization by overriding COleControl::OnResetState as
follows:

void CMyAxOptCtrl::OnResetState()
{
ResetVersion(MAKELONG(_wVerMinor, _wVerMajor));
ResetStockProps();

m_BoolProp = TRUE;
m_ShortProp = 0;
m_ColorProp = RGB(0xFF, 0x00, 0x00);
m_StringProp.Empty();
}

Although Serialize and OnResetState have been overridden, the DoPropExchange function should be kept intact
because it is still used for persistence in the property-bag format. It is important to maintain all three of these
functions to ensure that the control manages its properties consistently, regardless of which persistence
mechanism the container uses.

See also
MFC ActiveX Controls: Optimization
Providing Windowless Activation
3/4/2019 • 2 minutes to read • Edit Online

Window creation code (that is, everything that happens when you call CreateWindow ) is costly to execute. A
control that maintains an on-screen window has to manage messages for the window. Windowless controls are
therefore faster than controls with windows.
A further advantage of windowless controls is that, unlike windowed controls, windowless controls support
transparent painting and nonrectangular screen regions. A common example of a transparent control is a text
control with a transparent background. The controls paints the text but not the background, so whatever is under
the text shows through. Newer forms often make use of nonrectangular controls, such as arrows and round
buttons.
Often, a control does not need a window of its own and, instead, can use the window services of its container,
provided that the container has been written to support windowless objects. Windowless controls are backward
compatible with older containers. In older containers not written to support windowless controls, the windowless
controls create a window when active.
Because windowless controls do not have their own windows, the container (which does have a window) is
responsible for providing services that would otherwise have been provided by the control's own window. For
example, if your control needs to query the keyboard focus, capture the mouse, or obtain a device context, these
operations are managed by the container. The container routes user input messages sent to its window to the
appropriate windowless control, using the IOleInPlaceObjectWindowless interface. (See the ActiveX SDK for a
description of this interface.) COleControl member functions invoke these services from the container.
To make your control use windowless activation, include the windowlessActivate flag in the set of flags returned
by COleControl::GetControlFlags. For example:

DWORD CMyAxOptCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();

// The control can activate without creating a window.


dwFlags |= windowlessActivate;

return dwFlags;
}

The code to include this flag is automatically generated if you select the Windowless activation option on the
Control Settings page of the MFC ActiveX Control Wizard.
When windowless activation is enabled, the container will delegate input messages to the control's
IOleInPlaceObjectWindowless interface. COleControl 's implementation of this interface dispatches the messages
through your control's message map, after adjusting the mouse coordinates appropriately. You can process the
messages like ordinary window messages, by adding the corresponding entries to the message map. In your
handlers for these messages, avoid using the m_hWnd member variable (or any member function that uses it)
without first checking that its value is not NULL .
COleControl provides member functions that invoke mouse capture, keyboard focus, scrolling, and other window
services from the container as appropriate, including:
GetFocus, SetFocus
GetCapture, SetCapture, ReleaseCapture
GetDC, ReleaseDC
InvalidateRgn
ScrollWindow
GetClientRect
In windowless controls, you should always use the COleControl member functions instead of the corresponding
CWnd member functions or their related Win32 API functions.

You may want a windowless control to be the target of an OLE drag-and-drop operation. Normally, this would
require that the control's window be registered as a drop target. Since the control has no window of its own, the
container uses its own window as a drop target. The control provides an implementation of the IDropTarget
interface to which the container can delegate calls at the appropriate time. To expose this interface to the container,
override COleControl::GetWindowlessDropTarget. For example:

IDropTarget* CMyAxOptCtrl::GetWindowlessDropTarget()
{
m_DropTarget.m_xDropTarget.AddRef();
return &m_DropTarget.m_xDropTarget;
}

See also
MFC ActiveX Controls: Optimization
Turning off the Activate When Visible Option
3/4/2019 • 2 minutes to read • Edit Online

A control has two basic states: active and inactive. Traditionally, these states were distinguished by whether the
control had a window. An active control had a window; an inactive control did not. With the introduction of
windowless activation, this distinction is no longer universal, but still applies to many controls.
Compared with the rest of the initialization typically performed by an ActiveX control, the creation of a window is
an extremely expensive operation. Ideally, a control would defer creating its window until absolutely necessary.
Many controls do not need to be active the entire time they are visible in a container. Often, a control can remain
in the inactive state until the user performs an operation that requires it to become active (for example, clicking
with the mouse or pressing the TAB key). To cause a control to remain inactive until the container needs to activate
it, remove the OLEMISC_ACTIVATEWHENVISIBLE flag from the control's miscellaneous flags:

static const DWORD BASED_CODE _dwNVC_MFC_AxOptOleMisc =


OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;

The OLEMISC_ACTIVATEWHENVISIBLE flag is automatically omitted if you turn off the Activate When
Visible option in the Control Settings page of the MFC ActiveX Control Wizard when you create your control.

See also
MFC ActiveX Controls: Optimization
Providing Mouse Interaction While Inactive
3/4/2019 • 2 minutes to read • Edit Online

If your control is not immediately activated, you may still want it to process WM_SETCURSOR and
WM_MOUSEMOVE messages, even though the control has no window of its own. This can be accomplished by
enabling COleControl 's implementation of the IPointerInactive interface, which is disabled by default. (See the
ActiveX SDK for a description of this interface.) To enable it, include the pointerInactive flag in the set of flags
returned by COleControl::GetControlFlags:

DWORD CMyAxOptCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();

// The control can receive mouse notifications when inactive.


dwFlags |= pointerInactive;

return dwFlags;
}

The code to include this flag is automatically generated if you select the Mouse Pointer Notifications When
Inactive option on the Control Settings page when creating your control with the MFC ActiveX Control
Wizard .
When the IPointerInactive interface is enabled, the container delegates WM_SETCURSOR and
WM_MOUSEMOVE messages to it. COleControl 's implementation of IPointerInactive dispatches the messages
through your control's message map after adjusting the mouse coordinates appropriately. You can process the
messages just like ordinary window messages by adding the corresponding entries to the message map. In your
handlers for these messages, avoid using the m_hWnd member variable (or any member function that uses it)
without first checking that its value is not NULL .
You may also want an inactive control to be the target of an OLE drag-and-drop operation. This requires activating
the control at the moment the user drags an object over it, so that the control's window can be registered as a
drop target. To cause activation to occur during a drag, override COleControl::GetActivationPolicy, and return the
POINTERINACTIVE_ACTIVATEONDRAG flag:

DWORD CMyAxOptCtrl::GetActivationPolicy()
{
return POINTERINACTIVE_ACTIVATEONDRAG;
}

Enabling the IPointerInactive interface typically means that you want the control to be capable of processing
mouse messages at all times. To get this behavior in a container that doesn't support the IPointerInactive
interface, you need to have your control always activated when visible, which means the control should include
the OLEMISC_ACTIVATEWHENVISIBLE flag among its miscellaneous flags. However, to prevent this flag from
taking effect in a container that does support IPointerInactive , you can also specify the
OLEMISC_IGNOREACTIVATEWHENVISIBLE flag:
static const DWORD BASED_CODE _dwMyOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_IGNOREACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;

See also
MFC ActiveX Controls: Optimization
Providing Flicker-Free Activation
3/4/2019 • 2 minutes to read • Edit Online

If your control draws itself identically in the inactive and active states (and does not use windowless activation),
you can eliminate the drawing operations and the accompanying visual flicker that normally occur when making
the transition between the inactive and active states. To do this, include the noFlickerActivate flag in the set of
flags returned by COleControl::GetControlFlags. For example:

DWORD CMyAxOptCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();

dwFlags |= noFlickerActivate;

return dwFlags;
}

The code to include this flag is automatically generated if you select the Flicker-Free activation option on the
Control Settings page when creating your control with the MFC ActiveX Control Wizard.
If you are using windowless activation, this optimization has no effect.

See also
MFC ActiveX Controls: Optimization
Using an Unclipped Device Context
3/4/2019 • 2 minutes to read • Edit Online

If you are absolutely certain that your control does not paint outside its client rectangle, you can realize a small but
detectable speed gain by disabling the call to IntersectClipRect that is made by COleControl . To do this, remove
the clipPaintDC flag from the set of flags returned by COleControl::GetControlFlags. For example:

DWORD CMyAxOptCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();

dwFlags &= ~clipPaintDC;

return dwFlags;
}

The code to remove this flag is automatically generated if you select the Unclipped Device Context option on
the Control Settings page, when creating your control with the MFC ActiveX Control Wizard.
If you are using windowless activation, this optimization has no effect.

See also
MFC ActiveX Controls: Optimization
Optimizing Control Drawing
6/18/2019 • 2 minutes to read • Edit Online

When a control is instructed to draw itself into a container-supplied device context, it typically selects GDI objects
(such as pens, brushes, and fonts) into the device context, performs its drawing operations, and restores the
previous GDI objects. If the container has multiple controls that are to be drawn into the same device context, and
each control selects the GDI objects it requires, time can be saved if the controls do not individually restore
previously selected objects. After all the controls have been drawn, the container can automatically restore the
original objects.
To detect whether a container supports this technique, a control can call the COleControl::IsOptimizedDraw
member function. If this function returns TRUE , the control can skip the normal step of restoring the previously
selected objects.
Consider a control that has the following (unoptimized) OnDraw function:

void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)


{
CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
CBrush brush(TranslateColor(GetBackColor()));
CPen* pPenSave = pdc->SelectObject(&pen);
CBrush* pBrushSave = pdc->SelectObject(&brush);
pdc->Rectangle(rcBounds);
pdc->SelectObject(pPenSave);
pdc->SelectObject(pBrushSave);
}

The pen and brush in this example are local variables, meaning their destructors will be called when they go out of
scope (when the OnDraw function ends). The destructors will attempt to delete the corresponding GDI objects. But
they should not be deleted if you plan to leave them selected into the device context upon returning from OnDraw .
To prevent the CPen and CBrush objects from being destroyed when OnDraw finishes, store them in member
variables instead of local variables. In the control's class declaration, add declarations for two new member
variables:

class CMyAxOptCtrl : public COleControl


{

CPen m_pen;
CBrush m_brush;
};

Then, the OnDraw function can be rewritten as follows:


void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
CPen pen(PS_SOLID, 0, TranslateColor(GetForeColor()));
CBrush brush(TranslateColor(GetBackColor()));
CPen* pPenSave = pdc->SelectObject(&pen);
CBrush* pBrushSave = pdc->SelectObject(&brush);
pdc->Rectangle(rcBounds);
pdc->SelectObject(pPenSave);
pdc->SelectObject(pBrushSave);
}

This approach avoids creation of the pen and brush every time OnDraw is called. The speed improvement comes at
the cost of maintaining additional instance data.
If the ForeColor or BackColor property changes, the pen or brush needs to be created again. To do this, override
the OnForeColorChanged and OnBackColorChanged member functions:

void CMyAxOptCtrl::OnForeColorChanged()
{
m_pen.DeleteObject();
}

void CMyAxOptCtrl::OnBackColorChanged()
{
m_brush.DeleteObject();
}

Finally, to eliminate unnecessary SelectObject calls, modify OnDraw as follows:

void CMyAxOptCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)


{
if (m_pen.m_hObject == NULL)
m_pen.CreatePen(PS_SOLID, 0, TranslateColor(GetForeColor()));
if (m_brush.m_hObject == NULL)
m_brush.CreateSolidBrush(TranslateColor(GetBackColor()));
CPen* pPenSave = pdc->SelectObject(&m_pen);
CBrush* pBrushSave = pdc->SelectObject(&m_brush);
pdc->Rectangle(rcBounds);
if (!IsOptimizedDraw())
{
pdc->SelectObject(pPenSave);
pdc->SelectObject(pBrushSave);
}
}

See also
MFC ActiveX Controls: Optimization
COleControl Class
MFC ActiveX Controls
MFC ActiveX Control Wizard
MFC ActiveX Controls: Painting an ActiveX Control
MFC ActiveX Controls: Painting an ActiveX Control
3/27/2020 • 6 minutes to read • Edit Online

This article describes the ActiveX control painting process and how you can alter paint code to optimize the
process. (See Optimizing Control Drawing for techniques on how to optimize drawing by not having controls
individually restore previously selected GDI objects. After all of the controls have been drawn, the container can
automatically restore the original objects.)

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.

Examples in this article are from a control created by the MFC ActiveX Control Wizard with default settings. For
more information on creating a skeleton control application using the MFC ActiveX Control Wizard, see the article
MFC ActiveX Control Wizard.
The following topics are covered:
The overall process for painting a control and the code created by the ActiveX Control Wizard to support
painting
How to optimize the painting process
How to paint your control using metafiles

The Painting Process of an ActiveX Control


When ActiveX controls are initially displayed or are redrawn, they follow a painting process similar to other
applications developed using MFC, with one important distinction: ActiveX controls can be in an active or an
inactive state.
An active control is represented in an ActiveX control container by a child window. Like other windows, it is
responsible for painting itself when a WM_PAINT message is received. The control's base class, COleControl,
handles this message in its OnPaint function. This default implementation calls the OnDraw function of your
control.
An inactive control is painted differently. When the control is inactive, its window is either invisible or nonexistent,
so it can not receive a paint message. Instead, the control container directly calls the OnDraw function of the control.
This differs from an active control's painting process in that the OnPaint member function is never called.
As discussed in the preceding paragraphs, how an ActiveX control is updated depends on the state of the control.
However, because the framework calls the OnDraw member function in both cases, you add the majority of your
painting code in this member function.
The OnDraw member function handles control painting. When a control is inactive, the control container calls
OnDraw , passing the device context of the control container and the coordinates of the rectangular area occupied
by the control.
The rectangle passed by the framework to the OnDraw member function contains the area occupied by the control.
If the control is active, the upper-left corner is (0, 0) and the device context passed is for the child window that
contains the control. If the control is inactive, the upper-left coordinate is not necessarily (0, 0) and the device
context passed is for the control container containing the control.

NOTE
It is important that your modifications to OnDraw do not depend on the rectangle's upper left point being equal to (0, 0)
and that you draw only inside the rectangle passed to OnDraw . Unexpected results can occur if you draw beyond the
rectangle's area.

The default implementation provided by the MFC ActiveX Control Wizard in the control implementation file (.CPP),
shown below, paints the rectangle with a white brush and fills the ellipse with the current background color.

void CMyAxUICtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)


{
if (!pdc)
return;

// TODO: Replace the following code with your own drawing code.
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
}

NOTE
When painting a control, you should not make assumptions about the state of the device context that is passed as the pdc
parameter to the OnDraw function. Occasionally the device context is supplied by the container application and will not
necessarily be initialized to the default state. In particular, explicitly select the pens, brushes, colors, fonts, and other resources
that your drawing code depends upon.

Optimizing Your Paint Code


After the control is successfully painting itself, the next step is to optimize the OnDraw function.
The default implementation of ActiveX control painting paints the entire control area. This is sufficient for simple
controls, but in many cases repainting the control would be faster if only the portion that needed updating was
repainted, instead of the entire control.
The OnDraw function provides an easy method of optimization by passing rcInvalid, the rectangular area of the
control that needs redrawing. Use this area, usually smaller than the entire control area, to speed up the painting
process.

Painting Your Control Using Metafiles


In most cases the pdc parameter to the OnDraw function points to a screen device context (DC). However, when
printing images of the control or during a print preview session, the DC received for rendering is a special type
called a "metafile DC". Unlike a screen DC, which immediately handles requests sent to it, a metafile DC stores
requests to be played back at a later time. Some container applications may also choose to render the control
image using a metafile DC when in design mode.
Metafile drawing requests can be made by the container through two interface functions: IViewObject::Draw (this
function can also be called for non-metafile drawing) and IDataObject::GetData . When a metafile DC is passed as
one of the parameters, the MFC framework makes a call to COleControl::OnDrawMetafile. Because this is a virtual
member function, override this function in the control class to do any special processing. The default behavior calls
COleControl::OnDraw .

To make sure the control can be drawn in both screen and metafile device contexts, you must use only member
functions that are supported in both a screen and a metafile DC. Be aware that the coordinate system may not be
measured in pixels.
Because the default implementation of OnDrawMetafile calls the control's OnDraw function, use only member
functions that are suitable for both a metafile and a screen device context, unless you override OnDrawMetafile . The
following lists the subset of CDC member functions that can be used in both a metafile and a screen device context.
For more information on these functions, see class CDC in the MFC Reference.

A RC B IB B LT C H O RD

Ellipse Escape ExcludeClipRect

ExtTextOut FloodFill IntersectClipRect

LineTo MoveTo OffsetClipRgn

OffsetViewportOrg OffsetWindowOrg PatBlt

Pie Polygon Polyline

PolyPolygon RealizePalette RestoreDC

RoundRect SaveDC ScaleViewportExt

ScaleWindowExt SelectClipRgn SelectObject

SelectPalette SetBkColor SetBkMode

SetMapMode SetMapperFlags SetPixel

SetPolyFillMode SetROP2 SetStretchBltMode

SetTextColor SetTextJustification SetViewportExt

SetViewportOrg SetWindowExt SetWindowORg

StretchBlt TextOut

In addition to CDC member functions, there are several other functions that are compatible in a metafile DC. These
include CPalette::AnimatePalette, CFont::CreateFontIndirect, and three member functions of CBrush :
CreateBrushIndirect, CreateDIBPatternBrush, and CreatePatternBrush.
Functions that are not recorded in a metafile are: DrawFocusRect, DrawIcon, DrawText, ExcludeUpdateRgn, FillRect,
FrameRect, GrayString, InvertRect, ScrollDC, and TabbedTextOut. Because a metafile DC is not actually associated
with a device, you cannot use SetDIBits, GetDIBits, and CreateDIBitmap with a metafile DC. You can use
SetDIBitsToDevice and StretchDIBits with a metafile DC as the destination. CreateCompatibleDC,
CreateCompatibleBitmap, and CreateDiscardableBitmap are not meaningful with a metafile DC.
Another point to consider when using a metafile DC is that the coordinate system may not be measured in pixels.
For this reason, all your drawing code should be adjusted to fit in the rectangle passed to OnDraw in the rcBounds
parameter. This prevents accidental painting outside the control because rcBounds represents the size of the
control's window.
After you have implemented metafile rendering for the control, use Test Container to test the metafile. See Testing
Properties and Events with Test Container for information on how to access the test container.
To test the control's metafile using Test Container
1. On the Test Container's Edit menu, click Inser t New Control .
2. In the Inser t New Control box, select the control and click OK .
The control will appear in Test container.
3. On the Control menu, click Draw Metafile .
A separate window appears in which the metafile is displayed. You can change the size of this window to see
how scaling affects the control's metafile. You can close this window at any time.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Events
3/4/2019 • 2 minutes to read • Edit Online

ActiveX controls use events to notify a container that something has happened to the control. Common examples
of events include clicks on the control, data entered using the keyboard, and changes in the control's state. When
these actions occur, the control fires an event to alert the container.
Events are also called messages.
MFC supports two kinds of events: stock and custom. Stock events are those events that class COleControl handles
automatically. For a complete list of stock events, see the article MFC ActiveX Controls: Adding Stock Events.
Custom events allow a control the ability to notify the container when an action specific to that control occurs.
Some examples would be a change in the internal state of a control or receipt of a certain window message.
For your control to fire events properly, your control class must map each event of the control to a member
function that should be called when the related event occurs. This mapping mechanism (called an event map)
centralizes information about the event and allows Visual Studio to easily access and manipulate the control's
events. This event map is declared by the following macro, located in the header (.H) file of the control class
declaration:

DECLARE_EVENT_MAP()

After the event map has been declared, it must be defined in your control's implementation (.CPP) file. The
following lines of code define the event map, allowing your control to fire specific events:

BEGIN_EVENT_MAP(CMyAxUICtrl, COleControl)

END_EVENT_MAP()

If you use the MFC ActiveX Control Wizard to create the project, it automatically adds these lines. If you do not use
the MFC ActiveX Control Wizard, you must add these lines manually.
With Class View, you can add stock events supported by class COleControl or custom events that you define. For
each new event, Class View automatically adds the proper entry to the control's event map and the control's .IDL
file.
Two other articles discuss events in detail:
MFC ActiveX Controls: Adding Stock Events
MFC ActiveX Controls: Adding Custom Events

See also
MFC ActiveX Controls
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Adding Stock Events to an
ActiveX Control
3/27/2020 • 3 minutes to read • Edit Online

Stock events differ from custom events in that they are automatically fired by class COleControl. COleControl
contains predefined member functions that fire events resulting from common actions. Some common actions
implemented by COleControl include single- and double-clicks on the control, keyboard events, and changes in
the state of the mouse buttons. Event map entries for stock events are always preceded by the EVENT_STOCK
prefix.

Stock Events Supported by the Add Event Wizard


The COleControl class provides ten stock events, listed in the following table. You can specify the events you want
in your control using the Add Event Wizard.
Stock Events
EVEN T F IRIN G F UN C T IO N C O M M EN T S

Click void FireClick( ) Fired when the control captures the


mouse, any BUTTONUP (left, middle,
or right) message is received, and the
button is released over the control. The
stock MouseDown and MouseUp
events occur before this event.

Event map entry:


EVENT_STOCK_CLICK( )

DblClick void FireDblClick( ) Similar to Click but fired when a


BUTTONDBLCLK message is received.

Event map entry:


EVENT_STOCK_DBLCLICK( )

Error void FireError( SCODE scode , Fired when an error occurs within your
LPCSTR lpszDescription , UINT ActiveX control outside of the scope of
nHelpID = 0 ) a method call or property access.

Event map entry:


EVENT_STOCK_ERROREVENT( )

KeyDown void FireKeyDown( shor t nChar , Fired when a WM_SYSKEYDOWN or


shor t nShiftState ) WM_KEYDOWN message is received.

Event map entry:


EVENT_STOCK_KEYDOWN( )

KeyPress void FireKeyPress( shor t * pnChar ) Fired when a WM_CHAR message is


received.

Event map entry:


EVENT_STOCK_KEYPRESS( )
EVEN T F IRIN G F UN C T IO N C O M M EN T S

KeyUp void FireKeyUp( shor t nChar , Fired when a WM_SYSKEYUP or


shor t nShiftState ) WM_KEYUP message is received.

Event map entry:


EVENT_STOCK_KEYUP( )

MouseDown void FireMouseDown( shor t Fired if any BUTTONDOWN (left,


nButton , shor t nShiftState , middle, or right) is received. The mouse
float x , float y ) is captured immediately before this
event is fired.

Event map entry:


EVENT_STOCK_MOUSEDOWN( )

MouseMove void FireMouseMove( shor t Fired when a WM_MOUSEMOVE


nButton , shor t nShiftState , message is received.
float x , float y )
Event map entry:
EVENT_STOCK_MOUSEMOVE( )

MouseUp void FireMouseUp( shor t nButton Fired if any BUTTONUP (left, middle, or
, shor t nShiftState , float x , float y ) right) is received. The mouse capture is
released before this event is fired.

Event map entry:


EVENT_STOCK_MOUSEUP( )

ReadyStateChange void FireReadyStateChange( ) Fired when a control transitions to the


next ready state due to the amount of
data received.

Event map entry:


EVENT_STOCK_READYSTATECHANG
E( )

Adding a Stock Event Using the Add Event Wizard


Adding stock events requires less work than adding custom events because the firing of the actual event is
handled automatically by the base class, COleControl . The following procedure adds a stock event to a control that
was developed using MFC ActiveX Control Wizard. The event, called KeyPress, fires when a key is pressed and the
control is active. This procedure can also be used to add other stock events. Substitute the selected stock event
name for KeyPress.
To add the KeyPress stock event using the Add Event Wizard
1. Load your control's project.
2. In Class View, right-click your ActiveX control class to open the shortcut menu.
3. From the shortcut menu, click Add and then click Add Event .
This opens the Add Event Wizard.
4. In the Event Name drop-down list, select KeyPress .
5. Click Finish .

Add Event Wizard Changes for Stock Events


Because stock events are handled by the control's base class, the Add Event Wizard does not change your class
declaration in any way. It adds the event to the control's event map and makes an entry in its .IDL file. The
following line is added to the control's event map, located in the control class implementation (.CPP) file:

EVENT_STOCK_KEYPRESS()

Adding this code fires a KeyPress event when a WM_CHAR message is received and the control is active. The
KeyPress event can be fired at other times by calling its firing function (for example, FireKeyPress ) from within the
control code.
The Add Event Wizard adds the following line of code to the control's .IDL file:

[id(DISPID_KEYPRESS)] void KeyPress(SHORT* KeyAscii);

This line associates the KeyPress event with its standard dispatch ID and allows the container to anticipate the
KeyPress event.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Adding Custom Events
3/27/2020 • 5 minutes to read • Edit Online

Custom events differ from stock events in that they are not automatically fired by class COleControl . A custom
event recognizes a certain action, determined by the control developer, as an event. The event map entries for
custom events are represented by the EVENT_CUSTOM macro. The following section implements a custom event
for an ActiveX control project that was created using the ActiveX Control Wizard.

Adding a Custom Event with the Add Event Wizard


The following procedure adds a specific custom event, ClickIn. You can use this procedure to add other custom
events. Substitute your custom event name and its parameters for the ClickIn event name and parameters.
To add the ClickIn custom event using the Add Event Wizard
1. Load your control's project.
2. In Class View , right-click your ActiveX control class to open the shortcut menu.
3. From the shortcut menu, click Add and then click Add Event .
This opens the Add Event Wizard.
4. In the Event name box, first select any existing event, then click on the Custom radio button, then type
ClickIn.
5. In the Internal name box, type the name of the event's firing function. For this example, use the default
value provided by the Add Event Wizard ( FireClickIn ).
6. Add a parameter, called xCoord (type OLE_XPOS_PIXELS ), using the Parameter Name and Parameter
Type controls.
7. Add a second parameter, called yCoord (type OLE_YPOS_PIXELS ).
8. Click Finish to create the event.

Add Event Wizard Changes for Custom Events


When you add a custom event, the Add Event Wizard makes changes to the control class .H, .CPP, and .IDL files. The
following code samples are specific to the ClickIn event.
The following lines are added to the header (.H) file of your control class:

void FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord)


{
FireEvent(eventidClickIn, EVENT_PARAM(VTS_XPOS_PIXELS VTS_YPOS_PIXELS), xCoord, yCoord);
}

This code declares an inline function called FireClickIn that calls COleControl::FireEvent with the ClickIn event
and parameters you defined using the Add Event Wizard.
In addition, the following line is added to the event map for the control, located in the implementation (.CPP) file of
your control class:
EVENT_CUSTOM_ID("ClickIn", eventidClickIn, FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS)
EVENT_CUSTOM_ID("ClickIn", eventidClickIn, FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS)

This code maps the event ClickIn to the inline function FireClickIn , passing the parameters you defined using the
Add Event Wizard.
Finally, the following line is added to your control's .IDL file:

[id(1)] void ClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);

This line assigns the ClickIn event a specific ID number, taken from the event's position in the Add Event Wizard
event list. The entry in the event list allows a container to anticipate the event. For example, it might provide
handler code to be executed when the event is fired.

Calling FireClickIn
Now that you have added the ClickIn custom event using the Add Event Wizard, you must decide when this event
is to be fired. You do this by calling FireClickIn when the appropriate action occurs. For this discussion, the
control uses the InCircle function inside a WM_LBUTTONDOWN message handler to fire the ClickIn event when a user
clicks inside a circular or elliptical region. The following procedure adds the WM_LBUTTONDOWN handler.
To add a message handler with the Add Event Wizard
1. Load your control's project.
2. In Class View , select your ActiveX control class.
3. In the Proper ties window, you see a list of messages that can be handled by the ActiveX control. Any
message shown in bold already has a handler function assigned to it.
4. Select the message you want to handle. For this example, select WM_LBUTTONDOWN .
5. From the drop-down list box on the right, select <Add> OnLButtonDown .
6. Double-click the new handler function in Class View to jump to the message handler code in the
implementation (.CPP) file of your ActiveX control.
The following code sample calls the InCircle function every time the left mouse button is clicked within the
control window. This sample can be found in the WM_LBUTTONDOWN handler function, OnLButtonDown , in the Circ
sample abstract.

void CMyAxUICtrl::OnLButtonDown(UINT nFlags, CPoint point)


{
if (InCircle(point))
FireClickIn(point.x, point.y);

COleControl::OnLButtonDown(nFlags, point);
}

NOTE
When the Add Event Wizard creates message handlers for mouse button actions, a call to the same message handler of the
base class is automatically added. Do not remove this call. If your control uses any of the stock mouse messages, the
message handlers in the base class must be called to ensure that mouse capture is handled properly.

In the following example, the event fires only when the click occurs inside a circular or elliptical region within the
control. To achieve this behavior, you can place the InCircle function in your control's implementation (.CPP) file:

VARIANT_BOOL CMyAxUICtrl::InCircle(CPoint& point)


{
CRect rc;
GetClientRect(rc);
// Determine radii
double a = (rc.right - rc.left) / 2;
double b = (rc.bottom - rc.top) / 2;

// Determine x, y
double x = point.x - (rc.left + rc.right) / 2;
double y = point.y - (rc.top + rc.bottom) / 2;

// Apply ellipse formula


return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}

You will also need to add the following declaration of the InCircle function to your control's header (.H) file:

VARIANT_BOOL InCircle(CPoint& point);

Custom Events with Stock Names


You can create custom events with the same name as stock events, however you can not implement both in the
same control. For example, you might want to create a custom event called Click that does not fire when the stock
event Click would normally fire. You could then fire the Click event at any time by calling its firing function.
The following procedure adds a custom Click event.
To add a custom event that uses a stock event name
1. Load your control's project.
2. In Class View , right-click your ActiveX control class to open the shortcut menu.
3. From the shortcut menu, click Add and then click Add Event .
This opens the Add Event Wizard.
4. In the Event Name drop-down list, select a stock event name. For this example, select Click .
5. For Event Type , select Custom .
6. Click Finish to create the event.
7. Call FireClick at appropriate places in your code.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Methods
3/4/2019 • 2 minutes to read • Edit Online

An ActiveX control fires events to communicate between itself and its control container. A container can also
communicate with a control by means of methods and properties. Methods are also called functions.
Methods and properties provide an exported interface for use by other applications, such as Automation clients
and ActiveX control containers. For more information on ActiveX control properties, see the article MFC ActiveX
Controls: Properties.
Methods are similar in use and purpose to the member functions of a C++ class. There are two types of methods
your control can implement: stock and custom. Similar to stock events, stock methods are those methods for
which COleControl provides an implementation. For more information on stock methods, see the article MFC
ActiveX Controls: Adding Stock Methods. Custom methods, defined by the developer, allow additional
customization of the control. For more information, see the article MFC ActiveX Controls: Adding Custom
Methods.
The Microsoft Foundation Class Library (MFC) implements a mechanism that allows your control to support
stock and custom methods. The first part is class COleControl . Derived from CWnd , COleControl member
functions support stock methods that are common to all ActiveX controls. The second part of this mechanism is
the dispatch map. A dispatch map is similar to a message map; however, instead of mapping a function to a
Windows message ID, a dispatch map maps virtual member functions to IDispatch IDS.
For a control to support various methods properly, its class must declare a dispatch map. This is accomplished by
the following line of code located in control class header (.H) file:

DECLARE_DISPATCH_MAP()

The main purpose of the dispatch map is to establish the relationship between the method names used by an
external caller (such as the container) and the member functions of the control's class that implement the
methods. After the dispatch map has been declared, it needs to be defined in the control's implementation (.CPP)
file. The following lines of code define the dispatch map:

BEGIN_DISPATCH_MAP(CMyAxUICtrl, COleControl)

END_DISPATCH_MAP()

If you used the MFC ActiveX Control Wizard to create the project, these lines were added automatically. If the
MFC ActiveX Control Wizard was not used, you must add these lines manually.
The following articles discuss methods in detail:
MFC ActiveX Controls: Adding Stock Methods
MFC ActiveX Controls: Adding Custom Methods
MFC ActiveX Controls: Returning Error Codes From a Method

See also
MFC ActiveX Controls
MFC ActiveX Controls: Adding Stock Methods
3/27/2020 • 2 minutes to read • Edit Online

A stock method differs from a custom method in that it is already implemented by class COleControl. For example,
COleControl contains a predefined member function that supports the Refresh method for your control. The
dispatch map entry for this stock method is DISP_STOCKFUNC_REFRESH.

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.

COleControl supports two stock methods: DoClick and Refresh. Refresh is invoked by the control's user to
immediately update the control's appearance; DoClick is invoked to fire the control's Click event.

M ET H O D DISPATC H M A P EN T RY C O M M EN T

DoClick DISP_STOCKPROP_DOCLICK( ) Fires a Click event.

Refresh DISP_STOCKPROP_REFRESH( ) Immediately updates the control's


appearance.

Adding a Stock Method Using the Add Method Wizard


Adding a stock method is simple using the Add Method Wizard. The following procedure demonstrates adding the
Refresh method to a control created using the MFC ActiveX Control Wizard.
To add the stock Refresh method using the Add Method Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Method .
This opens the Add Method Wizard.
5. In the Method Name box, click Refresh .
6. Click Finish .

Add Method Wizard Changes for Stock Methods


Because the stock Refresh method is supported by the control's base class, the Add Method Wizard does not
change the control's class declaration in any way. It adds an entry for the method to the control's dispatch map and
to its .IDL file. The following line is added to the control's dispatch map, located in its implementation (.CPP) file:

DISP_STOCKFUNC_REFRESH()
This makes the Refresh method available to the control's users.
The following line is added to the control's .IDL file:

[id(DISPID_REFRESH), helpstring("method Refresh")] void Refresh(void);

This line assigns the Refresh method a specific ID number.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Adding Custom Methods
3/31/2020 • 2 minutes to read • Edit Online

Custom methods differ from stock methods in that they are not already implemented by COleControl . You must
supply the implementation for each custom method you add to your control.

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.

An ActiveX control user can call a custom method at any time to perform control-specific actions. The dispatch
map entry for custom methods is of the form DISP_FUNCTION.

Adding a Custom Method With the Add Method Wizard


The following procedure demonstrates adding the custom method PtInCircle to an ActiveX control's skeleton code.
PtInCircle determines whether the coordinates passed to the control are inside or outside the circle. This same
procedure can also be used to add other custom methods. Substitute your custom method name and its
parameters for the PtInCircle method name and parameters.

NOTE
This example uses the InCircle function from the article Events. For more information on this function, see the article
MFC ActiveX Controls: Adding Custom Events to an ActiveX Control.

To add the PtInCircle custom method using the Add Method Wizard
1. Load the control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Method .
This opens the Add Method Wizard.
5. In the Method Name box, type PtInCircle.
6. In the Internal Name box, type the name of the method's internal function or use the default value (in this
case, PtInCircle).
7. In the Return Type box, click VARIANT_BOOL for the method's return type.
8. Using the Parameter Type and Parameter Name controls, add a parameter called xCoord (type
OLE_XPOS_PIXELS ).
9. Using the Parameter Type and Parameter Name controls, add a parameter called yCoord (type
OLE_YPOS_PIXELS ).
10. Click Finish .
Add Method Wizard Changes for Custom Methods
When you add a custom method, the Add Method Wizard makes some changes to the control class header (.H)
and implementation (.CPP) files. The following line is added to the dispatch map declaration in the control class
header (.H) file:

VARIANT_BOOL PtInCircle(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);

This code declares a dispatch method handler called PtInCircle . This function can be called by the control user
using the external name PtInCircle .
The following line is added to the control's .IDL file:

[id(1), helpstring("method PtInCircle")] VARIANT_BOOL PtInCircle(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS


yCoord);

This line assigns the PtInCircle method a specific ID number, the method's position in the Add Method Wizard
methods and properties list. Because the Add Method Wizard was used to add the custom method, the entry for it
was added automatically to the project's .IDL file.
In addition, the following line, located in the implementation (.CPP) file of the control class, is added to the control's
dispatch map:

DISP_FUNCTION_ID(CMyAxUICtrl, "PtInCircle", dispidPtInCircle, PtInCircle, VT_BOOL, VTS_XPOS_PIXELS


VTS_YPOS_PIXELS)

The DISP_FUNCTION macro maps the method PtInCircle to the control's handler function, PtInCircle , declares
the return type to be VARIANT_BOOL , and declares two parameters of type VTS_XPOS_PIXELS and
VTS_YPOSPIXELS to be passed to PtInCircle .
Finally, the Add Method Wizard adds the stub function CSampleCtrl::PtInCircle to the bottom of the control's
implementation (.CPP) file. For PtInCircle to function as stated previously, it must be modified as follows:

VARIANT_BOOL CMyAxUICtrl::PtInCircle(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord)


{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

CPoint point(xCoord, yCoord);


return InCircle(point);
}

See also
MFC ActiveX Controls
Class View and Object Browser Icons
MFC ActiveX Controls: Returning Error Codes From a
Method
3/27/2020 • 2 minutes to read • Edit Online

This article describes how to return error codes from an ActiveX control method.
To indicate that an error has occurred within a method, you should use the COleControl::ThrowError member
function, which takes an SCODE (status code) as a parameter. You can use a predefined SCODE or define one of
your own.

NOTE
ThrowError is meant to be used only as a means of returning an error from within a property's Get or Set function or an
automation Method. These are the only times that the appropriate exception handler will be present on the stack.

Helper functions exist for the most common predefined SCODEs, such as COleControl::SetNotSupported,
COleControl::GetNotSupported, and COleControl::SetNotPermitted.
For a list of predefined SCODEs and instructions on defining custom SCODEs, see the section Handling Errors in
Your ActiveX Control in ActiveX Controls: Advanced Topics.
For more information on reporting exceptions in other areas of your code, see COleControl::FireError and the
section Handling Errors in Your ActiveX Control in ActiveX Controls: Advanced Topics.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Properties
3/4/2019 • 2 minutes to read • Edit Online

An ActiveX control fires events to communicate with its control container. The container, in return, uses methods
and properties to communicate with the control. Methods and properties are similar in use and purpose,
respectively, to member functions and member variables of a C++ class. Properties are data members of the
ActiveX control that are exposed to any container. Properties provide an interface for applications that contain
ActiveX controls, such as Automation clients and ActiveX control containers.
Properties are also called attributes.
For more information on ActiveX control methods, see the article MFC ActiveX Controls: Methods.
ActiveX controls can implement both stock and custom methods and properties. Class COleControl provides an
implementation for stock properties. (For a complete list of stock properties, see the article MFC ActiveX Controls:
Adding Stock Properties.) Custom properties, defined by the developer, add specialized capabilities to an ActiveX
control. For more information, see MFC ActiveX Controls: Adding Custom Properties.
Both custom and stock properties, like methods, are supported by a mechanism that consists of a dispatch map
that handles properties and methods and existing member functions of the COleControl class. In addition, these
properties can have parameters that the developer uses to pass extra information to the control.
The following articles discuss ActiveX control properties in more detail:
MFC ActiveX Controls: Adding Stock Properties
MFC ActiveX Controls: Adding Custom Properties
MFC ActiveX Controls: Advanced Property Implementation
MFC ActiveX Controls: Accessing Ambient Properties

See also
MFC ActiveX Controls
MFC ActiveX Controls: Adding Stock Properties
3/27/2020 • 4 minutes to read • Edit Online

Stock properties differ from custom properties in that they are already implemented by the class COleControl .
COleControl contains predefined member functions that support common properties for the control. Some
common properties include the control's caption and the foreground and background colors. For information on
other stock properties, see Stock Properties Supported by the Add Property Wizard later in this article. The
dispatch map entries for stock properties are always prefixed by DISP_STOCKPROP.
This article describes how to add a stock property (in this case, Caption) to an ActiveX control using the Add
Property Wizard and explains the resulting code modifications. Topics include:
Using the Add Property Wizard to add a stock property
Add Property Wizard changes for stock properties
Stock properties supported by the Add Property Wizard
Stock properties and notification
Color properties

NOTE
Visual Basic custom controls typically have properties such as Top, Left, Width, Height, Align, Tag, Name, TabIndex,
TabStop, and Parent. ActiveX control containers, however, are responsible for implementing these control properties
and therefore ActiveX controls should not support these properties.

Using the Add Property Wizard to Add a Stock Property


Adding stock properties requires less code than adding custom properties because support for the property is
handled automatically by COleControl . The following procedure demonstrates adding the stock Caption property
to an ActiveX control framework and can also be used to add other stock properties. Substitute the selected stock
property name for Caption.
To add the stock Caption property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, click Caption .
6. Click Finish .

Add Property Wizard Changes for Stock Properties


Because COleControl supports stock properties, the Add Property Wizard does not change the class declaration in
any way; it adds the property to the dispatch map. The Add Property Wizard adds the following line to the
dispatch map of the control, which is located in the implementation (.CPP) file:

DISP_STOCKPROP_CAPTION()

The following line is added to your control's interface description (.IDL) file:

[id(DISPID_CAPTION), helpstring("property Caption")] BSTR Caption;

This line assigns the Caption property a specific ID. Notice that the property is bindable and will request
permission from the database before modifying the value.
This makes the Caption property available to users of your control. To use the value of a stock property, access a
member variable or member function of the COleControl base class. For more information on these member
variables and member functions, see the next section, Stock Properties Supported by the Add Property Wizard.

Stock Properties Supported by the Add Property Wizard


The COleControl class provides nine stock properties. You can add the properties you want by using the Add
Property Wizard.

P RO P ERT Y DISPATC H M A P EN T RY H O W TO A C C ESS VA L UE

Appearance DISP_STOCKPROP_APPEARANCE( ) Value accessible as m_sAppearance .

BackColor DISP_STOCKPROP_BACKCOLOR( ) Value accessible by calling


GetBackColor .

BorderStyle DISP_STOCKPROP_BORDERSTYLE( ) Value accessible as m_sBorderStyle .

Caption DISP_STOCKPROP_CAPTION( ) Value accessible by calling


InternalGetText .

Enabled DISP_STOCKPROP_ENABLED( ) Value accessible as m_bEnabled .

Font DISP_STOCKPROP_FONT( ) See the article MFC ActiveX Controls:


Using Fonts for usage.

ForeColor DISP_STOCKPROP_FORECOLOR( ) Value accessible by calling


GetForeColor .

hWnd DISP_STOCKPROP_HWND( ) Value accessible as m_hWnd .

Text DISP_STOCKPROP_TEXT( ) Value accessible by calling


InternalGetText . This property is the
same as Caption , except for the
property name.

ReadyState DISP_STOCKPROP_READYSTATE() Value accessible as m_lReadyState or


GetReadyState

Stock Properties and Notification


Most stock properties have notification functions that can be overridden. For example, whenever the BackColor
property is changed, the OnBackColorChanged function (a member function of the control class) is called. The
default implementation (in COleControl ) calls InvalidateControl . Override this function if you want to take
additional actions in response to this situation.

Color Properties
You can use the stock ForeColor and BackColor properties, or your own custom color properties, when painting
the control. To use a color property, call the COleControl::TranslateColor member function. The parameters of this
function are the value of the color property and an optional palette handle. The return value is a COLORREF value
that can be passed to GDI functions, such as SetTextColor and CreateSolidBrush .
The color values for the stock ForeColor and BackColor properties are accessed by calling either the
GetForeColor or the GetBackColor function, respectively.

The following example demonstrates using these two color properties when painting a control. It initializes a
temporary COLORREF variable and a CBrush object with calls to TranslateColor : one using the ForeColor
property and the other using the BackColor property. A temporary CBrush object is then used to paint the
control's rectangle, and the text color is set using the ForeColor property.

CBrush bkBrush(TranslateColor(GetBackColor()));
COLORREF clrFore = TranslateColor(GetForeColor());
pdc->FillRect(rcBounds, &bkBrush);
pdc->SetTextColor(clrFore);
pdc->DrawText(InternalGetText(), -1, rcBounds, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

See also
MFC ActiveX Controls
MFC ActiveX Controls: Properties
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Adding Custom Properties
3/31/2020 • 4 minutes to read • Edit Online

Custom properties differ from stock properties in that custom properties are not already implemented by the
COleControl class. A custom property is used to expose a certain state or appearance of an ActiveX control to a
programmer using the control.
This article describes how to add a custom property to the ActiveX control using the Add Property Wizard and
explains the resulting code modifications. Topics include:
Using the Add Property Wizard to add a custom property
Add Property Wizard changes for custom properties
Custom properties come in four varieties of implementation: Member Variable, Member Variable with Notification,
Get/Set Methods, and Parameterized.
Member Variable Implementation
This implementation represents the property's state as a member variable in the control class. Use the
Member Variable implementation when it is not important to know when the property value changes. Of
the three types, this implementation creates the least amount of support code for the property. The dispatch
map entry macro for member variable implementation is DISP_PROPERTY.
Member Variable with Notification Implementation
This implementation consists of a member variable and a notification function created by the Add Property
Wizard. The notification function is automatically called by the framework after the property value changes.
Use the Member Variable with Notification implementation when you need to be notified after a property
value has changed. This implementation requires more time because it requires a function call. The dispatch
map entry macro for this implementation is DISP_PROPERTY_NOTIFY.
Get/Set Methods Implementation
This implementation consists of a pair of member functions in the control class. The Get/Set Methods
implementation automatically calls the Get member function when the control's user requests the current
value of the property and the Set member function when the control's user requests that the property be
changed. Use this implementation when you need to compute the value of a property during run time,
validate a value passed by the control's user before changing the actual property, or implement a read- or
write-only property type. The dispatch map entry macro for this implementation is DISP_PROPERTY_EX. The
following section, Using the Add Property Wizard to Add a Custom Property, uses the CircleOffset custom
property to demonstrate this implementation.
Parameterized Implementation
Parameterized implementation is supported by the Add Property Wizard. A parameterized property
(sometimes called a property array) can be used to access a set of values through a single property of your
control. The dispatch map entry macro for this implementation is DISP_PROPERTY_PARAM. For more
information on implementing this type, see Implementing a Parameterized Property in the article ActiveX
Controls: Advanced Topics.

Using the Add Property Wizard to Add a Custom Property


The following procedure demonstrates adding a custom property, CircleOffset, which uses the Get/Set Methods
implementation. The CircleOffset custom property allows the control's user to offset the circle from the center of
the control's bounding rectangle. The procedure for adding custom properties with an implementation other than
Get/Set Methods is very similar.
This same procedure can also be used to add other custom properties you want. Substitute your custom property
name for the CircleOffset property name and parameters.
To add the CircleOffset custom property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, type CircleOffset.
6. For Implementation Type , click Get/Set Methods .
7. In the Proper ty Type box, select shor t .
8. Type unique names for your Get and Set Functions, or accept the default names.
9. Click Finish .

Add Property Wizard Changes for Custom Properties


When you add the CircleOffset custom property, the Add Property Wizard makes changes to the header (.H) and
the implementation (.CPP) files of the control class.
The following lines are added to the .H file to declare two functions called GetCircleOffset and SetCircleOffset :

SHORT GetCircleOffset(void);
void SetCircleOffset(SHORT newVal);

The following line is added to your control's .IDL file:

[id(2), helpstring("property CircleOffset")] SHORT CircleOffset;


[id(3), helpstring("property MyProperty")] SHORT MyProperty;

This line assigns the CircleOffset property a specific ID number, taken from the method's position in the methods
and properties list of the Add Property Wizard.
In addition, the following line is added to the dispatch map (in the .CPP file of the control class) to map the
CircleOffset property to the control's two handler functions:

DISP_PROPERTY_EX_ID(CMyAxUICtrl, "CircleOffset", dispidCircleOffset, GetCircleOffset, SetCircleOffset, VT_I2)

Finally, the implementations of the GetCircleOffset and SetCircleOffset functions are added to the end of the
control's .CPP file. In most cases, you will modify the Get function to return the value of the property. The Set
function will usually contain code that should be executed either before or after the property changes.
void CMyAxUICtrl::SetCircleOffset(SHORT /*newVal*/)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: Add your property handler code here

SetModifiedFlag();
}

Note that the Add Property Wizard automatically adds a call, to SetModifiedFlag, to the body of the Set function.
Calling this function marks the control as modified. If a control has been modified, its new state will be saved when
the container is saved. This function should be called whenever a property, saved as part of the control's persistent
state, changes value.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Properties
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Advanced Property
Implementation
3/31/2020 • 2 minutes to read • Edit Online

This article describes topics related to implementing advanced properties in an ActiveX control.

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.

Read-only and write-only properties


Returning error codes from a property

Read-Only and Write-Only Properties


The Add Property Wizard provides a quick and easy method to implement read-only or write-only properties for
the control.
To implement a read-only or write-only property
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, type the name of your property.
6. For Implementation Type , click Get/Set Methods .
7. In the Proper ty Type box, select the proper type for the property.
8. If you want a read-only property, clear the Set function name. If you want a write-only property, clear the
Get function name.
9. Click Finish .
When you do this, the Add Property Wizard inserts the function SetNotSupported or GetNotSupported in the
dispatch map entry in place of a normal Set or Get function.
If you want to change an existing property to be read-only or write-only, you can edit the dispatch map manually
and remove the unnecessary Set or Get function from the control class.
If you want a property to be conditionally read-only or write-only (for example, only when your control is
operating in a particular mode), you can provide the Set or Get function, as normal, and call the SetNotSupported
or GetNotSupported function where appropriate. For example:
void CMyAxUICtrl::SetMyProperty(SHORT newVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

if (m_bReadOnlyMode) // some control-specific state


{
SetNotSupported();
}
else
{
m_iPropVal = newVal; // set property as normal
SetModifiedFlag();
}
}

This code sample calls SetNotSupported if the m_bReadOnlyMode data member is TRUE . If FALSE , then the property
is set to the new value.

Returning Error Codes From a Property


To indicate that an error has occurred while attempting to get or set a property, use the COleControl::ThrowError
function, which takes an SCODE (status code) as a parameter. You can use a predefined SCODE or define one of
your own. For a list of predefined SCODEs and instructions for defining custom SCODEs, see Handling Errors in
Your ActiveX Control in the article ActiveX controls: Advanced Topics.
Helper functions exist for the most common predefined SCODEs, such as COleControl::SetNotSupported,
COleControl::GetNotSupported, and COleControl::SetNotPermitted.

NOTE
ThrowError is meant to be used only as a means of returning an error from within a property's Get or Set function or an
automation method. These are the only times that the appropriate exception handler will be present on the stack.

For more information on reporting exceptions in other areas of the code, see COleControl::FireError and the section
Handling Errors in Your ActiveX Control in the article ActiveX Controls: Advanced Topics.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Properties
MFC ActiveX Controls: Methods
COleControl Class
MFC ActiveX Controls: Accessing Ambient Properties
3/4/2019 • 2 minutes to read • Edit Online

This article discusses how an ActiveX control can access the ambient properties of its control container.
A control can obtain information about its container by accessing the container's ambient properties. These
properties expose visual characteristics, such as the container's background color, the current font used by the
container, and operational characteristics, such as whether the container is currently in user mode or designer
mode. A control can use ambient properties to tailor its appearance and behavior to the particular container in
which it is embedded. However, a control should never assume that its container will support any particular
ambient property. In fact, some containers may not support any ambient properties at all. In the absence of an
ambient property, a control should assume a reasonable default value.
To access an ambient property, make a call to COleControl::GetAmbientProperty. This function expects the dispatch
ID for the ambient property as the first parameter (the file OLECTL.H defines dispatch IDs for the standard set of
ambient properties).
The parameters of the GetAmbientProperty function are the dispatch ID, a variant tag indicating the expected
property type, and a pointer to memory where the value should be returned. The type of data to which this pointer
refers will vary depending on the variant tag. The function returns TRUE if the container supports the property,
otherwise it returns FALSE .
The following code example obtains the value of the ambient property called "UserMode." If the property is not
supported by the container, a default value of TRUE is assumed:

BOOL bUserMode;
if (!GetAmbientProperty(DISPID_AMBIENT_USERMODE, VT_BOOL, &bUserMode))
bUserMode = TRUE;

For your convenience, COleControl supplies helper functions that access many of the commonly used ambient
properties and return appropriate defaults when the properties are not available. These helper functions are as
follows:
COleControl::AmbientBackColor
AmbientDisplayName
AmbientFont

NOTE
Caller must call Release( ) on the returned font.

AmbientForeColor
AmbientLocaleID
AmbientScaleUnits
AmbientTextAlign
AmbientUserMode
AmbientUIDead
AmbientShowHatching
AmbientShowGrabHandles
If the value of an ambient property changes (through some action of the container), the OnAmbientPropertyChanged
member function of the control is called. Override this member function to handle such a notification. The
parameter for OnAmbientPropertyChanged is the dispatch ID of the affected ambient property. The value of this
dispatch ID may be DISPID_UNKNOWN, which indicates that one or more ambient properties has changed, but
information about which properties were affected is unavailable.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Property Pages
3/27/2020 • 4 minutes to read • Edit Online

Property pages allow an ActiveX control user to view and change ActiveX control properties. These properties are
accessed by invoking a control properties dialog box, which contains one or more property pages that provide a
customized, graphical interface for viewing and editing the control properties.

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 control property pages are displayed in two ways:


When the control's Properties verb (OLEIVERB_PROPERTIES ) is invoked, the control opens a modal
property dialog box that contains the control's property pages.
The container can display its own modeless dialog box that shows the property pages of the selected
control.
The properties dialog box (illustrated in the following figure) consists of an area for displaying the current
property page, tabs for switching between property pages, and a collection of buttons that perform common tasks
such as closing the property page dialog, canceling any changes made, or immediately applying any changes to
the ActiveX control.

Properties Dialog Box


This article covers topics related to using property pages in an ActiveX control. These include:
Implementing the default property page for an ActiveX control
Adding controls to a property page
Customizing the DoDataExchange function
For more information on using property pages in an ActiveX control, see the following articles:
MFC ActiveX Controls: Adding Another Custom Property Page
MFC ActiveX Controls: Using Stock Property Pages
For information on using property sheets in an MFC application other than an ActiveX control, see Property
Sheets.

Implementing the Default Property Page


If you use the ActiveX Control Wizard to create your control project, the ActiveX Control Wizard provides a default
property page class for the control derived from COlePropertyPage Class. Initially, this property page is blank, but
you can add any dialog box control or set of controls to it. Because the ActiveX Control Wizard creates only one
property page class by default, additional property page classes (also derived from COlePropertyPage ) must be
created using Class View. For more information on this procedure, see MFC ActiveX Controls: Adding Another
Custom Property Page.
Implementing a property page (in this case, the default) is a three-step process:
To implement a property page
1. Add a COlePropertyPage -derived class to the control project. If the project was created using the ActiveX
Control Wizard (as in this case), the default property page class already exists.
2. Use the dialog editor to add any controls to the property page template.
3. Customize the DoDataExchange function of the COlePropertyPage -derived class to exchange values between
the property page control and the ActiveX control.
For example purposes, the following procedures use a simple control (named "Sample"). Sample was created
using the ActiveX Control Wizard and contains only the stock Caption property.

Adding Controls to a Property Page


To add controls to a property page
1. With your control project open, open Resource View.
2. Double-click the Dialog directory icon.
3. Open the IDD_PROPPAGE_SAMPLE dialog box.
The ActiveX Control Wizard appends the name of the project to the end of the dialog ID, in this case,
Sample.
4. Drag and drop the selected control from the Toolbox onto the dialog box area.
5. For this example, a text label control "Caption :" and an edit box control with an IDC_CAPTION identifier are
sufficient.
6. Click Save on the Toolbar to save your changes.
Now that the user interface has been modified, you need to link the edit box with the Caption property. This is
done in the following section by editing the CSamplePropPage::DoDataExchange function.

Customizing the DoDataExchange Function


Your property page CWnd::DoDataExchange function allows you to link property page values with the actual
values of properties in the control. To establish links, you must map the appropriate property page fields to their
respective control properties.
These mappings are implemented using the property page DDP_ functions. The DDP_ functions work like the
DDX_ functions used in standard MFC dialogs, with one exception. In addition to the reference to a member
variable, DDP_ functions take the name of the control property. The following is a typical entry in the
DoDataExchange function for a property page.
DDP_Text(pDX, IDC_CAPTION, m_caption, _T("Caption"));

This function associates the property page's m_caption member variable with the Caption, using the DDP_TEXT
function.
After you have the property page control inserted, you need to establish a link between the property page control,
IDC_CAPTION, and the actual control property, Caption, using the DDP_Text function as described above.
Property Pages are available for other dialog control types, such as check boxes, radio buttons, and list boxes. The
table below lists the entire set of property page DDP_ functions and their purposes:
Property Page Functions
F UN C T IO N N A M E USE T H IS F UN C T IO N TO L IN K

DDP_CBIndex The selected string's index in a combo box with a control


property.

DDP_CBString The selected string in a combo box with a control property.


The selected string can begin with the same letters as the
property's value but need not match it fully.

DDP_CBStringExact The selected string in a combo box with a control property.


The selected string and the property's string value must
match exactly.

DDP_Check A check box with a control property.

DDP_LBIndex The selected string's index in a list box with a control property.

DDP_LBString The selected string in a list box with a control property. The
selected string can begin with the same letters as the
property's value but need not match it fully.

DDP_LBStringExact The selected string in a list box with a control property. The
selected string and the property's string value must match
exactly.

DDP_Radio A radio button with a control property.

DDP_Text Text with a control property.

See also
MFC ActiveX Controls
COlePropertyPage Class
MFC ActiveX Controls: Adding Another Custom
Property Page
3/31/2020 • 3 minutes to read • Edit Online

Occasionally, an ActiveX control will have more properties than can reasonably fit on one property page. In this
case, you can add property pages to the ActiveX control to display these properties.
This article discusses adding new property pages to an ActiveX control that already has at least one property page.
For more information on adding stock property pages (font, picture, or color), see the article MFC ActiveX Controls:
Using Stock Property Pages.
The following procedures use a sample ActiveX control framework created by the ActiveX Control Wizard.
Therefore, the class names and identifiers are unique to this example.
For more information on using property pages in an ActiveX control, see the following articles:
MFC ActiveX Controls: Property Pages
MFC ActiveX Controls: Using Stock Property Pages

NOTE
It is strongly recommended that new property pages adhere to the size standard for ActiveX control property pages.
The stock picture and color property pages measure 250x62 dialog units (DLU). The standard font property page is
250x110 DLUs. The default property page created by the ActiveX Control Wizard uses the 250x62 DLU standard.

To insert a new property page template into your project


1. With your control project open, open Resource View in the project workspace.
2. Right-click in Resource View to open the shortcut menu and click Add Resource .
3. Expand the Dialog node, and select IDD_OLE_PROPPAGE_SMALL .
4. Click New to add the resource to your project.
5. Select the new property page template to refresh the Proper ties window (in Resource View ).
6. Enter a new value for the ID property. This example uses IDD_PROPPAGE_NEWPAGE .
7. Click Save on the toolbar.
To associate the new template with a class
1. Open Class View.
2. Right-click in Class View to open the shortcut menu.
3. From the shortcut menu, click Add and then click Add Class .
This opens the Add Class dialog box.
4. Double-click the MFC Class template.
5. In the Class Name box in the MFC Class Wizard, type a name for the new dialog class. (In this example,
CAddtlPropPage .)
6. If you want to change file names, click Change . Type in the names for your implementation and header
files, or accept the default names.
7. In the Base Class box, select COlePropertyPage .
8. In the Dialog ID box, select IDD_PROPPAGE_NEWPAGE .
9. Click Finish to create the class.
To allow the control's users access to this new property page, make the following changes to the control's property
page IDs macro section (located in the control implementation file):

BEGIN_PROPPAGEIDS(CMyAxUICtrl, 2)
PROPPAGEID(CMyAxUIPropPage::guid)
PROPPAGEID(CAddtlPropPage::guid)
END_PROPPAGEIDS(CMyAxUICtrl)

Note that you must increase the second parameter of the BEGIN_PROPPAGEIDS macro (the property page count)
from 1 to 2.
You must also modify the control implementation file (.CPP) file to include the header (.H) file of the new property
page class.
The next step involves creating two new string resources that will provide a type name and a caption for the new
property page.
To add new string resources to a property page
1. With your control project open, open Resource View.
2. Double-click the String Table folder and then double-click the existing string table resource to which you
want to add a string.
This opens the string table in a window.
3. Select the blank line at the end of the string table and type the text, or caption, of the string: for example,
"Additional Property Page."
This opens a String Proper ties page showing Caption and ID boxes. The Caption box contains the string
you typed.
4. In the ID box, select or type an ID for the string. Press Enter when you finish.
This example uses IDS_SAMPLE_ADDPAGE for the type name of the new property page.
5. Repeat steps 3 and 4 using IDS_SAMPLE_ADDPPG_CAPTION for the ID and "Additional Property Page"
for the caption.
6. In the .CPP file of your new property page class (in this example, CAddtlPropPage ) modify the
CAddtlPropPage::CAddtlPropPageFactory::UpdateRegistry so that IDS_SAMPLE_ADDPAGE is passed by
AfxOleRegisterPropertyPageClass, as in the following example:

BOOL CAddtlPropPage::CAddtlPropPageFactory::UpdateRegistry(BOOL bRegister)


{
if (bRegister)
return AfxOleRegisterPropertyPageClass(AfxGetInstanceHandle(),
m_clsid, IDS_SAMPLE_ADDPAGE);
else
return AfxOleUnregisterClass(m_clsid, NULL);
}
7. Modify the constructor of CAddtlPropPage so that IDS_SAMPLE_ADDPPG_CAPTION is passed to the
COlePropertyPage constructor, as follows:

CAddtlPropPage::CAddtlPropPage() :
COlePropertyPage(IDD, IDS_SAMPLE_ADDPPG_CAPTION)
{

After you have made the necessary modifications rebuild your project and use Test Container to test the new
property page. See Testing Properties and Events with Test Container for information on how to access the test
container.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Using Stock Property Pages
3/27/2020 • 2 minutes to read • Edit Online

This article discusses the stock property pages available for ActiveX controls and how to use them.

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.

For more information on using property pages in an ActiveX control, see the following articles:
MFC ActiveX Controls: Property Pages
MFC ActiveX Controls: Adding Another Custom Property Page
MFC provides three stock property pages for use with ActiveX controls: CLSID_CColorPropPage ,
CLSID_CFontPropPage , and CLSID_CPicturePropPage . These pages display a user interface for stock color, font, and
picture properties, respectively.
To incorporate these property pages into a control, add their IDs to the code that initializes the control's array of
property page IDs. In the following example, this code, located in the control implementation file (.CPP), initializes
the array to contain all three stock property pages and the default property page (named CMyPropPage in this
example):

BEGIN_PROPPAGEIDS(CMyAxOptCtrl, 4)
PROPPAGEID(CMyAxOptPropPage::guid)
PROPPAGEID(CLSID_CFontPropPage)
PROPPAGEID(CLSID_CColorPropPage)
PROPPAGEID(CLSID_CPicturePropPage)
END_PROPPAGEIDS(CMyAxOptCtrl)

Note that the count of property pages, in the BEGIN_PROPPAGEIDS macro, is 4. This represents the number of
property pages supported by the ActiveX control.
After these modifications have been made, rebuild your project. Your control now has property pages for the font,
picture, and color properties.

NOTE
If the control stock property pages cannot be accessed, it may be because the MFC DLL (MFCxx.DLL) has not been properly
registered with the current operating system. This usually results from installing Visual C++ under an operating system
different from the one currently running.

TIP
If your stock property pages are not visible (see previous Note), register the DLL by running RegSvr32.exe from the
command line with the full path name to the DLL.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Adding Stock Properties
MFC ActiveX Controls: Creating an Automation
Server
3/4/2019 • 2 minutes to read • Edit Online

You can develop an MFC ActiveX control as an Automation server for the purpose of programmatically embedding
that control in another application and calling methods in the control from the application. Such a control would
still be available to be hosted in an ActiveX control container.
To create a control as an Automation server
1. Create the control.
2. Add methods.
3. Override IsInvokeAllowed.
4. Build the control.
To programmatically access the methods in an Automation server
1. Create an application, for example, an MFC exe.
2. At the beginning of the InitInstance function, add the following line:

AfxOleInit();

3. In Class View, right-click the project node and select Add class from typelib to import the type library.
This will add files with the file name extensions .h and .cpp to the project.
4. In the header file of the class where you will call one or more methods in the ActiveX control, add the
following line: #include filename.h , where file name is the name of the header file that was created when
you imported the type library.
5. In the function where a call will be made to a method in the ActiveX control, add code that creates an object
of the control's wrapper class and create the ActiveX object. For example, the following MFC code
instantiates a CCirc control, gets the Caption property, and displays the result when the OK button is clicked
in a dialog box:
void CCircDlg::OnOK()
{
UpdateData(); // Get the current data from the dialog box.
CCirc2 circ; // Create a wrapper class for the ActiveX object.
COleException e; // In case of errors

// Create the ActiveX object.


// The name is the control's progid; look it up using OleView
if (circ.CreateDispatch(_T("CIRC.CircCtrl.1"), &e))
{
// get the Caption property of your ActiveX object
// get the result into m_strCaption
m_strCaption = circ.GetCaption();
UpdateData(FALSE); // Display the string in the dialog box.
}
else { // An error
TCHAR buf[255];
e.GetErrorMessage(buf, sizeof(buf) / sizeof(TCHAR));
AfxMessageBox(buf); // Display the error message.
}
}

If you add methods to the ActiveX control after you use it in an application, you can begin using the latest version of
the control in the application by deleting the files that were created when you imported the type library. Then
import the type library again.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Using Fonts
3/27/2020 • 9 minutes to read • Edit Online

If your ActiveX control displays text, you can allow the control user to change the text appearance by changing a
font property. Font properties are implemented as font objects and can be one of two types: stock or custom. Stock
Font properties are preimplemented font properties that you can add using the Add Property Wizard. Custom
Font properties are not preimplemented and the control developer determines the property's behavior and usage.
This article covers the following topics:
Using the Stock Font property
Using Custom Font Properties in Your Control

Using the Stock Font Property


Stock Font properties are preimplemented by the class COleControl. In addition, a standard Font property page is
also available, allowing the user to change various attributes of the font object, such as its name, size, and style.
Access the font object through the GetFont, SetFont, and InternalGetFont functions of COleControl . The control
user will access the font object via the GetFont and SetFont functions in the same manner as any other Get/Set
property. When access to the font object is required from within a control, use the InternalGetFont function.
As discussed in MFC ActiveX Controls: Properties, adding stock properties is easy with the Add Property Wizard.
You choose the Font property, and the Add Property Wizard automatically inserts the stock Font entry into the
control's dispatch map.
To add the stock Font property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, click Font .
6. Click Finish .
The Add Property Wizard adds the following line to the control's dispatch map, located in the control class
implementation file:

DISP_STOCKPROP_FONT()

In addition, the Add Property Wizard adds the following line to the control .IDL file:

[id(DISPID_FONT)] IFontDisp* Font;

The stock Caption property is an example of a text property that can be drawn using the stock Font property
information. Adding the stock Caption property to the control uses steps similar to those used for the stock Font
property.
To add the stock Caption property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, click Caption .
6. Click Finish .
The Add Property Wizard adds the following line to the control's dispatch map, located in the control class
implementation file:

DISP_STOCKPROP_CAPTION()

Modifying the OnDraw Function


The default implementation of OnDraw uses the Windows system font for all text displayed in the control. This
means that you must modify the OnDraw code by selecting the font object into the device context. To do this, call
COleControl::SelectStockFont and pass the control's device context, as shown in the following example:

CFont* pOldFont;
TEXTMETRIC tm;
const CString& strCaption = InternalGetText();

pOldFont = SelectStockFont(pdc);
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->Ellipse(rcBounds);
pdc->GetTextMetrics(&tm);
pdc->SetTextAlign(TA_CENTER | TA_TOP);
pdc->ExtTextOut((rcBounds.left + rcBounds.right) / 2,
(rcBounds.top + rcBounds.bottom - tm.tmHeight) / 2,
ETO_CLIPPED, rcBounds, strCaption, strCaption.GetLength(), NULL);

pdc->SelectObject(pOldFont);

After the OnDraw function has been modified to use the font object, any text within the control is displayed with
characteristics from the control's stock Font property.

Using Custom Font Properties in Your Control


In addition to the stock Font property, the ActiveX control can have custom Font properties. To add a custom font
property you must:
Use the Add Property Wizard to implement the custom Font property.
Processing font notifications.
Implementing a new font notification interface.
Implementing a Custom Font Property
To implement a custom Font property, you use the Add Property Wizard to add the property and then make some
modifications to the code. The following sections describe how to add the custom HeadingFont property to the
Sample control.
To a d d t h e c u st o m F o n t p r o p e r t y u si n g t h e A d d P r o p e r t y W i z a r d

1. Load your control's project.


2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
This opens the Add Property Wizard.
5. In the Proper ty Name box, type a name for the property. For this example, use HeadingFont .
6. For Implementation Type , click Get/Set Methods .
7. In the Proper ty Type box, select IDispatch * for the property's type.
8. Click Finish .
The Add Property Wizard creates the code to add the HeadingFont custom property to the CSampleCtrl class and
the SAMPLE.IDL file. Because HeadingFont is a Get/Set property type, the Add Property Wizard modifies the
CSampleCtrl class's dispatch map to include a DISP_PROPERTY_EX_IDDISP_PROPERTY_EX macro entry:

DISP_PROPERTY_EX_ID(CMyAxFontCtrl, "HeadingFont", dispidHeadingFont,


GetHeadingFont, SetHeadingFont, VT_DISPATCH)

The DISP_PROPERTY_EX macro associates the HeadingFont property name with its corresponding CSampleCtrl
class Get and Set methods, GetHeadingFont and SetHeadingFont . The type of the property value is also specified; in
this case, VT_FONT.
The Add Property Wizard also adds a declaration in the control header file (.H) for the GetHeadingFont and
SetHeadingFont functions and adds their function templates in the control implementation file (.CPP):

IDispatch* CWizardGenCtrl::GetHeadingFont(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: Add your dispatch handler code here

return NULL;
}

void CWizardGenCtrl::SetHeadingFont(IDispatch* /*pVal*/)


{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: Add your property handler code here

SetModifiedFlag();
}

Finally, the Add Property Wizard modifies the control .IDL file by adding an entry for the HeadingFont property:
[id(1)] IDispatch* HeadingFont;

Modifications to the Control Code


Now that you have added the HeadingFont property to the control, you must make some changes to the control
header and implementation files to fully support the new property.
In the control header file (.H), add the following declaration of a protected member variable:

protected:
CFontHolder m_fontHeading;

In the control implementation file (.CPP), do the following:


Initialize m_fontHeading in the control constructor.

CMyAxFontCtrl::CMyAxFontCtrl()
: m_fontHeading(&m_xFontNotification)
{
InitializeIIDs(&IID_DNVC_MFC_AxFont, &IID_DNVC_MFC_AxFontEvents);
}

Declare a static FONTDESC structure containing default attributes of the font.

static const FONTDESC _fontdescHeading =


{ sizeof(FONTDESC), OLESTR("MS Sans Serif"), FONTSIZE(12), FW_BOLD,
ANSI_CHARSET, FALSE, FALSE, FALSE };

In the control DoPropExchange member function, add a call to the PX_Font function. This provides
initialization and persistence for your custom Font property.

void CMyAxFontCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

// [...other PX_ function calls...]


PX_Font(pPX, _T("HeadingFont"), m_fontHeading, &_fontdescHeading);
}

Finish implementing the control GetHeadingFont member function.

IDispatch* CMyAxFontCtrl::GetHeadingFont(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

return m_fontHeading.GetFontDispatch();
}

Finish implementing the control SetHeadingFont member function.


void CMyAxFontCtrl::SetHeadingFont(IDispatch* pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

m_fontHeading.InitializeFont(&_fontdescHeading, pVal);
OnFontChanged(); //notify any changes
SetModifiedFlag();
}

Modify the control OnDraw member function to define a variable to hold the previously selected font.

CFont* pOldHeadingFont;

Modify the control OnDraw member function to select the custom font into the device context by adding the
following line wherever the font is to be used.

pOldHeadingFont = SelectFontObject(pdc, m_fontHeading);

Modify the control OnDraw member function to select the previous font back into the device context by
adding the following line after the font has been used.

pdc->SelectObject(pOldHeadingFont);

After the custom Font property has been implemented, the standard Font property page should be implemented,
allowing control users to change the control's current font. To add the property page ID for the standard Font
property page, insert the following line after the BEGIN_PROPPAGEIDS macro:

PROPPAGEID(CLSID_CFontPropPage)

You must also increment the count parameter of your BEGIN_PROPPAGEIDS macro by one. The following line
illustrates this:

BEGIN_PROPPAGEIDS(CMyAxFontCtrl, 2)

After these changes have been made, rebuild the entire project to incorporate the additional functionality.
Processing Font Notifications
In most cases the control needs to know when the characteristics of the font object have been modified. Each font
object is capable of providing notifications when it changes by calling a member function of the
IFontNotification interface, implemented by COleControl .

If the control uses the stock Font property, its notifications are handled by the OnFontChanged member function of
COleControl . When you add custom font properties, you can have them use the same implementation. In the
example in the previous section, this was accomplished by passing &m_xFontNotification when initializing the
m_fontHeading member variable.
Implementing Multiple Font Object Interfaces
The solid lines in the figure above show that both font objects are using the same implementation of
IFontNotification . This could cause problems if you wanted to distinguish which font changed.

One way to distinguish between the control's font object notifications is to create a separate implementation of the
IFontNotification interface for each font object in the control. This technique allows you to optimize your
drawing code by updating only the string, or strings, that use the recently modified font. The following sections
demonstrate the steps necessary to implement separate notification interfaces for a second Font property. The
second font property is assumed to be the HeadingFont property that was added in the previous section.
Implementing a New Font Notification Interface
To distinguish between the notifications of two or more fonts, a new notification interface must be implemented
for each font used in the control. The following sections describe how to implement a new font notification
interface by modifying the control header and implementation files.
Additions to the Header File
In the control header file (.H), add the following lines to the class declaration:

protected:
BEGIN_INTERFACE_PART(HeadingFontNotify, IPropertyNotifySink)
INIT_INTERFACE_PART(CMyAxFontCtrl, HeadingFontNotify)
STDMETHOD(OnRequestEdit)(DISPID);
STDMETHOD(OnChanged)(DISPID);
END_INTERFACE_PART(HeadingFontNotify)

This creates an implementation of the IPropertyNotifySink interface called HeadingFontNotify . This new interface
contains a method called OnChanged .
Additions to the Implementation File
In the code that initializes the heading font (in the control constructor), change &m_xFontNotification to
&m_xHeadingFontNotify. Then add the following code:
STDMETHODIMP_(ULONG) CMyAxFontCtrl::XHeadingFontNotify::AddRef()
{
METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
return 1;
}
STDMETHODIMP_(ULONG) CMyAxFontCtrl::XHeadingFontNotify::Release()
{
METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
return 0;
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::QueryInterface(REFIID iid, LPVOID FAR* ppvObj)


{
METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IPropertyNotifySink))
{
*ppvObj = this;
AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::OnChanged(DISPID)
{
METHOD_MANAGE_STATE(CMyAxFontCtrl, HeadingFontNotify)
pThis->InvalidateControl();
return NOERROR;
}

STDMETHODIMP CMyAxFontCtrl::XHeadingFontNotify::OnRequestEdit(DISPID)
{
return NOERROR;
}

The AddRef and Release methods in the IPropertyNotifySink interface keep track of the reference count for the
ActiveX control object. When the control obtains access to interface pointer, the control calls AddRef to increment
the reference count. When the control is finished with the pointer, it calls Release , in much the same way that
GlobalFree might be called to free a global memory block. When the reference count for this interface goes to
zero, the interface implementation can be freed. In this example, the QueryInterface function returns a pointer to a
IPropertyNotifySink interface on a particular object. This function allows an ActiveX control to query an object to
determine what interfaces it supports.
After these changes have been made to your project, rebuild the project and use Test Container to test the
interface. See Testing Properties and Events with Test Container for information on how to access the test
container.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Using Pictures in an ActiveX Control
MFC ActiveX Controls: Using Stock Property Pages
MFC ActiveX Controls: Using Pictures in an ActiveX
Control
3/31/2020 • 5 minutes to read • Edit Online

This article describes the common Picture type and how to implement it in your ActiveX control. Topics include:
Overview of Custom Picture Properties
Implementing a Custom Picture Property in Your ActiveX Control
Additions to Your Control Project

Overview of Custom Picture Properties


A Picture type is one of a group of types common to some ActiveX controls. The Picture type handles metafiles,
bitmaps, or icons and allows the user to specify a picture to be displayed in an ActiveX control. Custom Picture
properties are implemented using a picture object and Get/Set functions that allow the control user access to the
Picture property. Control users access the custom Picture property using the stock Picture property page.
In addition to the standard Picture type, Font and Color types are also available. For more information on using the
standard Font type in your ActiveX control, see the article MFC ActiveX Controls: Using Fonts.
The ActiveX control classes provide several components you can use to implement the Picture property within the
control. These components include:
The CPictureHolder class.
This class provides easy access to the picture object and functionality for the item displayed by the custom
Picture property.
Support for properties of type LPPICTUREDISP , implemented with Get/Set functions.
Using Class View you can quickly add a custom property, or properties, that supports the Picture type. For
more information on adding ActiveX control properties with Class View, see the article MFC ActiveX
Controls: Properties.
A property page that manipulates a control's Picture property or properties.
This property page is part of a group of stock property pages available to ActiveX controls. For more
information on ActiveX control property pages, see the article MFC ActiveX Controls: Using Stock Property
Pages

Implementing a Custom Picture Property in Your ActiveX Control


When you have completed the steps outlined in this section, the control can display pictures chosen by its user. The
user can change the displayed picture using a property page that shows the current picture and has a Browse
button that allows the user to the select different pictures.
A custom Picture property is implemented using a process similar to that used for implementing other properties,
the main difference being that the custom property must support a Picture type. Because the item of the Picture
property must be drawn by the ActiveX control, a number of additions and modifications must be made to the
property before it can be fully implemented.
To implement a custom Picture property, you must do the following:
Add code to your control project.
A standard Picture property page ID, a data member of type CPictureHolder , and a custom property of type
LPPICTUREDISP with a Get/Set implementation must be added.
Modify several functions in your control class.
These modifications will be made to several functions that are responsible for the drawing of your ActiveX
control.

Additions to Your Control Project


To add the property page ID for the standard Picture property page, insert the following line after the
BEGIN_PROPPAGEIDS macro in the control implementation file (.CPP):

PROPPAGEID(CLSID_CPicturePropPage)

You must also increment the count parameter of your BEGIN_PROPPAGEIDS macro by one. The following line
illustrates this:

BEGIN_PROPPAGEIDS(CMyAxPicCtrl, 2)

To add the CPictureHolder data member to the control class, insert the following line under the protected section
of the control class declaration in the control header file (.H):

CPictureHolder m_pic;

It is not necessary to name your data member m_pic; any name will suffice.
Next, add a custom property that supports a Picture type:
To add a custom picture property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, choose Add and then Add Proper ty .
5. In the Proper ty Name box, type the property name. For example purposes, ControlPicture is used in this
procedure.
6. In the Proper ty Type box, select IPictureDisp * for the property type.
7. For Implementation Type , click Get/Set Methods .
8. Type unique names for your Get and Set Functions or accept the default names. (In this example, the default
names GetControlPicture and SetControlPicture are used.)
9. Click Finish .
The Add Property Wizard adds the following code between the dispatch map comments in the control header (.H)
file:
IPictureDisp* GetControlPicture(void);
void SetControlPicture(IPictureDisp* pVal);

In addition, the following code was inserted in the dispatch map of the control implementation (.CPP) file:

DISP_PROPERTY_EX_ID(CMyAxPicCtrl, "ControlPicture", dispidControlPicture,


GetControlPicture, SetControlPicture, VT_PICTURE)

The Add Property Wizard also adds the following two stub functions in the control implementation file:

IPictureDisp* CWizardGenCtrl::GetControlPicture(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: Add your dispatch handler code here

return NULL;
}

void CWizardGenCtrl::SetControlPicture(IPictureDisp* /*pVal*/)


{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO: Add your property handler code here

SetModifiedFlag();
}

NOTE
Your control class and function names might differ from the example above.

Modifications to Your Control Project


After you have made the necessary additions to your control project, you need to modify several functions that
affect the rendering of your ActiveX control. These functions, OnResetState , OnDraw , and the Get/Set functions of a
custom Picture property, are located in the control implementation file. (Note that in this example the control class
is called CSampleCtrl , the CPictureHolder data member is called m_pic, and the custom picture property name is
ControlPicture .)

In the control OnResetState function, add the following optional line after the call to COleControl::OnResetState :

m_pic.CreateEmpty();
m_pic.CreateEmpty();

This sets the control's picture to a blank picture.


To draw the picture properly, make a call to CPictureHolder::Render in the control OnDraw function. Modify your
function to resemble the following example:
void CMyAxPicCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;

m_pic.Render(pdc, rcBounds, rcBounds);


}

In the Get function of the control's custom picture property, add the following line:

return m_pic.GetPictureDispatch();
return m_pic.GetPictureDispatch();

In the Set function of the control's custom Picture property, add the following lines:

m_pic.SetPictureDispatch(pVal);
InvalidateControl();

The picture property must be made persistent so that information added at design time will show up at run time.
Add the following line to the COleControl -derived class's DoPropExchange function:

PX_Picture(pPX, _T("ControlPicture"), m_pic);

NOTE
Your class and function names might differ from the example above.

After you complete the modifications, rebuild your project to incorporate the new functionality of the custom
Picture property and use Test Container to test the new property. See Testing Properties and Events with Test
Container for information on how to access the test container.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Using Fonts
MFC ActiveX Controls: Property Pages
MFC ActiveX Controls: Advanced Topics
3/31/2020 • 7 minutes to read • Edit Online

This article covers advanced topics related to developing ActiveX controls. These include:
Using Database Classes in ActiveX Controls
Implementing a Parameterized Property
Handling Errors in Your ActiveX Control
Handling Special Keys in the Control
Accessing Dialog Controls That Are Invisible at Run Time

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.

Using Database Classes in ActiveX Controls


Because the ActiveX control classes are part of the class library, you can apply the same procedures and rules for
using database classes in a standard MFC application to developing ActiveX controls that use the MFC database
classes.
For a general overview of the MFC database classes, see MFC Database Classes (DAO and ODBC). The article
introduces both the MFC ODBC classes and the MFC DAO classes and directs you to more details on either.

NOTE
DAO is supported through Office 2013. DAO 3.6 is the final version, and it is considered obsolete. 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 OLE DB Templates or ODBC and MFC for new projects. You should only use DAO in
maintaining existing applications.

Implementing a Parameterized Property


A parameterized property (sometimes called a property array) is a method for exposing a homogeneous
collection of values as a single property of the control. For example, you can use a parameterized property to
expose an array or a dictionary as a property. In Visual Basic, such a property is accessed using array notation:

x = o.Array(2, 3) ' gets element of 2D array


o.Array(2, 3) = 7 ' sets element of 2D array

Use the Add Property Wizard to implement a parameterized property. The Add Property Wizard implements the
property by adding a pair of Get/Set functions that allow the control user to access the property using the above
notation or in the standard fashion.
Similar to methods and properties, parameterized properties also have a limit to the number of parameters
allowed. In the case of parameterized properties, the limit is 15 parameters (with one parameter reserved for
storing the property value).
The following procedure adds a parameterized property, called Array, which can be accessed as a two-
dimensional array of integers.
To add a parameterized property using the Add Property Wizard
1. Load your control's project.
2. In Class View, expand the library node of your control.
3. Right-click the interface node for your control (the second node of the library node) to open the shortcut
menu.
4. From the shortcut menu, click Add and then click Add Proper ty .
5. In the Proper ty Name box, type Array .
6. In the Proper ty Type box, select shor t .
7. For Implementation Type, click Get/Set Methods .
8. In the Get Function and Set Function boxes, type unique names for your Get and Set Functions or
accept the default names.
9. Add a parameter, called row (type short), using the Parameter Name and Parameter Type controls.
10. Add a second parameter called column (type short).
11. Click Finish .
Changes Made by the Add Property Wizard
When you add a custom property, the Add Property Wizard makes changes to the control class header (.H) and
the implementation (.CPP) files.
The following lines are added to the control class .H file:

SHORT GetArray(SHORT row, SHORT column);


void SetArray(SHORT row, SHORT column, SHORT newVal);

This code declares two functions called GetArray and SetArray that allow the user to request a specific row and
column when accessing the property.
In addition, the Add Property Wizard adds the following lines to the control dispatch map, located in the control
class implementation (.CPP) file:

DISP_PROPERTY_PARAM_ID(CMyAxUICtrl, "Array", dispidArray, GetArray, SetArray, VT_I2, VTS_I2 VTS_I2)

Finally, the implementations of the GetArray and SetArray functions are added to the end of the .CPP file. In
most cases, you will modify the Get function to return the value of the property. The Set function will usually
contain code that should execute, either before or after the property changes.
For this property to be useful, you could declare a two-dimensional array member variable in the control class, of
type shor t , to store values for the parameterized property. You could then modify the Get function to return the
value stored at the proper row and column, as indicated by the parameters, and modify the Set function to update
the value referenced by the row and column parameters.

Handling Errors in Your ActiveX Control


If error conditions occur in the control, you may need to report the error to the control container. There are two
methods for reporting errors, depending on the situation in which the error occurs. If the error occurs within a
property's Get or Set function, or within the implementation of an OLE Automation method, the control should
call COleControl::ThrowError, which signals to the control user that an error has occurred. If the error occurs at
any other time, the control should call COleControl::FireError, which fires a stock Error event.
To indicate the kind of error that has occurred, the control must pass an error code to ThrowError or FireError .
An error code is an OLE status code, which has a 32-bit value. When possible, choose an error code from the
standard set of codes defined in the OLECTL.H header file. The following table summarizes these codes.
ActiveX Control Error Codes
ERRO R DESC RIP T IO N

CTL_E_ILLEGALFUNCTIONCALL Illegal function call

CTL_E_OVERFLOW Overflow

CTL_E_OUTOFMEMORY Out of memory

CTL_E_DIVISIONBYZERO Division by zero

CTL_E_OUTOFSTRINGSPACE Out of string space

CTL_E_OUTOFSTACKSPACE Out of stack space

CTL_E_BADFILENAMEORNUMBER Bad file name or number

CTL_E_FILENOTFOUND File not found

CTL_E_BADFILEMODE Bad file mode

CTL_E_FILEALREADYOPEN File already open

CTL_E_DEVICEIOERROR Device I/O error

CTL_E_FILEALREADYEXISTS File already exists

CTL_E_BADRECORDLENGTH Bad record length

CTL_E_DISKFULL Disk full

CTL_E_BADRECORDNUMBER Bad record number

CTL_E_BADFILENAME Bad file name

CTL_E_TOOMANYFILES Too many files

CTL_E_DEVICEUNAVAILABLE Device unavailable

CTL_E_PERMISSIONDENIED Permission denied

CTL_E_DISKNOTREADY Disk not ready


ERRO R DESC RIP T IO N

CTL_E_PATHFILEACCESSERROR Path/file access error

CTL_E_PATHNOTFOUND Path not found

CTL_E_INVALIDPATTERNSTRING Invalid pattern string

CTL_E_INVALIDUSEOFNULL Invalid use of NULL

CTL_E_INVALIDFILEFORMAT Invalid file format

CTL_E_INVALIDPROPERTYVALUE Invalid property value

CTL_E_INVALIDPROPERTYARRAYINDEX Invalid property array index

CTL_E_SETNOTSUPPORTEDATRUNTIME Set not supported at run time

CTL_E_SETNOTSUPPORTED Set not supported (read-only property)

CTL_E_NEEDPROPERTYARRAYINDEX Need property array index

CTL_E_SETNOTPERMITTED Set not permitted

CTL_E_GETNOTSUPPORTEDATRUNTIME Get not supported at run time

CTL_E_GETNOTSUPPORTED Get not supported (write-only property)

CTL_E_PROPERTYNOTFOUND Property not found

CTL_E_INVALIDCLIPBOARDFORMAT Invalid clipboard format

CTL_E_INVALIDPICTURE Invalid picture

CTL_E_PRINTERERROR Printer error

CTL_E_CANTSAVEFILETOTEMP Can't save file to TEMP

CTL_E_SEARCHTEXTNOTFOUND Search text not found

CTL_E_REPLACEMENTSTOOLONG Replacements too long

If necessary, use the CUSTOM_CTL_SCODE macro to define a custom error code for a condition that is not
covered by one of the standard codes. The parameter for this macro should be an integer between 1000 and
32767, inclusive. For example:

#define MYCTL_E_SPECIALERROR CUSTOM_CTL_SCODE(1000)

If you are creating an ActiveX control to replace an existing VBX control, define your ActiveX control error codes
with the same numeric values the VBX control uses to ensure that the error codes are compatible.

Handling Special Keys in the Control


In some cases you may want to handle certain keystroke combinations in a special way; for example, insert a new
line when the ENTER key is pressed in a multiline text box control or move between a group of edit controls when
a directional key ID pressed.
If the base class of your ActiveX control is COleControl , you can override CWnd::PreTranslateMessage to handle
messages before the container processes them. When using this technique, always return TRUE if you handle the
message in your override of PreTranslateMessage .
The following code example demonstrates a possible way of handling any messages related to the directional
keys.

BOOL CMyAxUICtrl::PreTranslateMessage(MSG* pMsg)


{
BOOL bHandleNow = FALSE;

switch (pMsg->message)
{
case WM_KEYDOWN:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
bHandleNow = TRUE;
break;
}
if (bHandleNow)
{
OnKeyDown((UINT)pMsg->wParam, LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
}
break;
}
return bHandleNow;
}

For more information on handling keyboard interfaces for an ActiveX control, see the ActiveX SDK
documentation.

Accessing Dialog Controls that Are Invisible at Run Time


You can create dialog controls that have no user interface and are invisible at run time. If you add an invisible at
run time ActiveX control to a dialog box and use CWnd::GetDlgItem to access the control, the control will not work
correctly. Instead, you should use one of the following techniques to obtain an object that represents the control:
Using the Add Member Variable Wizard, select Control Variable and then select the control's ID. Enter a
member variable name and select the control's wrapper class as the Control Type .
-or-
Declare a local variable and subclass as the dialog item. Insert code that resembles the following ( CMyCtrl
is the wrapper class, IDC_MYCTRL1 is the control's ID):

CCirc myCirc;
myCirc.SubclassDlgItem(IDC_CIRCCTRL2, this);
// ... use myCirc ...
myCirc.UnsubclassWindow();

See also
MFC ActiveX Controls
MFC ActiveX Controls: Distributing ActiveX Controls
3/27/2020 • 2 minutes to read • Edit Online

This article discusses several issues related to redistributing ActiveX controls:


ANSI or Unicode Control Versions
Installing ActiveX Controls and Redistributable DLLs
Registering Controls

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.

ANSI or Unicode Control Versions


You must decide whether to ship an ANSI or Unicode version of the control, or both. This decision is based on
portability factors inherent in ANSI and Unicode character sets.
ANSI controls, which work on all Win32 operating systems, allow for maximum portability between the various
Win32 operating systems. Unicode controls work on only Windows NT (version 3.51 or later), but not on Windows
95 or Windows 98. If portability is your primary concern, ship ANSI controls. If your controls will run only on
Windows NT, you can ship Unicode controls. You could also choose to ship both and have your application install
the version most appropriate for the user's operating system.

Installing ActiveX Controls and Redistributable DLLs


The setup program you provide with your ActiveX controls should create a special subdirectory of the Windows
directory and install the controls' .OCX files in it.

NOTE
Use the Windows GetWindowsDirectory API in your setup program to obtain the name of the Windows directory. You may
want to derive the subdirectory name from the name of your company or product.

The setup program must install the necessary redistributable DLL files in the Windows system directory. If any of
the DLLs are already present on the user's machine, the setup program should compare their versions with the
versions you are installing. Reinstall a file only if its version number is higher than the file already installed.
Because ActiveX controls can be used only in OLE container applications, there is no need to distribute the full set of
OLE DLLs with your controls. You can assume that the containing application (or the operating system itself) has
the standard OLE DLLs installed.

Registering Controls
Before a control can be used, appropriate entries must be created for it in the Windows registration database. Some
ActiveX control containers provide a menu item for users to register new controls, but this feature may not be
available in all containers. Therefore, you may want your setup program to register the controls when they are
installed.
If you prefer, you can write your setup program to register the control directly instead.
Use the LoadLibrary Windows API to load the control DLL. Next, use GetProcAddress to obtain the address of the
"DllRegisterServer" function. Finally, call the DllRegisterServer function. The following code sample demonstrates
one possible method, where hLib stores the handle of the control library, and lpDllEntryPoint stores the address
of the "DllRegisterServer" function.

HINSTANCE hLib = LoadLibrary(pszDllName);

if (hLib < (HINSTANCE)HINSTANCE_ERROR)


{
AfxMessageBox(IDS_LOADLIBFAILED); //unable to load DLL
iReturn = FAIL_LOAD; //unable to load DLL
}

// Find the entry point.


lpDllEntryPoint = GetProcAddress(hLib, "DllRegisterServer");
if (lpDllEntryPoint != NULL)
(*lpDllEntryPoint)();
else
;// Unable to locate entry point

The advantage of registering the control directly is that you do not need to invoke and load a separate process
(namely, REGSVR32), reducing installation time. In addition, because registration is an internal process, the setup
program can handle errors and unforeseen situations better than an external process can.

NOTE
Before your setup program installs an ActiveX control, it should call OleInitialize . When your setup program is finished,
call OleUnitialize . This ensures that the OLE system DLLs are in the proper state for registering an ActiveX control.

You should register MFCx0.DLL.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Licensing an ActiveX Control
3/27/2020 • 6 minutes to read • Edit Online

Licensing support, an optional feature of ActiveX controls, allows you to control who is able to use or distribute the
control. (For additional discussion of licensing issues, see Licensing Issues in Upgrading an Existing ActiveX
Control.)

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.

This article discusses the following topics:


Overview of ActiveX Control Licensing
Creating a Licensed Control
Licensing Support
Customizing the Licensing of an ActiveX Control
ActiveX controls that implement licensing allow you, as the control developer, to determine how other people will
use the ActiveX control. You provide the control purchaser with the control and .LIC file, with the agreement that
the purchaser may distribute the control, but not the .LIC file, with an application that uses the control. This
prevents users of that application from writing new applications that use the control, without first licensing the
control from you.

Overview of ActiveX Control Licensing


To provide licensing support for ActiveX controls, the COleObjectFactory class provides an implementation for
several functions in the IClassFactory2 interface: IClassFactory2::RequestLicKey , IClassFactory2::GetLicInfo ,
and IClassFactory2::CreateInstanceLic . When the container application developer makes a request to create an
instance of the control, a call to GetLicInfo is made to verify that the control .LIC file is present. If the control is
licensed, an instance of the control can be created and placed in the container. After the developer has finished
constructing the container application, another function call, this time to RequestLicKey , is made. This function
returns a license key (a simple character string) to the container application. The returned key is then embedded in
the application.
The figure below demonstrates the license verification of an ActiveX control that will be used during the
development of a container application. As mentioned previously, the container application developer must have
the proper .LIC file installed on the development machine to create an instance of the control.

Verification of a Licensed ActiveX Control During Development


The next process, shown in the following figure, occurs when the end user runs the container application.
When the application is started, an instance of the control usually needs to be created. The container accomplishes
this by making a call to CreateInstanceLic , passing the embedded license key as a parameter. A string comparison
is then made between the embedded license key and the control's own copy of the license key. If the match is
successful, an instance of the control is created and the application continues to execute normally. Note that the
.LIC file need not be present on the control user's machine.

Verification of a Licensed ActiveX Control During Execution


Control licensing consists of two basic components: specific code in the control implementation DLL and the
license file. The code is composed of two (or possibly three) function calls and a character string, hereafter referred
to as a "license string", containing a copyright notice. These calls and the license string are found in the control
implementation (.CPP) file. The license file, generated by the ActiveX Control Wizard, is a text file with a copyright
statement. It is named using the project name with an .LIC extension, for example SAMPLE.LIC. A licensed control
must be accompanied by the license file if design-time use is needed.

Creating a Licensed Control


When you use the ActiveX Control Wizard to create the control framework, it is easy to include licensing support.
When you specify that the control should have a run-time license, the ActiveX Control Wizard adds code to the
control class to support licensing. The code consists of functions that use a key and license file for license
verification. These functions also can be modified to customize the control licensing. For more information on
license customization, see Customizing the Licensing of an ActiveX Control later in this article.
To add support for licensing with the ActiveX Control Wizard when you create your control project
1. Use the instructions in Creating an MFC ActiveX Control. The Application Settings page of the ActiveX
Control Wizard contains the option to create the control with the run-time license.
The ActiveX Control Wizard now generates an ActiveX control framework that includes basic licensing support. For
a detailed explanation of the licensing code, see the next topic.

Licensing Support
When you use the ActiveX Control Wizard to add licensing support to an ActiveX control, the ActiveX Control
Wizard adds code that declares and implements the licensing capability is added to the control header and
implementation files. This code is composed of a VerifyUserLicense member function and a GetLicenseKey
member function, which override the default implementations found in COleObjectFactory . These functions
retrieve and verify the control license.

NOTE
A third member function, VerifyLicenseKey is not generated by the ActiveX Control Wizard, but can be overridden to
customize the license key verification behavior.

These member functions are:


VerifyUserLicense
Verifies that the control allows design-time usage by checking the system for the presence of the control
license file. This function is called by the framework as part of processing IClassFactory2::GetLicInfo and
IClassFactory::CreateInstanceLic .

GetLicenseKey
Requests a unique key from the control DLL. This key is embedded in the container application and used
later, in conjunction with VerifyLicenseKey , to create an instance of the control. This function is called by the
framework as part of processing IClassFactory2::RequestLicKey .
VerifyLicenseKey
Verifies that the embedded key and the control's unique key are the same. This allows the container to
create an instance of the control for its use. This function is called by the framework as part of processing
IClassFactory2::CreateInstanceLic and can be overridden to provide customized verification of the license
key. The default implementation performs a string comparison. For more information, see Customizing the
Licensing of an ActiveX Control, later in this article.
Header File Modifications
The ActiveX Control Wizard places the following code in the control header file. In this example, two member
functions of CSampleCtrl 's object factory are declared, one that verifies the presence of the control .LIC file and
another that retrieves the license key to be used in the application containing the control:

BEGIN_OLEFACTORY(CMyAxUICtrl) // Class factory and guid


virtual BOOL VerifyUserLicense();
virtual BOOL GetLicenseKey(DWORD, BSTR FAR*);
END_OLEFACTORY(CMyAxUICtrl)

Implementation File Modifications


The ActiveX Control Wizard places the following two statements in the control implementation file to declare the
license filename and license string:

static const TCHAR BASED_CODE _szLicFileName[] = _T("NVC_MFC_AxUI.lic");

static const WCHAR BASED_CODE _szLicString[] = L"Copyright (c) 2006 ";

NOTE
If you modify szLicString in any way, you must also modify the first line in the control .LIC file or licensing will not
function properly.

The ActiveX Control Wizard places the following code in the control implementation file to define the control class'
VerifyUserLicense and GetLicenseKey functions:

// CMyAxUICtrl::CMyAxUICtrlFactory::VerifyUserLicense -
// Checks for existence of a user license

BOOL CMyAxUICtrl::CMyAxUICtrlFactory::VerifyUserLicense()
{
return AfxVerifyLicFile(AfxGetInstanceHandle(), _szLicFileName, _szLicString);
}

// CMyAxUICtrl::CMyAxUICtrlFactory::GetLicenseKey -
// Returns a runtime licensing key

BOOL CMyAxUICtrl::CMyAxUICtrlFactory::GetLicenseKey(DWORD /*dwReserved*/,


BSTR FAR* pbstrKey)
{
if (pbstrKey == NULL)
return FALSE;

*pbstrKey = SysAllocString(_szLicString);
return (*pbstrKey != NULL);
}

Finally, the ActiveX Control Wizard modifies the control project .IDL file. The licensed keyword is added to the
coclass declaration of the control, as in the following example:

[uuid(913E450B-E720-4C71-BCDF-71C96EE98FEB), licensed,
helpstring("MyAxUI Control"), control]
coclass NVC_MFC_AxUI

Customizing the Licensing of an ActiveX Control


Because VerifyUserLicense , GetLicenseKey , and VerifyLicenseKey are declared as virtual member functions of
the control factory class, you can customize the control's licensing behavior.
For example, you can provide several levels of licensing for the control by overriding the VerifyUserLicense or
VerifyLicenseKey member functions. Inside this function you could adjust which properties or methods are
exposed to the user according to the license level you detected.
You can also add code to the VerifyLicenseKey function that provides a customized method for informing the user
that control creation has failed. For instance, in your VerifyLicenseKey member function you could display a
message box stating that the control failed to initialize and why.

NOTE
Another way to customize ActiveX control license verification is to check the registration database for a specific registry key,
instead of calling AfxVerifyLicFile . For an example of the default implementation, see the Implementation File
Modifications section of this article.

For additional discussion of licensing issues, see Licensing Issues in Upgrading an Existing ActiveX Control.

See also
MFC ActiveX Controls
MFC ActiveX Control Wizard
MFC ActiveX Controls: Localizing an ActiveX Control
3/27/2020 • 5 minutes to read • Edit Online

This article discusses procedures for localizing ActiveX control interfaces.

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.

If you want to adapt an ActiveX control to an international market, you may want to localize the control. Windows
supports many languages in addition to the default English, including German, French, and Swedish. This can
present problems for the control if its interface is in English only.
In general, ActiveX controls should always base their locale on the ambient LocaleID property. There are three ways
to do this:
Load resources, always on demand, based on the current value of the ambient LocaleID property. The MFC
ActiveX controls sample LOCALIZE uses this strategy.
Load resources when the first control is instanced, based on the ambient LocaleID property, and use these
resources for all other instances. This article demonstrates this strategy.

NOTE
This will not work correctly in some cases, if future instances have different locales.

Use the OnAmbientChanged notification function to dynamically load the proper resources for the container's
locale.

NOTE
This will work for the control, but the run-time DLL will not dynamically update its own resources when the ambient
LocaleID property changes. In addition, run-time DLLs for ActiveX controls use the thread locale to determine the
locale for its resources.

The rest of this article describes two localizing strategies. The first strategy localizes the control's programmability
interface (names of properties, methods, and events). The second strategy localizes the control's user interface,
using the container's ambient LocaleID property. For a demonstration of control localization, see the MFC ActiveX
controls sample LOCALIZE.

Localizing the Control's Programmability Interface


When localizing the control's programmability interface (the interface used by programmers writing applications
that use your control), you must create a modified version of the control .IDL file (a script for building the control
type library) for each language you intend to support. This is the only place you need to localize the control
property names.
When you develop a localized control, include the locale ID as an attribute at the type library level. For example, if
you want to provide a type library with French localized property names, make a copy of your SAMPLE.IDL file, and
call it SAMPLEFR.IDL. Add a locale ID attribute to the file (the locale ID for French is 0x040c), similar to the following:

[uuid(F8068FFB-9F76-4471-BD76-F3F7ADCD05BB), version(1.0), lcid(0x040c),


control]
library NVC_MFC_AxLocLib

Change the property names in SAMPLEFR.IDL to their French equivalents, and then use MKTYPLIB.EXE to produce
the French type library, SAMPLEFR.TLB.
To create multiple localized type libraries you can add any localized .IDL files to the project and they will be built
automatically.
To add an .IDL file to your ActiveX control project
1. With your control project open, on the Project menu, click Add Existing Item .
The Add Existing Item dialog box appears.
2. If necessary, select the drive and directory to view.
3. In the Files of Type box, select All Files (*.*) .
4. In the file list box, double-click the .IDL file you want to insert into the project.
5. Click Open when you have added all necessary .IDL files.
Because the files have been added to the project, they will be built when the rest of the project is built. The localized
type libraries are located in the current ActiveX control project directory.
Within your code, the internal property names (usually in English) are always used and are never localized. This
includes the control dispatch map, the property exchange functions, and your property page data exchange code.
Only one type library (.TLB) file may be bound into the resources of the control implementation (.OCX) file. This is
usually the version with the standardized (typically, English) names. To ship a localized version of your control you
need to ship the .OCX (which has already been bound to the default .TLB version) and the .TLB for the appropriate
locale. This means that only the .OCX is needed for English versions, since the correct .TLB has already been bound
to it. For other locales, the localized type library also must be shipped with the .OCX.
To ensure that clients of your control can find the localized type library, register your locale-specific .TLB file(s)
under the TypeLib section of the Windows system registry. The third parameter (normally optional) of the
AfxOleRegisterTypeLib function is provided for this purpose. The following example registers a French type library
for an ActiveX control:

STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);

if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);

AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid, _T("samplefr.tlb"));

if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);

return NOERROR;
}

When your control is registered, the AfxOleRegisterTypeLib function automatically looks for the specified .TLB file
in the same directory as the control and registers it in the Windows registration database. If the .TLB file is not
found, the function has no effect.
Localizing the Control's User Interface
To localize a control's user interface, place all of the control's user-visible resources (such as property pages and
error messages) into language-specific resource DLLs. You then can use the container's ambient LocaleID property
to select the appropriate DLL for the user's locale.
The following code example demonstrates one approach to locate and load the resource DLL for a specific locale.
This member function, called GetLocalizedResourceHandle for this example, can be a member function of your
ActiveX control class:

HINSTANCE CMyAxLocCtrl::GetLocalizedResourceHandle(LCID lcid)


{
LPCTSTR lpszResDll;
HINSTANCE hResHandle = NULL;
switch (PRIMARYLANGID(lcid))
{
case LANG_ENGLISH:
lpszResDll = _T("myctlen.dll");
break;

case LANG_FRENCH:
lpszResDll = _T("myctlfr.dll");
break;

case LANG_GERMAN:
lpszResDll = _T("myctlde.dll");
break;

case 0:
default:
lpszResDll = NULL;
}

if (lpszResDll != NULL)
hResHandle = LoadLibrary(lpszResDll);
#ifndef _WIN32
if (hResHandle <= HINSTANCE_ERROR)
hResHandle = NULL;
#endif

return hResHandle;
}

Note that the sublanguage ID could be checked in each case of the switch statement, to provide more specialized
localization. For a demonstration of this function, see the GetResourceHandle function in the MFC ActiveX controls
sample LOCALIZE.
When the control first loads itself into a container, it can call COleControl::AmbientLocaleID to retrieve the locale ID.
The control can then pass the returned locale ID value to the GetLocalizedResourceHandle function, which loads the
proper resource library. The control should pass the resulting handle, if any, to AfxSetResourceHandle:

m_hResDll = GetLocalizedResourceHandle(AmbientLocaleID());
if (m_hResDll != NULL)
AfxSetResourceHandle(m_hResDll);

Place the code sample above into a member function of the control, such as an override of
COleControl::OnSetClientSite. In addition, m_hResDLL should be a member variable of the control class.
You can use similar logic for localizing a control's property page. To localize the property page, add code similar to
the following sample to your property page's implementation file (in an override of
COlePropertyPage::OnSetPageSite):

void CMyAxLocPropPage::OnSetPageSite()
{
LPPROPERTYPAGESITE pSite;
LCID lcid = 0;
if ((pSite = GetPageSite()) != NULL)
pSite->GetLocaleID(&lcid);
HINSTANCE hResource = GetLocalizedResourceHandle(lcid);
HINSTANCE hResourceSave = NULL;

if (hResource != NULL)
{
hResourceSave = AfxGetResourceHandle();
AfxSetResourceHandle(hResource);
}

// Load dialog template and caption string.


COlePropertyPage::OnSetPageSite();

if (hResource != NULL)
AfxSetResourceHandle(hResourceSave);
}

See also
MFC ActiveX Controls
MFC ActiveX Controls: Serializing
3/27/2020 • 4 minutes to read • Edit Online

This article discusses how to serialize an ActiveX control. Serialization is the process of reading from or writing to a
persistent storage medium, such as a disk file. The Microsoft Foundation Class (MFC) Library provides built-in
support for serialization in class CObject . COleControl extends this support to ActiveX controls through the use of
a property exchange mechanism.

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.

Serialization for ActiveX controls is implemented by overriding COleControl::DoPropExchange. This function, called
during the loading and saving of the control object, stores all properties implemented with a member variable or a
member variable with change notification.
The following topics cover the main issues related to serializing an ActiveX control:
Implementing DoPropExchange function to serialize your control object
Customizing the Serialization Process
Implementing Version Support

Implementing the DoPropExchange Function


When you use the ActiveX Control Wizard to generate the control project, several default handler functions are
automatically added to the control class, including the default implementation of COleControl::DoPropExchange.
The following example shows the code added to classes created with the ActiveX Control Wizard:

void CMyAxUICtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

// TODO: Call PX_ functions for each persistent custom property.


}

If you want to make a property persistent, modify DoPropExchange by adding a call to the property exchange
function. The following example demonstrates the serialization of a custom Boolean CircleShape property, where
the CircleShape property has a default value of TRUE :

void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

PX_Bool(pPX, _T("CircleShape"), m_bCircleShape, TRUE);


}
The following table lists the possible property exchange functions you can use to serialize the control's properties:

P RO P ERT Y EXC H A N GE F UN C T IO N S P URP O SE

PX_Blob( ) Serializes a type Binary Large Object (BLOB) data property.

PX_Bool( ) Serializes a type Boolean property.

PX_Color( ) Serializes a type color property.

PX_Currency( ) Serializes a type CY (currency) property.

PX_Double( ) Serializes a type double property.

PX_Font( ) Serializes a Font type property.

PX_Float( ) Serializes a type float property.

PX_IUnknown( ) Serializes a property of type LPUNKNOWN .

PX_Long( ) Serializes a type long property.

PX_Picture( ) Serializes a type Picture property.

PX_Shor t( ) Serializes a type shor t property.

PXstring( ) Serializes a type CString property.

PX_ULong( ) Serializes a type ULONG property.

PX_UShor t( ) Serializes a type USHORT property.

For more information on these property exchange functions, see Persistence of OLE Controls in the MFC Reference.

Customizing the Default Behavior of DoPropExchange


The default implementation of DoPropertyExchange (as shown in the previous topic) makes a call to base class
COleControl . This serializes the set of properties automatically supported by COleControl , which uses more
storage space than serializing only the custom properties of the control. Removing this call allows your object to
serialize only those properties you consider important. Any stock property states the control has implemented will
not be serialized when saving or loading the control object unless you explicitly add PX_ calls for them.

Implementing Version Support


Version support enables a revised ActiveX control to add new persistent properties, and still be able to detect and
load the persistent state created by an earlier version of the control. To make a control's version available as part of
its persistent data, call COleControl::ExchangeVersion in the control's DoPropExchange function. This call is
automatically inserted if the ActiveX control was created using the ActiveX Control Wizard. It can be removed if
version support is not needed. However, the cost in control size is very small (4 bytes) for the added flexibility that
version support provides.
If the control was not created with the ActiveX Control Wizard, add a call to COleControl::ExchangeVersion by
inserting the following line at the beginning of your DoPropExchange function (before the call to
COleControl::DoPropExchange ):

void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

You can use any DWORD as the version number. Projects generated by the ActiveX Control Wizard use
_wVerMinor and _wVerMajor as the default. These are global constants defined in the implementation file of the
project's ActiveX control class. Within the remainder of your DoPropExchange function, you can call
CPropExchange::GetVersion at any time to retrieve the version you are saving or retrieving.
In the following example, version 1 of this sample control has only a "ReleaseDate" property. Version 2 adds an
"OriginalDate" property. If the control is instructed to load the persistent state from the old version, it initializes the
member variable for the new property to a default value.

void CMyAxSerCtrl::DoPropExchange(CPropExchange* pPX)


{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);

PX_Long(pPX, _T("ReleaseDate"), m_ReleaseDate);


if (pPX->GetVersion() >= MAKELONG(0, 2))
{
PX_Long(pPX, _T("OriginalDate"), m_OriginalDate);
}
else
{
if (pPX->IsLoading())
m_OriginalDate = 0;
}

By default, a control "converts" old data to the latest format. For example, if version 2 of a control loads data that
was saved by version 1, it will write the version 2 format when it is saved again. If you want the control to save
data in the format last read, pass FALSE as a third parameter when calling ExchangeVersion . This third parameter
is optional and is TRUE by default.

See also
MFC ActiveX Controls
MFC ActiveX Controls: Subclassing a Windows
Control
3/27/2020 • 5 minutes to read • Edit Online

This article describes the process for subclassing a common Windows control to create an ActiveX control.
Subclassing an existing Windows control is a quick way to develop an ActiveX control. The new control will have
the abilities of the subclassed Windows control, such as painting and responding to mouse clicks. The MFC ActiveX
controls sample BUTTON is an example of subclassing a Windows control.

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.

To subclass a Windows control, complete the following tasks:


Override the IsSubclassedControl and PreCreateWindow member functions of COleControl
Modify the OnDraw member function
Handle any ActiveX control messages (OCM) reflected to the control

NOTE
Much of this work is done for you by the ActiveX Control Wizard if you select control to be subclassed using the
Select Parent Window Class drop-down list on the Control Settings page.

Overriding IsSubclassedControl and PreCreateWindow


To override PreCreateWindow and IsSubclassedControl , add the following lines of code to the protected section
of the control class declaration:

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);


BOOL IsSubclassedControl();

In the control implementation file (.CPP), add the following lines of code to implement the two overridden
functions:
// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)


{
cs.lpszClass = _T("BUTTON");
return COleControl::PreCreateWindow(cs);
}

// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMyAxSubCtrl::IsSubclassedControl()
{
return TRUE;
}

Notice that, in this example, the Windows button control is specified in PreCreateWindow . However, any standard
Windows controls can be subclassed. For more information on standard Windows controls, see Controls.
When subclassing a Windows control, you may want to specify particular window style (WS_) or extended
window style (WS_EX_) flags to be used in creating the control's window. You can set values for these parameters
in the PreCreateWindow member function by modifying the cs.style and the cs.dwExStyle structure fields.
Modifications to these fields should be made using an OR operation, to preserve the default flags that are set by
class COleControl . For example, if the control is subclassing the BUTTON control and you want the control to
appear as a check box, insert the following line of code into the implementation of CSampleCtrl::PreCreateWindow ,
before the return statement:

cs.style |= BS_CHECKBOX;

This operation adds the BS_CHECKBOX style flag, while leaving the default style flag (WS_CHILD) of class
COleControl intact.

Modifying the OnDraw Member Function


If you want your subclassed control to keep the same appearance as the corresponding Windows control, the
OnDraw member function for the control should contain only a call to the DoSuperclassPaint member function, as
in the following example:

void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)


{
if (!pdc)
return;

DoSuperclassPaint(pdc, rcBounds);
}

The DoSuperclassPaint member function, implemented by COleControl , uses the window procedure of the
Windows control to draw the control in the specified device context, within the bounding rectangle. This makes the
control visible even when it is not active.

NOTE
The DoSuperclassPaint member function will work only with those control types that allow a device context to be passed
as the wParam of a WM_PAINT message. This includes some of the standard Windows controls, such as SCROLLBAR and
BUTTON, and all the common controls. For controls that do not support this behavior, you will have to provide your own
code to properly display an inactive control.
Handling Reflected Window Messages
Windows controls typically send certain window messages to their parent window. Some of these messages, such
as WM_COMMAND, provide notification of an action by the user. Others, such as WM_CTLCOLOR, are used to
obtain information from the parent window. An ActiveX control usually communicates with the parent window by
other means. Notifications are communicated by firing events (sending event notifications), and information about
the control container is obtained by accessing the container's ambient properties. Because these communication
techniques exist, ActiveX control containers are not expected to process any window messages sent by the control.
To prevent the container from receiving the window messages sent by a subclassed Windows control,
COleControl creates an extra window to serve as the control's parent. This extra window, called a "reflector," is
created only for an ActiveX control that subclasses a Windows control and has the same size and position as the
control window. The reflector window intercepts certain window messages and sends them back to the control.
The control, in its window procedure, can then process these reflected messages by taking actions appropriate for
an ActiveX control (for example, firing an event). See Reflected Window Message IDs for a list of intercepted
windows messages and their corresponding reflected messages.
An ActiveX control container may be designed to perform message reflection itself, eliminating the need for
COleControl to create the reflector window and reducing the run-time overhead for a subclassed Windows
control. COleControl detects whether the container supports this capability by checking for a MessageReflect
ambient property with a value of TRUE .
To handle a reflected window message, add an entry to the control message map and implement a handler
function. Because reflected messages are not part of the standard set of messages defined by Windows, Class
View does not support adding such message handlers. However, it is not difficult to add a handler manually.
To add a message handler for a reflected window message manually do the following:
In the control class .H file, declare a handler function. The function should have a return type of LRESULT
and two parameters, with types WPARAM and LPARAM , respectively. For example:

class CMyAxSubCtrl : public COleControl


{

protected:
LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam);
};

In the control class .CPP file, add an ON_MESSAGE entry to the message map. The parameters of this entry
should be the message identifier and the name of the handler function. For example:

BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl)
ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand)
END_MESSAGE_MAP()

Also in the .CPP file, implement the OnOcmCommand member function to process the reflected message. The
wParam and lParam parameters are the same as those of the original window message.
For an example of how reflected messages are processed, refer to the MFC ActiveX controls sample BUTTON. It
demonstrates an OnOcmCommand handler that detects the BN_CLICKED notification code and responds by firing
(sending) a Click event.

See also
MFC ActiveX Controls
Reflected Window Message IDs
4/21/2020 • 2 minutes to read • Edit Online

A quick way to create an ActiveX control, or other specialized control, is to subclass a window. For more
information, see MFC ActiveX Controls: Subclassing a Windows Control.
To prevent the control's container from receiving the window messages sent by a subclassed Windows control,
COleControl creates a "reflector" window to intercept certain window messages and send them back to the control.
The control, in its window procedure, can then process these reflected messages by taking actions appropriate for
an ActiveX control.
The following table shows the messages that are intercepted and the corresponding messages that the reflector
window sends.

M ESSA GE SEN T B Y T H E C O N T RO L M ESSA GE REF L EC T ED TO T H E C O N T RO L

WM_COMMAND OCM_COMMAND

WM_CTLCOLORBTN OCM_CTLCOLORBTN

WM_CTLCOLOREDIT OCM_CTLCOLOREDIT

WM_CTLCOLORDLG OCM_CTLCOLORDLG

WM_CTLCOLORLISTBOX OCM_CTLCOLORLISTBOX

WM_CTLCOLORSCROLLBAR OCM_CTLCOLORSCROLLBAR

WM_CTLCOLORSTATIC OCM_CTLCOLORSTATIC

WM_DRAWITEM OCM_DRAWITEM

WM_MEASUREITEM OCM_MEASUREITEM

WM_DELETEITEM OCM_DELETEITEM

WM_VKEYTOITEM OCM_VKEYTOITEM

WM_CHARTOITEM OCM_CHARTOITEM

WM_COMPAREITEM OCM_COMPAREITEM

WM_HSCROLL OCM_HSCROLL

WM_VSCROLL OCM_VSCROLL

WM_PARENTNOTIFY OCM_PARENTNOTIFY

WM_NOTIFY OCM_NOTIFY
NOTE
If the control runs on a Win32 system, there are several types of WM_CTLCOLOR* messages it may receive. For more
information, see WM_CTLCOLORBTN, WM_CTLCOLORDLG, WM_CTLCOLOREDIT, WM_CTLCOLORLISTBOX,
WM_CTLCOLORMSGBOX, WM_CTLCOLORSCROLLBAR, WM_CTLCOLORSTATIC.

See also
MFC ActiveX Controls: Subclassing a Windows Control
TN062: Message Reflection for Windows Controls
MFC ActiveX Controls: Using Data Binding in an
ActiveX Control
3/27/2020 • 4 minutes to read • Edit Online

One of the more powerful uses of ActiveX controls is data binding, which allows a property of the control to bind
with a specific field in a database. When a user modifies data in this bound property, the control notifies the
database and requests that the record field be updated. The database then notifies the control of the success or
failure of the request.

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.

This article covers the control side of your task. Implementing the data binding interactions with the database is the
responsibility of the control container. How you manage the database interactions in your container is beyond the
scope of this documentation. How you prepare the control for data binding is explained in the rest of this article.

Conceptual Diagram of a Data-Bound Control


The COleControl class provides two member functions that make data binding an easy process to implement. The
first function, BoundPropertyRequestEdit, is used to request permission to change the property value.
BoundPropertyChanged, the second function, is called after the property value has been successfully changed.
This article covers the following topics:
Creating a Bindable Stock Property
Creating a Bindable Get/Set Method

Creating a Bindable Stock Property


It is possible to create a data-bound stock property, although it is more likely that you will want a bindable get/set
method.

NOTE
Stock properties have the bindable and requestedit attributes by default.

To add a bindable stock property using the Add Property Wizard


1. Begin a project using the MFC ActiveX Control Wizard.
2. Right-click the interface node for your control.
This opens the shortcut menu.
3. From the shortcut menu, click Add and then click Add Proper ty .
4. Select one of the entries from the Proper ty Name drop-down list. For example, you can select Text .
Because Text is a stock property, the bindable and requestedit attributes are already checked.
5. Select the following check boxes from the IDL Attributes tab: displaybind and defaultbind to add the
attributes to the property definition in the project's .IDL file. These attributes make the control visible to the
user and make the stock property the default bindable property.
At this point, your control can display data from a data source, but the user will not be able to update data fields. If
you want your control to also be able to update data, change the OnOcmCommand OnOcmCommand function to look
as follows:

#ifdef _WIN32
WORD wNotifyCode = HIWORD(wParam);
#else
WORD wNotifyCode = HIWORD(lParam);
#endif

if (wNotifyCode == EN_CHANGE)
{
if (!BoundPropertyRequestEdit(DISPID_TEXT))
{
SetNotSupported();
}
else
{
GetText();
// Notify container of change
BoundPropertyChanged(DISPID_TEXT);
}
}

return 0;

You can now build the project, which will register the control. When you insert the control in a dialog box, the Data
Field and Data Source properties will have been added and you can now select a data source and field to display
in the control.

Creating a Bindable Get/Set Method


In addition to a data-bound get/set method, you can also create a bindable stock property.

NOTE
This procedure assumes you have an ActiveX control project that subclasses a Windows control.

To add a bindable get/set method using the Add Property Wizard


1. Load your control's project.
2. On the Control Settings page, select a window class for the control to subclass. For example, you may
want to subclass an EDIT control.
3. Load your control's project.
4. Right-click the interface node for your control.
This opens the shortcut menu.
5. From the shortcut menu, click Add and then click Add Proper ty .
6. Type the property name in the Proper ty Name box. Use MyProp for this example.
7. Select a data type from the Proper ty Type drop-down list box. Use shor t for this example.
8. For Implementation Type , click Get/Set Methods .
9. Select the following check boxes from the IDL Attributes tab: bindable , requestedit , displaybind , and
defaultbind to add the attributes to the property definition in the project's .IDL file. These attributes make
the control visible to the user and make the stock property the default bindable property.
10. Click Finish .
11. Modify the body of the SetMyProp function so that it contains the following code:

if (!BoundPropertyRequestEdit(1))
{
SetNotSupported();
return;
}
else
{
if (AmbientUserMode()) // SendMessage only at run-time
{
_stprintf_s(m_strText.GetBuffer(10), 10, _T("%d"), newVal);
SetWindowText(m_strText);
m_strText.ReleaseBuffer();
}
else
{
InvalidateControl();
}

// Signal a property change


// This is the MFC equivalent of OnChanged()
BoundPropertyChanged(1);
SetModifiedFlag();
}

12. The parameter passed to the BoundPropertyChanged and BoundPropertyRequestEdit functions is the dispid of
the property, which is the parameter passed to the id() attribute for the property in the .IDL file.
13. Modify the OnOcmCommand function so it contains the following code:
#ifdef _WIN32
WORD wNotifyCode = HIWORD(wParam);
#else
WORD wNotifyCode = HIWORD(lParam);
#endif

if (wNotifyCode == EN_CHANGE)
{
if (!BoundPropertyRequestEdit(DISPID_TEXT))
{
SetNotSupported();
}
else
{
GetText();
// Notify container of change
BoundPropertyChanged(DISPID_TEXT);
}
}

return 0;

14. Modify the OnDraw function so that it contains the following code:

if (!AmbientUserMode())
{
// Draw the Text property at design-time
pdc->FillRect(rcBounds,
CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
pdc->DrawText(m_strText, -1, (LPRECT)& rcBounds,
DT_LEFT | DT_TOP | DT_SINGLELINE);
}
else
{
DoSuperclassPaint(pdc, rcBounds);
}

15. To the public section of the header file the header file for your control class, add the following definitions
(constructors) for member variables:

CString m_strText;
short m_nMyNum;

16. Make the following line the last line in the DoPropExchange function:

PX_String(pPX, _T("MyProp"), m_strText);

17. Modify the OnResetState function so that it contains the following code:

m_strText = AmbientDisplayName();
m_strText = AmbientDisplayName();

18. Modify the GetMyProp function so that it contains the following code:
if (AmbientUserMode())
{
GetWindowText(m_strText);
m_nMyNum = (short)_ttoi(m_strText);
}
return m_nMyNum;

You can now build the project, which will register the control. When you insert the control in a dialog box, the Data
Field and Data Source properties will have been added and you can now select a data source and field to display
in the control.

See also
MFC ActiveX Controls
ActiveX Control Containers
3/4/2019 • 2 minutes to read • Edit Online

An ActiveX control container is a container that fully supports ActiveX controls and can incorporate them into its
own windows or dialogs. An ActiveX control is a reusable software element that you can use in many
development projects. Controls allow your application's user to access databases, monitor data, and make various
selections within your applications. For more information on ActiveX controls, see the article MFC ActiveX
Controls.

IMPORTANT
ActiveX is a legacy technology that should not be used for new development. For more information, see ActiveX Controls.

Control containers typically take two forms in a project:


Dialogs and dialog-like windows such as form views, where an ActiveX control is used somewhere in the
dialog box.
Windows in an application, where an ActiveX control is used in a toolbar, or other location in the user
window.
The ActiveX control container interacts with the control via exposed methods and properties. These methods and
properties, which can be accessed and modified by the control container, are accessed through a wrapper class in
the ActiveX control container project. The embedded ActiveX control can also interact with the container by firing
(sending) events to notify the container that an action has occurred. The control container can choose to act upon
these notifications or not.
Additional articles discuss several topics, from creating an ActiveX control container project to basic
implementation issues related to ActiveX control containers built with Visual C++:
Creating an MFC ActiveX Control Container
Containers for ActiveX Controls
ActiveX Control Containers: Manually Enabling ActiveX Control Containment
ActiveX Control Containers: Inserting a Control into a Control Container Application
ActiveX Control Containers: Connecting an ActiveX Control to a Member Variable
ActiveX Control Containers: Handling Events from an ActiveX control
ActiveX Control Containers: Viewing and Modifying Control Properties
ActiveX Control Containers: Programming ActiveX Controls in an ActiveX Control Container
ActiveX Control Containers: Using Controls in a Non-Dialog Container
For more information about using ActiveX controls in a dialog box, see the Dialog Editor topics.
For a list of articles that explain the details of developing ActiveX controls using Visual C++ and the MFC ActiveX
control classes, see MFC ActiveX controls. The articles are grouped by functional categories.

See also
MFC ActiveX Controls
Containers for ActiveX Controls
3/27/2020 • 2 minutes to read • Edit Online

You can use ActiveX controls developed in Visual C++ in other applications, as long as they support ActiveX control
containment. A number of Microsoft applications, beginning with the versions listed, support ActiveX control
containment.

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.

NOTE
The following list is not a complete list of applications that support ActiveX controls but represents the set used most often
in testing:

Applications that support ActiveX control containment include:


Internet Explorer 3.x and greater
Visual Basic 4.x and greater
Visual C++ 4.x and greater
Access 95 and greater
Excel 97 and greater
Word 97 and greater
Access 97 and greater
FrontPage 97 and greater
PowerPoint 97 and greater
Visual InterDev 97 and greater
The following are non-Microsoft applications that support ActiveX control containment:
PowerBuilder
Delphi
C++ Builder
NCompass Plug-in for Netscape Navigator

See also
ActiveX Control Containers
ActiveX Control Containers: Manually Enabling
ActiveX Control Containment
3/27/2020 • 2 minutes to read • Edit Online

If you did not enable ActiveX control support when you used the MFC Application Wizard to generate your
application, you will have to add this support manually. This article describes the process for manually adding
ActiveX control containment to an existing OLE container application. If you know in advance that you want ActiveX
control support in your OLE container, see the article Creating an MFC ActiveX Control Container.

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.

NOTE
This article uses a dialog-based ActiveX control container project named Container and an embedded control named Circ as
examples in the procedures and code.

To support ActiveX controls, you must add one line of code to two of your project's files.
Modify your main dialog's InitInstance function (found in CONTAINER.CPP) by the MFC Application
Wizard making a call to AfxEnableControlContainer, as in the following example:

// COleContainerApp initialization
BOOL COleContainerApp::InitInstance()
{
AfxEnableControlContainer();

Add the following to your project's STDAFX.H header file:

#include <afxdisp.h> // MFC Automation classes

After you have completed these steps, rebuild your project by clicking Build on the Build menu.

See also
ActiveX Control Containers
ActiveX Control Containers: Inserting a Control into a
Control Container Application
3/4/2019 • 2 minutes to read • Edit Online

Before you can access an ActiveX control from an ActiveX control container application, you must add the ActiveX
control to the container application using the Insert ActiveX Control dialog box.
To add an ActiveX control to the ActiveX control container project, see Viewing and Adding ActiveX Controls to a
Dialog Box.
Once you add the control, you need to add a member variable (of the ActiveX control type) to the dialog box class.
For more information on this procedure, see Adding a Member Variable.
Once you have added the member variable a class, referred to as a wrapper class, is automatically generated and
added to your project. This class is used as an interface between the control container and the embedded control.

See also
ActiveX Control Containers
ActiveX Control Containers: Connecting an ActiveX
Control to a Member Variable
3/27/2020 • 2 minutes to read • Edit Online

The easiest way to access an ActiveX control from within its control container application is to associate the ActiveX
control with a member variable of the dialog class that will contain the control.

NOTE
This is not the only way to access an embedded control from within a container class, but for the purposes of this article it is
sufficient.

Adding a member variable to the dialog class


1. From Class View, right-click the main dialog class to open the shortcut menu. For example, CContainerDlg .
2. From the shortcut menu, click Add and then Add Variable .
3. In the Add Member Variable Wizard, click Control variable .
4. In the Control ID list box, select the control ID of the embedded ActiveX control. For example,
IDC_CIRCCTRL1 .

5. In the Variable Name box, enter a name.


For example, m_circctl.
6. Click Finish to accept your choices and exit the Add Member Variable Wizard.

See also
ActiveX Control Containers
ActiveX Control Containers: Handling Events from an
ActiveX Control
3/27/2020 • 2 minutes to read • Edit Online

This article discusses using the Proper ties window (in Class View ) to install event handlers for ActiveX controls
in an ActiveX control container. The event handlers are used to receive notifications (from the control) of certain
events and perform some action in response. This notification is called "firing" the event.

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.

NOTE
This article uses a dialog-based ActiveX control container project named Container and an embedded control named Circ as
examples in the procedures and code.

Using the Events button in the Proper ties window (in Class View ), you can create a map of events that can occur
in your ActiveX control container application. This map, called an "event sink map,'' is created and maintained by
Visual C++ when you add event handlers to the control container class. Each event handler, implemented with an
event map entry, maps a specific event to a container event handler member function. This event handler function
is called when the specified event is fired by the ActiveX control object.
For more information on event sink maps, see Event Sink Maps in the Class Library Reference.

Event Handler Modifications to the Project


When you use the Proper ties window to add event handlers, an event sink map is declared and defined in your
project. The following statements are added to the control .CPP file the first time an event handler is added. This
code declares an event sink map for the dialog box class (in this case, CContainerDlg ):

BEGIN_EVENTSINK_MAP(CContainerDlg, CDialog)

END_EVENTSINK_MAP()

As you use the Proper ties window to add events, an event map entry ( ON_EVENT ) is added to the event sink map
and an event handler function is added to the container's implementation (.CPP) file.
The following example declares an event handler, called OnClickInCircCtrl , for the Circ control's ClickIn event:

BEGIN_EVENTSINK_MAP(CContainerDlg, CDialog)
ON_EVENT(CContainerDlg, IDC_CIRCCTRL1, 1 /* ClickIn */, OnClickInCircctrl1,
VTS_I4 VTS_I4)
END_EVENTSINK_MAP()

In addition, the following template is added to the CContainerDlg class implementation (.CPP) file for the event
handler member function:

BOOL CContainerDlg::OnClickInCircctrl1(OLE_XPOS_PIXELS nX, OLE_YPOS_PIXELS nY)


{
// use nX and nY here
TRACE(_T("nX = %d, nY = %d\n"), nX, nY);
return TRUE;
}

For more information on event sink macros, see Event Sink Maps in the Class Library Reference.
To create an event handler function
1. From Class View, select the dialog class that contains the ActiveX control. For this example, use
CContainerDlg .

2. In the Proper ties window, click the Events button.


3. In the Proper ties window, select the control ID of the embedded ActiveX control. For this example, use
IDC_CIRCCTRL1 .

The Proper ties window displays a list of events that can be fired by the embedded ActiveX control. Any
member function shown in bold already has handler functions assigned to it.
4. Select the event you want the dialog class to handle. For this example, select Click .
5. From the drop-down list box on the right, select <Add> ClickCircctrl1 .
6. Double-click the new handler function from Class View to jump to the event handler code in the
implementation (.CPP) file of CContainerDlg .

See also
ActiveX Control Containers
ActiveX Control Containers: Viewing and Modifying
Control Properties
9/11/2019 • 2 minutes to read • Edit Online

When you insert an ActiveX control into a project, it is useful to view and change the properties supported by the
ActiveX control. This article discusses how to use the Visual C++ resource editor to do this.
If your ActiveX control container application uses embedded controls, you can view and modify the control's
properties while in the resource editor. You can also use the resource editor to set property values during design
time. The resource editor then automatically saves these values in the project's resource file. Any instance of the
control will then have its properties initialized to these values.
This procedure assumes that you have inserted a control into your project. For information, see ActiveX Control
Containers: Inserting a Control Into a Control Container Application.
The first step in viewing the control's properties is to add an instance of the control to the project's dialog template.
To view the properties of a control
1. In Resource View, open the Dialog folder.
2. Open your main dialog box template.
3. Insert an ActiveX control using the Inser t ActiveX Control dialog box. For more information, see Viewing
and Adding ActiveX Controls to a Dialog Box.
4. Select the ActiveX control in the dialog box.
5. From the Proper ties window, click the Proper ties button.
Use the Proper ties dialog box to modify and test new properties immediately.

See also
ActiveX Control Containers
ActiveX Control Containers: Programming ActiveX
Controls in an ActiveX Control Container
3/27/2020 • 4 minutes to read • Edit Online

This article describes the process for accessing the exposed methods and properties of embedded ActiveX
controls.

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.

Basically, you will follow these steps:


1. Insert an ActiveX control into the ActiveX container project using Gallery.
2. Define a member variable (or other form of access) of the same type as the ActiveX control wrapper class.
3. Program the ActiveX control using predefined member functions of the wrapper class.
For this discussion, assume you've created a dialog-based project (named Container) with ActiveX control support.
The Circ sample control, Circ, will be added to the resulting project.
Once the Circ control is inserted into the project (step 1), insert an instance of the Circ control into the application's
main dialog box.

Procedures
To add the Circ control to the dialog template
1. Load the ActiveX control container project. For this example, use the Container project.
2. Click the Resource View tab.
3. Open the Dialog folder.
4. Double-click the main dialog box template. For this example, use IDD_CONTAINER_DIALOG .
5. Click the Circ control icon on the Toolbox.
6. Click a spot within the dialog box to insert the Circ control.
7. From the File menu, choose Save All to save all modifications to the dialog box template.

Modifications to the Project


To enable the Container application to access the Circ control, Visual C++ automatically adds the wrapper class (
CCirc ) implementation file (.CPP) to the Container project and the wrapper class header (.H) file to the dialog box
header file:

#include "circ.h"
The Wrapper Class Header (.H) File
To get and set properties (and invoke methods) for the Circ control, the CCirc wrapper class provides a
declaration of all exposed methods and properties. In the example, these declarations are found in CIRC.H. The
following sample is the portion of class CCirc that defines the exposed interfaces of the ActiveX control:

class CCirc : public CWnd


{

// Functions
//

void AboutBox()
{
InvokeHelper(DISPID_ABOUTBOX, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}

// Properties
//

unsigned long GetBackColor()


{
unsigned long result;
GetProperty(DISPID_BACKCOLOR, VT_UI4, (void*)& result);
return result;
}
void SetBackColor(unsigned long propVal)
{
SetProperty(DISPID_BACKCOLOR, VT_UI4, propVal);
}
signed char GetCircleShape()
{
signed char result;
GetProperty(0x1, VT_I1, (void*)& result);
return result;
}
void SetCircleShape(signed char propVal)
{
SetProperty(0x1, VT_I1, propVal);
}
short GetCircleOffset()
{
short result;
GetProperty(0x3, VT_I2, (void*)& result);
return result;
}
void SetCircleOffset(short propVal)
{
SetProperty(0x3, VT_I2, propVal);
}
CString GetCaption()
{
CString result;
GetProperty(DISPID_CAPTION, VT_BSTR, (void*)& result);
return result;
}
void SetCaption(CString propVal)
{
SetProperty(DISPID_CAPTION, VT_BSTR, propVal);
}
COleFont GetFont()
{
LPDISPATCH result;
GetProperty(DISPID_FONT, VT_DISPATCH, (void*)& result);
return COleFont(result);
return COleFont(result);
}
void SetFont(LPDISPATCH propVal)
{
SetProperty(DISPID_FONT, VT_DISPATCH, propVal);
}
unsigned long GetForeColor()
{
unsigned long result;
GetProperty(DISPID_FORECOLOR, VT_UI4, (void*)& result);
return result;
}
void SetForeColor(unsigned long propVal)
{
SetProperty(DISPID_FORECOLOR, VT_UI4, propVal);
}
CString GetNote()
{
CString result;
GetProperty(0x4, VT_BSTR, (void*)& result);
return result;
}
void SetNote(CString propVal)
{
SetProperty(0x4, VT_BSTR, propVal);
}
unsigned long GetFlashColor()
{
unsigned long result;
GetProperty(0x2, VT_UI4, (void*)& result);
return result;
}
void SetFlashColor(unsigned long propVal)
{
SetProperty(0x2, VT_UI4, propVal);
}
};

These functions can then be called from other of the application's procedures using normal C++ syntax. For more
information on using this member function set to access the control's methods and properties, see the section
Programming the ActiveX control.

Member Variable Modifications to the Project


Once the ActiveX control has been added to the project and embedded in a dialog box container, it can be accessed
by other parts of the project. The easiest way to access the control is to create a member variable of the dialog
class, CContainerDlg (step 2), that is of the same type as the wrapper class added to the project by Visual C++. You
can then use the member variable to access the embedded control at any time.
When the Add Member Variable dialog box adds the m_circctl member variable to the project, it also adds the
following lines to the header file (.H) of the CContainerDlg class:
class CContainerDlg : public CDialog
{
DECLARE_DYNAMIC(CContainerDlg)

public:
CContainerDlg(CWnd* pParent = NULL); // standard constructor
virtual ~CContainerDlg();

virtual void OnFinalRelease();

// Dialog Data
enum { IDD = IDD_CONTAINER_DIALOG };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

DECLARE_MESSAGE_MAP()
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
public:
CCirc m_circctl;

};

In addition, a call to DDX_Control is automatically added to the CContainerDlg 's implementation of


DoDataExchange :

DDX_Control(pDX, IDC_CIRCCTRL1, m_circctl);

Programming the ActiveX Control


At this point, you have inserted the ActiveX control into your dialog template and created a member variable for it.
You can now use common C++ syntax to access the properties and methods of the embedded control.
As noted (in The Wrapper Class Header (.H) File), the header file (.H) for the CCirc wrapper class, in this case
CIRC.H, contains a list of member functions that you can use to get and set any exposed property value. Member
functions for exposed methods are also available.
A common place to modify the control's properties is in the OnInitDialog member function of the main dialog
class. This function is called just before the dialog box appears and is used to initialize its contents, including any of
its controls.
The following code example uses the m_circctl member variable to modify the Caption and CircleShape properties
of the embedded Circ control:

BOOL CContainerDlg::OnInitDialog()
{
CDialog::OnInitDialog();

m_circctl.SetCaption(_T("Circ 2 Control"));
if (!m_circctl.GetCircleShape())
m_circctl.SetCircleShape(TRUE);

return TRUE; // return TRUE unless you set the focus to a control
}
See also
ActiveX Control Containers
ActiveX Control Containers: Using Controls in a Non-
Dialog Container
3/4/2019 • 2 minutes to read • Edit Online

In some applications, such as an SDI or MDI application, you will want to embed a control in a window of the
application. The Create member function of the wrapper class, inserted by Visual C++, can create an instance of
the control dynamically, without the need for a dialog box.
The Create member function has the following parameters:
lpszWindowName
A pointer to the text to be displayed in the control's Text or Caption property (if any).
dwStyle
Windows styles. For a complete list, see CWnd::CreateControl.
rect
Specifies the control's size and position.
pParentWnd
Specifies the control's parent window, usually a CDialog . It must not be NULL .
nID
Specifies the control ID and can be used by the container to refer to the control.
One example of using this function to dynamically create an ActiveX control would be in a form view of an SDI
application. You could then create an instance of the control in the WM_CREATE handler of the application.
For this example, CMyView is the main view class, CCirc is the wrapper class, and CIRC.H is the header (.H) file of
the wrapper class.
Implementing this feature is a four-step process.
To dynamically create an ActiveX control in a non-dialog window
1. Insert CIRC.H in CMYVIEW.H, just before the CMyView class definition:

#include "circ.h"

2. Add a member variable (of type CCirc ) to the protected section of the CMyView class definition located in
CMYVIEW.H:

class CMyView : public CView


{

protected:
CCirc m_myCtl;

public:
afx_msg void OnViewCircdlg();
}
;
3. Add a WM_CREATE message handler to class CMyView .
4. In the handler function, CMyView::OnCreate , make a call to the control's Create function using the this
pointer as the parent window:

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)


{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

m_myCtl.Create(NULL, WS_VISIBLE, CRect(50, 50, 100, 100), this, 0);


m_myCtl.SetCaption(_T("Control created"));

return 0;
}

5. Rebuild the project. A Circ control will be created dynamically whenever the application's view is created.

See also
ActiveX Control Containers
Testing Properties and Events with Test Container
4/1/2019 • 2 minutes to read • Edit Online

The Test Container application, shipped in Visual C++, is an ActiveX control container for testing and debugging
ActiveX controls. Test Container allows the control developer to test the control's functionality by changing its
properties, invoking its methods, and firing its events. Test Container can display logs of data-binding notifications
and also provides facilities for testing an ActiveX control's persistence functionality: you can save properties to a
stream or to substorage, reload them, and examine the stored stream data. This section describes how to use the
basic features of Test Container. For additional information, select the Help menu while running Test Container.
To access the ActiveX Control Test Container
1. Build the TSTCON Sample: ActiveX Control Test Container.
To test your ActiveX control
1. On the Edit menu of Test Container, click Inser t New Control .
2. In the Inser t Control box, select the desired control and click OK . The control will appear in the control
container.

NOTE
If your control is not listed in the Inser t Control dialog box, make sure you have registered it with the Register
Controls command from the File menu of Test Container.

At this point you can test your control's properties or events.


To test properties
1. On the Control menu, click Invoke Methods .
2. In the Method Name drop-down list, select the PropPut method for the property you want to test.
3. Modify the Parameter Value or Parameter Type and click on the Set Value button.
4. Click Invoke to apply the new value to the object.
The property now contains the new value.
To test events and specify the destination of event information.
1. On the Options menu, click Logging .
2. Specify the destination of event information.

See also
MFC ActiveX Controls
How to: Debug an ActiveX Control
Clipboard
2/10/2020 • 2 minutes to read • Edit Online

This family of articles explains how to implement support for the Windows Clipboard in MFC applications. The
Windows Clipboard is used in two ways:
Implementing standard Edit menu commands, such as Cut, Copy, and Paste.
Implementing uniform data transfer with OLE drag and drop.
The Clipboard is the standard Windows method of transferring data between a source and a destination. It can
also be very useful in OLE operations. With the advent of OLE, there are two Clipboard mechanisms in Windows.
The standard Windows Clipboard API is still available, but it has been supplemented with the OLE data transfer
mechanism. OLE uniform data transfer (UDT) supports Cut, Copy, and Paste with the Clipboard and drag and
drop.
The Clipboard is a system service shared by the entire Windows session, so it does not have a handle or class of
its own. You manage the Clipboard through member functions of class CWnd.

What do you want to know more about


When to use each Clipboard mechanism
Using the traditional Windows Clipboard API
Using the OLE Clipboard mechanism
Copying and pasting data
Adding other formats
The Windows Clipboard
OLE drag and drop

See also
User Interface Elements
Clipboard: When to Use Each Clipboard Mechanism
3/4/2019 • 2 minutes to read • Edit Online

Follow these guidelines in using the Clipboard:


Use the OLE Clipboard mechanism now to enable new capabilities in the future. While the standard
Clipboard API will be maintained, the OLE mechanism is the future of data transfer.
Use the OLE Clipboard mechanism if you are writing an OLE application or you want any of the OLE
features, such as drag and drop.
Use the OLE Clipboard mechanism if you are providing OLE formats.

What do you want to do


Use the OLE Clipboard mechanism
Use the Windows Clipboard mechanism

See also
Clipboard
Clipboard: Using the Windows Clipboard
3/4/2019 • 2 minutes to read • Edit Online

This topic describes how to use the standard Windows Clipboard API within your MFC application.
Most applications for Windows support cutting or copying data to the Windows Clipboard and pasting data from
the Clipboard. The Clipboard data formats vary among applications. The framework supports only a limited
number of Clipboard formats for a limited number of classes. You will normally implement the Clipboard-related
commands — Cut, Copy, and Paste — on the Edit menu for your view. The class library defines the command IDs
for these commands: ID_EDIT_CUT , ID_EDIT_COPY , and ID_EDIT_PASTE . Their message-line prompts are also
defined.
Messages and Commands in the Framework explains how to handle menu commands in your application by
mapping the menu command to a handler function. As long as your application does not define handler functions
for the Clipboard commands on the Edit menu, they remain disabled. To write handler functions for the Cut and
Copy commands, implement selection in your application. To write a handler function for the Paste command,
query the Clipboard to see whether it contains data in a format your application can accept. For example, to enable
the Copy command, you might write a handler something like the following:

void CMyListView::OnEditCopy()
{
if ( !OpenClipboard() )
{
AfxMessageBox( _T("Cannot open the Clipboard") );
return;
}
// Remove the current Clipboard contents
if( !EmptyClipboard() )
{
AfxMessageBox( _T("Cannot empty the Clipboard") );
return;
}
// Get the currently selected data
HGLOBAL hGlob = GlobalAlloc(GMEM_FIXED, 64);
strcpy_s((char*)hGlob, 64, "Current selection\r\n");
// For the appropriate data formats...
if ( ::SetClipboardData( CF_TEXT, hGlob ) == NULL )
{
CString msg;
msg.Format(_T("Unable to set Clipboard data, error: %d"), GetLastError());
AfxMessageBox( msg );
CloseClipboard();
GlobalFree(hGlob);
return;
}
CloseClipboard();
}

The Cut, Copy, and Paste commands are only meaningful in certain contexts. The Cut and Copy commands should
be enabled only when something is selected, and the Paste command only when something is in the Clipboard.
You can provide this behavior by defining update handler functions that enable or disable these commands
depending on the context. For more information, see How to Update User-Interface Objects.
The Microsoft Foundation Class Library does provide Clipboard support for text editing with the CEdit and
CEditView classes. The OLE classes also simplify implementing Clipboard operations that involve OLE items. For
more information on the OLE classes, see Clipboard: Using the OLE Clipboard Mechanism.
Implementing other Edit menu commands, such as Undo (ID_EDIT_UNDO ) and Redo (ID_EDIT_REDO ), is also
left to you. If your application does not support these commands, you can easily delete them from your resource
file using the Visual C++ resource editors.

What do you want to know more about


Copying and pasting data
Using the OLE Clipboard mechanism

See also
Clipboard
Clipboard: Using the OLE Clipboard Mechanism
8/15/2019 • 2 minutes to read • Edit Online

OLE uses standard formats and some OLE-specific formats for transferring data through the Clipboard.
When you cut or copy data from an application, the data is stored on the Clipboard to be used later in paste
operations. This data is in a variety of formats. When a user chooses to paste data from the Clipboard, the
application can choose which of these formats to use. The application should be written to choose the format that
provides the most information, unless the user specifically asks for a certain format, using Paste Special. Before
continuing, you may want to read the Data Objects and Data Sources (OLE) topics. They describe the
fundamentals of how data transfers work, and how to implement them in your applications.
Windows defines a number of standard formats that can be used for transferring data through the Clipboard.
These include metafiles, text, bitmaps, and others. OLE defines a number of OLE-specific formats, as well. For
applications that need more detail than given by these standard formats, it is a good idea to register their own
custom Clipboard formats. Use the Win32 API function RegisterClipboardFormat to do this.
For example, Microsoft Excel registers a custom format for spreadsheets. This format carries much more
information than, for example, a bitmap does. When this data is pasted into an application that supports the
spreadsheet format, all the formulas and values from the spreadsheet are retained and can be updated if
necessary. Microsoft Excel also puts data on the Clipboard in formats so that it can be pasted as an OLE item. Any
OLE document container can paste this information as an embedded item. This embedded item can be changed
using Microsoft Excel. The Clipboard also contains a simple bitmap of the image of the selected range on the
spreadsheet. This can also be pasted into OLE document containers or into bitmap editors, like Paint. In the case of
a bitmap, however, there is no way to manipulate the data as a spreadsheet.
To retrieve the maximum amount of information from the Clipboard, applications should check for these custom
formats before pasting data from the Clipboard.
For example, to enable the Cut command, you might write a handler something like the following:

void CMyListView::OnEditCut()
{
// Create an OLE data source on the heap
COleDataSource* pData = new COleDataSource;
// Get the currently selected data
HGLOBAL hGlob = GlobalAlloc(GMEM_FIXED, 64);
strcpy_s((char*)hGlob, 64, "Current selection\r\n");
// For the appropriate data formats...
pData->CacheGlobalData( CF_TEXT, hGlob );
// The Clipboard now owns the allocated memory
// and will delete this data object
// when new data is put on the Clipboard
pData->SetClipboard();
}

What do you want to know more about


Copying and pasting data
Adding other formats
Using the Windows Clipboard
OLE
OLE data objects and data sources and uniform data transfer

See also
Clipboard
Clipboard: Copying and Pasting Data
3/27/2020 • 2 minutes to read • Edit Online

This topic describes the minimum work necessary to implement copying to and pasting from the Clipboard in
your OLE application. It is recommended that you read the Data Objects and Data Sources (OLE) topics before
proceeding.
Before you can implement either copying or pasting, you must first provide functions to handle the Copy, Cut, and
Paste options on the Edit menu.

Copying or Cutting Data


To copy data to the Clipboard
1. Determine whether the data to be copied is native data or is an embedded or linked item.
If the data is embedded or linked, obtain a pointer to the COleClientItem object that has been
selected.
If the data is native and the application is a server, create a new object derived from COleServerItem
containing the selected data. Otherwise, create a COleDataSource object for the data.
2. Call the selected item's CopyToClipboard member function.
3. If the user chose a Cut operation instead of a Copy operation, delete the selected data from your
application.
To see an example of this sequence, see the OnEditCut and OnEditCopy functions in the MFC OLE sample
programs OCLIENT and HIERSVR. Note that these samples maintain a pointer to the currently selected data, so
step 1 is already complete.

Pasting Data
Pasting data is more complicated than copying it because you need to choose the format to use in pasting the data
into your application.
To paste data from the Clipboard
1. In your view class, implement OnEditPaste to handle users choosing the Paste option from the Edit menu.
2. In the OnEditPaste function, create a COleDataObject object and call its AttachClipboard member function
to link this object to the data on the Clipboard.
3. Call COleDataObject::IsDataAvailable to check whether a particular format is available.
Alternately, you can use COleDataObject::BeginEnumFormats to look for other formats until you find one most
suited to your application.
4. Perform the paste of the format.
For an example of how this works, see the implementation of the OnEditPaste member functions in the view
classes defined in the MFC OLE sample programs OCLIENT and HIERSVR.
TIP
The main benefit of separating the paste operation into its own function is that the same paste code can be used when data
is dropped in your application during a drag-and-drop operation. As in OCLIENT and HIERSVR, your OnDrop function can
also call DoPasteItem , reusing the code written to implement Paste operations.

To handle the Paste Special option on the Edit menu, see the topic Dialog Boxes in OLE.
What do you want to know more about
Adding other formats
OLE data objects and data sources and uniform data transfer
OLE drag and drop
OLE

See also
Clipboard: Using the OLE Clipboard Mechanism
Clipboard: Adding Other Formats
3/27/2020 • 2 minutes to read • Edit Online

This topic explains how to expand the list of supported formats, particularly for OLE support. The topic Clipboard:
Copying and Pasting Data describes the minimum implementation necessary to support copying and pasting from
the Clipboard. If this is all you implement, the only formats placed on the Clipboard are CF_METAFILEPICT ,
CF_EMBEDSOURCE , CF_OBJECTDESCRIPTOR , and possibly CF_LINKSOURCE . Most applications will need
more formats on the Clipboard than these three.

Registering Custom Formats


To create your own custom formats, follow the same procedure you would use when registering any custom
Clipboard format: pass the name of the format to the RegisterClipboardFormat function and use its return
value as the format ID.

Placing Formats on the Clipboard


To add more formats to those placed on the Clipboard, you must override the OnGetClipboardData function in the
class you derived from either COleClientItem or COleServerItem (depending on whether the data to be copied is
native). In this function, you should use the following procedure.
To place formats on the Clipboard
1. Create a COleDataSource object.
2. Pass this data source to a function that adds your native data formats to the list of supported formats by
calling COleDataSource::CacheGlobalData .
3. Add standard formats by calling COleDataSource::CacheGlobalData for each standard format you want to
support.
This technique is used in the MFC OLE sample program HIERSVR (examine the OnGetClipboardData member
function of the CSer verItem class). The only difference in this sample is that step three is not implemented
because HIERSVR supports no other standard formats.
What do you want to know more about
OLE data objects and data sources and uniform data transfer
OLE drag and drop
OLE

See also
Clipboard: Using the OLE Clipboard Mechanism
Controls (MFC)
3/27/2020 • 3 minutes to read • Edit Online

Controls are objects that users can interact with to enter or manipulate data. They
commonly appear in dialog boxes or on toolbars. This topic family covers three main kinds
of controls:
Windows common controls, including owner-drawn controls
ActiveX Controls
Other control classes supplied by the Microsoft Foundation Class Library (MFC)

Windows Common Controls


The Windows operating system has always provided a number of Windows common
controls. These control objects are programmable, and the Visual C++ dialog editor
supports adding them to your dialog boxes. The Microsoft Foundation Class Library (MFC)
supplies classes that encapsulate each of these controls, as shown in the table Windows
Common Controls and MFC Classes. (Some items in the table have related topics that
describe them further. For controls that lack topics, see the documentation for the MFC
class.)
Class CWnd is the base class of all window classes, including all of the control classes.

ActiveX Controls
ActiveX controls, formerly known as OLE controls, can be used in dialog boxes in your
applications for Windows, or in HTML pages on the World Wide Web. For more information,
see MFC ActiveX Controls.

Other MFC Control Classes


In addition to classes that encapsulate all of the Windows common controls and that
support programming your own ActiveX controls (or using ActiveX controls supplied by
others), MFC supplies the following control classes of its own:
CBitmapButton
CCheckListBox
CDragListBox

Finding Information About Windows Common Controls


The table below briefly describes each of the Windows common controls, including the
control's MFC wrapper class.
Windows Common Controls and MFC Classes
C O N T RO L M F C C L A SS DESC RIP T IO N N EW IN W IN DO W S 95
C O N T RO L M F C C L A SS DESC RIP T IO N N EW IN W IN DO W S 95

animation CAnimateCtrl Displays successive Yes


frames of an AVI video
clip

button CButton Pushbuttons that No


cause an action; also
used for check boxes,
radio buttons, and
group boxes

combo box CComboBox Combination of an No


edit box and a list box

date and time picker CDateTimeCtrl Allows the user to Yes


choose a specific date
or time value

edit box CEdit Boxes for entering text No

extended combo box CComboBoxEx A combo box control Yes


with the ability to
display images

header CHeaderCtrl Button that appears Yes


above a column of
text; controls width of
text displayed

hotkey CHotKeyCtrl Window that enables Yes


user to create a "hot
key" to perform an
action quickly

image list CImageList Collection of images Yes


used to manage large
sets of icons or
bitmaps (image list
isn't really a control; it
supports lists used by
other controls)

list CListCtrl Window that displays Yes


a list of text with icons

list box CListBox Box that contains a list No


of strings

month calendar CMonthCalCtrl Control that displays Yes


date information

progress CProgressCtrl Window that indicates Yes


progress of a long
operation
C O N T RO L M F C C L A SS DESC RIP T IO N N EW IN W IN DO W S 95

rebar CRebarCtrl Tool bar that can Yes


contain additional
child windows in the
form of controls

rich edit CRichEditCtrl Window in which user Yes


can edit with character
and paragraph
formatting (see
Classes Related to Rich
Edit Controls)

scroll bar CScrollBar Scroll bar used as a No


control inside a dialog
box (not on a window)

slider CSliderCtrl Window containing a Yes


slider control with
optional tick marks

spin button CSpinButtonCtrl Pair of arrow buttons Yes


user can click to
increment or
decrement a value

static-text CStatic Text for labeling other No


controls

status bar CStatusBarCtrl Window for displaying Yes


status information,
similar to MFC class
CStatusBar

tab CTabCtrl Analogous to the Yes


dividers in a
notebook; used in
"tab dialog boxes" or
property sheets

toolbar CToolBarCtrl Window with Yes


command-generating
buttons, similar to
MFC class CToolBar

tool tip CToolTipCtrl Small pop-up window Yes


that describes
purpose of a toolbar
button or other tool

tree CTreeCtrl Window that displays Yes


a hierarchical list of
items

What do you want to know more about


An individual control: see the table Windows Common Controls and MFC Classes in
this topic for links to all controls
Making and using controls
Using the dialog editor to add controls
Adding controls to a dialog box by hand
Deriving control classes from the MFC control classes
Using common controls as child windows
Notifications from common controls
Add common controls to a dialog box.
Derive a control from a standard Windows control
Access dialog-box controls with type safety
Receive notification messages from common controls
Samples
For information about Windows common controls in the Windows SDK, see Common
Controls.

See also
User Interface Elements
Dialog Editor
Common Control Sample List
4/1/2019 • 2 minutes to read • Edit Online

See the following sample programs that illustrate common controls:


CMNCTRL1
CMNCTRL2
CTRLTEST

See also
Controls
Making and Using Controls
3/4/2019 • 2 minutes to read • Edit Online

You make most controls for dialog boxes in the Visual C++ dialog editor. But you can also create controls in any
dialog box or window.

What do you want to know more about


Using common controls in a dialog box
Using the dialog editor to add controls
Adding controls by hand (without the dialog editor)
Deriving controls from a standard control
Using a common control as a child window
Receiving notification from common controls
Dialog Data Exchange and Validation
Type-Safe Access to Controls With Code Wizards
Individual controls: see Controls for links to all common controls
Dialog boxes
Dialog bars

See also
Controls
Using Common Controls in a Dialog Box
3/4/2019 • 2 minutes to read • Edit Online

The Windows common controls can be used in dialog boxes, form views, record views, and any other window
based on a dialog template. The following procedure, with minor changes, will work for forms as well.

Procedures
To use a common control in a dialog box
1. Place the control on the dialog template using the dialog editor.
2. Add to the dialog class a member variable that represents the control. In the Add Member Variable dialog
box, check Control variable and ensure that Control is selected for the Categor y .
3. If this common control is providing input to the program, declare additional member variable(s) in the
dialog class to handle those input values.

NOTE
You can add these member variables using the context menu in Class View (see Adding a Member Variable).

4. In OnInitDialog for your dialog class, set the initial conditions for the common control. Using the member
variable created in the previous step, use the member functions to set initial value and other settings. See
the following descriptions of the controls for details on settings.
You can also use dialog data exchange (DDX) to initialize controls in a dialog box.
5. In handlers for controls on the dialog box, use the member variable to manipulate the control. See the
following descriptions of the controls for details on methods.

NOTE
The member variable will exist only as long as the dialog box itself exists. You will not be able to query the control for
input values after the dialog box has been closed. To work with input values from a common control, override OnOK
in your dialog class. In your override, query the control for input values and store those values in member variables
of the dialog class.

NOTE
You can also use dialog data exchange to set or retrieve values from the controls in a dialog box.

Remarks
The addition of some common controls to a dialog box will cause the dialog box to no longer function. Refer to
Adding Controls to a Dialog Causes the Dialog to No Longer Function for more information on handling this
situation.

What do you want to do


Add controls to a dialog box by hand instead of with the dialog editor
Derive my control from one of the standard Windows common controls
Use a common control as a child window
Receive notification messages from a control
Use dialog data exchange (DDX)

See also
Making and Using Controls
Controls
Using the Dialog Editor to Add Controls
3/4/2019 • 2 minutes to read • Edit Online

When you create your dialog-template resource with the dialog editor, you drag controls from a controls palette
and drop them into the dialog box. This adds the specifications for that control type to the dialog-template
resource. When you construct a dialog object and call its Create or DoModal member function, the framework
creates a Windows control and places it in the dialog window on screen.
You can instead create controls by hand if you want. This is more work.

See also
Making and Using Controls
Controls
Adding Controls By Hand
3/4/2019 • 2 minutes to read • Edit Online

You can either add controls to a dialog box with the dialog editor or add them yourself, with code.
To create a control object yourself, you will usually embed the C++ control object in a C++ dialog or frame-
window object. Like many other objects in the framework, controls require two-stage construction. You should call
the control's Create member function as part of creating the parent dialog box or frame window. For dialog
boxes, this is usually done in OnInitDialog, and for frame windows, in OnCreate.
The following example shows how you might declare a CEdit object in the class declaration of a derived dialog
class and then call the Create member function in OnInitDialog . Because the CEdit object is declared as an
embedded object, it is automatically constructed when the dialog object is constructed, but it must still be
initialized with its own Create member function.

class CCustomDialog : public CDialog


{
CEdit m_edit;
virtual BOOL OnInitDialog();
};

The following OnInitDialog function sets up a rectangle, then calls Create to create the Windows edit control
and attach it to the uninitialized CEdit object.

BOOL CCustomDialog::OnInitDialog()
{
CDialog::OnInitDialog();
CRect rect(85, 110, 180, 210);

m_edit.Create(WS_CHILD | WS_VISIBLE | WS_TABSTOP |


ES_AUTOHSCROLL | WS_BORDER,
rect, this, IDC_EXTRA_EDIT);
m_edit.SetFocus();
return FALSE;
}

After creating the edit object, you can also set the input focus to the control by calling the SetFocus member
function. Finally, you return 0 from OnInitDialog to show that you set the focus. If you return a nonzero value, the
dialog manager sets the focus to the first control item in the dialog item list. In most cases, you'll want to add
controls to your dialog boxes with the dialog editor.

See also
Making and Using Controls
Controls
CDialog::OnInitDialog
Deriving Controls from a Standard Control
3/4/2019 • 2 minutes to read • Edit Online

As with any CWnd-derived class, you can modify a control's behavior by deriving a new class from an existing
control class.
To create a derived control class
1. Derive your class from an existing control class and optionally override the Create member function so
that it provides the necessary arguments to the base-class Create function.
2. Provide message-handler member functions and message-map entries to modify the control's behavior in
response to specific Windows messages. See Mapping Messages to Functions.
3. Provide new member functions to extend the functionality of the control (optional).
Using a derived control in a dialog box requires extra work. The types and positions of controls in a dialog box are
normally specified in a dialog-template resource. If you create a derived control class, you cannot specify it in a
dialog template since the resource compiler knows nothing about your derived class.
To place your derived control in a dialog box
1. Embed an object of the derived control class in the declaration of your derived dialog class.
2. Override the OnInitDialog member function in your dialog class to call the SubclassDlgItem member
function for the derived control.
SubclassDlgItem "dynamically subclasses" a control created from a dialog template. When a control is dynamically
subclassed, you hook into Windows, process some messages within your own application, then pass the
remaining messages on to Windows. For more information, see the SubclassDlgItem member function of class
CWnd in the MFC Reference. The following example shows how you might write an override of OnInitDialog to
call SubclassDlgItem :

BOOL CSubDialog::OnInitDialog()
{
CDialog::OnInitDialog();

m_wndMyBtn.SubclassDlgItem(IDC_MYBTN, this);

return TRUE;
}

Because the derived control is embedded in the dialog class, it will be constructed when the dialog box is
constructed, and it will be destroyed when the dialog box is destroyed. Compare this code to the example in
Adding Controls By Hand.

See also
Making and Using Controls
Controls
Using a Common Control as a Child Window
3/4/2019 • 2 minutes to read • Edit Online

Any of the Windows common controls can be used as a child window of any other window. The following
procedure describes how to create a common control dynamically and then work with it.
To use a common control as a child window
1. Define the control in the related class or handler.
2. Use the control's override of the CWnd::Create method to create the Windows control.
3. After the control has been created (as early as the OnCreate handler if you subclass the control), you can
manipulate the control using its member functions. See the descriptions of individual controls at Controls
for details on methods.
4. When you are finished with the control, use CWnd::DestroyWindow to destroy the control.

See also
Making and Using Controls
Controls
Receiving Notification from Common Controls
3/27/2020 • 2 minutes to read • Edit Online

Common controls are child windows that send notification messages to the parent window when events, such as
input from the user, occur in the control.
The application relies on these notification messages to determine what action the user wants it to take. Most
common controls send notification messages as WM_NOTIFY messages. Windows controls send most notification
messages as WM_COMMAND messages. CWnd::OnNotify is the handler for the WM_NOTIFY message. As with
CWnd::OnCommand , the implementation of OnNotify dispatches the notification message to OnCmdMsg for handling
in message maps. The message-map entry for handling notifications is ON_NOTIFY. For more information, see
Technical Note 61: ON_NOTIFY and WM_NOTIFY Messages.
Alternately, a derived class can handle its own notification messages using "message reflection." For more
information, see Technical Note 62: Message Reflection for Windows Controls.

Retrieving the Cursor Position in a Notification Message


On occasion, it is useful to determine the current position of the cursor when certain notification messages are
received by a common control. For example, it would be helpful to determine the current cursor location when a
common control receives a NM_RCLICK notification message.
There is a simple way to accomplish this by calling CWnd::GetCurrentMessage . However, this method only retrieves
the cursor position at the time the message was sent. Because the cursor may have been moved since the
message was sent you must call CWnd::GetCursorPos to get the current cursor position.

NOTE
CWnd::GetCurrentMessage should only be called within a message handler.

Add the following code to the body of the notification message handler (in this example, NM_RCLICK):

CPoint cursorPos;
cursorPos.x = GetCurrentMessage()->pt.x;
cursorPos.y = GetCurrentMessage()->pt.y;

At this point, the mouse cursor location is stored in the cursorPos object.

See also
Making and Using Controls
Controls
Using CAnimateCtrl
3/16/2020 • 2 minutes to read • Edit Online

An animation control, represented by the class CAnimateCtrl, is a window that displays a clip in Audio Video
Interleaved (AVI) format — the standard Windows video/audio format. An AVI clip is a series of bitmap frames, like
a movie.
Since your thread continues executing while the AVI clip is displayed, one common use for an animation control is
to indicate system activity during a lengthy operation. For example, the Windows Find dialog box displays a
moving magnifying glass as the system searches for a file.
Animation controls can only play simple AVI clips, and they do not support sound. (For a complete list of
limitations, see CAnimateCtrl.) Since the capabilities of an animation control are severely limited and subject to
change, you should use an alternative such as the MCIWnd control if you need a control to provide multimedia
playback and/or recording capabilities. For more information about the MCIWnd control, see the multimedia
documentation.

What do you want to know more about


Using an Animation Control
Notifications Sent by Animation Controls

See also
Controls
Using an Animation Control
3/4/2019 • 2 minutes to read • Edit Online

Typical usage of an animation control follows the pattern below:


The control is created. If the control is specified in a dialog box template, creation is automatic when the
dialog box is created. (You should have a CAnimateCtrl member in your dialog class that corresponds to the
animation control.) Alternatively, you can use the Create member function to create the control as a child
window of any window.
Load an AVI clip into the animation control by calling the Open member function. If your animation control
is in a dialog box, a good place to do this is in the dialog class's OnInitDialog function.
Play the clip by calling the Play member function. If your animation control is in a dialog box, a good place to
do this is in the dialog class's OnInitDialog function. Calling Play is not necessary if the animation control
has the ACS_AUTOPLAY style set.
If you want to display portions of the clip or play it frame by frame, use the Seek member function. To stop
a clip that is playing, use the Stop member function.
If you are not going to destroy the control right away, remove the clip from memory by calling the Close
member function.
If the animation control is in a dialog box, it and the CAnimateCtrl object will be destroyed automatically. If
not, you need to ensure that both the control and the CAnimateCtrl object are properly destroyed.
Destroying the control automatically closes the AVI clip.

See also
Using CAnimateCtrl
Controls
Notifications Sent by Animation Controls
8/15/2019 • 2 minutes to read • Edit Online

An animation control (CAnimateCtrl) sends two different types of notification messages. The notifications are sent
in the form of WM_COMMAND messages.
The ACN_START message is sent when the animation control has started playing a clip. The ACN_STOP message is
sent when the animation control has finished or stopped playing a clip.

See also
Using CAnimateCtrl
Controls
Using CDateTimeCtrl
3/27/2020 • 2 minutes to read • Edit Online

The date and time picker control (CDateTimeCtrl) implements an intuitive and recognizable method of entering or
selecting a specific date. The main interface of the control is similar in functionality to a combo box. However, if the
user expands the control, a month calendar control appears (by default), allowing the user to specify a particular
date. When a date is chosen, the month calendar control automatically disappears.

NOTE
To use both the CDateTimePicker and CMonthCalCtrl classes in your project, you must include AFXDTCTL.H, usually in
your project's STDAFX.H file.

What do you want to know more about


Creating the Date and Time Picker Control
Date and Time Picker Control Examples
Accessing the Embedded Month Calendar Control
Using Custom Format Strings in a Date and Time Picker Control
Using Callback Fields in a Date and Time Picker Control
Processing Notification Messages in Date and Time Picker Controls

See also
Controls
Creating the Date and Time Picker Control
9/11/2019 • 2 minutes to read • Edit Online

How the date and time picker control is created depends on whether you are using the control in a dialog box or
creating it in a nondialog window.
To use CDateTimeCtrl directly in a dialog box
1. In the dialog editor, add a Date and Time Picker Control to your dialog template resource. Specify its control
ID.
2. Specify any styles required, using the Properties dialog box of the date and time picker control.
3. Use the Add Member Variable Wizard to add a member variable of type CDateTimeCtrl with the Control
property. You can use this member to call CDateTimeCtrl member functions.
4. Use the Class Wizard to map handler functions in the dialog class for any date time picker control
notification messages you need to handle (see Mapping Messages to Functions).
5. In OnInitDialog, set any additional styles for the CDateTimeCtrl object.
To use CDateTimeCtrl in a nondialog window
1. Declare the control in the view or window class.
2. Call the control's Create member function, possibly in OnInitialUpdate, possibly as early as the parent
window's OnCreate handler function (if you're subclassing the control). Set the styles for the control.

See also
Using CDateTimeCtrl
Controls
Date and Time Picker Control Examples
4/1/2019 • 2 minutes to read • Edit Online

The CMNCTRL1 sample demonstrates the various attributes of the CDateTimeCtrl class. A separate page contains a
date and time picker control that the user can manipulate by changing various attributes and testing the basic
functionality of the control.

See also
Using CDateTimeCtrl
Controls
Accessing the Embedded Month Calendar Control
3/27/2020 • 2 minutes to read • Edit Online

The embedded month calendar control object can be accessed from the CDateTimeCtrl object with a call to the
GetMonthCalCtrl member function.

NOTE
The embedded month calendar control is used only when the date and time picker control does not have the
DTS_UPDOWN style set.

This is useful if you want to modify certain attributes before the embedded control is displayed. To accomplish this,
handle the DTN_DROPDOWN notification, retrieve the month calendar control (using
CDateTimeCtrl::GetMonthCalCtrl), and make your modifications. Unfortunately, the month calendar control is not
persistent.
In other words, when the user requests the display of the month calendar control, a new month calendar control is
created (before the DTN_DROPDOWN notification). The control is destroyed (after the DTN_CLOSEUP
notification) when dismissed by the user. This means that any attributes you modify, before the embedded control
is displayed, are lost when the embedded control is dismissed.
The following example demonstrates this procedure, using a handler for the DTN_DROPDOWN notification. The
code changes the background color of the month calendar control, with a call to SetMonthCalColor, to gray. The
code is as follows:

void CMyDialog::OnDtnDropdownDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult)


{
UNREFERENCED_PARAMETER(pNMHDR);

//set the background color of the month to gray


COLORREF clr = RGB(100, 100, 100);

m_DateTimeCtrl.SetMonthCalColor(MCSC_MONTHBK, clr);

*pResult = 0;
}

As stated previously, all modifications to properties of the month calendar control are lost, with two exceptions,
when the embedded control is dismissed. The first exception, the colors of the month calendar control, has already
been discussed. The second exception is the font used by the month calendar control. You can modify the default
font by making a call to CDateTimeCtrl::SetMonthCalFont, passing the handle of an existing font. The following
example (where m_dtPicker is the date and time control object) demonstrates one possible method:
//create and initialize the font to be used
LOGFONT logFont = {0};
logFont.lfHeight = -12;
logFont.lfWeight = FW_NORMAL;
logFont.lfCharSet = DEFAULT_CHARSET;
_tcscpy_s(logFont.lfFaceName, _countof(logFont.lfFaceName),
_T("Verdana"));

m_MonthCalFont.CreateFontIndirect(&logFont);
m_DateTimeCtrl.SetMonthCalFont(m_MonthCalFont);

Once the font has been changed, with a call to CDateTimeCtrl::SetMonthCalFont , the new font is stored and used the
next time a month calendar is to be displayed.

See also
Using CDateTimeCtrl
Controls
Using Custom Format Strings in a Date and Time
Picker Control
3/4/2019 • 2 minutes to read • Edit Online

By default, date and time picker controls provide three format types (each format corresponding to a unique style)
for displaying the current date or time:
DTS_LONGDATEFORMAT Displays the date in long format, producing output like "Wednesday, January 3,
2000".
DTS_SHORTDATEFORMAT Displays the date in short format, producing output like "1/3/00".
DTS_TIMEFORMAT Displays the time in long format, producing output like "5:31:42 PM".
However, you can customize the appearance of the date or time by using a custom format string. This custom
string is made up of either existing format characters, nonformat characters, or a combination of both. Once the
custom string is built, make a call to CDateTimeCtrl::SetFormat passing in your custom string. The date and time
picker control will then display the current value using your custom format string.
The following example code (where m_dtPicker is the CDateTimeCtrl object) demonstrates one possible solution:

CString formatStr = _T("'Today is: 'yy'/'MM'/'dd");


m_DateTimeCtrl.SetFormat(formatStr);

In addition to custom format strings, date and time picker controls also support callback fields.

See also
Using CDateTimeCtrl
Controls
Using Callback Fields in a Date and Time Picker
Control
3/27/2020 • 3 minutes to read • Edit Online

In addition to the standard format characters that define date and time picker fields, you can customize your
output by specifying certain parts of a custom format string as callback fields. To declare a callback field, include
one or more "X" characters (ASCII Code 88) anywhere in the body of the format string. For example, the following
string "'Today is: 'yy'/'MM'/'dd' (Day 'X')'"causes the date and time picker control to display the current value as
the year followed by the month, date, and finally the day of the year.

NOTE
The number of X's in a callback field does not correspond to the number of characters that will be displayed.

You can distinguish between multiple callback fields in a custom string by repeating the "X" character. Thus, the
format string "XXddddMMMdd', 'yyyXXX" contains two unique callback fields, "XX" and "XXX".

NOTE
Callback fields are treated as valid fields, so your application must be prepared to handle DTN_WMKEYDOWN notification
messages.

Implementing callback fields in your date and time picker control consists of three parts:
Initializing the custom format string
Handling the DTN_FORMATQUERY notification
Handling the DTN_FORMAT notification

Initializing the Custom Format String


Initialize the custom string with a call to CDateTimeCtrl::SetFormat . For more information, see Using Custom
Format Strings in a Date and Time Picker Control. A common place to set the custom format string is in the
OnInitDialog function of your containing dialog class or OnInitialUpdate function of your containing view class.

Handling the DTN_FORMATQUERY Notification


When the control parses the format string and encounters a callback field, the application sends DTN_FORMAT and
DTN_FORMATQUERY notification messages. The callback field string is included with the notifications so you can
determine which callback field is being queried.
The DTN_FORMATQUERY notification is sent to retrieve the maximum allowable size in pixels of the string that will
be displayed in the current callback field.
To properly calculate this value, you must calculate the height and width of the string, to be substituted for the
field, using the control's display font. The actual calculation of the string is easily achieved with a call to the
GetTextExtentPoint32 Win32 function. Once the size is determined, pass the value back to the application and exit
the handler function.
The following example is one method of supplying the size of the callback string:

void CMyDialog::OnDtnFormatqueryDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult)


{
LPNMDATETIMEFORMATQUERY pDTFormatQuery =
reinterpret_cast<LPNMDATETIMEFORMATQUERY>(pNMHDR);
CDC *pDC = NULL;
CFont *pFont = NULL;
CFont *pOrigFont = NULL;

// Prepare the device context for the GetTextExtentPoint32 call.


pDC = GetDC();
if (NULL == pDC)
{
return;
}

pFont = GetFont();
if (NULL == pFont)
{
pFont = new CFont();
VERIFY(pFont->CreateStockObject(DEFAULT_GUI_FONT));
}

pOrigFont = pDC->SelectObject(pFont);

// Check to see if this is the callback segment desired. If so,


// use the longest text segment to determine the maximum
// width of the callback field, and then place the information into
// the NMDATETIMEFORMATQUERY structure.
if (!_tcscmp(_T("X"), pDTFormatQuery->pszFormat))
{
::GetTextExtentPoint32(pDC->m_hDC, _T("366"), 3, &pDTFormatQuery->szMax);
}

// Reset the font in the device context then release the context.
pDC->SelectObject(pOrigFont);
ReleaseDC(pDC);

*pResult = 0;
}

Once the size of the current callback field has been calculated, you must supply a value for the field. This is done in
the handler for the DTN_FORMAT notification.

Handling the DTN_FORMAT Notification


The DTN_FORMAT notification is used by the application to request the character string that will be substituted.
The following example demonstrates one possible method:

void CMyDialog::OnDtnFormatDatetimepicker1(NMHDR *pNMHDR, LRESULT *pResult)


{
LPNMDATETIMEFORMAT pDTFormat = reinterpret_cast<LPNMDATETIMEFORMAT>(pNMHDR);

COleDateTime oCurTime;

m_DateTimeCtrl.GetTime(oCurTime);

_itot_s(oCurTime.GetDayOfYear(), pDTFormat->szDisplay,
sizeof(pDTFormat->szDisplay) / sizeof(TCHAR), 10);

*pResult = 0;
}
NOTE
The pointer to the NMDATETIMEFORMAT structure is found by casting the first parameter of the notification handler to
the proper type.

See also
Using CDateTimeCtrl
Controls
Processing Notification Messages in Date and Time
Picker Controls
9/11/2019 • 2 minutes to read • Edit Online

As users interact with the date and time picker control, the control ( CDateTimeCtrl ) sends notification messages to
its parent window, usually a view or dialog object. Handle these messages if you want to do something in
response. For example, when the user opens the date and time picker to display the embedded month calendar
control, the DTN_DROPDOWN notification is sent.
Use the Class Wizard to add notification handlers to the parent class for those messages you want to implement.
The following list describes the various notifications sent by the date and time picker control.
DTN_DROPDOWN Notifies the parent that the embedded month calendar control is about to be displayed.
This notification is only sent when the DTS_UPDOWN style has not been set. For more information on this
notification, see Accessing the Embedded Month Calendar Control.
DTN_CLOSEUP Notifies the parent that the embedded month calendar control is about to be closed. This
notification is only sent when the DTS_UPDOWN style has not been set.
DTN_DATETIMECHANGE Notifies the parent that a change has occurred in the control.
DTN_FORMAT Notifies the parent that text is needed to be displayed in a callback field. For more
information on this notification and callback fields, see Using Callback Fields in a Date and Time Picker
Control.
DTN_FORMATQUERY Requests the parent to supply the maximum allowable size of the string that will be
displayed in a callback field. Handling this notification allows the control to properly display output at all
times, reducing flicker within the control's display. For more information on this notification, see Using
Callback Fields in a Date and Time Picker Control.
DTN_USERSTRING Notifies the parent that the user has finished editing the contents of the date and time
picker control. This notification is only sent when the DTS_APPCANPARSE style has been set.
DTN_WMKEYDOWN Notifies the parent when the user types in a callback field. Handle this notification to
emulate the same keyboard response supported for non-callback fields in a date and time picker control.
For more information on this notification, see Supporting Callback Fields in a DTP Control in the Windows
SDK.

See also
Using CDateTimeCtrl
Controls
Using CComboBoxEx
3/16/2020 • 2 minutes to read • Edit Online

The extended combo box control is an extension of the standard combo box control that provides native support
for item images. These images can be used to indicate the status of individual items in the combo box, such as the
currently selected and unselected items. To make item images easily accessible, the control provides image list
support.
Use this control to provide the functionality of a combo box without having to manually draw item graphics.

What do you want to know more about


Creating an Extended Combo Box Control
Using Image Lists in an Extended Combo Box Control
Setting the Images for an Individual Item
Processing Notification Messages in Extended Combo Box Controls

See also
Controls
Creating an Extended Combo Box Control
9/11/2019 • 2 minutes to read • Edit Online

How the extended combo box control is created depends on whether you are using the control in a dialog box or
creating it in a nondialog window.
To use CComboBoxEx directly in a dialog box
1. In the dialog editor, add an Extended Combo Box control to your dialog template resource. Specify its control
ID.
2. Specify any styles required, using the Properties dialog box of the extended combo box control.
3. Use the Add Member Variable Wizard to add a member variable of type CComboBoxEx with the Control
property. You can use this member to call CComboBoxEx member functions.
4. Use the Class Wizard to map handler functions in the dialog class for any extended combo box control
notification messages you need to handle (see Mapping Messages to Functions).
5. In OnInitDialog, set any additional styles for the CComboBoxEx object.
To use CComboBoxEx in a nondialog window
1. Define the control in the view or window class.
2. Call the control's Create member function, possibly in OnInitialUpdate, possibly as early as the parent
window's OnCreate handler function. Set the styles for the control.

See also
Using CComboBoxEx
Controls
Using Image Lists in an Extended Combo Box Control
3/4/2019 • 2 minutes to read • Edit Online

The main feature of extended combo box controls is the ability to associate images from an image list with
individual items in a combo box control. Each item is able to display three different images: one for its selected
state, one for its nonselected state, and a third for an overlay image.
The following procedure associates an image list with an extended combo box control:
To associate an image list with an extended combo box control
1. Construct a new image list (or use an existing image list object), using the CImageList constructor and
storing the resultant pointer.
2. Initialize the new image list object by calling CImageList::Create. The following code is one example of this
call.

m_ComboImageList.Create(16, 16, ILC_COLOR, 2, 2);

3. Add optional images for each possible state: selected or nonselected, and an overlay. The following code
adds three predefined images.

m_ComboImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_ComboImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_ComboImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

4. Associate the image list with the control with a call to CComboBoxEx::SetImageList.
Once the image list has been associated with the control, you can individually specify the images each item will use
for the three possible states. For more information, see Setting the Images for an Individual Item.

See also
Using CComboBoxEx
Controls
Setting the Images for an Individual Item
8/15/2019 • 2 minutes to read • Edit Online

The different types of images used by the extended combo box item are determined by the values in the iImage,
iSelectedImage, and iOverlay members of the COMBOBOXEXITEM structure. Each value is the index of an image in
the associated image list of the control. By default, these members are set to 0, causing the control to display no
image for the item. If you want to use images for a specific item, you can modify the structure accordingly, either
when inserting the combo box item or by modifying an existing combo box item.

Setting the Image for a New Item


If you are inserting a new item, initialize the iImage, iSelectedImage, and iOverlay structure members with the
proper values and then insert the item with a call to CComboBoxEx::InsertItem.
The following example inserts a new extended combo box item ( cbi ) into the extended combo box control (
m_comboEx ), supplying indices for all three image states:

COMBOBOXEXITEM cbi = { 0 };
COMBOBOXEXITEM cbi = { 0 };
CString str;
int nItem;

cbi.mask = CBEIF_IMAGE | CBEIF_INDENT | CBEIF_OVERLAY |


CBEIF_SELECTEDIMAGE | CBEIF_TEXT;

cbi.iItem = 0;
cbi.pszText = _T("Item 0");
cbi.iImage = 0;
cbi.iSelectedImage = 1;
cbi.iOverlay = 2;
cbi.iIndent = (0 & 0x03); //Set indentation according
//to item position

nItem = m_ComboBoxEx.InsertItem(&cbi);
ASSERT(nItem == 0);

Setting the Image for an Existing Item


If you are modifying an existing item, you need to work with the mask member of a COMBOBOXEXITEM
structure.
To modify an existing item to use images
1. Declare a COMBOBOXEXITEM structure and set the mask data member to the values you are interested in
modifying.
2. Using this structure, make a call to CComboBoxEx::GetItem.
3. Modify the mask, iImage, and iSelectedImage members of the newly returned structure, using the
appropriate values.
4. Make a call to CComboBoxEx::SetItem, passing in the modified structure.
The following example demonstrates this procedure by swapping the selected and unselected images of the third
extended combo box item:
COMBOBOXEXITEM cbi = {0};
int iImageTemp;

cbi.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;


cbi.iItem = 0;
m_ComboBoxEx.GetItem(&cbi);

iImageTemp = cbi.iImage;
cbi.iImage = cbi.iSelectedImage;
cbi.iSelectedImage = iImageTemp;
VERIFY(m_ComboBoxEx.SetItem(&cbi));

See also
Using CComboBoxEx
Controls
Processing Notification Messages in Extended Combo
Box Controls
9/11/2019 • 2 minutes to read • Edit Online

As users interact with the extended combo box, the control ( CComboBoxEx ) sends notification messages to its parent
window, usually a view or dialog object. Handle these messages if you want to do something in response. For
example, when the user activates the drop-down list or clicks in the control's edit box, the CBEN_BEGINEDIT
notification is sent.
Use the Class Wizard to add notification handlers to the parent class for those messages you want to implement.
The following list describes the various notifications sent by the extended combo box control.
CBEN_BEGINEDIT Sent when the user activates the drop-down list or clicks in the control's edit box.
CBEN_DELETEITEM Sent when an item has been deleted.
CBEN_DRAGBEGIN Sent when the user begins dragging the image of the item displayed in the edit portion
of the control.
CBEN_ENDEDIT Sent when the user has concluded an operation within the edit box or has selected an item
from the control's drop-down list.
CBEN_GETDISPINFO Sent to retrieve display information about a callback item.
CBEN_INSERTITEM Sent when a new item has been inserted in the control.

See also
Using CComboBoxEx
Controls
Using CHeaderCtrl
3/27/2020 • 2 minutes to read • Edit Online

Use a header control, represented by class CHeaderCtrl, to display column headers for a columnar list. For
example, a header control would be useful for implementing column controls in a spreadsheet.
The header control is usually divided into parts, called "header items," each bearing a title for the associated
column of text or numbers. Depending on the styles you set, you can provide a number of direct ways for users
to manipulate the header items.

NOTE
CListCtrl provides an embedded header control, and CListView encapsulates CListCtrl in an MFC class. In general, think
of using CHeaderCtrl to label lists that you intend to draw yourself.

What do you want to know more about


Header Control and List Control
Header Control Examples
Header Items in a Header Control
Customizing the Header Item's Appearance
Providing Drag-and-Drop Support for Header Items
Using Image Lists with Header Controls
Making Owner-Drawn Header Controls
Working with a Header Control
Creating the Header Control
Adding Items to the Header Control
Ordering Items in the Header Control
Processing Header-Control Notifications

See also
Controls
Header Control and List Control
3/27/2020 • 2 minutes to read • Edit Online

In most cases, you will use the header control that is embedded in a CListCtrl or CListView object. However, there
are cases where a separate header control object is desirable, such as manipulating data, arranged in columns or
rows, in a CView-derived object. In these cases, you need greater control over the appearance and default behavior
of an embedded header control.
In the common case that you want a header control to provide standard, default behavior, you may want to use
CListCtrl or CListView instead. Use CListCtrl when you want the functionality of a default header control,
embedded in a list view common control. Use CListView when you want the functionality of a default header
control, embedded in a view object.

NOTE
These controls only include a built-in header control if the list view control is created using the LVS_REPORT style.

In most cases, the appearance of the embedded header control can be modified by changing the styles of the
containing list view control. In addition, information about the header control can be obtained through member
functions of the parent list view control. However, for complete control, and access, to the attributes and styles of
the embedded header control, it is recommended that a pointer to the header control object be obtained.
The embedded header control object can be accessed from either CListCtrl or CListView with a call to the
respective class's GetHeaderCtrl member function. The following code demonstrates this:

CHeaderCtrl* pHeaderCtrl = m_ListCtrl.GetHeaderCtrl();


ASSERT(NULL != pHeaderCtrl);
//perform any needed operations on the header using pHeader

What do you want to know more about


Using image lists with header controls

See also
Using CHeaderCtrl
Controls
Header Control Examples
8/15/2019 • 2 minutes to read • Edit Online

For examples of header controls, see the Header Controls in the Windows SDK.

See also
Using CHeaderCtrl
Controls
Header Items in a Header Control
3/4/2019 • 2 minutes to read • Edit Online

You have considerable control over the appearance and behavior of the header items that make up a header
control (CHeaderCtrl). Each header item can have a string, a bitmapped image, an image from an associated image
list, or an application-defined 32-bit value associated with it. The string, bitmap, or image is displayed in the header
item.
You can customize the appearance and contents of new items when they are created by making a call
CHeaderCtrl::InsertItem or by modifying an existing item, with a call to CHeaderCtrl::GetItem and
CHeaderCtrl::SetItem.

What do you want to know more about


Customizing the header item's appearance
Ordering items in the header control
Providing drag-and-drop support for the header items
Using image lists with header controls

See also
Using CHeaderCtrl
Customizing the Header Item's Appearance
8/15/2019 • 2 minutes to read • Edit Online

By setting the dwStyle parameter when you first create a header control (CHeaderCtrl::Create), you can define the
appearance and behavior of header items or of the header control itself.
Here is a sampling of the styles you can set, and their purpose:
To make a header item look like a pushbutton, use the HDS_BUTTONS style.
Use this style if you want to carry out actions in response to mouse clicks on a header item, such as sorting
data by a particular column, as is done in Microsoft Outlook.
To give the header items a "hot tracking" appearance when the mouse cursor passes over them, use the
HDS_HOTTRACK style.
Hot tracking displays a 3D outline as the pointer passes over an item in an otherwise flat bar.
To indicate that the header control should be hidden, use the HDS_HIDDEN style.
The HDS_HIDDEN style indicates that the header control is intended to be used as a data container and not
a visual control. This style does not automatically hide the control but, instead, affects the behavior of
CHeaderCtrl::Layout . The value returned in the cy member of the WINDOWPOS structure will be zero
indicating that the control should not be visible to the user.
For more information about these properties, see Items in the Windows SDK. For information about adding items
to a header control, see Adding Items to the Header Control.

See also
Using CHeaderCtrl
Controls
Providing Drag-and-Drop Support for Header Items
3/27/2020 • 2 minutes to read • Edit Online

To provide drag-and-drop support for header items, specify the HDS_DRAGDROP style. Drag-and-drop support
for header items gives the user the ability to reorder the header items of a header control. The default behavior
provides a semitransparent drag image of the header item being dragged and a visual indicator of the new
position, if the header item is dropped.
As with common drag-and-drop functionality, you can extend the default drag-and-drop behavior by handling the
HDN_BEGINDRAG and HDN_ENDDRAG notifications. You can also customize the appearance of the drag image by
overriding the CHeaderCtrl::CreateDragImage member function.

NOTE
If you are providing drag-and-drop support for an embedded header control in a list control, see the Extended Style section
in the Changing List Control Styles topic.

See also
Using CHeaderCtrl
Using Image Lists with Header Controls
3/27/2020 • 2 minutes to read • Edit Online

Header items have the ability to display an image within a header item. This image, stored in an associated image
list, is 16 x 16 pixels and has the same characteristics as the icon images used in a list view control. In order to
implement this behavior successfully, you must first create and initialize the image list, associate the list with the
header control, and then modify the attributes of the header item that will display the image.
The following procedure illustrates the details, using a pointer to a header control ( m_pHdrCtrl ) and a pointer to
an image list ( m_pHdrImages ).
To display an image in a header item
1. Construct a new image list (or use an existing image list object) using the CImageList constructor, storing
the resultant pointer.
2. Initialize the new image list object by calling CImageList::Create. The following code is one example of this
call.

m_ListImageList.Create(16, 16, ILC_COLOR, 2, 2);

3. Add the images for each header item. The following code adds two predefined images.

m_ListImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_ListImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

4. Associate the image list with the header control with a call to CHeaderCtrl::SetImageList.
5. Modify the header item to display an image from the associated image list. The following example assigns
the first image, from m_phdrImages , to the first header item, m_pHdrCtrl .

HDITEM curItem = {0};

pHeaderCtrl->SetImageList(&m_ListImageList);

curItem.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH | HDI_IMAGE;


curItem.pszText = _T("Column 1");
curItem.cxy = 100;
curItem.iImage = 0;
curItem.fmt = HDF_LEFT | HDF_STRING | HDF_IMAGE;
pHeaderCtrl->InsertItem(0, &curItem);

For detailed information on the parameter values used, consult the pertinent CHeaderCtrl.

NOTE
It is possible to have multiple controls using the same image list. For instance, in a standard list view control, there could be
an image list (of 16 x 16 pixel images) used by both the small icon view of a list view control and the header items of the list
view control.

See also
Using CHeaderCtrl
Making Owner-Drawn Header Controls
8/15/2019 • 2 minutes to read • Edit Online

You can define individual items of a header control (CHeaderCtrl) to be owner-drawn items. For more information,
see Owner-Drawn Header Controls in the Windows SDK.

See also
Using CHeaderCtrl
Controls
Working with a Header Control
3/4/2019 • 2 minutes to read • Edit Online

The easy way to use a header control (CHeaderCtrl) is in conjunction with a list control; see Using CListCtrl later in
this topic family. You can also use a header control by itself. MFC calls InitCommonControls for you. The key tasks
are as follows:
Creating the header control
Adding items to the header control
Ordering items in the header control
Processing header-control notifications
If the header control object is embedded in a parent view or dialog class, the control is destroyed when the parent
is destroyed.

See also
Using CHeaderCtrl
Controls
Creating the Header Control
9/11/2019 • 2 minutes to read • Edit Online

The header control is not directly available in the dialog editor (although you can add a list control, which includes
a header control).
To put a header control in a dialog box
1. Manually embed a member variable of type CHeaderCtrl in your dialog class.
2. In OnInitDialog, create and set the styles for the CHeaderCtrl , position it, and display it.
3. Add items to the header control.
4. Use the Class Wizard to map handler functions in the dialog class for any header-control notification
messages you need to handle (see Mapping Messages to Functions).
To put a header control in a view (not a CListView)
1. Embed a CHeaderCtrl object in your view class.
2. Style, position, and display the header control window in the view's OnInitialUpdate member function.
3. Add items to the header control.
4. Use the Class Wizard to map handler functions in the view class for any header-control notification
messages you need to handle (see Mapping Messages to Functions).
In either case, the embedded control object is created when the view or dialog object is created. Then you must call
CHeaderCtrl::Create to create the control window. To position the control, call CHeaderCtrl::Layout to determine the
control's initial size and position and SetWindowPos to set the position you want. Then add items as described in
Adding Items to the Header Control.
For more information, see Creating a Header Control in the Windows SDK.

See also
Using CHeaderCtrl
Controls
Adding Items to the Header Control
9/6/2019 • 2 minutes to read • Edit Online

After creating your header control (CHeaderCtrl) in its parent window, add as many "header items" as you need:
usually one per column.
To add a header item
1. Prepare an HD_ITEM structure.
2. Call CHeaderCtrl::InsertItem, passing the structure.
3. Repeat steps 1 and 2 for additional items.
For more information, see Adding an Item to a Header Control in the Windows SDK.

See also
Using CHeaderCtrl
Controls
Ordering Items in the Header Control
3/4/2019 • 2 minutes to read • Edit Online

Once you've added items to a header control, you can manipulate or get information about their order with the
following functions:
CHeaderCtrl::GetOrderArray and CHeaderCtrl::SetOrderArray
Retrieves and sets the left-to-right order of header items.
CHeaderCtrl::OrderToIndex.
Retrieves the index value for a specific header item.
In addition to the previous member functions, the HDS_DRAGDROP style allows the user to drag and drop header
items within the header control. For more information, see Providing Drag-and-Drop Support for Header Items.

See also
Using CHeaderCtrl
Processing Header-Control Notifications
9/11/2019 • 2 minutes to read • Edit Online

In your view or dialog class, use the Class Wizard to create an OnChildNotify handler function with a switch
statement for any header-control (CHeaderCtrl) notification messages you want to handle (see Mapping Messages
to Functions). Notifications are sent to the parent window when the user clicks or double-clicks a header item,
drags a divider between items, and so on.
The notification messages associated with a header control are listed in Header Control Reference in the Windows
SDK.

See also
Using CHeaderCtrl
Controls
Using CHotKeyCtrl
3/16/2020 • 2 minutes to read • Edit Online

A hot key control, represented by class CHotKeyCtrl, is a window that displays a text representation of the key
combination the user types into it, such as CTRL+SHIFT+Q. It also maintains an internal representation of this key
in the form of a virtual key code and a set of flags that represent the shift state. The hot key control does not
actually set the hot key — doing that is up to your program. (For a list of standard virtual key codes, see
Winuser.h.)
Use a hot key control to get a user's input for which hot key to associate with a window or thread. Hot key controls
are often used in dialog boxes, such as you might display when asking the user to assign a hot key. It is your
program's responsibility to retrieve the values describing the hot key from the hot key control and to call the
appropriate functions to associate the hot key with a window or thread.

What do you want to know more about


Using a Hot Key Control
Setting a Hot Key
Global Hot Keys
Thread-Specific Hot Keys

See also
Controls
Using a Hot Key Control
3/4/2019 • 2 minutes to read • Edit Online

Typical usage of a hot key control follows the pattern below:


The control is created. If the control is specified in a dialog box template, creation is automatic when the
dialog box is created. (You should have a CHotKeyCtrl member in your dialog class that corresponds to the
hot key control.) Alternatively, you can use the Create member function to create the control as a child
window of any window.
If you want to set a default value for the control, call the SetHotKey member function. If you want to prohibit
certain shift states, call SetRules. For controls in a dialog box, a good time to do this is in the dialog box's
OnInitDialog function.
The user interacts with the control by pressing a hot key combination when the hot key control has focus.
The user then somehow indicates that this task is complete, perhaps by clicking a button in the dialog box.
When your program is notified that the user has selected a hot key, it should use the member function
GetHotKey to retrieve the virtual key and shift state values from the hot key control.
Once you know what key the user selected, you can set the hot key using one of the methods described in
Setting a Hot Key.
If the hot key control is in a dialog box, it and the CHotKeyCtrl object will be destroyed automatically. If not,
you need to ensure that both the control and the CHotKeyCtrl object are properly destroyed.

See also
Using CHotKeyCtrl
Controls
Setting a Hot Key
8/15/2019 • 2 minutes to read • Edit Online

Your application can use the information provided by a hot key (CHotKeyCtrl) control in one of two ways:
Set up a global hot key for activating a nonchild window by sending a WM_SETHOTKEY message to the
window to be activated.
Set up a thread-specific hot key by calling the Windows function RegisterHotKey.

See also
Using CHotKeyCtrl
Controls
Global Hot Keys
8/15/2019 • 2 minutes to read • Edit Online

A global hot key is associated with a particular nonchild window. It allows the user to activate the window from any
part of the system. An application sets a global hot key for a particular window by sending the WM_SETHOTKEY
message to that window. For instance, if m_HotKeyCtrl is the CHotKeyCtrl object and pMainWnd is a pointer to the
window to be activated when the hot key is pressed, you could use the following code to associate the hot key
specified in the control with the window pointed to by pMainWnd .

WORD wKeyAndShift = static_cast<WORD>(m_HotKeyCtrl.GetHotKey());


this->SendMessage(WM_SETHOTKEY, wKeyAndShift);

Whenever the user presses a global hot key, the window specified receives a WM_SYSCOMMAND message that
specifies SC_HOTKEY as the type of the command. This message also activates the window that receives it.
Because this message does not include any information on the exact key that was pressed, using this method does
not allow distinguishing between different hot keys that may be attached to the same window. The hot key remains
valid until the application that sent WM_SETHOTKEY exits.

See also
Using CHotKeyCtrl
Controls
Thread-Specific Hot Keys
8/15/2019 • 2 minutes to read • Edit Online

An application sets a thread-specific hot key (CHotKeyCtrl) by using the Windows RegisterHotKey function. When
the user presses a thread-specific hot key, Windows posts a WM_HOTKEY message to the beginning of a particular
thread's message queue. The WM_HOTKEY message contains the virtual key code, shift state, and user-defined ID
of the specific hot key that was pressed. For a list of standard virtual key codes, see Winuser.h. For more
information on this method, see RegisterHotKey.
Note that the shift state flags used in the call to RegisterHotKey are not the same as those returned by the
GetHotKey member function; you'll have to translate these flags before calling RegisterHotKey .

See also
Using CHotKeyCtrl
Controls
Using CImageList
3/16/2020 • 2 minutes to read • Edit Online

An image list, represented by class CImageList, is a collection of same-sized images, each of which can be referred
to by its index. Image lists are used to efficiently manage large sets of icons or bitmaps. Image lists are not
themselves controls since they are not windows; however, they are used with several different types of controls,
including list controls (CListCtrl), tree controls (CTreeCtrl), and tab controls (CTabCtrl).
All images in an image list are contained in a single, wide bitmap in screen-device format. An image list may also
include a monochrome bitmap that contains masks used to draw images transparently (icon style). CImageList
provides member functions that enable you to draw images, create and destroy image lists, add and remove
images, replace images, merge images, and drag images.

What do you want to know more about


Types of Image Lists
Using an Image List
Manipulating Image Lists
Drawing Images from an Image List
Image Overlays in Image Lists
Dragging Images from an Image List
Image Information in Image Lists

See also
Controls
Types of Image Lists
3/4/2019 • 2 minutes to read • Edit Online

There are two types of image lists (CImageList): nonmasked and masked. A "nonmasked image list" consists of a
color bitmap that contains one or more images. A "masked image list" consists of two bitmaps of equal size. The
first is a color bitmap that contains the images, and the second is a monochrome bitmap that contains a series of
masks — one for each image in the first bitmap.
One of the overloads of the Create member function takes a flag to indicate whether or not the image list is
masked. (The other overloads create masked image lists.)
When a nonmasked image is drawn, it is simply copied into the target device context; that is, it is drawn over the
existing background color of the device context. When a masked image is drawn, the bits of the image are
combined with the bits of the mask, typically producing transparent areas in the bitmap where the background
color of the target device context shows through. You can specify several drawing styles when drawing a masked
image. For example, you can specify that the image be dithered to indicate a selected object.

See also
Using CImageList
Controls
Using an Image List
3/27/2020 • 2 minutes to read • Edit Online

Typical usage of an image list follows the pattern below:


Construct a CImageList object and call one of the overloads of its Create function to create an image list and
attach it to the CImageList object.
If you didn't add images when you created the image list, add images to the image list by calling the Add or
Read member function.
Associate the image list with a control by calling the appropriate member function of that control, or draw
images from the image list yourself using the image list's Draw member function.
Perhaps allow the user to drag an image, using the image list's built-in support for dragging.

NOTE
If the image list was created with the new operator, you must destroy the CImageList object when you are done with it.

See also
Using CImageList
Controls
Manipulating Image Lists
3/4/2019 • 2 minutes to read • Edit Online

The Replace member function replaces an image in an image list (CImageList) with a new image. This function is
also useful if you need to dynamically increase the number of images in an image list object. The SetImageCount
function dynamically changes the number of images stored in the image list. If you increase the size of the image
list, call Replace to add images to the new image slots. If you decrease the size of the image list, the images
beyond the new size are freed.
The Remove member function removes an image from an image list. The Copy member function can copy or swap
images within an image list. This function allows you to indicate whether the source image should be copied to the
destination index or the source and destination images should be swapped.
To create a new image list by merging two image lists, use the appropriate overload of the Create member
function. This overload of Create merges the first image of the existing image lists, storing the resultant image in a
new image list object. The new image is created by drawing the second image transparently over the first. The
mask for the new image is the result of performing a logical-OR operation on the bits of the masks for the two
existing images.
This is repeated until all images are merged and added to the new image list object.
You can write the image information to an archive by calling the Write member function, and read it back by calling
the Read member function.
The GetSafeHandle, Attach, and Detach member functions allow you to manipulate the handle of the image list
attached to the CImageList object, while the DeleteImageList member function deletes the image list without
destroying the CImageList object.

See also
Using CImageList
Controls
Drawing Images from an Image List
8/15/2019 • 2 minutes to read • Edit Online

To draw an image, use the CImageList::Draw member function. You'll specify a pointer to a device context object,
the index of the image to draw, the location in the device context at which to draw the image, and a set of flags to
indicate the drawing style.
When you specify the ILD_TRANSPARENT style, Draw uses a two-step process to draw a masked image. First, it
performs a logical-AND operation on the bits of the image and the bits of the mask. Then it performs a logical-XOR
operation on the results of the first operation and the background bits of the destination device context. This
process creates transparent areas in the resulting image; that is, each white bit in the mask causes the
corresponding bit in the resulting image to be transparent.
Before drawing a masked image on a solid color background, you should use the SetBkColor member function to
set the background color of the image list to the same color as the destination. Setting the color eliminates the
need to create transparent areas in the image and enables Draw to simply copy the image to the destination
device context, resulting in a significant increase in performance. To draw the image, specify the ILD_NORMAL
style when you call Draw .
You can set the background color for a masked image list (CImageList) at any time so that it draws correctly on any
solid background. Setting the background color to CLR_NONE causes images to be drawn transparently by
default. To retrieve the background color of an image list, use the GetBkColor member function.
The ILD_BLEND25 and ILD_BLEND50 styles dither the image with the system highlight color. These styles are
useful if you use a masked image to represent an object that the user can select. For example, you can use the
ILD_BLEND50 style to draw the image when the user selects it.
A nonmasked image is copied to the destination device context using the SRCCOPY raster operation. The colors in
the image appear the same regardless of the background color of the device context. The drawing styles specified
in Draw also have no effect on the appearance of a nonmasked image.
In addition to the Draw member function, another function, DrawIndirect, extends the ability to render an image.
DrawIndirect takes, as a parameter, an IMAGELISTDRAWPARAMS structure. This structure can be used to
customize the rendering of the current image, including the use of raster operation (ROP) codes. For more
information on ROP codes, see Raster Operation Codes and Bitmaps as Brushes in the Windows SDK.

See also
Using CImageList
Controls
Image Overlays in Image Lists
8/15/2019 • 2 minutes to read • Edit Online

Every image list (CImageList) includes a list of images to use as overlay masks. An "overlay mask" is an image
drawn transparently over another image. Any image can be used as an overlay mask. You can specify up to four
overlay masks per image list.
You add the index of an image to the list of overlay masks by using the SetOverlayImage member function, the
index of an image, and the index of an overlay mask. Note that the indices for the overlay masks are one-based
rather than zero-based.
You draw an overlay mask over an image using a single call to Draw . The parameters include the index of the
image to draw and the index of an overlay mask. You must use the INDEXTOOVERLAYMASK macro to specify the
index of the overlay mask. You can also specify an overlay image when calling the DrawIndirect member function.

See also
Using CImageList
Controls
Dragging Images from an Image List
8/15/2019 • 2 minutes to read • Edit Online

CImageList includes functions for dragging an image on the screen. The dragging functions move an image
smoothly, in color, and without any flashing of the cursor. Both masked and unmasked images can be dragged.
The BeginDrag member function begins a drag operation. The parameters include the index of the image to drag
and the location of the hot spot within the image. The hot spot is a single pixel that the dragging functions
recognize as the exact screen location of the image. Typically, an application sets the hot spot so that it coincides
with the hot spot of the mouse cursor. The DragMove member function moves the image to a new location.
The DragEnter member function sets the initial position of the drag image within a window and draws the image at
the position. The parameters include a pointer to the window in which to draw the image and a point that specifies
the coordinates of the initial position within the window. The coordinates are relative to the window's upper-left
corner, not the client area. The same is true for all of the image-dragging functions that take coordinates as
parameters. This means you must compensate for the widths of window elements, such as the border, title bar, and
menu bar, when specifying the coordinates. If you specify a NULL window handle when calling DragEnter , the
dragging functions draw the image in the device context associated with the desktop window, and the coordinates
are relative to the upper-left corner of the screen.
DragEnter locks all other updates to the given window during the drag operation. If you need to do any drawing
during a drag operation, such as highlighting the target of a drag-and-drop operation, you can temporarily hide
the dragged image by using the DragLeave member function. You can also use the DragShowNoLock member
function.
Call EndDrag when you're done dragging the image.
The SetDragCursorImage member function creates a new drag image by combining the given image (typically a
mouse cursor image) with the current drag image. Because the dragging functions use the new image during a
drag operation, you should use the Windows ShowCursor function to hide the actual mouse cursor after calling
SetDragCursorImage . Otherwise, the system may appear to have two mouse cursors for the duration of the drag
operation.
When an application calls BeginDrag , the system creates a temporary, internal image list and copies the specified
drag image to the internal list. You can retrieve a pointer to the temporary drag image list by using the
GetDragImage member function. The function also retrieves the current drag position and the offset of the drag
image relative to the drag position.

See also
Using CImageList
Controls
Image Information in Image Lists
3/4/2019 • 2 minutes to read • Edit Online

CImageList includes a number of functions that retrieve information from an image list. The GetImageInfo member
function fills an IMAGEINFO structure with information about a single image, including the handles of the image and
mask bitmaps, the number of color planes and bits per pixel, and the bounding rectangle of the image within the
image bitmap. You can use this information to directly manipulate the bitmaps for the image.
The GetImageCount member function retrieves the number of images in an image list.
You can create an icon based on an image and mask in an image list by using the ExtractIcon member function. The
function returns the handle of the new icon.

See also
Using CImageList
Controls
Using CListCtrl
3/27/2020 • 2 minutes to read • Edit Online

Use a list control to display any arrangement of icons with labels, as in File Explorer, or columnar lists of text, with
or without icons. For a description of the four possible "views" (not to be confused with MFC views) you can have
in a list control — icon view, small icon view, list view, and report view — see Views in the CListCtrl class
overview.
In some views, users can drag icons to different positions or edit icon labels. For example, see the right-hand
pane in File Explorer, which uses a list control in a nondialog window. You can experiment with the available
views in Explorer's View menu.
For related information, see About List-View Controls in the Windows SDK.

NOTE
The Windows SDK refers to list controls as "list view controls." This usage of "view" does not refer to MFC view classes,
particularly CListView . For more information, see List Control and List View.

What do you want to know more about


List Control and List View
List Items and Image Lists
Callback Items and the Callback Mask
Creating the List Control
Creating the Image Lists
Adding Columns to the Control (Report View)
Adding Items to the Control
Scrolling, Arranging, Sorting, and Finding in List Controls
Implementing Working Areas in List Controls
Processing Notification Messages in List Controls
Changing List Control Styles
Virtual List Controls
Destroying the List Control

See also
Controls
List Control and List View
3/4/2019 • 2 minutes to read • Edit Online

For convenience, MFC encapsulates the list control in two ways. You can use list controls:
Directly, by embedding a CListCtrl object in a dialog class.
Indirectly, by using class CListView.
CListView makes it easy to integrate a list control with the MFC document/view architecture, encapsulating the
control much as CEditView encapsulates an edit control: the control fills the entire surface area of an MFC view.
(The view is the control, cast to CListView .)
A CListView object inherits from CCtrlView and its base classes and adds a member function to retrieve the
underlying list control. Use view members to work with the view as a view. Use the GetListCtrl member function to
gain access to the list control's member functions. Use these members to:
Add, delete, or manipulate "items" in the list.
Set or get list control attributes.
To obtain a reference to the CListCtrl underlying a CListView , call GetListCtrl from your list view class:

CListCtrl& listCtrl = GetListCtrl();

This topic describes both ways to use the list control.

See also
Using CListCtrl
Controls
List Items and Image Lists
3/27/2020 • 2 minutes to read • Edit Online

An "item" in a list control (CListCtrl) consists of an icon, a label, and possibly other information (in "subitems").
The icons for list control items are contained in image lists. One image list contains full-sized icons used in icon
view. A second, optional, image list contains smaller versions of the same icons for use in other views of the
control. A third optional list contains "state" images, such as check boxes, for display in front of the small icons in
certain views. A fourth optional list contains images that are displayed in individual header items of the list control.

NOTE
If a list view control is created with the LVS_SHAREIMAGELISTS style, you are responsible for destroying the image lists when
they are no longer in use. Specify this style if you assign the same image lists to multiple list view controls; otherwise, more
than one control might try to destroy the same image list.

For more information about list items, see List View Image Lists and Items and Subitems in the Windows SDK. Also
see class CImageList in the MFC Reference and Using CImageList in this family of articles.
To create a list control, you need to supply image lists to be used when you insert new items into the list. The
following example demonstrates this procedure, where m_pImagelist is a pointer of type CImageList and m_listctrl
is a CListCtrl data member.

m_ListImageList.Create(16, 16, ILC_COLOR, 2, 2);


m_ListImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_ListImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_ListCtrl.SetImageList(&m_ListImageList, LVSIL_SMALL);

However, if you don't plan to display icons in your list view or list control, you don't need image lists.

See also
Using CListCtrl
Controls
Callback Items and the Callback Mask
8/15/2019 • 2 minutes to read • Edit Online

For each of its items, a list view control typically stores the label text, the image list index of the item's icons, and a
set of bit flags for the item's state. You can define individual items as callback items, which are useful if your
application already stores some of the information for an item.
You define an item as a callback item by specifying appropriate values for the pszText and iImage members of
the LVITEM structure (see CListCtrl::GetItem). If the application maintains the item's or subitem's text, specify the
LPSTR_TEXTCALLBACK value for the pszText member. If the application keeps track of the icon for the item,
specify the I_IMAGECALLBACK value for the iImage member.
In addition to defining callback items, you can also modify the control's callback mask. This mask is a set of bit
flags that specify the item states for which the application, rather than the control, stores the current data. The
callback mask applies to all of the control's items, unlike the callback item designation, which applies to a specific
item. The callback mask is zero by default, meaning that the control tracks all item states. To change this default
behavior, initialize the mask to any combination of the following values:
LVIS_CUT The item is marked for a cut-and-paste operation.
LVIS_DROPHILITED The item is highlighted as a drag-and-drop target.
LVIS_FOCUSED The item has the focus.
LVIS_SELECTED The item is selected.
LVIS_OVERL AYMASK The application stores the image list index of the current overlay image for each
item.
LVIS_STATEIMAGEMASK The application stores the image list index of the current state image for each
item.
For further information on retrieving and setting this mask, see CListCtrl::GetCallbackMask and
CListCtrl::SetCallbackMask.

See also
Using CListCtrl
Controls
Creating the List Control
9/11/2019 • 2 minutes to read • Edit Online

How the list control (CListCtrl) is created depends on whether you're using the control directly or using class
CListView instead. If you use CListView , the framework constructs the view as part of its document/view creation
sequence. Creating the list view creates the list control as well (the two are the same thing). The control is created in
the view's OnCreate handler function. In this case, the control is ready for you to add items, via a call to GetListCtrl.
To use CListCtrl directly in a dialog box
1. In the dialog editor, add a List Control to your dialog template resource. Specify its control ID.
2. Use the Add Member Variable Wizard to add a member variable of type CListCtrl with the Control
property. You can use this member to call CListCtrl member functions.
3. Use the Class Wizard to map handler functions in the dialog class for any list control notification messages
you need to handle (see Mapping Messages to Functions).
4. In OnInitDialog, set the styles for the CListCtrl . See Changing List Control Styles. This determines the kind
of "view" you get in the control, although you can change the view later.
To use CListCtrl in a nondialog window
1. Define the control in the view or window class.
2. Call the control's Create member function, possibly in OnInitialUpdate, possibly as early as the parent
window's OnCreate handler function (if you're subclassing the control). Set the styles for the control.

See also
Using CListCtrl
Controls
Creating the Image Lists
3/27/2020 • 2 minutes to read • Edit Online

Creating image lists is the same whether you use CListView or CListCtrl.

NOTE
You only need image lists if your list control includes the LVS_ICON style.

Use class CImageList to create one or more image lists (for full-size icons, small icons, and states). See CImageList,
and see List View Image Lists in the Windows SDK.
Call CListCtrl::SetImageList for each image list; pass a pointer to the appropriate CImageList object.

See also
Using CListCtrl
Controls
Adding Columns to the Control (Report View)
3/27/2020 • 2 minutes to read • Edit Online

NOTE
The following procedure applies to either a CListView or CListCtrl object.

When a list control is in report view, columns are displayed, providing a method of organizing the various
subitems of each list control item. This organization is implemented with a one-to-one correspondence between a
column in the list control and the associated subitem of the list control item. For more information on subitems,
see Adding Items to the Control. An example of a list control in report view is provided by the Details view in
Windows 95 and Windows 98 Explorer. The first column lists folder, file icons, and labels. Other columns list file
size, file type, date last modified, and so on.
Even though columns can be added to a list control at any time, the columns are visible only when the control has
the LVS_REPORT style bit turned on.
Each column has an associated header item (see CHeaderCtrl) object that labels the column and allows users to
resize the column.
If your list control supports a report view, you need to add a column for each possible subitem in a list control
item. Add a column by preparing an LVCOLUMN structure and then making a call to InsertColumn. After adding
the necessary columns (sometimes referred to as header items), you can reorder them using member functions
and styles belonging to the embedded header control. For more information, see Ordering Items in the Header
Control.

NOTE
If the list control is created with the LVS_NOCOLUMNHEADER style, any attempt to insert columns will be ignored.

See also
Using CListCtrl
Controls
Adding Items to the Control
8/15/2019 • 2 minutes to read • Edit Online

To add items to the list control (CListCtrl), call one of several versions of the InsertItem member function,
depending on what information you have. One version takes a LVITEM structure that you prepare. Because the
LVITEM structure contains numerous members, you have greater control over the attributes of the list control
item.
Two important members (in regard to the report view) of the LVITEM structure are the iItem and iSubItem
members. The iItem member is the zero-based index of the item the structure is referencing and the iSubItem
member is the one-based index of a subitem, or zero if the structure contains information about an item. With
these two members you determine, per item, the type and value of subitem information that is displayed when the
list control is in report view. For more information, see CListCtrl::SetItem.
Additional members specify the item's text, icon, state, and item data. "Item data" is an application-defined value
associated with a list view item. For more information about the LVITEM structure, see CListCtrl::GetItem.
Other versions of InsertItem take one or more separate values, corresponding to members in the LVITEM
structure, allowing you to initialize only those members you want to support. Generally, the list control manages
storage for list items, but you can store some of the information in your application instead, using "callback items."
For more information, see Callback Items and the Callback Mask in this topic and Callback Items and the Callback
Mask in the Windows SDK.
For more information, see Adding List-View Items and Subitems.

See also
Using CListCtrl
Controls
Scrolling, Arranging, Sorting, and Finding in List
Controls
8/15/2019 • 2 minutes to read • Edit Online

List controls (CListCtrl) are scrollable by default. For more information, see Scroll Position in the Windows SDK and
the Scroll member function.
You can call CListCtrl member functions to arrange list items in the control, sort items, and find particular items.
For more information, see Using ListView Controls in the Windows SDK and the CListCtrl members Arrange,
SortItems, and FindItem.

See also
Using CListCtrl
Controls
Implementing Working Areas in List Controls
3/27/2020 • 3 minutes to read • Edit Online

By default, a list control arranges all items in a standard grid fashion. However, another method is supported,
working areas, that arranges the list items into rectangular groups. For an image of a list control that implements
working areas, see Using List-View Controls in the Windows SDK.

NOTE
Working areas are visible only when the list control is in icon or small icon mode. However, any current working areas are
maintained if the view is switched to the report or list mode.

Working areas can be used to display an empty border (on the left, top and/or right of the items), or cause a
horizontal scroll bar to be displayed when there normally wouldn't be one. Another common usage is to create
multiple working areas to which items can be moved or dropped. With this method, you could create areas in a
single view that have different meanings. The user could then categorize the items by placing them in a different
area. An example of this would be a view of a file system that has an area for read/write files and another area for
read-only files. If a file item were moved into the read-only area, it would automatically become read-only. Moving
a file from the read-only area into the read/write area would make the file read/write.
CListCtrl provides several member functions for creating and managing working areas in your list control.
GetWorkAreas and SetWorkAreas retrieve and set an array of CRect objects (or RECT structures), which store the
currently implemented working areas for your list control. In addition, GetNumberOfWorkAreas retrieves the
current number of working areas for your list control (by default, zero).

Items and Working Areas


When a working area is created, items that lie within the working area become members of it. Similarly, if an item
is moved into a working area, it becomes a member of the working area to which it was moved. If an item does not
lie within any working area, it automatically becomes a member of the first (index 0) working area. If you want to
create an item and have it placed within a specific working area, you will need to create the item and then move it
into the desired working area with a call to SetItemPosition. The second example below demonstrates this
technique.
The following example implements four working areas ( rcWorkAreas ), of equal size with a 10-pixel-wide border
around each working area, in a list control ( m_WorkAreaListCtrl ).

CSize size;
size = m_WorkAreaListCtrl.ApproximateViewRect();
size.cx += 100;
size.cy += 100;

CRect rcWorkAreas[4];
rcWorkAreas[0].SetRect(0, 0, (size.cx / 2) - 5, (size.cy / 2) - 5);
rcWorkAreas[1].SetRect((size.cx / 2) + 5, 0, size.cx, (size.cy / 2) - 5);
rcWorkAreas[2].SetRect(0, (size.cy / 2) + 5, (size.cx / 2) - 5, size.cy);
rcWorkAreas[3].SetRect((size.cx / 2) + 5, (size.cy / 2) + 5, size.cx, size.cy);

//set work areas


m_WorkAreaListCtrl.SetWorkAreas(4, rcWorkAreas);

The call to ApproximateViewRect was made to get an estimate of the total area required to display all items in one
region. This estimate is then divided into four regions and padded with a 5-pixel-wide border.
The next example assigns the existing list items to each group ( rcWorkAreas ) and refreshes the control view (
m_WorkAreaListCtrl ) to complete the effect.

// set insertion points for each work area


CPoint rgptWork[4];
for (int i = 0; i < 4; i++)
{
rgptWork[i].x = rcWorkAreas[i].left + 10;
rgptWork[i].y = rcWorkAreas[i].top + 10;
}
// now move all the items to the different quadrants
for (int i = 0; i < 20; i++)
{
m_WorkAreaListCtrl.SetItemPosition(i, rgptWork[i % 4]);
}

// force the control to rearrange the shuffled items


m_WorkAreaListCtrl.Arrange(LVA_DEFAULT);

See also
Using CListCtrl
Controls
Processing Notification Messages in List Controls
9/11/2019 • 2 minutes to read • Edit Online

As users click column headers, drag icons, edit labels, and so on, the list control (CListCtrl) sends notification
messages to its parent window. Handle these messages if you want to do something in response. For example,
when the user clicks a column header, you might want to sort the items based on the contents of the clicked
column, as in Microsoft Outlook.
Process WM_NOTIFY messages from the list control in your view or dialog class. Use the Class Wizard to create an
OnChildNotify handler function with a switch statement based on which notification message is being handled.
For a list of the notifications a list control can send to its parent window, see List View Control Reference in the
Windows SDK.

See also
Using CListCtrl
Controls
Changing List Control Styles
3/27/2020 • 2 minutes to read • Edit Online

You can change the window style of a list control (CListCtrl) at any time after you create it. By changing the
window style, you change the kind of view the control uses. For example, to emulate the Explorer, you might
supply menu items or toolbar buttons for switching the control between different views: icon view, list view, and so
on.
For example, when the user selects your menu item, you could make a call to GetWindowLong to retrieve the
current style of the control and then call SetWindowLong to reset the style. For more information, see Using List
View Controls in the Windows SDK.
Available styles are listed in Create. The styles LVS_ICON , LVS_SMALLICON , LVS_LIST , and LVS_REPORT
designate the four list control views.

Extended Styles
In addition to the standard styles for a list control, there is another set, referred to as extended styles. These styles,
discussed in Extended List View Styles in the Windows SDK, provide a variety of useful features that customize the
behavior of your list control. To implement the behavior of a certain style (such as hover selection), make a call to
CListCtrl::SetExtendedStyle, passing the needed style. The following example demonstrates the function call:

m_ListCtrl.SetExtendedStyle(LVS_EX_TRACKSELECT | LVS_EX_ONECLICKACTIVATE);

NOTE
For hover selection to work, you must also have either LVS_EX_ONECLICKACTIVATE or LVS_EX_TWOCLICKACTIVATE
turned on.

See also
Using CListCtrl
Controls
Virtual List Controls
3/27/2020 • 3 minutes to read • Edit Online

A virtual list control is a list view control that has the LVS_OWNERDATA style. This style enables the control to
support an item count up to a DWORD (the default item count only extends to an int ). However, the biggest
advantage provided by this style is the ability to only have a subset of data items in memory at any one time. This
allows the virtual list view control to lend itself for use with large databases of information, where specific methods
of accessing data are already in place.

NOTE
In addition to providing virtual list functionality in CListCtrl , MFC also provides the same functionality in the CListView
class.

There are some compatibility issues you should be aware of when developing virtual list controls. For more
information, see the Compatibility Issues section of the List-View Controls topic in the Windows SDK.

Handling the LVN_GETDISPINFO Notification


Virtual list controls maintain very little item information. Except for the item selection and focus information, all
item information is managed by the owner of the control. Information is requested by the framework via a
LVN_GETDISPINFO notification message. To provide the requested information, the owner of the virtual list control
(or the control itself) must handle this notification. This can easily be done using the Class Wizard (see Mapping
Messages to Functions). The resultant code should look something like the following example (where CMyDialog
owns the virtual list control object and the dialog is handling the notification):

ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST3, &CMyDialog::OnLvnGetdispinfoList3)

In the handler for the LVN_GETDISPINFO notification message, you must check to see what type of information is
being requested. The possible values are:
LVIF_TEXT The pszText member must be filled in.
LVIF_IMAGE The iImage member must be filled in.
LVIF_INDENT The iIndent member must be filled in.
LVIF_PARAM The lParam member must be filled in. (Not present for sub-items.)
LVIF_STATE The state member must be filled in.
You should then supply whatever information is requested back to the framework.
The following example (taken from the body of the notification handler for the list control object) demonstrates
one possible method by supplying information for the text buffers and image of an item:
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO *>(pNMHDR);
LVITEM *pItem = &(pDispInfo)->item;

int iItem = pItem->iItem;

if (pItem->mask & LVIF_TEXT) //valid text buffer?


{
switch (pItem->iSubItem)
{
case 0: //fill in main text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strItemText);
break;
case 1: //fill in sub item 1 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem1Text);
break;
case 2: //fill in sub item 2 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem2Text);
break;
}
}

if (pItem->mask & LVIF_IMAGE) //valid image?


{
pItem->iImage = m_Items[iItem].m_iImage;
}

Caching and Virtual List Controls


Because this type of list control is intended for large data sets, it is recommended that you cache requested item
data to improve retrieval performance. The framework provides a cache-hinting mechanism to assist in optimizing
the cache by sending an LVN_ODCACHEHINT notification message.
The following example updates the cache with the range passed to the handler function.

void CMyDialog::OnLvnOdcachehintList3(NMHDR* pNMHDR, LRESULT* pResult)


{
LPNMLVCACHEHINT pCacheHint = reinterpret_cast<LPNMLVCACHEHINT>(pNMHDR);

// Update the cache with the recommended range.


for (int i = pCacheHint->iFrom; i <= pCacheHint->iTo; i++)
{
m_Items[i].m_iImage = i % 2;
m_Items[i].m_strItemText.Format(_T("Item %d"), i);
m_Items[i].m_strSubItem1Text = _T("Sub 1");
m_Items[i].m_strSubItem2Text = _T("Sub 2");
}

*pResult = 0;
}

For more information on preparing and maintaining a cache, see the Cache Management section of the List-View
Controls topic in the Windows SDK.

Finding Specific Items


The LVN_ODFINDITEM notification message is sent by the virtual list control when a particular list control item
needs to be found. The notification message is sent when the list view control receives quick key access or when it
receives an LVM_FINDITEM message. Search information is sent in the form of an LVFINDINFO structure, which is
a member of the NMLVFINDITEM structure. Handle this message by overriding the OnChildNotify function of
your list control object and inside the body of the handler, check for the LVN_ODFINDITEM message. If found,
perform the appropriate action.
You should be prepared to search for an item that matches the information given by the list view control. You
should return the index of the item if successful, or -1 if no matching item is found.

See also
Using CListCtrl
Controls
Destroying the List Control
8/15/2019 • 2 minutes to read • Edit Online

If you embed your CListCtrl object as a data member of a view or dialog class, it is destroyed when its owner is
destroyed. If you use a CListView, the framework destroys the control when it destroys the view.
If you arrange for some of your list data to be stored in the application rather than the list control, you will need to
arrange for its deallocation. For more information, see Callback Items and the Callback Mask in the Windows SDK.
In addition, you are responsible for deallocating any image lists you created and associated with the list control
object.

See also
Using CListCtrl
Controls
Using CMonthCalCtrl
3/27/2020 • 2 minutes to read • Edit Online

The month calendar control (CMonthCalCtrl) implements a calendar-like user interface. This provides the user with
a very intuitive and recognizable method of entering or selecting a date. The control also provides the application
with the means to obtain and set the date information in the control using existing data types. By default, the
month calendar control displays the current day and month. However, the user is able to scroll to the previous and
next months and select a specific month and/or year.

NOTE
To use the CMonthCalCtrl class in your project, you must include AFXDTCTL.H, usually in stdafx.h.

What do you want to know more about


Creating the Month Calendar Control
Month Calendar Control Examples
Processing Notification Messages in Month Calendar Controls
Setting the Day State of a Month Calendar Control

See also
Controls
Creating the Month Calendar Control
9/11/2019 • 2 minutes to read • Edit Online

How the month calendar control is created depends on whether you are using the control in a dialog box or
creating it in a nondialog window.
To use CMonthCalCtrl directly in a dialog box
1. In the dialog editor, add a Month Calendar Control to your dialog template resource. Specify its control ID.
2. Specify any styles required, using the Properties dialog box of the month calendar control.
3. Use the Add Member Variable Wizard to add a member variable of type CMonthCalCtrl with the Control
property. You can use this member to call CMonthCalCtrl member functions.
4. Use the Class Wizard to map handler functions in the dialog class for any month calendar control
notification messages you need to handle (see Mapping Messages to Functions).
5. In OnInitDialog, set any additional styles for the CMonthCalCtrl object.
To use CMonthCalCtrl in a nondialog window
1. Define the control in the view or window class.
2. Call the control's Create member function, possibly in OnInitialUpdate, possibly as early as the parent
window's OnCreate handler function (if you're subclassing the control). Set the styles for the control.

See also
Using CMonthCalCtrl
Controls
Month Calendar Control Examples
4/1/2019 • 2 minutes to read • Edit Online

The CMNCTRL1 sample application demonstrates the various attributes of the CMonthCalCtrl class. The control,
found on a separate tab in the sample, demonstrates basic functionality and allows the user to dynamically modify
certain attributes.

See also
Using CMonthCalCtrl
Controls
Processing Notification Messages in Month Calendar
Controls
9/11/2019 • 2 minutes to read • Edit Online

As users interact with the month calendar control (selecting dates and/or viewing a different month), the control (
CMonthCalCtrl ) sends notification messages to its parent window, usually a view or dialog object. Handle these
messages if you want to do something in response. For example, when the user selects a new month to view, you
could provide a set of dates that should be emphasized.
Use the Class Wizard to add notification handlers to the parent class for those messages you want to implement.
The following list describes the various notifications sent by the month calendar control.
MCN_GETDAYSTATE Requests information about which days should be displayed in bold. For information on
handling this notification, see Setting the Day State of a Month Calendar Control.
MCN_SELCHANGE Notifies the parent that the selected date or range of the date has changed.
MCN_SELECT Notifies the parent that an explicit date selection has been made.

See also
Using CMonthCalCtrl
Controls
Setting the Day State of a Month Calendar Control
3/27/2020 • 2 minutes to read • Edit Online

One of the attributes of a month calendar control is the ability to store information, referred to as the day state of
the control, for each day of the month. This information is used to emphasize certain dates for the month currently
displayed.

NOTE
The CMonthCalCtrl object must have the MCS_DAYSTATE style to display day state information.

Day state information is expressed as a 32-bit data type, MONTHDAYSTATE . Each bit in a MONTHDAYSTATE bit
field (1 through 31) represents the state of a day in a month. If a bit is on, the corresponding day will be displayed
in bold; otherwise it will be displayed with no emphasis.
There are two methods for setting the day state of the month calendar control: explicitly with a call to
CMonthCalCtrl::SetDayState or by handling the MCN_GETDAYSTATE notification message.

Handling the MCN_GETDAYSTATE Notification Message


The MCN_GETDAYSTATE message is sent by the control to determine how the days within the visible months
should be displayed.

NOTE
Because the control caches the previous and following months, in respect to the visible month, you will receive this
notification every time a new month is chosen.

To properly handle this message, you must determine how many months day state information is being requested
for, initialize an array of MONTHDAYSTATE structures with the proper values, and initialize the related structure
member with the new information. The following procedure, detailing the necessary steps, assumes that you have
a CMonthCalCtrl object called m_monthcal and an array of MONTHDAYSTATE objects, mdState.
To handle the MCN_GETDAYSTATE notification message
1. Using the Class Wizard, add a notification handler for the MCN_GETDAYSTATE message to the m_monthcal
object (see Mapping Messages to Functions).
2. In the body of the handler, add the following code:

LPNMDAYSTATE pDayState = reinterpret_cast<LPNMDAYSTATE>(pNMHDR);

int iMax = pDayState->cDayState;

for (int i = 0; i < iMax; i++)


{
pDayState->prgDayState[i] = (MONTHDAYSTATE)0; // init to 0
pDayState->prgDayState[i] |= 0x01 << 14; // set 15th bit to 1
}

The example converts the pNMHDR pointer to the proper type, then determines how many months of
information are being requested ( pDayState->cDayState ). For each month, the current bitfield (
pDayState->prgDayState[i] ) is initialized to zero and then the needed dates are set (in this case, the 15th of
each month).

See also
Using CMonthCalCtrl
Controls
Using CProgressCtrl
3/16/2020 • 2 minutes to read • Edit Online

You can use the progress control to indicate the progress of a lengthy operation. It is a rectangle that is gradually
filled with the system highlight color as the operation progresses.
The progress control is represented in MFC by class CProgressCtrl.
When you initially create the progress control, you specify its size and position, parent window (usually a dialog
box), and ID. By using the dwStyle parameter, you can also specify various window styles for the control and styles
for how it fills.

What do you want to know more about


Styles for the Progress Control
Settings for the Progress Control
Manipulating the Progress Control

See also
Controls
Styles for the Progress Control
3/4/2019 • 2 minutes to read • Edit Online

When you initially create the progress control (CProgressCtrl::Create), use the dwStyle parameter to specify the
desired window styles for your progress control. The following list details the applicable window styles. The control
ignores any window style other than the ones listed here. You should always create the control as a child window,
usually of a dialog box parent.

W IN DO W ST Y L E EF F EC T

WS_BORDER Creates a border around the window.

WS_CHILD Creates a child window (should always be used for


CProgressCtrl ).

WS_CLIPCHILDREN Excludes the area occupied by child windows when you draw
within the parent window. Used when you create the parent
window.

WS_CLIPSIBLINGS Clips child windows relative to each other.

WS_DISABLED Creates a window that is initially disabled.

WS_VISIBLE Creates a window that is initially visible.

WS_TABSTOP Specifies that the control can receive focus when the user
presses the TAB key to move to it.

In addition, you can specify two styles that apply only to the progress control, PBS_VERTICAL and PBS_SMOOTH.
Use PBS_VERTICAL to orient the control vertically, rather than horizontally. Use PBS_SMOOTH to fill the control
completely, rather than displaying small delineated squares that fill the control incrementally.
Without PBS_SMOOTH style:

With PBS_SMOOTH and PBS_VERTICAL styles:

For more information, see Window Styles in the MFC Reference.


See also
Using CProgressCtrl
Settings for the Progress Control
3/4/2019 • 2 minutes to read • Edit Online

The basic settings for the progress control (CProgressCtrl) are the range and current position. The range represents
the entire duration of the operation. The current position represents the progress that your application has made
toward completing the operation. Any changes to the range or position cause the progress control to redraw itself.
By default, the range is set to 0 - 100, and the initial position is set to 0. To retrieve the current range settings for the
progress control, use the GetRange member function. To change the range, use the SetRange member function.
To set the position, use SetPos. To retrieve the current position without specifying a new value, use GetPos. For
example, you might want to simply query on the status of the current operation.
To step the current position of the progress control, use StepIt. To set the amount of each step, use SetStep

See also
Using CProgressCtrl
Controls
Manipulating the Progress Control
3/4/2019 • 2 minutes to read • Edit Online

There are three ways to change the current position of a progress control (CProgressCtrl).
The position can be changed by a preset increment amount.
The position can be changed by an arbitrary amount.
The position can be changed to a specific value.
To change the position by a preset amount
1. Use the SetStep member function to set the increment amount. By default, this value is 10. This value is
typically set as one of the initial settings for the control. The step value can be negative.
2. Use the StepIt member function to increment the position. This causes the control to redraw itself.

NOTE
StepIt will cause the position to wrap. For example, given a range of 1 -100, a step of 20, and a position of 90,
StepIt will set the position to 10.

To change the position by an arbitrary amount


1. Use the OffsetPos member function to change the position. OffsetPos will accept negative values.

NOTE
OffsetPos , unlike StepIt , will not wrap the position. The new position is adjusted to remain within the range.

To change the position to a specific value


1. Use the SetPos member function to set the position to a specific value. If necessary, the new position is adjusted
to be within the range.
Typically, the progress control is used solely for output. To get the current position without specifying a new value,
use GetPos.

See also
Using CProgressCtrl
Controls
Using CReBarCtrl
3/16/2020 • 2 minutes to read • Edit Online

A rebar control acts as a container for child windows. These child windows, often other controls, are assigned to a
rebar control band. A rebar control can contain one or more bands, with each band having any combination of a
gripper bar, a bitmap, a text label, and a child window. However, bands cannot contain more than one child
window.
The following illustration shows a rebar control that has two bands. One contains a gripper bar, a text label
("Address"), and a combo box child window. The other band contains a gripper bar, a text label, and a flat toolbar
(implemented with a child window).

What do you want to know more about


CReBar vs. CReBarCtrl
Creating a Rebar Control
Rebar Controls and Bands
Using an Image List with a Rebar Control
Using a Dialog Bar with a Rebar Control
Processing Notification Messages in a Rebar Control

See also
Controls
CReBar vs. CReBarCtrl
3/16/2020 • 2 minutes to read • Edit Online

MFC provides two classes to create rebars: CReBar and CReBarCtrl (which wraps the Windows common control
API). CReBar provides all of the functionality of the rebar common control, and it handles many of the required
common control settings and structures for you.
CReBarCtrl is a wrapper class for the Win32 rebar control, and therefore may be easier to implement if you do not
intend to integrate the rebar into the MFC architecture. If you plan to use CReBarCtrl and integrate the rebar into
the MFC architecture, you must take additional care to communicate rebar control manipulations to MFC. This
communication is not difficult; however, it is additional work that is unneeded when you use CReBar .
Visual C++ provides two ways to take advantage of the rebar common control.
Create the rebar using CReBar , and then call CReBar::GetReBarCtrl to get access to the CReBarCtrl member
functions.

NOTE
CReBar::GetReBarCtrl is an inline member function that casts the this pointer of the rebar object. This means that,
at run time, the function call has no overhead.

Create the rebar using CReBarCtrl's constructor.


Either method will give you access to the member functions of the rebar control. When you call
CReBar::GetReBarCtrl , it returns a reference to a CReBarCtrl object so you can use either set of member functions.
See CReBar for information on constructing and creating a rebar using CReBar .

See also
Using CReBarCtrl
Controls
Creating a Rebar Control
3/4/2019 • 2 minutes to read • Edit Online

CReBarCtrl objects should be created before the parent object is visible. This minimizes the possibilities of painting
problems.
For instance, rebar controls (used in frame window objects) are commonly used as parent windows for toolbar
controls. Therefore, the parent of the rebar control is the frame window object. Because the frame window object is
the parent, the OnCreate member function (of the parent) is an excellent place to create the rebar control.
To use a CReBarCtrl object, you will typically follow these steps:
To use a CReBarCtrl object
1. Construct the CReBarCtrl object.
2. Call Create to create the Windows rebar common control and attach it to the CReBarCtrl object, specifying
any desired styles.
3. Load a bitmap, with a call to CBitmap::LoadBitmap, to be used as the background of the rebar control object.
4. Create and initialize any child window objects (toolbars, dialog controls, and so on) that will be contained by
the rebar control object.
5. Initialize a REBARBANDINFO structure with the necessary information for the band about to be inserted.
6. Call InsertBand to insert existing child windows (such as m_wndReToolBar ) into the new rebar control. For
more information on inserting bands into an existing rebar control, see Rebar Controls and Bands.

See also
Using CReBarCtrl
Controls
Rebar Controls and Bands
3/4/2019 • 2 minutes to read • Edit Online

The main purpose of a rebar control is to act as a container for child windows, common dialog controls, menus,
toolbars, and so on. This containment is supported by the concept of a "band." Each rebar band can contain any
combination of a gripper bar, a bitmap, a text label, and a child window.
Class CReBarCtrl has many member functions that you can use to retrieve, and manipulate, information for a
specific rebar band:
GetBandCount Retrieves the number of current bands in the rebar control.
GetBandInfo Initializes a REBARBANDINFO structure with information from the specified band. There is a
corresponding SetBandInfo member function.
GetRect Retrieves the bounding rectangle of a specified band.
GetRowCount Retrieves the number of band rows in a rebar control.
IDToIndex Retrieves the index of a specified band.
GetBandBorders Retrieves the borders of a band.
In addition to manipulation, several member functions are provided that allow you to operate on specific rebar
bands.
InsertBand and DeleteBand add and remove rebar bands. MinimizeBand and MaximizeBand affect the current size
of a specific rebar band. MoveBand changes the index of a specific rebar band. ShowBand shows or hides a rebar
band from the user.
The following example demonstrates adding a toolbar band (m_wndToolBar) to an existing rebar control
(m_wndReBar). The band is described by initializing the rbi structure and then calling the InsertBand member
function:

//load bitmap for toolbar background


m_RebarBitmap.LoadBitmap(IDB_BITMAP1);

//create a toolbar band


m_Toolbar1.Create(this, TBSTYLE_TRANSPARENT | TBSTYLE_FLAT);
m_Toolbar1.LoadToolBar(IDR_MAINFRAME);

REBARBANDINFO rbi = { 0 };
rbi.cbSize = sizeof(REBARBANDINFO);
rbi.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE |
RBBIM_STYLE | RBBIM_TEXT;
rbi.fStyle = RBBS_GRIPPERALWAYS;
rbi.cxMinChild = 300;
rbi.cyMinChild = 50;
rbi.lpText = _T("Band #1");
rbi.cch = 7;
rbi.cx = 300;
rbi.hbmBack = (HBITMAP)m_RebarBitmap;
rbi.hwndChild = (HWND)m_Toolbar1;
m_Rebar.GetReBarCtrl().InsertBand(0, &rbi);

See also
Using CReBarCtrl
Controls
Using an Image List with a Rebar Control
3/4/2019 • 2 minutes to read • Edit Online

Each rebar band can contain, among other things, an image from an associated image list. The following procedure
details the necessary steps for displaying an image in a rebar band.
To display images in a rebar band
1. Attach an image list to your rebar control object by making a call to SetImageList, passing a pointer to an
existing image list.
2. Modify the REBARBANDINFO structure to assign an image to a rebar band:
Set the fMask member to RBBIM_IMAGE , using the bitwise OR operator to include additional flags as
necessary.
Set the iImage member to the image list index of the image to be displayed.
3. Initialize any remaining data members, such as the size, text, and handle of the contained child window, with
the necessary information.
4. Insert the new band (with the image) with a call to CReBarCtrl::InsertBand, passing the REBARBANDINFO
structure.
The following example assumes that an existing image list object with two images was attached to the rebar
control object ( m_wndReBar ). A new rebar band (defined by rbi ), containing the first image, is added with a call to
InsertBand :

REBARBANDINFO rbi = {0};


rbi.cbSize = sizeof(REBARBANDINFO);
rbi.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_IMAGE |
RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_TEXT;
rbi.fStyle = RBBS_GRIPPERALWAYS;
rbi.cxMinChild = 200;
rbi.cyMinChild = 50;
rbi.lpText = _T("Band #2");
rbi.cch = 7;
rbi.cx = 300;
rbi.hbmBack = (HBITMAP)m_RebarBitmap;
rbi.iImage = 0;
rbi.hwndChild = (HWND)m_Toolbar2;
m_Rebar.GetReBarCtrl().InsertBand(1, &rbi);

See also
Using CReBarCtrl
Controls
Using a Dialog Bar with a Rebar Control
12/17/2019 • 2 minutes to read • Edit Online

As mentioned in Rebar Controls and Bands, each band can contain only one child window (or control). This might
be a limitation if you want to have more than one child window per band. A convenient workaround is to create a
dialog bar resource with multiple controls and then add a rebar band (containing the dialog bar) to the rebar
control.
Normally, if you wanted the dialog bar band to appear transparent, you would set the WS_EX_TRANSPARENT
extended style for the dialog bar object. However, because WS_EX_TRANSPARENT has some issues with properly
painting the background of a dialog bar, you will need to do a little extra work to achieve the desired effect.
The following procedure details the steps necessary to achieve transparency without using the
WS_EX_TRANSPARENT extended style.
To implement a transparent dialog bar in a rebar band
1. Using the Add Class dialog box, add a new class (for example, CMyDlgBar ) that implements your dialog bar
object.
2. Add a handler for the WM_ERASEBKGND message.
3. In the new handler, modify the existing code to match the following example:

BOOL CMyDlgBar::OnEraseBkgnd(CDC *pDC)


{
CWnd *pParent = GetParent();
ASSERT_VALID(pParent);
CPoint pt(0, 0);
MapWindowPoints(pParent, &pt, 1);
pt = pDC->OffsetWindowOrg(pt.x, pt.y);
LRESULT lResult = pParent->SendMessage(WM_ERASEBKGND,
(WPARAM)pDC->m_hDC, 0L);
pDC->SetWindowOrg(pt.x, pt.y);
return (BOOL)lResult;
}

4. Add a handler for the WM_MOVE message.


5. In the new handler, modify the existing code to match the following example:

void CMyDlgBar::OnMove(int x, int y)


{
UNREFERENCED_PARAMETER(x);
UNREFERENCED_PARAMETER(y);

Invalidate();
}

The new handlers simulate the transparency of the dialog bar by forwarding the WM_ERASEBKGND message to
the parent window and forcing a repaint every time the dialog bar object is moved.

See also
Using CReBarCtrl
Controls
Processing Notification Messages in a Rebar Control
8/15/2019 • 2 minutes to read • Edit Online

In the parent class of the rebar control, create an OnChildNotify handler function with a switch statement for any
rebar-control ( CReBarCtrl ) notification messages you want to handle. Notifications are sent to the parent window
when the user drags objects over the rebar control, changes the layout of the rebar bands, deletes bands from the
rebar control, and so on.
The following notification messages can be sent by the rebar control object:
RBN_AUTOSIZE Sent by a rebar control (created with the RBS_AUTOSIZE style) when the rebar automatically
resizes itself.
RBN_BEGINDRAG Sent by a rebar control when the user begins dragging a band.
RBN_CHILDSIZE Sent by a rebar control when a band's child window is resized.
RBN_DELETEDBAND Sent by a rebar control after a band has been deleted.
RBN_DELETINGBAND Sent by a rebar control when a band is about to be deleted.
RBN_ENDDRAG Sent by a rebar control when the user stops dragging a band.
RBN_GETOBJECT Sent by a rebar control (created with the RBS_REGISTERDROP style) when an object is
dragged over a band in the control.
RBN_HEIGHTCHANGE Sent by a rebar control when its height has changed.
RBN_LAYOUTCHANGED Sent by a rebar control when the user changes the layout of the control's bands.
For more information on these notifications, see Rebar Control Reference in the Windows SDK.

See also
Using CReBarCtrl
Controls
Using CRichEditCtrl
3/16/2020 • 2 minutes to read • Edit Online

A rich edit control is a window in which the user can enter and edit text. The text can be assigned character and
paragraph formatting, and can include embedded OLE objects. The rich edit control is represented in MFC by the
CRichEditCtrl class.

What do you want to know more about


Overview of the Rich Edit Control
Classes Related to Rich Edit Controls
Rich Edit Control Examples
Character Formatting in Rich Edit Controls
Paragraph Formatting in Rich Edit Controls
Current Selection in a Rich Edit Control
Word Breaks in a Rich Edit Control
Clipboard Operations in Rich Edit Controls
Stream Operations in Rich Edit Controls
Printing in Rich Edit Controls
Bottomless Rich Edit Controls
Notifications from a Rich Edit Control

See also
Controls
Overview of the Rich Edit Control
3/27/2020 • 2 minutes to read • Edit Online

IMPORTANT
If you are using a rich edit control in a dialog box (regardless of whether your application is SDI, MDI, or dialog-based), you
must call AfxInitRichEdit once before the dialog box is displayed. A typical place to call this function is in your program's
InitInstance member function. You do not need to call it for each time you display the dialog box, only the first time. You
do not have to call AfxInitRichEdit if you are working with CRichEditView .

Rich edit controls (CRichEditCtrl) provide a programming interface for formatting text. However, an application
must implement any user interface components necessary to make formatting operations available to the user.
That is, the rich edit control supports changing the character or paragraph attributes of the selected text. Some
examples of character attributes are bold, italics, font family, and point size. Examples of paragraph attributes
include alignment, margins, and tab stops. However, it is up to you to provide the user interface, whether that is
toolbar buttons, menu items, or a format character dialog box. There are also functions to query the rich edit
control for the attributes of the current selection. Use these functions to display the current settings for the
attributes, for example, setting a check mark on the command UI if the selection has the bold character formatting
attribute.
For more information on character and paragraph formatting, see Character Formatting and Paragraph Formatting
later in this topic.
Rich edit controls support almost all of the operations and notification messages used with multiline edit controls.
Thus, applications that already use edit controls can be easily changed to use rich edit controls. Additional
messages and notifications enable applications to access the functionality unique to rich edit controls. For
information about edit controls, see CEdit.
For more information on notifications, see Notifications from a Rich Edit Control later in this topic.

See also
Using CRichEditCtrl
Controls
Classes Related to Rich Edit Controls
3/4/2019 • 2 minutes to read • Edit Online

The CRichEditView, CRichEditDoc, and CRichEditCntrItem classes provide the functionality of the rich edit control
(CRichEditCtrl) within the context of MFC's document/view architecture. CRichEditView maintains the text and
formatting characteristic of text. CRichEditDoc maintains the list of OLE client items that are in the view.
CRichEditCntrItem provides container-side access to the OLE client item. To modify the contents of a
CRichEditView , use CRichEditView::GetRichEditCtrl to access the underlying rich edit control.

See also
Using CRichEditCtrl
Controls
Rich Edit Control Examples
3/4/2019 • 2 minutes to read • Edit Online

The MFC OLE sample WORDPAD uses the CRichEditView , CRichEditDoc , and CRichEditCntrItem classes. By
extension, it uses the CRichEditCtrl. For a quick description of these three classes, see Classes Related to Rich Edit
Controls.

See also
Using CRichEditCtrl
Controls
Character Formatting in Rich Edit Controls
9/6/2019 • 2 minutes to read • Edit Online

You can use member functions of the rich edit control (CRichEditCtrl) to format characters and to retrieve
formatting information. For characters, you can specify typeface, size, color, and effects such as bold, italic, and
protected.
You can apply character formatting by using the SetSelectionCharFormat and SetWordCharFormat member
functions. To determine the current character formatting for the selected text, use the GetSelectionCharFormat
member function. The CHARFORMAT structure is used with these member functions to specify character
attributes. One of the important members of CHARFORMAT is dwMask . In SetSelectionCharFormat and
SetWordCharFormat , dwMask specifies which character attributes will be set by this function call.
GetSelectionCharFormat reports the attributes of the first character in the selection; dwMask specifies the
attributes that are consistent throughout the selection.
You can also get and set the "default character formatting," which is the formatting applied to any subsequently
inserted characters. For example, if an application sets the default character formatting to bold and the user then
types a character, that character is bold. To get and set default character formatting, use the GetDefaultCharFormat
and SetDefaultCharFormat member functions.
The "protected" character attribute does not change the appearance of text. If the user attempts to modify
protected text, a rich edit control sends its parent window an EN_PROTECTED notification message, allowing the
parent window to allow or prevent the change. To receive this notification message, you must enable it by using
the SetEventMask member function. For more information about the event mask, see Notifications from a Rich
Edit Control, later in this topic.
Foreground color is a character attribute, but background color is a property of the rich edit control. To set the
background color, use the SetBackgroundColor member function.

See also
Using CRichEditCtrl
Controls
Paragraph Formatting in Rich Edit Controls
8/15/2019 • 2 minutes to read • Edit Online

You can use member functions of the rich edit control (CRichEditCtrl) to format paragraphs and to retrieve
formatting information. Paragraph formatting attributes include alignment, tabs, indents, and numbering.
You can apply paragraph formatting by using the SetParaFormat member function. To determine the current
paragraph formatting for the selected text, use the GetParaFormat member function. The PARAFORMAT structure is
used with these member functions to specify paragraph attributes. One of the important members of
PARAFORMAT is dwMask. In SetParaFormat , dwMask specifies which paragraph attributes will be set by this
function call. GetParaFormat reports the attributes of the first paragraph in the selection; dwMask specifies the
attributes that are consistent throughout the selection.

See also
Using CRichEditCtrl
Controls
Current Selection in a Rich Edit Control
8/15/2019 • 2 minutes to read • Edit Online

The user can select text in a rich edit control (CRichEditCtrl) by using the mouse or the keyboard. The current
selection is the range of selected characters, or the position of the insertion point if no characters are selected. An
application can get information about the current selection, set the current selection, determine when the current
selection changes, and show or hide the selection highlight.
To determine the current selection in a rich edit control, use the GetSel member function. To set the current
selection, use the SetSel member function. The CHARRANGE structure is used with these functions to specify a
range of characters. To retrieve information about the contents of the current selection, you can use the
GetSelectionType member function.
By default, a rich edit control shows and hides the selection highlight when it gains and loses the focus. You can
show or hide the selection highlight at any time by using the HideSelection member function. For example, an
application might provide a Search dialog box to find text in a rich edit control. The application might select
matching text without closing the dialog box, in which case it must use HideSelection to highlight the selection.
To get the selected text in a rich edit control, use the GetSelText member function. The text is copied to the specified
character array. You must ensure that the array is large enough to hold the selected text plus a terminating null
character.
You can search for a string in a rich edit control by using the FindText member function The FINDTEXTEX structure
used with this function specifies the text range to search and the string to search for. You can also specify such
options as whether the search is case-sensitive.

See also
Using CRichEditCtrl
Controls
Word Breaks in Rich Edit Controls
3/4/2019 • 2 minutes to read • Edit Online

A rich edit control (CRichEditCtrl) calls a function called a "word break procedure" to find breaks between words
and to determine where it can break lines. The control uses this information when performing word-wrap
operations and when processing the CTRL+LEFT and CTRL+RIGHT key combinations. An application can send
messages to a rich edit control to replace the default word-break procedure, to retrieve word-break information,
and to determine what line a given character falls on.

See also
Using CRichEditCtrl
Controls
Clipboard Operations in Rich Edit Controls
8/15/2019 • 2 minutes to read • Edit Online

Your application can paste the contents of the Clipboard into a rich edit control (CRichEditCtrl) using either the best
available Clipboard format or a specific Clipboard format. You can also determine whether a rich edit control is
capable of pasting a Clipboard format.
You can copy or cut the contents of the current selection by using the Copy or Cut member function. Similarly, you
can paste the contents of the Clipboard into a rich edit control by using the Paste member function. The control
pastes the first available format that it recognizes, which presumably is the most descriptive format.
To paste a specific Clipboard format, you can use the PasteSpecial member function. This function is useful for
applications with a Paste Special command that enables the user to select the Clipboard format. You can use the
CanPaste member function to determine whether a given format is recognized by the control.
You can also use CanPaste to determine whether any available Clipboard format is recognized by a rich edit
control. This function is useful in the OnInitMenuPopup handler. An application might enable or gray its Paste
command depending on whether the control can paste any available format.
Rich edit controls register two Clipboard formats: rich-text format and a format called RichEdit Text and Objects. An
application can register these formats by using the RegisterClipboardFormat function, specifying the CF_RTF and
CF_RETEXTOBJ values.

See also
Using CRichEditCtrl
Controls
Stream Operations in Rich Edit Controls
8/15/2019 • 2 minutes to read • Edit Online

You can use streams to transfer data into or out of a rich edit control (CRichEditCtrl). A stream is defined by an
EDITSTREAM structure, which specifies a buffer and an application-defined callback function.
To read data into a rich edit control (that is, stream the data in), use the StreamIn member function. The control
repeatedly calls the application-defined callback function, which transfers a portion of the data into the buffer each
time.
To save the contents of a rich edit control (that is, stream the data out), you can use the StreamOut member
function. The control repeatedly writes to the buffer and then calls the application-defined callback function. For
each call, the callback function saves the contents of the buffer.

See also
Using CRichEditCtrl
Controls
Printing in Rich Edit Controls
8/15/2019 • 2 minutes to read • Edit Online

You can tell a rich edit control (CRichEditCtrl) to render its output for a specified device, such as a printer. You can
also specify the output device for which a rich edit control formats its text.
To format part of the contents of a rich edit control for a specific device, you can use the FormatRange member
function. The FORMATRANGE structure used with this function specifies the range of text to format as well as the
device context (DC) for the target device.
After formatting text for an output device, you can send the output to the device by using the DisplayBand member
function. By repeatedly using FormatRange and DisplayBand , an application that prints the contents of a rich edit
control can implement banding. (Banding is division of output into smaller parts for printing purposes.)
You can use the SetTargetDevice member function to specify the target device for which a rich edit control formats
its text. This function is useful for WYSIWYG (what you see is what you get) formatting, in which an application
positions text using the default printer's font metrics instead of the screen's.

See also
Using CRichEditCtrl
Controls
Bottomless Rich Edit Controls
8/15/2019 • 2 minutes to read • Edit Online

Your application can resize a rich edit control (CRichEditCtrl) as needed so that it is always the same size as its
contents. A rich edit control supports this so-called "bottomless" functionality by sending its parent window an
EN_REQUESTRESIZE notification message whenever the size of its contents changes.
When processing the EN_REQUESTRESIZE notification message, an application should resize the control to the
dimensions in the specified REQRESIZE structure. An application might also move any information near the control
to accommodate the control's change in height. To resize the control, you can use the CWnd function
SetWindowPos.
You can force a bottomless rich edit control to send an EN_REQUESTRESIZE notification message by using the
RequestResize member function. This message can be useful in the OnSize handler.
To receive EN_REQUESTRESIZE notification messages, you must enable the notification by using the
SetEventMask member function.

See also
Using CRichEditCtrl
Controls
Notifications from a Rich Edit Control
8/15/2019 • 2 minutes to read • Edit Online

Notification messages report events affecting a rich edit control (CRichEditCtrl). They can be processed by the
parent window or, using message reflection, by the rich edit control itself. Rich edit controls support all of the
notification messages used with edit controls as well as several additional ones. You can determine which
notification messages a rich edit control sends its parent window by setting its "event mask."
To set the event mask for a rich edit control, use the SetEventMask member function. You can retrieve the current
event mask for a rich edit control by using the GetEventMask member function.
The following paragraphs list several specific notifications and their uses:
EN_MSGFILTER Handling the EN_MSGFILTER notification lets a class, either the rich edit control or its parent
window, filter all keyboard and mouse input to the control. The handler can prevent the keyboard or mouse
message from being processed or can change the message by modifying the specified MSGFILTER
structure.
EN_PROTECTED Handle the EN_PROTECTED notification message to detect when the user attempts to
modify protected text. To mark a range of text as protected, you can set the protected character effect. For
more information, see Character Formatting in Rich Edit Controls.
EN_DROPFILES You can enable the user to drop files in a rich edit control by processing the EN_DROPFILES
notification message. The specified ENDROPFILES structure contains information about the files being
dropped.
EN_SELCHANGE An application can detect when the current selection changes by processing the
EN_SELCHANGE notification message. The notification message specifies a SELCHANGE structure
containing information about the new selection.

See also
Using CRichEditCtrl
Controls
Using CSliderCtrl
3/16/2020 • 2 minutes to read • Edit Online

The CSliderCtrl class represents a slider control, which is also called a trackbar. A "slider control" is a window that
contains a slider and optional tick marks. When the user moves the slider, using either the mouse or the arrow
keys, the slider control sends notification messages to indicate the change.
Slider controls are useful when you want the user to select a discrete value or a set of consecutive values in a
range. For example, you might use a slider control to allow the user to set the repeat rate of the keyboard by
moving the slider to a given tick mark.
The slider in a slider control moves in increments that you specify when you create it. For example, if you specify
that the slider control should have a range of five, the slider can only occupy six positions: a position at the left
side of the slider control and one position for each increment in the range. Typically, each of these positions is
identified by a tick mark.

What do you want to know more about


Using Slider Controls
Slider Control Styles
Slider Control Member Functions
Slider Notification Messages

See also
Controls
Using Slider Controls
3/4/2019 • 2 minutes to read • Edit Online

Typical usage of an slider control follows the pattern below:


The control is created. If the control is specified in a dialog box template, creation is automatic when the
dialog box is created. (You should have a CSliderCtrl member in your dialog class that corresponds to the
slider control.) Alternatively, you can use the Create member function to create the control as a child window
of any window.
Call the various Set member functions to set values for the control. Changes that you can make include
setting the minimum and maximum positions for the slider, drawing tick marks, setting a selection range,
and repositioning the slider. For controls in a dialog box, a good time to do this is in the dialog's
OnInitDialog function.
As the user interacts with the control, it will send various notification messages. You can extract the slider
value from the control by calling the GetPos member function.
When you're done with the control, you need to make sure it's properly destroyed. If the slider control is in a
dialog box, it and the CSliderCtrl object will be destroyed automatically. If not, you need to ensure that
both the control and the CSliderCtrl object are properly destroyed.

See also
Using CSliderCtrl
Controls
Slider Control Styles
3/4/2019 • 2 minutes to read • Edit Online

Slider controls (CSliderCtrl) can have either a vertical or horizontal orientation. They can have tick marks on either
side, both sides, or neither. They can also be used to specify a range of consecutive values. These properties are
controlled by using slider control styles, which you specify when you create the slider control.
The TBS_HORZ and TBS_VERT styles determine the orientation of the slider control. If you do not specify an
orientation, the slider control is oriented horizontally.
The TBS_AUTOTICKS style creates a slider control that has a tick mark for each increment in its range of values.
These tick marks are added automatically when you call the SetRange member function. If you do not specify
TBS_AUTOTICKS, you can use member functions, such as SetTic and SetTicFreq, to specify the positions of the tick
marks. To create a slider control that does not display tick marks, you can use the TBS_NOTICKS style.
You can display tick marks on either or both sides of the slider control. For horizontal slider controls, you can
specify the TBS_BOTTOM or TBS_TOP style. For vertical slider controls, you can specify the TBS_RIGHT or TBS_LEFT
style. (TBS_BOTTOM and TBS_RIGHT are the default settings.) For tick marks on both sides of the slider control in
any orientation, specify the TBS_BOTH style.
A slider control can display a selection range only if you specify the TBS_ENABLESELRANGE style when you create
it. When a slider control has this style, the tick marks at the starting and ending positions of a selection range are
displayed as triangles (instead of vertical dashes) and the selection range is highlighted. For example, selection
ranges might be useful in a simple scheduling application. The user could select a range of tick marks
corresponding to hours in a day to identify a scheduled meeting time.
By default, the length of a slider control's slider varies as the selection range changes. If the slider control has the
TBS_FIXEDLENGTH style, the length of the slider remains the same even if the selection range changes. A slider
control that has the TBS_NOTHUMB style does not include a slider.

See also
Using CSliderCtrl
Controls
Slider Control Member Functions
3/4/2019 • 2 minutes to read • Edit Online

An application can call the slider control's member functions to retrieve information about the slider control
(CSliderCtrl) and to change its characteristics.
To retrieve the position of the slider (that is, the value the user has chosen), use the GetPos member function. To set
the position of the slider, use the SetPos member function. At any time you can use the VerifyPos member
function to make sure that the slider is between the minimum and maximum values.
The range of a slider control is the set of contiguous values that the slider control can represent. Most applications
use the SetRange member function to set the range of a slider control when it is first created. Applications can
dynamically alter the range after the slider control has been created by using the SetRangeMax and SetRangeMin
member functions. An application that allows the range to be changed dynamically typically retrieves the final
range settings when the user has finished working with the slider control. To retrieve these settings, use the
GetRange, GetRangeMax, and GetRangeMin member functions.
An application can use the TBS_AUTOTICKS style to have a slider control's tick marks displayed automatically. If an
application needs to control the position or frequency of the tick marks, however, a number of member functions
can be used.
To set the position of a tick mark, an application can use the SetTic member function. The SetTicFreq member
function allows an application to set tick marks that appear at regular intervals in the slider control's range. For
example, the application can use this member function to display only 10 tick marks in a range of 1 through 100.
To retrieve the index in the range corresponding to a tick mark, use the GetTic member function. The GetTicArray
member function retrieves an array of these indices. To retrieve the position of a tick mark, in client coordinates,
use the GetTicPos member function. An application can retrieve the number of tick marks by using the GetNumTics
member function.
The ClearTics member function removes all of a slider control's tick marks.
A slider control's line size determines how far the slider moves when an application receives a TB_LINEDOWN or
TB_LINEUP notification message. Similarly, the page size determines the response to the TB_PAGEDOWN and
TB_PAGEUP notification messages. Applications can retrieve and set the line and page size values by using the
GetLineSize, SetLineSize, GetPageSize, and SetPageSize member functions.
An application can use member functions to retrieve the dimensions of a slider control. The GetThumbRect
member function retrieves the bounding rectangle for the slider. The GetChannelRect member function retrieves
the bounding rectangle for the slider control's channel. (The channel is the area over which the slider moves and
which contains the highlight when a range is selected.)
If a slider control has the TBS_ENABLESELRANGE style, the user can select a range of contiguous values from it. A
number of member functions allow the selection range to be adjusted dynamically. The SetSelection member
function sets the starting and ending positions of a selection. When the user has finished setting a selection range,
an application can retrieve the settings by using the GetSelection member function. To clear a user's selection, use
the ClearSel member function.

See also
Using CSliderCtrl
Controls
Slider Notification Messages
3/4/2019 • 2 minutes to read • Edit Online

A slider control notifies its parent window of user actions by sending the parent WM_HSCROLL or WM_VSCROLL
messages, depending on the orientation of the slider control. To handle these messages, add handlers for the
WM_HSCROLL and WM_VSCROLL messages to the parent window. The OnHScroll and OnVScroll member
functions will be passed a notification code, the position of the slider, and a pointer to the CSliderCtrl object. Note
that the pointer is of type CScrollBar * even though it points to a CSliderCtrl object. You may need to typecast
this pointer if you need to manipulate the slider control.
Rather than using the scroll bar notification codes, slider controls send a different set of notification codes. A slider
control sends the TB_BOTTOM, TB_LINEDOWN, TB_LINEUP, and TB_TOP notification codes only when the user
interacts with a slider control by using the keyboard. The TB_THUMBPOSITION and TB_THUMBTRACK notification
messages are only sent when the user is using the mouse. The TB_ENDTRACK, TB_PAGEDOWN, and TB_PAGEUP
notification codes are sent in both cases.
The following table lists the slider control notification messages and the events (virtual key codes or mouse events)
that cause the notifications to be sent. (For a list of standard virtual key codes, see Winuser.h.)

N OT IF IC AT IO N M ESSA GE EVEN T C A USIN G N OT IF IC AT IO N TO B E SEN T

TB_BOTTOM VK_END

TB_ENDTRACK WM_KEYUP (the user released a key that sent a relevant


virtual key code)

TB_LINEDOWN VK_RIGHT or VK_DOWN

TB_LINEUP VK_LEFT or VK_UP

TB_PAGEDOWN VK_NEXT (the user clicked the channel below or to the right of
the slider)

TB_PAGEUP VK_PRIOR (the user clicked the channel above or to the left of
the slider)

TB_THUMBPOSITION WM_LBUTTONUP following a TB_THUMBTRACK notification


message

TB_THUMBTRACK Slider movement (the user dragged the slider)

TB_TOP VK_HOME

See also
Using CSliderCtrl
Controls
Using CSpinButtonCtrl
3/27/2020 • 2 minutes to read • Edit Online

The spin button control (also known as an up-down control) provides a pair of arrows that a user can click to
adjust a value. This value is known as the current position. The position stays within the range of the spin button.
When the user clicks the up arrow, the position moves toward the maximum; and when the user clicks the down
arrow, the position moves toward the minimum.
The spin button control is represented in MFC by the CSpinButtonCtrl class.

NOTE
By default, the range for the spin button has the maximum set to zero (0) and the minimum set to 100. Because the
maximum value is less than the minimum value, clicking the up arrow decreases the position and clicking the down arrow
increases it. Use CSpinButtonCtrl::SetRange to adjust these values.

Typically, the current position is displayed in a companion control. The companion control is known as the buddy
window . For an illustration of a spin button control, see About Up-Down Controls in the Windows SDK.
To create a spin control and an edit control buddy window, in Visual Studio, first drag an edit control to the dialog
box or window, and then drag a spin control. Select the spin control and set its Auto Buddy and Set Buddy
Integer properties to True . Also set the Alignment property; Right Align is most typical. With these settings, the
edit control is set as the buddy window because it directly precedes the edit control in the tab order. The edit
control displays integers and the spin control is embedded in the right side of the edit control. Optionally, you can
set the valid range of the spin control by using the CSpinButtonCtrl::SetRange method. No event handlers are
required to communicate between the spin control and buddy window because they exchange data directly. If you
use a spin control for some other purpose, for example, to page through a sequence of windows or dialog boxes,
then add a handler for the UDN_DELTAPOS message and perform your custom action there.

What do you want to know more about


Spin Button Styles
Spin Button Member Functions

See also
Controls
Spin Button Styles
9/11/2019 • 2 minutes to read • Edit Online

Many of the settings for a spin button (CSpinButtonCtrl) are controlled by styles. You can set the following styles
using the Class Wizard.
Orientation Either Vertical or Horizontal. Controls the orientation of the arrow buttons. Associated with the
UDS_HORZ style.
Alignment One of Unattached, Left, or Right. Controls the location of the spin button. Left and Right
position the spin button next to the buddy window. The width of the buddy window is decreased to
accommodate the spin button. Associated with the UDS_ALIGNLEFT and UDS_ALIGNRIGHT styles.
Auto Buddy Automatically selects the previous window in Z-order as buddy window to the spin button. In a
dialog template, this is the control which precedes the spin button in the tab order. Associated with the
UDS_AUTOBUDDY style.
Set Buddy Integer Causes the spin control to increment and decrement the caption of the buddy window
as the current position changes. Associated with the UDS_SETBUDDYINT style.
No Thousands Does not insert the thousands separator in the value in the caption of the buddy window.
Associated with the UDS_NOTHOUSANDS style.

NOTE
Set this style if you want to use dialog data exchange (DDX) to get the integer value from the buddy control.
DDX_Text does not accept embedded thousand separators.

Wrap Causes the position to "wrap" as the value is incremented or decremented beyond the range of the
control. Associated with the UDS_WRAP style.
Arrow Keys Causes the spin button to increment or decrement the position when the UP ARROW and
DOWN ARROW keys are pressed. Associated with the UDS_ARROWKEYS style.

See also
Using CSpinButtonCtrl
Controls
Spin Button Member Functions
3/4/2019 • 2 minutes to read • Edit Online

There are several member functions available for the spin control (CSpinButtonCtrl). Use these functions to change
the following attributes of the spin button.
Acceleration You can adjust the rate at which the position changes when the user holds down the arrow
button. To work with acceleration, use the SetAccel and GetAccel member functions.
Base You can change the base (either 10 or 16) used to display the position in the caption of the buddy
window. To work with the base, use the GetBase and SetBase member functions.
Buddy Window You can dynamically set the buddy window. To query or change which control is the buddy
window, use the GetBuddy and SetBuddy member functions.
Position You can query and change the position. To work directly with position, use the GetPos and SetPos
member functions. Since the caption of the buddy control may have changed (for example, in the case that
the buddy is an edit control), GetPos retrieves the current caption and adjusts the position accordingly.
Range You can change the maximum and minimum positions for the spin button. By default, the maximum
is set to 0, and the minimum is set to 100. Since the default maximum is less than the default minimum, the
actions of the arrow buttons is counter-intuitive. Typically, you will set the range using the SetRange
member function. To query the range use GetRange.

See also
Using CSpinButtonCtrl
Controls
Using CStatusBarCtrl
3/16/2020 • 2 minutes to read • Edit Online

You can use the status bar control (CStatusBarCtrl) to create a control window that reflects various kinds of status
information about the application. The status window can be divided into parts that display more than one type of
information.

What do you want to know more about


Methods of Creating a Status Bar
Settings for the CStatusBarCtrl
Using CStatusBarCtrl to Create a CStatusBarCtrl Object
Setting the Mode of a CStatusBarCtrl Object
Initializing the Parts of a CStatusBarCtrl Object
Using Tooltips in a CStatusBarCtrl Object

See also
Controls
Methods of Creating a Status Bar
3/4/2019 • 2 minutes to read • Edit Online

MFC provides two classes to create status bars: CStatusBar and CStatusBarCtrl (which wraps the Windows common
control API). CStatusBar provides all of the functionality of the status bar common control, it automatically
interacts with menus and toolbars, and it handles many of the required common control settings and structures for
you; however, your resulting executable usually will be larger than that created by using CStatusBarCtrl .
CStatusBarCtrl usually results in a smaller executable, and you may prefer to use CStatusBarCtrl if you do not
intend to integrate the status bar into the MFC architecture. If you plan to use CStatusBarCtrl and integrate the
status bar into the MFC architecture, you must take additional care to communicate status bar control
manipulations to MFC. This communication is not difficult; however, it is additional work that is unneeded when
you use CStatusBar .
Visual C++ provides two ways to take advantage of the status bar common control.
Create the status bar using CStatusBar , and then call CStatusBar::GetStatusBarCtrl to get access to the
CStatusBarCtrl member functions.

Create the status bar using CStatusBarCtrl's constructor.


Either method will give you access to the member functions of the status bar control. When you call
CStatusBar::GetStatusBarCtrl , it returns a reference to a CStatusBarCtrl object so you can use either set of
member functions. See CStatusBar for information on constructing and creating a status bar using CStatusBar .

See also
Using CStatusBarCtrl
Controls
Settings for the CStatusBarCtrl
3/27/2020 • 2 minutes to read • Edit Online

The default position of a CStatusBarCtrl status window is along the bottom of the parent window, but you can
specify the CCS_TOP style to have it appear at the top of the parent window's client area.
You can specify the SBARS_SIZEGRIP style to include a sizing grip at the right end of the CStatusBarCtrl status
window. A sizing grip is similar to a sizing border; it is a rectangular area that the user can click and drag to resize
the parent window.

NOTE
If you combine the CCS_TOP and SBARS_SIZEGRIP styles, the resulting sizing grip is not functional even though the system
draws it in the status window.

The window procedure for the status window automatically sets the initial size and position of the control window.
The width is the same as that of the parent window's client area. The height is based on the metrics of the font that
is currently selected into the status window's device context and on the width of the window's borders.
The window procedure automatically adjusts the size of the status window whenever it receives a WM_SIZE
message. Typically, when the size of the parent window changes, the parent sends a WM_SIZE message to the
status window.
You can set the minimum height of a status window's drawing area by calling SetMinHeight, specifying the
minimum height in pixels. The drawing area does not include the window's borders.
You retrieve the widths of the borders of a status window by calling GetBorders. This member function includes the
pointer to a three-element array that receives the width of the horizontal border, the vertical border, and the border
between rectangles.

See also
Using CStatusBarCtrl
Controls
Using CStatusBarCtrl to Create a CStatusBarCtrl
Object
3/16/2020 • 2 minutes to read • Edit Online

Here is an example of a typical use of CStatusBarCtrl:


To use a status bar control with parts
1. Construct the CStatusBarCtrl object.
2. Call SetMinHeight if you want to set the minimum height of the status bar control's drawing area.
3. Call SetBkColor to set the background color of the status bar control.
4. Call SetParts to set the number of parts in a status bar control and the coordinate of the right edge of each
part.
5. Call SetText to set the text in a given part of the status bar control. The message invalidates the portion of
the control that has changed, causing it to display the new text when the control next receives the
WM_PAINT message.
In some cases, the status bar only needs to display a line of text. In this case, make a call to SetSimple. This puts the
status bar control into "simple" mode, which displays a single line of text.

See also
Using CStatusBarCtrl
Controls
Setting the Mode of a CStatusBarCtrl Object
3/27/2020 • 2 minutes to read • Edit Online

There are two modes for a CStatusBarCtrl object: simple and nonsimple. In the majority of cases, your status bar
control will have one or more parts, along with text and perhaps an icon or icons. This is called the nonsimple
mode. For more information on this mode, see Initializing the Parts of a CStatusBarCtrl Object.
However, there are cases where you only need to display a single line of text. In this case, the simple mode is
sufficient for your needs. To change the mode of the CStatusBarCtrl object to simple, make a call to the SetSimple
member function. Once the status bar control is in simple mode, set the text by calling the SetText member
function, passing 255 as the value for the nPane parameter.
You can use the IsSimple function to determine what mode the CStatusBarCtrl object is in.

NOTE
If the status bar object is being changed from nonsimple to simple, or vice versa, the window is immediately redrawn and, if
applicable, any defined parts are automatically restored.

See also
Using CStatusBarCtrl
Controls
Initializing the Parts of a CStatusBarCtrl Object
3/16/2020 • 2 minutes to read • Edit Online

By default, a status bar displays status information using separate panes. These panes (also referred to as parts)
can contain either a text string, an icon, or both.
Use SetParts to define how many parts, and the length, the status bar will have. After you have created the parts of
the status bar, make calls to SetText and SetIcon to set the text or icon for a specific part of the status bar. Once the
part has been successfully set, the control is automatically redrawn.
The following example initializes an existing CStatusBarCtrl object ( m_StatusBarCtrl ) with four panes and then
sets an icon (IDI_ICON1) and some text in the second part.

int strPartDim[4] = { 80, 160, 240, -1 };

m_StatusBarIcon = AfxGetApp()->LoadIcon(IDI_ICON1);

m_StatusBarCtrl.SetParts(4, strPartDim);
m_StatusBarCtrl.SetIcon(1, m_StatusBarIcon);
m_StatusBarCtrl.SetText(_T("Part 1"), 1, 0);

For more information on setting the mode of a CStatusBarCtrl object to simple, see Setting the Mode of a
CStatusBarCtrl Object.

See also
Using CStatusBarCtrl
Controls
Using Tooltips in a CStatusBarCtrl Object
3/27/2020 • 2 minutes to read • Edit Online

To enable tooltips for a status bar control, create the CStatusBarCtrl object with the SBT_TOOLTIPS style.

NOTE
If you are using a CStatusBar object to implement your status bar, use the CStatusBar::CreateEx function. It allows you
to specify additional styles for the embedded CStatusBarCtrl object.

Once the CStatusBarCtrl object has been successfully created, use CStatusBarCtrl::SetTipText and
CStatusBarCtrl::GetTipText to set and retrieve the tip text for a specific pane.
Once the tool tip has been set, it is displayed only if the part has an icon and no text, or if all of the text cannot be
displayed inside the part. Tool tips are not supported in simple mode.

See also
Using CStatusBarCtrl
Controls
Using CTabCtrl
3/16/2020 • 2 minutes to read • Edit Online

A "tab control" is analogous to the dividers in a notebook or the labeled folders in a file cabinet. Use the tab
control, represented by class CTabCtrl, to show multiple pages of information or controls to a user, one at a time,
in a format that suggests a peer or logical relationship between each page.
For more information on tab controls, see Tab Controls in the Windows SDK.

What do you want to know more about


Tab Controls and Property Sheets
Tabs and Tab Control Attributes
Making Owner-Drawn Tabs
Working with a Tab Control
Creating the Tab Control
Adding Tabs to a Tab Control
Processing Tab Control Notification Messages

See also
Controls
Tab Controls and Property Sheets
4/1/2019 • 2 minutes to read • Edit Online

Property sheets are multiple-page dialogs or "tab dialogs" that can display up to 24 dialog template resources to
the user. For examples of property sheets, see the Windows Display Properties dialog box or the following MFC
sample application:
CMNCTRL1: Demonstrates Common Control Classes, Part 1
CMNCTRL2: Demonstrates Common Control Classes, Part 2
Property sheets can be easily implemented using the MFC class CPropertySheet.

See also
Using CTabCtrl
Controls
Tabs and Tab Control Attributes
8/15/2019 • 2 minutes to read • Edit Online

You have considerable control over the appearance and behavior of tabs that make up a tab control (CTabCtrl). Each
tab can have a label, an icon, an item state, and an application-defined 32-bit value associated with it. For each tab,
you can display the icon, the label, or both.
In addition, each tab item can have three possible states: pressed, unpressed, or highlighted. This state can only be
set by modifying an existing tab item. To modify an existing tab item, retrieve it with a call to GetItem, modify the
TCITEM structure (specifically the dwState and dwStateMask data members), and then return the modified TCITEM
structure with a call to SetItem. If you need to clear the item states of all the tab items in a CTabCtrl object, make a
call to DeselectAll. This function resets the state of all tab items or all items except the one currently selected.
The following code clears the state of all tab items and then modifies the state of the third item:

//modify the third item to be highlighted


TCITEM curItem = {0};

m_TabCtrl.DeselectAll(FALSE); //reset all tab items


curItem.mask = TCIF_STATE;
m_TabCtrl.GetItem(2, &curItem);
curItem.mask = TCIF_STATE;
curItem.dwState = TCIS_HIGHLIGHTED;
curItem.dwStateMask = TCIS_HIGHLIGHTED;
m_TabCtrl.SetItem(2, &curItem);

For more information about tab attributes, see Tabs and Tab Attributes in the Windows SDK. For more information
about adding tabs to a tab control, see Adding Tabs to a Tab Control later in this topic.

See also
Using CTabCtrl
Controls
Making Owner-Drawn Tabs
8/15/2019 • 2 minutes to read • Edit Online

You can define individual items of a tab control (CTabCtrl) to be owner-drawn items. For more information, see
Owner-Drawn Tabs in the Windows SDK.

See also
Using CTabCtrl
Controls
Working with a Tab Control
3/4/2019 • 2 minutes to read • Edit Online

The easiest way to use a tab control (CTabCtrl) is by adding it to a dialog template resource with the dialog editor.
You can also use a tab control by itself. MFC calls InitCommonControls for you. The key tasks are as follows:
Creating the tab control
Adding tabs to a tab control
Processing tab control notification messages
If the tab control object is embedded in a parent view or dialog class, the control is destroyed when the parent is
destroyed.

See also
Using CTabCtrl
Controls
Creating the Tab Control
3/4/2019 • 2 minutes to read • Edit Online

How the tab control is created depends on whether you are using the control in a dialog box or creating it in a
nondialog window.
To use CTabCtrl directly in a dialog box
1. In the dialog editor, add a Tab Control to your dialog template resource. Specify its control ID.
2. Use the Add Member Variable Wizard to add a member variable of type CTabCtrl with the Control property.
You can use this member to call CTabCtrl member functions.
3. Map handler functions in the dialog class for any tab control notification messages you need to handle. For
more information, see Mapping Messages to Functions.
4. In OnInitDialog, set the styles for the CTabCtrl .
To use CTabCtrl in a nondialog window
1. Define the control in the view or window class.
2. Call the control's Create member function, possibly in OnInitialUpdate, possibly as early as the parent
window's OnCreate handler function (if you're subclassing the control). Set the styles for the control.
After the CTabCtrl object has been created, you can set or clear the following extended styles:
TCS_EX_FL ATSEPARATORS The tab control will draw separators between the tab items. This extended
style only affects tab controls that have the TCS_BUTTONS and TCS_FL ATBUTTONS styles. By default,
creating the tab control with the TCS_FL ATBUTTONS style sets this extended style.
TCS_EX_REGISTERDROP The tab control generates TCN_GETOBJECT notification messages to request a
drop target object when an object is dragged over the tab items in the control.

NOTE
To receive the TCN_GETOBJECT notification, you must initialize the OLE libraries with a call to AfxOleInit.

These styles can be retrieved and set, after the control has been created, with respective calls to the
GetExtendedStyle and SetExtendedStyle member functions.
For instance, set the TCS_EX_FL ATSEPARATORS style with the following lines of code:

DWORD dwExStyle = m_TabCtrl.GetExtendedStyle();


m_TabCtrl.SetExtendedStyle(dwExStyle | TCS_EX_FLATSEPARATORS);

Clear the TCS_EX_FL ATSEPARATORS style from a CTabCtrl object with the following lines of code:

DWORD dwExStyle = m_TabCtrl.GetExtendedStyle();


m_TabCtrl.SetExtendedStyle(dwExStyle & ~TCS_EX_FLATSEPARATORS);

This will remove the separators that appear between the buttons of your CTabCtrl object.
See also
Using CTabCtrl
Controls
Adding Tabs to a Tab Control
8/15/2019 • 2 minutes to read • Edit Online

After creating the tab control (CTabCtrl), add as many tabs as you need.
To add a tab item
1. Prepare a TCITEM structure.
2. Call CTabCtrl::InsertItem, passing the structure.
3. Repeat steps 1 and 2 for additional tab items.
For more information, see Creating a Tab Control in the Windows SDK.

See also
Using CTabCtrl
Controls
Processing Tab Control Notification Messages
9/11/2019 • 2 minutes to read • Edit Online

As users click tabs or buttons, the tab control (CTabCtrl) sends notification messages to its parent window. Handle
these messages if you want to do something in response. For example, when the user clicks a tab, you may want to
preset control data on the page prior to displaying it.
Process WM_NOTIFY messages from the tab control in your view or dialog class. Use the Class Wizard to create an
OnChildNotify handler function with a switch statement based on which notification message is being handled. For
a list of the notifications a tab control can send to its parent window, see the Notifications section of Tab Control
Reference in the Windows SDK.

See also
Using CTabCtrl
Controls
Using CToolBarCtrl
3/16/2020 • 2 minutes to read • Edit Online

You can use the toolbar control (CToolBarCtrl) to create a control window containing buttons and optional spaces.
Each button in the toolbar control window sends a command message to the parent window as the user chooses
it. Typically, the buttons in a toolbar correspond to items in the application's menu, providing an additional and
more direct way for the user to access an application's commands.

What do you want to know more about


Methods of Creating a Toolbar
Settings for the Toolbar Control
Creating a CToolBarCtrl Object
Using Image Lists in a Toolbar Control
Using Drop-Down Buttons in a Toolbar Control
Customizing the Appearance of a Toolbar Control

See also
Controls
Methods of Creating a Toolbar
3/4/2019 • 2 minutes to read • Edit Online

MFC provides two classes to create toolbars: CToolBar and CToolBarCtrl (which wraps the Windows common
control API). CToolBar provides all of the functionality of the toolbar common control, and it handles many of the
required common control settings and structures for you; however, your resulting executable usually will be larger
than that created by using CToolBarCtrl .
CToolBarCtrl usually results in a smaller executable, and you may prefer to use CToolBarCtrl if you do not intend
to integrate the toolbar into the MFC architecture. If you plan to use CToolBarCtrl and integrate the toolbar into
the MFC architecture, you must take additional care to communicate toolbar control manipulations to MFC. This
communication is not difficult; however, it is additional work that is unneeded when you use CToolBar .
Visual C++ provides two ways to take advantage of the toolbar common control.
Create the toolbar using CToolBar , and then call CToolBar::GetToolBarCtrl to get access to the CToolBarCtrl
member functions.
Create the toolbar using CToolBarCtrl's constructor.
Either method will give you access to the member functions of the toolbar control. When you call
CToolBar::GetToolBarCtrl , it returns a reference to a CToolBarCtrl object so you can use either set of member
functions. See CToolBar for information on constructing and creating a toolbar using CToolBar .

See also
Using CToolBarCtrl
Controls
Settings for the Toolbar Control
3/4/2019 • 2 minutes to read • Edit Online

The buttons on a toolbar can display a bitmap, a string, or both. By default, the image size is set to the dimensions
of 16 by 15 pixels. All buttons are the same width, by default 24 by 22 pixels. A toolbar's height is determined by
the height of the buttons, and a toolbar's width is the same as the width of the parent window's client area, also by
default.
A toolbar can have built-in customization features, including a system-defined customization dialog box, that allow
the user to insert, delete, or rearrange toolbar buttons. An application determines whether the customization
features are available to the user and controls the extent to which the user can customize the toolbar. For more
information about customizing the toolbar, see class CToolBarCtrl in the MFC Reference.

See also
Using CToolBarCtrl
Controls
Creating a CToolBarCtrl Object
3/16/2020 • 2 minutes to read • Edit Online

CToolBarCtrl objects contain several internal data structures — a list of button image bitmaps, a list of button label
strings, and a list of TBBUTTON structures — that associate an image and/or string with the position, style, state, and
command ID of the button. Each of the elements of these data structures is referred to by a zero-based index.
Before you can use a CToolBarCtrl object, you must set up these data structures. For a list of the data structures,
see Toolbar Controls in the Windows SDK. The list of strings can only be used for button labels; you cannot retrieve
strings from the toolbar.
To use a CToolBarCtrl object, you will typically follow these steps:
To use a CToolBarCtrl object
1. Construct the CToolBarCtrl object.
2. Call Create to create the Windows toolbar common control and attach it to the CToolBarCtrl object. If you
want bitmap images for buttons, add the button bitmaps to the toolbar by calling AddBitmap. If you want
string labels for buttons, add the strings to the toolbar by calling AddString and/or AddStrings. After calling
AddString and/or AddStrings , you should call AutoSize in order to get the string or strings to appear.

3. Add button structures to the toolbar by calling AddButtons.


4. If you want tool tips, handle TTN_NEEDTEXT messages in the toolbar's owner window as described in
Handling Tool Tip Notifications.
5. If you want your user to be able to customize the toolbar, handle customization notification messages in the
owner window as described in Handling Customization Notifications.

See also
Using CToolBarCtrl
Controls
Using Image Lists in a Toolbar Control
3/27/2020 • 2 minutes to read • Edit Online

By default, the images used by the buttons in a toolbar control are stored as a single bitmap. However, you can also
store button images in a set of image lists. The toolbar control object can use up to three separate image lists:
Enabled image list Contains images for toolbar buttons that are currently enabled.
Disabled image list Contains images for toolbar buttons that are currently disabled.
Highlighted image list Contains images for toolbar buttons that are currently highlighted. This image list is
used only when the toolbar uses the TBSTYLE_FLAT style.
These image lists are used by the toolbar control when you associate them with the CToolBarCtrl object. This
association is accomplished by making calls to CToolBarCtrl::SetImageList, SetDisabledImageList, and
SetHotImageList.
By default, MFC uses the CToolBar class to implement MFC application toolbars. However, the GetToolBarCtrl
member function can be used to retrieve the embedded CToolBarCtrl object. You can then make calls to
CToolBarCtrl member functions using the returned object.

The following example demonstrates this technique by assigning an enabled ( m_ToolBarImages ) and disabled (
m_ToolBarDisabledImages ) image list to a CToolBarCtrl object ( m_ToolBarCtrl ).

CWinApp* pApp = AfxGetApp();

m_ToolBarImages.Create(16, 16, ILC_COLOR, 4, 4);


m_ToolBarImages.Add(pApp->LoadIcon(IDI_BLK));
m_ToolBarImages.Add(pApp->LoadIcon(IDI_RED));
m_ToolBarImages.Add(pApp->LoadIcon(IDI_YELL));
m_ToolBarImages.Add(pApp->LoadIcon(IDI_WHI));

m_ToolBarDisabledImages.Create(16, 16, ILC_COLOR, 4, 4);


m_ToolBarDisabledImages.Add(pApp->LoadIcon(IDI_DIS_BLK));
m_ToolBarDisabledImages.Add(pApp->LoadIcon(IDI_DIS_RED));
m_ToolBarDisabledImages.Add(pApp->LoadIcon(IDI_DIS_YELL));
m_ToolBarDisabledImages.Add(pApp->LoadIcon(IDI_DIS_WHI));

m_ToolBarCtrl.SetImageList(&m_ToolBarImages);
m_ToolBarCtrl.SetDisabledImageList(&m_ToolBarDisabledImages);

NOTE
The image lists used by the toolbar object must be permanent objects. For this reason, they are commonly data members of
an MFC class; in this example, the main frame window class.

Once the image lists are associated with the CToolBarCtrl object, the framework automatically displays the proper
button image.

See also
Using CToolBarCtrl
Controls
Using Drop-Down Buttons in a Toolbar Control
3/27/2020 • 2 minutes to read • Edit Online

In addition to standard push buttons, a toolbar can also have drop-down buttons. A drop-down button is usually
indicated by the presence of an attached down arrow.

NOTE
The attached down arrow will appear only if the TBSTYLE_EX_DRAWDDARROWS extended style has been set.

When the user clicks on this arrow (or the button itself, if no arrow is present), a TBN_DROPDOWN notification
message is sent to the parent of the toolbar control. You can then handle this notification and display a pop-up
menu; similar to the behavior of Internet Explorer.
The following procedure illustrates how to implement a drop-down toolbar button with a pop-up menu:
To implement a drop-down button
1. Once your CToolBarCtrl object has been created, set the TBSTYLE_EX_DRAWDDARROWS style, using the
following code:

m_ToolBarCtrl.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);

2. Set the TBSTYLE_DROPDOWN style for any new (InsertButton or AddButtons) or existing (SetButtonInfo)
buttons that will be drop-down buttons. The following example demonstrates modifying an existing button
in a CToolBarCtrl object:

TBBUTTONINFO tbi;

tbi.dwMask = TBIF_STYLE;
tbi.cbSize = sizeof(TBBUTTONINFO);
m_ToolBarCtrl.GetButtonInfo(0, &tbi);
tbi.fsStyle |= TBSTYLE_DROPDOWN;
m_ToolBarCtrl.SetButtonInfo(0, &tbi);

3. Add a TBN_DROPDOWN handler to the parent class of the toolbar object.

ON_NOTIFY(TBN_DROPDOWN, IDC_TOOLBAR1, &CMyDialog::OnTbnDropDownToolBar1)

4. In the new handler, display the appropriate popup menu. The following code demonstrates one method:
void CMyDialog::OnTbnDropDownToolBar1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTOOLBAR pToolBar = reinterpret_cast<LPNMTOOLBAR>(pNMHDR);
ClientToScreen(&(pToolBar->rcButton)); // TrackPopupMenu uses screen coords

CMenu menu;
VERIFY(menu.LoadMenu(IDR_MENU1));
CMenu *pPopup = menu.GetSubMenu(0);
if (NULL != pPopup)
{
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
pToolBar->rcButton.left, pToolBar->rcButton.bottom, this);
}

*pResult = 0;
}

See also
Using CToolBarCtrl
Controls
Customizing the Appearance of a Toolbar Control
3/27/2020 • 2 minutes to read • Edit Online

Class CToolBarCtrl provides many styles that affect the appearance (and, occasionally, the behavior) of the toolbar
object. Modify the toolbar object by setting the dwCtrlStyle parameter of the CToolBarCtrl::Create (or
CToolBar::CreateEx ) member function, when you first create the toolbar control.

The following styles affect the "3D" aspect of the toolbar buttons and the placement of the button text:
TBSTYLE_FL AT Creates a flat toolbar where both the toolbar and the buttons are transparent. Button text
appears under button bitmaps. When this style is used, the button underneath the cursor is automatically
highlighted.
TBSTYLE_TRANSPARENT Creates a transparent toolbar. In a transparent toolbar, the toolbar is transparent
but the buttons are not. Button text appears under button bitmaps.
TBSTYLE_LIST Places button text to the right of button bitmaps.

NOTE
To prevent repaint problems, the TBSTYLE_FL AT and TBSTYLE_TRANSPARENT styles should be set before the toolbar
object is visible.

The following styles determine if the toolbar allows a user to reposition individual buttons within a toolbar object
using drag and drop:
TBSTYLE_ALTDRAG Allows users to change a toolbar button's position by dragging it while holding down
ALT. If this style is not specified, the user must hold down SHIFT while dragging a button.

NOTE
The CCS_ADJUSTABLE style must be specified to enable toolbar buttons to be dragged.

TBSTYLE_REGISTERDROP Generates TBN_GETOBJECT notification messages to request drop target


objects when the mouse pointer passes over toolbar buttons.
The remaining styles affect visual and nonvisual aspects of the toolbar object:
TBSTYLE_WRAPABLE Creates a toolbar that can have multiple lines of buttons. Toolbar buttons can "wrap"
to the next line when the toolbar becomes too narrow to include all buttons on the same line. Wrapping
occurs on separation and nongroup boundaries.
TBSTYLE_CUSTOMERASE Generates NM_CUSTOMDRAW notification messages when it processes
WM_ERASEBKGND messages.
TBSTYLE_TOOLTIPS Creates a tool tip control that an application can use to display descriptive text for the
buttons in the toolbar.
For a complete listing of toolbar styles and extended styles, see Toolbar Control and Button Styles and Toolbar
Extended Styles in the Windows SDK.

See also
Using CToolBarCtrl
Controls
Handling Tool Tip Notifications
3/4/2019 • 2 minutes to read • Edit Online

When you specify the TBSTYLE_TOOLTIPS style, the toolbar creates and manages a tool tip control. A tool tip is a
small pop-up window that contains a line of text describing a toolbar button. The tool tip is hidden, appearing only
when the user puts the cursor on a toolbar button and leaves it there for approximately one-half second. The tool
tip is displayed near the cursor.
Before the tool tip is displayed, the TTN_NEEDTEXT notification message is sent to the toolbar's owner window to
retrieve the descriptive text for the button. If the toolbar's owner window is a CFrameWnd window, tool tips are
displayed without any extra effort, because CFrameWnd has a default handler for the TTN_NEEDTEXT notification.
If the toolbar's owner window is not derived from CFrameWnd , such as a dialog box or form view, you must add an
entry to your owner window's message map and provide a notification handler in the message map. The entry to
your owner window's message map is as follows:

ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyDialog::OnTtnNeedText)

Remarks
memberFxn
The member function to be called when text is needed for this button.
Note that the id of a tool tip is always 0.
In addition to the TTN_NEEDTEXT notification, a tool tip control can send the following notifications to a toolbar
control:

N OT IF IC AT IO N M EA N IN G

TTN_NEEDTEXTA Tool tip control requires ASCII text (Windows 95 only)

TTN_NEEDTEXTW Tool tip control requires UNICODE text (Windows NT only)

TBN_HOTITEMCHANGE Indicates that the hot (highlighted) item has changed.

NM_RCLICK Indicates the user has right-clicked a button.

TBN_DRAGOUT Indicates the user has clicked the button and dragged the
pointer off the button. It allows an application to implement
drag and drop from a toolbar button. When receiving this
notification, the application will begin the drag and drop
operation.

TBN_DROPDOWN Indicates the user has clicked a button that uses the
TBSTYLE_DROPDOWN style.

TBN_GETOBJECT Indicates the user moved the pointer over a button that uses
the TBSTYLE_DROPPABLE style.

For an example handler function and more information about enabling tool tips, see Tool Tips.
See also
Using CToolBarCtrl
Controls
Handling Customization Notifications
3/27/2020 • 7 minutes to read • Edit Online

A Windows toolbar common control has built-in customization features, including a system-defined customization
dialog box, which allow the user to insert, delete, or rearrange toolbar buttons. The application determines whether
the customization features are available and controls the extent to which the user can customize the toolbar.
You can make these customization features available to the user by giving the toolbar the CCS_ADJUSTABLE
style. The customization features allow the user to drag a button to a new position or to remove a button by
dragging it off the toolbar. In addition, the user can double-click the toolbar to display the Customize Toolbar
dialog box, which allows the user to add, delete, and rearrange toolbar buttons. The application can display the
dialog box by using the Customize member function.
The toolbar control sends notification messages to the parent window at each step in the customization process. If
the user holds the SHIFT key down and begins dragging a button, the toolbar automatically handles the drag
operation. The toolbar sends the TBN_QUERYDELETE notification message to the parent window to determine
whether the button may be deleted. The drag operation ends if the parent window returns FALSE . Otherwise, the
toolbar captures mouse input and waits for the user to release the mouse button.
When the user releases the mouse button, the toolbar control determines the location of the mouse cursor. If the
cursor is outside the toolbar, the button is deleted. If the cursor is on another toolbar button, the toolbar sends the
TBN_QUERYINSERT notification message to the parent window to determine if a button may be inserted to the
left of the given button. The button is inserted if the parent window returns TRUE ; otherwise, it is not. The toolbar
sends the TBN_TOOLBARCHANGE notification message to signal the end of the drag operation.
If the user begins a drag operation without holding down the SHIFT key, the toolbar control sends the
TBN_BEGINDRAG notification message to the owner window. An application that implements its own button-
dragging code can use this message as a signal to begin a drag operation. The toolbar sends the TBN_ENDDRAG
notification message to signal the end of the drag operation.
A toolbar control sends notification messages when the user customizes a toolbar by using the Customize
Toolbar dialog box. The toolbar sends the TBN_BEGINADJUST notification message after the user double-clicks
the toolbar, but before the dialog box is created. Next, the toolbar begins sending a series of TBN_QUERYINSERT
notification messages to determine whether the toolbar allows buttons to be inserted. When the parent window
returns TRUE , the toolbar stops sending TBN_QUERYINSERT notification messages. If the parent window does
not return TRUE for any button, the toolbar destroys the dialog box.
Next, the toolbar control determines if any buttons may be deleted from the toolbar by sending one
TBN_QUERYDELETE notification message for each button in the toolbar. The parent window returns TRUE to
indicate that a button may be deleted; otherwise, it returns FALSE . The toolbar adds all toolbar buttons to the
dialog box, but grays those that may not be deleted.
Whenever the toolbar control needs information about a button in the Customize Toolbar dialog box, it sends the
TBN_GETBUTTONINFO notification message, specifying the index of the button for which it needs information
and the address of a TBNOTIFY structure. The parent window must fill the structure with the relevant information.
The Customize Toolbar dialog box includes a Help button and a Reset button. When the user chooses the Help
button, the toolbar control sends the TBN_CUSTHELP notification message. The parent window should respond
by displaying help information. The dialog box sends the TBN_RESET notification message when the user selects
the Reset button. This message signals that the toolbar is about to reinitialize the dialog box.
These messages are all WM_NOTIFY messages, and they can be handled in your owner window by adding
message-map entries of the following form to your owner window's message map:

ON_NOTIFY( wNotifyCode, idControl, memberFxn )

wNotifyCode
Notification message identifier code, such as TBN_BEGINADJUST .
idControl
The identifier of the control sending the notification.
memberFxn
The member function to be called when this notification is received.
Your member function would be declared with the following prototype:

afx_msg void memberFxn( NMHDR * pNotifyStruct, LRESULT * result );

If the notification message handler returns a value, it should put it in the LRESULT pointed to by result.
For each message, pNotifyStruct points to either an NMHDR structure or a TBNOTIFY structure. These
structures are described below:
The NMHDR structure contains the following members:

typedef struct tagNMHDR {


HWND hwndFrom; // handle of control sending message
UINT idFrom;// identifier of control sending message
UINT code; // notification code; see below
} NMHDR;

hwndFrom
Window handle of the control that is sending the notification. To convert this handle to a CWnd pointer, use
CWnd::FromHandle.
idFrom
Identifier of the control sending the notification.
code
Notification code. This member can be a value specific to a control type, such as TBN_BEGINADJUST or
TTN_NEEDTEXT , or it can be one of the common notification values listed below:
NM_CLICK The user has clicked the left mouse button within the control.
NM_DBLCLK The user has double-clicked the left mouse button within the control.
NM_KILLFOCUS The control has lost the input focus.
NM_OUTOFMEMORY The control could not complete an operation because there is not enough
memory available.
NM_RCLICK The user has clicked the right mouse button within the control.
NM_RDBLCLK The user has double-clicked the right mouse button within the control.
NM_RETURN The control has the input focus, and the user has pressed the ENTER key.
NM_SETFOCUS The control has received the input focus.
The TBNOTIFY structure contains the following members:

typedef struct {
NMHDR hdr; // information common to all WM_NOTIFY messages
int iItem; // index of button associated with notification
TBBUTTON tbButton; // info about button associated withnotification
int cchText; // count of characters in button text
LPSTR lpszText;// address of button text
} TBNOTIFY, FAR* LPTBNOTIFY;

hdr
Information common to all WM_NOTIFY messages.
iItem
Index of button associated with notification.
tbButton
TBBUTTON structure that contains information about the toolbar button associated with the notification.
cchText
Count of characters in button text.
lpszText
Pointer to button text.
The notifications the toolbar sends are as follows:
TBN_BEGINADJUST
Sent when the user begins customizing a toolbar control. The pointer points to an NMHDR structure that
contains information about the notification. The handler doesn't need to return any specific value.
TBN_BEGINDRAG
Sent when the user begins dragging a button in a toolbar control. The pointer points to a TBNOTIFY
structure. The iItem member contains the zero-based index of the button being dragged. The handler
doesn't need to return any specific value.
TBN_CUSTHELP
Sent when the user chooses the Help button in the Customize Toolbar dialog box. No return value. The
pointer points to an NMHDR structure that contains information about the notification message. The
handler doesn't need to return any specific value.
TBN_ENDADJUST
Sent when the user stops customizing a toolbar control. The pointer points to an NMHDR structure that
contains information about the notification message. The handler doesn't need to return any specific value.
TBN_ENDDRAG
Sent when the user stops dragging a button in a toolbar control. The pointer points to a TBNOTIFY
structure. The iItem member contains the zero-based index of the button being dragged. The handler
doesn't need to return any specific value.
TBN_GETBUTTONINFO
Sent when the user is customizing a toolbar control. The toolbar uses this notification message to retrieve
information needed by the Customize Toolbar dialog box. The pointer points to a TBNOTIFY structure. The
iItem member specifies the zero-based index of a button. The pszText and cchText members specify the
address and length, in characters, of the current button text. An application should fill the structure with
information about the button. Return TRUE if button information was copied to the structure, or FALSE
otherwise.
TBN_QUERYDELETE
Sent while the user is customizing a toolbar to determine whether a button may be deleted from a toolbar
control. The pointer points to a TBNOTIFY structure. The iItem member contains the zero-based index of
the button to be deleted. Return TRUE to allow the button to be deleted or FALSE to prevent the button
from being deleted.
TBN_QUERYINSERT
Sent while the user is customizing a toolbar control to determine whether a button may be inserted to the
left of the given button. The pointer points to a TBNOTIFY structure. The iItem member contains the zero-
based index of the button to be inserted. Return TRUE to allow a button to be inserted in front of the given
button or FALSE to prevent the button from being inserted.
TBN_RESET
Sent when the user resets the content of the Customize Toolbar dialog box. The pointer points to an
NMHDR structure that contains information about the notification message. The handler doesn't need to
return any specific value.
TBN_TOOLBARCHANGE
Sent after the user has customized a toolbar control. The pointer points to an NMHDR structure that
contains information about the notification message. The handler doesn't need to return any specific value.

See also
Using CToolBarCtrl
Controls
Using CToolTipCtrl
3/16/2020 • 2 minutes to read • Edit Online

The CToolTipCtrl class encapsulates the functionality of a tool tip control, a small pop-up window that displays a
single line of text describing the purpose of a tool in an application. A tool tip is hidden most of the time, appearing
only when the user puts the cursor on a tool and leaves it there for approximately one-half second. The tool tip
appears near the cursor and disappears when the user clicks a mouse button or moves the cursor off of the tool.

What do you want to know more about


Methods of Creating Tool Tips
Settings for the Tool Tip Control
Using CToolTipCtrl to Create and Manipulate a CToolTipCtrl Object
Manipulating the Tool Tip Control

See also
Using CToolBarCtrl
Controls
Methods of Creating Tool Tips
3/4/2019 • 2 minutes to read • Edit Online

MFC provides three classes to create and manage the tool tip control: CWnd, CToolBarCtrl, CToolTipCtrl and
CMFCToolTipCtrl. The tool tip member functions in these classes wrap the Windows common control API. Class
CToolBarCtrl and class CToolTipCtrl are derived from class CWnd .

CWnd provides four member functions to create and manage tool tips: EnableToolTips, CancelToolTips,
FilterToolTipMessage, and OnToolHitTest. See these individual member functions for more information about how
they implement tool tips.
If you create a toolbar using CToolBarCtrl , you can implement tool tips for that toolbar directly using the following
member functions: GetToolTips and SetToolTips. See these individual member functions and Handling Tool Tip
Notifications for more information about how they implement tool tips.
The CToolTipCtrl class provides the functionality of the Windows common tool tip control. A single tool tip
control can provide information for more than one tool. A tool is either a window, such as a child window or
control, or an application-defined rectangular area within a window's client area. The CMFCToolTipCtrl class derives
from CToolTipCtrl and provides additional visual styles and functionality.

See also
Using CToolTipCtrl
Controls
Settings for the Tool Tip Control
3/4/2019 • 2 minutes to read • Edit Online

You can set the tool tip control (CToolTipCtrl) to be either active or inactive. When you set it to be active, the tool tip
control appears when the cursor is on a tool. When you set it to be inactive, the tool tip control does not appear,
even if the cursor is on a tool. Call Activate to activate or deactivate a tool tip control.
You can set an active tool tip to display the tool tip when the cursor is on a tool, whether or not the tool tip control's
owner window is active or inactive, by using the TTS_ALWAYSTIP style. If you do not use this style, the tool tip
control appears when the tool's owner window is active, but not when it is inactive.
Most applications contain toolbars with tools that correspond to menu commands. For such tools, it is convenient
for the tool tip control to display the same text as the corresponding menu item. The system automatically strips
the ampersand (&) accelerator characters from all strings passed to a tool tip control, unless the control has the
TTS_NOPREFIX style.

See also
Using CToolTipCtrl
Controls
Using CToolTipCtrl to Create and Manipulate a
CToolTipCtrl Object
3/16/2020 • 2 minutes to read • Edit Online

Here is an example of CToolTipCtrl usage:


To create and manipulate a CToolTipCtrl
1. Construct the CToolTipCtrl object.
2. Call Create to create the Windows tool tip common control and attach it to the CToolTipCtrl object.
3. Call AddTool to register a tool with the tool tip control, so that the information stored in the tool tip is
displayed when the cursor is on the tool.
4. Call SetToolInfo to set the information that a tool tip maintains for a tool.
5. Call SetToolRect to set a new bounding rectangle for a tool.
6. Call HitTest to test a point to determine whether it is within the bounding rectangle of the given tool and, if
so, retrieve information about the tool.
7. Call GetToolCount to retrieve a count of the tools registered with the tool tip control.

See also
Using CToolTipCtrl
Controls
Manipulating the Tool Tip Control
3/4/2019 • 2 minutes to read • Edit Online

Class CToolTipCtrl provides a group of member functions that control the various attributes of the CToolTipCtrl
object and the tool tip window.
The initial, pop-up, and reshow durations for the tool tip windows can be set and retrieved with calls to
GetDelayTime and SetDelayTime.
Change the appearance of the tool tip windows with the following functions:
GetMargin and SetMargin Retrieves and sets the width between the tool tip border and the tool tip text.
GetMaxTipWidth and SetMaxTipWidth Retrieves and sets the maximum width of the tool tip window.
GetTipBkColor and SetTipBkColor Retrieves and sets the background color of the tool tip window.
GetTipTextColor and SetTipTextColor Retrieves and sets the text color of the tool tip window.
In order for the tool tip control to be notified of important messages, such as WM_LBUTTONXXX messages, you
must relay the messages to your tool tip control. The best method for this relay is to make a call to
CToolTipCtrl::RelayEvent, in the PreTranslateMessage function of the owner window. The following example
illustrates one possible method (assuming the tool tip control is called m_ToolTip ):

BOOL CMyDialog::PreTranslateMessage(MSG* pMsg)


{
if (pMsg->message == WM_LBUTTONDOWN ||
pMsg->message == WM_LBUTTONUP ||
pMsg->message == WM_MOUSEMOVE)
{
m_ToolTipCtrl.RelayEvent(pMsg);
}

return CDialog::PreTranslateMessage(pMsg);
}

To immediately remove a tool tip window, call the Pop member function.

See also
Using CToolTipCtrl
Controls
Using CTreeCtrl
3/16/2020 • 2 minutes to read • Edit Online

A tree control, represented by the class CTreeCtrl, is a window that displays a hierarchical list of items, such as the
headings in a document, the entries in an index, or the files and directories on a disk. Each item consists of a label
and an optional bitmapped image, and each item can have a list of subitems associated with it. By clicking an
item, the user can expand and collapse the associated list of subitems. The directory tree in the left-hand pane of
File Explorer is an example of a tree control.

What do you want to know more about


CTreeCtrl vs. CTreeView
Using Tree Controls
Communicating with a Tree Control
Tree Control Styles
Tree Control Parent and Child Items
Tree Control Item Position
Tree Control Item Labels
Tree Control Label Editing
Tree Control Item States Overview
Tree Control Image Lists
Tree Control Item Selection
Tree Control Drag-and-Drop Operations
Tree Control Item Information
Tree Control Notification Messages

See also
Controls
CTreeCtrl vs. CTreeView
3/16/2020 • 2 minutes to read • Edit Online

MFC provides two classes that encapsulate tree controls: CTreeCtrl and CTreeView. Each class is useful in different
situations.
Use CTreeCtrl when you need a plain child window control; for instance, in a dialog box. You'd especially want to
use CTreeCtrl if there will be other child controls in the window, as in a typical dialog box.
Use CTreeView when you want the tree control to act like a view window in document/view architecture as well as
a tree control. A CTreeView will occupy the entire client area of a frame window or splitter window. It will be
automatically resized when its parent window is resized, and it can process command messages from menus,
accelerator keys, and toolbars. Since a tree control contains the data necessary to display the tree, the
corresponding document object does not have to be complicated — you could even use CDocument as the
document type in your document template.

See also
Using CTreeCtrl
Controls
Using Tree Controls
3/4/2019 • 2 minutes to read • Edit Online

Typical usage of a tree control (CTreeCtrl) follows the pattern below:


The control is created. If the control is specified in a dialog box template or if you're using CTreeView ,
creation is automatic when the dialog box or view is created. If you want to create the tree control as a child
window of some other window, use the Create member function.
If you want your tree control to use images, set an image list by calling SetImageList. You can also change
the indentation by calling SetIndent. A good time to do this is in OnInitDialog (for controls in dialog boxes)
or OnInitialUpdate (for views).
Put data into the control by calling the CTreeCtrl 's InsertItem function once for each data item. InsertItem
returns a handle to the item you can use to refer to it later, such as when adding child items. A good time to
initialize the data is in OnInitDialog (for controls in dialog boxes) or OnInitialUpdate (for views).
As the user interacts with the control, it will send various notification messages. You can specify a function to
handle each of the messages you want to handle by adding an ON_NOTIFY_REFLECT macro in your control
window's message map or by adding an ON_NOTIFY macro to your parent window's message map. See
Tree Control Notification Messages later in this topic for a list of possible notifications.
Call the various Set member functions to set values for the control. Changes that you can make include
setting the indentation and changing the text, image, or data associated with an item.
Use the various Get functions to examine the contents of the control. You can also traverse the contents of
the tree control with functions that allow you to retrieve handles to parents, children, and siblings of a
specified item. You can even sort the children of a particular node.
When you're done with the control, make sure it's properly destroyed. If the tree control is in a dialog box or
if it's a view, it and the CTreeCtrl object will be destroyed automatically. If not, you need to ensure that both
the control and the CTreeCtrl object are properly destroyed.

See also
Using CTreeCtrl
Controls
Communicating with a Tree Control
3/4/2019 • 2 minutes to read • Edit Online

You use different methods for calling member functions in a CTreeCtrl object depending on how the object was
created:
If the tree control is in a dialog box, use a member variable of type CTreeCtrl that you create in the dialog
box class.
If the tree control is a child window, use the CTreeCtrl object (or pointer) you used to construct the object.
If you're using a CTreeView object, use the function CTreeView::GetTreeCtrl to get a reference to the tree
control. You can initialize another reference with this value or assign the address of the reference to a
CTreeCtrl pointer.

See also
Using CTreeCtrl
Controls
Tree Control Styles
8/15/2019 • 2 minutes to read • Edit Online

Tree control (CTreeCtrl) styles govern aspects of a tree control's appearance. You set the initial styles when you
create the tree control. You can retrieve and change the styles after creating the tree control by using the
GetWindowLong and SetWindowLong Windows functions, specifying GWL_STYLE for the nIndex parameter. For a
complete list of styles, see Tree View Control Window Styles in the Windows SDK.
The TVS_HASLINES style enhances the graphic representation of a tree control's hierarchy by drawing lines that
link child items to their corresponding parent item. This style does not link items at the root of the hierarchy. To do
so, you need to combine the TVS_HASLINES and TVS_LINESATROOT styles.
The user can expand or collapse a parent item's list of child items by double-clicking the parent item. A tree control
that has the TVS_SINGLEEXPAND style causes the item being selected to expand and the item being unselected
to collapse. If the mouse is used to single-click the selected item and that item is closed, it will be expanded. If the
selected item is single-clicked when it is open, it will be collapsed.
A tree control that has the TVS_HASBUTTONS style adds a button to the left side of each parent item. The user
can click the button to expand or collapse the child items as an alternative to double-clicking the parent item.
TVS_HASBUTTONS does not add buttons to items at the root of the hierarchy. To do so, you must combine
TVS_HASLINES , TVS_LINESATROOT , and TVS_HASBUTTONS .
The TVS_EDITL ABELS style makes it possible for the user to edit the labels of tree control items. For more
information about editing labels, see Tree Control Label Editing later in this topic.
The TVS_NOTOOLTIPS style disables the automatic tool tip feature of tree view controls. This feature
automatically displays a tool tip, containing the title of the item under the mouse cursor, if the entire title is not
currently visible.

See also
Using CTreeCtrl
Controls
Tree Control Parent and Child Items
8/15/2019 • 2 minutes to read • Edit Online

Any item in a tree control (CTreeCtrl) can have a list of subitems, which are called child items, associated with it. An
item that has one or more child items is called a parent item. A child item is displayed below its parent item and is
indented to indicate it is subordinate to the parent. An item that has no parent is at the top of the hierarchy and is
called a root item.
At any given time, the state of a parent item's list of child items can be either expanded or collapsed. When the state
is expanded, the child items are displayed below the parent item. When it is collapsed, the child items are not
displayed. The list automatically toggles between the expanded and collapsed states when the user double-clicks
the parent item or, if the parent has the TVS_HASBUTTONS style, when the user clicks the button associated with
the parent item. An application can expand or collapse the child items by using the Expand member function.
You add an item to a tree control by calling the InsertItem member function. This function returns a handle of the
HTREEITEM type, which uniquely identifies the item. When adding an item, you must specify the handle of the
new item's parent item. If you specify NULL or the TVI_ROOT value instead of a parent item handle in the
TVINSERTSTRUCT structure or hParent parameter, the item is added as a root item.
A tree control sends a TVN_ITEMEXPANDING notification message when a parent item's list of child items is about
to be expanded or collapsed. The notification gives you the opportunity to prevent the change or to set any
attributes of the parent item that depend on the state of the list of child items. After changing the state of the list,
the tree control sends a TVN_ITEMEXPANDED notification message.
When a list of child items is expanded, it is indented relative to the parent item. You can set the amount of
indentation by using the SetIndent member function or retrieve the current amount by using the GetIndent
member function.

See also
Using CTreeCtrl
Controls
Tree Control Item Position
3/4/2019 • 2 minutes to read • Edit Online

An item's initial position is set when the item is added to the tree control (CTreeCtrl) by using the InsertItem
member function. The member function call specifies the handle of the parent item and the handle of the item after
which the new item is to be inserted. The second handle must identify either a child item of the given parent or one
of these values: TVI_FIRST , TVI_LAST , or TVI_SORT .
When TVI_FIRST or TVI_LAST is specified, the tree control places the new item at the beginning or end of the
given parent item's list of child items. When TVI_SORT is specified, the tree control inserts the new item into the list
of child items in alphabetical order based on the text of the item labels.
You can put a parent item's list of child items into alphabetical order by calling the SortChildren member function.
This function includes a parameter that specifies whether all levels of child items descending from the given parent
item are also sorted in alphabetical order.
The SortChildrenCB member function allows you to sort child items based on criteria that you define. When you
call this function, you specify an application-defined callback function that the tree control can call whenever the
relative order of two child items needs to be decided. The callback function receives two 32-bit application-defined
values for the items being compared and a third 32-bit value that you specify when calling SortChildrenCB .

See also
Using CTreeCtrl
Controls
Tree Control Item Labels
9/6/2019 • 2 minutes to read • Edit Online

You typically specify the text of an item's label when adding the item to the tree control (CTreeCtrl). The InsertItem
member function can pass a TVITEM structure that defines the item's properties, including a string containing the
text of the label. InsertItem has several overloads that can be called with various combinations of parameters.
A tree control allocates memory for storing each item; the text of the item labels takes up a significant portion of
this memory. If your application maintains a copy of the strings in the tree control, you can decrease the memory
requirements of the control by specifying the LPSTR_TEXTCALLBACK value in the pszText member of TV_ITEM or
the lpszItem parameter instead of passing actual strings to the tree control. Using LPSTR_TEXTCALLBACK causes
the tree control to retrieve the text of an item's label from the application whenever the item needs to be redrawn.
To retrieve the text, the tree control sends a TVN_GETDISPINFO notification message, which includes the address of
a NMTVDISPINFO structure. You must respond by setting the appropriate members of the included structure.
A tree control uses memory allocated from the heap of the process that creates the tree control. The maximum
number of items in a tree control is based on the amount of memory available in the heap. Each item takes 64
bytes.

See also
Using CTreeCtrl
Controls
Tree Control Label Editing
9/6/2019 • 2 minutes to read • Edit Online

The user can directly edit the labels of items in a tree control (CTreeCtrl) that has the TVS_EDITL ABELS style. The
user begins editing by clicking the label of the item that has the focus. An application begins editing by using the
EditLabel member function. The tree control sends the notification when editing begins and when it is canceled or
completed. When editing is completed, you are responsible for updating the item's label, if appropriate.
When label editing begins, a tree control sends a TVN_BEGINLABELEDIT notification message. By processing this
notification, you can allow editing of some labels and prevent editing of others. Returning 0 allows editing, and
returning nonzero prevents it.
When label editing is canceled or completed, a tree control sends a TVN_ENDLABELEDIT notification message. The
lParam parameter is the address of a NMTVDISPINFO structure. The item member is a TVITEM structure that
identifies the item and includes the edited text. You are responsible for updating the item's label, if appropriate,
perhaps after validating the edited string. The pszText member of TV_ITEM is 0 if editing is canceled.
During label editing, typically in response to the TVN_BEGINLABELEDIT notification message, you can get a pointer
to the edit control used for label editing by using the GetEditControl member function. You can call the edit
control's SetLimitText member function to limit the amount of text a user can enter or subclass the edit control to
intercept and discard invalid characters. Note, however, that the edit control is displayed only after
TVN_BEGINL ABELEDIT is sent.

See also
Using CTreeCtrl
Controls
Tree Control Item States Overview
8/15/2019 • 2 minutes to read • Edit Online

Each item in a tree control (CTreeCtrl) has a current state. For example, an item can be selected, disabled, expanded,
and so on. For the most part, the tree control automatically sets an item's state to reflect user actions, such as
selection of an item. However, you can also set an item's state by using the SetItemState member function and
retrieve the current state of an item by using the GetItemState member function. For a complete list of item states,
see Tree-View Control Constants in the Windows SDK.
An item's current state is specified by the nState parameter. A tree control might change an item's state to reflect a
user action, such as selecting the item or setting the focus to the item. In addition, an application might change an
item's state to disable or hide the item or to specify an overlay image or state image.
When you specify or change an item's state, the nStateMask parameter specifies which state bits to set, and the
nState parameter contains the new values for those bits. For example, the following example changes the current
state of a parent item (specified by hParentItem) in a CTreeCtrl object ( m_treeCtrl ) to TVIS_EXPANDPARTIAL :

TVITEM curItem;
HTREEITEM hParentItem;

hParentItem = m_TreeCtrl.GetSelectedItem();

//modify the parent item to keep the '+' sign


curItem.mask = TVIF_STATE | TVIF_HANDLE;
curItem.hItem = hParentItem;
curItem.state = TVIS_EXPANDPARTIAL;
curItem.stateMask = TVIS_EXPANDPARTIAL;
m_TreeCtrl.SetItem(&curItem);

Another example of changing the state would be to set an item's overlay image. To accomplish this, nStateMask
must include the TVIS_OVERLAYMASK value, and nState must include the one-based index of the overlay image
shifted left eight bits by using the INDEXTOOVERLAYMASK macro. The index can be 0 to specify no overlay image.
The overlay image must have been added to the tree control's list of overlay images by a previous call to the
CImageList::SetOverlayImage function. The function specifies the one-based index of the image to add; this is the
index used with the INDEXTOOVERLAYMASK macro. A tree control can have up to four overlay images.
To set an item's state image, nStateMask must include the TVIS_STATEIMAGEMASK value, and nState must include the
one-based index of the state image shifted left 12 bits by using the INDEXTOSTATEIMAGEMASK macro. The index
can be 0 to specify no state image. For more information about overlay and state images, see Tree Control Image
Lists.

See also
Using CTreeCtrl
Controls
Tree Control Image Lists
8/15/2019 • 2 minutes to read • Edit Online

Each item in a tree control (CTreeCtrl) can have a pair of bitmapped images associated with it. The images appear
on the left side of an item's label. One image is displayed when the item is selected, and the other is displayed
when the item is not selected. For example, an item might display an open folder when it is selected and a closed
folder when it is not selected.
To use item images, you must create an image list by constructing a CImageList object and using the
CImageList::Create function to create the associated image list. Then add the desired bitmaps to the list, and
associate the list with the tree control by using the SetImageList member function. By default, all items display the
first image in the image list for both the selected and nonselected states. You can change the default behavior for a
particular item by specifying the indexes of the selected and nonselected images when adding the item to the tree
control using the InsertItem member function. You can change the indexes after adding an item by using the
SetItemImage member function.
A tree control's image lists can also contain overlay images, which are designed to be superimposed on item
images. A nonzero value in bits 8 through 11 of a tree control item's state specifies the one-based index of an
overlay image (0 indicates no overlay image). Because a 4-bit, one-based index is used, overlay images must be
among the first 15 images in the image lists. For more information about tree control item states, see Tree Control
Item States Overview earlier in this topic.
If a state image list is specified, a tree control reserves space to the left of each item's icon for a state image. An
application can use state images, such as checked and cleared check boxes, to indicate application-defined item
states. A nonzero value in bits 12 through 15 specifies the one-based index of a state image (0 indicates no state
image).
By specifying the I_IMAGECALLBACK value instead of the index of an image, you can delay specifying the
selected or nonselected image until the item is about to be redrawn. I_IMAGECALLBACK directs the tree control
to query the application for the index by sending the TVN_GETDISPINFO notification message.
The GetImageList member function retrieves the handle of a tree control's image list. This function is useful if you
need to add more images to the list. For more information about image lists, see Using CImageList, CImageList in
the MFC Reference, and Image Lists in the Windows SDK.

See also
Using CTreeCtrl
Controls
Tree Control Item Selection
8/15/2019 • 2 minutes to read • Edit Online

When the selection changes from one item to another, a tree control (CTreeCtrl) sends TVN_SELCHANGING and
TVN_SELCHANGED notification messages. Both notifications include a value that specifies whether the change is
the result of a mouse click or a keystroke. The notifications also include information about the item that is gaining
the selection and the item that is losing the selection. You can use this information to set item attributes that
depend on the selection state of the item. Returning TRUE in response to TVN_SELCHANGING prevents the selection
from changing; returning FALSE allows the change.
An application can change the selection by calling the SelectItem member function.

See also
Using CTreeCtrl
Controls
Tree Control Drag-and-Drop Operations
8/15/2019 • 2 minutes to read • Edit Online

A tree control (CTreeCtrl) sends a notification when the user starts to drag an item. The control sends a
TVN_BEGINDRAG notification message when the user begins dragging an item with the left mouse button and a
TVN_BEGINRDRAG notification message when the user begins dragging with the right button. You can prevent a
tree control from sending these notifications by giving the tree control the TVS_DISABLEDRAGDROP style.
You obtain an image to display during a drag operation by calling the CreateDragImage member function. The tree
control creates a dragging bitmap based on the label of the item being dragged. Then the tree control creates an
image list, adds the bitmap to it, and returns a pointer to the CImageList object.
You must provide the code that actually drags the item. This typically involves using the dragging capabilities of the
image list functions and processing the WM_MOUSEMOVE and WM_LBUTTONUP (or WM_RBUTTONUP) messages
sent after the drag operation has begun. For more information about the image list functions, see CImageList in the
MFC Reference and Image Lists in the Windows SDK. For more information about dragging a tree control item, see
Dragging the Tree View Item, also in the Windows SDK.
If items in a tree control are to be the targets of a drag-and-drop operation, you need to know when the mouse
cursor is on a target item. You can find out by calling the HitTest member function. You specify either a point and
integer, or the address of a TVHITTESTINFO structure that contains the current coordinates of the mouse cursor.
When the function returns, the integer or structure contains a flag indicating the location of the mouse cursor
relative to the tree control. If the cursor is over an item in the tree control, the structure contains the handle of the
item as well.
You can indicate that an item is the target of a drag-and-drop operation by calling the SetItem member function to
set the state to the TVIS_DROPHILITED value. An item that has this state is drawn in the style used to indicate a drag-
and-drop target.

See also
Using CTreeCtrl
Controls
Tree Control Item Information
3/4/2019 • 2 minutes to read • Edit Online

Tree controls (CTreeCtrl) have a number of member functions that retrieve information about items in the control.
The GetItem member function retrieves some or all of the data associated with an item. This data could include the
item's text, state, images, count of child items, and an application-defined 32-bit data value. There is also a SetItem
function that can set some or all of the data associated with an item.
The GetItemState, GetItemText, GetItemData, and GetItemImage member functions retrieve individual attributes of
an item. Each of these functions has a corresponding Set function for setting the attributes of an item.
The GetNextItem member function retrieves the tree control item that bears the specified relationship to the
current item. This function can retrieve an item's parent, the next or previous visible item, the first child item, and so
on. There are also member functions to traverse the tree: GetRootItem, GetFirstVisibleItem, GetNextVisibleItem,
GetPrevVisibleItem, GetChildItem, GetNextSiblingItem, GetPrevSiblingItem, GetParentItem, GetSelectedItem, and
GetDropHilightItem.
The GetItemRect member function retrieves the bounding rectangle for a tree control item. The GetCount and
GetVisibleCount member functions retrieve a count of the items in a tree control and a count of the items that are
currently visible in the tree control's window, respectively. You can ensure that a particular item is visible by calling
the EnsureVisible member function.

See also
Using CTreeCtrl
Controls
Tree Control Notification Messages
3/4/2019 • 2 minutes to read • Edit Online

A tree control (CTreeCtrl) sends the following notification messages as WM_NOTIFY messages:

N OT IF IC AT IO N M ESSA GE DESC RIP T IO N

TVN_BEGINDRAG Signals the start of a drag-and-drop operation

TVN_BEGINLABELEDIT Signals the start of in-place label editing

TVN_BEGINRDRAG Signals the start of a drag-and-drop operation, using the


right mouse button

TVN_DELETEITEM Signals the deletion of a specific item

TVN_ENDLABELEDIT Signals the end of label editing

TVN_GETDISPINFO Requests information that the tree control requires to display


an item

TVN_ITEMEXPANDED Signals that a parent item's list of child items was expanded or
collapsed

TVN_ITEMEXPANDING Signals that a parent item's list of child items is about to be


expanded or collapsed

TVN_KEYDOWN Signals a keyboard event

TVN_SELCHANGED Signals that the selection has changed from one item to
another

TVN_SELCHANGING Signals that the selection is about to be changed from one


item to another

TVN_SETDISPINFO Notification to update the information maintained for an item

See also
Using CTreeCtrl
Controls
Control Bars
3/27/2020 • 3 minutes to read • Edit Online

"Control bar" is the general name for toolbars, status bars, and dialog bars. MFC classes CToolBar , CStatusBar ,
CDialogBar , COleResizeBar , and CReBar derive from class CControlBar, which implements their common
functionality.
Control bars are windows that display rows of controls with which users can select options, execute commands,
or obtain program information. Types of control bars include toolbars, dialog bars, and status bars.
Toolbars, in class CToolBar
Status bars, in class CStatusBar
Dialog bars, in class CDialogBar
Rebars, in class CReBar

IMPORTANT
As of MFC version 4.0, toolbars, status bars, and tool tips are implemented using system functionality implemented in the
comctl32.dll instead of the previous implementation specific to MFC. In MFC version 6.0, CReBar , which also wraps
comctl32.dll functionality, was added.

Brief introductions to the control-bar types follow. For further information, see the links below.

Control Bars
Control bars greatly enhance a program's usability by providing quick, one-step command actions. Class
CControlBar provides the common functionality of all toolbars, status bars, and dialog bars. CControlBar
provides the functionality for positioning the control bar in its parent frame window. Because a control bar is
usually a child window of a parent frame window, it is a "sibling" to the client view or MDI client of the frame
window. A control-bar object uses information about its parent window's client rectangle to position itself. Then it
alters the parent's remaining client-window rectangle so that the client view or MDI client window fills the rest of
the client window.

NOTE
If a button on the control bar doesn't have a COMMAND or UPDATE_COMMAND_UI handler, the framework
automatically disables the button.

Toolbars
A toolbar is a control bar that displays a row of bitmapped buttons that carry out commands. Pressing a toolbar
button is equivalent to choosing a menu item; it calls the same handler mapped to a menu item if that menu item
has the same ID as the toolbar button. The buttons can be configured to appear and behave as pushbuttons, radio
buttons, or check boxes. A toolbar is usually aligned to the top of a frame window, but an MFC toolbar can "dock"
to any side of its parent window or float in its own mini-frame window. A toolbar can also "float" and you can
change its size and drag it with a mouse. A toolbar can also display tool tips as the user moves the mouse over
the toolbar's buttons. A tool tip is a tiny popup window that briefly describes the button's purpose.
NOTE
As of MFC version 4.0, class CToolBar uses the Windows toolbar common control. A CToolBar contains a CToolBarCtrl.
Older toolbars are still supported, however. See the article ToolBars.

Status Bars
A status bar is a control bar that contains text-output panes, or "indicators." The output panes are commonly used
as message lines and as status indicators. Message line examples include the command help-message lines that
briefly explain the selected menu or toolbar command in the leftmost pane of the default status bar created by
the MFC Application Wizard. Status indicator examples include the SCROLL LOCK, NUM LOCK, and other keys.
Status bars are usually aligned to the bottom of a frame window. See class CStatusBar and class CStatusBarCtrl.

Dialog Bars
A dialog bar is a control bar, based on a dialog-template resource, with the functionality of a modeless dialog box.
Dialog bars can contain Windows, custom, or ActiveX controls. As in a dialog box, the user can tab among the
controls. Dialog bars can be aligned to the top, bottom, left, or right side of a frame window and they can also be
floated in their own frame window. See class CDialogBar.

Rebars
A rebar is a control bar that provides docking, layout, state, and persistence information for rebar controls. A
rebar object can contain a variety of child windows, usually other controls, including edit boxes, toolbars, and list
boxes. A rebar object can display its child windows over a specified bitmap. It can be automatically or manually
resized by clicking or dragging its gripper bar. See class CReBar.

See also
User Interface Elements
Dialog Bars
4/1/2019 • 2 minutes to read • Edit Online

A dialog bar is a toolbar, a kind of control bar that can contain any kind of control. Because it has the characteristics
of a modeless dialog box, a CDialogBar object provides a more powerful toolbar.
There are several key differences between a toolbar and a CDialogBar object. A CDialogBar object is created from
a dialog-template resource, which you can create with the Visual C++ dialog editor and which can contain any
kind of Windows control. The user can tab from control to control. And you can specify an alignment style to align
the dialog bar with any part of the parent frame window or even to leave it in place if the parent is resized. The
following figure shows a dialog bar with a variety of controls.

A Dialog Bar
In other respects, working with a CDialogBar object is like working with a modeless dialog box. Use the dialog
editor to design and create the dialog resource.
One of the virtues of dialog bars is that they can include controls other than buttons.
While it is normal to derive your own dialog classes from CDialog , you do not typically derive your own class for
a dialog bar. Dialog bars are extensions to a main window and any dialog-bar control-notification messages, such
as BN_CLICKED or EN_CHANGE , will be sent to the parent of the dialog bar, the main window.

See also
User Interface Elements
Sample
Dialog Boxes
9/30/2019 • 2 minutes to read • Edit Online

Applications for Windows frequently communicate with the user through dialog boxes. Class CDialog
provides an interface for managing dialog boxes, the Visual C++ dialog editor makes it easy to design dialog
boxes and create their dialog-template resources, and Code wizards simplify the process of initializing and
validating the controls in a dialog box and of gathering the values entered by the user.
Dialog boxes contain controls, including:
Windows common controls such as edit boxes, pushbuttons, list boxes, combo boxes, tree controls, list
controls, and progress indicators.
ActiveX controls.
Owner-drawn controls: controls that you are responsible for drawing in the dialog box.
Most dialog boxes are modal, which require the user to close the dialog box before using any other part of the
program. But it is possible to create modeless dialog boxes, which let users work with other windows while
the dialog box is open. MFC supports both kinds of dialog box with class CDialog . The controls are arranged
and managed using a dialog-template resource, created with the dialog editor.
Property sheets, also known as tab dialog boxes, are dialog boxes that contain "pages" of distinct dialog-box
controls. Each page has a file folder "tab" at the top. Clicking a tab brings that page to the front of the dialog
box.

What do you want to know more about


Example: Displaying a Dialog Box via a Menu Command
Dialog-box components in the framework
Modal and modeless dialog boxes
Property sheets and property pages in a dialog box
Creating the dialog resource
Creating a dialog class with Code Wizards
Working with Dialog Boxes in MFC
Dialog data exchange (DDX) and validation (DDV)
Type-safe access to controls in a dialog box
Mapping Windows messages to your class
Commonly Overridden Member Functions
Commonly Added Member Functions
Common dialog classes
Dialog boxes in OLE
Create an application whose user interface is a dialog box: see the CMNCTRL1 or CMNCTRL2 sample
programs. The Application Wizard provides this option as well.
Samples

See also
User Interface Elements
Example: Displaying a Dialog Box via a Menu
Command
3/19/2020 • 2 minutes to read • Edit Online

This topic contains procedures to:


Display a modal dialog box through a menu command.
Display a modeless dialog box through a menu command.
Both sample procedures are for MFC applications and will work in an application you create with the MFC
Application Wizard.
The procedures use the following names and values:

IT EM N A M E O R VA L UE

Application DisplayDialog

Menu command Test command on View menu; Command ID = ID_VIEW_TEST

Dialog box Test dialog box; Class = CTestDialog; Header file =


TestDialog.h; Variable = testdlg, ptestdlg

Command handler OnViewTest

To display a modal dialog box


1. Create the menu command; see Creating Menus or Menu Items.
2. Create the dialog box; see Starting the Dialog Editor.
3. Add a class for your dialog box. See Adding a Class for more information.
4. In Class View , select the document class (CDisplayDialogDoc). In the Proper ties window, click the Events
button. Double-click the ID of the menu command (ID_VIEW_TEST). Next, click the down arrow and select
<Add> OnViewTest .
If you added the menu command to the mainframe of an MDI application, select the application class
(CDisplayDialogApp) instead.
5. Add the following include statement to CDisplayDialogDoc.cpp (or CDisplayDialogApp.cpp) after the existing
include statements:

#include "TestDialog.h"

6. Add the following code to OnViewTest to implement the function:

CTestDialog testdlg;
testdlg.DoModal();

To display a modeless dialog box


1. Do the first four steps to display a modal dialog box, except select the view class (CDisplayDialogView) in
step 4.
2. Edit DisplayDialogView.h:
Declare the dialog box class preceding the first class declaration:

class CTestDialog;

Declare a pointer to the dialog box after the Attributes public section:

CTestDialog* m_pTestDlg;

3. Edit DisplayDialogView.cpp:
Add the following include statement after the existing include statements:

#include "TestDialog.h"

Add the following code to the constructor:

m_pTestDlg = NULL;

Add the following code to the destructor:

delete m_pTestDlg;

Add the following code to OnViewTest to implement the function:

if (NULL == m_pTestDlg)
{
m_pTestDlg = new CTestDialog(this);
m_pTestDlg->Create(CTestDialog::IDD, this);
}
m_pTestDlg->ShowWindow(SW_SHOW);

See also
Dialog Boxes
Modal and Modeless Dialog Boxes
Dialog Sample List
4/1/2019 • 2 minutes to read • Edit Online

See the following sample programs that illustrate dialog boxes and property sheets:
MDI Sample Application with Dialog Boxes
SCRIBBLE
Modeless Dialog Box
MODELESS
Property Sheet Dialog Box (Tab Dialog Box)
PROPDLG
CMNCTRL1
CMNCTRL2
Application Based on a Dialog Box
CMNCTRL1
CMNCTRL2
Dialog-Box Controls
CMNCTRL1
CMNCTRL2
CTRLTEST
Dialog-Like Form Views
VIEWEX
In-Memory Dialog Template
DLGTEMPL

See also
Dialog Boxes
Dialog-Box Components in the Framework
9/30/2019 • 2 minutes to read • Edit Online

In the MFC framework, a dialog box has two components:


A dialog-template resource that specifies the dialog box's controls and their placement.
The dialog resource stores a dialog template from which Windows creates the dialog window and displays
it. The template specifies the dialog box's characteristics, including its size, location, style, and the types and
positions of the dialog box's controls. You will usually use a dialog template stored as a resource, but you
can also create your own template in memory.
A dialog class, derived from CDialog, to provide a programmatic interface for managing the dialog box.
A dialog box is a window and will be attached to a Windows window when visible. When the dialog window
is created, the dialog-template resource is used as a template for creating child window controls for the
dialog box.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Modal and Modeless Dialog Boxes
9/30/2019 • 2 minutes to read • Edit Online

You can use class CDialog to manage two kinds of dialog boxes:
Modal dialog boxes, which require the user to respond before continuing the program
Modeless dialog boxes, which stay on the screen and are available for use at any time but permit other user
activities
The resource editing and procedures for creating a dialog template are the same for modal and modeless dialog
boxes.
Creating a dialog box for your program requires the following steps:
1. Use the dialog editor to design the dialog box and create its dialog-template resource.
2. Create a dialog class.
3. Connect the dialog resource's controls to message handlers in the dialog class.
4. Add data members associated with the dialog box's controls and to specify dialog data exchange and dialog
data validations for the controls.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Property Sheets and Property Pages (MFC)
9/30/2019 • 2 minutes to read • Edit Online

An MFC dialog box can take on a "tab dialog" look by incorporating property sheets and property pages. Called a
"property sheet" in MFC, this kind of dialog box, similar to many dialog boxes in Microsoft Word, Excel, and Visual
C++, appears to contain a stack of tabbed sheets, much like a stack of file folders seen from front to back, or a
group of cascaded windows. Controls on the front tab are visible; only the labeled tab is visible on the rear tabs.
Property sheets are particularly useful for managing large numbers of properties or settings that fall fairly neatly
into several groups. Typically, one property sheet can simplify a user interface by replacing several separate dialog
boxes.
As of MFC version 4.0, property sheets and property pages are implemented using the common controls that
come with Windows 95 and Windows NT version 3.51 and later.
Property sheets are implemented with classes CPropertySheet and CPropertyPage (described in the MFC
Reference). CPropertySheet defines the overall dialog box, which can contain multiple "pages" based on
CPropertyPage .

For information on creating and working with property sheets, see the topic Property Sheets.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Property Sheets and Property Pages in MFC
Exchanging Data
Creating a Modeless Property Sheet
Handling the Apply Button
Creating the Dialog Resource
9/30/2019 • 2 minutes to read • Edit Online

To design the dialog box and create the dialog resource, you use the dialog editor. In the dialog editor, you can:
Adjust the size and location your dialog box will have when it appears.
Drag various kinds of controls from a controls palette and drop them where you want them in the dialog
box.
Position the controls with alignment buttons on the toolbar.
Test your dialog box by simulating the appearance and behavior it will have in your program. In Test mode,
you can manipulate the dialog box's controls by typing text in text boxes, clicking pushbuttons, and so on.
When you finish, your dialog-template resource is stored in your application's resource script file. You can edit it
later if needed. For a full description of how to create and edit dialog resources, see the dialog editor topics. This
technique is also used to create the dialog-template resources for CFormView and CRecordView classes.
When the dialog box's appearance suits you, create a dialog class and map its messages, as discussed in Creating a
Dialog Class with Code Wizards.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Creating a Dialog Class with Code Wizards
9/30/2019 • 2 minutes to read • Edit Online

The following table lists dialog-related tasks that Code Wizards help you manage.
Dialog-Related Tasks
TA SK A P P LY TO . . .

Create a new CDialog-derived class to manage your dialog Each dialog box.
box.

Map Windows messages to your dialog class. Each message you want handled.

Declare class member variables to represent the controls in Each control that yields a text or numeric value you want to
the dialog box. access from your program.

Specify how data is to be exchanged between the controls Each control you want to access from your program.
and the member variables.

Specify validation rules for the member variables. Each control that yields a text or numeric value, if desired.

What do you want to know more about


Creating your dialog class
Handling Windows messages in your dialog box
Dialog data exchange and validation

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Creating Your Dialog Class
9/30/2019 • 2 minutes to read • Edit Online

For each dialog box in your program, create a new dialog class to work with the dialog resource.
Adding a Class explains how to create a new dialog class. When you create a dialog class with the Class Wizard, it
writes the following items in the .h and .cpp files you specify:
In the .h file:
A class declaration for the dialog class. The class is derived from CDialog.
In the .cpp file:
A message map for the class.
A standard constructor for the dialog box.
An override of the DoDataExchange member function. Edit this function. It is used for dialog data exchange
and validation capabilities as described later in Dialog data exchange and validation.

See also
Creating a Dialog Class with Code Wizards
Working with Dialog Boxes in MFC
Working with Dialog Boxes in MFC
9/30/2019 • 2 minutes to read • Edit Online

During the life cycle of a dialog box, the user invokes the dialog box, typically inside a command handler that
creates and initializes the dialog object, the user interacts with the dialog box, then dialog box closes.
For modal dialog boxes, your handler gathers any data the user entered once the dialog box closes. Since the
dialog object exists after its dialog window has closed, you can simply use the member variables of your dialog
class to extract the data.
For modeless dialog boxes, you may often extract data from the dialog object while the dialog box is still
visible. At some point, the dialog object is destroyed; when this happens depends on your code.

What do you want to know more about


Creating and displaying dialog boxes
Creating modal dialog boxes
Creating modeless dialog boxes
Using a dialog template in memory
Setting the dialog box's background color
Initializing the dialog box
Handling Windows messages in your dialog box
Retrieving data from the dialog object
Closing the dialog box
Destroying the dialog box
Dialog data exchange (DDX) and validation (DDV)
Property sheet dialog boxes

See also
Dialog Boxes
Creating and Displaying Dialog Boxes
9/30/2019 • 2 minutes to read • Edit Online

Creating a dialog object is a two-phase operation. First, construct the dialog object, then create the dialog window.
Modal and modeless dialog boxes differ somewhat in the process used to create and display them. The following
table lists how modal and modeless dialog boxes are normally constructed and displayed.
Dialog Creation
DIA LO G T Y P E H O W TO C REAT E IT

Modeless Construct CDialog , then call Create member function.

Modal Construct CDialog , then call DoModal member function.

You can, if you want, create your dialog box from an in-memory dialog template that you have constructed rather
than from a dialog template resource. This is an advanced topic, however.

See also
Working with Dialog Boxes in MFC
Creating Modal Dialog Boxes
9/30/2019 • 2 minutes to read • Edit Online

To create a modal dialog box, call either of the two public constructors declared in CDialog. Next, call the dialog
object's DoModal member function to display the dialog box and manage interaction with it until the user chooses
OK or Cancel. This management by DoModal is what makes the dialog box modal. For modal dialog boxes,
DoModal loads the dialog resource.

See also
Working with Dialog Boxes in MFC
Creating Modeless Dialog Boxes
9/30/2019 • 2 minutes to read • Edit Online

For a modeless dialog box, you must provide your own public constructor in your dialog class. To create a
modeless dialog box, call your public constructor and then call the dialog object's Create member function to load
the dialog resource. You can call Create either during or after the constructor call. If the dialog resource has the
property WS_VISIBLE , the dialog box appears immediately. If not, you must call its ShowWindow member
function.

See also
Working with Dialog Boxes in MFC
Using a Dialog Template in Memory
9/30/2019 • 2 minutes to read • Edit Online

Instead of using the methods given in the Dialog Creation table, you can create either kind of dialog box indirectly
from a dialog template in memory. For more information, see class CDialog in the MFC Reference.

See also
Working with Dialog Boxes in MFC
Setting the Dialog Box’s Background Color
9/30/2019 • 2 minutes to read • Edit Online

You can set the background color of your dialog boxes by handling WM_CTLCOLOR messages for the dialog box
window. The color you set is used for only the specified dialog box.
See codexpert blog for an example.

See also
Working with Dialog Boxes in MFC
Handling Windows Messages in Your Dialog Box
Initializing the Dialog Box
9/30/2019 • 2 minutes to read • Edit Online

After the dialog box and all of its controls are created but just before the dialog box (of either type) appears on the
screen, the dialog object's OnInitDialog member function is called. For a modal dialog box, this occurs during the
DoModal call. For a modeless dialog box, OnInitDialog is called when Create is called. You typically override
OnInitDialog to initialize the dialog box's controls, such as setting the initial text of an edit box. You must call the
OnInitDialog member function of the base class, CDialog , from your OnInitDialog override.

If you want to set your dialog box's background color (and that of all other dialog boxes in your application), see
Setting the Dialog Box's Background Color.

See also
Working with Dialog Boxes in MFC
Handling Windows Messages in Your Dialog Box
9/30/2019 • 2 minutes to read • Edit Online

Dialog boxes are windows, so they can handle Windows messages if you supply the appropriate handler functions.
When you create your dialog class with the Class Wizard, the wizard adds an empty message map to the class. Use
the wizard to map any Windows messages or commands you want your class to handle.
See Mapping Windows Messages to Your Dialog Class for more information.

See also
Working with Dialog Boxes in MFC
Retrieving Data from the Dialog Object
9/30/2019 • 2 minutes to read • Edit Online

The framework provides an easy way to initialize the values of controls in a dialog box and to retrieve values from
the controls. The more laborious manual approach is to call functions such as the SetDlgItemText and
GetDlgItemText member functions of class CWnd , which apply to control windows. With these functions, you
access each control individually to set or get its value, calling functions such as SetWindowText and GetWindowText .
The framework's approach automates both initialization and retrieval.
Dialog data exchange (DDX) lets you exchange data between the controls in the dialog box and member variables
in the dialog object more easily. This exchange works both ways. To initialize the controls in the dialog box, you can
set the values of data members in the dialog object, and the framework will transfer the values to the controls
before the dialog box is displayed. Then you can at any time update the dialog data members with data entered by
the user. At that point, you can use the data by referring to the data member variables.
You can also arrange for the values of dialog controls to be validated automatically with dialog data validation
(DDV).
DDX and DDV are explained in more detail in Dialog Data Exchange and Validation.
For a modal dialog box, you can retrieve any data the user entered when DoModal returns IDOK but before the
dialog object is destroyed. For a modeless dialog box, you can retrieve data from the dialog object at any time by
calling UpdateData with the argument TRUE and then accessing dialog class member variables. This subject is
discussed in more detail in Dialog Data Exchange and Validation.

See also
Working with Dialog Boxes in MFC
Closing the Dialog Box
9/30/2019 • 2 minutes to read • Edit Online

A modal dialog box closes when the user chooses one of its buttons, typically the OK button or the Cancel button.
Choosing the OK or Cancel button causes Windows to send the dialog object a BN_CLICKED control-notification
message with the button's ID, either IDOK or IDCANCEL . CDialog provides default handler functions for these
messages: OnOK and OnCancel . The default handlers call the EndDialog member function to close the dialog
window. You can also call EndDialog from your own code. For more information, see the EndDialog member
function of class CDialog in the MFC Reference.
To arrange for closing and deleting a modeless dialog box, override PostNcDestroy and invoke the delete operator
on the this pointer. Destroying the Dialog Box explains what happens next.

See also
Working with Dialog Boxes in MFC
Destroying the Dialog Box
9/30/2019 • 2 minutes to read • Edit Online

Modal dialog boxes are normally created on the stack frame and destroyed when the function that created them
ends. The dialog object's destructor is called when the object goes out of scope.
Modeless dialog boxes are normally created and owned by a parent view or frame window — the application's
main frame window or a document frame window. The default OnClose handler calls DestroyWindow, which
destroys the dialog-box window. If the dialog box stands alone, with no pointers to it or other special ownership
semantics, you should override PostNcDestroy to destroy the C++ dialog object. You should also override
OnCancel and call DestroyWindow from within it. If not, the owner of the dialog box should destroy the C++ object
when it is no longer necessary.

See also
Working with Dialog Boxes in MFC
Dialog Data Exchange and Validation
9/30/2019 • 2 minutes to read • Edit Online

Dialog data exchange (DDX) is an easy way to initialize the controls in your dialog box and to gather
data input by the user. Dialog data validation (DDV) is an easy way to validate data entry in a dialog box.
To take advantage of DDX and DDV in your dialog boxes, use the Add Member Variable Wizard to create
the data members and set their data types and specify validation rules.

What do you want to know more about


Dialog data exchange
Dialog data validation

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Dialog Data Exchange
9/30/2019 • 2 minutes to read • Edit Online

If you use the DDX mechanism, you set the initial values of the dialog object's member variables, typically in your
OnInitDialog handler or the dialog constructor. Immediately before the dialog is displayed, the framework's DDX
mechanism transfers the values of the member variables to the controls in the dialog box, where they appear
when the dialog box itself appears in response to DoModal or Create . The default implementation of
OnInitDialog in CDialog calls the UpdateData member function of class CWnd to initialize the controls in the
dialog box.
The same mechanism transfers values from the controls to the member variables when the user clicks the OK
button (or whenever you call the UpdateData member function with the argument TRUE ). The dialog data
validation mechanism validates any data items for which you specified validation rules.
The following figure illustrates dialog data exchange.

Dialog Data Exchange


UpdateData works in both directions, as specified by the BOOL parameter passed to it. To carry out the exchange,
UpdateData sets up a CDataExchange object and calls your dialog class's override of CDialog 's DoDataExchange
member function. DoDataExchange takes an argument of type CDataExchange . The CDataExchange object passed to
UpdateData represents the context of the exchange, defining such information as the direction of the exchange.

When you (or a Code wizard) override DoDataExchange , you specify a call to one DDX function per data member
(control). Each DDX function knows how to exchange data in both directions based on the context supplied by the
CDataExchange argument passed to your DoDataExchange by UpdateData .

MFC provides many DDX functions for different kinds of exchange. The following example shows a
DoDataExchange override in which two DDX functions and one DDV function are called:

void CTestDialog::DoDataExchange(CDataExchange* pDX)


{
CDialog::DoDataExchange(pDX);
DDX_Check(pDX, IDC_MY_CHECKBOX, m_bVal);
DDX_Text(pDX, IDC_MY_TEXTBOX, m_strName);
DDV_MaxChars(pDX, m_strName, 20);
}

The DDX_ and DDV_ lines are a data map. The sample DDX and DDV functions shown are for a check-box control
and an edit-box control, respectively.
If the user cancels a modal dialog box, the OnCancel member function terminates the dialog box and DoModal
returns the value IDCANCEL . In that case, no data is exchanged between the dialog box and the dialog object.
See also
Dialog Data Exchange and Validation
Working with Dialog Boxes in MFC
Dialog Data Validation
Dialog Data Validation
9/30/2019 • 2 minutes to read • Edit Online

You can specify validation in addition to data exchange by calling DDV functions, as shown in the example in
Dialog Data Exchange. The DDV_MaxChars call in the example validates that the string entered in the text-box
control is not longer than 20 characters. The DDV function typically alerts the user with a message box if the
validation fails and puts the focus on the offending control so the user can reenter the data. A DDV function for a
given control must be called immediately after the DDX function for the same control.
You can also define your own custom DDX and DDV routines. For details on this and other aspects of DDX and
DDV, see MFC Technical Note 26.
The Add Member Variable Wizard will write all of the DDX and DDV calls in the data map for you.

See also
Dialog Data Exchange and Validation
Working with Dialog Boxes in MFC
Dialog Data Exchange
Type-Safe Access to Controls in a Dialog Box
3/4/2019 • 2 minutes to read • Edit Online

The controls in a dialog box can use the interfaces of MFC control classes such as CListBox and CEdit . You can
create a control object and attach it to a dialog control. Then you can access the control through its class interface,
calling member functions to operate on the control. The methods described here are designed to give you type-
safe access to a control. This is especially useful for controls such as edit boxes and list boxes.
There are two approaches to making a connection between a control in a dialog box and a C++ control member
variable in a CDialog -derived class:
Without Code Wizards
With Code Wizards

See also
Dialog Boxes
Type-Safe Access to Controls Without Code Wizards
3/4/2019 • 2 minutes to read • Edit Online

The first approach to creating type-safe access to controls uses an inline member function to cast the return type of
class CWnd 's GetDlgItem member function to the appropriate C++ control type, as in this example:

CButton* CMyDialog::GetMyCheckbox()
{
return (CButton*)GetDlgItem(IDC_CHECKBOX);
}

You can then use this member function to access the control in a type-safe manner with code similar to the
following:

GetMyCheckbox()->SetCheck(BST_CHECKED);

See also
Type-Safe Access to Controls in a Dialog Box
Type-Safe Access to Controls With Code Wizards
Type-Safe Access to Controls With Code Wizards
3/27/2020 • 2 minutes to read • Edit Online

If you are familiar with DDX features, you can use the Control property in the Add Member Variable Wizard to
create type-safe access. This approach is easier than creating controls without code wizards.
If you simply want access to a control's value, DDX provides it. If you want to do more than access a control's value,
use the Add Member Variable Wizard to add a member variable of the appropriate class to your dialog class.
Attach this member variable to the Control property.
Member variables can have a Control property instead of a Value property. The Value property refers to the type
of data returned from the control, such as CString or int . The Control property enables direct access to the
control through a data member whose type is one of the control classes in MFC, such as CButton or CEdit .

NOTE
For a given control, you can, if you wish, have multiple member variables with the Value property and at most one member
variable with the Control property. You can have only one MFC object mapped to a control because multiple objects
attached to a control, or any other window, would lead to an ambiguity in the message map.

You can use this object to call any member functions for the control object. Such calls affect the control in the
dialog box. For example, for a check-box control represented by a variable m_Checkbox, of type CButton , you
could call:

m_Checkbox.SetCheck(BST_CHECKED);

Here the member variable m_Checkbox serves the same purpose as the member function GetMyCheckbox shown
in Type-Safe Access to Controls Without Code Wizards. If the check box is not an auto check box, you would still
need a handler in your dialog class for the BN_CLICKED control-notification message when the button is clicked.
For more information about controls, see Controls.

See also
Type-Safe Access to Controls in a Dialog Box
Working with Dialog Boxes in MFC
Type-Safe Access to Controls Without Code Wizards
Mapping Windows Messages to Your Class
9/30/2019 • 2 minutes to read • Edit Online

If you need your dialog box to handle Windows messages, override the appropriate handler functions. To do so,
choose the Class View tab in Solution Explorer , right click on the class that represents the dialog box, and
choose Class Wizard. Use the wizard to map the messages to the dialog class. This writes a message-map entry for
each message and adds the message-handler member functions to the class. Use the code editor to write code in
the message handlers.
You can also override member functions of CDialog and its base classes, especially CWnd.

What do you want to know more about


Message handling and mapping
Commonly overridden member functions
Commonly added member functions

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Commonly Overridden Member Functions
9/30/2019 • 2 minutes to read • Edit Online

The following table lists the most likely member functions to override in your CDialog -derived class.
Commonly Overridden Member Functions of Class CDialog
M EM B ER F UN C T IO N M ESSA GE IT RESP O N DS TO P URP O SE O F T H E O VERRIDE

OnInitDialog WM_INITDIALOG Initialize the dialog box's controls.

OnOK BN_CLICKED for button IDOK Respond when the user clicks the OK
button.

OnCancel BN_CLICKED for button IDCANCEL Respond when the user clicks the
Cancel button.

OnInitDialog , OnOK , and OnCancel are virtual functions. To override them, you declare an overriding function in
your derived dialog class using the MFC Class Wizard.
OnInitDialog is called just before the dialog box is displayed. You must call the default OnInitDialog handler from
your override — usually as the first action in the handler. By default, OnInitDialog returns TRUE to indicate that
the focus should be set to the first control in the dialog box.
OnOK is typically overridden for modeless but not modal dialog boxes. If you override this handler for a modal
dialog box, call the base class version from your override — to ensure that EndDialog is called — or call
EndDialog yourself.

OnCancel is usually overridden for modeless dialog boxes.


For more information about these member functions, see class CDialog in the MFC Reference and the discussion
on Working with Dialog Boxes in MFC.

See also
Dialog Boxes
Commonly Added Member Functions
Commonly Added Member Functions
9/30/2019 • 2 minutes to read • Edit Online

If your dialog box contains pushbuttons other than OK or Cancel, you need to write message-handler member
functions in your dialog class to respond to the control-notification messages they generate. For an example, see
the Scribble sample program. You can also handle control-notification messages from other controls in your
dialog box.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Commonly Overridden Member Functions
Common Dialog Classes
9/30/2019 • 2 minutes to read • Edit Online

In addition to class CDialog, MFC supplies several classes derived from CDialog that encapsulate commonly used
dialog boxes, as shown in the following table. The dialog boxes encapsulated are called the "common dialog
boxes" and are part of the Windows common dialog library (COMMDLG.DLL). The dialog-template resources and
code for these classes are provided in the Windows common dialog boxes that are part of Windows versions 3.1
and later.
Common Dialog Classes
DERIVED DIA LO G C L A SS P URP O SE

CColorDialog Lets user select colors.

CFileDialog Lets user select a filename to open or to save.

CFindReplaceDialog Lets user initiate a find or replace operation in a text file.

CFontDialog Lets user specify a font.

CPrintDialog Lets user specify information for a print job.

CPrintDialogEx Windows Print property sheet.

For more information about the common dialog classes, see the individual class names in the MFC Reference. MFC
also supplies a number of standard dialog classes used for OLE. For information about these classes, see the base
class, COleDialog, in the MFC Reference.
Three other classes in MFC have dialog-like characteristics. For information about classes CFormView,
CRecordView, and CDaoRecordView, see the classes in the MFC Reference. For information about class CDialogBar,
see Dialog Bars.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
Dialog Boxes in OLE
Dialog Boxes in OLE
9/30/2019 • 3 minutes to read • Edit Online

While a user runs an OLE-enabled application, there are times when the application needs information from the
user in order to carry out the operation. The MFC OLE classes provide a number of dialog boxes to gather the
required information. This topic lists the tasks handled by the OLE dialog boxes and the classes needed to display
those dialog boxes. For details on OLE dialog boxes and the structures used to customize their behavior, see MFC
Reference.
Insert Object
This dialog box allows the user to insert newly created or existing objects into the compound document. It also
allows the user to choose to display the item as an icon and enables the Change Icon command button. Display
this dialog box when the user chooses Insert Object from the Edit menu. Use the COleInsertDialog class to
display this dialog box. Note that you cannot insert an MDI application into itself. An application that is a
container/server cannot be inserted into itself unless it is an SDI application.
Paste Special
This dialog box allows the user to control the format used when pasting data into a compound document. The
user can choose the format of the data, whether to embed or link the data, and whether to display it as an icon.
Display this dialog box when the user chooses Paste Special from the Edit menu. Use the COlePasteSpecialDialog
class to display this dialog box.
Change Icon
This dialog box allows the user to select which icon is displayed to represent the linked or embedded item.
Display this dialog box when the user chooses Change Icon from the Edit menu or chooses the Change Icon
button in either the Paste Special or Convert dialog boxes. Also display it when the user opens the Insert Object
dialog box and chooses Display as Icon. Use the COleChangeIconDialog class to display this dialog box.
Convert
This dialog box allows the user to change the type of an embedded or linked item. For example, if you have
embedded a metafile in a compound document and later want to use another application to modify the
embedded metafile, you can use the Convert dialog box. This dialog box is usually displayed by clicking item type
Object on the Edit menu and then, on the cascading menu, clicking Convert. Use the COleConvertDialog class to
display this dialog box. For an example, run the MFC OLE sample OCLIENT.
Edit Links or Update Links
The Edit Links dialog box allows the user to change information about the source of a linked object. The Update
Links dialog box verifies the sources of all the linked items in the current dialog box and displays the Edit Links
dialog box if necessary. Display the Edit Links dialog box when the user chooses Links from the Edit menu. The
Update Links dialog box is usually displayed when a compound document is first opened. Use either the
COleLinksDialog or the COleUpdateDialog class, depending on which dialog box you want to display.
Server Busy or Server Not Responding
The Server Busy dialog box is displayed when the user attempts to activate an item and the server is currently
unable to handle the request, usually because the server is in use by another user or task. The Server Not
Responding dialog box is displayed if the server does not respond to the activation request at all. These dialog
boxes are displayed via COleMessageFilter , based on an implementation of the OLE interface IMessageFilter ,
and the user can decide whether to attempt the activation request again. Use the COleBusyDialog class to display
this dialog box.

See also
Dialog Boxes
Working with Dialog Boxes in MFC
OLE
Walkthrough: Adding a CTaskDialog to an
Application
9/18/2019 • 5 minutes to read • Edit Online

This walkthrough introduces the CTaskDialog Class and shows you how to add one to your application.
The CTaskDialogis a task dialog box that replaces the Windows message box in Windows Vista or later. The
CTaskDialog improves the original message box and adds functionality. The Windows message box is still
supported in Visual Studio.

NOTE
Versions of Windows earlier than Windows Vista do not support the CTaskDialog . You must program an alternative dialog
box option if you want to show a message to a user who runs your application on an earlier version of Windows. You can use
the static method CTaskDialog::IsSupported to determine at run time whether a user's computer can display a CTaskDialog .
In addition, the CTaskDialog is only available when your application is built with the Unicode library.

The CTaskDialog supports several optional elements to gather and display information. For example, a
CTaskDialog can display command links, customized buttons, customized icons, and a footer. The CTaskDialog also
has several methods that enable you to query the state of the task dialog box to determine what optional elements
the user selected.

Prerequisites
You need the following components to complete this walkthrough:
Visual Studio 2010 or later
Windows Vista or later

Replacing a Windows Message Box with a CTaskDialog


The following procedure demonstrates the most basic use of the CTaskDialog , which is to replace the Windows
message box. This example also changes the icon associated with the task dialog box. Changing the icon makes the
CTaskDialog appear same to the Windows message box.

To Replace a Windows Message Box with a CTaskDialog


1. Use the MFC Application Wizard to create an MFC application with all the default settings. See
Walkthrough: Using the New MFC Shell Controls for instructions on how to open the wizard for your version
of Visual Studio.
2. Call it MyProject.
3. Use the Solution Explorer to open the file MyProject.cpp.
4. Add #include "afxtaskdialog.h" after the list of includes.
5. Find the method CMyProjectApp::InitInstance . Insert the following lines of code before the return TRUE;
statement. This code creates the strings that we use in either the Windows message box or in the
CTaskDialog .
CString message("My message to the user");
CString dialogTitle("My Task Dialog title");
CString emptyString;

6. Add the following code after the code from step 4. This code guarantees that the user's computer supports
the CTaskDialog . If the dialog isn't supported, the application displays a Windows message box instead.

if (CTaskDialog::IsSupported())
{

}
else
{
AfxMessageBox(message);
}

7. Insert the following code between the brackets after the if statement from step 5. This code creates the
CTaskDialog .

CTaskDialog taskDialog(message, emptyString, dialogTitle, TDCBF_OK_BUTTON);

8. On the next line, add the following code. This code sets the warning icon.

taskDialog.SetMainIcon(TD_WARNING_ICON);

9. On the next line, add the following code. This code displays the task dialog box.

taskDialog.DoModal();

You can avoid step 7 if you don't want the CTaskDialog to display the same icon as the Windows message box. If
you avoid that step, the CTaskDialog has no icon when the application displays it.
Compile and run the application. The application displays the task dialog box after it starts.

Adding Functionality to the CTaskDialog


The following procedure shows you how to add functionality to the CTaskDialog that you created in the previous
procedure. The example code shows you how to execute specific instructions based on the user's selections.
To Add Functionality to the CTaskDialog
1. Navigate to the Resource View . If you can't see the Resource View , you can open it from the View menu.
2. Expand the Resource View until you can select the String Table folder. Expand it and double-click the
String Table entry.
3. Scroll to the bottom of the string table and add a new entry. Change the ID to TEMP_LINE1 . Set the caption to
Command Line 1 .
4. Add another new entry. Change the ID to TEMP_LINE2 . Set the caption to Command Line 2 .
5. Navigate back to MyProject.cpp.
6. After CString emptyString; , add the following code:
CString expandedLabel("Hide extra information");
CString collapsedLabel("Show extra information");
CString expansionInfo("This is the additional information to the user,\nextended over two lines.");

7. Find the taskDialog.DoModal() statement and replace that statement with the following code. This code
updates the task dialog box and adds new controls:

taskDialog.SetMainInstruction(L"Warning");
taskDialog.SetCommonButtons(
TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
taskDialog.LoadCommandControls(TEMP_LINE1, TEMP_LINE2);
taskDialog.SetExpansionArea(
expansionInfo, collapsedLabel, expandedLabel);
taskDialog.SetFooterText(L"This is the a small footnote to the user");
taskDialog.SetVerificationCheckboxText(L"Remember your selection");

8. Add the following line of code that displays the task dialog box to the user and retrieves the user's selection:

INT_PTR result = taskDialog.DoModal();

9. Insert the following code after the call to taskDialog.DoModal() . This section of code processes the user's
input:

if (taskDialog.GetVerificationCheckboxState())
{
// PROCESS IF the user selects the verification checkbox
}

switch (result)
{
case TEMP_LINE1:
// PROCESS IF the first command line
break;
case TEMP_LINE2:
// PROCESS IF the second command line
break;
case IDYES:
// PROCESS IF the user clicks yes
break;
case IDNO:
// PROCESS IF the user clicks no
break;
case IDCANCEL:
// PROCESS IF the user clicks cancel
break;
default:
// This case should not be hit because closing
// the dialog box results in IDCANCEL
break;
}

In the code in step 9, replace the comments that start with PROCESS IF with the code that you want to execute
under the specified conditions.
Compile and run the application. The application displays the task dialog box that uses the new controls and
additional information.

Displaying a CTaskDialog Without Creating a CTaskDialog Object


The following procedure shows you how to display a CTaskDialog without first creating a CTaskDialog object. This
example continues the previous procedures.
To Display a CTaskDialog Without Creating a CTaskDialog Object
1. Open the MyProject.cpp file if it isn't already open.
2. Navigate to the closing bracket for the if (CTaskDialog::IsSupported()) statement.
3. Insert the following code immediately before the closing bracket of the if statement (before the else
block):

HRESULT result2 = CTaskDialog::ShowDialog(L"My error message",


L"Error",
L"New Title",
TEMP_LINE1,
TEMP_LINE2);

Compile and run the application. The application displays two task dialog boxes. The first dialog box is from the To
Add Functionality to the CTaskDialog procedure; the second dialog box is from the last procedure.
These examples don't demonstrate all the available options for a CTaskDialog , but should help you get started. See
CTaskDialog Class for a full description of the class.

See also
Dialog Boxes
CTaskDialog Class
CTaskDialog::CTaskDialog
Document/View Architecture
4/1/2019 • 3 minutes to read • Edit Online

By default, the MFC Application Wizard creates an application skeleton with a document class and a view class.
MFC separates data management into these two classes. The document stores the data and manages printing
the data and coordinates updating multiple views of the data. The view displays the data and manages user
interaction with it, including selection and editing.
In this model, an MFC document object reads and writes data to persistent storage. The document may also
provide an interface to the data wherever it resides (such as in a database). A separate view object manages data
display, from rendering the data in a window to user selection and editing of data. The view obtains display data
from the document and communicates back to the document any data changes.
While you can easily override or ignore the document/view separation, there are compelling reasons to follow
this model in most cases. One of the best is when you need multiple views of the same document, such as both
a spreadsheet and a chart view. The document/view model lets a separate view object represent each view of
the data, while code common to all views (such as a calculation engine) can reside in the document. The
document also takes on the task of updating all views whenever the data changes.
The MFC document/view architecture makes it easy to support multiple views, multiple document types, splitter
windows, and other valuable user-interface features.
The parts of the MFC framework most visible both to the user and to you, the programmer, are the document
and view. Most of your work in developing an application with the framework goes into writing your document
and view classes. This article family describes:
The purposes of documents and views and how they interact in the framework.
What you must do to implement them.
At the heart of document/view are four key classes:
The CDocument (or COleDocument) class supports objects used to store or control your program's data and
provides the basic functionality for programmer-defined document classes. A document represents the unit of
data that the user typically opens with the Open command on the File menu and saves with the Save command
on the File menu.
The CView (or one of its many derived classes) provides the basic functionality for programmer-defined view
classes. A view is attached to a document and acts as an intermediary between the document and the user: the
view renders an image of the document on the screen and interprets user input as operations upon the
document. The view also renders the image for both printing and print preview.
CFrameWnd (or one of its variations) supports objects that provides the frame around one or more views of a
document.
CDocTemplate (or CSingleDocTemplate or CMultiDocTemplate) supports an object that coordinates one or more
existing documents of a given type and manages creating the correct document, view, and frame window
objects for that type.
The following figure shows the relationship between a document and its view.
Document and View
The document/view implementation in the class library separates the data itself from its display and from user
operations on the data. All changes to the data are managed through the document class. The view calls this
interface to access and update the data.
Documents, their associated views, and the frame windows that frame the views are created by a document
template. The document template is responsible for creating and managing all documents of one document
type.

What do you want to know more about


A portrait of the document/view architecture
Advantages of the document/view architecture
Document and view classes created by the Application Wizard
Alternatives to the document/view architecture
Adding Multiple Views to a Single Document
Using Documents
Using Views
Multiple Document Types, Views, and Frame Windows
Initializing and cleaning up documents and views
Initialize your own additions to document & view classes
Using database classes with documents and views
Using database classes without documents and views
Samples

See also
User Interface Elements
Windows
Frame Windows
Document Templates and the Document/View Creation Process
Document/View Creation
Creating New Documents, Windows, and Views
Document/View Sample List
4/1/2019 • 2 minutes to read • Edit Online

See the following sample programs that illustrate using MFC's document/view architecture in interesting ways:
Document/View Variations
MDI
SCRIBBLE
VIEWEX
Dialog-Box Interface Replaces Document/View
CMNCTRL1
CMNCTRL2
Using COleDocument and Its Derived Classes
CONTAINER
HIERSVR
OCLIENT

See also
Document/View Architecture
A Portrait of the Document/View Architecture
3/4/2019 • 2 minutes to read • Edit Online

Documents and views are paired in a typical MFC application. Data is stored in the document, but the view has
privileged access to the data. The separation of document from view separates the storage and maintenance of
data from its display.

Gaining Access to Document Data from the View


The view accesses its document's data either with the GetDocument function, which returns a pointer to the
document, or by making the view class a C++ friend of the document class. The view then uses its access to the
data to obtain the data when it is ready to draw or otherwise manipulate it.
For example, from the view's OnDraw member function, the view uses GetDocument to obtain a document pointer.
Then it uses that pointer to access a CString data member in the document. The view passes the string to the
TextOut function. To see the code for this example, see Drawing in a View.

User Input to the View


The view might also interpret a mouse click within itself as either selection or editing of data. Similarly it might
interpret keystrokes as data entry or editing. Suppose the user types a string in a view that manages text. The view
obtains a pointer to the document and uses the pointer to pass the new data to the document, which stores it in
some data structure.

Updating Multiple Views of the Same Document


In an application with multiple views of the same document — such as a splitter window in a text editor — the view
first passes the new data to the document. Then it calls the document's UpdateAllViews member function, which
tells all views of the document to update themselves, reflecting the new data. This synchronizes the views.
What do you want to know more about
Advantages of the document/view architecture
Alternatives to the document/view architecture

See also
Document/View Architecture
Advantages of the Document/View Architecture
3/4/2019 • 2 minutes to read • Edit Online

The key advantage to using the MFC document/view architecture is that the architecture supports multiple views
of the same document particularly well. (If you don't need multiple views and the small overhead of
document/view is excessive in your application, you can avoid the architecture. Alternatives to the Document/View
Architecture.)
Suppose your application lets users view numerical data either in spreadsheet form or in chart form. A user might
want to see simultaneously both the raw data, in spreadsheet form, and a chart that results from the data. You
display these separate views in separate frame windows or in splitter panes within a single window. Now suppose
the user can edit the data in the spreadsheet and see the changes instantly reflected in the chart.
In MFC, the spreadsheet view and the chart view would be based on different classes derived from CView. Both
views would be associated with a single document object. The document stores the data (or perhaps obtains it
from a database). Both views access the document and display the data they retrieve from it.
When a user updates one of the views, that view object calls CDocument::UpdateAllViews . That function notifies all
of the document's views, and each view updates itself using the latest data from the document. The single call to
UpdateAllViews synchronizes the different views.

This scenario would be difficult to code without the separation of data from view, particularly if the views stored
the data themselves. With document/view, it's easy. The framework does most of the coordination work for you.

What do you want to know more about


Alternatives to document/view
CDocument
CView
CDocument::UpdateAllViews
CView::GetDocument

See also
Document/View Architecture
Document and View Classes Created by the MFC
Application Wizard
3/4/2019 • 2 minutes to read • Edit Online

The MFC Application Wizard gives you a head start on your program development by creating skeletal document
and view classes for you. You can then map commands and messages to these classes and use the Visual C++
source code editor to write their member functions.
The document class created by the MFC Application Wizard is derived from class CDocument. The view class is
derived from CView. The names that the Application Wizard gives these classes and the files that contain them are
based on the project name you supply in the Application Wizard dialog box. In the Application Wizard, you can use
the Generated Classes page to alter the default names.
Some applications might need more than one document class, view class, or frame-window class. For more
information, see Multiple Document Types, Views, and Frame Windows.

See also
Document/View Architecture
Alternatives to the Document/View Architecture
3/27/2020 • 3 minutes to read • Edit Online

MFC applications normally use the document/view architecture to manage information, file formats, and the
visual representation of data to users. For the majority of desktop applications, the document/view architecture is
an appropriate and efficient application architecture. This architecture separates data from viewing and, in most
cases, simplifies your application and reduces redundant code.
However, the document/view architecture is not appropriate for some situations. Consider these examples:
If you are porting an application written in C for Windows, you might want to complete your port before
adding document/view support to your application.
If you are writing a lightweight utility, you might find that you can do without the document/view
architecture.
If your original code already mixes data management with data viewing, moving the code to the
document/view model is not worth the effort because you must separate the two. You might prefer to leave
the code as is.
To create an application that does not use the document/view architecture, clear the Document/View
architecture suppor t check box in step 1 of the MFC Application Wizard. See MFC Application Wizard for
details.

NOTE
Dialog-based applications produced by the MFC Application Wizard do not use the document/view architecture, so the
Document/View architecture suppor t check box is disabled if you select the dialog application type.

The Visual C++ wizards, as well as the source and dialog editors, work with the generated application just as they
would with any other Wizard-generated application. The application can support toolbars, scrollbars, and a status
bar, and has an About box. Your application will not register any document templates, and it will not contain a
document class.
Note that your generated application has a view class, CChildView , derived from CWnd . MFC creates and positions
one instance of the view class within the frame windows created by your application. MFC still enforces using a
view window, because it simplifies positioning and managing the application's content. You can add painting code
to the OnPaint member of this class. Your code should add scrollbars to the view rather than to the frame.
Because the document/view architecture provided by MFC is responsible for implementing many of an
application's basic features, its absence in your project means that you are responsible for implementing many
important features of your application:
As provided by the MFC Application Wizard, the menu for your application contains only New and Exit
commands on the File menu. (The New command is supported only for MDI applications, not SDI
applications without Document/View support.) The generated menu resource will not support an MRU
(most recently used) list.
You must add handler functions and implementations for any commands that your application will support,
including Open and Save on the File menu. MFC normally provides code to support these features, but
that support is tightly bound to the document/view architecture.
The toolbar for your application, if you requested one, will be minimal.
It is strongly recommended that you use the MFC Application Wizard to create applications without the
document/view architecture, because the wizard guarantees a correct MFC architecture. However, if you must
avoid using the wizard, here are several approaches for bypassing the document/view architecture in your code:
Treat the document as an unused appendage and implement your data management code in the view class,
as suggested above. Overhead for the document is relatively low. A single CDocument object incurs a small
amount of overhead by itself, plus the small overhead of CDocument 's base classes, CCmdTarget and
CObject. Both of the latter classes are small.
Declared in CDocument :
Two CString objects.
Three BOOL s.
One CDocTemplate pointer.
One CPtrList object, which contains a list of the document's views.
Additionally, the document requires the amount of time to create the document object, its view objects, a
frame window, and a document template object.
Treat both the document and view as unused appendages. Put your data management and drawing code in
the frame window rather than the view. This approach is closer to the C-language programming model.
Override the parts of the MFC framework that create the document and view to eliminate creating them at
all. The document creation process begins with a call to CWinApp::AddDocTemplate . Eliminate that call from
your application class's InitInstance member function and, instead, create a frame window in
InitInstance yourself. Put your data management code in your frame window class. The document/view
creation process is illustrated in Document/View Creation. This is more work and requires a deeper
understanding of the framework, but it frees you entirely of the document/view overhead.
The article MFC: Using Database Classes Without Documents and Views gives more concrete examples of
document/view alternatives in the context of database applications.

See also
Document/View Architecture
Using Documents
3/4/2019 • 2 minutes to read • Edit Online

Working together, documents and views:


Contain, manage, and display your application-specific data.
Provide an interface consisting of document data variables for manipulating the data.
Participate in writing and reading files.
Participate in printing.
Handle most of your application's commands and messages.
The document is particularly involved in managing data. Store your data, normally, in document class member
variables. The view uses these variables to access the data for display and update. The document's default
serialization mechanism manages reading and writing the data to and from files. Documents can also handle
commands (but not Windows messages other than WM_COMMAND).

What do you want to know more about


Deriving a document class from CDocument
Managing data with document data variables
Serializing data to and from files
Bypassing the serialization mechanism
Handling commands in the document
The OnNewDocument member function
The DeleteContents member function

See also
Document/View Architecture
Deriving a Document Class from CDocument
3/4/2019 • 2 minutes to read • Edit Online

Documents contain and manage your application's data. To use the MFC Application Wizard-supplied document
class, you must do the following:
Derive a class from CDocument for each type of document.
Add member variables to store each document's data.
Override CDocument 's Serialize member function in your document class. Serialize writes and reads the
document's data to and from disk.

Other Document Functions Often Overridden


You may also want to override other CDocument member functions. In particular, you will often need to override
OnNewDocument and OnOpenDocument to initialize the document's data members and DeleteContents to
destroy dynamically allocated data. For information about overridable members, see class CDocument in the MFC
Reference.

See also
Using Documents
Managing Data with Document Data Variables
3/4/2019 • 2 minutes to read • Edit Online

Implement your document's data as member variables of your document class. For example, the Scribble program
declares a data member of type CObList — a linked list that stores pointers to CObject objects. This list is used to
store arrays of points that make up a freehand line drawing.
How you implement your document's member data depends on the nature of your application. To help you out,
MFC supplies a group of "collection classes" — arrays, lists, and maps (dictionaries), including collections based on
C++ templates — along with classes that encapsulate a variety of common data types such as CString , CRect ,
CPoint , CSize , and CTime . For more information about these classes, see the Class Library Overview in the MFC
Reference.
When you define your document's member data, you will usually add member functions to the document class to
set and get data items and perform other useful operations on them.
Your views access the document object by using the view's pointer to the document, installed in the view at
creation time. You can retrieve this pointer in a view's member functions by calling the CView member function
GetDocument . Be sure to cast this pointer to your own document type. Then you can access public document
members through the pointer.
If frequent data transfer requires direct access, or you wish to use the nonpublic members of the document class,
you may want to make your view class a friend (in C++ terms) of the document class.

See also
Using Documents
Serializing Data to and from Files
3/27/2020 • 2 minutes to read • Edit Online

The basic idea of persistence is that an object should be able to write its current state, indicated by the values of its
member variables, to persistent storage. Later, the object can be re-created by reading, or "deserializing," the
object's state from persistent storage. A key point here is that the object itself is responsible for reading and writing
its own state. Thus, for a class to be persistent, it must implement the basic serialization operations.
The framework provides a default implementation for saving documents to disk files in response to the Save and
Save As commands on the File menu and for loading documents from disk files in response to the Open
command. With very little work, you can implement a document's ability to write and read its data to and from a
file. The main thing you must do is override the Serialize member function in your document class.
The MFC Application Wizard places a skeletal override of the CDocument member function Serialize in the
document class it creates for you. After you have implemented your application's member variables, you can fill in
your Serialize override with code that sends the data to an "archive object" connected to a file. A CArchive object
is similar to the cin and cout input/output objects from the C++ iostream library. However, CArchive writes and
reads binary format, not formatted text.

What do you want to know more about


Serialization
The document's role in serialization
The data's role in serialization
Bypassing the serialization mechanism

The Document's Role in Serialization


The framework responds automatically to the File menu's Open, Save, and Save As commands by calling the
document's Serialize member function if it is implemented. An ID_FILE_OPEN command, for example, calls a
handler function in the application object. During this process, the user sees and responds to the File Open dialog
box and the framework obtains the filename the user chooses. The framework creates a CArchive object set up for
loading data into the document and passes the archive to Serialize . The framework has already opened the file.
The code in your document's Serialize member function reads the data in through the archive, reconstructing
data objects as needed. For more information about serialization, see the article Serialization.

The Data's Role in Serialization


In general, class-type data should be able to serialize itself. That is, when you pass an object to an archive, the
object should know how to write itself to the archive and how to read itself from the archive. MFC provides
support for making classes serializable in this way. If you design a class to define a data type and you intend to
serialize data of that type, design for serialization.

See also
Using Documents
Bypassing the Serialization Mechanism
3/4/2019 • 2 minutes to read • Edit Online

As you have seen, the framework provides a default way to read and write data to and from files. Serializing
through an archive object suits the needs of a great many applications. Such an application reads a file entirely into
memory, lets the user update the file, and then writes the updated version to disk again.
However, some applications operate on data very differently, and for these applications serialization through an
archive is not suitable. Examples include database programs, programs that edit only parts of large files, programs
that write text-only files, and programs that share data files.
In these cases, you can override the Serialize function in a different way to mediate file actions through a CFile
object rather than a CArchive object.
You can use the Open , Read , Write , Close , and Seek member functions of class CFile to open a file, move the
file pointer (seek) to a specific point in the file, read a record (a specified number of bytes) at that point, let the user
update the record, then seek to the same point again and write the record back to the file. The framework will open
the file for you, and you can use the GetFile member function of class CArchive to obtain a pointer to the CFile
object. For even more sophisticated and flexible use, you can override the OnOpenDocument and
OnSaveDocument member functions of class CWinApp . For more information, see class CFile in the MFC
Reference.
In this scenario, your Serialize override does nothing, unless, for example, you want to have it read and write a
file header to keep it up to date when the document closes.

See also
Using Documents
Handling Commands in the Document
3/4/2019 • 2 minutes to read • Edit Online

Your document class may also handle certain commands generated by menu items, toolbar buttons, or accelerator
keys. By default, CDocument handles the Save and Save As commands on the File menu, using serialization. Other
commands that affect the data may also be handled by member functions of your document. For example, in the
Scribble program, class CScribDoc provides a handler for the Edit Clear All command, which deletes all of the data
currently stored in the document. Documents can have message maps, but unlike views, documents cannot handle
standard Windows messages — only WM_COMMAND messages, or "commands."

See also
Using Documents
Using Views
3/4/2019 • 2 minutes to read • Edit Online

The view's responsibilities are to display the document's data graphically to the user and to accept and interpret
user input as operations on the document. Your tasks in writing your view class are to:
Write your view class's OnDraw member function, which renders the document's data.
Connect appropriate Windows messages and user-interface objects such as menu items to message-
handler member functions in the view class.
Implement those handlers to interpret user input.
In addition, you may need to override other CView member functions in your derived view class. In particular, you
may want to override OnInitialUpdate to perform special initialization for the view and OnUpdate to do any
special processing needed just before the view redraws itself. For multipage documents, you also must override
OnPreparePrinting to initialize the Print dialog box with the number of pages to print and other information. For
more information on overriding CView member functions, see class CView in the MFC Reference.

What do you want to know more about


Derived view classes available in MFC
Drawing in a view
Interpreting user input through a view
The role of the view in printing
Scrolling and scaling views
Initializing and cleaning up documents and views

See also
Document/View Architecture
CFormView Class
Record Views (MFC Data Access)
Bypassing the Serialization Mechanism
Derived View Classes Available in MFC
3/27/2020 • 2 minutes to read • Edit Online

The following table shows MFC's view classes and their relationships to one another. The capabilities of your view
class depend on the MFC view class from which it derives.
View Classes
C L A SS DESC RIP T IO N

CView Base class of all views.

CCtrlView Base class of , CListView , CEditView , and


CTreeView
CRichEditView . These classes let you use document/view
architecture with the indicated Windows common controls.

CEditView A simple view based on the Windows edit box control. Allows
entering and editing text and can be used as the basis for a
simple text editor application. See also CRichEditView .

CRichEditView A view containing a CRichEditCtrl object. This class is


analogous to CEditView , but unlike CEditView ,
CRichEditView handles formatted text.

CListView A view containing a CListCtrl object.

CTreeView A view containing a CTreeCtrl object, for views that resemble


the Solution Explorer window in Visual C++.

CScrollView Base class of CFormView , CRecordView , and


CDaoRecordView . Implements scrolling the view's contents.

CFormView A form view, a view that contains controls. A forms-based


application provides one or more such form interfaces.

CHtmlView A Web browser view with which the application's user can
browse sites on the World Wide Web, as well as folders in the
local file system and on a network. The Web browser view can
also work as an Active document container.

CRecordView A form view that displays ODBC database records in controls.


If you select ODBC support in your project, the view's base
class is CRecordView . The view is connected to a CRowset
object.

CDaoRecordView A form view that displays DAO database records in controls. If


you select DAO support in your project, the view's base class
is CDaoRecordView . The view is connected to a
CDaoRecordset object.
C L A SS DESC RIP T IO N

COleDBRecordView A form view that displays OLE DB records in controls. If you


select OLE DB support in your project, the view's base class is
COleDBRecordView . The view is connected to a CRowset
object.

NOTE
As of MFC version 4.0, CEditView is derived from CCtrlView .

To use these classes in your application, derive the application's view classes from them. For related information,
see Scrolling and Scaling Views. For more information on the database classes, see Overview: Database
Programming.

See also
Using Views
Drawing in a View
3/24/2020 • 2 minutes to read • Edit Online

Nearly all drawing in your application occurs in the view's OnDraw member function, which you must override in
your view class. (The exception is mouse drawing, discussed in Interpreting User Input Through a View.) Your
OnDraw override:

1. Gets data by calling the document member functions you provide.


2. Displays the data by calling member functions of a device-context object that the framework passes to
OnDraw .

When a document's data changes in some way, the view must be redrawn to reflect the changes. Typically, this
happens when the user makes a change through a view on the document. In this case, the view calls the
document's UpdateAllViews member function to notify all views on the same document to update themselves.
UpdateAllViews calls each view's OnUpdate member function. The default implementation of OnUpdate
invalidates the view's entire client area. You can override it to invalidate only those regions of the client area that
map to the modified portions of the document.
The UpdateAllViews member function of class CDocument and the OnUpdate member function of class CView let
you pass information describing what parts of the document were modified. This "hint" mechanism lets you limit
the area that the view must redraw. OnUpdate takes two "hint" arguments. The first, lHint, of type LPARAM , lets
you pass any data you like, while the second, pHint, of type CObject *, lets you pass a pointer to any object derived
from CObject .
When a view becomes invalid, Windows sends it a WM_PAINT message. The view's OnPaint handler function
responds to the message by creating a device-context object of class CPaintDC and calls your view's OnDraw
member function. You do not normally have to write an overriding OnPaint handler function.
A device context is a Windows data structure that contains information about the drawing attributes of a device
such as a display or a printer. All drawing calls are made through a device-context object. For drawing on the
screen, OnDraw is passed a CPaintDC object. For drawing on a printer, it is passed a CDC object set up for the
current printer.
Your code for drawing in the view first retrieves a pointer to the document, then makes drawing calls through the
device context. The following simple OnDraw example illustrates the process:

void CMyView::OnDraw(CDC* pDC)


{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

CString s = pDoc->GetData(); // Returns a CString


CRect rect;
GetClientRect(&rect);

pDC->SetTextAlign(TA_BASELINE | TA_CENTER);
pDC->TextOut(rect.right / 2, rect.bottom / 2, s, s.GetLength());
}

In this example, you would define the GetData function as a member of your derived document class.
The example prints whatever string it gets from the document, centered in the view. If the OnDraw call is for screen
drawing, the CDC object passed in pDC is a CPaintDC whose constructor has already called BeginPaint . Calls to
drawing functions are made through the device-context pointer. For information about device contexts and
drawing calls, see class CDC in the MFC Reference and Working with Window Objects.
For more examples of how to write OnDraw , see the MFC Samples.

See also
Using Views
Interpreting User Input Through a View
3/4/2019 • 2 minutes to read • Edit Online

Other member functions of the view handle and interpret all user input. You will usually define message-handler
member functions in your view class to process:
Windows messages generated by mouse and keyboard actions.
Commands from menus, toolbar buttons, and accelerator keys.
These message-handler member functions interpret the following actions as data input, selection, or editing,
including moving data to and from the Clipboard:
Mouse movements and clicks, drags, and double-clicks
Keystrokes
Menu commands
Which Windows messages your view handles depends on your application's needs.
Message Handling and Mapping Topics explains how to assign menu items and other user-interface objects to
commands and how to bind the commands to handler functions. Message Handling and Mapping Topics also
explains how MFC routes commands and sends standard Windows messages to the objects that contain handlers
for them.
For example, your application might need to implement direct mouse drawing in the view. The Scribble sample
shows how to handle the WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP messages respectively
to begin, continue, and end the drawing of a line segment. On the other hand, you might sometimes need to
interpret a mouse click in your view as a selection. Your view's OnLButtonDown handler function would determine
whether the user was drawing or selecting. If selecting, the handler would determine whether the click was within
the bounds of some object in the view and, if so, alter the display to show the object as selected.
Your view might also handle certain menu commands, such as those from the Edit menu to cut, copy, paste, or
delete selected data using the Clipboard. Such a handler would call some of the Clipboard-related member
functions of class CWnd to transfer a selected data item to or from the Clipboard.

See also
Using Views
Role of the View in Printing
3/4/2019 • 2 minutes to read • Edit Online

Your view also plays two important roles in printing its associated document.
The view:
Uses the same OnDraw code to draw on the printer as to draw on the screen.
Manages dividing the document into pages for printing.
For more information about printing and about the view's role in printing, see Printing and Print Preview.

See also
Using Views
Scrolling and Scaling Views
3/27/2020 • 2 minutes to read • Edit Online

MFC supports views that scroll and views that are automatically scaled to the size of the frame window that
displays them. Class CScrollView supports both kinds of views.
For more information about scrolling and scaling, see class CScrollView in the MFC Reference. For a scrolling
example, see the Scribble sample.

What do you want to know more about


Scrolling a view
Scaling a view
View coordinates

Scrolling a View
Frequently the size of a document is greater than the size its view can display. This may occur because the
document's data increases or the user shrinks the window that frames the view. In such cases, the view must
support scrolling.
Any view can handle scroll-bar messages in its OnHScroll and OnVScroll member functions. You can either
implement scroll-bar message handling in these functions, doing all the work yourself, or you can use the
CScrollView class to handle scrolling for you.

CScrollView does the following:


Manages window and viewport sizes and mapping modes
Scrolls automatically in response to scroll-bar messages
You can specify how much to scroll for a "page" (when the user clicks in a scroll-bar shaft) and a "line" (when the
user clicks in a scroll arrow). Plan these values to suit the nature of your view. For example, you might want to
scroll in 1-pixel increments for a graphics view but in increments based on the line height in text documents.

Scaling a View
When you want the view to automatically fit the size of its frame window, you can use CScrollView for scaling
instead of scrolling. The logical view is stretched or shrunk to fit the window's client area exactly. A scaled view has
no scroll bars.

See also
Using Views
Multiple Document Types, Views, and Frame
Windows
3/27/2020 • 4 minutes to read • Edit Online

The standard relationship among a document, its view, and its frame window is described in Document/View
Creation. Many applications support a single document type (but possibly multiple open documents of that type)
with a single view on the document and only one frame window per document. But some applications may need
to alter one or more of those defaults.

What do you want to know more about


Multiple document types
Multiple views
Multiple frame windows
Splitter windows

Multiple Document Types


The MFC Application Wizard creates a single document class for you. In some cases, though, you may need to
support more than one document type. For example, your application may need worksheet and chart documents.
Each document type is represented by its own document class and probably by its own view class as well. When
the user chooses the File New command, the framework displays a dialog box that lists the supported document
types. Then it creates a document of the type that the user chooses. Each document type is managed by its own
document-template object.
To create extra document classes, see Adding a Class. Choose CDocument as the Class Type to derive from and
supply the requested document information. Then implement the new class's data.
To let the framework know about your extra document class, you must add a second call to AddDocTemplate in
your application class's InitInstance override. For more information, see Document Templates.

Multiple Views
Many documents require only a single view, but it is possible to support more than one view of a single
document. To help you implement multiple views, a document object keeps a list of its views, provides member
functions for adding and removing views, and supplies the UpdateAllViews member function for letting multiple
views know when the document's data has changed.
MFC supports three common user interfaces requiring multiple views on the same document. These models are:
View objects of the same class, each in a separate MDI document frame window.
You might want to support creating a second frame window on a document. The user could choose a New
Window command to open a second frame with a view of the same document and then use the two
frames to view different portions of the document simultaneously. The framework supports the New
Window command on the Window menu for MDI applications by duplicating the initial frame window and
view attached to the document.
View objects of the same class in the same document frame window.
Splitter windows split the view space of a single document window into multiple separate views of the
document. The framework creates multiple view objects from the same view class. For more information,
see Splitter Windows.
View objects of different classes in a single frame window.
In this model, a variation of the splitter window, multiple views share a single frame window. The views are
constructed from different classes, each view providing a different way to view the same document. For
example, one view might show a word-processing document in normal mode while the other view shows
it in outline mode. A splitter control allows the user to adjust the relative sizes of the views.
The following figure, divided into parts a, b, and c, shows the three user-interface models in the order presented
above.

Multiple-View User Interfaces


The framework provides these models by implementing the New Window command and by providing class
CSplitterWnd, as discussed in Splitter Windows. You can implement other models using these as your starting
point. For sample programs that illustrate different configurations of views, frame windows, and splitters, see
MFC Samples.
For more information about UpdateAllViews , see class CView in the MFC Reference and the Scribble sample.

Multiple Frame Windows


You can use the New Window command on the Window menu for MDI applications to create a second frame
window on the same document. For more information, see the first model in the figure Multiple-View User
Interfaces.

Splitter Windows
In a splitter window, the window is, or can be, split into two or more scrollable panes. A splitter control (or "split
box") in the window frame next to the scroll bars allows the user to adjust the relative sizes of the panes. Each
pane is a view on the same document. In "dynamic" splitters, the views are of the same class, as shown in part b
of the figure Multiple-View User Interfaces. In "static" splitters, the views can be of different classes. Splitter
windows of both kinds are supported by class CSplitterWnd.
Dynamic splitter windows, with views of the same class, allow the user to split a window into multiple panes at
will and then scroll different panes to see different parts of the document. The user can also unsplit the window to
remove the additional views. The splitter windows added to the Scribble sample are an example. That topic
describes the technique for creating dynamic splitter windows. A dynamic splitter window is shown in part b of
the figure Multiple-View User Interfaces.
Static splitter windows, with views of different classes, start with the window split into multiple panes, each with a
different purpose. For example, in the Visual C++ bitmap editor, the image window shows two panes side by side.
The left-hand pane displays a life-sized image of the bitmap. The right-hand pane displays a zoomed or magnified
image of the same bitmap. The panes are separated by a "splitter bar" that the user can drag to change the
relative sizes of the panes. A static splitter window is shown in part c of the figure Multiple-View User Interfaces.
For more information, see class CSplitterWnd in the MFC Reference and MFC Samples.

See also
Document/View Architecture
Initializing and Cleaning Up Documents and Views
3/27/2020 • 2 minutes to read • Edit Online

Use the following guidelines for initializing and cleaning up after your documents and views:
The MFC framework initializes documents and views; you initialize any data you add to them.
The framework cleans up as documents and views close; you must deallocate any memory that you
allocated on the heap from within the member functions of those documents and views.

NOTE
Recall that initialization for the whole application is best done in your override of the InitInstance member function of class
CWinApp , and cleanup for the whole application is best done in your override of the CWinApp member function
ExitInstance.

The life cycle of a document (and its frame window and view or views) in an MDI application is as follows:
1. During dynamic creation, the document constructor is called.
2. For each new document, the document's OnNewDocument or OnOpenDocument is called.
3. The user interacts with the document throughout its lifetime. Typically this happens as the user works on
document data through the view, selecting and editing the data. The view passes changes on to the
document for storage and updating other views. During this time both the document and the view might
handle commands.
4. The framework calls DeleteContents to delete data specific to a document.
5. The document's destructor is called.
In an SDI application, step 1 is performed once, when the document is first created. Then steps 2 through 4 are
performed repeatedly each time a new document is opened. The new document reuses the existing document
object. Finally, step 5 is performed when the application ends.

What do you want to know more about


Initializing Documents and Views
Cleaning Up Documents and Views

See also
Document/View Architecture
Initializing Documents and Views
3/4/2019 • 2 minutes to read • Edit Online

Documents are created in two different ways, so your document class must support both ways. First, the user can
create a new, empty document with the File New command. In that case, initialize the document in your override of
the OnNewDocument member function of class CDocument. Second, the user can use the Open command on the
File menu to create a new document whose contents are read from a file. In that case, initialize the document in
your override of the OnOpenDocument member function of class CDocument . If both initializations are the same,
you can call a common member function from both overrides, or OnOpenDocument can call OnNewDocument to
initialize a clean document and then finish the open operation.
Views are created after their documents are created. The best time to initialize a view is after the framework has
finished creating the document, frame window, and view. You can initialize your view by overriding the
OnInitialUpdate member function of CView. If you need to reinitialize or adjust anything each time the document
changes, you can override OnUpdate.

See also
Initializing and Cleaning Up Documents and Views
Cleaning Up Documents and Views
3/27/2020 • 2 minutes to read • Edit Online

When a document is closing, the framework first calls its DeleteContents member function. If you allocated any
memory on the heap during the course of the document's operation, DeleteContents is the best place to deallocate
it.

NOTE
You should not deallocate document data in the document's destructor. In the case of an SDI application, the document
object might be reused.

You can override a view's destructor to deallocate any memory you allocated on the heap.

See also
Initializing and Cleaning Up Documents and Views
Adding Multiple Views to a Single Document
3/27/2020 • 4 minutes to read • Edit Online

In a single-document interface (SDI) application created with the Microsoft Foundation Class (MFC) Library, each
document type is associated with a single view type. In some cases, it is desirable to have the ability to switch the
current view of a document with a new view.

TIP
For additional procedures on implementing multiple views for a single document, see CDocument::AddView and the
COLLECT MFC sample.

You can implement this functionality by adding a new CView -derived class and additional code for switching the
views dynamically to an existing MFC application.
The steps are as follows:
Modify the Existing Application Class
Create and Modify the New View Class
Create and Attach the New View
Implement the Switching Function
Add Support for Switching the View
The remainder of this topic assumes the following:
The name of the CWinApp -derived object is CMyWinApp , and CMyWinApp is declared and defined in
MYWINAPP.H and MYWINAPP.CPP.
is the name of the new
CNewView CView -derived object, and CNewView is declared and defined in
NEWVIEW.H and NEWVIEW.CPP.

Modify the Existing Application Class


For the application to switch between views, you need to modify the application class by adding member variables
to store the views and a method to switch them.
Add the following code to the declaration of CMyWinApp in MYWINAPP.H:

CView *m_pOldView;
CView *m_pNewView;
CView *SwitchView();

The new member variables, m_pOldView and m_pNewView , point to the current view and the newly created one. The
new method ( SwitchView ) switches the views when requested by the user. The body of the method is discussed
later in this topic in Implement the Switching Function.
The last modification to the application class requires including a new header file that defines a Windows message
(WM_INITIALUPDATE ) that is used in the switching function.
Insert the following line in the include section of MYWINAPP.CPP:
#include <AFXPRIV.H>

Save your changes and continue to the next step.

Create and Modify the New View Class


Creating the new view class is made easy by using the New Class command available from Class View. The only
requirement for this class is that it derives from CView . Add this new class to the application. For specific
information on adding a new class to the project, see Adding a Class.
Once you have added the class to the project, you need to change the accessibility of some view class members.
Modify NEWVIEW.H by changing the access specifier from protected to public for the constructor and destructor.
This allows the class to be created and destroyed dynamically and to modify the view appearance before it is
visible.
Save your changes and continue to the next step.

Create and Attach the New View


To create and attach the new view, you need to modify the InitInstance function of your application class. The
modification adds new code that creates a new view object and then initializes both m_pOldView and m_pNewView
with the two existing view objects.
Because the new view is created within the InitInstance function, both the new and existing views persist for the
lifetime of the application. However, the application could just as easily create the new view dynamically.
Insert this code after the call to ProcessShellCommand :
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();
m_pOldView = pActiveView;
m_pNewView = (CView *)new CNewView;
if (NULL == m_pNewView)
return FALSE;

CDocument *pCurrentDoc = ((CFrameWnd *)m_pMainWnd)->GetActiveDocument();

// Initialize a CCreateContext to point to the active document.


// With this context, the new view is added to the document
// when the view is created in CView::OnCreate().
CCreateContext newContext;
newContext.m_pNewViewClass = NULL;
newContext.m_pNewDocTemplate = NULL;
newContext.m_pLastView = NULL;
newContext.m_pCurrentFrame = NULL;
newContext.m_pCurrentDoc = pCurrentDoc;

// The ID of the initial active view is AFX_IDW_PANE_FIRST.


// Incrementing this value by one for additional views works
// in the standard document/view case but the technique cannot
// be extended for the CSplitterWnd case.
UINT viewID = AFX_IDW_PANE_FIRST + 1;
CRect rect(0, 0, 0, 0); // Gets resized later.

// Create the new view. In this example, the view persists for
// the life of the application. The application automatically
// deletes the view when the application is closed.
m_pNewView->Create(NULL, _T("AnyWindowName"), WS_CHILD, rect, m_pMainWnd, viewID, &newContext);

// When a document template creates a view, the WM_INITIALUPDATE


// message is sent automatically. However, this code must
// explicitly send the message, as follows.
m_pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);

Save your changes and continue to the next step.

Implement the Switching Function


In the previous step, you added code that created and initialized a new view object. The last major piece is to
implement the switching method, SwitchView .
At the end of the implementation file for your application class (MYWINAPP.CPP), add the following method
definition:
CView *CMyWinApp::SwitchView()
{
CView *pActiveView = ((CFrameWnd *)m_pMainWnd)->GetActiveView();

CView *pNewView = NULL;


if (pActiveView == m_pOldView)
pNewView = m_pNewView;
else
pNewView = m_pOldView;

// Exchange view window IDs so RecalcLayout() works.


#ifndef _WIN32
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
#else
UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
#endif

pActiveView->ShowWindow(SW_HIDE);
pNewView->ShowWindow(SW_SHOW);
((CFrameWnd *)m_pMainWnd)->SetActiveView(pNewView);
((CFrameWnd *)m_pMainWnd)->RecalcLayout();
pNewView->Invalidate();
return pActiveView;
}

Save your changes and continue to the next step.

Add Support for Switching the View


The final step involves adding code that calls the SwitchView method when the application needs to switch
between views. This can be done in several ways: by either adding a new menu item for the user to choose or
switching the views internally when certain conditions are met.
For more information on adding new menu items and command handler functions, see Handlers for Commands
and Control Notifications.

See also
Document/View Architecture
Form Views (MFC)
3/27/2020 • 2 minutes to read • Edit Online

You can add forms to any Visual C++ application that supports the MFC libraries, including a forms-based
application (one whose view class is derived from CFormView ). If you did not initially create your application to
support forms, Visual C++ will add this support for you when you insert a new form. In an SDI or MDI application,
which implements the default document/view architecture, when the user chooses the New command (by default,
on the File menu), Visual C++ prompts the user to choose from the available forms.
With an SDI application, when the user chooses the New command, the current instance of the form continues to
run but a new instance of the application with the selected form is created if one is not found. In an MDI
application, the current instance of the form continues to run when the user chooses the New command.

NOTE
You can insert a form into a dialog-based application (one whose dialog class is based on CDialog and one in which no
view class is implemented). However, without the document/view architecture, Visual C++ does not automatically implement
the File |New functionality. You must create a way for the user to view additional forms, such as by implementing a tabbed
dialog box with various property pages.

When you insert a new form into your application, Visual C++ does the following:
Creates a class based on one of the form-style classes that you choose ( CFormView , CRecordView ,
CDaoRecordView , or CDialog ).

Creates a dialog resource with appropriate styles (or you can use an existing dialog resource that has not
yet been associated with a class).
If you choose an existing dialog resource, you may need to set these styles by using the Properties page for
the dialog box. Styles for a dialog box must include:
WS_CHILD =On
WS_BORDER =Off
WS_VISIBLE =Off
WS_CAPTION =Off
For applications based on the document/view architecture, the New Form command (right-click in Class View)
also:
Creates a CDocument -based class
Instead of having a new class created, you can use any existing CDocument -based class in your project.
Generates a document template (derived from CDocument ) with string, menu, and icon resources.
You can also create a new class on which to base the template.
Adds a call to AddDocumentTemplate in your application's InitInstance code.
Visual C++ adds this code for each new form you create, which adds the form to the list of available forms
when the user chooses the New command. This code includes the form's associated resource ID and the
names of the associated document, view, and frame classes that together make up the new form object.
Document templates serve as the connection between documents, frame windows, and views. For a single
document, you can create many templates.
For more information, see:
Create a Forms-Based Application
Inserting a Form into a Project

See also
User Interface Elements
Inserting a Form into a Project
3/4/2019 • 2 minutes to read • Edit Online

Forms provide a convenient container for controls. You can easily insert an MFC-based form into your application
as long as the application supports the MFC libraries.
To insert a form into your project
1. From Class View, select the project to which you want to add the form, and click the right mouse button.
2. From the shortcut menu, click Add and then click Add Class .
If the New Form command is not available, your project may be based on the Active Template Library (ATL).
To add a form to an ATL project, you must specify certain settings when first creating the project.
3. From the MFC folder, click MFC Class .
4. Using the MFC Class Wizard, make the new class derive from CFormView.
Visual C++ adds the form to your application, opening it inside the Dialog editor so that you can begin adding
controls and working on its overall design.
You may want to perform the following additional steps (not applicable for dialog-based applications):
1. Override the OnUpdate member function.
2. Implement a member function to move data from your view to your document.
3. Create an OnPrint member function.

See also
Form Views
HTML Help: Context-Sensitive Help for Your
Programs
3/27/2020 • 2 minutes to read • Edit Online

IMPORTANT
HTML Help is not supported in this version of MFC.

See also
User Interface Elements
MDI Tabbed Groups
3/4/2019 • 2 minutes to read • Edit Online

The multiple document interface (MDI) tabbed groups feature enables multiple document interface (MDI)
applications to display one or more tabbed windows (or groups of tabbed windows, known as tabbed groups) in
the MDI client area. The tabbed windows can be aligned vertically or horizontally. If an application hosts more than
one MDI tabbed group, the groups are separated by splitters.

Features
The following are the features of MDI tabbed groups:
An application can create tabbed windows dynamically.
An application can align tabbed windows horizontally or vertically.
Groups of tabbed windows are separated by splitters. The user can resize tabbed groups by using the
splitter.
The user can drag individual tabs between groups.
The user can drag individual tabs to create new groups.
The user can move tabs or create new groups by using a shortcut menu.
An application can save and load the layout of tabbed windows.
An application can save and load the list of MDI documents.
An application can access individual tabbed groups and modify their parameters.
Using MDI Tabbed Groups
The following are tasks commonly performed with MDI tabbed groups:
To enable MDI tabbed groups for a main frame window, call CMDIFrameWndEx::EnableMDITabbedGroups.
The second parameter of this method is an instance of the CMDITabInfo class. You can use the default
parameters or modify them before you call CMDIFrameWndEx::EnableMDITabbedGroups .
To modify the properties of an MDI tabbed group at run time, create or modify a CMDITabInfo object and
call CMDIFrameWndEx::EnableMDITabbedGroups again
To obtain a list of MDI tabbed windows, call CMDIFrameWndEx::GetMDITabGroups .
To create a new MDI tabbed group next to an active tabbed group, call CMDIFrameWndEx::MDITabNewGroup .
To shift the input focus to the previous or next window of a tabbed group, call
CMDIFrameWndEx::MDITabMoveToNextGroup .

To determine whether a window is a member of an MDI tabbed group call


CMDIFrameWndEx::IsMemberOfMDITabGroup .

To determine whether MDI tabs or MDI tabbed groups are enabled for a main frame window, call
CMDIFrameWndEx::AreMDITabs . To determine only whether MDI tabbed groups are enabled, call
CMDIFrameWndEx::IsMDITabbedGroup .

To display a shortcut menu when the user clicks a tab or drags it to another MDI tabbed group, override
CMDIFrameWndEx::OnShowMDITabContextMenu in the CMDIFrameWndEx -derived class. If you do not implement this
method, the application will not display the shortcut menu.
To save the layout of MDI tabbed groups in an application, call CMDIFrameWndEx::SaveMDIState . To load a
previously saved MDI tabbed group profile, call CMDIFrameWndEx::LoadMDIState . You can also call these
methods to load or save the list of opened documents in an MDI application. For more information about
saving and loading MDI state, see CMDIFrameWndEx::LoadMDIState.

See also
User Interface Elements
CMDIFrameWndEx Class
CMDIChildWndEx Class
CMDITabInfo Class
Menus (MFC)
3/4/2019 • 2 minutes to read • Edit Online

MFC supplies two elements to help you work with menus:


Class CMenu for manipulating your program's menus at run time. Use the documentation for CMenu and
the sample to learn how to use CMenu effectively.
A mechanism for updating menus and toolbar buttons: enabling or disabling them on the fly to suit current
program conditions.
Visual C++ also provides a menu editor for creating and editing your program's menu resources.

What do you want to know more about


Manipulating menu objects during program execution
How to Update User-Interface Objects
Sample

See also
User Interface Elements
Menu Sample List
4/1/2019 • 2 minutes to read • Edit Online

See the following sample programs that illustrate creating, editing, and updating menus:
MDI Sample: Enable and Disable Menu Items
SCRIBBLE
Dynamically Change Menus
DYNAMENU

See also
Menus
Manipulating Menus During Program Execution
3/4/2019 • 2 minutes to read • Edit Online

Use class CMenu to manipulate menus and menu items on the fly. CMenu encapsulates a Windows HMENU handle
and supplies member functions for working with menus.
See the overview for class CMenu for details.

See also
Menus
How to: Update User-Interface Objects
3/4/2019 • 2 minutes to read • Edit Online

Typically, menu items and toolbar buttons have more than one state. For example, a menu item is grayed
(dimmed) if it is unavailable in the present context. Menu items can also be checked or unchecked. A toolbar
button can also be disabled if unavailable, or it can be checked.
Who updates the state of these items as program conditions change Logically, if a menu item generates a
command that is handled by, say, a document, it makes sense to have the document update the menu item. The
document probably contains the information on which the update is based.
If a command has multiple user-interface objects (perhaps a menu item and a toolbar button), both are routed to
the same handler function. This encapsulates your user-interface update code for all of the equivalent user-
interface objects in a single place.
The framework provides a convenient interface for automatically updating user-interface objects. You can choose
to do the updating in some other way, but the interface provided is efficient and easy to use.
The following topics explain the use of update handlers:
When update handlers are called
The ON_UPDATE_COMMAND_UI macro
The CCmdUI class

See also
Menus
When Update Handlers Are Called
3/4/2019 • 2 minutes to read • Edit Online

Suppose the user clicks the mouse in the File menu, which generates a WM_INITMENUPOPUP message. The
framework's update mechanism collectively updates all items on the File menu before the menu drops down so the
user can see it.
To do this, the framework routes update commands for all menu items in the pop-up menu along the standard
command routing. Command targets on the routing have an opportunity to update any menu items by matching
the update command with an appropriate message-map entry (of the form ON_UPDATE_COMMAND_UI ) and calling an
"update handler" function. Thus, for a menu with six menu items, six update commands are sent out. If an update
handler exists for the command ID of the menu item, it is called to do the updating. If not, the framework checks for
the existence of a handler for that command ID and enables or disables the menu item as appropriate.
If the framework does not find an ON_UPDATE_COMMAND_UI entry during command routing, it automatically enables
the user-interface object if there is an ON_COMMAND entry somewhere with the same command ID. Otherwise, it
disables the user-interface object. Therefore, to ensure that a user-interface object is enabled, supply a handler for
the command the object generates or supply an update handler for it. See the figure in the topic User-Interface
Objects and Command IDs.
It is possible to disable the default disabling of user-interface objects. For more information, see the
m_bAutoMenuEnable member of class CFrameWnd in the MFC Reference.
Menu initialization is automatic in the framework, occurring when the application receives a
WM_INITMENUPOPUP message. During the idle loop, the framework searches the command routing for button
update handlers in much the same way as it does for menus.

See also
How to: Update User-Interface Objects
ON_UPDATE_COMMAND_UI Macro
9/18/2019 • 2 minutes to read • Edit Online

To connect a user-interface object to a command-update handler in a command-target object, open Class View ,
then right-click on the class to which the handler will be added, and choose Class Wizard . Find the user-interface
object's ID in the list on the left, then choose UPDATE_COMMAND_UI in the right pane and click Add Handler .
This creates a handler function in the class and adds the appropriate entry in the message map. See Mapping
Messages to Functions for more information. You can specify additional messages to handle in the Messages
pane.
For example, to update a Clear All command in your program's Edit menu, use the Class Wizard to add a
message-map entry in the selected class, a function declaration for a command-update handler called
OnUpdateEditClearAll in the class declaration, and an empty function template in the class's implementation file.
The function prototype looks like this:

afx_msg void OnUpdateEditClearAll(CCmdUI* pCmdUI);

Like all handlers, the function declaration shows the afx_msg keyword. Like all update handlers, it takes one
argument, a pointer to a CCmdUI object.

See also
How to: Update User-Interface Objects
The CCmdUI Class
3/16/2020 • 2 minutes to read • Edit Online

When it routes an update command to its handler, the framework passes the handler a pointer to a CCmdUI object
(or to an object of a CCmdUI -derived class). This object represents the menu item or toolbar button or other user-
interface object that generated the command. The update handler calls member functions of the CCmdUI structure
through the pointer to update the user-interface object. For example, here is an update handler for the Clear All
menu item:

void CMyWinApp::OnUpdateEditClearAll(CCmdUI *pCmdUI)


{
pCmdUI->Enable(m_bClearAllAvailable);
}

This handler calls the Enable member function of an object with access to the menu item. Enable makes the item
available for use.

See also
How to: Update User-Interface Objects
OLE (MFC)
3/4/2019 • 2 minutes to read • Edit Online

Implementing OLE functionality in your program affects your user interface in several ways:
Visual editing (in-place activation) displays the user interface of another program in your program's
windows and modifies your program's menus with items from the other program.
Drag and drop allows users to drag objects within and between windows and even between programs.
Trackers provide visual cues to the state of objects during visual editing and drag and drop.
For more information, see:
OLE and MFC
Visual Editing (Activation)
Drag and Drop
Trackers

See also
User Interface Elements
Printing and Print Preview
4/1/2019 • 2 minutes to read • Edit Online

MFC supports printing and print preview for your program's documents via class CView. For basic printing and
print preview, simply override your view class's OnDraw member function, which you must do anyway. That
function can draw to the view on the screen, to a printer device context for an actual printer, or to a device context
that simulates your printer on the screen.
You can also add code to manage multipage document printing and preview, to paginate your printed documents,
and to add headers and footers to them.
This family of articles explains how printing is implemented in the Microsoft Foundation Class Library (MFC) and
how to take advantage of the printing architecture already built into the framework. The articles also explain how
MFC supports easy implementation of print preview functionality and how you can use and modify that
functionality.

What do you want to know more about


Printing
Print preview architecture
Sample

See also
User Interface Elements
Printing
3/27/2020 • 2 minutes to read • Edit Online

Microsoft Windows implements device-independent display. In MFC, this means that the same drawing calls, in
the OnDraw member function of your view class, are responsible for drawing on the display and on other devices,
such as printers. For print preview, the target device is a simulated printer output to the display.

Your Role in Printing vs. the Framework's Role


Your view class has the following responsibilities:
Inform the framework how many pages are in the document.
When asked to print a specified page, draw that portion of the document.
Allocate and deallocate any fonts or other graphics device interface (GDI) resources needed for printing.
If necessary, send any escape codes needed to change the printer mode before printing a given page, for
example, to change the printing orientation on a per-page basis.
The framework's responsibilities are as follows:
Display the Print dialog box.
Create a CDC object for the printer.
Call the StartDoc and EndDoc member functions of the CDC object.
Repeatedly call the StartPage member function of the CDC object, inform the view class which page should
be printed, and call the EndPage member function of the CDC object.
Call overridable functions in the view at the appropriate times.
The following articles discuss how the framework supports printing and print preview:
What do you want to know more about
How default printing is done
Multipage documents
Headers and footers
Allocating GDI resources for printing
Print preview

See also
Printing and Print Preview
How Default Printing Is Done
8/15/2019 • 2 minutes to read • Edit Online

This article explains the default printing process in Windows in terms of the MFC framework.
In MFC applications, the view class has a member function named OnDraw that contains all the drawing code.
OnDraw takes a pointer to a CDC object as a parameter. That CDC object represents the device context to receive
the image produced by OnDraw . When the window displaying the document receives a WM_PAINT message, the
framework calls OnDraw and passes it a device context for the screen (a CPaintDC object, to be specific).
Accordingly, OnDraw 's output goes to the screen.
In programming for Windows, sending output to the printer is very similar to sending output to the screen. This is
because the Windows graphics device interface (GDI) is hardware-independent. You can use the same GDI
functions for screen display or for printing simply by using the appropriate device context. If the CDC object that
OnDraw receives represents the printer, OnDraw 's output goes to the printer.

This explains how MFC applications can perform simple printing without requiring extra effort on your part. The
framework takes care of displaying the Print dialog box and creating a device context for the printer. When the user
selects the Print command from the File menu, the view passes this device context to OnDraw , which draws the
document on the printer.
However, there are some significant differences between printing and screen display. When you print, you have to
divide the document into distinct pages and display them one at a time, rather than display whatever portion is
visible in a window. As a corollary, you have to be aware of the size of the paper (whether it's letter size, legal size,
or an envelope). You may want to print in different orientations, such as landscape or portrait mode. The Microsoft
Foundation Class Library can't predict how your application will handle these issues, so it provides a protocol for
you to add these capabilities.
That protocol is described in the article Multipage Documents.

See also
Printing
Multipage Documents
3/27/2020 • 8 minutes to read • Edit Online

This article describes the Windows printing protocol and explains how to print documents that contain more than
one page. The article covers the following topics:
Printing protocol
Overriding view class functions
Pagination
Printer pages vs. document pages
Print-time pagination

The Printing Protocol


To print a multipage document, the framework and view interact in the following manner. First the framework
displays the Print dialog box, creates a device context for the printer, and calls the StartDoc member function of
the CDC object. Then, for each page of the document, the framework calls the StartPage member function of the
CDC object, instructs the view object to print the page, and calls the EndPage member function. If the printer mode
must be changed before starting a particular page, the view calls ResetDC, which updates the DEVMODE structure
containing the new printer mode information. When the entire document has been printed, the framework calls
the EndDoc member function.

Overriding View Class Functions


The CView class defines several member functions that are called by the framework during printing. By overriding
these functions in your view class, you provide the connections between the framework's printing logic and your
view class's printing logic. The following table lists these member functions.
CView's Overridable Functions for Printing
NAME REA SO N F O R O VERRIDIN G

OnPreparePrinting To insert values in the Print dialog box, especially the length of
the document

OnBeginPrinting To allocate fonts or other GDI resources

OnPrepareDC To adjust attributes of the device context for a given page, or


to do print-time pagination

OnPrint To print a given page

OnEndPrinting To deallocate GDI resources

You can do printing-related processing in other functions as well, but these functions are the ones that drive the
printing process.
The following figure illustrates the steps involved in the printing process and shows where each of CView 's
printing member functions are called. The rest of this article explains most of these steps in more detail. Additional
parts of the printing process are described in the article Allocating GDI Resources.

The Printing Loop

Pagination
The framework stores much of the information about a print job in a CPrintInfo structure. Several of the values in
CPrintInfo pertain to pagination; these values are accessible as shown in the following table.

Page Number Information Stored in CPrintInfo


M EM B ER VA RIA B L E O R

F UN C T IO N N A M E( S) PA GE N UM B ER REF EREN C ED

GetMinPage / SetMinPage First page of document

GetMaxPage / SetMaxPage Last page of document

GetFromPage First page to be printed

GetToPage Last page to be printed

m_nCurPage Page currently being printed

Page numbers start at 1, that is, the first page is numbered 1, not 0. For more information about these and other
members of CPrintInfo, see the MFC Reference.
At the beginning of the printing process, the framework calls the view's OnPreparePrinting member function,
passing a pointer to a CPrintInfo structure. The Application Wizard provides an implementation of
OnPreparePrinting that calls DoPreparePrinting, another member function of CView . DoPreparePrinting is the
function that displays the Print dialog box and creates a printer device context.
At this point the application doesn't know how many pages are in the document. It uses the default values 1 and
0xFFFF for the numbers of the first and last page of the document. If you know how many pages your document
has, override OnPreparePrinting and call [SetMaxPage]--brokenlink--(reference/cprintinfo-class.md#setmaxpage)
for the CPrintInfo structure before you send it to DoPreparePrinting . This lets you specify the length of your
document.
DoPreparePrinting then displays the Print dialog box. When it returns, the CPrintInfo structure contains the
values specified by the user. If the user wishes to print only a selected range of pages, he or she can specify the
starting and ending page numbers in the Print dialog box. The framework retrieves these values using the
GetFromPage and GetToPage functions of CPrintInfo. If the user doesn't specify a page range, the framework calls
GetMinPage and GetMaxPage and uses the values returned to print the entire document.

For each page of a document to be printed, the framework calls two member functions in your view class,
OnPrepareDC and OnPrint, and passes each function two parameters: a pointer to a CDC object and a pointer to a
CPrintInfo structure. Each time the framework calls OnPrepareDC and OnPrint , it passes a different value in the
m_nCurPage member of the CPrintInfo structure. In this way the framework tells the view which page should be
printed.
The OnPrepareDC member function is also used for screen display. It makes adjustments to the device context
before drawing takes place. OnPrepareDC serves a similar role in printing, but there are a couple of differences:
first, the CDC object represents a printer device context instead of a screen device context, and second, a
CPrintInfo object is passed as a second parameter. (This parameter is NULL when OnPrepareDC is called for
screen display.) Override OnPrepareDC to make adjustments to the device context based on which page is being
printed. For example, you can move the viewport origin and the clipping region to ensure that the appropriate
portion of the document gets printed.
The OnPrint member function performs the actual printing of the page. The article How Default Printing Is Done
shows how the framework calls OnDraw with a printer device context to perform printing. More precisely, the
framework calls OnPrint with a CPrintInfo structure and a device context, and OnPrint passes the device
context to OnDraw . Override OnPrint to perform any rendering that should be done only during printing and not
for screen display. For example, to print headers or footers (see the article Headers and Footers for more
information). Then call OnDraw from the override of OnPrint to do the rendering common to both screen display
and printing.
The fact that OnDraw does the rendering for both screen display and printing means that your application is
WYSIWYG: "What you see is what you get." However, suppose you aren't writing a WYSIWYG application. For
example, consider a text editor that uses a bold font for printing but displays control codes to indicate bold text on
the screen. In such a situation, you use OnDraw strictly for screen display. When you override OnPrint , substitute
the call to OnDraw with a call to a separate drawing function. That function draws the document the way it appears
on paper, using the attributes that you don't display on the screen.

Printer Pages vs. Document Pages


When you refer to page numbers, it's sometimes necessary to distinguish between the printer's concept of a page
and a document's concept of a page. From the point of view of the printer, a page is one sheet of paper. However,
one sheet of paper doesn't necessarily equal one page of the document. For example, if you're printing a
newsletter, where the sheets are to be folded, one sheet of paper might contain both the first and last pages of the
document, side by side. Similarly, if you're printing a spreadsheet, the document doesn't consist of pages at all.
Instead, one sheet of paper might contain rows 1 through 20, columns 6 through 10.
All the page numbers in the CPrintInfo structure refer to printer pages. The framework calls OnPrepareDC and
OnPrint once for each sheet of paper that will pass through the printer. When you override the OnPreparePrinting
function to specify the length of the document, you must use printer pages. If there is a one-to-one
correspondence (that is, one printer page equals one document page), then this is easy. If, on the other hand,
document pages and printer pages do not directly correspond, you must translate between them. For example,
consider printing a spreadsheet. When overriding OnPreparePrinting , you must calculate how many sheets of
paper will be required to print the entire spreadsheet and then use that value when calling the SetMaxPage
member function of CPrintInfo . Similarly, when overriding OnPrepareDC , you must translate m_nCurPage into the
range of rows and columns that will appear on that particular sheet and then adjust the viewport origin
accordingly.

Print-Time Pagination
In some situations, your view class may not know in advance how long the document is until it has actually been
printed. For example, suppose your application isn't WYSIWYG, so a document's length on the screen doesn't
correspond to its length when printed.
This causes a problem when you override OnPreparePrinting for your view class: you can't pass a value to the
SetMaxPage function of the CPrintInfo structure, because you don't know the length of a document. If the user
doesn't specify a page number to stop at using the Print dialog box, the framework doesn't know when to stop the
print loop. The only way to determine when to stop the print loop is to print out the document and see when it
ends. Your view class must check for the end of the document while it is being printed, and then inform the
framework when the end is reached.
The framework relies on your view class's OnPrepareDC function to tell it when to stop. After each call to
OnPrepareDC , the framework checks a member of the CPrintInfo structure called m_bContinuePrinting. Its default
value is TRUE. As long as it remains so, the framework continues the print loop. If it is set to FALSE , the
framework stops. To perform print-time pagination, override OnPrepareDC to check whether the end of the
document has been reached, and set m_bContinuePrinting to FALSE when it has.
The default implementation of OnPrepareDC sets m_bContinuePrinting to FALSE if the current page is greater than
1. This means that if the length of the document wasn't specified, the framework assumes the document is one
page long. One consequence of this is that you must be careful if you call the base class version of OnPrepareDC .
Do not assume that m_bContinuePrinting will be TRUE after calling the base class version.
What do you want to know more about
Headers and footers
Allocating GDI resources

See also
Printing
CView Class
CDC Class
Headers and Footers
3/4/2019 • 2 minutes to read • Edit Online

This article explains how to add headers and footers to a printed document.
When you look at a document on the screen, the name of the document and your current location in the document
are commonly displayed in a title bar and a status bar. When looking at a printed copy of a document, it's useful to
have the name and page number shown in a header or footer. This is a common way in which even WYSIWYG
programs differ in how they perform printing and screen display.
The OnPrint member function is the appropriate place to print headers or footers because it is called for each
page, and because it is called only for printing, not for screen display. You can define a separate function to print a
header or footer, and pass it the printer device context from OnPrint . You might need to adjust the window origin
or extent before calling OnDraw to avoid having the body of the page overlap the header or footer. You might also
have to modify OnDraw because the amount of the document that fits on the page could be reduced.
One way to compensate for the area taken by the header or footer is to use the m_rectDraw member of
CPrintInfo. Each time a page is printed, this member is initialized with the usable area of the page. If you print a
header or footer before printing the body of the page, you can reduce the size of the rectangle stored in
m_rectDraw to account for the area taken by the header or footer. Then OnPrint can refer to m_rectDraw to
find out how much area remains for printing the body of the page.
You cannot print a header, or anything else, from OnPrepareDC, because it is called before the StartPage member
function of CDC has been called. At that point, the printer device context is considered to be at a page boundary.
You can perform printing only from the OnPrint member function.

What do you want to know more about


Printing multipage documents
Allocating GDI resources for printing

See also
Printing
Allocating GDI Resources
3/27/2020 • 2 minutes to read • Edit Online

This article explains how to allocate and deallocate the Windows graphics device interface (GDI) objects needed for
printing.

NOTE
For more information, see the GDI+ SDK documentation.

Suppose you need to use certain fonts, pens, or other GDI objects for printing, but not for screen display. Because
of the memory they require, it's inefficient to allocate these objects when the application starts up. When the
application isn't printing a document, that memory might be needed for other purposes. It's better to allocate
them when printing begins, and then delete them when printing ends.
To allocate these GDI objects, override the OnBeginPrinting member function. This function is well suited to this
purpose for two reasons: the framework calls this function once at the beginning of each print job and, unlike
OnPreparePrinting, this function has access to the CDC object representing the printer device driver. You can store
these objects for use during the print job by defining member variables in your view class that point to GDI objects
(for example, CFont * members, and so on).
To use the GDI objects you've created, select them into the printer device context in the OnPrint member function.
If you need different GDI objects for different pages of the document, you can examine the m_nCurPage member of
the CPrintInfo structure and select the GDI object accordingly. If you need a GDI object for several consecutive
pages, Windows requires that you select it into the device context each time OnPrint is called.
To deallocate these GDI objects, override the OnEndPrinting member function. The framework calls this function at
the end of each print job, giving you the opportunity to deallocate printing-specific GDI objects before the
application returns to other tasks.

See also
Printing
How Default Printing Is Done
Print Preview Architecture
3/27/2020 • 4 minutes to read • Edit Online

This article explains how the MFC framework implements print preview functionality. Topics covered include:
Print preview process
Modifying print preview
Print preview is somewhat different from screen display and printing because, instead of directly drawing an
image on a device, the application must simulate the printer using the screen. To accommodate this, the Microsoft
Foundation Class Library defines a special (undocumented) class derived from CDC Class, called CPreviewDC . All
CDC objects contain two device contexts, but usually they are identical. In a CPreviewDC object, they are different:
the first represents the printer being simulated, and the second represents the screen on which output is actually
displayed.

The Print Preview Process


When the user selects the Print Preview command from the File menu, the framework creates a CPreviewDC
object. Whenever your application performs an operation that sets a characteristic of the printer device context, the
framework also performs a similar operation on the screen device context. For example, if your application selects
a font for printing, the framework selects a font for screen display that simulates the printer font. Whenever your
application would send output to the printer, the framework instead sends the output to the screen.
Print preview also differs from printing in the order that each draws the pages of a document. During printing, the
framework continues a print loop until a certain range of pages has been rendered. During print preview, one or
two pages are displayed at any time, and then the application waits; no further pages are displayed until the user
responds. During print preview, the application must also respond to WM_PAINT messages, just as it does during
ordinary screen display.
The CView::OnPreparePrinting function is called when preview mode is invoked, just as it is at the beginning of a
print job. The CPrintInfo Structure structure passed to the function contains several members whose values you
can set to adjust certain characteristics of the print preview operation. For example, you can set the
m_nNumPreviewPages member to specify whether you want to preview the document in one-page or two-page
mode.

Modifying Print Preview


You can modify the behavior and appearance of print preview in a number of ways rather easily. For example, you
can, among other things:
Cause the print preview window to display a scroll bar for easy access to any page of the document.
Cause print preview to maintain the user's position in the document by beginning its display at the current
page.
Cause different initialization to be performed for print preview and printing.
Cause print preview to display page numbers in your own formats.
If you know how long the document is and call SetMaxPage with the appropriate value, the framework can use this
information in preview mode as well as during printing. Once the framework knows the length of the document, it
can provide the preview window with a scroll bar, allowing the user to page back and forth through the document
in preview mode. If you haven't set the length of the document, the framework cannot position the scroll box to
indicate the current position, so the framework doesn't add a scroll bar. In this case, the user must use the Next
Page and Previous Page buttons on the preview window's control bar to page through the document.
For print preview, you may find it useful to assign a value to the m_nCurPage member of CPrintInfo , even though
you would never do so for ordinary printing. During ordinary printing, this member carries information from the
framework to your view class. This is how the framework tells the view which page should be printed.
By contrast, when print preview mode is started, the m_nCurPage member carries information in the opposite
direction: from the view to the framework. The framework uses the value of this member to determine which page
should be previewed first. The default value of this member is 1, so the first page of the document is displayed
initially. You can override OnPreparePrinting to set this member to the number of the page being viewed at the
time the Print Preview command was invoked. This way, the application maintains the user's current position when
moving from normal display mode to print preview mode.
Sometimes you may want OnPreparePrinting to perform different initialization depending on whether it is called
for a print job or for print preview. You can determine this by examining the m_bPreview member variable in the
CPrintInfo structure. This member is set to TRUE when print preview is invoked.

The CPrintInfo structure also contains a member named m_strPageDesc, which is used to format the strings
displayed at the bottom of the screen in single-page and multiple-page modes. By default these strings are of the
form "Page n" and "Pages n - m," but you can modify m_strPageDesc from within OnPreparePrinting and set the
strings to something more elaborate. See CPrintInfo Structure in the MFC Reference for more information.

See also
Printing and Print Preview
Printing
CView Class
CDC Class
Property Sheets (MFC)
4/1/2019 • 2 minutes to read • Edit Online

This family of articles explains how to implement support for property sheets in MFC applications. A property
sheet, also known as a tab dialog box, provides a way to manage large numbers of controls in a dialog box. The
property sheet contains property pages, each based on a separate dialog template resource. You can divide your
dialog box's controls into logical groups and put each group on its own property page.

What do you want to know more about


Property sheets and property pages
Using Property Sheets in Your Application
Adding Controls to a Property Sheet (as opposed to a property page)
Exchanging data between a property sheet and your program
Creating a modeless property sheet
Handling the Apply button
Property Sheets as Wizards
Class CPropertySheet
Class CPropertyPage
Sample

See also
User Interface Elements
Property Sheets and Property Pages in MFC
3/27/2020 • 2 minutes to read • Edit Online

A property sheet, also known as a tab dialog box, is a dialog box that contains property pages. Each property page
is based on a dialog template resource and contains controls. It is enclosed on a page with a tab on top. The tab
names the page and indicates its purpose. Users click a tab in the property sheet to select a set of controls.
Use pages to group the controls in the property sheet into meaningful sets. The contained property sheet typically
has several controls of its own. These apply to all pages.
Property sheets are based on class CPropertySheet. Property pages are based on class CPropertyPage.
A property sheet is a special kind of dialog box that is generally used to modify the attributes of some external
object, such as the current selection in a view. The property sheet has three main parts: the containing dialog box,
one or more property pages shown one at a time, and a tab at the top of each page that the user clicks to select
that page. Property sheets are useful for situations where you have several similar groups of settings or options to
change. A property sheet groups information in an easily understood manner.

NOTE
When you are trying to show a property sheet by using CPropertySheet::DoModal , the system might generate a first-
chance exception. This exception occurs because the system is trying to change the Window Styles of the object before the
object has been created. For more information about this exception, and also how to avoid it or handle it, see
CPropertySheet::DoModal.

See also
Property Sheets
Using Property Sheets in Your Application
4/1/2019 • 3 minutes to read • Edit Online

To use a property sheet in your application, complete the following steps:


1. Create a dialog template resource for each property page. Keep in mind that the user may be switching from
one page to another, so lay out each page as consistently as possible.
The dialog templates for all pages do not have to be the same size. The framework uses the size of the
largest page to determine how much space to allocate in the property sheet for the property pages.
When you create the dialog template resource for a property page, you must specify the following styles in
the Dialog Properties property sheet:
Set the Caption edit box on the General page to the text you wish to appear in the tab for this page.
Set the Style list box on the Styles page to Child .
Set the Border list box on the Styles page to Thin .
Ensure that the Titlebar check box on the Styles page is selected.
Ensure that the Disabled check box on the More Styles page is selected.
2. Create a CPropertyPage-derived class corresponding to each property page dialog template. See Adding a
Class. Choose CPropertyPage as the base class.
3. Create member variables to hold the values for this property page. The process for adding member
variables to a property page is exactly the same as adding member variables to a dialog box, because a
property page is a specialized dialog box. For more information, see Defining Member Variables for Dialog
Controls.
4. Construct a CPropertySheet object in your source code. Usually, you construct the CPropertySheet object in
the handler for the command that displays the property sheet. This object represents the entire property
sheet. If you create a modal property sheet with the DoModal function, the framework supplies three
command buttons by default: OK, Cancel, and Apply. The framework creates no command buttons for
modeless property sheets created with the Create function. You do not need to derive a class from
CPropertySheet unless you want to either add other controls (such as a preview window) or display a
modeless property sheet. This step is necessary for modeless property sheets because they do not contain
any default controls that could be used to close the property sheet.
5. For each page to be added to the property sheet, do the following:
Construct one object for each CPropertyPage -derived class that you created earlier in this process.
Call CPropertySheet::AddPage for each page.
Typically, the object that creates the CPropertySheet also creates the CPropertyPage objects in this step.
However, if you implement a CPropertySheet -derived class, you can embed the CPropertyPage objects in the
CPropertySheet object and call AddPage for each page from the CPropertySheet -derived class constructor.
AddPage adds the CPropertyPage object to the property sheet's list of pages but does not actually create the
window for that page. Therefore, it is not necessary to wait until creation of the property sheet window to
call AddPage ; you can call AddPage from the property sheet's constructor.
By default, if a property sheet has more tabs than will fit in a single row of the property sheet, the tabs will
stack in multiple rows. To disable stacking, call CPropertySheet::EnableStackedTabs with the parameter set to
FALSE . You must call EnableStackedTabs when you create the property sheet.
6. Call CPropertySheet::DoModal or Create to display the property sheet. Call DoModal to create a property
sheet as a modal dialog box. Call Create to create the property sheet as a modeless dialog box.
7. Exchange data between property pages and the owner of the property sheet. This is explained in the article
Exchanging Data.
For an example of how to use property sheets, see the MFC General sample PROPDLG.

See also
Property Sheets
Adding Controls to a Property Sheet
3/4/2019 • 2 minutes to read • Edit Online

By default, a property sheet allocates window area for the property pages, the tab index, and the OK, Cancel, and
Apply buttons. (A modeless property sheet does not have the OK, Cancel, and Apply buttons.) You can add other
controls to the property sheet. For example, you can add a preview window to the right of the property page area
to show the user what the current settings would look like if applied to an external object.
You can add controls to the property sheet dialog in the OnCreate handler. Accommodating additional controls
usually requires expanding the size of the property sheet dialog. After calling the base class
CProper tySheet::OnCreate , call GetWindowRect to get the width and height of the currently allocated property
sheet window, expand the rectangle's dimensions, and call MoveWindow to change the size of the property sheet
window.

See also
Property Sheets
CPropertyPage Class
CPropertySheet Class
Exchanging Data
3/4/2019 • 2 minutes to read • Edit Online

As with most dialog boxes, the exchange of data between the property sheet and the application is one of the most
important functions of the property sheet. This article describes how to accomplish this task.
Exchanging data with a property sheet is actually a matter of exchanging data with the individual property pages
of the property sheet. The procedure for exchanging data with a property page is the same as for exchanging data
with a dialog box, since a CPropertyPage object is just a specialized CDialog object. The procedure takes advantage
of the framework's dialog data exchange (DDX) facility, which exchanges data between controls in a dialog box and
member variables of the dialog box object.
The important difference between exchanging data with a property sheet and with a normal dialog box is that the
property sheet has multiple pages, so you must exchange data with all the pages in the property sheet. For more
information on DDX, see Dialog Data Exchange and Validation.
The following example illustrates exchanging data between a view and two pages of a property sheet:

void CMyView::DoModalPropertySheet()
{
CPropertySheet propsheet;
CMyFirstPage pageFirst; // derived from CPropertyPage
CMySecondPage pageSecond; // derived from CPropertyPage

// Move member data from the view (or from the currently
// selected object in the view, for example).
pageFirst.m_nMember1 = m_nMember1;
pageFirst.m_nMember2 = m_nMember2;

pageSecond.m_strMember3 = m_strMember3;
pageSecond.m_strMember4 = m_strMember4;

propsheet.AddPage(&pageFirst);
propsheet.AddPage(&pageSecond);

if (propsheet.DoModal() == IDOK)
{
m_nMember1 = pageFirst.m_nMember1;
m_nMember2 = pageFirst.m_nMember2;
m_strMember3 = pageSecond.m_strMember3;
m_strMember4 = pageSecond.m_strMember4;
GetDocument()->SetModifiedFlag();
GetDocument()->UpdateAllViews(NULL);
}
}

See also
Property Sheets
Creating a Modeless Property Sheet
9/30/2019 • 2 minutes to read • Edit Online

Normally, the property sheets you create will be modal. When using a modal property sheet, the user must close
the property sheet before using any other part of the application. This article describes methods you can use to
create a modeless property sheet that allows the user to keep the property sheet open while using other parts of
the application.
To display a property sheet as a modeless dialog box instead of as a modal dialog box, call CPropertySheet::Create
instead of DoModal. You must also implement some extra tasks to support a modeless property sheet.
One of the additional tasks is exchanging data between the property sheet and the external object it is modifying
when the property sheet is open. This is generally the same task as for standard modeless dialog boxes. Part of this
task is implementing a channel of communication between the modeless property sheet and the external object to
which the property settings apply. This implementation is far easier if you derive a class from CPropertySheet for
your modeless property sheet. This article assumes you have done so.
One method for communicating between the modeless property sheet and the external object (the current
selection in a view, for example) is to define a pointer from the property sheet to the external object. Define a
function (called something like SetMyExternalObject ) in the CPropertySheet -derived class to change the pointer
whenever the focus changes from one external object to another. The SetMyExternalObject function needs to reset
the settings for each property page to reflect the newly selected external object. To accomplish this, the
SetMyExternalObject function must be able to access the CPropertyPage objects belonging to the CPropertySheet
class.
The most convenient way to provide access to property pages within a property sheet is to embed the
CPropertyPage objects in the CPropertySheet -derived object. Embedding CPropertyPage objects in the
CPropertySheet -derived object differs from the typical design for modal dialog boxes, where the owner of the
property sheet creates the CPropertyPage objects and passes them to the property sheet via
CPropertySheet::AddPage.
There are many user-interface alternatives for determining when the settings of the modeless property sheet
should be applied to an external object. One alternative is to apply the settings of the current property page
whenever the user changes any value. Another alternative is to provide an Apply button, which allows the user to
accumulate changes in the property pages before committing them to the external object. For information on ways
to handle the Apply button, see the article Handling the Apply Button.

See also
Property Sheets
Exchanging Data
Working with Dialog Boxes in MFC
Handling the Apply Button
4/1/2019 • 2 minutes to read • Edit Online

Property sheets have a capability that standard dialog boxes do not: They allow the user to apply changes they
have made before closing the property sheet. This is done using the Apply button. This article discusses methods
you can use to implement this feature properly.
Modal dialog boxes usually apply the settings to an external object when the user clicks OK to close the dialog box.
The same is true for a property sheet: When the user clicks OK, the new settings in the property sheet take effect.
However, you may want to allow the user to save settings without having to close the property sheet dialog box.
This is the function of the Apply button. The Apply button applies the current settings in all of the property pages
to the external object, as opposed to applying only the current settings of the currently active page.
By default, the Apply button is always disabled. You must write code to enable the Apply button at the appropriate
times, and you must write code to implement the effect of Apply, as explained below.
If you do not wish to offer the Apply functionality to the user, it is not necessary to remove the Apply button. You
can leave it disabled, as will be common among applications that use standard property sheet support available in
future versions of Windows.
To report a page as being modified and enable the Apply button, call CPropertyPage::SetModified( TRUE ) . If any of
the pages report being modified, the Apply button will remain enabled, regardless of whether the currently active
page has been modified.
You should call CPropertyPage::SetModified whenever the user changes any settings in the page. One way to
detect when a user changes a setting in the page is to implement change notification handlers for each of the
controls in the property page, such as EN_CHANGE or BN_CLICKED .
To implement the effect of the Apply button, the property sheet must tell its owner, or some other external object
in the application, to apply the current settings in the property pages. At the same time, the property sheet should
disable the Apply button by calling CPropertyPage::SetModified( FALSE ) for all pages that applied their
modifications to the external object.
For an example of this process, see the MFC General sample PROPDLG.

See also
Property Sheets
Property Sheets as Wizards
3/4/2019 • 2 minutes to read • Edit Online

A key characteristic of a wizard property sheet is that navigation is provided with Next or Finish, Back, and Cancel
buttons instead of tabs. You need to call CPropertySheet::SetWizardMode before calling CPropertySheet::DoModal
on the property sheet object to take advantage of this feature.
The user receives the same CPropertyPage::OnSetActive and CPropertyPage::OnKillActive notifications while
moving from one page to another page. Next and Finish buttons are mutually exclusive controls; that is, only one of
them will be shown at a time. On the first page, the Next button should be enabled. If the user is on the last page,
the Finish button should be enabled. This is not done automatically by the framework. You have to call
CPropertySheet::SetWizardButton on the last page to achieve this.
To display all of the default buttons, you mush show the Finish button and move the Next button. Then move the
Back button so that its relative position to the Next button is maintained.

Example
void CMyView::OnWizard()
{
CPropertySheet sheet;
// CMyFirstPage and CMySecondPage are derived from CPropertyPage
CMyFirstPage page1;
CMySecondPage page2;

sheet.AddPage(&page1);
sheet.AddPage(&page2);
sheet.SetWizardMode();
sheet.DoModal();
}

See also
Property Sheets
Ribbon Designer (MFC)
3/31/2020 • 3 minutes to read • Edit Online

The Ribbon Designer lets you create and customize ribbons in MFC applications. A ribbon is a user interface (UI)
element that organizes commands into logical groups. These groups appear on separate tabs in a strip across the
top of the window. The ribbon replaces the menu bar and toolbars. A ribbon can significantly improve application
usability. For more information, see Ribbons. The following illustration shows a ribbon.

In earlier versions of Visual Studio, ribbons had to be created by writing code that uses the MFC ribbon classes
such as CMFCRibbonBar Class. In Visual Studio 2010 and later, the ribbon designer provides an alternative method
for building ribbons. First, create and customize a ribbon as a resource. Then load the ribbon resource from code
in the MFC application. You can even use ribbon resources and MFC ribbon classes together. For example, you can
create a ribbon resource, and then programmatically add more elements to it at runtime by using code.

Understanding the Ribbon Designer


The ribbon designer creates and stores the ribbon as a resource. When you create a ribbon resource, the ribbon
designer does these three things:
Adds an entry in the project resource definition script (*.rc). In the following example, IDR_RIBBON is the
unique name that identifies the ribbon resource, RT_RIBBON_XML is the resource type, and ribbon.mfcribbon-
ms is the name of the resource file.

IDR_RIBBON RT_RIBBON_XML "res\\ribbon.mfcribbon-ms"

Adds the definitions of Command IDs to resource.h.

#define IDR_RIBBON 307

Creates a ribbon resource file (*.mfcribbon-ms) that contains the XML code that defines the ribbon's buttons,
controls, and attributes. Changes to the ribbon in the ribbon designer are stored in the resource file as XML. The
following code example shows part of the contents of a *.mfcribbon-ms file:

<RIBBON_BAR>
<ELEMENT_NAME>RibbonBar</ELEMENT_NAME>
<IMAGE>
<ID>
<NAME>IDB_BUTTONS</NAME>
<VALUE>113</VALUE>
</ID>

To use the ribbon resource in your MFC application, load the resource by calling
CMFCRibbonBar::LoadFromResource.

Creating a Ribbon By Using the Ribbon Designer


These are the two ways to add a ribbon resource to your MFC project:
Create an MFC application and configure the MFC Project Wizard to create the ribbon. For more
information, see Walkthrough: Creating a Ribbon Application By Using MFC.
In an existing MFC project, create a ribbon resource and load it. For more information, see Walkthrough:
Updating the MFC Scribble Application (Part 1).
If your project already has a manually coded ribbon, MFC has functions that you can use to convert the existing
ribbon to a ribbon resource. For more information, see How to: Convert an Existing MFC Ribbon to a Ribbon
Resource.

NOTE
Ribbons cannot be created in dialog-based applications. For more information, see Application Type, MFC Application
Wizard.

Customizing Ribbons
To open a ribbon in the ribbon designer, double-click the ribbon resource in Resource View. In the designer, you
can add, remove, and customize elements on the ribbon, the Application button, or the quick access toolbar. You
can also link events, for example, button-click events and menu events, to a method in your application.
The following illustration shows the various components in the ribbon designer.

Toolbox: Contains controls that can be dragged to the designer surface.


Designer Surface: Contains the visual representation of the ribbon resource.
Class Wizard : Lists the attributes of the item that is selected on the designer surface.
Resource View window: Displays the resources that include ribbon resources, in your project.
Ribbon Editor Toolbar : Contains commands that let you preview the ribbon and change its visual theme.
The following topics describe how to use the features in the ribbon designer:
How to: Customize the Application Button
How to: Customize the Quick Access Toolbar
How to: Add Ribbon Controls and Event Handlers
How to: Load a Ribbon Resource from an MFC Application

Definitions of Ribbon Elements

Application button: The button that appears on the upper-left corner of a ribbon. The Application button
replaces the File menu and is visible even when the ribbon is minimized. When the button is clicked, a menu
that has a list of commands is displayed.
Quick Access toolbar : A small, customizable toolbar that displays frequently used commands.
Categor y : The logical grouping that represents the contents of a ribbon tab.
Categor y Default button: The button that appears on the ribbon when the ribbon is minimized. When
the button is clicked, the category reappears as a menu.
Panel: An area of the ribbon bar that displays a group of related controls. Every ribbon category contains
one or more ribbon panels.
Ribbon elements: Controls in the panels, for example, buttons and combo boxes. To see the various
controls that can be hosted on a ribbon, see RibbonGadgets Sample: Ribbon Gadgets Application.

See also
User Interface Elements
Working with Resource Files
How to: Convert an Existing MFC Ribbon to a
Ribbon Resource
3/4/2019 • 2 minutes to read • Edit Online

Ribbon resources are easier to visualize, modify, and maintain than manually coded ribbons. This topic describes
how to convert a manually coded ribbon in an MFC Project into a ribbon resource.
You must have an existing MFC project that has code that uses the MFC ribbon classes, for example,
CMFCRibbonBar Class.
To convert an MFC ribbon to a ribbon resource
1. In Visual Studio, in an existing MFC project, open the source file where the CMFCRibbonBar object is initialized.
Typically, the file is mainfrm.cpp. Add the following code after the initialization code for the ribbon.

m_wndRibbonBar.SaveToXMLFile("RibbonOutput.xml");

Save and close the file.


1. Build and run the MFC application, and then in Notepad, open RibbonOutput.txt and copy its contents.
2. In Visual Studio, on the Project menu, click Add Resource . In the Add Resource dialog box, select Ribbon
and then click New .
Visual Studio creates a ribbon resource and opens it in design view. The ribbon resource ID is IDR_RIBBON1,
which is displayed in Resource View . The ribbon is defined in the ribbon1.mfcribbon-ms XML file.
3. In Visual Studio, open ribbon1.mfcribbon-ms, delete its contents, and then paste the contents of
RibbonOutput.txt, which you copied earlier. Save and close ribbon1.mfcribbon-ms.
4. Again open the source file where the CMFCRibbonBar object is initialized (typically, mainfrm.cpp) and
comment out the existing ribbon code. Add the following code after the code that you commented out.

m_wndRibbonBar.LoadFromResource(IDR_RIBBON1);

1. Build the project and run the program.

See also
Ribbon Designer (MFC)
How to: Customize the Application Button
9/11/2019 • 2 minutes to read • Edit Online

When you click the Application button, a menu of commands is displayed. Typically, the menu contains file-related
commands such as Open , Save , Print , and Exit .

To customize the Application button, open it in the Proper ties window (in Resource View ), modify its properties,
and then preview the ribbon control.
To open the Application button in the Properties window
1. In Visual Studio, on the View menu, click Resource View .
2. In Resource View , double-click the ribbon resource to display it on the design surface.
3. On design surface, right-click the Application button menu and then click Proper ties .

Application Button Properties


The following table defines the properties of the Application button.

P RO P ERT Y DEF IN IT IO N

Buttons Contains the collection of up to three buttons that appear in


the bottom-right corner of the Application menu.

Caption Specifies the text of the control. Unlike other ribbon elements,
the Application button does not display caption text. Instead,
the text is used for accessibility.

HDPI Image Specifies the identifier of the high dots per inch (HDPI)
Application button icon. When the application runs on a high
DPI monitor, HDPI Image is used instead of Image .

HDPI Large Images Specifies the identifier of the high DPI large images. When the
application runs on a high DPI monitor, HDPI Large Images
is used instead of Large Images .
P RO P ERT Y DEF IN IT IO N

HDPI Small Images Specifies the identifier of the high DPI small images. When the
application runs on a high DPI monitor, HDPI Small Images
is used instead of Small Images .

ID Specifies the identifier of the control.

Image Specifies the identifier of the Application button icon. The icon
is a 32-bit 26x26 bitmap that has alpha transparency. The
transparent portions of the icon are highlighted when the
Application button is clicked or hovered over.

Keys Specifies the string that is displayed when key-tip navigation is


enabled. Key-tip navigation is enabled when you press ALT.

Large Images Specifies the identifier of the image that contains a series of
32x32 icons. The icons are used by the buttons in the Main
Items collection.

Main Items Contains a collection of menu items that appear on the


Application menu.

MRU Caption Specifies the text displayed on the Recent List panel.

Small Images Specifies the identifier of the image that contains a series of
16x16 icons. The icons are used by the buttons in the Buttons
collection.

Use Enables or disables the Recent List panel. The Recent List panel
appears on the Application menu.

Width Specifies the width in pixels of the Recent List panel.

The Application menu does not appear on the design surface. To view it, you must either preview the ribbon or run
the application.
To preview the ribbon control
On the Ribbon Editor Toolbar , click Test Ribbon .

See also
Ribbon Designer (MFC)
How to: Customize the Quick Access Toolbar
9/11/2019 • 2 minutes to read • Edit Online

The Quick Access Toolbar (QAT) is a customizable toolbar that contains a set of commands that are either displayed
next to the Application button or under the category tabs. The following illustration shows a typical Quick Access
Toolbar.

To customize the Quick Access Toolbar, open it in the Proper ties window, modify its commands, and then preview
the ribbon control.
To open the Quick Access Toolbar in the Properties window
1. In Visual Studio, on the View menu, click Resource View .
2. In Resource View , double-click the ribbon resource to display it on the design surface.
3. On design surface, right-click the Quick Access Toolbar menu and then click Proper ties .

Quick Access Toolbar Properties


The following table defines the properties of the Quick Access Toolbar.

P RO P ERT Y DEF IN IT IO N

QAT Position Specifies the position of the Quick Access Toolbar when the
application starts. The position can be either Above or Below
the ribbon control.

QAT Items Specifies the commands that are available for the Quick Access
Toolbar.

To add or remove commands on the Quick Access Toolbar


1. In the Proper ties window, click QAT Items , and then click the ellipsis button (...) .
2. In the QAT Items Editor dialog box, use the Add and Remove buttons to modify the list of commands on
the Quick Access Toolbar.
3. If you want a command to appear on both the Quick Access Toolbar and the Quick Access Toolbar menu,
select the box next to the command. If you want the command to appear only on the menu, clear the box.

Previewing the Ribbon


Quick Access Toolbar commands do not appear on the design surface. To view them, you must either preview the
ribbon or run the application.
To preview the ribbon control
On the Ribbon Editor Toolbar , click Test Ribbon .

See also
Ribbon Designer (MFC)
How to: Add Ribbon Controls and Event Handlers
4/1/2019 • 2 minutes to read • Edit Online

Ribbon controls are elements, such as buttons and combo boxes, that you add to panels. Panels are areas of the
ribbon bar that display a group of related controls.
In this topic, you will open the Ribbon Designer, add a button, and then link an event that displays "Hello World".
To open the Ribbon Designer
1. In Visual Studio, on the View menu, click Resource View .
2. In Resource View , double-click the ribbon resource to display it on the design surface.
To add a Button and an Event Handler
1. From the Toolbar , click Button and drag it on to a panel in the design surface.
2. Right-click the button, and click Add Event Handler .
3. In the Event Handler Wizard , confirm the default settings and click Add and Edit . For more information,
see Event Handler Wizard.
4. In the code editor, add the following code into the handler function:

MessageBox((LPCTSTR)L"Hello World");

See also
RibbonGadgets Sample: Ribbon Gadgets Application
Ribbon Designer (MFC)
How to: Load a Ribbon Resource from an MFC
Application
3/4/2019 • 2 minutes to read • Edit Online

To use the ribbon resource in your application, modify the application to load the ribbon resource.
To load a ribbon resource
1. Declare the Ribbon Control object in the CMainFrame class.

CMFCRibbonBar m_wndRibbonBar;

1. In CMainFrame::OnCreate , create and initialize the Ribbon Control.

if (!m_wndRibbonBar.Create (this))
{
return -1;
}

if (!m_wndRibbonBar.LoadFromResource(IDR_RIBBON))
{
return -1;
}

See also
Ribbon Designer (MFC)
Walkthrough: Creating a Ribbon Application By Using
MFC
1/28/2020 • 4 minutes to read • Edit Online

This walkthrough shows how to use the MFC Application Wizard to create an application that has a ribbon by
default. You can then expand the ribbon by adding a Custom ribbon category that has a Favorites ribbon panel,
and then adding some frequently used commands to the panel.

Prerequisites
This walkthrough assumes that you have set Visual Studio to use General Development Settings . If you're using
different settings, some of the user interface (UI) elements that are referenced in the following instructions might
not be displayed.
To create an MFC application that has a ribbon
1. Use the MFC Application Wizard to create an MFC application that has a ribbon. See Walkthrough: Using
the New MFC Shell Controls for instructions on how to open the wizard for your version of Visual Studio.
2. Set the following options in the MFC Application Wizard :
a. In the Application Type section, under Visual style and colors , select Office 2007 (Blue
theme) .
b. In the Compound Document Suppor t section, make sure that None is selected.
c. In the Document Template Proper ties section, in the File extension box, type a file name
extension for documents that this application creates, for example, mfcrbnapp.
d. In the Database Suppor t section (Visual Studio 2015 only), make sure that None is selected.
e. In the User Interface Features section, make sure that Use a ribbon is selected.
f. By default, the MFC Application Wizard adds support for several docking panes. Because this
walkthrough just teaches about the ribbon, you can remove these options from the application. In the
Advanced Features section, clear all options.
3. Click Finish to create the MFC application.
4. To verify that the application was created successfully, build it and run it. To build the application, on the
Build menu, click Build Solution . If the application builds successfully, run it by clicking Star t Debugging
on the Debug menu.
The wizard automatically creates a ribbon that has one ribbon category that is named Home . This ribbon
contains three ribbon panels, which are named Clipboard , View , and Window .
To add a category and panel to the ribbon
1. To open the ribbon resource that the wizard created, on the View menu, point to Other Windows and then
click Resource View . In Resource View , click Ribbon and then double-click IDR_RIBBON .
2. First, add a custom category to the ribbon by double-clicking Categor y in the Toolbox .
A category that has the caption Categor y1 is created. By default, the category contains one panel.
Right-click Categor y1 and then click Proper ties . In Proper ties window, change Caption to Custom.
The Large Images and Small Images properties specify the bitmaps that are used as icons for the ribbon
elements in this category. Because creating custom bitmaps is beyond the scope of this walkthrough, just
reuse the bitmaps that were created by the wizard. Small bitmaps are 16 pixels by 16 pixels. For small
images, use the bitmaps that are accessed by the IDB_FILESMALL resource ID. Large bitmaps are 32 pixels by
32 pixels. For large images, use the bitmaps that are accessed by the IDB_FILELARGE resource ID.

NOTE
On high dots per inch (HDPI) displays, the HDPI versions of the images are automatically used.

3. Next, customize the panel. Panels are used to group items that are logically related to one another. For
example, on the Home tab of this application, the Cut , Copy , and Paste commands are all located on the
Clipboard panel. To customize the panel, right-click Panel1 and then click Proper ties . In the Proper ties
window, change Caption to Favorites.
You can specify the Image Index for the panel. This number specifies the icon that is displayed if the ribbon
panel is added to the Quick Access Toolbar . The icon isn't displayed on the ribbon panel itself.
4. To verify that the ribbon category and panel were created successfully, preview the ribbon control. On the
Ribbon Editor Toolbar , click the Test Ribbon button. A Custom tab and Favorites panel should be
displayed on the ribbon.
To add elements to the ribbon panels
1. To add elements to the panel that you created in the previous procedure, drag controls from the Ribbon
Editor section of the Toolbox to the panel in the design view.
2. First, add a Print button. The Print button will have a submenu that contains a Quick Print command that
prints by using the default printer. Both of these commands are already defined for this application. They're
located on the application menu.
To create the Print button, drag a Button tool to the panel.
In Proper ties window, change the ID property to ID_FILE_PRINT , which should already be defined.
Change Caption to Print. Change Image Index to 4.
To create the Quick Print button, click the property value column next to Menu Items , and then click the
ellipsis (...). In the Items Editor , click the unlabeled Add button to create a menu item. In the Proper ties
window, change Caption to Quick Print, ID to ID_FILE_PRINT_DIRECT, and Image to 5. The image property
specifies the Quick Print icon in the IDB_FILESMALL bitmap resource.
3. To verify that the buttons were added to the ribbon panel, build the application and run it. To build the
application, on the Build menu, click Build Solution . If the application builds successfully, run the
application by clicking Star t Debugging on the Debug menu. The Print button and the combo box on the
Favorites panel on the Custom tab on the ribbon should be displayed.

Next Steps
How to: Customize the Quick Access Toolbar
How to: Customize the Application Button
For end-to-end samples, see Samples (MFC Feature Pack).

See also
Walkthroughs
Samples (MFC Feature Pack)
Walkthrough: Updating the MFC Scribble Application
(Part 1)
3/27/2020 • 10 minutes to read • Edit Online

This walkthrough demonstrates how to modify an existing MFC application to use the Ribbon user interface. Visual
Studio supports both the Office 2007 Ribbon and the Windows 7 Scenic Ribbon. For more information about the
Ribbon user interface, see Ribbons.
This walkthrough modifies the classic Scribble 1.0 MFC sample that lets you use the mouse to create line drawings.
This part of the walkthrough shows how to modify the Scribble sample so that it displays a ribbon bar. Part 2 adds
more buttons to the ribbon bar.

Prerequisites
The Scribble 1.0 MFC sample. For help on converting to Visual Studio 2017 or later, see Porting Guide: MFC
Scribble.

Sections
This part of the walkthrough has the following sections:
Replacing the Base Classes
Adding Bitmaps to the Project
Adding a Ribbon Resource to the Project
Creating an Instance of the Ribbon Bar
Adding a Ribbon Category
Setting the Look of the Application

Replacing the Base Classes


To convert an application that supports a menu to an application that supports a ribbon, you must derive the
application, frame window, and toolbar classes from updated base classes. (We suggest that you don't modify the
original Scribble sample. Instead, clean the Scribble project, copy it to another directory, and then modify the copy.)
To replace the base classes in the Scribble application
1. In scribble.cpp, verify that CScribbleApp::InitInstance includes a call to AfxOleInit.
2. Add the following code to the pch.h file (stdafx.h in Visual Studio 2017 and earlier):

#include <afxcontrolbars.h>

3. In scribble.h, modify the definition for the CScribbleApp class so that it's derived from CWinAppEx Class.

class CScribbleApp: public CWinAppEx

4. Scribble 1.0 was written when Windows applications used an initialization (.ini) file to save user preference
data. Instead of an initialization file, modify Scribble to store user preferences in the registry. To set the
registry key and base, type the following code in CScribbleApp::InitInstance after the
LoadStdProfileSettings() statement.

SetRegistryKey(_T("MFCNext\\Samples\\Scribble2"));
SetRegistryBase(_T("Settings"));

5. The main frame for a multiple document interface (MDI) application is no longer derived from the
CMDIFrameWnd class. Instead, it's derived from the CMDIFrameWndEx class.

In the mainfrm.h and mainfrm.cpp files, replace all references to CMDIFrameWnd with CMDIFrameWndEx .
6. In the childfrm.h and childfrm.cpp files, replace CMDIChildWnd with CMDIChildWndEx .
In the childfrm. h file, replace CSplitterWnd with CSplitterWndEx .
7. Modify toolbars and status bars to use the new MFC classes.
In the mainfrm.h file:
a. Replace CToolBar with CMFCToolBar .
b. Replace CStatusBar with CMFCStatusBar .
8. In the mainfrm.cpp file:
a. Replace m_wndToolBar.SetBarStyle with m_wndToolBar.SetPaneStyle

b. Replace m_wndToolBar.GetBarStyle with m_wndToolBar.GetPaneStyle

c. Replace DockControlBar(&m_wndToolBar) with DockPane(&m_wndToolBar)

9. In the ipframe.cpp file, comment out the following three lines of code.

m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
pWndFrame->EnableDocking(CBRS_ALIGN_ANY);
pWndFrame->DockPane(&m_wndToolBar);

10. Save the changes and then build and run the application.

Adding Bitmaps to the Project


The next four steps of this walkthrough require bitmap resources. You can get the appropriate bitmaps in various
ways:
Use the Resource Editors to invent your own bitmaps. Or use the resource editors to assemble bitmaps
from the portable network graphics (.png) images that are included with Visual Studio and can be
downloaded from the Visual Studio image library.
However, the Ribbon user interface requires that certain bitmaps support transparent images. Transparent
bitmaps use 32-bit pixels, where 24 bits specify the red, green, and blue components of the color, and 8 bits
define an alpha channel that specifies the transparency of the color. The current resource editors can view,
but not modify bitmaps with 32-bit pixels. Consequently, use an external image editor instead of the
resource editors to manipulate transparent bitmaps.
Copy an appropriate resource file from another application to your project and then import bitmaps from
that file.
This walkthrough copies resource files from the example created in Walkthrough: Creating a Ribbon Application By
Using MFC.
To add bitmaps to the Project
1. Use File Explorer to copy the following .bmp files from the resources directory ( res ) of the Ribbon
example to the resource directory ( res ) of the Scribble project:
a. Copy main.bmp to your Scribble project.
b. Copy filesmall.bmp and filelarge.bmp to your Scribble project.
c. Make new copies of the filelarge.bmp and filesmall.bmp files, but save the copies in the Ribbon
example. Rename the copies homesmall.bmp and homelarge.bmp and then move the copies to your
Scribble project.
d. Make a copy of the toolbar.bmp file, but save the copy in the Ribbon example. Rename the copy
panelicons.bmp and then move the copy to your Scribble project.
2. Import the bitmap for an MFC application. In Resource View , double-click the scribble.rc node, double-
click the Bitmap node, and then click Add resource . On the dialog box that appears, click Impor t . Browse
to the res directory, select the main.bmp file, and then click Open .
The main.bmp bitmap contains a 26x26 image. Change the ID of the bitmap to IDB_RIBBON_MAIN .
3. Import the bitmaps for the file menu that is attached to the Application button.
a. Import the filesmall.bmp file, which contains eleven 16x16 (16x176) images. Change the ID of the
bitmap to IDB_RIBBON_FILESMALL .

NOTE
Because we need only the first eight 16x16 images (16x128), you may optionally crop the right-side width of this
bitmap from 176 to 128.

a. Import the filelarge.bmp, which contains nine 32x32 (32x288) images. Change the ID of the bitmap to
IDB_RIBBON_FILELARGE .
4. Import the bitmaps for the ribbon categories and panels. Each tab on the ribbon bar is a category, and
consists of a text label and an optional image.
a. Import the homesmall.bmp bitmap, which contains eleven 16x16 images for small button bitmaps.
Change the ID of the bitmap to IDB_RIBBON_HOMESMALL .
b. Import the homelarge.bmp bitmap, which contains nine 32x32 images for large button bitmaps.
Change the ID of the bitmap to IDB_RIBBON_HOMELARGE .
5. Import bitmaps for the resized ribbon panels. These bitmaps, or panel icons, are used after a resize
operation if the ribbon is too small to display the entire panel.
a. Import the panelicons.bmp bitmap, which contains eight 16x16 images. In the Proper ties window of
the Bitmap Editor , adjust the width of the bitmap to 64 (16x64). Change the ID of the bitmap to
IDB_PANEL_ICONS .

NOTE
Because we need only the first four 16x16 images (16x64), you may optionally crop the right-side width of this
bitmap from 128 to 64.
Adding a Ribbon Resource to the Project
When you convert an application that uses menus to an application that uses a ribbon, you don't have to remove
or disable the existing menus. Just create a ribbon resource, add ribbon buttons, and then associate the new
buttons with the existing menu items. Although the menus are no longer visible, messages from the ribbon bar are
routed through the menus and menu shortcuts continue to work.
A ribbon consists of the Application button, which is the large button on the upper-left side of the ribbon, and
one or more category tabs. Each category tab contains one or more panels that act as containers for ribbon
buttons and controls. The following procedure shows how to create a ribbon resource and then customize the
Application button.
To add a ribbon resource to the project
1. With the Scribble project selected in Solution Explorer , in the Project menu, click Add Resource .
2. In the Add Resource dialog box, select Ribbon and then click New .
Visual Studio creates a ribbon resource and opens it in the design view. The ribbon resource ID is
IDR_RIBBON1 , which is displayed in Resource View . The ribbon contains one category and one panel.

3. You can customize the Application button by modifying its properties. The message IDs that are used in
this code are already defined in the menu for Scribble 1.0.
4. In the design view, click the Application button to display its properties. Change property values as
follows: Image to IDB_RIBBON_MAIN , Prompt to File , Keys to f , Large Images to IDB_RIBBON_FILELARGE ,
and Small Images to IDB_RIBBON_FILESMALL .
5. The following modifications create the menu that appears when the user clicks the Application button.
Click the ellipsis (...) next to Main Items to open the Items Editor .
a. With the Item type Button selected, click Add to add a button. Change Caption to &New , ID to
ID_FILE_NEW , Image to 0 , Image Large to 0 .

b. Click Add to add a button. Change Caption to &Save , ID to ID_FILE_SAVE , Image to 2 , and Image
Large to 2 .
c. Click Add to add a button. Change Caption to Save &As , ID to ID_FILE_SAVE_AS , Image to 3 , and
Image Large to 3 .
d. Click Add to add a button. Change Caption to &Print , ID to ID_FILE_PRINT , Image to 4 , and
Image Large to 4 .
e. Change the Item type to Separator and then click Add .
f. Change the Item type to Button . Click Add to add a fifth button. Change Caption to &Close , ID to
ID_FILE_CLOSE , Image to 5 , and Image Large to 5 .

6. The following modifications create a submenu under the Print button that you created in the previous step.
a. Click the Print button, change the Item type to Label , and then click Inser t . Change Caption to
Preview and print the document .

b. Click the Print button, change the Item type to Button , and click Inser t . Change Caption to
&Print , ID to ID_FILE_PRINT , Image to 4 , and Image Large to 4 .

c. Click the Print button and then click Inser t to add a button. Change Caption to &Quick Print , ID to
ID_FILE_PRINT_DIRECT , Image to 7 , and Image Large to 7 .

d. Click the Print button and then click Inser t to add another button. Change Caption to
Print Pre&view , ID to ID_FILE_PRINT_PREVIEW , Image to 6 , and Image Large to 6 .
e. You've now modified the Main Items . Click Close to exit the Items Editor .
7. The following modification creates an exit button that appears at the bottom of the Application button
menu.
a. Choose the Resource View tab in Solution Explorer .
b. In the Proper ties window, click the ellipsis (...) next to Button to open the Items Editor .
c. With the Item type Button selected, click Add to add a button. Change Caption to E&xit , ID to
ID_APP_EXIT , Image to 8 .

d. You've modified the Buttons . Click Close to exit the Items Editor .

Creating an Instance of the Ribbon Bar


The following steps show how to create an instance of the ribbon bar when your application starts. To add a ribbon
bar to an application, declare the ribbon bar in the mainfrm.h file. Then, in the mainfrm.cpp file, write code to load
the ribbon resource.
To create an instance of the ribbon bar
1. In the mainfrm.h file, add a data member to the protected section of CMainFrame , the class definition for the
main frame. This member is for the ribbon bar.

// Ribbon bar for the application


CMFCRibbonBar m_wndRibbonBar;

2. In the mainfrm.cpp file, add the following code before the final return statement at the end of the
CMainFrame::OnCreate function. It creates an instance of the ribbon bar.

// Create the ribbon bar


if (!m_wndRibbonBar.Create(this))
{
return -1; //Failed to create ribbon bar
}
m_wndRibbonBar.LoadFromResource(IDR_RIBBON1);

Customizing the Ribbon Resource


Now that you've created the Application button, you can add elements to the ribbon.

NOTE
This walkthrough uses the same panel icon for all panels. However, you can use other image list indexes to display other
icons.

To add a Home category and Edit panel


1. The Scribble program requires only one category. In the design view, in the Toolbox , double-click
Categor y to add one and display its properties. Change property values as follows: Caption to &Home ,
Large Images to IDB_RIBBON_HOMELARGE , Small Images to IDB_RIBBON_HOMESMALL .
2. Each ribbon category is organized into named panels. Each panel contains a set of controls that complete
related operations. This category has one panel. Click Panel , and then change Caption to Edit .
3. To the Edit panel, add a button responsible for clearing the contents of the document. The message ID for
this button has already been defined in the IDR_SCRIBBTYPE menu resource. Specify Clear All as the
button text and the index of the bitmap that decorates the button. Open the Toolbox , and then drag a
Button to the Edit panel. Click the button and then change Caption to Clear All , ID to
ID_EDIT_CLEAR_ALL , Image Index to 0 , Large Image Index to 0 .

4. Save the changes, and then build and run the application. The Scribble application should be displayed, and
it should have a ribbon bar at the top of the window instead of a menu bar. The ribbon bar should have one
category, Home , and Home should have one panel, Edit . The ribbon buttons that you added should be
associated with the existing event handlers, and the Open , Close , Save , Print , and Clear All buttons
should work as expected.

Setting the Look of the Application


A visual manager is a global object that controls all drawing for an application. Because the original Scribble
application uses the Office 2000 user interface (UI) style, the application may look old-fashioned. You can reset the
application to use the Office 2007 visual manager so that it resembles an Office 2007 application.
To set the look of the application
1. In the CMainFrame::OnCreate function, type the following code before the return 0; statement to change
the default visual manager and style.

// Set the default manager to Office 2007


CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));
CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007_LunaBlue);

2. Save the changes, and then build and run the application. The application UI should resemble the Office
2007 UI.

Next Steps
You've modified the classic Scribble 1.0 MFC sample to use the Ribbon Designer . Now go to Part 2.

See also
Walkthroughs
Walkthrough: Updating the MFC Scribble Application (Part 2)
Walkthrough: Updating the MFC Scribble Application
(Part 2)
3/27/2020 • 9 minutes to read • Edit Online

Part 1 of this walkthrough showed how to add an Office Fluent Ribbon to the classic Scribble application. This part
shows how to add ribbon panels and controls that users can use instead of menus and commands.

Prerequisites
Visual C++ Samples

Sections
This part of the walkthrough has the following sections:
Adding New Panels to the Ribbon
Adding a Help Panel to the Ribbon
Adding a Pen Panel to the Ribbon
Adding a Color Button to the Ribbon
Adding a Color Member to the Document Class
Initializing Pens and Saving Preferences

Adding New Panels to the Ribbon


These steps show how to add a View panel that contains two check boxes that control the visibility of the toolbar
and the status bar, and also a Window panel that contains a vertically oriented split button that controls the
creation and arrangement of multiple-document interface (MDI) windows.
To add a View panel and Window panel to the ribbon bar
1. Create a panel named View , which has two check boxes that toggle the status bar and toolbar.
a. From the Toolbox , drag a Panel to the Home category. Then drag two Check Boxes to the panel.
b. Click the panel to modify its properties. Change Caption to View .
c. Click the first check box to modify its properties. Change ID to ID_VIEW_TOOLBAR and Caption to
Toolbar .

d. Click the second check box to modify its properties. Change ID to ID_VIEW_STATUS_BAR and Caption
to Status Bar .
2. Create a panel named Window that has a split button. When a user clicks the split button, a shortcut menu
displays three commands that are already defined in the Scribble application.
a. From the Toolbox , drag a Panel to the Home category. Then drag a Button to the panel.
b. Click the panel to modify its properties. Change Caption to Window .
c. Click the button. Change Caption to Windows , Keys to w , Large Image Index to 1 , and Split
Mode to False . Then click the ellipsis (...) next to Menu Items to open the Items Editor dialog
box.
d. Click Add three times to add three buttons.
e. Click the first button and then change Caption to New Window , and ID to ID_WINDOW_NEW .
f. Click the second button and then change Caption to Cascade , and ID to ID_WINDOW_CASCADE .
g. Click the third button and then change Caption to Tile , and ID to ID_WINDOW_TILE_HORZ .
3. Save the changes, and then build and run the application. The View and Window panels should be
displayed. Click the buttons to confirm that they function correctly.

Adding a Help Panel to the Ribbon


Now, you can assign two menu items that are defined in the Scribble application to ribbon buttons that are named
Help Topics and About Scribble . The buttons are added to a new panel named Help .
To add a Help panel
1. From the Toolbox , drag a Panel to the Home category. Then drag two Buttons to the panel.
2. Click the panel to modify its properties. Change Caption to Help .
3. Click the first button. Change Caption to Help Topics , and ID to ID_HELP_FINDER .
4. Click the second button. Change Caption to About Scribble... , and ID to ID_APP_ABOUT .
5. Save the changes, and then build and run the application. A Help panel that contains two ribbon buttons
should be displayed.

IMPORTANT
When you click the Help Topics button, the Scribble application opens a compressed HTML (.chm) help file named
your_project_name.chm. Consequently, if your project is not named Scribble, you must rename the help file to your
project name.

Adding a Pen Panel to the Ribbon


Now, add a panel to display buttons that control the thickness and the color of the pen. This panel contains a check
box that toggles between thick and thin pens. Its functionality resembles that of the Thick Line menu item in the
Scribble application.
The original Scribble application lets the user select pen widths from a dialog box that appears when the user
clicks Pen Widths on the menu. Because the ribbon bar has ample room for new controls, you can replace the
dialog box by using two combo boxes on the ribbon. One combo box adjusts the width of the thin pen and the
other combo box adjusts the width of the thick pen.
To add a Pen panel and combo boxes to the ribbon
1. From the Toolbox , drag a Panel to the Home category. Then drag a Check Box and two Combo Boxes to
the panel.
2. Click the panel to modify its properties. Change Caption to Pen .
3. Click the check box. Change Caption to Use Thick , and ID to ID_PEN_THICK_OR_THIN .
4. Click the first combo box. Change Caption to Thin Pen , ID to ID_PEN_THIN_WIDTH , Type to Drop List ,
Data to 1;2;3;4;5;6;7;8;9; , and Text to 2 .
5. Click the second combo box. Change Caption to Thick Pen , ID to ID_PEN_THICK_WIDTH , Type to Drop List ,
Data to 5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20; , and Text to 5 .
6. The new combo boxes don't correspond to any existing menu items, so you must create a menu item for
every pen option.
a. In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
b. Click Pen to open the pen menu. Then click Type Here and type Thi&n Pen .
c. Right-click the text that you typed to open the Proper ties window, and then change the ID property
to ID_PEN_THIN_WIDTH .
d. Create an event handler for every pen menu item. Right-click the Thi&n Pen menu item that you
created and then click Add Event Handler . The Event Handler Wizard is displayed.
e. In the Class list box in the wizard, select CScribbleDoc and then click Add and Edit . The
command creates an event handler named CScribbleDoc::OnPenThinWidth .
f. Add the following code to CScribbleDoc::OnPenThinWidth .

// Get a pointer to the ribbon bar


CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
ASSERT_VALID(pRibbon);

// Get a pointer to the Thin Width combo box


CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST(
CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THIN_WIDTH));

//Get the selected value


int nCurSel = pThinComboBox->GetCurSel();
if (nCurSel>= 0)
{
m_nThinWidth = atoi(CStringA(pThinComboBox->GetItem(nCurSel)));
}

// Create a new pen using the selected width


ReplacePen();

7. Next, create a menu item and event handlers for the thick pen.
a. In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
b. Click Pen to open the pen menu. Then click Type Here and type Thic&k Pen .
c. Right-click the text that you typed to display the Proper ties window. Change the ID property to
ID_PEN_THICK_WIDTH .

d. Right-click the Thick Pen menu item that you created and then click Add Event Handler . The
Event Handler Wizard is displayed.
e. In the Class list box of the wizard, select CScribbleDoc and then click Add and Edit . The
command creates an event handler named CScribbleDoc::OnPenThickWidth .
f. Add the following code to CScribbleDoc::OnPenThickWidth .
// Get a pointer to the ribbon bar
CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx *) AfxGetMainWnd())->GetRibbonBar();
ASSERT_VALID(pRibbon);

CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST(


CMFCRibbonComboBox, pRibbon->FindByID(ID_PEN_THICK_WIDTH));
// Get the selected value
int nCurSel = pThickComboBox->GetCurSel();
if (nCurSel>= 0)
{
m_nThickWidth = atoi(CStringA(pThickComboBox->GetItem(nCurSel)));
}

// Create a new pen using the selected width


ReplacePen();

8. Save the changes, and then build and run the application. New buttons and combo boxes should be
displayed. Try using different pen widths to scribble.

Adding a Color Button to the Pen Panel


Next, add a CMFCRibbonColorButton object that lets the user scribble in color.
To add a color button to the Pen panel
1. Before you add the color button, create a menu item for it. In the Resource View window, open the
IDR_SCRIBBTYPE menu resource. Click the Pen menu item to open the pen menu. Then click Type Here
and type &Color . Right-click the text that you typed to display the Proper ties window. Change the ID to
ID_PEN_COLOR .

2. Now add the color button. From the Toolbox , drag a Color Button to the Pen panel.
3. Click the color button. Change Caption to Color , ID to ID_PEN_COLOR , Simple Look to True , Large
Image Index to 1 , and Split Mode to False .
4. Save the changes, and then build and run the application. The new color button should be displayed on the
Pen panel. However, it can't be used because it doesn't yet have an event handler. The next steps show how
to add an event handler for the color button.

Adding a Color Member to the Document Class


Because the original Scribble application doesn't have color pens, you must write an implementation for them. To
store the pen color of the document, add a new member to the document class, CscribbleDoc .
To add a color member to the document class
1. In scribdoc.h, in the CScribbleDoc class, find the // Attributes section. Add the following lines of code
after the definition of the m_nThickWidth data member.

// Current pen color


COLORREF m_penColor;

2. Every document contains a list of stokes that the user has already drawn. Every stroke is defined by a
CStroke object. The CStroke class doesn't include information about pen color, so you must modify the
class. In scribdoc.h, in the CStroke class, add the following lines of code after the definition of the
m_nPenWidth data member.
// Pen color for the stroke
COLORREF m_penColor;

3. In scribdoc.h, add a new CStroke constructor whose parameters specify a width and color. Add the
following line of code after the CStroke(UINT nPenWidth); statement.

CStroke(UINT nPenWidth, COLORREF penColor);

4. In scribdoc.cpp, add the implementation of the new CStroke constructor. Add the following code after the
implementation of the CStroke::CStroke(UINT nPenWidth) constructor.

// Constructor that uses the document's current width and color


CStroke::CStroke(UINT nPenWidth, COLORREF penColor)
{
m_nPenWidth = nPenWidth;
m_penColor = penColor;
m_rectBounding.SetRectEmpty();
}

5. Change the second line of the CStroke::DrawStroke method as follows.

if (!penStroke.CreatePen(PS_SOLID, m_nPenWidth, m_penColor))

6. Set the default pen color for the document class. In scribdoc.cpp, add the following lines to
CScribbleDoc::InitDocument , after the m_nThickWidth = 5; statement.

// default pen color is black


m_penColor = RGB(0, 0, 0);

7. In scribdoc.cpp, change the first line of the CScribbleDoc::NewStroke method to the following.

CStroke* pStrokeItem = new CStroke(m_nPenWidth, m_penColor);

8. Change the last line of the CScribbleDoc::ReplacePen method to the following.

m_penCur.CreatePen(PS_SOLID, m_nPenWidth, m_penColor);

9. You added the m_penColor member in a previous step. Now, create an event handler for the color button
that sets the member.
a. In the Resource View window, open the IDR_SCRIBBTYPE menu resource.
b. Right-click the Color menu item and click Add Event Handler . The Event Handler Wizard
appears.
c. In the Class list box in the wizard, select CScribbleDoc and then click the Add and Edit button.
The command creates the CScribbleDoc::OnPenColor event handler stub.
10. Replace the stub for the CScribbleDoc::OnPenColor event handler with the following code.
void CScribbleDoc::OnPenColor()
{
// Change pen color to reflect color button's current selection
CMFCRibbonBar* pRibbon = ((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
ASSERT_VALID(pRibbon);

CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(


CMFCRibbonColorButton, pRibbon->FindByID(ID_PEN_COLOR));

m_penColor = pColorBtn->GetColor();
// Create new pen using the selected color
ReplacePen();
}

11. Save the changes and then build and run the application. You can now press the color button and change
the pen's color.

Initializing Pens and Saving Preferences


Next, initialize the color and width of the pens. Finally, save and load a color drawing from a file.
To initialize controls on the ribbon bar
1. Initialize the pens on the ribbon bar.
Add the following code to scribdoc.cpp, in the CScribbleDoc::InitDocument method, after the
m_sizeDoc = CSize(200,200) statement.

// Reset the ribbon UI to its initial values


CMFCRibbonBar* pRibbon =
((CMDIFrameWndEx*) AfxGetMainWnd())->GetRibbonBar();
ASSERT_VALID(pRibbon);

CMFCRibbonColorButton* pColorBtn = DYNAMIC_DOWNCAST(


CMFCRibbonColorButton,
pRibbon->FindByID(ID_PEN_COLOR));

// Set ColorButton to black


pColorBtn->SetColor(RGB(0, 0, 0));

CMFCRibbonComboBox* pThinComboBox = DYNAMIC_DOWNCAST(


CMFCRibbonComboBox,
pRibbon->FindByID(ID_PEN_THIN_WIDTH));

// Set Thin pen combobox to 2


pThinComboBox->SelectItem(1);

CMFCRibbonComboBox* pThickComboBox = DYNAMIC_DOWNCAST(


CMFCRibbonComboBox,
pRibbon->FindByID(ID_PEN_THICK_WIDTH));

// Set Thick pen combobox to 5


pThickComboBox->SelectItem(0);

2. Save a color drawing to a file. Add the following statement to scribdoc.cpp, in the CStroke::Serialize
method, after the ar << (WORD)m_nPenWidth; statement.

ar << (COLORREF)m_penColor;

3. Finally, load a color drawing from a file. Add the following line of code, in the CStroke::Serialize method,
after the m_nPenWidth = w; statement.

ar >> m_penColor;

4. Now scribble in color and save your drawing to a file.

Conclusion
You've updated the MFC Scribble application. Use this walkthrough as a guide when you modify your existing
applications.

See also
Walkthroughs
Walkthrough: Updating the MFC Scribble Application (Part 1)
Status Bars
3/4/2019 • 2 minutes to read • Edit Online

Status bars give your application a place to display messages and useful information to the user without
interrupting the user's work. Typically displayed at the bottom of a window, status bars have "panes," which include
"indicators" and a "message line." The indicators give the status of such things as SCROLL LOCK, whether macro
recording is turned on, and so on. The message line on the status bar can display information about program
status or about a toolbar button or menu item that the user is pointing to with the mouse.
Create a status bar in your program by selecting the Initial Status Bar option in the MFC Application Wizard.

What do you want to know more about


Status bar implementation in MFC
Updating the text of a status bar pane
Creating a new status-bar pane (Updating the text of a status bar pane)
Making a status-bar pane display text (Updating the text of a status bar pane)
Display command information in the status bar

See also
User Interface Elements
Status Bar Implementation in MFC
3/4/2019 • 2 minutes to read • Edit Online

A CStatusBar object is a control bar with a row of text output panes. The output panes are commonly used as
message lines and as status indicators. Examples include the menu help-message lines that briefly explain the
selected menu command and the indicators that show the status of the SCROLL LOCK, NUM LOCK, and other keys.
As of MFC version 4.0, status bars are implemented using class CStatusBarCtrl, which encapsulates a status bar
common control. For backward compatibility, MFC retains the older status bar implementation in class
COldStatusBar . The documentation for earlier versions of MFC describes COldStatusBar under CStatusBar .

CStatusBar::GetStatusBarCtrl, a member function new to MFC 4.0, allows you to take advantage of the Windows
common control's support for status bar customization and additional functionality. CStatusBar member
functions give you most of the functionality of the Windows common controls; however, when you call
GetStatusBarCtrl , you can give your status bars even more of the characteristics of a status bar. When you call
GetStatusBarCtrl , it will return a reference to a CStatusBarCtrl object. You can use that reference to manipulate
the status bar control.
The following figure shows a status bar that displays several indicators.

A Status Bar
Like the toolbar, the status-bar object is embedded in its parent frame window and is constructed automatically
when the frame window is constructed. The status bar, like all control bars, is destroyed automatically as well when
the parent frame is destroyed.

What do you want to know more about


Updating the text of a status bar pane
MFC classes CStatusBar and CStatusBarCtrl
Control bars
Dialog bars
Toolbars (MFC Toolbar Implementation)

See also
Status Bars
Updating the Text of a Status-Bar Pane
3/27/2020 • 3 minutes to read • Edit Online

This article explains how to change the text that appears in an MFC status bar pane. A status bar — a window
object of class CStatusBar — contains several "panes." Each pane is a rectangular area of the status bar that you
can use to display information. For example, many applications display the status of the CAPS LOCK, NUM LOCK,
and other keys in the rightmost panes. Applications also often display informative text in the leftmost pane (pane
0), sometimes called the "message pane." For example, the default MFC status bar uses the message pane to
display a string explaining the currently selected menu item or toolbar button. The figure in Status Bars shows a
status bar from an Application Wizard-created MFC application.
By default, MFC does not enable a CStatusBar pane when it creates the pane. To activate a pane, you must use the
ON_UPDATE_COMMAND_UI macro for each pane on the status bar and update the panes. Because panes do not
send WM_COMMAND messages (they aren't like toolbar buttons), you must type the code manually.
For example, suppose one pane has ID_INDICATOR_PAGE as its command identifier and that it contains the current
page number in a document. The following procedure describes how to create a new pane in the status bar.
To make a new pane
1. Define the pane's command ID.
On the View menu, click Resource View . Right-click the project resource and click Resource Symbols . In
the Resource Symbols dialog box, click New . Type a command ID name: for example, ID_INDICATOR_PAGE .
Specify a value for the ID, or accept the value suggested by the Resource Symbols dialog box. For example,
for ID_INDICATOR_PAGE , accept the default value. Close the Resource Symbols dialog box.
2. Define a default string to display in the pane.
With Resource View open, double-click String Table in the window that lists resource types for your
application. With the String Table editor open, choose New String from the Inser t menu. Select your
pane's command ID (for example, ID_INDICATOR_PAGE ) and type a default string value, such as "Page ". Close
the string editor. (You need a default string to avoid a compiler error.)
3. Add the pane to the indicators array.
In file MAINFRM.CPP, locate the indicators array. This array lists command IDs for all of the status bar's
indicators, in order from left to right. At the appropriate point in the array, enter your pane's command ID,
as shown here for ID_INDICATOR_PAGE :

static UINT indicators[] =


{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
ID_INDICATOR_PAGE,
};

The recommended way to display text in a pane is to call the SetText member function of class CCmdUI in an
update handler function for the pane. For example, you might want to set up an integer variable m_nPage that
contains the current page number and use SetText to set the pane's text to a string version of that number.
NOTE
The SetText approach is recommended. It is possible to perform this task at a slightly lower level by calling the
CStatusBar member function SetPaneText . Even so, you still need an update handler. Without such a handler for the
pane, MFC automatically disables the pane, erasing its content.

The following procedure shows how to use an update handler function to display text in a pane.
To make a pane display text
1. Add a command update handler for the command.
Manually add a prototype for the handler, as shown here for ID_INDICATOR_PAGE (in MAINFRM.H):

afx_msg void OnUpdatePage(CCmdUI* pCmdUI);

2. In the appropriate .CPP file, add the handler's definition, as shown here for ID_INDICATOR_PAGE (in
MAINFRM.CPP):

void CMainFrame::OnUpdatePage(CCmdUI* pCmdUI)


{
pCmdUI->Enable();
CString strPage;
strPage.Format(_T("Page %d"), m_nPage);
pCmdUI->SetText(strPage);
}

The last three lines of this handler are the code that displays your text.
3. In the appropriate message map, add the ON_UPDATE_COMMAND_UI macro, as shown here for
ID_INDICATOR_PAGE (in MAINFRM.CPP):

ON_UPDATE_COMMAND_UI(ID_INDICATOR_PAGE, &CMainFrame::OnUpdatePage)

Once you define the value of the m_nPage member variable (of class CMainFrame ), this technique causes the page
number to appear in the pane during idle processing in the same manner that the application updates other
indicators. If m_nPage changes, the display changes during the next idle loop.
What do you want to know more about
Updating user-interface objects (how to update toolbar buttons and menu items as program conditions
change)

See also
Status Bar Implementation in MFC
CStatusBar Class
Tool Tips
3/4/2019 • 2 minutes to read • Edit Online

The procedures are distinct for adding tool tips to controls contained in windows derived from MFC class
CFrameWnd and windows not derived from CFrameWnd .

What do you want to know more about


Tool tips for controls in a window that is:
Toolbar Tooltips (derived from CFrameWnd)
Tooltips in Windows not derived from CFrameWnd

See also
User Interface Elements
Tool Tips in Windows Not Derived from CFrameWnd
8/15/2019 • 2 minutes to read • Edit Online

This article family covers enabling tool tips for controls contained in a window that is not derived from
CFrameWnd. The article Toolbars Tool Tips provides information about tool tips for controls in a CFrameWnd .
Topics covered in this article family include:
Enabling Tool Tips
Handling TTN_NEEDTEXT Notification for Tool Tips
The TOOLTIPTEXT Structure
Tool tips are automatically displayed for buttons and other controls contained in a parent window derived from
CFrameWnd . This is because CFrameWnd has a default handler for the TTN_GETDISPINFO notification, which handles
TTN_NEEDTEXT notifications from tool tip controls associated with controls.
However, this default handler is not called when the TTN_NEEDTEXT notification is sent from a tool tip control
associated with a control in a window that is not a CFrameWnd , such as a control on a dialog box or a form view.
Therefore, it is necessary for you to provide a handler function for the TTN_NEEDTEXT notification message in
order to display tool tips for child controls.
The default tool tips provided for your windows by CWnd::EnableToolTips do not have text associated with them.
To retrieve text for the tool tip to display, the TTN_NEEDTEXT notification is sent to the tool tip control's parent
window just before the tool tip window is displayed. If there is no handler for this message to assign some value
to the pszText member of the TOOLTIPTEXT structure, there will be no text displayed for the tool tip.

See also
Tool Tips
Enabling Tool Tips
3/4/2019 • 2 minutes to read • Edit Online

You can enable tool tip support for the child controls of a window (such as the controls on a form view or dialog
box).
To enable tool tips for the child controls of a window
1. Call EnableToolTips for the window for which you want to provide tool tips.
2. Provide a string for each control in your TTN_NEEDTEXT notification handler. The handler is in the message
map of the window that contains the child controls (for example, your form view class). This handler should
call a function that identifies the control and sets pszText to specify the text used by the tool tip control.

See also
Tool Tips in Windows Not Derived from CFrameWnd
Handling TTN_NEEDTEXT Notification for Tool Tips
8/15/2019 • 2 minutes to read • Edit Online

As part of enabling tool tips, you handle the TTN_NEEDTEXT message by adding the following entry to your
owner window's message map:

ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CMyDialog::OnTtnNeedText)

memberFxn
The member function to be called when text is needed for this button.
Note that the ID of a tool tip is always 0.
Declare your handler function in the class definition as follows:

afx_msg BOOL OnTtnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult);

where the italicized parameters are:


id
Identifier of the control that sent the notification. Not used. The control id is taken from the NMHDR structure.
pNMHDR
A pointer to the NMTTDISPINFO structure. This structure is also discussed further in The TOOLTIPTEXT Structure.
pResult
A pointer to result code you can set before you return. TTN_NEEDTEXT handlers can ignore the pResult
parameter.
As an example of a form-view notification handler:
BOOL CMyDialog::OnTtnNeedText(UINT id, NMHDR* pNMHDR, LRESULT* pResult)
{
UNREFERENCED_PARAMETER(id);

NMTTDISPINFO* pTTT = (NMTTDISPINFO*)pNMHDR;


UINT_PTR nID = pNMHDR->idFrom;
BOOL bRet = FALSE;

if (pTTT->uFlags & TTF_IDISHWND)


{
// idFrom is actually the HWND of the tool
nID = ::GetDlgCtrlID((HWND)nID);
if (nID)
{
_stprintf_s(pTTT->szText, sizeof(pTTT->szText) / sizeof(TCHAR),
_T("Control ID = %d"), nID);
pTTT->hinst = AfxGetResourceHandle();
bRet = TRUE;
}
}

*pResult = 0;

return bRet;
}

Call EnableToolTips (this fragment taken from OnInitDialog ):

EnableToolTips(TRUE);

See also
Tool Tips in Windows Not Derived from CFrameWnd
TOOLTIPTEXT Structure
8/15/2019 • 2 minutes to read • Edit Online

In writing your tool tip notification handler, you need to use the TOOLTIPTEXT structure. The members of the
TOOLTIPTEXT structure are:

typedef struct {
NMHDR hdr; // required for all WM_NOTIFY messages
LPTSTR lpszText; // see below
TCHAR szText[80]; // buffer for tool tip text
HINSTANCE hinst; // see below
UINT uflags; // flag indicating how to interpret the
// idFrom member of the NMHDR structure
// that is included in the structure
} TOOLTIPTEXT, FAR *LPTOOLTIPTEXT;

hdr
Identifies the tool that needs text. The only member of this structure you might need is the control's command ID.
The control's command ID will be in the idFrom member of the NMHDR structure, accessed with the syntax
hdr.idFrom . See NMHDR for a discussion of members of the NMHDR structure.

lpszText
Address of a string to receive the text for a tool.
szText
Buffer that receives the tool tip text. An application can copy the text to this buffer as an alternative to specifying a
string address.
hinst
Handle of the instance that contains a string to be used as the tool tip text. If lpszText is the address of the tool tip
text, this member is NULL.
When you handle the TTN_NEEDTEXT notification message, specify the string to be displayed in one of the following
ways:
Copy the text to the buffer specified by the szText member.
Copy the address of the buffer that contains the text to the lpszText member.
Copy the identifier of a string resource to the lpszText member, and copy the handle of the instance that
contains the resource to the hinst member.

See also
Tool Tips in Windows Not Derived from CFrameWnd
Toolbars
3/4/2019 • 2 minutes to read • Edit Online

The toolbar family of articles describes MFC toolbars and how to create and use them.

What do you want to know more about


MFC toolbar implementation
Toolbar fundamentals
How to Update User-Interface Objects (enable/disable toolbar buttons)
The CToolBar and CToolBarCtrl classes
Sample

See also
User Interface Elements
Toolbar Editor
Toolbar Sample List
4/1/2019 • 2 minutes to read • Edit Online

See the following sample programs that illustrate using MFC's toolbars:
SCRIBBLE
CTRLBARS
DOCKTOOL

See also
Toolbars
MFC Toolbar Implementation
3/27/2020 • 3 minutes to read • Edit Online

A toolbar is a control bar that contains the bitmap images of controls. These images can behave like pushbuttons,
check boxes, or radio buttons. MFC supplies class CToolbar to manage toolbars.
If you enable it, users of MFC toolbars can dock them to the edge of a window or "float" them anywhere within
the application window. MFC doesn't support customizable toolbars like those in the development environment.
MFC also supports tool tips: small pop-up windows that describe a toolbar button's purpose when you position
the mouse over the button. By default, when the user presses a toolbar button, a status string appears in the
status bar (if there is one). You can activate "fly by" status bar updating to display the status string when the
mouse is positioned over the button without pressing it.

NOTE
As of MFC version 4.0, toolbars and tool tips are implemented using Windows 95 and later functionality instead of the
previous implementation specific to MFC.

For backward compatibility, MFC retains the older toolbar implementation in class COldToolBar . The
documentation for earlier versions of MFC describe COldToolBar under CToolBar .
Create the first toolbar in your program by selecting the Toolbar option in the Application Wizard. You can also
create additional toolbars.
The following are introduced in this article:
Toolbar buttons
Docking and floating toolbars
Toolbars and tool tips
The CToolBar and CToolBarCtrl classes
The Toolbar bitmap

Toolbar Buttons
The buttons in a toolbar are analogous to the items in a menu. Both kinds of user-interface objects generate
commands, which your program handles by providing handler functions. Often toolbar buttons duplicate the
functionality of menu commands, providing an alternative user interface to the same functionality. Such
duplication is arranged simply by giving the button and the menu item the same ID.
You can make the buttons in a toolbar appear and behave as pushbuttons, check boxes, or radio buttons. For
more information, see class CToolBar.

Docking and Floating Toolbars


An MFC toolbar can:
Remain stationary along one side of its parent window.
Be dragged and "docked," or attached, by the user to any side or sides of the parent window you specify.
Be "floated," or detached from the frame window, in its own mini-frame window so the user can move it
around to any convenient position.
Be resized while floating.
For more information, see the article Docking and Floating Toolbars.

Toolbars and Tool Tips


MFC toolbars can also be made to display "tool tips" — tiny popup windows containing a short text description of
a toolbar button's purpose. As the user moves the mouse over a toolbar button, the tool tip window pops up to
offer a hint. For more information, see the article Toolbar Tool Tips.

The CToolBar and CToolBarCtrl Classes


You manage your application's toolbars via class CToolBar. As of MFC version 4.0, CToolBar has been
reimplemented to use the toolbar common control available under Windows 95 or later and Windows NT version
3.51 or later.
This reimplementation results in less MFC code for toolbars, because MFC makes use of the operating system
support. The reimplementation also improves capability. You can use CToolBar member functions to manipulate
toolbars, or you can obtain a reference to the underlying CToolBarCtrl object and call its member functions for
toolbar customization and additional functionality.

TIP
If you have invested heavily in the older MFC implementation of CToolBar , that support is still available. See the article
Using Your Old Toolbars.

Also see the MFC General sample DOCKTOOL.

The Toolbar Bitmap


Once constructed, a CToolBar object creates the toolbar image by loading a single bitmap that contains one
image for each button. The Application Wizard creates a standard toolbar bitmap that you can customize with the
Visual C++ toolbar editor.
What do you want to know more about
Toolbar fundamentals
Docking and floating toolbars
Toolbar tool tips
Working with the Toolbar Control
Using Your Old Toolbars
The CToolBar and CToolBarCtrl classes

See also
Toolbars
Toolbar Editor
Toolbar Fundamentals
3/27/2020 • 3 minutes to read • Edit Online

This article describes the fundamental MFC implementation that lets you add a default toolbar to your application
by selecting an option in the Application Wizard. Topics covered include:
The Application Wizard toolbar option
The toolbar in code
Editing the toolbar resource
Multiple toolbars

The Application Wizard Toolbar Option


To get a single toolbar with default buttons, select the Standard Docking toolbar option on the page labeled User
Interface Features. This adds code to your application that:
Creates the toolbar object.
Manages the toolbar, including its ability to dock or to float.

The Toolbar in Code


The toolbar is a CToolBar object declared as a data member of your application's CMainFrame class. In other words,
the toolbar object is embedded in the main frame window object. This means that MFC creates the toolbar when it
creates the frame window and destroys the toolbar when it destroys the frame window. The following partial class
declaration, for a multiple document interface (MDI) application, shows data members for an embedded toolbar
and an embedded status bar. It also shows the override of the OnCreate member function.

class CMainFrame : public CMDIFrameWnd


{
// Implementation
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;

// Generated message map functions


protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()

Toolbar creation occurs in CMainFrame::OnCreate . MFC calls OnCreate after creating the window for the frame but
before it becomes visible. The default OnCreate that the Application Wizard generates does the following toolbar
tasks:
1. Calls the CToolBar object's Create member function to create the underlying CToolBarCtrl object.
2. Calls LoadToolBar to load the toolbar resource information.
3. Calls functions to enable docking, floating, and tool tips. For details about these calls, see the article Docking
and Floating Toolbars.
NOTE
The MFC General sample DOCKTOOL includes illustrations of both old and new MFC toolbars. The toolbars that use
COldToolbar require calls in step 2 to LoadBitmap (rather than LoadToolBar ) and to SetButtons . The new toolbars
require calls to LoadToolBar .

The docking, floating, and tool tips calls are optional. You can remove those lines from OnCreate if you prefer. The
result is a toolbar that remains fixed, unable to float or redock and unable to display tool tips.

Editing the Toolbar Resource


The default toolbar you get with the Application Wizard is based on an RT_TOOLBAR custom resource,
introduced in MFC version 4.0. You can edit this resource with the toolbar editor. The editor lets you easily add,
delete, and rearrange buttons. It contains a graphical editor for the buttons that is very similar to the general
graphics editor in Visual C++. If you edited toolbars in previous versions of Visual C++, you'll find the task much
easier now.
To connect a toolbar button to a command, you give the button a command ID, such as ID_MYCOMMAND . Specify the
command ID in the button's property page in the toolbar editor. Then create a handler function for the command
(see Mapping Messages to Functions for more information).
New CToolBar member functions work with the RT_TOOLBAR resource. LoadToolBar now takes the place of
LoadBitmap to load the bitmap of the toolbar button images, and SetButtons to set the button styles and connect
buttons with bitmap images.
For details about using the toolbar editor, see Toolbar Editor.

Multiple Toolbars
The Application Wizard provides you with one default toolbar. If you need more than one toolbar in your
application, you can model your code for additional toolbars based on the wizard-generated code for the default
toolbar.
If you want to display a toolbar as the result of a command, you'll need to:
Create a new toolbar resource with the toolbar editor and load it in OnCreate with the LoadToolbar
member function.
Embed a new CToolBar object in your main frame window class.
Make the appropriate function calls in OnCreate to dock or float the toolbar, set its styles, and so on.
What do you want to know more about
MFC Toolbar Implementation (overview information on toolbars)
Docking and floating toolbars
Toolbar tool tips
The CToolBar and CToolBarCtrl classes
Working with the toolbar control
Using your old toolbars

See also
MFC Toolbar Implementation
Docking and Floating Toolbars
3/27/2020 • 4 minutes to read • Edit Online

The Microsoft Foundation Class Library supports dockable toolbars. A dockable toolbar can be attached, or
docked, to any side of its parent window, or it can be detached, or floated, in its own mini-frame window. This
article explains how to use dockable toolbars in your applications.
If you use the Application Wizard to generate the skeleton of your application, you are asked to choose whether
you want dockable toolbars. By default, the Application Wizard generates the code that performs the three actions
necessary to place a dockable toolbar in your application:
Enable docking in a frame window.
Enable docking for a toolbar.
Dock the toolbar (to the frame window).
If any of these steps are missing, your application will display a standard toolbar. The last two steps must be
performed for each dockable toolbar in your application.
Other topics covered in this article include:
Floating the toolbar
Dynamically resizing the toolbar
Setting wrap positions for a fixed-style toolbar
See the MFC General sample DOCKTOOL for examples.

Enabling Docking in a Frame Window


To dock toolbars to a frame window, the frame window (or destination) must be enabled to allow docking. This is
done using the CFrameWnd::EnableDocking function, which takes one DWORD parameter that is a set of style
bits indicating which side of the frame window accepts docking. If a toolbar is about to be docked and there are
multiple sides that it could be docked to, the sides indicated in the parameter passed to EnableDocking are used
in the following order: top, bottom, left, right. If you want to be able to dock control bars anywhere, pass
CBRS_ALIGN_ANY to EnableDocking .

Enabling Docking for a Toolbar


After you have prepared the destination for docking, you must prepare the toolbar (or source) in a similar
fashion. Call CControlBar::EnableDocking for each toolbar you want to dock, specifying the destination sides to
which the toolbar should dock. If none of the sides specified in the call to CControlBar::EnableDocking match the
sides enabled for docking in the frame window, the toolbar cannot dock — it will float. Once it has been floated, it
remains a floating toolbar, unable to dock to the frame window.
If the effect you want is a permanently floating toolbar, call EnableDocking with a parameter of 0. Then call
CFrameWnd::FloatControlBar. The toolbar remains floating, permanently unable to dock anywhere.

Docking the Toolbar


The framework calls CFrameWnd::DockControlBar when the user attempts to drop the toolbar on a side of the
frame window that allows docking.
In addition, you can call this function at any time to dock control bars to the frame window. This is normally done
during initialization. More than one toolbar can be docked to a particular side of the frame window.

Floating the Toolbar


Detaching a dockable toolbar from the frame window is called floating the toolbar. Call
CFrameWnd::FloatControlBar to do this. Specify the toolbar to be floated, the point where it should be placed, and
an alignment style that determines whether the floating toolbar is horizontal or vertical.
The framework calls this function when a user drags a toolbar off its docked location and drops it in a location
where docking is not enabled. This can be anywhere inside or outside the frame window. As with DockControlBar ,
you can also call this function during initialization.
The MFC implementation of dockable toolbars does not provide some of the extended features found in some
applications that support dockable toolbars. Features such as customizable toolbars are not provided.

Dynamically Resizing the Toolbar


As of Visual C++ version 4.0, you can make it possible for users of your application to resize floating toolbars
dynamically. Typically, a toolbar has a long, linear shape, displayed horizontally. But you can change the toolbar's
orientation and its shape. For example, when the user docks a toolbar against one of the vertical sides of the
frame window, the shape changes to a vertical layout. It's also possible to reshape the toolbar into a rectangle
with multiple rows of buttons.
You can:
Specify dynamic sizing as a toolbar characteristic.
Specify fixed sizing as a toolbar characteristic.
To provide this support, there are two new toolbar styles for use in your calls to the CToolBar::Create member
function. They are:
CBRS_SIZE_DYNAMIC Control bar is dynamic.
CBRS_SIZE_FIXED Control bar is fixed.
The size dynamic style lets your user resize the toolbar while it is floating, but not while it is docked. The toolbar
"wraps" where needed to change shape as the user drags its edges.
The size fixed style preserves the wrap states of a toolbar, fixing the position of the buttons in each column. Your
application's user can't change the shape of the toolbar. The toolbar wraps at designated places, such as the
locations of separators between the buttons. It maintains this shape whether the toolbar is docked or floating. The
effect is a fixed palette with multiple columns of buttons.
You can also use CToolBar::GetButtonStyle to return a state and style for buttons on your toolbars. A button's style
determines how the button appears and how it responds to user input; the state tells whether the button is in a
wrapped state.

Setting Wrap Positions for a Fixed-Style Toolbar


For a toolbar with the size fixed style, designate toolbar button indexes at which the toolbar will wrap. The
following code shows how to do this in your main frame window's OnCreate override:
// Get the style of the first button separator
UINT nStyle = m_wndToolBar.GetButtonStyle(3);
// Augment the state for wrapping
nStyle |= TBBS_WRAPPED;
m_wndToolBar.SetButtonStyle(3, nStyle);

// Do the same for other wrap locations ...

// Set the bar style to size fixed


m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_FIXED);

// Call docking/floating functions as needed ...

The MFC General sample DOCKTOOL shows how to use member functions of classes CControlBar and CToolBar
to manage dynamic layout of a toolbar. See the file EDITBAR.CPP in DOCKTOOL.
What do you want to know more about
Toolbar fundamentals
Toolbar tool tips
Using your old toolbars

See also
MFC Toolbar Implementation
Toolbar Tool Tips
3/27/2020 • 2 minutes to read • Edit Online

Tool tips are the tiny popup windows that present short descriptions of a toolbar button's purpose when you
position the mouse over a button for a period of time. When you create an application with the Application
Wizard that has a toolbar, tool tip support is provided for you. This article explains both the tool tip support
created by the Application Wizard and how to add tool tip support to your application.
This article covers:
Activating tool tips
Flyby status bar updates

Activating Tool Tips


To activate tool tips in your application, you must do two things:
Add the CBRS_TOOLTIPS style to the other styles (such as WS_CHILD, WS_VISIBLE, and other CBRS_
styles) passed as the dwStyle parameter to the CToolBar::Create function or in SetBarStyle.
As described in the procedure below, append the toolbar tip text, separated by a newline character ('\n'), to
the string resource containing the command-line prompt for the toolbar command. The string resource
shares the ID of the toolbar button.
To add the tool tip text
1. While you are editing the toolbar in the toolbar editor, open the Toolbar Button Proper ties window for
a given button.
2. In the Prompt box, specify the text you want to appear in the tool tip for that button.

NOTE
Setting the text as a button property in the toolbar editor replaces the former procedure, in which you had to open and
edit the string resource.

If a control bar with tool tips enabled has child controls placed on it, the control bar will display a tool tip for
every child control on the control bar as long as it meets the following criteria:
The ID of the control is not - 1.
The string-table entry with the same ID as the child control in the resource file has a tool tip string.

Flyby Status Bar Updates


A feature related to tool tips is "flyby" status bar updating. By default, the message on the status bar describes
only a particular toolbar button when the button is activated. By including CBRS_FLYBY in your list of styles
passed to CToolBar::Create , you can have these messages updated when the mouse cursor passes over the
toolbar without actually activating the button.
What do you want to know more about
MFC Toolbar Implementation (overview information on toolbars)
Docking and floating toolbars
The CToolBar and CToolBarCtrl classes
Working with the toolbar control
Using your old toolbars

See also
MFC Toolbar Implementation
Working with the Toolbar Control
3/27/2020 • 2 minutes to read • Edit Online

This article explains how you can access the CToolBarCtrl object underlying a CToolBar for greater control over
your toolbars. This is an advanced topic.

Procedures
To access the toolbar common control underlying your CToolBar object
1. Call CToolBar::GetToolBarCtrl.
GetToolBarCtrl returns a reference to a CToolBarCtrl object. You can use the reference to call member functions of
the toolbar control class.
Cau t i on

While calling CToolBarCtrl Get functions is safe, use caution if you call the Set functions. This is an advanced
topic. Normally you shouldn't need to access the underlying toolbar control.
What do you want to know more about
Controls (Windows common controls)
Toolbar fundamentals
Docking and floating toolbars
Dynamically resizing the toolbar
Toolbar tool tips
Flyby status bar updates
Handling tool tip notifications
The CToolBar and CToolBarCtrl classes
Handling customization notifications
Multiple toolbars
Using your old toolbars
Control bars
For general information about using Windows common controls, see Common Controls.

See also
MFC Toolbar Implementation
Using Your Old Toolbars
3/4/2019 • 2 minutes to read • Edit Online

If you have used previous versions of Visual C++ to create customized toolbars, the new implementation of class
CToolBar could cause you problems. So that you don't have to give up your old toolbars to use the new
functionality, the old implementation is still supported.
The DOCKTOOL sample does not use the old-style toolbars, only the new-style toolbars.
You can't edit old-style toolbars with the toolbar resource editor.

What do you want to know more about


Toolbar fundamentals
Docking and floating toolbars
Toolbar tool tips
Working with the toolbar control

See also
MFC Toolbar Implementation
Visualization Manager
11/20/2018 • 2 minutes to read • Edit Online

The visual manager is an object that controls the appearance of a whole application. It acts as a single class where
you can put all the drawing code for your application. The MFC Library includes several visual managers. You can
also create your own visual manager if you want to create a custom view for your application. The following
images show the same application when different visual managers are enabled:

MyApp that uses the CMFCVisualManagerWindows visual manager

MyApp that uses the CMFCVisualManagerVS2005 visual manager

MyApp that uses the CMFCVisualManagerOfficeXP visual manager


MyApp that uses the CMFCVisualManagerOffice2003 visual manager

MyApp that uses the CMFCVisualManagerOffice2007 visual manager


By default, the visual manager maintains the drawing code for several GUI elements. To provide custom UI
elements, you need to override the related drawing methods of the visual manager. For the list of these methods,
see CMFCVisualManager Class. The methods that you can override to provide a custom appearance are all the
methods that start with OnDraw .
Your application can have only one CMFCVisualManager object. To obtain a pointer to the visual manager for your
application, call the static function CMFCVisualManager::GetInstance. Because all visual managers inherit from
CMFCVisualManager , the CMFCVisualManager::GetInstance method will get a pointer to the appropriate visual
manager, even if you create a custom visual manager.
If you want to create a custom visual manager, you must derive it from a visual manager that already exists. The
default class to derive from is CMFCVisualManager . However, you can use a different visual manager if it better
resembles what you want for your application. For example, if you wanted to use the CMFCVisualManagerOffice2007
visual manager, but wanted only to change how separators look, you could derive your custom class from
CMFCVisualManagerOffice2007 . In this scenario, you should overwrite only the methods for drawing separators.

There are two possible ways to use a specific visual manager for your application. One way is to call the
CMFCVisualManager::SetDefaultManager method and pass the appropriate visual manager as a parameter. The
following code example shows how you would use the CMFCVisualManagerVS2005 visual manager with this method:

CMFCVisualManager::SetDefaultManager (RUNTIME_CLASS (CMFCVisualManagerVS2005));

The other way to use a visual manager in your application is to create it manually. The application will then use this
new visual manager for all the rendering. However, because there can be only one CMFCVisualManager object per
application, you will have to delete the current visual manager before you create a new one. In the following
example, CMyVisualManager is a custom visual manager that is derived from CMFCVisualManager . The following
method will change what visual manager is used to display your application, depending on an index:

void CMyApp::SetSkin (int index)


{
if (CMFCVisualManager::GetInstance() != NULL)
{
delete CMFCVisualManager::GetInstance();
}

switch (index)
{
case DEFAULT_STYLE:
// The following statement creates a new CMFCVisualManager
CMFCVisualManager::GetInstance();
break;

case CUSTOM_STYLE:
new CMyVisualManager;
break;

default:
CMFCVisualManager::GetInstance();
break;
}

CMFCVisualManager::GetInstance()->RedrawAll();
}

See also
User Interface Elements
CMFCVisualManager Class
Windows
3/4/2019 • 2 minutes to read • Edit Online

This family of articles covers window objects in the MFC framework. All MFC windows derive from class CWnd,
including frame windows, views, dialog boxes, and controls.
The first group of articles describes window objects in general. Refer to this group for general information about
C++ window objects, how they encapsulate an HWND , and how you use them when creating your own windows,
such as child windows.
The second group of articles describes frame windows—windows that put a frame around content — in particular.
Refer to this group for information about how the MFC framework manages frame windows and the contents that
they frame, including control bars and views.

What do you want to know more about


Topics on Window Objects in General
Window objects
Relationship between a C++ window objects and HWND handles
Derived Window classes
Creating window objects
Destroying Window Objects
Registering window "classes"
Working with window objects
Device contexts: objects that make Windows drawing device-independent
Graphic objects: pens, brushes, fonts, bitmaps, palettes, regions
Frame Window Topics
Frame windows: window objects that provide frames
Frame windows and views
Frame-window classes
Frame-window styles
Changing the styles of a window created by MFC
What frame windows do
Using frame windows
Managing MD/Child windows (the MDICLIENT window)
Managing menus, control bars, and accelerators
CFrameWnd
CMDIFrameWnd
CMDIChildWnd
Using Views
Multiple Document Types, Views, and Frame Windows (Splitter windows)
Messages (maps and handler functions)
Create and Destroy Windows
General Window Creation Sequence
Destroy window objects
Create document frame windows
Destroy frame windows
Create Splitter Windows
Create splitter windows
Manage Child Windows and the Current View
Manage MDI child windows
Manage the current view
Manage menus, control bars, and accelerators
Work with Device Contexts and Window Styles
Use pens and other graphic objects in a device context
Change the styles of a window created by MFC

See also
User Interface Elements
Dialog Boxes
Toolbars
Status Bars
Dialog Bars
Window Objects
3/4/2019 • 2 minutes to read • Edit Online

MFC supplies class CWnd to encapsulate the HWND handle of a window. The CWnd object is a C++ window
object, distinct from the HWND that represents a Windows window but containing it. Use CWnd to derive your
own child window classes, or use one of the many MFC classes derived from CWnd . Class CWnd is the base class
for all windows, including frame windows, dialog boxes, child windows, controls, and control bars such as
toolbars. A good understanding of the relationship between a C++ window object and an HWND is crucial for
effective programming with MFC.
MFC provides some default functionality and management of windows, but you can derive your own class from
CWnd and use its member functions to customize the provided functionality. You can create child windows by
constructing a CWnd object and calling its Create member function, then customize the child windows using
CWnd member functions. You can embed objects derived from CView, such as form views or tree views, in a
frame window. And you can support multiple views of your documents via splitter panes, supplied by class
CSplitterWnd.
Each object derived from class CWnd contains a message map, through which you can map Windows messages
or command IDs to your own handlers.
The general literature on programming for Windows is a good resource for learning how to use the CWnd
member functions, which encapsulate the HWND APIs.

Functions for Operating On a CWnd


CWnd and its derived window classes provide constructors, destructors, and member functions to initialize the
object, create the underlying Windows structures, and access the encapsulated HWND . CWnd also provides
member functions that encapsulate Windows APIs for sending messages, accessing the window's state,
converting coordinates, updating, scrolling, accessing the Clipboard, and many other tasks. Most Windows
window-management APIs that take an HWND argument are encapsulated as member functions of CWnd . The
names of the functions and their parameters are preserved in the CWnd member function. For details about the
Windows APIs encapsulated by CWnd , see class CWnd.

CWnd and Windows Messages


One of the primary purposes of CWnd is to provide an interface for handling Windows messages, such as
WM_PAINT or WM_MOUSEMOVE. Many of the member functions of CWnd are handlers for standard messages
— those beginning with the identifier afx_msg and the prefix "On," such as OnPaint and OnMouseMove .
Message Handling and Mapping covers messages and message handling in detail. The information there applies
equally to the framework's windows and those that you create yourself for special purposes.
What do you want to know more about
The relationship between a C++ window object and an HWND
Derived window classes
Creating windows
Destroying window objects
Detaching a CWnd from Its HWND
Working with window objects
Device contexts: objects that make Windows drawing device independent
Graphic objects: pens, brushes, fonts, bitmaps, palettes, regions

See also
Windows
Relationship Between a C++ Window Object and an
HWND
3/4/2019 • 2 minutes to read • Edit Online

The window object is an object of the C++ CWnd class (or a derived class) that your program creates directly. It
comes and goes in response to your program's constructor and destructor calls. The Windows window , on the
other hand, is an opaque handle to an internal Windows data structure that corresponds to a window and
consumes system resources when present. A Windows window is identified by a "window handle" ( HWND ) and is
created after the CWnd object is created by a call to the Create member function of class CWnd . The window may
be destroyed either by a program call or by a user's action. The window handle is stored in the window object's
m_hWnd member variable. The following figure shows the relationship between the C++ window object and the
Windows window. Creating windows is discussed in Creating Windows. Destroying windows is discussed in
Destroying Window Objects.

Window Object and Windows Window

See also
Window Objects
Derived Window Classes
3/4/2019 • 2 minutes to read • Edit Online

You can create windows directly from CWnd, or derive new window classes from CWnd . This is how you typically
create your own custom windows. However, most windows used in a framework program are instead created
from one of the CWnd -derived frame-window classes supplied by MFC.

Frame Window Classes


CFrameWnd
Used for SDI frame windows that frame a single document and its view. The frame window is both the main frame
window for the application and the frame window for the current document.
CMDIFrameWnd
Used as the main frame window for MDI applications. The main frame window is a container for all MDI document
windows and shares its menu bar with them. An MDI frame window is a top-level window that appears on the
desktop.
CMDIChildWnd
Used for individual documents opened in an MDI main frame window. Each document and its view are framed by
an MDI child frame window contained by the MDI main frame window. An MDI child window looks much like a
typical frame window but is contained inside an MDI frame window instead of sitting on the desktop. However, the
MDI child window lacks a menu bar of its own and must share the menu bar of the MDI frame window that
contains it.
For more information, see Frame Windows.

Other Window Classes Derived from CWnd


In addition to frame windows, several other major categories of windows are derived from CWnd :
Views
Views are created using the CWnd -derived class CView (or one of its derived classes). A view is attached to a
document and acts as an intermediary between the document and the user. A view is a child window (not an MDI
child) that typically fills the client area of an SDI frame window or an MDI child frame window (or that portion of
the client area not covered by a toolbar and/or a status bar).
Dialog Boxes
Dialog boxes are created using the CWnd -derived class CDialog.
Forms
Form views based on dialog-template resources, such as dialog boxes, are created using classes CFormView,
CRecordView, or CDaoRecordView.
Controls
Controls such as buttons, list boxes, and combo boxes are created using other classes derived from CWnd . See
Control Topics.
Control Bars
Child windows that contain controls. Examples include toolbars and status bars. See Control Bars.

Window Class Hierarchy


Refer to the MFC hierarchy chart in the MFC Reference. Views are explained in Document/View Architecture.
Dialog boxes are explained in Dialog Boxes.

Creating Your Own Special-Purpose Window Classes


In addition to the window classes provided by the class library, you may need special-purpose child windows. To
create such a window, create your own CWnd-derived class and make it a child window of a frame or view. Bear in
mind that the framework manages the extent of the client area of a document frame window. Most of the client
area is managed by a view, but other windows, such as control bars or your own custom windows, may share the
space with the view. You may need to interact with the mechanisms in classes CView and CControlBar for
positioning child windows in a frame window's client area.
Creating Windows discusses creation of window objects and the windows they manage.

See also
Window Objects
Creating Windows
3/4/2019 • 2 minutes to read • Edit Online

The framework automatically creates most of the windows you need in a framework program. Document/View
Creation shows how the framework creates the frame windows associated with documents and views. But for
special purposes you can create your own windows — including your own child windows of frame windows or
views — in addition to the windows supplied by the framework.

What do you want to know more about


Registering window "classes" (as opposed to C++ window objects)
General window creation sequence
Destroying window objects
Working with window objects

See also
Window Objects
Registering Window Classes
3/4/2019 • 2 minutes to read • Edit Online

Window "classes" in traditional programming for Windows define the characteristics of a "class" (not a C++ class)
from which any number of windows can be created. This kind of class is a template or model for creating windows.

Window Class Registration in Traditional Programs for Windows


In a traditional program for Windows, without MFC, you process all messages to a window in its "window
procedure" or " WndProc ." A WndProc is associated with a window by means of a "window class registration"
process. The main window is registered in the WinMain function, but other classes of windows can be registered
anywhere in the application. Registration depends on a structure that contains a pointer to the WndProc function
together with specifications for the cursor, background brush, and so forth. The structure is passed as a parameter,
along with the string name of the class, in a prior call to the RegisterClass function. Thus, a registration class can
be shared by multiple windows.

Window Class Registration in MFC Programs


In contrast, most window class registration activity is done automatically in an MFC framework program. If you are
using MFC, you typically derive a C++ window class from an existing library class using the normal C++ syntax for
class inheritance. The framework still uses traditional "registration classes," and it provides several standard ones,
registered for you when needed. You can register additional registration classes by calling the
AfxRegisterWndClass global function and then passing the registered class to the Create member function of
CWnd . As described here, the traditional "registration class" in Windows is not to be confused with a C++ class.

For more information, see Technical Note 1.

See also
Creating Windows
General Window Creation Sequence
3/27/2020 • 2 minutes to read • Edit Online

When you create a window of your own, such as a child window, the framework uses much the same process as
that described in Document/View Creation.
All the window classes provided by MFC employ two-stage construction. That is, during an invocation of the C++
new operator, the constructor allocates and initializes a C++ object but does not create a corresponding Windows
window. That is done afterward by calling the Create member function of the window object.
The Create member function makes the Windows window and stores its HWND in the C++ object's public data
member m_hWnd. Create gives complete flexibility over the creation parameters. Before calling Create , you may
want to register a window class with the global function AfxRegisterWndClass in order to set the icon and class
styles for the frame.
For frame windows, you can use the LoadFrame member function instead of Create . LoadFrame makes the
Windows window using fewer parameters. It gets many default values from resources, including the frame's
caption, icon, accelerator table, and menu.

NOTE
Your icon, accelerator table, and menu resources must have a common resource ID, such as IDR_MAINFRAME , for them to
be loaded by LoadFrame.

What do you want to know more about


Window objects
Registering window "classes"
Destroying window objects
Creating document frame windows

See also
Creating Windows
Destroying Window Objects
3/4/2019 • 2 minutes to read • Edit Online

Care must be taken with your own child windows to destroy the C++ window object when the user is finished
with the window. If these objects are not destroyed, your application will not recover their memory. Fortunately,
the framework manages window destruction as well as creation for frame windows, views, and dialog boxes. If
you create additional windows, you are responsible for destroying them.

What do you want to know more about


Window destruction sequence
Allocating and deallocating window memory
Detaching a CWnd from its HWND
General Window Creation Sequence
Destroying frame windows

See also
Window Objects
Window Destruction Sequence
3/4/2019 • 2 minutes to read • Edit Online

In the MFC framework, when the user closes the frame window, the window's default OnClose handler calls
DestroyWindow. The last member function called when the Windows window is destroyed is OnNcDestroy, which
does some cleanup, calls the Default member function to perform Windows cleanup, and lastly calls the virtual
member function PostNcDestroy. The CFrameWnd implementation of PostNcDestroy deletes the C++ window
object.

What do you want to know more about


Allocating and deallocating window memory
Detaching a CWnd from its HWND

See also
Destroying Window Objects
Allocating and Deallocating Window Memory
3/4/2019 • 2 minutes to read • Edit Online

Do not use the C++ delete operator to destroy a frame window or view. Instead, call the CWnd member function
DestroyWindow . Frame windows, therefore, should be allocated on the heap with operator new . Be careful when
allocating frame windows on the stack frame or globally. Other windows should be allocated on the stack frame
whenever possible.

What do you want to know more about


Creating windows
Window destruction sequence
Detaching a CWnd from its HWND

See also
Destroying Window Objects
Detaching a CWnd from Its HWND
3/16/2020 • 2 minutes to read • Edit Online

If you need to circumvent the object- HWND relationship, MFC provides another CWnd member function, Detach,
which disconnects the C++ window object from the Windows window. This prevents the destructor from
destroying the Windows window when the object is destroyed.

What do you want to know more about


Creating windows
Window destruction sequence
Allocating and deallocating window memory

See also
Window Objects
Working with Window Objects
3/4/2019 • 2 minutes to read • Edit Online

Working with windows calls for two kinds of activity:


Handling Windows messages
Drawing in the window
To handle Windows messages in any window, including your own child windows, see Mapping Messages to
Functions to map the messages to your C++ window class. Then write message-handler member functions in
your class.
Most drawing in a framework application occurs in the view, whose OnDraw member function is called whenever
the window's contents must be drawn. If your window is a child of the view, you might delegate some of the
view's drawing to your child window by having OnDraw call one of your window's member functions.
In any case, you will need a device context for drawing. You can use the stock pen, brush, and other graphic objects
contained in the device context associated with your window. Or you can modify these objects to get the drawing
effects you need. With your device context set up as you like, call member functions of class CDC (device-context
class) to draw lines, shapes, and text; to use colors; and to work with a coordinate system.

What do you want to know more about


Message handling and mapping
Drawing in a view
Device contexts
Graphic objects

See also
Window Objects
Device Contexts
8/15/2019 • 2 minutes to read • Edit Online

A device context is a Windows data structure containing information about the drawing attributes of a device
such as a display or a printer. All drawing calls are made through a device-context object, which encapsulates the
Windows APIs for drawing lines, shapes, and text. Device contexts allow device-independent drawing in
Windows. Device contexts can be used to draw to the screen, to the printer, or to a metafile.
CPaintDC objects encapsulate the common idiom of Windows, calling the BeginPaint function, then drawing in
the device context, then calling the EndPaint function. The CPaintDC constructor calls BeginPaint for you, and
the destructor calls EndPaint . The simplified process is to create the CDC object, draw, and then destroy the CDC
object. In the framework, much of even this process is automated. In particular, your OnDraw function is passed a
CPaintDC already prepared (via OnPrepareDC ), and you simply draw into it. It is destroyed by the framework and
the underlying device context is released to Windows upon return from the call to your OnDraw function.
CClientDC objects encapsulate working with a device context that represents only the client area of a window. The
CClientDC constructor calls the GetDC function, and the destructor calls the ReleaseDC function. CWindowDC
objects encapsulate a device context that represents the whole window, including its frame.
CMetaFileDC objects encapsulate drawing into a Windows metafile. In contrast to the CPaintDC passed to
OnDraw , you must in this case call OnPrepareDC yourself.

Mouse Drawing
Most drawing in a framework program — and thus most device-context work — is done in the view's OnDraw
member function. However, you can still use device-context objects for other purposes. For example, to provide
tracking feedback for mouse movement in a view, you need to draw directly into the view without waiting for
OnDraw to be called.

In such a case, you can use a CClientDC device-context object to draw directly into the view.
What do you want to know more about
Device contexts (definition)
Drawing in a View
Interpreting User Input Through a View
Lines and curves
Filled shapes
Fonts and text
Colors
Coordinate spaces and transformations

See also
Window Objects
Graphic Objects
3/27/2020 • 2 minutes to read • Edit Online

Windows provides a variety of drawing tools to use in device contexts. It provides pens to draw lines, brushes to
fill interiors, and fonts to draw text. MFC provides graphic-object classes equivalent to the drawing tools in
Windows. The table below shows the available classes and the equivalent Windows graphics device interface
(GDI) handle types.

NOTE
For more information, see the GDI+ SDK documentation.

This article explains the use of these graphic-object classes:


Classes for Windows GDI Objects
C L A SS W IN DO W S H A N DL E T Y P E

CPen HPEN

CBrush HBRUSH

CFont HFONT

CBitmap HBITMAP

CPalette HPALETTE

CRgn HRGN

NOTE
The class CImage provides enhanced bitmap support.

Each graphic-object class in the class library has a constructor that allows you to create graphic objects of that
class, which you must then initialize with the appropriate create function, such as CreatePen .
Each graphic-object class in the class library has a cast operator that will cast an MFC object to the associated
Windows handle. The resulting handle is valid until the associated object detaches it. Use the object's Detach
member function to detach the handle.
The following code casts a CPen object to a Windows handle:

CPen myPen;
myPen.CreatePen(PS_COSMETIC, 1, RGB(255, 255, 0));
HPEN hMyPen = (HPEN)myPen;

To create a graphic object in a device context


1. Define a graphic object on the stack frame. Initialize the object with the type-specific create function, such
as CreatePen . Alternatively, initialize the object in the constructor. See the discussion of one-stage and
two-stage creation, which provides example code.
2. Select the object into the current device context, saving the old graphic object that was selected before.
3. When done with the current graphic object, select the old graphic object back into the device context to
restore its state.
4. Allow the frame-allocated graphic object to be deleted automatically when the scope is exited.

NOTE
If you will be using a graphic object repeatedly, you can allocate it once and select it into a device context each time it is
needed. Be sure to delete such an object when you no longer need it.

What do you want to know more about


One-stage and two-stage construction of graphic objects
Example of constructing a pen in one and two stages
Selecting a Graphic Object into a Device Context
Device contexts

See also
Window Objects
One-Stage and Two-Stage Construction of Objects
3/27/2020 • 2 minutes to read • Edit Online

You have a choice between two techniques for creating graphic objects, such as pens and brushes:
One-stage construction: Construct and initialize the object in one stage, all with the constructor.
Two-stage construction: Construct and initialize the object in two separate stages. The constructor creates
the object and an initialization function initializes it.
Two-stage construction is always safer. In one-stage construction, the constructor could throw an exception if you
provide incorrect arguments or memory allocation fails. That problem is avoided by two-stage construction,
although you do have to check for failure. In either case, destroying the object is the same process.

NOTE
These techniques apply to creating any objects, not just graphic objects.

Example of Both Construction Techniques


The following brief example shows both methods of constructing a pen object:

// One-stage
CPen myPen1(PS_DOT, 5, RGB(0, 0, 0));

// Two-stage: first construct the pen


CPen myPen2;
// Then initialize it
if (myPen2.CreatePen(PS_DOT, 5, RGB(0, 0, 0)))
{
// Use the pen
}

What do you want to know more about


Graphic objects
Selecting a graphic object into a device context
Device contexts
Drawing in a View

See also
Graphic Objects
Selecting a Graphic Object into a Device Context
3/4/2019 • 2 minutes to read • Edit Online

This topic applies to using graphic objects in a window's device context. After you create a drawing object, you
must select it into the device context in place of the default object stored there:

void CNewView::OnDraw(CDC* pDC)


{
CPen penBlack; // Construct it, then initialize
if (penBlack.CreatePen(PS_SOLID, 2, RGB(0, 0, 0)))
{
// Select it into the device context
// Save the old pen at the same time
CPen* pOldPen = pDC->SelectObject(&penBlack);

// Draw with the pen


pDC->MoveTo(20, 20);
pDC->LineTo(40, 40);

// Restore the old pen to the device context


pDC->SelectObject(pOldPen);
}
else
{
// Alert the user that resources are low
}
}

Lifetime of Graphic Objects


The graphic object returned by SelectObject is "temporary." That is, it will be deleted by the OnIdle member
function of class CWinApp the next time the program gets idle time. As long as you use the object returned by
SelectObject in a single function without returning control to the main message loop, you will have no problem.

What do you want to know more about


Graphic objects
One-stage and two-stage construction of graphic objects
Device contexts
Drawing in a View

See also
Graphic Objects
Frame Windows
3/4/2019 • 2 minutes to read • Edit Online

When an application runs under Windows, the user interacts with documents displayed in frame windows. A
document frame window has two major components: the frame and the contents that it frames. A document
frame window can be a single document interface (SDI) frame window or a multiple document interface (MDI)
child window. Windows manages most of the user's interaction with the frame window: moving and resizing the
window, closing it, and minimizing and maximizing it. You manage the contents inside the frame.

Frame Windows and Views


The MFC framework uses frame windows to contain views. The two components — frame and contents — are
represented and managed by two different classes in MFC. A frame-window class manages the frame, and a
view class manages the contents. The view window is a child of the frame window. Drawing and other user
interaction with the document take place in the view's client area, not the frame window's client area. The frame
window provides a visible frame around a view, complete with a caption bar and standard window controls such
as a control menu, buttons to minimize and maximize the window, and controls for resizing the window. The
"contents" consist of the window's client area, which is fully occupied by a child window — the view. The
following figure shows the relationship between a frame window and a view.

Frame Window and View

Frame Windows and Splitter Windows


Another common arrangement is for the frame window to frame multiple views, usually using a splitter window.
In a splitter window, the frame window's client area is occupied by a splitter window, which in turn has multiple
child windows, called panes, which are views.
What do you want to know more about
General Frame Window Topics
Window objects
Frame window classes
The Frame-Window classes created by the Application Wizard
Frame window styles
What frame windows do
Topics on Using Frame Windows
Using frame windows
Creating document frame windows
Destroying frame windows
Managing MDI child windows
Managing the current view in a frame window that contains more than one view
Managing menus, control bars, and accelerators (other objects that share the frame window's space)
Topics on Special Frame Window Capabilities
Dragging and dropping files from File Explorer or File Manager into a frame window
Responding to dynamic data exchange (DDE)
Semimodal states: Context-sensitive Windows Help (Orchestrating other window actions)
Semimodal states: printing and print preview (Orchestrating other window actions)
Topics on Other Kinds of Windows
Using Views
Dialog boxes
Controls

See also
Windows
Frame-Window Classes
3/4/2019 • 2 minutes to read • Edit Online

Each application has one "main frame window," a desktop window that usually has the application name in its
caption. Each document usually has one "document frame window." A document frame window contains at least
one view, which presents the document's data.

Frame Windows in SDI and MDI Applications


For an SDI application, there is one frame window derived from class CFrameWnd. This window is both the main
frame window and the document frame window. For an MDI application, the main frame window is derived from
class CMDIFrameWnd, and the document frame windows, which are MDI child windows, are derived from class
CMDIChildWnd.

Use the Frame-Window Class, or Derive from It


These classes provide most of the frame-window functionality you need for your applications. Under normal
circumstances, the default behavior and appearance they provide will suit your needs. If you need additional
functionality, derive from these classes.
What do you want to know more about
Frame-window classes created by the Application Wizard
Frame-window styles
Changing the styles of a window created by MFC

See also
Frame Windows
Frame-Window Classes Created by the Application
Wizard
3/19/2020 • 2 minutes to read • Edit Online

When you to create a new MFC project from the New Project dialog, in addition to application, document, and
view classes, the Application Wizard creates a derived frame-window class for your application's main frame
window. The class is called CMainFrame by default, and the files that contain it are named MAINFRM.H and
MAINFRM.CPP.
If your application is SDI, your CMainFrame class is derived from class CFrameWnd.
If your application is MDI, CMainFrame is derived from class CMDIFrameWnd. In this case CMainFrame implements
the main frame, which holds the menu, toolbar, and status bars. The Application Wizard does not derive a new
document frame-window class for you. Instead, it uses the default implementation in CMDIChildWnd Class. The
MFC framework creates a child window to contain each view (which can be of type CScrollView , CEditView ,
CTreeView , CListView , and so on) that the application requires. If you need to customize your document frame
window, you can create a new document frame-window class (see Adding a Class).
If you choose to support a toolbar, the class also has member variables of type CToolBar and CStatusBar and an
OnCreate message-handler function to initialize the two control bars.

These frame-window classes work as created, but to enhance their functionality, you must add member variables
and member functions. You may also want to have your window classes handle other Windows messages. For
more information, see Changing the Styles of a Window Created by MFC.

See also
Frame-Window Classes
MFC Program or Control Source and Header Files
Frame-Window Styles (C++)
3/4/2019 • 2 minutes to read • Edit Online

The frame windows you get with the framework are suitable for most programs, but you can gain additional
flexibility by using the advanced functions PreCreateWindow and the MFC global function AfxRegisterWndClass.
PreCreateWindow is a member function of CWnd .

If you apply the WS_HSCROLL and WS_VSCROLL styles to the main frame window, they are instead applied to
the MDICLIENT window so users can scroll the MDICLIENT area.
If the window's FWS_ADDTOTITLE style bit is set (which it is by default), the view tells the frame window what
title to display in the window's title bar based on the view's document name.

What do you want to know more about


Managing MDI child windows (MDICLIENT), the window within an MDI frame that contains the MDI child
windows
Changing the styles of a window created by MFC
Window styles

See also
Frame Windows
Changing the Styles of a Window Created by MFC
3/27/2020 • 3 minutes to read • Edit Online

In its version of the WinMain function, MFC registers several standard window classes for you. Because you don't
normally edit MFC's WinMain , that function gives you no opportunity to change the MFC default window styles.
This article explains how you can change the styles of such a preregistered window class in an existing
application.

Changing Styles in a New MFC Application


If you're using Visual C++ 2.0 or later, you can change the default window styles in the Application Wizard when
you create your application. In the Application Wizard's User Interface Features page, you can change styles for
your main frame window and MDI child windows. For either window type, you can specify its frame thickness
(thick or thin) and any of the following:
Whether the window has Minimize or Maximize controls.
Whether the window appears initially minimized, maximized, or neither.
For main frame windows, you can also specify whether the window has a System Menu. For MDI child windows,
you can specify whether the window supports splitter panes.

Changing Styles in an Existing Application


If you're changing window attributes in an existing application, follow the instructions in the rest of this article
instead.
To change the default window attributes used by a framework application created with the Application Wizard,
override the window's PreCreateWindow virtual member function. PreCreateWindow allows an application to
access the creation process normally managed internally by the CDocTemplate class. The framework calls
PreCreateWindow just prior to creating the window. By modifying the CREATESTRUCT structure passed to
PreCreateWindow , your application can change the attributes used to create the window. For example, to ensure
that a window does not use a caption, use the following bitwise operation:

// cs has been declared as CREATESTRUCT& cs;


cs.style &= ~WS_CAPTION;

The CTRLBARS sample application demonstrates this technique for changing window attributes. Depending on
what your application changes in PreCreateWindow , it may be necessary to call the base class implementation of
the function.
The following discussion covers the SDI case and the MDI case.

The SDI Case


In a single document interface (SDI) application, the default window style in the framework is a combination of
the WS_OVERL APPEDWINDOW and FWS_ADDTOTITLE styles. FWS_ADDTOTITLE is an MFC-specific style
that instructs the framework to add the document title to the window's caption. To change the window attributes
in an SDI application, override the PreCreateWindow function in your class derived from CFrameWnd (which the
Application Wizard names CMainFrame ). For example:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT &cs)
{
// Call the base-class version
if (!CFrameWnd::PreCreateWindow(cs))
return FALSE;

// Create a window without min/max buttons or sizable border


cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER;

// Size the window to 1/3 screen size and center it


cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
cs.y = ((cs.cy * 3) - cs.cy) / 2;
cs.x = ((cs.cx * 3) - cs.cx) / 2;

return TRUE;
}

This code creates a main frame window without Minimize and Maximize buttons and without a sizable border. The
window is initially centered on the screen.

The MDI Case


A little more work is required to change the window style of a child window in a multiple document interface
(MDI) application. By default, an MDI application created with the Application Wizard uses the default
CMDIChildWnd class defined in MFC. To change the window style of an MDI child window, you must derive a new
class from CMDIChildWnd and replace all references to CMDIChildWnd in your project with references to the new
class. Most likely, the only reference to CMDIChildWnd in the application is located in your application's
InitInstance member function.

The default window style used in an MDI application is a combination of the WS_CHILD ,
WS_OVERL APPEDWINDOW , and FWS_ADDTOTITLE styles. To change the window attributes of an MDI
application's child windows, override the PreCreateWindow function in your class derived from CMDIChildWnd . For
example:

BOOL CChildFrame::PreCreateWindow(CREATESTRUCT &cs)


{
// Create a child window without the maximize button
cs.style &= ~WS_MAXIMIZEBOX;

return CMDIChildWnd::PreCreateWindow(cs);
}

This code creates MDI child windows without a Maximize button.


What do you want to know more about
Windows styles
Frame-window styles
Window styles

See also
Frame-Window Styles
What Frame Windows Do
3/4/2019 • 2 minutes to read • Edit Online

Besides simply framing a view, frame windows are responsible for numerous tasks involved in coordinating the
frame with its view and with the application. CMDIFrameWnd and CMDIChildWnd inherit from CFrameWnd, so
they have CFrameWnd capabilities as well as new capabilities that they add. Examples of child windows include
views, controls such as buttons and list boxes, and control bars, including toolbars, status bars, and dialog bars.
The frame window is responsible for managing the layout of its child windows. In the MFC framework, a frame
window positions any control bars, views, and other child windows inside its client area.
The frame window also forwards commands to its views and can respond to notification messages from control
windows.

What do you want to know more about


Control bars (how they fit into the frame window)
Managing menus, control bars, and accelerators (how they fit into the frame window)
Command Routing (from the frame window to its view and other command targets)
Document /View Architecture
Control bars
Controls

See also
Frame Windows
Using Frame Windows
3/4/2019 • 2 minutes to read • Edit Online

The MFC framework creates document frame windows — and their views and documents — as part of its
implementation of the New and Open commands on the File menu. Because the framework does most of the
frame-window work for you, you play only a small role in creating, using, and destroying those windows. You can,
however, explicitly create your own frame windows and child windows for special purposes.

What do you want to know more about


Creating document frame windows
When to Initialize CWnd Objects
Destroying frame windows
Managing MDI child windows
Managing the current view
Managing menus, control bars, and accelerators
Dragging and dropping files in a frame window
Responding to dynamic data exchange (DDE)
Orchestrating other window actions
Managing context-sensitive help
The frame window's role in printing and print preview

See also
Frame Windows
Creating Document Frame Windows
3/4/2019 • 2 minutes to read • Edit Online

Document/View Creation shows how the CDocTemplate object orchestrates creating the frame window,
document, and view and connecting them all together. Three CRuntimeClass arguments to the CDocTemplate
constructor specify the frame window, document, and view classes that the document template creates
dynamically in response to user commands such as the New command on the File menu or the New Window
command on an MDI Window menu. The document template stores this information for later use when it creates
a frame window for a view and document.
For the RUNTIME_CLASS mechanism to work correctly, your derived frame-window classes must be declared
with the DECLARE_DYNCREATE macro. This is because the framework needs to create document frame windows
using the dynamic construction mechanism of class CObject .
When the user chooses a command that creates a document, the framework calls upon the document template to
create the document object, its view, and the frame window that will display the view. When it creates the
document frame window, the document template creates an object of the appropriate class — a class derived
from CFrameWnd for an SDI application or from CMDIChildWnd for an MDI application. The framework then calls
the frame-window object's LoadFrame member function to get creation information from resources and to create
the Windows window. The framework attaches the window handle to the frame-window object. Then it creates the
view as a child window of the document frame window.
Use caution in deciding when to initialize your CWnd -derived object.

What do you want to know more about


Deriving a Class from CObject (its dynamic creation mechanism)
Document/View Creation (templates and frame window creation)
Destroying frame windows

See also
Using Frame Windows
When to Initialize CWnd Objects
3/4/2019 • 2 minutes to read • Edit Online

You cannot create your own child windows or call any Windows API functions in the constructor of a CWnd -derived
object. This is because the HWND for the CWnd object has not been created yet. Most Windows-specific
initialization, such as adding child windows, must be done in an OnCreate message handler.

What do you want to know more about


Creating document frame windows
Document/view creation

See also
Using Frame Windows
Destroying Frame Windows
3/4/2019 • 2 minutes to read • Edit Online

The MFC framework manages window destruction as well as creation for those windows associated with
framework documents and views. If you create additional windows, you are responsible for destroying them.
In the framework, when the user closes the frame window, the window's default OnClose handler calls
DestroyWindow. The last member function called when the Windows window is destroyed is OnNcDestroy, which
does some cleanup, calls the Default member function to perform Windows cleanup, and lastly calls the virtual
member function PostNcDestroy. The CFrameWnd implementation of PostNcDestroy deletes the C++ window
object. You should never use the C++ delete operator on a frame window. Use DestroyWindow instead.
When the main window closes, the application closes. If there are modified unsaved documents, the framework
displays a message box to ask if the documents should be saved and ensures that the appropriate documents are
saved if necessary.

What do you want to know more about


Creating document frame windows

See also
Using Frame Windows
Managing MDI Child Windows
3/4/2019 • 2 minutes to read • Edit Online

MDI main frame windows (one per application) contain a special child window called the MDICLIENT window. The
MDICLIENT window manages the client area of the main frame window, and itself has child windows: the
document windows, derived from CMDIChildWnd . Because the document windows are frame windows themselves
(MDI child windows), they can also have their own children. In all of these cases, the parent window manages its
child windows and forwards some commands to them.
In an MDI frame window, the frame window manages the MDICLIENT window, repositioning it in conjunction with
control bars. The MDICLIENT window, in turn, manages all MDI child frame windows. The following figure shows
the relationship between an MDI frame window, its MDICLIENT window, and its child document frame windows.

MDI Frame Windows and Children


An MDI frame window also works in conjunction with the current MDI child window, if there is one. The MDI
frame window delegates command messages to the MDI child before it tries to handle them itself.

What do you want to know more about


Creating document frame windows
Frame-window styles

See also
Using Frame Windows
Managing the Current View
3/4/2019 • 2 minutes to read • Edit Online

As part of the default implementation of frame windows, a frame window keeps track of a currently active view. If
the frame window contains more than one view, as for example in a splitter window, the current view is the most
recent view in use. The active view is independent of the active window in Windows or the current input focus.
When the active view changes, the framework notifies the current view by calling its OnActivateView member
function. You can tell whether the view is being activated or deactivated by examining OnActivateView 's bActivate
parameter. By default, OnActivateView sets the focus to the current view on activation. You can override
OnActivateView to perform any special processing when the view is deactivated or reactivated. For example, you
might want to provide special visual cues to distinguish the active view from other, inactive views.
A frame window forwards commands to its current (active) view, as described in Command Routing, as part of the
standard command routing.

See also
Using Frame Windows
Managing Menus, Control Bars, and Accelerators
3/4/2019 • 2 minutes to read • Edit Online

The frame window manages updating user-interface objects, including menus, toolbar buttons, the status bar, and
accelerators. It also manages sharing the menu bar in MDI applications.

Managing Menus
The frame window participates in updating user-interface items using the ON_UPDATE_COMMAND_UI
mechanism described in How to Update User-Interface Objects. Buttons on toolbars and other control bars are
updated during the idle loop. Menu items in drop-down menus on the menu bar are updated just before the
menu drops down.
For MDI applications, the MDI frame window manages the menu bar and caption. An MDI frame window owns
one default menu that is used as the menu bar when there are no active MDI child windows. When there are
active children, the MDI frame window's menu bar is taken over by the menu for the active MDI child window. If
an MDI application supports multiple document types, such as chart and worksheet documents, each type puts its
own menus into the menu bar and changes the main frame window's caption.
CMDIFrameWnd provides default implementations for the standard commands on the Window menu that
appears for MDI applications. In particular, the New Window command (ID_WINDOW_NEW) is implemented to
create a new frame window and view on the current document. You need to override these implementations only
if you need advanced customization.
Multiple MDI child windows of the same document type share menu resources. If several MDI child windows are
created by the same document template, they can all use the same menu resource, saving on system resources in
Windows.

Managing the Status Bar


The frame window also positions the status bar within its client area and manages the status bar's indicators. The
frame window clears and updates the message area in the status bar as needed and displays prompt strings as
the user selects menu items or toolbar buttons, as described in How to Display Command Information in the
Status Bar.

Managing Accelerators
Each frame window maintains an optional accelerator table that does keyboard accelerator translation for you
automatically. This mechanism makes it easy to define accelerator keys (also called shortcut keys) that invoke
menu commands.

See also
Using Frame Windows
Dragging and Dropping Files in a Frame Window
3/4/2019 • 2 minutes to read • Edit Online

The frame window manages a relationship with File Explorer or File Manager.
By adding a few initializing calls in your override of the CWinApp member function InitInstance , as described in
CWinApp: The Application Class, you can have your frame window indirectly open files dragged from File Explorer
or File Manager and dropped in the frame window. See File Manager Drag and Drop.

See also
Using Frame Windows
Responding to Dynamic Data Exchange (DDE)
3/4/2019 • 2 minutes to read • Edit Online

The frame window can respond to dynamic data exchange (DDE) requests to open files from the File Manager (if
the file extension is registered or associated with the application). See Shell Registration.

See also
Using Frame Windows
Orchestrating Other Window Actions
3/4/2019 • 2 minutes to read • Edit Online

The frame window orchestrates semimodal states such as context-sensitive help and print preview. For a
description of the frame window's role in print preview, see Printing and Print Preview.

See also
Using Frame Windows
Windows Sockets
3/4/2019 • 2 minutes to read • Edit Online

This family of articles covers the MFC implementation of Windows Sockets. MFC supplies two classes to support
programming network applications with the Windows Sockets API. Class CAsyncSocket encapsulates the Windows
Sockets API one for one, giving advanced network programmers the most power and flexibility. Class CSocket
provides a simplified interface for serializing data to and from a CArchive object.

In This Section
Windows Sockets in MFC
Windows Sockets in MFC
3/27/2020 • 2 minutes to read • Edit Online

NOTE
MFC supports Windows Sockets 1 but does not support Windows Sockets 2. Windows Sockets 2 first shipped with
Windows 98 and is the version included with Windows 2000.

MFC supplies two models for writing network communications programs with Windows Sockets, embodied in
two MFC classes. This article describes these models and further details MFC sockets support. A "socket" is an
endpoint of communication: an object through which your application communicates with other Windows
Sockets applications across a network.
For information on Windows Sockets, including an explanation of the socket concept, see Windows Sockets:
Background.

Sockets Programming Models


The two MFC Windows Sockets programming models are supported by the following classes:
CAsyncSocket

This class encapsulates the Windows Sockets API. CAsyncSocket is for programmers who know network
programming and want the flexibility of programming directly to the sockets API but also want the
convenience of callback functions for notification of network events. Other than packaging sockets in
object-oriented form for use in C++, the only additional abstraction this class supplies is converting
certain socket-related Windows messages into callbacks. For more information, see Windows Sockets:
Socket Notifications.
CSocket

This class, derived from CAsyncSocket , supplies a higher level abstraction for working with sockets
through an MFC CArchive object. Using a socket with an archive greatly resembles using MFC's file
serialization protocol. This makes it easier to use than the CAsyncSocket model. CSocket inherits many
member functions from CAsyncSocket that encapsulate Windows Sockets APIs; you will have to use some
of these functions and understand sockets programming generally. But CSocket manages many aspects
of the communication that you would have to do yourself using either the raw API or class CAsyncSocket .
Most importantly, CSocket provides blocking (with background processing of Windows messages),
which is essential to the synchronous operation of CArchive .
Creating and using CSocket and CAsyncSocket objects is described in Windows Sockets: Using Sockets with
Archives and Windows Sockets: Using Class CAsyncSocket.

Windows Sockets DLLs


The Microsoft Windows operating systems supply the Windows Sockets dynamic-link libraries (DLL). Visual
C++ supplies the appropriate header files and libraries and the Windows Sockets specification.
For more information about Windows Sockets, see:
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets
Windows Sockets: Using Sockets with Archives
Windows Sockets: Sequence of Operations
Windows Sockets: Example of Sockets Using Archives
Windows Sockets: How Sockets with Archives Work
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Deriving from Socket Classes
Windows Sockets: Socket Notifications
Windows Sockets: Blocking
Windows Sockets: Byte Ordering
Windows Sockets: Converting Strings
Windows Sockets: Ports and Socket Addresses

See also
Windows Sockets
Windows Sockets: Background
3/27/2020 • 3 minutes to read • Edit Online

This article explains the nature and purpose of Windows Sockets. The article also:
Defines the term "socket".
Describes the SOCKET handle data type.
Describes uses for sockets.
The Windows Sockets specification defines a binary-compatible network programming interface for Microsoft
Windows. Windows Sockets are based on the UNIX sockets implementation in the Berkeley Software Distribution
(BSD, release 4.3) from the University of California at Berkeley. The specification includes both BSD-style socket
routines and extensions specific to Windows. Using Windows Sockets permits your application to communicate
across any network that conforms to the Windows Sockets API. On Win32, Windows Sockets provide for thread
safety.
Many network software vendors support Windows Sockets under network protocols including Transmission
Control Protocol/Internet Protocol (TCP/IP), Xerox Network System (XNS), Digital Equipment Corporation's
DECNet protocol, Novell Corporation's Internet Packet Exchange/Sequenced Packed Exchange (IPX/SPX), and
others. Although the present Windows Sockets specification defines the sockets abstraction for TCP/IP, any
network protocol can comply with Windows Sockets by supplying its own version of the dynamic-link library
(DLL) that implements Windows Sockets. Examples of commercial applications written with Windows Sockets
include X Windows servers, terminal emulators, and electronic mail systems.

NOTE
The purpose of Windows Sockets is to abstract away the underlying network so that you do not have to be knowledgeable
about that network and so your application can run on any network that supports sockets. Consequently, this
documentation does not discuss the details of network protocols.

The Microsoft Foundation Class Library (MFC) supports programming with the Windows Sockets API by
supplying two classes. One of these classes, CSocket , provides a high level of abstraction to simplify your
network communications programming.
The Windows Sockets specification, Windows Sockets: An Open Interface for Network Computing Under
Microsoft Windows, now at version 1.1, was developed as an open networking standard by a large group of
individuals and corporations in the TCP/IP community and is freely available for use. The sockets programming
model supports one "communication domain" currently, using the Internet Protocol Suite. The specification is
available in the Windows SDK.

TIP
Because sockets use the Internet Protocol Suite, they are the preferred route for applications that support Internet
communications on the "information highway."

Definition of a Socket
A socket is a communication endpoint — an object through which a Windows Sockets application sends or
receives packets of data across a network. A socket has a type and is associated with a running process, and it
may have a name. Currently, sockets generally exchange data only with other sockets in the same
"communication domain," which uses the Internet Protocol Suite.
Both kinds of sockets are bidirectional; they are data flows that can be communicated in both directions
simultaneously (full-duplex).
Two socket types are available:
Stream sockets
Stream sockets provide for a data flow without record boundaries: a stream of bytes. Streams are
guaranteed to be delivered and to be correctly sequenced and unduplicated.
Datagram sockets
Datagram sockets support a record-oriented data flow that is not guaranteed to be delivered and may not
be sequenced as sent or unduplicated.
"Sequenced" means that packets are delivered in the order sent. "Unduplicated" means that you get a particular
packet only once.

NOTE
Under some network protocols, such as XNS, streams can be record oriented, as streams of records rather than streams of
bytes. Under the more common TCP/IP protocol, however, streams are byte streams. Windows Sockets provides a level of
abstraction independent of the underlying protocol.

For information about these types and which kind of socket to use in which situations, see Windows Sockets:
Stream Sockets and Windows Sockets: Datagram Sockets.

The SOCKET Data Type


Each MFC socket object encapsulates a handle to a Windows Sockets object. The data type of this handle is
SOCKET . A SOCKET handle is analogous to the HWND for a window. MFC socket classes provide operations on
the encapsulated handle.
The SOCKET data type is described in detail in the Windows SDK. See "Socket Data Type and Error Values" under
Windows Sockets.

Uses for Sockets


Sockets are highly useful in at least three communications contexts:
Client/server models.
Peer-to-peer scenarios, such as messaging applications.
Making remote procedure calls (RPC) by having the receiving application interpret a message as a function
call.

TIP
The ideal case for using MFC sockets is when you are writing both ends of the communication: using MFC at both ends.
For more information on this topic, including how to manage the case when you're communicating with non-MFC
applications, see Windows Sockets: Byte Ordering.

For more information, see Windows Sockets Specification: ntohs , ntohl , htons , htonl . Also, see the following
topics:
Windows Sockets: Using Sockets with Archives
Windows Sockets: Example of Sockets Using Archives
Windows Sockets: Using Class CAsyncSocket

See also
Windows Sockets in MFC
Windows Sockets: Stream Sockets
3/4/2019 • 2 minutes to read • Edit Online

This article describes stream sockets, one of the two Windows Socket types available. (The other type is the
datagram socket.)
Stream sockets provide for a data flow without record boundaries: a stream of bytes that can be bidirectional (the
application is full duplex: it can both transmit and receive through the socket). Streams can be relied upon to
deliver sequenced, unduplicated data. ("Sequenced" means that packets are delivered in the order sent.
"Unduplicated" means that you get a particular packet only once.) Receipt of stream messages is guaranteed, and
streams are well suited to handling large amounts of data.
The network transport layer may break up or group data into packets of reasonable size. The CSocket class will
handle the packing and unpacking for you.
Streams are based on explicit connections: socket A requests a connection to socket B; socket B accepts or rejects
the connection request.
A telephone call provides a good analogy for a stream. Under normal circumstances, the receiving party hears
what you say in the order that you say it, without duplication or loss. Stream sockets are appropriate, for example,
for implementations such as the File Transfer Protocol (FTP), which facilitates transferring ASCII or binary files of
arbitrary size.
Stream sockets are preferable to datagram sockets when the data must be guaranteed to arrive and when data
size is large. For more information about stream sockets, see the Windows Sockets specification. The specification
is available in the Windows SDK.
Using stream sockets can be superior to applications designed to use a datagram socket for broadcasting to all
receiving sockets on the network because
The broadcast model is subject to network flood (or "storm") problems.
The client-server model adopted subsequently is more efficient.
The stream model supplies reliable data transfer, where the datagram model does not.
The final model takes advantage of the ability to communicate between Unicode and ANSI socket
applications that class CArchive lends to class CSocket.

NOTE
If you use class CSocket , you must use a stream. An MFC assertion fails if you specify the socket type as
SOCK_DGRAM .

See also
Windows Sockets in MFC
Windows Sockets: Background
Windows Sockets: Datagram Sockets
3/4/2019 • 2 minutes to read • Edit Online

This article describes datagram sockets, one of the two Windows Socket types available. (The other type is the
stream socket.)
Datagram sockets support a bidirectional data flow that is not guaranteed to be sequenced or unduplicated.
Datagrams also are not guaranteed to be reliable; they can fail to arrive. Datagram data may arrive out of order
and possibly duplicated, but record boundaries in the data are preserved, as long as the records are smaller than
the receiver's internal size limit. You are responsible for managing sequencing and reliability. (Reliability tends to
be good on local-area networks [LAN] but less so on wide-area networks [WAN], such as the Internet.)
Datagrams are "connectionless", that is, no explicit connection is established; you send a datagram message to a
specified socket and you can receive messages from a specified socket.
An example of a datagram socket is an application that keeps system clocks on the network synchronized. This
illustrates an additional capability of datagram sockets in at least some settings: broadcasting messages to a large
number of network addresses.
Datagram sockets are better than stream sockets for record-oriented data. For more information about datagram
sockets, see the Windows Sockets specification, available in the Windows SDK.

See also
Windows Sockets in MFC
Windows Sockets: Background
Windows Sockets: Using Sockets with Archives
3/27/2020 • 3 minutes to read • Edit Online

This article describes the CSocket programming model. Class CSocket supplies socket support at a higher level
of abstraction than does class CAsyncSocket. CSocket uses a version of the MFC serialization protocol to pass
data to and from a socket object through an MFC CArchive object. CSocket provides blocking (while managing
background processing of Windows messages) and gives you access to CArchive , which manages many
aspects of the communication that you would have to do yourself using either the raw API or class
CAsyncSocket .

TIP
You can use class CSocket by itself, as a more convenient version of CAsyncSocket , but the simplest programming
model is to use CSocket with a CArchive object.

For more information about how the implementation of sockets with archives works, see Windows Sockets:
How Sockets with Archives Work. For example code, see Windows Sockets: Sequence of Operations and
Windows Sockets: Example of Sockets Using Archives. For information about some of the functionality you can
gain by deriving your own classes from the sockets classes, see Windows Sockets: Deriving from Socket Classes.

NOTE
If you are writing an MFC client program to communicate with established (non-MFC) servers, do not send C++ objects
through the archive. Unless the server is an MFC application that understands the kinds of objects you want to send, it
will not be able to receive and deserialize your objects. For related material on the subject of communicating with non-
MFC applications, also see the article Windows Sockets: Byte Ordering.

The CSocket Programming Model


Using a CSocket object involves creating and associating together several MFC class objects. In the general
procedure below, each step is taken by both the server socket and the client socket, except for step 3, in which
each socket type requires a different action.

TIP
At run time, the server application usually starts first to be ready and "listening" when the client application seeks a
connection. If the server is not ready when the client tries to connect, you typically require the user application to try
connecting again later.

To set up communication between a server socket and a client socket


1. Construct a CSocket object.
2. Use the object to create the underlying SOCKET handle.
For a CSocket client object, you should normally use the default parameters to Create, unless you need a
datagram socket. For a CSocket server object, you must specify a port in the Create call.
NOTE
CArchive does not work with datagram sockets. If you want to use CSocket for a datagram socket, you must
use the class as you would use CAsyncSocket , that is, without an archive. Because datagrams are unreliable (not
guaranteed to arrive and may be repeated or out of sequence), they are not compatible with serialization through
an archive. You expect a serialization operation to complete reliably and in sequence. If you try to use CSocket
with a CArchive object for a datagram, an MFC assertion fails.

3. If the socket is a client, call CAsyncSocket::Connect to connect the socket object to a server socket.
-or-
If the socket is a server, call CAsyncSocket::Listen to begin listening for connect attempts from a client.
Upon receiving a connection request, accept it by calling CAsyncSocket::Accept.

NOTE
The Accept member function takes a reference to a new, empty CSocket object as its parameter. You must
construct this object before you call Accept . If this socket object goes out of scope, the connection closes. Do
not call Create for this new socket object.

4. Create a CSocketFile object, associating the CSocket object with it.


5. Create a CArchive object for either loading (receiving) or storing (sending) data. The archive is associated
with the CSocketFile object.
Keep in mind that CArchive does not work with datagram sockets.
6. Use the CArchive object to pass data between the client and server sockets.
Keep in mind that a given CArchive object moves data in one direction only: either for loading
(receiving) or storing (sending). In some cases, you will use two CArchive objects: one for sending data,
the other for receiving acknowledgments.
After accepting a connection and setting up the archive, you can perform such tasks as validating
passwords.
7. Destroy the archive, socket file, and socket objects.

NOTE
Class CArchive supplies the IsBufferEmpty member function specifically for use with class CSocket . If the
buffer contains multiple data messages, for example, you need to loop until all of them are read and the buffer is
cleared. Otherwise, your next notification that there is data to be received may be indefinitely delayed. Use
IsBufferEmpty to assure that you retrieve all data.

The article Windows Sockets: Sequence of Operations illustrates both sides of this process with example code.
For more information, see:
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
CSocket::Create
Windows Sockets: Sequence of Operations
3/4/2019 • 3 minutes to read • Edit Online

This article illustrates, side by side, the sequence of operations for a server socket and a client socket. Because the
sockets use CArchive objects, they are necessarily stream sockets.

Sequence of Operations for a Stream Socket Communication


Up to the point of constructing a CSocketFile object, the following sequence is accurate (with a few parameter
differences) for both CAsyncSocket and CSocket . From that point on, the sequence is strictly for CSocket . The
following table illustrates the sequence of operations for setting up communication between a client and a server.
Setting Up Communication Between a Server and a Client
SERVER C L IEN T

// construct a socket // construct a socket

CSocket sockSrvr; CSocket sockClient;

// create the SOCKET // create the SOCKET

sockSrvr.Create(nPort); 1,2 sockClient.Create( ); 2

// start listening

sockSrvr.Listen( );

// seek a connection

sockClient.Connect(strAddr, nPort); 3,4

// construct a new, empty socket

CSocket sockRecv;

// accept connection

sockSrvr.Accept( sockRecv ); 5

// construct file object // construct file object

CSocketFile file(&sockRecv); CSocketFile file(&sockClient);


SERVER C L IEN T

// construct an archive // construct an archive

CArchive arIn(&file, CArchive::load); CArchive arIn(&file, CArchive::load);

-or- -or-

CArchive arOut(&file, CArchive::store); CArchive arOut(&file, CArchive::store);

- or Both - - or Both -

// use the archive to pass data: // use the archive to pass data:

arIn >> dwValue; arIn >> dwValue;

-or- -or-

arOut << dwValue; 6 arOut << dwValue; 6

1. Where nPort is a port number. See Windows Sockets: Ports and Socket Addresses for details about ports.
2. The server must always specify a port so clients can connect. The Create call sometimes also specifies an
address. On the client side, use the default parameters, which ask MFC to use any available port.
3. Where nPort is a port number and strAddr is a machine address or an Internet Protocol (IP) address.
4. Machine addresses can take several forms: "ftp.microsoft.com", "microsoft.com". IP addresses use the
"dotted number" form "127.54.67.32". The Connect function checks to see if the address is a dotted
number (although it does not check to ensure the number is a valid machine on the network). If not,
Connect assumes a machine name of one of the other forms.

5. When you call Accept on the server side, you pass a reference to a new socket object. You must construct
this object first, but do not call Create for it. Keep in mind that if this socket object goes out of scope, the
connection closes. MFC connects the new object to a SOCKET handle. You can construct the socket on the
stack, as shown, or on the heap.
6. The archive and the socket file are closed when they go out of scope. The socket object's destructor also
calls the Close member function for the socket object when the object goes out of scope or is deleted.

Additional Notes About the Sequence


The sequence of calls shown in the preceding table is for a stream socket. Datagram sockets, which are
connectionless, do not require the CAsyncSocket::Connect, Listen, and Accept calls (although you can optionally
use Connect ). Instead, if you are using class CAsyncSocket , datagram sockets use the CAsyncSocket::SendTo and
ReceiveFrom member functions. (If you use Connect with a datagram socket, you use Send and Receive .)
Because CArchive does not work with datagrams, do not use CSocket with an archive if the socket is a datagram.
CSocketFile does not support all of CFile 's functionality; CFile members such as Seek , which make no sense
for a socket communication, are unavailable. Because of this, some default MFC Serialize functions are not
compatible with CSocketFile . This is particularly true of the CEditView class. You should not try to serialize
CEditView data through a CArchive object attached to a CSocketFile object using CEditView::SerializeRaw ; use
CEditView::Serialize instead (not documented). The SerializeRaw function expects the file object to have
functions, such as Seek , that CSocketFile does not support.
For more information, see:
Windows Sockets: Using Sockets with Archives
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Ports and Socket Addresses
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
CSocket Class
CAsyncSocket::Create
CAsyncSocket::Close
Windows Sockets: Example of Sockets Using Archives
3/27/2020 • 3 minutes to read • Edit Online

This article presents an example of using class CSocket. The example employs CArchive objects to serialize data
through a socket. Note that this is not document serialization to or from a file.
The following example illustrates how you use the archive to send and receive data through CSocket objects. The
example is designed so that two instances of the application (on the same machine or on different machines on
the network) exchange data. One instance sends data, which the other instance receives and acknowledges. Either
application can initiate an exchange, and either can act as server or as client to the other application. The following
function is defined in the application's view class:

void PacketSerialize(long nPackets, CArchive &arData, CArchive &arAck)


{
BYTE bValue = 0;
WORD nCopies = 0;

if (arData.IsStoring())
{
CString strText;
errno_t err;
unsigned int number;

for (int p = 0; p < nPackets; p++)


{
err = rand_s(&number);
// if (err == 0)...
bValue = (BYTE)(number % 256);

err = rand_s(&number);
// if (err == 0)...
nCopies = (WORD)(number % 32000);

// Send header information


arData << bValue << nCopies;
for (int c = 0; c < nCopies; c++)
{
// Send data
arData << bValue;
}

strText.Format(_T("Sender sent packet %d of %d (Value = %d, Copies = %d)"),


p + 1, nPackets, (int)bValue, nCopies);

// Send receipt string


arData << strText;
arData.Flush();

// Receive acknowledgment
arAck >> strText;
// display it
DisplayMessage(strText);
}
}
else
{
CString strText;
BYTE bCheck;

for (int p = 0; p < nPackets; p++)


{
{
// Receive header information
arData >> bCheck >> nCopies;
for (int c = 0; c < nCopies; c++)
{
// Receive data
arData >> bValue;
if (bCheck != bValue)
{
AfxMessageBox(_T("Packet Failure"));
}
}

// Receive receipt string and display it


arData >> strText;
DisplayMessage(strText);

strText.Format(_T("Recipient received packet %d of %d (Value = %d, Copies = %d)"),


p + 1, nPackets, (int)bValue, nCopies);

// Send acknowledgment
arAck << strText;
arAck.Flush();
}
}
}

The most important thing about this example is that its structure parallels that of an MFC Serialize function. The
PacketSerialize member function consists of an if statement with an else clause. The function receives two
CArchive references as parameters: arData and arAck. If the arData archive object is set for storing (sending), the if
branch executes; otherwise, if arData is set for loading (receiving) the function takes the else branch. For more
information about serialization in MFC, see Serialization.

NOTE
The arAck archive object is assumed to be the opposite of arData. If arData is for sending, arAck receives, and the converse
is true.

For sending, the example function loops for a specified number of times, each time generating some random data
for demonstration purposes. Your application would obtain real data from some source, such as a file. The arData
archive's insertion operator (<< ) is used to send a stream of three consecutive chunks of data:
A "header" that specifies the nature of the data (in this case, the value of the bValue variable and how many
copies will be sent).
Both items are generated randomly for this example.
The specified number of copies of the data.
The inner for loop sends bValue the specified number of times.
A string called strText that the receiver displays to its user.
For receiving, the function operates similarly, except that it uses the archive's extraction operator (>> ) to get data
from the archive. The receiving application verifies the data it receives, displays the final "Received" message, and
then sends back a message that says "Sent" for the sending application to display.
In this communications model, the word "Received", the message sent in the strText variable, is for display at the
other end of the communication, so it specifies to the receiving user that a certain number of packets of data have
been received. The receiver replies with a similar string that says "Sent", for display on the original sender's screen.
Receipt of both strings indicates that successful communication has occurred.
Cau t i on

If you are writing an MFC client program to communicate with established (non-MFC) servers, do not send C++
objects through the archive. Unless the server is an MFC application that understands the kinds of objects you
want to send, it won't be able to receive and deserialize your objects. An example in the article Windows Sockets:
Byte Ordering shows a communication of this type.
For more information, see Windows Sockets Specification: htonl , htons , ntohl , ntohs . Also, for more
information, see:
Windows Sockets: Deriving from Socket Classes
Windows Sockets: How Sockets with Archives Work
Windows Sockets: Background

See also
Windows Sockets in MFC
CArchive::IsStoring
CArchive::operator <<
CArchive::operator >>
CArchive::Flush
CObject::Serialize
Windows Sockets: How Sockets with Archives Work
3/4/2019 • 3 minutes to read • Edit Online

This article explains how a CSocket object, a CSocketFile object, and a CArchive object are combined to simplify
sending and receiving data through a Windows Socket.
The article Windows Sockets: Example of Sockets Using Archives presents the PacketSerialize function. The
archive object in the PacketSerialize example works much like an archive object passed to an MFC Serialize
function. The essential difference is that for sockets, the archive is attached not to a standard CFile object (typically
associated with a disk file) but to a CSocketFile object. Rather than connecting to a disk file, the CSocketFile
object connects to a CSocket object.
A CArchive object manages a buffer. When the buffer of a storing (sending) archive is full, an associated CFile
object writes out the buffer's contents. Flushing the buffer of an archive attached to a socket is equivalent to
sending a message. When the buffer of a loading (receiving) archive is full, the CFile object stops reading until
the buffer is available again.
Class CSocketFile derives from CFile , but it does not support CFile member functions such as the positioning
functions ( Seek , GetLength , SetLength , and so on), the locking functions ( LockRange , UnlockRange ), or the
GetPosition function. All the CSocketFile object must do is write or read sequences of bytes to or from the
associated CSocket object. Because a file is not involved, operations such as Seek and GetPosition make no
sense. CSocketFile is derived from CFile , so it would normally inherit all of these member functions. To prevent
this, the unsupported CFile member functions are overridden in CSocketFile to throw a
CNotSupportedException.
The CSocketFile object calls member functions of its CSocket object to send or receive data.
The following figure shows the relationships among these objects on both sides of the communication.

CArchive, CSocketFile, and CSocket


The purpose of this apparent complexity is to shield you from the necessity of managing the details of the socket
yourself. You create the socket, the file, and the archive, and then begin sending or receiving data by inserting it to
the archive or extracting it from the archive. CArchive, CSocketFile, and CSocket manage the details behind the
scenes.
A CSocket object is actually a two-state object: sometimes asynchronous (the usual state) and sometimes
synchronous. In its asynchronous state, a socket can receive asynchronous notifications from the framework.
However, during an operation such as receiving or sending data the socket becomes synchronous. This means the
socket will receive no further asynchronous notifications until the synchronous operation has completed. Because
it switches modes, you can, for example, do something like the following:

void CMySocket::OnReceive(int nErrorCode)


{
if (0 == nErrorCode)
{
CSocketFile file(this);
CArchive ar(&file, CArchive::load);
CString str;

ar >> str;
}
}

If CSocket were not implemented as a two-state object, it might be possible to receive additional notifications for
the same kind of event while you were processing a previous notification. For example, you might get an
OnReceive notification while processing an OnReceive . In the code fragment above, extracting str from the
archive might lead to recursion. By switching states, CSocket prevents recursion by preventing additional
notifications. The general rule is no notifications within notifications.

NOTE
A CSocketFile can also be used as a (limited) file without a CArchive object. By default, the CSocketFile constructor's
bArchiveCompatible parameter is TRUE . This specifies that the file object is for use with an archive. To use the file object
without an archive, pass FALSE in the bArchiveCompatible parameter.

In its "archive compatible" mode, a CSocketFile object provides better performance and reduces the danger of a
"deadlock." A deadlock occurs when both the sending and receiving sockets are waiting on each other, or waiting
for a common resource. This situation might occur if the CArchive object worked with the CSocketFile the way it
does with a CFile object. With CFile , the archive can assume that if it receives fewer bytes than it requested, the
end of file has been reached. With CSocketFile , however, data is message based; the buffer can contain multiple
messages, so receiving fewer than the number of bytes requested does not imply end of file. The application does
not block in this case as it might with CFile , and it can continue reading messages from the buffer until the
buffer is empty. The IsBufferEmpty function in CArchive is useful for monitoring the state of the archive's buffer in
such a case.
For more information, see Windows Sockets: Using Sockets with Archives

See also
Windows Sockets in MFC
CObject::Serialize
Windows Sockets: Using Class CAsyncSocket
3/27/2020 • 3 minutes to read • Edit Online

This article explains how to use class CAsyncSocket. Be aware that this class encapsulates the Windows Sockets
API at a very low level. CAsyncSocket is for use by programmers who know network communications in detail
but want the convenience of callbacks for notification of network events. Based on this assumption, this article
provides only basic instruction. You should probably consider using CAsyncSocket if you want Windows Sockets'
ease of dealing with multiple network protocols in an MFC application but do not want to sacrifice flexibility. You
might also feel that you can get better efficiency by programming the communications more directly yourself
than you could using the more general alternative model of class CSocket .
CAsyncSocket is documented in the MFC Reference. Visual C++ also supplies the Windows Sockets specification,
located in the Windows SDK. The details are left to you. Visual C++ does not supply a sample application for
CAsyncSocket .

If you are not highly knowledgeable about network communications and want a simple solution, use class
CSocket with a CArchive object. See Windows Sockets: Using Sockets with Archives for more information.
This article covers:
Creating and using a CAsyncSocket object.
Your responsibilities with CAsyncSocket.

Creating and Using a CAsyncSocket Object


To use CAsyncSocket
1. Construct a CAsyncSocket object and use the object to create the underlying SOCKET handle.
Creation of a socket follows the MFC pattern of two-stage construction.
For example:

CAsyncSocket sock;
sock.Create(); // Use the default parameters

-or-

CAsyncSocket *pSocket = new CAsyncSocket;


int nPort = 27;
pSocket->Create(nPort, SOCK_DGRAM);

The first constructor above creates a CAsyncSocket object on the stack. The second constructor creates a
CAsyncSocket on the heap. The first Create call above uses the default parameters to create a stream
socket. The second Create call creates a datagram socket with a specified port and address. (You can use
either Create version with either construction method.)
The parameters to Create are:
A "port": a short integer.
For a server socket, you must specify a port. For a client socket, you typically accept the default
value for this parameter, which lets Windows Sockets select a port.
A socket type: SOCK_STREAM (the default) or SOCK_DGRAM .
A socket "address," such as "ftp.microsoft.com" or "128.56.22.8".
This is your Internet Protocol (IP) address on the network. You will probably always rely on the
default value for this parameter.
The terms "port" and "socket address" are explained in Windows Sockets: Ports and Socket Addresses.
2. If the socket is a client, connect the socket object to a server socket, using CAsyncSocket::Connect.
-or-
If the socket is a server, set the socket to begin listening (with CAsyncSocket::Listen) for connect attempts
from a client. Upon receiving a connection request, accept it with CAsyncSocket::Accept.
After accepting a connection, you can perform such tasks as validating passwords.

NOTE
The Accept member function takes a reference to a new, empty CSocket object as its parameter. You must
construct this object before you call Accept . If this socket object goes out of scope, the connection closes. Do not
call Create for this new socket object. For an example, see the article Windows Sockets: Sequence of Operations.

3. Carry out communications with other sockets by calling the CAsyncSocket object's member functions that
encapsulate the Windows Sockets API functions.
See the Windows Sockets specification and class CAsyncSocket in the MFC Reference.
4. Destroy the CAsyncSocket object.
If you created the socket object on the stack, its destructor is called when the containing function goes out
of scope. If you created the socket object on the heap, using the new operator, you are responsible for
using the delete operator to destroy the object.
The destructor calls the object's Close member function before destroying the object.
For an example of this sequence in code (actually for a CSocket object), see Windows Sockets: Sequence of
Operations.

Your Responsibilities with CAsyncSocket


When you create an object of class CAsyncSocket, the object encapsulates a Windows SOCKET handle and
supplies operations on that handle. When you use CAsyncSocket , you must deal with all the issues you might face
if using the API directly. For example:
"Blocking" scenarios.
Byte order differences between the sending and receiving machines.
Converting between Unicode and multibyte character set (MBCS) strings.
For definitions of these terms and additional information, see Windows Sockets: Blocking, Windows Sockets: Byte
Ordering, Windows Sockets: Converting Strings.
Despite these issues, class CAsycnSocket may be the right choice for you if your application requires all the
flexibility and control you can get. If not, you should consider using class CSocket instead. CSocket hides a lot of
detail from you: it pumps Windows messages during blocking calls and gives you access to CArchive , which
manages byte order differences and string conversion for you.
For more information, see:
Windows Sockets: Background
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
Windows Sockets: Deriving from Socket Classes
3/4/2019 • 2 minutes to read • Edit Online

This article describes some of the functionality you can gain by deriving your own class from one of the socket
classes.
You can derive your own socket classes from either CAsyncSocket or CSocket to add your own functionality. In
particular, these classes supply a number of virtual member functions that you can override. These functions
include OnReceive, OnSend, OnAccept, OnConnect, and OnClose. You can override the functions in your derived
socket class to take advantage of the notifications they provide when network events occur. The framework calls
these notification callback functions to notify you of important socket events, such as the receipt of data that you
can begin reading. For more information about notification functions, see Windows Sockets: Socket Notifications.
Additionally, class CSocket supplies the OnMessagePending member function (an advanced overridable). MFC
calls this function while the socket is pumping Windows-based messages. You can override OnMessagePending to
look for particular messages from Windows and respond to them.
The default version of OnMessagePending supplied in class CSocket examines the message queue for WM_PAINT
messages while waiting for a blocking call to complete. It dispatches paint messages to improve display quality.
Aside from doing something useful, this illustrates one way you might override the function yourself. As another
example, consider using OnMessagePending for the following task. Suppose you display a modeless dialog box
while waiting for a network transaction to complete. The dialog box contains a Cancel button that the user can use
to cancel blocking transactions that take too long. Your OnMessagePending override might pump messages related
to this modeless dialog box.
In your OnMessagePending override, return either TRUE or the return from a call to the base-class version of
OnMessagePending . Call the base-class version if it performs work that you still want done.

For more information, see:


Windows Sockets: Using Sockets with Archives
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Blocking
Windows Sockets: Byte Ordering
Windows Sockets: Converting Strings

See also
Windows Sockets in MFC
Windows Sockets: Socket Notifications
3/24/2020 • 2 minutes to read • Edit Online

This article describes the notification functions in the socket classes. These member functions are callback
functions that the framework calls to notify your socket object of important events. The notification functions are:
OnReceive: Notifies this socket that there is data in the buffer for it to retrieve by calling Receive.
OnSend: Notifies this socket that it can now send data by calling Send.
OnAccept: Notifies this listening socket that it can accept pending connection requests by calling Accept.
OnConnect: Notifies this connecting socket that its connection attempt completed: perhaps successfully or
perhaps in error.
OnClose: Notifies this socket that the socket it is connected to has closed.

NOTE
An additional notification function is OnOutOfBandData. This notification tells the receiving socket that the sending
socket has "out-of-band" data to send. Out-of-band data is a logically independent channel associated with each
pair of connected stream sockets. The out-of-band channel is typically used to send "urgent" data. MFC supports
out-of-band data. Advanced users working with class CAsyncSocket might need to use the out-of-band channel,
but users of class CSocket are discouraged from using it. The easier way is to create a second socket for passing
such data. For more information about out-of-band data, see the Windows Sockets specification, available in the
Windows SDK.

If you derive from class CAsyncSocket , you must override the notification functions for those network events of
interest to your application. If you derive a class from class CSocket , it is your choice whether to override the
notification functions of interest. You can also use CSocket itself, in which case the notification functions default
to doing nothing.
These functions are overridable callback functions. CAsyncSocket and CSocket convert messages to notifications,
but you must implement how the notification functions respond if you wish to use them. The notification
functions are called at the time your socket is notified of an event of interest, such as the presence of data to be
read.
MFC calls the notification functions to let you customize your socket's behavior at the time it is notified. For
example, you might call Receive from your OnReceive notification function, that is, on being notified that there is
data to read, you call Receive to read it. This approach is not necessary, but it is a valid scenario. As an
alternative, you might use your notification function to track progress, print TRACE messages, and so on.
You can take advantage of these notifications by overriding the notification functions in a derived socket class and
providing an implementation.
During an operation such as receiving or sending data, a CSocket object becomes synchronous. During the
synchronous state, any notifications meant for other sockets are queued while the current socket waits for the
notification it wants. (For example, during a Receive call, the socket wants a notification to read.) Once the socket
completes its synchronous operation and becomes asynchronous again, other sockets can begin receiving the
queued notifications.
NOTE
In CSocket , the OnConnect notification function is never called. For connections, you call Connect , which will return
when the connection is completed (either successfully or in error). How connection notifications are handled is an MFC
implementation detail.

For details about each notification function, see the function under class CAsyncSocket in the MFC Reference. For
source code and information about MFC samples, see MFC Samples.
For more information, see:
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Deriving from Socket Classes
Windows Sockets: How Sockets with Archives Work
Windows Sockets: Blocking
Windows Sockets: Byte Ordering
Windows Sockets: Converting Strings

See also
Windows Sockets in MFC
Windows Sockets: Blocking
3/27/2020 • 2 minutes to read • Edit Online

This article and two companion articles explain several issues in Windows Sockets programming. This article
covers blocking. The other issues are covered in the articles: Windows Sockets: Byte Ordering and Windows
Sockets: Converting Strings.
If you use or derive from class CAsyncSocket, you will need to manage these issues yourself. If you use or derive
from class CSocket, MFC manages them for you.

Blocking
A socket can be in "blocking mode" or "nonblocking mode." The functions of sockets in blocking (or synchronous)
mode do not return until they can complete their action. This is called blocking because the socket whose function
was called cannot do anything — is blocked — until the call returns. A call to the Receive member function, for
example, might take an arbitrarily long time to complete as it waits for the sending application to send (this is if
you are using CSocket , or using CAsyncSocket with blocking). If a CAsyncSocket object is in nonblocking mode
(operating asynchronously), the call returns immediately and the current error code, retrievable with the
GetLastError member function, is WSAEWOULDBLOCK , indicating that the call would have blocked had it not
returned immediately because of the mode. ( CSocket never returns WSAEWOULDBLOCK . The class manages
blocking for you.)
The behavior of sockets is different under 32-bit and 64-bit operating systems (such as Windows 95 or Windows
98) than under 16-bit operating systems (such as Windows 3.1). Unlike 16-bit operating systems, the 32-bit and
64-bit operating systems use preemptive multitasking and provide multithreading. Under the 32-bit and 64-bit
operating systems, you can put your sockets in separate worker threads. A socket in a thread can block without
interfering with other activities in your application and without spending compute time on the blocking. For
information on multithreaded programming, see the article Multithreading.

NOTE
In multithreaded applications, you can use the blocking nature of CSocket to simplify your program's design without
affecting the responsiveness of the user interface. By handling user interactions in the main thread and CSocket
processing in alternate threads, you can separate these logical operations. In an application that is not multithreaded, these
two activities must be combined and handled as a single thread, which usually means using CAsyncSocket so you can
handle communications requests on demand, or overriding CSocket::OnMessagePending to handle user actions during
lengthy synchronous activity.

The rest of this discussion is for programmers targeting 16-bit operating systems:
Normally, if you are using CAsyncSocket , you should avoid using blocking operations and operate asynchronously
instead. In asynchronous operations, from the point at which you receive a WSAEWOULDBLOCK error code
after calling Receive , for example, you wait until your OnReceive member function is called to notify you that you
can read again. Asynchronous calls are made by calling back your socket's appropriate callback notification
function, such as OnReceive.
Under Windows, blocking calls are considered bad practice. By default, CAsyncSocket supports asynchronous
calls, and you must manage the blocking yourself using callback notifications. Class CSocket, on the other hand, is
synchronous. It pumps Windows messages and manages blocking for you.
For more information about blocking, see the Windows Sockets specification. For more information about "On"
functions, see Windows Sockets: Socket Notifications and Windows Sockets: Deriving from Socket Classes.
For more information, see:
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Using Sockets with Archives
Windows Sockets: Background
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
CAsyncSocket::OnSend
Windows Sockets: Byte Ordering
3/27/2020 • 5 minutes to read • Edit Online

This article and two companion articles explain several issues in Windows Sockets programming. This article
covers byte ordering. The other issues are covered in the articles: Windows Sockets: Blocking and Windows
Sockets: Converting Strings.
If you use or derive from class CAsyncSocket, you will need to manage these issues yourself. If you use or derive
from class CSocket, MFC manages them for you.

Byte Ordering
Different machine architectures sometimes store data using different byte orders. For example, Intel-based
machines store data in the reverse order of Macintosh (Motorola) machines. The Intel byte order, called "little-
Endian," is also the reverse of the network standard "big-Endian" order. The following table explains these terms.
Big- and Little -Endian Byte Ordering
B Y T E O RDERIN G M EA N IN G

Big-Endian The most significant byte is on the left end of a word.

Little-Endian The most significant byte is on the right end of a word.

Typically, you do not have to worry about byte-order conversion for data that you send and receive over the
network, but there are situations in which you must convert byte orders.

When You Must Convert Byte Orders


You need to convert byte orders in the following situations:
You are passing information that needs to be interpreted by the network, as opposed to the data you are
sending to another machine. For example, you might pass ports and addresses, which the network must
understand.
The server application with which you are communicating is not an MFC application (and you do not have
source code for it). This calls for byte order conversions if the two machines do not share the same byte
ordering.

When You Do Not Have to Convert Byte Orders


You can avoid the work of converting byte orders in the following situations:
The machines on both ends can agree not to swap bytes, and both machines use the same byte order.
The server you are communicating with is an MFC application.
You have source code for the server you're communicating with, so you can tell explicitly whether you
must convert byte orders or not.
You can port the server to MFC. This is fairly easy to do, and the result is usually smaller, faster code.
Working with CAsyncSocket, you must manage any necessary byte-order conversions yourself. Windows
Sockets standardizes the "big-Endian" byte-order model and provides functions to convert between this order
and others. CArchive, however, which you use with CSocket, uses the opposite ("little-Endian") order, but
CArchive takes care of the details of byte-order conversions for you. By using this standard ordering in your
applications, or using Windows Sockets byte-order conversion functions, you can make your code more
portable.
The ideal case for using MFC sockets is when you are writing both ends of the communication: using MFC at
both ends. If you are writing an application that will communicate with non-MFC applications, such as an FTP
server, you will probably need to manage byte-swapping yourself before you pass data to the archive object,
using the Windows Sockets conversion routines ntohs , ntohl , htons , and htonl . An example of these functions
used in communicating with a non-MFC application appears later in this article.

NOTE
When the other end of the communication is not an MFC application, you also must avoid streaming C++ objects derived
from CObject into your archive because the receiver will not be able to handle them. See the note in Windows Sockets:
Using Sockets with Archives.

For more information about byte orders, see the Windows Sockets specification, available in the Windows SDK.

A Byte-Order Conversion Example


The following example shows a serialization function for a CSocket object that uses an archive. It also illustrates
using the byte-order conversion functions in the Windows Sockets API.
This example presents a scenario in which you are writing a client that communicates with a non-MFC server
application for which you have no access to the source code. In this scenario, you must assume that the non-MFC
server uses standard network byte order. In contrast, your MFC client application uses a CArchive object with a
CSocket object, and CArchive uses "little-Endian" byte order, the opposite of the network standard.

Suppose the non-MFC server with which you plan to communicate has an established protocol for a message
packet like the following:

struct Message
{
long MagicNumber;
unsigned short Command;
short Param1;
long Param2;
};

In MFC terms, this would be expressed as follows:

struct Message
{
long m_lMagicNumber;
short m_nCommand;
short m_nParam1;
long m_lParam2;

void Serialize(CArchive &ar);


};

In C++, a struct is essentially the same thing as a class. The Message structure can have member functions, such
as the Serialize member function declared above. The Serialize member function might look like this:
void Message::Serialize(CArchive &ar)
{
if (ar.IsStoring())
{
ar << (DWORD)htonl(m_lMagicNumber);
ar << (WORD)htons(m_nCommand);
ar << (WORD)htons(m_nParam1);
ar << (DWORD)htonl(m_lParam2);
}
else
{
WORD w;
DWORD dw;
ar >> dw;
m_lMagicNumber = ntohl((long)dw);
ar >> w;
m_nCommand = ntohs((short)w);
ar >> w;
m_nParam1 = ntohs((short)w);
ar >> dw;
m_lParam2 = ntohl((long)dw);
}
}

This example calls for byte-order conversions of data because there is a clear mismatch between the byte
ordering of the non-MFC server application on one end and the CArchive used in your MFC client application on
the other end. The example illustrates several of the byte-order conversion functions that Windows Sockets
supplies. The following table describes these functions.
Windows Sockets Byte -Order Conversion Functions
F UN C T IO N P URP O SE

ntohs Convert a 16-bit quantity from network byte order to host


byte order (big-Endian to little-Endian).

ntohl Convert a 32-bit quantity from network byte order to host


byte order (big-Endian to little-Endian).

Htons Convert a 16-bit quantity from host byte order to network


byte order (little-Endian to big-Endian).

Htonl Convert a 32-bit quantity from host byte order to network


byte order (little-Endian to big-Endian).

Another point of this example is that when the socket application on the other end of the communication is a
non-MFC application, you must avoid doing something like the following:
ar << pMsg;

where pMsg is a pointer to a C++ object derived from class CObject . This will send extra MFC information
associated with objects and the server will not understand it, as it would if it were an MFC application.
For more information, see:
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Background
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
Windows Sockets: Converting Strings
3/4/2019 • 2 minutes to read • Edit Online

This article and two companion articles explain several issues in Windows Sockets programming. This article
covers converting strings. The other issues are covered in Windows Sockets: Blocking and Windows Sockets: Byte
Ordering.
If you use or derive from class CAsyncSocket, you will need to manage these issues yourself. If you use or derive
from class CSocket, MFC manages them for you.

Converting Strings
If you communicate between applications that use strings stored in different wide-character formats, such as
Unicode or multibyte character sets (MBCS), or between one of these and an application using ANSI character
strings, you must manage the conversions yourself under CAsyncSocket . The CArchive object used with a
CSocket object manages this conversion for you through the capabilities of class CString. For more information,
see the Windows Sockets specification, located in the Windows SDK.
For more information, see:
Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Using Sockets with Archives
Windows Sockets: Background
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
Windows Sockets: Ports and Socket Addresses
3/27/2020 • 2 minutes to read • Edit Online

This article explains the terms "port" and "address" as used with Windows Sockets.

Port
A port identifies a unique process for which a service can be provided. In the present context, a port is associated
with an application that supports Windows Sockets. The idea is to identify each Windows Sockets application
uniquely so you can have more than one Windows Sockets application running on a machine at the same time.
Certain ports are reserved for common services, such as FTP. You should avoid using those ports unless you are
providing that kind of service. The Windows Sockets specification details these reserved ports. The file
WINSOCK.H also lists them.
To let the Windows Sockets DLL select a usable port for you, pass 0 as the port value. MFC selects a port value
greater than 1,024 decimal. You can retrieve the port value that MFC selected by calling the
CAsyncSocket::GetSockName member function.

Socket Address
Each socket object is associated with an Internet Protocol (IP) address on the network. Typically, the address is a
machine name, such as "ftp.microsoft.com", or a dotted number, such as "128.56.22.8".
When you seek to create a socket, you typically do not need to specify your own address.

NOTE
It is possible that your machine has multiple network cards (or your application might someday run on such a machine),
each representing a different network. If so, you might need to give an address to specify which network card the socket will
use. This is certain to be an advanced usage and a possible portability issue.

For more information, see:


Windows Sockets: Using Class CAsyncSocket
Windows Sockets: Using Sockets with Archives
Windows Sockets: How Sockets with Archives Work
Windows Sockets: Stream Sockets
Windows Sockets: Datagram Sockets

See also
Windows Sockets in MFC
Win32 Internet Extensions (WinInet)
3/4/2019 • 2 minutes to read • Edit Online

An Internet client application is a program that accesses information from a network data source (server)
using Internet protocols such as gopher, FTP, or HTTP. An Internet client application might access a server to
retrieve data such as weather maps, stock prices, or newspaper headlines, for example. The Internet client can
access the server through an external network (the Internet) or an internal network (sometimes called an
intranet).
MFC includes the Win32 Internet Extensions, or WinInet, for creating an Internet client application. MFC
encapsulates these Internet extensions in a set of standard, easy-to-use classes. You can write a WinInet client
application by calling the Win32 functions directly or by using the MFC WinInet classes.
The Microsoft Win32 Internet functions (WinInet) assist you in making the Internet an integral part of any
application. The new functions, contained in WININET.DLL, simplify accessing the Internet using HTTP
(Hypertext Transfer Protocol), FTP (File Transfer Protocol), and gopher.
The following topics discuss the process of creating an Internet client application:
How WinInet Makes It Easier to Create Internet Client Applications
How MFC Makes It Easier to Create Internet Client Applications
MFC Classes for Creating Internet Client Applications
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
The following topics provide steps for performing typical WinInet tasks:
Steps in a Typical Internet Client Application
Steps in a Typical FTP Client Application
Steps in a Typical FTP Client Application to Delete a File
Steps in a Typical Gopher Client Application
Steps in a Typical HTTP Client Application

See also
MFC Internet Programming Basics
WinInet Basics
How WinInet Makes It Easier to Create Internet
Client Applications
3/4/2019 • 2 minutes to read • Edit Online

The Win32 Internet Extensions, or WinInet, provide access to common Internet protocols, including gopher, FTP,
and HTTP. Using WinInet, you can write Internet client applications at a higher level of programming, without
having to deal with WinSock, TCP/IP, or the details of specific Internet protocols. WinInet provides a consistent set
of functions for all three protocols, with a familiar Win32 API interface. This consistency minimizes code changes
you need to make if the underlying protocol changes (for example, from FTP to HTTP).
Visual C++ provides two ways for you to use WinInet. You can call the Win32 Internet functions directly (see the
OLE documentation in the Windows SDK for more information) or you can use WinInet through the MFC WinInet
classes.
You can use WinInet to:
Download HTML pages.
HTTP is a protocol used to transfer HTML pages from a server to a client browser.
Send FTP requests to upload or download files or get directory listings.
A typical request is an anonymous logon to download a file.
Use gopher's menu system for accessing resources on the Internet.
Menu items can be several types, including other menus, an indexed database you can search, a newsgroup,
or a file.
For all three protocols, you establish a connection, make requests to the server, and close the connection.
The MFC WinInet classes make it easy to:
Read information from HTTP, FTP, and gopher servers as easily as reading files from a hard drive.
Use HTTP, FTP, and gopher protocols without programming directly to WinSock or TCP/IP.
Developers who use the Win32 Internet functions do not need to be familiar with TCP/IP or Windows
Sockets. You can still program at the socket level, using WinSock and TCP/IP protocols directly, but it's even
easier to use the MFC WinInet classes to access HTTP, FTP, and gopher protocols across the Internet. For
many common operations, developers do not need to know the details of the particular protocol they are
using.
Many operations that can be performed by your computer as a client to other computers on the Internet can take a
long time. The speed of these operations is usually limited by the speed of your network connection, but they can
also be affected by other network traffic and the complexity of the operation. Connecting to a remote FTP server,
for example, requires that your computer first look up the name of that server to find its address. Your application
will then attempt to connect to the server at that address. Once the connection is opened, your computer and the
remote server will initiate a conversation with the file transfer protocol before you can actually use the connection
to retrieve files.

See also
Win32 Internet Extensions (WinInet)
How MFC Makes It Easier to Create Internet Client Applications
How MFC Makes It Easier to Create Internet Client
Applications
3/4/2019 • 2 minutes to read • Edit Online

The Microsoft Foundation Classes encapsulate the Win32 Internet Extension (WinInet) functions in a manner that
provides a familiar context for MFC programmers. MFC provides three Internet file classes (CInternetFile,
CHttpFile, and CGopherFile) derived from the CStdioFile class. Not only do these classes make retrieving and
manipulating Internet data familiar to programmers who have used CStdioFile for local files, but with these
classes you can handle local files and Internet files in a consistent, transparent manner.
The MFC WinInet classes provide the same functionality as CStdioFile for data that is transferred across the
Internet. These classes abstract the Internet protocols for HTTP, FTP, and gopher into a high-level application
programming interface, providing a fast and straightforward path to making applications Internet-aware. For
example, connecting to an FTP server still requires several steps at a low level, but as an MFC developer, you only
need to make one call to CInternetSession::GetFTPConnection to create that connection.
In addition, the MFC WinInet classes provide the following advantages:
Buffered I/O
Type-safe handles for your data
Default parameters for many functions
Exception handling for common Internet errors
Automatic cleanup of open handles and connections

See also
Win32 Internet Extensions (WinInet)
How WinInet Makes It Easier to Create Internet Client Applications
MFC Classes for Creating Internet Client Applications
3/27/2020 • 2 minutes to read • Edit Online

MFC provides the following classes and global functions for writing Internet client applications. Indentation
indicates a class is derived from the unindented class above it. CGopherFile and CHttpFile derive from
CInternetFile , for example. These classes and global functions are declared in AFXINET.H, except CFileFind ,
which is declared in AFX.H.

Classes
CInternetSession
CInternetConnection
CFtpConnection
CGopherConnection
CHttpConnection
CInternetFile
CGopherFile
CHttpFile
CFileFind
CFtpFileFind
CGopherFileFind
CGopherLocator
CInternetException

Global Functions
AfxParseURL
AfxGetInternetHandleType
AfxThrowInternetException

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Prerequisites for Internet Client Classes
3/4/2019 • 2 minutes to read • Edit Online

Some actions taken by an Internet client (reading a file, for example) have prerequisite actions (in this case,
establishing an Internet connection). The following tables list the prerequisites for some client actions.
General Internet URL (FTP, Gopher, or HTTP)
A C T IO N P REREQ UISIT E

Establish a connection. Create a CInternetSession to establish the basis of an Internet


client application.

Open a URL. Establish a connection. Call CInternetSession::OpenURL. The


OpenURL function returns a read-only resource object.

Read URL data. Open the URL. Call CInternetFile::Read.

Set an Internet option. Establish a connection. Call CInternetSession::SetOption.

Set a function to be called with status information. Establish a connection. Call


CInternetSession::EnableStatusCallback. Override
CInternetSession::OnStatusCallback to handle calls.

FTP
A C T IO N P REREQ UISIT E

Establish an FTP connection. Create a CInternetSession as the basis of this Internet client
application. Call CInternetSession::GetFtpConnection to create
a CFtpConnection object.

Find the first resource. Establish an FTP connection. Create a CFtpFileFind object. Call
CFtpFileFind::FindFile.

Enumerate all available resources. Find the first file. Call CFtpFileFind::FindNextFile until it returns
FALSE.

Open an FTP file. Establish an FTP connection. Call CFtpConnection::OpenFile to


create and open a CInternetFile object.

Read an FTP file. Open an FTP file with read access. Call CInternetFile::Read.

Write to an FTP file. Open an FTP file with write access. Call CInternetFile::Write.

Change the client's directory on the server. Establish an FTP connection. Call
CFtpConnection::SetCurrentDirectory.

Retrieve the client's current directory on the server. Establish an FTP connection. Call
CFtpConnection::GetCurrentDirectory.

HTTP
A C T IO N P REREQ UISIT E

Establish an HTTP connection. Create a CInternetSession as the basis of this Internet client
application. Call CInternetSession::GetHttpConnection to
create a CHttpConnection object.

Open an HTTP file. Establish an HTTP connection. Call


CHttpConnection::OpenRequest to create a CHttpFile object.
Call CHttpFile::AddRequestHeaders. Call
CHttpFile::SendRequest.

Read an HTTP file. Open an HTTP file. Call CInternetFile::Read.

Get information about an HTTP request. Establish an HTTP connection. Call


CHttpConnection::OpenRequest to create a CHttpFile object.
Call CHttpFile::QueryInfo.

Gopher
A C T IO N P REREQ UISIT E

Establish a gopher connection. Create a CInternetSession as the basis of this Internet client
application. Call CInternetSession::GetGopherConnection to
create a CGopherConnection.

Find the first file in the current directory. Establish a gopher connection. Create a CGopherFileFind
object. Call CGopherConnection::CreateLocator to create a
CGopherLocator object. Pass the locator to
CGopherFileFind::FindFile. Call CGopherFileFind::GetLocator to
get the locator of a file if you need it later.

Enumerate all available files. Find the first file. Call CGopherFileFind::FindNextFile until it
returns FALSE.

Open a gopher file. Establish a gopher connection. Create a gopher locator with
CGopherConnection::CreateLocator or find a locator with
CGopherFileFind::GetLocator. Call
CGopherConnection::OpenFile.

Read a gopher file. Open a gopher file. Use CGopherFile.

See also
Win32 Internet Extensions (WinInet)
MFC Classes for Creating Internet Client Applications
Writing an Internet Client Application Using MFC WinInet Classes
Writing an Internet Client Application Using MFC
WinInet Classes
3/4/2019 • 2 minutes to read • Edit Online

The basis of every Internet client application is the Internet session. MFC implements Internet sessions as objects
of class CInternetSession. Using this class, you can create one Internet session or several simultaneous sessions.
To communicate with a server, you need a CInternetConnection object as well as a CInternetSession . You can
create a CInternetConnection by using CInternetSession::GetFtpConnection,
CInternetSession::GetHttpConnection, or CInternetSession::GetGopherConnection. Each of these calls is specific to
the protocol type. These calls do not open a file on the server for reading or writing. If you intend to read or write
data, you must open the file as a separate step.
For most Internet sessions, the CInternetSession object works hand-in-hand with a CInternetFile object:
For an Internet session, you must create an instance of CInternetSession.
If your Internet session reads or writes data, you must create an instance of CInternetFile (or its
subclasses, CHttpFile or CGopherFile). The easiest way to read data is to call CInternetSession::OpenURL.
This function parses a Universal Resource Locator (URL) supplied by you, opens a connection to the server
specified by the URL, and returns a read-only CInternetFile object. CInternetSession::OpenURL is not
specific to one protocol type — the same call works for any FTP, HTTP, or gopher URL.
CInternetSession::OpenURL even works with local files (returning a CStdioFile instead of a CInternetFile
).
If your Internet session does not read or write data, but performs other tasks, such as deleting a file in an
FTP directory, you may not need to create an instance of CInternetFile .
There are two ways to create a CInternetFile object:
If you use CInternetSession::OpenURL to establish your server connection, the call to OpenURL returns a
CStdioFile .
If use CInternetSession::GetFtpConnection , GetGopherConnection , or GetHttpConnection to establish your
server connection, you must call CFtpConnection::OpenFile , CGopherConnection::OpenFile , or
CHttpConnection::OpenRequest , respectively, to return a CInternetFile , CGopherFile , or CHttpFile ,
respectively.
The steps in implementing an Internet client application vary depending on whether you create a generic Internet
client based on OpenURL or a protocol-specific client using one of the GetConnection functions.

What do you want to know more about


How do I write an Internet client application that works generically with FTP, HTTP, and gopher
How do I write an FTP client application that opens a file
How do I write an FTP client application that does not open a file but performs a directory operation, such
as deleting a file
How do I write a gopher client application
How do I write an HTTP client application
See also
Win32 Internet Extensions (WinInet)
MFC Classes for Creating Internet Client Applications
Prerequisites for Internet Client Classes
Steps in a Typical Internet Client Application
3/4/2019 • 2 minutes to read • Edit Online

The following table shows the steps you might perform in a typical Internet client application.

Y O UR GO A L A C T IO N S Y O U TA K E EF F EC T S

Begin an Internet session. Create a CInternetSession object. Initializes WinInet and connects to
server.

Set an Internet query option (time-out Use CInternetSession::SetOption. Returns FALSE if operation was
limit or number of retries, for example). unsuccessful.

Establish a callback function to monitor Use Establishes a callback to


the status of the session. CInternetSession::EnableStatusCallback. CInternetSession::OnStatusCallback.
Override OnStatusCallback to create
your own callback routine.

Connect to an Internet server, intranet Use CInternetSession::OpenURL. Parses the URL and opens a connection
server, or local file. to the specified server. Returns a
CStdioFile (if you pass OpenURL a local
file name). This is the object through
which you access data retrieved from
the server or file.

Read from the file. Use CInternetFile::Read. Reads the specified number of bytes
using a buffer you supply.

Handle exceptions. Use the CInternetException class. Handles all common Internet exception
types.

End the Internet session. Dispose of the CInternetSession object. Automatically cleans up open file
handles and connections.

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Steps in a Typical FTP Client Application
3/4/2019 • 2 minutes to read • Edit Online

A typical FTP client application creates a CInternetSession and a CFtpConnection object. Note that these MFC
WinInet classes do not actually control the proxy type settings; IIS does.
The following table shows the steps you might perform in a typical FTP client application.

Y O UR GO A L A C T IO N S Y O U TA K E EF F EC T S

Begin an FTP session. Create a CInternetSession object. Initializes WinInet and connects to
server.

Connect to an FTP server. Use Returns a CFtpConnection object.


CInternetSession::GetFtpConnection.

Change to a new FTP directory on the Use Changes the directory you are currently
server. CFtpConnection::SetCurrentDirectory. connected to on the server.

Find the first file in the FTP directory. Use CFtpFileFind::FindFile. Finds the first file. Returns FALSE if no
files are found.

Find the next file in the FTP directory. Use CFtpFileFind::FindNextFile. Finds the next file. Returns FALSE if the
file is not found.

Open the file found by FindFile or Use CFtpConnection::OpenFile, using Opens the file on the server for reading
FindNextFile for reading or writing. the file name returned by FindFile or or writing. Returns a CInternetFile
FindNextFile. object.

Read from or write to the file. Use CInternetFile::Read or Reads or writes the specified number of
CInternetFile::Write. bytes, using a buffer you supply.

Handle exceptions. Use the CInternetException class. Handles all common Internet exception
types.

End the FTP session. Dispose of the CInternetSession object. Automatically cleans up open file
handles and connections.

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Steps in a Typical FTP Client Application to Delete a
File
3/4/2019 • 2 minutes to read • Edit Online

The following table shows the steps you might perform in a typical FTP client application that deletes a file.

Y O UR GO A L A C T IO N S Y O U TA K E EF F EC T S

Begin an FTP session. Create a CInternetSession object. Initializes WinInet and connects to
server.

Connect to an FTP server. Use Returns a CFtpConnection object.


CInternetSession::GetFtpConnection.

Check to make sure you're in the right Use Returns the name or URL of the
directory on the FTP server. CFtpConnection::GetCurrentDirectory directory you are currently connected
or to on the server, depending on the
CFtpConnection::GetCurrentDirectoryAs member function selected.
URL.

Change to a new FTP directory on the Use Changes the directory you are currently
server. CFtpConnection::SetCurrentDirectory. connected to on the server.

Find the first file in the FTP directory. Use CFtpFileFind::FindFile. Finds the first file. Returns FALSE if no
files are found.

Find the next file in the FTP directory. Use CFtpFileFind::FindNextFile. Finds the next file. Returns FALSE if the
file is not found.

Delete the file found by FindFile or Use CFtpConnection::Remove, using the Deletes the file on the server for
FindNextFile . file name returned by FindFile or reading or writing.
FindNextFile .

Handle exceptions. Use the CInternetException class. Handles all common Internet exception
types.

End the FTP session. Dispose of the CInternetSession object. Automatically cleans up open file
handles and connections.

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Steps in a Typical Gopher Client Application
3/4/2019 • 2 minutes to read • Edit Online

The following table shows the steps you might perform in a typical gopher client application.

Y O UR GO A L A C T IO N S Y O U TA K E EF F EC T S

Begin a gopher session. Create a CInternetSession object. Initializes WinInet and connects to
server.

Connect to a gopher server. Use Returns a CGopherConnection object.


CInternetSession::GetGopherConnectio
n.

Find the first resource in the gopher. Use CGopherFileFind::FindFile. Finds the first file. Returns FALSE if no
files are found.

Find the next resource in the gopher. Use CGopherFileFind::FindNextFile. Finds the next file. Returns FALSE if the
file is not found.

Open the file found by FindFile or Get a gopher locator using Opens the file specified by the locator.
FindNextFile for reading. CGopherFileFind::GetLocator. Use OpenFile returns a CGopherFile
CGopherConnection::OpenFile. object.

Open a file using a gopher locator you Create a gopher locator using Opens the file specified by the locator.
supply. CGopherConnection::CreateLocator. OpenFile returns a CGopherFile
Use CGopherConnection::OpenFile. object.

Read from the file. Use CGopherFile. Reads the specified number of bytes,
using a buffer you supply.

Handle exceptions. Use the CInternetException class. Handles all common Internet exception
types.

End the gopher session. Dispose of the CInternetSession object. Automatically cleans up open file
handles and connections.

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Steps in a Typical HTTP Client Application
3/4/2019 • 2 minutes to read • Edit Online

The following table shows the steps you might perform in a typical HTTP client application:

Y O UR GO A L A C T IO N S Y O U TA K E EF F EC T S

Begin an HTTP session. Create a CInternetSession object. Initializes WinInet and connects to
server.

Connect to an HTTP server. Use Returns a CHttpConnection object.


CInternetSession::GetHttpConnection.

Open an HTTP request. Use CHttpConnection::OpenRequest. Returns a CHttpFile object.

Send an HTTP request. Use CHttpFile::AddRequestHeaders and Finds the file. Returns FALSE if the file is
CHttpFile::SendRequest. not found.

Read from the file. Use CHttpFile. Reads the specified number of bytes
using a buffer you supply.

Handle exceptions. Use the CInternetException class. Handles all common Internet exception
types.

End the HTTP session. Dispose of the CInternetSession object. Automatically cleans up open file
handles and connections.

See also
Win32 Internet Extensions (WinInet)
Prerequisites for Internet Client Classes
Writing an Internet Client Application Using MFC WinInet Classes
Hierarchy Chart
5/14/2019 • 2 minutes to read • Edit Online

The following illustration represents the MFC classes derived


from CObject :

The following illustration represents the MFC classes derived


from CWnd and CCmdTarget :

The following illustration represents the MFC classes not


derived from CObject :
You can download the complete chart from the following
location: MFC Hierarchy Charts Download.

See also
Hierarchy Chart Categories
Class Overview
Hierarchy Chart Categories
5/14/2019 • 2 minutes to read • Edit Online

See also
Hierarchy Chart
MFC Desktop Applications
Customization for MFC
3/4/2019 • 2 minutes to read • Edit Online

This topic provides tips for customizing an MFC application.

General Customizations
You can save and load the state of your application to the registry. When you enable this option, your application
will load its initial state from the registry. If you change the initial docking layout for your application, you will have
to clear the registry data for your application. Otherwise, the data in the registry will override any changes that
you made to the initial layout.

Class-Specific Customizations
Additional customization tips can be found in the following topics:
CBasePane Class
CDockablePane Class
CDockingManager Class
CMFCBaseTabCtrl Class

Additional Customization Tips


Keyboard and Mouse Customization
User-defined Tools

See also
MFC Desktop Applications
Security Implications of Customization
Keyboard and Mouse Customization
3/4/2019 • 4 minutes to read • Edit Online

MFC allows the user of your application to customize how it handles keyboard and mouse input. The user can
customize keyboard input by assigning keyboard shortcuts to commands. The user can also customize the mouse
input by selecting the command that should be executed when the user double-clicks inside specific windows of
the application. This topic explains how to customize the input for your application.
In the Customization dialog box, the user can change the custom controls for the mouse and the keyboard. To
display this dialog box, the user points to Customize on the View menu and then clicks Toolbars and Docking .
In the dialog box, the user clicks either the Keyboard tab or the Mouse tab.

Keyboard Customization
The following illustration shows the Keyboard tab of the Customization dialog box.

Keyboard Customization Tab


The user interacts with the keyboard tab to assign one or more keyboard shortcuts to a command. The available
commands are listed on the left side of the tab. The user can select any available command from the menu. Only
menu commands can be associated with a keyboard shortcut. After the user enters a new shortcut, the Assign
button becomes enabled. When the user clicks this button, the application associates the selected command with
that shortcut.
All of the currently assigned keyboard shortcuts are listed in the list box in the right column. The user can also
select individual shortcuts and remove them, or reset all the mappings for the application.
If you want to support this customization in your application, you must create a CKeyboardManager object. To
create a CKeyboardManager object, call the function CWinAppEx::InitKeyboardManager. This method creates and
initializes a keyboard manager. If you create a keyboard manager manually, you still must call
CWinAppEx::InitKeyboardManager to initialize it.

If you use the Wizard to create your application, the Wizard will initialize the keyboard manager. After your
application initializes the keyboard manager, the framework adds a Keyboard tab to the Customization dialog
box.

Mouse Customization
The following illustration shows the Mouse tab of the Customization dialog box.
Mouse Customization Tab
The user interacts with this tab to assign a menu command to the mouse double-click action. The user selects a
view from the left side of the window and then uses the controls on the right side to associate a command with
the double-click action. After the user clicks Close , the application executes the associated command whenever
the user double-clicks anywhere in the view.
By default, mouse customization is not enabled when you create an application by using the Wizard.
To enable mouse customization
1. Initialize a CMouseManager object by calling CWinAppEx::InitMouseManager.
2. Obtain a pointer to the mouse manager by using CWinAppEx::GetMouseManager.
3. Add views to the mouse manager by using the CMouseManager::AddView method. Do this for every view
you want to add to the mouse manager.
After your application initializes the mouse manager, the framework adds the Mouse tab to the Customize dialog
box. If you do not add any views, accessing the tab will cause an unhandled exception. After you have created a list
of views, the Mouse tab is available to the user.
When you add a new view to the mouse manager, you give it a unique ID. If you want to support mouse
customization for a window, you must process the WM_LBUTTONDBLCLICK message and call the
CWinAppEx::OnViewDoubleClick function. When you call this function, one of the parameters is the ID for that
window. It is the responsibility of the programmer to keep track of the ID numbers and the objects associated with
them.

Security Concerns
As described in User-defined Tools, the user can associate a user-defined tool ID with the double-click event. When
the user double-clicks a view, the application looks for a user tool that matches the associated ID. If the application
finds a matching tool, it executes the tool. If the application cannot find a matching tool, it sends a
WM_COMMAND message with the ID to the view that was double-clicked.
The customized settings are stored in the registry. By editing the registry, an attacker can replace a valid user tool
ID with an arbitrary command. When the user double-clicks a view, the view processes the command that the
attacker planted. This could cause unexpected and potentially dangerous behavior.
In addition, this kind of attack can bypass user interface safeguards. For example, suppose an application has
printing disabled. That is, in its user interface, the Print menu and button are unavailable. Normally this prevents
the application from printing. But if an attacker edited the registry, a user could now could send the print
command directly by double-clicking the view, bypassing the user interface elements that are unavailable.
To guard against this kind of attack, add code to your application command handler to verify that a command is
valid before it is executed. Do not depend on the user interface to prevent a command from being sent to the
application.

See also
Customization for MFC
CKeyboardManager Class
CMouseManager Class
Security Implications of Customization
User-defined Tools
3/4/2019 • 3 minutes to read • Edit Online

MFC supports user-defined tools. A user-defined tool is a special command that executes an external, user-
specified program. You can use the customization process to manage user-defined tools. However, you cannot use
this process if your application object is not derived from CWinAppEx Class. For more information about
customization, see Customization for MFC.
If you enabled user-defined tools support, the customization dialog box automatically includes the Tools tab. The
following illustration shows the Tools page.

Customization dialog box Tools tab

Enabling user-defined tools support


To enable user-defined tools in an application, call CWinAppEx::EnableUserTools. However, you must first define
several constants in the resource files of your application to use as parameters for this call.
In the resource editor create a dummy command that uses an appropriate command ID. In the following example,
we use ID_TOOLS_ENTRY as the command ID. This command ID marks a location in one or more menus where the
framework will insert the user-defined tools.
You must set aside some consecutive IDs in the string table to represent the user-defined tools. The number of
strings that you set aside is equal to the maximum number of user tools that the users can define. In the following
example, these are named ID_USER_TOOL1 through ID_USER_TOOL10 .
You can offer suggestions to the users to help them select directories and arguments for the external programs
that will be called as tools. To do this, create two popup menus in the resource editor. In the following example
these are named IDR_MENU_ARGS and IDR_MENU_DIRS . For each command in these menus, define a string in your
application string table. The resource ID of the string must be equal to the command ID.
You can also create a derived class from CUserTool Class to replace the default implementation. To do this, pass the
runtime information for your derived class as the fourth parameter in CWinAppEx::EnableUserTools, instead of
RUNTIME_CLASS(CUserTool Class).
After you define the appropriate constants, call CWinAppEx::EnableUserTools to enable user-defined tools.
The following method call shows how to use these constants:
EnableUserTools(ID_TOOLS_ENTRY,
ID_USER_TOOL1,
ID_USER_TOOL10,
RUNTIME_CLASS(CUserTool),
IDR_MENU_ARGS,
IDR_MENU_DIRS);

In this example, the tools tab will be included on the Customization dialog box. The framework will replace any
command that matches the command ID ID_TOOLS_ENTRY in any menu with the set of currently defined user tools
whenever a user opens that menu. The command IDs ID_USER_TOOL1 through ID_USER_TOOL10 are reserved for use
for user-defined tools. The class CUserTool Class handles calls to the user tools. The tool tab of the Customization
dialog box provides buttons to the right of the argument and directory entry fields to access the menus
IDR_MENU_ARGS and IDR_MENU_DIRS .When a user selects a command from one of these menus, the
framework appends to the appropriate text box the string that has the resource ID equal to the command ID.
Including predefined tools
If you want to predefine some tools on the application startup, you must override the CFrameWnd::LoadFrame
method of the main window of your application. In that method, you must perform the following steps.
To a d d n e w t o o l s i n L o a d F r a m e

1. Obtain a pointer to the CUserToolsManager Class object by calling CWinAppEx::GetUserToolsManager.


2. For every tool that you want to create, call CUserToolsManager::CreateNewTool. This method returns a
pointer to a CUserTool Class object and adds the newly created user tool to the internal collection of tools. If
you provided the runtime information for a derived class of CUserTool Class as the fourth parameter of
CWinAppEx::EnableUserTools, CUserToolsManager::CreateNewTool will instantiate and return an instance of
that class instead.
3. For each tool, set its text label by setting CUserTool::m_strLabel and set its command by calling
CUserTool::SetCommand . The default implementation of CUserTool Class automatically retrieves available
icons from the program that is specified in the call to SetCommand .

See also
Customization for MFC
CUserTool Class
CUserToolsManager Class
CWinAppEx Class
Security Implications of Customization
3/4/2019 • 2 minutes to read • Edit Online

This topic discusses a potential security weakness in MFC.

Potential Security Weakness


MFC allows the user customize the look of an application user interface, for example, the appearance of buttons
and icons. MFC also supports user-defined tools, which let the user execute shell commands. A security
vulnerability arises because the customized settings of the application are saved in the user profile in the registry.
Anyone who can access the registry can edit those settings and change the application appearance or behavior. For
example, an administrator on the computer could impersonate a user by causing the user's application to execute
arbitrary programs (even from a network share).

Workarounds
We recommend any of these three ways to close the vulnerabilities in the registry:
Encrypt the data that is stored there
Store the data in a secure file instead of in the registry.
To accomplish either of these first two ways, derive a class from CSettingsStore Class and override its
methods to implement encryption or storage outside the registry.
You can also disable customizations in your application.

See also
Customization for MFC
MFC Technical Notes
5/14/2019 • 2 minutes to read • Edit Online

A technical note is a document written for programmers by programmers.


Each technical note describes a problem or feature that is beyond the scope of the rest of the MFC documentation.
The technical notes supplied reflect requests for information from users, as well as specialized information that the
MFC developers anticipate advanced users will want.
There are two ways to browse through the technical notes:
Technical Notes By Number
Technical Notes By Category

See also
MFC Desktop Applications
Technical Notes by Category
3/16/2020 • 2 minutes to read • Edit Online

Technical notes are divided into the following categories. For a numerical listing of the technical notes, see
Technical Notes by Number.
MFC and Windows

TN001: Window Class Registration

TN003: Mapping of Windows Handles to Objects

TN017: Destroying Window Objects

TN051: Using CTL3D Now and in the Future

MFC Architecture

TN002: Persistent Object Data Format

TN006: Message Maps

TN016: Using C++ Multiple Inheritance with MFC

TN021: Command and Message Routing

TN022: Standard Commands Implementation

TN025: Document, View, and Frame Creation

TN026: DDX and DDV Routines

TN029: Splitter Windows

TN030: Customizing Printing and Print Preview

TN031: Control Bars

TN032: MFC Exception Mechanism

TN037: Multithreaded MFC 2.1 Applications

TN044: MFC Support for DBCS

TN046: Commenting Conventions for the MFC Classes

TN058: MFC Module State Implementation


TN059: Using MFC MBCS/Unicode Conversion Macros

TN066: Common MFC 3.x to 4.0 Porting Issues

MFC Controls

TN014: Custom Controls

TN060: Windows Common Controls

TN061: ON_NOTIFY and WM_NOTIFY Messages

TN062: Message Reflection for Windows Controls

MFC Database

TN042: ODBC Driver Developer Recommendations

TN043: RFX Routines

TN045: MFC/Database Support for Long Varchar/Varbinary

TN047: Relaxing Database Transaction Requirements

TN048: Writing ODBC Setup and Administration Programs for MFC Database Applications

TN053: Custom DFX Routines for MFC DAO Classes

TN054: Calling DAO Directly While Using MFC DAO Classes

TN055: Migrating MFC ODBC Database Class Applications to MFC DAO Classes

TN068: Performing Transactions with the Microsoft Access 7 ODBC Driver

MFC DLLs

TN011: Using MFC as Part of a DLL

TN033: DLL Version of MFC

TN056: Installation of Localized MFC Components

TN057: Localization of MFC Components

MFC OLE
TN038: MFC/OLE IUnknown Implementation

TN039: MFC/OLE Automation Implementation

TN040: MFC/OLE In-Place Resizing and Zooming

TN041: MFC/OLE1 Migration to MFC/OLE2

TN049: MFC/OLE MBCS to Unicode Translation Layer (MFCANS32)

TN050: MFC/OLE Common Dialogs (MFCUIx32)

TN064: Apartment-Model Threading in OLE Controls

TN065: Dual-Interface Support for OLE Automation Servers

TN071: MFC IOleCommandTarget Implementation

MFC Resources

TN020: ID Naming and Numbering Conventions

TN023: Standard MFC Resources

TN024: MFC-Defined Messages and Resources

TN028: Context-Sensitive Help Support

TN035: Using Multiple Resource Files and Header Files with Visual C++

TN036: Using CFormView with AppWizard and ClassWizard

TN070: MFC Window Class Names

MFC Internet

TN063: Debugging Internet MFC extension DLLs


Technical Notes by Number
10/31/2018 • 2 minutes to read • Edit Online

The technical notes below are listed numerically, with the most recently written technical note first. For a
listing by category, see Technical Notes by Category.

N UM B ER T IT L E

71 MFC IOleCommandTarget Implementation

70 MFC Window Class Names

68 Performing Transactions with the Microsoft Access 7


ODBC Driver

66 Common MFC 3.x to 4.0 Porting Issues

65 Dual-Interface Support for OLE Automation Servers

64 Apartment-Model Threading in OLE Controls

63 Debugging Internet MFC extension DLLs

62 Message Reflection for Windows Controls

61 ON_NOTIFY and WM_NOTIFY Messages

60 Windows Common Controls

59 Using MFC MBCS/Unicode Conversion Macros

58 MFC Module State Implementation

57 Localization of MFC Components

56 Installation of Localized MFC Components

55 Migrating MFC ODBC Database Class Applications to


MFC DAO Classes

54 Calling DAO Directly While Using MFC DAO Classes

53 Writing Custom DFX Routines for DAO Database Classes

51 Using CTL3D Now and in the Future

50 MFC/OLE Common Dialogs (MFCUIx32)


N UM B ER T IT L E

49 MFC/OLE MBCS to Unicode Translation Layer


(MFCANS32)

48 Writing ODBC Setup and Administration Programs for


MFC Database Applications

47 Relaxing Database Transaction Requirements

46 Commenting Conventions for the MFC Classes

45 MFC/Database Support for Long Varchar/Varbinary

44 MFC Support for DBCS

43 RFX Routines

42 ODBC Driver Developer Recommendations

41 MFC/OLE1 Migration to MFC/OLE2

40 MFC/OLE In-Place Resizing and Zooming

39 MFC/OLE Automation Implementation

38 MFC/OLE IUnknown Implementation

37 Multithreaded MFC 2.1 Applications

36 Using CFormView with AppWizard and ClassWizard

35 Using Multiple Resource Files and Header Files with Visual


C++

33 DLL Version of MFC

32 MFC Exception Mechanism

31 Control Bars

30 Customizing Printing and Print Preview

29 Splitter Windows

28 Context-Sensitive Help Support

26 DDX and DDV Routines

25 Document, View, and Frame Creation

24 MFC-Defined Messages and Resources


N UM B ER T IT L E

23 Standard MFC Resources

22 Standard Commands Implementation

21 Command and Message Routing

20 ID Naming and Numbering Conventions

17 Destroying Window Objects

16 Using C++ Multiple Inheritance with MFC

14 Custom Controls

11 Using MFC as Part of a DLL

6 Message Maps

3 Mapping of Windows Handles to Objects

2 Persistent Object Data Format

1 Window Class Registration


TN001: Window Class Registration
8/15/2019 • 3 minutes to read • Edit Online

This note describes the MFC routines that register the special WNDCLASSes needed by Microsoft Windows.
Specific WNDCLASS attributes used by MFC and Windows are discussed.

The Problem
The attributes of a CWnd object, like an HWND handle in Windows, are stored in two places: the window object and
the WNDCLASS . The name of the WNDCLASS is passed to general window creation functions such as CWnd::Create
and CFrameWnd::Create in the lpszClassName parameter.
This WNDCLASS must be registered through one of four means:
Implicitly by using a MFC provided WNDCLASS .
Implicitly by subclassing a Windows control (or some other control).
Explicitly by calling the MFC AfxRegisterWndClass or AfxRegisterClass.
Explicitly by calling the Windows routine RegisterClass.

WNDCLASS Fields
The WNDCLASS structure consists of various fields that describe a window class. The following table shows the fields
and specifies how they are used in an MFC application:

F IEL D DESC RIP T IO N

lpfnWndProc window proc, must be an AfxWndProc

cbClsExtra not used (should be zero)

cbWndExtra not used (should be zero)

hInstance automatically filled with AfxGetInstanceHandle

hIcon icon for frame windows, see below

hCursor cursor for when mouse is over window, see below

hbrBackground background color, see below

lpszMenuName not used (should be NULL)

lpszClassName class name, see below

Provided WNDCLASSes
Earlier versions of MFC (before MFC 4.0), provided several predefined Window classes. These Window classes are
no longer provided by default. Applications should use AfxRegisterWndClass with the appropriate parameters.
If the application provides a resource with the specified resource ID (for example, AFX_IDI_STD_FRAME), MFC will
use that resource. Otherwise it will use the default resource. For the icon, the standard application icon is used, and
for the cursor, the standard arrow cursor is used.
Two icons support MDI applications with single document types: one icon for the main application, the other icon
for iconic document/MDIChild windows. For multiple document types with different icons, you must register
additional WNDCLASS es or use the CFrameWnd::LoadFrame function.
CFrameWnd::LoadFrame will register a WNDCLASS using the icon ID you specify as the first parameter and the
following standard attributes:
class style : CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
icon AFX_IDI_STD_FRAME
arrow cursor
COLOR_WINDOW background color
The values for background color and cursor for the CMDIFrameWnd are not used since the client area of the
CMDIFrameWnd is completely covered by the MDICLIENT window. Microsoft does not encourage subclassing the
MDICLIENT window so use the standard colors and cursor types when possible.

Subclassing and Superclassing Controls


If you subclass or superclass a Windows control (for example, CButton) then your class automatically gets the
WNDCLASS attributes provided in the Windows implementation of that control.

The AfxRegisterWndClass Function


MFC provides a helper function for registering a window class. Given a set of attributes (window class style, cursor,
background brush, and icon), a synthetic name is generated, and the resulting window class is registered. For
example,

const char* AfxRegisterWndClass(UINT nClassStyle,


HCURSOR hCursor,
HBRUSH hbrBackground,
HICON hIcon);

This function returns a temporary string of the generated registered window class name. For more information
about this function, see AfxRegisterWndClass.
The returned string is a temporary pointer to a static string buffer. It is valid until the next call to
AfxRegisterWndClass . If you want to keep this string around, store it in a CString variable, as in this example:

CString strWndClass = AfxRegisterWndClass(CS_DBLCLK, ...);

...
CWnd* pWnd = new CWnd;
pWnd->Create(strWndClass, ...);

...

AfxRegisterWndClass will throw a CResourceException if the window class failed to register (either because of bad
parameters, or out of Windows memory).
The RegisterClass and AfxRegisterClass Functions
If you want to do anything more sophisticated than what AfxRegisterWndClass provides, you can call the Windows
API RegisterClass or the MFC function AfxRegisterClass . The CWnd , CFrameWnd and CMDIChildWnd Create
functions take a lpszClassName string name for the window class as the first parameter. You can use any
registered window class name, regardless of the method you used to register it.
It is important to use AfxRegisterClass (or AfxRegisterWndClass ) in a DLL on Win32. Win32 does not
automatically unregister classes registered by a DLL, so you must explicitly unregister classes when the DLL is
terminated. By using AfxRegisterClass instead of RegisterClass this is handled automatically for you.
AfxRegisterClass maintains a list of unique classes registered by your DLL and will automatically unregister them
when the DLL terminates. When you use RegisterClass in a DLL, you must ensure that all classes are unregistered
when the DLL is terminated (in your DllMain function). Failure to do so might cause RegisterClass to fail
unexpectedly when another client application tries to use your DLL.

See also
Technical Notes by Number
Technical Notes by Category
TN002: Persistent Object Data Format
3/27/2020 • 7 minutes to read • Edit Online

This note describes the MFC routines that support persistent C++ objects and the format of the object data when
it is stored in a file. This applies only to classes with the DECLARE_SERIAL and IMPLEMENT_SERIAL macros.

The Problem
The MFC implementation for persistent data stores data for many objects in a single contiguous part of a file. The
object's Serialize method translates the object's data into a compact binary format.
The implementation guarantees that all data is saved in the same format by using the CArchive Class. It uses a
CArchive object as a translator. This object persists from the time it is created until you call CArchive::Close. This
method can be called either explicitly by the programmer or implicitly by the destructor when the program exits
the scope that contains the CArchive .
This note describes the implementation of the CArchive members CArchive::ReadObject and
CArchive::WriteObject. You will find the code for these functions in Arcobj.cpp, and the main implementation for
CArchive in Arccore.cpp. User code does not call ReadObject and WriteObject directly. Instead, these objects are
used by class-specific type-safe insertion and extraction operators that are generated automatically by the
DECLARE_SERIAL and IMPLEMENT_SERIAL macros. The following code shows how WriteObject and ReadObject
are implicitly called:

class CMyObject : public CObject


{
DECLARE_SERIAL(CMyObject)
};

IMPLEMENT_SERIAL(CMyObj, CObject, 1)

// example usage (ar is a CArchive&)


CMyObject* pObj;
CArchive& ar;
ar <<pObj; // calls ar.WriteObject(pObj)
ar>> pObj; // calls ar.ReadObject(RUNTIME_CLASS(CObj))

Saving Objects to the Store (CArchive::WriteObject)


The method CArchive::WriteObject writes header data that is used to reconstruct the object. This data consists of
two parts: the type of the object and the state of the object. This method is also responsible for maintaining the
identity of the object being written out, so that only a single copy is saved, regardless of the number of pointers to
that object (including circular pointers).
Saving (inserting) and restoring (extracting) objects relies on several "manifest constants." These are values that
are stored in binary and provide important information to the archive (note the "w" prefix indicates 16-bit
quantities):

TA G DESC RIP T IO N

wNullTag Used for NULL object pointers (0).


TA G DESC RIP T IO N

wNewClassTag Indicates class description that follows is new to this archive


context (-1).

wOldClassTag Indicates class of the object being read has been seen in this
context (0x8000).

When storing objects, the archive maintains a CMapPtrToPtr (the m_pStoreMap) which is a mapping from a stored
object to a 32-bit persistent identifier (PID). A PID is assigned to every unique object and every unique class name
that is saved in the context of the archive. These PIDs are handed out sequentially starting at 1. These PIDs have no
significance outside the scope of the archive and, in particular, are not to be confused with record numbers or
other identity items.
In the CArchive class, PIDs are 32-bit, but they are written out as 16-bit unless they are larger than 0x7FFE. Large
PIDs are written as 0x7FFF followed by the 32-bit PID. This maintains compatibility with projects that were created
in earlier versions.
When a request is made to save an object to an archive (usually by using the global insertion operator), a check is
made for a NULL CObject pointer. If the pointer is NULL, the wNullTag is inserted into the archive stream.
If the pointer is not NULL and can be serialized (the class is a DECLARE_SERIAL class), the code checks the
m_pStoreMap to see whether the object has been saved already. If it has, the code inserts the 32-bit PID associated
with that object into the archive stream.
If the object has not been saved before, there are two possibilities to consider: either both the object and the exact
type (that is, class) of the object are new to this archive context, or the object is of an exact type already seen. To
determine whether the type has been seen, the code queries the m_pStoreMap for a CRuntimeClass object that
matches the CRuntimeClass object associated with the object being saved. If there is a match, WriteObject inserts
a tag that is the bit-wise OR of wOldClassTag and this index. If the CRuntimeClass is new to this archive context,
WriteObject assigns a new PID to that class and inserts it into the archive, preceded by the wNewClassTag value.

The descriptor for this class is then inserted into the archive using the CRuntimeClass::Store method.
CRuntimeClass::Store inserts the schema number of the class (see below) and the ASCII text name of the class.
Note that the use of the ASCII text name does not guarantee uniqueness of the archive across applications.
Therefore, you should tag your data files to prevent corruption. Following the insertion of the class information,
the archive puts the object into the m_pStoreMap and then calls the Serialize method to insert class-specific
data. Placing the object into the m_pStoreMap before calling Serialize prevents multiple copies of the object
from being saved to the store.
When returning to the initial caller (usually the root of the network of objects), you must call CArchive::Close. If you
plan to perform other CFileoperations, you must call the CArchive method Flush to prevent corruption of the
archive.

NOTE
This implementation imposes a hard limit of 0x3FFFFFFE indices per archive context. This number represents the maximum
number of unique objects and classes that can be saved in a single archive, but a single disk file can have an unlimited
number of archive contexts.

Loading Objects from the Store (CArchive::ReadObject)


Loading (extracting) objects uses the CArchive::ReadObject method and is the converse of WriteObject . As with
WriteObject , ReadObject is not called directly by user code; user code should call the type-safe extraction
operator that calls ReadObject with the expected CRuntimeClass . This insures the type integrity of the extract
operation.
Since the WriteObject implementation assigned increasing PIDs, starting with 1 (0 is predefined as the NULL
object), the ReadObject implementation can use an array to maintain the state of the archive context. When a PID
is read from the store, if the PID is larger than the current upper bound of the m_pLoadArray, ReadObject knows
that a new object (or class description) follows.

Schema Numbers
The schema number, which is assigned to the class when the IMPLEMENT_SERIAL method of the class is
encountered, is the "version" of the class implementation. The schema refers to the implementation of the class,
not to the number of times a given object has been made persistent (usually referred to as the object version).
If you intend to maintain several different implementations of the same class over time, incrementing the schema
as you revise your object's Serialize method implementation will enable you to write code that can load objects
stored by using older versions of the implementation.
The CArchive::ReadObject method will throw a CArchiveException when it encounters a schema number in the
persistent store that differs from the schema number of the class description in memory. It is not easy to recover
from this exception.
You can use VERSIONABLE_SCHEMA combined with (bitwise OR ) your schema version to keep this exception from
being thrown. By using VERSIONABLE_SCHEMA , your code can take the appropriate action in its Serialize function
by checking the return value from CArchive::GetObjectSchema.

Calling Serialize Directly


In many cases the overhead of the general object archive scheme of WriteObject and ReadObject is not
necessary. This is the common case of serializing the data into a CDocument. In this case, the Serialize method
of the CDocument is called directly, not with the extract or insert operators. The contents of the document may in
turn use the more general object archive scheme.
Calling Serialize directly has the following advantages and disadvantages:
No extra bytes are added to the archive before or after the object is serialized. This not only makes the
saved data smaller, but allows you to implement Serialize routines that can handle any file formats.
The MFC is tuned so the WriteObject and ReadObject implementations and related collections will not be
linked into your application unless you need the more general object archive scheme for some other
purpose.
Your code does not have to recover from old schema numbers. This makes your document serialization
code responsible for encoding schema numbers, file format version numbers, or whatever identifying
numbers you use at the start of your data files.
Any object that is serialized with a direct call to Serialize must not use CArchive::GetObjectSchema or must
handle a return value of (UINT)-1 indicating that the version was unknown.
Because Serialize is called directly on your document, it is not usually possible for the sub-objects of the
document to archive references to their parent document. These objects must be given a pointer to their container
document explicitly or you must use CArchive::MapObject function to map the CDocument pointer to a PID before
these back pointers are archived.
As noted earlier, you should encode the version and class information yourself when you call Serialize directly,
enabling you to change the format later while still maintaining backward compatibility with older files. The
CArchive::SerializeClass function can be called explicitly before directly serializing an object or before calling a
base class.

See also
Technical Notes by Number
Technical Notes by Category
TN003: Mapping of Windows Handles to Objects
8/15/2019 • 2 minutes to read • Edit Online

This note describes the MFC routines that support mapping Windows object handles to C++ objects.

The Problem
Windows objects are typically represented by various HANDLE objects The MFC classes wrap Windows object
handles with C++ objects. The handle wrapping functions of the MFC class library let you find the C++ object that
is wrapping the Windows object that has a particular handle. However, sometimes an object does not have a C++
wrapper object and at these times the system creates a temporary object to act as the C++ wrapper.
The Windows objects that use handle maps are as follows:
HWND (CWnd and CWnd -derived classes)
HDC (CDC and CDC -derived classes)
HMENU (CMenu)
HPEN (CGdiObject)
HBRUSH ( CGdiObject )
HFONT ( CGdiObject )
HBITMAP ( CGdiObject )
HPALETTE ( CGdiObject )
HRGN ( CGdiObject )
HIMAGELIST (CImageList)
SOCKET (CSocket)
Given a handle to any one of these objects, you can find the MFC object that wraps the handle by calling the static
method FromHandle . For example, given an HWND called hWnd, the following line will return a pointer to the
CWnd that wraps hWnd:

CWnd::FromHandle(hWnd)

If hWnd does not have a specific wrapper object, a temporary CWnd is created to wrap hWnd. This makes it
possible to obtain a valid C++ object from any handle.
After you have a wrapper object, you can retrieve its handle from a public member variable of the wrapper class. In
the case of a CWnd , m_hWnd contains the HWND for that object.

Attaching Handles to MFC Objects


Given a newly created handle-wrapper object and a handle to a Windows object, you can associate the two by
calling the Attach function as in this example:
CWnd myWnd;
myWnd.Attach(hWnd);

This makes an entry in the permanent map associating myWnd and hWnd. Calling CWnd::FromHandle(hWnd) will
now return a pointer to myWnd. When myWnd is deleted, the destructor will automatically destroy hWnd by
calling the Windows DestroyWindow function. If this is not desired, hWnd must be detached from myWnd before
myWnd is destroyed (normally when leaving the scope at which myWnd was defined). The Detach method does
this.

myWnd.Detach();

More About Temporary Objects


Temporary objects are created whenever FromHandle is given a handle that does not already have a wrapper
object. These temporary objects are detached from their handle and deleted by the DeleteTempMap functions. By
default CWinThread::OnIdle automatically calls DeleteTempMap for each class that supports temporary handle
maps. This means that you cannot assume a pointer to a temporary object will be valid past the point of exit from
the function where the pointer was obtained.

Wrapper Objects and Multiple Threads


Both temporary and permanent objects are maintained on a per-thread basis. That is, one thread cannot access
another thread's C++ wrapper objects, regardless of whether it is temporary or permanent.
To pass these objects from one thread to another, always send them as their native HANDLE type. Passing a C++
wrapper object from one thread to another will often cause unexpected results.

See also
Technical Notes by Number
Technical Notes by Category
TN006: Message Maps
8/15/2019 • 6 minutes to read • Edit Online

This note describes the MFC message map facility.

The Problem
Microsoft Windows implements virtual functions in window classes that use its messaging facility. Due to the large
number of messages involved, providing a separate virtual function for each Windows message would create a
prohibitively large vtable.
Because the number of system-defined Windows messages changes over time, and because applications can
define their own Windows messages, message maps provide a level of indirection that prevents interface changes
from breaking existing code.

Overview
MFC provides an alternative to the switch statement that was used in traditional Windows-based programs to
handle messages sent to a window. A mapping from messages to methods can be defined so that when a message
is received by a window, the appropriate method is called automatically. This message-map facility is designed to
resemble virtual functions but has additional benefits not possible with C++ virtual functions.

Defining a Message Map


The DECLARE_MESSAGE_MAP macro declares three members for a class.
A private array of AFX_MSGMAP_ENTRY entries called _messageEntries.
A protected AFX_MSGMAP structure called messageMap that points to the _messageEntries array.
A protected virtual function called GetMessageMap that returns the address of messageMap.
This macro should be put in the declaration of any class using message maps. By convention, it is at the end of the
class declaration. For example:

class CMyWnd : public CMyParentWndClass


{
// my stuff...

protected:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

This is the format generated by AppWizard and ClassWizard when they create new classes. The //{{ and //}}
brackets are needed for ClassWizard.
The message map's table is defined by using a set of macros that expand to message map entries. A table starts
with a BEGIN_MESSAGE_MAP macro call, which defines the class that is handled by this message map and the
parent class to which unhandled messages are passed. The table ends with the END_MESSAGE_MAP macro call.
Between these two macro calls is an entry for each message to be handled by this message map. Every standard
Windows message has a macro of the form ON_WM_MESSAGE_NAME that generates an entry for that message.
A standard function signature has been defined for unpacking the parameters of each Windows message and
providing type safety. These signatures may be found in the file Afxwin.h in the declaration of CWnd. Each one is
marked with the keyword afx_msg for easy identification.

NOTE
ClassWizard requires that you use the afx_msg keyword in your message map handler declarations.

These function signatures were derived by using a simple convention. The name of the function always starts with
"On ". This is followed by the name of the Windows message with the "WM_" removed and the first letter of each
word capitalized. The ordering of the parameters is wParam followed by LOWORD (lParam) then HIWORD (lParam).
Unused parameters are not passed. Any handles that are wrapped by MFC classes are converted to pointers to the
appropriate MFC objects. The following example shows how to handle the WM_PAINT message and cause the
CMyWnd::OnPaint function to be called:

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

The message map table must be defined outside the scope of any function or class definition. It should not be put
in an extern "C" block.

NOTE
ClassWizard will modify the message map entries that occur between the //{{ and //}} comment bracket.

User Defined Windows Messages


User-defined messages may be included in a message map by using the ON_MESSAGE macro. This macro accepts
a message number and a method of the form:

// inside the class declaration


afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

#define WM_MYMESSAGE (WM_USER + 100)

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
ON_MESSAGE(WM_MYMESSAGE, OnMyMessage)
END_MESSAGE_MAP()

In this example, we establish a handler for a custom message that has a Windows message ID derived from the
standard WM_USER base for user-defined messages. The following example shows how to call this handler:

CWnd* pWnd = ...;


pWnd->SendMessage(WM_MYMESSAGE);

The range of user-defined messages that use this approach must be in the range WM_USER to 0x7fff.
NOTE
ClassWizard does not support entering ON_MESSAGE handler routines from the ClassWizard user interface. You must
manually enter them from the Visual C++ editor. ClassWizard will parse these entries and let you browse them just like any
other message-map entries.

Registered Windows Messages


The RegisterWindowMessage function is used to define a new window message that is guaranteed to be unique
throughout the system. The macro ON_REGISTERED_MESSAGE is used to handle these messages. This macro
accepts a name of a UINT NEAR variable that contains the registered windows message ID. For example

class CMyWnd : public CMyParentWndClass


{
public:
CMyWnd();

//{{AFX_MSG(CMyWnd)
afx_msg LRESULT OnFind(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

static UINT NEAR WM_FIND = RegisterWindowMessage("COMMDLG_FIND");

BEGIN_MESSAGE_MAP(CMyWnd, CMyParentWndClass)
//{{AFX_MSG_MAP(CMyWnd)
ON_REGISTERED_MESSAGE(WM_FIND, OnFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

The registered Windows message ID variable (WM_FIND in this example) must be a NEAR variable because of the
way ON_REGISTERED_MESSAGE is implemented.
The range of user-defined messages that use this approach will be in the range 0xC000 to 0xFFFF.

NOTE
ClassWizard does not support entering ON_REGISTERED_MESSAGE handler routines from the ClassWizard user interface.
You must manually enter them from the text editor. ClassWizard will parse these entries and let you browse them just like
any other message-map entries.

Command Messages
Command messages from menus and accelerators are handled in message maps with the ON_COMMAND macro.
This macro accepts a command ID and a method. Only the specific WM_COMMAND message that has a wParam
equal to the specified command ID is handled by the method specified in the message-map entry. Command
handler member functions take no parameters and return void . The macro has the following form:

ON_COMMAND(id, memberFxn)

Command update messages are routed through the same mechanism, but use the ON_UPDATE_COMMAND_UI
macro instead. Command update handler member functions take a single parameter, a pointer to a CCmdUI object,
and return void . The macro has the form
ON_UPDATE_COMMAND_UI(id, memberFxn)

Advanced users can use the ON_COMMAND_EX macro, which is an extended form of command message
handlers. The macro provides a superset of the ON_COMMAND functionality. Extended command-handler
member functions take a single parameter, a UINT that contains the command ID, and return a BOOL . The return
value should be TRUE to indicate that the command has been handled. Otherwise routing will continue to other
command target objects.
Examples of these forms:
Inside Resource.h (usually generated by Visual C++)

#define ID_MYCMD 100


#define ID_COMPLEX 101

Inside the class declaration

afx_msg void OnMyCommand();


afx_msg void OnUpdateMyCommand(CCmdUI* pCmdUI);
afx_msg BOOL OnComplexCommand(UINT nID);

Inside the message map definition

ON_COMMAND(ID_MYCMD, OnMyCommand)
ON_UPDATE_COMMAND_UI(ID_MYCMD, OnUpdateMyCommand)
ON_COMMAND_EX(ID_MYCMD, OnComplexCommand)

In the implementation file

void CMyClass::OnMyCommand()
{
// handle the command
}

void CMyClass::OnUpdateMyCommand(CCmdUI* pCmdUI)


{
// set the UI state with pCmdUI
}

BOOL CMyClass::OnComplexCommand(UINT nID)


{
// handle the command
return TRUE;
}

Advanced users can handle a range of commands by using a single command handler: ON_COMMAND_RANGE
or ON_COMMAND_RANGE_EX. See the product documentation for more information about these macros.

NOTE
ClassWizard supports creating ON_COMMAND and ON_UPDATE_COMMAND_UI handlers, but it does not support creating
ON_COMMAND_EX or ON_COMMAND_RANGE handlers. However, Class Wizard will parse and let you browse all four
command handler variants.
Control Notification Messages
Messages that are sent from child controls to a window have an extra bit of information in their message map
entry: the control's ID. The message handler specified in a message map entry is called only if the following
conditions are true:
The control notification code (high word of lParam), such as BN_CLICKED, matches the notification code
specified in the message-map entry.
The control ID (wParam) matches the control ID specified in the message-map entry.
Custom control notification messages may use the ON_CONTROL macro to define a message map entry with a
custom notification code. This macro has the form

ON_CONTROL(wNotificationCode, id, memberFxn)

For advanced usage ON_CONTROL_RANGE can be used to handle a specific control notification from a range of
controls with the same handler.

NOTE
ClassWizard does not support creating an ON_CONTROL or ON_CONTROL_RANGE handler in the user interface. You must
manually enter them with the text editor. ClassWizard will parse these entries and let you browse them just like any other
message map entries.

The Windows Common Controls use the more powerful WM_NOTIFY for complex control notifications. This
version of MFC has direct support for this new message by using the ON_NOTIFY and ON_NOTIFY_RANGE
macros. See the product documentation for more information about these macros.

See also
Technical Notes by Number
Technical Notes by Category
TN011: Using MFC as Part of a DLL
3/31/2020 • 5 minutes to read • Edit Online

This note describes regular MFC DLLs, which allow you to use the MFC library as part of a Windows dynamic-link
library (DLL). It assumes that you are familiar with Windows DLLs and how to build them. For information about
MFC extension DLLs, with which you can create extensions to the MFC library, see DLL Version of MFC.

DLL Interfaces
regular MFC DLLs assume interfaces between the application and the DLL are specified in C-like functions or
explicitly exported classes. MFC class interfaces cannot be exported.
If both a DLL and an application want to use MFC, both have a choice to either use the shared version of the MFC
libraries or to statically link to a copy of the libraries. The application and DLL may both use one of the standard
versions of the MFC library.
regular MFC DLLs have several advantages:
The application that uses the DLL does not have to use MFC and does not have to be a Visual C++
application.
With regular MFC DLLs that statically link to MFC, the size of the DLL depends only on the MFC and C
runtime routines that are used and linked.
With regular MFC DLLs that dynamically link to MFC, the savings in memory from using the shared version
of MFC can be significant. However, you must distribute the shared DLLs, Mfc<version>.dll and
Msvvcrt<version>.dll, with your DLL.
The DLL design is independent of how classes are implemented. Your DLL design exports only to the APIs
you want. As a result, if the implementation changes, regular MFC DLLs are still valid.
With regular MFC DLLs that statically link to MFC, if both DLL and application use MFC, there are no
problems with the application that wants a different version of MFC than the DLL or vice versa. Because the
MFC library is statically linked into each DLL or EXE, there is no question about which version you have.

API Limitations
Some MFC functionality does not apply to the DLL version, either because of technical limitations or because those
services are usually provided by the application. With the current version of MFC, the only function that is not
applicable is CWinApp::SetDialogBkColor .

Building Your DLL


When compiling regular MFC DLLs that statically link to MFC, the symbols _USRDLL and _WINDLL must be defined.
Your DLL code must also be compiled with the following compiler switches:
/D_WINDLL signifies the compilation is for a DLL
/D_USRDLL specifies you are building a regular MFC DLL
You must also define these symbols and use these compiler switches when you compile regular MFC DLLs that
dynamically link to MFC. Additionally, the symbol _AFXDLL must be defined and your DLL code must be compiled
with:
/D_AFXDLL specifies that you are building a regular MFC DLL that dynamically links to MFC
The interfaces (APIs) between the application and the DLL must be explicitly exported. We recommend that you
define your interfaces to be low bandwidth, and use only C interfaces if you can. Direct C interfaces are easier to
maintain than more complex C++ classes.
Place your APIs in a separate header that can be included by both C and C++ files. See the header ScreenCap.h in
the MFC Advanced Concepts sample DLLScreenCap for an example. To export your functions, enter them in the
EXPORTS section of your module definition file (.DEF) or include __declspec(dllexport) on your function
definitions. Use __declspec(dllimport) to import these functions into the client executable.
You must add the AFX_MANAGE_STATE macro at the beginning of all the exported functions in regular MFC DLLs
that dynamically link to MFC. This macro sets the current module state to the one for the DLL. To use this macro,
add the following line of code to the beginning of functions exported from the DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))

WinMain -> DllMain


The MFC library defines the standard Win32 DllMain entry point that initializes your CWinApp derived object as
in a typical MFC application. Place all DLL-specific initialization in the InitInstance method as in a typical MFC
application.
Note that the CWinApp::Run mechanism does not apply to a DLL, because the application owns the main message
pump. If your DLL displays modeless dialogs or has a main frame window of its own, your application's main
message pump must call a DLL-exported routine that calls CWinApp::PreTranslateMessage.
See the DLLScreenCap sample for use of this function.
The DllMain function that MFC provides will call the CWinApp::ExitInstance method of your class that is derived
from CWinApp before the DLL is unloaded.

Linking Your DLL


With regular MFC DLLs that statically link to MFC, you must link your DLL with Nafxcwd.lib or Nafxcw.lib and with
the version of the C runtimes named Libcmt.lib. These libraries are pre-built and may be installed by specifying
them when you run Visual C++ setup.

Sample Code
See the MFC Advanced Concepts sample program DLLScreenCap for a complete sample. Several interesting
things to note in this sample are as follows:
The compiler flags of the DLL and those of the application are different.
The link lines and .DEF files for the DLL and those for the application are different.
The application that uses the DLL does not have to be in C++.
The interface between the application and the DLL is an API that is usable by C or C++ and is exported with
DLLScreenCap.def.
The following example illustrates an API that is defined in a regular MFC DLL that statically links to MFC. In this
example, the declaration is enclosed in an extern "C" { } block for C++ users. This has several advantages. First,
it makes your DLL APIs usable by non-C++ client applications. Second, it reduces DLL overhead because C++
name mangling will not be applied to the exported name. Lastly, it makes it easier to explicitly add to a .DEF file
(for exporting by ordinal) without having to worry about name mangling.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

struct TracerData
{
BOOL bEnabled;
UINT flags;
};

BOOL PromptTraceFlags(TracerData FAR* lpData);

#ifdef __cplusplus
}
#endif

The structures used by the API are not derived from MFC classes and are defined in the API header. This reduces
the complexity of the interface between the DLL and the application and makes the DLL usable by C programs.

See also
Technical Notes by Number
Technical Notes by Category
TN014: Custom Controls
8/15/2019 • 5 minutes to read • Edit Online

This note describes the MFC Support for custom and self-drawing controls. It also describes dynamic subclassing,
and describes the relationship between CWnd objects and HWND s.
The MFC sample application CTRLTEST illustrates how to use many custom controls. See the source code for the
MFC General sample CTRLTEST and online help.

Owner-Draw Controls/Menus
Windows provides support for owner-draw controls and menus by using Windows messages. The parent window
of any control or menu receives these messages and calls functions in response. You can override these functions
to customize the visual appearance and behavior of your owner-draw control or menu.
MFC directly supports owner-draw with the following functions:
CWnd::OnDrawItem
CWnd::OnMeasureItem
CWnd::OnCompareItem
CWnd::OnDeleteItem
You can override these functions in your CWnd derived class to implement custom draw behavior.
This approach does not lead to reusable code. If you have two similar controls in two different CWnd classes, you
must implement the custom control behavior in two locations. The MFC-supported self-drawing control
architecture solves this problem.

Self-Draw Controls and Menus


MFC provides a default implementation (in the CWnd and CMenu classes) for the standard owner-draw messages.
This default implementation will decode the owner-draw parameters and delegate the owner-draw messages to
the controls or menu. This is called self-draw because the drawing code is in the class of the control or menu, not
in the owner window.
By using self-draw controls you can build reusable control classes that use owner-draw semantics to display the
control. The code for drawing the control is in the control class, not its parent. This is an object-oriented approach
to custom control programming. Add the following list of functions to your self-draw classes:
For self-draw buttons:

CButton:DrawItem(LPDRAWITEMSTRUCT);
// insert code to draw this button

For self-draw menus:

CMenu:MeasureItem(LPMEASUREITEMSTRUCT);
// insert code to measure the size of an item in this menu
CMenu:DrawItem(LPDRAWITEMSTRUCT);
// insert code to draw an item in this menu
For self-draw list boxes:

CListBox:MeasureItem(LPMEASUREITEMSTRUCT);
// insert code to measure the size of an item in this list box
CListBox:DrawItem(LPDRAWITEMSTRUCT);
// insert code to draw an item in this list box

CListBox:CompareItem(LPCOMPAREITEMSTRUCT);
// insert code to compare two items in this list box if LBS_SORT
CListBox:DeleteItem(LPDELETEITEMSTRUCT);
// insert code to delete an item from this list box

For self-draw combo boxes:

CComboBox:MeasureItem(LPMEASUREITEMSTRUCT);
// insert code to measure the size of an item in this combo box
CComboBox:DrawItem(LPDRAWITEMSTRUCT);
// insert code to draw an item in this combo box

CComboBox:CompareItem(LPCOMPAREITEMSTRUCT);
// insert code to compare two items in this combo box if CBS_SORT
CComboBox:DeleteItem(LPDELETEITEMSTRUCT);
// insert code to delete an item from this combo box

For details on the owner-draw structures (DRAWITEMSTRUCT, MEASUREITEMSTRUCT, COMPAREITEMSTRUCT,


and DELETEITEMSTRUCT) see the MFC documentation for CWnd::OnDrawItem , CWnd::OnMeasureItem ,
CWnd::OnCompareItem , and CWnd::OnDeleteItem respectively.

Using self-draw controls and menus


For self-draw menus, you must override both the OnMeasureItem and OnDrawItem methods.
For self-draw list boxes and combo boxes, you must override OnMeasureItem and OnDrawItem . You must specify the
LBS_OWNERDRAWVARIABLE style for list boxes or CBS_OWNERDRAWVARIABLE style for combo boxes in the
dialog template. The OWNERDRAWFIXED style will not work with self-draw items because the fixed item height is
determined before self-draw controls are attached to the list box. (You can use the methods
CListBox::SetItemHeight and CComboBox::SetItemHeight to overcome this limitation.)
Switching to an OWNERDRAWVARIABLE style will force the system to apply the NOINTEGRALHEIGHT style to the
control. Because the control cannot calculate an integral height with variable sized items, the default style of
INTEGRALHEIGHT is ignored and the control is always NOINTEGRALHEIGHT. If your items are fixed height, you can
prevent partial items from being drawn by specifying the control size to be an integer multiplier of the item size.
For self-drawing list boxes and combo boxes with the LBS_SORT or CBS_SORT style, you must override the
OnCompareItem method.

For self-drawing list boxes and combo boxes, OnDeleteItem is not usually overridden. You can override
OnDeleteItem if you want to perform any special processing. One case where this would be applicable is when
additional memory or other resources are stored with each list box or combo box item.

Examples of Self-Drawing Controls and Menus


The MFC General sample CTRLTEST provides samples of a self-draw menu and a self-draw list box.
The most typical example of a self-drawing button is a bitmap button. A bitmap button is a button that shows one,
two, or three bitmap images for the different states. An example of this is provided in the MFC class
CBitmapButton.
Dynamic Subclassing
Occasionally you will want to change the functionality of an object that already exists. The previous examples
required you to customize the controls before they were created. Dynamic subclassing enables you to customize a
control that has already been created.
Subclassing is the Windows term for replacing the WndProc of a window with a customized WndProc and calling
the old WndProc for default functionality.
This should not be confused with C++ class derivation. For clarification, the C++ terms base class and derived
class are analogous to superclass and subclass in the Windows object model. C++ derivation with MFC and
Windows subclassing are functionally similar, except C++ does not support dynamic subclassing.
The CWnd class provides the connection between a C++ object (derived from CWnd ) and a Windows window
object (known as an HWND ).
There are three common ways these are related:
CWnd creates the HWND . You can modify the behavior in a derived class by creating a class derived from
CWnd . The HWND is created when your application calls CWnd::Create.

The application attaches a CWnd to an existing HWND . The behavior of the existing window is not modified.
This is a case of delegation and is made possible by calling CWnd::Attach to alias an existing HWND to a
CWnd object.

CWnd is attached to an existing HWND and you can modify the behavior in a derived class. This is called
dynamic subclassing because we are changing the behavior, and therefore the class, of a Windows object at
run time.
You can achieve dynamic subclassing by using the methods CWnd::SubclassWindow andCWnd::SubclassDlgItem.
Both routines attach a CWnd object to an existing HWND . SubclassWindow takes the HWND directly. SubclassDlgItem
is a helper function that takes a control ID and the parent window. SubclassDlgItem is designed for attaching C++
objects to dialog controls created from a dialog template.
See the CTRLTEST example for several examples of when to use SubclassWindow and SubclassDlgItem .

See also
Technical Notes by Number
Technical Notes by Category
TN016: Using C++ Multiple Inheritance with MFC
10/31/2018 • 5 minutes to read • Edit Online

This note describes how to use multiple inheritance (MI) with the Microsoft Foundation Classes. The use of MI is
not required with MFC. MI is not used in any MFC classes and is not required to write a class library.
The following subtopics describe how MI affects the use of common MFC idioms as well as covering some of the
restrictions of MI. Some of these restrictions are general C++ restrictions. Others are imposed by the MFC
architecture.
At the end of this technical note you will find a complete MFC application that uses MI.

CRuntimeClass
The persistence and dynamic object creation mechanisms of MFC use the CRuntimeClass data structure to
uniquely identify classes. MFC associates one of these structures with each dynamic and/or serializable class in
your application. These structures are initialized when the application starts by using a special static object of type
AFX_CLASSINIT .

The current implementation of CRuntimeClass does not support MI runtime type information. This does not mean
you cannot use MI in your MFC application. However, you will have certain responsibilities when you work with
objects that have more than one base class.
The CObject::IsKindOf method will not correctly determine the type of an object if it has multiple base classes.
Therefore, you cannot use CObject as a virtual base class, and all calls to CObject member functions such as
CObject::Serialize and CObject::operator new must have scope qualifiers so that C++ can disambiguate the
appropriate function call. When a program uses MI within MFC, the class that contains the CObject base class
needs to be the left-most class in the list of base classes.
An alternative is to use the dynamic_cast operator. Casting an object with MI to one of its base classes will force
the compiler to use the functions in the supplied base class. For more information, see dynamic_cast Operator.

CObject - The Root of all Classes


All significant classes derive directly or indirectly from class CObject . CObject does not have any member data,
but it does have some default functionality. When you use MI, you will typically inherit from two or more CObject -
derived classes. The following example illustrates how a class can inherit from a CFrameWnd and a CObList:

class CListWnd : public CFrameWnd, public CObList


{
// ...
};
CListWnd myListWnd;

In this case CObject is included two times. This means that you need a way to disambiguate any reference to
CObject methods or operators. The operator new and operator delete are two operators that must be
disambiguated. As another example, the following code causes an error at compile time:

myListWnd.Dump(afxDump); // compile time error, CFrameWnd::Dump or CObList::Dump


Reimplementing CObject Methods
When you create a new class that has two or more CObject derived base classes, you should reimplement the
CObject methods that you want other people to use. Operators new and delete are mandatory and Dump is
recommended. The following example reimplements the new and delete operators and the Dump method:

class CListWnd : public CFrameWnd, public CObList


{
public:
void* operator new(size_t nSize)
{
return CFrameWnd:: operator new(nSize);
}
void operator delete(void* p)
{
CFrameWnd:: operator delete(p);
}
void Dump(CDumpContent& dc)
{
CFrameWnd::Dump(dc);
CObList::Dump(dc);
}
// ...
};

Virtual Inheritance of CObject


It might seem that virtually inheriting CObject would solve the problem of function ambiguity, but that is not the
case. Because there is no member data in CObject , you do not need virtual inheritance to prevent multiple copies
of a base class member data. In the first example that was shown earlier, the Dump virtual method is still
ambiguous because it is implemented differently in CFrameWnd and CObList . The best way to remove ambiguity is
to follow the recommendations presented in the previous section.

CObject::IsKindOf and Run-Time Typing


The run-time typing mechanism supported by MFC in CObject uses the macros DECLARE_DYNAMIC,
IMPLEMENT_DYNAMIC, DECLARE_DYNCREATE, IMPLEMENT_DYNCREATE, DECLARE_SERIAL and
IMPLEMENT_SERIAL. These macros can perform a run-time type check to guarantee safe downcasts.
These macros support only a single base class and will work in a limited way for multiply inherited classes. The
base class you specify in IMPLEMENT_DYNAMIC or IMPLEMENT_SERIAL should be the first (or left-most) base
class. This placement will enable you to do type checking for the left-most base class only. The run-time type
system will know nothing about additional base classes. In the following example, the run-time systems will do
type checking against CFrameWnd , but will know nothing about CObList .

class CListWnd : public CFrameWnd, public CObList


{
DECLARE_DYNAMIC(CListWnd)
// ...
};
IMPLEMENT_DYNAMIC(CListWnd, CFrameWnd)

CWnd and Message Maps


For the MFC message map system to work correctly, there are two additional requirements:
There must be only one CWnd -derived base class.
The CWnd -derived base class must be the first (or left-most) base class.

Here are some examples that will not work:

class CTwoWindows : public CFrameWnd, public CEdit


{ /* ... */ }; // error : two copies of CWnd

class CListEdit : public CObList, public CEdit


{ /* ... */ }; // error : CEdit (derived from CWnd) must be first

A Sample Program using MI


The following sample is a stand-alone application that consists of one class derived from CFrameWnd and CWinApp.
We do not recommend that you structure an application in this manner, but this is an example of the smallest MFC
application that has one class.
#include <afxwin.h>

class CHelloAppAndFrame : public CFrameWnd, public CWinApp


{
public:
CHelloAppAndFrame() {}

// Necessary because of MI disambiguity


void* operator new(size_t nSize)
{ return CFrameWnd::operator new(nSize); }
void operator delete(void* p)
{ CFrameWnd::operator delete(p); }

// Implementation
// CWinApp overrides
virtual BOOL InitInstance();
// CFrameWnd overrides
virtual void PostNcDestroy();
afx_msg void OnPaint();

DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CHelloAppAndFrame, CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()

// because the frame window is not allocated on the heap, we must


// override PostNCDestroy not to delete the frame object
void CHelloAppAndFrame::PostNcDestroy()
{
// do nothing (do not call base class)
}

void CHelloAppAndFrame::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(rect);

CString s = "Hello, Windows!";


dc.SetTextAlign(TA_BASELINE | TA_CENTER);
dc.SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
dc.SetBkMode(TRANSPARENT);
dc.TextOut(rect.right / 2, rect.bottom / 2, s);
}

// Application initialization
BOOL CHelloAppAndFrame::InitInstance()
{
// first create the main frame
if (!CFrameWnd::Create(NULL, "Multiple Inheritance Sample",
WS_OVERLAPPEDWINDOW, rectDefault))
return FALSE;

// the application object is also a frame window


m_pMainWnd = this;
ShowWindow(m_nCmdShow);
return TRUE;
}

CHelloAppAndFrame theHelloAppAndFrame;

See also
Technical Notes by Number
Technical Notes by Category
TN017: Destroying Window Objects
3/27/2020 • 4 minutes to read • Edit Online

This note describes the use of the CWnd::PostNcDestroy method. Use this method if you want to do customized
allocation of CWnd -derived objects. This note also explains why you should use CWnd::DestroyWindow to destroy
a C++ Windows object instead of the delete operator.
If you follow the guidelines in this topic, you will have few cleanup problems. These problems can result from
issues such as forgetting to delete/free C++ memory, forgetting to free system resources like HWND s, or freeing
objects too many times.

The Problem
Each windows object (object of a class derived from CWnd ) represents both a C++ object and an HWND . C++
objects are allocated in the application's heap and HWND s are allocated in system resources by the window
manager. Because there are several ways to destroy a window object, we must provide a set of rules that prevent
system resource or memory leaks. These rules must also prevent objects and Windows handles from being
destroyed more than one time.

Destroying Windows
The following are the two permitted ways to destroy a Windows object:
Calling CWnd::DestroyWindow or the Windows API DestroyWindow .
Explicitly deleting with the delete operator.
The first case is by far the most common. This case applies even if your code does not call DestroyWindow directly.
When the user directly closes a frame window, this action generates the WM_CLOSE message, and the default
response to this message is to call DestroyWindow. When a parent window is destroyed, Windows calls
DestroyWindow for all its children.

The second case, the use of the delete operator on Windows objects, should be rare. The following are some cases
where using delete is the correct choice.

Auto Cleanup with CWnd::PostNcDestroy


When the system destroys a Windows window, the last Windows message sent to the window is
WM_NCDESTROY. The default CWnd handler for that message is CWnd::OnNcDestroy. OnNcDestroy will detach the
HWND from the C++ object and call the virtual function PostNcDestroy . Some classes override this function to
delete the C++ object.
The default implementation of CWnd::PostNcDestroy does nothing, which is appropriate for window objects that
are allocated on the stack frame or embedded in other objects. This is not appropriate for window objects that are
designed to be allocated on the heap without any other objects. In other words, it is not appropriate for window
objects that are not embedded in other C++ objects.
Those classes that are designed to be allocated alone on the heap override the PostNcDestroy method to perform
a delete this . This statement will free any memory associated with the C++ object. Even though the default CWnd
destructor calls DestroyWindow if m_hWnd is non-NULL, this does not lead to infinite recursion because the handle
will be detached and NULL during the cleanup phase.
NOTE
The system usually calls CWnd::PostNcDestroy after it processes the Windows WM_NCDESTROY message and the HWND
and the C++ window object are no longer connected. The system will also call CWnd::PostNcDestroy in the
implementation of most CWnd::Create calls if failure occurs. The auto cleanup rules are described later in this topic.

Auto Cleanup Classes


The following classes are not designed for auto-cleanup. They are typically embedded in other C++ objects or on
the stack:
All standard Windows controls ( CStatic , CEdit , CListBox , and so on).
Any child windows derived directly from CWnd (for example, custom controls).
Splitter windows ( CSplitterWnd ).
Default control bars (classes derived from CControlBar , see Technical Note 31 for enabling auto-delete for
control bar objects).
Dialogs ( CDialog ) designed for modal dialogs on the stack frame.
All the standard dialogs except CFindReplaceDialog .
The default dialogs created by ClassWizard.
The following classes are designed for auto-cleanup. They are typically allocated by themselves on the heap:
Main frame windows (derived directly or indirectly from CFrameWnd ).
View windows (derived directly or indirectly from CView ).

If you want to break these rules, you must override the PostNcDestroy method in your derived class. To add auto-
cleanup to your class, call your base class and then do a delete this . To remove auto-cleanup from your class, call
CWnd::PostNcDestroy directly instead of the PostNcDestroy method of your direct base class.

The most common use of changing auto cleanup behavior is to create a modeless dialog that can be allocated on
the heap.

When to Call delete


We recommend that you call DestroyWindow to destroy a Windows object, either the C++ method or the global
DestroyWindow API.

Do not call the global DestroyWindow API to destroy a MDI Child window. You should use the virtual method
CWnd::DestroyWindow instead.
For C++ Window objects that do not perform auto-cleanup, using the delete operator can cause a memory leak
when you try to call DestroyWindow in the CWnd::~CWnd destructor if the VTBL does not point to the correctly
derived class. This occurs because the system cannot find the appropriate destroy method to call. Using
DestroyWindow instead of delete avoids these problems. Because this can be a subtle error, compiling in debug
mode will generate the following warning if you are at risk.

Warning: calling DestroyWindow in CWnd::~CWnd


OnDestroy or PostNcDestroy in derived class will not be called

In the case of C++ Windows objects that do perform auto-cleanup, you must call DestroyWindow . If you use the
delete operator directly, the MFC diagnostic memory allocator will notify you that you are freeing memory two
times. The two occurrences are your first explicit call and the indirect call to delete this in the auto-cleanup
implementation of PostNcDestroy .
After calling DestroyWindow on a non-auto-cleanup object, the C++ object will still be around, but m_hWnd will be
NULL. After calling DestroyWindow on an auto-cleanup object, the C++ object will be gone, freed by the C++ delete
operator in the auto-cleanup implementation of PostNcDestroy .

See also
Technical Notes by Number
Technical Notes by Category
TN020: ID Naming and Numbering Conventions
3/4/2019 • 3 minutes to read • Edit Online

This note describes the ID naming and numbering conventions that MFC 2.0 uses for resources, commands,
strings, controls, and child windows.
The MFC ID naming and numbering conventions are intended to meet the following requirements:
Provide a consistent ID-naming standard used across the MFC library and MFC applications that are
supported by the Visual C++ resource editor. This makes it easier for the programmer to interpret the type
and origin of a resource from its ID.
Emphasize the strong 1-to-1 relationship between certain types of IDs.
Conform to already widely used standards for naming IDs in Windows.
Partition the ID-numbering space. ID numbers can be assigned by the programmer, MFC, Windows, and
Visual C++-edited resources. Appropriate partitioning will help avoid duplication of ID numbers.

The ID Prefix Naming Convention


Several types of IDs can occur in an application. The MFC ID-naming convention defines different prefixes for
different resource types.
MFC uses the prefix "IDR_" to indicate a resource ID that applies to multiple resource types. For example, for a
given frame window, MFC uses the same "IDR_" prefix to indicate a menu, accelerator, string and icon resource.
The following table shows the various prefixes and their usage:

P REF IX USE

IDR_ For multiple resource types (primarily used for menus,


accelerators, and ribbons).

IDD_ For dialog template resources (for example, IDD_DIALOG1).

IDC_ For cursor resources.

IDI_ For icon resources.

IDB_ For bitmap resources.

IDS_ For string resources.

Within a DIALOG resource, MFC follows these conventions:

P REF IX O R L A B EL USE

IDOK, IDCANCEL For standard push button IDs.

IDC_ For other dialog controls.

The "IDC_" prefix is also used for cursors. This naming conflict is not usually a problem because a typical
application will have few cursors and many dialog controls.
Within a menu resource, MFC follows these conventions:

P REF IX USE

IDM_ For menu items that do not use the MFC command
architecture.

ID_ For menu commands that use the MFC command


architecture.

Commands that follow the MFC command architecture must have an ON_COMMAND command handler and can
have an ON_UPDATE_COMMAND_UI handler. If these command handlers follow the MFC command architecture,
they will function correctly whether they are bound to a menu command, a toolbar button, or a dialog bar button.
The same "ID_" prefix is also used for a menu prompt string that is displayed on the program's message bar. Most
of the menu items in your application should follow the MFC command conventions. All of the standard command
IDs (for example, ID_FILE_NEW) follow this convention.
MFC also uses "IDP_" as a specialized form of strings (instead of "IDS_"). Strings with the "IDP_" prefix are prompts,
that is, strings used in message boxes. "IDP_" strings can contain "%1" and "%2" as placeholders of strings
determined by the program. "IDP_" strings usually have help topics associated with them, and "IDS_" strings do
not. "IDP_" strings are always localized, and "IDS_" strings might not be localized.
The MFC library also uses the "IDW_" prefix as a specialized form of control IDs (instead of "IDC_"). These IDs are
assigned to child windows such as views and splitters by the framework classes. MFC implementation IDs are
prefixed with "AFX_".

The ID-Numbering Convention


The following table lists the valid ranges for the IDs of the specific types. Some of the limits are technical
implementation limits, and others are conventions that are designed to prevent your IDs from colliding with
Windows predefined IDs or MFC default implementations.
We strongly recommend that you define all IDs inside the recommended ranges. The lower limit of these ranges is
1 because 0 is not used. We recommend that you use the common convention and use 100 or 101 as the first ID.

P REF IX RESO URC E T Y P E VA L ID RA N GE

IDR_ multiple 1 through 0x6FFF

IDD_ dialog templates 1 through 0x6FFF

IDC_,IDI_,IDB_ cursors, icons, bitmaps 1 through 0x6FFF

IDS_, IDP_ general strings 1 through 0x7FFF

ID_ commands 0x8000 through 0xDFFF

IDC_ controls 8 through 0xDFFF

Reasons for these range limits:


By convention, the ID value of 0 is not used.
Windows implementation limitations restrict true resource IDs to be less than or equal to 0x7FFF.
MFC's internal framework reserves these ranges:
0x7000 through 0x7FFF (see afxres.h)
0xE000 through 0xEFFF (see afxres.h)
16000 through 18000 (see afxribbonres.h)
These ranges may change in future MFC implementations.
Several Windows system commands use the range of 0xF000 through 0xFFFF.
Control IDs of 1 through 7 are reserved for standard controls such as IDOK and IDCANCEL.
The range of 0x8000 through 0xFFFF for strings is reserved for menu prompts for commands.

See also
Technical Notes by Number
Technical Notes by Category
TN021: Command and Message Routing
3/27/2020 • 11 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the command routing and dispatch architecture as well as advanced topics in general window
message routing.
Please refer to Visual C++ for general details on the architectures described here, especially the distinction
between Windows messages, control notifications, and commands. This note assumes you are very familiar with
the issues described in the printed documentation and only addresses very advanced topics.

Command Routing and Dispatch MFC 1.0 Functionality Evolves to MFC


2.0 Architecture
Windows has the WM_COMMAND message that is overloaded to provide notifications of menu commands,
accelerator keys and dialog-control notifications.
MFC 1.0 built on that a little by allowing a command handler (for example, "OnFileNew") in a CWnd derived class
to get called in response to a specific WM_COMMAND. This is glued together with a data structure called the
message map, and results in a very space-efficient command mechanism.
MFC 1.0 also provided additional functionality for separating control notifications from command messages.
Commands are represented by a 16-bit ID, sometimes known as a Command ID. Commands normally start from a
CFrameWnd (that is, a menu select or a translated accelerator) and get routed to a variety of other windows.

MFC 1.0 used command routing in a limited sense for the implementation of Multiple Document Interface (MDI).
(An MDI frame window delegate commands to its active MDI Child window.)
This functionality has been generalized and extended in MFC 2.0 to allow commands to be handled by a wider
range of objects (not just window objects). It provides a more formal and extensible architecture for routing
messages and reuses the command target routing for not only handling of commands, but also for updating UI
objects (like menu items and toolbar buttons) to reflect the current availability of a command.

Command IDs
See Visual C++ for an explanation of the command routing and binding process. Technical Note 20 contains
information on ID naming.
We use the generic prefix "ID_" for command IDs. Command IDs are >= 0x8000. The message line or status bar
will show the command description string if there is a STRINGTABLE resource with the same IDs as the command
ID.
In the resources of your application, a command ID can appears in several places:
In one STRINGTABLE resource that has the same ID as the message-line prompt.
In possibly many MENU resources that are attached to menu items that invoke the same command.
(ADVANCED) in a dialog button for a GOSUB command.
In the source code of your application, a command ID can appears in several places:
In your RESOURCE.H (or other main symbol header file) to define application-specific command IDs.
PERHAPS In an ID array used to create a toolbar.
In an ON_COMMAND macro.
PERHAPS In an ON_UPDATE_COMMAND_UI macro.
Currently, the only implementation in MFC that requires command IDs be >= 0x8000 is the implementation of
GOSUB dialogs/commands.

GOSUB Commands, Using Command Architecture in Dialogs


The command architecture of routing and enabling commands works well with frame windows, menu items,
toolbar buttons, dialog bar buttons, other control bars and other user-interface elements designed to update on
demand and route commands or control IDs to a main command target (usually the main frame window). That
main command target may route the command or control notifications to other command target objects as
appropriate.
A dialog (modal or modeless) can benefit from some of the features of the command architecture if you assign the
control ID of the dialog control to the appropriate command ID. Support for dialogs is not automatic, so you may
have to write some additional code.
Note that for all these features to work properly, your command IDs should be >= 0x8000. Since many dialogs
could get routed to the same frame, shared commands should be >= 0x8000, while the nonshared IDCs in a
specific dialog should be <= 0x7FFF.
You can place a normal button in a normal modal dialog with the IDC of the button set to the appropriate
command ID. When the user selects the button, the owner of the dialog (usually the main frame window) gets the
command just like any other command. This is called a GOSUB command since it usually is used to bring up
another dialog (a GOSUB of the first dialog).
You can also call the function CWnd::UpdateDialogControls on your dialog and pass it the address of your main
frame window. This function will enable or disable your dialog controls based on whether they have command
handlers in the frame. This function is called automatically for you for control bars in your application's idle loop,
but you must call it directly for normal dialogs that you wish to have this feature.

When ON_UPDATE_COMMAND_UI is Called


Maintaining the enabled/checked state of all a program's menu items all the time can be a computationally
expensive problem. A common technique is to enable/check menu items only when the user selects the POPUP.
The MFC 2.0 implementation of CFrameWnd handles the WM_INITMENUPOPUP message and uses the command
routing architecture to determine the states of menus through ON_UPDATE_COMMAND_UI handlers.
CFrameWnd also handles the WM_ENTERIDLE message to describe the current menu item selected on the status
bar (also known as the message line).
An application's menu structure, edited by Visual C++, is used to represent the potential commands available at
WM_INITMENUPOPUP time. ON_UPDATE_COMMAND_UI handlers can modify the state or text of a menu, or for
advanced uses (like the File MRU list or the OLE Verbs pop-up menu), actually modify the menu structure before
the menu is drawn.
The same sort of ON_UPDATE_COMMAND_UI processing is done for toolbars (and other control bars) when the
application enters its idle loop. See the Class Library Reference and Technical Note 31 for more information on
control bars.

Nested Pop-up Menus


If you are using a nested menu structure, you will notice that the ON_UPDATE_COMMAND_UI handler for the first
menu item in the pop-up menu is called in two different cases.
First, it is called for the pop-up menu itself. This is necessary because pop-up menus do not have IDs and we use
the ID of the first menu item of the pop-up menu to refer to the entire pop-up menu. In this case, the
m_pSubMenu member variable of the CCmdUI object will be non-NULL and will point to the pop-up menu.
Second, it is called just before the menu items in the pop-up menu are to be drawn. In this case, the ID refers just
to the first menu item and the m_pSubMenu member variable of the CCmdUI object will be NULL.
This allows you to enable the pop-up menu distinct from its menu items, but requires that you write some menu
aware code. For example, in a nested menu with the following structure:

File>
New>
Sheet (ID_NEW_SHEET)
Chart (ID_NEW_CHART)

The ID_NEW_SHEET and ID_NEW_CHART commands can be independently enabled or disabled. The New pop-up
menu should be enabled if either of the two is enabled.
The command handler for ID_NEW_SHEET (the first command in the pop-up) would look something like:

void CMyApp::OnUpdateNewSheet(CCmdUI* pCmdUI)


{
if (pCmdUI->m_pSubMenu != NULL)
{
// enable entire pop-up for "New" sheet and chart
BOOL bEnable = m_bCanCreateSheet || m_bCanCreateChart;
// CCmdUI::Enable is a no-op for this case, so we
// must do what it would have done.
pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex,
MF_BYPOSITION |
(bEnable MF_ENABLED : (MF_DISABLED | MF_GRAYED)));

return;
}
// otherwise just the New Sheet command
pCmdUI->Enable(m_bCanCreateSheet);
}

The command handler for ID_NEW_CHART would be a normal update command handler and look something like:

void CMyApp::OnUpdateNewChart(CCmdUI* pCmdUI)


{
pCmdUI->Enable(m_bCanCreateChart);
}

ON_COMMAND and ON_BN_CLICKED


The message map macros for ON_COMMAND and ON_BN_CLICKED are the same. The MFC command and
control notification routing mechanism only uses the command ID to decide where to route to. Control
notifications with control notification code of zero (BN_CLICKED ) are interpreted as commands.
NOTE
In fact, all control notification messages go through the command handler chain. For example, it is technically possible for
you to write a control notification handler for EN_CHANGE in your document class. This is not generally advisable because
the practical applications of this feature are few, the feature is not supported by ClassWizard, and use of the feature can
result in fragile code.

Disabling the Automatic Disabling of Button Controls


If you place a button control on a dialog bar, or in a dialog using where you are calling
CWnd::UpdateDialogControls on your own, you will notice that buttons which do not have ON_COMMAND
or ON_UPDATE_COMMAND_UI handlers will be automatically disabled for you by the framework. In some
cases, you will not need to have a handler, but you will want the button to remain enabled. The easiest way to
achieve this is to add a dummy command handler (easy to do with ClassWizard) and do nothing in it.

Window Message Routing


The following describes some more advanced topics on the MFC classes and how Windows message routing and
other topics impact them. The information here is only described briefly. Refer to the Class Library Reference for
details about public APIs. Please refer to the MFC library source code for more information on implementation
details.
Please refer to Technical Note 17 for details on Window cleanup, a very important topic for all CWnd -derived
classes.

CWnd Issues
The implementation member function CWnd::OnChildNotify provides a powerful and extensible architecture
for child windows (also known as controls) to hook or otherwise be informed of messages, commands, and
control notifications that go to their parent (or "owner"). If the child window (/control) is a C++ CWnd object itself,
the virtual function OnChildNotify is called first with the parameters from the original message (that is, a MSG
structure). The child window can leave the message alone, eat it, or modify the message for the parent (rare).
The default CWnd implementation handles the following messages and uses the OnChildNotify hook to allow
child windows (controls) to first access at the message:
WM_MEASUREITEM and WM_DRAWITEM (for self-draw)
WM_COMPAREITEM and WM_DELETEITEM (for self-draw)
WM_HSCROLL and WM_VSCROLL
WM_CTLCOLOR
WM_PARENTNOTIFY
You will notice the OnChildNotify hook is used for changing owner-draw messages into self-draw messages.
In addition to the OnChildNotify hook, scroll messages have further routing behavior. Please see below for more
details on scroll bars and sources of WM_HSCROLL and WM_VSCROLL messages.

CFrameWnd Issues
The CFrameWnd class provides most of the command routing and user-interface updating implementation. This
is primarily used for the main frame window of the application (CWinApp::m_pMainWnd ) but applies to all
frame windows.
The main frame window is the window with the menu bar and is the parent of the status bar or message line.
Please refer to the above discussion on command routing and WM_INITMENUPOPUP.
The CFrameWnd class provides management of the active view. The following messages are routed through the
active view:
All command messages (the active view gets first access to them).
WM_HSCROLL and WM_VSCROLL messages from sibling scroll bars (see below).
WM_ACTIVATE (and WM_MDIACTIVATE for MDI) get turned into calls to the virtual function
CView::OnActivateView .

CMDIFrameWnd/CMDIChildWnd Issues
Both MDI frame window classes derive from CFrameWnd and therefore are both enabled for the same sort of
command routing and user-interface updating provided in CFrameWnd . In a typical MDI application, only the
main frame window (that is, the CMDIFrameWnd object) holds the menu bar and the status bar and therefore is
the main source of the command routing implementation.
The general routing scheme is that the active MDI child window gets first access to commands. The default
PreTranslateMessage functions handle accelerator tables for both MDI child windows (first) and the MDI frame
(second) as well as the standard MDI system-command accelerators normally handled by
TranslateMDISysAccel (last).

Scroll Bar Issues


When handling scroll-message (WM_HSCROLL /OnHScroll and/or WM_VSCROLL /OnVScroll ), you should try
to write the handler code so it does not rely on where the scroll bar message came from. This is not only a general
Windows issue, since scroll messages can come from true scroll bar controls or from
WS_HSCROLL /WS_VSCROLL scroll bars which are not scroll bar controls.
MFC extends that to allow for scroll bar controls to be either child or siblings of the window being scrolled (in fact,
the parent/child relationship between the scroll bar and window being scrolled can be anything). This is especially
important for shared scroll bars with splitter windows. Please refer to Technical Note 29 for details on the
implementation of CSplitterWnd including more information on shared scroll bar issues.
On a side note, there are two CWnd derived classes where the scroll bar styles specified at create time are trapped
and not passed to Windows. When passed to a creation routine, WS_HSCROLL and WS_VSCROLL can be
independently set, but after creation cannot be changed. Of course, you should not directly test or set the
WS_SCROLL style bits of the window that they created.
For CMDIFrameWnd the scroll bar styles you pass in to Create or LoadFrame are used to create the
MDICLIENT. If you wish to have a scrollable MDICLIENT area (like the Windows Program Manager) be sure to set
both scroll bar styles (WS_HSCROLL | WS_VSCROLL ) for the style used to create the CMDIFrameWnd .
For CSplitterWnd the scroll bar styles apply to the special shared scroll bars for the splitter regions. For static
splitter windows, you will normally not set either scroll bar style. For dynamic splitter windows, you will usually
have the scroll bar style set for the direction you will split, That is, WS_HSCROLL if you can split rows,
WS_VSCROLL if you can split columns.

See also
Technical Notes by Number
Technical Notes by Category
TN022: Standard Commands Implementation
3/27/2020 • 23 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the standard command implementations provided by MFC 2.0. Read Technical Note 21 first
because it describes the mechanisms used to implement many of the standard commands.
This description assumes knowledge of the MFC architectures, APIs, and common programming practice.
Documented as well as undocumented "implementation only" APIs are described. This is not a place to start
learning about the features of or how to program in MFC. Refer to Visual C++ for more general information and
for details of documented APIs.

The Problem
MFC defines many standard command IDs in the header file AFXRES.H. Framework support for these commands
varies. Understanding where and how the framework classes handle these commands will not only show you
how the framework works internally but will provide useful information on how to customize the standard
implementations and teach you a few techniques for implementing your own command handlers.

Contents of This Technical Note


Each command ID is described in two sections:
The title: the symbolic name of the command ID (for example, ID_FILE_SAVE) followed by the purpose of
the command (for example, "saves the current document") separated by a colon.
One or more paragraphs describing which classes implement the command, and what the default
implementation does
Most default command implementations are prewired in the framework's base class message map. There are
some command implementations that require explicit wiring in your derived class. These are described under
"Note". If you chose the right options in AppWizard, these default handlers will be connected for you in the
generated skeleton application.

Naming Convention
Standard commands follow a simple naming convention that we recommend you use if possible. Most standard
commands are located in standard places in an application's menu bar. The symbolic name of the command
starts with "ID_" followed by the standard pop-up menu name, followed by the menu item name. The symbolic
name is in upper case with underscore word-breaks. For commands that do not have standard menu item
names, a logical command name is defined starting with "ID_" (for example, ID_NEXT_PANE).
We use the prefix "ID_" to indicate commands that are designed to be bound to menu items, toolbar buttons, or
other command user-interface objects. Command handlers handling "ID_" commands should use the
ON_COMMAND and ON_UPDATE_COMMAND_UI mechanisms of the MFC command architecture.
We recommend you use the standard "IDM_" prefix for menu items which do not follow the command
architecture and need menu-specific code to enable and disable them. Of course the number of menu specific
commands should be small since following the MFC command architecture not only makes command handlers
more powerful (since they will work with toolbars) but makes the command handler code reusable.

ID Ranges
Please refer to Technical Note 20 for more details on the use of ID ranges in MFC.
MFC standard commands fall in the range 0xE000 to 0xEFFF. Please do not rely on the specific values of these IDs
since they are subject to change in future versions of the library.
Your application should define its commands in the range 0x8000 to 0xDFFF.

Standard Command IDs


For each command ID, there is a standard message line prompt string that can be found in the file PROMPTS.RC.
The string ID for that menu prompt must be the same as for the command ID.
ID_FILE_NEW Creates a new/empty document.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnFileNew implements this command differently depending on the number of document


templates in the application. If there is only one CDocTemplate , CWinApp::OnFileNew will create a new
document of that type, as well as the proper frame and view class.
If there is more than one CDocTemplate , CWinApp::OnFileNew will prompt the user with a dialog
(AFX_IDD_NEWTYPEDLG) letting them select which document type to use. The selected CDocTemplate is
used to create the document.
One common customization of ID_FILE_NEW is to provide a different and more graphical choice of
document types. In this case you can implement your own CMyApp::OnFileNew and place it in your
message map instead of CWinApp::OnFileNew . There is no need to call the base class implementation.
Another common customization of ID_FILE_NEW is to provide a separate command for creating a
document of each type. In this case you should define new command IDs, for example
ID_FILE_NEW_CHART and ID_FILE_NEW_SHEET.
ID_FILE_OPEN Opens an existing document.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnFileOpen has a very simple implementation of calling CWinApp::DoPromptFileName followed by


CWinApp::OpenDocumentFile with the file or path name of the file to open. The CWinApp implementation
routine DoPromptFileName brings up the standard FileOpen dialog and fills it with the file extensions
obtained from the current document templates.
One common customization of ID_FILE_OPEN is to customize the FileOpen dialog or add additional file
filters. The recommended way to customize this is to replace the default implementation with your own
FileOpen dialog, and call CWinApp::OpenDocumentFile with the document's file or path name. There is no
need to call the base class.
ID_FILE_CLOSE Closes the currently open document.
CDocument::OnFileClose calls CDocument::SaveModified to prompt the user to save the document if it has
been modified and then calls OnCloseDocument . All the closing logic, including destroying the document, is
done in the OnCloseDocument routine.

NOTE
ID_FILE_CLOSE acts differently from a WM_CLOSE message or an SC_CLOSE system command sent to the
documents frame window. Closing a window will close the document only if that is the last frame window showing
the document. Closing the document with ID_FILE_CLOSE will not only close the document but will close down all
frame windows showing the document.

ID_FILE_SAVE Saves the current document.


The implementation uses a helper routine CDocument::DoSave which is used for both OnFileSave and
OnFileSaveAs . If you save a document that has not been saved before (that is, it does not have a path
name, as in the case of FileNew) or that was read from a read-only document, the OnFileSave logic will
act like the ID_FILE_SAVE_AS command and ask the user to provide a new file name. The actual process of
opening the file and doing the saving is done through the virtual function OnSaveDocument .
There are two common reasons to customize ID_FILE_SAVE. For documents that do not save, simply
remove the ID_FILE_SAVE menu items and toolbar buttons from your user interface. Also make sure that
you never dirty your document (that is, never call CDocument::SetModifiedFlag ) and the framework will
never cause the document to be saved. For documents that save to someplace other than a disk file, define
a new command for that operation.
In the case of a COleServerDoc , ID_FILE_SAVE is used both for file save (for normal documents) and file
update (for embedded documents).
If your document data is stored in individual disk files, but you don't want to use the default CDocument
serialize implementation, you should override CDocument::OnSaveDocument instead of OnFileSave .
ID_FILE_SAVE_AS Saves the current document under a different file name.
The CDocument::OnFileSaveAs implementation uses the same CDocument::DoSave helper routine as
OnFileSave . The OnFileSaveAs command is handled just as ID_FILE_SAVE if the documents had no file
name before the save. COleServerDoc::OnFileSaveAs implements the logic to save a normal document data
file or to save a server document representing an OLE object embedded in some other application as a
separate file.
If you customize the logic of ID_FILE_SAVE, you will probably want to customize ID_FILE_SAVE_AS in a
similar fashion or the operation of "Save As" may not apply to your document. You can remove the menu
item from your menu bar if it is not needed.
ID_FILE_SAVE_COPY_AS Saves a copy current document under a new name.
The COleServerDoc::OnFileSaveCopyAs implementation is very similar to CDocument::OnFileSaveAs , except
that the document object is not "attached" to the underlying file after the save. That is, if the in-memory
document was "modified" before the save, it is still "modified". In addition, this command has no effect on
the path name or title stored in the document.
ID_FILE_UPDATE Notifies the container to save an embedded document.
The COleServerDoc::OnUpdateDocument implementation simply notifiies the container that the embedding
should be saved. The container then calls the appropriate OLE APIs in order to save the embedded object.
ID_FILE_PAGE_SETUP Invokes an application-specific page setup/layout dialog.
Currently there is no standard for this dialog, and the framework has no default implementation of this
command.
If you choose to implement this command, we recommend you use this command ID.
ID_FILE_PRINT_SETUP Invoke the standard Print Setup dialog.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

This command invokes the standard print setup dialog that allows the user to customize the printer and
print settings for at least this document or at most all the documents in this application. You must use the
Control Panel to change the default printer settings for the entire system.
CWinApp::OnFilePrintSetup has a very simple implementation creating a CPrintDialog object and calling
the CWinApp::DoPrintDialog implementation function. This sets the application default printer setup.
The common need for customizing this command is to allow for per-document printer settings, which
should be stored with the document when saved. To do this you should add a message-map handler in
your CDocument class that creates a CPrintDialog object, initializes it with the appropriate printer
attributes (usually hDevMode and hDevNames), call the CPrintDialog::DoModal , and save the changed
printer settings. For a robust implementation, you should look at the implementation of
CWinApp::DoPrintDialog for detecting errors and CWinApp::UpdatePrinterSelection for dealing with
sensible defaults and tracking system-wide printer changes.
ID_FILE_PRINT Standard printing of the current document

NOTE
You must connect this to your CView -derived class's message map to enable this functionality.

This command prints the current document, or more correctly, starts the printing process, which involves
invoking the standard print dialog and running the print engine.
CView::OnFilePrint implements this command and the main print loop. It calls the virtual
CView::OnPreparePrinting to prompt of the user with the print dialog. It then prepares the output DC to go
to the printer, brings up the printing progress dialog (AFX_IDD_PRINTDLG), and sends the StartDoc
escape to the printer. CView::OnFilePrint also contains the main page-oriented print loop. For each page,
it calls the virtual CView::OnPrepareDC followed by a StartPage escape and calling the virtual
CView::OnPrint for that page. When complete, the virtual CView::OnEndPrinting is called, and the printing
progress dialog is closed.
The MFC printing architecture is designed to hook in many different ways for printing and print preview.
You will normally find the various CView overridable functions adequate for any page-oriented printing
tasks. Only in the case of an application that uses the printer for non-page oriented output, should you
find the need to replace the ID_FILE_PRINT implementation.
ID_FILE_PRINT_PREVIEW Enter print-preview mode for the current document.
NOTE
You must connect this to your CView -derived class's message map to enable this functionality.

CView::OnFilePrintPreview starts the print preview mode by calling the documented helper function
CView::DoPrintPreview . CView::DoPrintPreview is the main engine for the print preview loop, just as
OnFilePrint is the main engine for the printing loop.

The print preview operation can be customized in a variety of ways by passing different parameters to
DoPrintPreview . Please refer to Technical Note 30, which discusses some of the details of print preview
and how to customize it.
ID_FILE_MRU_FILE1...FILE16 A range of command IDs for the File MRU list .
is a update command UI handler that is one of the more advanced uses
CWinApp::OnUpdateRecentFileMenu
of the ON_UPDATE_COMMAND_UI mechanism. In your menu resource, you need only define a single
menu item with ID ID_FILE_MRU_FILE1. That menu item remains initially disabled.
As the MRU list grows, more menu items are added to the list. The standard CWinApp implementation
defaults to the standard limit of the four most recently used files. You can change the default by calling
CWinApp::LoadStdProfileSettings with a larger or smaller value. The MRU list is stored in the application's
.INI file. The list is loaded in your application's InitInstance function if you call LoadStdProfileSettings ,
and is saved when your application exits. The MRU update command UI handler also will convert absolute
paths to relative paths for display on the file menu.
CWinApp::OnOpenRecentFile is the ON_COMMAND handler that performs the actual command. It simply
gets the file name from the MRU list and calls CWinApp::OpenDocumentFile , which does all the work of
opening the file and updating the MRU list.
Customization of this command handler is not recommended.
ID_EDIT_CLEAR Clears the current selection
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command using CEdit::Clear . The command is disabled if
there is no current selection.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_CLEAR_ALL Clears the entire document.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

If you choose to implement this command, we recommend you use this command ID. See the MFC Tutorial
sample SCRIBBLE for an example implementation.
ID_EDIT_COPY Copies the current selection to the Clipboard.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, which copies the currently selected text to the
Clipboard as CF_TEXT using CEdit::Copy . The command is disabled if there is no current selection.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_CUT Cuts the current selection to the Clipboard.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, which cuts the currently selected text to the
Clipboard as CF_TEXT using CEdit::Cut . The command is disabled if there is no current selection.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_FIND Begins the find operation, brings up the modeless find dialog.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, which calls the implementation helper function
OnEditFindReplace to use and store the previous find/replace settings in private implementation variables.
The CFindReplaceDialog class is used to manage the modeless dialog for prompting the user.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_PASTE Inserts the current Clipboard contents.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, which copies the current Clipboard data
replacing the selected text using CEdit::Paste . The command is disabled if there is no CF_TEXT in the
Clipboard.
COleClientDoc just provides a update command UI handler for this command. If the Clipboard does not
contain an embeddable OLE item/object, the command will be disabled. You are responsible for writing
the handler for the actual command to do the actual pasting. If your OLE application can also paste other
formats, you should provide your own update command UI handler in your view or document (that is,
somewhere before COleClientDoc in the command target routing).
If you choose to implement this command, we recommend you use this command ID.
For replacing the standard OLE implementation, use COleClientItem::CanPaste .
ID_EDIT_PASTE_LINK Inserts a link from the current Clipboard contents.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

COleDocument just provides a update command UI handler for this command. If the Clipboard does not
contain linkable OLE item/object, the command will be disabled. You are responsible for writing the
handler for the actual command to do the actual pasting. If your OLE application can also paste other
formats, you should provide your own update command UI handler in your view or document (that is,
somewhere before COleDocument in the command target routing).
If you choose to implement this command, we recommend you use this command ID.
For replacing the standard OLE implementation, use COleClientItem::CanPasteLink .
ID_EDIT_PASTE_SPECIAL Inserts the current Clipboard contents with options.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class. MFC does not provide this dialog.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_REPEAT Repeats the last operation.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command to repeat the last find operation. The private
implementation variables for the last find are used. The command is disabled if a find cannot be
attempted.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_REPLACE Begins the replace operation, brings up the modeless replace dialog.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, which calls the implementation helper function
OnEditFindReplace to use and store the previous find/replace settings in private implementation variables.
The CFindReplaceDialog class is used to manage the modeless dialog that prompts the user.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_SELECT_ALL Selects the entire document.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditViewprovides an implementation of this command, which selects all the text in the document. The
command is disabled if there is no text to select.
If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_UNDO Undoes the last operation.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

CEditView provides an implementation of this command, using CEdit::Undo . The command is disabled if
CEdit::CanUndo returns FALSE.

If you choose to implement this command, we recommend you use this command ID.
ID_EDIT_REDO Redoes the last operation.
Currently there is no standard implementation for this command. You must implement this for each
CView -derived class.

If you choose to implement this command, we recommend you use this command ID.
ID_WINDOW_NEW Opens another window on the active document.
CMDIFrameWnd::OnWindowNew implements this powerful feature by using the document template of the
current document to create another frame containing another view of the current document.
Like most multiple document interface (MDI) Window menu commands, the command is disabled if there
is no active MDI child window.
Customization of this command handler is not recommended. If you wish to provide a command that
creates additional views or frame windows, you will probably be better off inventing your own command.
You can clone the code from CMDIFrameWnd::OnWindowNew and modify it to the specific frame and view
classes of your liking.
ID_WINDOW_ARRANGE Arranges icons at the bottom of an MDI window.
CMDIFrameWnd implements this standard MDI command in an implementation helper function
OnMDIWindowCmd . This helper maps command IDs to MDI Windows messages and can therefore share a lot
of code.
Like most MDI Window menu commands, the command is disabled if there is no active MDI child window.
Customization of this command handler is not recommended.
ID_WINDOW_CASCADE Cascades windows so they overlap.
CMDIFrameWnd implements this standard MDI command in an implementation helper function
OnMDIWindowCmd . This helper maps command IDs to MDI Windows messages and can therefore share a lot
of code.
Like most MDI Window menu commands, the command is disabled if there is no active MDI child window.
Customization of this command handler is not recommended.
ID_WINDOW_TILE_HORZ Tiles windows horizontally.
This command is implemented in CMDIFrameWnd just like ID_WINDOW_CASCADE, except a different MDI
Windows message is used for the operation.
You should pick the default tile orientation for your application. You can do this by changing the ID for the
Window "Tile" menu item to either ID_WINDOW_TILE_HORZ or ID_WINDOW_TILE_VERT.
ID_WINDOW_TILE_VERT Tiles windows vertically.
This command is implemented in CMDIFrameWnd just like ID_WINDOW_CASCADE, except a different MDI
Windows message is used for the operation.
You should pick the default tile orientation for your application. You can do this by changing the ID for the
Window "Tile" menu item to either ID_WINDOW_TILE_HORZ or ID_WINDOW_TILE_VERT.
ID_WINDOW_SPLIT Keyboard interface to splitter.
CView handles this command for the CSplitterWnd implementation. If the view is part of a splitter
window, this command will delegate to the implementation function CSplitterWnd::DoKeyboardSplit . This
will place the splitter in a mode that will allow keyboard users to split or unsplit a splitter window.
This command is disabled if the view is not in a splitter.
Customization of this command handler is not recommended.
ID_APP_ABOUT Invokes the About dialog box.
There is no standard implementation for an application's About box. The default AppWizard-created
application will create a custom dialog class for your application and use it as your About box. AppWizard
will also write the trivial command handler which handles this command and invokes the dialog.
You will almost always implement this command.
ID_APP_EXIT Exit the application.
CWinApp::OnAppExit handles this command by sending a WM_CLOSE message to the application's main
window. The standard shutting down of the application (prompting for dirty files and so on) is handled by
the CFrameWnd implementation.
Customization of this command handler is not recommended. Overriding CWinApp::SaveAllModified or
the CFrameWnd closing logic is recommended.
If you choose to implement this command, we recommend you use this command ID.
ID_HELP_INDEX Lists Help topics from .HLP file.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnHelpIndex handles this command by trivially calling CWinApp::WinHelp .


Customization of this command handler is not recommended.
ID_HELP_USING Displays help on how to use Help.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnHelpUsing handles this command by trivially calling CWinApp::WinHelp .


Customization of this command handler is not recommended.
ID_CONTEXT_HELP Enters SHIFT-F1 help mode.

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnContextHelp handles this command by setting the help mode cursor, entering a modal loop
and waiting for the user to select a window to get help on. Please refer to Technical Note 28 for more
details on the MFC Help implementation.
Customization of this command handler is not recommended.
ID_HELP Gives help on the current context

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.

CWinApp::OnHelp handles this command by getting the right help context for the current application
context. This handles simple F1 help, help on message boxes and so on. Please refer to Technical Note 28
for more details on the MFC help implementation.
Customization of this command handler is not recommended.
ID_DEFAULT_HELP Displays default help for context

NOTE
You must connect this to your CWinApp -derived class's message map to enable this functionality.
This command is usually mapped to CWinApp::OnHelpIndex .
A different command handler can be provided if a distinction between default Help and the Help index is
desired.
ID_NEXT_PANE Goes to next pane
CView handles this command for the CSplitterWnd implementation. If the view is part of a splitter
window, this command will delegate to the implementation function CSplitterWnd::OnNextPaneCmd . This
will move the active view to the next pane in the splitter.
This command is disabled if the view is not in a splitter or there is no next pane to go to.
Customization of this command handler is not recommended.
ID_PREV_PANE Goes to previous pane
CView handles this command for the CSplitterWnd implementation. If the view is part of a splitter
window, this command will delegate to the implementation function CSplitterWnd::OnNextPaneCmd . This
will move the active view to the previous pane in the splitter.
This command is disabled if the view is not in a splitter or there is no previous pane to go to.
Customization of this command handler is not recommended.
ID_OLE_INSERT_NEW Inserts a new OLE object
Currently there is no standard implementation for this command. You must implement this for your
CView -derived class to insert a new OLE item/object at the current selection.

All OLE client applications should implement this command. AppWizard, with the OLE option, will create a
skeleton implementation of OnInsertObject in your view class that you will have to complete.
See the MFC OLE sample OCLIENT example for a complete implementation of this command.
ID_OLE_EDIT_LINKS Edits OLE links
COleDocument handles this command by using the MFC-provided implementation of the standard OLE
links dialog. The implementation of this dialog is accessed through the COleLinksDialog class. If the
current document does not contain any links, the command is disabled.
Customization of this command handler is not recommended.
ID_OLE_VERB_FIRST...LAST An ID range for OLE verbs
COleDocument uses this command ID range for the verbs supported by the currently selected OLE
item/object. This must be a range since a given OLE item/object type can support zero or more custom
verbs. In your application's menu, you should have one menu item with the ID of ID_OLE_VERB_FIRST.
When the program is run, the menu will be updated with the appropriate menu verb description (or pop-
up menu with many verbs). The management of the OLE menu is handled by AfxOleSetEditMenu , done in
the update command UI handler for this command.
There are no explicit command handlers for handling each of the command ID in this range.
COleDocument::OnCmdMsg is overridden to trap all command IDs in this range, turn them into zero-based
verb numbers, and launch the server for that verb (using COleClientItem::DoVerb ).
Customization or other use of this command ID range is not recommended.
ID_VIEW_TOOLBAR Toggles the toolbar on and off
CFrameWnd handles this command and the update-command UI handler to toggle the visible state of the
toolbar. The toolbar must be a child window of the frame with child window ID of AFX_IDW_TOOLBAR. The
command handler actually toggles the visibility of the toolbar window. CFrameWnd::RecalcLayout is used to
redraw the frame window with the toolbar in its new state. The update-command UI handler checks the
menu item when the toolbar is visible.
Customization of this command handler is not recommended. If you wish to add additional toolbars, you
will want to clone and modify the command handler and the update-command UI handler for this
command.
ID_VIEW_STATUS_BAR Toggles the status bar on and off
This command is implemented in CFrameWnd just like ID_VIEW_TOOLBAR, except a different child window
ID (AFX_IDW_STATUS_BAR) is used.

Update-Only Command Handlers


Several standard command IDs are used as indicators in status bars. These use the same update-command UI
handling mechanism to display their current visual state during application idle time. Since they can't be selected
by the user (that is, you cannot push a status bar pane), then it makes no sense to have an ON_COMMAND
handler for these command IDs.
ID_INDICATOR_CAPS : CAP lock indicator.
ID_INDICATOR_NUM : NUM lock indicator.
ID_INDICATOR_SCRL : SCRL lock indicator.
ID_INDICATOR_KANA : KANA lock indicator (applicable only to Japanese systems).
All three of these are implemented in CFrameWnd::OnUpdateKeyIndicator , an implementation helper that uses the
command ID to map to the appropriate Virtual Key. A common implementation enables or disables (for status
panes disabled = no text) the CCmdUI object depending on whether the appropriate Virtual Key is currently
locked.
Customization of this command handler is not recommended.
ID_INDICATOR_EXT : EXTended select indicator.
ID_INDICATOR_OVR : OVeRstrike indicator.
ID_INDICATOR_REC : RECording indicator.
Currently there is no standard implementation for these indicators.
If you choose to implement these indicators, we recommend you use these indicator IDs and maintaining the
ordering of the indicators in your status bar (that is, in this order: EXT, CAP, NUM, SCRL, OVR, REC).

See also
Technical Notes by Number
Technical Notes by Category
TN023: Standard MFC Resources
3/27/2020 • 3 minutes to read • Edit Online

This note describes the standard resources provided with and needed by the MFC library.

Standard Resources
MFC offers two categories of predefined resources that you can use in your application: clip-art resources and
standard framework resources.
Clip-art resources are additional resources that the framework does not depend on, but which you might want to
add to your application's user interface. The following clip-art resources are contained in the MFC General sample
CLIPART:
Common.rc: A single file of resources that contains:
A large collection of icons that represent a variety of business and data-processing tasks.
Several common cursors (see also Afxres.rc).
A toolbar bitmap that contains several toolbar buttons.
The bitmap and icon resources that are used by Commdlg.dll.
Indicate.rc: Contains string resources for the status-bar key-state indicators, such as "CAP" for Caps Lock.
Prompts.rc: Contains menu-prompt string resources for each predefined command, such as "Create a new
document" for ID_FILE_NEW.
Commdlg.rc: A Visual C++ compatible .rc file that contains the standard COMMDLG dialog templates.
Standard framework resources are resources with AFX-defined IDs that the framework depends on for internal
implementations. You will rarely need to change these AFX-defined resources. If you do, you should follow the
procedure outlined later in this topic.
The following framework resources are contained in the MFC\INCLUDE directory:
Afxres.rc: Common resources used by the framework.
Afxprint.rc: Resources specific to printing.
Afxolecl.rc: Resources specific to OLE client applications.
Afxolev.rc: Resources specific to full OLE server applications.

Using Clip-Art Resources


To use a clip-art binary resource
1. Open your application's resource file in Visual C++.
2. Open Common.rc. This file contains all the binary clip-art resources. This may take some time because the
Common.rc file is compiled.
3. Hold down CTRL while you drag the resources that you want to use from Common.rc to your application's
resource file.
To use other clip-art resources, follow the same steps. The only difference is that you will open the appropriate .rc
file instead of Common.rc.

NOTE
Be careful not to unintentionally move resources out of Common.rc permanently. If you hold the CTRL key while you drag
resources, you will create a copy. If you do not hold CTRL down while you drag, the resources will be moved. If you are
concerned that you might have accidentally made changes to the Common.rc file, click "No" when you are asked whether to
save the changes to Common.rc.

NOTE
The .rc resource files have a special TEXTINCLUDE resource in them that will prevent you from accidentally saving on top of
the standard .rc files.

Customizing Standard Framework Resources


Standard framework resources are usually included in an application by using the #include command in an
application's resource file. AppWizard will generate a resource file. This file includes the appropriate standard
framework resources, depending on which AppWizard options you select. You can review, add, or remove which
resources are included by changing the compile-time directives. To do this, open the Resource menu and select
Set Includes . Look at the "Compile-Time Directives" edit item. For example:

#include "afxres.rc"
#include "afxprint.rc"

The most common case of customizing standard framework resources is adding or removing additional includes
for printing, OLE Client, and OLE Server support.
In some rare cases you might want to customize the contents of the standard framework resources for your
particular application, not just add and remove the entire file. The followings steps show how you can limit the
resources that are included:
To c u st o m i z e t h e c o n t e n t s o f a st a n d a r d r e so u r c e fi l e

1. Open the resource file in Visual C++.


2. Using the Resource Set Includes command, remove the #include for the standard .rc file that you want to
customize. For example, to customize the print-preview toolbar, remove the #include "afxprint.rc" line.
3. Open the appropriate standard resources files in MFC\INCLUDE. Following the example earlier in this topic,
the appropriate file is MFC\Include\Aafxprint.rc
4. Copy all the resources from the standard .rc file to your application resource file.
5. Modify the copy of the standard resources in your application resource file.

NOTE
Do not modify the resources directly in the standard .rc files. Doing so will modify the resources available in every
application, not just in the one you are currently working on.

See also
Technical Notes by Number
Technical Notes by Category
TN024: MFC-Defined Messages and Resources
3/27/2020 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the internal Windows messages and resource formats used by MFC. This information explains
the implementation of the framework, and will assist you in debugging your application. For the adventurous,
even though all this information is officially unsupported, you may use some of this information for advanced
implementations.
This note contains MFC private implementation details; all the contents are subject to change in the future. MFC
private Windows messages have meaning in the scope of one application only but will change in the future to
contain system-wide messages.
The range of MFC private Windows messages and resource types are in the reserved "system" range set aside by
Microsoft Windows. Currently not all numbers in the ranges are used and, in the future, new numbers in the range
may be used. The currently used numbers may be changed.
MFC private Windows messages are in the range 0x360->0x37F.
MFC private resource types are in the range 0xF0->0xFF.
MFC Private Windows Messages
These Windows messages are used in place of C++ virtual functions where relatively loose coupling is required
between window objects and where a C++ virtual function would not be appropriate.
These private Windows messages and associated parameter structures are declared in the MFC private header
'AFXPRIV.H'. Be warned that any of your code that includes this header may be relying on undocumented behavior
and will likely break in future versions of MFC.
In the rare case of needing to handle one of these messages, you should use the ON_MESSAGE message map
macro and handle the message in the generic LRESULT/WPARAM/LPARAM format.
WM_QUERYAFXWNDPROC
This message is sent to a window that is being created. This is sent very early in the creation process as a method
of determining if the WndProc is AfxWndProc. AfxWndProc returns 1.

wParam Not used

lParam Not used

returns 1 if processed by AfxWndProc

WM_SIZEPARENT
This message is sent by a frame window to its immediate children during resizing ( CFrameWnd::OnSize calls
CFrameWnd::RecalcLayoutwhich calls CWnd::RepositionBars ) to reposition the control bars around the side of the
frame. The AFX_SIZEPARENTPARAMS structure contains the current available client rectangle of the parent and a
HDWP (which may be NULL) with which to call DeferWindowPos to minimize repainting.

wParam Not used

lParam Address of an AFX_SIZEPARENTPARAMS structure

returns Not used (0)

Ignoring the message indicates that the window doesn't take part in the layout.
WM_SETMESSAGESTRING
This message is sent to a frame window to ask it to update the message line in the status bar. Either a string ID or a
LPCSTR can be specified (but not both).

wParam String ID (or zero)

lParam LPCSTR for the string (or NULL)

returns Not used (0)

WM_IDLEUPDATECMDUI
This message is sent in idle time to implement the idle-time update of update-command UI handlers. If the
window (usually a control bar) handles the message, it creates a CCmdUI object (or an object of a derived class)
and call CCmdUI::DoUpdate for each of the "items" in the window. This will in turn check for an
ON_UPDATE_COMMAND_UI handler for the objects in the command-handler chain.

wParam BOOL bDisableIfNoHandler

lParam Not used (0)

returns Not used (0)

bDisableIfNoHandler is nonzero to disable the UI object if there is neither an ON_UPDATE_COMMAND_UI nor an


ON_COMMAND handler.
WM_EXITHELPMODE
This message is posted to a CFrameWnd that to exit context sensitive help mode. The receipt of this message
terminates the modal loop started by CFrameWnd::OnContextHelp .

wParam Not used (0)

lParam Not used (0)

returns Not used


WM_INITIALUPDATE
This message is sent by the document template to all descendants of a frame window when it is safe for them to
do their initial update. It maps to a call to CView::OnInitialUpdate but can be used in other CWnd -derived classes
for other one-shot updating.

wParam Not used (0)

lParam Not used (0)

returns Not used (0)

WM_RECALCPARENT
This message is sent by a view to its parent window (obtained via GetParent ) to force a layout recalculation
(usually, the parent will call RecalcLayout ). This is used in OLE server applications where it is necessary for the
frame to grow in size as the view's total size grows.
If the parent window processes this message it should return TRUE and fill the RECT passed in lParam with the
new size of the client area. This is used in CScrollView to properly handle scrollbars (place then on the outside of
the window when they are added) when a server object is in-place activated.

wParam Not used (0)

lParam LPRECT rectClient, may be NULL

returns TRUE if new client rectangle returned, FALSE otherwise

WM_SIZECHILD
This message is sent by COleResizeBar to its owner window (via GetOwner ) when the user resizes the resize bar
with the resize handles. COleIPFrameWnd responds to this message by attempting to reposition the frame window
as the user has requested.
The new rectangle, given in client coordinates relative to the frame window which contains the resize bar, is
pointed at by lParam.

wParam Not used (0)

lParam LPRECT rectNew

returns Not used (0)

WM_DISABLEMODAL
This message is sent to all pop-up windows owned by a frame window that is being deactivated. The frame
window uses the result to determine whether or not to disable the pop-up window.
You can use this to perform special processing in your pop-up window when the frame enters a modal state or to
keep certain pop-up windows from getting disabled. Tooltips use this message to destroy themselves when the
frame window goes into a modal state, for example.
wParam Not used (0)

lParam Not used (0)

returns Non-zero to NOT disable the window, 0 indicates the window


will be disabled

WM_FLOATSTATUS
This message is sent to all pop-up windows owned by a frame window when the frame is either activated or
deactivated by another top-level frame window. This is used by the implementation of MFS_SYNCACTIVE in
CMiniFrameWnd , to keep the activation of these pop-up windows in sync with the activation of the top level frame
window.

wParam Is one of the following values:

FS_SHOW

FS_HIDE

FS_ACTIVATE

FS_DEACTIVATE

FS_ENABLEFS_DISABLE

FS_SYNCACTIVE

lParam Not used (0)

The return value should be non-zero if FS_SYNCACTIVE is set and the window syncronizes its activation with the
parent frame. CMiniFrameWnd returns non-zero when the style is set to MFS_SYNCACTIVE.
For more information, see the implementation of CMiniFrameWnd .

WM_ACTIVATETOPLEVEL
This message is sent to a top-level window when a window in its "top-level group" is either activated or
deactivated. A window is part of a top-level group if it is a top-level window (no parent or owner), or it is owned by
such a window. This message is similar in use to WM_ACTIVATEAPP, but works in situations where windows
belonging to different processes are mixed in a single window hierarchy (common in OLE applications).

WM_COMMANDHELP, WM_HELPHITTEST, WM_EXITHELPMODE


These messages are used in the implementation of context-sensitive Help. Please refer to Technical Note 28 for
more information.

MFC Private Resource Formats


Currently, MFC defines two private resource formats: RT_TOOLBAR and RT_DLGINIT.

RT_TOOLBAR Resource Format


The default toolbar supplied by AppWizard is based on an RT_TOOLBAR custom resource, which was introduced in
MFC 4.0. You can edit this resource using the Toolbar editor.

RT_DLGINIT Resource Format


One MFC private resource format is used to store extra dialog initialization information. This includes the initial
strings stored in a combo box. The format of this resource is not designed to be manually edited, but is handled by
Visual C++.
Visual C++ and this RT_DLGINIT resource are not required to use the related features of MFC since there are API
alternative to using the information in the resource. Using Visual C++ makes it much easier to write, maintain, and
translate your application in the long run.
The basic structure of a RT_DLGINIT resource is as follows:

+---------------+ \
| Control ID | UINT |
+---------------+ |
| Message # | UINT |
+---------------+ |
|length of data | DWORD |
+---------------+ | Repeated
| Data | Variable Length | for each control
| ... | and Format | and message
+---------------+ /
| 0 | BYTE
+---------------+

A repeated section contains the control ID to send the message to, the Message # to send (a normal Windows
message) and a variable length of data. The Windows message is sent in a form:

SendDlgItemMessage(<Control ID>, <Message #>, 0, &<Data>);

This is a very general format, allowing any Windows messages and data content. The Visual C++ resource editor
and MFC only support a limited subset of Windows messages: CB_ADDSTRING for the initial list-choices for
combo boxes (the data is a text string).

See also
Technical Notes by Number
Technical Notes by Category
TN025: Document, View, and Frame Creation
3/27/2020 • 3 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the creation and ownership issues for WinApps, DocTemplates, Documents, Frames and Views.

WinApp
There is one CWinApp object in the system.
It is statically constructed and initialized by the framework's internal implementation of WinMain . You must derive
from CWinApp to do anything useful (exception: MFC extension DLLs should not have a CWinApp instance —
initialization is done in DllMain instead).
The one CWinApp object owns a list of document templates (a CPtrList ). There is one or more document template
per application. DocTemplates are usually loaded from the resource file (that is, a string array) in
CWinApp::InitInstance .

pTemplate = new CDocTemplate(IDR_MYDOCUMENT, ...);

AddDocTemplate(pTemplate);

The one CWinApp object owns all frame windows in the application. The main frame window for the application
should be stored in CWinApp::m_pMainWnd ; usually you set m_pMainWnd in the InitInstance implementation if
you have not let AppWizard do it for you. For single document interface (SDI) this is one CFrameWnd that serves as
the main application frame window as well as the only document frame window. For multiple document interface
(MDI) this is an MDI-Frame (class CMDIFrameWnd ) that serves as the main application frame window that contains
all the child CFrameWnd s. Each child window is of class CMDIChildWnd (derived from CFrameWnd ) and serves as one
of potentially many document frame windows.

DocTemplates
The CDocTemplate is the creator and manager of documents. It owns the documents that it creates. If your
application uses the resource-based approach described below, it will not need to derive from CDocTemplate .
For an SDI application, the class CSingleDocTemplate keeps track of one open document. For an MDI application,
the class CMultiDocTemplate keeps a list (a CPtrList ) of all the currently open documents created from that
template. CDocTemplate::AddDocument and CDocTemplate::RemoveDocument provide the virtual member functions for
adding or removing a document from the template. CDocTemplate is a friend of CDocument so we can set the
protected CDocument::m_pDocTemplate back pointer to point back to the doc template that created the document.
CWinApphandles the default OnFileOpen implementation, which will in turn query all the doc templates. The
implementation includes looking for already open documents and deciding what format to open new documents
in.
CDocTemplate manages the UI binding for documents and frames.
CDocTemplate keeps a count of the number of unnamed documents.

CDocument
A CDocument is owned by a CDocTemplate .
Documents have a list of currently open views (derived from CView ) that are viewing the document (a CPtrList ).
Documents do not create/destroy the views, but they are attached to each other after they are created. When a
document is closed (that is, through File/Close), all attached views will be closed. When the last view on a
document is closed (that is, Window/Close) the document will be closed.
The CDocument::AddView , RemoveView interface is used to maintain the view list. CDocument is a friend of CView so
we can set the CView::m_pDocument back pointer.

CFrameWnd
A CFrameWnd (also known as a frame) plays the same role as in MFC 1.0, but now the CFrameWnd class is designed
to be used in many cases without deriving a new class. The derived classes CMDIFrameWnd and CMDIChildWnd are
also enhanced so many standard commands are already implemented.
The CFrameWnd is responsible for creating windows in the client area of the frame. Normally there is one main
window filling the client area of the frame.
For an MDI-Frame window, the client area is filled with the MDICLIENT control which is in turn the parent of all the
MDI-Child frame windows. For an SDI-Frame window or an MDI-Child frame window, the client area is usually
filled with a CView -derived window object. In the case of CSplitterWnd , the client area of the view is filled with the
CSplitterWnd window object, and the CView -derived window objects (one per split pane) are created as child
windows of the CSplitterWnd .

See also
Technical Notes by Number
Technical Notes by Category
TN026: DDX and DDV Routines
3/27/2020 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the dialog data exchange (DDX) and dialog data validation (DDV) architecture. It also describes
how you write a DDX_ or DDV_ procedure and how you can extend ClassWizard to use your routines.

Overview of Dialog Data Exchange


All dialog data functions are done with C++ code. There are no special resources or magic macros. The heart of
the mechanism is a virtual function that is overridden in every dialog class that does dialog data exchange and
validation. It is always found in this form:

void CMyDialog::DoDataExchange(CDataExchange* pDX)


{
CDialog::DoDataExchange(pDX); // call base class

//{{AFX_DATA_MAP(CMyDialog)
<data_exchange_function_call>
<data_validation_function_call>
//}}AFX_DATA_MAP
}

The special format AFX comments allow ClassWizard to locate and edit the code within this function. Code that is
not compatible with ClassWizard should be placed outside of the special format comments.
In the above example, <data_exchange_function_call> is in the form:

DDX_Custom(pDX, nIDC, field);

and <data_validation_function_call> is optional and is in the form:

DDV_Custom(pDX, field, ...);

More than one DDX_/DDV_ pair may be included in each DoDataExchange function.
See 'afxdd_.h' for a list of all the dialog data exchange routines and dialog data validation routines provided with
MFC.
Dialog data is just that: member data in the CMyDialog class. It is not stored in a struct or anything similar.

Notes
Although we call this "dialog data," all features are available in any class derived from CWnd and are not limited
to just dialogs.
Initial values of data are set in the standard C++ constructor, usually in a block with //{{AFX_DATA_INIT and
//}}AFX_DATA_INIT comments.

CWnd::UpdateData is the operation that does the initialization and error handling around the call to
DoDataExchange .
You can call CWnd::UpdateData at any time to perform data exchange and validation. By default UpdateData (TRUE)
is called in the default CDialog::OnOK handler and UpdateData (FALSE) is called in the default
CDialog::OnInitDialog .

The DDV_ routine should immediately follow the DDX_ routine for that field.

How Does It Work


You do not need to understand the following in order to use dialog data. However, understanding how this works
behind the scenes will help you write your own exchange or validation procedure.
The DoDataExchange member function is much like the Serialize member function - it is responsible for getting
or setting data to/from an external form (in this case controls in a dialog) from/to member data in the class. The
pDX parameter is the context for doing data exchange and is similar to the CArchive parameter to
CObject::Serialize . The pDX (a CDataExchange object) has a direction flag much like CArchive has a direction
flag:
If !m_bSaveAndValidate , then load the data state into the controls.
If m_bSaveAndValidate , then set the data state from the controls.

Validation only occurs when m_bSaveAndValidate is set. The value of m_bSaveAndValidate is determined by the
BOOL parameter to CWnd::UpdateData .
There are three other interesting CDataExchange members:
: The window (usually a dialog) that contains the controls. This is to prevent callers of the DDX_
m_pDlgWnd
and DDV_ global functions from having to pass 'this' to every DDX/DDV routine.
PrepareCtrl , and PrepareEditCtrl : Prepares a dialog control for data exchange. Stores that control's
handle for setting the focus if a validation fails. PrepareCtrl is used for non-edit controls and
PrepareEditCtrl is used for edit controls.

Fail : Called after bringing up a message box alerting the user to the input error. This routine will restore
the focus to the last control (the last call to PrepareCtrl or PrepareEditCtrl ) and throw an exception. This
member function may be called from both DDX_ and DDV_ routines.

User Extensions
There are several ways to extend the default DDX/DDV mechanism. You can:
Add new data types.

CTime

Add new exchange procedures (DDX_).

void PASCAL DDX_Time(CDataExchange* pDX, int nIDC, CTime& tm);

Add new validation procedures (DDV_).


void PASCAL DDV_TimeFuture(CDataExchange* pDX, CTime tm, BOOL bFuture);
// make sure time is in the future or past

Pass arbitrary expressions to the validation procedures.

DDV_MinMax(pDX, age, 0, m_maxAge);

NOTE
Such arbitrary expressions cannot be edited by ClassWizard and therefore should be moved outside of the special
format comments (//{{AFX_DATA_MAP(CMyClass)).

Have the DoDialogExchange member function include conditionals or any other valid C++ statements with
intermixed exchange and validation function calls.

//{{AFX_DATA_MAP(CMyClass)
DDX_Check(pDX, IDC_SEX, m_bFemale);
DDX_Text(pDX, IDC_EDIT1, m_age);
//}}AFX_DATA_MAP
if (m_bFemale)
DDV_MinMax(pDX, age, 0, m_maxFemaleAge);
else
DDV_MinMax(pDX, age, 0, m_maxMaleAge);

NOTE
As shown above, such code cannot be edited by ClassWizard and should be used only outside of the special format
comments.

ClassWizard Support
ClassWizard supports a subset of DDX/DDV customizations by allowing you to integrate your own DDX_ and
DDV_ routines into the ClassWizard user interface. Doing this is only cost beneficial if you plan to reuse particular
DDX and DDV routines in a project or in many projects.
To do this, special entries are made in DDX.CLW (previous versions of Visual C++ stored this information in
APSTUDIO.INI) or in your project's .CLW file. The special entries can be entered either in the [General Info] section
of your project's .CLW file or in the [ExtraDDX] section of the DDX.CLW file in the \Program Files\Microsoft Visual
Studio\Visual C++\bin directory. You may need to create the DDX.CLW file if it doesn't already exist. If you plan to
use the custom DDX_/DDV_ routines only in a certain project, add the entries to the [General Info] section of your
project .CLW file instead. If you plan to use the routines on many projects, add the entries to the [ExtraDDX]
section of DDX.CLW.
The general format of these special entries is:

ExtraDDXCount=n

where n is the number of ExtraDDX? lines to follow, of the form

ExtraDDX?=keys; vb-keys; prompt; type; initValue; DDX_Proc [; DDV_Proc; prompt1; arg1 [; prompt2; fmt2]]

where ? is a number 1 - n indicating which DDX type in the list that is being defined.
Each field is delimited by a ';' character. The fields and their purpose are described below.
keys
A list of single characters indicating for which dialog controls this variable type is allowed.

C H A RA C T ER A L LO W ED C O N T RO L

E edit

C two-state check box

c tri-state check box

R first radio button in a group

L nonsorted list box

l sorted list box

M combo box (with edit item)

N nonsorted drop list

n sorted drop list

1 if the DDX insert should be added to head of list (default


is add to tail) This is generally used for DDX routines that
transfer the 'Control' property.

vb-keys
This field is used only in the 16-bit product for VBX controls (VBX controls are not supported in the 32-bit
product)
prompt
String to place in the Property combo box (no quotes)
type
Single identifier for type to emit in the header file. In our example above with DDX_Time, this would be set
to CTime.
vb-keys
Not used in this version and should always be empty
initValue
Initial value — 0 or blank. If it is blank, then no initialization line will be written in the //{{AFX_DATA_INIT
section of the implementation file. A blank entry should be used for C++ objects (such as CString , CTime ,
and so on) that have constructors that guarantee correct initialization.
DDX_Proc
Single identifier for the DDX_ procedure. The C++ function name must start with "DDX_," but don't include
"DDX_" in the <DDX_Proc> identifier. In the example above, the <DDX_Proc> identifier would be Time.
When ClassWizard writes the function call to the implementation file in the {{AFX_DATA_MAP section, it
appends this name to DDX_, thus arriving at DDX_Time.
comment
Comment to show in dialog for variable with this DDX. Place any text you would like here, and usually
provide something that describes the operation performed by the DDX/DDV pair.
DDV_Proc
The DDV portion of the entry is optional. Not all DDX routines have corresponding DDV routines. Often, it
is more convenient to include the validation phase as an integral part of the transfer. This is often the case
when your DDV routine doesn't require any parameters, because ClassWizard does not support DDV
routines without any parameters.
arg
Single identifier for the DDV_ procedure. The C++ function name must start with "DDV_", but do not
include "DDX_" in the <DDX_Proc> identifier.
arg is followed by 1 or 2 DDV args:
promptN
String to place above the edit item (with & for accelerator).
fmtN
Format character for the arg type, one of:

C H A RA C T ER TYPE

d int

u unsigned int

D long int (that is, long)

U long unsigned (that is, DWORD)

f float

F double

s string

See also
Technical Notes by Number
Technical Notes by Category
TN028: Context-Sensitive Help Support
3/27/2020 • 9 minutes to read • Edit Online

This note describes the rules for assigning Help contexts IDs and other help issues in MFC. Context-sensitive help
support requires the help compiler that is available in Visual C++.

NOTE
In addition to implementing context-sensitive help using WinHelp, MFC also supports using HTML Help. For more
information on this support and programming with HTML Help, see HTML Help: Context-Sensitive Help for Your Programs.

Types of Help Supported


There are two types of context-sensitive help implemented in Windows applications. The first, referred to as "F1
Help" involves launching WinHelp with the appropriate context based on the currently active object. The second is
"Shift+ F1" mode. In this mode, the mouse cursor changes to the help cursor, and the user proceeds to click on an
object. At that point, WinHelp is launched to give help for the object that the user clicked on.
The Microsoft Foundation Classes implement both of these forms of help. In addition, the framework supports
two simple help commands, Help Index and Using Help.

Help Files
The Microsoft Foundation classes assume a single Help file. That Help file must have the same name and path as
the application. For example, if the executable is C:\MyApplication\MyHelp.exe the help file must be
C:\MyApplication\MyHelp.hlp. You set the path through the m_pszHelpFilePath member variable of the CWinApp
Class.

Help Context Ranges


The default implementation of MFC requires a program to follow some rules about the assignment of Help
context IDs. These rules are a range of IDs allocated to specific controls. You can override these rules by providing
different implementations of the various Help-related member functions.

0x00000000 - 0x0000FFFF : user defined


0x00010000 - 0x0001FFFF : commands (menus/command buttons)
0x00010000 + ID_
(note: 0x18000-> 0x1FFFF is the practical range since command IDs are>=0x8000)
0x00020000 - 0x0002FFFF : windows and dialogs
0x00020000 + IDR_
(note: 0x20000-> 0x27FFF is the practical range since IDRs are <= 0x7FFF)
0x00030000 - 0x0003FFFF : error messages (based on error string ID)
0x00030000 + IDP_
0x00040000 - 0x0004FFFF : special purpose (non-client areas)
0x00040000 + HitTest area
0x00050000 - 0x0005FFFF : controls (those that are not commands)
0x00040000 + IDW_

Simple "Help" Commands


There are two simple Help commands that are implemented by the Microsoft Foundation Classes:
ID_HELP_INDEX which is implemented by CWinApp::OnHelpIndex
ID_HELP_USING which is implemented by CWinApp::OnHelpUsing
The first command shows the Help index for the application. The second shows the user help on using the
WinHelp program.

Context-Sensitive Help (F1 Help)


The F1 key is usually translated to a command with an ID of ID_HELP by an accelerator placed into the main
window's accelerator table. The ID_HELP command may also be generated by a button with an ID of ID_HELP on
the main window or dialog box.
Regardless of how the ID_HELP command is generated, it is routed as a normal command until it reaches a
command handler. For more information about the MFC command-routing architecture, refer to Technical Note
21. If the application has Help enabled, the ID_HELP command will be handled by CWinApp::OnHelp. The
application object receives the help message and then routes the command appropriately. This is necessary since
the default command routing is not adequate for determining the most specific context.
CWinApp::OnHelp attempts to launch WinHelp in the following order:
1. Checks for an active AfxMessageBox call with a Help ID. If a message box is currently active, WinHelp is
launched with the context appropriate to that message box.
2. Sends a WM_COMMANDHELP message to the active window. If that window does not respond by
launching WinHelp, the same message is then sent to the ancestors of that window until the message is
processed or the current window is a top-level window.
3. Sends a ID_DEFAULT_HELP command to the main window. This invokes the default Help. This command is
generally mapped to CWinApp::OnHelpIndex .

To globally override the default ID base values (e.g. 0x10000 for commands and 0x20000 for resources such as
dialogs), the application should override CWinApp::WinHelp.
To override this functionality and the way that a Help context is determined, you should handle the
WM_COMMANDHELP message. You may wish to provide more specific Help routing than the framework
provides, as it only goes as deep as the current MDI child window. You may also want to provide more specific
help for a particular window or dialog, perhaps based on the current internal state of that object or the active
control within the dialog.

WM_COMMANDHELP
afx_msg LRESULT CWnd::OnCommandHelp(WPARAM wParam, LPARAM lParam)

WM_COMMANDHELP is a private Windows MFC message that is received by the active window when Help is
requested. When the window receives this message, it may call CWinApp::WinHelp with context that matches the
window's internal state.
lParam
Contains the currently available Help context. lParam is zero if no Help context has been determined. An
implementation of OnCommandHelp can use the context ID in lParam to determine a different context or can just
pass it to CWinApp::WinHelp .
wParam
Is not used and will be zero.
If the OnCommandHelp function calls CWinApp::WinHelp , it should return TRUE . Returning TRUE stops the routing of
this command to other classes and to other windows.

Help Mode (Shift+F1 Help)


This is the second form of context-sensitive Help. Generally, this mode is entered by pressing SHIFT+F1 or via the
menu/toolbar. It is implemented as a command (ID_CONTEXT_HELP). The message filter hook is not used to
translate this command while a modal dialog box or menu is active, therefore this command is only available to
the user when the application is executing the main message pump ( CWinApp::Run ).
After entering this mode, the Help mouse cursor is displayed over all areas of the application, even if the
application would normally display its own cursor for that area (such as the sizing border around the window).
The user is able to use the mouse or keyboard to select a command. Instead of executing the command, Help on
that command is displayed. Also, the user can click a visible object on the screen, such as a button on the toolbar,
and Help will be displayed for that object. This mode of Help is provided by CWinApp::OnContextHelp .
During the execution of this loop, all keyboard input is inactive, except for keys that access the menu. Also,
command translation is still performed via PreTranslateMessage to allow the user to press an accelerator key and
receive help on that command.
If there are particular translations or actions taking place in the PreTranslateMessage function that shouldn't take
place during SHIFT+F1 Help mode, you should check the m_bHelpMode member of CWinApp before performing
those operations. The CDialog implementation of PreTranslateMessage checks this before calling
IsDialogMessage , for example. This disables "dialog navigation" keys on modeless dialogs during SHIFT+F1
mode. In addition, CWinApp::OnIdle is still called during this loop.
If the user chooses a command from the menu, it is handled as help on that command (through
WM_COMMANDHELP, see below). If the user clicks a visible area of the applications window, a determination is
made as to whether it is a nonclient click or a client click. OnContextHelp handles mapping of nonclient clicks to
client clicks automatically. If it is a client click, it then sends a WM_HELPHITTEST to the window that was clicked. If
that window returns a nonzero value, that value is used as the context for help. If it returns zero, OnContextHelp
tries the parent window (and failing that, its parent, and so on). If a Help context cannot be determined, the default
is to send a ID_DEFAULT_HELP command to the main window, which is then (usually) mapped to
CWinApp::OnHelpIndex .

WM_HELPHITTEST
afx_msg LRESULT CWnd::OnHelpHitTest(
WPARAM, LPARAM lParam)

WM_HELPHITTEST is an MFC private windows message that is received by the active window clicked during
SHIFT+F1 Help mode. When the Window receives this message, it returns a DWORD Help ID for use by WinHelp.
LOWORD(lParam) contains the X-axis device coordinate where the mouse was clicked relative to the client area of
the window.
HIWORD(lParam) contains the Y-axis coordinate.
wParam
is not used and will be zero. If the return value is nonzero, WinHelp is called with that context. If the return value is
zero, the parent window is queried for help.
In many cases, you can leverage hit-testing code you may already have. See the implementation of
CToolBar::OnHelpHitTest for an example of handling the WM_HELPHITTEST message (the code leverages the hit-
test code used on buttons and tooltips in CControlBar ).

MFC Application Wizard Support and MAKEHM


The MFC Application Wizard creates the necessary files to build a Help file (.cnt and .hpj files). It also includes a
number of prebuilt .rtf files that are accepted by the Microsoft Help Compiler. Many of the topics are complete,
but some may need to be modified for your specific application.
Automatic creation of a "help mapping" file is supported by a utility called MAKEHM. The MAKEHM utility can
translate an application's RESOURCE.H file to a Help mapping file. For example:

#define IDD_MY_DIALOG 2000


#define ID_MY_COMMAND 150

will be translated into:

HIDD_MY_DIALOG 0x207d0
HID_MY_COMMAND 0x10096

This format is compatible with the Help compiler's facility, which maps context IDs (the numbers on the right side)
with topic names (the symbols on the left side).
The source code for MAKEHM is available in the MFC Programming Utilities sample MAKEHM.

Adding Help Support After Running the MFC Application Wizard


The best way to add Help to your application is to check the "Context-sensitive Help" option on the Advanced
Features page of the MFC Application Wizard before creating your application. That way the MFC Application
Wizard automatically adds the necessary message map entries to your CWinApp -derived class to support Help.

Help on Message Boxes


Help on Message Boxes (sometimes called alerts) is supported through the AfxMessageBox function, a wrapper
for the MessageBox Windows API.
There are two versions of AfxMessageBox , one for use with a string ID and another for use with a pointer to string
( LPCSTR ):

int AFXAPI AfxMessageBox(LPCSTR lpszText,


UINT nType,
UINT nIDHelp);

int AFXAPI AfxMessageBox(UINT nIDPrompt,


UINT nType,
UINT nIDHelp);

In both cases, there is an optional Help ID.


In the first case, the default for nIDHelp is 0, which indicates no Help for this message box. If the user presses F1
while such as message box is active, the user will not receive Help (even if the application supports Help). If this is
not desirable, a Help ID should be provided for nIDHelp.
In the second case, the default value for nIDHelp is -1, which indicates the Help ID is the same as nIDPrompt. Help
will work only if the application is Help-enabled, of course). You should provide 0 for nIDHelp if you wish that the
message box have no help support. Should you want the message to be Help enabled, but desire a different help
ID than nIDPrompt, simply provide a positive value for nIDHelp different from that of nIDPrompt.

See also
Technical Notes by Number
Technical Notes by Category
TN029: Splitter Windows
4/1/2019 • 6 minutes to read • Edit Online

This note describes the MFC CSplitterWnd Class, which provides window splits and manages the resizing of other
pane windows.

Splitter Styles
A CSplitterWnd supports two different styles of splitting windows.
In "static splitters," the splitter window creates the panes when it is created. The order and number of panes never
change. Splitter bars are used to resize the different panes. You can use this style to display a different view class
in each pane. The Visual C++ graphics editor and the Windows File Manager are examples of programs that use
this splitter style. This style of splitter window does not use splitter boxes.
In "dynamic splitters," additional panes are created and destroyed as the user splits and un-splits new views. This
splitter starts out with a single view and provides splitter boxes for the user to initiate splitting. The splitter
window dynamically creates a new view object when the view is split in one direction. This new view object
represents the new pane. If the view is split in two directions by using the keyboard interface, the splitter window
creates three new view objects for the three new panes. While the split is active, Windows displays the splitter box
as a splitter bar between the panes. Windows destroys additional view objects when the user removes a split, but
the original view remains until the splitter window itself is destroyed. Microsoft Excel and Microsoft Word are
examples of applications that use the dynamic splitter style.
When you create either kind of splitter window, you must specify the maximum number of rows and columns that
the splitter will manage. A static splitter will create panes to fill all the rows and columns. A dynamic splitter will
create only the first pane when the CSplitterWnd is created.
The maximum number of panes you can specify for static splitters is 16 rows by 16 columns. The recommended
configurations are:
1 row x 2 columns : usually with dissimilar panes
2 rows x 1 column : usually with dissimilar panes
2 rows x 2 columns : usually with similar panes
The maximum number of panes that you can specify for dynamic splitters is 2 rows by 2 columns. The
recommended configurations are:
1 row x 2 columns : for columnar data
2 rows x 1 column : for textual or other data
2 rows x 2 columns : for grid or table oriented data

Splitter Examples
Many of the MFC sample programs use splitter windows directly or indirectly. The MFC General sample VIEWEX
illustrates several uses of static splitters, including how to place a splitter in a splitter.
You can also use ClassWizard to create a new multiple document interface (MDI) Child frame window class that
contains a splitter window. For more information on splitter windows, see Multiple Document Types, Views, and
Frame Windows.
Terminology Used by Implementation
Here is a list of terms that are specific to splitter windows:
CSplitterWnd : A window that provides pane-splitting controls and scroll bars that are shared between all panes
on a row or column. You specify rows and columns with zero-based numbers (the first pane is row = 0 and
column = 0).
Pane: An application-specific window that a CSplitterWnd manages. A pane is usually an object that is derived
from the CView Class, but can be any CWnd object that has the appropriate child window ID.
To use a CWnd -derived object, pass the RUNTIME_CLASS of the object to the CreateView function as you would if
you were using a CView -derived class. Your class must use DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE
because the framework uses dynamic creation at runtime. Although there is a lot of code in CSplitterWnd that is
specific to the CView class, CObject::IsKindOf is always used before those actions are performed.
Splitter Bar: A control that is placed between rows and columns of panes. It may be used to adjust the sizes of
rows or columns of panes.
Splitter Box: A control in a dynamic CSplitterWnd that you can use to create new rows or columns of panes. It is
located at the top of the vertical scroll bars or to the left of the horizontal scroll bars.
Splitter Intersection: The intersection of a vertical splitter bar and a horizontal splitter bar. You can drag it to adjust
the size of a row and column of panes simultaneously.

Shared Scroll Bars


The CSplitterWnd class also supports shared scroll bars. These scroll bar controls are children of the
CSplitterWnd and are shared with the different panes in the splitter.
For example, in a 1 row x 2 column window, you can specify WS_VSCROLL when creating the CSplitterWnd .
Windows creates a special scroll bar control that is shared between the two panes.

[ ][ ][^]
[pane00][pane01][|]
[ ][ ][v]

When the user moves the scroll bar, WM_VSCROLL messages will be sent to both views. When either view sets
the scroll bar position, the shared scroll bar will be set.
Note that shared scroll bars are most useful with similar view objects. If you mix views of different types in a
splitter, then you may have to write special code to coordinate their scroll positions. Any CView -derived class that
uses the CWnd scroll bar APIs will delegate to the shared scroll bar if it exists. The CScrollView implementation is
one example of a CView class that supports shared scroll bars. Classes that are not derived from CView , classes
that rely on non-control scroll bars, or classes that use standard Windows implementations (for example,
CEditView ) will not work with the shared scroll bar feature of CSplitterWnd .

Minimum Sizes
For each row there is a minimum row height, and for each column there is a minimum column width. This
minimum guarantees that a pane is not too small to be shown in complete detail.
For a static splitter window, the initial minimum row height and column width is 0. For a dynamic splitter window,
the initial minimum row height and column width are set by the sizeMin parameter of the CSplitterWnd::Create
function.
You can change these minimum sizes by using the CSplitterWnd::SetRowInfo and CSplitterWnd::SetColumnInfo
functions.

Actual vs. Ideal Sizes


The layout of the panes in the splitter window depends on the size of the frame that contains them. When a user
resizes the containing frame, the CSplitterWnd repositions and resizes the panes so that they fit as well as
possible.
The user can manually set the row height and column width sizes, or the program can set the ideal size by using
the CSplitterWnd class. The actual size can be smaller or larger than the ideal. Windows will adjust the actual size
if there is not enough room to display the ideal size or if there is too much empty space on the right or bottom of
the splitter window.

Custom Controls
You can override many functions to provide customized behavior and a customized interface. You can override
this first set to provide alternate imagery for the various graphical components of a splitter window.
virtual void OnDrawSpltter(CDC* pDC, ESplitType nType, const CRect& rect);

virtual void OnInvertTracker(const CRect& rect);

You call this function to create a shared scroll bar control. You can override it to create extra controls next to the
scroll bar.
virtual BOOL CreateScrollBarCtrl(DWORD dwStyle, UINT nID);

These functions implement the logic of the dynamic splitter window. You can override these to provide more
advanced splitter logic.
virtual void DeleteView(int row, int col);

virtual BOOL SplitRow(int cyBefore);

virtual BOOL SplitColumn(int cxBefore);

virtual void DeleteRow(int rowDelete);

virtual void DeleteColumn(int colDelete);

CView Functionality
The CView class uses the following high level commands to delegate to the CSplitterWnd implementation.
Because these commands are virtual, the standard CView implementation will not require the entire
CSplitterWnd implementation to be linked in. For applications that use CView but not CSplitterWnd , the
CSplitterWnd implementation will not be linked with the application.

virtual BOOL CanActivateNext(BOOL bPrev = FALSE);

Checks whether ID_NEXT_PANE or ID_PREV_PANE is currently possible.


virtual void ActivateNext(BOOL bPrev = FALSE);

Executes the "Next Pane" or "Previous Pane" command.


virtual BOOL DoKeyboardSplit();

Executes the keyboard split command, usually "Window Split".


See also
Technical Notes by Number
Technical Notes by Category
TN030: Customizing Printing and Print Preview
10/31/2018 • 6 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the process of customizing printing and print preview and describes the purposes of the
callback routines used in CView and the callback routines and member functions of CPreviewView .

The Problem
MFC provides a complete solution for most printing and print preview needs. In most cases, little additional code is
required to have a view able to print and preview. However, there are ways to optimize printing that require
significant effort on the part of the developer, and some applications need to add specific user interface elements
to the print preview mode.

Efficient Printing
When an MFC application prints using the standard methods, Windows directs all Graphical Device Interface (GDI)
output calls to an in-memory metafile. When EndPage is called, Windows plays the metafile once for each physical
band that the printer requires to print one page. During this rendering, GDI frequently queries the Abort Procedure
to determine if it should continue. Typically the abort procedure allows messages to be processed so that the user
may abort the print job using a printing dialog.
Unfortunately, this can slow the printing process. If the printing in your application must be faster than can be
achieved using the standard technique, you must implement manual banding.

Print Banding
In order to manually band, you must re implement the print loop such that OnPrint is called multiple times per
page (once per band). The print loop is implemented in the OnFilePrint function in viewprnt.cpp. In your CView -
derived class, you overload this function so that the message map entry for handling the print command calls your
print function. Copy the OnFilePrint routine and change the print loop to implement banding. You will probably
also want to pass the banding rectangle to your printing functions so that you can optimize drawing based on the
section of the page being printed.
Second, you must frequently call QueryAbort while drawing the band. Otherwise, the Abort Procedure will not get
called and the user will be unable to cancel the print job.

Print Preview: Electronic Paper with User Interface


Print Preview, in essence, tries to turn the display into an emulation of a printer. By default, the client area of the
main window is used to display one or two pages fully within the window. The user is able to zoom in on an area
of the page to see it in more detail. With additional support, the user may even be allowed to edit the document in
preview mode.
Customizing Print Preview
This note only deals with one aspect of modifying print preview: Adding UI to preview mode. Other modifications
are possible, but such changes are out of the scope of this discussion.

To add UI to the preview mode


1. Derive a view class from CPreviewView .
2. Add command handlers for the UI aspects you desire.
3. If you are adding visual aspects to the display, override OnDraw and perform your drawing after calling
CPreviewView::OnDraw .

OnFilePrintPreview
This is the command handler for print preview. Its default implementation is:

void CView::OnFilePrintPreview()
{
// In derived classes, implement special window handling here
// Be sure to Unhook Frame Window close if hooked.

// must not create this on the frame. Must outlive this function
CPrintPreviewState* pState = new CPrintPreviewState;

if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this,
RUNTIME_CLASS(CPreviewView), pState))
{
// In derived classes, reverse special window handling
// here for Preview failure case

TRACE0("Error: DoPrintPreview failed");


AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
delete pState; // preview failed to initialize, delete State now
}
}

DoPrintPreview will hide the main pane of the application. Control Bars, such as the status bar, can be retained by
specifying them in the pState->dwStates member (This is a bit mask and the bits for individual control bars are
defined by AFX_CONTROLBAR_MASK( AFX_IDW_MYBAR)). The window pState->nIDMainPane is the window that
will be automatically hidden and reshown. DoPrintPreview will then create a button bar for the standard Preview
UI. If special window handling is needed, such as to hide or show other windows, that should be done before
DoPrintPreview is called.

By default, when print preview finishes, it returns the control bars to their original states and the main pane to
visible. If special handling is needed, it should be done in an override of EndPrintPreview . If DoPrintPreview fails,
also provide special handling.
DoPrintPreview is called with:
The Resource ID of the dialog template for the preview toolbar.
A pointer to the view to perform the printing for the print preview.
The run-time class of the Preview View class. This will be dynamically created in DoPrintPreview.
The CPrintPreviewState pointer. Note that the CPrintPreviewState structure (or the derived structure if the
application needs more state preserved) must not be created on the frame. DoPrintPreview is modeless and
this structure must survive until EndPrintPreview is called.
NOTE
If a separate view or view class is needed for printing support, a pointer to that object should be passed as the
second parameter.

EndPrintPreview
This is called to terminate the print preview mode. It is often desirable to move to the page in the document that
was last displayed in print preview. EndPrintPreview is the application's chance to do that. The pInfo->m_nCurPage
member is the page that was last displayed (leftmost if two pages were displayed), and the pointer is a hint as to
where on the page the user was interested. Since the structure of the application's view is unknown to the
framework, then you must provide the code to move to the chosen point.
You should perform most actions before calling CView::EndPrintPreview . This call reverses the effects of
DoPrintPreview and deletes pView, pDC, and pInfo.

// Any further cleanup should be done here.


CView::EndPrintPreview(pDC, pInfo, point, pView);

CWinApp::OnFilePrintSetup
This must be mapped for the Print Setup menu item. In most cases, it is not necessary to override the
implementation.

Page Nomenclature
Another issue is that of page numbering and order. For simple word processor type applications, this is a
straightforward issue. Most print preview systems assume that each printed page corresponds to one page in the
document.
In trying to provide a generalized solution, there are several things to consider. Imagine a CAD system. The user
has a drawing that covers several E-size sheets. On an E-size (or a smaller, scaled) plotter, page numbering would
be as in the simple case. But on a laser printer, printing 16 A-size pages per sheet, what does print preview
consider a "page"
As the introductory paragraph states, Print Preview is acting like a printer. Therefore, the user will see what would
come out of the particular printer that is selected. It is up to the view to determine what image is printed on each
page.
The page description string in the CPrintInfo structure provides a means of displaying the page number to the
user if it can be represented as one number per page (as in "Page 1" or "Pages 1-2"). This string is used by the
default implementation of CPreviewView::OnDisplayPageNumber . If a different display is needed, one may override
this virtual function to provide, for example, "Sheet1, Sections A, B".

See also
Technical Notes by Number
Technical Notes by Category
TN031: Control Bars
3/27/2020 • 9 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the control bar classes in MFC: the general CControlBar, CStatusBar, CToolBar, CDialogBar, and
CDockBar .

CControlBar
A ControlBar is a CWnd -derived class that:
Is aligned to the top or bottom of a frame window.
May contain child items that are either HWND-based controls (for example, CDialogBar ) or non- HWND
based items (for example, CToolBar , CStatusBar ).
Control bars support the additional styles:
CBRS_TOP (The default) pin the control bar to the top.
CBRS_BOTTOM Pin the control bar to the bottom.
CBRS_NOALIGN Do not reposition the control bar when the parent resizes.
Classes derived from CControlBar provide more interesting implementations:
CStatusBar A status bar, items are status bar panes containing text.
CToolBar A toolbar, items are bitmap buttons aligned in a row.
CDialogBar A toolbar-like frame containing standard windows controls (created from a dialog template
resource).
CDockBar A generalized docking area for other CControlBar derived objects. The specific member
functions and variables available in this class are likely to change in future releases.
All control bar objects/windows will be child windows of some parent frame window. They are usually added as a
sibling to the client area of the frame (for example, an MDI Client or view). The child window ID of a control bar is
important. The default layout of control bar only works for control bars with IDs in the range of
AFX_IDW_CONTROLBAR_FIRST to AFX_IDW_CONTROLBAR_LAST. Note that even though there is a range of 256
control bar IDs, the first 32 of these control bar IDs are special since they are directly supported by the print
preview architecture.
The CControlBar class gives standard implementation for:
Aligning the control bar to the top, bottom, or either side of the frame.
Allocating control item arrays.
Supporting the implementation of derived classes.
C++ control bar objects will usually be embedded as members of a CFrameWnd derived class, and will be cleaned
up when the parent HWND and object are destroyed. If you need to allocate a control bar object on the heap, you
can simply set the m_bAutoDestruct member to TRUE to make the control bar "delete this " when the HWND is
destroyed.

NOTE
If you create your own CControlBar -derived class, rather than using one of MFC's derived classes, such as CStatusBar ,
CToolBar , or CDialogBar , you will need to set the m_dwStyle data member. This can be done in the override of Create
:

// CMyControlBar is derived from CControlBar


BOOL CMyControlBar::Create(CWnd* pParentWnd,
DWORD dwStyle,
UINT nID)
{
m_dwStyle = dwStyle;

.
.
.
}

Control Bar Layout Algorithm


The control bar layout algorithm is very simple. The frame window sends a message WM_SIZEPARENT to all
children in the control bar range. Along with this message, a pointer to the parent's client rectangle is passed. This
message is sent to children in Z-order. The control-bar children use this information to position themselves and to
decrease the size of the parent's client area. The final rectangle that is left for the normal client area (less control
bars) is used to position the main client window (usually an MDI client, view or splitter window).
See CWnd::RepositionBars and CFrameWnd::RecalcLayout for more details.
MFC private Windows messages, including WM_SIZEPARENT, are documented in Technical Note 24.

CStatusBar
A status bar is a control bar that has a row of text output panes. There are two common ways to use text output
panes:
As a message line
(for example, the standard menu help message line). These are usually accessed by a 0-based indexed
As status indicators
(for example, the CAP, NUM and SCRL indicators). These are usually accessed by string/command ID.
The font for the status bar is 10-point MS Sans Serif (dictated by the Windows Interface Application Design Guide
or the font mappers best match of a 10-point Swiss proportional font). On certain versions of Windows, such as
the Japanese edition, the fonts selected are different.
The colors used in the status bar are also consistent with the recommendation of the Windows Interface
Application Design Guide. These colors are not hard coded and are changed dynamically in response to user
customization in Control Panel.
IT EM W IN DO W S C O LO R VA L UE DEFA ULT RGB

Status bar background COLOR_BTNFACE RGB(192, 192, 192)

Status bar text COLOR_BTNTEXT RGB(000, 000, 000)

Status bar top/left edges COLOR_BTNHIGHLIGHT RGB(255, 255, 255)

Status bar bot/right edges COLOR_BTNSHADOW RGB(128, 128, 128)

CCmdUI Suppor t for CStatusBar


The way indicators are usually updated is through the ON_UPDATE_COMMAND_UI mechanism. On idle time, the
status bar will call the ON_UPDATE_COMMAND_UI handler with the string ID of the indicator pane.
The ON_UPDATE_COMMAND_UI handler can call:
Enable : To enable or disable the pane. A disabled pane looks exactly like an enabled pane but the text is
invisible (that is, turns off the text indicator).
SetText : To change the text. Be careful if you use this because the pane will not automatically resize.

Refer to class CStatusBar in the Class Library Reference for details about CStatusBar creation and customization
APIs. Most customization of status bars should be done before the status bar is initially made visible.
The status bar supports only one stretchy pane, usually the first pane. The size of that pane is really a minimum
size. If the status bar is bigger than the minimum size of all the panes, any extra width will be given to the stretchy
pane. The default application with a status bar has right-aligned indicators for CAP, NUM and SCRL since the first
pane is stretchy.

CToolBar
A toolbar is a control bar with a row of bitmap buttons that may include separators. Two styles of buttons are
supported: pushbuttons and check box buttons. Radio group functionality can be built with check box buttons
and ON_UPDATE_COMMAND_UI.
All the bitmap buttons in the toolbar are taken from one bitmap. This bitmap must contain one image or glyph
for each button. Typically the order of the images/glyphs in the bitmap is the same order they will be drawn on
the screen. (This can be changed using the customization APIs.)
Each button must be the same size. The default is the standard 24x22 pixels. Each image/glyph must be the same
size and must be side-by-side in the bitmap. The default image/glyph size is 16x15 pixels. Therefore, for a toolbar
with 10 buttons (using standard sizes), you need a bitmap that is 160 pixels wide and 15 pixels high.
Each button has one and only one image/glyph. The different button states and styles (for example, pressed, up,
down, disabled, disabled down, indeterminate) are algorithmically generated from that one image/glyph. Any
color bitmap or DIB can be used in theory. The algorithm for generating the different button states works best if
the original image is shades of gray. Look at the standard toolbar buttons and the toolbar button clipart provided
in MFC General sample CLIPART for examples.
The colors used in the toolbar are also consistent with the recommendation of the Windows Interface Application
Design Guide. These colors are not hard coded and are changed dynamically in response to user customization in
Control Panel.
IT EM W IN DO W S C O LO R VA L UE DEFA ULT RGB

ToolBar background COLOR_BTNFACE RGB(192,192,192)

ToolBar buttons top/left edges COLOR_BTNHIGHLIGHT RGB(255,255,255)

ToolBar buttons bot/right edges COLOR_BTNSHADOW RGB(128,128,128)

In addition, the toolbar bitmap buttons are recolored as though they were standard Windows button controls.
This recoloring occurs when the bitmap is loaded from the resource and in response to a change in system colors
in response to user customization in Control Panel. The following colors in a toolbar bitmap will be recolored
automatically so they should be used with caution. If you do not wish to have a portion of your bitmap recolored,
then use a color that closely approximates one of the mapped RGB values. The mapping is done based on exact
RGB values.

RGB VA L UE DY N A M IC A L LY M A P P ED C O LO R VA L UE

RGB(000, 000, 000) COLOR_BTNTEXT

RGB(128, 128, 128) COLOR_BTNSHADOW

RGB(192, 192, 192) COLOR_BTNFACE

RGB(255, 255, 255) COLOR_BTNHIGHLIGHT

Refer to class CToolBar the Class Library Reference for details about the CToolBar creation and customization
APIs. Most customization of toolbars should be done before the toolbar is initially made visible.
The customization APIs can be used to adjust the button IDs, styles, spacer width and which image/glyph is used
for what button. By default you do not need to use these APIs.

CCmdUI Support for CToolBar


The way toolbar buttons are always updated is through the ON_UPDATE_COMMAND_UI mechanism. On idle
time, the toolbar will call the ON_UPDATE_COMMAND_UI handler with the command ID of that button.
ON_UPDATE_COMMAND_UI is not called for separators, but it is called for pushbuttons and check box buttons.
The ON_UPDATE_COMMAND_UI handler can call:
Enable : To enable or disable the button. This works equally for pushbuttons and check box buttons.
SetCheck: To set the check state of a button. Calling this for a toolbar button will turn it into a check box
button. SetCheck takes a parameter which can be 0 (not checked), 1 (checked) or 2 (indeterminate)
SetRadio : Shorthand for SetCheck .

Check box buttons are "AUTO" check box buttons; that is, when the user presses them they will immediately
change state. Checked is the down or depressed state. There is no built-in user interface way to change a button
into the "indeterminate" state; that must be done through code.
The customization APIs will permit you to change the state of a given toolbar button, preferably you should
change these states in the ON_UPDATE_COMMAND_UI handler for the command the toolbar button represents.
Remember, the idle processing will change the state of toolbar buttons with the ON_UPDATE_COMMAND_UI
handler, so any changes to these states made through SetButtonStyle may get lost after the next idle.
Toolbar buttons will send WM_COMMAND messages like normal buttons or menu items and are normally
handled by an ON_COMMAND handler in the same class that provides the ON_UPDATE_COMMAND_UI handler.
There are four Toolbar button styles (TBBS_ values) used for display states:
TBBS_CHECKED: Check box is currently checked (down).
TBBS_INDETERMINATE: Check box is currently indeterminate.
TBBS_DISABLED: Button is currently disabled.
TBBS_PRESSED: Button is currently pressed.
The six official Windows Interface Application Design Guide button styles are represented by the following TBBS
values:
Up = 0
Mouse Down = TBBS_PRESSED (| any other style)
Disabled = TBBS_DISABLED
Down = TBBS_CHECKED
Down Disabled = TBBS_CHECKED | TBBS_DISABLED
Indeterminate = TBBS_INDETERMINATE

CDialogBar
A dialog bar is a control bar that contains standard Windows controls. It acts like a dialog in that it contains the
controls and supports tabbing between them. It also acts like a dialog in that it uses a dialog template to
represent the bar.
A CDialogBar is used for the print-preview toolbar, which contains standard pushbutton controls.
Using a CDialogBar is like using a CFormView . You must define a dialog template for the dialog bar and remove
all the styles except WS_CHILD. Note that the dialog must not be visible.
The control notifications for a CDialogBar will be sent to the parent of the control bar ( just like toolbar buttons).

CCmdUI Support for CDialogBar


Dialog bar buttons should be updated through the ON_UPDATE_COMMAND_UI handler mechanism. At idle time,
the dialog bar will call the ON_UPDATE_COMMAND_UI handler with the command ID of all the buttons that have
a ID >= 0x8000 (that is, in the range of command IDs).
The ON_UPDATE_COMMAND_UI handler can call:
Enable: to enable or disable the button.
SetText: to change the text of the button.
Customization can be done through standard window manager APIs.

See also
Technical Notes by Number
Technical Notes by Category
TN032: MFC Exception Mechanism
5/14/2019 • 2 minutes to read • Edit Online

Previous versions of Visual C++ did not support the standard C++ exception mechanism, and MFC provided
macros TRY/CATCH/THROW that were used instead. This version of Visual C++ fully supports C++ exceptions.
This note covered some of the advanced implementation details of the previous macros including how to
automatically cleanup stack based objects. Because C++ exceptions support stack unwinding by default, this
technical note is no longer necessary.
Refer to Exceptions: Using MFC Macros and C++ Exceptions for more information on the differences between the
MFC macros and the new C++ keywords.

See also
Technical Notes by Number
Technical Notes by Category
TN033: DLL Version of MFC
3/27/2020 • 27 minutes to read • Edit Online

This note describes how you can use the MFCxx.DLL and MFCxxD.DLL (where x is the MFC version number) shared
dynamic link libraries with MFC applications and MFC extension DLLs. For more information about regular MFC
DLLs, see Using MFC as Part of a DLL.
This technical note covers three aspects of DLLs. The last two are for the more advanced users:
How you build an MFC Extension DLL
How you build an MFC application that uses the DLL version of MFC
How the MFC shared dynamic-link libraries are implemented
If you are interested in building a DLL using MFC that can be used with non-MFC applications (this is called a
regular MFC DLL), refer to Technical Note 11.

Overview of MFCxx.DLL Support: Terminology and Files


Regular MFC DLL : You use a regular MFC DLL to build a stand-alone DLL using some of the MFC classes.
Interfaces across the App/DLL boundary are "C" interfaces, and the client application does not have to be an MFC
application.
This is the version of DLL support supported in MFC 1.0. It is described in Technical Note 11 and the MFC
Advanced Concepts sample DLLScreenCap.

NOTE
As of Visual C++ version 4.0, the term USRDLL is obsolete and has been replaced by a regular MFC DLL that statically links
to MFC. You may also build a regular MFC DLL that dynamically links to MFC.

MFC 3.0 (and above) supports regular MFC DLLs with all the new functionality including the OLE and Database
classes.
AFXDLL : This is also referred to as the shared version of the MFC libraries. This is the new DLL support added in
MFC 2.0. The MFC library itself is in a number of DLLs (described below) and a client application or DLL
dynamically links the DLLs that it requires. Interfaces across the application/DLL boundary are C++/MFC class
interfaces. The client application MUST be an MFC application. This supports all MFC 3.0 functionality (exception:
UNICODE is not supported for the database classes).

NOTE
As of Visual C++ version 4.0, this type of DLL is referred to as an "Extension DLL."

This note will use MFCxx.DLL to refer to the entire MFC DLL set, which includes:
Debug: MFCxxD.DLL (combined) and MFCSxxD.LIB (static).
Release: MFCxx.DLL (combined) and MFCSxx.LIB (static).
Unicode Debug: MFCxxUD.DLL (combined) and MFCSxxD.LIB (static).
Unicode Release: MFCxxU.DLL (combined) and MFCSxxU.LIB (static).

NOTE
The MFCSxx[U][D].LIB libraries are used in conjunction with the MFC shared DLLs. These libraries contain code that must be
statically linked to the application or DLL.

An application links to the corresponding import libraries:


Debug: MFCxxD.LIB
Release: MFCxx.LIB
Unicode Debug: MFCxxUD.LIB
Unicode Release: MFCxxU.LIB
An "MFC Extension DLL" is a DLL built upon MFCxx.DLL (and/or the other MFC shared DLLs). Here the MFC
component architecture kicks in. If you derive a useful class from an MFC class, or build another MFC-like toolkit,
you can place it in a DLL. That DLL uses MFCxx.DLL, as does the ultimate client application. This permits reusable
leaf classes, reusable base classes, and reusable view/document classes.

Pros and Cons


Why should you use the shared version of MFC
Using the shared library can result in smaller applications (a minimal application that uses most of the MFC
library is less than 10K).
The shared version of MFC supports MFC Extension DLLs and regular MFC DLLs.
Building an application that uses the shared MFC libraries is faster than building a statically linked MFC
application because it is not necessary to link MFC itself. This is especially true in DEBUG builds where the
linker must compact the debug information — by linking with a DLL that already contains the debug
information, there is less debug information to compact within your application.
Why should you not use the shared version of MFC:
Shipping an application that uses the shared library requires that you ship the MFCxx.DLL (and others) library
with your program. MFCxx.DLL is freely redistributable like many DLLs, but you still must install the DLL in your
SETUP program. In addition, you must ship the MSVCRTxx.DLL, which contains the C-runtime library which is
used both by your program and the MFC DLLs themselves.

How to Write an MFC Extension DLL


An MFC Extension DLL is a DLL containing classes and functions written to embellish the functionality of the MFC
classes. An MFC Extension DLL uses the shared MFC DLLs in the same way an application uses it, with a few
additional considerations:
The build process is similar to building an application that uses the shared MFC libraries with a few
additional compiler and linker options.
An MFC Extension DLL does not have a CWinApp -derived class.
An MFC Extension DLL must provide a special DllMain . AppWizard supplies a DllMain function that you
can modify.
An MFC Extension DLL will usually provide an initialization routine to create a CDynLinkLibrary if the MFC
extension DLL wishes to export CRuntimeClass es or resources to the application. A derived class of
CDynLinkLibrary may be used if per-application data must be maintained by the MFC extension DLL.

These considerations are described in more detail below. You should also refer to the MFC Advanced Concepts
sample DLLHUSK since it illustrates:
Building an application using the shared libraries. (DLLHUSK.EXE is an MFC application that dynamically
links to the MFC libraries as well as other DLLs.)
Building an MFC Extension DLL. (Note the special flags such as _AFXEXT that are used in building an MFC
extension DLL)
Two examples of MFC Extension DLLs. One shows the basic structure of an MFC Extension DLL with limited
exports (TESTDLL1) and the other shows exporting an entire class interface (TESTDLL2).
Both the client application and any MFC extension DLLs must use the same version of MFCxx.DLL. You should
follow the convention of MFC DLL and provide both a debug and retail (/release) version of your MFC extension
DLL. This permits client programs to build both debug and retail versions of their applications and link them with
the appropriate debug or retail version of all DLLs.

NOTE
Because C++ name mangling and export issues, the export list from an MFC extension DLL may be different between the
debug and retail versions of the same DLL and DLLs for different platforms. The retail MFCxx.DLL has about 2000 exported
entry points; the debug MFCxxD.DLL has about 3000 exported entry points.

Quick Note on Memory Management


The section titled "Memory Management," near the end of this technical note, describes the implementation of the
MFCxx.DLL with the shared version of MFC. The information you need to know to implement just an MFC
extension DLL is described here.
MFCxx.DLL and all MFC extension DLLs loaded into a client application's address space will use the same memory
allocator, resource loading and other MFC "global" states as if they were in the same application. This is significant
because the non-MFC DLL libraries and regular MFC DLLs that statically link to MFC do the exact opposite and
have each DLL allocating out of its own memory pool.
If an MFC extension DLL allocates memory, then that memory can freely intermix with any other application-
allocated object. Also, if an application that uses the shared MFC libraries crashes, the protection of the operating
system will maintain the integrity of any other MFC application sharing the DLL.
Similarly other "global" MFC states, like the current executable file to load resources from, are also shared between
the client application and all MFC extension DLLs as well as MFCxx.DLL itself.
Building an MFC extension DLL
You can use AppWizard to create an MFC extension DLL project, and it will automatically generate the appropriate
compiler and linker settings. It was also generate a DllMain function that you can modify.
If you are converting an existing project to an MFC extension DLL, start with the standard rules for building an
application using the shared version of MFC, then do the following:
Add /D_AFXEXT to the compiler flags. On the Project Properties dialog, select the C/C++ node. Then select
the Preprocessor category. Add _AFXEXT to the Define Macros field, separating each of the items with
semicolons.
Remove the /Gy compiler switch. On the Project Properties dialog, select the C/C++ node. Then select the
Code Generation category. Ensure that the "Enable Function-Level Linking" option is not enabled. This will
make it easier to export classes because the linker will not remove unreferenced functions. If the original
project is used to build a regular MFC DLL statically linked to MFC, change the /MT[d] compiler option to
/MD[d] .
Build an export library with the /DLL option to LINK. This will be set when you create a new target,
specifying Win32 Dynamic-Link Library as the target type.
Changing your Header Files
The goal of an MFC extension DLL is usually to export some common functionality to one or more applications
that can use that functionality. This boils down to exporting classes and global functions that are available for your
client applications.
In order to do this you must insure that each of the member functions is marked as import or export as
appropriate. This requires special declarations: __declspec(dllexport) and __declspec(dllimport) . When your
classes are used by the client applications, you want them to be declared as __declspec(dllimport) . When the MFC
extension DLL itself is being built, they should be declared as __declspec(dllexport) . In addition, the functions
must be actually exported, so that the client programs bind to them at load time.
To export your entire class, use AFX_EXT_CLASS in the class definition. This macro is defined by the framework as
__declspec(dllexport) when _AFXDLL and _AFXEXT is defined, but defined as __declspec(dllimport) when
_AFXEXT is not defined. _AFXEXT as described above, is only defined when building your MFC extension DLL. For
example:

class AFX_EXT_CLASS CExampleExport : public CObject


{ /* ... class definition ... */ };

Not Exporting the Entire Class


Sometimes you may want to export just the individual necessary members of your class. For example, if you are
exporting a CDialog -derived class, you might only need to export the constructor and the DoModal call. You can
export these members using the DLL's .DEF file, but you can also use AFX_EXT_CLASS in much the same way on the
individual members you need to export.
For example:

class CExampleDialog : public CDialog


{
public:
AFX_EXT_CLASS CExampleDialog();
AFX_EXT_CLASS int DoModal();
// rest of class definition
// ...
};

When you do this, you may run into an additional problem because you are no longer exporting all members of
the class. The problem is in the way that MFC macros work. Several of MFC's helper macros actually declare or
define data members. Therefore, these data members will also need to be exported from your DLL.
For example, the DECLARE_DYNAMIC macro is defined as follows when building an MFC extension DLL:

#define DECLARE_DYNAMIC(class_name) \
protected: \
static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static AFX_DATA CRuntimeClass class##class_name; \
virtual CRuntimeClass* GetRuntimeClass() const; \

The line that begins "static AFX_DATA " is declaring a static object inside of your class. To export this class correctly
and access the runtime information from a client .EXE, you need to export this static object. Because the static
object is declared with the modifier AFX_DATA , you only need to define AFX_DATA to be __declspec(dllexport)
when building your DLL and define it as __declspec(dllimport) when building your client executable.
As discussed above, AFX_EXT_CLASS is already defined in this way. You just need to re-define AFX_DATA to be the
same as AFX_EXT_CLASS around your class definition.
For example:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_CLASS
class CExampleView : public CView
{
DECLARE_DYNAMIC()
// ... class definition ...
};
#undef AFX_DATA
#define AFX_DATA

MFC always uses the AFX_DATA symbol on data items it defines within its macros, so this technique will work for
all such scenarios. For example, it will work for DECLARE_MESSAGE_MAP.

NOTE
If you are exporting the entire class rather than selected members of the class, static data members are automatically
exported.

You can use the same technique to automatically export the CArchive extraction operator for classes that use the
DECLARE_SERIAL and IMPLEMENT_SERIAL macros. Export the archive operator by bracketing the class
declarations (located in the .H file) with the following code:

#undef AFX_API
#define AFX_API AFX_EXT_CLASS

/* your class declarations here */

#undef AFX_API
#define AFX_API

Limitations of _AFXEXT
You can use the _AFXEXT pre-processor symbol for your MFC extension DLLs as long as you do not have multiple
layers of MFC extension DLLs. If you have MFC extension DLLs that call or derive from classes in your own MFC
extension DLLs, which then derive from the MFC classes, you must use your own preprocessor symbol to avoid
ambiguity.
The problem is that in Win32, you must explicitly declare any data as __declspec(dllexport) if it is to be exported
from a DLL, and __declspec(dllimport) if it is to be imported from a DLL. When you define _AFXEXT , the MFC
headers make sure that AFX_EXT_CLASS is defined correctly.
When you have multiple layers, one symbol such as AFX_EXT_CLASS is not sufficient, since an MFC extension DLL
may be exporting new classes as well as importing other classes from another MFC extension DLL. In order to deal
with this problem, use a special preprocessor symbol that indicates that you are building the DLL itself versus
using the DLL. For example, imagine two MFC extension DLLs, A.DLL, and B.DLL. They each export some classes in
A.H and B.H, respectively. B.DLL uses the classes from A.DLL. The header files would look something like this:
/* A.H */
#ifdef A_IMPL
#define CLASS_DECL_A __declspec(dllexport)
#else
#define CLASS_DECL_A __declspec(dllimport)
#endif

class CLASS_DECL_A CExampleA : public CObject


{ /* ... class definition ... */ };

/* B.H */
#ifdef B_IMPL
#define CLASS_DECL_B __declspec(dllexport)
#else
#define CLASS_DECL_B __declspec(dllimport)
#endif

class CLASS_DECL_B CExampleB : public CExampleA


{ /* ... class definition ... */ };

When A.DLL is built, it is built with /DA_IMPL and when B.DLL is built, it is built with /DB_IMPL . By using separate
symbols for each DLL, CExampleB is exported and CExampleA is imported when building B.DLL. CExampleA is
exported when building A.DLL and imported when used by B.DLL (or some other client).
This type of layering cannot be done when using the built-in AFX_EXT_CLASS and _AFXEXT preprocessor symbols.
The technique described above solves this problem in a manner not unlike the mechanism MFC itself uses when
building its OLE, Database, and Network MFC extension DLLs.
Not Exporting the Entire Class
Again, you will have to take special care when you are not exporting an entire class. You have to ensure that the
necessary data items created by the MFC macros are exported correctly. This can be done by re-defining AFX_DATA
to your specific class' macro. This should be done any time you are not exporting the entire class.
For example:

// A.H
#ifdef A_IMPL
#define CLASS_DECL_A _declspec(dllexport)
#else
#define CLASS_DECL_A _declspec(dllimport)
#endif

#undef AFX_DATA
#define AFX_DATA CLASS_DECL_A

class CExampleA : public CObject


{
DECLARE_DYNAMIC()
CLASS_DECL_A int SomeFunction();
// class definition
// ...
};

#undef AFX_DATA
#define AFX_DATA

DllMain
The following is the exact code you should place in your main source file for your MFC extension DLL. It should
come after the standard includes. Note that when you use AppWizard to create starter files for an MFC extension
DLL, it supplies a DllMain for you.
#include "afxdllx.h"

static AFX_EXTENSION_MODULE extensionDLL;

extern "C" int APIENTRY


DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// MFC extension DLL one-time initialization
if (!AfxInitExtensionModule(
extensionDLL, hInstance))
return 0;

// TODO: perform other initialization tasks here


}
else if (dwReason == DLL_PROCESS_DETACH)
{
// MFC extension DLL per-process termination
AfxTermExtensionModule(extensionDLL);

// TODO: perform other cleanup tasks here


}
return 1; // ok
}

The call to AfxInitExtensionModule captures the modules runtime-classes ( CRuntimeClass structures) as well as its
object factories ( COleObjectFactory objects) for use later when the CDynLinkLibrary object is created. The
(optional) call to AfxTermExtensionModule allows MFC to cleanup the MFC extension DLL when each process
detaches (which happens when the process exits, or when the DLL is unloaded as a result of a FreeLibrary call)
from the MFC extension DLL. Since most MFC extension DLLs are not dynamically loaded (usually, they are linked
via their import libraries), the call to AfxTermExtensionModule is usually not necessary.
If your application loads and frees MFC extension DLLs dynamically, be sure to call AfxTermExtensionModule as
shown above. Also be sure to use AfxLoadLibrary and AfxFreeLibrary (instead of Win32 functions LoadLibrary
and FreeLibrary ) if your application uses multiple threads or if it dynamically loads an MFC extension DLL. Using
AfxLoadLibrary and AfxFreeLibrary insures that the startup and shutdown code that executes when the MFC
extension DLL is loaded and unloaded does not corrupt the global MFC state.
The header file AFXDLLX.H contains special definitions for structures used in MFC extension DLLs, such as the
definition for AFX_EXTENSION_MODULE and CDynLinkLibrary .
The global extensionDLL must be declared as shown. Unlike the 16-bit version of MFC, you can allocate memory
and call MFC functions during this time, since the MFCxx.DLL is fully initialized by the time your DllMain is called.
Sharing Resources and Classes
Simple MFC extension DLLs need only export a few low-bandwidth functions to the client application and nothing
more. More user-interface intensive DLLs may want to export resources and C++ classes to the client application.
Exporting resources is done through a resource list. In each application is a singly linked list of CDynLinkLibrary
objects. When looking for a resource, most of the standard MFC implementations that load resources look first at
the current resource module ( AfxGetResourceHandle ) and if not found walk the list of CDynLinkLibrary objects
attempting to load the requested resource.
Dynamic creation of C++ objects given a C++ class name is similar. The MFC object deserialization mechanism
needs to have all of the CRuntimeClass objects registered so that it can reconstruct by dynamically creating C++
object of the required type based on what was stored earlier.
If you want the client application to use classes in your MFC extension DLL that are DECLARE_SERIAL , then you will
need to export your classes to be visible to the client application. This is also done by walking the CDynLinkLibrary
list.
In the case of the MFC Advanced Concepts sample DLLHUSK, the list looks something like:

head -> DLLHUSK.EXE - or - DLLHUSK.EXE


| |
TESTDLL2.DLL TESTDLL2.DLL
| |
TESTDLL1.DLL TESTDLL1.DLL
| |
| |
MFC90D.DLL MFC90.DLL

The MFCxx.DLL is usually last on the resource and class list. MFCxx.DLL includes all of the standard MFC resources,
including prompt strings for all the standard command IDs. Placing it at the tail of the list allows DLLs and the
client application itself to not have a their own copy of the standard MFC resources, but to rely on the shared
resources in the MFCxx.DLL instead.
Merging the resources and class names of all DLLs into the client application's name space has the disadvantage
that you have to be careful what IDs or names you pick. You can of course disable this feature by not exporting
either your resources or a CDynLinkLibrary object to the client application. The DLLHUSK sample manages the
shared resource name space by using multiple header files. See Technical Note 35 for more tips on using shared
resource files.
Initializing the DLL
As mentioned above, you will usually want to create a CDynLinkLibrary object in order to export your resources
and classes to the client application. You will need to provide an exported entry point to initialize the DLL.
Minimally, this is a void routine that takes no arguments and returns nothing, but it can be anything you like.
Each client application that wants to use your DLL must call this initialization routine, if you use this approach. You
may also allocate this CDynLinkLibrary object in your DllMain just after calling AfxInitExtensionModule .
The initialization routine must create a CDynLinkLibrary object in the current application's heap, wired up to your
MFC extension DLL information. This can be done with the following:

extern "C" extern void WINAPI InitXxxDLL()


{
new CDynLinkLibrary(extensionDLL);
}

The routine name, InitXxxDLL in this example, can be anything you want. It does not need to be extern "C" , but
doing so makes the export list easier to maintain.

NOTE
If you use your MFC extension DLL from a regular MFC DLL, you must export this initialization function. This function must
be called from the regular MFC DLL before using any MFC extension DLL classes or resources.

Exporting Entries
The simple way to export your classes is to use __declspec(dllimport) and __declspec(dllexport) on each class
and global function you wish to export. This makes it a lot easier, but is less efficient than naming each entry point
(described below) since you have less control over what functions are exported and you cannot export the
functions by ordinal. TESTDLL1 and TESTDLL2 use this method to export their entries.
A more efficient method (and the method used by MFCxx.DLL) is to export each entry by hand by naming each
entry in the .DEF file. Since we are exporting selective exports from our DLL (that is, not everything), we must
decide which particular interfaces we wish to export. This is difficult since you must specify the mangled names to
the linker in the form of entries in the .DEF file. Don't export any C++ classes unless you really need to have a
symbolic link for it.
If you have tried exporting C++ classes with a .DEF file before, you may want to develop a tool to generate this list
automatically. This can be done using a two-stage link process. Link your DLL once with no exports, and allow the
linker to generate a .MAP file. The .MAP file can be used to generate a list of functions that should be exported, so
with some rearranging, it can be used to generate your EXPORT entries for your .DEF file. The export list for
MFCxx.DLL and the OLE and Database MFC extension DLLs, several thousand in number, was generated with such
a process (although it is not completely automatic and requires some hand tuning every once in a while).
CWinApp vs. CDynLinkLibrary
An MFC Extension DLL does not have a CWinApp -derived object of its own; instead it must work with the CWinApp -
derived object of the client application. This means that the client application owns the main message pump, the
idle loop and so on.
If your MFC Extension DLL needs to maintain extra data for each application, you can derive a new class from
CDynLinkLibrary and create it in the InitXxxDLL routine describe above. When running, the DLL can check the
current application's list of CDynLinkLibrary objects to find the one for that particular MFC extension DLL.
Using Resources in Your DLL Implementation
As mentioned above, the default resource load will walk the list of CDynLinkLibrary objects looking for the first
EXE or DLL that has the requested resource. All MFC APIs as well as all the internal code uses
AfxFindResourceHandle to walk the resource list to find any resource, no matter where it may reside.

If you wish to only load resources from a specific place, use the APIs AfxGetResourceHandle and
AfxSetResourceHandle to save the old handle and set the new handle. Be sure to restore the old resource handle
before you return to the client application. The sample TESTDLL2 uses this approach for explicitly loading a menu.
Walking the list has the disadvantages that it is slightly slower and requires managing resource ID ranges. It has
the advantage that a client application that links to several MFC extension DLLs can use any DLL-provided
resource without having to specify the DLL instance handle. AfxFindResourceHandle is an API used for walking the
resource list to look for a given match. It takes the name and type of a resource and returns the resource handle
where it was first found (or NULL).

Writing an Application That Uses the DLL Version


Application Requirements
An application that uses the shared version of MFC must follow a few simple rules:
It must have a CWinApp object and follow the standard rules for a message pump.
It must be compiled with a set of required compiler flags (see below).
It must link with the MFCxx import libraries. By setting the required compiler flags, the MFC headers
determine at link time which library the application should link with.
To run the executable, MFCxx.DLL must be on the path or in the Windows system directory.
Building with the Development Environment
If you are using the internal makefile with most of the standard defaults, you can easily change the project to build
the DLL version.
The following step assumes you have a correctly functioning MFC application linked with NAFXCWD.LIB (for
debug) and NAFXCW.LIB (for retail) and you want to convert it to use the shared version of the MFC library. You
are running the Visual C++ environment and have an internal project file.
1. On the Projects menu, click Proper ties . In the General page under Project Defaults , set Microsoft
Foundation Classes to Use MFC in a Shared DLL (MFCxx(d).dll).
Building with NMAKE
If you are using the external makefile feature of the Visual C++, or are using NMAKE directly, you will have to edit
your makefile to support compiler and linker options
Required compiler flags:
/D_AFXDLL /MD /D_AFXDLL
The standard MFC headers need this symbol to be defined:
/MD The application must use the DLL version of the C run-time library
All other compiler flags follow the MFC defaults (for example, _DEBUG for debug).
Edit the linker list of libraries. Change NAFXCWD.LIB to MFCxxD.LIB and change NAFXCW.LIB to MFCxx.LIB. Replace
LIBC.LIB with MSVCRT.LIB. As with any other MFC library it is important that MFCxxD.LIB is placed before any C-
runtime libraries.
Optionally add /D_AFXDLL to both your retail and debug resource compiler options (the one that actually
compiles the resources with /R ). This makes your final executable smaller by sharing the resources that are
present in the MFC DLLs.
A full rebuild is required after these changes are made.
Building the Samples
Most of the MFC sample programs can be built from Visual C++ or from a shared NMAKE-compatible MAKEFILE
from the command line.
To convert any of these samples to use MFCxx.DLL, you can load the .MAK file into the Visual C++ and set the
Project options as described above. If you are using the NMAKE build, you can specify "AFXDLL=1" on the NMAKE
command line and that will build the sample using the shared MFC libraries.
The MFC Advanced Concepts sample DLLHUSK is built with the DLL version of MFC. This sample not only
illustrates how to build an application linked with MFCxx.DLL, but it also illustrates other features of the MFC DLL
packaging option such as MFC Extension DLLs described later in this technical note.
Packaging Notes
The retail version of the DLLs (MFCxx[U].DLL) are freely redistributable. The debug version of the DLLs are not
freely redistributable and should be used only during the development of your application.
The debug DLLs are provided with debugging information. By using the Visual C++ debugger, you can trace
execution of your application as well as the DLL. The Release DLLs (MFCxx[U].DLL) do not contain debugging
information.
If you customize or rebuild the DLLs, then you should call them something other than "MFCxx" The MFC SRC file
MFCDLL.MAK describes build options and contains the logic for renaming the DLL. Renaming the files is necessary,
since these DLLs are potentially shared by many MFC applications. Having your custom version of the MFC DLLs
replace those installed on the system may break another MFC application using the shared MFC DLLs.
Rebuilding the MFC DLLs is not recommended.

How the MFCxx.DLL Is Implemented


The following section describes how the MFC DLL (MFCxx.DLL and MFCxxD.DLL) is implemented. Understanding
the details here are also not important if all you want to do is use the MFC DLL with your application. The details
here are not essential for understanding how to write an MFC extension DLL, but understanding this
implementation may help you write your own DLL.
Implementation Overview
The MFC DLL is really a special case of an MFC Extension DLL as described above. It has a very large number of
exports for a large number of classes. There are a few additional things we do in the MFC DLL that make it even
more special than a regular MFC extension DLL.
Win32 Does Most of the Work
The 16-bit version of MFC needed a number of special techniques including per-app data on the stack segment,
special segments created by some 80x86 assembly code, per-process exception contexts, and other techniques.
Win32 directly supports per-process data in a DLL, which is what you want most of the time. For the most part
MFCxx.DLL is just NAFXCW.LIB packaged in a DLL. If you look at the MFC source code, you'll find very few #ifdef
_AFXDLL, since there are very few special cases that need to be made. The special cases that are there are
specifically to deal with Win32 on Windows 3.1 (otherwise known as Win32s). Win32s does not support per-
process DLL data directly so the MFC DLL must use the thread-local storage (TLS) Win32 APIs to obtain process
local data.
Impact on Library Sources, Additional Files
The impact of the _AFXDLL version on the normal MFC class library sources and headers is relatively minor. There
is a special version file (AFXV_DLL.H) as well as an additional header file (AFXDLL_.H) included by the main
AFXWIN.H header. The AFXDLL_.H header includes the CDynLinkLibrary class and other implementation details of
both _AFXDLL applications and MFC Extension DLLs. The AFXDLLX.H header is provided for building MFC
Extension DLLs (see above for details).
The regular sources to the MFC library in MFC SRC have some additional conditional code under the _AFXDLL
#ifdef. An additional source file (DLLINIT.CPP) contains the extra DLL initialization code and other glue for the
shared version of MFC.
In order to build the shared version of MFC, additional files are provided. (See below for details on how to build
the DLL.)
Two .DEF files are used for exporting the MFC DLL entry points for debug (MFCxxD.DEF) and release
(MFCxx.DEF) versions of the DLL.
An .RC file (MFCDLL.RC) contains all the standard MFC resources and a VERSIONINFO resource for the DLL.
A .CLW file (MFCDLL.CLW) is provided to allow browsing the MFC classes using ClassWizard. Note: this
feature is not particular to the DLL version of MFC.
Memory Management
An application using MFCxx.DLL uses a common memory allocator provided by MSVCRTxx.DLL, the shared C-
runtime DLL. The application, any MFC extension DLLs, and well as the MFC DLLs themselves use this shared
memory allocator. By using a shared DLL for memory allocation, the MFC DLLs can allocate memory that is later
freed by the application or vice versa. Because both the application and the DLL must use the same allocator, you
should not override the C++ global operator new or operator delete . The same rules apply to the rest of the C
run-time memory allocation routines (such as malloc , realloc , free , and others).
Ordinals and class __declspec(dllexport) and DLL naming
We do not use the class __declspec(dllexpor t) functionality of the C++ compiler. Instead, a list of exports is
included with the class library sources (MFCxx.DEF and MFCxxD.DEF). Only these select set of entry points
(functions and data) are exported. Other symbols, such as MFC private implementation functions or classes, are
not exported All exports are done by ordinal without a string name in the resident or non-resident name table.
Using class __declspec(dllexpor t) may be a viable alternative for building smaller DLLs, but in the case of a
large DLL like MFC, the default exporting mechanism has efficiency and capacity limits.
What this all means is that we can package a large amount of functionality in the release MFCxx.DLL that is only
around 800 KB without compromising much execution or loading speed. MFCxx.DLL would have been 100K larger
had this technique not been used. This also makes it possible to add additional entry points at the end of the .DEF
file to allow simple versioning without compromising the speed and size efficiency of exporting by ordinal. Major
version revisions in the MFC class library will change the library name. That is, MFC30.DLL is the redistributable
DLL containing version 3.0 of the MFC class library. An upgrade of this DLL, say, in a hypothetical MFC 3.1, the DLL
would be named MFC31.DLL instead. Again, if you modify the MFC source code to produce a custom version of
the MFC DLL, use a different name (and preferably one without "MFC" in the name).

See also
Technical Notes by Number
Technical Notes by Category
TN035: Using Multiple Resource Files and Header
Files with Visual C++
12/19/2019 • 17 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes how the Visual C++ resource editor supports multiple resource files and header files shared in
a single project or shared across multiple projects and how you can take advantage of that support. This note
answers these questions:
When might you want to split a project into multiple resource files and/or header files, and how you do it
How do you share a common header .H file between two .RC files
How do you divide project resources into multiple .RC files
How do you (and the tools) manage build dependencies between .RC, .CPP, and .H files
You should be aware that if you add an additional resource file to your project, ClassWizard will not recognize the
resources in the added file.
This note is structured to answer the above questions as follows:
Over view of How Visual C++ Manages Resource Files and Header Files provides an overview of
how the Resource Set Includes command in Visual C++ lets you use multiple resource files and header files
in the same project.
Analysis of AppWizard-created .RC and .H Files looks at the multiple resource and header files that
are used by an AppWizard-created application. These files serve as a good model for additional resource
files and header files you might want to add to your project.
Including Additional Header Files describes where you might want to include multiple header files, and
provides details how to do so.
Sharing a Header File Between Two .RC Files shows how you can share one header file between
multiple .RC files in different projects, or perhaps in the same project.
Using Multiple Resource Files in the Same Project describes where you might want to break up your
project into multiple .RC files, and provides details how to do so.
Enforcement of Non-Editable Visual C++ Files describes how you can make sure Visual C++ does
not edit and unintentionally reformat a custom resource.
Managing Symbols Shared by Multiple Visual C++-Edited .RC Files describes how to share the
same symbols across multiple .RC files and how to avoid assigning duplicate ID numeric values.
Managing Dependencies Between .RC, .CPP, and .H Files describes how Visual C++ avoids
unnecessary recompiling .CPP files that are dependent on resource symbol files.
How Visual C++ Manages Set Includes Information provides technical details about how Visual C++
keeps track of multiple (nested) .RC files and multiple header files that are #include'd by an .RC file.

Overview of How Visual C++ Manages Resource Files and Header Files
Visual C++ manages a single .RC resource file and a corresponding .H header file as a tightly coupled pair of files.
When you edit and save resources in an .RC file, you indirectly edit and save symbols in the corresponding .H file.
Although you can open and edit multiple .RC files at a time (using Visual C++'s MDI user interface) for any given
.RC file you indirectly edit exactly one corresponding header file.
Symbol Header File
By default, Visual C++ always names the corresponding header file RESOURCE.H, regardless of the name of the
resource file (e.g., MYAPP.RC). Using the Resource Includes command from the View menu in Visual C++, you
can change the name of this header file by updating the Symbol Header File file in the Set Includes dialog box.
Read-Only Symbol Directives
Although Visual C++ only edits one header file for any given .RC file, Visual C++ supports references to symbols
defined in additional read-only header files. Using the Resource Includes command from the View menu in
Visual C++, you can specify any number of additional read-only header files as Read-Only Symbol Directives. The
"read-only" restriction means that when you add a new resource in the .RC file, you can use a symbol defined in
the read-only header file; but if you delete the resource, the symbol still remains defined in the read-only header
file. You cannot change the numeric value assigned to a read-only symbol.
Compile -Time Directives
Visual C++ also supports nesting of resource files, where one .RC file is #include'd within another. When you edit a
given .RC file using Visual C++, any resources in the #include'd files are not visible. But when you compile the .RC
file, the #include'd files are also compiled. Using the Resource Includes command from the View menu in Visual
C++, you can specify any number of #include'd .RC files as Compile-Time Directives.
Note what happens if you read into Visual C++ an .RC file that #include's another .RC file that is not specified as a
Compile-Time Directive. This situation might arise when you bring to Visual C++ an .RC file that you had been
previously maintaining manually with a text editor. When Visual C++ reads the #include'd .RC file, it merges the
#include'd resources into the parent .RC file. When you save the parent .RC file, the #include statement, in effect,
will be replaced by the #include'd resources. If you do not want this merge to happen, you should remove the
#include statement from the parent .RC file prior to reading it into Visual C++; then using Visual C++, add back
the same #include statement as a Compile-Time Directive.
Visual C++ saves in an .RC file the three kinds of above Set Includes information (Symbol Header File, Read-Only
Symbol Directives, and Compile-Time Directives) in #include directives and in TEXTINCLUDE resources. The
TEXTINCLUDE resources, an implementation detail that you do not normally need to deal with, are explained in
How Visual C++ Manages Set Includes Information.

Analysis of AppWizard-Created .RC and .H Files


Examining the application code produced by AppWizard provides insight into how Visual C++ manages multiple
resource files and header files. The code excerpts examined below are from a MYAPP application produced by
AppWizard using the default options.
An AppWizard-created application uses multiple resource files and multiple header files, as summarized in the
diagram below:
RESOURCE.H AFXRES.H
\ /
\ /
MYAPP.RC
|
|
RES\MYAPP.RC2
AFXRES.RC
AFXPRINT.RC

You can view these multiple file relationships using the Visual C++ File/Set Includes command.
MYAPP.RC
The application resource file that you edit using Visual C++.
RESOURCE.H is the application-specific header file. It is always named RESOURCE.H by AppWizard, consistent with
Visual C++'s default naming of the header file. The #include for this header file is the first statement in the
resource file (MYAPP.RC):

//Microsoft Visual C++ generated resource script


//
#include "resource.h"

RES\MYAPP.RC2
Contains resources that will not be edited by Visual C++ but will be included in the final compiled .EXE file.
AppWizard creates no such resources by default, since Visual C++ can edit all of the standard resources, including
the version resource (a new feature in this release). An empty file is generated by AppWizard in case you wish to
add your own custom formatted resources to this file.
If you use custom formatted resources, you can add them to RES\MYAPP.RC2 and edit them using the Visual C++
text editor.
AFXRES.RC and AFXPRINT.RC contain standard resources required by certain features of the framework. Like
RES\MYAPP.RC2, these two framework-provided resource files are #include'd at the end of MYAPP.RC, and they are
specified in the Compile-Time Directives of the Set Includes dialog box. Thus, you do not directly view or edit these
framework resources while you edit MYAPP.RC in Visual C++, but they are compiled into the application's binary
.RES file and final .EXE file. For more information on the standard framework resources, including procedures for
modifying them, see Technical Note 23.
AFXRES.H defines standard symbols, such as ID_FILE_NEW , used by the framework and specifically used in
AFXRES.RC. AFXRES.H also #include's WINRES.H, which contains a subset of WINDOWS.H that are needed by
Visual C++ generated .RC files as well as AFXRES.RC. The symbols defined in AFXRES.H are available as you edit
the application resource file (MYAPP.RC). For example, ID_FILE_NEW is used for the File New menu item in
MYAPP.RC's menu resource. You cannot change or delete these framework-defined symbols.

Including Additional Header Files


The AppWizard-created application includes only two header files: RESOURCE.H and AFXRES.H. Only RESOURCE.H
is application-specific. You may need to include additional read-only header files in the following cases:
The header file is provided by an external source, or you want to share the header file among multiple projects or
multiple parts of the same project.
The header file has formatting and comments that you do not want Visual C++ to change or filter out when it
saves the file. For example, maybe you want to preserve #define's that use symbolic arithmetic such as:
#define RED 0
#define BLUE 1
#define GREEN 2
#define ID_COLOR_BUTTON 1001
#define ID_RED_BUTTON (ID_COLOR_BUTTON + RED)
#define ID_BLUE_BUTTON (ID_COLOR_BUTTON + BLUE)
#define ID_GREEN_BUTTON (ID_COLOR_BUTTON + GREEN)

You can include additional read-only header files by using the Resource Includes command to specify the
#include statement as a second Read-Only Symbol Directive, as in:

#include "afxres.h"
#include "second.h"

The new file relationship diagram now looks like this:

AFXRES.H
RESOURCE.H SECOND.H
\ /
\ /
MYAPP.RC
|
|
RES\MYAPP.RC2
AFXRES.RC
AFXPRINT.RC

Sharing a Header File Between Two .RC Files


You may want to share a header file between two .RC files that are in different projects, or possibly the same
project. To do so, simply apply the Read-Only Directives technique described above to both .RC files. In the case
where the two .RC files are for different applications (different projects), the result is illustrated in the following
diagram:

RESOURCE.H AFXRES.H RESOURCE.H


(for MYAPP1) SECOND.H (for MYAPP2)
\ / \ /
\ / \ /
MYAPP1.RC MYAPP2.RC
/ \ / \
/ \ / \
RES\MYAPP1.RC2 AFXRES.RC RES\MYAPP2.RC2
AFXPRINT.RC

The case where the second header file is shared by two .RC files in the same application (project) is discussed
below.

Using Multiple Resource Files in the Same Project


Visual C++ and the Resource Compiler support multiple .RC files in the same project through #include's of one .RC
file within another. Multiple nesting is allowed. There are various reasons to split your project's resources into
multiple .RC files:
It is easier to manage a large number of resources among multiple project team members if you split the
resources into multiple .RC files. If you use a source control management package for checking out files and
checking in changes, splitting the resources into multiple .RC files will give you finer control over managing
changes to resources.
If you want to use preprocessor directives, such as #ifdef, #endif, and #define, for portions of your
resources, you must isolate them in read-only resources that will be compiled by the Resource Compiler.
Component .RC files will load and save faster in Visual C++ than one composite .RC file.
If you want to maintain a resource with a text editor in a human-readable form, you should keep it in a .RC
file separate from the one Visual C++ edits.
If you need to keep a user-defined resource in a binary or text form that is interpretable by another
specialized data editor, then you should keep it in a separate .RC file so Visual C++ does not change the
format to hexadecimal data. The .WAV (sound) file resources in the MFC Advanced Concepts sample
SPEAKN are a good example.
You can #include a SECOND.RC in the Compile-Time Directives in the Set Includes dialog box:

#include "res\myapp.rc2" // non-Visual C++ edited resources


#include "second.rc" // THE SECOND .RC FILE

#include "afxres.rc" // Standard components


#include "afxprint.rc" // printing/print preview resources

The result is illustrated in the following diagram:

RESOURCE.H AFXRES.H
\ /
\ /
MYAPP.RC
|
|
RES\MYAPP.RC2
SECOND.RC
AFXRES.RC
AFXPRINT.RC

Using Compile-Time Directives, you can organize your Visual C++-editable and non-editable resources into
multiple .RC files, where the "master" MYAPP.RC does nothing but #include the other .RC files. If you are using a
Visual Studio C++ project .MAK file, then you should include the "master" .RC file in the project so that all the
#include'd resources are compiled with your application.

Enforcement of Noneditable Visual C++ Files


The AppWizard-created RES\MYAPP.RC2 file is an example of a file that contains resources that you do not want to
accidentally read into Visual C++ and then write it back out with loss of formatting information. To protect against
this, place the following lines in the beginning of the RES\MYAPP.RC2 file:

#ifdef APSTUDIO_INVOKED
#error this file is not editable by Visual C++
#endif //APSTUDIO_INVOKED

When Visual C++ compiles the .RC file, it defines APSTUDIO_INVOKED as well as RC_INVOKED . If the AppWizard-
created file structure is corrupted and Visual C++ reads the #error line above, it reports a fatal error and abort the
reading of the .RC file.

Managing Symbols Shared by Multiple Visual C++-Edited .RC Files


Two issues arise when you split up your resources into multiple .RC files that you want to edit separately in Visual
C++:
You might want to share the same symbols across multiple .RC files.
You need to help Visual C++ avoid assigning the same ID numeric values to distinct resources (symbols).
The following diagram illustrates an organization of .RC and .H files that deals with the first issue:

MYAPP.RC
/ \
/ \
MYSTRS.H / MYSHARED.H \ MYMENUS.H
\ / / \ \ \
\ / / \ \ \
MYSTRS.RC MYMENUS.RC

In this example, string resources are kept in one resource file, MYSTRS.RC, and menus are kept in another,
MYMENUS.RC. Some symbols, such as for commands, may need to be shared between the two files. For example,
a ID_TOOLS_SPELL may be the menu command ID for the Spell item in a Tools menu; and it may also be the string
ID of the command prompt displayed by the framework in the application's main window status bar.
The ID_TOOLS_SPELL symbol is kept in the shared header file, MYSHARED.H. You maintain this shared header file
manually with a text editor; Visual C++ does not directly edit it. In the two resource files MYSTRS.RC and
MYMENUS.RC, you specify #include MYSHARED.H in the Read-Only Directives for MYAPP.RC, using the Resource
Includes command, as described earlier.
It is most convenient to anticipate a symbol you will share before you attempt to use it to identify any resource.
Add the symbol to the shared header file and, if you have not already #include'd the shared header file in the
Read-Only Directives for the .RC file, do so before using the symbol. If you did not anticipate sharing the symbol in
this way, then you will have to manually (using a text editor) move the #define statement for the symbol from, say,
MYMENUS.H to MYSHARED.H before using it in MYSTRS.RC.
When you manage symbols in multiple .RC files, you also must help Visual C++ avoid assigning the same ID
numeric values to distinct resources (symbols). For any given .RC file, Visual C++ incrementally assigns IDs in each
of four ID domains. Between editing sessions, Visual C++ keeps track of the last ID it assigned in each of the
domains in the symbol header file for the .RC file. Here is what the APS_NEXT values are for an empty (new) .RC
file:

#define _APS_NEXT_RESOURCE_VALUE 101


#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101

_APS_NEXT_RESOURCE_VALUE is the next symbol value that will be used for a dialog resource, menu resource, and so
on. The valid range for resource symbol values is 1 to 0x6FFF.
_APS_NEXT_COMMAND_VALUE is the next symbol value that will be used for a command identification. The valid range
for command symbol values is 0x8000 to 0xDFFF.
_APS_NEXT_CONTROL_VALUE is the next symbol value that will be used for a dialog control. The valid range for dialog
control symbol values is 8 to 0xDFFF.
is the next symbol value that will be issued when you manually assign a symbol value
_APS_NEXT_SYMED_VALUE
using the New command in the Symbol Browser.
Visual C++ starts with slightly higher values that the lowest legal value when creating a new .RC file. AppWizard
will also initialize these values to something more appropriate for MFC applications. For more information about
ID value ranges, see Technical Note 20.
Now every time you create a new resource file, even in the same project, Visual C++ defines the same _APS_NEXT_
values. This means that if you add, say, multiple dialogs in two different .RC files, it is highly likely that the same
#define value will be assigned to different dialogs. For example, IDD_MY_DLG1 in the first .RC file might be
assigned the same number, 101, as IDD_MY_DLG2 in a second .RC file.
To avoid this, you should reserve a separate numeric range for each of the four domains of IDs in the respective
.RC files. Do this by manually updating the _APS_NEXT values in each of the .RC files before you start adding
resources. For example, if the first .RC file uses the default _APS_NEXT values, then you might want to assign the
following _APS_NEXT values to the second .RC file:

#define _APS_NEXT_RESOURCE_VALUE 2000


#define _APS_NEXT_COMMAND_VALUE 42000
#define _APS_NEXT_CONTROL_VALUE 2000
#define _APS_NEXT_SYMED_VALUE 2000

Of course, it is still possible that Visual C++ will assign so many IDs in the first .RC file that the numeric values
start to overlap those reserved for the second .RC file. You should reserve sufficiently large ranges so that this
does not happen.

Managing Dependencies Between .RC, .CPP, and .H Files


When Visual C++ saves an .RC file, it also saves symbol changes to the corresponding RESOURCE.H file. Any of
your .CPP files that refer to resources in the .RC file must #include the RESOURCE.H file, usually from within your
project's master header file. This leads to an undesirable side-effect because of the development environment's
internal project management which scans source files for header dependencies. Every time you add a new symbol
in Visual C++, all the .CPP files that #include RESOURCE.H would need to be recompiled.
Visual C++, circumvents the dependency on RESOURCE.H by including the following comment as the first line of
the RESOURCE.H file:

//{{NO_DEPENDENCIES}}

The development environment interprets this comment by ignoring the changes to RESOURCE.H so that
dependent .CPP files will not need to be recompiled.
Visual C++ always adds the //{{NO_DEPENDENCIES}} comment line to a .RC file when it saves the file. In some
cases, circumventing of the build dependency on RESOURCE.H may lead to run-time errors undetected at link
time. For example, if you use the Symbol Browser to change the numeric value assigned to a symbol for a
resource, the resource will not be correctly found and loaded at application run-time if the .CPP file referring to the
resource is not recompiled. In such cases, you should explicitly recompile any .CPP files that you know are affected
by the symbol changes in RESOURCE.H or select Rebuild All . If you have the need to frequently change symbol
values for a certain group of resources, you will probably find it more convenient and safer to break out these
symbols into a separate read-only header file, as described in the above section Including Additional Header Files.

How Visual C++ Manages Set Includes Information


As discussed above, the File menu Set Includes command lets you specify three types of information:
Symbol Header File
Read-Only Symbol Directives
Compile-Time Directives
The following describes how Visual C++ maintains this information in a .RC file. You do not need this information
to use Visual C++, but it may enhance your understanding so that you can more confidently use the Set Includes
feature.
Each of the above three types of Set Includes information is stored in the .RC file in two forms: (1) as #include or
other directives interpretable by the Resource Compiler, and (2) as special TEXTINCLUDE resources interpretable
only by Visual C++.
The purpose of the TEXTINCLUDE resource is to safely store Set Include information in a form that is readily
presentable in Visual C++'s Set Includes dialog box. TEXTINCLUDE is a resource type defined by Visual C++.
Visual C++ recognizes three specific TEXTINCLUDE resources that have the resource identification numbers 1, 2
and 3:

T EXT IN C L UDE RESO URC E ID T Y P E O F SET IN C L UDES IN F O RM AT IO N

1 Symbol Header File

2 Read-Only Symbol Directives

3 Compile-Time Directives

Each of the three types of Set Includes information is illustrated by the default MYAPP.RC and RESOURCE.H files
created by AppWizard, as described below. The extra \0 and "" tokens between BEGIN and END blocks are required
by the RC syntax to specify zero terminated strings and the double quote character respectively.
Symbol Header File
The form of the Symbol Header File information interpreted by the Resource Compiler is simply a #include
statement:

#include "resource.h"

The corresponding TEXTINCLUDE resource is:

1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END

Read-Only Symbol Directives


Read-Only Symbol Directives are included at the top of MYAPP.RC in the following form interpretable by the
Resource Compiler:

#include "afxres.h"

The corresponding TEXTINCLUDE resource is:

2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
Compile -Time Directives
Compile-Time Directives are included at the end of MYAPP.RC in the following form interpretable by the Resource
Compiler:

#ifndef APSTUDIO_INVOKED
///////////////////////
//
// From TEXTINCLUDE 3
//
#include "res\myapp.rc2" // non-Visual C++ edited resources

#include "afxres.rc" // Standard components


#include "afxprint.rc" // printing/print preview resources
#endif // not APSTUDIO_INVOKED

The #ifndef APSTUDIO_INVOKED directive instructs Visual C++ to skip over Compile-Time Directives.
The corresponding TEXTINCLUDE resource is:

3 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""res\myapp.rc2"" // non-Visual C++ edited resources\r\n"
"\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#include ""afxprint.rc"" // printing/print preview resources\r\n"
"\0"
END

See also
Technical Notes by Number
Technical Notes by Category
TN036: Using CFormView with AppWizard and
ClassWizard
3/16/2020 • 2 minutes to read • Edit Online

This technical note described how to modify an AppWizard generated application so that it used a CFormView
instead of the default CView as its main view class. This is supported directly with this version of Visual C++.

See also
Technical Notes by Number
Technical Notes by Category
TN037: Multithreaded MFC 2.1 Applications
5/14/2019 • 2 minutes to read • Edit Online

This technical note originally described the limitations of multithreaded programs with MFC 2.1, originally
provided with Visual C++ 1.0 for Windows NT. MFC 3.0 supports multithreading directly and is documented. See
that reference for more information.

See also
Technical Notes by Number
Technical Notes by Category
TN038: MFC/OLE IUnknown Implementation
12/16/2019 • 20 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

At the heart of OLE 2 is the "OLE Component Object Model", or COM. COM defines a standard for how
cooperating objects communicate to one another. This includes the details of what an "object" looks like, including
how methods are dispatched on an object. COM also defines a base class, from which all COM compatible classes
are derived. This base class is IUnknown. Although the IUnknown interface is referred to as a C++ class, COM is
not specific to any one language — it can be implemented in C, PASCAL, or any other language that can support
the binary layout of a COM object.
OLE refers to all classes derived from IUnknown as "interfaces." This is an important distinction, since an
"interface" such as IUnknown carries with it no implementation. It simply defines the protocol by which objects
communicate, not the specifics of what those implementations do. This is reasonable for a system that allows for
maximum flexibility. It is MFC's job to implement a default behavior for MFC/C++ programs.
To understand MFC's implementation of IUnknown you must first understand what this interface is. A simplified
version of IUnknown is defined below:

class IUnknown
{
public:
virtual HRESULT QueryInterface(REFIID iid, void** ppvObj) = 0;
virtual ULONG AddRef() = 0;
virtual ULONG Release() = 0;
};

NOTE
Certain necessary calling convention details, such as __stdcall are left out for this illustration.

The AddRef and Release member functions control memory management of the object. COM uses a reference
counting scheme to keep track of objects. An object is never referenced directly as you would in C++. Instead,
COM objects are always referenced through a pointer. To release the object when the owner is done using it, the
object's Release member is called (as opposed to using operator delete, as would be done for a traditional C++
object). The reference counting mechanism allows for multiple references to a single object to be managed. An
implementation of AddRef and Release maintains a reference count on the object — the object is not deleted until
its reference count reaches zero.
AddRef and Release are fairly straightforward from an implementation standpoint. Here is a trivial
implementation:
ULONG CMyObj::AddRef()
{
return ++m_dwRef;
}

ULONG CMyObj::Release()
{
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}

The QueryInterface member function is a little more interesting. It is not very interesting to have an object whose
only member functions are AddRef and Release — it would be nice to tell the object to do more things than
IUnknown provides. This is where QueryInterface is useful. It allows you to obtain a different "interface" on the
same object. These interfaces are usually derived from IUnknown and add additional functionality by adding new
member functions. COM interfaces never have member variables declared in the interface, and all member
functions are declared as pure-virtual. For example,

class IPrintInterface : public IUnknown


{
public:
virtual void PrintObject() = 0;
};

To get an IPrintInterface if you only have an IUnknown, call QueryInterface using the IID of the IPrintInterface .
An IID is a 128-bit number that uniquely identifies the interface. There is an IID for each interface that either
you or OLE define. If pUnk is a pointer to an IUnknown object, the code to retrieve an IPrintInterface from it might
be:

IPrintInterface* pPrint = NULL;


if (pUnk->QueryInterface(IID_IPrintInterface, (void**)&pPrint) == NOERROR)
{
pPrint->PrintObject();
pPrint->Release();
// release pointer obtained via QueryInterface
}

That seems fairly easy, but how would you implement an object supporting both the IPrintInterface and
IUnknown interface In this case it is simple since the IPrintInterface is derived directly from IUnknown — by
implementing IPrintInterface, IUnknown is automatically supported. For example:

class CPrintObj : public CPrintInterface


{
virtual HRESULT QueryInterface(REFIID iid, void** ppvObj);
virtual ULONG AddRef();
virtual ULONG Release();
virtual void PrintObject();
};

The implementations of AddRef and Release would be exactly the same as those implemented above.
CPrintObj::QueryInterface would look something like this:
HRESULT CPrintObj::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
if (iid == IID_IUnknown || iid == IID_IPrintInterface)
{
*ppvObj = this;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}

As you can see, if the interface identifier (IID) is recognized, a pointer is returned to your object; otherwise an error
occurs. Also note that a successful QueryInterface results in an implied AddRef. Of course, you'd also have to
implement CEditObj::Print. That is simple because the IPrintInterface was directly derived from the IUnknown
interface. However, if you wanted to support two different interfaces, both derived from IUnknown, consider the
following:

class IEditInterface : public IUnkown


{
public:
virtual void EditObject() = 0;
};

Although there are a number of different ways to implement a class supporting both IEditInterface and
IPrintInterface, including using C++ multiple inheritance, this note will concentrate on the use of nested classes to
implement this functionality.

class CEditPrintObj
{
public:
CEditPrintObj();

HRESULT QueryInterface(REFIID iid, void**);


ULONG AddRef();
ULONG Release();
DWORD m_dwRef;

class CPrintObj : public IPrintInterface


{
public:
CEditPrintObj* m_pParent;
virtual HRESULT QueryInterface(REFIID iid, void** ppvObj);
virtual ULONG AddRef();
virtual ULONG Release();
} m_printObj;

class CEditObj : public IEditInterface


{
public:
CEditPrintObj* m_pParent;
virtual ULONG QueryInterface(REFIID iid, void** ppvObj);
virtual ULONG AddRef();
virtual ULONG Release();
} m_editObj;
};

The entire implementation is included below:

CEditPrintObj::CEditPrintObj()
{
m_editObj.m_pParent = this;
m_editObj.m_pParent = this;
m_printObj.m_pParent = this;
}

ULONG CEditPrintObj::AddRef()
{
return ++m_dwRef;
}

CEditPrintObj::Release()
{
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}

HRESULT CEditPrintObj::QueryInterface(REFIID iid, void** ppvObj)


{
if (iid == IID_IUnknown || iid == IID_IPrintInterface)
{
*ppvObj = &m_printObj;
AddRef();
return NOERROR;
}
else if (iid == IID_IEditInterface)
{
*ppvObj = &m_editObj;
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}

ULONG CEditPrintObj::CEditObj::AddRef()
{
return m_pParent->AddRef();
}

ULONG CEditPrintObj::CEditObj::Release()
{
return m_pParent->Release();
}

HRESULT CEditPrintObj::CEditObj::QueryInterface(REFIID iid, void** ppvObj)


{
return m_pParent->QueryInterface(iid, ppvObj);
}

ULONG CEditPrintObj::CPrintObj::AddRef()
{
return m_pParent->AddRef();
}

ULONG CEditPrintObj::CPrintObj::Release()
{
return m_pParent->Release();
}

HRESULT CEditPrintObj::CPrintObj::QueryInterface(REFIID iid, void** ppvObj)


{
return m_pParent->QueryInterface(iid, ppvObj);
}

Notice that most of the IUnknown implementation is placed into the CEditPrintObj class rather than duplicating
the code in CEditPrintObj::CEditObj and CEditPrintObj::CPrintObj. This reduces the amount of code and avoids
bugs. The key point here is that from the IUnknown interface it is possible to call QueryInterface to retrieve any
interface the object might support, and from each of those interfaces it is possible to do the same. This means that
all QueryInterface functions available from each interface must behave exactly the same way. In order for these
embedded objects to call the implementation in the "outer object", a back-pointer is used (m_pParent). The
m_pParent pointer is initialized during the CEditPrintObj constructor. Then you would implement
CEditPrintObj::CPrintObj::PrintObject and CEditPrintObj::CEditObj::EditObject as well. Quite a bit of code was
added to add one feature — the ability to edit the object. Fortunately, it is quite uncommon for interfaces to have
only a single member function (although it does happen) and in this case, EditObject and PrintObject would
usually be combined into a single interface.
That's a lot of explanation and a lot of code for such a simple scenario. The MFC/OLE classes provide a simpler
alternative. The MFC implementation uses a technique similar to the way Windows messages are wrapped with
Message Maps. This facility is called Interface Maps and is discussed in the next section.

MFC Interface Maps


MFC/OLE includes an implementation of "Interface Maps" similar to MFC's "Message Maps" and "Dispatch Maps"
in concept and execution. The core features of MFC's Interface Maps are as follows:
A standard implementation of IUnknown, built into the CCmdTarget class.
Maintenance of the reference count, modified by AddRef and Release
Data driven implementation of QueryInterface
In addition, interface maps support the following advanced features:
Support for creating aggregatable COM objects
Support for using aggregate objects in the implementation of a COM object
The implementation is hookable and extensible
For more information on aggregation, see the Aggregation topic.
MFC's interface map support is rooted in the CCmdTarget class. CCmdTarget "has-a" reference count as well as all
the member functions associated with the IUnknown implementation (the reference count for example is in
CCmdTarget ). To create a class that supports OLE COM, you derive a class from CCmdTarget and use various
macros as well as member functions of CCmdTarget to implement the desired interfaces. MFC's implementation
uses nested classes to define each interface implementation much like the example above. This is made easier
with a standard implementation of IUnknown as well as a number of macros that eliminate some of the repetitive
code.

Interface Map Basics


To implement a class using MFC's interface maps
1. Derive a class either directly or indirectly from CCmdTarget .
2. Use the DECLARE_INTERFACE_MAP function in the derived class definition.
3. For each interface you wish to support, use the BEGIN_INTERFACE_PART and END_INTERFACE_PART
macros in the class definition.
4. In the implementation file, use the BEGIN_INTERFACE_MAP and END_INTERFACE_MAP macros to define
the class's interface map.
5. For each IID supported, use the INTERFACE_PART macro between the BEGIN_INTERFACE_MAP and
END_INTERFACE_MAP macros to map that IID to a specific "part" of your class.
6. Implement each of the nested classes that represent the interfaces you support.
7. Use the METHOD_PROLOGUE macro to access the parent, CCmdTarget -derived object.
8. AddRef, Release, and QueryInterface can delegate to the CCmdTarget implementation of these functions (
ExternalAddRef , ExternalRelease , and ExternalQueryInterface ).

The CPrintEditObj example above could be implemented as follows:

class CPrintEditObj : public CCmdTarget


{
public:
// member data and member functions for CPrintEditObj go here

// Interface Maps
protected:
DECLARE_INTERFACE_MAP()

BEGIN_INTERFACE_PART(EditObj, IEditInterface)
STDMETHOD_(void, EditObject)();
END_INTERFACE_PART(EditObj)

BEGIN_INTERFACE_PART(PrintObj, IPrintInterface)
STDMETHOD_(void, PrintObject)();
END_INTERFACE_PART(PrintObj)
};

The above declaration creates a class derived from CCmdTarget . The DECLARE_INTERFACE_MAP macro tells the
framework that this class will have a custom interface map. In addition, the BEGIN_INTERFACE_PART and
END_INTERFACE_PART macros define nested classes, in this case with names CEditObj and CPrintObj (the X is
used only to differentiate the nested classes from global classes which start with "C" and interface classes which
start with "I"). Two nested members of these classes are created: m_CEditObj, and m_CPrintObj, respectively. The
macros automatically declare the AddRef, Release, and QueryInterface functions; therefore you only declare the
functions specific to this interface: EditObject and PrintObject (the OLE macro STDMETHOD is used so that
_stdcall and virtual keywords are provided as appropriate for the target platform).
To implement the interface map for this class:

BEGIN_INTERFACE_MAP(CPrintEditObj, CCmdTarget)
INTERFACE_PART(CPrintEditObj, IID_IPrintInterface, PrintObj)
INTERFACE_PART(CPrintEditObj, IID_IEditInterface, EditObj)
END_INTERFACE_MAP()

This connects the IID_IPrintInterface IID with m_CPrintObj and IID_IEditInterface with m_CEditObj respectively. The
CCmdTarget implementation of QueryInterface ( CCmdTarget::ExternalQueryInterface ) uses this map to return
pointers to m_CPrintObj and m_CEditObj when requested. It is not necessary to include an entry for
IID_IUnknown ; the framework will use the first interface in the map (in this case, m_CPrintObj) when
IID_IUnknown is requested.

Even though the BEGIN_INTERFACE_PART macro automatically declared the AddRef, Release and QueryInterface
functions for you, you still need to implement them:
ULONG FAR EXPORT CEditPrintObj::XEditObj::AddRef()
{
METHOD_PROLOGUE(CEditPrintObj, EditObj)
return pThis->ExternalAddRef();
}

ULONG FAR EXPORT CEditPrintObj::XEditObj::Release()


{
METHOD_PROLOGUE(CEditPrintObj, EditObj)
return pThis->ExternalRelease();
}

HRESULT FAR EXPORT CEditPrintObj::XEditObj::QueryInterface(


REFIID iid,
void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CEditPrintObj, EditObj)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}

void FAR EXPORT CEditPrintObj::XEditObj::EditObject()


{
METHOD_PROLOGUE(CEditPrintObj, EditObj)
// code to "Edit" the object, whatever that means...
}

The implementation for CEditPrintObj::CPrintObj, would be similar to the above definitions for
CEditPrintObj::CEditObj. Although it would be possible to create a macro that could be used to automatically
generate these functions (but earlier in MFC/OLE development this was the case), it becomes difficult to set break
points when a macro generates more than one line of code. For this reason, this code is expanded manually.
By using the framework implementation of message maps, there are a number of things that were not necessary
to do:
Implement QueryInterface
Implement AddRef and Release
Declare either of these built-in methods on both of your interfaces
In addition, the framework uses message maps internally. This allows you to derive from a framework class, say
COleServerDoc , that already supports certain interfaces and provides either replacements or additions to the
interfaces provided by the framework. You can do this because the framework fully supports inheriting an
interface map from a base class. That is the reason why BEGIN_INTERFACE_MAP takes as its second parameter the
name of the base class.

NOTE
It is generally not possible to reuse the implementation of MFC's built-in implementations of the OLE interfaces just by
inheriting the embedded specialization of that interface from the MFC version. This is not possible because the use of the
METHOD_PROLOGUE macro to get access to the containing CCmdTarget -derived object implies a fixed offset of the
embedded object from the CCmdTarget -derived object. This means, for example, you cannot derive an embedded
XMyAdviseSink from MFC's implementation in COleClientItem::XAdviseSink , because XAdviseSink relies on being at a
specific offset from the top of the COleClientItem object.
NOTE
You can, however, delegate to the MFC implementation for all of the functions that you want MFC's default behavior. This is
done in the MFC implementation of IOleInPlaceFrame (XOleInPlaceFrame) in the COleFrameHook class (it delegates to
m_xOleInPlaceUIWindow for many functions). This design was chosen to reduce the runtime size of objects which
implement many interfaces; it eliminates the need for a back-pointer (such as the way m_pParent was used in the previous
section).

Aggregation and Interface Maps


In addition to supporting stand-alone COM objects, MFC also supports aggregation. Aggregation itself is too
complex a topic to discuss here; refer to the Aggregation topic for more information on aggregation. This note will
simply describe the support for aggregation built into the framework and interface maps.
There are two ways to use aggregation: (1) using a COM object that supports aggregation, and (2) implementing
an object that can be aggregated by another. These capabilities can be referred to as "using an aggregate object"
and "making an object aggregatable". MFC supports both.
Using an Aggregate Object
To use an aggregate object, there needs to be some way to tie the aggregate into the QueryInterface mechanism.
In other words, the aggregate object must behave as though it is a native part of your object. So how does this tie
into MFC's interface map mechanism In addition to the INTERFACE_PART macro, where a nested object is mapped
to an IID, you can also declare an aggregate object as part of your CCmdTarget derived class. To do so, the
INTERFACE_AGGREGATE macro is used. This allows you to specify a member variable (which must be a pointer to
an IUnknown or derived class), which is to be integrated into the interface map mechanism. If the pointer is not
NULL when CCmdTarget::ExternalQueryInterface is called, the framework will automatically call the aggregate
object's QueryInterface member function, if the IID requested is not one of the native IID s supported by the
CCmdTarget object itself.

To use the INTERFACE_AGGREGATE macro


1. Declare a member variable (an IUnknown* ) which will contain a pointer to the aggregate object.
2. Include an INTERFACE_AGGREGATE macro in your interface map, which refers to the member variable by
name.
3. At some point (usually during CCmdTarget::OnCreateAggregates ), initialize the member variable to
something other than NULL.
For example:
class CAggrExample : public CCmdTarget
{
public:
CAggrExample();

protected:
LPUNKNOWN m_lpAggrInner;
virtual BOOL OnCreateAggregates();

DECLARE_INTERFACE_MAP()
// "native" interface part macros may be used here
};

CAggrExample::CAggrExample()
{
m_lpAggrInner = NULL;
}

BOOL CAggrExample::OnCreateAggregates()
{
// wire up aggregate with correct controlling unknown
m_lpAggrInner = CoCreateInstance(CLSID_Example,
GetControllingUnknown(), CLSCTX_INPROC_SERVER,
IID_IUnknown, (LPVOID*)&m_lpAggrInner);

if (m_lpAggrInner == NULL)
return FALSE;
// optionally, create other aggregate objects here
return TRUE;
}

BEGIN_INTERFACE_MAP(CAggrExample, CCmdTarget)
// native "INTERFACE_PART" entries go here
INTERFACE_AGGREGATE(CAggrExample, m_lpAggrInner)
END_INTERFACE_MAP()

The m_lpAggrInner variable is initialized in the constructor to NULL. The framework ignores a NULL member
variable in the default implementation of QueryInterface. OnCreateAggregates is a good place to actually create
your aggregate objects. You'll have to call it explicitly if you are creating the object outside of the MFC
implementation of COleObjectFactory . The reason for creating aggregates in CCmdTarget::OnCreateAggregates as
well as the usage of CCmdTarget::GetControllingUnknown will become apparent when creating aggregatable objects
is discussed.
This technique will give your object all of the interfaces that the aggregate object supports plus its native
interfaces. If you only want a subset of the interfaces that the aggregate supports, you can override
CCmdTarget::GetInterfaceHook . This allows you very low-level hookability, similar to QueryInterface. Usually, you
want all the interfaces that the aggregate supports.
Making an Object Implementation Aggregatable
For an object to be aggregatable, the implementation of AddRef, Release, and QueryInterface must delegate to a
"controlling unknown." In other words, for it to be part of the object, it must delegate AddRef, Release, and
QueryInterface to a different object, also derived from IUnknown. This "controlling unknown" is provided to the
object when it is created, that is, it is provided to the implementation of COleObjectFactory . Implementing this
carries a small amount of overhead, and in some cases is not desirable, so MFC makes this optional. To enable an
object to be aggregatable, you call CCmdTarget::EnableAggregation from the object's constructor.
If the object also uses aggregates, you must also be sure to pass the correct "controlling unknown" to the
aggregate objects. Usually this IUnknown pointer is passed to the object when the aggregate is created. For
example, the pUnkOuter parameter is the "controlling unknown" for objects created with CoCreateInstance . The
correct "controlling unknown" pointer can be retrieved by calling CCmdTarget::GetControllingUnknown . The value
returned from that function, however, is not valid during the constructor. For this reason, it is suggested that you
create your aggregates only in an override of CCmdTarget::OnCreateAggregates , where the return value from
GetControllingUnknown is reliable, even if created from the COleObjectFactory implementation.

It is also important that the object manipulate the correct reference count when adding or releasing artificial
reference counts. To ensure this is the case, always call ExternalAddRef and ExternalRelease instead of
InternalRelease and InternalAddRef . It is rare to call InternalRelease or InternalAddRef on a class that
supports aggregation.

Reference Material
Advanced usage of OLE, such as defining your own interfaces or overriding the framework's implementation of
the OLE interfaces requires the use of the underlying interface map mechanism.
This section discusses each macro and the APIs which is used to implement these advanced features.
CCmdTarget::EnableAggregation — Function Description

void EnableAggregation();

Remarks
Call this function in the constructor of the derived class if you wish to support OLE aggregation for objects of this
type. This prepares a special IUnknown implementation that is required for aggregatable objects.
CCmdTarget::ExternalQueryInterface — Function Description

DWORD ExternalQueryInterface(
const void FAR* lpIID,
LPVOIDFAR* ppvObj
);

Parameters
lpIID
A far pointer to an IID (the first argument to QueryInterface)
ppvObj
A pointer to an IUnknown* (second argument to QueryInterface)
Remarks
Call this function in your implementation of IUnknown for each interface your class implements. This function
provides the standard data-driven implementation of QueryInterface based on your object's interface map. It is
necessary to cast the return value to an HRESULT. If the object is aggregated, this function will call the "controlling
IUnknown" instead of using the local interface map.
CCmdTarget::ExternalAddRef — Function Description

DWORD ExternalAddRef();

Remarks
Call this function in your implementation of IUnknown::AddRef for each interface your class implements. The
return value is the new reference count on the CCmdTarget object. If the object is aggregated, this function will call
the "controlling IUnknown" instead of manipulating the local reference count.
CCmdTarget::ExternalRelease — Function Description
DWORD ExternalRelease();

Remarks
Call this function in your implementation of IUnknown::Release for each interface your class implements. The
return value indicates the new reference count on the object. If the object is aggregated, this function will call the
"controlling IUnknown" instead of manipulating the local reference count.
DECLARE_INTERFACE_MAP — Macro Description

DECLARE_INTERFACE_MAP

Remarks
Use this macro in any class derived from CCmdTarget that will have an interface map. Used in much the same way
as DECLARE_MESSAGE_MAP. This macro invocation should be placed in the class definition, usually in a header
(.H) file. A class with DECLARE_INTERFACE_MAP must define the interface map in the implementation file (.CPP)
with the BEGIN_INTERFACE_MAP and END_INTERFACE_MAP macros.
BEGIN_INTERFACE_PART and END_INTERFACE_PART — Macro Descriptions

BEGIN_INTERFACE_PART(localClass, iface);
END_INTERFACE_PART(localClass)

Parameters
localClass
The name of the class that implements the interface
iface
The name of the interface that this class implements
Remarks
For each interface that your class will implement, you need to have a BEGIN_INTERFACE_PART and
END_INTERFACE_PART pair. These macros define a local class derived from the OLE interface that you define as
well as an embedded member variable of that class. The AddRef, Release, and QueryInterface members are
declared automatically. You must include the declarations for the other member functions that are part of the
interface being implemented (those declarations are placed between the BEGIN_INTERFACE_PART and
END_INTERFACE_PART macros).
The iface argument is the OLE interface that you wish to implement, such as IAdviseSink , or IPersistStorage (or
your own custom interface).
The localClass argument is the name of the local class that will be defined. An 'X' will automatically be prepended
to the name. This naming convention is used to avoid collisions with global classes of the same name. In addition,
the name of the embedded member, the same as the localClass name except it is prefixed by 'm_x'.
For example:

BEGIN_INTERFACE_PART(MyAdviseSink, IAdviseSink)
STDMETHOD_(void, OnDataChange)(LPFORMATETC, LPSTGMEDIUM);
STDMETHOD_(void, OnViewChange)(DWORD, LONG);
STDMETHOD_(void, OnRename)(LPMONIKER);
STDMETHOD_(void, OnSave)();
STDMETHOD_(void, OnClose)();
END_INTERFACE_PART(MyAdviseSink)

would define a local class called XMyAdviseSink derived from IAdviseSink, and a member of the class in which it
is declared called m_xMyAdviseSink.Note:

NOTE
The lines beginning with STDMETHOD _ are essentially copied from OLE2.H and modified slightly. Copying them from OLE2.H
can reduce errors that are hard to resolve.

BEGIN_INTERFACE_MAP and END_INTERFACE_MAP — Macro Descriptions

BEGIN_INTERFACE_MAP(theClass, baseClass)
END_INTERFACE_MAP

Parameters
theClass
The class in which the interface map is to be defined
baseClass
The class from which theClass derives from.
Remarks
The BEGIN_INTERFACE_MAP and END_INTERFACE_MAP macros are used in the implementation file to actually
define the interface map. For each interface that is implemented there is one or more INTERFACE_PART macro
invocations. For each aggregate that the class uses, there is one INTERFACE_AGGREGATE macro invocation.
INTERFACE_PART — Macro Description

INTERFACE_PART(theClass, iid, localClass)

Parameters
theClass
The name of the class that contains the interface map.
iid
The IID that is to be mapped to the embedded class.
localClass
The name of the local class (less the 'X').
Remarks
This macro is used between the BEGIN_INTERFACE_MAP macro and the END_INTERFACE_MAP macro for each
interface your object will support. It allows you to map an IID to a member of the class indicated by theClass and
localClass. The 'm_x' will be added to the localClass automatically. Note that more than one IID may be
associated with a single member. This is very useful when you are implementing only a "most derived" interface
and wish to provide all intermediate interfaces as well. A good example of this is the IOleInPlaceFrameWindow
interface. Its hierarchy looks like this:

IUnknown
IOleWindow
IOleUIWindow
IOleInPlaceFrameWindow

If an object implements IOleInPlaceFrameWindow , a client may QueryInterface on any of these interfaces:


IOleUIWindow , IOleWindow , or IUnknown, besides the "most derived" interface IOleInPlaceFrameWindow (the one
you are actually implementing). To handle this you can use more than one INTERFACE_PART macro to map each
and every base interface to the IOleInPlaceFrameWindow interface:
in the class definition file:

BEGIN_INTERFACE_PART(CMyFrameWindow, IOleInPlaceFrameWindow)

in the class implementation file:

BEGIN_INTERFACE_MAP(CMyWnd, CFrameWnd)
INTERFACE_PART(CMyWnd, IID_IOleWindow, MyFrameWindow)
INTERFACE_PART(CMyWnd, IID_IOleUIWindow, MyFrameWindow)
INTERFACE_PART(CMyWnd, IID_IOleInPlaceFrameWindow, MyFrameWindow)
END_INTERFACE_MAP

The framework takes care of IUnknown because it is always required.


INTERFACE_PART — Macro Description

INTERFACE_AGGREGATE(theClass, theAggr)

Parameters
theClass
The name of the class that contains the interface map,
theAggr
The name of the member variable that is to be aggregated.
Remarks
This macro is used to tell the framework that the class is using an aggregate object. It must appear between the
BEGIN_INTERFACE_PART and END_INTERFACE_PART macros. An aggregate object is a separate object, derived
from IUnknown. By using an aggregate and the INTERFACE_AGGREGATE macro, you can make all the interfaces
that the aggregate supports appear to be directly supported by the object. The theAggr argument is simply the
name of a member variable of your class which is derived from IUnknown (either directly or indirectly). All
INTERFACE_AGGREGATE macros must follow the INTERFACE_PART macros when placed in an interface map.

See also
Technical Notes by Number
Technical Notes by Category
TN039: MFC/OLE Automation Implementation
5/14/2019 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

Overview of OLE IDispatch Interface


The IDispatch interface is the means by which applications expose methods and properties such that other
applications such as Visual BASIC, or other languages, can make use of the application's features. The most
important part of this interface is the IDispatch::Invoke function. MFC uses "dispatch maps" to implement
IDispatch::Invoke . The dispatch map provides the MFC implementation information on the layout or "shape" of
your CCmdTarget -derived classes, such that it can directly manipulate the properties of the object, or call member
functions within your object to satisfy IDispatch::Invoke requests.
For the most part, ClassWizard and MFC cooperate to hide most of the details of OLE automation from the
application programmer. The programmer concentrates on the actual functionality to expose in the application and
doesn't have to worry about the underlying plumbing.
There are cases, however, where it is necessary to understand what MFC is doing behind the scenes. This note will
address how the framework assigns DISPID s to member functions and properties. Knowledge of the algorithm
MFC uses for assigning DISPID s is only necessary when you need to know the IDs, such as when you create a
"type library" for your application's objects.

MFC DISPID assignment


Although the end-user of automation (a Visual Basic user, for example), sees the actual names of the automation
enabled properties and methods in their code (such as obj.ShowWindow), the implementation of
IDispatch::Invoke does not receive the actual names. For optimization reasons, it receives a DISPID , which is a
32-bit "magic cookie" that describes the method or property that is to be accessed. These DISPID values are
returned from the IDispatch implementation through another method, called IDispatch::GetIDsOfNames . An
automation client application will call GetIDsOfNames once for each member or property it intends to access, and
cache them for later calls to IDispatch::Invoke . This way, the expensive string lookup is only done once per object
use, instead of once per IDispatch::Invoke call.
MFC determines the DISPID s for each method and property based on two things:
The distance from the top of the dispatch map (1 relative)
The distance of the dispatch map from the most derived class (0 relative)
The DISPID is divided into two parts. The LOWORD of the DISPID contains the first component, the distance
from the top of the dispatch map. The HIWORD contains the distance from the most derived class. For example:
class CDispPoint : public CCmdTarget
{
public:
short m_x, m_y;
// ...
DECLARE_DISPATCH_MAP()
// ...
};

class CDisp3DPoint : public CDispPoint


{
public:
short m_z;
// ...
DECLARE_DISPATCH_MAP()
// ...
};

BEGIN_DISPATCH_MAP(CDispPoint, CCmdTarget)
DISP_PROPERTY(CDispPoint, "x", m_x, VT_I2)
DISP_PROPERTY(CDispPoint, "y", m_y, VT_I2)
END_DISPATCH_MAP()

BEGIN_DISPATCH_MAP(CDisp3DPoint, CDispPoint)
DISP_PROPERTY(CDisp3DPoint, "z", m_z, VT_I2)
END_DISPATCH_MAP()

As you can see, there are two classes, both of which expose OLE automation interfaces. One of these classes is
derived from the other and thus leverages the base class's functionality, including the OLE automation part ("x"
and "y" properties in this case).
MFC will generate DISPID s for class CDispPoint as follows:

property X (DISPID)0x00000001
property Y (DISPID)0x00000002

Since the properties are not in a base class, the HIWORD of the DISPID is always zero (the distance from the
most derived class for CDispPoint is zero).
MFC will generate DISPID s for class CDisp3DPoint as follows:

property Z (DISPID)0x00000001
property X (DISPID)0x00010001
property Y (DISPID)0x00010002

The Z property is given a DISPID with a zero HIWORD since it is defined in the class that is exposing the
properties, CDisp3DPoint. Since the X and Y properties are defined in a base class, the HIWORD of the DISPID is
1, since the class in which these properties are defined is at a distance of one derivation from the most derived
class.

NOTE
The LOWORD is always determined by the position in the map, even if there exist entries in the map with explicit DISPID
(see next section for information on the _ID versions of the DISP_PROPERTY and DISP_FUNCTION macros).

Advanced MFC Dispatch Map Features


There are a number of additional features that ClassWizard does not support with this release of Visual C++.
ClassWizard supports DISP_FUNCTION , DISP_PROPERTY , and DISP_PROPERTY_EX which define a method, member
variable property, and get/set member function property, respectively. These capabilities are usually all that is
needed to create most automation servers.
The following additional macros can be used when the ClassWizard supported macros are not adequate:
DISP_PROPERTY_NOTIFY , and DISP_PROPERTY_PARAM .

DISP_PROPERTY_NOTIFY — Macro Description


DISP_PROPERTY_NOTIFY(
theClass,
pszName,
memberName,
pfnAfterSet,
vtPropType)

Parameters
theClass
Name of the class.
pszName
External name of the property.
memberName
Name of the member variable in which the property is stored.
pfnAfterSet
Name of member function to call when property is changed.
vtPropType
A value specifying the property's type.
Remarks
This macro is much like DISP_PROPERTY, except that it accepts an additional argument. The additional argument,
pfnAfterSet, should be a member function that returns nothing and takes no parameters, 'void
OnPropertyNotify()'. It will be called after the member variable has been modified.

DISP_PROPERTY_PARAM — Macro Description


DISP_PROPERTY_PARAM(
theClass,
pszName,
pfnGet,
pfnSet,
vtPropType,
vtsParams)

Parameters
theClass
Name of the class.
pszName
External name of the property.
memberGet
Name of the member function used to get the property.
memberSet
Name of the member function used to set the property.
vtPropType
A value specifying the property's type.
vtsParams
A string of space separated VTS_ for each parameter.
Remarks
Much like the DISP_PROPERTY_EX macro, this macro defines a property accessed with separate Get and Set
member functions. This macro, however, allows you to specify a parameter list for the property. This is useful for
implementing properties that are indexed or parameterized in some other way. The parameters will always be
placed first, followed by the new value for the property. For example:

DISP_PROPERTY_PARAM(CMyObject, "item", GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)

would correspond to get and set member functions:

LPDISPATCH CMyObject::GetItem(short row, short col)


void CMyObject::SetItem(short row, short col, LPDISPATCH newValue)

DISP_XXXX_ID — Macro Descriptions


DISP_FUNCTION_ID(
theClass,
pszName,
dispid,
pfnMember,
vtRetVal,
vtsParams)
DISP_PROPERTY_ID(
theClass,
pszName,
dispid,
memberName,
vtPropType)
DISP_PROPERTY_NOTIFY_ID(
theClass,
pszName,
dispid,
memberName,
pfnAfterSet,
vtPropType)
DISP_PROPERTY_EX_ID(
theClass,
pszName,
dispid,
pfnGet,
pfnSet,
vtPropType)
DISP_PROPERTY_PARAM_ID(
theClass,
pszName,
dispid,
pfnGet,
pfnSet,
vtPropType,
vtsParams)
Parameters
theClass
Name of the class.
pszName
External name of the property.
dispid
The fixed DISPID for the property or method.
pfnGet
Name of the member function used to get the property.
pfnSet
Name of the member function used to set the property.
memberName
The name of the member variable to map to the property
vtPropType
A value specifying the property's type.
vtsParams
A string of space separated VTS_ for each parameter.
Remarks
These macros allow you to specify a DISPID instead of letting MFC automatically assign one. These advanced
macros have the same names except that ID is appended to the macro name (e.g. DISP_PROPERTY_ID ) and the
ID is determined by the parameter specified just after the pszName parameter. See AFXDISP.H for more
information on these macros. The _ID entries must be placed at the end of the dispatch map. They will affect the
automatic DISPID generation in the same way as a non-_ID version of the macro would (the DISPID s are
determined by position). For example:

BEGIN_DISPATCH_MAP(CDisp3DPoint, CCmdTarget)
DISP_PROPERTY(CDisp3DPoint, "y", m_y, VT_I2)
DISP_PROPERTY(CDisp3DPoint, "z", m_z, VT_I2)
DISP_PROPERTY_ID(CDisp3DPoint, "x", 0x00020003, m_x, VT_I2)
END_DISPATCH_MAP()

MFC will generate DISPIDs for class CDisp3DPoint as follows:

property X (DISPID)0x00020003
property Y (DISPID)0x00000002
property Z (DISPID)0x00000001

Specifying a fixed DISPID is useful to maintain backward compatibility to a previously existing dispatch interface,
or to implement certain system defined methods or properties (usually indicated by a negative DISPID , such as
the DISPID_NEWENUM collection).

Retrieving the IDispatch Interface for a COleClientItem


Many servers will support automation within their document objects, along with the OLE server functionality. In
order to gain access to this automation interface, it is necessary to directly access the COleClientItem::m_lpObject
member variable. The code below will retrieve the IDispatch interface for an object derived from COleClientItem .
You can include the code below in your application if you find this functionality necessary:
LPDISPATCH CMyClientItem::GetIDispatch()
{
ASSERT_VALID(this);
ASSERT(m_lpObject != NULL);

LPUNKNOWN lpUnk = m_lpObject;

Run(); // must be running

LPOLELINK lpOleLink = NULL;


if (m_lpObject->QueryInterface(IID_IOleLink,
(LPVOID FAR*)&lpOleLink) == NOERROR)
{
ASSERT(lpOleLink != NULL);
lpUnk = NULL;
if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
{
TRACE0("Warning: Link is not connected!\n");
lpOleLink->Release();
return NULL;
}
ASSERT(lpUnk != NULL);
}

LPDISPATCH lpDispatch = NULL;


if (lpUnk->QueryInterface(IID_IDispatch, &lpDispatch) != NOERROR)
{
TRACE0("Warning: does not support IDispatch!\n");
return NULL;
}

ASSERT(lpDispatch != NULL);
return lpDispatch;
}

The dispatch interface returned from this function could then be used directly or attached to a COleDispatchDriver
for type-safe access. If you use it directly, make sure that you call its Release member when through with the
pointer (the COleDispatchDriver destructor does this by default).

See also
Technical Notes by Number
Technical Notes by Category
TN040: MFC/OLE In-Place Resizing and Zooming
3/27/2020 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note will discuss the issues relating to in-place editing and how a server should accomplish correct zooming
and in-place resizing. With in-place activation, the WYSIWYG concept is taken one step further in that containers
and servers cooperate with each other, and in particular interpret the OLE specification in much the same way.
Because of the close interaction between a container and server supporting in-place activation there are a number
of expectations from the end-user that should be maintained:
The presentation display (the metafile drawn in the COleServerItem::OnDraw override) should look exactly
the same as when it is drawn for editing (except that editing tools are not visible).
When the container zooms, the server window should too!
Both the container and server should display objects for editing using the same metrics. This means using a
mapping mode based on the number of logical pixels per inch — not physical pixels per inch, when
rendering on the display device.

NOTE
Because in-place activation only applies to items that are embedded (not linked), zooming only applies to embedded objects.
You will see APIs in both COleServerDoc and COleServerItem that are used for zooming. The reason for this dichotomy
is that only functions that are valid for both linked and embedded items are in COleServerItem (this allows you to have a
common implementation) and functions that are valid only for embedded objects are located in the COleServerDoc class
(from the server's perspective, it is the document which is embedded).

Most of the burden is placed on the server implementer, in that the server must be aware of the container's zoom
factor and modify its editing interface as appropriate. But how does the server determine the zoom factor that the
container is using

MFC Support for Zooming


The current zoom factor can be determined by calling COleServerDoc::GetZoomFactor . Calling this when the
document is not in-place active will always result in a 100% zoom factor (or 1:1 ratio). Calling it while in-place
active may return something other than 100%.
For an example of zooming correctly see the MFC OLE sample HIERSVR. Zooming in HIERSVR is complicated by
the fact that it displays text, and text, in general, does not scale in a linear fashion (hints, typographic conventions,
design widths, and heights all complicate the matter). Still, HIERSVR is a reasonable reference for implementing
zooming correctly, and so is the MFC Tutorial SCRIBBLE (step 7).
COleServerDoc::GetZoomFactor determines the zoom factor based on a number of different metrics available either
from the container or from the implementation of your COleServerItem and COleServerDoc classes. In short, the
current zoom factor is determined by the following formula:
Position Rectangle (PR) / Container Extent (CE)

The POSITION RECTANGLE is determined by the container. It is returned to the server during in-place activation
when COleClientItem::OnGetItemPosition is called and is updated when the container calls the server's
COleServerDoc::OnSetItemRects (with a call to COleClientItem::SetItemRects ).

The CONTAINER EXTENT is slightly more complex to calculate. If the container has called
COleServerItem::OnSetExtent (with a call to COleClientItem::SetExtent ), then the CONTAINER EXTENT is this value
converted to pixels based on the number of pixels per logical inch. If the container has not called SetExtent (which
is usually the case), then the CONTAINER EXTENT is the size returned from COleServerItem::OnGetExtent . So, if the
container has not called SetExtent, the framework assumes that if it did the container would have called it with
100% of the natural extent (the value returned from COleServerItem::GetExtent ). Stated another way, the
framework assumes that the container is displaying 100% (no more, no less) of the item.
It is important to note that although COleServerItem::OnSetExtent and COleServerItem::OnGetExtent have similar
names, they do not manipulate the same attribute of the item. OnSetExtent is called to let the server know how
much of the object is visible in the container (regardless of the zoom factor) and OnGetExtent is called by the
container to determine ideal size of the object.
By looking at each of the APIs involved, you can get a clearer picture:

COleServerItem::OnGetExtent
This function should return the "natural size" in HIMETRIC units of the item. The best way to think of the "natural
size" is to define it as the size it might appear when printed. The size returned here is constant for a particular item
contents (much like the metafile, which is constant for a particular item). This size does not change when zooming
is applied to the item. It usually does not change when the container gives the item more or less space by calling
OnSetExtent . An example of a change might be that of a simple text editor with no "margin" capability that
wrapped text based on the last extent sent by the container. If a server does change, the server should probably set
the OLEMISC_RECOMPOSEONRESIZE bit in the system registry (see the OLE SDK documentation for more
information on this option).

COleServerItem::OnSetExtent
This function is called when the container shows "more or less" of the object. Most containers will not call this at
all. The default implementation stores the last value received from the container in 'm_sizeExtent', which is used in
COleServerDoc::GetZoomFactor when computing the CONTAINER EXTENT value described above.

COleServerDoc::OnSetItemRects
This function is called only when the document is in-place active. It is called when the container updates either the
item's position or the clipping applied to the item. The POSITION RECTANGLE, as discussed above, provides the
numerator for the zoom factor calculation. A server can request that the item position be changed by calling
COleServerDoc::RequestPositionChange . The container may or may not respond to this request by calling
OnSetItemRects (with a call to COleServerItem::SetItemRects ).

COleServerDoc::OnDraw
It is important to realize that the metafile created by overriding of COleServerItem::OnDraw produces exactly the
same metafile, regardless of the current zoom factor. The container will scale the metafile as appropriate. This is an
important distinction between the view's OnDraw and the server item's OnDraw . The view handles zooming, the
item just creates a zoomable metafile and leaves it up to the container to do the appropriate zooming.
The best way to insure that your server behaves correctly is to use the implementation of
COleServerDoc::GetZoomFactor if your document is in-place active.

MFC Support for In-Place Resizing


MFC fully implements the in-place resizing interface as described in the OLE 2 specification. The user-interface is
supported by the COleResizeBar class, a custom message WM_SIZECHILD, and special handling of this message in
COleIPFrameWnd .

You may want to implement different handling of this message than what is provided by the framework. As
described above, the framework leaves the results of in-place resizing up to the container — the server responds
to the change in the zoom factor. If the container reacts by setting the both CONTAINER EXTENT and POSITION
RECTANGLE during the processing of its COleClientItem::OnChangeItemPosition (called as a result of a call to
COleServerDoc::RequestPositionChange ) then the in-place resize will result in showing "more or less" of the item in
the editing window. If the container reacts by just setting the POSITION RECTANGLE during the processing of
COleClientItem::OnChangeItemPosition , the zoom factor will change and the item will be shown "zoomed in or out."

A server can control (to some degree) what happens during this negotiation. A spreadsheet, for example might
elect to show more or fewer cells when the user resizes the window while editing the item in-place. A word-
processor might elect to change the "page margins" so they are the same as the window and rewrap the text to the
new margin. Servers implement this by changing the natural extent (the size returned from
COleServerItem::OnGetExtent ) when the resizing is done. This will cause both the POSITION RECTANGLE and the
CONTAINER EXTENT to change by the same amount, resulting in the same zoom factor, but a bigger or smaller
viewing area. In addition, more or less of the document will be visible in the metafile generated by OnDraw . In this
case, the document itself is changing when the user resizes the item, instead of just the viewing area.
You can implement custom resizing and still leverage the user interface provided by COleResizeBar by overriding
the WM_SIZECHILD message in your COleIPFrameWnd class. For more information on the specifics of
WM_SIZECHILD, see Technical Note 24.

See also
Technical Notes by Number
Technical Notes by Category
TN041: MFC/OLE1 Migration to MFC/OLE 2
5/14/2019 • 27 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

General Issues Relating to Migration


One of the design goals for the OLE 2 classes in MFC 2.5 (and higher) was to retain much of the same architecture
put in place in MFC 2.0 for OLE 1.0 support. As a result, many of the same OLE classes in MFC 2.0 still exist in this
version of MFC ( COleDocument , COleServerDoc , COleClientItem , COleServerItem ). In addition, many of the APIs in
these classes are exactly the same. However, OLE 2 is drastically different from OLE 1.0 so you can expect that
some of the details have changed. If you are familiar with MFC 2.0's OLE1 support, you'll feel at home with MFC's
2.0 support.
If you are taking an existing MFC/OLE1 application and adding OLE 2 functionality to it, you should read this note
first. This note covers some general issues you may encounter while porting your OLE1 functionality to MFC/OLE
2 and then discusses the problems uncovered while porting two applications included in MFC 2.0: the MFC OLE
samples OCLIENT and HIERSVR.

MFC Document/View Architecture Is Important


If your application does not use MFC's Document/View architecture and you want to add OLE 2 support to your
application, now is the time to move to Document/View. Many of the benefits of MFC's OLE 2 classes are only
realized once your application is using the built-in architecture and components of MFC.
Implementing a server or container without using the MFC architecture is possible, but not recommended.

Use MFC Implementation Instead of Your Own


MFC "canned implementation" classes such as CToolBar , CStatusBar , and CScrollView have built-in special case
code for OLE 2 support. So, if you can use these classes in your application you'll benefit from the effort put into
them to make them OLE aware. Again, it is possible to "roll-your-own" classes here for these purposes, but it is not
suggested. If you need to implement similar functionality, the MFC source code is an excellent reference for
dealing with some of the finer points of OLE (especially when it comes to in-place activation).

Examine the MFC Sample Code


There are a number of MFC samples that include OLE functionality. Each of these applications implements OLE
from a different angle:
HIERSVR Meant mostly for use as a server application. It was included in MFC 2.0 as an MFC/OLE1
application and has been ported to MFC/OLE 2 and then extended such that it implements many OLE
features available in OLE 2.
OCLIENT This is a stand-alone container application, meant to demonstrate many of the OLE features from
a container standpoint. It too was ported from MFC 2.0, and then extended to support many of the more
advanced OLE features, such as custom clipboard formats and links to embedded items.
DRAWCLI This application implements OLE container support much like OCLIENT does, except that it does
so within the framework of an existing object-oriented drawing program. It shows you how you might
implement OLE container support and integrate it into your existing application.
SUPERPAD This application, as well as being a fine stand-alone application, is also an OLE server. The server
support it implements is quite minimalist. Of particular interest is how it uses OLE clipboard services to
copy data to the clipboard, but uses the functionality built into the Windows "edit" control to implement
clipboard paste functionality. This shows an interesting mix of traditional Windows API usage as well as
integration with the new OLE APIs.
For more information on the sample applications, see the "MFC Sample Help".

Case Study: OCLIENT from MFC 2.0


As discussed above, OCLIENT was included in MFC 2.0 and implemented OLE with MFC/OLE1. The steps by which
this application was initially converted to use the MFC/OLE 2 classes are described below. A number of features
were added after the initial port was completed to better illustrate the MFC/OLE classes. These features will not be
covered here; refer to the sample itself for more information on those advanced features.

NOTE
The compiler errors and step-by-step process was created with Visual C++ 2.0. Specific error messages and locations may
have changed with Visual C++ 4.0, but the conceptual information remains valid.

Getting It Up and Running


The approach taken to port the OCLIENT sample to MFC/OLE is to start by building it and fixing the obvious
compiler errors that will result. If you take the OCLIENT sample from MFC 2.0 and compile it under this version of
MFC, you'll find that there are not that many errors to resolve. The errors in the order in which they occurred are
described below.

Compile and Fix Errors


\oclient\mainview.cpp(104) : error C2660: 'Draw' : function does not take 4 parameters

The first error concerns COleClientItem::Draw . In MFC/OLE1 it took more parameters than the MFC/OLE version
takes. The extra parameters were often not necessary and usually NULL (as in this example). This version of MFC
can automatically determine the values for the lpWBounds when the CDC that is being drawn to is a metafile DC.
In addition, the pFormatDC parameter is no longer necessary since the framework will build one from the
"attribute DC" of the pDC passed in. So to fix this problem, you simply remove the two extra NULL parameters to
the Draw call.

\oclient\mainview.cpp(273) : error C2065: 'OLE_MAXNAMESIZE' : undeclared identifier


\oclient\mainview.cpp(273) : error C2057: expected constant expression
\oclient\mainview.cpp(280) : error C2664: 'CreateLinkFromClipboard' : cannot convert parameter 1 from 'char
[1]' to 'enum ::tagOLERENDER '
\oclient\mainview.cpp(286) : error C2664: 'CreateFromClipboard' : cannot convert parameter 1 from 'char [1]'
to 'enum ::tagOLERENDER '
\oclient\mainview.cpp(288) : error C2664: 'CreateStaticFromClipboard' : cannot convert parameter 1 from 'char
[1]' to 'enum ::tagOLERENDER '

The errors above result from the fact that all of the COleClientItem::CreateXXXX functions in MFC/OLE1 required
that a unique name be passed to represent the item. This was a requirement of the underlying OLE API. This is not
necessary in MFC/OLE 2 since OLE 2 does not use DDE as the underlying communications mechanism (the name
was used in DDE conversations). To fix this problem, you can remove the CreateNewName function as well as all
references to it. It is easy to find out what each MFC/OLE function is expecting in this version simply by placing
your cursor on the call and pressing F1.
Another area that is significantly different is OLE 2 clipboard handling. With OLE1, you used the Windows
clipboard APIs interact with the clipboard. With OLE 2 this is done with a different mechanism. The MFC/OLE1 APIs
assumed that the clipboard was open before copying a COleClientItem object to the clipboard. This is no longer
necessary and will cause all MFC/OLE clipboard operations to fail. While you edit the code to remove
dependencies on CreateNewName , you should also remove the code that opens and closes the Windows clipboard.

\oclient\mainview.cpp(332) : error C2065: 'AfxOleInsertDialog' : undeclared identifier


\oclient\mainview.cpp(332) : error C2064: term does not evaluate to a function
\oclient\mainview.cpp(344) : error C2057: expected constant expression
\oclient\mainview.cpp(347) : error C2039: 'CreateNewObject' : is not a member of 'CRectItem'

These errors result from the CMainView::OnInsertObject handler. Handling the "Insert New Object" command is
another area where things have changed quite a bit. In this case, it is easiest to simply merge the original
implementation with that provided by AppWizard for a new OLE Container application. In fact, this is a technique
that you can apply to porting other applications. In MFC/OLE1, you displayed the "Insert Object" dialog by calling
AfxOleInsertDialog function. In this version you construct a COleInsertObject dialog object and call DoModal . In
addition, new OLE items are created with a CLSID instead of a classname string. The end result should look
something like this
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;

BeginWaitCursor();

CRectItem* pItem = NULL;


TRY
{
// First create the C++ object
pItem = GetDocument()->CreateItem();
ASSERT_VALID(pItem);

// Initialize the item from the dialog data.


if (!dlg.CreateItem(pItem))
AfxThrowMemoryException();
// any exception will do
ASSERT_VALID(pItem);

// run the object if appropriate


if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);

// update right away


pItem->UpdateLink();
pItem->UpdateItemRectFromServer();

// set selection to newly inserted item


SetSelection(pItem);
pItem->Invalidate();
}
CATCH (CException, e)
{
// clean up item
if (pItem != NULL)
GetDocument()->DeleteItem(pItem);

AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH

EndWaitCursor();

NOTE
Insert New Object may be different for your application):

It is also necessary to include <afxodlgs.h>, which contains the declaration for the COleInsertObject dialog class
as well as the other standard dialogs provided by MFC.

\oclient\mainview.cpp(367) : error C2065: 'OLEVERB_PRIMARY' : undeclared identifier


\oclient\mainview.cpp(367) : error C2660: 'DoVerb' : function does not take 1 parameters

These errors are caused by the fact that some OLE1 constants have changed in OLE 2, even though in concept they
are the same. In this case OLEVERB_PRIMARY has changed to OLEIVERB_PRIMARY . In both OLE1 and OLE 2, the primary
verb is usually executed by a container when the user double-clicks on an item.
In addition, DoVerb now takes an extra parameter — a pointer to a view ( CView *). This parameter is only used to
implement "Visual Editing" (or in-place activation). For now you set that parameter to NULL, because you are not
implementing this feature at this time.
To make sure that the framework never attempts to in-place activate, you should override
COleClientItem::CanActivate as follows:

BOOL CRectItem::CanActivate()
{
return FALSE;
}

\oclient\rectitem.cpp(53) : error C2065: 'GetBounds' : undeclared identifier


\oclient\rectitem.cpp(53) : error C2064: term does not evaluate to a function
\oclient\rectitem.cpp(84) : error C2065: 'SetBounds' : undeclared identifier
\oclient\rectitem.cpp(84) : error C2064: term does not evaluate to a function

In MFC/OLE1, COleClientItem::GetBounds and SetBounds were used to query and manipulate the extent of an item
(the left and top members were always zero). In MFC/OLE 2 this is more directly supported by
COleClientItem::GetExtent and SetExtent , which deal with a SIZE or CSize instead.

The code for your new SetItemRectToServer, and UpdateItemRectFromServer calls look like this:
BOOL CRectItem::UpdateItemRectFromServer()
{
ASSERT(m_bTrackServerSize);
CSize size;
if (!GetExtent(&size))
return FALSE; // blank

// map from HIMETRIC to screen coordinates


{
CClientDC screenDC(NULL);
screenDC.SetMapMode(MM_HIMETRIC);
screenDC.LPtoDP(&size);
}
// just set the item size
if (m_rect.Size() != size)
{
// invalidate the old size/position
Invalidate();
m_rect.right = m_rect.left + size.cx;
m_rect.bottom = m_rect.top + size.cy;
// as well as the new size/position
Invalidate();
}
return TRUE;
}

BOOL CRectItem::SetItemRectToServer()
{
// set the official bounds for the embedded item
CSize size = m_rect.Size();
{
CClientDC screenDC(NULL);
screenDC.SetMapMode(MM_HIMETRIC);
screenDC.DPtoLP(&size);
}
TRY
{
SetExtent(size); // may do a wait
}
CATCH(CException, e)
{
return FALSE; // links will not allow SetBounds
}
END_CATCH
return TRUE;
}

\oclient\frame.cpp(50) : error C2039: 'InWaitForRelease' : is not a member of 'COleClientItem'


\oclient\frame.cpp(50) : error C2065: 'InWaitForRelease' : undeclared identifier
\oclient\frame.cpp(50) : error C2064: term does not evaluate to a function

In MFC/OLE1 synchronous API calls from a container to a server were simulated, because OLE1 was inherently
asynchronous in many cases. It was necessary to check for an outstanding asynchronous call in progress before
processing commands from the user. MFC/OLE1 provided the COleClientItem::InWaitForRelease function for
doing so. In MFC/OLE 2 this is not necessary, so you can to remove the override of OnCommand in CMainFrame
all together.
At this point OCLIENT will compile and link.

Other Necessary Changes


There are few things that are not done that will keep OCLIENT from running, however. It is better to fix these
problems now instead of later.
First, it is necessary to initialize the OLE libraries. This is done by calling AfxOleInit from InitInstance :

if (!AfxOleInit())
{
AfxMessageBox("Failed to initialize OLE libraries");
return FALSE;
}

It is also a good idea to check for virtual functions for parameter list changes. One such function is
COleClientItem::OnChange , overridden in every MFC/OLE container application. By looking at online help, you'll see
that an extra 'DWORD dwParam' was added. The new CRectItem::OnChange looks as follows:

void
CRectItem::OnChange(OLE_NOTIFICATION wNotification, DWORD dwParam)
{
if (m_bTrackServerSize && !UpdateItemRectFromServer())
{
// Blank object
if (wNotification == OLE_CLOSED)
{
// no data received for the object - destroy it
ASSERT(!IsVisible());
GetDocument()->DeleteItem(this);
return; // no update (item is gone now)
}
}
if (wNotification != OLE_CLOSED)
Dirty();
Invalidate();
// any change will cause a redraw
}

In MFC/OLE1, container applications derived the document class from COleClientDoc . In MFC/OLE 2 this class has
been removed and replaced by COleDocument (this new organization makes it easier to build container/server
applications). There is a #define that maps COleClientDoc to COleDocument to simplify porting of MFC/OLE1
applications to MFC/OLE 2, such as OCLIENT. One of the features not supplied by COleDocument that was provided
by COleClientDoc is the standard command message map entries. This is done so that server applications, which
also use COleDocument (indirectly), do not carry with them the overhead of these command handlers unless they
are a container/server application. You need to add the following entries to the CMainDoc message map:

ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdatePasteMenu)
ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE_LINK, OnUpdatePasteLinkMenu)
ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_LINKS, OnUpdateEditLinksMenu)
ON_COMMAND(ID_OLE_EDIT_LINKS, COleDocument::OnEditLinks)
ON_UPDATE_COMMAND_UI(ID_OLE_VERB_FIRST, OnUpdateObjectVerbMenu)
ON_UPDATE_COMMAND_UI(ID_OLE_EDIT_CONVERT, OnUpdateObjectVerbMenu)
ON_COMMAND(ID_OLE_EDIT_CONVERT, OnEditConvert)

The implementation of all of these commands is in COleDocument , which is the base class for your document.
At this point, OCLIENT is a functional OLE container application. It is possible to insert items of any type (OLE1 or
OLE 2). Since the necessary code to enable in-place activation is not implemented, items are edited in a separate
window much like with OLE1. The next section discusses the necessary changes to enable in-place editing
(sometimes called "Visual Editing").

Adding "Visual Editing"


One of the most interesting features of OLE is in-place activation (or "Visual Editing"). This feature allows the
server application to take over portions of the container's user interface to provided a more seamless editing
interface for the user. To implement in-place activation to OCLIENT, some special resources need to be added, as
well as some additional code. These resources and the code are normally provided by AppWizard — in fact, much
of the code here was borrowed directly from a fresh AppWizard application with "Container" support.
First of all, it is necessary to add a menu resource to be used when there is an item which is in-place active. You
can create this extra menu resource in Visual C++ by copying the IDR_OCLITYPE resource and removing all but
the File and Window pop-ups. Two separator bars are inserted between the File and Window pop-ups to indicate
the separation of groups (it should look like: File || Window). For more information on what these separators mean
and how the server and container menus are merged see Menus and Resources: Menu Merging.
Once you have these menus created, you need to let the framework know about them. This is done by calling
CDocTemplate::SetContainerInfo for the document template before you add it to the document template list in
your InitInstance. The new code to register the document template looks like this:

CDocTemplate* pTemplate = new CMultiDocTemplate(


IDR_OLECLITYPE,
RUNTIME_CLASS(CMainDoc),
RUNTIME_CLASS(CMDIChildWnd), // standard MDI child frame
RUNTIME_CLASS(CMainView));

pTemplate->SetContainerInfo(IDR_OLECLITYPE_INPLACE);

AddDocTemplate(pTemplate);

The IDR_OLECLITYPE_INPLACE resource is the special in-place resource created in Visual C++.
To enable in-place activation, there are some things that need to change in both the CView (CMainView) derived
class as well as the COleClientItem derived class (CRectItem). All of these overrides are provided by AppWizard
and most of the implementation will come directly from a default AppWizard application.
In the first step of this port, in-place activation was disabled entirely by overriding COleClientItem::CanActivate .
This override should be removed to allow in-place activation. In addition, NULL was passed to all calls to DoVerb
(there are two of them) because providing the view was only necessary for in-place activation. To fully implement
in-place activation, it is necessary to pass the correct view in the DoVerb call. One of these calls is in
CMainView::OnInsertObject :

pItem->DoVerb(OLEIVERB_SHOW, this);

Another is in CMainView::OnLButtonDblClk :

m_pSelection->DoVerb(OLEIVERB_PRIMARY, this);

It is necessary to override COleClientItem::OnGetItemPosition . This tells the server where to put its window relative
to the container's window when the item is in-place activated. For OCLIENT, the implementation is trivial:

void CRectItem::OnGetItemPosition(CRect& rPosition)


{
rPosition = m_rect;
}

Most servers also implement what is called "in-place resizing." This allows the server window to be sized and
moved while the user is editing the item. The container must participate in this action, since moving or resizing the
window usually affects the position and size within the container document itself. The implementation for OCLIENT
synchronizes the internal rectangle maintained by m_rect with the new position and size.

BOOL CRectItem::OnChangeItemPosition(const CRect& rectPos)


{
ASSERT_VALID(this);

if (!COleClientItem::OnChangeItemPosition(rectPos))
return FALSE;

Invalidate();
m_rect = rectPos;
Invalidate();
GetDocument()->SetModifiedFlag();

return TRUE;
}

At this point, there is enough code to allow an item to be in-place activated and to deal with sizing and moving the
item when it is active, but no code will allow the user to exit the editing session. Although some servers will
provide this functionality themselves by handling the escape key, it is suggested that containers provide two ways
to deactivate an item: (1) by clicking outside the item, and (2) by pressing the ESCAPE key.
For the ESCAPE key, add an accelerator with Visual C++ that maps the VK_ESCAPE key to a command,
ID_CANCEL_EDIT is added to the resources. The handler for this command follows:

// The following command handler provides the standard


// keyboard user interface to cancel an in-place
// editing session.void CMainView::OnCancelEdit()
{
// Close any in-place active item on this view.
COleClientItem* pActiveItem =
GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->Close();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}

To handle the case where the user clicks outside the item, you add the following code to the start of
CMainView::SetSelection :

if (pNewSel != m_pSelection || pNewSel == NULL)


{
COleClientItem* pActiveItem =
GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL&& pActiveItem != pNewSel)
pActiveItem->Close();
}

When an item is in-place active, it should have the focus. To make sure this is the case you handle OnSetFocus so
that focus is always transferred to the active item when your view receives the focus:
// Special handling of OnSetFocus and OnSize are required
// when an object is being edited in-place.
void CMainView::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem =
GetDocument()->GetInPlaceActiveItem(this);

if (pActiveItem != NULL &&


pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
// need to set focus to this item if it is same view
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // don't call the base class
return;
}
}

CView::OnSetFocus(pOldWnd);
}

When the view is resized, you need to notify the active item that the clipping rectangle has changed. To do this you
provide a handler for OnSize :

void CMainView::OnSize(UINT nType, int cx, int cy)


{
CView::OnSize(nType, cx, cy);
COleClientItem* pActiveItem =
GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->SetItemRects();
}

Case Study: HIERSVR from MFC 2.0


HIERSVR was also included in MFC 2.0 and implemented OLE with MFC/OLE1. This note briefly describes the steps
by which this application was initially converted to use the MFC/OLE 2 classes. A number of features were added
after the initial port was completed to better illustrate the MFC/OLE 2 classes. These features will not be covered
here; refer to the sample itself for more information on those advanced features.

NOTE
The compiler errors and step-by-step process was created with Visual C++ 2.0. Specific error messages and locations may
have changed with Visual C++ 4.0, but the conceptual information remains valid.

Getting It Up and Running


The approach taken to port the HIERSVR sample to MFC/OLE is to start by building it and fixing the obvious
compiler errors that will result. If you take the HIERSVR sample from MFC 2.0 and compile it under this version of
MFC, you'll find that there are not many errors to resolve (although there are more than with the OCLIENT
sample). The errors in the order in which they usually occur are described below.

Compile and Fix Errors


\hiersvr\hiersvr.cpp(83) : error C2039: 'RunEmbedded' : is not a member of 'COleTemplateServer'

This first error points out a much larger problem with the InitInstance function for servers. The initialization
required for an OLE server is probably one of the biggest changes you'll have to make to your MFC/OLE1
application to get it running. The best thing to do is look at what AppWizard creates for an OLE server and modify
your code as appropriate. Here are some points to keep in mind:
It is necessary to initialize the OLE libraries by calling AfxOleInit

Call SetServerInfo on the document template object to set server resource handles and runtime class information
that you can't set with the CDocTemplate constructor.
Don't show the main window of your application if /Embedding is present on the command line.
You'll need a GUID for your document. This is a unique identifier for your document's type (128 bits). AppWizard
will create one for you — so if you use the technique described here of copying the new code from a new
AppWizard generated server application, you can simply "steal" the GUID from that application. If not, you can use
the GUIDGEN.EXE utility in the BIN directory.
It is necessary to "connect" your COleTemplateServer object to the document template by calling
COleTemplateServer::ConnectTemplate .
Update the system registry when your application is run stand-alone. This way, if the user moves the .EXE for your
application, running it from its new location will update the Windows system registration database to point to the
new location.
After applying all of these changes based on what AppWizard creates for InitInstance , the InitInstance (and
related GUID) for HIERSVR should read as follows:

// this is the GUID for HIERSVR documents


static const GUID BASED_CODE clsid =
{ 0xA0A16360L, 0xC19B, 0x101A, { 0x8C, 0xE5, 0x00, 0xDD, 0x01, 0x11, 0x3F, 0x12 } };

/////////////////////////////////////////////////////////////////////////////
// COLEServerApp initialization

BOOL COLEServerApp::InitInstance()
{
// OLE 2 initialization
if (!AfxOleInit())
{
AfxMessageBox("Initialization of the OLE failed!");
return FALSE;
}

// Standard initialization
LoadStdProfileSettings(); // Load standard INI file options

// Register document templates


CDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(IDR_HIERSVRTYPE,
RUNTIME_CLASS(CServerDoc),
RUNTIME_CLASS(CMDIChildWnd),
RUNTIME_CLASS(CServerView));
pDocTemplate->SetServerInfo(IDR_HIERSVRTYPE_SRVR_EMB);
AddDocTemplate(pDocTemplate);

// create main MDI Frame window


CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
return FALSE;
m_pMainWnd = pMainFrame;
m_pMainWnd = pMainFrame;

SetDialogBkColor(); // gray look

// enable file manager drag/drop and DDE Execute open


m_pMainWnd->DragAcceptFiles();
EnableShellOpen();

m_server.ConnectTemplate(clsid, pDocTemplate, FALSE);


COleTemplateServer::RegisterAll();

// try to launch as an OLE server


if (RunEmbedded())
{
// "short-circuit" initialization -- run as server!
return TRUE;
}
m_server.UpdateRegistry();
RegisterShellFileTypes();

// not run as OLE server, so show the main window


if (m_lpCmdLine[0] == '\0')
{
// create a new (empty) document
OnFileNew();
}
else
{
// open an existing document
OpenDocumentFile(m_lpCmdLine);
}

pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();

return TRUE;
}

You will notice that the code above refers to a new resource ID, IDR_HIERSVRTYPE_SRVR_EMB. This is the menu
resource to be used when a document that is embedded in another container is edited. In MFC/OLE1 the menu
items specific to editing an embedded item were modified on the fly. Using an entirely different menu structure
when editing an embedded item instead of editing a file-based document makes it much easier to provide
different user interfaces for these two separate modes. As you'll see later, an entirely separate menu resource is
used when editing an embedded object in-place.
To create this resource, load the resource script into Visual C++ and copy the existing IDR_HIERSVRTYPE menu
resource. Rename the new resource to IDR_HIERSVRTYPE_SRVR_EMB (this is the same naming convention that
AppWizard uses). Next change "File Save" to "File Update"; give it command ID ID_FILE_UPDATE. Also change "File
Save As" to "File Save Copy As"; give it command ID ID_FILE_SAVE_COPY_AS. The framework provides the
implementation of both of these commands.

\hiersvr\svritem.h(60) : error C2433: 'OLESTATUS' : 'virtual' not permitted on data declarations


\hiersvr\svritem.h(60) : error C2501: 'OLESTATUS' : missing decl-specifiers
\hiersvr\svritem.h(60) : error C2146: syntax error : missing ';' before identifier 'OnSetData'
\hiersvr\svritem.h(60) : error C2061: syntax error : identifier 'OLECLIPFORMAT'
\hiersvr\svritem.h(60) : error C2501: 'OnSetData' : missing decl-specifiers

There are a number of errors resulting from the override of OnSetData , since it is referring to the OLESTATUS
type. OLESTATUS was the way OLE1 returned errors. This has changed to HRESULT in OLE 2, although MFC
usually converts an HRESULT into a COleException containing the error. In this particular case, the override of
OnSetData is no longer necessary, so the easiest thing to do is to remove it.
\hiersvr\svritem.cpp(30) : error C2660: 'COleServerItem::COleServerItem' : function does not take 1 parameters

The COleServerItem constructor takes an extra 'BOOL' parameter. This flag determines how memory management
is done on the COleServerItem objects. By setting it to TRUE, the framework handles the memory management of
these objects — deleting them when they are no longer necessary. HIERSVR uses CServerItem (derived from
COleServerItem ) objects as part of its native data, so you'll set this flag to FALSE. This lets HIERSVR determine
when each server item is deleted.

\hiersvr\svritem.cpp(44) : error C2259: 'CServerItem' : illegal attempt to instantiate abstract class


\hiersvr\svritem.cpp(44) : error C2259: 'CServerItem' : illegal attempt to instantiate abstract class

As these errors imply, there are some 'pure-virtual' functions that have not been overridden in CServerItem. Most
likely this is caused by the fact that OnDraw's parameter list has changed. To fix this error, change
CServerItem::OnDraw as follows (as well as the declaration in svritem.h):

BOOL CServerItem::OnDraw(CDC* pDC, CSize& rSize)


{
// request from OLE to draw node
pDC->SetMapMode(MM_TEXT); // always in pixels
return DoDraw(pDC, CPoint(0, 0), FALSE);
}

The new parameter is 'rSize'. This allows you to fill in the size of the drawing, if convenient. This size must be in
HIMETRIC . In this case, it is not convenient to fill this value in, so the framework calls OnGetExtent to retrieve the
extent. For that to work, you'll have to implement OnGetExtent :

BOOL CServerItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)


{
if (dwDrawAspect != DVASPECT_CONTENT)
return COleServerItem::OnGetExtent(dwDrawAspect, rSize);

rSize = CalcNodeSize();
return TRUE;
}

\hiersvr\svritem.cpp(104) : error C2065: 'm_rectBounds' : undeclared identifier


\hiersvr\svritem.cpp(104) : error C2228: left of '.SetRect' must have class/struct/union type
\hiersvr\svritem.cpp(106) : error C2664: 'void __pascal __far DPtoLP(struct ::tagPOINT __far *,
int)__far const ' : cannot convert parameter 1 from 'int __far *' to 'struct ::tagPOINT __far *'

In the CServerItem::CalcNodeSize function the item size is converted to HIMETRIC and stored in m_rectBounds.
The undocumented 'm_rectBounds' member of COleServerItem does not exist (it has been partially replaced by
m_sizeExtent, but in OLE 2 this member has a slightly different usage than m_rectBounds did in OLE1). Instead of
setting the HIMETRIC size into this member variable, you'll return it. This return value is used in OnGetExtent ,
implemented previously.
CSize CServerItem::CalcNodeSize()
{
CClientDC dcScreen(NULL);

m_sizeNode = dcScreen.GetTextExtent(m_strDescription,
m_strDescription.GetLength());
m_sizeNode += CSize(CX_INSET * 2, CY_INSET * 2);

// set suggested HIMETRIC size


CSize size(m_sizeNode.cx, m_sizeNode.cy);
dcScreen.SetMapMode(MM_HIMETRIC);
dcScreen.DPtoLP(&size);
return size;
}

CServerItem also overrides COleServerItem::OnGetTextData . This function is obsolete in MFC/OLE and is replaced
by a different mechanism. The MFC 3.0 version of the MFC OLE sample HIERSVR implements this functionality by
overriding COleServerItem::OnRenderFileData . This functionality is not important for this basic port, so you can
remove the OnGetTextData override.
There are many more errors in svritem.cpp that have not been addressed. They are not "real" errors — just errors
caused by previous errors.

\hiersvr\svrview.cpp(325) : error C2660: 'CopyToClipboard' : function does not take 2 parameters

COleServerItem::CopyToClipboard no longer supports the bIncludeNative flag. The native data (the data written
out by the server item's Serialize function) is always copied, so you remove the first parameter. In addition,
CopyToClipboard will throw an exception when an error happens instead of returning FALSE. Change the code for
CServerView::OnEditCopy as follows:

void CServerView::OnEditCopy()
{
if (m_pSelectedNode == NULL)
AfxThrowNotSupportedException();

TRY
{
m_pSelectedNode->CopyToClipboard(TRUE);
}
CATCH_ALL(e)
{
AfxMessageBox("Copy to clipboard failed");
}
END_CATCH_ALL
}

Although there were more errors resulting from the compilation of the MFC 2.0 version of HIERSVR than there
were for the same version of OCLIENT, there were actually fewer changes.
At this point HIERSVR will compile and link and function as an OLE server, but without the in-place editing feature,
which will be implemented next.

Adding "Visual Editing"


To add "Visual Editing" (or in-place activation) to this server application, there are only a few things you must take
care of:
You need a special menu resource to be used when the item is in-place active.
This application has a toolbar, so you'll need a toolbar with only a subset of the normal toolbar to match the
menu commands available from the server (matches the menu resource mentioned above).
You need a new class derived from COleIPFrameWnd that provides the in-place user interface (much like
CMainFrame, derived from CMDIFrameWnd , provides the MDI user interface).
You need to tell the framework about these special resources and classes.
The menu resource is easy to create. Run Visual C++, copy the menu resource IDR_HIERSVRTYPE to a menu
resource called IDR_HIERSVRTYPE_SRVR_IP. Modify the menu so that only the Edit and Help menu popups are left.
Add two separators to the menu in between the Edit and Help menus (it should look like: Edit || Help). For more
information on what these separators mean and how the server and container menus are merged, see Menus and
Resources: Menu Merging.
The bitmap for the subset toolbar can be easily created by copying the one from a fresh AppWizard generated
application with a "Server" option checked. This bitmap can then be imported into Visual C++. Be sure to give the
bitmap an ID of IDR_HIERSVRTYPE_SRVR_IP.
The class derived from COleIPFrameWnd can be copied from an AppWizard generated application with server
support as well. Copy both files, IPFRAME.CPP and IPFRAME.H and add them to the project. Make sure that the
LoadBitmap call refers to IDR_HIERSVRTYPE_SRVR_IP, the bitmap created in the previous step.

Now that all the new resources and classes are created, add the necessary code so that the framework knows
about these (and knows that this application now supports in-place editing). This is done by adding some more
parameters to the SetServerInfo call in the InitInstance function:

pDocTemplate->SetServerInfo(IDR_HIERSVRTYPE_SRVR_EMB,
IDR_HIERSVRTYPE_SRVR_IP,
RUNTIME_CLASS(CInPlaceFrame));

It is now ready to run in-place in any container that also supports in-place activation. But, there is one minor bug
still lurking in the code. HIERSVR supports a context menu, displayed when the user presses the right mouse
button. This menu works when HIERSVR is fully open, but does not work when editing an embedding in-place. The
reason can be pinned down to this single line of code in CServerView::OnRButtonDown:

pMenu->TrackPopupMenu(TPM_CENTERALIGN | TPM_RIGHTBUTTON,
point.x,
point.y,
AfxGetApp()->m_pMainWnd);

Notice the reference to AfxGetApp()->m_pMainWnd . When the server is in-place activated, it has a main window and
m_pMainWnd is set, but it is usually invisible. Furthermore, this window refers to the main window of the
application, the MDI frame window that appears when the server is fully open or run stand-alone. It does not refer
to the active frame window — which when in-place activated is a frame window derived from COleIPFrameWnd . To
get the correct active window even when in-place editing, this version of MFC adds a new function, AfxGetMainWnd .
Generally, you should use this function instead of AfxGetApp()->m_pMainWnd . This code needs to change as follows:

pMenu->TrackPopupMenu(TPM_CENTERALIGN | TPM_RIGHTBUTTON,
point.x,
point.y,
AfxGetMainWnd());

Now you have an OLE server minimally enabled for functional in-place activation. But there are still many features
available with MFC/OLE 2 that were not available in MFC/OLE1. See the HIERSVR sample for more ideas on
features you might want to implement. Some of the features that HIERSVR implements are listed below:
Zooming, for true WYSIWYG behavior with respect to the container.
Drag / drop and a custom clipboard format.
Scrolling the container window as the selection is changed.
The HIERSVR sample in MFC 3.0 also uses a slightly different design for its server items. This helps conserve
memory and makes your links more flexible. With the 2.0 version of HIERSVR each node in the tree is-a
COleServerItem . COleServerItem carries a bit more overhead than is strictly necessary for each of these nodes, but
a COleServerItem is required for each active link. But for the most part, there are very few active links at any given
time. To make this more efficient, the HIERSVR in this version of MFC separates the node from the COleServerItem .
It has both a CServerNode and a CServerItem class. The CServerItem (derived from COleServerItem ) is only
created as necessary. Once the container (or containers) stop using that particular link to that particular node, the
CServerItem object associated with the CServerNode is deleted. This design is more efficient and more flexible. Its
flexibility comes in when dealing with multiple selection links. Neither of these two versions of HIERSVR support
multiple selection, but it would be much easier to add (and to support links to such selections) with the MFC 3.0
version of HIERSVR, since the COleServerItem is separated from the native data.

See also
Technical Notes by Number
Technical Notes by Category
TN042: ODBC Driver Developer Recommendations
3/27/2020 • 4 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes guidelines for ODBC driver writers. It outlines general requirements and assumptions of ODBC
functionality that the MFC Database classes make, and various expected semantic details. Required driver
functionality to support the three CRecordset Open modes (for wardOnly , snapshot and dynaset ) are
described.

ODBC's Cursor Library


The MFC Database classes present functionality to the user that in many cases surpasses the functionality provided
by most level 1 ODBC drivers. Fortunately, ODBC's Cursor Library will layer itself between the database classes and
the driver, and will automatically provide much of this additional functionality.
For instance, most 1.0 drivers do not support backward scrolling. The Cursor Library can detect this, and will cache
rows from the driver and present them as requested on FETCH_PREV calls in SQLExtendedFetch .
Another important example of cursor library dependence is positioned updates. Most 1.0 drivers also do not have
positioned updates, but the cursor library will generate update statements which identify a target row on the data
source based upon its current cached data values, or a cached timestamp value.
The class library never makes use of multiple rowsets. Therefore, the few SQLSetPos statements are always applied
to row 1 of the rowset.

CDatabases
Each CDatabase allocates a single HDBC . (If CDatabase 's ExecuteSQL function is used, an HSTMT is temporarily
allocated.) So if multiple CDatabase 's are required, multiple HDBC s per HENV must be supported.
The database classes require the cursor library. This is reflected in a SQLSetConnections call
SQL_ODBC_CURSORS , SQL_CUR_USE_ODBC .
SQLDriverConnect , SQL_DRIVER_COMPLETE is used by CDatabase::Open to establish the connection to the data
source.
The driver must support >= SQL_OAC_LEVEL1 ,
SQLGetInfo SQL_ODBC_API_CONFORMANCE
SQLGetInfo SQL_ODBC_SQL_CONFORMANCE >= SQL_OSC_MINIMUM .
In order for transactions to be supported for the CDatabase and its dependent recordsets,
SQLGetInfo SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR must have
SQL_CR_PRESERVE . Otherwise, attempts to perform transaction control will be ignored.
SQLGetInfo SQL_DATA_SOURCE_READ_ONLY must be supported. If it returns "Y", no update operations will be performed
on the data source.
If the CDatabase is opened ReadOnly, an attempt to set the data source read only will be made with
SQLSetConnectOption SQL_ACCESS_MODE , SQL_MODE_READ_ONLY .
If identifiers require quoting, this information should be returned from the driver with an
SQLGetInfo SQL_IDENTIFIER_QUOTE_CHAR call.

For debugging purposes, SQLGetInfo SQL_DBMS_VER and SQL_DBMS_NAME are retrieved from the driver.
SQLSetStmtOption SQL_QUERY_TIMEOUT and SQL_ASYNC_ENABLE may be called on a CDatabase 's HDBC .
SQLError may be called with any or all arguments NULL.
Of course, SQLAllocEnv , SQLAllocConnect , SQLDisconnect and SQLFreeConnect must be supported.

ExecuteSQL
In addition to allocating and freeing a temporary HSTMT , ExecuteSQL calls SQLExecDirect , SQLFetch ,
SQLNumResultCol and SQLMoreResults . SQLCancel may be called on the HSTMT .

GetDatabaseName
SQLGetInfo SQL_DATABASE_NAME will be called.

BeginTrans, CommitTrans, Rollback


SQLSetConnectOption SQL_AUTOCOMMIT and SQLTransact SQL_COMMIT , SQL_ROLLBACK and SQL_AUTOCOMMIT
will be called if transaction requests are made.

CRecordsets
SQLAllocStmt , SQLPrepare , SQLExecute (For Open and Requery ), SQLExecDirect (for update operations),
SQLFreeStmt must be supported. SQLNumResultCols and SQLDescribeCol will be called on the results set at various
times.
SQLSetParam is used extensively for binding parameter data and DATA_AT_EXEC functionality.
SQLBindCol is used extensively to register output Column data storage locations with ODBC.
Two SQLGetData calls are used to retrieve SQL_LONG_VARCHAR and SQL_LONG_VARBINARY data. The first
call attempts to find the total length of the column value by calling SQLGetData with cbMaxValue of 0, but with a
valid pcbValue. If pcbValue holds SQL_NO_TOTAL , an exception is thrown. Otherwise, an HGLOBAL is allocated,
and another SQLGetData call made to retrieve the entire result.

Updating
If pessimistic locking is requested, SQLGetInfo SQL_LOCK_TYPES will be queried. If SQL_LCK_EXCLUSIVE is not
supported, an exception will be thrown.
Attempts to update a CRecordset (snapshot or dynaset ) will cause a second HSTMT to be allocated. For drivers
that do not support second HSTMT , the cursor library will simulate this functionality. Unfortunately, this may
sometimes mean forcing the current query on the first HSTMT to completion before processing the second
HSTMT 's request.
SQLFreeStmt SQL_CLOSE and SQL_RESET_PARAMS and SQLGetCursorName will be called during update operations.
If there are CLongBinar ys in the outputColumns , ODBC's DATA_AT_EXEC functionality must be supported.
This includes returning SQL_NEED_DATA from SQLExecDirect , SQLParamData and SQLPutData .
SQLRowCount is called after executing to verify that only 1 record was updated by the SQLExecDirect .

ForwardOnly Cursors
Only SQLFetch is required for the Move operations. Note that for wardOnly cursors do not support updates.

Snapshot Cursors
Snapshot functionality requires SQLExtendedFetch support. As noted above, the ODBC cursor library will detect
when a driver does not support SQLExtendedFetch , and provide the necessary support itself.

SQLGetInfo , SQL_SCROLL_OPTIONS must support SQL_SO_STATIC .

Dynaset Cursors
Below is the minimum support required to open a dynaset:
SQLGetInfo , SQL_ODBC_VER must return > "01".
SQLGetInfo , SQL_SCROLL_OPTIONS must support SQL_SO_KEYSET_DRIVEN .
SQLGetInfo , SQL_ROW_UPDATES must return "Y".
, SQL_POSITIONED_UPDATES must support SQL_PS_POSITIONED_DELETE and
SQLGetInfo
SQL_PS_POSITIONED_UPDATE .
In addition, if pessimistic locking is requested, a call to SQLSetPos with irow 1, fRefresh FALSE and fLock
SQL_LCK_EXCLUSIVE will be made.

See also
Technical Notes by Number
Technical Notes by Category
TN043: RFX Routines
3/4/2019 • 5 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes the record field exchange (RFX) architecture. It also describes how you write an RFX_
procedure.

Overview of Record Field Exchange


All recordset field functions are done with C++ code. There are no special resources or magic macros. The heart of
the mechanism is a virtual function that must be overridden in every derived recordset class. It is always found in
this form:

void CMySet::DoFieldExchange(CFieldExchange* pFX)


{
//{{AFX_FIELD_MAP(CMySet)
<recordset exchange field type call>
<recordset exchange function call>
//}}AFX_FIELD_MAP
}

The special format AFX comments allow ClassWizard to locate and edit the code within this function. Code that is
not compatible with ClassWizard should be placed outside of the special format comments.
In the above example, <recordset_exchange_field_type_call> is in the form:

pFX->SetFieldType(CFieldExchange::outputColumn);

and <recordset_exchange_function_call> is in the form:

RFX_Custom(pFX, "Col2", m_Col2);

Most RFX_ functions have three arguments as shown above, but some (e.g. RFX_Text and RFX_Binary ) have
additional optional arguments.
More than one RFX_ may be included in each DoDataExchange function.
See 'afxdb.h' for a list of all the recordset field exchange routines provided with MFC.
Recordset field calls are a way of registering memory locations (usually data members) to store field data for a
CMySet class.

Notes
Recordset field functions are designed to work only with the CRecordset classes. They are not generally usable by
any other MFC classes.
Initial values of data are set in the standard C++ constructor, usually in a block with //{{AFX_FIELD_INIT(CMylSet)
and //}}AFX_FIELD_INIT comments.
Each RFX_ function must support various operations, ranging from returning the dirty status of the field to
archiving the field in preparation for editing the field.
Each function that calls DoFieldExchange (for instance SetFieldNull , IsFieldDirty ), does its own initialization
around the call to DoFieldExchange .

How Does It Work


You do not need to understand the following in order to use record field exchange. However, understanding how
this works behind the scenes will help you write your own exchange procedure.
The DoFieldExchange member function is much like the Serialize member function — it is responsible for
getting or setting data to/from an external form (in this case columns from the result of an ODBC query) from/to
member data in the class. The pFX parameter is the context for doing data exchange and is similar to the CArchive
parameter to CObject::Serialize . The pFX (a CFieldExchange object) has an operation indicator, which is similar
to, but a generalization of the CArchive direction flag. An RFX function may have to support the following
operations:
BindParam — Indicate where ODBC should retrieve parameter data
BindFieldToColumn — Indicate where ODBC must retrieve/deposit outputColumn data
Fixup — Set CString/CByteArray lengths, set NULL status bit
MarkForAddNew — Mark dirty if value has changed since AddNew call
MarkForUpdate — Mark dirty if value has changed since Edit call
Name — Append field names for fields marked dirty
NameValue — Append "<column name>=" for fields marked dirty
Value — Append "" followed by separator, like ',' or ' '
SetFieldDirty — Set status bit dirty (i.e. changed) field
SetFieldNull — Set status bit indicating null value for field
IsFieldDirty — Return value of dirty status bit
IsFieldNull — Return value of null status bit
IsFieldNullable — Return TRUE if field can hold NULL values
StoreField — Archive field value
LoadField — Reload archived field value
GetFieldInfoValue — Return general information on a field
GetFieldInfoOrdinal — Return general information on a field

User Extensions
There are several ways to extend the default RFX mechanism. You can
Add new data types. For example:

CBookmark

Add new exchange procedures (RFX_).

void AFXAPI RFX_Bigint(CFieldExchange* pFX,


const char *szName,
BIGINT& value);

Have the DoFieldExchange member function conditionally include additional RFX calls or any other valid
C++ statements.

while (posExtraFields != NULL)


{
RFX_Text(pFX,
m_listName.GetNext(posExtraFields),
m_listValue.GetNext(posExtraValues));
}

NOTE
Such code cannot be edited by ClassWizard and should be used only outside of the special format comments.

Writing a Custom RFX


To write your own Custom RFX function, it is suggested that you copy an existing RFX function and modify it to
your own purposes. Selecting the right RFX to copy can make your job much easier. Some RFX functions have
some unique properties that you should take into account when deciding which to copy.
RFX_Long and RFX_Int : These are the simplest RFX functions. The data value does not need any special
interpretation, and the data size is fixed.
RFX_Single and RFX_Double : Like RFX_Long and RFX_Int above, these functions are simple and can make use of
the default implementation extensively. They are stored in dbflt.cpp instead of dbrfx.cpp, however, to enable
loading the runtime floating point library only when they are explicitly reference.
RFX_Text and RFX_Binary : These two functions preallocate a static buffer to hold string/binary information, and
must register these buffers with ODBC SQLBindCol instead of registering &value. Because of this, these two
functions have lots of special-case code.
RFX_Date : ODBC returns date and time information in their own TIMESTAMP_STRUCT data structure. This function
dynamically allocates a TIMESTAMP_STRUCT as a "proxy" for sending and receiving date time data. Various
operations must transfer the date and time information between the C++ CTime object and the
TIMESTAMP_STRUCT proxy. This complicates this function considerably, but it is a good example of how to use a
proxy for data transfer.
RFX_LongBinary : This is the only class library RFX function that does not use column binding to receive and send
data. This function ignores the BindFieldToColumn operation and instead, during the Fixup operation, allocates
storage to hold the incoming SQL_LONGVARCHAR or SQL_LONGVARBINARY data, then performs an SQLGetData
call to retrieve the value into the allocated storage. When preparing to send data values back to the data source
(such as NameValue and Value operations), this function uses ODBC's DATA_AT_EXEC functionality. See Technical
Note 45 for more information on working with SQL_LONGVARBINARY and SQL_LONGVARCHARs.
When writing your own RFX_ function, you will often be able to use CFieldExchange::Default to implement a
given operation. Look at the implementation of Default for the operation in question. If it performs the operation
you would be writing in your RFX_ function you can delegate to the CFieldExchange::Default . You can see
examples of calling CFieldExchange::Default in dbrfx.cpp
It is important to call IsFieldType at the start of your RFX function, and return immediately if it returns FALSE. This
mechanism keeps parameter operations from being performed on outputColumns, and vice versa (like calling
BindParam on an outputColumn). In addition, IsFieldType automatically keeps track of the count of
outputColumns (m_nFields) and params (m_nParams).

See also
Technical Notes by Number
Technical Notes by Category
TN044: MFC Support for DBCS
5/14/2019 • 2 minutes to read • Edit Online

This technical note described the support in MFC for "double-byte character sets" or DBCS. This information as
well as information on MFC's support for UNICODE is now available in the Class Library Reference.

See also
Technical Notes by Number
Technical Notes by Category
TN045: MFC/Database Support for Long
Varchar/Varbinary
4/21/2020 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes how to retrieve and send the ODBC SQL_LONGVARCHAR and SQL_LONGVARBINARY
data types using the MFC database classes.

Overview of Long Varchar/Varbinary Support


The ODBC SQL_LONG_VARCHAR and SQL_LONGBINARY data types (referred to here as long data columns)
can hold huge amounts of data. There are 3 ways you can handle this data:
Bind it to a CString / CByteArray .
Bind it to a CLongBinary .
Do not bind it at all and retrieve and send the long data value manually, independent of the database
classes.
Each of the three methods has advantages and disadvantages.
Long data columns are not supported for parameters to a query. They are only supported for outputColumns.

Binding a Long Data Column to a CString/CByteArray


Advantages:
This approach is simple to understand, and you work with familiar classes. The framework provides CFormView
support for CString with DDX_Text . You have lots of general string or collection functionality with the CString
and CByteArray classes, and you can control the amount of memory allocated locally to hold the data value. The
framework maintains an old copy of field data during Edit or AddNew function calls, and the framework can
automatically detect changes to the data for you.

NOTE
Since CString is designed for working on character data, and CByteArray for working on binary data, it is recommended
that you put the character data (SQL_LONGVARCHAR) into CString , and the binary data (SQL_LONGVARBINARY )
into CByteArray .

The RFX functions for CString and CByteArray have an additional argument which lets you override the default
size of allocated memory to hold the retrieved value for the data column. Note the nMaxLength argument in the
following function declarations:
void AFXAPI RFX_Text(CFieldExchange* pFX,
const char *szName,
CString& value,
int nMaxLength = 255,
int nColumnType =
SQL_VARCHAR);

void AFXAPI RFX_Binary(CFieldExchange* pFX,


const char *szName,
CByteArray& value,
int nMaxLength = 255);

If you retrieve a long data column into a CString or CByteArray , the maximum returned amount of data is, by
default, 255 bytes. Anything beyond this is ignored. In this case, the framework will throw the exception
AFX_SQL_ERROR_DATA_TRUNCATED . Fortunately, you can explicitly increase nMaxLength to greater values,
up to MAXINT .

NOTE
The value of nMaxLength is used by MFC to set the local buffer of the SQLBindColumn function. This is the local buffer for
storage of the data and does not actually affect the amount of data returned by the ODBC driver. RFX_Text and
RFX_Binary only make one call using SQLFetch to retrieve the data from the back-end database. Each ODBC driver has a
different limitation on the amount of data they can return in a single fetch. This limit may be much smaller than the value set
in nMaxLength, in which case the exception AFX_SQL_ERROR_DATA_TRUNCATED will be thrown. Under these
circumstances, switch to using RFX_LongBinary instead of RFX_Text or RFX_Binary so that all the data can be retrieved.

ClassWizard will bind a SQL_LONGVARCHAR to a CString , or a SQL_LONGVARBINARY to a CByteArray for


you. If you want to allocate more than 255 bytes into which you retrieve your long data column, you can then
supply an explicit value for nMaxLength.
When a long data column is bound to a CString or CByteArray , updating the field works just the same as when it
is bound to a SQL_VARCHAR or SQL_VARBINARY . During Edit , the data value is cached away and later
compared when Update is called to detect changes to the data value and set the Dirty and Null values for the
column appropriately.

Binding a Long Data Column to a CLongBinary


If your long data column may contain more MAXINT bytes of data, you should probably consider retrieving it into
a CLongBinary .
Advantages:
This retrieves an entire long data column, up to available memory.
Disadvantages:
The data is held in memory. This approach is also prohibitively expensive for very large amounts of data. You must
call SetFieldDirty for the bound data member to ensure the field is included in an Update operation.
If you retrieve long data columns into a CLongBinary , the database classes will check the total size of the long data
column, then allocate an HGLOBAL memory segment large enough to hold it the entire data value. The database
classes then retrieve the entire data value into the allocated HGLOBAL .
If the data source cannot return the expected size of the long data column, the framework will throw the exception
AFX_SQL_ERROR_SQL_NO_TOTAL . If the attempt to allocate the HGLOBAL fails, a standard memory exception is
thrown.
ClassWizard will bind an SQL_LONGVARCHAR or SQL_LONGVARBINARY to a CLongBinary for you. Select
CLongBinary as the Variable Type in the Add Member Variable dialog. ClassWizard will then add an
RFX_LongBinary call to your DoFieldExchange call and increment the total number of bound fields.

To update long data column values, first make sure the allocated HGLOBAL is large enough to hold your new data
by calling ::GlobalSize on the m_hData member of the CLongBinary . If it is too small, release the HGLOBAL and
allocate one the appropriate size. Then set m_dwDataLength to reflect the new size.
Otherwise, if m_dwDataLength is larger than the size of the data you're replacing, you can either free and
reallocate the HGLOBAL , or leave it allocated. Make sure to indicate the number of bytes actually used in
m_dwDataLength.

How Updating a CLongBinary Works


It is not necessary to understand how updating a CLongBinary works, but it may be useful as an example on how
to send long data values to a data source, if you choose this third method, described below.

NOTE
In order for a CLongBinary field to be included in an update, you must explicitly call SetFieldDirty for the field. If you
make any change to a field, including setting it Null, you must call SetFieldDirty . You must also call SetFieldNull , with
the second parameter being FALSE , to mark the field as having a value.

When updating a CLongBinary field, the database classes use ODBC's DATA_AT_EXEC mechanism (see ODBC
documentation on SQLSetPos 's rgbValue argument). When the framework prepares the insert or update
statement, instead of pointing to the HGLOBAL containing the data, the address of the CLongBinary is set as the
value of the column instead, and the length indicator set to SQL_DATA_AT_EXEC . Later, when the update
statement is sent to the data source, SQLExecDirect will return SQL_NEED_DATA . This alerts the framework that
the value of the param for this column is actually the address of a CLongBinary . The framework calls SQLGetData
once with a small buffer, expecting the driver to return the actual length of the data. If the driver returns the actual
length of the binary large object (the BLOB), MFC reallocates as much space as necessary to fetch the BLOB. If the
data source returns SQL_NO_TOTAL , indicating that it can't determine the size of the BLOB, MFC will create
smaller blocks. The default initial size is 64K, and subsequent blocks will be double the size; for example, the
second will be 128K, the third is 256K, and so on. The initial size is configurable.

Not Binding: Retrieving/Sending Data Directly from ODBC with


SQLGetData
With this method you completely bypass the database classes, and deal with the long data column yourself.
Advantages:
You can cache data to disk if necessary, or decide dynamically how much data to retrieve.
Disadvantages:
You don't get the framework's Edit or AddNew support, and you must write code yourself to perform basic
functionality ( Delete does work though, since it is not a column level operation).
In this case, the long data column must be in the select list of the recordset, but should not be bound to by the
framework. One way to do this is to supply your own SQL statement via GetDefaultSQL or as the lpszSQL
argument to CRecordset 's Open function, and not bind the extra column with an RFX_ function call. ODBC
requires that unbound fields appear to the right of bound fields, so add your unbound column or columns to the
end of the select list.
NOTE
Because your long data column is not bound by the framework, changes to it will not be handled with
CRecordset::Update calls. You must create and send the required SQL INSERT and UPDATE statements yourself.

See also
Technical Notes by Number
Technical Notes by Category
TN046: Commenting Conventions for the MFC
Classes
5/14/2019 • 2 minutes to read • Edit Online

This technical note originally described the conventions used to comment the MFC classes. This information is now
covered in MFC: Using the MFC Source Files.

See also
Technical Notes by Number
Technical Notes by Category
TN047: Relaxing Database Transaction Requirements
3/4/2019 • 2 minutes to read • Edit Online

This tech note, which discussed the transaction requirements of the MFC ODBC database classes, is now obsolete.
Before MFC 4.2, the database classes required that cursors be preserved on recordsets after a CommitTrans or
Rollback operation. If the ODBC driver and DBMS did not support this level of cursor preservation, then the
database classes did not enable transactions.
Beginning with MFC 4.2, the database classes have relaxed the restriction of requiring cursor preservation.
Transactions will be enabled if the driver supports them. However, you must now check the effect of a
CommitTrans or Rollback operation on open recordsets. See the member functions
CDatabase::GetCursorCommitBehavior and CDatabase::GetCursorRollbackBehavior for more information.

See also
Technical Notes by Number
Technical Notes by Category
TN048: Writing ODBC Setup and Administration
Programs for MFC Database Applications
3/27/2020 • 3 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

Applications using MFC database classes will need a setup program that installs ODBC components. They may also
need an ODBC Administration program that will retrieve information about the available drivers, to specify default
drivers and to configure data sources. This note describes the use of the ODBC Installer API to write these
programs.

Writing an ODBC Setup Program


An MFC database application requires the ODBC Driver Manager (ODBC.DLL) and ODBC drivers to be able to get
to data sources. Many ODBC drivers also require additional network and communication DLLs. Most ODBC drivers
ship with a setup program that will install the required ODBC components. Application developers using MFC
database classes can:
Rely on the driver-specific setup programs for installing ODBC components. This will require no further
work on the developer's part — you can just redistribute the driver's setup program.
Alternatively, you can write your own setup program, which will install the driver manager and the driver.
The ODBC installer API can be used to write application-specific setup programs. The functions in the installer API
are implemented by the ODBC installer DLL — ODBCINST.DLL on 16-bit Windows and ODBCCP32.DLL on Win32.
An application can call SQLInstallODBC in the installer DLL, which will install the ODBC driver manager, ODBC
drivers, and any required translators. It then records the installed drivers and translators in the ODBCINST.INI file
(or the registry, on NT). SQLInstallODBC requires the full path to the ODBC.INF file, which contains the list of
drivers to be installed and describes the files that comprise each driver. It also contains similar information about
the driver manager and translators. ODBC.INF files are typically supplied by driver developers.
A program can also install individual ODBC components. To install the Driver Manager, a program first calls
SQLInstallDriverManager in the installer DLL to get the target directory for the Driver Manager. This is usually the
directory in which Windows DLLs reside. The program then uses the information in the [ODBC Driver Manager]
section of the ODBC.INF file to copy the Driver Manager and related files from the installation disk to this directory.
To install an individual driver, a program first calls SQLInstallDriver in the installer DLL to add the driver
specification to the ODBCINST.INI file (or the registry, on NT). SQLInstallDriver returns the driver's target
directory — usually the directory in which Windows DLLs reside. The program then uses the information in the
driver's section of the ODBC.INF file to copy the driver DLL and related files from the installation disk to this
directory.
For more information on ODBC.INF, ODBCINST.INI and using the installer API, see ODBC SDK Programmer's
Reference, Chapter 19, Installing ODBC Software.

Writing an ODBC Administrator


An MFC database application can set up and configure ODBC data sources in one of two ways, as follows:
Use the ODBC Administrator (available as a program or as a Control Panel item).
Create your own program to configure data sources.
A program that configures data sources makes function calls to the installer DLL. The installer DLL calls a setup DLL
to configure a data source. There is one setup DLL for each driver; it may be the driver DLL itself, or a separate DLL.
The setup DLL prompts the user for information that the driver needs to connect to the data source and the default
translator, if supported. It then calls the installer DLL and Windows APIs to record this information in the ODBC.INI
file (or registry).
To display a dialog box with which a user can add, modify, and delete data sources, a program calls
SQLManageDataSources in the installer DLL. This function is invoked when the installer DLL is called from the Control
Panel. To add, modify, or delete a data source, SQLManageDataSources calls ConfigDSN in the setup DLL for the driver
associated with that data source. To directly add, modify, or delete data sources, a program calls
SQLConfigDataSource in the installer DLL. The program passes the name of the data source and an option that
specifies the action to take. SQLConfigDataSource calls ConfigDSN in the setup DLL and passes it the arguments
from SQLConfigDataSource .
For more information, see ODBC SDK Programmer's Reference, Chapter 23, Setup DLL Function Reference, and
Chapter 24, Installer DLL Function Reference.

See also
Technical Notes by Number
Technical Notes by Category
TN049: MFC/OLE MBCS to Unicode Translation
Layer (MFCANS32)
5/14/2019 • 2 minutes to read • Edit Online

This note originally described how MFCANS32.DLL provides ANSI interfaces in the primarily Unicode world of 32-
bit OLE. This DLL is no longer used by MFC.

See also
Technical Notes by Number
Technical Notes by Category
TN050: MFC/OLE Common Dialogs (MFCUIx32)
5/14/2019 • 2 minutes to read • Edit Online

This note originally covered some issues and the future of the OLE common dialogs provided and used by MFC.
The OLE common dialogs are now provided as a component built-in to the system (OLEDLG.DLL) and are fully
documented in the product documentation.

See also
Technical Notes by Number
Technical Notes by Category
TN051: Using CTL3D Now and in the Future
5/14/2019 • 2 minutes to read • Edit Online

This technical note, which previously discussed CTL3D and MFC, is now obsolete. The 3D effect for controls is
automatically implemented by MFC.

See also
Technical Notes by Number
Technical Notes by Category
TN053: Custom DFX Routines for DAO Database
Classes
3/27/2020 • 8 minutes to read • Edit Online

NOTE
DAO is used with Access databases and is supported through Office 2013. DAO 3.6 is the final version, and it is considered
obsolete. 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 OLE DB Templates or ODBC and MFC for new projects. You should
only use DAO in maintaining existing applications.

This technical note describes the DAO record field exchange (DFX) mechanism. To help understand what is
happening in the DFX routines, the DFX_Text function will be explained in detail as an example. As an additional
source of information to this technical note, you can examine the code for the other the individual DFX functions.
You probably will not need a custom DFX routine as often as you might need a custom RFX routine (used with
ODBC database classes).
This technical note contains:
DFX Overview
Examples using DAO Record Field Exchange and Dynamic Binding
How DFX Works
What Your Custom DFX Routine Does
Details of DFX_Text
DFX Over view
The DAO record field exchange mechanism (DFX) is used to simplify the procedure of retrieving and updating data
when using the CDaoRecordset class. The process is simplified using data members of the CDaoRecordset class. By
deriving from CDaoRecordset , you can add data members to the derived class representing each field in a table or
query. This "static binding" mechanism is simple, but it may not be the data fetch/update method of choice for all
applications. DFX retrieves every bound field each time the current record is changed. If you are developing a
performance-sensitive application that does not require fetching every field when currency is changed, "dynamic
binding" via CDaoRecordset::GetFieldValue and CDaoRecordset::SetFieldValue may be the data access method of
choice.

NOTE
DFX and dynamic binding are not mutually exclusive, so a hybrid use of static and dynamic binding can be used.

Example 1 — Use of DAO Record Field Exchange only


(assumes CDaoRecordset — derived class CMySet already open)
// Add a new record to the customers table
myset.AddNew();

myset.m_strCustID = _T("MSFT");

myset.m_strCustName = _T("Microsoft");

myset.Update();

Example 2 — Use of dynamic binding only


(assumes using CDaoRecordset class, rs , and it is already open)

// Add a new record to the customers table


COleVariant varFieldValue1 (_T("MSFT"),
VT_BSTRT);

//Note: VT_BSTRT flags string type as ANSI,


instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"),
VT_BSTRT);

rs.AddNew();

rs.SetFieldValue(_T("Customer_ID"),
varFieldValue1);

rs.SetFieldValue(_T("Customer_Name"),
varFieldValue2);

rs.Update();

Example 3 — Use of DAO Record Field Exchange and dynamic binding


(assumes browsing employee data with CDaoRecordset -derived class emp )

// Get the employee's data so that it can be displayed


emp.MoveNext();

// If user wants to see employee's photograph,


// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"),
varPhoto);

// Display the data


PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName,
varPhoto);

How DFX Works


The DFX mechanism works in a similar fashion to the record field exchange (RFX) mechanism used by the MFC
ODBC classes. The principles of DFX and RFX are the same but there are numerous internal differences. The design
of the DFX functions was such that virtually all the code is shared by the individual DFX routines. At the highest
level DFX only does a few things.
DFX constructs the SQL SELECT clause and SQL PARAMETERS clause if necessary.
DFX constructs the binding structure used by DAO's GetRows function (more on this later).
DFX manages the data buffer used to detect dirty fields (if double-buffering is being used)
DFX manages the NULL and DIRTY status arrays and sets values if necessary on updates.
At the heart of the DFX mechanism is the CDaoRecordset derived class's DoFieldExchange function. This function
dispatches calls to the individual DFX functions of an appropriate operation type. Before calling DoFieldExchange
the internal MFC functions set the operation type. The following list shows the various operation types and a brief
description.

O P ERAT IO N DESC RIP T IO N

AddToParameterList Builds PARAMETERS clause

AddToSelectList Builds SELECT clause

BindField Sets up binding structure

BindParam Sets parameter values

Fixup Sets NULL status

AllocCache Allocates cache for dirty check

StoreField Saves current record to cache

LoadField Restores cache to member values

FreeCache Frees cache

SetFieldNull Sets field status & value to NULL

MarkForAddNew Marks fields dirty if not PSEUDO NULL

MarkForEdit Marks fields dirty if don't match cache

SetDirtyField Sets field values marked as dirty

In the next section, each operation will be explained in more detail for DFX_Text .
The most important feature to understand about the DAO record field exchange process is that it uses the
GetRows function of the CDaoRecordset object. The DAO GetRows function can work in several ways. This technical
note will only briefly describe GetRows as it is outside of the scope of this technical note. DAO GetRows can work
in several ways.
It can fetch multiple records and multiple fields of data at one time. This allows for faster data access with
the complication of dealing with a large data structure and the appropriate offsets to each field and for each
record of data in the structure. MFC does not take advantage of this multiple record fetching mechanism.
Another way GetRows can work is to allow programmers to specify binding addresses for the retrieved
data of each field for one record of data.
DAO will also "call back" into the caller for variable length columns in order to allow the caller to allocate
memory. This second feature has the benefit of minimizing the number of copies of data as well as allowing
direct storage of data into members of a class (the CDaoRecordset derived class). This second mechanism is
the method MFC uses to bind to data members in CDaoRecordset derived classes.

What Your Custom DFX Routine Does


It is apparent from this discussion that the most important operation implemented in any DFX function must be
the ability to set up the required data structures to successfully call GetRows . There are a number of other
operations that a DFX function must support as well, but none as important or complex as correctly preparing for
the GetRows call.
The use of DFX is described in the online documentation. Essentially, there are two requirements. First, members
must be added to the CDaoRecordset derived class for each bound field and parameter. Following this
CDaoRecordset::DoFieldExchange should be overridden. Note that the data type of the member is important. It
should match the data from the field in the database or at least be convertible to that type. For example a numeric
field in database, such as a long integer, can always be converted to text and bound to a CString member, but a
text field in a database may not necessarily be converted to a numeric representation, such as long integer and
bound to a long integer member. DAO and the Microsoft Jet database engine are responsible for the conversion
(rather than MFC).

Details of DFX_Text
As mentioned previously, the best way to explain how DFX works is to work through an example. For this purpose
going through the internals of DFX_Text should work quite well to help provide at least a basic understanding of
DFX.
AddToParameterList

This operation builds the SQL PARAMETERS clause (" Parameters <param name>, <param type> ... ; ")
required by Jet. Each parameter is named and typed (as specified in the RFX call). See the function
CDaoFieldExchange::AppendParamType function to see the names of the individual types. In the case of
DFX_Text , the type used is text .

AddToSelectList

Builds the SQL SELECT clause. This is pretty straight forward as the column name specified by the DFX call
is simply appended (" SELECT <column name>, ... ").
BindField

The most complex of the operations. As mentioned previously this is where the DAO binding structure used
by GetRows is set up. As you can see from the code in DFX_Text the types of information in the structure
include the DAO type used (DAO_CHAR or DAO_WCHAR in the case of DFX_Text ). Additionally, the type
of binding used is also set up. In an earlier section GetRows was described only briefly, but it was sufficient
to explain that the type of binding used by MFC is always direct address binding (DAOBINDING_DIRECT ).
In addition for variable-length column binding (like DFX_Text ) callback binding is used so that MFC can
control the memory allocation and specify an address of the correct length. What this means is that MFC
can always tell DAO "where" to put the data, thus allowing binding directly to member variables. The rest of
the binding structure is filled in with things like the address of the memory allocation callback function and
the type of column binding (binding by column name).
BindParam

This is a simple operation that calls SetParamValue with the parameter value specified in your parameter
member.
Fixup

Fills in the NULL status for each field.


SetFieldNull

This operation only marks each field status as NULL and sets the member variable's value to
PSEUDO_NULL .
SetDirtyField

Calls SetFieldValue for each field marked dirty.

All the remaining operations only deal with using the data cache. The data cache is an extra buffer of the data in
the current record that is used to make certain things simpler. For instance, "dirty" fields can be automatically
detected. As described in the online documentation it can be turned off completely or at the field level. The
implementation of the buffer utilizes a map. This map is used to match up dynamically allocated copies of the data
with the address of the "bound" field (or CDaoRecordset derived data member).
AllocCache

Dynamically allocates the cached field value and adds it to the map.
FreeCache

Deletes the cached field value and removes it from the map.
StoreField

Copies the current field value into the data cache.


LoadField

Copies the cached value into the field member.


MarkForAddNew

Checks if current field value is non-NULL and marks it dirty if necessary.


MarkForEdit

Compares current field value with data cache and marks dirty if necessary.

TIP
Model your custom DFX routines on the existing DFX routines for standard data types.

See also
Technical Notes by Number
Technical Notes by Category
TN054: Calling DAO Directly While Using MFC DAO
Classes
11/21/2019 • 8 minutes to read • Edit Online

NOTE
DAO is used with Access databases and is supported through Office 2013. DAO 3.6 is the final version, and it is considered
obsolete. 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 OLE DB Templates or ODBC and MFC for new projects. You should
only use DAO in maintaining existing applications.

When using the MFC DAO database classes, there may be situations where it is necessary to use DAO directly.
Usually, this will not be the case, but MFC has provided some helper mechanisms to facilitate making direct DAO
calls simple when combining the use of the MFC classes with direct DAO calls. Making direct DAO calls to the
methods of an MFC-managed DAO object should require only a few lines of code. If you need to create and use
DAO objects that are not managed by MFC, you will have to do a little more work by actually calling Release on
the object. This technical note explains when you might want to call DAO directly, what the MFC helpers can do to
help you, and how to use the DAO OLE interfaces. Finally, this note provides some sample functions showing how
to call DAO directly for DAO security features.

When to Make Direct DAO Calls


The most common situations for making direct DAO calls occur when collections need to be refreshed or when
you are implementing features not wrapped by MFC. The most significant feature not exposed by MFC is security.
If you want to implement security features, you will need to use the DAO User(s) and Group(s) objects directly.
Besides security, there are only a few other DAO features not supported by MFC. These include recordset cloning
and database replication features as well as a few late additions to DAO.

A Brief Overview of DAO and MFC's Implementation


MFC's wrapping of DAO makes using DAO easier by handling many of the details so you do not have to worry
about the little things. This includes the initialization of OLE, the creation and management of the DAO objects
(especially the collection objects), error checking, and providing a strongly typed, simpler interface (no VARIANT
or BSTR arguments). You can make direct DAO calls and still take advantage of these features. All your code must
do is call Release for any objects created by direct DAO calls and not modify any of the interface pointers that
MFC may rely on internally. For example, do not modify the m_pDAORecordset member of an open
CDaoRecordset object unless you understand all the internal ramifications. You could, however, use the
m_pDAORecordset interface to call DAO directly to get the Fields collection. In this case the m_pDAORecordset
member would not be modified. You simply have to call Release on the Fields collection object when you are
finished with the object.

Description of Helpers to Make DAO Calls Easier


The helpers provided to make calling DAO easier are the same helpers that are used internally in the MFC DAO
Database classes. These helpers are used to check the return codes when making a direct DAO call, logging debug
output, checking for expected errors, and throwing appropriate exceptions if necessary. There are two underlying
helper functions and four macros that map to one of these two helpers. The best explanation would be to simply
read the code. See DAO_CHECK , DAO_CHECK_ERROR , DAO_CHECK_MEM , and DAO_TRACE in AFXDAO.H
to see the macros, and see AfxDaoCheck and AfxDaoTrace in DAOCORE.CPP.

Using the DAO OLE Interfaces


The OLE interfaces for each object in the DAO object hierarchy are defined in the header file DBDAOINT.H, which is
found in the \Program Files\Microsoft Visual Studio .NET 2003\VC7\include directory. These interfaces provide
methods that allow you to manipulate the entire DAO hierarchy.
For many of the methods in the DAO interfaces, you will need to manipulate a BSTR object (a length-prefixed
string used in OLE automation). The BSTR object typically is encapsulated within the VARIANT data type. The
MFC class COleVariant itself inherits from the VARIANT data type. Depending on whether you build your project
for ANSI or Unicode, the DAO interfaces will return ANSI or Unicode BSTR s. Two macros, V_BSTR and V_BSTRT,
are useful for assuring that the DAO interface gets the BSTR of the expected type.
V_BSTR will extract the bstrVal member of a COleVariant . This macro is typically used when you need to pass the
contents of a COleVariant to a method of a DAO interface. The following code fragment shows both the
declarations and actual use for two methods of the DAO DAOUser interface that take advantage of the V_BSTR
macro:

COleVariant varOldName;
COleVariant varNewName(_T("NewUser"), VT_BSTRT);

// Code to assign pUser to a valid value omitted DAOUser *pUser = NULL;

// These method declarations were taken from DBDAOINT.H


// STDMETHOD(get_Name) (THIS_ BSTR FAR* pbstr) PURE;
// STDMETHOD(put_Name) (THIS_ BSTR bstr) PURE;
DAO_CHECK(pUser->get_Name(&V_BSTR (&varOldName)));
DAO_CHECK(pUser->put_Name(V_BSTR (&varNewName)));

Note that the VT_BSTRT argument specified in the COleVariant constructor above ensures that there will be an
ANSI BSTR in the COleVariant if you build an ANSI version of your application and a Unicode BSTR for a
Unicode version of your application. This is what DAO expects.
The other macro, V_BSTRT, will extract either an ANSI or Unicode bstrVal member of COleVariant depending on
the type of build (ANSI or Unicode). The following code demonstrates how to extract the BSTR value from a
COleVariant into a CString :

COleVariant varName(_T("MyName"), VT_BSTRT);


CString str = V_BSTRT(&varName);

The V_BSTRT macro, along with other techniques to open other types that are stored in COleVariant , is
demonstrated in the DAOVIEW sample. Specifically, this translation is performed in the CCrack::strVARIANT
method. This method, where possible, translates the value of a COleVariant into an instance of CString .

Simple Example of a Direct Call to DAO


Situations may arise when it is necessary to refresh the underlying DAO collection objects. Normally, this should
not be necessary, but it is a simple procedure if it is necessary. An example of when a collection might need to be
refreshed is when operating in a multiuser environment with multiple users creating new tabledefs. In this case
your tabledefs collection might become stale. To refresh the collection, you simply need to call the Refresh
method of the particular collection object and check for errors:

DAO_CHECK(pMyDaoDatabase->m_pDAOTableDefs->Refresh());
Note that currently all DAO collection object interfaces are undocumented implementation details of the MFC
DAO database classes.

Using DAO Directly for DAO Security Features


The MFC DAO database classes do not wrap DAO security features. You must call methods of DAO interfaces to
use some DAO security features. The following function sets the system database and then changes the user's
password. This function calls three other functions, which are subsequently defined.

void ChangeUserPassword()
{
// Specify path to the Microsoft Access *// system database
CString strSystemDB =
_T("c:\\Program Files\\MSOffice\\access\\System.mdw");

// Set system database before MFC initilizes DAO


// NOTE: An MFC module uses only one instance
// of a DAO database engine object. If you have
// called a DAO object in your application prior
// to calling the function below, you must call
// AfxDaoTerm to destroy the existing database
// engine object. Otherwise, the database engine
// object already in use will be reused, and setting
// a system datbase will have no effect.
//
// If you have used a DAO object prior to calling
// this function it is important that DAO be
// terminated with AfxDaoTerm since an MFC
// module only gets one copy of the database engine
// and that engine will be reused if it hasn't been
// terminated. In other words, if you do not call
// AfxDaoTerm and there is currently a database
// initialized, setting the system database will
// have no effect.
SetSystemDB(strSystemDB);

// User name and password manually added


// by using Microsoft Access
CString strUserName = _T("NewUser");
CString strOldPassword = _T("Password");
CString strNewPassword = _T("NewPassword");

// Set default user so that MFC will be able


// to log in by default using the user name and
// password from the system database
SetDefaultUser(strUserName, strOldPassword);

// Change the password. You should be able to


// call this function from anywhere in your
// MFC application
ChangePassword(strUserName, strOldPassword, strNewPassword);

// ...
}

The next four examples demonstrate how to:


Set the system DAO database (.MDW file).
Set the default user and password.
Change the password of a user.
Change the password of an .MDB file.
Setting the System Database
Below is a sample function to set the system database that will be used by an application. This function must be
called before any other DAO calls are made.

// Set the system database that the


// DAO database engine will use

void SetSystemDB(CString& strSystemMDB)


{
COleVariant varSystemDB(strSystemMDB, VT_BSTRT);

// Initialize DAO for MFC


AfxDaoInit();
DAODBEngine* pDBEngine = AfxDaoGetEngine();

ASSERT(pDBEngine != NULL);

// Call put_SystemDB method to set the *// system database for DAO engine
DAO_CHECK(pDBEngine->put_SystemDB(varSystemDB.bstrVal));
}

Setting the Default User and Password


To set the default user and password for a system database, use the following function:

void SetDefaultUser(CString& strUserName,


CString& strPassword)
{
COleVariant varUserName(strUserName, VT_BSTRT);
COleVariant varPassword(strPassword, VT_BSTRT);

DAODBEngine* pDBEngine = AfxDaoGetEngine();


ASSERT(pDBEngine != NULL);

// Set default user:


DAO_CHECK(pDBEngine->put_DefaultUser(varUserName.bstrVal));

// Set default password:


DAO_CHECK(pDBEngine->put_DefaultPassword(varPassword.bstrVal));
}

Changing a User's Password


To change a user's password, use the following function:
void ChangePassword(CString &strUserName,
CString &strOldPassword,
CString &strNewPassword)
{
// Create (open) a workspace
CDaoWorkspace wsp;
CString strWspName = _T("Temp Workspace");

wsp.Create(strWspName, strUserName, strOldPassword);


wsp.Append();

// Determine how many objects there are *// in the Users collection
short nUserCount;
short nCurrentUser;
DAOUser *pUser = NULL;
DAOUsers *pUsers = NULL;

// Side-effect is implicit OLE AddRef()


// on DAOUser object:
DAO_CHECK(wsp.m_pDAOWorkspace->get_Users(&pUsers));

// Side-effect is implicit OLE AddRef()


// on DAOUsers object
DAO_CHECK(pUsers->getcount(&nUserCount));

// Traverse through the list of users


// and change password for the userid
// used to create/open the workspace
for(nCurrentUser = 0; nCurrentUser <nUserCount; nCurrentUser++)
{
COleVariant varIndex(nCurrentUser, VT_I2);
COleVariant varName;

// Retrieve information for user nCurrentUser


DAO_CHECK(pUsers->get_Item(varIndex, &pUser));

// Retrieve name for user nCurrentUser


DAO_CHECK(pUser->get_Name(&V_BSTR(&varName)));

CString strTemp = V_BSTRT(&varName);

// If there is a match, change the password


if (strTemp == strUserName)
{
COleVariant varOldPwd(strOldPassword, VT_BSTRT);
COleVariant varNewPwd(strNewPassword, VT_BSTRT);

DAO_CHECK(pUser->NewPassword(V_BSTR(&varOldPwd),
V_BSTR(&varNewPwd)));

TRACE("\t Password is changed\n");


}
}
// Clean up: decrement the usage count
// on the OLE objects
pUser->Release();
pUsers->Release();
wsp.Close();
}

Changing the Password of an .MDB File


To change the password of an .MDB file, use the following function:
void SetDBPassword(LPCTSTR pDB,
LPCTSTR pszOldPassword,
LPCTSTR pszNewPassword)
{
CDaoDatabase db;
CString strConnect(_T(";pwd="));

// the database must be opened as exclusive


// to set a password
db.Open(pDB, TRUE, FALSE, strConnect + pszOldPassword);

COleVariant NewPassword(pszNewPassword, VT_BSTRT),


OldPassword(pszOldPassword, VT_BSTRT);

DAO_CHECK(db.m_pDAODatabase->NewPassword(V_BSTR(&OldPassword),
V_BSTR(&NewPassword)));

db.Close();
}

See also
Technical Notes by Number
Technical Notes by Category
TN055: Migrating MFC ODBC Database Class
Applications to MFC DAO Classes
11/21/2019 • 5 minutes to read • Edit Online

NOTE
DAO is used with Access databases and is supported through Office 2013. DAO 3.6 is the final version, and it is considered
obsolete. 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 OLE DB Templates or ODBC and MFC for new projects. You should
only use DAO in maintaining existing applications.

Overview
In many situations it may be desirable to migrate applications that use MFC's ODBC database classes to MFC's
DAO database classes. This technical note will detail most of the differences between the MFC ODBC and DAO
classes. With the differences in mind, it should not be overly difficult to migrate applications from the ODBC
classes to the MFC classes if desired.

Why Migrate from ODBC to DAO


There are a number of reasons why you might want to migrate applications from the ODBC Database Classes to
the DAO Database Classes, but the decision is not necessarily simple or obvious. One thing to keep in mind is that
the Microsoft Jet database engine that is used by DAO can read any ODBC data source for which you have an
ODBC driver. It may be more efficient to use the ODBC Database Classes or call ODBC directly yourself, but the
Microsoft Jet database engine can read ODBC data.
Some simple cases that make the ODBC/DAO decision easy. For instance, when you only need access to data in a
format that the Microsoft Jet engine can read directly (Access format, Excel format, and so on) the obvious choice is
to use the DAO Database Classes.
More complex cases arise when your data exists on a server or on a variety of different servers. In this case, the
decision to use the ODBC Database classes or the DAO Database classes is a difficult one. If you want to do things
like heterogeneous joins ( join data from servers in multiple formats like SQL Server and Oracle), then the
Microsoft Jet database engine will perform the join for you rather than forcing you to do the work necessary if you
used the ODBC Database Classes or called ODBC directly. If you are using an ODBC driver that supports driver
cursors, your best choice might be the ODBC Database classes.
The choice can be complicated, so you might want to write some sample code to test the performance of various
methods given your special needs. This technical note assumes that you have made the decision to migrate from
the ODBC Database Classes to the DAO Database classes.

Similarities Between ODBC Database Classes and MFC DAO Database


Classes
The original design of the MFC ODBC classes was based on the DAO object model that has been in use in
Microsoft Access and Microsoft Visual Basic. This means that there are many common features of the ODBC and
DAO MFC classes, which will not all be listed in this section. In general, the programming models are the same.
To highlight a few similarities:
Both the ODBC and DAO classes have database objects that manage using the underlying database
management system (DBMS).
Both have recordset objects representing a set of results returned from that DBMS.
The DAO database and recordset objects have members nearly identical to the ODBC classes.
With both sets of classes, the code to retrieve data is identical except for some object and member name
changes. Changes will be required, but usually the process is a straightforward name change when
switching from the ODBC classes to DAO classes.
For example, in both models the procedure to retrieve data is to create and open a database object, create and
open a recordset object, and navigate (move) though the data performing some operation.

Differences Between ODBC and DAO MFC Classes


The DAO classes include more objects and a richer set of methods, but this section will only detail the differences
in similar classes and functionality.
Probably the most obvious differences between the classes are the name changes for similar classes and global
functions. The following list shows the name changes of the objects, methods and global functions associated with
the database classes:

C L A SS O R F UN C T IO N EQ UIVA L EN T IN M F C DA O C L A SSES

CDatabase CDaoDatabase

CDatabase::ExecuteSQL CDaoDatabase::Execute

CRecordset CDaoRecordset

CRecordset::GetDefaultConnect CDaoRecordset::GetDefaultDBName

CFieldExchange CDaoFieldExchange

RFX_Bool DFX_Bool

RFX_Byte DFX_Byte

RFX_Int DFX_Short

RFX_Long DFX_Long

DFX_Currency

RFX_Single DFX_Single

RFX_Double DFX_Double

RFX_Date 1 DFX_Date ( COleDateTime -based)

RFX_Text DFX_Text
C L A SS O R F UN C T IO N EQ UIVA L EN T IN M F C DA O C L A SSES

RFX_Binary DFX_Binary

RFX_LongBinary DFX_LongBinary

1 The RFX_Date function is based on CTime and TIMESTAMP_STRUCT .


The major changes to functionality which may affect your application and require more than simple name changes
are listed below.
The constants and macros used to specify things like recordset open type and recordset open options have
been changed.
With the ODBC classes MFC needed to define these options via macros or enumerated types.
With the DAO classes, DAO provides the definition of these options in a header file (DBDAOINT.H). Thus the
recordset type is an enumerated member of CRecordset , but with DAO it is a constant instead. For example
you would use snapshot when specifying the type of CRecordset in ODBC but DB_OPEN_SNAPSHOT
when specifying the type of CDaoRecordset .
The default recordset type for CRecordset is snapshot while the default recordset type for CDaoRecordset
is dynaset (see the Note below for an additional issue about ODBC class snapshots).
The ODBC CRecordset class has an option to create a forward-only recordset type. In the CDaoRecordset
class, forward-only is not a recordset type, but rather a property (or option) of certain types of recordsets.
An append-only recordset when opening a CRecordset object meant that the recordset's data could be read
and appended. With CDaoRecordset object, the append-only option means literally that the recordset's data
can only be appended (and not read).
The ODBC classes' transaction member functions are members of CDatabase and act at the database level.
In the DAO classes, the transaction member functions are members of a higher level class ( CDaoWorkspace )
and thus may impact multiple CDaoDatabase objects sharing the same workspace (transaction space).
The exception class has been changed. CDBExceptions are thrown in the ODBC classes and CDaoExceptions
in the DAO classes.
RFX_Date uses CTime and TIMESTAMP_STRUCT objects while DFX_Date uses COleDateTime . The COleDateTime
is nearly identical to CTime , but is based on a 8-byte OLE DATE rather than a 4-byte time_t so it can hold a
much bigger range of data.

NOTE
DAO ( CDaoRecordset ) snapshots are read-only while ODBC ( CRecordset ) snapshots may be updateable
depending on the driver and use of the ODBC cursor library. If you are using the cursor library, CRecordset
snapshots are updateable. If you are using any of the Microsoft drivers from Desktop Driver Pack 3.0 without the
ODBC cursor library, the CRecordset snapshots are read-only. If you are using another driver, check the driver's
documentation to see if snapshots ( STATIC_CURSORS ) are read-only.

See also
Technical Notes by Number
Technical Notes by Category
TN056: Installation of Localized MFC Components
5/14/2019 • 2 minutes to read • Edit Online

This tech note, which discussed the installation of localized MFC components, is now obsolete.
See TechNote 57 for more information on localizing MFC applications.

See also
Technical Notes by Number
Technical Notes by Category
TN057: Localization of MFC Components
5/14/2019 • 5 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes some of the designs and procedures you can use to localize your component, if it an
application or an OLE control or a DLL that uses MFC.

Overview
There are really two issues to resolve when localizing a component that uses MFC. First, you must localize your
own resources — strings, dialogs, and other resources that are specific to your component. Most components built
using MFC also include and use a number of resources that are defined by MFC. You must provide localized MFC
resources as well. Fortunately, several languages are already provided by MFC itself.
In addition, your component should be prepared to run in its target environment (European or DBCS-enabled
environment). For the most part, this depends on your application treating characters with the high bit set
correctly and handling strings with double byte characters. MFC is enabled, by default, for both of these
environments, such that it is possible to have a single worldwide binary that is used on all platforms with just
different resources plugged in at setup time.

Localizing your Component's Resources


Localizing your application or DLL should involve simply replacing the resources with resources that match the
target language. For your own resources, this is relatively simple: edit the resources in the resource editor and
build your application. If your code is written properly there will be no strings or text that you wish to localize
hard-coded into your C++ source code - all localization can be done by simply modifying resources. In fact, you
can implement your component such that all providing a localized version does not even involve a build of the
original code. This is more complex, but is well worth it and is the mechanism chosen for MFC itself. It is also
possible to localize an application by loading the EXE or DLL file into the resource editor and editing the resources
directly. While possible, it requires reapplication of those changes each time you build a new version of your
application.
One way to avoid that is to locate all resources in a separate DLL, sometimes called a satellite DLL. This DLL is then
loaded dynamically at runtime and the resources are loaded from that DLL instead of from the main module with
all your code. MFC directly supports this approach. Consider an application called MYAPP.EXE; it could have all of
its resources located in a DLL called MYRES.DLL. In the application's InitInstance it would perform the following
to load that DLL and cause MFC to load resources from that location:
CMyApp::InitInstance()
{
// one of the first things in the init code
HINSTANCE hInst = LoadLibrary("myres.dll");

if (hInst != NULL)
AfxSetResourceHandle(hInst);

// other initialization code would follow


// ...
}

From then on, MFC will load resources from that DLL instead of from myapp.exe. All resources, however, must be
present in that DLL; MFC will not search the application's instance in search of a given resource. This technique
applies equally well to regular MFC DLLs as well as OLE Controls. Your setup program would copy the appropriate
version of MYRES.DLL depending upon which resource locale the user would like.
It is relatively easy to create a resource only DLL. You create a DLL project, add your .RC file to it, and add the
necessary resources. If you have an existing project that does not use this technique, you can copy the resources
from that project. After adding the resource file to the project, you are almost ready to build the project. The only
thing you must do is set the linker options to include /NOENTRY . This tells the linker that the DLL has no entry
point - since it has no code, it has no entry point.

NOTE
The resource editor in Visual C++ 4.0 and later supports multiple languages per .RC file. This can make it very easy to
manage your localization in a single project. The resources for each language are controlled by preprocessor directives
generated by the resource editor.

Using the Provided MFC Localized Resources


Any MFC application that you build reuses two things from MFC: code and resources. That is, MFC has various
error messages, built-in dialogs, and other resources that are used by the MFC classes. In order to completely
localize your application, you need to localize not only your application's resources, but also the resources that
come directly from MFC. MFC provides a number of different language resource files automatically, so that if the
language you are targeting is one of the languages MFC already supports, you just need to make sure you use
those localized resources.
As of this writing, MFC supports Chinese, German, Spanish, French, Italian, Japanese, and Korean. The files which
contain these localized versions are in the MFC\INCLUDE\L.* (the 'L' stands for localized) directories. The German
files are in MFC\INCLUDE\L.DEU, for example. To cause your application to use these RC files instead of the files
located in MFC\INCLUDE, add a /IC:\PROGRAM FILES\MICROSOFT VISUAL STUDIO .NET 2003\VC7\MFC\INCLUDE\L.DEU to
your RC command line (this is just an example; you would need to substitute your locale of choice as well as the
directory into which you installed Visual C++).
The above instructions will work if your application links statically with MFC. Most applications link dynamically
(because that is the AppWizard default). In this scenario, not only the code is dynamically linked - so are the
resources. As a result, you can localize your resources in your application, but the MFC implementation resources
will still be loaded from the MFC7x.DLL (or a later version) or from MFC7xLOC.DLL if it exists. You can approach
this from two different angles.
The more complex approach is to ship one of the localized MFC7xLOC.DLLs (such as MFC7xDEU, for German,
MFC7xESP.DLL for Spanish, etc.), or a later version, and install the appropriate MFC7xLOC.DLL into the system
directory when the user installs your application. This can be very complex for both the developer and the end
user and as such is not recommended. See Technical Note 56 for more information on this technique and its
caveats.
The simplest and safest approach is to include the localized MFC resources in your application or DLL itself (or its
satellite DLL if you are using one). This avoids the problems of installing MFC7xLOC.DLL properly. To do so, you
follow the same instructions for the static case given above (setting the RC command line properly to point to the
localized resources), except that you must also remove the /D_AFXDLL define that was added by AppWizard. When
/D_AFXDLL is defined, AFXRES.H (and the other MFC RC files) do not actually define any resources (because they
will be pulled from the MFC DLLs instead).

See also
Technical Notes by Number
Technical Notes by Category
TN058: MFC Module State Implementation
3/31/2020 • 11 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This technical note describes the implementation of MFC "module state" constructs. An understanding of the
module state implementation is critical for using the MFC shared DLLs from a DLL (or OLE in-process server).
Before reading this note, refer to "Managing the State Data of MFC Modules" in Creating New Documents,
Windows, and Views. This article contains important usage information and overview information on this subject.

Overview
There are three kinds of MFC state information: Module State, Process State, and Thread State. Sometimes these
state types can be combined. For example, MFC's handle maps are both module local and thread local. This allows
two different modules to have different maps in each of their threads.
Process State and Thread State are similar. These data items are things that have traditionally been global variables,
but have need to be specific to a given process or thread for proper Win32s support or for proper multithreading
support. Which category a given data item fits in depends on that item and its desired semantics with regard to
process and thread boundaries.
Module State is unique in that it can contain either truly global state or state that is process local or thread local. In
addition, it can be switched quickly.

Module State Switching


Each thread contains a pointer to the "current" or "active" module state (not surprisingly, the pointer is part of
MFC's thread local state). This pointer is changed when the thread of execution passes a module boundary, such as
an application calling into an OLE Control or DLL, or an OLE Control calling back into an application.
The current module state is switched by calling AfxSetModuleState . For the most part, you will never deal directly
with the API. MFC, in many cases, will call it for you (at WinMain, OLE entry-points, AfxWndProc , etc.). This is done
in any component you write by statically linking in a special WndProc , and a special WinMain (or DllMain ) that
knows which module state should be current. You can see this code by looking at DLLMODUL.CPP or
APPMODUL.CPP in the MFC\SRC directory.
It is rare that you want to set the module state and then not set it back. Most of the time you want to "push" your
own module state as the current one and then, after you are done, "pop" the original context back. This is done by
the macro AFX_MANAGE_STATE and the special class AFX_MAINTAIN_STATE .
CCmdTarget has special features for supporting module state switching. In particular, a CCmdTarget is the root class
used for OLE automation and OLE COM entry points. Like any other entry point exposed to the system, these
entry points must set the correct module state. How does a given CCmdTarget know what the "correct" module
state should be The answer is that it "remembers" what the "current" module state is when it is constructed, such
that it can set the current module state to that "remembered" value when it is later called. As a result, the module
state that a given CCmdTarget object is associated with is the module state that was current when the object was
constructed. Take a simple example of loading an INPROC server, creating an object, and calling its methods.
1. The DLL is loaded by OLE using LoadLibrary .
2. RawDllMain is called first. It sets the module state to the known static module state for the DLL. For this
reason RawDllMain is statically linked to the DLL.
3. The constructor for the class factory associated with our object is called. COleObjectFactory is derived from
CCmdTarget and as a result, it remembers in which module state it was instantiated. This is important —
when the class factory is asked to create objects, it knows now what module state to make current.
4. DllGetClassObject is called to obtain the class factory. MFC searches the class factory list associated with
this module and returns it.
5. COleObjectFactory::XClassFactory2::CreateInstance is called. Before creating the object and returning it, this
function sets the module state to the module state that was current in step 3 (the one that was current when
the COleObjectFactory was instantiated). This is done inside of METHOD_PROLOGUE.
6. When the object is created, it too is a CCmdTarget derivative and in the same way COleObjectFactory
remembered which module state was active, so does this new object. Now the object knows which module
state to switch to whenever it is called.
7. The client calls a function on the OLE COM object it received from its CoCreateInstance call. When the
object is called it uses METHOD_PROLOGUE to switch the module state just like COleObjectFactory does.
As you can see, the module state is propagated from object to object as they are created. It is important to have
the module state set appropriately. If it is not set, your DLL or COM object may interact poorly with an MFC
application that is calling it, or may be unable to find its own resources, or may fail in other miserable ways.
Note that certain kinds of DLLs, specifically "MFC Extension" DLLs do not switch the module state in their
RawDllMain (actually, they usually don't even have a RawDllMain ). This is because they are intended to behave "as
if" they were actually present in the application that uses them. They are very much a part of the application that is
running and it is their intention to modify that application's global state.
OLE Controls and other DLLs are very different. They do not want to modify the calling application's state; the
application that is calling them may not even be an MFC application and so there may be no state to modify. This is
the reason that module state switching was invented.
For exported functions from a DLL, 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_MODULE_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_MODULE_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_MODULE_STATE does not need to be put in every function in the DLL. For example, InitInstance can be
called by the MFC code in the application without AFX_MODULE_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.
Process Local Data
Process local data would not be of such great concern had it not been for the difficulty of the Win32s DLL model.
In Win32s all DLLs share their global data, even when loaded by multiple applications. This is very different from
the "real" Win32 DLL data model, where each DLL gets a separate copy of its data space in each process that
attaches to the DLL. To add to the complexity, data allocated on the heap in a Win32s DLL is in fact process specific
(at least as far as ownership goes). Consider the following data and code:

static CString strGlobal; // at file scope

__declspec(dllexport)
void SetGlobalString(LPCTSTR lpsz)
{
strGlobal = lpsz;
}

__declspec(dllexport)
void GetGlobalString(LPCTSTR lpsz, size_t cb)
{
StringCbCopy(lpsz, cb, strGlobal);
}

Consider what happens if the above code is in located in a DLL and that DLL is loaded by two processes A and B (it
could, in fact, be two instances of the same application). A calls SetGlobalString("Hello from A") . As a result,
memory is allocated for the CString data in the context of process A. Keep in mind that the CString itself is
global and is visible to both A and B. Now B calls GetGlobalString(sz, sizeof(sz)) . B will be able to see the data
that A set. This is because Win32s offers no protection between processes like Win32 does. That is the first
problem; in many cases it is not desirable to have one application affect global data that is considered to be owned
by a different application.
There are additional problems as well. Let's say that A now exits. When A exits, the memory used by the '
strGlobal ' string is made available for the system — that is, all memory allocated by process A is freed
automatically by the operating system. It is not freed because the CString destructor is being called; it hasn't been
called yet. It is freed simply because the application which allocated it has left the scene. Now if B called
GetGlobalString(sz, sizeof(sz)) , it may not get valid data. Some other application may have used that memory
for something else.
Clearly a problem exists. MFC 3.x used a technique called thread-local storage (TLS). MFC 3.x would allocate a TLS
index that under Win32s really acts as a process-local storage index, even though it is not called that and then
would reference all data based on that TLS index. This is similar to the TLS index that was used to store thread-
local data on Win32 (see below for more information on that subject). This caused every MFC DLL to utilize at least
two TLS indices per process. When you account for loading many OLE Control DLLs (OCXs), you quickly run out of
TLS indices (there are only 64 available). In addition, MFC had to place all this data in one place, in a single
structure. It was not very extensible and was not ideal with regard to its use of TLS indices.
MFC 4.x addresses this with a set of class templates you can "wrap" around the data that should be process local.
For example, the problem mentioned above could be fixed by writing:
struct CMyGlobalData : public CNoTrackObject
{
CString strGlobal;
};
CProcessLocal<CMyGlobalData> globalData;

__declspec(dllexport)
void SetGlobalString(LPCTSTR lpsz)
{
globalData->strGlobal = lpsz;
}

__declspec(dllexport)
void GetGlobalString(LPCTSTR lpsz, size_t cb)
{
StringCbCopy(lpsz, cb, globalData->strGlobal);
}

MFC implements this in two steps. First, there is a layer on top of the Win32 Tls* APIs (TlsAlloc , TlsSetValue ,
TlsGetValue , etc.) which use only two TLS indexes per process, no matter how many DLLs you have. Second, the
CProcessLocal template is provided to access this data. It overrides operator-> which is what allows the intuitive
syntax you see above. All objects that are wrapped by CProcessLocal must be derived from CNoTrackObject .
CNoTrackObject provides a lower-level allocator (LocalAlloc /LocalFree ) and a virtual destructor such that MFC
can automatically destroy the process local objects when the process is terminated. Such objects can have a
custom destructor if additional cleanup is required. The above example doesn't require one, since the compiler will
generate a default destructor to destroy the embedded CString object.
There are other interesting advantages to this approach. Not only are all CProcessLocal objects destroyed
automatically, they are not constructed until they are needed. CProcessLocal::operator-> will instantiate the
associated object the first time it is called, and no sooner. In the example above, that means that the ' strGlobal '
string will not be constructed until the first time SetGlobalString or GetGlobalString is called. In some instances,
this can help decrease DLL startup time.

Thread Local Data


Similar to process local data, thread local data is used when the data must be local to a given thread. That is, you
need a separate instance of the data for each thread that accesses that data. This can many times be used in lieu of
extensive synchronization mechanisms. If the data does not need to be shared by multiple threads, such
mechanisms can be expensive and unnecessary. Suppose we had a CString object (much like the sample above).
We can make it thread local by wrapping it with a CThreadLocal template:
struct CMyThreadData : public CNoTrackObject
{
CString strThread;
};
CThreadLocal<CMyThreadData> threadData;

void MakeRandomString()
{
// a kind of card shuffle (not a great one)
CString& str = threadData->strThread;
str.Empty();
while (str.GetLength() != 52)
{
unsigned int randomNumber;
errno_t randErr;
randErr = rand_s(&randomNumber);

if (randErr == 0)
{
TCHAR ch = randomNumber % 52 + 1;
if (str.Find(ch) <0)
str += ch; // not found, add it
}
}
}

If MakeRandomString was called from two different threads, each would "shuffle" the string in different ways
without interfering with the other. This is because there is actually a strThread instance per thread instead of just
one global instance.
Note how a reference is used to capture the CString address once instead of once per loop iteration. The loop
code could have been written with threadData->strThread everywhere ' str ' is used, but the code would be much
slower in execution. It is best to cache a reference to the data when such references occur in loops.
The CThreadLocal class template uses the same mechanisms that CProcessLocal does and the same
implementation techniques.

See also
Technical Notes by Number
Technical Notes by Category
TN059: Using MFC MBCS/Unicode Conversion
Macros
4/21/2020 • 6 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes how to use the macros for MBCS/Unicode conversion, which are defined in AFXPRIV.H. These
macros are most useful if your application deals directly with the OLE API or for some reason, often needs to
convert between Unicode and MBCS.

Overview
In MFC 3.x, a special DLL was used (MFCANS32.DLL) to automatically convert between Unicode and MBCS when
OLE interfaces were called. This DLL was an almost transparent layer that allowed OLE applications to be written as
if the OLE APIs and interfaces were MBCS, even though they are always Unicode (except on the Macintosh). While
this layer was convenient and allowed applications to be quickly ported from Win16 to Win32 (MFC, Microsoft
Word, Microsoft Excel, and VBA, are just some of the Microsoft applications that used this technology), it had a
sometimes significant performance hit. For this reason, MFC 4.x does not use this DLL and instead talks directly to
the Unicode OLE interfaces. To do this, MFC needs to convert to Unicode to MBCS when making a call to an OLE
interface, and often needs to convert to MBCS from Unicode when implementing an OLE interface. In order to
handle this efficiently and easily, a number of macros were created to make this conversion easier.
One of the biggest hurdles of creating such a set of macros is memory allocation. Because the strings cannot be
converted in place, new memory to hold the converted results must be allocated. This could have been done with
code similar to the following:

// we want to convert an MBCS string in lpszA


int nLen = MultiByteToWideChar(CP_ACP,
0,
lpszA, -1,
NULL,
NULL);

LPWSTR lpszW = new WCHAR[nLen];


MultiByteToWideChar(CP_ACP,
0,
lpszA, -1,
lpszW,
nLen);

// use it to call OLE here


pI->SomeFunctionThatNeedsUnicode(lpszW);

// free the string


delete[] lpszW;

This approach as a number of problems. The main problem is that it is a lot of code to write, test, and debug.
Something that was a simple function call, is now much more complex. In addition, there is a significant runtime
overhead in doing so. Memory has to be allocated on the heap and freed each time a conversion is done. Finally,
the code above would need to have appropriate #ifdefs added for Unicode and Macintosh builds (which don't
require this conversion to take place).
The solution we came up with is to create some macros which 1) mask the difference between the various
platforms, and 2) use an efficient memory allocation scheme, and 3) are easy to insert into the existing source
code. Here is an example of one of the definitions:

#define A2W(lpa) (\
((LPCSTR)lpa == NULL) NULL : (\
_convert = (strnlen(lpa)+1),\
AfxA2WHelper((LPWSTR) alloca(_convert*2),
lpa,
_convert)\)\)

Using this macro instead of the code above and things are much simpler:

// use it to call OLE here


USES_CONVERSION;
pI->SomeFunctionThatNeedsUnicode(T2OLE(lpszA));

There are extra calls where conversion is necessary, but using the macros is simple and effective.
The implementation of each macro uses the _alloca() function to allocate memory from the stack instead of the
heap. Allocating memory from the stack is much faster than allocating memory on the heap, and the memory is
automatically freed when the function is exited. In addition, the macros avoid calling MultiByteToWideChar (or
WideCharToMultiByte ) more than one time. This is done by allocating a little bit more memory than is necessary.
We know that an MBC will convert into at most one WCHAR and that for each WCHAR we will have a maximum
of two MBC bytes. By allocating a little more than necessary, but always enough to handle the conversion the
second call second call to the conversion function is avoided. The call to the helper function AfxA2Whelper reduces
the number of argument pushes that must be done in order to perform the conversion (this results in smaller
code, than if it called MultiByteToWideChar directly).
In order to for the macros to have space to store the a temporary length, it is necessary to declare a local variable
called _convert that does this in each function that uses the conversion macros. This is done by invoking the
USES_CONVERSION macro as seen above in the example.
There are both generic conversion macros and OLE specific macros. These two different macro sets are discussed
below. All of the macros reside in AFXPRIV.H.

Generic Conversion Macros


The generic conversion macros form the underlying mechanism. The macro example and implementation shown
in the previous section, A2W, is one such "generic" macro. It is not related to OLE specifically. The set of generic
macros is listed below:

A2CW (LPCSTR) -> (LPCWSTR)


A2W (LPCSTR) -> (LPWSTR)
W2CA (LPCWSTR) -> (LPCSTR)
W2A (LPCWSTR) -> (LPSTR)

Besides doing text conversions, there are also macros and helper functions for converting TEXTMETRIC , DEVMODE ,
BSTR , and OLE allocated strings. These macros are beyond the scope of this discussion - refer to AFXPRIV.H for
more information on those macros.
OLE Conversion Macros
The OLE conversion macros are designed specifically for handling functions that expect OLESTR characters. If you
examine the OLE headers, you will see many references to LPCOLESTR and OLECHAR . These types are used to
refer to the type of characters used in OLE interfaces in a way that is not specific to the platform. OLECHAR maps
to char in Win16 and Macintosh platforms and WCHAR in Win32.
In order to keep the number of #ifdef directives in the MFC code to a minimum we have a similar macro for each
conversion that where OLE strings are involved. The following macros are the most commonly used:

T2COLE (LPCTSTR) -> (LPCOLESTR)


T2OLE (LPCTSTR) -> (LPOLESTR)
OLE2CT (LPCOLESTR) -> (LPCTSTR)
OLE2T (LPCOLESTR) -> (LPCSTR)

Again, there are similar macros for doing TEXTMETRIC, DEVMODE, BSTR, and OLE allocated strings. Refer to
AFXPRIV.H for more information.

Other Considerations
Do not use the macros in a tight loop. For example, you do not want to write the following kind of code:

void BadIterateCode(LPCTSTR lpsz)


{
USES_CONVERSION;
for (int ii = 0; ii <10000; ii++)
pI->SomeMethod(ii, T2COLE(lpsz));

The code above could result in allocating megabytes of memory on the stack depending on what the contents of
the string lpsz is! It also takes time to convert the string for each iteration of the loop. Instead, move such
constant conversions out of the loop:

void MuchBetterIterateCode(LPCTSTR lpsz)


{
USES_CONVERSION;
LPCOLESTR lpszT = T2COLE(lpsz);

for (int ii = 0; ii <10000; ii++)


pI->SomeMethod(ii, lpszT);

If the string is not constant, then encapsulate the method call into a function. This will allow the conversion buffer
to be freed each time. For example:
void CallSomeMethod(int ii, LPCTSTR lpsz)
{
USES_CONVERSION;
pI->SomeMethod(ii, T2COLE(lpsz));

void MuchBetterIterateCode2(LPCTSTR* lpszArray)


{
for (int ii = 0; ii <10000; ii++)
CallSomeMethod(ii, lpszArray[ii]);

Never return the result of one of the macros, unless the return value implies making a copy of the data before the
return. For example, this code is bad:

LPTSTR BadConvert(ISomeInterface* pI)


{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI->GetFileName(&lpsz);

LPTSTR lpszT = OLE2T(lpsz);

CoMemFree(lpsz);

return lpszT; // bad! returning alloca memory


}

The code above could be fixed by changing the return value to something that copies the value:

CString BetterConvert(ISomeInterface* pI)


{
USES_CONVERSION;
LPOLESTR lpsz = NULL;
pI->GetFileName(&lpsz);

LPTSTR lpszT = OLE2T(lpsz);

CoMemFree(lpsz);

return lpszT; // CString makes copy


}

The macros are easy to use and easy to insert into your code, but as you can tell from the caveats above, you need
to be careful when using them.

See also
Technical Notes by Number
Technical Notes by Category
TN060: The New Windows Common Controls
3/4/2019 • 2 minutes to read • Edit Online

Technical Note 60, describing the new Windows common controls and how to use them, has been incorporated
into Controls.

See also
Technical Notes by Number
Technical Notes by Category
TN061: ON_NOTIFY and WM_NOTIFY Messages
3/27/2020 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This technical note provides background information on the new WM_NOTIFY message and describes the
recommended (and most common) way of handling WM_NOTIFY messages in your MFC application.
Notification Messages in Windows 3.x
In Windows 3.x, controls notify their parents of events such as mouse clicks, changes in content and selection, and
control background painting by sending a message to the parent. Simple notifications are sent as special
WM_COMMAND messages, with the notification code (such as BN_CLICKED) and control ID packed into wParam
and the control's handle in lParam. Note that since wParam and lParam are full, there is no way to pass any
additional data — these messages can be only simple notification. For instance, in the BN_CLICKED notification,
there's no way to send information about the location of the mouse cursor when the button was clicked.
When controls in Windows 3.x need to send a notification message that includes additional data, they use a variety
of special-purpose messages, including WM_CTLCOLOR, WM_VSCROLL, WM_HSCROLL, WM_DRAWITEM,
WM_MEASUREITEM, WM_COMPAREITEM, WM_DELETEITEM, WM_CHARTOITEM, WM_VKEYTOITEM, and so on.
These messages can be reflected back to the control that sent them. For more information, see TN062: Message
Reflection for Windows Controls.
Notification Messages in Win32
For controls that existed in Windows 3.1, the Win32 API uses most of the notification messages that were used in
Windows 3.x. However, Win32 also adds a number of sophisticated, complex controls to those supported in
Windows 3.x. Frequently, these controls need to send additional data with their notification messages. Rather than
adding a new WM_ * message for each new notification that needs additional data, the designers of the Win32 API
chose to add just one message, WM_NOTIFY, which can pass any amount of additional data in a standardized
fashion.
WM_NOTIFY messages contain the ID of the control sending the message in wParam and a pointer to a structure
in lParam. This structure is either an NMHDR structure or some larger structure that has an NMHDR structure as
its first member. Note that since the NMHDR member is first, a pointer to this structure can be used as either a
pointer to an NMHDR or as a pointer to the larger structure depending on how you cast it.
In most cases, the pointer will point to a larger structure and you'll need to cast it when you use it. In only a few
notifications, such as the common notifications (whose names start with NM_ ) and the tool tip control's
TTN_SHOW and TTN_POP notifications, is an NMHDR structure actually used.
The NMHDR structure or initial member contains the handle and ID of the control sending the message and the
notification code (such as TTN_SHOW). The format of the NMHDR structure is shown below:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;

For a TTN_SHOW message, the code member would be set to TTN_SHOW.


Most notifications pass a pointer to a larger structure that contains an NMHDR structure as its first member. For
instance, consider the structure used by the list view control's LVN_KEYDOWN notification message, which is sent
when a key is pressed in a list view control. The pointer points to an LV_KEYDOWN structure, which is defined as
shown below:

typedef struct tagLV_KEYDOWN {


NMHDR hdr;
WORD wVKey;
UINT flags;
} LV_KEYDOWN;

Note that since the NMHDR member is first in this structure, the pointer you're passed in the notification message
can be cast to either a pointer to an NMHDR or a pointer to an LV_KEYDOWN .
Notifications Common to All New Windows Controls
Some notifications are common to all of the new Windows controls. These notifications pass a pointer to an
NMHDR structure.

N OT IF IC AT IO N C O DE SEN T B EC A USE

NM_CLICK User clicked left mouse button in the control

NM_DBLCLK User double-clicked left mouse button in the control

NM_RCLICK User clicked right mouse button in the control

NM_RDBLCLK User double-clicked right mouse button in the control

NM_RETURN User pressed the ENTER key while control has input focus

NM_SETFOCUS Control has been given input focus

NM_KILLFOCUS Control has lost input focus

NM_OUTOFMEMORY Control could not complete an operation because there was


not enough memory available

ON_NOTIFY: Handling WM_NOTIFY Messages in MFC Applications


The function CWnd::OnNotify handles notification messages. Its default implementation checks the message map
for notification handlers to call. In general, you do not override OnNotify . Instead, you provide a handler function
and add a message-map entry for that handler to the message map of your owner window's class.
ClassWizard, via the ClassWizard property sheet, can create the ON_NOTIFY message-map entry and provide you
with a skeleton handler function. For more information on using ClassWizard to make this easier, see Mapping
Messages to Functions.
The ON_NOTIFY message-map macro has the following syntax:

ON_NOTIFY(wNotifyCode, id, memberFxn)

where the parameters are:


wNotifyCode
The code for the notification message to be handled, such as LVN_KEYDOWN.
id
The child identifier of the control for which the notification is sent.
memberFxn
The member function to be called when this notification is sent.
Your member function must be declared with the following prototype:

afx_msg void memberFxn(NMHDR* pNotifyStruct, LRESULT* result);

where the parameters are:


pNotifyStruct
A pointer to the notification structure, as described in the section above.
result
A pointer to the result code you'll set before you return.

Example
To specify that you want the member function OnKeydownList1 to handle LVN_KEYDOWN messages from the
CListCtrl whose ID is IDC_LIST1 , you would use ClassWizard to add the following to your message map:

ON_NOTIFY(LVN_KEYDOWN, IDC_LIST1, OnKeydownList1)

In the example above, the function provided by ClassWizard is:

void CMessageReflectionDlg::OnKeydownList1(NMHDR* pNMHDR, LRESULT* pResult)


{
LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;

// TODO: Add your control notification handler


// code here

*pResult = 0;
}

Note that ClassWizard provides a pointer of the proper type automatically. You can access the notification
structure through either pNMHDR or pLVKeyDow .

ON_NOTIFY_RANGE
If you need to process the same WM_NOTIFY message for a set of controls, you can use ON_NOTIFY_RANGE
rather than ON_NOTIFY. For instance, you may have a set of buttons for which you want to perform the same
action for a certain notification message.
When you use ON_NOTIFY_RANGE, you specify a contiguous range of child identifiers for which to handle the
notification message by specifying the beginning and ending child identifiers of the range.
ClassWizard does not handle ON_NOTIFY_RANGE; to use it, you need to edit your message map yourself.
The message-map entry and function prototype for ON_NOTIFY_RANGE are as follows:

ON_NOTIFY_RANGE(wNotifyCode, id, idLast, memberFxn)

where the parameters are:


wNotifyCode
The code for the notification message to be handled, such as LVN_KEYDOWN.
id
The first identifier in the contiguous range of identifiers.
idLast
The last identifier in the contiguous range of identifiers.
memberFxn
The member function to be called when this notification is sent.
Your member function must be declared with the following prototype:

afx_msg void memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);

where the parameters are:


id
The child identifier of the control that sent the notification.
pNotifyStruct
A pointer to the notification structure, as described above.
result
A pointer to the result code you'll set before you return.

ON_NOTIFY_EX, ON_NOTIFY_EX_RANGE
If you want more than one object in the notification routing to handle a message, you can use ON_NOTIFY_EX (or
ON_NOTIFY_EX_RANGE) rather than ON_NOTIFY (or ON_NOTIFY_RANGE). The only difference between the EX
version and the regular version is that the member function called for the EX version returns a BOOL that
indicates whether or not message processing should continue. Returning FALSE from this function allows you to
process the same message in more than one object.
ClassWizard does not handle ON_NOTIFY_EX or ON_NOTIFY_EX_RANGE; if you want to use either of them, you
need to edit your message map yourself.
The message-map entry and function prototype for ON_NOTIFY_EX and ON_NOTIFY_EX_RANGE are as follows.
The meanings of the parameters are the same as for the non-EX versions.

ON_NOTIFY_EX(nCode, id, memberFxn)


ON_NOTIFY_EX_RANGE(wNotifyCode, id, idLast, memberFxn)

The prototype for both of the above is the same:


afx_msg BOOL memberFxn(UINT id, NMHDR* pNotifyStruct, LRESULT* result);

In both cases, id holds the child identifier of the control that sent the notification.
Your function must return TRUE if the notification message has been completely handled or FALSE if other
objects in the command routing should have a chance to handle the message.

See also
Technical Notes by Number
Technical Notes by Category
TN062: Message Reflection for Windows Controls
10/31/2018 • 7 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result,
some procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you
search for the topic of interest in the online documentation index.

This technical note describes message reflection, a new feature in MFC 4.0. It also contains directions for creating
a simple reusable control that uses message reflection.
This technical note does not discuss message reflection as it applies to ActiveX controls (formerly called OLE
controls). Please see the article ActiveX Controls: Subclassing a Windows Control.
What Is Message Reflection
Windows controls frequently send notification messages to their parent windows. For instance, many controls
send a control color notification message (WM_CTLCOLOR or one of its variants) to their parent to allow the
parent to supply a brush for painting the background of the control.
In Windows and in MFC before version 4.0, the parent window, often a dialog box, is responsible for handling
these messages. This means that the code for handling the message needs to be in the parent window's class
and that it has to be duplicated in every class that needs to handle that message. In the case above, every dialog
box that wanted controls with custom backgrounds would have to handle the control color notification message.
It would be much easier to reuse code if a control class could be written that would handle its own background
color.
In MFC 4.0, the old mechanism still works — parent windows can handle notification messages. In addition,
however, MFC 4.0 facilitates reuse by providing a feature called "message reflection" that allows these
notification messages to be handled in either the child control window or the parent window, or in both. In the
control background color example, you can now write a control class that sets its own background color by
handling the reflected WM_CTLCOLOR message — all without relying on the parent. (Note that since message
reflection is implemented by MFC, not by Windows, the parent window class must be derived from CWnd for
message reflection to work.)
Older versions of MFC did something similar to message reflection by providing virtual functions for a few
messages, such as messages for owner-drawn list boxes (WM_DRAWITEM, and so on). The new message
reflection mechanism is generalized and consistent.
Message reflection is backward compatible with code written for versions of MFC before 4.0.
If you have supplied a handler for a specific message, or for a range of messages, in your parent window's class,
it will override reflected message handlers for the same message provided you don't call the base class handler
function in your own handler. For example, if you handle WM_CTLCOLOR in your dialog box class, your handling
will override any reflected message handlers.
If, in your parent window class, you supply a handler for a specific WM_NOTIFY message or a range of
WM_NOTIFY messages, your handler will be called only if the child control sending those messages does not
have a reflected message handler through ON_NOTIFY_REFLECT() . If you use ON_NOTIFY_REFLECT_EX() in your
message map, your message handler may or may not allow the parent window to handle the message. If the
handler returns FALSE , the message will be handled by the parent as well, while a call that returns TRUE does
not allow the parent to handle it. Note that the reflected message is handled before the notification message.
When a WM_NOTIFY message is sent, the control is offered the first chance to handle it. If any other reflected
message is sent, the parent window has the first chance to handle it and the control will receive the reflected
message. To do so, it will need a handler function and an appropriate entry in the control's class message map.
The message-map macro for reflected messages is slightly different than for regular notifications: it has
_REFLECT appended to its usual name. For instance, to handle a WM_NOTIFY message in the parent, you use the
macro ON_NOTIFY in the parent's message map. To handle the reflected message in the child control, use the
ON_NOTIFY_REFLECT macro in the child control's message map. In some cases, the parameters are different, as
well. Note that ClassWizard can usually add the message-map entries for you and provide skeleton function
implementations with correct parameters.
See TN061: ON_NOTIFY and WM_NOTIFY Messages for information on the new WM_NOTIFY message.
Message-Map Entries and Handler Function Prototypes for Reflected Messages
To handle a reflected control notification message, use the message-map macros and function prototypes listed
in the table below.
ClassWizard can usually add these message-map entries for you and provide skeleton function implementations.
See Defining a Message Handler for a Reflected Message for information about how to define handlers for
reflected messages.
To convert from the message name to the reflected macro name, prepend ON_ and append _REFLECT. For
example, WM_CTLCOLOR becomes ON_WM_CTLCOLOR_REFLECT. (To see which messages can be reflected, do
the opposite conversion on the macro entries in the table below.)
The three exceptions to the rule above are as follows:
The macro for WM_COMMAND notifications is ON_CONTROL_REFLECT.
The macro for WM_NOTIFY reflections is ON_NOTIFY_REFLECT.
The macro for ON_UPDATE_COMMAND_UI reflections is ON_UPDATE_COMMAND_UI_REFLECT.
In each of the above special cases, you must specify the name of the handler member function. In the other
cases, you must use the standard name for your handler function.
The meanings of the parameters and return values of the functions are documented under either the function
name or the function name with On prepended. For instance, CtlColor is documented in OnCtlColor . Several
reflected message handlers need fewer parameters than the similar handlers in a parent window. Just match the
names in the table below with the names of the formal parameters in the documentation.

M A P EN T RY F UN C T IO N P ROTOT Y P E

ON_CONTROL_REFLECT( wNotifyCode , memberFxn ) afx_msg void memberFxn ( );

ON_NOTIFY_REFLECT( wNotifyCode , memberFxn ) afx_msg void memberFxn ( NMHDR * pNotifyStruct ,


LRESULT * result );

ON_UPDATE_COMMAND_UI_REFLECT( memberFxn ) afx_msg void memberFxn ( CCmdUI * pCmdUI );

ON_WM_CTLCOLOR_REFLECT( ) afx_msg HBRUSH CtlColor ( CDC * pDC , UINT


nCtlColor );

ON_WM_DRAWITEM_REFLECT( ) afx_msg void DrawItem ( LPDRAWITEMSTRUCT


lpDrawItemStruct );
M A P EN T RY F UN C T IO N P ROTOT Y P E

ON_WM_MEASUREITEM_REFLECT( ) afx_msg void MeasureItem (


LPMEASUREITEMSTRUCT lpMeasureItemStruct );

ON_WM_DELETEITEM_REFLECT( ) afx_msg void DeleteItem ( LPDELETEITEMSTRUCT


lpDeleteItemStruct );

ON_WM_COMPAREITEM_REFLECT( ) afx_msg int CompareItem ( LPCOMPAREITEMSTRUCT


lpCompareItemStruct );

ON_WM_CHARTOITEM_REFLECT( ) afx_msg int CharToItem ( UINT nKey , UINT nIndex


);

ON_WM_VKEYTOITEM_REFLECT( ) afx_msg int VKeyToItem ( UINT nKey , UINT nIndex


);

ON_WM_HSCROLL_REFLECT( ) afx_msg void HScroll ( UINT nSBCode , UINT nPos );

ON_WM_VSCROLL_REFLECT( ) afx_msg void VScroll ( UINT nSBCode , UINT nPos );

ON_WM_PARENTNOTIFY_REFLECT( ) afx_msg void ParentNotify ( UINT message , LPARAM


lParam );

The ON_NOTIFY_REFLECT and ON_CONTROL_REFLECT macros have variations that allow more than one object
(such as the control and its parent) to handle a given message.

M A P EN T RY F UN C T IO N P ROTOT Y P E

ON_NOTIFY_REFLECT_EX( wNotifyCode , memberFxn ) afx_msg BOOL memberFxn ( NMHDR * pNotifyStruct


, LRESULT * result );

ON_CONTROL_REFLECT_EX( wNotifyCode , afx_msg BOOL memberFxn ( );


memberFxn )

Handling Reflected Messages: An Example of a Reusable control


This simple example creates a reusable control called CYellowEdit . The control works the same as a regular edit
control except that it displays black text on a yellow background. It would be easy to add member functions that
would allow the CYellowEdit control to display different colors.
To try the example that creates a reusable control
1. Create a new dialog box in an existing application. For more information, see the dialog editor topic.
You must have an application in which to develop the reusable control. If you don't have an existing
application to use, create a dialog-based application using AppWizard.
2. With your project loaded into Visual C++, use ClassWizard to create a new class called CYellowEdit
based on CEdit .
3. Add three member variables to your CYellowEdit class. The first two will be COLORREF variables to hold
the text color and the background color. The third will be a CBrush object that will hold the brush for
painting the background. The CBrush object allows you to create the brush once, merely referencing it
after that, and to destroy the brush automatically when the CYellowEdit control is destroyed.
4. Initialize the member variables by writing the constructor as follows:

CYellowEdit::CYellowEdit()
{
m_clrText = RGB(0, 0, 0);
m_clrBkgnd = RGB(255, 255, 0);
m_brBkgnd.CreateSolidBrush(m_clrBkgnd);
}

5. Using ClassWizard, add a handler for the reflected WM_CTLCOLOR message to your CYellowEdit class.
Note that the equal sign in front of the message name in the list of messages you can handle indicates
that the message is reflected. This is described in Defining a Message Handler for a Reflected Message.
ClassWizard adds the following message-map macro and skeleton function for you:

ON_WM_CTLCOLOR_REFLECT()
// Note: other code will be in between....

HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor)


{
// TODO: Change any attributes of the DC here
// TODO: Return a non-NULL brush if the
// parent's handler should not be called
return NULL;
}

6. Replace the body of the function with the following code. The code specifies the text color, the text
background color, and the background color for rest of the control.

pDC->SetTextColor(m_clrText); // text
pDC->SetBkColor(m_clrBkgnd); // text bkgnd
return m_brBkgnd; // ctl bkgnd

7. Create an edit control in your dialog box, then attach it to a member variable by double-clicking the edit
control while holding a control key down. In the Add Member Variable dialog box, finish the variable
name and choose "Control" for the category, then "CYellowEdit" for the variable type. Don't forget to set
the tab order in the dialog box. Also, be sure to include the header file for the CYellowEdit control in your
dialog box's header file.
8. Build and run your application. The edit control will have a yellow background.

See also
Technical Notes by Number
Technical Notes by Category
TN063: Debugging Internet MFC extension DLLs
3/4/2019 • 2 minutes to read • Edit Online

This information is obsolete and has been removed.

See also
Technical Notes by Number
Technical Notes by Category
TN064: Apartment-Model Threading in ActiveX
Controls
3/31/2020 • 3 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This technical note explains how to enable apartment-model threading in an ActiveX control. Note that apartment-
model threading is only supported in Visual C++ versions 4.2 or later.

What Is Apartment-Model Threading


The apartment model is an approach to supporting embedded objects, such as ActiveX controls, within a
multithreaded container application. Although the application may have multiple threads, each instance of an
embedded object will be assigned to one "apartment," which will execute on only one thread. In other words, all
calls into an instance of a control will happen on the same thread.
However, different instances of the same type of control may be assigned to different apartments. So, if multiple
instances of a control share any data in common (for example, static or global data), then access to this shared
data will need to be protected by a synchronization object, such as a critical section.
For complete details on the apartment threading model, please see Processes and Threads in the OLE
Programmer's Reference.

Why Support Apartment-Model Threading


Controls that support apartment-model threading can be used in multithreaded container applications that also
support the apartment model. If you do not enable apartment-model threading, you will limit the potential set of
containers in which your control could be used.
Enabling apartment-model threading is easy for most controls, particularly if they have little or no shared data.

Protecting Shared Data


If your control uses shared data, such as a static member variable, access to that data should be protected with a
critical section to prevent more than one thread from modifying the data at the same time. To set up a critical
section for this purpose, declare a static member variable of class CCriticalSection in your control's class. Use the
Lock and Unlock member functions of this critical section object wherever your code accesses the shared data.

Consider, for example, a control class that needs to maintain a string that is shared by all instances. This string can
be maintained in a static member variable and protected by a critical section. The control's class declaration would
contain the following:
class CSampleCtrl : public COleControl
{
...
static CString _strShared;
static CCriticalSection _critSect;
};

The implementation for the class would include definitions for these variables:

int CString CSampleCtrl::_strShared;


CCriticalSection CSampleCtrl::_critSect;

Access to the _strShared static member can then be protected by the critical section:

void CSampleCtrl::SomeMethod()
{
_critSect.Lock();
if (_strShared.Empty())
_strShared = "<text>";
_critSect.Unlock();

...
}

Registering an Apartment-Model-Aware Control


Controls that support apartment-model threading should indicate this capability in the registry, by adding the
named value "ThreadingModel" with a value of "Apartment" in their class ID registry entry under the class
id\InprocSer ver32 key. To cause this key to be automatically registered for your control, pass the
afxRegApartmentThreading flag in the sixth parameter to AfxOleRegisterControlClass :

BOOL CSampleCtrl::CSampleCtrlFactory::UpdateRegistry(BOOL bRegister)


{
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_SAMPLE,
IDB_SAMPLE,
afxRegApartmentThreading,
_dwSampleOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);

else
return AfxOleUnregisterClass(m_clsid,
m_lpszProgID);

If your control project was generated by ControlWizard in Visual C++ version 4.1 or later, this flag will already be
present in your code. No changes are necessary to register the threading model.
If your project was generated by an earlier version of ControlWizard, your existing code will have a Boolean value
as the sixth parameter. If the existing parameter is TRUE, change it to afxRegInsertable |
afxRegApartmentThreading. If the existing parameter is FALSE, change it to afxRegApartmentThreading.
If your control does not follow the rules for apartment-model threading, you must not pass
afxRegApartmentThreading in this parameter.

See also
Technical Notes by Number
Technical Notes by Category
TN065: Dual-Interface Support for OLE Automation
Servers
8/20/2019 • 10 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note discusses how to add dual-interface support to an MFC-based OLE Automation server application. The
ACDUAL sample illustrates dual-interface support, and the example code in this note is taken from ACDUAL. The
macros described in this note, such as DECLARE_DUAL_ERRORINFO, DUAL_ERRORINFO_PART, and
IMPLEMENT_DUAL_ERRORINFO, are part of the ACDUAL sample and can be found in MFCDUAL.H.

Dual Interfaces
Although OLE Automation allows you to implement an IDispatch interface, a VTBL interface, or a dual interface
(which encompasses both), Microsoft strongly recommends that you implement dual interfaces for all exposed
OLE Automation objects. Dual interfaces have significant advantages over IDispatch -only or VTBL-only interfaces:
Binding can take place at compile time through the VTBL interface, or at run time through IDispatch .
OLE Automation controllers that can use the VTBL interface may benefit from improved performance.
Existing OLE Automation controllers that use the IDispatch interface will continue to work.
The VTBL interface is easier to call from C++.
Dual interfaces are required for compatibility with Visual Basic object support features.

Adding Dual-Interface Support to a CCmdTarget-Based Class


A dual interface is really just a custom interface derived from IDispatch . The most straightforward way to
implement dual-interface support in a CCmdTarget -based class is to first implement the normal dispatch interface
on your class using MFC and ClassWizard, then add the custom interface later. For the most part, your custom
interface implementation will simply delegate back to the MFC IDispatch implementation.
First, modify the ODL file for your server to define dual interfaces for your objects. To define a dual interface, you
must use an interface statement, instead of the DISPINTERFACE statement that the Visual C++ wizards generate.
Rather than removing the existing DISPINTERFACE statement, add a new interface statement. By retaining the
DISPINTERFACE form, you can continue to use ClassWizard to add properties and methods to your object, but you
must add the equivalent properties and methods to your interface statement.
An interface statement for a dual interface must have the OLEAUTOMATION and DUAL attributes, and the interface
must be derived from IDispatch . You can use the GUIDGEN sample to create a IID for the dual interface:
[ uuid(0BDD0E81-0DD7-11cf-BBA8-444553540000), // IID_IDualAClick
oleautomation,
dual
]
interface IDualAClick : IDispatch
{
};

Once you have the interface statement in place, start adding entries for the methods and properties. For dual
interfaces, you need to rearrange the parameter lists so that your methods and property accessor functions in the
dual interface return an HRESULT and pass their return values as parameters with the attributes [retval,out] .
Remember that for properties, you will need to add both a read ( propget ) and write ( propput ) access function
with the same id. For example:

[propput, id(1)] HRESULT text([in] BSTR newText);


[propget, id(1)] HRESULT text([out, retval] BSTR* retval);

After your methods and properties are defined, you need to add a reference to the interface statement in your
coclass statement. For example:

[ uuid(4B115281-32F0-11cf-AC85-444553540000) ]
coclass Document
{
dispinterface IAClick;
[default] interface IDualAClick;
};

Once your ODL file has been updated, use MFC's interface map mechanism to define an implementation class for
the dual interface in your object class and make the corresponding entries in MFC's QueryInterface mechanism.
You need one entry in the INTERFACE_PART block for each entry in the interface statement of the ODL, plus the
entries for a dispatch interface. Each ODL entry with the propput attribute needs a function named
put_propertyname . Each entry with the propget attribute needs a function named get_propertyname .

To define an implementation class for your dual interface, add a DUAL_INTERFACE_PART block to your object class
definition. For example:

BEGIN_DUAL_INTERFACE_PART(DualAClick, IDualAClick)
STDMETHOD(put_text)(THIS_ BSTR newText);
STDMETHOD(get_text)(THIS_ BSTR FAR* retval);
STDMETHOD(put_x)(THIS_ short newX);
STDMETHOD(get_x)(THIS_ short FAR* retval);
STDMETHOD(put_y)(THIS_ short newY);
STDMETHOD(get_y)(THIS_ short FAR* retval);
STDMETHOD(put_Position)(THIS_ IDualAutoClickPoint FAR* newPosition);
STDMETHOD(get_Position)(THIS_ IDualAutoClickPoint FAR* FAR* retval);
STDMETHOD(RefreshWindow)(THIS);
STDMETHOD(SetAllProps)(THIS_ short x, short y, BSTR text);
STDMETHOD(ShowWindow)(THIS);
END_DUAL_INTERFACE_PART(DualAClick)

To connect the dual interface to MFC's QueryInterface mechanism, add an INTERFACE_PART entry to the interface
map:
BEGIN_INTERFACE_MAP(CAutoClickDoc, CDocument)
INTERFACE_PART(CAutoClickDoc, DIID_IAClick, Dispatch)
INTERFACE_PART(CAutoClickDoc, IID_IDualAClick, DualAClick)
END_INTERFACE_MAP()

Next, you need to fill in the implementation of the interface. For the most part, you will be able to delegate to the
existing MFC IDispatch implementation. For example:

STDMETHODIMP_(ULONG) CAutoClickDoc::XDualAClick::AddRef()
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CAutoClickDoc::XDualAClick::Release()
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
return pThis->ExternalRelease();
}

STDMETHODIMP CAutoClickDoc::XDualAClick::QueryInterface(
REFIID iid,
LPVOID* ppvObj)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP CAutoClickDoc::XDualAClick::GetTypeInfoCount(
UINT FAR* pctinfo)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
ASSERT(lpDispatch != NULL);
return lpDispatch->GetTypeInfoCount(pctinfo);
}

STDMETHODIMP CAutoClickDoc::XDualAClick::GetTypeInfo(
UINT itinfo,
LCID lcid,
ITypeInfo FAR* FAR* pptinfo)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
ASSERT(lpDispatch != NULL);

return lpDispatch->GetTypeInfo(itinfo, lcid, pptinfo);


}

STDMETHODIMP CAutoClickDoc::XDualAClick::GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
UINT cNames,
LCID lcid,
DISPID FAR* rgdispid)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
ASSERT(lpDispatch != NULL);

return lpDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);


}

STDMETHODIMP CAutoClickDoc::XDualAClick::Invoke(
DISPID dispidMember,
REFIID riid,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS FAR* pdispparams,
VARIANT FAR* pvarResult,
EXCEPINFO FAR* pexcepinfo,
UINT FAR* puArgErr)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE);
ASSERT(lpDispatch != NULL);

return lpDispatch->Invoke(dispidMember, riid, lcid,


wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}

For your object's methods and property accessor functions, you need to fill in the implementation. Your method
and property functions can generally delegate back to the methods generated using ClassWizard. However, if you
set up properties to access variables directly, you need to write the code to get/put the value into the variable. For
example:

STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)


{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
// MFC automatically converts from Unicode BSTR to
// Ansi CString, if necessary...
pThis->m_str = newText;
return NOERROR;
}

STDMETHODIMP CAutoClickDoc::XDualAClick::get_text(BSTR* retval)


{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
// MFC automatically converts from Ansi CString to
// Unicode BSTR, if necessary...
pThis->m_str.SetSysString(retval);
return NOERROR;
}

Passing Dual-Interface Pointers


Passing your dual-interface pointer isn't straightforward, especially if you need to call CCmdTarget::FromIDispatch .
FromIDispatch only works on MFC's IDispatch pointers. One way to work around this is to query for the original
IDispatch pointer set up by MFC and pass that pointer to functions that need it. For example:

STDMETHODIMP CAutoClickDoc::XDualAClick::put_Position(
IDualAutoClickPoint FAR* newPosition)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDisp = NULL;
newPosition->QueryInterface(IID_IDispatch, (LPVOID*)&lpDisp);
pThis->SetPosition(lpDisp);
lpDisp->Release();
return NOERROR;
}

Before passing a pointer back through the dual-interface method, you might need to convert it from the MFC
IDispatch pointer to your dual-interface pointer. For example:
STDMETHODIMP CAutoClickDoc::XDualAClick::get_Position(
IDualAutoClickPoint FAR* FAR* retval)
{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
LPDISPATCH lpDisp;
lpDisp = pThis->GetPosition();
lpDisp->QueryInterface(IID_IDualAutoClickPoint, (LPVOID*)retval);
return NOERROR;
}

Registering the Application's Type Library


AppWizard does not generate code to register an OLE Automation server application's type library with the
system. While there are other ways to register the type library, it is convenient to have the application register the
type library when it is updating its OLE type information, that is, whenever the application is run stand-alone.
To register the application's type library whenever the application is run stand alone:
Include AFXCTL.H in your standard includes header file, STDAFX.H, to access the definition of the
AfxOleRegisterTypeLib function.

In your application's InitInstance function, locate the call to COleObjectFactory::UpdateRegistryAll .


Following this call, add a call to AfxOleRegisterTypeLib , specifying the LIBID corresponding to your type
library, along with the name of your type library:

// When a server application is launched stand-alone, it is a good idea


// to update the system registry in case it has been damaged.
m_server.UpdateRegistry(OAT_DISPATCH_OBJECT);

COleObjectFactory::UpdateRegistryAll();

// DUAL_SUPPORT_START
// Make sure the type library is registered or dual interface won't work.
AfxOleRegisterTypeLib(AfxGetInstanceHandle(),
LIBID_ACDual,
_T("AutoClik.TLB"));
// DUAL_SUPPORT_END

Modifying Project Build Settings to Accommodate Type Library


Changes
To modify a project's build settings so that a header file containing UUID definitions is generated by MkTypLib
whenever the type library is rebuilt:
1. On the Build menu, click Settings , and then select the ODL file from the file list for each configuration.
2. Click the OLE Types tab and specify a filename in the Output header filename field. Use a filename that is
not already used by your project, because MkTypLib will overwrite any existing file. Click OK to close the
Build Settings dialog box.
To add the UUID definitions from the MkTypLib-generated header file to your project:
1. Include the MkTypLib-generated header file in your standard includes header file, stdafx.h.
2. Create a new file, INITIIDS.CPP, and add it to your project. In this file, include your MkTypLib-generated
header file after including OLE2.H and INITGUID.H:
// initIIDs.c: defines IIDs for dual interfaces
// This must not be built with precompiled header.
#include <ole2.h>
#include <initguid.h>
#include "acdual.h"

3. On the Build menu, click Settings , and then select INITIIDS.CPP from the file list for each configuration.
4. Click the C++ tab, click category Precompiled Headers , and select the Not using precompiled
headers radio button. Click OK to close the Build Settings dialog box.

Specifying the Correct Object Class Name in the Type Library


The wizards shipped with Visual C++ incorrectly use the implementation class name to specify the coclass in the
server's ODL file for OLE-creatable classes. While this will work, the implementation class name is probably not the
class name you want users of your object to use. To specify the correct name, open the ODL file, locate each coclass
statement, and replace the implementation class name with the correct external name.
Note that when the coclass statement is changed, the variable names of CLSID s in the MkTypLib-generated header
file will change accordingly. You will need to update your code to use the new variable names.

Handling Exceptions and the Automation Error Interfaces


Your automation object's methods and property accessor functions may throw exceptions. If so, you should handle
them in your dual-interface implementation and pass information about the exception back to the controller
through the OLE Automation error-handling interface, IErrorInfo . This interface provides for detailed, contextual
error information through both IDispatch and VTBL interfaces. To indicate that an error handler is available, you
should implement the ISupportErrorInfo interface.
To illustrate the error-handling mechanism, assume that the ClassWizard-generated functions used to implement
the standard dispatch support throw exceptions. MFC's implementation of IDispatch::Invoke typically catches
these exceptions and converts them into an EXCEPTINFO structure that is returned through the Invoke call.
However, when VTBL interface is used, you are responsible for catching the exceptions yourself. As an example of
protecting your dual-interface methods:

STDMETHODIMP CAutoClickDoc::XDualAClick::put_text(BSTR newText)


{
METHOD_PROLOGUE(CAutoClickDoc, DualAClick)
TRY_DUAL(IID_IDualAClick)
{
// MFC automatically converts from Unicode BSTR to
// Ansi CString, if necessary...
pThis->m_str = newText;
return NOERROR;
}
CATCH_ALL_DUAL
}

CATCH_ALL_DUAL takes care of returning the correct error code when an exception occurs. CATCH_ALL_DUAL converts
an MFC exception into OLE Automation error-handling information using the ICreateErrorInfo interface. (An
example CATCH_ALL_DUAL macro is in the file MFCDUAL.H in the ACDUAL sample. The function it calls to handle
exceptions, DualHandleException , is in the file MFCDUAL.CPP.) CATCH_ALL_DUAL determines the error code to return
based on the type of exception that occurred:
COleDispatchException - In this case, HRESULT is constructed using the following code:
hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, (e->m_wCode + 0x200));

This creates an HRESULT specific to the interface that caused the exception. The error code is offset by 0x200
to avoid any conflicts with system-defined HRESULT s for standard OLE interfaces.
CMemoryException - In this case, E_OUTOFMEMORY is returned.
Any other exception - In this case, E_UNEXPECTED is returned.

To indicate that the OLE Automation error handler is used, you should also implement the ISupportErrorInfo
interface.
First, add code to your automation class definition to show it supports ISupportErrorInfo .
Second, add code to your automation class's interface map to associate the ISupportErrorInfo implementation
class with MFC's QueryInterface mechanism. The INTERFACE_PART statement matches the class defined for
ISupportErrorInfo .

Finally, implement the class defined to support ISupportErrorInfo .


(The ACDUAL sample contains three macros to help do these three steps, DECLARE_DUAL_ERRORINFO ,
DUAL_ERRORINFO_PART , and IMPLEMENT_DUAL_ERRORINFO , all contained in MFCDUAL.H.)

The following example implements a class defined to support ISupportErrorInfo . CAutoClickDoc is the name of
your automation class and IID_IDualAClick is the IID for the interface that is the source of errors reported
through the OLE Automation error object:

STDMETHODIMP_(ULONG) CAutoClickDoc::XSupportErrorInfo::AddRef()
{
METHOD_PROLOGUE(CAutoClickDoc, SupportErrorInfo)
return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG) CAutoClickDoc::XSupportErrorInfo::Release()
{
METHOD_PROLOGUE(CAutoClickDoc, SupportErrorInfo)
return pThis->ExternalRelease();
}

STDMETHODIMP CAutoClickDoc::XSupportErrorInfo::QueryInterface(
REFIID iid,
LPVOID* ppvObj)
{
METHOD_PROLOGUE(CAutoClickDoc, SupportErrorInfo)
return pThis->ExternalQueryInterface(&iid, ppvObj);
}

STDMETHODIMP CAutoClickDoc::XSupportErrorInfo::InterfaceSupportsErrorInfo(
REFIID iid)
{
METHOD_PROLOGUE(CAutoClickDoc, SupportErrorInfo)
return (iid == IID_IDualAClick) S_OK : S_FALSE;
}

See also
Technical Notes by Number
Technical Notes by Category
TN066: Common MFC 3.x to 4.0 Porting Issues
5/14/2019 • 2 minutes to read • Edit Online

This technical note described the most common problems that can occur when attempting to port an application
written with MFC 3.x (the MFC included with Visual C++ 2.x) to MFC 4.0.

See also
Technical Notes by Number
Technical Notes by Category
TN068: Performing Transactions with the Microsoft
Access 7 ODBC Driver
10/31/2018 • 3 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

This note describes how to perform transactions when using the MFC ODBC database classes and the Microsoft
Access 7.0 ODBC driver included in the Microsoft ODBC Desktop Driver Pack version 3.0.

Overview
If your database application performs transactions, you must be careful to call CDatabase::BeginTrans and
CRecordset::Open in the correct sequence in your application. The Microsoft Access 7.0 driver uses the Microsoft
Jet database engine, and Jet requires that your application not begin a transaction on any database that has an
open cursor. For the MFC ODBC database classes, an open cursor equates to an open CRecordset object.
If you open a recordset before calling BeginTrans , you may not see any error messages. However, any recordset
updates your application makes become permanent after calling CRecordset::Update , and the updates will not be
rolled back by calling Rollback . To avoid this problem, you must call BeginTrans first and then open the recordset.
MFC checks the driver functionality for cursor commit and rollback behavior. Class CDatabase provides two
member functions, GetCursorCommitBehavior and GetCursorRollbackBehavior , to determine the effect of any
transaction on your open CRecordset object. For the Microsoft Access 7.0 ODBC driver, these member functions
return SQL_CB_CLOSE because the Access driver does not support cursor preservation. Therefore, you must call
CRecordset::Requery following a CommitTrans or Rollback operation.

When you need to perform multiple transactions one after another, you cannot call Requery after the first
transaction and then start the next one. You must close the recordset before the next call to BeginTrans in order to
satisfy Jet's requirement. This technical note describes two methods of handling this situation:
Closing the recordset after each CommitTrans or Rollback operation.
Using the ODBC API function SQLFreeStmt .

Closing the Recordset after each CommitTrans or Rollback Operation


Before starting a transaction, make sure the recordset object is closed. After calling BeginTrans , call the recordset's
Open member function. Close the recordset immediately after calling CommitTrans or Rollback . Note that
repeatedly opening and closing the recordset can slow an application's performance.

Using SQLFreeStmt
You can also use the ODBC API function SQLFreeStmt to explicitly close the cursor after ending a transaction. To
start another transaction, call BeginTrans followed by CRecordset::Requery . When calling SQLFreeStmt , you must
specify the recordset's HSTMT as the first parameter and SQL_CLOSE as the second parameter. This method is
faster than closing and opening the recordset at the start of every transaction. The following code demonstrates
how to implement this technique:

CMyDatabase db;
db.Open("MYDATASOURCE");
CMyRecordset rs(&db);

// start transaction 1 and


// open the recordset
db.BeginTrans();
rs.Open();

// manipulate data

// end transaction 1
db.CommitTrans(); // or Rollback()

// close the cursor


::SQLFreeStmt(rs.m_hstmt, SQL_CLOSE);

// start transaction 2
db.BeginTrans();
// now get the result set
rs.Requery();

// manipulate data

// end transaction 2
db.CommitTrans();

rs.Close();
db.Close();

Another way to implement this technique is to write a new function, RequeryWithBeginTrans , which you can call to
start the next transaction after you commit or rollback the first one. To write such a function, do the following
steps:
1. Copy the code for CRecordset::Requery( ) to the new function.
2. Add the following line immediately after the call to SQLFreeStmt :
m_pDatabase->BeginTrans( );

Now you can call this function between each pair of transactions:
// start transaction 1 and
// open the recordset
db.BeginTrans();

rs.Open();

// manipulate data

// end transaction 1
db.CommitTrans(); // or Rollback()

// close the cursor, start new transaction,


// and get the result set
rs.RequeryWithBeginTrans();

// manipulate data

// end transaction 2
db.CommitTrans(); // or Rollback()

NOTE
Do not use this technique if you need to change the recordset member variables m_strFilter or m_strSort between
transactions. In that case, you should close the recordset after each CommitTrans or Rollback operation.

See also
Technical Notes by Number
Technical Notes by Category
TN070: MFC Window Class Names
3/27/2020 • 2 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

MFC windows use a dynamically created class name that reflects the features of the window. MFC generates class
names dynamically for frame windows, views, and popup windows produced by the application. Dialog boxes and
controls produced by an MFC application have the Windows-supplied name for the class of window in question.
You can replace the dynamically provided class name by registering your own window class and using it in an
override of PreCreateWindow. Their MFC-supplied class names fit one of the two following forms:

Afx:%x:%x
Afx:%x:%x:%x:%x:%x

The hex digits that replace the %x characters are filled in from data from the WNDCLASS structure. MFC uses this
technique so that multiple C++ classes requiring identical WNDCL ASS structures can share the same registered
window class. Unlike most simple Win32 applications, MFC applications have only one WNDPROC , so you can
easily share WNDCL ASS structures to save time and memory. The replaceable values for the %x characters
shown above are as follows:
WNDCL ASS.hInstance
WNDCL ASS.style
WNDCL ASS.hCursor
WNDCL ASS.hbrBackground
WNDCL ASS.hIcon
The first form ( Afx:%x:%x ) is used when hCursor , hbrBackground , and hIcon are all NULL .

See also
Technical Notes by Number
Technical Notes by Category
TN020: ID Naming and Numbering Conventions
TN071: MFC IOleCommandTarget Implementation
3/16/2020 • 5 minutes to read • Edit Online

NOTE
The following technical note has not been updated since it was first included in the online documentation. As a result, some
procedures and topics might be out of date or incorrect. For the latest information, it is recommended that you search for
the topic of interest in the online documentation index.

The IOleCommandTarget interface enables objects and their containers to dispatch commands to each other. For
example, an object's toolbars may contain buttons for commands such as Print , Print Preview , Save , New , and
Zoom . If such an object were embedded in a container that supports IOleCommandTarget , the object could enable its
buttons and forward the commands to the container for processing when the user clicked them. If a container
wanted the embedded object to print itself, it could make this request by sending a command through the
IOleCommandTarget interface of the embedded object.

IOleCommandTarget is an Automation-like interface in that it is used by a client to invoke methods on a server.


However, using IOleCommandTarget saves the overhead of making calls via Automation interfaces because
programmers don't have to use the typically expensive Invoke method of IDispatch .
In MFC, the IOleCommandTarget interface is used by Active document servers to allow Active document containers
to dispatch commands to the server. The Active document server class, CDocObjectServerItem , uses MFC interface
maps (see TN038: MFC/OLE IUnknown Implementation) to implement the IOleCommandTarget interface.
IOleCommandTarget is also implemented in the COleFrameHook class. COleFrameHook is an undocumented MFC class
that implements the frame window functionality of in-place editing containers. COleFrameHook also uses MFC
interface maps to implement the IOleCommandTarget interface. COleFrameHook 's implementation of
IOleCommandTarget forwards OLE commands to COleDocObjectItem -derived Active document containers. This
allows any MFC Active document container to receive messages from contained Active document servers.

MFC OLE Command Maps


MFC developers can take advantage of IOleCommandTarget by using MFC OLE command maps. OLE command
maps are like message maps because they can be used to map OLE commands to member functions of the class
that contains the command map. To make this work, place macros in the command map to specify the OLE
command group of the command you want to handle, the OLE command, and the command ID of the
WM_COMMAND message that will be sent when the OLE command is received. MFC also provides a number of
predefined macros for standard OLE commands. For a list of the standard OLE commands that were originally
designed for use with Microsoft Office applications, see the OLECMDID enumeration, which is defined in docobj.h.
When an OLE command is received by an MFC application that contains an OLE command map, MFC tries to find
the command ID and command group for the requested command in the OLE command map of the application. If
a match is found, a WM_COMMAND message is dispatched to the application containing the command map with
the ID of the requested command. (See the description of ON_OLECMD below.) In this way, OLE commands
dispatched to an application are turned into WM_COMMAND messages by MFC. The WM_COMMAND messages
are then routed through the application's message maps using the MFC standard command routing architecture.
Unlike message maps, MFC OLE command maps are not supported by ClassWizard. MFC developers must add
OLE command map support and OLE command map entries by hand. OLE command maps can be added to MFC
Active document servers in any class that is in the WM_COMMAND message-routing chain at the time the Active
document is in-place active in a container. These classes include the application's classes derived from CWinApp,
CView, CDocument, and COleIPFrameWnd. In Active document containers, OLE command maps can only be added
to the COleDocObjectItem-derived class. Also, in Active document containers, the WM_COMMAND messages will
only be dispatched to the message map in the COleDocObjectItem -derived class.

OLE Command Map Macros


Use the following macros to add command map functionality to your class:

DECLARE_OLECMD_MAP ()

This macro goes in the class declaration (typically in the header file) of the class that contains the command map.

BEGIN_OLECMD_MAP(theClass, baseClass)

theClass
Name of the class that contains the command map.
baseClass
Name of the base class of the class that contains the command map.
This macro marks the beginning of the command map. Use this macro in the implementation file for the class that
contains the command map.

END_OLECMD_MAP()

This macro marks the end of the command map. Use this macro in the implementation file for the class that
contains the command map. This macro must always follow the BEGIN_OLECMD_MAP macro.

ON_OLECMD(pguid, olecmdid, id)

pguid
Pointer to the GUID of the OLE command's command group. This parameter is NULL for the standard OLE
command group.
olecmdid
OLE command ID of the command to be invoked.
id
ID of the WM_COMMAND message to be sent to the application containing the command map when this OLE
command is invoked.
Use the ON_OLECMD macro in the command map to add entries for the OLE commands you want to handle.
When the OLE commands are received, they will be converted to the specified WM_COMMAND message and
routed through the application's message map using the standard MFC command-routing architecture.

Example
The following example shows how to add OLE command-handling capability to an MFC Active document server to
handle the OLECMDID_PRINT OLE command. This example assumes that you used AppWizard to generate an MFC
application that is an Active document server.
1. In your CView -derived class's header file, add the DECLARE_OLECMD_MAP macro to the class declaration.
NOTE
Use the CView -derived class because it is one of the classes in the Active document server that is in the
WM_COMMAND message-routing chain.

class CMyServerView : public CView


{
protected: // create from serialization only
CMyServerView();
DECLARE_DYNCREATE(CMyServerView)
DECLARE_OLECMD_MAP()
// . . .
};

2. In the implementation file for the CView -derived class, add the BEGIN_OLECMD_MAP and
END_OLECMD_MAP macros:

BEGIN_OLECMD_MAP(CMyServerView, CView)

END_OLECMD_MAP()

3. To handle the standard OLE print command, add an ON_OLECMD macro to the command map specifying
the OLE command ID for the standard print command and ID_FILE_PRINT for the WM_COMMAND ID.
ID_FILE_PRINT is the standard print command ID used by AppWizard-generated MFC applications:

BEGIN_OLECMD_MAP(CMyServerView, CView)
ON_OLECMD(NULL, OLECMDID_PRINT, ID_FILE_PRINT)
END_OLECMD_MAP()

Note that one of the standard OLE command macros, defined in afxdocob.h, could be used in place of the
ON_OLECMD macro because OLECMDID_PRINT is a standard OLE command ID. The ON_OLECMD_PRINT macro
will accomplish the same task as the ON_OLECMD macro shown above.
When a container application sends this server an OLECMDID_PRINT command through the server's
IOleCommandTarget interface, the MFC printing command handler will be invoked in the server, causing the server
to print the application. The Active document container's code to invoke the print command added in the steps
above would look something like this:
void CContainerCntrItem::DoOleCmd()
{
IOleCommandTarget *pCmd = NULL;
HRESULT hr = E_FAIL;
OLECMD ocm={OLECMDID_PRINT, 0};

hr = m_lpObject->QueryInterface(
IID_IOleCommandTarget,reinterpret_cast<void**>(&pCmd));

if (FAILED(hr))
return;

hr = pCmd->QueryStatus(NULL, 1, &ocm, NULL);

if (SUCCEEDED(hr) && (ocm.cmdf& OLECMDF_ENABLED))


{
//Command is available and enabled so call it
COleVariant vIn;
COleVariant vOut;
hr = pCmd->Exec(NULL, OLECMDID_PRINT,
OLECMDEXECOPT_DODEFAULT, &vIn, &vOut);
ASSERT(SUCCEEDED(hr));
}
pCmd->Release();
}

See also
Technical Notes by Number
Technical Notes by Category
Class Library Overview
3/27/2020 • 2 minutes to read • Edit Online

This overview categorizes and describes the classes in the Microsoft Foundation Class Library (MFC)
version 9.0. The classes in MFC, taken together, constitute an application framework — the framework of an
application written for the Windows API. Your programming task is to fill in the code that is specific to your
application.
The library's classes are presented here in the following categories:
Root Class: CObject
MFC Application Architecture Classes
Application and Thread Support Classes
Command Routing Classes
Document Classes
View Classes (Architecture)
Frame Window Classes (Architecture)
Document-Template Classes
Window, Dialog, and Control Classes
Frame Window Classes (Windows)
View Classes (Windows)
Dialog Box Classes
Control Classes
Control Bar Classes
Drawing and Printing Classes
Output (Device Context) Classes
Drawing Tool Classes
Simple Data Type Classes
Array, List, and Map Classes
Template Classes for Arrays, Lists, and Maps
Ready-to-Use Array Classes
Ready-to-Use List Classes
Ready-to-Use Map Classes
File and Database Classes
File I/O Classes
DAO Classes
ODBC Classes
OLE DB Classes
Internet and Networking Classes
Windows Sockets Classes
Win32 Internet Classes
OLE Classes
OLE Container Classes
OLE Server Classes
OLE Drag-and-Drop and Data Transfer Classes
OLE Common Dialog Classes
OLE Automation Classes
OLE Control Classes
Active Document Classes
OLE-Related Classes
Debugging and Exception Classes
Debugging Support Classes
Exception Classes
The section General Class Design Philosophy explains how the MFC Library was designed.
For an overview of the framework, see Using the Classes to Write Applications for Windows. Some of the
classes listed above are general-purpose classes that can be used outside of the framework and provide
useful abstractions such as collections, exceptions, files, and strings.
To see the inheritance of a class, use the Class Hierarchy Chart.
In addition to the classes listed in this overview, the MFC Library contains a number of global functions,
global variables, and macros. There is an overview and detailed listing of these in the topic MFC Macros and
Globals, which follows the alphabetical reference to the MFC classes.

See also
MFC Desktop Applications
General Class Design Philosophy
3/16/2020 • 2 minutes to read • Edit Online

Microsoft Windows was designed long before the C++ language became popular. Because thousands of
applications use the C-language Windows application programming interface (API), that interface will be
maintained for the foreseeable future. Any C++ Windows interface must therefore be built on top of the
procedural C-language API. This guarantees that C++ applications will be able to coexist with C applications.
The Microsoft Foundation Class Library is an object-oriented interface to Windows that meets the following design
goals:
Significant reduction in the effort to write an application for Windows.
Execution speed comparable to that of the C-language API.
Minimum code size overhead.
Ability to call any Windows C function directly.
Easier conversion of existing C applications to C++.
Ability to leverage from the existing base of C-language Windows programming experience.
Easier use of the Windows API with C++ than with C.
Easier to use yet powerful abstractions of complicated features such as ActiveX controls, database support,
printing, toolbars, and status bars.
True Windows API for C++ that effectively uses C++ language features.
For more on the design of the MFC Library, see:
The Application Framework
Relationship to the C-Language API

See also
Class Overview
Application Framework
3/16/2020 • 2 minutes to read • Edit Online

The core of the Microsoft Foundation Class (MFC) Library is an encapsulation of a large portion of the Windows
API in C++ form. Library classes represent windows, dialog boxes, device contexts, common GDI objects such as
brushes and pens, controls, and other standard Windows items. These classes provide a convenient C++ member
function interface to the structures in Windows that they encapsulate. For more about using these classes, see
Window Object Topics.
But the MFC Library also supplies a layer of additional application functionality built on the C++ encapsulation of
the Windows API. This layer is a working application framework for Windows that provides most of the common
user interface expected of programs for Windows, including toolbars, status bars, printing, print preview, database
support, and ActiveX support. Using the Classes to Write Applications for Windows explains the framework in
detail.

See also
General Class Design Philosophy
Relationship to the C-Language API
3/27/2020 • 2 minutes to read • Edit Online

The single characteristic that sets the Microsoft Foundation Class (MFC) Library apart from other class libraries for
Windows is the very close mapping to the Windows API written in the C language. Further, you can generally mix
calls to the class library freely with direct calls to the Windows API. This direct access does not, however, imply that
the classes are a complete replacement for that API. Developers must still occasionally make direct calls to some
Windows functions, such as SetCursor and GetSystemMetrics, for example. A Windows function is wrapped by a
class member function only when there is a clear advantage to doing so.
Because you sometimes need to make native Windows function calls, you should have access to the C-language
Windows API documentation. This documentation is included with Microsoft Visual C++.

NOTE
For an overview of how the MFC Library framework operates, see Using the Classes to Write Applications for Windows.

See also
General Class Design Philosophy
Root Class: CObject
3/16/2020 • 2 minutes to read • Edit Online

Most of the classes in the Microsoft Foundation Class (MFC) Library are derived from a single base class at the root
of the class hierarchy. CObject provides a number of useful capabilities to all classes derived from it, with very low
overhead. For more information about CObject and its capabilities, see Using CObject.
CObject
The ultimate base class of most MFC classes. Supports serializing data and obtaining run-time information about a
class.
CRuntimeClass
Structure used to determine the exact class of an object at run time.

See also
Class Overview
MFC Application Architecture Classes
3/16/2020 • 2 minutes to read • Edit Online

Classes in this category contribute to the architecture of a framework application. They supply functionality
common to most applications. You fill in the framework to add application-specific functionality. Typically, you do
so by deriving new classes from the architecture classes, and then adding new members or overriding existing
member functions.
Application wizards generate several types of applications, all of which use the application framework in differing
ways. SDI (single document interface) and MDI (multiple document interface) applications make full use of a part of
the framework called document/view architecture. Other types of applications, such as dialog-based applications,
form-based applications, and DLLs, use only some of document/view architecture features.
Document/view applications contain one or more sets of documents, views, and frame windows. A document-
template object associates the classes for each document/view/frame set.
Although you do not have to use document/view architecture in your MFC application, there are a number of
advantages to doing so. The MFC OLE container and server support is based on document/view architecture, as is
support for printing and print preview.
All MFC applications have at least two objects: an application object derived from CWinApp, and some sort of main
window object, derived (often indirectly) from CWnd. (Most often, the main window is derived from CFrameWnd,
CMDIFrameWnd, or CDialog, all of which are derived from CWnd .)
Applications that use document/view architecture contain additional objects. The principal objects are:
An application object derived from class CWinApp, as mentioned before.
One or more document class objects derived from class CDocument. Document class objects are
responsible for the internal representation of the data manipulated in the view. They may be associated with
a data file.
One or more view objects derived from class CView. Each view is a window that is attached to a document
and associated with a frame window. Views display and manipulate the data contained in a document class
object.
Document/view applications also contain frame windows (derived from CFrameWnd) and document templates
(derived from CDocTemplate).

See also
Class Overview
Application and Thread Support Classes
3/4/2019 • 2 minutes to read • Edit Online

Each application has one and only one application object; this object coordinates other objects in the running
program and is derived from CWinApp .
The Microsoft Foundation Class (MFC) Library supports multiple threads of execution within an application. All
applications must have at least one thread; the thread used by your CWinApp object is this primary thread.
CWinThread encapsulates a portion of the operating system's threading capabilities. To make using multiple
threads easier, MFC also provides synchronization object classes to provide a C++ interface to Win32
synchronization objects.

Application and Thread Classes


CWinApp
Encapsulates the code to initialize, run, and terminate the application. You will derive your application object from
this class.
CWinThread
The base class for all threads. Use directly, or derive a class from CWinThread if your thread performs user-interface
functions. CWinApp is derived from CWinThread .

Synchronization Object Classes


CSyncObject
Base class of the synchronization object classes.
CCriticalSection
A synchronization class that allows only one thread within a single process to access an object.
CSemaphore
A synchronization class that allows between one and a specified maximum number of simultaneous accesses to an
object.
CMutex
A synchronization class that allows only one thread within any number of processes to access an object.
CEvent
A synchronization class that notifies an application when an event has occurred.
CSingleLock
Used in member functions of thread-safe classes to lock on one synchronization object.
CMultiLock
Used in member functions of thread-safe classes to lock on one or more synchronization objects from an array of
synchronization objects.

Related Classes
CCommandLineInfo
Parses the command line with which your program was started.
CWaitCursor
Puts a wait cursor on the screen. Used during lengthy operations.
CDockState
Handles persistent storage of docking state data for control bars.
CRecentFileList
Maintains the most recently used (MRU) file list.

See also
Class Overview
Command Routing Classes
3/4/2019 • 2 minutes to read • Edit Online

As the user interacts with the application by choosing menus or control-bar buttons with the mouse, the
application sends messages from the affected user-interface object to an appropriate command-target object.
Command-target classes derived from CCmdTarget include CWinApp, CWnd, CDocTemplate, CDocument, CView,
and the classes derived from them. The framework supports automatic command routing so that commands can
be handled by the most appropriate object currently active in the application.
An object of class CCmdUI is passed to your command targets' update command UI (ON_UPDATE_COMMAND_UI)
handlers to allow you to update the state of the user interface for a particular command (for instance, to check or
remove the check from menu items). You call member functions of the CCmdUI object to update the state of the UI
object. This process is the same whether the UI object associated with a particular command is a menu item or a
button or both.
CCmdTarget
Serves as the base class for all classes of objects that can receive and respond to messages.
CCmdUI
Provides a programmatic interface for updating user-interface objects such as menu items or control-bar buttons.
The command target object enables, disables, checks, and/or clears the user-interface object with this object.

See also
Class Overview
Document Classes
3/4/2019 • 2 minutes to read • Edit Online

Document class objects, created by document-template objects, manage the application's data. You will derive a
class for your documents from one of these classes.
Document class objects interact with view objects. View objects represent the client area of a window, display a
document's data, and allow users to interact with it. Documents and views are created by a document-template
object.
CDocument
The base class for application-specific documents. Derive your document class or classes from CDocument .
COleDocument
Used for compound document implementation, as well as basic container support. Serves as a container for
classes derived from CDocItem. This class can be used as the base class for container documents and is the base
class for COleServerDoc .
COleLinkingDoc
A class derived from COleDocument that provides the infrastructure for linking. You should derive the document
classes for your container applications from this class instead of from COleDocument if you want them to support
links to embedded objects.
CRichEditDoc
Maintains the list of OLE client items that are in the rich edit control. Used with CRichEditView and
CRichEditCntrItem.
COleServerDoc
Used as the base class for server-application document classes. COleServerDoc objects provide the bulk of server
support through interactions with COleServerItem objects. Visual editing capability is provided using the class
library's document/view architecture.
CHtmlEditDoc
Provides, with CHtmlEditView, the functionality of the WebBrowser HTML editing platform within the context of the
MFC document-view architecture.

Related Classes
Document class objects can be persistent — in other words, they can write their state to a storage medium and
read it back. MFC provides the CArchive class to facilitate transferring the document's data to a storage medium.
CArchive
Cooperates with a CFile object to implement persistent storage for objects through serialization (see
CObject::Serialize).
Documents can also contain OLE objects. CDocItem is the base class of the server and client items.
CDocItem
Abstract base class of COleClientItem and COleServerItem. Objects of classes derived from CDocItem represent
parts of documents.

See also
Class Overview
View Classes (Architecture)
3/16/2020 • 2 minutes to read • Edit Online

CView and its derived classes are child windows that represent the client area of a frame window. Views show data
and accept input for a document.
A view class is associated with a document class and a frame window class using a document-template object.
CView
The base class for application-specific views of a document's data. Views display data and accept user input to edit
or select the data. Derive your view class(es) from CView .
CScrollView
The base class for views with scrolling capabilities. Derive your view class from CScrollView for automatic
scrolling.

Form and Record Views


Form views are also scrolling views. They are based on a dialog box template.
Record views are derived from form views. In addition to the dialog box template, they also have a connection to a
database.
CFormView
A scroll view whose layout is defined in a dialog box template. Derive a class from CFormView to implement a user
interface based on a dialog box template.
CDaoRecordView
Provides a form view directly connected to a Data Access Object (DAO) recordset object. Like all form views, a
CDaoRecordView is based on a dialog box template. DAO is used with Access databases and is supported through
Office 2013. DAO 3.6 is the final version, and it is considered obsolete.
CHtmlView
Supports a control for Web browsing within an application. The control supports dynamic HTML in MFC.
COLEDBRecordView
Provides MFC OLE DB support for form views.
CRecordView
Provides a form view directly connected to an Open Database Connectivity (ODBC) recordset object. Like all form
views, a CRecordView is based on a dialog box template.

Control Views
Control views display a control as their view.
CCtrlView
The base class for all views associated with Windows controls. The views based on controls are described below.
CEditView
A view that contains a Windows standard edit control (see CEdit). Edit controls support text editing, searching,
replacing, and scrolling capabilities.
CRichEditView
A view that contains a Windows rich edit control (see CRichEditCtrl). In addition to the capabilities of an edit
control, rich edit controls support fonts, colors, paragraph formatting, and embedded OLE objects.
CListView
A view that contains a Windows list control (see CListCtrl). A list control displays icons and strings in a manner
similar to the right pane of File Explorer.
CTreeView
A view that contains a Windows tree control (see CTreeCtrl). A tree control displays icons and strings arranged in a
hierarchy in a manner similar to the left pane of File Explorer.

See also
Class Overview
Frame Window Classes (Architecture)
3/16/2020 • 2 minutes to read • Edit Online

In document/view architecture, frame windows are windows that contain a view window. They also support having
control bars attached to them.
In multiple document interface (MDI) applications, the main window is derived from CMDIFrameWnd . It indirectly
contains the documents' frames, which are CMDIChildWnd objects. The CMDIChildWnd objects, in turn, contain the
documents' views.
In single document interface (SDI) applications, the main window, derived from CFrameWnd , contains the view of the
current document.
CFrameWnd
The base class for an SDI application's main frame window. Also the base class for all other frame window classes.
CMDIFrameWnd
The base class for an MDI application's main frame window.
CMDIChildWnd
The base class for an MDI application's document frame windows.
COleIPFrameWnd
Provides the frame window for a view when a server document is being edited in place.

See also
Class Overview
Document-Template Classes
3/16/2020 • 2 minutes to read • Edit Online

Document-template objects coordinate the creation of document, view, and frame window objects when a new
document or view is created.
CDocTemplate
The base class for document templates. You will never use this class directly; instead, you use one of the other
document-template classes derived from this class.
CMultiDocTemplate
A template for documents in the multiple document interface (MDI). MDI applications can have multiple documents
open at a time.
CSingleDocTemplate
A template for documents in the single document interface (SDI). SDI applications have only one document open at
a time.

Related Class
CCreateContext
A structure passed by a document template to window-creation functions to coordinate the creation of document,
view, and frame-window objects.

See also
Class Overview
Window, Dialog, and Control Classes
3/16/2020 • 2 minutes to read • Edit Online

Class CWnd and its derived classes encapsulate an HWND , a handle to a Windows window. CWnd can be used by
itself or as a base for deriving new classes. The derived classes supplied by the class library represent various kinds
of windows.
CWnd
The base class for all windows. You can use one of the classes derived from CWnd or derive your own classes
directly from it.

See also
Class Overview
Frame Window Classes (Windows)
3/4/2019 • 2 minutes to read • Edit Online

Frame windows are windows that frame an application or a part of an application. Frame windows usually contain
other windows, such as views, tool bars, and status bars. In the case of CMDIFrameWnd , they may contain
CMDIChildWnd objects indirectly.

CFrameWnd
The base class for an SDI application's main frame window. Also the base class for all other frame window classes.
CMDIFrameWnd
The base class for an MDI application's main frame window.
CMDIChildWnd
The base class for an MDI application's document frame windows.
CMiniFrameWnd
A half-height frame window typically seen around floating toolbars.
COleIPFrameWnd
Provides the frame window for a view when a server document is being edited in place.

Related Class
Class CMenu provides an interface through which to access your application's menus. It is useful for manipulating
menus dynamically at run time; for example, when adding or deleting menu items according to context. Although
menus are most often used with frame windows, they can also be used with dialog boxes and other nonchild
windows.
CMenu
Encapsulates an HMENU handle to the application's menu bar and pop-up menus.

See also
Class Overview
View Classes (Windows)
11/21/2019 • 2 minutes to read • Edit Online

CView and its derived classes are child windows that represent the client area of a frame window. Views show data
and accept input for a document.
A view class is associated with a document class and a frame window class using a document-template object.
CView
The base class for application-specific views of a document's data. Views display data and accept user input to edit
or select the data. Derive your view class or classes from CView .
CScrollView
The base class for views with scrolling capabilities. Derive your view class from CScrollView for automatic
scrolling.

Form and Record Views


Form views are also scrolling views. They are based on a dialog box template.
Record views are derived from form views. In addition to the dialog box template, they also have a connection to a
database.
CFormView
A scroll view whose layout is defined in a dialog box template. Derive a class from CFormView to implement a user
interface based on a dialog box template.
CDaoRecordView
Provides a form view directly connected to a Data Access Object (DAO) recordset object. Like all form views, a
CDaoRecordView is based on a dialog box template. DAO is used with Access databases and is supported through
Office 2013. DAO 3.6 is the final version, and it is considered obsolete.
CRecordView
Provides a form view directly connected to an Open Database Connectivity (ODBC) recordset object. Like all form
views, a CRecordView is based on a dialog box template.
CHtmlEditView
A form view that provides the functionality of the WebBrowser HTML editing platform.

Control Views
Control views display a control as their view.
CCtrlView
The base class for all views associated with Windows controls. The views based on controls are described below.
CEditView
A view that contains a Windows standard edit control (see CEdit). Edit controls support text editing, searching,
replacing, and scrolling capabilities.
CRichEditView
A view that contains a Windows rich edit control (see CRichEditCtrl). In addition to the capabilities of an edit
control, rich edit controls support fonts, colors, paragraph formatting, and embedded OLE objects.
CListView
A view that contains a Windows list control (see CListCtrl). A list control displays a collection of items, each
consisting of an icon and a label, in a manner similar to the right pane of File Explorer.
CTreeView
A view that contains a Windows tree control (see CTreeCtrl). A tree control displays a hierarchical list of icons and
labels arranged in a manner similar to the left pane of File Explorer.

Related Classes
CSplitterWnd allows you to have multiple views within a single frame window. CPrintDialog and CPrintInfo
support the print and print preview ability of views. CRichEditDoc and CRichEditCntrItem are used with
CRichEditView to implement OLE container capabilities.

CSplitterWnd
A window that the user can split into multiple panes. These panes can be resizable by the user or fixed size.
CPrintDialog
Provides a standard dialog box for printing a file.
CPrintInfo
A structure containing information about a print or print preview job. Used by CView 's printing architecture.
CRichEditDoc
Maintains the list of OLE client items that are in a CRichEditView .
CRichEditCntrItem
Provides client-side access to an OLE item stored in a CRichEditView .

See also
Class Overview
Dialog Box Classes
3/4/2019 • 3 minutes to read • Edit Online

Class CDialog and its derived classes encapsulate dialog-box functionality. Since a dialog box is a special kind of
window, CDialog is derived from CWnd . Derive your dialog classes from CDialog or use one of the common
dialog classes for standard dialog boxes, such as opening or saving a file, printing, selecting a font or color,
initiating a search-and-replace operation, or performing various OLE-related operations.
CDialog
The base class for all dialog boxes, both modal and modeless.
CDataExchange
Supplies data exchange and validation information for dialog boxes.

Common Dialogs
These dialog box classes encapsulate the Windows common dialog boxes. They provide easy-to-use
implementations of complicated dialog boxes.
CCommonDialog
Base class for all common dialog boxes.
CFileDialog
Provides a standard dialog box for opening or saving a file.
CColorDialog
Provides a standard dialog box for selecting a color.
CFontDialog
Provides a standard dialog box for selecting a font.
CFindReplaceDialog
Provides a standard dialog box for a search-and-replace operation.
CPrintDialog
Provides a standard dialog box for printing a file.
CPrintDialogEx
Provides a Windows Print property sheet.
CPageSetupDialog
Encapsulates the services provided by the Windows common Page Setup dialog box with additional support for
setting and modifying print margins.

OLE Common Dialogs


OLE adds several common dialog boxes to Windows. These classes encapsulate the OLE common dialog boxes.
COleDialog
Used by the framework to contain common implementations for all OLE dialog boxes. All dialog box classes in the
user-interface category are derived from this base class. COleDialog cannot be used directly.
COleInsertDialog
Displays the Insert Object dialog box, the standard user interface for inserting new OLE linked or embedded items.
COlePasteSpecialDialog
Displays the Paste Special dialog box, the standard user interface for implementing the Edit Paste Special
command.
COleLinksDialog
Displays the Edit Links dialog box, the standard user interface for modifying information about linked items.
COleChangeIconDialog
Displays the Change Icon dialog box, the standard user interface for changing the icon associated with an OLE
embedded or linked item.
COleConvertDialog
Displays the Convert dialog box, the standard user interface for converting OLE items from one type to another.
COlePropertiesDialog
Encapsulates the Windows common OLE Properties dialog box. Common OLE Properties dialog boxes provide an
easy way to display and modify the properties of an OLE document item in a manner consistent with Windows
standards.
COleUpdateDialog
Displays the Update dialog box, the standard user interface for updating all links in a document. The dialog box
contains a progress indicator to indicate how close the update procedure is to completion.
COleChangeSourceDialog
Displays the Change Source dialog box, the standard user interface for changing the destination or source of a link.
COleBusyDialog
Displays the Server Busy and Server Not Responding dialog boxes, the standard user interface for handling calls to
busy applications. Usually displayed automatically by the COleMessageFilter implementation.

Property Sheet Classes


The property sheet classes allow your applications to use property sheets, also known as tabbed dialogs. Property
sheets are an efficient way to organize a large number of controls in a single dialog box.
CPropertyPage
Provides the individual pages within a property sheet. Derive a class from CPropertyPage for each page to be
added to your property sheet.
CPropertySheet
Provides the frame for multiple property pages. Derive your property sheet class from CPropertySheet to
implement your property sheets quickly.
COlePropertyPage
Displays the properties of an OLE control in a graphical interface, similar to a dialog box.

HTML-based Dialog Classes


CDHtmlDialog
Used to create dialog boxes that implement their user interface with HTML rather than dialog resources.
CMultiPageDHtmlDialog
Displays multiple HTML pages sequentially and handles the events from each page.

Related Classes
These classes are not dialog boxes per se, but they use dialog box templates and have much of the behavior of
dialog boxes.
CDialogBar
A control bar that is based on a dialog box template.
CFormView
A scroll view whose layout is defined in a dialog box template. Derive a class from CFormView to implement a user
interface based on a dialog box template.
CDaoRecordView
Provides a form view directly connected to a Data Access Object (DAO) recordset object. Like all form views, a
CDaoRecordView is based on a dialog box template.

CRecordView
Provides a form view directly connected to an Open Database Connectivity (ODBC) recordset object. Like all form
views, a CRecordView is based on a dialog box template.
CPrintInfo
A structure containing information about a print or print preview job. Used by the printing architecture of CView.

See also
Class Overview
Control Classes
3/4/2019 • 3 minutes to read • Edit Online

Control classes encapsulate a wide variety of standard Windows controls ranging from static text controls to tree
controls. In addition, MFC provides some new controls, including buttons with bitmaps and control bars.
The controls whose class names end in "Ctrl " were new in Windows 95 and Windows NT version 3.51.

Static Display Controls


CStatic
A static-display window. Static controls are used to label, box, or separate other controls in a dialog box or window.
They may also display graphical images rather than text or a box.

Text Controls
CEdit
An editable-text control window. Edit controls are used to accept textual input from the user.
CIPAddressCtrl
Supports an edit box for manipulating an Internet Protocol (IP) address.
CRichEditCtrl
A control in which the user can enter and edit text. Unlike the control encapsulated in CEdit , a rich edit control
supports character and paragraph formatting and OLE objects.

Controls That Represent Numbers


CSliderCtrl
A control containing a slider, which the user moves to select a value or set of values.
CSpinButtonCtrl
A pair of arrow buttons the user can click to increment or decrement a value.
CProgressCtrl
Displays a rectangle that is gradually filled from left to right to indicate the progress of an operation.
CScrollBar
A scroll-bar control window. The class provides the functionality of a scroll bar, for use as a control in a dialog box
or window, through which the user can specify a position within a range.

Buttons
CButton
A button control window. The class provides a programmatic interface for a push button, check box, or radio
button in a dialog box or window.
CBitmapButton
A button with a bitmap rather than a text caption.

Lists
CListBox
A list-box control window. A list box displays a list of items that the user can view and select.
CDragListBox
Provides the functionality of a Windows list box; allows the user to move list box items, such as filenames and
string literals, within the list box. List boxes with this capability are useful for an item list in an order other than
alphabetical, such as include pathnames or files in a project.
CComboBox
A combo-box control window. A combo box consists of an edit control plus a list box.
CComboBoxEx
Extends the combo box control by providing support for image lists.
CCheckListBox
Displays a list of items with check boxes, which the user can check or clear, next to each item.
CListCtrl
Displays a collection of items, each consisting of an icon and a label, in a manner similar to the right pane of File
Explorer.
CTreeCtrl
Displays a hierarchical list of icons and labels arranged in a manner similar to the left pane of File Explorer.

Toolbars and Status Bars


CToolBarCtrl
Provides the functionality of the Windows toolbar common control. Most MFC programs use CToolBar instead of
this class.
CStatusBarCtrl
A horizontal window, usually divided into panes, in which an application can display status information. Most MFC
programs use CStatusBar instead of this class.

Miscellaneous Controls
CAnimateCtrl
Displays a simple video clip.
CToolTipCtrl
A small pop-up window that displays a single line of text describing the purpose of a tool in an application.
CDateTimeCtrl
Supports either an extended edit control, or a simple calendar interface control, that allows a user to choose a
specific date or time value.
CHeaderCtrl
Displays titles or labels for columns.
CMonthCalCtrl
Supports a simple calendar interface control that allows a user to select a date.
CTabCtrl
A control with tabs on which the user can click, analogous to the dividers in a notebook.
CHotKeyCtrl
Enables the user to create a hot key combination, which the user can press to perform an action quickly.
CLinkCtrl
Renders marked-up text and launches appropriate applications when the user clicks the embedded link.
CHtmlEditCtrl
Provides the functionality of the WebBrowser ActiveX control in an MFC window.

Related Classes
CImageList
Provides the functionality of the Windows image list. Image lists are used with list controls and tree controls. They
can also be used to store and archive a set of same-sized bitmaps.
CCtrlView
The base class for all views associated with Windows controls. The views based on controls are described below.
CEditView
A view that contains a Windows standard edit control.
CRichEditView
A view that contains a Windows rich edit control.
CListView
A view that contains a Windows list control.
CTreeView
A view that contains a Windows tree control.

See also
Class Overview
Control Bar Classes
3/16/2020 • 2 minutes to read • Edit Online

Control bars are attached to a frame window. They contain buttons, status panes, or a dialog template. Free-floating
control bars, also called tool palettes, are implemented by attaching them to a CMiniFrameWnd object.

Framework Control Bars


These control bars are an integral part of the MFC framework. They are easier to use and more powerful than the
Windows control bars because they are integrated with the framework. Most MFC applications use these control
bars rather than the Windows control bars.
CControlBar
The base class for MFC control bars listed in this section. A control bar is a window aligned to the edge of a frame
window. The control bar contains either HWND -based child controls or controls not based on an HWND , such as
toolbar buttons.
CDialogBar
A control bar that is based on a dialog box template.
CReBar
Supports a toolbar that can contain additional child windows in the form of controls.
CToolBar
Toolbar control windows that contain bitmap command buttons not based on an HWND . Most MFC applications use
this class rather than CToolBarCtrl .
CStatusBar
The base class for status-bar control windows. Most MFC applications use this class rather than CStatusBarCtrl .

Windows Control Bars


These control bars are thin wrappers for the corresponding Windows controls. Because they are not integrated
with the framework, they are harder to use than the control bars previously listed. Most MFC applications use the
control bars previously listed.
CRebarCtrl
Implements the internal control of the CRebar object.
CStatusBarCtrl
A horizontal window, usually divided into panes, in which an application can display status information.
CToolBarCtrl
Provides the functionality of the Windows toolbar common control.

Related Classes
CToolTipCtrl
A small pop-up window that displays a single line of text describing the purpose of a tool in an application.
CDockState
Handles persistent storage of docking state data for control bars.
See also
Class Overview
Drawing and Printing Classes
3/16/2020 • 2 minutes to read • Edit Online

In Windows, all graphical output is drawn on a virtual drawing area called a device context (DC). MFC provides
classes to encapsulate the various types of DCs, as well as encapsulations for Windows drawing tools such as
bitmaps, brushes, palettes, and pens.

See also
Class Overview
Output (Device Context) Classes
3/4/2019 • 2 minutes to read • Edit Online

These classes encapsulate the different types of device contexts available in Windows.
Most of the following classes encapsulate a handle to a Windows device context. A device context is a Windows
object that contains information about the drawing attributes of a device such as a display or a printer. All drawing
calls are made through a device-context object. Additional classes derived from CDC encapsulate specialized
device-context functionality, including support for Windows metafiles.
CDC
The base class for device contexts. Used directly for accessing the whole display and for accessing nondisplay
contexts such as printers.
CPaintDC
A display context used in OnPaint member functions of windows. Automatically calls BeginPaint on construction
and EndPaint on destruction.
CClientDC
A display context for client areas of windows. Used, for example, to draw in an immediate response to mouse
events.
CWindowDC
A display context for entire windows, including both the client and nonclient areas.
CMetaFileDC
A device context for Windows metafiles. A Windows metafile contains a sequence of graphics device interface (GDI)
commands that can be replayed to create an image. Calls made to the member functions of a CMetaFileDC are
recorded in a metafile.

Related Classes
CPoint
Holds coordinate (x, y) pairs.
CSize
Holds distance, relative positions, or paired values.
CRect
Holds coordinates of rectangular areas.
CRgn
Encapsulates a GDI region for manipulating an elliptical, polygonal, or irregular area within a window. Used in
conjunction with the clipping member functions in class CDC .
CRectTracker
Displays and handles the user interface for resizing and moving rectangular objects.
CColorDialog
Provides a standard dialog box for selecting a color.
CFontDialog
Provides a standard dialog box for selecting a font.
CPrintDialog
Provides a standard dialog box for printing a file.

See also
Class Overview
Drawing Tool Classes
3/4/2019 • 2 minutes to read • Edit Online

These classes encapsulate drawing tools that are used to draw on a device context.
CGdiObject
The base class for GDI drawing tools.
CBrush
Encapsulates a GDI brush that can be selected as the current brush in a device context. Brushes are used for filling
interiors of objects being drawn.
CPen
Encapsulates a GDI pen that can be selected as the current pen in a device context. Pens are used for drawing the
border lines of objects.
CFont
Encapsulates a GDI font that can be selected as the current font in a device context.
CBitmap
Encapsulates a GDI bitmap, providing an interface for manipulating bitmaps.
CPalette
Encapsulates a GDI color palette for use as an interface between the application and a color output device such as a
display.
CRectTracker
Displays and handles the user interface for resizing and moving rectangular objects.

See also
Class Overview
Simple Data Type Classes
3/27/2020 • 2 minutes to read • Edit Online

The following classes encapsulate drawing coordinates, character strings, and time and date information, allowing
convenient use of C++ syntax. These objects are used widely as parameters to the member functions of Windows
classes in the class library. Because CPoint , CSize , and CRect correspond to the POINT , SIZE , and RECT
structures, respectively, in the Windows SDK, you can use objects of these C++ classes wherever you can use these
C-language structures. The classes provide useful interfaces through their member functions. CStringT provides
very flexible dynamic character strings. CTime , COleDateTime , CTimeSpan , and COleTimeSpan represent time and
date values. For more information about these classes, see the article Date and Time.
The classes that begin with " COle " are encapsulations of data types provided by OLE. These data types can be used
in Windows programs regardless of whether other OLE features are used.
CStringT Class
Holds character strings.
CTime
Holds absolute time and date values.
COleDateTime
Wrapper for the OLE automation type DATE . Represents date and time values.
CTimeSpan
Holds relative time and date values.
COleDateTimeSpan
Holds relative COleDateTime values, such as the difference between two COleDateTime values.
CPoint
Holds coordinate (x, y) pairs.
CSize
Holds distance, relative positions, or paired values.
CRect
Holds coordinates of rectangular areas.
CImageList
Provides the functionality of the Windows image list. Image lists are used with list controls and tree controls. They
can also be used to store and archive a set of same-sized bitmaps.
COleVariant
Wrapper for the OLE automation type VARIANT . Data in VARIANT s can be stored in many formats.
COleCurrency
Wrapper for the OLE automation type CURRENCY , a fixed-point arithmetic type, with 15 digits before the decimal
point and 4 digits after.

NOTE
CRect , CSize , and CPoint are usable in either ATL or MFC applications. In addition, CStringT provides an MFC-
independent CString -like class. For more information on shared utility classes, see Shared Classes.
See also
Class Overview
Array, List, and Map Classes
3/16/2020 • 2 minutes to read • Edit Online

For handling aggregates of data, the class library provides a group of collection classes — arrays, lists, and maps —
that can hold a variety of object and predefined types. The collections are dynamically sized. These classes can be
used in any program, whether written for Windows or not. However, they are most useful for implementing the
data structures that define your document classes in the application framework. You can readily derive specialized
collection classes from these, or you can create them based on the template classes. For more information about
these approaches, see the article Collections. For a list of the template collection classes, see the article Template
Classes for Arrays, Lists, and Maps.
Arrays are one-dimensional data structures that are stored contiguously in memory. They support very fast
random access since the memory address of any given element can be calculated by multiplying the index of the
element by the size of an element and adding the result to the base address of the array. But arrays are very
expensive if you have to insert elements into the array, since the entire array past the element inserted has to be
moved to make room for the element to be inserted. Arrays can grow and shrink as necessary.
Lists are similar to arrays but are stored very differently. Each element in a list also includes a pointer to the
previous and next elements, making it a doubly linked list. It is very fast to add or delete items because doing so
only involves changing a few pointers. However, searching a list can be expensive since all searches need to start at
one of the list's ends.
Maps relate a key value to a data value. For instance, the key of a map could be a string and the data a pointer into
a list. You would ask the map to give you the pointer associated with a particular string. Map lookups are fast
because maps use hash tables for key lookups. Adding and deleting items is also fast. Maps are often used with
other data structures as auxiliary indices. MFC uses a special kind of map called a message map to map Windows
messages to a pointer to the handler function for that message.

See also
Class Overview
Template Classes for Arrays, Lists, and Maps
3/4/2019 • 2 minutes to read • Edit Online

These collection classes are templates whose parameters determine the types of the objects stored in the
aggregates. The CArray , CMap , and CList classes use global helper functions that must usually be customized.
For more information about these helper functions, see Collection Class Helpers. The typed pointer classes are
wrappers for other classes in the class library. By using these wrappers, you enlist the compiler's type-checking to
help you avoid errors. For more information on using these classes, see Collections.
These classes provide templates you can use to create arrays, lists, and maps using any type you like.
CArray
Template class for making arrays of arbitrary types.
CList
Template class for making lists of arbitrary types.
CMap
Template class for making maps with arbitrary key and value types.
CTypedPtrArray
Template class for type-safe arrays of pointers.
CTypedPtrList
Template class for type-safe lists of pointers.
CTypedPtrMap
Template class for type-safe maps with pointers.

See also
Class Overview
Ready-to-Use Array Classes
3/4/2019 • 2 minutes to read • Edit Online

The following classes are ready-to-use array classes.


CByteArray
Stores elements of type BYTE in an array.
CDWordArray
Stores elements of type DWORD in an array.
CObArray
Stores pointers to objects of class CObject or to objects of classes derived from CObject in an array.
CPtrArray
Stores pointers to void (generic pointers) in an array.
CUIntArray
Stores elements of type UINT in an array.
CWordArray
Stores elements of type WORD in an array.
CStringArray
Stores CString objects in an array.

See also
Class Overview
Ready-to-Use List Classes
3/4/2019 • 2 minutes to read • Edit Online

The following classes are ready-to-use list classes.


CObList
Stores pointers to objects of class CObject or to objects of classes derived from CObject in a linked list.
CPtrList
Stores pointers to void (generic pointers) in a linked list.
CStringList
Stores CString objects in a linked list.

See also
Class Overview
Ready-to-Use Map Classes
3/4/2019 • 2 minutes to read • Edit Online

The following classes are ready-to-use map classes.


CMapPtrToPtr
Uses void pointers as keys for finding other void pointers.
CMapPtrToWord
Uses void pointers as keys for finding data of type WORD .
CMapStringToOb
Uses CString objects as keys for finding CObject pointers.
CMapStringToPtr
Uses CString objects as keys for finding void pointers.
CMapStringToString
Uses CString objects as keys for finding other CString objects.
CMapWordToOb
Uses data of type WORD to find CObject pointers.
CMapWordToPtr
Uses data of type WORD to find void pointers.

See also
Class Overview
File and Database Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes allow you to store information to a database or a disk file. There are three sets of database classes —
OLE DB, ODBC, and DAO — that provide similar functionality. The OLE DB group is implemented using OLE DB and
works with the OLE DB consumer templates, the DAO group is implemented using the Data Access Object, and the
ODBC group is implemented using Open Database Connectivity. There are also a set of classes for manipulating
standard files, Active streams, and HTML streams.
The following categories of classes support data persistence.
File I/O Classes
OLE DB Classes
DAO Classes
ODBC Classes

See also
Class Overview
File I/O Classes
3/4/2019 • 2 minutes to read • Edit Online

These classes provide an interface to traditional disk files, in-memory files, Active streams, and Windows sockets.
All of the classes derived from CFile can be used with a CArchive object to perform serialization.
Use the following classes, particularly CArchive and CFile , if you write your own input/output processing.
Normally you do not need to derive from these classes. If you use the application framework, the default
implementations of the Open and Save commands on the File menu will handle file I/O (using class CArchive ),
as long as you override your document's Serialize function to supply details about how a document serializes its
contents. For more information about the file classes and serialization, see the article Files in MFC and the article
Serialization.
CFile
Provides a file interface to binary disk files.
CStdioFile
Provides a CFile interface to buffered stream disk files, usually in text mode.
CMemFile
Provides a CFile interface to in-memory files.
CSharedFile
Provides a CFile interface to shared in-memory files.
COleStreamFile
Uses the COM IStream interface to provide CFile access to compound files.
CSocketFile
Provides a CFile interface to a Windows Socket.

Related Classes
CArchive
Cooperates with a CFile object to implement persistent storage for objects through serialization (see
CObject::Serialize).
CArchiveException
An archive exception.
CFileException
A file-oriented exception.
CFileDialog
Provides a standard dialog box for opening or saving a file.
CRecentFileList
Maintains the most recently used (MRU) file list.

See also
Class Overview
OLE DB Classes
3/16/2020 • 2 minutes to read • Edit Online

The OLE DB support in MFC currently consists of the class COLEDBRecordView. COleDBRecordView displays
database records in controls, through a form view directly connected to a CRowset object. For more information
about the OLE DB consumer templates, see List of OLE DB Consumer Templates.

See also
Class Overview
DAO Classes
3/27/2020 • 2 minutes to read • Edit Online

DAO is used with Access databases and is supported through Office 2013. DAO 3.6 is the final version, and it is
considered obsolete.
These classes work with the other application framework classes to give easy access to Data Access Object (DAO)
databases, which use the same database engine as Microsoft Visual Basic and Microsoft Access. The DAO classes
can also access a wide variety of databases for which Open Database Connectivity (ODBC) drivers are available.
Programs that use DAO databases will have at least a CDaoDatabase object and a CDaoRecordset object.

NOTE
The Visual C++ environment and wizards no longer 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.

CDaoWorkspace
Manages a named, password-protected database session from login to logoff. Most programs use the default
workspace.
CDaoDatabase
A connection to a database through which you can operate on the data.
CDaoRecordset
Represents a set of records selected from a data source.
CDaoRecordView
A view that displays database records in controls.
CDaoQueryDef
Represents a query definition, usually one saved in a database.
CDaoTableDef
Represents the stored definition of a base table or an attached table.
CDaoException
Represents an exception condition arising from the DAO classes.
CDaoFieldExchange
Supports the DAO record field exchange (DFX) routines used by the DAO database classes. You will normally not
directly use this class.

Related Classes
CLongBinary
Encapsulates a handle to storage for a binary large object (BLOB), such as a bitmap. CLongBinary objects are used
to manage large data objects stored in database tables.
COleCurrency
Wrapper for the OLE automation type CURRENCY , a fixed-point arithmetic type, with 15 digits before the decimal
point and 4 digits after.
COleDateTime
Wrapper for the OLE automation type DATE . Represents date and time values.
COleVariant
Wrapper for the OLE automation type VARIANT . Data in VARIANT s can be stored in many formats.

See also
Class Overview
ODBC Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes work with the other application framework classes to give easy access to a wide variety of databases
for which Open Database Connectivity (ODBC) drivers are available.
Programs that use ODBC databases will have at least a CDatabase object and a CRecordset object.
CDatabase
Encapsulates a connection to a data source, through which you can operate on the data source.
CRecordset
Encapsulates a set of records selected from a data source. Recordsets enable scrolling from record to record,
updating records (adding, editing, and deleting records), qualifying the selection with a filter, sorting the selection,
and parameterizing the selection with information obtained or calculated at run time.
CRecordView
Provides a form view directly connected to a recordset object. The dialog data exchange (DDX) mechanism
exchanges data between the recordset and the controls of the record view. Like all form views, a record view is
based on a dialog template resource. Record views also support moving from record to record in the recordset,
updating records, and closing the associated recordset when the record view closes.
CDBException
An exception resulting from failures in data access processing. This class serves the same purpose as other
exception classes in the exception-handling mechanism of the class library.
CFieldExchange
Supplies context information to support record field exchange (RFX), which exchanges data between the field data
members and parameter data members of a recordset object and the corresponding table columns on the data
source. Analogous to class CDataExchange, which is used similarly for dialog data exchange (DDX).

Related Classes
CLongBinary
Encapsulates a handle to storage for a binary large object (BLOB), such as a bitmap. CLongBinary objects are used
to manage large data objects stored in database tables.
CDBVariant
Allows you to store a value without worrying about the value's data type. CDBVariant tracks the data type of the
current value, which is stored in a union.

See also
Class Overview
Internet and Networking Classes
3/4/2019 • 2 minutes to read • Edit Online

These classes allow you to exchange information with another computer using a Windows Socket or Win32
Internet (WinInet). There are also a set of classes for manipulating Windows Sockets.
The following categories of classes support connectivity.
Windows Sockets Classes
Win32 Internet Classes

See also
Class Overview
Windows Sockets Classes
3/16/2020 • 2 minutes to read • Edit Online

Windows Sockets provide a network protocol-independent way to communicate between two computers. These
sockets can be synchronous (your program waits until the communication is done) or asynchronous (your
program continues running while the communication is going on).
CAsyncSocket
Encapsulates the Windows Sockets API in a thin wrapper.
CSocket
Higher level abstraction derived from CAsyncSocket . It operates synchronously.
CSocketFile
Provides a CFile interface to a Windows Socket.

See also
Class Overview
Win32 Internet Classes
3/4/2019 • 2 minutes to read • Edit Online

MFC wraps the Win32 Internet (WinInet) and ActiveX technology to make Internet programming easier.

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.

CInternetSession
Creates and initializes one Internet session or several simultaneous Internet sessions and, if necessary, describes
the connection to a proxy server.
CInternetConnection
Manages your connection to an Internet server.
CInternetFile
This class and its derived classes allow access to files on remote systems that use Internet protocols.
CHttpConnection
Manages your connection to an HTTP server.
CHttpFile
Provides the functionality to find and read files on an HTTP server.
CGopherFile
Provides the functionality to find and read files on a gopher server.
CFtpConnection
Manages your connection to an FTP server.
CGopherConnection
Manages your connection to a gopher server.
CFileFind
Performs local and Internet file searches.
CFtpFileFind
Aids in Internet file searches of FTP servers.
CGopherFileFind
Aids in Internet file searches of gopher servers.
CGopherLocator
Gets a gopher "locator" from a gopher server, determines the locator's type, and makes the locator available to
CGopherFileFind .

CInternetException
Represents an exception condition related to an Internet operation.

See also
Class Overview
OLE Classes
3/4/2019 • 2 minutes to read • Edit Online

The OLE classes work with the other application framework classes to provide easy access to the ActiveX API, giving
your programs an easy way to provide the power of ActiveX to your users. Using ActiveX, you can:
Create compound documents, which allow users to create and edit documents containing data created by
multiple applications, including text, graphics, spreadsheets, sound, or other types of data.
Create OLE objects that can be embedded in compound documents.
Use OLE drag and drop to copy data between applications.
Use Automation to control one program with another.
Create ActiveX controls and ActiveX control containers (formerly called OLE controls and OLE control
containers, respectively).
The following categories of classes support ActiveX:
OLE Container Classes
OLE Server Classes
OLE Drag-and-Drop and Data Transfer Classes
OLE Common Dialog Classes
OLE Automation Classes
OLE Control Classes
Active Document Classes
OLE-Related Classes
To see the inheritance of a class, use the Class Hierarchy Chart.

See also
Class Overview
OLE Container Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes are used by container applications. Both COleLinkingDoc and COleDocument manage collections of
COleClientItem objects. Rather than deriving your document class from CDocument , you'll derive it from
COleLinkingDoc or COleDocument , depending on whether you want support for links to objects embedded in your
document.
Use a COleClientItem object to represent each OLE item in your document that is embedded from another
document or is a link to another document.
COleDocObjectItem
Supports active document containment.
COleDocument
Used for compound document implementation, as well as basic container support. Serves as a container for
classes derived from CDocItem . This class can be used as the base class for container documents and is the base
class for COleServerDoc .
COleLinkingDoc
A class derived from COleDocument that provides the infrastructure for linking. You should derive the document
classes for your container applications from this class instead of from COleDocument if you want them to support
links to embedded objects.
CRichEditDoc
Maintains the list of OLE client items that are in the rich edit control. Used with CRichEditView and
CRichEditCntrItem.
CDocItem
Abstract base class of COleClientItem and COleServerItem . Objects of classes derived from CDocItem represent
parts of documents.
COleClientItem
A client item class that represents the client's side of the connection to an embedded or linked OLE item. Derive
your client items from this class.
CRichEditCntrItem
Provides client-side access to an OLE item stored in a rich edit control when used with CRichEditView and
CRichEditDoc .

COleException
An exception resulting from a failure in OLE processing. This class is used by both containers and servers.

See also
Class Overview
OLE Server Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes are used by server applications. Server documents are derived from COleServerDoc rather than from
CDocument . Note that because COleServerDoc is derived from COleLinkingDoc , server documents can also be
containers that support linking.
The COleServerItem class represents a document or portion of a document that can be embedded in another
document or linked to.
COleIPFrameWnd and COleResizeBar support in-place editing while the object is in a container, and
COleTemplateServer supports creation of document/view pairs so OLE objects from other applications can be
edited.
COleServerDoc
Used as the base class for server-application document classes. COleServerDoc objects provide the bulk of server
support through interactions with COleServerItem objects. Visual editing capability is provided using the class
library's document/view architecture.
CDocItem
Abstract base class of COleClientItem and COleServerItem . Objects of classes derived from CDocItem represent
parts of documents.
COleServerItem
Used to represent the OLE interface to COleServerDoc items. There is usually one COleServerDoc object, which
represents the embedded part of a document. In servers that support links to parts of documents, there can be
many COleServerItem objects, each of which represents a link to a portion of the document.
COleIPFrameWnd
Provides the frame window for a view when a server document is being edited in place.
COleResizeBar
Provides the standard user interface for in-place resizing. Objects of this class are always used in conjunction with
COleIPFrameWnd objects.

COleTemplateServer
Used to create documents using the framework's document/view architecture. A COleTemplateServer object
delegates most of its work to an associated CDocTemplate object.
COleException
An exception resulting from a failure in OLE processing. This class is used by both containers and servers.

See also
Class Overview
OLE Drag-and-Drop and Data Transfer Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes are used in OLE data transfers. They allow data to be transferred between applications by using the
Clipboard or through drag and drop.
COleDropSource
Controls the drag-and-drop operation from start to finish. This class determines when the drag operation starts
and when it ends. It also displays cursor feedback during the drag-and-drop operation.
COleDataSource
Used when an application provides data for a data transfer. COleDataSource could be viewed as an object-oriented
Clipboard object.
COleDropTarget
Represents the target of a drag-and-drop operation. A COleDropTarget object corresponds to a window on screen.
It determines whether to accept any data dropped onto it and implements the actual drop operation.
COleDataObject
Used as the receiver side to COleDataSource . COleDataObject objects provide access to the data stored by a
COleDataSource object.

See also
Class Overview
OLE Common Dialog Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes handle common OLE tasks by implementing a number of standard OLE dialog boxes. They also
provide a consistent user interface for OLE functionality.
COleDialog
Used by the framework to contain common implementations for all OLE dialog boxes. All dialog box classes in the
user-interface category are derived from this base class. COleDialog cannot be used directly.
COleInsertDialog
Displays the Insert Object dialog box, the standard user interface for inserting new OLE linked or embedded items.
COlePasteSpecialDialog
Displays the Paste Special dialog box, the standard user interface for implementing the Edit Paste Special
command.
COleLinksDialog
Displays the Edit Links dialog box, the standard user interface for modifying information about linked items.
COleChangeIconDialog
Displays the Change Icon dialog box, the standard user interface for changing the icon associated with an OLE
embedded or linked item.
COleConvertDialog
Displays the Convert dialog box, the standard user interface for converting OLE items from one type to another.
COlePropertiesDialog
Encapsulates the Windows common OLE Properties dialog box. Common OLE Properties dialog boxes provide an
easy way to display and modify the properties of an OLE document item in a manner consistent with Windows
standards.
COleUpdateDialog
Displays the Update dialog box, the standard user interface for updating all links in a document. The dialog box
contains a progress indicator to indicate how close the update procedure is to completion.
COleChangeSourceDialog
Displays the Change Source dialog box, the standard user interface for changing the destination or source of a link.
COleBusyDialog
Displays the Server Busy and Server Not Responding dialog boxes, the standard user interface for handling calls to
busy applications. Usually displayed automatically by the COleMessageFilter implementation.

See also
Class Overview
OLE Automation Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes support automation clients (applications that control other applications). Automation servers
(applications that can be controlled by other applications) are supported through dispatch maps.
COleDispatchDriver
Used to call automation servers from your automation client. When adding a class, this class is used to create type-
safe classes for automation servers that provide a type library.
COleDispatchException
An exception resulting from an error during OLE automation. Automation exceptions are thrown by automation
servers and caught by automation clients.

See also
Class Overview
OLE Control Classes
3/16/2020 • 2 minutes to read • Edit Online

These are the primary classes you use when writing OLE controls. The COleControlModule class in an OLE control
module is like the CWinApp class in an application. Each module implements one or more OLE controls; these
controls are represented by COleControl objects. These controls communicate with their containers using
CConnectionPoint objects.

The CPictureHolder and CFontHolder classes encapsulate COM interfaces for pictures and fonts, while the
COlePropertyPage and CPropExchange classes help you implement property pages and property persistence for
your control.
COleControlModule
Replaces the CWinApp class for your OLE control module. Derive from the COleControlModule class to develop an
OLE control module object. It provides member functions for initializing your OLE control's module.
COleControl
Derive from the COleControl class to develop an OLE control. Derived from CWnd , this class inherits all the
functionality of a Windows window object plus additional OLE-specific functionality, such as event firing and the
ability to support methods and properties.
CConnectionPoint
The CConnectionPoint class defines a special type of interface used to communicate with other OLE objects, called
a connection point. A connection point implements an outgoing interface that is able to initiate actions on other
objects, such as firing events and change notifications.
CPictureHolder
Encapsulates the functionality of a Windows picture object and the IPicture COM interface; used to implement
the custom Picture property of an OLE control.
CFontHolder
Encapsulates the functionality of a Windows font object and the IFont COM interface; used to implement the
stock Font property of an OLE control.
COlePropertyPage
Displays the properties of an OLE control in a graphical interface, similar to a dialog box.
CPropExchange
Supports the implementation of property persistence for your OLE controls. Analogous to CDataExchange for
dialog boxes.
CMonikerFile
Takes a moniker, or a string representation that it can make into a moniker, and binds it synchronously to the
stream for which the moniker is a name.
CAsyncMonikerFile
Works similarly to CMonikerFile ; however, it binds the moniker asynchronously to the stream for which the
moniker is a name.
CDataPathProperty
Implements an OLE control property that can be loaded asynchronously.
CCachedDataPathProperty
Implements an OLE control property transferred asynchronously and cached in a memory file.
COleCmdUI
Allows an Active document to receive commands that originate in its container's user interface (such as FileNew,
Open, Print, and so on), and allows a container to receive commands that originate in the Active document's user
interface.
COleSafeArray
Works with arrays of arbitrary type and dimension.

See also
Class Overview
Active Document Classes
3/16/2020 • 2 minutes to read • Edit Online

Active documents can be displayed either in the entire client window of a Web browser, such as Internet Explorer
5.5, or in an Active container, such as the Microsoft Office Binder, that supports Active documents.
CDocObjectServer
Maps the Active document interfaces, and initializes and activates an Active document object.
CDocObjectServerItem
Implements OLE server verbs specifically for Active document servers.
COleDocObjectItem
Implements Active document containment.

See also
Class Overview
OLE-Related Classes
3/16/2020 • 2 minutes to read • Edit Online

These classes provide a number of different services, ranging from exceptions to file input and output.
COleObjectFactory
Used to create items when requested from other containers. This class serves as the base class for more specific
types of factories, including COleTemplateServer .
COleMessageFilter
Used to manage concurrency with OLE Lightweight Remote Procedure Calls (LRPC).
COleStreamFile
Uses the COM IStream interface to provide CFile access to compound files. This class (derived from CFile )
enables MFC serialization to use OLE structured storage.
CRectTracker
Used to allow moving, resizing, and reorientation of in-place items.

See also
Class Overview
Debugging and Exception Classes
3/4/2019 • 2 minutes to read • Edit Online

These classes provide support for debugging dynamic memory allocation and for passing exception information
from the function where the exception is thrown to the function where it is caught.
Use classes CDumpContext and CMemoryState during development to assist with debugging, as described in
Debugging MFC Applications. Use CRuntimeClass to determine the class of any object at run time, as described in
the article Accessing Run-Time Class Information. The framework uses CRuntimeClass to create objects of a
particular class dynamically.

See also
Class Overview
Debugging Support Classes
3/16/2020 • 2 minutes to read • Edit Online

MFC provides the following classes to help you debug dynamic memory allocation problems.
CDumpContext
Provides a destination for diagnostic dumps.
CMemoryState
Structure that provides snapshots of memory use. Also used to compare earlier and later memory snapshots.

See also
Class Overview
Exception Classes
3/4/2019 • 2 minutes to read • Edit Online

The class library provides an exception-handling mechanism based on class CException . The application
framework uses exceptions in its code; you can also use them in yours. For more information, see the article
Exceptions. You can derive your own exception types from CException .
MFC provides an exception class from which you can derive your own exception as well as exception classes for all
of the exceptions it supports.
CException
The base class for exceptions.
CArchiveException
An archive exception.
CDaoException
An exception resulting from a failure in a DAO database operation.
CDBException
An exception resulting from a failure in ODBC database processing.
CFileException
A file-oriented exception.
CMemoryException
An out-of-memory exception.
CNotSupportedException
An exception resulting from using an unsupported feature.
COleException
An exception resulting from a failure in OLE processing. This class is used by both containers and servers.
COleDispatchException
An exception resulting from an error during automation. Automation exceptions are thrown by automation servers
and caught by automation clients.
CResourceException
An exception resulting from a failure to load a Windows resource.
CUserException
An exception used to stop a user-initiated operation. Typically, the user has been notified of the problem before this
exception is thrown.

See also
Class Overview
Walkthroughs (MFC)
3/4/2019 • 2 minutes to read • Edit Online

This section contains articles that walk you through various tasks associated with new MFC library features.

In This Section
Walkthrough: Using the New MFC Shell Controls
In this walkthrough, you'll create an application that resembles File Explorer. You'll create a window that contains
two panes. The left pane has a CMFCShellTreeCtrl object that will display your Desktop in a hierarchical view. The
right pane has a CMFCShellListCtrl that will show the files in the folder that is selected in the left pane.
Walkthrough: Putting Controls On Toolbars
Modern MFC toolbars can host controls other than simple buttons. This article explains how to do it.
Walkthrough: Adding a D2D Object to an MFC Project
Demonstrates how to add a D2D object to a project and introduces how to use D2D.
Walkthrough: Adding Animation to an MFC Project
Demonstrates how to add a graphical object to a project and introduces how to animate it.

See also
MFC Desktop Applications
Walkthrough: Using the New MFC Shell Controls
4/9/2020 • 7 minutes to read • Edit Online

In this walkthrough, you'll create an application that resembles File Explorer. You'll create a window that has two
panes. The left pane will hold a CMFCShellTreeCtrl object that displays your Desktop in a hierarchical view. The
right pane will hold a CMFCShellListCtrl that shows the files in the folder that is selected in the left pane.

Prerequisites
In Visual Studio 2017 and later, MFC support is an optional component. To install it, open the Visual Studio
Installer from the Windows Start menu. Find the version of Visual Studio you are using and choose the
Modify button. Make sure the Desktop Development with C++ tile is checked. Under Optional
Components , check the MFC Suppor t button.
This walkthrough assumes that you have set up Visual Studio to use General Development Settings . If
you're using a different development setting, some Visual Studio windows that we use in this walkthrough
might not be displayed by default.

To create a new MFC application by using the MFC Application Wizard


These steps vary depending on which version of Visual Studio you are using. To see the documentation for your
preferred version of Visual Studio, use the Version selector control. It's found at the top of the table of contents on
this page.
To create an MFC project in Visual Studio 2019
1. From the main menu, choose File > New > Project to open the Create a New Project dialog box.
2. In the search box at the top, type MFC and then choose MFC App from the results list.
3. Click Next . In the next page, enter a name for the project, and specify the project location if desired.
4. Choose the Create button to create the project.
After MFC Application Wizard displays, use the following options:
a. Choose Application Type on the left. Then select Single document and select Document/View
architecture suppor t . Under Project style , select Visual Studio , and from the Visual style and
colors drop down list select Office 2007 (Blue theme) .
b. On the Compound Document Suppor t pane, select None .
c. Don't make any changes to the Document Template Proper ties pane.
d. On the User Interface Features pane, make sure the Use a menu bar and toolbar option is
selected. Leave all other options as they are.
e. On the Advanced Features pane, select ActiveX controls , Common Control Manifest , and
Navigation pane option. Leave everything else as it is. The Navigation Pane option will cause the
wizard to create the pane to the left of the window with a CMFCShellTreeCtrl already embedded.
f. We aren't going to make any changes to the Generated Classes pane, so click Finish to create
your new MFC project.
To create an MFC project in Visual Studio 2017 or earlier
1. Use the MFC Application Wizard to create a new MFC application. To run the wizard, from the File menu
select New , and then select Project . The New Project dialog box will be displayed.
2. In the New Project dialog box, expand the Visual C++ node in the Project types pane and select MFC .
Then, in the Templates pane, select MFC Application . Type a name for the project, such as
MFCShellControls and click OK .

After MFC Application Wizard displays, use the following options:


a. On the Application Type pane, under Application type , clear the Tabbed documents option.
Next, select Single document and select Document/View architecture suppor t . Under Project
style , select Visual Studio , and from the Visual style and colors drop down list select Office
2007 (Blue theme) .
b. On the Compound Document Suppor t pane, select None .
c. Don't make any changes to the Document Template Strings pane.
d. On the Database Suppor t pane (Visual Studio 2015 and older), select None because the
application doesn't use a database.
e. On the User Interface Features pane, make sure the Use a menu bar and toolbar option is
selected. Leave all other options as they are.
f. On the Advanced Features pane, under Advanced features , select only ActiveX controls and
Common Control Manifest . Under Advanced frame panes , select only the Navigation pane
option. It will cause the wizard to create the pane to the left of the window with a CMFCShellTreeCtrl
already embedded.
g. We aren't going to make any changes to the Generated Classes pane, so click Finish to create
your new MFC project.
Verify that the application was created successfully by building and running it. To build the application, from the
Build menu select Build Solution . If the application builds successfully, run the application by selecting Star t
Debugging from the Debug menu.
The wizard automatically creates an application that has a standard menu bar, a standard toolbar, a standard status
bar, and an Outlook bar to the left of the window with a Folders view and a Calendar view.
To add the shell list control to the document view
1. In this section, you'll add an instance of CMFCShellListCtrl to the view that the wizard created. Open the
view header file by double-clicking MFCShellControlsView.h in the Solution Explorer .
Locate the #pragma once directive near the top of the header file. Immediately underneath it add this code
to include the header file for CMFCShellListCtrl :

#include <afxShellListCtrl.h>

Now add a member variable of type CMFCShellListCtrl . First, locate the following comment in the header
file:

// Generated message map functions

Immediately above that comment, add this code:


private:
CMFCShellListCtrl m_wndList;

2. The MFC Application Wizard already created a CMFCShellTreeCtrl object in the CMainFrame class, but it's
a protected member. We'll access the object later, so create an accessor for it now. Open the MainFrm.h
header file by double-clicking it in the Solution Explorer . Locate the following comment:

// Attributes

Immediately under it, add the following method declaration:

public:
CMFCShellTreeCtrl& GetShellTreeCtrl();

Next, open the MainFrm.cpp source file by double-clicking it in the Solution Explorer . At the bottom of
that file, add the following method definition:

CMFCShellTreeCtrl& CMainFrame::GetShellTreeCtrl()
{
return m_wndTree;
}

3. Now we update the CMFCShellControlsView class to handle the WM_CREATE windows message. Open the
Class View window and select the CMFCShellControlsView class. Right-click and select Proper ties .
Next, in Class Wizard, click the Messages tab. Scroll down until you find the WM_CREATE message. From the
drop-down list next to WM_CREATE , select <Add> OnCreate . The command creates a message handler for
us and automatically updates the MFC message map.
In the OnCreate method, we'll now create our CMFCShellListCtrl object. Find the OnCreate method
definition in the MFCShellControlsView.cpp source file, and replace its implementation with the following
code:

int CMFCShellControlsView::OnCreate(LPCREATESTRUCT lpCreateStruct)


{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

CRect rectDummy (0, 0, 0, 0);

m_wndList.Create(WS_CHILD | WS_VISIBLE | LVS_REPORT,


rectDummy, this, 1);

return 0;
}

4. Repeat the previous step but for the WM_SIZE message. It will cause your applications view to be redrawn
whenever a user changes the size of the application window. Replace the definition for the OnSize method
with the following code:
void CMFCShellControlsView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

m_wndList.SetWindowPos(NULL, -1, -1, cx, cy,


SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}

5. The last step is to connect the CMFCShellTreeCtrl and CMFCShellListCtrl objects by using the
CMFCShellTreeCtrl::SetRelatedList method. After you call CMFCShellTreeCtrl::SetRelatedList , the
CMFCShellListCtrl will automatically display the contents of the item selected in the CMFCShellTreeCtrl .
We connect the objects in the OnActivateView method, which is overridden from CView::OnActivateView.
In the MFCShellControlsView.h header file, inside the CMFCShellControlsView class declaration, add the
following method declaration:

protected:
virtual void OnActivateView(BOOL bActivate,
CView* pActivateView,
CView* pDeactiveView);

Next, add the definition for the method to the MFCShellControlsView.cpp source file:

void CMFCShellControlsView::OnActivateView(BOOL bActivate,


CView* pActivateView,
CView* pDeactiveView)
{
if (bActivate&& AfxGetMainWnd() != NULL)
{
((CMainFrame*)AfxGetMainWnd())->GetShellTreeCtrl().SetRelatedList(&m_wndList);
}

CView::OnActivateView(bActivate,
pActivateView,
pDeactiveView);
}

Because we're calling methods from the CMainFrame class, we must add an #include directive at the top of
the MFCShellControlsView.cpp source file:

#include "MainFrm.h"

6. Verify that the application was created successfully by building and running it. To build the application, from
the Build menu select Build Solution . If the application builds successfully, run it by selecting Star t
Debugging from the Debug menu.
You should now see the details for the item selected in the CMFCShellTreeCtrl in the view pane. When you
click a node in the CMFCShellTreeCtrl , the CMFCShellListCtrl will be automatically updated. Likewise, if you
double-click a folder in the CMFCShellListCtrl , the CMFCShellTreeCtrl should be automatically updated.
Right-click any item in the tree control or in the list control. You get the same context menu as if you were
using the real File Explorer .

Next steps
The wizard created an Outlook bar with both a Folders pane and a Calendar pane. It probably doesn't
make sense to have a Calendar pane in an Explorer window, so remove that pane now.
The CMFCShellListCtrl supports viewing files in different modes, such as Large Icons , Small Icons , List ,
and Details . Update your application to implement this functionality. Hint: see Visual C++ Samples.

See also
Walkthroughs
Walkthrough: Putting Controls On Toolbars
3/27/2020 • 4 minutes to read • Edit Online

This article describes how to add a toolbar button that contains a Windows control to a toolbar. In MFC, a toolbar
button must be a CMFCToolBarButton Class-derived class, for example CMFCToolBarComboBoxButton Class,
CMFCToolBarEditBoxButton Class, CMFCDropDownToolbarButton Class, or CMFCToolBarMenuButton Class.

Adding Controls to Toolbars


To add a control to a toolbar, follow these steps:
1. Reserve a dummy resource ID for the button in the parent toolbar resource. For more information about
how to create buttons by using the Toolbar Editor in Visual Studio, see the Toolbar Editor article.
2. Reserve a toolbar image (button icon) for the button in all bitmaps of the parent toolbar.
3. In the message handler that processes the AFX_WM_RESETTOOLBAR message, do the following steps:
a. Construct the button control by using a CMFCToolbarButton -derived class.
b. Replace the dummy button with the new control by using CMFCToolBar::ReplaceButton. You can
construct the button object on the stack, because ReplaceButton copies the button object and
maintains the copy.

NOTE
If you enabled customization in your application, you may have to reset the toolbar by using the Reset button on the
Toolbars tab of the Customize dialog box to see the updated control in your application after recompiling. The toolbar
state is saved in the Windows registry, and the registry information is loaded and applied after the ReplaceButton
method is executed during application startup.

Toolbar Controls and Customization


The Commands tab of the Customize dialog box contains a list of commands that are available in the
application. By default, the Customize dialog box processes the application menus and builds a list of standard
toolbar buttons in each menu category. To keep the extended functionality that the toolbar controls provide, you
must replace the standard toolbar button with the custom control in the Customize dialog box.
When you enable customization, you create the Customize dialog box in the customization handler
OnViewCustomize by using the CMFCToolBarsCustomizeDialog Class class. Before you display the Customize
dialog box by calling CMFCToolBarsCustomizeDialog::Create, call CMFCToolBarsCustomizeDialog::ReplaceButton
to replace the standard button with the new control.

Example: Creating a Find Combo Box


This section describes how to create a Find combo box control that appears on a toolbar and contains recent-
used search strings. The user can type a string in the control and then press the enter key to search a document,
or press the escape key to return the focus to the main frame. This example assumes that the document is
displayed in a CEditView Class-derived view.
Creating the Find Control
First, create the Find combo box control:
1. Add the button and its commands to the application resources:
a. In the application resources, add a new button with an ID_EDIT_FIND command ID to a toolbar in
your application and to any bitmaps associated with the toolbar.
b. Create a new menu item with the ID_EDIT_FIND command ID.
c. Add a new string "Find the text\nFind" to the string table and assign it an ID_EDIT_FIND_COMBO
command ID. This ID will be used as the command ID of the Find combo box button.

NOTE
Because ID_EDIT_FIND is a standard command that is processed by CEditView , you are not required to
implement a special handler for this command. However, you must implement a handler for the new
command ID_EDIT_FIND_COMBO .

2. Create a new class, CFindComboBox , derived from CComboBox Class.


3. In the CFindComboBox class, override the PreTranslateMessage virtual method. This method will enable the
combo box to process the WM_KEYDOWN message. If the user hits the escape key ( VK_ESCAPE ), return the
focus to the main frame window. If the user hits the Enter key ( VK_ENTER ), post to the main frame window
a WM_COMMAND message that contains the ID_EDIT_FIND_COMBO command ID.
4. Create a class for the Find combo box button, derived from CMFCToolBarComboBoxButton Class. In this
example, it's named CFindComboButton .
5. The constructor of CMFCToolbarComboBoxButton takes three parameters: the command ID of the button, the
button image index, and the style of the combo box. Set these parameters as follows:
a. Pass the ID_EDIT_FIND_COMBO as the command ID.
b. Use CCommandManager::GetCmdImage with ID_EDIT_FIND to get the image index.
c. For a list of available combo box styles, see Combo-Box Styles.
6. In the CFindComboButton class, override the CMFCToolbarComboBoxButton::CreateCombo method. Here you
should create the CFindComboButton object and return a pointer to it.
7. Use the IMPLEMENT_SERIAL macro to make the combo button persistent. The workspace manager
automatically loads and saves the button's state in the Windows registry.
8. Implement the ID_EDIT_FIND_COMBO handler in your document view. Use
CMFCToolBar::GetCommandButtons with ID_EDIT_FIND_COMBO to retrieve all Find combo box buttons.
There can be several copies of a button with the same command ID because of customization.
9. In the ID_EDIT_FIND message handler OnFind , use CMFCToolBar::IsLastCommandFromButton to
determine whether the find command was sent from the Find combo box button. If so, find the text and
add the search string to the combo box.
Adding the Find Control to the Main Toolbar
To add the combo box button to the toolbar, follow these steps:
1. Implement the AFX_WM_RESETTOOLBAR message handler OnToolbarReset in the main frame window.
NOTE
The framework sends this message to the main frame window when a toolbar is initialized during application
startup, or when a toolbar is reset during customization. In either case, you must replace the standard toolbar
button with the custom Find combo box button.

2. In the AFX_WM_RESETTOOLBAR handler, examine the toolbar ID, that is, the WPARAM of the
AFX_WM_RESETTOOLBAR message. If the toolbar ID is equal to that of the toolbar that contains the Find
combo box button, call CMFCToolBar::ReplaceButton to replace the Find button (that is, the button with the
command ID ID_EDIT_FIND) with a CFindComboButton object.

NOTE
You can construct a CFindComboBox object on the stack, because ReplaceButton copies the button object and
maintains the copy.

Adding the Find Control to the Customize Dialog Box


In the customization handler OnViewCustomize , call CMFCToolBarsCustomizeDialog::ReplaceButton to replace the
Find button (that is, the button with the command ID ID_EDIT_FIND ) with a CFindComboButton object.

See also
Hierarchy Chart
Classes
CMFCToolBar Class
CMFCToolBarButton Class
CMFCToolBarComboBoxButton Class
CMFCToolBarsCustomizeDialog Class
Walkthrough: Adding a D2D Object to an MFC
Project
11/21/2019 • 2 minutes to read • Edit Online

This walkthrough teaches how to add a basic Direct2D (D2D) object to a Visual C++, Microsoft Foundation Class
Library (MFC) project, and then build the project into an application that prints "Hello, World!" on a gradient
background.
The walkthrough shows how to accomplish these tasks:
Create an MFC application.
Create a solid-color brush and a linear-gradient brush.
Modify the gradient brush so that it will change appropriately when the window is resized.
Implement a D2D drawing handler.
Verify the results.

NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the following
instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more
information, see Personalizing the IDE.

Prerequisites
To complete this walkthrough, you must have Visual Studio installed with the Desktop development with C++
workload and the optional Visual C++ MFC for x86 and x64 component.

To create an MFC application


1. Use the MFC Application Wizard to create an MFC application. See Walkthrough: Using the New MFC
Shell Controls for instructions on how to open the wizard for your version of Visual Studio.
2. In the Name box, type MFCD2DWalkthrough. Choose OK .
3. In the MFC Application Wizard , choose Finish without changing any settings.

To create a solid-color brush and a linear-gradient brush


1. In Solution Explorer , in the MFCD2DWalkthrough project, in the Header Files folder, open
MFCD2DWalkthroughView.h. Add this code to the CMFCD2DWalkthroughView class to create three data
variables:

CD2DTextFormat* m_pTextFormat;
CD2DSolidColorBrush* m_pBlackBrush;
CD2DLinearGradientBrush* m_pLinearGradientBrush;

Save the file and close it.


2. In the Source Files folder, open MFCD2DWalkthroughView.cpp. In the constructor for the
CMFCD2DWalkthroughView class, add this code:

// Enable D2D support for this window:


EnableD2DSupport();

// Initialize D2D resources:


m_pBlackBrush = new CD2DSolidColorBrush(
GetRenderTarget(),
D2D1::ColorF(D2D1::ColorF::Black));

m_pTextFormat = new CD2DTextFormat(


GetRenderTarget(),
_T("Verdana"),
50);

m_pTextFormat->Get()->SetTextAlignment(
DWRITE_TEXT_ALIGNMENT_CENTER);

m_pTextFormat->Get()->SetParagraphAlignment(
DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

D2D1_GRADIENT_STOP gradientStops[2];

gradientStops[0].color =
D2D1::ColorF(D2D1::ColorF::White);

gradientStops[0].position = 0.f;
gradientStops[1].color =
D2D1::ColorF(D2D1::ColorF::Indigo);

gradientStops[1].position = 1.f;

m_pLinearGradientBrush = new CD2DLinearGradientBrush(


GetRenderTarget(),
gradientStops,
ARRAYSIZE(gradientStops),
D2D1::LinearGradientBrushProperties(
D2D1::Point2F(0,0),
D2D1::Point2F(0,0)));

Save the file and close it.

To modify the gradient brush so that it will change appropriately when


the window is resized
1. On the Project menu, choose Class Wizard .
2. In the MFC Class Wizard , under Class name , select CMFCD2DWalkthroughView .
3. On the Messages tab, in the Messages box, select WM_SIZE and then choose Add Handler . This action
adds the OnSize message handler to the CMFCD2DWalkthroughView class.
4. In the Existing handlers box, select OnSize . Choose Edit Code to display the
CMFCD2DWalkthroughView::OnSize method. At the end of the method, add the following code.

m_pLinearGradientBrush->SetEndPoint(CPoint(cx, cy));

Save the file and close it.


To implement a D2D drawing handler
1. On the Project menu, choose Class Wizard .
2. In the MFC Class Wizard , under Class name , select CMFCD2DWalkthroughView .
3. On the Messages tab, choose Add Custom Message .
4. In the Add Custom Message dialog box, in the Custom Windows Message box, type
AFX_WM_DRAW2D. In the Message handler name box, type OnDraw2D. Select the Registered Message
option and then choose OK . This action adds a message handler for the AFX_WM_DRAW2D message to the
CMFCD2DWalkthroughView class.

5. In the Existing handlers box, select OnDraw2D . Choose Edit Code to display the
CMFCD2DWalkthroughView::OnDraw2D method. Use this code for the CMFCD2DWalkthroughView::OnDrawD2D
method:

afx_msg LRESULT CMFCD2DWalkthroughView::OnDraw2D(


WPARAM wParam,
LPARAM lParam)
{
CHwndRenderTarget* pRenderTarget = (CHwndRenderTarget*)lParam;
ASSERT_VALID(pRenderTarget);

CRect rect;
GetClientRect(rect);

pRenderTarget->FillRectangle(rect, m_pLinearGradientBrush);

pRenderTarget->DrawText(
_T("Hello, World!"),
rect,
m_pBlackBrush,
m_pTextFormat);

return TRUE;
}

Save the file and close it.

To verify the results


Build and run the application. It should have a gradient rectangle that changes when you resize the window. "Hello
World!" should be displayed in the center of the rectangle.

See also
Walkthroughs
Walkthrough: Adding Animation to an MFC Project
4/26/2019 • 6 minutes to read • Edit Online

This walkthrough teaches how to add a basic animated object to a Visual C++, Microsoft Foundation Class Library
(MFC) project.
The walkthrough shows how to accomplish these tasks:
Create an MFC application.
Add a menu and then add commands to start and stop an animation.
Create handlers for the start and stop commands.
Add an animated object to the project.
Center the animated object in the window.
Verify the results.

NOTE
Your computer might show different names or locations for some of the Visual Studio user interface elements in the following
instructions. The Visual Studio edition that you have and the settings that you use determine these elements. For more
information, see Personalizing the IDE.

Prerequisites
To complete this walkthrough, you must have Visual Studio.
To create an MFC application
1. Use the MFC Application Wizard to create an MFC application. See Walkthrough: Using the New MFC
Shell Controls for instructions on how to open the wizard for your version of Visual Studio.
2. In the Name box, type MFCAnimationWalkthrough. Click OK .
3. In the MFC Application Wizard dialog box, verify that Application Type is Multiple Documents ,
Project Style is Visual Studio , and the Document/View architecture suppor t option is selected. Click
Finish .
To add a menu and then add commands to start and stop an animation
1. On the View menu, point to Other Windows and then click Resource View .
2. In Resource View , navigate to the Menu folder and open it. Double-click the
IDR_MFCAnimationWalkthroughTYPE resource to open it for modification.
3. On the menu bar, in the Type Here box, type A&nimation to create an Animation menu.
4. Under Animation , in the Type Here box, type Start &Forward to create a Start Forward command.
5. Under Star t For ward , in the Type Here box, type Start &Backward.
6. Under Star t Backward , in the Type Here box, type S&top to create a Stop command.
7. Save MFCAnimationWalkthrough.rc and close it.
8. In Solution Explorer , double-click MainFrm.cpp to open it for modification. In the CMainFrame::OnCreate
method, locate the section that has several calls to lstBasicCommands.AddTail . Just after that section, add the
following code.

lstBasicCommands.AddTail(ID_ANIMATION_STARTFORWARD);
lstBasicCommands.AddTail(ID_ANIMATION_STARTBACKWARD);
lstBasicCommands.AddTail(ID_ANIMATION_STOP);

9. Save the file and close it.


To create handlers for the start and stop commands
1. On the Project menu, click Class Wizard .
2. In the MFC Class Wizard , under Class name , select CMFCAnimationWalkthroughView .
3. On the Commands tab, in the Object IDs box, select ID_ANIMATION_STARTFORWARD , and then in the
Messages box, select COMMAND . Click Add Handler .
4. In the Add Member Function dialog box, click OK .
5. In the Object IDs box, select ID_ANIMATION_STARTBACKWARD , and then in the Messages box, select
COMMAND . Click Add Handler .
6. In the Add Member Function dialog box, click OK .
7. In the Object IDs box, select ID_ANIMATION_STOP , and then in the Messages box, select COMMAND .
Click Add Handler and then click OK .
8. In the Add Member Function dialog box, click OK .
9. In the MFC Class Wizard , click OK .
10. Save MFCAnimationWalkthroughView.cpp, which is open in the editor, but don't close it.
To add an animated object to the project
1. In Solution Explorer , double-click MFCAnimationWalkthroughView.h to open it for modification. Just
before the definition of the CMFCAnimationWalkthroughView class, add the following code to create a custom
animation controller that will handle scheduling conflicts with the animation object.

class CCustomAnimationController : public CAnimationController


{
public:
CCustomAnimationController()
{
}

virtual BOOL OnHasPriorityTrim(CAnimationGroup* pGroupScheduled,


CAnimationGroup* pGroupNew,
UI_ANIMATION_PRIORITY_EFFECT priorityEffect)
{
return TRUE;
}
};

2. At the end of the CMFCAnimationWalkthroughView class, add the following code.


CCustomAnimationController m_animationController;
CAnimationColor m_animationColor;
CAnimationRect m_animationRect;

3. After the DECLARE_MESSAGE_MAP() line, add the following code.

void Animate(BOOL bDirection);

4. Save the file and close it.


5. In MFCAnimationWalkthroughView.cpp, at the top of the file after the #include statements but before any
class methods, add the following code.

static int nAnimationGroup = 0;


static int nInfoAreaHeight = 40;

6. At the end of the constructor for CMFCAnimationWalkthroughView , add the following code.

m_animationController.EnableAnimationTimerEventHandler();
m_animationController.EnablePriorityComparisonHandler(UI_ANIMATION_PHT_TRIM);
m_animationColor = RGB(255, 255, 255);
m_animationRect = CRect(0, 0, 0, 0);
m_animationColor.SetID(-1, nAnimationGroup);
m_animationRect.SetID(-1, nAnimationGroup);
m_animationController.AddAnimationObject(&m_animationColor);
m_animationController.AddAnimationObject(&m_animationRect);

7. Locate the CAnimationWalthroughView::PreCreateWindow method and then replace it with the following code.

BOOL CMFCAnimationWalkthroughView::PreCreateWindow(CREATESTRUCT& cs)


{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
m_animationController.SetRelatedWnd(this);

return CView::PreCreateWindow(cs);
}

8. Locate the CAnimationWalkthroughView::OnDraw method and then replace it with the following code.
void CMFCAnimationWalkthroughView::OnDraw(CDC* pDC)
{
CMFCAnimationWalkthroughDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: add draw code for native data here


CMemDC dcMem(*pDC, this);
CDC& dc = dcMem.GetDC();
CRect rect;
GetClientRect(rect);

dc.FillSolidRect(rect, GetSysColor(COLOR_WINDOW));

CString strRGB;
strRGB.Format(_T("Fill Color is: %d; %d; %d"),
GetRValue(m_animationColor),
GetGValue(m_animationColor),
GetBValue(m_animationColor));

dc.DrawText(strRGB, rect, DT_CENTER);


rect.top += nInfoAreaHeight;

CBrush br;
br.CreateSolidBrush(m_animationColor);
CBrush* pBrushOld = dc.SelectObject(&br);

dc.Rectangle((CRect)m_animationRect);

dc.SelectObject(pBrushOld);
}

9. At the end of the file, add the following code.


void CMFCAnimationWalkthroughView::Animate(BOOL bDirection)
{
static UI_ANIMATION_SECONDS duration = 3;
static DOUBLE dblSpeed = 35.;
static BYTE nStartColor = 50;
static BYTE nEndColor = 255;

BYTE nRedColorFinal = bDirection ? nStartColor : nEndColor;


BYTE nGreenColorFinal = bDirection ? nStartColor : nEndColor;
BYTE nBlueColorFinal = bDirection ? nStartColor : nEndColor;

CLinearTransition* pRedTransition =
new CLinearTransition(duration, (DOUBLE)nRedColorFinal);

CSmoothStopTransition* pGreenTransition =
new CSmoothStopTransition(duration, (DOUBLE)nGreenColorFinal);

CLinearTransitionFromSpeed* pBlueTransition =
new CLinearTransitionFromSpeed(dblSpeed, (DOUBLE)nBlueColorFinal);

m_animationColor.AddTransition(pRedTransition,
pGreenTransition,
pBlueTransition);

CRect rectClient;
GetClientRect(rectClient);

rectClient.top += nInfoAreaHeight;

int nLeftFinal = bDirection ? rectClient.left : rectClient.CenterPoint().x;


int nTopFinal = bDirection ? rectClient.top : rectClient.CenterPoint().y;
int nRightFinal = bDirection ? rectClient.right : rectClient.CenterPoint().x;
int nBottomFinal = bDirection ? rectClient.bottom : rectClient.CenterPoint().y;

CLinearTransition* pLeftTransition =
new CLinearTransition(duration, nLeftFinal);

CLinearTransition* pTopTransition =
new CLinearTransition(duration, nTopFinal);

CLinearTransition* pRightTransition =
new CLinearTransition(duration, nRightFinal);

CLinearTransition* pBottomTransition =
new CLinearTransition(duration, nBottomFinal);

m_animationRect.AddTransition(pLeftTransition,
pTopTransition,
pRightTransition,
pBottomTransition);

CBaseKeyFrame* pKeyframeStart =
CAnimationController::GetKeyframeStoryboardStart();
CKeyFrame* pKeyFrameEnd =
m_animationController.CreateKeyframe(nAnimationGroup,
pBlueTransition);

pLeftTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd);
pTopTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd);
pRightTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd);
pBottomTransition->SetKeyframes(pKeyframeStart, pKeyFrameEnd);

m_animationController.AnimateGroup(nAnimationGroup);
}

10. On the Project menu, click Class Wizard .


11. In the MFC Class Wizard , under Class name , select CMFCAnimationWalkthroughView .
12. On the Messages tab, in the Messages box, select WM_ERASEBKGND , click Add Handler , and then click
OK .
13. In MFCAnimationWalkthroughView.cpp, replace the implementation of OnEraseBkgnd with the following
code to reduce flickering in the animated object when it's redrawn.

BOOL CMFCAnimationWalkthroughView::OnEraseBkgnd(CDC* /*pDC*/)


{
return TRUE;
}

14. Replace the implementations of CMFCAnimationWalkthroughView::OnAnimationStartforward ,


CMFCAnimationWalkthroughView::OnAnimationStartbackward , and
CMFCAnimationWalkthroughView::OnAnimationStop with the following code.

void CMFCAnimationWalkthroughView::OnAnimationStartforward()
{
Animate(TRUE);
}

void CMFCAnimationWalkthroughView::OnAnimationStartbackward()
{
Animate(FALSE);
}

void CMFCAnimationWalkthroughView::OnAnimationStop()
{
IUIAnimationManager* pManager = m_animationController.GetUIAnimationManager();
if (pManager != NULL)
{
pManager->AbandonAllStoryboards();

}
}

15. Save the file and close it.


To center the animated object in the window
1. In Solution Explorer , double-click MFCAnimationWalkthroughView.h to open it for modification. At the
end of the CMFCAnimationWalkthroughView class, just after the definition of m_animationRect , add the
following code.

BOOL m_bCurrentDirection;

2. Save the file and close it.


3. On the Project menu, click Class Wizard .
4. In the MFC Class Wizard , under Class name , select CMFCAnimationWalkthroughView .
5. On the Messages tab, in the Messages box, select WM_SIZE , click Add Handler , and then click OK .
6. In MFCAnimationWalkthroughView.cpp, replace the code for CMFCAnimationWalkthroughView::OnSize with the
following code.
void CMFCAnimationWalkthroughView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(rect);

rect.top += nInfoAreaHeight;

CRect rectAnim = m_animationRect;


m_animationRect = CRect(CPoint(rect.CenterPoint().x - rectAnim.Width() / 2,
rect.CenterPoint().y - rectAnim.Height() / 2),
rectAnim.Size());

if (m_animationController.IsAnimationInProgress())
{
Animate(m_bCurrentDirection);
}
}

7. At the beginning of the constructor for CMFCAnimationWalkthroughView , add the following code.

m_bCurrentDirection = TRUE;

8. At the beginning of the CMFCAnimationWalkthroughView::Animate method, add the following code.

m_bCurrentDirection = bDirection;

9. Save the file and close it.


To verify the results
1. Build and run the application. On the Animation menu, click Star t For ward . A rectangle should appear and
then fill the center area. When you click Star t Backward , the animation should reverse, and when you click
Stop , it should stop. The fill color of the rectangle should change as the animation progresses, and the current
color should be displayed at the top of the animation window.

See also
Walkthroughs
MFC Classes
3/27/2020 • 34 minutes to read • Edit Online

The classes in the following list are included in the Microsoft Foundation Class (MFC)
Library.

TIP
For information about CStringT and other classes that are common to both MFC and ATL
programming, see Classes Shared by MFC and ATL.

IMPORTANT
The MFC classes and their members cannot be used in applications that execute in the
Windows Runtime.

In This Section
CAccelerateDecelerateTransition Class
Implements an accelerate-decelerate transition.
CAnimateCtrl Class
Provides the functionality of the Windows common animation control.
CAnimationBaseObject Class
The base class for all animation objects.
CAnimationColor Class
Implements the functionality of a color whose red, green, and blue components can
be animated.
CAnimationController Class
Implements the animation controller, which provides a central interface for creating
and managing animations.
CAnimationGroup Class
Implements the animation controller, which provides a central interface for creating
and managing animations.
CAnimationManagerEventHandler Class
Implements a callback, which is called by the Animation API when a status of an
animation manager is changed.
CAnimationPoint Class
Implements the functionality of a point whose coordinates can be animated.
CAnimationRect Class
Implements the functionality of a rectangle whose sides can be animated.
CAnimationSize Class
Implements the functionality of a size object whose dimensions can be animated.
CAnimationStoryboardEventHandler Class
Implements a callback, which is called by the Animation API when the status of a
storyboard is changed or a storyboard is updated.
CAnimationTimerEventHandler Class
Implements a callback, which is called by the Animation API when timing events
occur.
CAnimationValue Class
Implements the functionality of animation object that has one value.
CAnimationVariable Class
Represents an animation variable.
CAnimationVariableChangeHandler Class
Implements a callback, which is called by the Animation API when the value of an
animation variable changes.
CAnimationVariableIntegerChangeHandler Class
Implements a callback, which is called by the Animation API when the value of an
animation variable changes.
CArchive Class
Lets you save a complex network of objects in a permanent binary form (usually disk
storage) that persists after those objects are deleted.
CArchiveException Class
Represents a serialization exception condition.
CArray Class
Supports arrays that resemble C arrays, but can dynamically reduce and grow as
necessary.
CAsyncMonikerFile Class
Provides functionality for the use of asynchronous monikers in ActiveX controls
(formerly OLE controls).
CAsyncSocket Class
Represents a Windows Socket, which is an endpoint of network communication.
CAutoHideDockSite Class
Extends the CDockSite Class to implement auto-hide dock panes.
CBaseKeyFrame Class
Implements the basic functionality of a keyframe.
CBasePane Class
Base class for all panes.
CBaseTabbedPane Class
Extends the functionality of the CDockablePane Class to support the creation of
tabbed windows.
CBaseTransition Class
Represents a basic transition.
CBitmap Class
Encapsulates a Windows graphics device interface (GDI) bitmap and provides
member functions to manipulate the bitmap.
CBitmapButton Class
Creates pushbutton controls labeled with bitmapped images instead of text.
CBitmapRenderTarget Class
A wrapper for ID2D1BitmapRenderTarget .
CBrush Class
Encapsulates a Windows graphics device interface (GDI) brush.
CButton Class
Provides the functionality of Windows button controls.
CByteArray Class
Supports dynamic arrays of bytes.
CCachedDataPathProperty Class
Implements an OLE control property transferred asynchronously and cached in a
memory file.
CCheckListBox Class
Provides the functionality of a Windows checklist box.
CClientDC Class
Handles the calling of the Windows functions GetDC at construction time and
ReleaseDC at destruction time.
CCmdTarget Class
Base class for the Microsoft Foundation Class Library message-map architecture.
CCmdUI Class
Used only within an ON_UPDATE_COMMAND_UI handler in a CCmdTarget -derived class.
CColorDialog Class
Lets you incorporate a color-selection dialog box into your application.
CComboBox Class
Provides the functionality of a Windows combo box.
CComboBoxEx Class
Extends the combo box control by providing support for image lists.
CCommandLineInfo Class
Aids in parsing the command line at application startup.
CCommonDialog Class
The base class for classes that encapsulate functionality of the Windows common
dialogs.
CConnectionPoint Class
Defines a special type of interface used to communicate with other OLE objects,
called a "connection point."
CConstantTransition Class
Encapsulates a constant transition.
CContextMenuManager Class
Manages shortcut menus, also known as context menus.
CControlBar Class
Base class for the control-bar classes CStatusBar Class, CToolBar Class, CDialogBar
Class, CReBar Class, and COleResizeBar Class.
CCriticalSection Class
Represents a "critical section", which is a synchronization object that enables one
thread at a time to access a resource or section of code.
CCtrlView Class
Adapts the document-view architecture to the common controls supported by
Windows 98 and Windows NT versions 3.51 and later.
CCubicTransition Class
Encapsulates a cubic transition.
CCustomInterpolator Class
Implements a basic interpolator.
CCustomTransition Class
Implements a custom transition.
CD2DBitmap Class
A wrapper for ID2D1Bitmap .
CD2DBitmapBrush Class
A wrapper for ID2D1BitmapBrush .
CD2DBrush Class
A wrapper for ID2D1Brush .
CD2DBrushProperties Class
A wrapper for D2D1_BRUSH_PROPERTIES .
CD2DEllipse Class
A wrapper for D2D1_BRUSH_PROPERTIES .
CD2DGeometry Class
A wrapper for ID2D1Geometry .
CD2DGeometrySink Class
A wrapper for ID2D1GeometrySink .
CD2DGradientBrush Class
The base class of the CD2DLinearGradientBrush and the CD2DRadialGradientBrush
classes.
CD2DLayer Class
A wrapper for ID2D1Layer .
CD2DLinearGradientBrush Class
A wrapper for ID2D1LinearGradientBrush .
CD2DMesh Class
A wrapper for ID2D1Mesh .
CD2DPathGeometry Class
A wrapper for ID2D1PathGeometry .
CD2DPointF Class
A wrapper for D2D1_POINT_2F .
CD2DPointU Class
A wrapper for D2D1_POINT_2U .
CD2DRadialGradientBrush Class
A wrapper for ID2D1RadialGradientBrush .
CD2DRectF Class
A wrapper for D2D1_RECT_F .
CD2DRectU Class
A wrapper for D2D1_RECT_U .
CD2DResource Class
An abstract class that provides a interface for creating and managing D2D resources
such as brushes, layers, and texts.
CD2DRoundedRect Class
A wrapper for D2D1_ROUNDED_RECT .
CD2DSizeF Class
A wrapper for D2D1_SIZE_F .
CD2DSizeU Class
A wrapper for D2D1_SIZE_U .
CD2DSolidColorBrush Class
A wrapper for ID2D1SolidColorBrush .
CD2DTextFormat Class
A wrapper for IDWriteTextFormat .
CD2DTextLayout Class
A wrapper for IDWriteTextLayout .
CDaoDatabase Class
Represents a connection to a database through which you can operate on the data.
CDaoException Class
Represents an exception condition arising from the MFC database classes based on
data access objects (DAO).
CDaoFieldExchange Class
Supports the DAO record field exchange (DFX) routines used by the DAO database
classes.
CDaoQueryDef Class
Represents a query definition, or "querydef," usually one saved in a database.
CDaoRecordset Class
Represents a set of records selected from a data source.
CDaoRecordView Class
A view that displays database records in controls.
CDaoTableDef Class
Represents the stored definition of a base table or an attached table.
CDaoWorkspace Class
Manages a named, password-protected database session from login to logoff, by a
single user.
CDatabase Class
Represents a connection to a data source, through which you can operate on the data
source.
CDataExchange Class
Supports the dialog data exchange (DDX) and dialog data validation (DDV) routines
used by the Microsoft Foundation classes.
CDataPathProperty Class
Implements an OLE control property that can be loaded asynchronously.
CDataRecoveryHandler Class
Autosaves documents and restores them if an application unexpectedly exits.
CDateTimeCtrl Class
Encapsulates the functionality of a date and time picker control.
CDBException Class
Represents an exception condition arising from the database classes.
CDBVariant Class
Represents a variant data type for the MFC ODBC classes.
CDC Class
Defines a class of device-context objects.
CDCRenderTarget Class
A wrapper for ID2D1DCRenderTarget .
CDHtmlDialog Class
Used to create dialog boxes that use HTML rather than dialog resources to
implement their user interface.
CDialog Class
Base class used for displaying dialog boxes on the screen.
CDialogBar Class
Provides the functionality of a Windows modeless dialog box in a control bar.
CDialogEx Class
Specifies the background color and background image of a dialog box.
CDiscreteTransition Class
Encapsulates a discrete transition.
CDocItem Class
The base class for document items, which are components of a document's data.
CDockablePane Class
Implements a pane that can either be docked in a dock site or included in a tabbed
pane.
CDockablePaneAdapter Class
Provides docking support for CWnd -derived panes.
CDockingManager Class
Implements the core functionality that controls docking layout in a main frame
window.
CDockingPanesRow Class
Manages a list of panes that are located in the same horizontal or vertical row
(column) of a dock site.
CDockSite Class
Provides functionality for arranging panes that are derived from the CPane Class into
sets of rows.
CDockState Class
A serialized CObject class that loads, unloads, or clears the state of one or more
docking control bars in persistent memory (a file).
CDocObjectServer Class
Implements the additional OLE interfaces needed to make a normal COleDocument
server into a full DocObject server: IOleDocument , IOleDocumentView ,
IOleCommandTarget , and IPrint .

CDocObjectServerItem Class
Implements OLE server verbs specifically for DocObject servers.
CDocTemplate Class
An abstract base class that defines the basic functionality for document templates.
CDocument Class
Provides the basic functionality for user-defined document classes.
CDragListBox Class
In addition to providing the functionality of a Windows list box, the CDragListBox
class lets the user move list box items, such as filenames, within the list box.
CDrawingManager Class
Implements complex drawing algorithms.
CDumpContext Class
Supports stream-oriented diagnostic output in the form of human-readable text.
CDWordArray Class
Supports arrays of 32-bit doublewords.
CEdit Class
Provides the functionality of a Windows edit control.
CEditView Class
A type of view class that provides the functionality of a Windows edit control and can
be used to implement simple text-editor functionality.
CEvent Class
Represents an "event", which is a synchronization object that enables one thread to
notify another that an event has occurred.
CException Class
The base class for all exceptions in the Microsoft Foundation Class Library.
CFieldExchange Class
Supports the record field exchange (RFX) and bulk record field exchange (Bulk RFX)
routines used by the database classes.
CFile Class
The base class for Microsoft Foundation Class file classes.
CFileDialog Class
Encapsulates the common file dialog box for Windows.
CFileException Class
Represents a file-related exception condition.
CFileFind Class
Performs local file searches and is the base class for CGopherFileFind Class and
CFtpFileFind Class, which perform Internet file searches.
CFindReplaceDialog Class
Lets you implement standard string Find/Replace dialog boxes in your application.
CFolderPickerDialog Class
Implements CFileDialog in the folder picker mode.
CFont Class
Encapsulates a Windows graphics device interface (GDI) font and provides member
functions for manipulating the font.
CFontDialog Class
Lets you incorporate a font-selection dialog box into your application.
CFontHolder Class
Implements the stock Font property and encapsulates the functionality of a Windows
font object and the IFont interface.
CFormView Class
The base class used for form views.
CFrameWnd Class
Provides the functionality of a Windows single document interface (SDI) overlapped
or pop-up frame window, along with members for managing the window.
CFrameWndEx Class
Implements the functionality of a Windows single document interface (SDI)
overlapped or popup frame window, and provides members for managing the
window. It extends the CFrameWnd Class class.
CFtpConnection Class
Manages your FTP connection to an Internet server and enables direct manipulation
of directories and files on that server.
CFtpFileFind Class
Aids in Internet file searches of FTP servers.
CGdiObject Class
Provides a base class for various kinds of Windows graphics device interface (GDI)
objects such as bitmaps, regions, brushes, pens, palettes, and fonts.
CGopherConnection Class
Manages your connection to a gopher Internet server.
CGopherFile Class
Provides the functionality to find and read files on a gopher server.
CGopherFileFind Class
Aids in Internet file searches of gopher servers.
CGopherLocator Class
Gets a gopher "locator" from a gopher server, determines the locator's type, and
makes the locator available to CGopherFileFind Class.
CHeaderCtrl Class
Provides the functionality of the Windows common header control.
CHotKeyCtrl Class
Provides the functionality of the Windows common hot key control.
CHtmlEditCtrl Class
Provides the functionality of the WebBrowser ActiveX control in an MFC window.
CHtmlEditCtrlBase Class
Represents an HTML editing component.
CHtmlEditDoc Class
With CHtmlEditView Class, provides the functionality of the WebBrowser editing
platform within the context of the MFC document-view architecture.
CHtmlEditView Class
Provides the functionality of the WebBrowser editing platform within the context of
MFC's document/view architecture.
CHtmlView Class
Provides the functionality of the WebBrowser control within the context of MFC's
document/view architecture.
CHttpConnection Class
Manages your connection to an HTTP server.
CHttpFile Class
Provides the functionality to request and read files on an HTTP server.
CHwndRenderTarget Class
A wrapper for ID2D1HwndRenderTarget .
CImageList Class
Provides the functionality of the Windows common image list control.
CInstantaneousTransition Class
Encapsulates an instantaneous transition.
CInternetConnection Class
Manages your connection to an Internet server.
CInternetException Class
Represents an exception condition related to an Internet operation.
CInternetFile Class
Enables access to files on remote systems that use Internet protocols.
CInternetSession Class
Creates and initializes a single or several simultaneous Internet sessions and, if
necessary, describes your connection to a proxy server.
CInterpolatorBase Class
Implements a callback, which is called by the Animation API when it has to calculate
a new value of an animation variable.
CInvalidArgException Class
This class represents an invalid argument exception condition.
CIPAddressCtrl Class
Provides the functionality of the Windows common IP Address control.
CJumpList Class
The list of shortcuts revealed when you right click on an icon in the task bar.
CKeyboardManager Class
Manages shortcut key tables for the main frame window and child frame windows.
CKeyFrame Class
Represents an animation keyframe.
CLinearTransition Class
Encapsulates a linear transition.
CLinearTransitionFromSpeed Class
Encapsulates a linear-speed transition.
CLinkCtrl Class
Provides the functionality of the Windows common SysLink control.
CList Class
Supports ordered lists of nonunique objects accessible sequentially or by value.
CListBox Class
Provides the functionality of a Windows list box.
CListCtrl Class
Encapsulates the functionality of a "list view control," which displays a collection of
items each consisting of an icon (from an image list) and a label.
CListView Class
Simplifies use of the list control and of CListCtrl Class, the class that encapsulates list-
control functionality, with MFC's document-view architecture.
CLongBinary Class
Simplifies working with very large binary data objects (often called BLOBs, or "binary
large objects") in a database.
CMap Class
A dictionary collection class that maps unique keys to values.
CMapPtrToPtr Class
Supports maps of void pointers keyed by void pointers.
CMapPtrToWord Class
Supports maps of 16-bit words keyed by void pointers.
CMapStringToOb Class
A dictionary collection class that maps unique CString objects to CObject pointers.
CMapStringToPtr Class
Supports maps of void pointers keyed by CString objects.
CMapStringToString Class
Supports maps of CString objects keyed by CString objects.
CMapWordToOb Class
Supports maps of CObject pointers keyed by 16-bit words.
CMapWordToPtr Class
Supports maps of void pointers keyed by 16-bit words.
CMDIChildWnd Class
Provides the functionality of a Windows multiple document interface (MDI) child
window, along with members for managing the window.
CMDIChildWndEx Class
Provides the functionality of a Windows multiple document interface (MDI) child
window. It extends the functionality of CMDIChildWnd Class. The framework requires
this class when an MDI application uses certain MFC classes.
CMDIFrameWnd Class
Provides the functionality of a Windows multiple document interface (MDI) frame
window, along with members for managing the window.
CMDIFrameWndEx Class
Extends the functionality of CFrameWnd Class, a Windows Multiple Document
Interface (MDI) frame window.
CMDITabInfo Class
Used to pass parameters to CMDIFrameWndEx::EnableMDITabbedGroups method.
Set members of this class to control the behavior of MDI tabbed groups.
CMemFile Class
The CFile Class-derived class that supports memory files.
CMemoryException Class
Represents an out-of-memory exception condition.
CMenu Class
An encapsulation of the Windows HMENU .
CMenuTearOffManager Class
Manages tear-off menus. A tear-off menu is a menu on the menu bar. The user can
remove a tear-off menu from the menu bar, causing the tear-off menu to float.
CMetaFileDC Class
Implements a Windows metafile, which contains a sequence of graphics device
interface (GDI) commands that you can replay to create a desired image or text.
CMFCAcceleratorKey Class
Helper class that implements virtual key mapping and formatting.
CMFCAcceleratorKeyAssignCtrl Class
Extends the CEdit Class to support extra system buttons such as ALT, CONTROL, and
SHIFT.
CMFCAutoHideButton Class
A button that displays or hides a CDockablePane Class that is configured to hide.
CMFCBaseTabCtrl Class
Implements the base functionality for tabbed windows.
CMFCButton Class
Adds functionality to the CButton Class class such as aligning button text, combining
button text and an image, selecting a cursor, and specifying a tool tip.
CMFCCaptionBar Class
Control bar that can display three elements: a button, a text label, and a bitmap. It can
only display one element of each type at a time. You can align each element to the
left or right edges of the control or to the center. You can also apply a flat or 3D style
to the top and bottom borders of the caption bar.
CMFCCaptionButton Class
Implements a button that is displayed on the caption bar for a docking pane or a
mini-frame window. Typically, the framework creates caption buttons automatically.
CMFCColorBar Class
Represents a docking control bar that can select colors in a document or application.
CMFCColorButton Class
The CMFCColorButton and CMFCColorBar Class classes are used together to
implement a color picker control.
CMFCColorDialog Class
Represents a color selection dialog box.
CMFCColorMenuButton Class
Supports a menu command or a toolbar button that starts a color picker dialog box.
CMFCColorPickerCtrl Class
Provides functionality for a control that is used to select colors.
CMFCDesktopAlertDialog Class
Used together with the CMFCDesktopAlertWnd Class to display a custom dialog in a
popup window.
CMFCDesktopAlertWnd Class
Implements the functionality of a modeless dialog box which appears on the screen
to inform the user about an event.
CMFCDesktopAlertWndInfo Class
Used with the CMFCDesktopAlertWnd Class. It specifies the controls that are
displayed if the desktop alert window pops up.
CMFCDragFrameImpl Class
Draws the drag rectangle that appears when the user drags a pane in the standard
dock mode.
CMFCDropDownToolBar Class
A toolbar that appears when the user presses and holds a top-level toolbar button.
CMFCDropDownToolbarButton Class
A type of toolbar button that behaves like a regular button when it is clicked.
However, it opens a drop-down toolbar (CMFCDropDownToolBar Class if the user
presses and holds the toolbar button down.
CMFCDynamicLayout Class
Specifies how controls in a window are moved and resized as the user resizes the
window.
CMFCEditBrowseCtrl Class
Supports the edit browse control, which is an editable text box that optionally
contains a browse button. When the user clicks the browse button, the control
performs a custom action or displays a standard dialog box that contains a file
browser or a folder browser.
CMFCFilterChunkValueImpl Class
Simplifies both chunk and property value pair logic.
CMFCFontComboBox Class
Creates a combo box control that contains a list of fonts.
CMFCFontInfo Class
Describes the name and other attributes of a font.
CMFCHeaderCtrl Class
Supports sorting multiple columns in a header control.
CMFCImageEditorDialog Class
Supports an image editor dialog box.
CMFCKeyMapDialog Class
Supports a control that maps commands to keys on the keyboard.
CMFCLinkCtrl Class
Displays a button as a hyperlink and invokes the link's target when the button is
clicked.
CMFCListCtrl Class
Extends the functionality of CListCtrl Class class by supporting the advanced header
control functionality of the CMFCHeaderCtrl Class.
CMFCMaskedEdit Class
Supports a masked edit control, which validates user input against a mask and
displays the validated results according to a template.
CMFCMenuBar Class
A menu bar that implements docking.
CMFCMenuButton Class
A button that displays a pop-up menu and reports on the user's menu selections.
CMFCOutlookBar Class
A tabbed pane with the visual appearance of the Navigation Pane in Microsoft
Outlook 2000 or Outlook 2003. The CMFCOutlookBar object contains a
CMFCOutlookBarTabCtrl Class object and a series of tabs. The tabs can be either
CMFCOutlookBarPane Class objects or CWnd -derived objects. To the user, the
Outlook bar appears as a series of buttons and a display area. When the user clicks a
button, the corresponding control or button pane is displayed.
CMFCOutlookBarPane Class
A control derived from CMFCToolBar Class that can be inserted into an Outlook bar
(CMFCOutlookBar Class). The Outlook bar pane contains a column of large buttons.
The user can scroll up and down the list of buttons if it is larger than the pane. When
the user detaches an Outlook bar pane from the Outlook bar, it can float or dock in
the main frame window.
CMFCOutlookBarTabCtrl Class
A tab control that has the visual appearance of the Navigation Pane in Microsoft
Outlook.
CMFCPopupMenu Class
Implements Windows pop-up menu functionality and extends it by adding features
such as tear-off menus and tooltips.
CMFCPopupMenuBar Class
A menu bar embedded into a pop-up menu.
CMFCPreviewCtrlImpl Class
Implements a window that is placed on a host window provided by the Shell for Rich
Preview.
CMFCPropertyGridColorProperty Class
Supports a property list control item that opens a color selection dialog box.
CMFCPropertyGridCtrl Class
Supports an editable property grid control that can display properties in alphabetical
or hierarchical order.
CMFCPropertyGridFileProperty Class
Supports a property list control item that opens a file selection dialog box.
CMFCPropertyGridFontProperty Class
Supports a property list control item that opens a font selection dialog box.
CMFCPropertyGridProperty Class
Represents a list item in a property list control.
CMFCPropertyPage Class
Supports the display of pop-up menus on a property page.
CMFCPropertySheet Class
Supports a property sheet where each property page is denoted by a page tab, a
toolbar button, a tree control node, or a list item.
CMFCReBar Class
Control bar that provides layout, persistence, and state information for rebar
controls.
CMFCRibbonApplicationButton Class
Implements a special button located in the top-left corner of the application window.
When clicked, the button opens a menu that usually contains common File
commands like Open , Save , and Exit .
CMFCRibbonBaseElement Class
Base class for all elements that you can add to a CMFCRibbonBar Class. Examples of
ribbon elements are ribbon buttons, ribbon check boxes, and ribbon combo boxes.
CMFCRibbonButton Class
Implements buttons that you can position on ribbon bar elements such as panels,
Quick Access Toolbars, and pop-up menus.
CMFCRibbonButtonsGroup Class
Lets you organize a set of ribbon buttons into a group. All buttons in the group are
directly adjacent to each other horizontally and enclosed in a border.
CMFCRibbonCategory Class
Implements a ribbon tab that contains a group of CMFCRibbonPanel Class.
CMFCRibbonCheckBox Class
Implements a check box that you can add to a ribbon panel, Quick Access Toolbar, or
popup menu.
CMFCRibbonColorButton Class
Implements a color button that you can add to a ribbon bar. The ribbon color button
displays a drop-down menu that contains one or more color palettes.
CMFCRibbonComboBox Class
Implements a combo box control that you can add to a ribbon bar, a ribbon panel, or
a ribbon popup menu.
CMFCRibbonContextCaption Class
Implements a colored caption that appears at the top of a ribbon category or a
context category.
CMFCRibbonEdit Class
Implements an edit control that is positioned on a ribbon.
CMFCRibbonFontComboBox Class
Implements a combo box that contains a list of fonts. You place the combo box on a
ribbon panel.
CMFCRibbonGallery Class
Implements Office 2007-style ribbon galleries.
CMFCRibbonGalleryMenuButton Class
Implements a ribbon menu button that contains ribbon galleries.
CMFCRibbonLabel Class
Implements a non-clickable text label for a ribbon.
CMFCRibbonLinkCtrl Class
Implements a hyperlink that is positioned on a ribbon. The hyperlink opens a Web
page when you click it.
CMFCRibbonMainPanel Class
Implements a ribbon panel that displays when you click the
CMFCRibbonApplicationButton Class.
CMFCRibbonMiniToolBar Class
Implements a contextual popup toolbar.
CMFCRibbonPanel Class
Implements a panel that contains a set of ribbon elements. When the panel is drawn,
it displays as many elements as possible, given the size of the panel.
CMFCRibbonProgressBar Class
Implements a control that visually indicates the progress of a lengthy operation.
CMFCRibbonSlider Class
Implements a slider control that you can add to a ribbon bar or ribbon status bar. The
ribbon slider control resembles the zoom sliders that appear in Office 2007
applications.
CMFCRibbonStatusBar Class
Implements a status bar control that can display ribbon elements.
CMFCRibbonStatusBarPane Class
Implements a ribbon element that you can add to a ribbon status bar.
CMFCRibbonUndoButton Class
Implements a split button, a small button with a downward pointing triangle on the
rightmost part of the main button. Users can click the triangle to display a drop-
down list of their most recently performed actions. Users can then select one or
more actions from the drop-down list. However, if the user clicks the button, only the
last (the most recently added) action on the drop-down list is undone. You should
populate the list with actions as the user performs them.
CMFCShellListCtrl Class
Provides Windows list control functionality and expands it by including the ability to
display a list of shell items.
CMFCShellTreeCtrl Class
Extends CTreeCtrl Class functionality by displaying a hierarchy of Shell items.
CMFCSpinButtonCtrl Class
Supports a visual manager that draws a spin button control.
CMFCStatusBar Class
Implements a status bar similar to the CStatusBar class. However, the CMFCStatusBar
class has features not offered by the CStatusBar class, such as the ability to display
images, animations, and progress bars; and the ability to respond to mouse double-
clicks.
CMFCTabCtrl Class
Provides functionality for a tab control. The tab control displays a dockable window
with flat or three-dimensional tabs at its top or bottom. The tabs can display text and
an image and can change color when active.
CMFCTabToolTipInfo Structure
Provides information about the MDI tab that the user is hovering over.
CMFCTasksPane Class
Implements a list of clickable items (tasks).
CMFCTasksPaneTask Class
Helper class that represents tasks for the task pane control (CMFCTasksPane Class).
The task object represents an item in the task group (CMFCTasksPaneTaskGroup
Class). Each task can have a command that the framework executes when a user
clicks on the task and an icon that appears to the left of the task name.
CMFCTasksPaneTaskGroup Class
Helper class used by the CMFCTasksPane Class control. Objects of type
CMFCTasksPaneTaskGroup represent a task group. The task group is a list of items that
the framework displays in a separate box that has a collapse button. The box can
have an optional caption (group name). If a group is collapsed, the list of tasks is not
visible.
CMFCToolBar Class
Resembles CToolBar Class, but provides additional support for user interface
features. These include flat toolbars, toolbars with hot images, large icons, pager
buttons, locked toolbars, rebar controls, text under images, background images, and
tabbed toolbars. The CMFCToolBar class also contains built-in support for user
customization of toolbars and menus, drag-and-drop between toolbars and menus,
combo box buttons, edit box buttons, color pickers, and roll-up buttons.
CMFCToolBarImages Class
Manages toolbar images loaded from application resources or from files.
CMFCToolBarInfo Class
Contains the resource IDs of toolbar images in various states. CMFCToolBarInfo is a
helper class that is used as a parameter of the CMFCToolBar::LoadToolBarEx method.
CMFCToolBarMenuButton Class
A toolbar button that contains a pop-up menu.
CMFCToolBarsCustomizeDialog Class
A modeless tab dialog box (CPropertySheet Class) that enables the user to customize
the toolbars, menus, keyboard shortcuts, user-defined tools, and visual style in an
application. Typically, the user accesses this dialog box by selecting Customize from
the Tools menu.
CMFCToolTipCtrl Class
An extended tooltip implementation based on the CToolTipCtrl Class. A tooltip based
on the CMFCToolTipCtrl class can display an icon, a label, and a description. You can
customize its visual appearance by using a gradient fill, custom text and border
colors, bold text, rounded corners, or a balloon style.
CMFCToolTipInfo Class
Stores information about the visual appearance of tooltips.
CMFCVisualManager Class
Provides support for changing the appearance of your application at a global level.
The CMFCVisualManager class works together with a class that provides instructions to
draw the GUI controls of your application using a consistent style. These other
classes are referred to as visual managers and they inherit from
CMFCBaseVisualManager .

CMFCVisualManagerOffice2003 Class
Gives an application a Microsoft Office 2003 appearance.
CMFCVisualManagerOffice2007 Class
Gives an application a Microsoft Office 2007 appearance.
CMFCVisualManagerVS2005 Class
Gives an application a Microsoft Visual Studio 2005 appearance.
CMFCVisualManagerWindows Class
Mimics the appearance of Microsoft Windows XP or Microsoft Vista when the user
selects a Windows XP or Vista theme.
CMFCVisualManagerWindows7 Class
Gives an application the appearance of a Windows 7 application.
CMFCWindowsManagerDialog Class
Enables a user to manage MDI child windows in a MDI application.
CMiniFrameWnd Class
Represents a half-height frame window typically seen around floating toolbars.
CMonikerFile Class
Represents a stream of data (IStream) named by an IMoniker.
CMonthCalCtrl Class
Encapsulates the functionality of a month calendar control.
CMouseManager Class
Lets a user associate different commands with a particular CView Class object when
the user double-clicks inside that view.
CMultiDocTemplate Class
Defines a document template that implements the multiple document interface
(MDI).
CMultiLock Class
Represents the access-control mechanism used in controlling access to resources in
a multithreaded program.
CMultiPageDHtmlDialog Class
A multipage dialog displays multiple HTML pages sequentially and handles the
events from each page.
CMultiPaneFrameWnd Class
Extends CPaneFrameWnd Class. It can support multiple panes. Instead of a single
embedded handle to a control bar, CMultiPaneFrameWnd contains a
CPaneContainerManager Class object that enables the user to dock one
CMultiPaneFrameWnd to another and dynamically create multiple floating, tabbed
windows.
CMutex Class
Represents a mutex, which is a synchronization object that allows one thread
mutually exclusive access to a resource.
CNetAddressCtrl Class
The CNetAddressCtrl class represents the network address control, which you can
use to input and validate the format of IPv4, IPv6, and named DNS addresses.
CNotSupportedException Class
Represents an exception that is the result of a request for an unsupported feature.
CObArray Class
Supports arrays of CObject pointers.
CObject Class
The principal base class for the Microsoft Foundation Class Library.
CObList Class
Supports ordered lists of non-unique CObject pointers accessible sequentially or by
pointer value.
COccManager Class
Manages various custom control sites; implemented by COleControlContainer and
COleControlSite objects.

COleBusyDialog Class
Used for the OLE Server Not Responding or Server Busy dialog boxes.
COleChangeIconDialog Class
Used for the OLE Change Icon dialog box.
COleChangeSourceDialog Class
Used for the OLE Change Source dialog box.
COleClientItem Class
Defines the container interface to OLE items.
COleCmdUI Class
Implements a method for MFC to update the state of user-interface objects related to
the IOleCommandTarget -driven features of your application.
COleControl Class
A powerful base class for developing OLE controls.
COleControlContainer Class
Acts as a control container for ActiveX controls.
COleControlModule Class
The base class from which you derive an OLE control module object.
COleControlSite Class
Provides support for custom client-side control interfaces.
COleConvertDialog Class
For more information, see the OLEUICONVERT structure in the Windows SDK.
COleCurrency Class
Encapsulates the CURRENCY data type of OLE automation.
COleDataObject Class
Used in data transfers for retrieving data in various formats from the Clipboard,
through drag and drop, or from an embedded OLE item.
COleDataSource Class
Acts as a cache into which an application places the data that it will offer during data
transfer operations, such as Clipboard or drag-and-drop operations.
COleDBRecordView Class
A view that displays database records in controls.
COleDialog Class
Provides functionality common to dialog boxes for OLE.
COleDispatchDriver Class
Implements the client side of OLE automation.
COleDispatchException Class
Handles exceptions specific to the OLE IDispatch interface, which is a key part of
OLE automation.
COleDocObjectItem Class
Implements Active document containment.
COleDocument Class
The base class for OLE documents that support visual editing.
COleDropSource Class
Enables data to be dragged to a drop target.
COleDropTarget Class
Provides the communication mechanism between a window and the OLE libraries.
COleException Class
Represents an exception condition related to an OLE operation.
COleInsertDialog Class
Used for the OLE Insert Object dialog box.
COleIPFrameWnd Class
The base for your application's in-place editing window.
COleIPFrameWndEx Class
Implements an OLE container that supports MFC. You must derive the in-place frame
window class for your application from the COleIPFrameWndEx class, instead of
deriving it from the COleIPFrameWnd class.
COleLinkingDoc Class
The base class for OLE container documents that support linking to the embedded
items they contain.
COleLinksDialog Class
Used for the OLE Edit Links dialog box.
COleMessageFilter Class
Manages the concurrency required by the interaction of OLE applications.
COleObjectFactory Class
Implements the OLE class factory, which creates OLE objects such as servers,
automation objects, and documents.
COlePasteSpecialDialog Class
Used for the OLE Paste Special dialog box.
COlePropertiesDialog Class
Encapsulates the Windows common OLE Object Properties dialog box.
COlePropertyPage Class
Used to display the properties of a custom control in a graphical interface, similar to
a dialog box.
COleResizeBar Class
A type of control bar that supports resizing of in-place OLE items.
COleSafeArray Class
A class for working with arrays of arbitrary type and dimension.
COleServerDoc Class
The base class for OLE server documents.
COleServerItem Class
Provides the server interface to OLE items.
COleStreamFile Class
Represents a stream of data ( IStream ) in a compound file as part of OLE Structured
Storage.
COleTemplateServer Class
Used for OLE visual editing servers, automation servers, and link containers
(applications that support links to embeddings).
COleUpdateDialog Class
Used for a special case of the OLE Edit Links dialog box, which should be used when
you need to update only existing linked or embedded objects in a document.
COleVariant Class
Encapsulates the VARIANT data type.
CPagerCtrl Class
The CPagerCtrl class wraps the Windows pager control, which can scroll into view a
contained window that does not fit the containing window.
CPageSetupDialog Class
Encapsulates the services provided by the Windows common OLE Page Setup dialog
box with additional support for setting and modifying print margins.
CPaintDC Class
A device-context class derived from CDC Class.
CPalette Class
Encapsulates a Windows color palette.
CPane Class
Enhancement of the CControlBar Class. If you are upgrading an existing MFC project,
you need to replace all occurrences of CControlBar with CPane .
CPaneContainer Class
Basic component of the docking model implemented by MFC. An object of this class
stores pointers to two docking panes or to two instances of CPaneContainer. It also
stores a pointer to the divider that separates the panes (or the containers). By nesting
containers inside containers, the framework can build a binary tree that represents
complex docking layouts. The root of the binary tree is stored in a
CPaneContainerManager Class object.
CPaneContainerManager Class
Manages the storage and display of the current docking layout.
CPaneDialog Class
Supports a modeless, dockable dialog box.
CPaneDivider Class
Divides two panes, divides two groups of panes, or separates a group of panes from
the client area of the main frame window.
CPaneFrameWnd Class
Implements a mini-frame window that contains one pane. The pane fills the client
area of the window.
CParabolicTransitionFromAcceleration Class
Encapsulates a parabolic-acceleration transition.
CPen Class
Encapsulates a Windows graphics device interface (GDI) pen.
CPictureHolder Class
Implements a Picture property, which lets the user display a picture in your control.
CPoint Class
Similar to the Windows POINT structure.
CPrintDialog Class
Encapsulates the services provided by the Windows common dialog box for printing.
CPrintDialogEx Class
Encapsulates the services provided by the Windows Print property sheet.
CProgressCtrl Class
Provides the functionality of the Windows common progress bar control.
CPropertyPage Class
Represents individual pages of a property sheet, otherwise known as a tab dialog
box.
CPropertySheet Class
Represents property sheets, also known as tab dialog boxes.
CPropExchange Class
Supports the implementation of persistence for your OLE controls.
CPtrArray Class
Supports arrays of void pointers.
CPtrList Class
Supports lists of void pointers.
CReBar Class
A control bar that provides layout, persistence, and state information for rebar
controls.
CReBarCtrl Class
Encapsulates the functionality of a rebar control, which is a container for a child
window.
CRecentDockSiteInfo Class
Helper class that stores recent state information for the CPane Class.
CRecentFileList Class
Supports control of the most recently used (MRU) file list.
CRecordset Class
Represents a set of records selected from a data source.
CRecordView Class
A view that displays database records in controls.
CRect Class
Similar to a Windows RECT structure.
CRectTracker Class
Enables an item to be displayed, moved, and resized in different fashions.
CRenderTarget Class
A wrapper for ID2D1RenderTarget .
CResourceException Class
Generated when Windows cannot find or allocate a requested resource.
CReversalTransition Class
Encapsulates a reversal transition.
CRgn Class
Encapsulates a Windows graphics device interface (GDI) region.
CRichEditCntrItem Class
With CRichEditView Class and CRichEditDoc Class, provides the functionality of the
rich edit control within the context of MFC's document view architecture.
CRichEditCtrl Class
Provides the functionality of the rich edit control.
CRichEditDoc Class
With CRichEditView Class and CRichEditCntrItem Class, provides the functionality of
the rich edit control within the context of MFC's document view architecture.
CRichEditView Class
With CRichEditDoc Class and CRichEditCntrItem Class, provides the functionality of
the rich edit control within the context of MFC's document view architecture.
CScrollBar Class
Provides the functionality of a Windows scroll-bar control.
CScrollView Class
A CView Class with scrolling capabilities.
CSemaphore Class
Represents a "semaphore", which is a synchronization object that allows a limited
number of threads in one or more processes to access aMaintains a count of the
number of threads currently accessing a specified resource.
CSettingsStore Class
Wraps Windows API functions, providing an object-oriented interface that you use to
access the registry.
CSettingsStoreSP Class
Helper class that you can use to create instances of the CSettingsStore Class.
CSharedFile Class
The CMemFile Class-derived class that supports shared memory files.
CShellManager Class
Implements several methods that enable you to work with pointers to identifier lists
(PIDLs).
CSimpleException Class
This class is a base class for resource-critical MFC exceptions.
CSingleDocTemplate Class
Defines a document template that implements the single document interface (SDI).
CSingleLock Class
Represents the access-control mechanism used in controlling access to a resource in
a multithreaded program.
CSinusoidalTransitionFromRange Class
Encapsulates a sinusoidal-range transition that has a given range of oscillation.
CSinusoidalTransitionFromVelocity Class
Encapsulates a sinusoidal-velocity transition that has an amplitude that is
determined by the initial velocity of the animation variable.
CSize Class
Similar to the Windows SIZE structure, which implements a relative coordinate or
position.
CSliderCtrl Class
Provides the functionality of the Windows common slider control.
CSmartDockingInfo Class
Defines the appearance of smart docking markers.
CSmoothStopTransition Class
Encapsulates a smooth-stop transition.
CSocket Class
Derives from CAsyncSocket , and represents a higher level of abstraction of the
Windows Sockets API.
CSocketFile Class
A CFile object used for sending and receiving data across a network via Windows
Sockets.
CSpinButtonCtrl Class
Provides the functionality of the Windows common spin button control.
CSplitButton Class
Represents a split button control. The split button control performs a default
behavior when a user clicks the main part of the button, and displays a drop-down
menu when a user clicks the drop-down arrow of the button.
CSplitterWnd Class
Provides the functionality of a splitter window, which is a window that contains
multiple panes.
CSplitterWndEx Class
Represents a customized splitter window.
CStatic Class
Provides the functionality of a Windows static control.
CStatusBar Class
A control bar with a row of text output panes, or "indicators."
CStatusBarCtrl Class
Provides the functionality of the Windows common status bar control.
CStdioFile Class
Represents a C run-time stream file as opened by the run-time function fopen,
_wfopen.
CStringArray Class
Supports arrays of CString objects.
CStringList Class
Supports lists of CString objects.
CSyncObject Class
A pure virtual class that provides functionality common to the synchronization
objects in Win32.
CTabbedPane Class
Implements the functionality of a pane with detachable tabs.
CTabCtrl Class
Provides the functionality of the Windows common tab control.
CTabView Class
Simplifies the use of the tab control class (CTabView Class) in applications that use
MFC's document/view architecture.
CTaskDialog Class
A pop-up dialog box that functions like a message box but can display additional
information to the user. The CTaskDialog also includes functionality for gathering
information from the user.
CToolBar Class
Control bars that have a row of bitmapped buttons and optional separators.
CToolBarCtrl Class
Provides the functionality of the Windows toolbar common control.
CToolTipCtrl Class
Encapsulates the functionality of a "tool tip control," a small pop-up window that
displays a single line of text describing the purpose of a tool in an application.
CTooltipManager Class
Maintains runtime information about tooltips. The CTooltipManager class is
instantiated one time per application.
CTreeCtrl Class
Provides the functionality of the Windows common tree view control.
CTreeView Class
Simplifies use of the tree control and of CTreeCtrl Class, the class that encapsulates
tree-control functionality, with MFC's document-view architecture.
CTypedPtrArray Class
Provides a type-safe "wrapper" for objects of class CPtrArray or CObArray .
CTypedPtrList Class
Provides a type-safe "wrapper" for objects of class CPtrList .
CTypedPtrMap Class
Provides a type-safe "wrapper" for objects of the pointer-map classes CMapPtrToPtr ,
CMapPtrToWord , CMapWordToPtr , and CMapStringToPtr .

CUIntArray Class
Supports arrays of unsigned integers.
CUserException Class
Thrown to stop an end-user operation.
CUserTool Class
Menu item that runs an external application. The Tools tab of the Customize dialog
box (CMFCToolBarsCustomizeDialog Class) enables the user to add user tools, and to
specify the name, command, arguments, and initial directory for each user tool.
CUserToolsManager Class
Maintains the collection of CUserTool Class objects in an application. A user tool is a
menu item that runs an external application. The CUserToolsManager object enables
the user or developer to add new user tools to the application. It supports the
execution of the commands associated with user tools, and it also saves information
about user tools in the Windows registry.
CView Class
Provides the basic functionality for user-defined view classes.
CVSListBox Class
Supports an editable list control.
CWaitCursor Class
Provides a one-line way to show a wait cursor, which is usually displayed as an
hourglass, while you're doing a lengthy operation.
CWinApp Class
The base class from which you derive a Windows application object.
CWinAppEx Class
Handles the application state, saves the state to the registry, loads the state from the
registry, initializes application managers, and provides links to those same
application managers.
CWindowDC Class
Derived from CDC .
CWinFormsControl Class
Provides the basic functionality for hosting of a Windows Forms control.
CWinFormsDialog Class
A wrapper for an MFC dialog class that hosts a Windows Forms user control.
CWinFormsView Class
Provides generic functionality for hosting of a Windows Forms control as an MFC
view.
CWinThread Class
Represents a thread of execution within an application.
CWnd Class
Provides the base functionality of all window classes in the Microsoft Foundation
Class Library.
CWordArray Class
Supports arrays of 16-bit words.

Related Sections
MFC Desktop Applications
Contains links to topics about the classes, global functions, global variables, and
macros that make up the MFC Library.
CAccelerateDecelerateTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Implements an accelerate-decelerate transition.

Syntax
class CAccelerateDecelerateTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CAccelerateDecelerateTransition::CAccelerateDecelerateTransiti Constructs a transition object.


on

Public Methods
NAME DESC RIP T IO N

CAccelerateDecelerateTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CAccelerateDecelerateTransition::m_accelerationRatio The ratio of the time spent accelerating to the duration.

CAccelerateDecelerateTransition::m_decelerationRatio The ratio of the time spent decelerating to the duration.

CAccelerateDecelerateTransition::m_duration The duration of the transition.

CAccelerateDecelerateTransition::m_finalValue The value of the animation variable at the end of the


transition.

Remarks
During an accelerate-decelerate transition, the animation variable speeds up and then slows down over the
duration of the transition, ending at a specified value. You can control how quickly the variable accelerates and
decelerates independently, by specifying different acceleration and deceleration ratios. When the initial velocity is
zero, the acceleration ratio is the fraction of the duration that the variable will spend accelerating; likewise with the
deceleration ratio. If the initial velocity is non-zero, it is the fraction of the time between the velocity reaching zero
and the end of transition. The acceleration ratio and the deceleration ratio should sum to a maximum of 1.0.
Because all transitions are cleared automatically, it's recommended to allocated them using operator new. The
encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then it's
NULL. Changing member variables after creation of this COM object has no effect.
Inheritance Hierarchy
CObject
CBaseTransition
CAccelerateDecelerateTransition

Requirements
Header : afxanimationcontroller.h

CAccelerateDecelerateTransition::CAccelerateDecelerateTransition
Constructs a transition object.

CAccelerateDecelerateTransition(
UI_ANIMATION_SECONDS duration,
DOUBLE finalValue,
DOUBLE accelerationRatio = 0.3,
DOUBLE decelerationRatio = 0.3);

Parameters
duration
The duration of the transition.
finalValue
The value of the animation variable at the end of the transition.
accelerationRatio
The ratio of the time spent accelerating to the duration.
decelerationRatio
The ratio of the time spent decelerating to the duration.

CAccelerateDecelerateTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* *\not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CAccelerateDecelerateTransition::m_accelerationRatio
The ratio of the time spent accelerating to the duration.
DOUBLE m_accelerationRatio;

CAccelerateDecelerateTransition::m_decelerationRatio
The ratio of the time spent decelerating to the duration.

DOUBLE m_decelerationRatio;

CAccelerateDecelerateTransition::m_duration
The duration of the transition.

UI_ANIMATION_SECONDS m_duration;

CAccelerateDecelerateTransition::m_finalValue
The value of the animation variable at the end of the transition.

DOUBLE m_finalValue;

See also
Classes
CAnimateCtrl Class
4/21/2020 • 8 minutes to read • Edit Online

Provides the functionality of the Windows common animation control.

Syntax
class CAnimateCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CAnimateCtrl::CAnimateCtrl Constructs a CAnimateCtrl object.

Public Methods
NAME DESC RIP T IO N

CAnimateCtrl::Close Closes the AVI clip.

CAnimateCtrl::Create Creates an animation control and attaches it to a


CAnimateCtrl object.

CAnimateCtrl::CreateEx Creates an animation control with the specified Windows


extended styles and attaches it to a CAnimateCtrl object.

CAnimateCtrl::IsPlaying Indicates whether an Audio-Video Interleaved (AVI) clip is


playing.

CAnimateCtrl::Open Opens an AVI clip from a file or resource and displays the first
frame.

CAnimateCtrl::Play Plays the AVI clip without sound.

CAnimateCtrl::Seek Displays a selected single frame of the AVI clip.

CAnimateCtrl::Stop Stops playing the AVI clip.

Remarks
This control (and therefore the CAnimateCtrl class) is available only to programs running under Windows 95,
Windows 98, and Windows NT version 3.51 and later.
An animation control is a rectangular window that displays a clip in AVI (Audio Video Interleaved) format— the
standard Windows video/audio format. An AVI clip is a series of bitmap frames, like a movie.
Animation controls can play only simple AVI clips. Specifically, the clips to be played by an animation control must
meet the following requirements:
There must be exactly one video stream and it must have at least one frame.
There can be at most two streams in the file (typically the other stream, if present, is an audio stream,
although the animation control ignores audio information).
The clip must either be uncompressed or compressed with RLE8 compression.
No palette changes are allowed in the video stream.
You can add the AVI clip to your application as an AVI resource, or it can accompany your application as a
separate AVI file.
Because your thread continues executing while the AVI clip is displayed, one common use for an animation
control is to indicate system activity during a lengthy operation. For example, the Find dialog box of File Explorer
displays a moving magnifying glass as the system searches for a file.
If you create a CAnimateCtrl object within a dialog box or from a dialog resource using the dialog editor, it will be
automatically destroyed when the user closes the dialog box.
If you create a CAnimateCtrl object within a window, you may need to destroy it. If you create the CAnimateCtrl
object on the stack, it is destroyed automatically. If you create the CAnimateCtrl object on the heap by using the
new function, you must call delete on the object to destroy it. If you derive a new class from CAnimateCtrl and
allocate any memory in that class, override the CAnimateCtrl destructor to dispose of the allocations.
For more information on using CAnimateCtrl , see Controls and Using CAnimateCtrl.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CAnimateCtrl

Requirements
Header : afxcmn.h

CAnimateCtrl::CAnimateCtrl
Constructs a CAnimateCtrl object.

CAnimateCtrl();

Remarks
You must call the Create member function before you can perform any other operations on the object you create.
Example

// This example creates a secondary thread that implements


// the methods of CAnimateCtrl. The procedure of the thread
// is MyClipThreadProc and the thread was created with the
// code AfxBeginThread( MyClipThreadProc, (LPVOID) pParentWnd).
// The example code creates and initializes an animation control,
// then proceeds to pump messages from the queue until one the
// then proceeds to pump messages from the queue until one the
// private messages WM_STOPCLIP, WM_PLAYCLIP, WM_SHOWFIRSTFRAME or
// WM_SHOWLASTFRAME is received. The appropriate action is done for
// these messages. The thread ends when the WM_STOPCLIP is received.
// NOTE: the thread parameter, pParam, is a pointer to a CWnd object
// that will be the parent of the animation control.

#define WM_STOPCLIP WM_USER + 1


#define WM_PLAYCLIP WM_USER + 2
#define WM_SHOWFIRSTFRAME WM_USER + 3
#define WM_SHOWLASTFRAME WM_USER + 4

UINT MyClipThreadProc(LPVOID pParam)


{
// NOTE: pParentWnd is the parent window of the animation control.
CWnd *pParentWnd = (CWnd *)pParam;
CAnimateCtrl cAnimCtrl;

// Create the animation control.


if (!cAnimCtrl.Create(WS_CHILD | WS_VISIBLE | ACS_CENTER,
CRect(10, 10, 100, 100), pParentWnd, 1))
{
return false;
}

// Open the AVI file.


if (!cAnimCtrl.Open(_T("MyAvi.avi")))
{
return false;
}

// Pump message from the queue until the stop play message is received.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) && (msg.message != WM_STOPCLIP))
{
switch (msg.message)
{
// Start playing from the first frame to the last,
// continuously repeating.
case WM_PLAYCLIP:
if (!cAnimCtrl.Play(0, (UINT)-1, (UINT)-1))
return false;
break;

// Show the first frame.


case WM_SHOWFIRSTFRAME:
if (!cAnimCtrl.Seek(0))
return false;
cAnimCtrl.RedrawWindow();
break;

// Show the last frame.


case WM_SHOWLASTFRAME:
if (!cAnimCtrl.Seek((UINT)-1))
return false;
cAnimCtrl.RedrawWindow();
break;
}

TranslateMessage(&msg);
DispatchMessage(&msg);
}

cAnimCtrl.Stop();
cAnimCtrl.Close();

return true;
}
CAnimateCtrl::Close
Closes the AVI clip that was previously opened in the animation control (if any) and removes it from memory.

BOOL Close();

Return Value
Nonzero if successful; otherwise zero.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

CAnimateCtrl::Create
Creates an animation control and attaches it to a CAnimateCtrl object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the animation control's style. Apply any combination of the windows styles described in the Remarks
section below and the animation control styles described in Animation Control Styles in the Windows SDK.
rect
Specifies the animation control's position and size. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the animation control's parent window, usually a CDialog . It must not be NULL.
nID
Specifies the animation control's ID.
Return Value
Nonzero if successful; otherwise zero.
Remarks
You construct a CAnimateCtrl in two steps. First, call the constructor, and then call Create , which creates the
animation control and attaches it to the CAnimateCtrl object.
Apply the following window styles to an animation control.
WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
If you want to use extended windows styles with your animation control, call CreateEx instead of Create .
In addition to the window styles listed above, you may want to apply one or more of the animation control styles
to an animation control. See the Windows SDK for more information on animation control styles.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

CAnimateCtrl::CreateEx
Creates a control (a child window) and associates it with the CAnimateCtrl object.

virtual BOOL CreateEx(


DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the dwExStyle
parameter for CreateWindowEx in the Windows SDK.
dwStyle
Specifies the animation control's style. Apply any combination of the window and animation control styles
described in Animation Control Styles in the Windows SDK.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client coordinates
of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended style
preface WS_EX_ .

CAnimateCtrl::IsPlaying
Indicates whether an Audio-Video Interleaved (AVI) clip is playing.

BOOL IsPlaying() const;

Return Value
TRUE if an AVI clip is playing; otherwise, FALSE.
Remarks
This method sends the ACM_ISPLAYING message, which is described in the Windows SDK.

CAnimateCtrl::Open
Call this function to open an AVI clip and display its first frame.
BOOL Open(LPCTSTR lpszFileName);
BOOL Open(UINT nID);

Parameters
lpszFileName
A CString object or a pointer to a null-terminated string that contains either the name of the AVI file or the name
of an AVI resource. If this parameter is NULL, the system closes the AVI clip that was previously opened for the
animation control, if any.
nID
The AVI resource identifier. If this parameter is NULL, the system closes the AVI clip that was previously opened
for the animation control, if any.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The AVI resource is loaded from the module that created the animation control.
Open does not support sound in an AVI clip; you can open only silent AVI clips.
If the animation control has the ACS_AUTOPLAY style, the animation control will automatically start playing the clip
immediately after it opens it. It will continue to play the clip in the background while your thread continues
executing. When the clip is done playing, it will automatically be repeated.
If the animation control has the ACS_CENTER style, the AVI clip will be centered in the control and the size of the
control will not change. If the animation control does not have the ACS_CENTER style, the control will be resized
when the AVI clip is opened to the size of the images in the AVI clip. The position of the top left corner of the
control will not change, only the size of the control.
If the animation control has the ACS_TRANSPARENT style, the first frame will be drawn using a transparent
background rather than the background color specified in the animation clip.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

CAnimateCtrl::Play
Call this function to play an AVI clip in an animation control.

BOOL Play(
UINT nFrom,
UINT nTo,
UINT nRep);

Parameters
nFrom
Zero-based index of the frame where playing begins. Value must be less than 65,536. A value of 0 means begin
with the first frame in the AVI clip.
nTo
Zero-based index of the frame where playing ends. Value must be less than 65,536. A value of - 1 means end with
the last frame in the AVI clip.
nRep
Number of times to replay the AVI clip. A value of - 1 means replay the file indefinitely.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The animation control will play the clip in the background while your thread continues executing. If the animation
control has ACS_TRANSPARENT style, the AVI clip will be played using a transparent background rather than the
background color specified in the animation clip.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

CAnimateCtrl::Seek
Call this function to statically display a single frame of your AVI clip.

BOOL Seek(UINT nTo);

Parameters
nTo
Zero-based index of the frame to display. Value must be less than 65,536. A value of 0 means display the first
frame in the AVI clip. A value of -1 means display the last frame in the AVI clip.
Return Value
Nonzero if successful; otherwise zero.
Remarks
If the animation control has ACS_TRANSPARENT style, the AVI clip will be drawn using a transparent background
rather than the background color specified in the animation clip.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

CAnimateCtrl::Stop
Call this function to stop playing an AVI clip in an animation control.

BOOL Stop();

Return Value
Nonzero if successful; otherwise zero.
Example
See the example for CAnimateCtrl::CAnimateCtrl.

See also
CWnd Class
Hierarchy Chart
CAnimateCtrl::Create
ON_CONTROL
CAnimationBaseObject Class
4/21/2020 • 7 minutes to read • Edit Online

The base class for all animation objects.

Syntax
class CAnimationBaseObject : public CObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationBaseObject::CAnimationBaseObject Overloaded. Constructs an animation object.

CAnimationBaseObject::~CAnimationBaseObject The destructor. Called when an animation object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CAnimationBaseObject::ApplyTransitions Adds transitions to storyboard with encapsulated animation


variable.

CAnimationBaseObject::ClearTransitions Removes all related transitions.

CAnimationBaseObject::ContainsVariable Determines whether an animation object contains a particular


animation variable.

CAnimationBaseObject::CreateTransitions Creates transitions associated with an animation object.

CAnimationBaseObject::DetachFromController Detaches an animation object from parent animation


controller.

CAnimationBaseObject::EnableIntegerValueChangedEvent Sets up Integer Value Changed event handler.

CAnimationBaseObject::EnableValueChangedEvent Sets up Value Changed event handler.

CAnimationBaseObject::GetAutodestroyTransitions Tells whether related transition are destroyed automatically.

CAnimationBaseObject::GetGroupID Returns current Group ID.

CAnimationBaseObject::GetObjectID Returns current Object ID.

CAnimationBaseObject::GetUserData Returns user-defined data.


NAME DESC RIP T IO N

CAnimationBaseObject::SetAutodestroyTransitions Sets a flag to automatically destroy transitions.

CAnimationBaseObject::SetID Sets new IDs.

CAnimationBaseObject::SetUserData Sets user-defined data.

Protected Methods
NAME DESC RIP T IO N

CAnimationBaseObject::GetAnimationVariableList Collects pointers to contained animation variables.

CAnimationBaseObject::SetParentAnimationObjects Establishes relationship between animation variables,


contained in an animation object, and their container.

Protected Data Members


NAME DESC RIP T IO N

CAnimationBaseObject::m_bAutodestroyTransitions Specifies whether related transitions should be automatically


destroyed.

CAnimationBaseObject::m_dwUserData Stores user-defined data.

CAnimationBaseObject::m_nGroupID Specifies the Group ID of the animation object.

CAnimationBaseObject::m_nObjectID Specifies the Object ID of the animation object.

CAnimationBaseObject::m_pParentController A pointer to the parent animation controller.

Remarks
This class implements basic methods for all animation objects. An animation object can represent a value, point,
size, rectangle, or color in an application, as well as any custom entity. Animation objects are stored in animation
groups (see CAnimationGroup). Each group can be animated separately and can be treated as an analog of
storyboard. An animation object encapsulates one or more animation variables (see CAnimationVariable),
depending on its logical representation. For example, CAnimationRect contains four animation variables - one
variable for each side of rectangle. Each animation object class exposes overloaded AddTransition method, which
should be used to apply transitions to encapsulated animation variables. An animation object can be identified by
Object ID (optionally) and by Group ID. A Group ID is necessary in order to place an animation object to correct
group, but if a Group ID is not specified, an object is placed in the default group with ID 0. If you call SetID with
different GroupID, an animation object will be moved to another group (a new group is created if necessary).

Inheritance Hierarchy
CObject
CAnimationBaseObject

Requirements
Header : afxanimationcontroller.h
CAnimationBaseObject::~CAnimationBaseObject
The destructor. Called when an animation object is being destroyed.

virtual ~CAnimationBaseObject();

CAnimationBaseObject::ApplyTransitions
Adds transitions to storyboard with encapsulated animation variable.

virtual BOOL ApplyTransitions(


IUIAnimationStoryboard* pStoryboard,
BOOL bDependOnKeyframes);

Parameters
pStoryboard
A pointer to a storyboard.
bDependOnKeyframes
When FALSE, this method adds only those transitions that do not depend on keyframes.
Return Value
TRUE if transitions were added successfully.
Remarks
Adds related transitions, that have been added with AddTransition (overloaded methods in derived classes), to
storyboard.

CAnimationBaseObject::CAnimationBaseObject
Constructs an animation object.

CAnimationBaseObject();

CAnimationBaseObject(
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
User-defined data, which can be associated with animation object and retrieved later at runtime.
Remarks
Constructs an animation objects and assigns default Object ID (0) and Group ID (0).

CAnimationBaseObject::ClearTransitions
Removes all related transitions.

virtual void ClearTransitions(BOOL bAutodestroy);

Parameters
bAutodestroy
Specifies whether to destroy transition objects automatically, or just remove them from the related list.
Remarks
Removes all related transitions and destroys them if bAutodestroy or m_bAutodestroyTransitions flag is TRUE.
Transitions should be destroyed automatically only if they are not allocated on the stack. If the above flags are
FALSE, transitions are just removed from the internal list of related transitions.

CAnimationBaseObject::ContainsVariable
Determines whether an animation object contains a particular animation variable.

virtual BOOL ContainsVariable(IUIAnimationVariable* pVariable);

Parameters
pVariable
A pointer to animation variable.
Return Value
TRUE if the animation variable is contained in the animation object; otherwise FALSE.
Remarks
This method can be used to determine whether an animation variable specified by pVariable is contained within an
animation object. An animation object, depending on its type, may contain several animation variables. For
example, CAnimationColor contains three variables, one for each color component (red, green, and blue). When a
value of animation variable has changed, Windows Animation API sends ValueChanged or IntegerValueChanged
events (if enabled), and the parameter of this event is a pointer to interface IUIAnimationVariable of animation
variable. This method helps to obtain a pointer to animation from a pointer to contained COM object.

CAnimationBaseObject::CreateTransitions
Creates transitions associated with an animation object.

BOOL CreateTransitions();

Return Value
TRUE if transitions were created successfully; otherwise FALSE.
Remarks
Loops over list of animation variables encapsulated in a derived animation object and creates transitions
associated with each animation variable.

CAnimationBaseObject::DetachFromController
Detaches an animation object from parent animation controller.
void DetachFromController();

Remarks
This method is used internally.

CAnimationBaseObject::EnableIntegerValueChangedEvent
Sets up Integer Value Changed event handler.

virtual void EnableIntegerValueChangedEvent(


CAnimationController* pController,
BOOL bEnable);

Parameters
pController
A pointer to a parent controller.
bEnable
Specifies whether to enable, or disable Integer Value Changed event.
Remarks
If the Integer Value Changed event handler is enabled, you can handle this event in
CAnimationController::OnAnimationIntegerValueChanged method, which should be overridden in a
CAnimationController-derived class. This method is called every time the animation integer value has changed.

CAnimationBaseObject::EnableValueChangedEvent
Sets up Value Changed event handler.

virtual void EnableValueChangedEvent(


CAnimationController* pController,
BOOL bEnable);

Parameters
pController
A pointer to a parent controller.
bEnable
Specifies whether to enable, or disable Value Changed event.
Remarks
If the Value Changed event handler is enabled, you can handle this event in
CAnimationController::OnAnimationValueChanged method, which should be overridden in a
CAnimationController-derived class. This method is called every time the animation value has changed.

CAnimationBaseObject::GetAnimationVariableList
Collects pointers to contained animation variables.

virtual void GetAnimationVariableList(


CList<CAnimationVariable*,
CAnimationVariable*>& list) = 0;
Parameters
list
A list that must be filled with animation variables contained in an animation object.
Remarks
This pure virtual method must be overridden in a derived class. An animation object, depending on its type,
contains one or more animation variables. For example, CAnimationPoint contains two variables, for X and Y
coordinates respectively. The base class CAnimationBaseObject implements some generic methods, which act on a
list of animation variables: ApplyTransitions, ClearTransitions, EnableValueChangedEvent,
EnableIntegerValueChangedEvent. These methods call GetAnimationVariableList, which is filled in a derived class
with actual animation variables contained in a particular animation object, then loop over the list and perform
necessary actions. If you create a custom animation object, you must add to list all animation variables contained
in that object.

CAnimationBaseObject::GetAutodestroyTransitions
Tells whether related transition are destroyed automatically.

BOOL GetAutodestroyTransitions() const;

Return Value
If TRUE, related transitions are destroyed automatically; if FALSE, transition objects should be deallocated by calling
application.
Remarks
By default this flag is TRUE. Set this flag only if you allocated transition on the stack and/or transitions should be
deallocated by the calling application.

CAnimationBaseObject::GetGroupID
Returns current Group ID.

UINT32 GetGroupID() const;

Return Value
Current Group ID.
Remarks
Use this method to retrieve Group ID. It's 0 if Group ID has not been set explicitly in constructor or with SetID.

CAnimationBaseObject::GetObjectID
Returns current Object ID.

UINT32 GetObjectID() const;

Return Value
Current Object ID.
Remarks
Use this method to retrieve Object ID. It's 0 if Object ID has not been set explicitly in constructor or with SetID.
CAnimationBaseObject::GetUserData
Returns user-defined data.

DWORD GetUserData() const;

Return Value
A value of custom data.
Remarks
Call this method to retrieve the custom data at runtime. The returned value will be 0 if it was not explicitly
initialized in constructor or with SetUserData.

CAnimationBaseObject::m_bAutodestroyTransitions
Specifies whether related transitions should be automatically destroyed.

BOOL m_bAutodestroyTransitions;

CAnimationBaseObject::m_dwUserData
Stores user-defined data.

DWORD m_dwUserData;

CAnimationBaseObject::m_nGroupID
Specifies the Group ID of the animation object.

UINT32 m_nGroupID;

CAnimationBaseObject::m_nObjectID
Specifies the Object ID of the animation object.

UINT32 m_nObjectID;

CAnimationBaseObject::m_pParentController
A pointer to the parent animation controller.

CAnimationController* m_pParentController;

CAnimationBaseObject::SetAutodestroyTransitions
Sets a flag to automatically destroy transitions.
void SetAutodestroyTransitions(BOOL bValue);

Parameters
bValue
Specifies the auto destroy flag.
Remarks
Set this flag only if you allocated transition objects using operator new. If for some reason transition objects are
allocated on the stack, the auto destroy flag should be FALSE. By default this flag is TRUE.

CAnimationBaseObject::SetID
Sets new IDs.

void SetID(
UINT32 nObjectID,
UINT32 nGroupID = 0);

Parameters
nObjectID
Specifies new Object ID.
nGroupID
Specifies new Group ID.
Remarks
Allows you to change Object ID and Group ID. If the new Group ID differs from the current ID, an animation object
is moved to another group (a new group will be created, if necessary).

CAnimationBaseObject::SetParentAnimationObjects
Establishes relationship between animation variables, contained in an animation object, and their container.

virtual void SetParentAnimationObjects();

Remarks
This helper can be used to establish a relationship between animation variables contained in an animation object,
and their container. It loops over animation variables and sets a back pointer to a parent animation object to each
animation variable. In the current implementation, the actual relationship is established in
CAnimationBaseObject::ApplyTransitions, therefore back pointers are not set until you call
CAnimationGroup::Animate. Knowing the relationship may be helpful when you processing events and need to get
a parent animation object from CAnimationVariable. Use CAnimationVariable::GetParentAnimationObject.

CAnimationBaseObject::SetUserData
Sets user-defined data.

void SetUserData (DWORD dwUserData);

Parameters
dwUserData
Specifies the custom data.
Remarks
Use this method to associate a custom data with an animation object. This data may be retrieved later at runtime
by GetUserData.

See also
Classes
CAnimationColor Class
4/21/2020 • 4 minutes to read • Edit Online

Implements the functionality of a color whose red, green, and blue components can be animated.

Syntax
class CAnimationColor : public CAnimationBaseObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationColor::CAnimationColor Overloaded. Constructs an animation color object.

Public Methods
NAME DESC RIP T IO N

CAnimationColor::AddTransition Adds transitions for Red, Green and Blue components.

CAnimationColor::GetB Provides access to CAnimationVariable representing Blue


component.

CAnimationColor::GetDefaultValue Returns the default values for color components.

CAnimationColor::GetG Provides access to CAnimationVariable representing Green


component.

CAnimationColor::GetR Provides access to CAnimationVariable representing Red


component.

CAnimationColor::GetValue Returns current value.

CAnimationColor::SetDefaultValue Sets default value.

Protected Methods
NAME DESC RIP T IO N

CAnimationColor::GetAnimationVariableList Puts the encapsulated animation variables into a list.


(Overrides CAnimationBaseObject::GetAnimationVariableList.)

Public Operators
NAME DESC RIP T IO N

CAnimationColor::operator COLORREF

CAnimationColor::operator= Assigns color to CAnimationColor.

Protected Data Members


NAME DESC RIP T IO N

CAnimationColor::m_bValue The encapsulated animation variable that represents Blue


component of animation color.

CAnimationColor::m_gValue The encapsulated animation variable that represents Green


component of animation color.

CAnimationColor::m_rValue The encapsulated animation variable that represents Red


component of animation color.

Remarks
The CAnimationColor class encapsulates three CAnimationVariable objects and can represent in applications a
color. For example, you can use this class to animate colors of any object on the screen (like text color, background
color etc). To use this class in application, just instantiate an object of this class, add it to animation controller using
CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to Red, Green
and Blue components.

Inheritance Hierarchy
CObject
CAnimationBaseObject
CAnimationColor

Requirements
Header : afxanimationcontroller.h

CAnimationColor::AddTransition
Adds transitions for Red, Green and Blue components.

void AddTransition(
CBaseTransition* pRTransition,
CBaseTransition* pGTransition,
CBaseTransition* pBTransition);

Parameters
pRTransition
Transition for Red component.
pGTransition
Transition for Green component.
pBTransition
Transition for Blue component.
Remarks
Call this function to add the specified transitions to the internal list of transitions to be applied to animation
variables representing color components. When you add transitions, they are not applied immediately and stored
in an internal list. Transitions are applied (added to a storyboard for a particular value) when you call
CAnimationController::AnimateGroup. If you don't need to apply a transition to one of the color components, you
can pass NULL.

CAnimationColor::CAnimationColor
Constructs a CAnimationColor object.

CAnimationColor();

CAnimationColor(
COLORREF color,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
color
Specifies default color.
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
Specifies user-defined data.
Remarks
The object is constructed with default values for red, green, blue, Object ID and Group ID, which will be set to 0.
They can be changed later at runtime using SetDefaultValue and SetID.

CAnimationColor::GetAnimationVariableList
Puts the encapsulated animation variables into a list.

virtual void GetAnimationVariableList(CList<CAnimationVariable*>& lst);

Parameters
lst
When the function returns, it contains pointers to three CAnimationVariable objects representing red, green and
blue components.

CAnimationColor::GetB
Provides access to CAnimationVariable representing Blue component.
CAnimationVariable& GetB();

Return Value
A reference to encapsulated CAnimationVariable representing Blue component.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Blue component.

CAnimationColor::GetDefaultValue
Returns the default values for color components.

COLORREF GetDefaultValue();

Return Value
A COLORREF value containing defaults for RGB components.
Remarks
Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.

CAnimationColor::GetG
Provides access to CAnimationVariable representing Green component.

CAnimationVariable& GetG();

Return Value
A reference to encapsulated CAnimationVariable representing Green component.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Green component.

CAnimationColor::GetR
Provides access to CAnimationVariable representing Red component.

CAnimationVariable& GetR();

Return Value
A reference to encapsulated CAnimationVariable representing Red component.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Red component.

CAnimationColor::GetValue
Returns current value.

BOOL GetValue(COLORREF& color);


Parameters
color
Output. Contains the current value when this method returns.
Return Value
TRUE, if the current value was successfully retrieved; otherwise FALSE.
Remarks
Call this function to retrieve the current value of animation color. If this method fails or underlying COM objects for
color components have not been initialized, color contains default value, which was previously set in constructor or
by SetDefaultValue.

CAnimationColor::m_bValue
The encapsulated animation variable that represents Blue component of animation color.

CAnimationVariable m_bValue;

CAnimationColor::m_gValue
The encapsulated animation variable that represents Green component of animation color.

CAnimationVariable m_gValue;

CAnimationColor::m_rValue
The encapsulated animation variable that represents Red component of animation color.

CAnimationVariable m_rValue;

CAnimationColor::operator COLORREF
operator COLORREF();

Return Value

CAnimationColor::operator=
Assigns color to CAnimationColor.

void operator=(COLORREF color);

Parameters
color
Specifies new value Animation Color.
Remarks
It's recommended to do that before animation start, because this operator calls SetDefaultValue, which recreates
the underlying COM objects for color components if they have been created. If you subscribed this animation
object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.

CAnimationColor::SetDefaultValue
Sets default value.

void SetDefaultValue(COLORREF color);

Parameters
color
Specifies new default values for red, green and blue components.
Remarks
Use this function to set a default value to animation object. This methods assigns default values to color
components of animation color. It also recreates underlying COM objects if they have been created. If you
subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these
events.

See also
Classes
CAnimationController Class
4/21/2020 • 19 minutes to read • Edit Online

Implements the animation controller, which provides a central interface for creating and managing animations.

Syntax
class CAnimationController : public CObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationController::CAnimationController Constructs an animation controller.

CAnimationController::~CAnimationController The destructor. Called when animation controller object is


being destroyed.

Public Methods
NAME DESC RIP T IO N

CAnimationController::AddAnimationObject Adds an animation object to a group that belongs to the


animation controller.

CAnimationController::AddKeyframeToGroup Adds a keyframe to group.

CAnimationController::AnimateGroup Prepares a group to run animation and optionally schedules it.

CAnimationController::CleanUpGroup Overloaded. Called by the framework to clean up the group


when animation has been scheduled.

CAnimationController::CreateKeyframe Overloaded. Creates a keyframe that depends on transition


and adds it to the specified group.

CAnimationController::EnableAnimationManagerEvent Sets or releases a handler to call when animation manager's


status changes.

CAnimationController::EnableAnimationTimerEventHandler Sets or releases a handler for timing events and handler for
timing updates.

CAnimationController::EnablePriorityComparisonHandler Sets or releases the priority comparison handler to call to


determine whether a scheduled storyboard can be canceled,
concluded, trimmed or compressed.

CAnimationController::EnableStoryboardEventHandler Sets or releases a handler for storyboard status and update


events.
NAME DESC RIP T IO N

CAnimationController::FindAnimationGroup Overloaded. Finds an animation group by its storyboard.

CAnimationController::FindAnimationObject Finds animation object containing a specified animation


variable.

CAnimationController::GetKeyframeStoryboardStart Returns a keyframe that identifies start of storyboard.

CAnimationController::GetUIAnimationManager Provides access to encapsulated IUIAnimationManager object.

CAnimationController::GetUIAnimationTimer Provides access to encapsulated IUIAnimationTimer object.

CAnimationController::GetUITransitionFactory A pointer to IUIAnimationTransitionFactory interface or NULL,


if creation of transition library failed.

CAnimationController::GetUITransitionLibrary Provides access to encapsulated IUIAnimationTransitionLibrary


object.

CAnimationController::IsAnimationInProgress Tells whether at least one group is playing animation.

CAnimationController::IsValid Tells whether animation controller is valid.

CAnimationController::OnAnimationIntegerValueChanged Called by the framework when integer value of animation


variable has changed.

CAnimationController::OnAnimationManagerStatusChanged Called by the framework in response to StatusChanged event


from animation manager.

CAnimationController::OnAnimationTimerPostUpdate Called by the framework after an animation update is finished.

CAnimationController::OnAnimationTimerPreUpdate Called by the framework before an animation update begins.

CAnimationController::OnAnimationTimerRenderingTooSlow Called by the framework when the rendering frame rate for an
animation falls below a minimum desirable frame rate.

CAnimationController::OnAnimationValueChanged Called by the framework when value of animation variable has


changed.

CAnimationController::OnBeforeAnimationStart Called by the framework right before the animation is


scheduled.

CAnimationController::OnHasPriorityCancel Called by the framework to resolve scheduling conflicts.

CAnimationController::OnHasPriorityCompress Called by the framework to resolve scheduling conflicts.

CAnimationController::OnHasPriorityConclude Called by the framework to resolve scheduling conflicts.

CAnimationController::OnHasPriorityTrim Called by the framework to resolve scheduling conflicts.

CAnimationController::OnStoryboardStatusChanged Called by the framework when storyboard status has


changed.

CAnimationController::OnStoryboardUpdated Called by the framework when storyboard has been updated.


NAME DESC RIP T IO N

CAnimationController::RemoveAllAnimationGroups Removes all animation groups from animation controller.

CAnimationController::RemoveAnimationGroup Removes an animation group with specified ID from animation


controller.

CAnimationController::RemoveAnimationObject Remove an animation object from animation controller.

CAnimationController::RemoveTransitions Removes transitions from animation objects that belong to


the specified group.

CAnimationController::ScheduleGroup Schedules an animation.

CAnimationController::SetRelatedWnd Establishes a relationship between animation controller and a


window.

CAnimationController::UpdateAnimationManager Directs the animation manager to update the values of all


animation variables.

Protected Methods
NAME DESC RIP T IO N

CAnimationController::CleanUpGroup Overloaded. A helper that cleans up the group.

CAnimationController::OnAfterSchedule Called by the framework when an animation for the specified


group has just been scheduled.

Protected Data Members


NAME DESC RIP T IO N

CAnimationController::gkeyframeStoryboardStart A keyframe that represents start of storyboard.

CAnimationController::m_bIsValid Specifies whether an animation controller is valid or not. This


member is set to FALSE if current OS does not support
Windows Animation API.

CAnimationController::m_lstAnimationGroups A list of animation groups that belong to this animation


controller.

CAnimationController::m_pAnimationManager Stores a pointer to Animation Manager COM object.

CAnimationController::m_pAnimationTimer Stores a pointer to Animation Timer COM object.

CAnimationController::m_pRelatedWnd A pointer to a related CWnd object, which can be


automatically redrawn when the status of animation manager
has changed, or post update event has occurred. Can be
NULL.

CAnimationController::m_pTransitionFactory Stores a pointer to Transition Factory COM object.

CAnimationController::m_pTransitionLibrary Stores a pointer to Transition Library COM object.


Remarks
The CAnimationController class is the key class that manages animations. You may create one or more instances of
animation controller in an application and, optionally, connect an instance of animation controller to a CWnd object
using CAnimationController::SetRelatedWnd. This connection is required to send WM_PAINT messages to the
related window automatically when animation manager status has changed or animation timer has been updated.
If you do not enable this relation, you must redraw a window that displays an animation manually. For this purpose
you can derive a class from CAnimationController and override OnAnimationManagerStatusChanged and/or
OnAnimationTimerPostUpdate and invalidate one or more windows when necessary.

Inheritance Hierarchy
CObject
CAnimationController

Requirements
Header : afxanimationcontroller.h

CAnimationController::~CAnimationController
The destructor. Called when animation controller object is being destroyed.

virtual ~CAnimationController(void);

CAnimationController::AddAnimationObject
Adds an animation object to a group that belongs to the animation controller.

CAnimationGroup* AddAnimationObject(CAnimationBaseObject* pObject);

Parameters
pObject
A pointer to an animation object.
Return Value
A pointer to existing or new animation group where pObject has been added if function succeeds; NULL if pObject
has already been added to a group that belongs to another animation controller.
Remarks
Call this method to add an animation object to the animation controller. An object will be added to a group
according to object's GroupID (see CAnimationBaseObject::SetID). The animation controller will create a new group
if it's the first object being added with the specified GroupID. An animation object can be added to one animation
controller only. If you need to add an object to another controller, call RemoveAnimationObject first. If you call
SetID with new GroupID for an object that has been already added to a group, the object will be removed from the
old group and added to another group with specified ID.

CAnimationController::AddKeyframeToGroup
Adds a keyframe to group.
BOOL AddKeyframeToGroup(
UINT32 nGroupID,
CBaseKeyFrame* pKeyframe);

Parameters
nGroupID
Specifies Group ID.
pKeyframe
A pointer to a keyframe.
Return Value
TRUE if the function succeeds; otherwise FALSE.
Remarks
Usually you don't need to call this method, use CAnimationController::CreateKeyframe instead, which creates and
adds the created keyframe to a group automatically.

CAnimationController::AnimateGroup
Prepares a group to run animation and optionally schedules it.

BOOL AnimateGroup(
UINT32 nGroupID,
BOOL bScheduleNow = TRUE);

Parameters
nGroupID
Specifies GroupID.
bScheduleNow
Specifies whether to run animation right away.
Return Value
TRUE if animation was successfully scheduled and run.
Remarks
This method does the actual work creating storyboard, adding animation variables, applying transitions and setting
keyframes. It's possible to delay scheduling if you set bScheduleNow to FALSE. In this case the specified group will
hold a storyboard that has been set up for animation. At that point you can setup events for the storyboard and
animation variables. When you actually need to run the animation call CAnimationController::ScheduleGroup.

CAnimationController::CAnimationController
Constructs an animation controller.

CAnimationController(void);

CAnimationController::CleanUpGroup
Called by the framework to clean up the group when animation has been scheduled.
void CleanUpGroup(UINT32 nGroupID);
void CleanUpGroup(CAnimationGroup* pGroup);

Parameters
nGroupID
Specifies GroupID.
pGroup
A pointer to animation group to clean.
Remarks
This method removes all transitions and keyframes from the specified group, because they are not relevant after an
animation has been scheduled.

CAnimationController::CreateKeyframe
Creates a keyframe that depends on transition and adds it to the specified group.

CKeyFrame* CreateKeyframe(
UINT32 nGroupID,
CBaseTransition* pTransition);

CKeyFrame* CreateKeyframe(
UINT32 nGroupID,
CBaseKeyFrame* pKeyframe,
UI_ANIMATION_SECONDS offset = 0.0);

Parameters
nGroupID
Specifies Group ID for which keyframe is created.
pTransition
A pointer to transition. Keyframe will be inserted to storyboard after this transition.
pKeyframe
A pointer to base keyframe for this keyframe.
offset
Offset in seconds from the base keyframe specified by pKeyframe.
Return Value
A pointer to newly created keyframe if the function succeeds.
Remarks
You can store the returned pointer and base other keyframes on the newly created keyframe (see the second
overload). It's possible to begin transitions at keyframes - see CBaseTransition::SetKeyframes. You don't need to
delete keyframes created in this way, because they are deleted automatically by animation groups. Be careful when
creating keyframes based on other keyframes and transitions and avoid circular references.

CAnimationController::EnableAnimationManagerEvent
Sets or releases a handler to call when animation manager's status changes.

virtual BOOL EnableAnimationManagerEvent(BOOL bEnable = TRUE);


Parameters
bEnable
Specifies whether to set or release a handler.
Return Value
TRUE if the handler was successfully set or released.
Remarks
When a handler is set (enabled) Windows Animation calls OnAnimationManagerStatusChanged when animation
manager's status changes.

CAnimationController::EnableAnimationTimerEventHandler
Sets or releases a handler for timing events and handler for timing updates.

virtual BOOL EnableAnimationTimerEventHandler(


BOOL bEnable = TRUE,
UI_ANIMATION_IDLE_BEHAVIOR idleBehavior = UI_ANIMATION_IDLE_BEHAVIOR_DISABLE);

Parameters
bEnable
Specifies whether to set or release the handlers.
idleBehavior
Specifies idle behavior for timer update handler.
Return Value
TRUE if handlers were successfully set or released; FALSE if this method is called for a second time without
releasing the handlers first, or if any other error occurs.
Remarks
When the handlers are set (enabled) Windows Animation API calls OnAnimationTimerPreUpdate,
OnAnimationTimerPostUpdate, OnRenderingTooSlow methods. You need to enable animation timers to allow
Windows Animation API update storyboards. Otherwise you'll need to call
CAnimationController::UpdateAnimationManager in order to direct the animation manager to update the values of
all animation variables.

CAnimationController::EnablePriorityComparisonHandler
Sets or releases the priority comparison handler to call to determine whether a scheduled storyboard can be
canceled, concluded, trimmed or compressed.

virtual BOOL EnablePriorityComparisonHandler(DWORD dwHandlerType);

Parameters
dwHandlerType
A combination of UI_ANIMATION_PHT_ flags (see remarks), which specifies what handlers to set or release.
Return Value
TRUE if the handler was successfully set or released.
Remarks
When a handler is set (enabled) Windows Animation calls the following virtual methods depending on
dwHandlerType: OnHasPriorityCancel, OnHasPriorityConclude, OnHasPriorityTrim, OnHasPriorityCompress.
dwHandler can be a combination of the following flags: UI_ANIMATION_PHT_NONE - release all handlers
UI_ANIMATION_PHT_CANCEL - set Cancel comparison handler UI_ANIMATION_PHT_CONCLUDE - set Conclude
comparison handler UI_ANIMATION_PHT_COMPRESS - set Compress comparison handler
UI_ANIMATION_PHT_TRIM - set Trim comparison handler UI_ANIMATION_PHT_CANCEL_REMOVE - remove Cancel
comparison handler UI_ANIMATION_PHT_CONCLUDE_REMOVE - remove Conclude comparison handler
UI_ANIMATION_PHT_COMPRESS_REMOVE - remove Compress comparison handler
UI_ANIMATION_PHT_TRIM_REMOVE - remove Trim comparison handler

CAnimationController::EnableStoryboardEventHandler
Sets or releases a handler for storyboard status and update events.

virtual BOOL EnableStoryboardEventHandler(


UINT32 nGroupID,
BOOL bEnable = TRUE);

Parameters
nGroupID
Specifies Group ID.
bEnable
Specifies whether to set or release a handler.
Return Value
TRUE if the handler was successfully set or released; FALSE if the specified animation group is now found or
animation for the specified group has not been initiated and its internal storyboard is NULL.
Remarks
When a handler is set (enabled) Windows Animation API calls OnStoryboardStatusChanges and
OnStoryboardUpdated virtual methods. A handler must be set after CAnimationController::Animate has been
called for the specified animation group, because it creates encapsulated IUIAnimationStoryboard object.

CAnimationController::FindAnimationGroup
Finds an animation group by its Group ID.

CAnimationGroup* FindAnimationGroup(UINT32 nGroupID);


CAnimationGroup* FindAnimationGroup(IUIAnimationStoryboard* pStoryboard);

Parameters
nGroupID
Specifies a GroupID.
pStoryboard
A pointer to a storyboard.
Return Value
A pointer to animation group or NULL if the group with specified ID is not found.
Remarks
Use this method to find an animation group at runtime. A group is created and added to the internal list of
animation groups when a first animation object with particular GroupID is being added to animation controller.
CAnimationController::FindAnimationObject
Finds animation object containing a specified animation variable.

BOOL FindAnimationObject(
IUIAnimationVariable* pVariable,
CAnimationBaseObject** ppObject,
CAnimationGroup** ppGroup);

Parameters
pVariable
A pointer to animation variable.
ppObject
Output. Contains a pointer to animation object or NULL.
ppGroup
Output. Contains a pointer to animation group that holds the animation object, or NULL.
Return Value
TRUE if object was found; otherwise FALSE.
Remarks
Called from event handlers when it's required to find an animation object from incoming animation variable.

CAnimationController::gkeyframeStoryboardStart
A keyframe that represents start of storyboard.

static CBaseKeyFrame gkeyframeStoryboardStart;

CAnimationController::GetKeyframeStoryboardStart
Returns a keyframe that identifies start of storyboard.

static CBaseKeyFrame* GetKeyframeStoryboardStart();

Return Value
A pointer to base keyframe, which identifies start of storyboard.
Remarks
Obtain this keyframe to base any other keyframes or transitions on the moment in time when a storyboard starts.

CAnimationController::GetUIAnimationManager
Provides access to encapsulated IUIAnimationManager object.

IUIAnimationManager* GetUIAnimationManager();

Return Value
A pointer to IUIAnimationManager interface or NULL, if creation of animation manager failed.
Remarks
If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent
calls on CAnimationController::IsValid return FALSE. You may need to access IUIAnimationManager in order to call
its interface methods, which are not wrapped by animation controller.

CAnimationController::GetUIAnimationTimer
Provides access to encapsulated IUIAnimationTimer object.

IUIAnimationTimer* GetUIAnimationTimer();

Return Value
A pointer to IUIAnimationTimer interface or NULL, if creation of animation timer failed.
Remarks
If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent
calls on CAnimationController::IsValid return FALSE.

CAnimationController::GetUITransitionFactory
A pointer to IUIAnimationTransitionFactory interface or NULL, if creation of transition library failed.

IUIAnimationTransitionFactory* GetUITransitionFactory();

Return Value
A pointer to IUIAnimationTransitionFactory or NULL, if creation of transition factory failed.
Remarks
If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent
calls on CAnimationController::IsValid return FALSE.

CAnimationController::GetUITransitionLibrary
Provides access to encapsulated IUIAnimationTransitionLibrary object.

IUIAnimationTransitionLibrary* GetUITransitionLibrary();

Return Value
A pointer to IUIAnimationTransitionLibrary interface or NULL, if creation of transition library failed.
Remarks
If current OS does not support Windows Animation API, this method returns NULL and after that all subsequent
calls on CAnimationController::IsValid return FALSE.

CAnimationController::IsAnimationInProgress
Tells whether at least one group is playing animation.

virtual BOOL IsAnimationInProgress();

Return Value
TRUE if there is an animation in progress for this animation controller; otherwise FALSE.
Remarks
Checks status of animation manager and returns TRUE if the status is UI_ANIMATION_MANAGER_BUSY.

CAnimationController::IsValid
Tells whether animation controller is valid.

BOOL IsValid() const;

Return Value
TRUE if animation controller is valid; otherwise FALSE.
Remarks
This method returns FALSE only if Windows Animation API is not supported on the current OS and creation of
animation manager failed because it's not registered. You need to call GetUIAnimationManager at least once after
initialization of COM libraries to cause setting of this flag.

CAnimationController::m_bIsValid
Specifies whether an animation controller is valid or not. This member is set to FALSE if current OS does not
support Windows Animation API.

BOOL m_bIsValid;

CAnimationController::m_lstAnimationGroups
A list of animation groups that belong to this animation controller.

CList<CAnimationGroup*, CAnimationGroup*> m_lstAnimationGroups;

CAnimationController::m_pAnimationManager
Stores a pointer to Animation Manager COM object.

ATL::CComPtr<IUIAnimationManager> m_pAnimationManager;

CAnimationController::m_pAnimationTimer
Stores a pointer to Animation Timer COM object.

ATL::CComPtr<IUIAnimationTimer> m_pAnimationTimer;

CAnimationController::m_pRelatedWnd
A pointer to a related CWnd object, which can be automatically redrawn when the status of animation manager has
changed, or post update event has occurred. Can be NULL.
CWnd* m_pRelatedWnd;

CAnimationController::m_pTransitionFactory
Stores a pointer to Transition Factory COM object.

ATL::CComPtr<IUIAnimationTransitionFactory> m_pTransitionFactory;

CAnimationController::m_pTransitionLibrary
Stores a pointer to Transition Library COM object.

ATL::CComPtr<IUIAnimationTransitionLibrary> m_pTransitionLibrary;

CAnimationController::OnAfterSchedule
Called by the framework when an animation for the specified group has just been scheduled.

virtual void OnAfterSchedule(CAnimationGroup* pGroup);

Parameters
pGroup
A pointer to an animation group, which has been scheduled.
Remarks
The default implementation removes keyframes from the specified group and transitions from animation variables
that belong to the specified group. Can be overridden in a derived class to take any additional actions upon
animation schedule.

CAnimationController::OnAnimationIntegerValueChanged
Called by the framework when integer value of animation variable has changed.

virtual void OnAnimationIntegerValueChanged(


CAnimationGroup* pGroup,
CAnimationBaseObject* pObject,
IUIAnimationVariable* variable,
INT32 newValue,
INT32 prevValue);

Parameters
pGroup
A pointer to an animation group that holds an animation object whose value has changed.
pObject
A pointer to an animation object that contains an animation variable whose value has changed.
variable
A pointer to an animation variable.
newValue
Specifies new value.
prevValue
Specifies previous value.
Remarks
This method is called if you enable animation variable events with EnableIntegerValueChangedEvent called for a
specific animation variable or animation object. It can be overridden in a derived class to take application-specific
actions.

CAnimationController::OnAnimationManagerStatusChanged
Called by the framework in response to StatusChanged event from animation manager.

virtual void OnAnimationManagerStatusChanged(


UI_ANIMATION_MANAGER_STATUS newStatus,
UI_ANIMATION_MANAGER_STATUS previousStatus);

Parameters
newStatus
New animation manager status.
previousStatus
Previous animation manager status.
Remarks
This method is called if you enable animation manager events with EnableAnimationManagerEvent. It can be
overridden in a derived class to take application-specific actions. The default implementation updates a related
window if it has been set with SetRelatedWnd.

CAnimationController::OnAnimationTimerPostUpdate
Called by the framework after an animation update is finished.

virtual void OnAnimationTimerPostUpdate();

Remarks
This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler. It can be
overridden in a derived class to take application-specific actions.

CAnimationController::OnAnimationTimerPreUpdate
Called by the framework before an animation update begins.

virtual void OnAnimationTimerPreUpdate();

Remarks
This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler. It can be
overridden in a derived class to take application-specific actions.

CAnimationController::OnAnimationTimerRenderingTooSlow
Called by the framework when the rendering frame rate for an animation falls below a minimum desirable frame
rate.

virtual void OnAnimationTimerRenderingTooSlow(UINT32 fps);

Parameters
fps
The current frame rate in frames per second.
Remarks
This method is called if you enable timer event handlers using EnableAnimationTimerEventHandler. It can be
overridden in a derived class to take application-specific actions. The minimum desirable frame rate is specified by
calling IUIAnimationTimer::SetFrameRateThreshold.

CAnimationController::OnAnimationValueChanged
Called by the framework when value of animation variable has changed.

virtual void OnAnimationValueChanged(


CAnimationGroup* pGroup,
CAnimationBaseObject* pObject,
IUIAnimationVariable* variable,
DOUBLE newValue,
DOUBLE prevValue);

Parameters
pGroup
A pointer to an animation group that holds an animation object whose value has changed.
pObject
A pointer to an animation object that contains an animation variable whose value has changed.
variable
A pointer to an animation variable.
newValue
Specifies new value.
prevValue
Specifies previous value.
Remarks
This method is called if you enable animation variable events with EnableValueChangedEvent called for a specific
animation variable or animation object. It can be overridden in a derived class to take application-specific actions.

CAnimationController::OnBeforeAnimationStart
Called by the framework right before the animation is scheduled.

virtual void OnBeforeAnimationStart(CAnimationGroup* pGroup);

Parameters
pGroup
A pointer to an animation group whose animation is about to start.
Remarks
This call is routed to related CWnd and can be overridden in a derived class to perform any additional actions
before the animation starts for the specified group.

CAnimationController::OnHasPriorityCancel
Called by the framework to resolve scheduling conflicts.

virtual BOOL OnHasPriorityCancel(


CAnimationGroup* pGroupScheduled,
CAnimationGroup* pGroupNew,
UI_ANIMATION_PRIORITY_EFFECT priorityEffect);

Parameters
pGroupScheduled
The group that owns the currently scheduled storyboard.
pGroupNew
The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by
pGroupScheduled.
priorityEffect
The potential effect on pGroupNew if pGroupScheduled has a higher priority.
Return Value
Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
pGroupScheduled has priority.
Remarks
This method is called if you enable priority comparison events using
CAnimationController::EnablePriorityComparisonHandler and specify UI_ANIMATION_PHT_CANCEL. It can be
overridden in a derived class to take application-specific actions. Read Windows Animation API documentation for
more information about Conflict Management.

CAnimationController::OnHasPriorityCompress
Called by the framework to resolve scheduling conflicts.

virtual BOOL OnHasPriorityCompress(


CAnimationGroup* pGroupScheduled,
CAnimationGroup* pGroupNew,
UI_ANIMATION_PRIORITY_EFFECT priorityEffect);

Parameters
pGroupScheduled
The group that owns the currently scheduled storyboard.
pGroupNew
The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by
pGroupScheduled.
priorityEffect
The potential effect on pGroupNew if pGroupScheduled has a higher priority.
Return Value
Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
pGroupScheduled has priority.
Remarks
This method is called if you enable priority comparison events using
CAnimationController::EnablePriorityComparisonHandler and specify UI_ANIMATION_PHT_COMPRESS. It can be
overridden in a derived class to take application-specific actions. Read Windows Animation API documentation for
more information about Conflict Management.

CAnimationController::OnHasPriorityConclude
Called by the framework to resolve scheduling conflicts.

virtual BOOL OnHasPriorityConclude(


CAnimationGroup* pGroupScheduled,
CAnimationGroup* pGroupNew,
UI_ANIMATION_PRIORITY_EFFECT priorityEffect);

Parameters
pGroupScheduled
The group that owns the currently scheduled storyboard.
pGroupNew
The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by
pGroupScheduled.
priorityEffect
The potential effect on pGroupNew if pGroupScheduled has a higher priority.
Return Value
Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
pGroupScheduled has priority.
Remarks
This method is called if you enable priority comparison events using
CAnimationController::EnablePriorityComparisonHandler and specify UI_ANIMATION_PHT_CONCLUDE. It can be
overridden in a derived class to take application-specific actions. Read Windows Animation API documentation for
more information about Conflict Management.

CAnimationController::OnHasPriorityTrim
Called by the framework to resolve scheduling conflicts.

virtual BOOL OnHasPriorityTrim(


CAnimationGroup* pGroupScheduled,
CAnimationGroup* pGroupNew,
UI_ANIMATION_PRIORITY_EFFECT priorityEffect);

Parameters
pGroupScheduled
The group that owns the currently scheduled storyboard.
pGroupNew
The group that owns the new storyboard that is in scheduling conflict with the scheduled storyboard owned by
pGroupScheduled.
priorityEffect
The potential effect on pGroupNew if pGroupScheduled has a higher priority.
Return Value
Should return TRUE if storyboard owned by pGroupNew has priority. Should return FALSE if storyboard owned by
pGroupScheduled has priority.
Remarks
This method is called if you enable priority comparison events using
CAnimationController::EnablePriorityComparisonHandler and specify UI_ANIMATION_PHT_TRIM. It can be
overridden in a derived class to take application-specific actions. Read Windows Animation API documentation for
more information about Conflict Management.

CAnimationController::OnStoryboardStatusChanged
Called by the framework when storyboard status has changed.

virtual void OnStoryboardStatusChanged(


CAnimationGroup* pGroup,
UI_ANIMATION_STORYBOARD_STATUS newStatus,
UI_ANIMATION_STORYBOARD_STATUS previousStatus);

Parameters
pGroup
A pointer to an animation group that owns the storyboard whose status has changed.
newStatus
Specifies the new status.
previousStatus
Specifies the previous status.
Remarks
This method is called if you enable storyboard events using CAnimationController::EnableStoryboardEventHandler.
It can be overridden in a derived class to take application-specific actions.

CAnimationController::OnStoryboardUpdated
Called by the framework when storyboard has been updated.

virtual void OnStoryboardUpdated(CAnimationGroup* pGroup);

Parameters
pGroup
A pointer to a group that owns the storyboard.
Remarks
This method is called if you enable storyboard events using CAnimationController::EnableStoryboardEventHandler.
It can be overridden in a derived class to take application-specific actions.

CAnimationController::RemoveAllAnimationGroups
Removes all animation groups from animation controller.

void RemoveAllAnimationGroups();

Remarks
All groups will be deleted, their pointer, if stored at the application level, must be invalidated. If
CAnimationGroup::m_bAutodestroyAnimationObjects for a group being deleted is TRUE, all animation objects that
belong to that group will be deleted; otherwise their references to parent animation controller will be set to NULL
and they can be added to another controller.

CAnimationController::RemoveAnimationGroup
Removes an animation group with specified ID from animation controller.

void RemoveAnimationGroup(UINT32 nGroupID);

Parameters
nGroupID
Specifies animation group ID.
Remarks
This method removes an animation group from the internal list of groups and deletes it, therefore if you stored a
pointer to that animation group, it must be invalidated. If CAnimationGroup::m_bAutodestroyAnimationObjects is
TRUE, all animation objects that belong to that group will be deleted; otherwise their references to parent
animation controller will be set to NULL and they can be added to another controller.

CAnimationController::RemoveAnimationObject
Remove an animation object from animation controller.

void RemoveAnimationObject(
CAnimationBaseObject* pObject,
BOOL bNoDelete = FALSE);

Parameters
pObject
A pointer to an animation object.
bNoDelete
If this parameter is TRUE the object will not be deleted upon remove.
Remarks
Removes an animation object from animation controller and animation group. Call this function if a particular
object should not be animated anymore, or if you need to move the object to another animation controller. In the
last case bNoDelete must be TRUE.

CAnimationController::RemoveTransitions
Removes transitions from animation objects that belong to the specified group.

void RemoveTransitions(UINT32 nGroupID);


Parameters
nGroupID
Specifies Group ID.
Remarks
The group loops over its animation objects and calls ClearTransitions(FALSE) for each animation object. This
method is called by the framework after animation has been scheduled.

CAnimationController::ScheduleGroup
Schedules an animation.

BOOL ScheduleGroup(
UINT32 nGroupID,
UI_ANIMATION_SECONDS time = 0.0);

Parameters
nGroupID
Specifies animation Group ID to schedule.
time
Specifies time to schedule.
Return Value
TRUE if animation was scheduled successfully. FALSE if storyboard has not been created, or other error occurs.
Remarks
You must call AnimateGroup with parameter bScheduleNow set to FALSE prior ScheduleGroup. You can specify the
desired animation time obtained from IUIAnimationTimer::GetTime. If the time parameter is 0.0, the animation is
scheduled for the current time.

CAnimationController::SetRelatedWnd
Establishes a relationship between animation controller and a window.

void SetRelatedWnd(CWnd* pWnd);

Parameters
pWnd
A pointer to window object to set.
Remarks
If a related CWnd object is set, the animation controller can automatically update it (send WM_PAINT message)
when the status of animation manager has changed or timer post update event has occurred.

CAnimationController::UpdateAnimationManager
Directs the animation manager to update the values of all animation variables.

virtual void UpdateAnimationManager();

Remarks
Calling this method advances the animation manager to current time, changing statuses of storyboards as
necessary and updating any animation variables to appropriate interpolated values. Internally this method calls
IUIAnimationTimer::GetTime(timeNow) and IUIAnimationManager::Update(timeNow). Override this method in a
derived class to customize this behavior.

See also
Classes
CAnimationGroup Class
4/21/2020 • 5 minutes to read • Edit Online

Implements an animation group, which combines an animation storyboard, animation objects, and transitions to
define an animation.

Syntax
class CAnimationGroup;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationGroup::CAnimationGroup Constructs an animation group.

CAnimationGroup::~CAnimationGroup The destructor. Called when an animation group is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CAnimationGroup::Animate Animates a group.

CAnimationGroup::ApplyTransitions Applies transitions to animation objects.

CAnimationGroup::FindAnimationObject Finds an animation object that contains the specified


animation variable.

CAnimationGroup::GetGroupID Returns GroupID.

CAnimationGroup::RemoveKeyframes Removes and optionally destroys all keyframes that belong to


an animation group.

CAnimationGroup::RemoveTransitions Removes transitions from animation objects that belong to an


animation group.

CAnimationGroup::Schedule Schedules an animation at the specified time.

CAnimationGroup::SetAutodestroyTransitions Directs all animation objects that belong to group


automatically destroy transitions.

Protected Methods
NAME DESC RIP T IO N

CAnimationGroup::AddKeyframes A helper that adds keyframes to a storyboard.

CAnimationGroup::AddTransitions A helper that adds transitions to a storyboard.

CAnimationGroup::CreateTransitions A helper that creates COM transition objects.

Public Data Members


NAME DESC RIP T IO N

CAnimationGroup::m_bAutoclearTransitions Specifies how to clear transitions from animation objects that


belong to group. If this member is TRUE, transitions are
removed automatically when an animation has been
scheduled. Otherwise you need to remove transitions
manually.

CAnimationGroup::m_bAutodestroyAnimationObjects Specifies how to destroy animation objects. If this parameter is


TRUE, animation objects will be destroyed automatically when
the group is destroyed. Otherwise animation objects must be
destroyed manually. The default value is FALSE. Set this value
to TRUE only if all animation objects that belong to group are
allocated dynamically with operator new.

CAnimationGroup::m_bAutodestroyKeyframes Specifies how to destroy keyframes. If this value is TRUE, all


keyframes are removed and destroyed; otherwise they are
removed from the list only. The default value is TRUE.

CAnimationGroup::m_lstAnimationObjects Contains a list of animation objects.

CAnimationGroup::m_lstKeyFrames Contains a list of keyframes.

CAnimationGroup::m_pStoryboard Points to animation storyboard. This pointer is valid only after


call on Animate.

Protected Data Members


NAME DESC RIP T IO N

CAnimationGroup::m_nGroupID A unique identifier of animation group.

CAnimationGroup::m_pParentController A pointer to animation controller this group belongs to.

Remarks
Animation groups are created automatically by animation controller (CAnimationController) when you add
animation objects using CAnimationController::AddAnimationObject. An animation group is identified by GroupID,
which is usually taken as a parameter to manipulate animation groups. The GroupID is taken from the first
animation object being added to a new animation group. An encapsulated animation storyboard is created after
you call CAnimationController::AnimateGroup and can be accessed via public member m_pStoryboard.

Inheritance Hierarchy
CAnimationGroup
Requirements
Header : afxanimationcontroller.h

CAnimationGroup::~CAnimationGroup
The destructor. Called when an animation group is being destroyed.

~CAnimationGroup();

CAnimationGroup::AddKeyframes
A helper that adds keyframes to a storyboard.

void AddKeyframes(IUIAnimationStoryboard* pStoryboard, BOOL bAddDeep);

Parameters
pStoryboard
A pointer to a storyboard COM object.
bAddDeep
Specifies whether this method should add to the storyboard keyframes that depend on other keyframes.

CAnimationGroup::AddTransitions
A helper that adds transitions to a storyboard.

void AddTransitions(
IUIAnimationStoryboard* pStoryboard,
BOOL bDependOnKeyframes);

Parameters
pStoryboard
A pointer to a storyboard COM object.
bDependOnKeyframes

CAnimationGroup::Animate
Animates a group.

BOOL Animate(
IUIAnimationManager* pManager,
IUIAnimationTimer* pTimer,
BOOL bScheduleNow);

Parameters
pManager
pTimer bScheduleNow
Return Value
TRUE if the method succeeds; otherwise FALSE.
Remarks
This method creates an internal storyboard, creates and applies transitions and schedules an animation if
bScheduleNow is TRUE. If bScheduleNow is FALSE, you need to call Schedule to start animation at the specified
time.

CAnimationGroup::ApplyTransitions
Applies transitions to animation objects.

void ApplyTransitions();

Remarks
This method ASSERTS in debug mode if storyboard has not been created. It creates all transitions first, then adds
"static" keyframes (keyframes that depend on offsets), adds transitions that do not depend on keyframes, adds
keyframes depending on transitions and other keyframes, and at last adds transitions that depend on keyframes.

CAnimationGroup::CAnimationGroup
Constructs an animation group.

CAnimationGroup(CAnimationController* pParentController, UINT32 nGroupID);

Parameters
pParentController
A pointer to animation controller that creates a group.
nGroupID
Specifies GroupID.

CAnimationGroup::CreateTransitions
A helper that creates COM transition objects.

BOOL CreateTransitions();

Return Value
TRUE is the method succeeds, otherwise FALSE.

CAnimationGroup::FindAnimationObject
Finds an animation object that contains the specified animation variable.

CAnimationBaseObject* FindAnimationObject(IUIAnimationVariable* pVariable);

Parameters
pVariable
A pointer to animation variable.
Return Value
A pointer to animation object, or NULL if animation object is not found.
CAnimationGroup::GetGroupID
Returns GroupID.

UINT32 GetGroupID() const;

Return Value
A group identifier.

CAnimationGroup::m_bAutoclearTransitions
Specifies how to clear transitions from animation objects that belong to group. If this member is TRUE, transitions
are removed automatically when an animation has been scheduled. Otherwise you need to remove transitions
manually.

BOOL m_bAutoclearTransitions;

CAnimationGroup::m_bAutodestroyAnimationObjects
Specifies how to destroy animation objects. If this parameter is TRUE, animation objects will be destroyed
automatically when the group is destroyed. Otherwise animation objects must be destroyed manually. The default
value is FALSE. Set this value to TRUE only if all animation objects that belong to group are allocated dynamically
with operator new.

BOOL m_bAutodestroyAnimationObjects;

CAnimationGroup::m_bAutodestroyKeyframes
Specifies how to destroy keyframes. If this value is TRUE, all keyframes are removed and destroyed; otherwise they
are removed from the list only. The default value is TRUE.

BOOL m_bAutodestroyKeyframes;

CAnimationGroup::m_lstAnimationObjects
Contains a list of animation objects.

CObList m_lstAnimationObjects;

CAnimationGroup::m_lstKeyFrames
Contains a list of keyframes.

CObList m_lstKeyFrames;

CAnimationGroup::m_nGroupID
A unique identifier of animation group.
UINT32 m_nGroupID;

CAnimationGroup::m_pParentController
A pointer to animation controller this group belongs to.

CAnimationController* m_pParentController;

CAnimationGroup::m_pStoryboard
Points to animation storyboard. This pointer is valid only after call on Animate.

ATL::CComPtr<IUIAnimationStoryboard> m_pStoryboard;

CAnimationGroup::RemoveKeyframes
Removes and optionally destroys all keyframes that belong to an animation group.

void RemoveKeyframes();

Remarks
If m_bAutodestroyKeyframes member is TRUE then keyframes are removed and destroyed, otherwise keyframes
are just removed from the internal list of keyframes.

CAnimationGroup::RemoveTransitions
Removes transitions from animation objects that belong to an animation group.

void RemoveTransitions();

Remarks
If m_bAutoclearTransitions flag is set to TRUE, this method loops over all animation objects that belong to the
group and calls CAnimationObject::ClearTransitions(FALSE).

CAnimationGroup::Schedule
Schedules an animation at the specified time.

BOOL Schedule(IUIAnimationTimer* pTimer, UI_ANIMATION_SECONDS time);

Parameters
pTimer
A pointer to animation timer.
time
Specifies time to schedule the animation.
Return Value
TRUE if the method succeeds; FALSE if the method fails or if Animate has not been called with bScheduleNow set to
FALSE.
Remarks
Call this function to schedule an animation at the specified time. You must call Animate with bScheduleNow set to
FALSE first.

CAnimationGroup::SetAutodestroyTransitions
Directs all animation objects that belong to group automatically destroy transitions.

void SetAutodestroyTransitions(BOOL bAutoDestroy = TRUE);

Parameters
bAutoDestroy
Specifies how to destroy transitions.
Remarks
Set this value to FALSE only if you allocate transitions on the stack. The default value is TRUE, therefore it's highly
recommended to allocate transition objects using operator new.

See also
Classes
CAnimationManagerEventHandler Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when a status of an animation manager is changed.

Syntax
class CAnimationManagerEventHandler : public
CUIAnimationManagerEventHandlerBase<CAnimationManagerEventHandler>;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationManagerEventHandler::CAnimationManagerEvent Constructs a CAnimationManagerEventHandler object.


Handler

Public Methods
NAME DESC RIP T IO N

CAnimationManagerEventHandler::CreateInstance Creates an instance of CAnimationManagerEventHandler


object.

CAnimationManagerEventHandler::OnManagerStatusChanged Called when a status of animation manager has changed.


(Overrides
CUIAnimationManagerEventHandlerBase::OnManagerStatusChanged
.)

CAnimationManagerEventHandler::SetAnimationController Stores a pointer to animation controller to route events.

Remarks
This event handler is created and passed to IUIAnimationManager::SetManagerEventHandler method, when you
call CAnimationController::EnableAnimationManagerEvent.

Inheritance Hierarchy
CUIAnimationCallbackBase

CUIAnimationManagerEventHandlerBase

CAnimationManagerEventHandler

Requirements
Header : afxanimationcontroller.h
CAnimationManagerEventHandler::CAnimationManagerEventHandler
Visual Studio 2010 SP1 is required.
Constructs a CAnimationManagerEventHandler object.

CAnimationManagerEventHandler();

CAnimationManagerEventHandler::CreateInstance
Visual Studio 2010 SP1 is required.
Creates an instance of CAnimationManagerEventHandler object.

static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(


CAnimationController* pAnimationController,
IUIAnimationManagerEventHandler** ppManagerEventHandler);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.
ppManagerEventHandler
Output. If the method succeeds it contains a pointer to COM object that will handle status updates to an animation
manager.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CAnimationManagerEventHandler::OnManagerStatusChanged
Visual Studio 2010 SP1 is required.
Called when a status of animation manager has changed.

IFACEMETHOD(OnManagerStatusChanged)(
UI_ANIMATION_MANAGER_STATUS newStatus,
UI_ANIMATION_MANAGER_STATUS previousStatus);

Parameters
newStatus
New status.
previousStatus
Previous status.
Return Value
Current implementation always returns S_OK;

CAnimationManagerEventHandler::SetAnimationController
Visual Studio 2010 SP1 is required.
Stores a pointer to animation controller to route events.
void SetAnimationController(CAnimationController* pAnimationController);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.

See also
Classes
CAnimationPoint Class
4/21/2020 • 3 minutes to read • Edit Online

Implements the functionality of a point whose coordinates can be animated.

Syntax
class CAnimationPoint : public CAnimationBaseObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationPoint::CAnimationPoint Overloaded. Constructs CAnimationPoint object.

Public Methods
NAME DESC RIP T IO N

CAnimationPoint::AddTransition Adds transitions for X and Y coordinates.

CAnimationPoint::GetDefaultValue Returns the default values for X and Y coordinates.

CAnimationPoint::GetValue Returns current value.

CAnimationPoint::GetX Provides access to CAnimationVariable for X coordinate.

CAnimationPoint::GetY Provides access to CAnimationVariable for Y coordinate.

CAnimationPoint::SetDefaultValue Sets default value.

Protected Methods
NAME DESC RIP T IO N

CAnimationPoint::GetAnimationVariableList Puts the encapsulated animation variables into a list.


(Overrides CAnimationBaseObject::GetAnimationVariableList.)

Public Operators
NAME DESC RIP T IO N

CAnimationPoint::operator CPoint Converts a CAnimationPoint to a CPoint.

CAnimationPoint::operator= Assigns ptSrc to CAnimationPoint.

Protected Data Members


NAME DESC RIP T IO N

CAnimationPoint::m_xValue The encapsulated animation variable that represents X


coordinate of animation point.

CAnimationPoint::m_yValue The encapsulated animation variable that represents Y


coordinate of animation point.

Remarks
The CAnimationPoint class encapsulates two CAnimationVariable objects and can represent in applications a point.
For example, you can use this class to animate a position of any object on the screen (like text string, circle, point
etc). To use this class in application, just instantiate an object of this class, add it to animation controller using
CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to X and/or Y
coordinates.

Inheritance Hierarchy
CObject
CAnimationBaseObject
CAnimationPoint

Requirements
Header : afxanimationcontroller.h

CAnimationPoint::AddTransition
Adds transitions for X and Y coordinates.

void AddTransition(
CBaseTransition* pXTransition,
CBaseTransition* pYTransition);

Parameters
pXTransition
A pointer to transition for X coordinates.
pYTransition
A pointer to transition for Y coordinate.
Remarks
Call this function to add the specified transitions to the internal list of transitions to be applied to animation
variables for X and Y coordinates. When you add transitions, they are not applied immediately and stored in an
internal list. Transitions are applied (added to a storyboard for a particular value) when you call
CAnimationController::AnimateGroup. If you don't need to apply a transition to one of coordinates, you can pass
NULL.

CAnimationPoint::CAnimationPoint
Constructs CAnimationPoint object.
CAnimationPoint();

CAnimationPoint(
const CPoint& ptDefault,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
ptDefault
Specifies default point coordinates.
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
Specifies user-defined data.
Remarks
Constructs CAnimationPoint object with default properties: default point coordinates, Group ID and Object ID are
set to 0.

CAnimationPoint::GetAnimationVariableList
Puts the encapsulated animation variables into a list.

virtual void GetAnimationVariableList(CList<CAnimationVariable*, CAnimationVariable*>& lst);

Parameters
lst
When the function returns, it contains pointers to two CAnimationVariable objects representing the X and Y
coordinates.

CAnimationPoint::GetDefaultValue
Returns the default values for X and Y coordinates.

CPoint GetDefaultValue();

Return Value
A point containing default value.
Remarks
Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.

CAnimationPoint::GetValue
Returns current value.
BOOL GetValue(CPoint& ptValue);

Parameters
ptValue
Output. Contains the current value when this method returns.
Return Value
TRUE, if the current value was successfully retrieved; otherwise FALSE.
Remarks
Call this function to retrieve the current value of animation point. If this method fails or underlying COM objects for
X and Y coordinates have not been initialized, ptValue contains default value, which was previously set in
constructor or by SetDefaultValue.

CAnimationPoint::GetX
Provides access to CAnimationVariable for X coordinate.

CAnimationVariable& GetX();

Return Value
A reference to encapsulated CAnimationVariable representing X coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing X coordinate.

CAnimationPoint::GetY
Provides access to CAnimationVariable for Y coordinate.

CAnimationVariable& GetY();

Return Value
A reference to encapsulated CAnimationVariable representing Y coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Y coordinate.

CAnimationPoint::m_xValue
The encapsulated animation variable that represents X coordinate of animation point.

CAnimationVariable m_xValue;

CAnimationPoint::m_yValue
The encapsulated animation variable that represents Y coordinate of animation point.

CAnimationVariable m_yValue;
CAnimationPoint::operator CPoint
Converts a CAnimationPoint to a CPoint.

operator CPoint();

Return Value
Current value of CAnimationPoint as CPoint.
Remarks
This function internally calls GetValue. If GetValue for some reason fails, the returned point will contain default
values for X and Y coordinates.

CAnimationPoint::operator=
Assigns ptSrc to CAnimationPoint.

void operator=(const CPoint& ptSrc);

Parameters
ptSrc
Refers to CPoint or POINT.
Remarks
Assigns ptSrc to CAnimationPoint. It's recommended to do that before animation start, because this operator calls
SetDefaultValue, which recreates the underlying COM objects for X and Y coordinates if they have been created. If
you subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable
these events.

CAnimationPoint::SetDefaultValue
Sets default value.

void SetDefaultValue(const POINT& ptDefault);

Parameters
ptDefault
Specifies the default point value.
Remarks
Use this function to set a default value to animation object. This methods assigns default values to X and Y
coordinates of animation point. It also recreates underlying COM objects if they have been created. If you
subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these
events.

See also
Classes
CAnimationRect Class
4/21/2020 • 5 minutes to read • Edit Online

Implements the functionality of a rectangle whose sides can be animated.

Syntax
class CAnimationRect : public CAnimationBaseObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationRect::CAnimationRect Overloaded. Constructs an animation rect object.

Public Methods
NAME DESC RIP T IO N

CAnimationRect::AddTransition Adds transitions for left, top, right and bottom coordinates.

CAnimationRect::GetBottom Provides access to CAnimationVariable representing bottom


coordinate.

CAnimationRect::GetDefaultValue Returns the default values for rectangle's bounds.

CAnimationRect::GetLeft Provides access to CAnimationVariable representing left


coordinate.

CAnimationRect::GetRight Provides access to CAnimationVariable representing right


coordinate.

CAnimationRect::GetTop Provides access to CAnimationVariable representing top


coordinate.

CAnimationRect::GetValue Returns current value.

CAnimationRect::SetDefaultValue Sets default value.

Protected Methods
NAME DESC RIP T IO N

CAnimationRect::GetAnimationVariableList Puts the encapsulated animation variables into a list.


(Overrides CAnimationBaseObject::GetAnimationVariableList.)

Public Operators
NAME DESC RIP T IO N

CAnimationRect::operator RECT Converts a CAnimationRect to RECT.

CAnimationRect::operator= Assigns rect to CAnimationRect.

Public Data Members


NAME DESC RIP T IO N

CAnimationRect::m_bFixedSize Specifies whether the rectangle has fixed size.

Protected Data Members


NAME DESC RIP T IO N

CAnimationRect::m_bottomValue The encapsulated animation variable that represents Bottom


bound of animation rectangle.

CAnimationRect::m_leftValue The encapsulated animation variable that represents Left


bound of animation rectangle.

CAnimationRect::m_rightValue The encapsulated animation variable that represents Right


bound of animation rectangle.

CAnimationRect::m_szInitial Specifies initial size of animation rectangle.

CAnimationRect::m_topValue The encapsulated animation variable that represents Top


bound of animation rectangle.

Remarks
The CAnimationRect class encapsulates four CAnimationVariable objects and can represent in applications a
rectangle. To use this class in application, just instantiate an object of this class, add it to animation controller using
CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to left, right top
and bottom coordinates.

Inheritance Hierarchy
CObject
CAnimationBaseObject
CAnimationRect

Requirements
Header : afxanimationcontroller.h

CAnimationRect::AddTransition
Adds transitions for left, top, right and bottom coordinates.
void AddTransition(
CBaseTransition* pLeftTransition,
CBaseTransition* pTopTransition,
CBaseTransition* pRightTransition,
CBaseTransition* pBottomTransition);

Parameters
pLeftTransition
Specifies transition for the left side.
pTopTransition
Specifies transition for the top side.
pRightTransition
Specifies transition for the right side.
pBottomTransition
Specifies transition for the bottom side.
Remarks
Call this function to add the specified transitions to the internal list of transitions to be applied to animation
variables for each rectangle sides. When you add transitions, they are not applied immediately and stored in an
internal list. Transitions are applied (added to a storyboard for a particular value) when you call
CAnimationController::AnimateGroup. If you don't need to apply a transition to one of the rectangle sides, you can
pass NULL.

CAnimationRect::CAnimationRect
Constructs a CAnimationRect object.

CAnimationRect();

CAnimationRect(
const CRect& rect,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

CAnimationRect(
const CPoint& pt,
const CSize& sz,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

CAnimationRect(
int nLeft,
int nTop,
int nRight,
int nBottom,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
rect
Specifies default rectangle.
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
Specifies user-defined data.
pt
Coordinate of top-left corner.
sz
Size of rectangle.
nLeft
Specifies coordinate of left bound.
nTop
Specifies coordinate of top bound.
nRight
Specifies coordinate of right bound.
nBottom
Specifies coordinate of bottom bound.
Remarks
The object is constructed with default values for left, top, right and bottom, Object ID and Group ID, which will be
set to 0. They can be changed later at runtime using SetDefaultValue and SetID.

CAnimationRect::GetAnimationVariableList
Puts the encapsulated animation variables into a list.

virtual void GetAnimationVariableList(


CList<CAnimationVariable*,
CAnimationVariable*>& lst);

Parameters
lst
When the function returns, it contains pointers to four CAnimationVariable objects representing coordinates of
rectangle.

CAnimationRect::GetBottom
Provides access to CAnimationVariable representing bottom coordinate.

CAnimationVariable& GetBottom();

Return Value
A reference to encapsulated CAnimationVariable representing bottom coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing the bottom coordinate.
CAnimationRect::GetDefaultValue
Returns the default values for rectangle's bounds.

CRect GetDefaultValue();

Return Value
A CRect value containing defaults for left, right, top and bottom.
Remarks
Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.

CAnimationRect::GetLeft
Provides access to CAnimationVariable representing left coordinate.

CAnimationVariable& GetLeft();

Return Value
A reference to encapsulated CAnimationVariable representing left coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing the left coordinate.

CAnimationRect::GetRight
Provides access to CAnimationVariable representing right coordinate.

CAnimationVariable& GetRight();

Return Value
A reference to encapsulated CAnimationVariable representing right coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing the right coordinate.

CAnimationRect::GetTop
Provides access to CAnimationVariable representing top coordinate.

CAnimationVariable& GetTop();

Return Value
A reference to encapsulated CAnimationVariable representing top coordinate.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing the top coordinate.

CAnimationRect::GetValue
Returns current value.
BOOL GetValue(CRect& rect);

Parameters
rect
Output. Contains the current value when this method returns.
Return Value
TRUE, if the current value was successfully retrieved; otherwise FALSE.
Remarks
Call this function to retrieve the current value of animation rectangle. If this method fails or underlying COM
objects for left, top, right and bottom have not been initialized, rect contains default value, which was previously set
in constructor or by SetDefaultValue.

CAnimationRect::m_bFixedSize
Specifies whether the rectangle has fixed size.

BOOL m_bFixedSize;

Remarks
If this member is true, then the size of rectangle is fixed and right and bottom values are recalculated each time the
top-left corner is moved according to the fixed size. Set this value to TRUE to easily move the rectangle around the
screen. In this case transitions applied to right and bottom coordinates are ignored. The size is stored internally
when you construct the object and/or call SetDefaultValue. By default this member is set to FALSE.

CAnimationRect::m_bottomValue
The encapsulated animation variable that represents Bottom bound of animation rectangle.

CAnimationVariable m_bottomValue;

CAnimationRect::m_leftValue
The encapsulated animation variable that represents Left bound of animation rectangle.

CAnimationVariable m_leftValue;

CAnimationRect::m_rightValue
The encapsulated animation variable that represents Right bound of animation rectangle.

CAnimationVariable m_rightValue;

CAnimationRect::m_szInitial
Specifies initial size of animation rectangle.
CSize m_szInitial;

CAnimationRect::m_topValue
The encapsulated animation variable that represents Top bound of animation rectangle.

CAnimationVariable m_topValue;

CAnimationRect::operator RECT
Converts a CAnimationRect to RECT.

operator RECT();

Return Value
Current value of animation rectangle as RECT.
Remarks
This function internally calls GetValue. If GetValue for some reason fails, the returned RECT will contain default
values for all rectangle coordinates.

CAnimationRect::operator=
Assigns rect to CAnimationRect.

void operator=(const RECT& rect);

Parameters
rect
The new value of animation rectangle.
Remarks
It's recommended to do that before animation start, because this operator calls SetDefaultValue, which recreates
the underlying COM objects for color components if they have been created. If you subscribed this animation
object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.

CAnimationRect::SetDefaultValue
Sets default value.

void SetDefaultValue(const CRect& rect);

Parameters
rect
Specifies new default values for left, top, right and bottom.
Remarks
Use this function to set a default value to animation object. This methods assigns default values to rectangle's
bounds. It also recreates underlying COM objects if they have been created. If you subscribed this animation object
to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.

See also
Classes
CAnimationSize Class
4/21/2020 • 3 minutes to read • Edit Online

Implements the functionality of a size object whose dimensions can be animated.

Syntax
class CAnimationSize : public CAnimationBaseObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationSize::CAnimationSize Overloaded. Constructs an animation size object.

Public Methods
NAME DESC RIP T IO N

CAnimationSize::AddTransition Adds transitions for Width and Height.

CAnimationSize::GetCX Provides access to CAnimationVariable representing Width.

CAnimationSize::GetCY Provides access to CAnimationVariable representing Height.

CAnimationSize::GetDefaultValue Returns the default values for Width and Height.

CAnimationSize::GetValue Returns current value.

CAnimationSize::SetDefaultValue Sets default value.

Protected Methods
NAME DESC RIP T IO N

CAnimationSize::GetAnimationVariableList Puts the encapsulated animation variables into a list.


(Overrides CAnimationBaseObject::GetAnimationVariableList.)

Public Operators
NAME DESC RIP T IO N

CAnimationSize::operator CSize Converts a CAnimationSize to a CSize.

CAnimationSize::operator= Assigns szSrc to CAnimationSize.

Protected Data Members


NAME DESC RIP T IO N

CAnimationSize::m_cxValue The encapsulated animation variable that represents width of


animation size.

CAnimationSize::m_cyValue The encapsulated animation variable that represents height of


animation size.

Remarks
The CAnimationSize class encapsulates two CAnimationVariable objects and can represent in applications a size.
For example, you can use this class to animate a size of any two dimensional object on the screen (like rectangle,
control etc). To use this class in application, just instantiate an object of this class, add it to animation controller
using CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to Width
and/or Height.

Inheritance Hierarchy
CObject
CAnimationBaseObject
CAnimationSize

Requirements
Header : afxanimationcontroller.h

CAnimationSize::AddTransition
Adds transitions for Width and Height.

void AddTransition(
CBaseTransition* pCXTransition,
CBaseTransition* pCYTransition);

Parameters
pCXTransition
A pointer to transition for Width.
pCYTransition
A pointer to transition for Height.
Remarks
Call this function to add the specified transitions to the internal list of transitions to be applied to animation
variables for Width and Height. When you add transitions, they are not applied immediately and stored in an
internal list. Transitions are applied (added to a storyboard for a particular value) when you call
CAnimationController::AnimateGroup. If you don't need to apply a transition to one of dimensions, you can pass
NULL.

CAnimationSize::CAnimationSize
Constructs an animation size object.
CAnimationSize();

CAnimationSize(
const CSize& szDefault,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
szDefault
Specifies default size.
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
Specifies user-defined data.
Remarks
The object is constructed with default values for width, height, Object ID and Group ID, which will be set to 0. They
can be changed later at runtime using SetDefaultValue and SetID.

CAnimationSize::GetAnimationVariableList
Puts the encapsulated animation variables into a list.

virtual void GetAnimationVariableList(


CList<CAnimationVariable*,
CAnimationVariable*>& lst);

Parameters
lst
When the function returns, it contains pointers to two CAnimationVariable objects representing the width and
height.

CAnimationSize::GetCX
Provides access to CAnimationVariable representing Width.

CAnimationVariable& GetCX();

Return Value
A reference to encapsulated CAnimationVariable representing Width.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Width.

CAnimationSize::GetCY
Provides access to CAnimationVariable representing Height.
CAnimationVariable& GetCY();

Return Value
A reference to encapsulated CAnimationVariable representing Height.
Remarks
You can call this method to get direct access to underlying CAnimationVariable representing Height.

CAnimationSize::GetDefaultValue
Returns the default values for Width and Height.

CSize GetDefaultValue();

Return Value
A CSize object containing default values.
Remarks
Call this function to retrieve default value, which was previously set by constructor or SetDefaultValue.

CAnimationSize::GetValue
Returns current value.

BOOL GetValue(CSize& szValue);

Parameters
szValue
Output. Contains the current value when this method returns.
Return Value
TRUE, if the current value was successfully retrieved; otherwise FALSE.
Remarks
Call this function to retrieve the current value of animation size. If this method fails or underlying COM objects for
Width and Size have not been initialized, szValue contains default value, which was previously set in constructor or
by SetDefaultValue.

CAnimationSize::m_cxValue
The encapsulated animation variable that represents width of animation size.

CAnimationVariable m_cxValue;

CAnimationSize::m_cyValue
The encapsulated animation variable that represents height of animation size.

CAnimationVariable m_cyValue;
CAnimationSize::operator CSize
Converts a CAnimationSize to a CSize.

operator CSize();

Return Value
Current value of animation size as CSize.
Remarks
This function internally calls GetValue. If GetValue for some reason fails, the returned size will contain default values
for Width and Height.

CAnimationSize::operator=
Assigns szSrc to CAnimationSize.

void operator=(const CSize& szSrc);

Parameters
szSrc
Refers to CSize or SIZE.
Remarks
Assigns szSrc to CAnimationSize. It's recommended to do that before animation start, because this operator calls
SetDefaultValue, which recreates the underlying COM objects for Width and Height if they have been created. If
you subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable
these events.

CAnimationSize::SetDefaultValue
Sets default value.

void SetDefaultValue(const CSize& szDefault);

Parameters
szDefault
Specifies new default size.
Remarks
Use this function to set a default value to animation object. This methods assigns default values to Width and
Height of animation size. It also recreates underlying COM objects if they have been created. If you subscribed this
animation object to events (ValueChanged or IntegerValueChanged), you need to re-enable these events.

See also
Classes
CAnimationStoryboardEventHandler Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when the status of a storyboard is changed or a storyboard
is updated.

Syntax
class CAnimationStoryboardEventHandler : public
CUIAnimationStoryboardEventHandlerBase<CAnimationStoryboardEventHandler>;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationStoryboardEventHandler::CAnimationStoryboardEven Constructs a CAnimationStoryboardEventHandler object.


tHandler

Public Methods
NAME DESC RIP T IO N

CAnimationStoryboardEventHandler::CreateInstance Creates an instance of CAnimationStoryboardEventHandler


callback.

CAnimationStoryboardEventHandler::OnStoryboardStatusChang Handles OnStoryboardStatusChanged events, which occur


ed when a storyboard's status changes (Overrides
CUIAnimationStoryboardEventHandlerBase::OnStoryboardStatusChanged
.)

CAnimationStoryboardEventHandler::OnStoryboardUpdated Handles OnStoryboardUpdated events, which occur when a


storyboard is updated (Overrides
CUIAnimationStoryboardEventHandlerBase::OnStoryboardUpdated
.)

CAnimationStoryboardEventHandler::SetAnimationController Stores a pointer to animation controller to route events.

Remarks
This event handler is created and passed to IUIAnimationStoryboard::SetStoryboardEventHandler method, when you call
CAnimationController::EnableStoryboardEventHandler .

Inheritance Hierarchy
CUIAnimationCallbackBase

CUIAnimationStoryboardEventHandlerBase

CAnimationStoryboardEventHandler
Requirements
Header : afxanimationcontroller.h

CAnimationStoryboardEventHandler::CAnimationStoryboardEventHandler
Constructs a CAnimationStoryboardEventHandler object.

CAnimationStoryboardEventHandler();

CAnimationStoryboardEventHandler::CreateInstance
Creates an instance of CAnimationStoryboardEventHandler callback.

static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(


CAnimationController* pAnimationController,
IUIAnimationStoryboardEventHandler** ppHandler);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.
ppHandler
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CAnimationStoryboardEventHandler::OnStoryboardStatusChanged
Handles OnStoryboardStatusChanged events, which occur when a storyboard's status changes

IFACEMETHOD(OnStoryboardStatusChanged) (
__in IUIAnimationStoryboard* storyboard,
__in UI_ANIMATION_STORYBOARD_STATUS newStatus,
__in UI_ANIMATION_STORYBOARD_STATUS previousStatus);

Parameters
storyboard
A pointer to storyboard whose status has changed.
newStatus
Specifies new storyboard status.
previousStatus
Specifies previous storyboard status.
Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationStoryboardEventHandler::OnStoryboardUpdated
Handles OnStoryboardUpdated events, which occur when a storyboard is updated

IFACEMETHOD(OnStoryboardUpdated) (__in IUIAnimationStoryboard* storyboard);


Parameters
storyboard
A pointer to storyboard, which was updated.
Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationStoryboardEventHandler::SetAnimationController
Stores a pointer to animation controller to route events.

void SetAnimationController(CAnimationController* pAnimationController);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.

See also
Classes
CAnimationTimerEventHandler Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when timing events occur.

Syntax
class CAnimationTimerEventHandler : public CUIAnimationTimerEventHandlerBase<CAnimationTimerEventHandler>;

Members
Public Methods
NAME DESC RIP T IO N

CAnimationTimerEventHandler::CreateInstance Creates an instance of CAnimationTimerEventHandler


callback.

CAnimationTimerEventHandler::OnPostUpdate Handles events that occur after an animation update is


finished. (Overrides
CUIAnimationTimerEventHandlerBase::OnPostUpdate .)

CAnimationTimerEventHandler::OnPreUpdate Handles events that occur before an animation update begins.


(Overrides
CUIAnimationTimerEventHandlerBase::OnPreUpdate .)

CAnimationTimerEventHandler::OnRenderingTooSlow Handles events that occur when the rendering frame rate for
an animation falls below the minimum desirable frame rate.
(Overrides
CUIAnimationTimerEventHandlerBase::OnRenderingTooSlow
.)

CAnimationTimerEventHandler::SetAnimationController Stores a pointer to animation controller to route events.

Remarks
This event handler is created and passed to IUIAnimationTimer::SetTimerEventHandler when you call
CAnimationController::EnableAnimationTimerEventHandler.

Inheritance Hierarchy
CUIAnimationCallbackBase

CUIAnimationTimerEventHandlerBase

CAnimationTimerEventHandler

Requirements
Header : afxanimationcontroller.h
CAnimationTimerEventHandler::CreateInstance
Creates an instance of CAnimationTimerEventHandler callback.

static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(


CAnimationController* pAnimationController,
IUIAnimationTimerEventHandler** ppTimerEventHandler);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.
ppTimerEventHandler
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CAnimationTimerEventHandler::OnPostUpdate
Handles events that occur after an animation update is finished.

IFACEMETHOD(OnPostUpdate)();

Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationTimerEventHandler::OnPreUpdate
Handles events that occur before an animation update begins.

IFACEMETHOD(OnPreUpdate)();

Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationTimerEventHandler::OnRenderingTooSlow
Handles events that occur when the rendering frame rate for an animation falls below the minimum desirable
frame rate.

IFACEMETHOD(OnRenderingTooSlow)(UINT32 fps);

Parameters
fps
Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationTimerEventHandler::SetAnimationController
Stores a pointer to animation controller to route events.
void SetAnimationController(CAnimationController* pAnimationController);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.

See also
Classes
CAnimationValue Class
4/21/2020 • 3 minutes to read • Edit Online

Implements the functionality of animation object that has one value.

Syntax
class CAnimationValue : public CAnimationBaseObject;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationValue::CAnimationValue Overloaded. Constructs a CAnimationValue object.

Public Methods
NAME DESC RIP T IO N

CAnimationValue::AddTransition Adds a transition to be applied to a value.

CAnimationValue::GetValue Overloaded. Retrieves the current value.

CAnimationValue::GetVariable Provides access to encapsulated animation variable.

CAnimationValue::SetDefaultValue Sets default value.

Protected Methods
NAME DESC RIP T IO N

CAnimationValue::GetAnimationVariableList Puts the encapsulated animation variable into a list. (Overrides


CAnimationBaseObject::GetAnimationVariableList.)

Public Operators
NAME DESC RIP T IO N

CAnimationValue::operator DOUBLE Provides conversion between CAnimationValue and DOUBLE.

CAnimationValue::operator INT32 Provides conversion between CAnimationValue and INT32.

CAnimationValue::operator= Overloaded. Assigns an INT32 value to CAnimationValue.

Protected Data Members


NAME DESC RIP T IO N

CAnimationValue::m_value The encapsulated animation variable that represents


animation value.

Remarks
The CAnimationValue class encapsulates a single CAnimationVariable object and can represent in applications a
single animated value. For example, you can use this class for animated transparency (fade effect), angle (to rotate
objects), or for any other case when you need to create an animation depending on a single animated value. To use
this class in application, just instantiate an object of this class, add it to animation controller using
CAnimationController::AddAnimationObject and call AddTransition for each transition to be applied to the value.

Inheritance Hierarchy
CObject
CAnimationBaseObject
CAnimationValue

Requirements
Header : afxanimationcontroller.h

CAnimationValue::AddTransition
Adds a transition to be applied to a value.

void AddTransition(CBaseTransition* pTransition);

Parameters
pTransition
A pointer to transition object.
Remarks
Call this function to add a transition to internal list of transitions to be applied to an animation variable. When you
add transitions, they are not applied immediately and stored in an internal list. Transitions are applied (added to a
storyboard for a particular value) when you call CAnimationController::AnimateGroup.

CAnimationValue::CAnimationValue
Constructs a CAnimationValue object.

CAnimationValue();

CAnimationValue(
DOUBLE dblDefaultValue,
UINT32 nGroupID,
UINT32 nObjectID = (UINT32)-1,
DWORD dwUserData = 0);

Parameters
dblDefaultValue
Specifies default value.
nGroupID
Specifies Group ID.
nObjectID
Specifies Object ID.
dwUserData
specifies user-defined data.
Remarks
Constructs CAnimationValue object with default properties: default value, Group ID and Object ID are set to 0.

CAnimationValue::GetAnimationVariableList
Puts the encapsulated animation variable into a list.

virtual void GetAnimationVariableList(


CList<CAnimationVariable*,
CAnimationVariable*>& lst);

Parameters
lst
When the function returns, it contains a pointer to CAnimationVariable representing the animated value.

CAnimationValue::GetValue
Retrieves the current value.

BOOL GetValue(DOUBLE& dblValue);


BOOL GetValue(INT32& nValue);

Parameters
dblValue
Output. When the function returns it contains a current value of animation variable.
nValue
Output. When the function returns it contains a current value of animation variable.
Return Value
TRUE if the current value was retrieved successfully; otherwise FALSE.
Remarks
Call this function to retrieve the current value. This implementation calls the encapsulated COM object, and if the
call fails, this method returns the default value that was previously set in constructor or with SetDefaultValue.

CAnimationValue::GetVariable
Provides access to encapsulated animation variable.

CAnimationVariable& GetVariable();

Return Value
A reference to encapsulated animation variable.
Remarks
Use this method to access the encapsulated animation variable. From CAnimationVariable you get access to
underlying IUIAnimationVariable object, whose pointer can be NULL if animation variable has not been created.

CAnimationValue::m_value
The encapsulated animation variable that represents animation value.

CAnimationVariable m_value;

CAnimationValue::operator DOUBLE
Provides conversion between CAnimationValue and DOUBLE.

operator DOUBLE();

Return Value
Current value of Animation Value.
Remarks
Provides conversion between CAnimationValue and DOUBLE. This method internally calls GetValue and doesn't
check for errors. If GetValue fails, the returned value will contain a default value previously set in constructor or
with SetDefaultValue.

CAnimationValue::operator INT32
Provides conversion between CAnimationValue and INT32.

operator INT32();

Return Value
Current value of Animation Value as integer.
Remarks
Provides conversion between CAnimationValue and INT32. This method internally calls GetValue and doesn't check
for errors. If GetValue fails, the returned value will contain a default value previously set in constructor or with
SetDefaultValue.

CAnimationValue::operator=
Assigns a DOUBLE value to CAnimationValue.

void operator=(DOUBLE dblVal);


void operator=(INT32 nVal);

Parameters
dblVal
Specifies the value to be assigned to Animation Value.
nVal
Specifies the value to be assigned to Animation Value.
Remarks
Assigns a DOUBLE value to CAnimationValue. This value is set as a default value for encapsulated animation
variable. If you subscribed this animation object to events (ValueChanged or IntegerValueChanged), you need to re-
enable these events.

CAnimationValue::SetDefaultValue
Sets default value.

void SetDefaultValue(DOUBLE dblDefaultValue);

Parameters
dblDefaultValue
Specifies the default value.
Remarks
Use this method to set a default value. A default value is returned to application when animation has not been
started and/or underlying COM object has not been created. If the underlying COM object encapsulated in
CAnimationVarible was already created, this method recreates it, therefore you might need to call
EnableValueChanged/EnableIntegerValueChanged methods again.

See also
Classes
CAnimationVariable Class
4/21/2020 • 6 minutes to read • Edit Online

Represents an animation variable.

Syntax
class CAnimationVariable;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationVariable::CAnimationVariable Constructs an animation variable object.

CAnimationVariable::~CAnimationVariable The destructor. Called when a CAnimationVariable object is


being destroyed.

Public Methods
NAME DESC RIP T IO N

CAnimationVariable::AddTransition Adds a transition.

CAnimationVariable::ApplyTransitions Adds transitions from the internal list to storyboard.

CAnimationVariable::ClearTransitions Clears transitions.

CAnimationVariable::Create Creates the underlying animation variable COM object.

CAnimationVariable::CreateTransitions Creates all transitions to be applied to this animation variable.

CAnimationVariable::EnableIntegerValueChangedEvent Enables or disables the IntegerValueChanged event.

CAnimationVariable::EnableValueChangedEvent Enables or disables the ValueChanged event.

CAnimationVariable::GetDefaultValue Returns default value.

CAnimationVariable::GetParentAnimationObject Returns the parent animation object.

CAnimationVariable::GetValue Overloaded. Returns the current value of animation variable.

CAnimationVariable::GetVariable Returns a pointer to IUIAnimationVariable COM object.

CAnimationVariable::SetDefaultValue Sets default value and releases IUIAnimationVariable COM


object.
Protected Methods
NAME DESC RIP T IO N

CAnimationVariable::SetParentAnimationObject Sets the relationship between an animation variable and an


animation object.

Public Data Members


NAME DESC RIP T IO N

CAnimationVariable::m_bAutodestroyTransitions Specifies whether related transition objects should be deleted.

Protected Data Members


NAME DESC RIP T IO N

CAnimationVariable::m_dblDefaultValue Specifies the default value, which is propagated to


IUIAnimationVariable.

CAnimationVariable::m_lstTransitions Contains a list of transitions that animate this animation


variable.

CAnimationVariable::m_pParentObject A pointer to an animation object that encapsulates this


animation variable.

CAnimationVariable::m_variable Stores a pointer to IUIAnimationVariable COM object. NULL if


the COM object has not been created yet, or if creation failed.

Remarks
The CAnimationVariable class encapsulates IUIAnimationVariable COM object. It also holds a list of transitions to be
applied to the animation variable in a storyboard. CAnimationVariable objects are embedded to animation objects,
which can represent in an application an animated value, point, size, color and rectangle.

Inheritance Hierarchy
CAnimationVariable

Requirements
Header : afxanimationcontroller.h

CAnimationVariable::~CAnimationVariable
The destructor. Called when a CAnimationVariable object is being destroyed.

virtual ~CAnimationVariable();

CAnimationVariable::AddTransition
Adds a transition.
void AddTransition(CBaseTransition* pTransition);

Parameters
pTransition
A pointer to a transition to add.
Remarks
This method is called to add a transition to the internal list of transitions to be applied to the animation variable.
This list should be cleared when an animation has been scheduled.

CAnimationVariable::ApplyTransitions
Adds transitions from the internal list to storyboard.

void ApplyTransitions(
CAnimationController* pController,
IUIAnimationStoryboard* pStoryboard,
BOOL bDependOnKeyframes);

Parameters
pController
A pointer to parent animation controller.
pStoryboard
A pointer to storyboard.
bDependOnKeyframes
TRUE, if this method should add transitions that depend on keyframes.
Remarks
This method adds transitions from the internal list to storyboard. It's called from the top level code several times to
add transitions that do not depend on keyframes and add transitions that depend on keyframes. If the underlying
animation variable COM object has not been created, this method creates it at this stage.

CAnimationVariable::CAnimationVariable
Constructs an animation variable object.

CAnimationVariable(DOUBLE dblDefaultValue = 0.0);

Parameters
dblDefaultValue
Specifies the default value.
Remarks
Constructs an animation variable object and sets its default value. A default value is used when a variable is not
animated, or can't be animated.

CAnimationVariable::ClearTransitions
Clears transitions.
void ClearTransitions(BOOL bAutodestroy);

Parameters
bAutodestroy
Specifies whether this method should delete transition objects.
Remarks
This method removes all transitions from the internal list of transitions. If bAutodestroy is TRUE, or
m_bAutodestroyTransitions is TRUE, then transitions are deleted. Otherwise the caller should deallocate the
transition objects.

CAnimationVariable::Create
Creates the underlying animation variable COM object.

virtual BOOL Create(IUIAnimationManager* pManager);

Parameters
pManager
A pointer to animation manager.
Return Value
TRUE if the animation variable was successfully created; otherwise FALSE.
Remarks
This method creates the underlying animation variable COM object and sets its default value.

CAnimationVariable::CreateTransitions
Creates all transitions to be applied to this animation variable.

BOOL CreateTransitions(
IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transitions were created successfully; otherwise FALSE.
Remarks
This method is called by the framework when it needs to create transitions that have been added to the variable's
internal list of transitions.

CAnimationVariable::EnableIntegerValueChangedEvent
Enables or disables the IntegerValueChanged event.
void EnableIntegerValueChangedEvent (
CAnimationController* pController,
BOOL bEnable);

Parameters
pController
A pointer to parent controller.
bEnable
TRUE - enable event, FALSE - disable event.
Remarks
When ValueChanged event is enabled, the framework calls virtual method
CAnimationController::OnAnimationIntegerValueChanged. You need to override it in a class derived from
CAnimationController in order to process this event. This method is called every time the integer value of
animation variable is changed.

CAnimationVariable::EnableValueChangedEvent
Enables or disables the ValueChanged event.

void EnableValueChangedEvent (
CAnimationController* pController,
BOOL bEnable);

Parameters
pController
A pointer to parent controller.
bEnable
TRUE - enable event, FALSE - disable event.
Remarks
When ValueChanged event is enabled, the framework calls virtual method
CAnimationController::OnAnimationValueChanged. You need to override it in a class derived from
CAnimationController in order to process this event. This method is called every time the value of animation
variable is changed.

CAnimationVariable::GetDefaultValue
Returns default value.

DOUBLE GetDefaultValue() const;

Return Value
The default value.
Remarks
Use this function to obtain default value of animation variable. The default value can be set in constructor or by
SetDefaultValue method.

CAnimationVariable::GetParentAnimationObject
Returns the parent animation object.

CAnimationBaseObject* GetParentAnimationObject();

Return Value
A pointer to parent animation object, if relationship was established, otherwise NULL.
Remarks
This method can be called to retrieve a pointer to a parent animation object (a container).

CAnimationVariable::GetValue
Returns the current value of animation variable.

HRESULT GetValue(DOUBLE& dblValue);


HRESULT GetValue(INT32& nValue);

Parameters
dblValue
The current value of the animation variable.
nValue
The current value of the animation variable.
Return Value
S_OK if the value was obtained successfully, or underlying animation variable has not been created. Otherwise
HRESULT error code.
Remarks
This method can be called to retrieve the current value of animation variable. If the underlying COM object has not
been created, dblValue will contain a default value, when the function returns.

CAnimationVariable::GetVariable
Returns a pointer to IUIAnimationVariable COM object.

IUIAnimationVariable* GetVariable();

Return Value
A valid pointer to IUIAnimationVariable COM object, or NULL if animation variable was not created, or can't be
created.
Remarks
Use this function to access the underlying IUIAnimationVariable COM object and call its methods directly if needed.

CAnimationVariable::m_bAutodestroyTransitions
Specifies whether related transition objects should be deleted.

BOOL m_bAutodestroyTransitions;

Remarks
Set this value to TRUE to force deletion of transition objects when they are being removed from the internal list of
transitions. If this value is FALSE the transitions should be deleted by calling application. The list of transitions is
always cleared after an animation has been scheduled. The default value is FALSE.

CAnimationVariable::m_dblDefaultValue
Specifies the default value, which is propagated to IUIAnimationVariable.

DOUBLE m_dblDefaultValue;

CAnimationVariable::m_lstTransitions
Contains a list of transitions that animate this animation variable.

CObList m_lstTransitions;

CAnimationVariable::m_pParentObject
A pointer to an animation object that encapsulates this animation variable.

CAnimationBaseObject* m_pParentObject;

CAnimationVariable::m_variable
Stores a pointer to IUIAnimationVariable COM object. NULL if the COM object has not been created yet, or if
creation failed.

ATL::CComPtr<IUIAnimationVariable> m_variable;

CAnimationVariable::SetDefaultValue
Sets default value and releases IUIAnimationVariable COM object.

void SetDefaultValue(DOUBLE dblDefaultValue);

Parameters
dblDefaultValue
Specifies the new default value.
Remarks
Use this method to reset the default value. This method releases the internal IUIAnimationVariable COM object,
therefore when animation variable is recreated, the underlying COM object gets the new default value. The default
value is returned by GetValue if the COM object representing the animation variable is not created, or if the
variable has not been animated.

CAnimationVariable::SetParentAnimationObject
Sets the relationship between an animation variable and an animation object.
void SetParentAnimationObject(CAnimationBaseObject* pParentObject);

Parameters
pParentObject
A pointer to an animation object that contains this variable.
Remarks
This method is called internally to establish one-to-one relationship between an animation variable and an
animation object that encapsulates it.

See also
Classes
CAnimationVariableChangeHandler Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when the value of an animation variable changes.

Syntax
class CAnimationVariableChangeHandler : public
CUIAnimationVariableChangeHandlerBase<CAnimationVariableChangeHandler>;

Members
Public Constructors
NAME DESC RIP T IO N

Constructs a CAnimationVariableChangeHandler
CAnimationVariableChangeHandler::CAnimationVariableChangeHandler object.

Public Methods
NAME DESC RIP T IO N

CAnimationVariableChangeHandler::CreateInstance Creates an instance of CAnimationVariableChangeHandler


object.

CAnimationVariableChangeHandler::OnValueChanged Called when a value of an animation variable has changed.


(Overrides
CUIAnimationVariableChangeHandlerBase::OnValueChanged
.)

CAnimationVariableChangeHandler::SetAnimationController Stores a pointer to animation controller to route events.

Remarks
This event handler is created and passed to method, when you call
IUIAnimationVariable::SetVariableChangeHandler
CAnimationVariable::EnableValueChangedEvent or CAnimationBaseObject::EnableValueChangedEvent (which enables
this event for all animation variables encapsulated in an animation object).

Inheritance Hierarchy
CUIAnimationCallbackBase

CUIAnimationVariableChangeHandlerBase

CAnimationVariableChangeHandler

Requirements
Header : afxanimationcontroller.h
CAnimationVariableChangeHandler::OnValueChanged
Called when a value of an animation variable has changed.

IFACEMETHOD(OnValueChanged) (
__in IUIAnimationStoryboard* storyboard,
__in IUIAnimationVariable* variable,
__in DOUBLE newValue,
__in DOUBLE previousValue);

Parameters
storyboard
The storyboard that is animating the variable.
variable
The animation variable that was updated.
newValue
The new value.
previousValue
The previous value.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CAnimationVariableChangeHandler::SetAnimationController
Stores a pointer to animation controller to route events.

void SetAnimationController(CAnimationController* pAnimationController);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.

See also
Classes
CAnimationVariableIntegerChangeHandler Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when the value of an animation variable changes.

Syntax
class CAnimationVariableIntegerChangeHandler : public
CUIAnimationVariableIntegerChangeHandlerBase<CAnimationVariableIntegerChangeHandler>;

Members
Public Constructors
NAME DESC RIP T IO N

CAnimationVariableIntegerChangeHandler::CAnimationVariableInt Constructs a CAnimationVariableIntegerChangeHandler object.


egerChangeHandler

Public Methods
NAME DESC RIP T IO N

CAnimationVariableIntegerChangeHandler::CreateInstance Creates an instance of


CAnimationVariableIntegerChangeHandler callback.

CAnimationVariableIntegerChangeHandler::OnIntegerValueChang Called when a value of an animation variable has changed.


ed (Overrides
CUIAnimationVariableIntegerChangeHandlerBase::OnIntegerValueChanged
.)

CAnimationVariableIntegerChangeHandler::SetAnimationControlle Stores a pointer to animation controller to route events.


r

Remarks
This event handler is created and passed to IUIAnimationVariable::SetVariableIntegerChangeHandler method, when you
call CAnimationVariable::EnableIntegerValueChangedEvent or CAnimationBaseObject::EnableIntegerValueChangedEvent
(which enables this event for all animation variables encapsulated in an animation object).

Inheritance Hierarchy
MFC Classes
CUIAnimationCallbackBase

CUIAnimationVariableIntegerChangeHandlerBase

CAnimationVariableIntegerChangeHandler

Requirements
Header : afxanimationcontroller.h
CAnimationVariableIntegerChangeHandler::CAnimationVariableIntegerChan
geHandler
Constructs a CAnimationVariableIntegerChangeHandler object.

CAnimationVariableIntegerChangeHandler ();

CAnimationVariableIntegerChangeHandler::CreateInstance
Creates an instance of CAnimationVariableIntegerChangeHandler callback.

static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(


CAnimationController* pAnimationController,
IUIAnimationVariableIntegerChangeHandler** ppHandler);

Parameters
pAnimationController
A pointer to animation controller, which will receive events.
ppHandler
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CAnimationVariableIntegerChangeHandler::OnIntegerValueChanged
Called when a value of an animation variable has changed.

IFACEMETHOD(OnIntegerValueChanged) (
__in IUIAnimationStoryboard* storyboard,
__in IUIAnimationVariable* variable,
__in INT32 newValue,
__in INT32 previousValue);

Parameters
storyboard
The storyboard that is animating the variable.
variable
The animation variable that was updated.
newValue
The new rounded value.
previousValue
The previous rounded value.
Return Value
S_OK if the method succeeds; otherwise E_FAIL.

CAnimationVariableIntegerChangeHandler::SetAnimationController
Stores a pointer to animation controller to route events.

void SetAnimationController(CAnimationController* pAnimationController);


Parameters
pAnimationController
A pointer to animation controller, which will receive events.

See also
Classes
CArchive Class
4/21/2020 • 22 minutes to read • Edit Online

Allows you to save a complex network of objects in a permanent binary form (usually disk storage) that
persists after those objects are deleted.

Syntax
class CArchive

Members
Public Constructors
NAME DESC RIP T IO N

CArchive::CArchive Creates a CArchive object.

Public Methods
NAME DESC RIP T IO N

CArchive::Abort Closes an archive without throwing an exception.

CArchive::Close Flushes unwritten data and disconnects from the CFile .

CArchive::Flush Flushes unwritten data from the archive buffer.

CArchive::GetFile Gets the CFile object pointer for this archive.

CArchive::GetObjectSchema Called from the Serialize function to determine the


version of the object that is being deserialized.

CArchive::IsBufferEmpty Determines whether the buffer has been emptied during a


Windows Sockets receive process.

CArchive::IsLoading Determines whether the archive is loading.

CArchive::IsStoring Determines whether the archive is storing.

CArchive::MapObject Places objects in the map that are not serialized to the file,
but that are available for subobjects to reference.

CArchive::Read Reads raw bytes.

CArchive::ReadClass Reads a class reference previously stored with WriteClass


.
NAME DESC RIP T IO N

CArchive::ReadObject Calls an object's Serialize function for loading.

CArchive::ReadString Reads a single line of text.

CArchive::SerializeClass Reads or writes the class reference to the CArchive object


depending on the direction of the CArchive .

CArchive::SetLoadParams Sets the size to which the load array grows. Must be called
before any object is loaded or before MapObject or
ReadObject is called.

CArchive::SetObjectSchema Sets the object schema stored in the archive object.

CArchive::SetStoreParams Sets the hash table size and the block size of the map used
to identify unique objects during the serialization process.

CArchive::Write Writes raw bytes.

CArchive::WriteClass Writes a reference to the CRuntimeClass to the


CArchive .

CArchive::WriteObject Calls an object's Serialize function for storing.

CArchive::WriteString Writes a single line of text.

Public Operators
NAME DESC RIP T IO N

CArchive::operator << Stores objects and primitive types to the archive.

CArchive::operator >> Loads objects and primitive types from the archive.

Public Data Members


NAME DESC RIP T IO N

CArchive::m_pDocument

Remarks
CArchive does not have a base class.
Later you can load the objects from persistent storage, reconstituting them in memory. This process of
making data persistent is called "serialization."
You can think of an archive object as a kind of binary stream. Like an input/output stream, an archive is
associated with a file and permits the buffered writing and reading of data to and from storage. An
input/output stream processes sequences of ASCII characters, but an archive processes binary object data in
an efficient, nonredundant format.
You must create a CFile object before you can create a CArchive object. In addition, you must ensure that the
archive's load/store status is compatible with the file's open mode. You are limited to one active archive per
file.
When you construct a CArchive object, you attach it to an object of class CFile (or a derived class) that
represents an open file. You also specify whether the archive will be used for loading or storing. A CArchive
object can process not only primitive types but also objects of CObject-derived classes designed for
serialization. A serializable class usually has a Serialize member function, and it usually uses the
DECLARE_SERIAL and IMPLEMENT_SERIAL macros, as described under class CObject .
The overloaded extraction ( >> ) and insertion ( << ) operators are convenient archive programming
interfaces that support both primitive types and CObject -derived classes.
CArchive also supports programming with the MFC Windows Sockets classes CSocket and CSocketFile. The
IsBufferEmpty member function supports that usage.
For more information on CArchive , see the articles Serialization and Windows Sockets: Using Sockets with
Archives.

Inheritance Hierarchy
CArchive

Requirements
Header : afx.h

CArchive::Abort
Call this function to close the archive without throwing an exception.

void Abort ();

Remarks
The CArchive destructor will normally call Close , which will flush any data that has not been saved to the
associated CFile object. This can cause exceptions.
When catching these exceptions, it is a good idea to use Abort , so that destructing the CArchive object
doesn't cause further exceptions. When handling exceptions, CArchive::Abort will not throw an exception on
failures because, unlike CArchive::Close, Abort ignores failures.
If you used new to allocate the CArchive object on the heap, then you must delete it after closing the file.
Example
See the example for CArchive::WriteClass.

CArchive::CArchive
Constructs a CArchive object and specifies whether it will be used for loading or storing objects.

CArchive(
CFile* pFile,
UINT nMode,
int nBufSize = 4096,
void* lpBuf = NULL);
Parameters
pFile
A pointer to the CFile object that is the ultimate source or destination of the persistent data.
nMode
A flag that specifies whether objects will be loaded from or stored to the archive. The nMode parameter must
have one of the following values:
CArchive::load Loads data from the archive. Requires only CFile read permission.
CArchive::store Saves data to the archive. Requires CFile write permission.
CArchive::bNoFlushOnDelete Prevents the archive from automatically calling Flush when the archive
destructor is called. If you set this flag, you are responsible for explicitly calling Close before the
destructor is called. If you do not, your data will be corrupted.
nBufSize
An integer that specifies the size of the internal file buffer, in bytes. Note that the default buffer size is 4,096
bytes. If you routinely archive large objects, you will improve performance if you use a larger buffer size that
is a multiple of the file buffer size.
lpBuf
An optional pointer to a user-supplied buffer of size nBufSize. If you do not specify this parameter, the archive
allocates a buffer from the local heap and frees it when the object is destroyed. The archive does not free a
user-supplied buffer.
Remarks
You cannot change this specification after you have created the archive.
You may not use CFile operations to alter the state of the file until you have closed the archive. Any such
operation will damage the integrity of the archive. You may access the position of the file pointer at any time
during serialization by obtaining the archive's file object from the GetFile member function and then using the
CFile::GetPosition function. You should call CArchive::Flush before obtaining the position of the file pointer.
Example

CFile file;
TCHAR szBuf[512];
if (!file.Open(_T("CArchive__test__file.txt"),
CFile::modeCreate | CFile::modeWrite))
{
#ifdef _DEBUG
AFXDUMP(_T("Unable to open file\n"));
exit(1);
#endif
}
CArchive ar(&file, CArchive::store, 512, szBuf);

CArchive::Close
Flushes any data remaining in the buffer, closes the archive, and disconnects the archive from the file.

void Close();

Remarks
No further operations on the archive are permitted. After you close an archive, you can create another archive
for the same file or you can close the file.
The member function Close ensures that all data is transferred from the archive to the file, and it makes the
archive unavailable. To complete the transfer from the file to the storage medium, you must first use
CFile::Close and then destroy the CFile object.
Example
See the example for CArchive::WriteString.

CArchive::Flush
Forces any data remaining in the archive buffer to be written to the file.

void Flush();

Remarks
The member function Flush ensures that all data is transferred from the archive to the file. You must call
CFile::Close to complete the transfer from the file to the storage medium.
Example

CFile myFile(_T("CArchive__test__file.txt"),
CFile::modeCreate | CFile::modeWrite);
CArchive ar(&myFile, CArchive::store);

// Write a string to the archive.


ar.WriteString(_T("My string."));

// Flush all of the data to the file.


ar.Flush();

CArchive::GetFile
Gets the CFile object pointer for this archive.

CFile* GetFile() const;

Return Value
A constant pointer to the CFile object in use.
Remarks
You must flush the archive before using GetFile .
Example

const CFile *fp = ar.GetFile();

CArchive::GetObjectSchema
Call this function from the Serialize function to determine the version of the object that is currently being
deserialized.
UINT GetObjectSchema();

Return Value
During deserialization, the version of the object being read.
Remarks
Calling this function is only valid when the CArchive object is being loaded ( CArchive::IsLoading returns
nonzero). It should be the first call in the Serialize function and called only once. A return value of ( UINT)-1
indicates that the version number is unknown.
A CObject -derived class may use VERSIONABLE_SCHEMA combined (using bitwise OR ) with the schema
version itself (in the IMPLEMENT_SERIAL macro) to create a "versionable object," that is, an object whose
Serialize member function can read multiple versions. The default framework functionality (without
VERSIONABLE_SCHEMA) is to throw an exception when the version is mismatched.
Example

IMPLEMENT_SERIAL(CSchemaObject, CObject, VERSIONABLE_SCHEMA | 1)

void CSchemaObject::Serialize(CArchive &ar)


{
CObject::Serialize(ar);

if (ar.IsLoading())
{
int nVersion = ar.GetObjectSchema();

switch (nVersion)
{
case 0:
// read in previous version of
// this object
break;
case 1:
// read in current version of
// this object
break;
default:
// report unknown version of
// this object
break;
}
}
else
{
// Normal storing code goes here
}
}

CArchive::IsBufferEmpty
Call this member function to determine whether the archive object's internal buffer is empty.

BOOL IsBufferEmpty() const;

Return Value
Nonzero if the archive's buffer is empty; otherwise 0.
Remarks
This function is supplied to support programming with the MFC Windows Sockets class CSocketFile . You do
not need to use it for an archive associated with a CFile object.
The reason for using IsBufferEmpty with an archive associated with a CSocketFile object is that the archive's
buffer might contain more than one message or record. After receiving one message, you should use
IsBufferEmpty to control a loop that continues receiving data until the buffer is empty. For more information,
see the Receive member function of class CAsyncSocket , which shows how to use IsBufferEmpty .
For more information, see Windows Sockets: Using Sockets with Archives.

CArchive::IsLoading
Determines whether the archive is loading data.

BOOL IsLoading() const;

Return Value
Nonzero if the archive is currently being used for loading; otherwise 0.
Remarks
This member function is called by the Serialize functions of the archived classes.
Example

int i = 0;
if (ar.IsLoading())
ar >> i;
else
ar << i;

CArchive::IsStoring
Determines whether the archive is storing data.

BOOL IsStoring() const;

Return Value
Nonzero if the archive is currently being used for storing; otherwise 0.
Remarks
This member function is called by the Serialize functions of the archived classes.
If the IsStoring status of an archive is nonzero, then its IsLoading status is 0, and vice versa.
Example

int i = 0;
if (ar.IsStoring())
ar << i;
else
ar >> i;
CArchive::MapObject
Call this member function to place objects in the map that are not really serialized to the file, but that are
available for subobjects to reference.

void MapObject(const CObject* pOb);

Parameters
pOb
A constant pointer to the object being stored.
Remarks
For example, you might not serialize a document, but you would serialize the items that are part of the
document. By calling MapObject , you allow those items, or subobjects, to reference the document. Also,
serialized subitems can serialize their m_pDocument back pointer.
You can call MapObject when you store to and load from the CArchive object. MapObject adds the specified
object to the internal data structures maintained by the CArchive object during serialization and
deserialization, but unlike ReadObject and WriteObject, it does not call serialize on the object.
Example

//MyDocument.h
class CMyDocument : public CDocument
{
public:
DECLARE_SERIAL(CMyDocument)

CObList m_listOfSubItems;

virtual void Serialize(CArchive &ar);


};

//MyDocument.cpp
IMPLEMENT_SERIAL(CMyDocument, CDocument, 1)

void CMyDocument::Serialize(CArchive& ar)


{
CDocument::Serialize(ar);

if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}

ar.MapObject(this);

//serialize the subitems in the document;


//they will be able to serialize their m_pDoc
//back pointer
m_listOfSubItems.Serialize(ar);
}
//SubItem.h
class CSubItem : public CObject
{
DECLARE_SERIAL(CSubItem)
CSubItem() : m_i(0){};

public:
CSubItem(CMyDocument *pDoc)
{
m_pDoc = pDoc;
}

// back pointer to owning document


CMyDocument *m_pDoc;
WORD m_i; // other item data

virtual void Serialize(CArchive &ar);


};

//SubItem.cpp
IMPLEMENT_SERIAL(CSubItem, CObject, 1);

void CSubItem::Serialize(CArchive &ar)

{
if (ar.IsStoring())
{
// will serialize a reference
// to the "mapped" document pointer
ar << (CObject *)m_pDoc;
ar << m_i;
}
else
{
// Will load a reference to
// the "mapped" document pointer
ar >> (CObject *&)m_pDoc;
ar >> m_i;
}
}

CArchive::m_pDocument
Set to NULL by default, this pointer to a CDocument can be set to anything the user of the CArchive instance
wants.

CDocument* m_pDocument;

Remarks
A common usage of this pointer is to convey additional information about the serialization process to all
objects being serialized. This is achieved by initializing the pointer with the document (a CDocument -derived
class) that is being serialized, in such a way that objects within the document can access the document if
necessary. This pointer is also used by COleClientItem objects during serialization.
The framework sets m_pDocument to the document being serialized when a user issues a File Open or Save
command. If you serialize an Object Linking and Embedding (OLE) container document for reasons other than
File Open or Save, you must explicitly set m_pDocument. For example, you would do this when serializing a
container document to the Clipboard.
Example

CFile myFile(_T("My__test__file.dat"),
CFile::modeCreate | CFile::modeWrite);
CArchive ar(&myFile, CArchive::store);
CMyDocument mydoc;
ar.m_pDocument = &mydoc;

// Serialize the document to the archive.


if (ar.m_pDocument != NULL)
ar.m_pDocument->Serialize(ar);

CArchive::operator <<
Stores the indicated object or primitive type to the archive.

friend CArchive& operator<<(


CArchive& ar,
const CObject* pOb);

throw(
CArchiveException*,
CFileException*);

CArchive& AFXAPI operator<<(


CArchive& ar,
const RECT& rect);

CArchive& AFXAPI operator<<(


CArchive& ar,
POINT point);

CArchive& AFXAPI operator<<(


CArchive& ar,
SIZE size);

template<typename BaseType,
class StringTraits> CArchive& operator<<(
const ATL::CStringT<BaseType,
StringTraits>& str);

CArchive& operator<<(BYTE by);


CArchive& operator<<(WORD w);
CArchive& operator<<(LONG l);
CArchive& operator<<(DWORD dw);
CArchive& operator<<(float f);
CArchive& operator<<(double d);
CArchive& operator<<(int i);
CArchive& operator<<(short w);
CArchive& operator<<(char ch);
CArchive& operator<<(wchar_t ch);
CArchive& operator<<(unsigned u);
CArchive& operator<<(bool b);
CArchive& operator<<(ULONGLONG dwdw);
CArchive& operator<<(LONGLONG dwdw);

Return Value
A CArchive reference that enables multiple insertion operators on a single line.
Remarks
The last two versions above are specifically for storing 64-bit integers.
If you used the IMPLEMENT_SERIAL macro in your class implementation, then the insertion operator
overloaded for CObject calls the protected WriteObject . This function, in turn, calls the Serialize function
of the class.
The CStringT insertion operator (<<) supports diagnostic dumping and storing to an archive.
Example
This example demonstrates the use of the CArchive insertion operator << with the int and long types.

long l = 5;
int i = 10;
if (ar.IsStoring())
ar << l << i;

Example
This example 2 demonstrates the use of the CArchive insertion operator << with the CStringT type.

CString s("abc");
ar << s; // Prints the value (abc)

CArchive::operator >>
Loads the indicated object or primitive type from the archive.
friend CArchive& operator>>(
CArchive& ar,
CObject *& pOb);

throw(
CArchiveException*,
CFileException*,
CMemoryException*);

friend CArchive& operator>>(


CArchive& ar,
const CObject *& pOb);

throw(
CArchiveException*,
CFileException*,
CMemoryException*);

CArchive& AFXAPI operator>>(


CArchive& ar,
const RECT& rect);

CArchive& AFXAPI operator>>(


CArchive& ar,
POINT point);

CArchive& AFXAPI operator>>(


CArchive& ar,
SIZE size);

template<typename BaseType,
class StringTraits> CArchive& operator>>(
ATL::CStringT<BaseType,
StringTraits>& str);

CArchive& operator>>(BYTE& by);


CArchive& operator>>(WORD& w);
CArchive& operator>>(int& i);
CArchive& operator>>(LONG& l);
CArchive& operator>>(DWORD& dw);
CArchive& operator>>(float& f);
CArchive& operator>>(double& d);
CArchive& operator>>(short& w);
CArchive& operator>>(char& ch);
CArchive& operator>>(wchar_t& ch);
CArchive& operator>>(unsigned& u);
CArchive& operator>>(bool& b);
CArchive& operator>>(ULONGLONG& dwdw);
CArchive& operator>>(LONGLONG& dwdw);

Return Value
A CArchive reference that enables multiple extraction operators on a single line.
Remarks
The last two versions above are specifically for loading 64-bit integers.
If you used the IMPLEMENT_SERIAL macro in your class implementation, then the extraction operators
overloaded for CObject call the protected ReadObject function (with a nonzero run-time class pointer). This
function, in turn, calls the Serialize function of the class.
The CStringT extraction operator (>>) supports loading from an archive.
Example
This example demonstrates the use of the CArchive extraction operator >> with the int type.

long l;
int i;
if (ar.IsLoading())
ar >> l >> i;

Example
This example demonstrates the use of the CArchive insertion and extraction operators << and >> with the
CStringT type.

CString s;
if (ar.IsLoading())
ar >> s;

CArchive::Read
Reads a specified number of bytes from the archive.

UINT Read(void* lpBuf, UINT nMax);

Parameters
lpBuf
A pointer to a user-supplied buffer that is to receive the data read from the archive.
nMax
An unsigned integer specifying the number of bytes to be read from the archive.
Return Value
An unsigned integer containing the number of bytes actually read. If the return value is less than the number
requested, the end of file has been reached. No exception is thrown on the end-of-file condition.
Remarks
The archive does not interpret the bytes.
You can use the Read member function within your Serialize function for reading ordinary structures that
are contained in your objects.
Example

char pbRead[100];
ar.Read(pbRead, 100);

CArchive::ReadClass
Call this member function to read a reference to a class previously stored with WriteClass.

CRuntimeClass* ReadClass(
const CRuntimeClass* pClassRefRequested = NULL,
UINT* pSchema = NULL,
DWORD* pObTag = NULL);

Parameters
pClassRefRequested
A pointer to the CRuntimeClass structure that corresponds to the class reference requested. Can be NULL.
pSchema
A pointer to a schema of the run-time class previously stored.
pObTag
A number that refers to an object's unique tag. Used internally by the implementation of ReadObject. Exposed
for advanced programming only; pObTag normally should be NULL.
Return Value
A pointer to the CRuntimeClass structure.
Remarks
If pClassRefRequested is not NULL, ReadClass verifies that the archived class information is compatible with
your runtime class. If it is not compatible, ReadClass will throw a CArchiveException.
Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, ReadClass will throw a
CNotSupportedException.
If pSchema is NULL, the schema of the stored class can be retrieved by calling CArchive::GetObjectSchema;
otherwise, * pSchema will contain the schema of the run-time class that was previously stored.
You can use SerializeClass instead of ReadClass , which handles both reading and writing of the class
reference.
Example
See the example for CArchive::WriteClass.

CArchive::ReadObject
Reads object data from the archive and constructs an object of the appropriate type.

CObject* ReadObject(const CRuntimeClass* pClass);

Parameters
pClass
A constant pointer to the CRuntimeClass structure that corresponds to the object you expect to read.
Return Value
A CObject pointer that must be safely cast to the correct derived class by using CObject::IsKindOf.
Remarks
This function is normally called by the CArchive extraction ( >> ) operator overloaded for a CObject pointer.
ReadObject , in turn, calls the Serialize function of the archived class.

If you supply a nonzero pClass parameter, which is obtained by the RUNTIME_CLASS macro, then the
function verifies the run-time class of the archived object. This assumes you have used the
IMPLEMENT_SERIAL macro in the implementation of the class.
Example
See the example for CArchive::WriteObject.

CArchive::ReadString
Call this member function to read text data into a buffer from the file associated with the CArchive object.

BOOL ReadString(CString& rString);


LPTSTR ReadString(LPTSTR lpsz, UINT nMax);

Parameters
rString
A reference to a CString that will contain the resultant string after it is read from the file associated with the
CArchive object.
lpsz
Specifies a pointer to a user-supplied buffer that will receive a null-terminated text string.
nMax
Specifies the maximum number of characters to read. Should be one less than the size of the lpsz buffer.
Return Value
In the version that returns BOOL, TRUE if successful; FALSE otherwise.
In the version that returns an LPTSTR , a pointer to the buffer containing the text data; NULL if end-of-file was
reached.
Remarks
In the version of the member function with the nMax parameter, the buffer will hold up to a limit of nMax - 1
characters. Reading is stopped by a carriage return-line feed pair. Trailing newline characters are always
removed. A null character ('\0') is appended in either case.
CArchive::Read is also available for text-mode input, but it does not terminate on a carriage return-line feed
pair.
Example
See the example for CArchive::WriteString.

CArchive::SerializeClass
Call this member function when you want to store and load the version information of a base class.

void SerializeClass(const CRuntimeClass* pClassRef);

Parameters
pClassRef
A pointer to a run-time class object for the base class.
Remarks
SerializeClass reads or writes the reference to a class to the CArchive object, depending on the direction of
the CArchive . Use SerializeClass in place of ReadClass and WriteClass as a convenient way to serialize
base-class objects; SerializeClass requires less code and fewer parameters.
Like ReadClass , SerializeClass verifies that the archived class information is compatible with your runtime
class. If it is not compatible, SerializeClass will throw a CArchiveException.
Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, SerializeClass will
throw a CNotSupportedException.
Use the RUNTIME_CLASS macro to retrieve the value for the pRuntimeClass parameter. The base class must
have used the IMPLEMENT_SERIAL macro.
Example

class CBaseClass : public CObject


{
DECLARE_SERIAL(CBaseClass);
};
class CDerivedClass : public CBaseClass
{
public:
virtual void Serialize(CArchive &ar);
};
void CDerivedClass::Serialize(CArchive &ar)
{
if (ar.IsStoring())
{
//normal code for storing contents
//of this object
}
else
{
//normal code for reading contents
//of this object
}

//allow the base class to serialize along


//with its version information
ar.SerializeClass(RUNTIME_CLASS(CBaseClass));
CBaseClass::Serialize(ar);
}

CArchive::SetLoadParams
Call SetLoadParams when you are going to read a large number of CObject -derived objects from an archive.

void SetLoadParams(UINT nGrowBy = 1024);

Parameters
nGrowBy
The minimum number of element slots to allocate if a size increase is necessary.
Remarks
CArchive uses a load array to resolve references to objects stored in the archive. SetLoadParams allows you
to set the size to which the load array grows.
You must not call SetLoadParams after any object is loaded, or after MapObject or ReadObject is called.
Example
class CMyLargeDocument : public CDocument
{
public:
virtual void Serialize(CArchive &ar);
};
void CMyLargeDocument::Serialize(CArchive &ar)
{
if (ar.IsStoring())
ar.SetStoreParams(); // use large defaults
else
ar.SetLoadParams();

if (ar.IsStoring())
{
// code for storing CMyLargeDocument
}
else
{
// code for loading CMyLargeDocument
}
}

CArchive::SetObjectSchema
Call this member function to set the object schema stored in the archive object to nSchema.

void SetObjectSchema(UINT nSchema);

Parameters
nSchema
Specifies the object's schema.
Remarks
The next call to GetObjectSchema will return the value stored in nSchema.
Use SetObjectSchema for advanced versioning; for example, when you want to force a particular version to be
read in a Serialize function of a derived class.
Example

ar.SetObjectSchema(2);
ASSERT(2 == ar.GetObjectSchema());

CArchive::SetStoreParams
Use SetStoreParams when storing a large number of CObject -derived objects in an archive.

void SetStoreParams(UINT nHashSize = 2053, UINT nBlockSize = 128);

Parameters
nHashSize
The size of the hash table for interface pointer maps. Should be a prime number.
nBlockSize
Specifies the memory-allocation granularity for extending the parameters. Should be a power of 2 for the
best performance.
Remarks
SetStoreParams allows you to set the hash table size and the block size of the map used to identify unique
objects during the serialization process.
You must not call SetStoreParams after any objects are stored, or after MapObject or WriteObject is called.
Example

class CMyLargeDocument : public CDocument


{
public:
virtual void Serialize(CArchive &ar);
};
void CMyLargeDocument::Serialize(CArchive &ar)
{
if (ar.IsStoring())
ar.SetStoreParams(); // use large defaults
else
ar.SetLoadParams();

if (ar.IsStoring())
{
// code for storing CMyLargeDocument
}
else
{
// code for loading CMyLargeDocument
}
}

CArchive::Write
Writes a specified number of bytes to the archive.

void Write(const void* lpBuf, INT nMax);

Parameters
lpBuf
A pointer to a user-supplied buffer that contains the data to be written to the archive.
nMax
An integer that specifies the number of bytes to be written to the archive.
Remarks
The archive does not format the bytes.
You can use the Write member function within your Serialize function to write ordinary structures that are
contained in your objects.
Example

char pbWrite[100];
memset(pbWrite, 'a', 100);
ar.Write(pbWrite, 100);
CArchive::WriteClass
Use WriteClass to store the version and class information of a base class during serialization of the derived
class.

void WriteClass(const CRuntimeClass* pClassRef);

Parameters
pClassRef
A pointer to the CRuntimeClass structure that corresponds to the class reference requested.
Remarks
WriteClass writes a reference to the CRuntimeClass for the base class to the CArchive . Use
CArchive::ReadClass to retrieve the reference.
WriteClass verifies that the archived class information is compatible with your runtime class. If it is not
compatible, WriteClass will throw a CArchiveException.
Your runtime class must use DECLARE_SERIAL and IMPLEMENT_SERIAL; otherwise, WriteClass will throw a
CNotSupportedException.
You can use SerializeClass instead of WriteClass , which handles both reading and writing of the class
reference.
Example

CFile myFile(_T("My__test__file.dat"),
CFile::modeCreate | CFile::modeReadWrite);

// Create a storing archive.


CArchive arStore(&myFile, CArchive::store);

// Store the class CAge in the archive.


arStore.WriteClass(RUNTIME_CLASS(CAge));

// Close the storing archive.


arStore.Close();

// Create a loading archive.


myFile.SeekToBegin();
CArchive arLoad(&myFile, CArchive::load);

// Load a class from the archive.


CRuntimeClass *pClass = arLoad.ReadClass();
if (!pClass->IsDerivedFrom(RUNTIME_CLASS(CAge)))
{
arLoad.Abort();
}

CArchive::WriteObject
Stores the specified CObject to the archive.

void WriteObject(const CObject* pOb);

Parameters
pOb
A constant pointer to the object being stored.
Remarks
This function is normally called by the CArchive insertion ( << ) operator overloaded for CObject .
WriteObject , in turn, calls the Serialize function of the archived class.

You must use the IMPLEMENT_SERIAL macro to enable archiving. WriteObject writes the ASCII class name to
the archive. This class name is validated later during the load process. A special encoding scheme prevents
unnecessary duplication of the class name for multiple objects of the class. This scheme also prevents
redundant storage of objects that are targets of more than one pointer.
The exact object encoding method (including the presence of the ASCII class name) is an implementation
detail and could change in future versions of the library.

NOTE
Finish creating, deleting, and updating all your objects before you begin to archive them. Your archive will be corrupted
if you mix archiving with object modification.

Example
For a definition of the class CAge , see the example for CObList::CObList.

CFile myFile(_T("My__test__file.dat"),
CFile::modeCreate | CFile::modeReadWrite);
CAge age(21), *pAge;

// Create a storing archive.


CArchive arStore(&myFile, CArchive::store);

// Write the object to the archive


arStore.WriteObject(&age);

// Close the storing archive


arStore.Close();

// Create a loading archive.


myFile.SeekToBegin();
CArchive arLoad(&myFile, CArchive::load);

// Verify the object is in the archive.


pAge = (CAge *)arLoad.ReadObject(RUNTIME_CLASS(CAge));
ASSERT(age == *pAge);

CArchive::WriteString
Use this member function to write data from a buffer to the file associated with the CArchive object.

void WriteString(LPCTSTR lpsz);

Parameters
lpsz
Specifies a pointer to a buffer containing a null-terminated text string.
Remarks
The terminating null character ('\0') is not written to the file; nor is a newline automatically written.
WriteString throws an exception in response to several conditions, including the disk-full condition.
Write is also available, but rather than terminating on a null character, it writes the requested number of
bytes to the file.
Example

CFile myFile(_T("My__test__file.dat"),
CFile::modeCreate | CFile::modeReadWrite);
CString str1("String1"), str2("String2"), str;

// Create a storing archive.


CArchive arStore(&myFile, CArchive::store);

// Write str1 and str2 to the archive


arStore.WriteString(str1);
arStore.WriteString(_T("\n"));
arStore.WriteString(str2);
arStore.WriteString(_T("\n"));

// Close the storing archive


arStore.Close();

// Create a loading archive.


myFile.SeekToBegin();
CArchive arLoad(&myFile, CArchive::load);

// Verify the two strings are in the archive.


arLoad.ReadString(str);
ASSERT(str == str1);
arLoad.ReadString(str);
ASSERT(str == str2);

See also
Hierarchy Chart
CFile Class
CObject Class
CSocket Class
CSocketFile Class
CArchiveException Class
3/27/2020 • 2 minutes to read • Edit Online

Represents a serialization exception condition

Syntax
class CArchiveException : public CException

Members
Public Constructors
NAME DESC RIP T IO N

CArchiveException::CArchiveException Constructs a CArchiveException object.

Public Data Members


NAME DESC RIP T IO N

CArchiveException::m_cause Indicates the exception cause.

CArchiveException::m_strFileName Specifies the name of the file for this exception condition.

Remarks
The CArchiveException class includes a public data member that indicates the cause of the exception.
CArchiveException objects are constructed and thrown inside CArchive member functions. You can access these
objects within the scope of a CATCH expression. The cause code is independent of the operating system. For
more information about exception processing, see Exception Handling (MFC).

Inheritance Hierarchy
CObject
CException
CArchiveException

Requirements
Header : afx.h

CArchiveException::CArchiveException
Constructs a CArchiveException object, storing the value of cause in the object.
CArchiveException(
int cause = CArchiveException::none,
LPCTSTR lpszArchiveName = NULL);

Parameters
cause
An enumerated type variable that indicates the reason for the exception. For a list of the enumerators, see the
m_cause data member.
lpszArchiveName
Points to a string containing the name of the CArchive object causing the exception.
Remarks
You can create a CArchiveException object on the heap and throw it yourself or let the global function
AfxThrowArchiveException handle it for you.
Do not use this constructor directly; instead, call the global function AfxThrowArchiveException .

CArchiveException::m_cause
Specifies the cause of the exception.

int m_cause;

Remarks
This data member is a public variable of type int . Its values are defined by a CArchiveException enumerated type.
The enumerators and their meanings are as follows:
CArchiveException::none No error occurred.
CArchiveException::genericException Unspecified error.
CArchiveException::readOnly Tried to write into an archive opened for loading.
CArchiveException::endOfFile Reached end of file while reading an object.
CArchiveException::writeOnly Tried to read from an archive opened for storing.
CArchiveException::badIndex Invalid file format.
CArchiveException::badClass Tried to read an object into an object of the wrong type.
CArchiveException::badSchema Tried to read an object with a different version of the class.

NOTE
These CArchiveException cause enumerators are distinct from the CFileException cause enumerators.

NOTE
CArchiveException::generic is deprecated. Use genericException instead. If generic is used in an
application and built with /clr, there will be syntax errors that are not easy to decipher.
CArchiveException::m_strFileName
Specifies the name of the file for this exception condition.

CString m_strFileName;

See also
CException Class
Hierarchy Chart
CArchive Class
AfxThrowArchiveException
Exception Processing
CArray Class
4/21/2020 • 13 minutes to read • Edit Online

Supports arrays that are like C arrays, but can dynamically reduce and grow as necessary.

Syntax
template <class TYPE, class ARG_TYPE = const TYPE&>
class CArray : public CObject

Parameters
TYPE
Template parameter that specifies the type of objects stored in the array. TYPE is a parameter that is returned by
CArray .

ARG_TYPE
Template parameter that specifies the argument type that is used to access objects stored in the array. Often a
reference to TYPE. ARG_TYPE is a parameter that is passed to CArray .

Members
Public Constructors
NAME DESC RIP T IO N

CArray::CArray Constructs an empty array.

Public Methods
NAME DESC RIP T IO N

CArray::Add Adds an element to the end of the array; grows the array if
necessary.

CArray::Append Appends another array to the array; grows the array if


necessary

CArray::Copy Copies another array to the array; grows the array if


necessary.

CArray::ElementAt Returns a temporary reference to the element pointer within


the array.

CArray::FreeExtra Frees all unused memory above the current upper bound.

CArray::GetAt Returns the value at a given index.

CArray::GetCount Gets the number of elements in this array.

CArray::GetData Allows access to elements in the array. Can be NULL.


NAME DESC RIP T IO N

CArray::GetSize Gets the number of elements in this array.

CArray::GetUpperBound Returns the largest valid index.

CArray::InsertAt Inserts an element (or all the elements in another array) at a


specified index.

CArray::IsEmpty Determines whether the array is empty.

CArray::RemoveAll Removes all the elements from this array.

CArray::RemoveAt Removes an element at a specific index.

CArray::SetAt Sets the value for a given index; array not allowed to grow.

CArray::SetAtGrow Sets the value for a given index; grows the array if necessary.

CArray::SetSize Sets the number of elements to be contained in this array.

Public Operators
NAME DESC RIP T IO N

operator[] Sets or gets the element at the specified index.

Remarks
Array indexes always start at position 0. You can decide whether to fix the upper bound or enable the array to
expand when you add elements past the current bound. Memory is allocated contiguously to the upper bound,
even if some elements are null.

NOTE
Most methods that resize a CArray object or add elements to it use memcpy_s to move elements. This is a problem
because memcpy_s is not compatible with any objects that require the constructor to be called. If the items in the
CArray are not compatible with memcpy_s , you must create a new CArray of the appropriate size. You must then use
CArray::Copy and CArray::SetAt to populate the new array because those methods use an assignment operator instead of
memcpy_s .

As with a C array, the access time for a CArray indexed element is constant and is independent of the array size.

TIP
Before using an array, use SetSize to establish its size and allocate memory for it. If you do not use SetSize , adding
elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient
and can fragment memory.

If you need a dump of individual elements in an array, you must set the depth of the CDumpContext object to 1
or larger.
Certain member functions of this class call global helper functions that must be customized for most uses of the
CArray class. See the topic Collection Class Helpers in the MFC Macros and Globals section.
Array class derivation is like list derivation.
For more information about how to use CArray , see the article Collections.

Inheritance Hierarchy
CObject
CArray

Requirements
Header : afxtempl.h

CArray::Add
Adds a new element to the end of an array, growing the array by 1.

INT_PTR Add(ARG_TYPE newElement);

Parameters
ARG_TYPE
Template parameter specifying the type of arguments referencing elements in this array.
newElement
The element to be added to this array.
Return Value
The index of the added element.
Remarks
If SetSize has been used with an nGrowBy value greater than 1, then extra memory may be allocated. However,
the upper bound will increase by only 1.
Example

// example for CArray::Add


CArray<CPoint, CPoint> ptArray;

CPoint pt(10, 20);


ptArray.Add(pt); // Element 0
ptArray.Add(CPoint(30, 40)); // Element 1

CArray::Append
Call this member function to add the contents of one array to the end of another.

INT_PTR Append(const CArray& src);

Parameters
src
Source of the elements to be appended to an array.
Return Value
The index of the first appended element.
Remarks
The arrays must be of the same type.
If necessary, Append may allocate extra memory to accommodate the elements appended to the array.
Example

CArray<CPoint, CPoint> myArray1, myArray2;

// Add elements to the second array.


myArray2.Add(CPoint(11, 22));
myArray2.Add(CPoint(12, 42));

// Add elements to the first array and also append the second array.
myArray1.Add(CPoint(1, 2));
myArray1.Append(myArray2);

CArray::CArray
Constructs an empty array.

CArray();

Remarks
The array grows one element at a time.
Example

CArray<CPoint, CPoint> ptArray;

CArray::Copy
Use this member function to copy the elements of one array to another.

void Copy(const CArray& src);

Parameters
src
Source of the elements to be copied to an array.
Remarks
Call this member function to overwrite the elements of one array with the elements of another array.
Copy does not free memory; however, if necessary, Copy may allocate extra memory to accommodate the
elements copied to the array.
Example
CArray<CPoint, CPoint> myArray1, myArray2;

// Add elements to the second array.


myArray2.Add(CPoint(11, 22));
myArray2.Add(CPoint(12, 42));

// Copy the elements from the second array to the first.


myArray1.Copy(myArray2);

CArray::ElementAt
Returns a temporary reference to the specified element within the array.

TYPE& ElementAt(INT_PTR nIndex);


const TYPE& ElementAt(INT_PTR nIndex) const;

Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by
GetUpperBound.
Return Value
A reference to an array element.
Remarks
It is used to implement the left-side assignment operator for arrays.
Example
See the example for GetSize.

CArray::FreeExtra
Frees any extra memory that was allocated while the array was grown.

void FreeExtra();

Remarks
This function has no effect on the size or upper bound of the array.
Example
See the example for GetData.

CArray::GetAt
Returns the array element at the specified index.

TYPE& GetAt(INT_PTR nIndex);


const TYPE& GetAt(INT_PTR nIndex) const;

Parameters
TYPE
Template parameter specifying the type of the array elements.
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by
GetUpperBound.
Return Value
The array element currently at this index.
Remarks
Passing a negative value or a value greater than the value returned by GetUpperBound will result in a failed
assertion.
Example

CArray<CPoint, CPoint> myArray;


CPoint pt;

// Add elements to the array.


for (int i = 0; i < 10; i++)
{
myArray.Add(CPoint(i, 2 * i));
}

// Modify all the points in the array.


for (int i = 0; i <= myArray.GetUpperBound(); i++)
{
pt = myArray.GetAt(i);
pt.x = 0;
myArray.SetAt(i, pt);
}

CArray::GetCount
Returns the number of array elements.

INT_PTR GetCount() const;

Return Value
The number of items in the array.
Remarks
Call this method to retrieve the number of elements in the array. Because indexes are zero-based, the size is 1
greater than the largest index. Calling this method will generate the same result as the CArray::GetSize method.
Example

CArray<CPoint, CPoint> myArray;

// Add elements to the array.


for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2 * i));

// Modify all the points in the array.


for (int i = 0; i < myArray.GetCount(); i++)
{
CPoint &pt = myArray.ElementAt(i);
pt.x = 0;
}
CArray::GetData
Use this member function to gain direct access to the elements in an array.

const TYPE* GetData() const;


TYPE* GetData();

Parameters
TYPE
Template parameter specifying the type of the array elements.
Return Value
A pointer to an array element.
Remarks
If no elements are available, GetData returns a null value.
While direct access to the elements of an array can help you work more quickly, use caution when calling
GetData ; any errors you make directly affect the elements of your array.

Example

CArray<CPoint, CPoint> myArray;

// Allocate memory for at least 32 elements.


myArray.SetSize(32, 128);

// Add elements to the array.


CPoint *pPt = (CPoint *)myArray.GetData();
for (int i = 0; i < 32; i++, pPt++)
{
*pPt = CPoint(i, 2 * i);
}

// Only keep first 5 elements and free extra (unused) bytes.


myArray.SetSize(5, 128);
myArray.FreeExtra();

#if _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif

CArray::GetSize
Returns the size of the array.

INT_PTR GetSize() const;

Remarks
Because indexes are zero-based, the size is 1 greater than the largest index. Calling this method will generate the
same result as the CArray::GetCount method.
Example
CArray<CPoint, CPoint> myArray;

// Add elements to the array.


for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2 * i));

// Modify all the points in the array.


for (int i = 0; i < myArray.GetSize(); i++)
{
CPoint &pt = myArray.ElementAt(i);
pt.x = 0;
}

CArray::GetUpperBound
Returns the current upper bound of this array.

INT_PTR GetUpperBound() const;

Remarks
Because array indexes are zero-based, this function returns a value 1 less than GetSize .
The condition GetUpperBound( ) = -1 indicates that the array contains no elements.
Example
See the example for CArray::GetAt.

CArray::InsertAt
The first version of InsertAt inserts one element (or multiple copies of an element) at a specified index in an
array.

void InsertAt(
INT_PTR nIndex,
ARG_TYPE newElement,
INT_PTR nCount = 1);

void InsertAt(
INT_PTR nStartIndex,
CArray* pNewArray);

Parameters
nIndex
An integer index that may be greater than the value returned by GetUpperBound .
ARG_TYPE
Template parameter specifying the type of elements in this array.
newElement
The element to be placed in this array.
nCount
The number of times this element should be inserted (defaults to 1).
nStartIndex
An integer index that may be greater than the value returned by GetUpperBound.
pNewArray
Another array that contains elements to be added to this array.
Remarks
In the process, it shifts up (by incrementing the index) the existing element at this index, and it shifts up all the
elements above it.
The second version inserts all the elements from another CArray collection, starting at the nStartIndex position.
The SetAt function, in contrast, replaces one specified array element and does not shift any elements.
Example

// example for CArray::InsertAt

CArray<CPoint, CPoint> ptArray;

ptArray.Add(CPoint(10, 20)); // Element 0


ptArray.Add(CPoint(30, 40)); // Element 1 (will become element 2)
ptArray.InsertAt(1, CPoint(50, 60)); // New element 1

CArray::IsEmpty
Determines whether the array is empty.

BOOL IsEmpty() const;

Return Value
Nonzero if the array contains no elements; otherwise 0.

CArray::operator []
These subscript operators are a convenient substitute for the SetAt and GetAt functions.

TYPE& operator[](int_ptr nindex);


const TYPE& operator[](int_ptr nindex) const;

Parameters
TYPE
Template parameter specifying the type of elements in this array.
nIndex
Index of the element to be accessed.
Remarks
The first operator, called for arrays that are not const , may be used on either the right (r-value) or the left (l-
value) of an assignment statement. The second, called for const arrays, may be used only on the right.
The Debug version of the library asserts if the subscript (either on the left or right side of an assignment
statement) is out of bounds.
Example
CArray<CPoint, CPoint> myArray;

// Add elements to the array.


for (int i = 0; i < 10; i++)
{
myArray.Add(CPoint(i, 2 * i));
}

// Modify all the points in the array.


for (int i = 0; i <= myArray.GetUpperBound(); i++)
{
myArray[i].x = 0;
}

CArray::RelocateElements
Relocates data to a new buffer when the array should grow or shrink.

template<class TYPE, class ARG_TYPE>


AFX_INLINE void CArray<TYPE, ARG_TYPE>::RelocateElements(
TYPE* pNewData,
const TYPE* pData,
INT_PTR nCount);

Parameters
pNewData
A new buffer for the array of elements.
pData
The old array of elements.
nCount
Number of elements in the old array.
Remarks
pNewData is always large enough to hold all the pData elements.
The CArray implementation uses this method to copy the old data to a new buffer when the array should grow or
shrink (when SetSize or FreeExtra are called). The default implementation just copies the data.
For arrays in which an element contains a pointer to one of its own members, or another structure contains a
pointer to one of the array elements, the pointers are not updated in plain copy. In this case, you can correct
pointers by implementing a specialization of RelocateElements with the relevant types. You are also responsible
for data copying.

CArray::RemoveAll
Removes all the elements from this array.

void RemoveAll();

Remarks
If the array is already empty, the function still works.
Example
CArray<CPoint, CPoint> myArray;

// Add elements to the array.


for (int i = 0; i < 10; i++)
myArray.Add(CPoint(i, 2 * i));

myArray.RemoveAll();

#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif

CArray::RemoveAt
Removes one or more elements starting at a specified index in an array.

void RemoveAt(
INT_PTR nIndex,
INT_PTR nCount = 1);

Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by
GetUpperBound.
nCount
The number of elements to remove.
Remarks
In the process, it shifts down all the elements above the removed element(s). It decrements the upper bound of
the array but does not free memory.
If you try to remove more elements than are contained in the array above the removal point, then the Debug
version of the library asserts.
Example

CArray<CPoint, CPoint> myArray;

// Add elements to the array.


for (int i = 0; i < 10; i++)
{
myArray.Add(CPoint(i, 2 * i));
}

myArray.RemoveAt(5);

#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << "myArray: " << &myArray << "\n";
#endif

CArray::SetAt
Sets the array element at the specified index.
void SetAt(INT_PTR nIndex, ARG_TYPE newElement);

Parameters
nIndex
An integer index that is greater than or equal to 0 and less than or equal to the value returned by
GetUpperBound.
ARG_TYPE
Template parameter specifying the type of arguments used for referencing array elements.
newElement
The new element value to be stored at the specified position.
Remarks
SetAt will not cause the array to grow. Use SetAtGrow if you want the array to grow automatically.

You must ensure that your index value represents a valid position in the array. If it is out of bounds, then the
Debug version of the library asserts.
Example
See the example for GetAt.

CArray::SetAtGrow
Sets the array element at the specified index.

void SetAtGrow(INT_PTR nIndex, ARG_TYPE newElement);

Parameters
nIndex
An integer index that is greater than or equal to 0.
ARG_TYPE
Template parameter specifying the type of elements in the array.
newElement
The element to be added to this array. A NULL value is allowed.
Remarks
The array grows automatically if necessary (that is, the upper bound is adjusted to accommodate the new
element).
Example

// example for CArray::SetAtGrow


CArray<CPoint, CPoint> ptArray;

ptArray.Add(CPoint(10, 20)); // Element 0


ptArray.Add(CPoint(30, 40)); // Element 1
// Element 2 deliberately skipped
ptArray.SetAtGrow(3, CPoint(50, 60)); // Element 3

CArray::SetSize
Establishes the size of an empty or existing array; allocates memory if necessary.
void SetSize(
INT_PTR nNewSize,
INT_PTR nGrowBy = -1);

Parameters
nNewSize
The new array size (number of elements). Must be greater than or equal to 0.
nGrowBy
The minimum number of element slots to allocate if a size increase is necessary.
Remarks
If the new size is smaller than the old size, then the array is truncated and all unused memory is released.
Use this function to set the size of your array before you begin using the array. If you do not use SetSize , adding
elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are
inefficient and can fragment memory.
The nGrowBy parameter affects internal memory allocation while the array is growing. Its use never affects the
array size as reported by GetSize and GetUpperBound. If the default value is used, MFC allocates memory in a
way calculated to avoid memory fragmentation and optimize efficiency for most cases.
Example
See the example for GetData.

See also
MFC Sample COLLECT
CObject Class
Hierarchy Chart
CObArray Class
Collection Class Helpers
CAsyncMonikerFile Class
3/27/2020 • 9 minutes to read • Edit Online

Provides functionality for the use of asynchronous monikers in ActiveX controls (formerly OLE controls).

Syntax
class CAsyncMonikerFile : public CMonikerFile

Members
Public Constructors
NAME DESC RIP T IO N

CAsyncMonikerFile::CAsyncMonikerFile Constructs a CAsyncMonikerFile object.

Public Methods
NAME DESC RIP T IO N

CAsyncMonikerFile::Close Closes and releases all resources.

CAsyncMonikerFile::GetBinding Retrieves a pointer to the asynchronous transfer binding.

CAsyncMonikerFile::GetFormatEtc Retrieves the format of the data in the stream.

CAsyncMonikerFile::Open Opens a file asynchronously.

Protected Methods
NAME DESC RIP T IO N

CAsyncMonikerFile::CreateBindStatusCallback Creates a COM object that implements


IBindStatusCallback .

CAsyncMonikerFile::GetBindInfo Called by the OLE system library to request information on


the type of bind to be created.

CAsyncMonikerFile::GetPriority Called by the OLE system library to get the priority of the
binding.

CAsyncMonikerFile::OnDataAvailable Called to provide data as it becomes available to the client


during asynchronous bind operations.

CAsyncMonikerFile::OnLowResource Called when resources are low.

CAsyncMonikerFile::OnProgress Called to indicate progress on the data downloading process.


NAME DESC RIP T IO N

CAsyncMonikerFile::OnStartBinding Called when binding is starting up.

CAsyncMonikerFile::OnStopBinding Called when asynchronous transfer is stopped.

Remarks
Derived from CMonikerFile, which in turn is derived from COleStreamFile, CAsyncMonikerFile uses the IMoniker
interface to access any data stream asynchronously, including loading files asynchronously from a URL. The files
can be datapath properties of ActiveX controls.
Asynchronous monikers are used primarily in Internet-enabled applications and ActiveX controls to provide a
responsive user-interface during file transfers. A prime example of this is the use of CDataPathProperty to
provide asynchronous properties for ActiveX controls. The CDataPathProperty object will repeatedly get a
callback to indicate availability of new data during a lengthy property exchange process.
For more information about how to use asynchronous monikers and ActiveX controls in Internet applications,
see the following articles:
Internet First Steps: Asynchronous Monikers
Internet First Steps: ActiveX Controls

Inheritance Hierarchy
CObject
CFile
COleStreamFile
CMonikerFile
CAsyncMonikerFile

Requirements
Header : afxole.h

CAsyncMonikerFile::CAsyncMonikerFile
Constructs a CAsyncMonikerFile object.

CAsyncMonikerFile();

Remarks
It does not create the IBindHost interface. IBindHost is used only if you provide it in the Open member
function.
For a description of the IBindHost interface, see the Windows SDK.

CAsyncMonikerFile::Close
Call this function to close and release all resources.
virtual void Close();

Remarks
Can be called on unopened or already closed files.

CAsyncMonikerFile::CreateBindStatusCallback
Creates a COM object that implements IBindStatusCallback .

virtual IUnknown* CreateBindStatusCallback(IUnknown* pUnkControlling);

Parameters
pUnkControlling
A pointer to the controlling unknown (the outer IUnknown ) or NULL if aggregation is not being used.
Return Value
If pUnkControlling is not NULL, the function returns a pointer to the inner IUnknown on a new COM object
supporting IBindStatusCallback . If pUnkControlling is NULL, the function returns a pointer to an IUnknown on a
new COM object supporting IBindStatusCallback .
Remarks
CAsyncMonikerFile requires a COM object that implements IBindStatusCallback . MFC implements such an
object, and it is aggregatable. You can override CreateBindStatusCallback to return your own COM object. Your
COM object can aggregate MFC's implementation by calling CreateBindStatusCallback with the controlling
unknown of your COM object. COM objects implemented using the CCmdTarget COM support can retrieve the
controlling unknown using CCmdTarget::GetControllingUnknown .
Alternately, your COM object can delegate to MFC's implementation by calling
CreateBindStatusCallback( NULL ) .

CAsyncMonikerFile::Open calls CreateBindStatusCallback .


For more information about asynchronous monikers and asynchronous binding, see the IBindStatusCallback
interface and How Asynchronous Binding and Storage Work. For a discussion of aggregation, see Aggregation.
All three topics are in the Windows SDK.

CAsyncMonikerFile::GetBindInfo
Called from the client of an asynchronous moniker to tell the asynchronous moniker how it wants to bind.

virtual DWORD GetBindInfo() const;

Return Value
Retrieves the settings for IBindStatusCallBack . For a description of the IBindStatusCallback interface, see the
Windows SDK.
Remarks
The default implementation sets the binding to be asynchronous, to use a storage medium (a stream), and to
use the data-push model. Override this function if you want to change the behavior of the binding.
One reason for doing this would be to bind using the data-pull model instead of the data-push model. In a data-
pull model, the client drives the bind operation, and the moniker only provides data to the client when it is read.
In a data-push model, the moniker drives the asynchronous bind operation and continuously notifies the client
whenever new data is available.

CAsyncMonikerFile::GetBinding
Call this function to retrieve a pointer to the asynchronous transfer binding.

IBinding* GetBinding() const;

Return Value
A pointer to the IBinding interface provided when asynchronous transfer begins. Returns NULL if for any
reason the transfer cannot be made asynchronously.
Remarks
This allows you to control the data transfer process through the IBinding interface, for example, with
IBinding::Abort , IBinding::Pause , and IBinding::Resume .

For a description of the IBinding interface, see the Windows SDK.

CAsyncMonikerFile::GetFormatEtc
Call this function to retrieve the format of the data in the stream.

FORMATETC* GetFormatEtc() const;

Return Value
A pointer to the Windows structure FORMATETC for the currently opened stream. Returns NULL if the moniker
has not been bound, if it is not asynchronous, or if the asynchronous operation has not begun.

CAsyncMonikerFile::GetPriority
Called from the client of an asynchronous moniker as the binding process starts to receive the priority given to
the thread for the binding operation.

virtual LONG GetPriority() const;

Return Value
The priority at which the asynchronous transfer will take place. One of the standard thread priority flags:
THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_HIGHEST,
THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_NORMAL, and
THREAD_PRIORITY_TIME_CRITICAL. See the Windows function SetThreadPriority for a description of these
values.
Remarks
GetPriority should not be called directly. THREAD_PRIORITY_NORMAL is returned by the default
implementation.

CAsyncMonikerFile::OnDataAvailable
An asynchronous moniker calls OnDataAvailable to provide data to the client as it becomes available, during
asynchronous bind operations.
virtual void OnDataAvailable(DWORD dwSize, DWORD bscfFlag);

Parameters
dwSize
The cumulative amount (in bytes) of data available since the beginning of the binding. Can be zero, indicating
that the amount of data is not relevant to the operation, or that no specific amount became available.
bscfFlag
A BSCF enumeration value. Can be one or more of the following values:
BSCF_FIRSTDATANOTIFICATION Identifies the first call to OnDataAvailable for a given bind operation.
BSCF_INTERMEDIATEDATANOTIFICATION Identifies an intermediary call to OnDataAvailable for a bind
operation.
BSCF_LASTDATANOTIFICATION Identifies the last call to OnDataAvailable for a bind operation.
Remarks
The default implementation of this function does nothing. See the following example for a sample
implementation.
Example

void CMyMoniker::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)


{
if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) != 0)
{
m_dwReadBefore = 0;
m_strText.Empty();
}

DWORD dwArriving = dwSize - m_dwReadBefore;

if (dwArriving > 0)
{
int nLen = m_strText.GetLength();
ASSERT((DWORD)nLen == m_dwReadBefore);
LPTSTR psz = m_strText.GetBuffer(nLen + dwArriving);
Read(psz + nLen, dwArriving);
m_strText.ReleaseBuffer(nLen + dwArriving);
m_dwReadBefore = dwSize;
}
}

CAsyncMonikerFile::OnLowResource
Called by the moniker when resources are low.

virtual void OnLowResource();

Remarks
The default implementation calls GetBinding( )-> Abort( ) .

CAsyncMonikerFile::OnProgress
Called by the moniker repeatedly to indicate the current progress of this bind operation, typically at reasonable
intervals during a lengthy operation.
virtual void OnProgress(
ULONG ulProgress,
ULONG ulProgressMax,
ULONG ulStatusCode,
LPCTSTR szStatusText);

Parameters
ulProgress
Indicates the current progress of the bind operation relative to the expected maximum indicated in
ulProgressMax.
ulProgressMax
Indicates the expected maximum value of ulProgress for the duration of calls to OnProgress for this operation.
ulStatusCode
Provides additional information regarding the progress of the bind operation. Valid values are taken from the
BINDSTATUS enumeration. See Remarks for possible values.

szStatusText
Information about the current progress, depending on the value of ulStatusCode. See Remarks for possible
values.
Remarks
Possible values for ulStatusCode (and the szStatusText for each value) are:

BINDSTATUS_FINDINGRESOURCE The bind operation is finding the resource that holds the
object or storage being bound to. The szStatusText provides
the display name of the resource being searched for (for
example, "www.microsoft.com").

BINDSTATUS_CONNECTING The bind operation is connecting to the resource that holds


the object or storage being bound to. The szStatusText
provides the display name of the resource being connected
to (for example, an IP address).

BINDSTATUS_SENDINGREQUEST The bind operation is requesting the object or storage being


bound to. The szStatusText provides the display name of the
object (for example, a file name).

BINDSTATUS_REDIRECTING The bind operation has been redirected to a different data


location. The szStatusText provides the display name of the
new data location.

BINDSTATUS_USINGCACHEDCOPY The bind operation is retrieving the requested object or


storage from a cached copy. The szStatusText is NULL.

BINDSTATUS_BEGINDOWNLOADDATA The bind operation has begun receiving the object or


storage being bound to. The szStatusText provides the
display name of the data location.

BINDSTATUS_DOWNLOADINGDATA The bind operation continues to receive the object or


storage being bound to. The szStatusText provides the
display name of the data location.
BINDSTATUS_ENDDOWNLOADDATA The bind operation has finished receiving the object or
storage being bound to. The szStatusText provides the
display name of the data location.

BINDSTATUS_CLASSIDAVAILABLE An instance of the object being bound to is just about to be


created. The szStatusText provides the CLSID of the new
object in string format, allowing the client an opportunity to
cancel the bind operation, if desired.

CAsyncMonikerFile::OnStartBinding
Override this function in your derived classes to perform actions when binding is starting up.

virtual void OnStartBinding();

Remarks
This function is called back by the moniker. The default implementation does nothing.

CAsyncMonikerFile::OnStopBinding
Called by the moniker at the end of the bind operation.

virtual void OnStopBinding(HRESULT hresult, LPCTSTR szError);

Parameters
hresult
An HRESULT that is the error or warning value.
szErrort
A character string describing the error.
Remarks
Override this function to perform actions when the transfer is stopped. By default, the function releases
IBinding .

For a description of the IBinding interface, see the Windows SDK.

CAsyncMonikerFile::Open
Call this member function to open a file asynchronously.
virtual BOOL Open(
LPCTSTR lpszURL,
CFileException* pError = NULL);

virtual BOOL Open(


IMoniker* pMoniker,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszURL,
IBindHost* pBindHost,
CFileException* pError = NULL);

virtual BOOL Open(


IMoniker* pMoniker,
IBindHost* pBindHost,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszURL,
IServiceProvider* pServiceProvider,
CFileException* pError = NULL);

virtual BOOL Open(


IMoniker* pMoniker,
IServiceProvider* pServiceProvider,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszURL,
IUnknown* pUnknown,
CFileException* pError = NULL);

virtual BOOL Open(


IMoniker* pMoniker,
IUnknown* pUnknown,
CFileException* pError = NULL);

Parameters
lpszURL
A pointer to file to be opened asynchronously. The file can be any valid URL or filename.
pError
A pointer to the file exceptions. In the event of an error, it will be set to the cause.
pMoniker
A pointer to the asynchronous moniker interface IMoniker , a precise moniker that is the combination of the
document's own moniker, which you can retrieve with IOleClientSite::GetMoniker(OLEWHICHMK_CONTAINER) , and a
moniker created from the path name. The control can use this moniker to bind, but this is not the moniker the
control should save.
pBindHost
A pointer to the IBindHost interface that will be used to create the moniker from a potentially relative
pathname. If the bind host is invalid or does not provide a moniker, the call defaults to
Open(lpszFileName,pError) . For a description of the IBindHost interface, see the Windows SDK.

pServiceProvider
A pointer to the IServiceProvider interface. If the service provider is invalid or fails to provide the service for
IBindHost , the call defaults to Open(lpszFileName,pError) .

pUnknown
A pointer to the IUnknown interface. If IServiceProvider is found, the function queries for IBindHost . If the
service provider is invalid or fails to provide the service for IBindHost , the call defaults to
Open(lpszFileName,pError) .

Return Value
Nonzero if the file is opened successfully; otherwise 0.
Remarks
This call initiates the binding process.
You can use a URL or a filename for the lpszURL parameter. For example:

CMyMoniker *pMyMoniker = new CMyMoniker();


pMyMoniker->Open(_T("http://www.microsoft.com"));

- or -

CMyMoniker *pMyMoniker = new CMyMoniker();


pMyMoniker->Open(_T("file:c:\\mydata.dat"));

See also
CMonikerFile Class
Hierarchy Chart
CMonikerFile Class
CDataPathProperty Class
CAsyncSocket Class
4/21/2020 • 56 minutes to read • Edit Online

Represents a Windows Socket — an endpoint of network communication.

Syntax
class CAsyncSocket : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CAsyncSocket::CAsyncSocket Constructs a CAsyncSocket object.

Public Methods
NAME DESC RIP T IO N

CAsyncSocket::Accept Accepts a connection on the socket.

CAsyncSocket::AsyncSelect Requests event notification for the socket.

CAsyncSocket::Attach Attaches a socket handle to a CAsyncSocket object.

CAsyncSocket::Bind Associates a local address with the socket.

CAsyncSocket::Close Closes the socket.

CAsyncSocket::Connect Establishes a connection to a peer socket.

CAsyncSocket::Create Creates a socket.

CAsyncSocket::Detach Detaches a socket handle from a CAsyncSocket object.

CAsyncSocket::FromHandle Returns a pointer to a CAsyncSocket object, given a


socket handle.

CAsyncSocket::GetLastError Gets the error status for the last operation that failed.

CAsyncSocket::GetPeerName Gets the address of the peer socket to which the socket is
connected.

CAsyncSocket::GetPeerNameEx Gets the address of the peer socket to which the socket is
connected (handles IPv6 addresses).
NAME DESC RIP T IO N

CAsyncSocket::GetSockName Gets the local name for a socket.

CAsyncSocket::GetSockNameEx Gets the local name for a socket (handles IPv6 addresses).

CAsyncSocket::GetSockOpt Retrieves a socket option.

CAsyncSocket::IOCtl Controls the mode of the socket.

CAsyncSocket::Listen Establishes a socket to listen for incoming connection


requests.

CAsyncSocket::Receive Receives data from the socket.

CAsyncSocket::ReceiveFrom Receives a datagram and stores the source address.

CAsyncSocket::ReceiveFromEx Receives a datagram and stores the source address (handles


IPv6 addresses).

CAsyncSocket::Send Sends data to a connected socket.

CAsyncSocket::SendTo Sends data to a specific destination.

CAsyncSocket::SendToEx Sends data to a specific destination (handles IPv6


addresses).

CAsyncSocket::SetSockOpt Sets a socket option.

CAsyncSocket::ShutDown Disables Send and/or Receive calls on the socket.

CASyncSocket::Socket Allocates a socket handle.

Protected Methods
NAME DESC RIP T IO N

CAsyncSocket::OnAccept Notifies a listening socket that it can accept pending


connection requests by calling Accept .

CAsyncSocket::OnClose Notifies a socket that the socket connected to it has closed.

CAsyncSocket::OnConnect Notifies a connecting socket that the connection attempt is


complete, whether successfully or in error.

CAsyncSocket::OnOutOfBandData Notifies a receiving socket that there is out-of-band data to


be read on the socket, usually an urgent message.

CAsyncSocket::OnReceive Notifies a listening socket that there is data to be retrieved


by calling Receive .

CAsyncSocket::OnSend Notifies a socket that it can send data by calling Send .

Public Operators
NAME DESC RIP T IO N

CAsyncSocket::operator = Assigns a new value to a CAsyncSocket object.

CAsyncSocket::operator SOCKET Use this operator to retrieve the SOCKET handle of the
CAsyncSocket object.

Public Data Members


NAME DESC RIP T IO N

CAsyncSocket::m_hSocket Indicates the SOCKET handle attached to this


CAsyncSocket object.

Remarks
Class CAsyncSocket encapsulates the Windows Socket Functions API, providing an object-oriented abstraction
for programmers who want to use Windows Sockets in conjunction with MFC.
This class is based on the assumption that you understand network communications. You are responsible for
handling blocking, byte-order differences, and conversions between Unicode and multibyte character set
(MBCS) strings. If you want a more convenient interface that manages these issues for you, see class CSocket.
To use a CAsyncSocket object, call its constructor, then call the Create function to create the underlying socket
handle (type SOCKET ), except on accepted sockets. For a server socket call the Listen member function, and for
a client socket call the Connect member function. The server socket should call the Accept function upon
receiving a connection request. Use the remaining CAsyncSocket functions to carry out communications
between sockets. Upon completion, destroy the CAsyncSocket object if it was created on the heap; the
destructor automatically calls the Close function. The SOCKET data type is described in the article Windows
Sockets: Background.

NOTE
When using MFC sockets in secondary threads in a statically linked MFC application, you must call AfxSocketInit in
each thread that uses sockets to initialize the socket libraries. By default, AfxSocketInit is called only in the primary
thread.

For more information, see Windows Sockets: Using Class CAsyncSocket and related articles., as well as
Windows Sockets 2 API.

Inheritance Hierarchy
CObject
CAsyncSocket

Requirements
Header : afxsock.h

CAsyncSocket::Accept
Call this member function to accept a connection on a socket.
virtual BOOL Accept(
CAsyncSocket& rConnectedSocket,
SOCKADDR* lpSockAddr = NULL,
int* lpSockAddrLen = NULL);

Parameters
rConnectedSocket
A reference identifying a new socket that is available for connection.
lpSockAddr
A pointer to a SOCKADDR structure that receives the address of the connecting socket, as known on the
network. The exact format of the lpSockAddr argument is determined by the address family established when
the socket was created. If lpSockAddr and/or lpSockAddrLen are equal to NULL, then no information about the
remote address of the accepted socket is returned.
lpSockAddrLen
A pointer to the length of the address in lpSockAddr in bytes. The lpSockAddrLen is a value-result parameter:
it should initially contain the amount of space pointed to by lpSockAddr; on return it will contain the actual
length (in bytes) of the address returned.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument is too small (less than the size of a SOCKADDR structure).
WSAEINPROGRESS A blocking Windows Sockets call is in progress.
WSAEINVAL Listen was not invoked prior to accept.
WSAEMFILE The queue is empty upon entry to accept and there are no descriptors available.
WSAENOBUFS No buffer space is available.
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP The referenced socket is not a type that supports connection-oriented service.
WSAEWOULDBLOCK The socket is marked as nonblocking and no connections are present to be
accepted.
Remarks
This routine extracts the first connection in the queue of pending connections, creates a new socket with the
same properties as this socket, and attaches it to rConnectedSocket. If no pending connections are present on
the queue, Accept returns zero and GetLastError returns an error. The accepted socket ( rConnectedSocket)
cannot be used to accept more connections. The original socket remains open and listening.
The argument lpSockAddr is a result parameter that is filled in with the address of the connecting socket, as
known to the communications layer. Accept is used with connection-based socket types such as
SOCK_STREAM.

CAsyncSocket::AsyncSelect
Call this member function to request event notification for a socket.
BOOL AsyncSelect(long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);

Parameters
lEvent
A bitmask which specifies a combination of network events in which the application is interested.
FD_READ Want to receive notification of readiness for reading.
FD_WRITE Want to receive notification when data is available to be read.
FD_OOB Want to receive notification of the arrival of out-of-band data.
FD_ACCEPT Want to receive notification of incoming connections.
FD_CONNECT Want to receive notification of connection results.
FD_CLOSE Want to receive notification when a socket has been closed by a peer.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEINVAL Indicates that one of the specified parameters was invalid.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
Remarks
This function is used to specify which MFC callback notification functions will be called for the socket.
AsyncSelect automatically sets this socket to nonblocking mode. For more information, see the article
Windows Sockets: Socket Notifications.

CAsyncSocket::Attach
Call this member function to attach the hSocket handle to an CAsyncSocket object.

BOOL Attach(
SOCKET hSocket, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);

Parameters
hSocket
Contains a handle to a socket.
lEvent
A bitmask which specifies a combination of network events in which the application is interested.
FD_READ Want to receive notification of readiness for reading.
FD_WRITE Want to receive notification when data is available to be read.
FD_OOB Want to receive notification of the arrival of out-of-band data.
FD_ACCEPT Want to receive notification of incoming connections.
FD_CONNECT Want to receive notification of connection results.
FD_CLOSE Want to receive notification when a socket has been closed by a peer.
Return Value
Nonzero if the function is successful.
Remarks
The SOCKET handle is stored in the object's m_hSocket data member.

CAsyncSocket::Bind
Call this member function to associate a local address with the socket.

BOOL Bind(
UINT nSocketPort,
LPCTSTR lpszSocketAddress = NULL);

BOOL Bind (
const SOCKADDR* lpSockAddr,
int nSockAddrLen);

Parameters
nSocketPort
The port identifying the socket application.
lpszSocketAddress
The network address, a dotted number such as "128.56.22.8". Passing the NULL string for this parameter
indicates the CAsyncSocket instance should listen for client activity on all network interfaces.
lpSockAddr
A pointer to a SOCKADDR structure that contains the address to assign to this socket.
nSockAddrLen
The length of the address in lpSockAddr in bytes.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following list covers a few of the errors that might be returned. For a complete list, see
Windows Sockets Error Codes.
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEADDRINUSE The specified address is already in use. (See the SO_REUSEADDR socket option
under SetSockOpt.)
WSAEFAULT The nSockAddrLen argument is too small (less than the size of a SOCKADDR structure).
WSAEINPROGRESS A blocking Windows Sockets call is in progress.
WSAEAFNOSUPPORT The specified address family is not supported by this port.
WSAEINVAL The socket is already bound to an address.
WSAENOBUFS Not enough buffers available, too many connections.
WSAENOTSOCK The descriptor is not a socket.
Remarks
This routine is used on an unconnected datagram or stream socket, before subsequent Connect or Listen
calls. Before it can accept connection requests, a listening server socket must select a port number and make it
known to Windows Sockets by calling Bind . Bind establishes the local association (host address/port
number) of the socket by assigning a local name to an unnamed socket.

CAsyncSocket::CAsyncSocket
Constructs a blank socket object.

CAsyncSocket();

Remarks
After constructing the object, you must call its Create member function to create the SOCKET data structure
and bind its address. (On the server side of a Windows Sockets communication, when the listening socket
creates a socket to use in the Accept call, you do not call Create for that socket.)

CAsyncSocket::Close
Closes the socket.

virtual void Close();

Remarks
This function releases the socket descriptor so that further references to it will fail with the error
WSAENOTSOCK. If this is the last reference to the underlying socket, the associated naming information and
queued data are discarded. The socket object's destructor calls Close for you.
For CAsyncSocket , but not for CSocket , the semantics of Close are affected by the socket options SO_LINGER
and SO_DONTLINGER. For further information, see member function GetSockOpt .

CAsyncSocket::Connect
Call this member function to establish a connection to an unconnected stream or datagram socket.

BOOL Connect(
LPCTSTR lpszHostAddress,
UINT nHostPort);

BOOL Connect(
const SOCKADDR* lpSockAddr,
int nSockAddrLen);

Parameters
lpszHostAddress
The network address of the socket to which this object is connected: a machine name such as
"ftp.microsoft.com", or a dotted number such as "128.56.22.8".
nHostPort
The port identifying the socket application.
lpSockAddr
A pointer to a SOCKADDR structure that contains the address of the connected socket.
nSockAddrLen
The length of the address in lpSockAddr in bytes.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. If this indicates an error code of WSAEWOULDBLOCK, and your application is using the
overridable callbacks, your application will receive an OnConnect message when the connect operation is
complete. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEADDRINUSE The specified address is already in use.
WSAEINPROGRESS A blocking Windows Sockets call is in progress.
WSAEADDRNOTAVAIL The specified address is not available from the local machine.
WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED The attempt to connect was rejected.
WSAEDESTADDRREQ A destination address is required.
WSAEFAULT The nSockAddrLen argument is incorrect.
WSAEINVAL Invalid host address.
WSAEISCONN The socket is already connected.
WSAEMFILE No more file descriptors are available.
WSAENETUNREACH The network cannot be reached from this host at this time.
WSAENOBUFS No buffer space is available. The socket cannot be connected.
WSAENOTSOCK The descriptor is not a socket.
WSAETIMEDOUT Attempt to connect timed out without establishing a connection.
WSAEWOULDBLOCK The socket is marked as nonblocking and the connection cannot be completed
immediately.
Remarks
If the socket is unbound, unique values are assigned to the local association by the system, and the socket is
marked as bound. Note that if the address field of the name structure is all zeroes, Connect will return zero. To
get extended error information, call the GetLastError member function.
For stream sockets (type SOCK_STREAM), an active connection is initiated to the foreign host. When the socket
call completes successfully, the socket is ready to send/receive data.
For a datagram socket (type SOCK_DGRAM), a default destination is set, which will be used on subsequent
Send and Receive calls.

CAsyncSocket::Create
Call the Create member function after constructing a socket object to create the Windows socket and attach
it.
BOOL Create(
UINT nSocketPort = 0,
int nSocketType = SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
LPCTSTR lpszSocketAddress = NULL);

Parameters
nSocketPort
A well-known port to be used with the socket, or 0 if you want Windows Sockets to select a port.
nSocketType
SOCK_STREAM or SOCK_DGRAM.
lEvent
A bitmask which specifies a combination of network events in which the application is interested.
FD_READ Want to receive notification of readiness for reading.
FD_WRITE Want to receive notification of readiness for writing.
FD_OOB Want to receive notification of the arrival of out-of-band data.
FD_ACCEPT Want to receive notification of incoming connections.
FD_CONNECT Want to receive notification of completed connection.
FD_CLOSE Want to receive notification of socket closure.
lpszSockAddress
A pointer to a string containing the network address of the connected socket, a dotted number such as
"128.56.22.8".Passing the NULL string for this parameter indicates the CAsyncSocket instance should listen for
client activity on all network interfaces.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEAFNOSUPPORT The specified address family is not supported.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEMFILE No more file descriptors are available.
WSAENOBUFS No buffer space is available. The socket cannot be created.
WSAEPROTONOSUPPORT The specified port is not supported.
WSAEPROTOTYPE The specified port is the wrong type for this socket.
WSAESOCKTNOSUPPORT The specified socket type is not supported in this address family.
Remarks
Create calls Socket and if successful, it calls Bind to bind the socket to the specified address. The following
socket types are supported:
SOCK_STREAM Provides sequenced, reliable, full-duplex, connection-based byte streams. Uses the
Transmission Control Protocol (TCP) for the Internet address family.
SOCK_DGRAM Supports datagrams, which are connectionless, unreliable packets of a fixed (typically
small) maximum length. Uses the User Datagram Protocol (UDP) for the Internet address family.

NOTE
The Accept member function takes a reference to a new, empty CSocket object as its parameter. You must
construct this object before you call Accept . Keep in mind that if this socket object goes out of scope, the
connection closes. Do not call Create for this new socket object.

IMPORTANT
Create is not thread-safe. If you are calling it in a multi-threaded environment where it could be invoked
simultaneously by different threads, be sure to protect each call with a mutex or other synchronization lock.

For more information about stream and datagram sockets, see the articles Windows Sockets: Background and
Windows Sockets: Ports and Socket Addresses and Windows Sockets 2 API.

CAsyncSocket::Detach
Call this member function to detach the SOCKET handle in the m_hSocket data member from the
CAsyncSocket object and set m_hSocket to NULL.

SOCKET Detach();

CAsyncSocket::FromHandle
Returns a pointer to a CAsyncSocket object.

static CAsyncSocket* PASCAL FromHandle(SOCKET hSocket);

Parameters
hSocket
Contains a handle to a socket.
Return Value
A pointer to an CAsyncSocket object, or NULL if there is no CAsyncSocket object attached to hSocket.
Remarks
When given a SOCKET handle, if a CAsyncSocket object is not attached to the handle, the member function
returns NULL.

CAsyncSocket::GetLastError
Call this member function to get the error status for the last operation that failed.

static int PASCAL GetLastError();

Return Value
The return value indicates the error code for the last Windows Sockets API routine performed by this thread.
Remarks
When a particular member function indicates that an error has occurred, GetLastError should be called to
retrieve the appropriate error code. See the individual member function descriptions for a list of applicable
error codes.
For more information about the error codes, see Windows Sockets 2 API.

CAsyncSocket::GetPeerName
Call this member function to get the address of the peer socket to which this socket is connected.

BOOL GetPeerName(
CString& rPeerAddress,
UINT& rPeerPort);

BOOL GetPeerName(
SOCKADDR* lpSockAddr,
int* lpSockAddrLen);

Parameters
rPeerAddress
Reference to a CString object that receives a dotted number IP address.
rPeerPort
Reference to a UINT that stores a port.
lpSockAddr
A pointer to the SOCKADDR structure that receives the name of the peer socket.
lpSockAddrLen
A pointer to the length of the address in lpSockAddr in bytes. On return, the lpSockAddrLen argument
contains the actual size of lpSockAddr returned in bytes.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument is not large enough.
WSAEINPROGRESS A blocking Windows Sockets call is in progress.
WSAENOTCONN The socket is not connected.
WSAENOTSOCK The descriptor is not a socket.
Remarks
To handle IPv6 addresses, use CAsyncSocket::GetPeerNameEx.

CAsyncSocket::GetPeerNameEx
Call this member function to get the address of the peer socket to which this socket is connected (handles IPv6
addresses).
BOOL GetPeerNameEx(
CString& rPeerAddress,
UINT& rPeerPort);

Parameters
rPeerAddress
Reference to a CString object that receives a dotted number IP address.
rPeerPort
Reference to a UINT that stores a port.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument is not large enough.
WSAEINPROGRESS A blocking Windows Sockets call is in progress.
WSAENOTCONN The socket is not connected.
WSAENOTSOCK The descriptor is not a socket.
Remarks
This function is the same as CAsyncSocket::GetPeerName except that it handles IPv6 addresses as well as older
protocols.

CAsyncSocket::GetSockName
Call this member function to get the local name for a socket.

BOOL GetSockName(
CString& rSocketAddress,
UINT& rSocketPort);

BOOL GetSockName(
SOCKADDR* lpSockAddr,
int* lpSockAddrLen);

Parameters
rSocketAddress
Reference to a CString object that receives a dotted number IP address.
rSocketPort
Reference to a UINT that stores a port.
lpSockAddr
A pointer to a SOCKADDR structure that receives the address of the socket.
lpSockAddrLen
A pointer to the length of the address in lpSockAddr in bytes.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument is not large enough.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOTSOCK The descriptor is not a socket.
WSAEINVAL The socket has not been bound to an address with Bind .
Remarks
This call is especially useful when a Connect call has been made without doing a Bind first; this call provides
the only means by which you can determine the local association which has been set by the system.
To handle IPv6 addresses, use CAsyncSocket::GetSockNameEx

CAsyncSocket::GetSockNameEx
Call this member function to get the local name for a socket (handles IPv6 addresses).

BOOL GetSockNameEx(
CString& rSocketAddress,
UINT& rSocketPort);

Parameters
rSocketAddress
Reference to a CString object that receives a dotted number IP address.
rSocketPort
Reference to a UINT that stores a port.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument is not large enough.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOTSOCK The descriptor is not a socket.
WSAEINVAL The socket has not been bound to an address with Bind .
Remarks
This call is the same as CAsyncSocket::GetSockName except that it handles IPv6 addresses as well as older
protocols.
This call is especially useful when a Connect call has been made without doing a Bind first; this call provides
the only means by which you can determine the local association which has been set by the system.
CAsyncSocket::GetSockOpt
Call this member function to retrieve a socket option.

BOOL GetSockOpt(
int nOptionName,
void* lpOptionValue,
int* lpOptionLen,
int nLevel = SOL_SOCKET);

Parameters
nOptionName
The socket option for which the value is to be retrieved.
lpOptionValue
A pointer to the buffer in which the value for the requested option is to be returned. The value associated with
the selected option is returned in the buffer lpOptionValue. The integer pointed to by lpOptionLen should
originally contain the size of this buffer in bytes; and on return, it will be set to the size of the value returned.
For SO_LINGER, this will be the size of a LINGER structure; for all other options it will be the size of a BOOL or
an int , depending on the option. See the list of options and their sizes in the Remarks section.
lpOptionLen
A pointer to the size of the lpOptionValue buffer in bytes.
nLevel
The level at which the option is defined; the only supported levels are SOL_SOCKET and IPPROTO_TCP.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. If an option was never set with SetSockOpt , then GetSockOpt returns the default value for the
option. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpOptionLen argument was invalid.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOPROTOOPT The option is unknown or unsupported. In particular, SO_BROADCAST is not
supported on sockets of type SOCK_STREAM, while SO_ACCEPTCONN, SO_DONTLINGER,
SO_KEEPALIVE, SO_LINGER, and SO_OOBINLINE are not supported on sockets of type SOCK_DGRAM.
WSAENOTSOCK The descriptor is not a socket.
Remarks
GetSockOpt retrieves the current value for a socket option associated with a socket of any type, in any state,
and stores the result in lpOptionValue. Options affect socket operations, such as the routing of packets, out-of-
band data transfer, and so on.
The following options are supported for GetSockOpt . The Type identifies the type of data addressed by
lpOptionValue. The TCP_NODELAY option uses level IPPROTO_TCP; all other options use level SOL_SOCKET.

VA L UE TYPE M EA N IN G

SO_ACCEPTCONN BOOL Socket is listening.


VA L UE TYPE M EA N IN G

SO_BROADCAST BOOL Socket is configured for the


transmission of broadcast messages.

SO_DEBUG BOOL Debugging is enabled.

SO_DONTLINGER BOOL If true, the SO_LINGER option is


disabled.

SO_DONTROUTE BOOL Routing is disabled.

SO_ERROR int Retrieve error status and clear.

SO_KEEPALIVE BOOL Keep-alives are being sent.

SO_LINGER struct LINGER Returns the current linger options.

SO_OOBINLINE BOOL Out-of-band data is being received in


the normal data stream.

SO_RCVBUF int Buffer size for receives.

SO_REUSEADDR BOOL The socket can be bound to an


address which is already in use.

SO_SNDBUF int Buffer size for sends.

SO_TYPE int The type of the socket (for example,


SOCK_STREAM).

TCP_NODELAY BOOL Disables the Nagle algorithm for send


coalescing.

Berkeley Software Distribution (BSD) options not supported for GetSockOpt are:

VA L UE TYPE M EA N IN G

SO_RCVLOWAT int Receive low water mark.

SO_RCVTIMEO int Receive timeout.

SO_SNDLOWAT int Send low water mark.

SO_SNDTIMEO int Send timeout.

IP_OPTIONS Get options in IP header.

TCP_MAXSEG int Get TCP maximum segment size.

Calling GetSockOpt with an unsupported option will result in an error code of WSAENOPROTOOPT being
returned from GetLastError .
CAsyncSocket::IOCtl
Call this member function to control the mode of a socket.

BOOL IOCtl(
long lCommand,
DWORD* lpArgument);

Parameters
lCommand
The command to perform on the socket.
lpArgument
A pointer to a parameter for lCommand.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEINVAL lCommand is not a valid command, or lpArgument is not an acceptable parameter for
lCommand, or the command is not applicable to the type of socket supplied.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOTSOCK The descriptor is not a socket.
Remarks
This routine can be used on any socket in any state. It is used to get or retrieve operating parameters
associated with the socket, independent of the protocol and communications subsystem. The following
commands are supported:
FIONBIO Enable or disable nonblocking mode on the socket. The lpArgument parameter points at a
DWORD , which is nonzero if nonblocking mode is to be enabled and zero if it is to be disabled. If
AsyncSelect has been issued on a socket, then any attempt to use IOCtl to set the socket back to
blocking mode will fail with WSAEINVAL. To set the socket back to blocking mode and prevent the
WSAEINVAL error, an application must first disable AsyncSelect by calling AsyncSelect with the lEvent
parameter equal to 0, then call IOCtl .
FIONREAD Determine the maximum number of bytes that can be read with one Receive call from this
socket. The lpArgument parameter points at a DWORD in which IOCtl stores the result. If this socket is
of type SOCK_STREAM, FIONREAD returns the total amount of data which can be read in a single
Receive ; this is normally the same as the total amount of data queued on the socket. If this socket is of
type SOCK_DGRAM, FIONREAD returns the size of the first datagram queued on the socket.
SIOCATMARK Determine whether all out-of-band data has been read. This applies only to a socket of
type SOCK_STREAM which has been configured for in-line reception of any out-of-band data (
SO_OOBINLINE). If no out-of-band data is waiting to be read, the operation returns nonzero. Otherwise
it returns 0, and the next Receive or ReceiveFrom performed on the socket will retrieve some or all of
the data preceding the "mark"; the application should use the SIOCATMARK operation to determine
whether any data remains. If there is any normal data preceding the "urgent" (out-of-band) data, it will
be received in order. (Note that a Receive or ReceiveFrom will never mix out-of-band and normal data
in the same call.) The lpArgument parameter points at a DWORD in which IOCtl stores the result.
This function is a subset of ioctl() as used in Berkeley sockets. In particular, there is no command which is
equivalent to FIOASYNC, while SIOCATMARK is the only socket-level command which is supported.

CAsyncSocket::Listen
Call this member function to listen for incoming connection requests.

BOOL Listen(int nConnectionBacklog = 5);

Parameters
nConnectionBacklog
The maximum length to which the queue of pending connections can grow. Valid range is from 1 to 5.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEADDRINUSE An attempt has been made to listen on an address in use.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEINVAL The socket has not been bound with Bind or is already connected.
WSAEISCONN The socket is already connected.
WSAEMFILE No more file descriptors are available.
WSAENOBUFS No buffer space is available.
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP The referenced socket is not of a type that supports the Listen operation.
Remarks
To accept connections, the socket is first created with Create , a backlog for incoming connections is specified
with Listen , and then the connections are accepted with Accept . Listen applies only to sockets that
support connections, that is, those of type SOCK_STREAM. This socket is put into "passive" mode where
incoming connections are acknowledged and queued pending acceptance by the process.
This function is typically used by servers (or any application that wants to accept connections) that could have
more than one connection request at a time: if a connection request arrives with the queue full, the client will
receive an error with an indication of WSAECONNREFUSED.
Listen attempts to continue to function rationally when there are no available ports (descriptors). It will
accept connections until the queue is emptied. If ports become available, a later call to Listen or Accept will
refill the queue to the current or most recent "backlog," if possible, and resume listening for incoming
connections.

CAsyncSocket::m_hSocket
Contains the SOCKET handle for the socket encapsulated by this CAsyncSocket object.
SOCKET m_hSocket;

CAsyncSocket::OnAccept
Called by the framework to notify a listening socket that it can accept pending connection requests by calling
the Accept member function.

virtual void OnAccept(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes applies to the OnAccept member function:
0 The function executed successfully.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
Remarks
For more information, see Windows Sockets: Socket Notifications.

CAsyncSocket::OnClose
Called by the framework to notify this socket that the connected socket is closed by its process.

virtual void OnClose(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes apply to the OnClose member function:
0 The function executed successfully.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAECONNRESET The connection was reset by the remote side.
WSAECONNABORTED The connection was aborted due to timeout or other failure.
Remarks
For more information, see Windows Sockets: Socket Notifications.

CAsyncSocket::OnConnect
Called by the framework to notify this connecting socket that its connection attempt is completed, whether
successfully or in error.

virtual void OnConnect(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes apply to the OnConnect member function:
0 The function executed successfully.
WSAEADDRINUSE The specified address is already in use.
WSAEADDRNOTAVAIL The specified address is not available from the local machine.
WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.
WSAECONNREFUSED The attempt to connect was forcefully rejected.
WSAEDESTADDRREQ A destination address is required.
WSAEFAULT The lpSockAddrLen argument is incorrect.
WSAEINVAL The socket is already bound to an address.
WSAEISCONN The socket is already connected.
WSAEMFILE No more file descriptors are available.
WSAENETUNREACH The network cannot be reached from this host at this time.
WSAENOBUFS No buffer space is available. The socket cannot be connected.
WSAENOTCONN The socket is not connected.
WSAENOTSOCK The descriptor is a file, not a socket.
WSAETIMEDOUT The attempt to connect timed out without establishing a connection.
Remarks

NOTE
In CSocket, the OnConnect notification function is never called. For connections, you simply call Connect , which will
return when the connection is completed (either successfully or in error). How connection notifications are handled is an
MFC implementation detail.

For more information, see Windows Sockets: Socket Notifications.


Example
void CMyAsyncSocket::OnConnect(int nErrorCode) // CMyAsyncSocket is
// derived from CAsyncSocket
{
if (0 != nErrorCode)
{
switch (nErrorCode)
{
case WSAEADDRINUSE:
AfxMessageBox(_T("The specified address is already in use.\n"));
break;
case WSAEADDRNOTAVAIL:
AfxMessageBox(_T("The specified address is not available from ")
_T("the local machine.\n"));
break;
case WSAEAFNOSUPPORT:
AfxMessageBox(_T("Addresses in the specified family cannot be ")
_T("used with this socket.\n"));
break;
case WSAECONNREFUSED:
AfxMessageBox(_T("The attempt to connect was forcefully rejected.\n"));
break;
case WSAEDESTADDRREQ:
AfxMessageBox(_T("A destination address is required.\n"));
break;
case WSAEFAULT:
AfxMessageBox(_T("The lpSockAddrLen argument is incorrect.\n"));
break;
case WSAEINVAL:
AfxMessageBox(_T("The socket is already bound to an address.\n"));
break;
case WSAEISCONN:
AfxMessageBox(_T("The socket is already connected.\n"));
break;
case WSAEMFILE:
AfxMessageBox(_T("No more file descriptors are available.\n"));
break;
case WSAENETUNREACH:
AfxMessageBox(_T("The network cannot be reached from this host ")
_T("at this time.\n"));
break;
case WSAENOBUFS:
AfxMessageBox(_T("No buffer space is available. The socket ")
_T("cannot be connected.\n"));
break;
case WSAENOTCONN:
AfxMessageBox(_T("The socket is not connected.\n"));
break;
case WSAENOTSOCK:
AfxMessageBox(_T("The descriptor is a file, not a socket.\n"));
break;
case WSAETIMEDOUT:
AfxMessageBox(_T("The attempt to connect timed out without ")
_T("establishing a connection. \n"));
break;
default:
TCHAR szError[256];
_stprintf_s(szError, _T("OnConnect error: %d"), nErrorCode);
AfxMessageBox(szError);
break;
}
AfxMessageBox(_T("Please close the application"));
}
CAsyncSocket::OnConnect(nErrorCode);
}
CAsyncSocket::OnOutOfBandData
Called by the framework to notify the receiving socket that the sending socket has out-of-band data to send.

virtual void OnOutOfBandData(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes apply to the OnOutOfBandData member function:
0 The function executed successfully.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
Remarks
Out-of-band data is a logically independent channel that is associated with each pair of connected sockets of
type SOCK_STREAM. The channel is generally used to send urgent data.
MFC supports out-of-band data, but users of class CAsyncSocket are discouraged from using it. The easier way
is to create a second socket for passing such data. For more information about out-of-band data, see Windows
Sockets: Socket Notifications.

CAsyncSocket::OnReceive
Called by the framework to notify this socket that there is data in the buffer that can be retrieved by calling the
Receive member function.

virtual void OnReceive(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes apply to the OnReceive member function:
0 The function executed successfully.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
Remarks
For more information, see Windows Sockets: Socket Notifications.
Example
void CMyAsyncSocket::OnReceive(int nErrorCode) // CMyAsyncSocket is
// derived from CAsyncSocket
{
static int i = 0;

i++;

TCHAR buff[4096];
int nRead;
nRead = Receive(buff, 4096);

switch (nRead)
{
case 0:
Close();
break;
case SOCKET_ERROR:
if (GetLastError() != WSAEWOULDBLOCK)
{
AfxMessageBox(_T("Error occurred"));
Close();
}
break;
default:
buff[nRead] = _T('\0'); //terminate the string
CString szTemp(buff);
m_strRecv += szTemp; // m_strRecv is a CString declared
// in CMyAsyncSocket
if (szTemp.CompareNoCase(_T("bye")) == 0)
{
ShutDown();
s_eventDone.SetEvent();
}
}
CAsyncSocket::OnReceive(nErrorCode);
}

CAsyncSocket::OnSend
Called by the framework to notify the socket that it can now send data by calling the Send member function.

virtual void OnSend(int nErrorCode);

Parameters
nErrorCode
The most recent error on a socket. The following error codes apply to the OnSend member function:
0 The function executed successfully.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
Remarks
For more information, see Windows Sockets: Socket Notifications.
Example
// CMyAsyncSocket is derived from CAsyncSocket and defines the
// following variables:
// CString m_sendBuffer; //for async send
// int m_nBytesSent;
// int m_nBytesBufferSize;
void CMyAsyncSocket::OnSend(int nErrorCode)
{
while (m_nBytesSent < m_nBytesBufferSize)
{
int dwBytes;

if ((dwBytes = Send((LPCTSTR)m_sendBuffer + m_nBytesSent,


m_nBytesBufferSize - m_nBytesSent)) == SOCKET_ERROR)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
break;
}
else
{
TCHAR szError[256];
_stprintf_s(szError, _T("Server Socket failed to send: %d"),
GetLastError());
Close();
AfxMessageBox(szError);
}
}
else
{
m_nBytesSent += dwBytes;
}
}

if (m_nBytesSent == m_nBytesBufferSize)
{
m_nBytesSent = m_nBytesBufferSize = 0;
m_sendBuffer = _T("");
}

CAsyncSocket::OnSend(nErrorCode);
}

CAsyncSocket::operator =
Assigns a new value to a CAsyncSocket object.

void operator=(const CAsyncSocket& rSrc);

Parameters
rSrc
A reference to an existing CAsyncSocket object.
Remarks
Call this function to copy an existing CAsyncSocket object to another CAsyncSocket object.

CAsyncSocket::operator SOCKET
Use this operator to retrieve the SOCKET handle of the CAsyncSocket object.
operator SOCKET() const;

Return Value
If successful, the handle of the SOCKET object; otherwise, NULL.
Remarks
You can use the handle to call Windows APIs directly.

CAsyncSocket::Receive
Call this member function to receive data from a socket.

virtual int Receive(


void* lpBuf,
int nBufLen,
int nFlags = 0);

Parameters
lpBuf
A buffer for the incoming data.
nBufLen
The length of lpBuf in bytes.
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the
input queue.
MSG_OOB Process out-of-band data.
Return Value
If no error occurs, Receive returns the number of bytes received. If the connection has been closed, it returns
0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAENOTCONN The socket is not connected.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call Receive on a socket after
ShutDown has been invoked with nHow set to 0 or 2.

WSAEWOULDBLOCK The socket is marked as nonblocking and the Receive operation would block.
WSAEMSGSIZE The datagram was too large to fit into the specified buffer and was truncated.
WSAEINVAL The socket has not been bound with Bind .
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
Remarks
This function is used for connected stream or datagram sockets and is used to read incoming data.
For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer
supplied is returned. If the socket has been configured for in-line reception of out-of-band data (socket option
SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application can
use the IOCtlSIOCATMARK option or OnOutOfBandData to determine whether any more out-of-band data
remains to be read.
For datagram sockets, data is extracted from the first enqueued datagram, up to the size of the buffer supplied.
If the datagram is larger than the buffer supplied, the buffer is filled with the first part of the datagram, the
excess data is lost, and Receive returns a value of SOCKET_ERROR with the error code set to WSAEMSGSIZE.
If no incoming data is available at the socket, a value of SOCKET_ERROR is returned with the error code set to
WSAEWOULDBLOCK. The OnReceive callback function can be used to determine when more data arrives.
If the socket is of type SOCK_STREAM and the remote side has shut down the connection gracefully, a
Receive will complete immediately with 0 bytes received. If the connection has been reset, a Receive will fail
with the error WSAECONNRESET.
Receive should be called only once for each time CAsyncSocket::OnReceive is called.
Example
See the example for CAsyncSocket::OnReceive.

CAsyncSocket::ReceiveFrom
Call this member function to receive a datagram and store the source address in the SOCKADDR structure or
in rSocketAddress.

int ReceiveFrom(
void* lpBuf,
int nBufLen,
CString& rSocketAddress,
UINT& rSocketPort,
int nFlags = 0);

int ReceiveFrom(
void* lpBuf,
int nBufLen,
SOCKADDR* lpSockAddr,
int* lpSockAddrLen,
int nFlags = 0);

Parameters
lpBuf
A buffer for the incoming data.
nBufLen
The length of lpBuf in bytes.
rSocketAddress
Reference to a CString object that receives a dotted number IP address.
rSocketPort
Reference to a UINT that stores a port.
lpSockAddr
A pointer to a SOCKADDR structure that holds the source address upon return.
lpSockAddrLen
A pointer to the length of the source address in lpSockAddr in bytes.
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the
input queue.
MSG_OOB Process out-of-band data.
Return Value
If no error occurs, ReceiveFrom returns the number of bytes received. If the connection has been closed, it
returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by
calling GetLastError . The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument was invalid: the lpSockAddr buffer was too small to
accommodate the peer address.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEINVAL The socket has not been bound with Bind .
WSAENOTCONN The socket is not connected ( SOCK_STREAM only).
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call ReceiveFrom on a socket
after ShutDown has been invoked with nHow set to 0 or 2.
WSAEWOULDBLOCK The socket is marked as nonblocking and the ReceiveFrom operation would
block.
WSAEMSGSIZE The datagram was too large to fit into the specified buffer and was truncated.
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
Remarks
This function is used to read incoming data on a (possibly connected) socket and capture the address from
which the data was sent.
To handle IPv6 addresses, use CAsyncSocket::ReceiveFromEx.
For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer
supplied is returned. If the socket has been configured for in-line reception of out-of-band data (socket option
SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application can
use the IOCtlSIOCATMARK option or OnOutOfBandData to determine whether any more out-of-band data
remains to be read. The lpSockAddr and lpSockAddrLen parameters are ignored for SOCK_STREAM sockets.
For datagram sockets, data is extracted from the first enqueued datagram, up to the size of the buffer supplied.
If the datagram is larger than the buffer supplied, the buffer is filled with the first part of the message, the
excess data is lost, and ReceiveFrom returns a value of SOCKET_ERROR with the error code set to
WSAEMSGSIZE.
If lpSockAddr is nonzero, and the socket is of type SOCK_DGRAM, the network address of the socket which
sent the data is copied to the corresponding SOCKADDR structure. The value pointed to by lpSockAddrLen is
initialized to the size of this structure, and is modified on return to indicate the actual size of the address
stored there. If no incoming data is available at the socket, the ReceiveFrom call waits for data to arrive unless
the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to
WSAEWOULDBLOCK. The OnReceive callback can be used to determine when more data arrives.
If the socket is of type SOCK_STREAM and the remote side has shut down the connection gracefully, a
ReceiveFrom will complete immediately with 0 bytes received.

CAsyncSocket::ReceiveFromEx
Call this member function to receive a datagram and store the source address in the SOCKADDR structure or
in rSocketAddress (handles IPv6 addresses).

int ReceiveFromEx(
void* lpBuf,
int nBufLen,
CString& rSocketAddress,
UINT& rSocketPort,
int nFlags = 0);

Parameters
lpBuf
A buffer for the incoming data.
nBufLen
The length of lpBuf in bytes.
rSocketAddress
Reference to a CString object that receives a dotted number IP address.
rSocketPort
Reference to a UINT that stores a port.
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_PEEK Peek at the incoming data. The data is copied into the buffer but is not removed from the
input queue.
MSG_OOB Process out-of-band data.
Return Value
If no error occurs, ReceiveFromEx returns the number of bytes received. If the connection has been closed, it
returns 0. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by
calling GetLastError . The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT The lpSockAddrLen argument was invalid: the lpSockAddr buffer was too small to
accommodate the peer address.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEINVAL The socket has not been bound with Bind .
WSAENOTCONN The socket is not connected ( SOCK_STREAM only).
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call ReceiveFromEx on a socket
after ShutDown has been invoked with nHow set to 0 or 2.
WSAEWOULDBLOCK The socket is marked as nonblocking and the ReceiveFromEx operation would
block.
WSAEMSGSIZE The datagram was too large to fit into the specified buffer and was truncated.
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
Remarks
This function is used to read incoming data on a (possibly connected) socket and capture the address from
which the data was sent.
This function is the same as CAsyncSocket::ReceiveFrom except that it handles IPv6 addresses as well as older
protocols.
For sockets of type SOCK_STREAM, as much information as is currently available up to the size of the buffer
supplied is returned. If the socket has been configured for in-line reception of out-of-band data (socket option
SO_OOBINLINE) and out-of-band data is unread, only out-of-band data will be returned. The application can
use the IOCtlSIOCATMARK option or OnOutOfBandData to determine whether any more out-of-band data
remains to be read. The lpSockAddr and lpSockAddrLen parameters are ignored for SOCK_STREAM sockets.
For datagram sockets, data is extracted from the first enqueued datagram, up to the size of the buffer supplied.
If the datagram is larger than the buffer supplied, the buffer is filled with the first part of the message, the
excess data is lost, and ReceiveFromEx returns a value of SOCKET_ERROR with the error code set to
WSAEMSGSIZE.
If lpSockAddr is nonzero, and the socket is of type SOCK_DGRAM, the network address of the socket which
sent the data is copied to the corresponding SOCKADDR structure. The value pointed to by lpSockAddrLen is
initialized to the size of this structure, and is modified on return to indicate the actual size of the address
stored there. If no incoming data is available at the socket, the ReceiveFromEx call waits for data to arrive
unless the socket is nonblocking. In this case, a value of SOCKET_ERROR is returned with the error code set to
WSAEWOULDBLOCK. The OnReceive callback can be used to determine when more data arrives.
If the socket is of type SOCK_STREAM and the remote side has shut down the connection gracefully, a
ReceiveFromEx will complete immediately with 0 bytes received.
CAsyncSocket::Send
Call this member function to send data on a connected socket.

virtual int Send(


const void* lpBuf,
int nBufLen,
int nFlags = 0);

Parameters
lpBuf
A buffer containing the data to be transmitted.
nBufLen
The length of the data in lpBuf in bytes.
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_DONTROUTE Specifies that the data should not be subject to routing. A Windows Sockets
supplier can choose to ignore this flag.
MSG_OOB Send out-of-band data (SOCK_STREAM only).
Return Value
If no error occurs, Send returns the total number of characters sent. (Note that this can be less than the
number indicated by nBufLen.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
be retrieved by calling GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEFAULT The lpBuf argument is not in a valid part of the user address space.
WSAENETRESET The connection must be reset because the Windows Sockets implementation dropped
it.
WSAENOBUFS The Windows Sockets implementation reports a buffer deadlock.
WSAENOTCONN The socket is not connected.
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call Send on a socket after
ShutDown has been invoked with nHow set to 1 or 2.

WSAEWOULDBLOCK The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum
supported by the Windows Sockets implementation.
WSAEINVAL The socket has not been bound with Bind .
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
Remarks
Send is used to write outgoing data on connected stream or datagram sockets. For datagram sockets, care
must be taken not to exceed the maximum IP packet size of the underlying subnets, which is given by the
iMaxUdpDg element in the WSADATA structure returned by AfxSocketInit . If the data is too long to pass
atomically through the underlying protocol, the error WSAEMSGSIZE is returned via GetLastError , and no
data is transmitted.
Note that for a datagram socket the successful completion of a Send does not indicate that the data was
successfully delivered.
On CAsyncSocket objects of type SOCK_STREAM, the number of bytes written can be between 1 and the
requested length, depending on buffer availability on both the local and foreign hosts.
Example
See the example for CAsyncSocket::OnSend.

CAsyncSocket::SendTo
Call this member function to send data to a specific destination.

int SendTo(
const void* lpBuf,
int nBufLen,
UINT nHostPort,
LPCTSTR lpszHostAddress = NULL,
int nFlags = 0);

int SendTo(
const void* lpBuf,
int nBufLen,
const SOCKADDR* lpSockAddr,
int nSockAddrLen,
int nFlags = 0);

Parameters
lpBuf
A buffer containing the data to be transmitted.
nBufLen
The length of the data in lpBuf in bytes.
nHostPort
The port identifying the socket application.
lpszHostAddress
The network address of the socket to which this object is connected: a machine name such as
"ftp.microsoft.com," or a dotted number such as "128.56.22.8".
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_DONTROUTE Specifies that the data should not be subject to routing. A Windows Sockets
supplier can choose to ignore this flag.
MSG_OOB Send out-of-band data (SOCK_STREAM only).
lpSockAddr
A pointer to a SOCKADDR structure that contains the address of the target socket.
nSockAddrLen
The length of the address in lpSockAddr in bytes.
Return Value
If no error occurs, SendTo returns the total number of characters sent. (Note that this can be less than the
number indicated by nBufLen.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
be retrieved by calling GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEFAULT The lpBuf or lpSockAddr parameters are not part of the user address space, or the
lpSockAddr argument is too small (less than the size of a SOCKADDR structure).
WSAEINVAL The host name is invalid.
WSAENETRESET The connection must be reset because the Windows Sockets implementation dropped
it.
WSAENOBUFS The Windows Sockets implementation reports a buffer deadlock.
WSAENOTCONN The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call SendTo on a socket after
ShutDown has been invoked with nHow set to 1 or 2.

WSAEWOULDBLOCK The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum
supported by the Windows Sockets implementation.
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
WSAEADDRNOTAVAIL The specified address is not available from the local machine.
WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ A destination address is required.
WSAENETUNREACH The network cannot be reached from this host at this time.
Remarks
SendTo is used on datagram or stream sockets and is used to write outgoing data on a socket. For datagram
sockets, care must be taken not to exceed the maximum IP packet size of the underlying subnets, which is
given by the iMaxUdpDg element in the WSADATA structure filled out by AfxSocketInit. If the data is too long to
pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned, and no data is
transmitted.
Note that the successful completion of a SendTo does not indicate that the data was successfully delivered.
SendTo is only used on a SOCK_DGRAM socket to send a datagram to a specific socket identified by the
lpSockAddr parameter.
To send a broadcast (on a SOCK_DGRAM only), the address in the lpSockAddr parameter should be
constructed using the special IP address INADDR_BROADCAST (defined in the Windows Sockets header file
WINSOCK.H) together with the intended port number. Or, if the lpszHostAddress parameter is NULL, the
socket is configured for broadcast. It is generally inadvisable for a broadcast datagram to exceed the size at
which fragmentation can occur, which implies that the data portion of the datagram (excluding headers)
should not exceed 512 bytes.
To handle IPv6 addresses, use CAsyncSocket::SendToEx.

CAsyncSocket::SendToEx
Call this member function to send data to a specific destination (handles IPv6 addresses).

int SendToEx(
const void* lpBuf,
int nBufLen,
UINT nHostPort,
LPCTSTR lpszHostAddress = NULL,
int nFlags = 0);

Parameters
lpBuf
A buffer containing the data to be transmitted.
nBufLen
The length of the data in lpBuf in bytes.
nHostPort
The port identifying the socket application.
lpszHostAddress
The network address of the socket to which this object is connected: a machine name such as
"ftp.microsoft.com," or a dotted number such as "128.56.22.8".
nFlags
Specifies the way in which the call is made. The semantics of this function are determined by the socket
options and the nFlags parameter. The latter is constructed by combining any of the following values with the
C++ OR operator:
MSG_DONTROUTE Specifies that the data should not be subject to routing. A Windows Sockets
supplier can choose to ignore this flag.
MSG_OOB Send out-of-band data (SOCK_STREAM only).
Return Value
If no error occurs, SendToEx returns the total number of characters sent. (Note that this can be less than the
number indicated by nBufLen.) Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
be retrieved by calling GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEACCES The requested address is a broadcast address, but the appropriate flag was not set.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEFAULT The lpBuf or lpSockAddr parameters are not part of the user address space, or the
lpSockAddr argument is too small (less than the size of a SOCKADDR structure).
WSAEINVAL The host name is invalid.
WSAENETRESET The connection must be reset because the Windows Sockets implementation dropped
it.
WSAENOBUFS The Windows Sockets implementation reports a buffer deadlock.
WSAENOTCONN The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK The descriptor is not a socket.
WSAEOPNOTSUPP MSG_OOB was specified, but the socket is not of type SOCK_STREAM.
WSAESHUTDOWN The socket has been shut down; it is not possible to call SendToEx on a socket after
ShutDown has been invoked with nHow set to 1 or 2.

WSAEWOULDBLOCK The socket is marked as nonblocking and the requested operation would block.
WSAEMSGSIZE The socket is of type SOCK_DGRAM, and the datagram is larger than the maximum
supported by the Windows Sockets implementation.
WSAECONNABORTED The virtual circuit was aborted due to timeout or other failure.
WSAECONNRESET The virtual circuit was reset by the remote side.
WSAEADDRNOTAVAIL The specified address is not available from the local machine.
WSAEAFNOSUPPORT Addresses in the specified family cannot be used with this socket.
WSAEDESTADDRREQ A destination address is required.
WSAENETUNREACH The network cannot be reached from this host at this time.
Remarks
This method is the same as CAsyncSocket::SendTo except that it handles IPv6 addresses as well as older
protocols.
SendToEx is used on datagram or stream sockets and is used to write outgoing data on a socket. For datagram
sockets, care must be taken not to exceed the maximum IP packet size of the underlying subnets, which is
given by the iMaxUdpDg element in the WSADATA structure filled out by AfxSocketInit. If the data is too long to
pass atomically through the underlying protocol, the error WSAEMSGSIZE is returned, and no data is
transmitted.
Note that the successful completion of a SendToEx does not indicate that the data was successfully delivered.
SendToEx is only used on a SOCK_DGRAM socket to send a datagram to a specific socket identified by the
lpSockAddr parameter.
To send a broadcast (on a SOCK_DGRAM only), the address in the lpSockAddr parameter should be
constructed using the special IP address INADDR_BROADCAST (defined in the Windows Sockets header file
WINSOCK.H) together with the intended port number. Or, if the lpszHostAddress parameter is NULL, the
socket is configured for broadcast. It is generally inadvisable for a broadcast datagram to exceed the size at
which fragmentation can occur, which implies that the data portion of the datagram (excluding headers)
should not exceed 512 bytes.

CAsyncSocket::SetSockOpt
Call this member function to set a socket option.

BOOL SetSockOpt(
int nOptionName,
const void* lpOptionValue,
int nOptionLen,
int nLevel = SOL_SOCKET);

Parameters
nOptionName
The socket option for which the value is to be set.
lpOptionValue
A pointer to the buffer in which the value for the requested option is supplied.
nOptionLen
The size of the lpOptionValue buffer in bytes.
nLevel
The level at which the option is defined; the only supported levels are SOL_SOCKET and IPPROTO_TCP.
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEFAULT lpOptionValue is not in a valid part of the process address space.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAEINVAL nLevel is not valid, or the information in lpOptionValue is not valid.
WSAENETRESET Connection has timed out when SO_KEEPALIVE is set.
WSAENOPROTOOPT The option is unknown or unsupported. In particular, SO_BROADCAST is not
supported on sockets of type SOCK_STREAM, while SO_DONTLINGER, SO_KEEPALIVE, SO_LINGER, and
SO_OOBINLINE are not supported on sockets of type SOCK_DGRAM.
WSAENOTCONN Connection has been reset when SO_KEEPALIVE is set.
WSAENOTSOCK The descriptor is not a socket.
Remarks
SetSockOpt sets the current value for a socket option associated with a socket of any type, in any state.
Although options can exist at multiple protocol levels, this specification only defines options that exist at the
uppermost "socket" level. Options affect socket operations, such as whether expedited data is received in the
normal data stream, whether broadcast messages can be sent on the socket, and so on.
There are two types of socket options: Boolean options that enable or disable a feature or behavior, and
options which require an integer value or structure. To enable a Boolean option, lpOptionValue points to a
nonzero integer. To disable the option lpOptionValue points to an integer equal to zero. nOptionLen should be
equal to sizeof(BOOL) for Boolean options. For other options, lpOptionValue points to the integer or structure
that contains the desired value for the option, and nOptionLen is the length of the integer or structure.
SO_LINGER controls the action taken when unsent data is queued on a socket and the Close function is called
to close the socket.
By default, a socket cannot be bound (see Bind) to a local address which is already in use. On occasion,
however, it may be desirable to "reuse" an address in this way. Since every connection is uniquely identified by
the combination of local and remote addresses, there is no problem with having two sockets bound to the
same local address as long as the remote addresses are different.
To inform the Windows Sockets implementation that a Bind call on a socket should not be disallowed
because the desired address is already in use by another socket, the application should set the
SO_REUSEADDR socket option for the socket before issuing the Bind call. Note that the option is interpreted
only at the time of the Bind call: it is therefore unnecessary (but harmless) to set the option on a socket which
is not to be bound to an existing address, and setting or resetting the option after the Bind call has no effect
on this or any other socket.
An application can request that the Windows Sockets implementation enable the use of "keep-alive" packets
on Transmission Control Protocol (TCP) connections by turning on the SO_KEEPALIVE socket option. A
Windows Sockets implementation need not support the use of keep-alives: if it does, the precise semantics are
implementation-specific but should conform to section 4.2.3.6 of RFC 1122: "Requirements for Internet Hosts
— Communication Layers." If a connection is dropped as the result of "keep-alives" the error code
WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with
WSAENOTCONN.
The TCP_NODELAY option disables the Nagle algorithm. The Nagle algorithm is used to reduce the number of
small packets sent by a host by buffering unacknowledged send data until a full-size packet can be sent.
However, for some applications this algorithm can impede performance, and TCP_NODELAY can be used to
turn it off. Application writers should not set TCP_NODELAY unless the impact of doing so is well-understood
and desired, since setting TCP_NODELAY can have a significant negative impact on network performance.
TCP_NODELAY is the only supported socket option which uses level IPPROTO_TCP; all other options use level
SOL_SOCKET.
Some implementations of Windows Sockets supply output debug information if the SO_DEBUG option is set
by an application.
The following options are supported for SetSockOpt . The Type identifies the type of data addressed by
lpOptionValue.

VA L UE TYPE M EA N IN G

SO_BROADCAST BOOL Allow transmission of broadcast


messages on the socket.

SO_DEBUG BOOL Record debugging information.

SO_DONTLINGER BOOL Don't block Close waiting for unsent


data to be sent. Setting this option is
equivalent to setting SO_LINGER with
l_onoff set to zero.
VA L UE TYPE M EA N IN G

SO_DONTROUTE BOOL Don't route: send directly to interface.

SO_KEEPALIVE BOOL Send keep-alives.

SO_LINGER struct LINGER Linger on Close if unsent data is


present.

SO_OOBINLINE BOOL Receive out-of-band data in the


normal data stream.

SO_RCVBUF int Specify buffer size for receives.

SO_REUSEADDR BOOL Allow the socket to be bound to an


address which is already in use. (See
Bind.)

SO_SNDBUF int Specify buffer size for sends.

TCP_NODELAY BOOL Disables the Nagle algorithm for send


coalescing.

Berkeley Software Distribution (BSD) options not supported for SetSockOpt are:

VA L UE TYPE M EA N IN G

SO_ACCEPTCONN BOOL Socket is listening

SO_ERROR int Get error status and clear.

SO_RCVLOWAT int Receive low water mark.

SO_RCVTIMEO int Receive timeout

SO_SNDLOWAT int Send low water mark.

SO_SNDTIMEO int Send timeout.

SO_TYPE int Type of the socket.

IP_OPTIONS Set options field in IP header.

CAsyncSocket::ShutDown
Call this member function to disable sends, receives, or both on the socket.

BOOL ShutDown(int nHow = sends);

Parameters
nHow
A flag that describes what types of operation will no longer be allowed, using the following enumerated
values:
receives = 0
sends = 1
both = 2
Return Value
Nonzero if the function is successful; otherwise 0, and a specific error code can be retrieved by calling
GetLastError. The following errors apply to this member function:
WSANOTINITIALISED A successful AfxSocketInit must occur before using this API.
WSAENETDOWN The Windows Sockets implementation detected that the network subsystem failed.
WSAEINVAL nHow is not valid.
WSAEINPROGRESS A blocking Windows Sockets operation is in progress.
WSAENOTCONN The socket is not connected (SOCK_STREAM only).
WSAENOTSOCK The descriptor is not a socket.
Remarks
ShutDown is used on all types of sockets to disable reception, transmission, or both. If nHow is 0, subsequent
receives on the socket will be disallowed. This has no effect on the lower protocol layers.
For Transmission Control Protocol (TCP), the TCP window is not changed and incoming data will be accepted
(but not acknowledged) until the window is exhausted. For User Datagram Protocol (UDP), incoming
datagrams are accepted and queued. In no case will an ICMP error packet be generated. If nHow is 1,
subsequent sends are disallowed. For TCP sockets, a FIN will be sent. Setting nHow to 2 disables both sends
and receives as described above.
Note that ShutDown does not close the socket, and resources attached to the socket will not be freed until
Close is called. An application should not rely on being able to reuse a socket after it has been shut down. In
particular, a Windows Sockets implementation is not required to support the use of Connect on such a socket.
Example
See the example for CAsyncSocket::OnReceive.

CASyncSocket::Socket
Allocates a socket handle.

BOOL Socket(
int nSocketType = SOCK_STREAM,
long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
int nProtocolType = 0,
int nAddressFormat = PF_INET);

Parameters
nSocketType
Specifies SOCK_STREAM or SOCK_DGRAM .
lEvent
A bitmask that specifies a combination of network events in which the application is interested.
FD_READ : Want to receive notification of readiness for reading.
FD_WRITE : Want to receive notification of readiness for writing.
FD_OOB : Want to receive notification of the arrival of out-of-band data.
FD_ACCEPT : Want to receive notification of incoming connections.
FD_CONNECT : Want to receive notification of completed connection.
FD_CLOSE : Want to receive notification of socket closure.
nProtocolType
Protocol to be used with the socket that is specific to the indicated address family.
nAddressFormat
Address family specification.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This method allocates a socket handle. It does not call CAsyncSocket::Bind to bind the socket to a specified
address, so you need to call Bind later to bind the socket to a specified address. You can use
CAsyncSocket::SetSockOpt to set the socket option before it is bound.

See also
CObject Class
Hierarchy Chart
CSocket Class
CSocketFile Class
CAutoHideDockSite Class
4/21/2020 • 3 minutes to read • Edit Online

The CAutoHideDockSite extends the CDockSite Class to implement auto-hide dock panes.

Syntax
class CAutoHideDockSite : public CDockSite

Members
Public Constructors

Name Description

CAutoHideDockSite::CAutoHideDockSite Constructs a CAutoHideDockSite object.

CAutoHideDockSite::~CAutoHideDockSite Destructor.

Public Methods

Name Description

CAutoHideDockSite::AllowShowOnPaneMenu Indicates whether the CAutoHideDockSite is shown on the


pane menu.

CAutoHideDockSite::CanAcceptPane Determines whether a base pane object is derived from the


CMFCAutoHideBar Class.

CAutoHideDockSite::DockPane Docks a pane to this CAuotHideDockSite object.

CAutoHideDockSite::GetAlignRect Retrieves the size of the dock site in screen coordinates.

CAutoHideDockSite::RepositionPanes Redraws the pane on the CAutoHideDockSite with the


global margins and button spacing.

CAutoHideDockSite::SetOffsetLeft Sets the margin on the left side of the docking bar.

CAutoHideDockSite::SetOffsetRight Sets the margin on the right side of the docking bar.

CAutoHideDockSite::UnSetAutoHideMode Calls CMFCAutoHideBar::UnSetAutoHideMode for objects on


the CAutoHideDockSite .

Data Members
Name Description

CAutoHideDockSite::m_nExtraSpace Defines the size of the space between the toolbars and the
edge of the docking bar. This space is measured from either
the left edge or the top edge, depending on the alignment
for the dock space.

Remarks
When you call CFrameWndEx::EnableAutoHidePanes, the framework automatically creates a CAutoHideDockSite
object. In most cases, you should not have to instantiate or use this class directly.
The docking bar is the gap between the left side of the dock pane and the left side of the CMFCAutoHideButton
Class.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CBasePane
CDockSite

Example
The following example demonstrates how to retrieve a CAutoHideDockSite object from a CMFCAutoHideBar object,
and how to set the left and right margins of the docking bar.

CAutoHideDockSite *pParentDockBar = DYNAMIC_DOWNCAST(CAutoHideDockSite, pParentBar->GetParentDockSite());


pParentDockBar->SetOffsetLeft(10);
pParentDockBar->SetOffsetRight(10);

Requirements
Header : afxautohidedocksite.h

CAutoHideDockSite::CanAcceptPane
Determines whether a base pane is a CMFCAutoHideBar object or derived from CMFCAutoHideBar .

virtual BOOL CanAcceptPane(const CBasePane* pBar) const;

Parameters

Parameter Description

pBar [in] The base pane that the framework tests.


Return Value
TRUE if pBar is derived from CMFCAutoHideBar ; FALSE otherwise.
Remarks
If a base pane object is derived from CMFCAutoHideBar , it can contain a CAutoHideDockSite .

CAutoHideDockSite::DockPane
Docks a pane to this CAutoHideDockSite object.

virtual void DockPane(


CPane* pWnd,
AFX_DOCK_METHOD dockMethod,
LPRECT lpRect = NULL);

Parameters

Parameter Description

pWnd [in] The pane that the framework docks.

dockMethod [in] Docking options for the pane.

lpRect [in] A rectangle that specifies the boundaries for the docked
pane.

Remarks
The default implementation does not use the parameter dockMethod, which is provided for future use.
If lpRect is NULL, the framework puts the pane in the default location on the dock site. If the dock site is horizontal,
the default location is at the far left of the dock site. Otherwise, the default location is at the top of the dock site.

CAutoHideDockSite::GetAlignRect
Retrieves the size of the dock site in screen coordinates.

void GetAlignRect(CRect& rect) const;

Parameters

Parameter Description

rect [in] A reference to a rectangle. The method stores the size of


the dock site in this rectangle.

Remarks
The rectangle is adjusted for the offset margins so that they are not included.

CAutoHideDockSite::m_nExtraSpace
The size of the space between the edges of the CAutoHideDockSite Class and the CMFCAutoHideBar Class objects.
static int m_nExtraSpace;

Remarks
When a CMFCAutoHideBar is docked at a CAutoHideDockSite , it should not occupy the whole dock site. This global
variable controls the extra space between the left or top border of the CMFCAutoHideBar and the corresponding
CAutoHideDockSite edge. Whether the top or left edge is used depends on the current alignment.

CAutoHideDockSite::SetOffsetLeft
Sets the margin on the left side of the docking bar.

void SetOffsetLeft(int nOffset);

Parameters
nOffset
[in] The new offset.
Remarks
CMFCAutoHideBar objects are positioned statically on the CAutoHideDockSite object. This means that the user
cannot manually change the location of CMFCAutoHideBar objects. The SetOffsetLeft method controls the spacing
between the left side of the left-most CMFCAutoHideBar and the left side of the CAutoHideDockSite .

CAutoHideDockSite::SetOffsetRight
Sets the margin on the right side of the docking bar.

void SetOffsetRight(int nOffset);

Parameters
nOffset
[in] The new offset.
Remarks
CMFCAutoHideBar objects are positioned statically on the CAutoHideDockSite object. This means that the user
cannot manually change the location of the CMFCAutoHideBar objects. The SetOffsetRight method controls the
spacing between the right side of the right-most CMFCAutoHideBar and the right side of the CAutoHideDockSite .

CAutoHideDockSite::RepositionPanes
Redraws the panes on the CAutoHideDockSite.

virtual void RepositionPanes(CRect& rectNewClientArea);

Parameters

Parameter Description

rectNewClientArea [in] A reserved value.


Remarks
The default implementation does not use rectNewClientArea. It redraws the panes with the global toolbar margins
and button spacing.

CAutoHideDockSite::UnSetAutoHideMode
Calls CMFCAutoHideBar::UnSetAutoHideMode for objects on the dock site.

void UnSetAutoHideMode(CMFCAutoHideBar* pAutoHideToolbar);

Parameters

Parameter Description

pAutoHideToolbar [in] A pointer to a CMFCAutoHideBar object pane located on


the CAutoHideDockSite .

Remarks
This method searches for the row that contains pAutoHideToolbar. It calls CMFCAutoHideBar.UnSetAutoHideMode for
all the CMFCAutoHideBar objects on that row. If pAutoHideToolbar is not found or it is NULL, this method calls
CMFCAutoHideBar.UnSetAutoHideMode for all the CMFCAutoHideBar objects on the CAutoHideDockSite .

See also
Hierarchy Chart
Classes
CDockSite Class
CBaseKeyFrame Class
3/27/2020 • 2 minutes to read • Edit Online

Implements the basic functionality of a keyframe.

Syntax
class CBaseKeyFrame : public CObject;

Members
Public Constructors
NAME DESC RIP T IO N

CBaseKeyFrame::CBaseKeyFrame Constructs a keyframe object.

Public Methods
NAME DESC RIP T IO N

CBaseKeyFrame::AddToStoryboard Adds a keyframe to storyboard.

CBaseKeyFrame::GetAnimationKeyframe Returns the underlying keyframe value.

CBaseKeyFrame::IsAdded Tells whether a keyframe has been added to storyboard.

CBaseKeyFrame::IsKeyframeAtOffset Specifies whether the keyframe should be added to


storyboard at offset, or after transition.

Protected Data Members


NAME DESC RIP T IO N

CBaseKeyFrame::m_bAdded Specifies whether this keyframe has been added to a


storyboard.

CBaseKeyFrame::m_bIsKeyframeAtOffset Specifies whether this keyframe should be added to


storyboard at an offset from another existing keyframe, or at
the end of some transition.

CBaseKeyFrame::m_keyframe Represents a Windows Animation API keyframe. When a


keyframe is not initialized it is set to the predefined value
UI_ANIMATION_KEYFRAME_STORYBOARD_START.

Remarks
Encapsulates UI_ANIMATION_KEYFRAME variable. Serves as a base class for any keyframe implementation. A
keyframe represents a moment in time within a storyboard and can be used to specify the start and end times of
transitions. There are two types of keyframes - keyframes added to storyboard at the specified offset (in time), or
keyframes added after specified transition. Because durations of some transitions can't be known before animation
starts, the actual values of some keyframes are determined at runtime only. Because keyframes may depend on
transitions, which in their turn depend on keyframes, it's important to prevent infinite recursions when building
keyframe chains.

Inheritance Hierarchy
CObject
CBaseKeyFrame

Requirements
Header : afxanimationcontroller.h

CBaseKeyFrame::AddToStoryboard
Adds a keyframe to storyboard.

virtual BOOL AddToStoryboard(


IUIAnimationStoryboard* pStoryboard,
BOOL bDeepAdd);

Parameters
pStoryboard
A pointer to a storyboard.
bDeepAdd
If this parameter is TRUE and the keyframe being added depends on some other keyframe or transition, this
method tries to add this keyframe or transition to storyboard first.
Return Value
TRUE if keyframe was added to storyboard successfully; otherwise FALSE.
Remarks
This method is called to add a keyframe to storyboard.

CBaseKeyFrame::CBaseKeyFrame
Constructs a keyframe object.

CBaseKeyFrame();

CBaseKeyFrame::GetAnimationKeyframe
Returns the underlying keyframe value.

UI_ANIMATION_KEYFRAME GetAnimationKeyframe() const;

Return Value
A current keyframe. The default value is UI_ANIMATION_KEYFRAME_STORYBOARD_START.
Remarks
This is an accessor to the underlying keyframe value.

CBaseKeyFrame::IsAdded
Tells whether a keyframe has been added to storyboard.

BOOL IsAdded() const;

Return Value
TRUE if a keyframe is added to a storyboard; otehrwise FALSE.
Remarks
In the base class IsAdded always returns TRUE, but it's overridden in derived classes.

CBaseKeyFrame::IsKeyframeAtOffset
Specifies whether the keyframe should be added to storyboard at offset, or after transition.

BOOL IsKeyframeAtOffset() const;

Return Value
TRUE if the keyframe should be added to storyboard at some specified offset. FALSE if the keyframe should be
added to storyboard after some transition.
Remarks
Specifies whether the keyframe should be added to storyboard at offset. The offset or transition must be specified
in a derived class.

CBaseKeyFrame::m_bAdded
Specifies whether this keyframe has been added to a storyboard.

BOOL m_bAdded;

CBaseKeyFrame::m_bIsKeyframeAtOffset
Specifies whether this keyframe should be added to storyboard at an offset from another existing keyframe, or at
the end of some transition.

BOOL m_bIsKeyframeAtOffset;

CBaseKeyFrame::m_keyframe
Represents a Windows Animation API keyframe. When a keyframe is not initialized it is set to the predefined value
UI_ANIMATION_KEYFRAME_STORYBOARD_START.

UI_ANIMATION_KEYFRAME m_keyframe;

See also
Classes
CBasePane Class
4/21/2020 • 33 minutes to read • Edit Online

Base class for all panes in MFC.

Syntax
class CBasePane : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CBasePane::CBasePane Default constructor.

CBasePane::~CBasePane Destructor.

Public Methods
NAME DESC RIP T IO N

CBasePane::accHitTest Called by the framework to retrieve the child element or


child object at a given point on the screen. (Overrides
CWnd::accHitTest.)

CBasePane::accLocation Called by the framework to retrieve the current screen


location for the specified object. (Overrides
CWnd::accLocation.)

CBasePane::AccNotifyObjectFocusEvent CBasePane does not use this method.

CBasePane::accSelect Called by the framework to modify the selection or move


the keyboard focus of the specified object. (Overrides
CWnd::accSelect.)

CBasePane::AddPane Adds a pane to the docking manager.

CBasePane::AdjustDockingLayout Redirects a call to the docking manager to adjust the


docking layout.

CBasePane::AdjustLayout Called by the framework when the pane should adjust its
internal layout.

CBasePane::CalcFixedLayout Calculates the horizontal size of a control bar.

CBasePane::CanAcceptPane Determines whether another pane can be docked to the


pane.
NAME DESC RIP T IO N

CBasePane::CanAutoHide Determines whether the pane supports auto-hide mode.

CBasePane::CanBeAttached Determines whether the pane can be docked to another


pane.

CBasePane::CanBeClosed Determines whether the pane can be closed.

CBasePane::CanBeDocked Determines whether the pane can be docked to another


pane.

CBasePane::CanBeResized Determines whether the pane can be resized.

CBasePane::CanBeTabbedDocument Specifies whether the pane can be converted to an MDI


tabbed document.

CBasePane::CanFloat Determines whether the pane can float.

CBasePane::CanFocus Specifies whether the pane can receive focus.

CBasePane::CopyState Copies the state of a given pane.

CBasePane::CreateDefaultMiniframe If the pane can float, creates a mini-frame window.

CBasePane::CreateEx Creates the pane control.

CBasePane::DockPane Docks a pane to another pane or to a frame window.

CBasePane::DockPaneUsingRTTI Docks the pane by using run-time type information.

CBasePane::DockToFrameWindow Docks a dockable pane to a frame.

CBasePane::DoesAllowDynInsertBefore Determines whether another pane can be dynamically


inserted between this pane and the parent frame.

CBasePane::EnableDocking Enables docking of the pane to the main frame.

CBasePane::EnableGripper Enables or disables the gripper. If the gripper is enabled,


the user can drag it to reposition the pane.

CBasePane::FillWindowRect Used internally.

CBasePane::FloatPane Floats the pane.

CBasePane::get_accChild Called by the framework to retrieve the address of an


IDispatch interface for the specified child. (Overrides
CWnd::get_accChild.)

CBasePane::get_accChildCount Called by the framework to retrieve the number of children


that belong to this object. (Overrides
CWnd::get_accChildCount.)
NAME DESC RIP T IO N

CBasePane::get_accDefaultAction Called by the framework to retrieve a string that describes


the default action for the object. (Overrides
CWnd::get_accDefaultAction.)

CBasePane::get_accDescription Called by framework to retrieve a string that describes the


visual appearance of the specified object. (Overrides
CWnd::get_accDescription.)

CBasePane::get_accFocus Called by the framework to retrieve the object that has the
keyboard focus. (Overrides CWnd::get_accFocus.)

CBasePane::get_accHelp Called by the framework to retrieve a Help property string


for the object. (Overrides CWnd::get_accHelp.)

CBasePane::get_accHelpTopic Called by the framework to retrieve the full path of the


WinHelp file that is associated with the specified object and
the identifier of the appropriate topic in that file. (Overrides
CWnd::get_accHelpTopic.)

CBasePane::get_accKeyboardShortcut Called by the framework to retrieve the specified shortcut


key for the object. (Overrides
CWnd::get_accKeyboardShortcut.)

CBasePane::get_accName Called by the framework to retrieve the name of the


specified object. (Overrides CWnd::get_accName.)

CBasePane::get_accParent Called by the framework to retrieve the IDispatch


interface for the parent of the object. (Overrides
CWnd::get_accParent.)

CBasePane::get_accRole Called by the framework to retrieve information that


describes the role of the specified object. (Overrides
CWnd::get_accRole.)

CBasePane::get_accSelection Called by the framework to retrieve the selected children of


this object. (Overrides CWnd::get_accSelection.)

CBasePane::get_accState Called by the framework to retrieve the current state of


the specified object. (Overrides CWnd::get_accState.)

CBasePane::get_accValue Called by the framework to retrieve the value of the


specified object. (Overrides CWnd::get_accValue.)

CBasePane::GetCaptionHeight Returns the caption height.

CBasePane::GetControlBarStyle Returns the control bar style.

CBasePane::GetCurrentAlignment Returns the current pane alignment.

CBasePane::GetDockingMode Returns the current docking mode for the pane.

CBasePane::GetDockSiteFrameWnd Returns a pointer to the window that is the dock site for
the pane.
NAME DESC RIP T IO N

CBasePane::GetEnabledAlignment Returns the CBRS_ALIGN_ styles that are applied to the


pane.

CBasePane::GetMFCStyle Returns the pane styles specific to MFC.

CBasePane::GetPaneIcon Returns a handle to the pane icon.

CBasePane::GetPaneRect Used internally.

CBasePane::GetPaneRow Returns a pointer to the CDockingPanesRowobject where


the pane is docked.

CBasePane::GetPaneStyle Returns the pane style.

CBasePane::GetParentDockSite Returns a pointer to the parent dock site.

CBasePane::GetParentMiniFrame Returns a pointer to the parent mini-frame window.

CBasePane::GetParentTabbedPane Returns a pointer to the parent tabbed pane.

CBasePane::GetParentTabWnd Returns a pointer to the parent window that is inside a tab.

CBasePane::GetRecentVisibleState The framework calls this method when a pane is restored


from an archive.

CBasePane::HideInPrintPreviewMode Specifies whether the pane is hidden in print preview.

CBasePane::InsertPane Registers the specified pane with the docking manager.

CBasePane::IsAccessibilityCompatible Specifies whether the pane supports Active Accessibility.

CBasePane::IsAutoHideMode Determines whether a pane is in auto-hide mode.

CBasePane::IsDialogControl Specifies whether the pane is a dialog control.

CBasePane::IsDocked Determines whether the pane is docked.

CBasePane::IsFloating Determines whether the pane is floating.

CBasePane::IsHorizontal Determines whether the pane is docked horizontally.

CBasePane::IsInFloatingMultiPaneFrameWnd Specifies whether the pane is in a multi-pane frame


window.

CBasePane::IsMDITabbed Determines whether the pane has been added to an MDI


child window as a tabbed document.

CBasePane::IsPaneVisible Specifies whether the WS_VISIBLE flag is set for the pane.

CBasePane::IsPointNearDockSite Determines whether a specified point is near the dock site.


NAME DESC RIP T IO N

CBasePane::IsResizable Determines whether the pane can be resized.

CBasePane::IsRestoredFromRegistry Determines whether the pane is restored from the registry.

CBasePane::IsTabbed Determines whether the pane has been inserted in the tab
control of a tabbed window.

CBasePane::IsTooltipTopmost Used internally.

CBasePane::IsVisible Determines whether the pane is visible.

CBasePane::LoadState Loads the pane state from the registry.

CBasePane::MoveWindow Moves the pane.

CBasePane::OnAfterChangeParent Called by the framework when the pane's parent has been
changed.

CBasePane::OnBeforeChangeParent Called by the framework just before the pane changes its
parent window.

CBasePane::OnDrawCaption The framework calls this method when the caption is


drawn.

CBasePane::OnMovePaneDivider This method is currently not used.

CBasePane::OnPaneContextMenu Called by the framework when it builds a menu that has a


list of panes.

CBasePane::OnRemoveFromMiniFrame Called by the framework when a pane is removed from its


parent mini frame window.

CBasePane::OnSetAccData CBasePane does not use this method.

CBasePane::OnUpdateCmdUI Used internally.

CBasePane::PaneFromPoint Returns the pane that contains the given point.

CBasePane::PreTranslateMessage Used by class CWinApp to translate window messages


before they are dispatched to the TranslateMessage and
DispatchMessage Windows functions. (Overrides
CWnd::PreTranslateMessage.)

CBasePane::RecalcLayout CBasePane does not use this method.

CBasePane::RemovePaneFromDockManager Unregisters a pane and removes it from the list in the


docking manager.

CBasePane::SaveState Saves the pane's state to the registry.

CBasePane::SelectDefaultFont Selects the default font for a given device context.


NAME DESC RIP T IO N

CBasePane::Serialize Reads or writes this object from or to an archive.


(Overrides CObject::Serialize.)

CBasePane::SetControlBarStyle Sets the control bar style.

CBasePane::SetDockingMode Sets the docking mode for the pane.

CBasePane::SetMDITabbed Used internally.

CBasePane::SetPaneAlignment Sets the alignment for the pane.

CBasePane::SetPaneRect Used internally.

CBasePane::SetPaneStyle Sets the style of the pane.

CBasePane::SetRestoredFromRegistry Used internally.

CBasePane::SetWindowPos Changes the size, position, and Z-order of a pane.

CBasePane::ShowPane Shows or hides the pane.

CBasePane::StretchPane Stretches a pane vertically or horizontally.

CBasePane::UndockPane Removes the pane from the dock site, default slider, or
mini-frame window where it is currently docked.

Protected Methods
NAME DESC RIP T IO N

CBasePane::DoPaint Fills the background of the pane.

Remarks
If you want to create a pane class that supports the extended docking features available in MFC, you must
derive it from CBasePane or from CPane Class.

Customization Tips
The following customization tips pertain to the CBasePane Class and any classes that inherit from it:
When you create a pane, you can apply several new styles:
AFX_CBRS_FLOAT makes the pane float.
AFX_CBRS_AUTOHIDE enables auto-hide mode.
AFX_CBRS_CLOSE enables the pane to be closed (hidden).
These are flags that you can combine with a bitwise-OR operation.
CBasePane implements the following virtual Boolean methods to reflect these flags:
CBasePane::CanBeClosed, CBasePane::CanAutoHide, CBasePane::CanFloat. You can override them in derived
classes to customize their behavior.
You can customize docking behavior by overriding CBasePane::CanAcceptPane. Have your pane return
FALSE from this method to prevent another pane from docking to it.
If you want to create a static pane that cannot float and that prevents any other pane from docking
before it (similar to the Outlook bar in the OutlookDemo example), create it as non-floating and
override CBasePane::DoesAllowDynInsertBefore to return FALSE. The default implementation returns
FALSE if the pane is created without the AFX_CBRS_FLOAT style.
Create all panes with IDs other than -1.
To determine pane visibility, use CBasePane::IsVisible. It correctly handles the visibility state in tabbed
and auto-hide modes.
If you want to create a non-floating resizable pane, create it without the AFX_CBRS_FLOAT style and
call CFrameWnd::DockControlBar.
To exclude a pane from a docking layout or to remove a toolbar from its dock bar, call
CBasePane::UndockPane. Do not call this method for panes in auto-hide mode or for panes that reside
in tabs of tabbed windows.
If you want to float or undock a pane that is in auto-hide mode, you must call
CDockablePane::SetAutoHideMode with FALSE as the first argument before you call
CBasePane::FloatPane or CBasePane::UndockPane.

Example
The following example demonstrates how to use various methods in the CBasePane class. The example
demonstrates how to retrieve a pane from the CFrameWndEx class and how to set the docking mode, the pane
alignment, and the pane style. The code is from the Word Pad sample.

// This CMainFrame class extends the CFrameWndEx class.


// GetPane is a method in the CFrameWndEx class which
// Returns a pointer to the pane that has the specified ID.
CBasePane *pBar = GetPane(ID_VIEW_FORMATBAR);
if (pBar != NULL)
{
// Set the docking mode, the pane alignment, and the pane style.
pBar->SetDockingMode(DT_STANDARD);
pBar->SetPaneAlignment(CBRS_ALIGN_LEFT);
pBar->SetPaneStyle(pBar->GetCurrentAlignment() | CBRS_TOOLTIPS);
pBar->ShowPane(TRUE, FALSE, FALSE);
}

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CBasePane

Requirements
Header : afxbasepane.h
CBasePane::AccNotifyObjectFocusEvent
CBasePane does not use this method.

virtual void AccNotifyObjectFocusEvent(int);

Parameters
int
[in] Not used.

CBasePane::AddPane
Adds a pane to the docking manager.

void AddPane(CBasePane* pBar);

Parameters
pBar
[in] A pointer to a pane to add.
Remarks
This is a convenience method that adds a pane to a docking manager. By using this method, you do not have
to write code that analyzes the type of the parent frame.
For more information, see CDockingManager Class and CMDIFrameWndEx::AddPane.

CBasePane::AdjustDockingLayout
Redirects a call to the docking manager to adjust the docking layout.

virtual void AdjustDockingLayout(HDWP hdwp=NULL);

Parameters
hdwp
[out] A handle to a structure containing multiple window positions.
Remarks
This is a convenience method that adjusts the docking layout. By using this method, you do not have to write
code that analyzes the type of the parent frame.
For more information, see CDockingManager::AdjustDockingLayout

CBasePane::AdjustLayout
Called by the framework to adjust the internal layout of a pane.

virtual void AdjustLayout();

Remarks
The framework calls this method when a pane has to adjust its internal layout. The base implementation does
nothing.
CBasePane::CalcFixedLayout
Calculates the horizontal size of a control bar.

virtual CSize CalcFixedLayout(


BOOL bStretch,
BOOL bHorz);

Parameters
bStretch
[in] Indicates whether the bar should be stretched to the size of the frame. The bStretch parameter is nonzero
when the bar is not a docking bar (not available for docking) and is 0 when it is docked or floating (available
for docking).
bHorz
[in] Indicates that the bar is horizontally or vertically oriented. The bHorz parameter is nonzero if the bar is
horizontally oriented and is 0 if it is vertically oriented.
Return Value
The control bar size, in pixels, of a CSize object.
Remarks
See the remarks section in CControlBar::CalcFixedLayout

CBasePane::CanAcceptPane
Determines whether another pane can be docked to the pane.

virtual BOOL CanAcceptPane(const CBasePane* pBar) const;

Parameters
pBar
[in] A pointer to the pane to dock.
Return Value
TRUE if another pane can be accepted; otherwise FALSE.
Remarks
The framework calls this method before it docks the pane specified by pBar to the current pane.
Use this method and the CBasePane::CanBeDocked method to control how panes dock to other panes in your
application.
The default implementation returns FALSE.

CBasePane::CanAutoHide
Determines whether the pane supports auto-hide mode.

virtual BOOL CanAutoHide() const;

Return Value
TRUE if this pane supports auto-hide mode; otherwise FALSE.
Remarks
The framework calls this function to determine whether the pane supports auto-hide mode.
During construction, you can set this ability by passing the AFX_CBRS_AUTOHIDE flag to
CBasePane::CreateEx.
The default implementation checks for the AFX_CBRS_AUTOHIDE flag. Override this method in a derived
class to customize this behavior.

CBasePane::CanBeAttached
Determines whether the pane can be docked to another pane or frame window.

virtual BOOL CanBeAttached() const;

Return Value
TRUE if the pane can be docked to another pane or frame window; otherwise FALSE.
Remarks
The default implementation returns FALSE. Override this method in a derived class to enable or disable the
ability to dock without calling CBasePane::EnableDocking.

CBasePane::CanBeClosed
Determines whether the pane can be closed.

virtual BOOL CanBeClosed() const;

Return Value
TRUE if the pane can be closed; otherwise FALSE.
Remarks
The framework calls this method to determine whether the pane can be closed. If the method returns TRUE, a
Close button is added to the pane's title bar or, if the pane is floating, to the title bar of the pane's miniframe
window.
During construction, you can set this ability by passing the AFX_CBRS_CLOSE flag to CBasePane::CreateEx.
The default implementation checks for the AFX_CBRS_CLOSE flag.

CBasePane::CanBeDocked
Determines whether the pane can be docked to another pane.

virtual BOOL CanBeDocked(CBasePane* pDockBar) const;

Parameters
pDockBar
[in] A pointer to another pane.
Return Value
TRUE if this pane can be docked to another pane; otherwise FALSE.
Remarks
The framework calls this method before it docks the pane specified by pDockBar to the current pane.
Use this method and the CBasePane::CanAcceptPane method to control how panes dock to other panes in
your application.
The default implementation returns FALSE.

CBasePane::CanBeResized
Determines whether the pane can be resized.

virtual BOOL CanBeResized() const;

Return Value
TRUE if the pane can be resized; otherwise, FALSE.
Remarks
This method checks for the AFX_CBRS_RESIZE flag, which is specified by default in CBasePane::OnCreate . If
this flag is not specified, the docking manager flags the pane internally as immovable instead of docking it.

CBasePane::CanBeTabbedDocument
Specifies whether the pane can be converted to an MDI tabbed document.

virtual BOOL CanBeTabbedDocument() const;

Return Value
TRUE if the pane can be converted to a tabbed document; otherwise, FALSE. CBasePane::CanBeTabbedDocument
always returns FALSE.
Remarks
Only objects of certain CBasePane -derived types, such as the CDockablePane Class, can be converted to
tabbed documents.

CBasePane::CanFloat
Determines whether the pane can float.

virtual BOOL CanFloat() const;

Return Value
TRUE if the pane can float; otherwise FALSE.
Remarks
The framework calls this method to determine whether the pane can float.
During construction, you can set this ability by passing the AFX_CBRS_FLOAT flag to CBasePane::CreateEx.
NOTE
The framework assumes that non-floating panes are static and that their docking state cannot change. Therefore, the
framework does not save the docking state of non-floating panes.

The default implementation checks for the AFX_CBRS_FLOAT style.

CBasePane::CanFocus
Specifies whether the pane can receive focus.

virtual BOOL CanFocus() const;

Return Value
TRUE if the pane can receive focus; otherwise FALSE.
Remarks
Override this method in a derived class to control focus. For example, because toolbars cannot receive focus,
this method returns FALSE when it is called on toolbar objects.
The framework tries to set the input focus when a pane is docked or floated.

CBasePane::CopyState
Copies the state of a given pane.

virtual void CopyState(CBasePane* pOrgBar);

Parameters
pOrgBar
[in] A pointer to another pane.
Remarks
This method copies the state from pOrgBar to this pane.

CBasePane::CreateDefaultMiniframe
If the pane can float, this method creates a mini-frame window for it.

virtual CPaneFrameWnd* CreateDefaultMiniframe(CRect rectInitial);

Parameters
rectInitial
[in] Specifies the initial coordinates of the mini-frame window.
Return Value
A pointer to the new mini-frame window or NULL if the creation failed.
Remarks
The framework calls this method when a pane switches to a floating state. The method creates a mini-frame
window and attaches the pane to this window.
The default implementation returns NULL.

CBasePane::CreateEx
Creates the pane control.

virtual BOOL CreateEx(


DWORD dwStyleEx,
LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID,
DWORD dwControlBarStyle=0,
CCreateContext* pContext=NULL);

Parameters
dwStyleEx
[in] The extended styles (see CWnd::CreateEx for more information).
lpszClassName
[in] The window class name.
lpszWindowName
[in] The window name.
dwStyle
[in] The window style (see CWnd::CreateEx).
rect
[in] The initial rectangle.
pParentWnd
[in] A pointer to the parent window.
nID
[in] Specifies the pane ID. Must be unique.
dwControlBarStyle
[in] Style flags for panes.
pContext
[in] A pointer to CcreateContext

Return Value
TRUE if the pane is created successfully; otherwise FALSE.
Remarks
Creates a window of class lpszClassName . If you specify WS_CAPTION, this method clears the WS_CAPTION
style bit and sets CBasePane::m_bHasCaption to TRUE, because the library does not support panes with
captions.
You can use any combination of child window styles and MFC control bar (CBRS_) styles.
The library adds several new styles for panes. The following table describes the new styles:
ST Y L E DESC RIP T IO N

AFX_CBRS_FLOAT The pane can float.

AFX_CBRS_AUTOHIDE The pane supports auto-hide mode

AFX_CBRS_RESIZE The pane can be resized. Impor tant: This style is not
implemented.

AFX_CBRS_CLOSE The pane can be closed.

AFX_CBRS_AUTO_ROLLUP The pane can be rolled up when it floats.

AFX_CBRS_REGULAR_TABS When one pane docks to another pane that has this style,
a regular tabbed window is created. (For more information,
see CTabbedPane Class.)

AFX_CBRS_OUTLOOK_TABS When one pane docks to another pane that has this style,
an Outlook-style tabbed window is created. (For more
information, see CMFCOutlookBar Class.)

To use the new styles, specify them in dwControlBarStyle.

CBasePane::DockPane
Docks a pane to another pane or to a frame window.

virtual BOOL DockPane(


CBasePane* pDockBar,
LPCRECT lpRect,
AFX_DOCK_METHOD dockMethod);

Parameters
pDockBar
[in] A pointer to another pane.
lpRect
[in] Specifies the destination rectangle.
dockMethod
[in] Specifies the docking method.
Return Value
TRUE if the control bar was docked successfully; otherwise, FALSE.
Remarks
Call this function to dock a pane to another pane or a dock bar ( CDockSite Class) that is specified by
pDockBar, or to a main frame if pDockBar is NULL.
dockMethod specifies how the pane is docked. See CPane::DockPane for a list of possible values.

CBasePane::DockPaneUsingRTTI
Docks the pane by using run-time type information.
void DockPaneUsingRTTI(BOOL bUseDockSite);

Parameters
bUseDockSite
[in] If TRUE, dock to the docking site. If FALSE, dock to the parent frame.

CBasePane::DockToFrameWindow
Docks a dockable pane to a frame.

virtual BOOL DockToFrameWindow(


DWORD dwAlignment,
LPCRECT lpRect = NULL,
DWORD dwDockFlags = DT_DOCK_LAST,
CBasePane* pRelativeBar = NULL,
int nRelativeIndex = -1,
BOOL bOuterEdge = FALSE);

Parameters
dwAlignment
[in] The side of the parent frame that you want to dock the pane to.
lpRect
[in] The desired size.
dwDockFlags
[in] Ignored.
pRelativeBar
[in] Ignored.
nRelativeIndex
[in] Ignored.
bOuterEdge
[in] If TRUE and there are other dockable panes at the side specified by dwAlignment, the pane is docked
outside the other panes, closer to the edge of the parent frame. If FALSE, the pane is docked closer to the
center of the client area.
Return Value
TRUE if the method was successful; otherwise FALSE.
Remarks
This method fails if a pane divider ( CPaneDivider Class) cannot be created. Otherwise, it always returns
TRUE.

CBasePane::DoesAllowDynInsertBefore
Determines whether another pane can be dynamically inserted between this pane and the parent frame.

virtual BOOL DoesAllowDynInsertBefore() const;

Return Value
TRUE if a user can insert another pane; otherwise FALSE.
Remarks
The framework calls this method to determine whether a user can dynamically insert a pane before this
pane.
For example, suppose your application creates a pane docked at the left side of the frame (such as the
Outlook bar). To prevent the user from docking another pane to the left of the first pane, override this
method and return FALSE.
We recommend that you override this method and return FALSE for non-floating panes derived from
CDockablePane Class.
The default implementation returns TRUE.

CBasePane::DoPaint
Fills the background of the pane.

virtual void DoPaint(CDC* pDC);

Parameters
pDC
[in] A pointer to a device context.
Remarks
The default implementation calls the current visual manager to fill the background (
CMFCVisualManager::OnFillBarBackground).

CBasePane::EnableDocking
Enables docking of the pane to the main frame.

virtual void EnableDocking(DWORD dwAlignment);

Parameters
dwAlignment
[in] Specifies the docking alignment to enable.
Remarks
Call this method to enable docking alignment to the main frame. You can pass a combination of
CBRS_ALIGN_ flags (for more information, see CControlBar::EnableDocking).
EnableDocking sets the internal flag CBasePane::m_dwEnabledAlignment and the framework checks this flag
when a pane is docked.
Call CBasePane::GetEnabledAlignment to determine the docking alignment for a pane.

CBasePane::EnableGripper
Enables or disables the gripper. If the gripper is enabled, the user can drag it to reposition the pane.

virtual void EnableGripper(BOOL bEnable);

Parameters
bEnable
[in] TRUE to enable the gripper; FALSE to disable it.
Remarks
The framework uses this method to enable a gripper instead of using the WS_CAPTION style.

CBasePane::FloatPane
Floats the pane.

virtual BOOL FloatPane(


CRect rectFloat,
AFX_DOCK_METHOD dockMethod=DM_UNKNOWN,
bool bShow=true);

Parameters
rectFloat
[in] Specifies the screen coordinates where the floating pane appears.
dockMethod
[in] Specifies the dock method to use to float the pane.
bShow
[in] Specifies whether the floating pane is visible (TRUE) or hidden (FALSE).
Return Value
TRUE if the pane was floated successfully; otherwise FALSE.
Remarks
Call this method to float a pane at the screen position specified by rectFloat.

CBasePane::get_accHelpTopic
The framework calls this method to retrieve the full path of the WinHelp file that is associated with the
specified object and the identifier of the appropriate topic in that file.

virtual HRESULT get_accHelpTopic(


BSTR* pszHelpFile,
VARIANT varChild,
long* pidTopic);

Parameters
pszHelpFile
[in] Address of a BSTR that receives the full path of the WinHelp file that is associated with the specified
object, if any.
varChild
[in] Specifies whether the Help topic to be retrieved is that of the object or one of the child elements of the
object. This parameter can be either CHILDID_SELF (to obtain a Help topic for the object) or a child ID (to
obtain a Help topic for one of the child elements of the object).
pidTopic
[in] Identifies the Help file topic that is associated with the specified object.
Return Value
CBasePane does not implement this method. Therefore, CBasePane::get_accHelpTopic always returns
S_FALSE.
Remarks
This function is part of the Active Accessibility support in MFC. Override this function in a derived class to
provide help information about your object.

CBasePane::get_accSelection
The framework calls this method to retrieve the selected children of this object.

virtual HRESULT get_accSelection(VARIANT* pvarChildren);

Parameters
pvarChildren
[in] Receives information that identifies the selected children.
Return Value
CBasePane does not implement this method. If pvarChildren is NULL, this method returns E_INVALIDARG.
Otherwise, this method returns DISP_E_MEMBERNOTFOUND.
Remarks
This function is part of the Active Accessibility support in MFC. Override this function in a derived class if you
have non-windowed user interface elements other than windowless ActiveX controls.

CBasePane::GetCaptionHeight
Returns the caption height.

virtual int GetCaptionHeight() const;

Return Value
The caption height.

CBasePane::GetControlBarStyle
Returns the control bar style.

virtual DWORD GetControlBarStyle() const

Return Value
A bitwise-OR combination of AFX_CBRS_ flags.
Remarks
The return value is a combination of the following possible values.

ST Y L E DESC RIP T IO N

AFX_CBRS_FLOAT Makes the control bar float.

AFX_CBRS_AUTOHIDE Enables auto-hide mode.


ST Y L E DESC RIP T IO N

AFX_CBRS_RESIZE Enables resizing of the control bar. When this flag is set,
the control bar can be placed in a dockable pane.

AFX_CBRS_CLOSE Enables hiding of the control bar.

CBasePane::GetCurrentAlignment
Returns the current pane alignment.

virtual DWORD GetCurrentAlignment() const;

Return Value
The current alignment of the control bar. The following table shows the possible values:

VA L UE A L IGN M EN T

CBRS_ALIGN_LEFT Left alignment.

CBRS_ALIGN_RIGHT Right alignment.

CBRS_ALIGN_TOP Top alignment.

CBRS_ALIGN_BOTTOM Bottom alignment.

CBasePane::GetDockingMode
Returns the current docking mode for the pane.

virtual AFX_DOCK_TYPE GetDockingMode() const;

Return Value
DT_STANDARD if dragging the pane is indicated on the screen by a drag rectangle. DT_IMMEDIATE if the
contents of the pane are dragged.
Remarks
The framework calls this method to determine the current docking mode of the pane.
If CBasePane::m_dockMode is undefined (DT_UNDEFINED), then the docking mode is taken from the global
docking mode ( AFX_GLOBAL_DATA::m_dockModeGlobal ).
By setting m_dockMode or overriding GetDockingMode you can control the docking mode for each pane.

CBasePane::GetDockSiteFrameWnd
Returns a pointer to the CDockingPanesRowobject where the pane is docked.

virtual CWnd* GetDockSiteFrameWnd() const;

Return Value
A pointer to the dock site of the pane.
Remarks
Call this method to retrieve a pointer to the dock site of the pane. The dock site can be either a main frame
window if the pane is docked to the main frame, or a mini-frame window if the pane is floating.

CBasePane::GetEnabledAlignment
Returns the CBRS_ALIGN_ styles that are applied to the pane.

virtual DWORD GetEnabledAlignment() const;

Return Value
A combination of CBRS_ALIGN_ styles. The following table shows the possible styles:

FLAG EN A B L ED A L IGN M EN T

CBRS_ALIGN_LEFT Left.

CBRS_ALIGN_RIGHT Right.

CBRS_ALIGN_TOP Top.

CBRS_ALIGN_BOTTOM Bottom.

CBRS_ALIGN_ANY Combination of all flags.

Remarks
Call this method to determine the enabled alignment for the pane. Enabled alignment means the sides of the
main frame window that a pane can be docked to.
Enable docking alignment by using CBasePane::EnableDocking.

CBasePane::GetMFCStyle
Returns the pane styles that are specific to MFC.

virtual DWORD GetMFCStyle() const;

Return Value
A combination of library-specific (AFX_CBRS_) pane styles.

CBasePane::GetPaneIcon
Returns a handle to the pane icon.

virtual HICON GetPaneIcon(BOOL bBigIcon);

Parameters
bBigIcon
[in] Specifies a 32 pixel by 32 pixel icon if TRUE; specifies a 16 pixel by 16 pixel icon if FALSE.
Return Value
A handle to the pane icon. If unsuccessful, returns NULL.
Remarks
The default implementation calls CWnd::GetIcon.

CBasePane::GetPaneRow
Returns a pointer to the CDockingPanesRowobject where the pane is docked.

CDockingPanesRow* GetPaneRow();

Return Value
A pointer to CDockingPanesRow if the pane is docked, or NULL if it is floating.
Remarks
Call this method to access the row where a pane is docked. For example, to arrange the panes in a particular
row, call GetPaneRow and then call CDockingPanesRow::ArrangePanes.

CBasePane::GetPaneStyle
Returns the pane style.

virtual DWORD GetPaneStyle() const;

Return Value
A combination of control bar styles (including CBRS_ styles) that was set by the CBasePane::SetPaneStyle
method at creation time.

CBasePane::GetParentDockSite
Returns a pointer to the parent dock site.

virtual CDockSite* GetParentDockSite() const;

Return Value
The parent dock site.

CBasePane::GetParentMiniFrame
Returns a pointer to the parent mini-frame window.

virtual CPaneFrameWnd* GetParentMiniFrame(BOOL bNoAssert=FALSE) const;

Parameters
bNoAssert
[in] If TRUE, this method does not check for non-valid pointers. If you call this method when your application
exits, set this parameter to TRUE.
Return Value
A valid pointer to the parent mini-frame window if the pane is floating; otherwise NULL.
Remarks
Call this function to retrieve a pointer to the parent mini-frame window. This method iterates through all
parents and checks for an object derived from CPaneFrameWnd Class.
Use GetParentMiniFrame to determine whether the pane is floating.

CBasePane::GetParentTabbedPane
Returns a pointer to the parent tabbed pane.

CBaseTabbedPane* GetParentTabbedPane() const;

Return Value
A pointer to the parent tabbed pane if it exists; otherwise NULL.

CBasePane::GetParentTabWnd
Returns a pointer to the parent window that is inside a tab.

CMFCBaseTabCtrl* GetParentTabWnd(HWND& hWndTab) const;

Parameters
hWndTab
[out] If the return value is not NULL, this parameter contains the handle to the parent tabbed window.
Return Value
A valid pointer to the parent tabbed window or NULL.
Remarks
Use this function to retrieve a pointer to the parent tabbed window. Sometimes it is not enough to call
GetParent , because a pane may be inside a docking wrapper ( CDockablePaneAdapter Class) or inside a
pane adapter ( CDockablePaneAdapter Class). By using GetParentTabWnd you will be able to retrieve a valid
pointer in those cases (assuming that the parent is a tabbed window).

CBasePane::GetRecentVisibleState
The framework calls this method when a pane is restored from an archive.

virtual BOOL GetRecentVisibleState() const;

Return Value
A BOOL that specifies the recent visible state. If TRUE, the pane was visible when serialized and should be
visible when restored. If FALSE, the pane was hidden when serialized and should be hidden when restored.

CBasePane::HideInPrintPreviewMode
Specifies whether the pane is hidden in print preview.

virtual BOOL HideInPrintPreviewMode() const;


Return Value
TRUE if the pane is not shown in print preview; otherwise, FALSE.
Remarks
Base panes are not shown in print preview. Therefore, this method always returns TRUE.

CBasePane::InsertPane
Registers the specified pane with the docking manager.

BOOL InsertPane(
CBasePane* pControlBar,
CBasePane* pTarget,
BOOL bAfter = TRUE);

Parameters
pControlBar
[in] A pointer to the pane to insert.
pTarget
[in] A pointer to the adjacent pane.
bAfter
[in] If TRUE, pControlBar is inserted after pTarget. If FALSE, pControlBar is inserted before pTarget.
Return Value
TRUE if the method succeeds, FALSE otherwise.

CBasePane::IsAccessibilityCompatible
Specifies whether the pane supports Active Accessibility.

virtual BOOL IsAccessibilityCompatible();

Return Value
TRUE if the pane supports Active Accessibility; otherwise, FALSE.

CBasePane::IsAutoHideMode
Determines whether a pane is in auto-hide mode.

virtual BOOL IsAutoHideMode() const;

Return Value
TRUE if the pane is in auto-hide mode; otherwise, FALSE.
Remarks
Base panes cannot auto-hide. This method always returns FALSE.

CBasePane::IsDialogControl
Specifies whether the pane is a dialog box control.
BOOL IsDialogControl() const;

Return Value
TRUE if the pane is a dialog box control; otherwise, FALSE.
Remarks
The framework uses this method to ensure layout consistency for all panes.

CBasePane::IsDocked
Determines whether the pane is docked.

virtual BOOL IsDocked() const;

Return Value
TRUE if the parent of the pane is not a mini-frame or if the pane is floating in a mini-frame with another
pane; otherwise, FALSE.

CBasePane::IsFloating
Determines whether the pane is floating.

virtual BOOL IsFloating() const;

Return Value
TRUE if the pane is floating; otherwise, FALSE.
Remarks
This method returns the opposite value of CBasePane::IsDocked.

CBasePane::IsHorizontal
Determines whether the pane is docked horizontally.

virtual BOOL IsHorizontal() const;

Return Value
TRUE if the pane is docked horizontally; otherwise FALSE.
Remarks
The default implementation checks the current docking alignment for CBRS_ORIENT_HORZ.

CBasePane::IsInFloatingMultiPaneFrameWnd
Specifies whether the pane is in a multi-pane frame window ( CMultiPaneFrameWnd Class).

virtual BOOL IsInFloatingMultiPaneFrameWnd() const;

Return Value
TRUE if the pane is in a multi-pane frame window; otherwise, FALSE.
Remarks
Only dockable panes can float in a multi-pane frame window. Therefore,
CBasePane::IsInFloatingMultiPaneFrameWnd always returns FALSE.

CBasePane::IsMDITabbed
Determines whether the pane has been added to an MDI child window as a tabbed document.

virtual BOOL IsMDITabbed() const;

Return Value
TRUE if the pane was added to an MDI child window as a tabbed document; otherwise, FALSE.

CBasePane::IsPaneVisible
Specifies whether the WS_VISIBLE flag is set for the pane.

BOOL IsPaneVisible() const;

Return Value
TRUE if WS_VISIBLE is set; otherwise, FALSE.
Remarks
Use CBasePane::IsVisible to determine pane visibility.

CBasePane::IsPointNearDockSite
Determines whether a specified point is near the dock site.

BOOL IsPointNearDockSite(
CPoint point,
DWORD& dwBarAlignment,
BOOL& bOuterEdge) const;

Parameters
point
[in] The specified point.
dwBarAlignment
[out] Specifies which edge the point is near. Possible values are CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT,
CBRS_ALIGN_TOP, and CBRS_ALIGN_BOTTOM
bOuterEdge
[out] TRUE if the point is near the outer border of the dock site; FALSE otherwise.
Return Value
TRUE if the point is near the dock site; otherwise FALSE.
Remarks
The point is near the dock site when it is within the sensitivity set in the docking manager. The default
sensitivity is 15 pixels.
CBasePane::IsResizable
Determines whether the pane can be resized.

virtual BOOL IsResizable() const;

Return Value
TRUE if the pane can be resized by the user; otherwise, FALSE.
Remarks
Panes of CDockablePane Class can be resized.
The status bar ( CMFCStatusBar Class) and the dock bar ( CDockSite Class) cannot be resized.

CBasePane::IsRestoredFromRegistry
Determines whether the pane is restored from the registry.

virtual BOOL IsRestoredFromRegistry() const;

Return Value
TRUE if the pane is restored from the registry; otherwise, FALSE.

CBasePane::IsTabbed
Determines whether the pane has been inserted in the tab control of a tabbed window.

virtual BOOL IsTabbed() const;

Return Value
TRUE if the control bar is inserted in a tab of a tabbed window; otherwise FALSE.
Remarks
This method retrieves a pointer to the immediate parent and determines if the parent's runtime class is
CMFCBaseTabCtrl Class.

CBasePane::IsVisible
Determines whether the pane is visible.

virtual BOOL IsVisible() const;

Return Value
TRUE if the pane is visible; otherwise FALSE.
Remarks
Use this method to determine the visibility of a pane. Do not use ::IsWindowVisible .
If the pane is not tabbed (see CBasePane::IsTabbed), this method checks for the WS_VISIBLE style. If the pane
is tabbed, this method checks the visibility of the parent tabbed window. If the parent window is visible, the
function checks the visibility of the pane tab using CMFCBaseTabCtrl::IsTabVisible.
CBasePane::LoadState
Loads the pane's state from the registry.

virtual BOOL LoadState(


LPCTSTR lpszProfileName=NULL,
int nIndex=-1,
UINT uiID=(UINT)-1);

Parameters
lpszProfileName
[in] Profile name.
nIndex
[in] Profile index.
uiID
[in] Pane ID.
Return Value
TRUE if the pane state was loaded successfully; otherwise FALSE.
Remarks
The framework calls this method to load the pane state from the registry. Override it in a derived class to
load additional information saved by CBasePane::SaveState.

CBasePane::MoveWindow
Moves the pane.

virtual HDWP MoveWindow(


CRect& rect,
BOOL bRepaint = TRUE,
HDWP hdwp = NULL);

Parameters
rect
[in] A rectangle specifying the new location and size of the pane.
bRepaint
[in] If TRUE, the pane is repainted. If FALSE, the pane is not repainted.
hdwp
[in] Handle to a deferred window position structure.
Return Value
A handle to a deferred window position structure, or NULL.
Remarks
If you pass NULL as the hdwp parameter, this method moves the window normally. If you pass a handle, this
method performs a deferred window move. You can obtain a handle by calling BeginDeferWindowPos or by
storing the return value of a previous call to this method.

CBasePane::OnAfterChangeParent
Called by the framework after the pane's parent changes.

virtual void OnAfterChangeParent(CWnd* pWndOldParent);

Parameters
pWndOldParent
[in] A pointer to the previous parent.
Remarks
The framework calls this method after the pane's parent changes, usually because of a docking or floating
operation.
The default implementation does nothing.

CBasePane::OnBeforeChangeParent
Called by the framework just before the pane changes its parent window.

virtual void OnBeforeChangeParent(


CWnd* pWndNewParent,
BOOL bDelay=FALSE);

Parameters
pWndNewParent
[in] A pointer to a new parent window.
bDelay
[in] Specifies whether layout adjustments must be delayed.
Remarks
The framework calls this method just before the pane's parent changes, usually because of a docking,
floating, or auto-hide operation.
The default implementation does nothing.

CBasePane::OnDrawCaption
The framework calls this method when the caption is drawn.

virtual void OnDrawCaption();

Remarks
This method has no functionality for the CBasePane class.

CBasePane::OnMovePaneDivider
This method is currently not used.

virtual void OnMovePaneDivider(CPaneDivider* /* unused */);

Parameters
unused
[in] Not used.

CBasePane::OnPaneContextMenu
Called by the framework when it builds a menu that has a list of panes.

virtual void OnPaneContextMenu(


CWnd* pParentFrame,
CPoint point);

Parameters
pParentFrame
[in] A pointer to the parent frame.
point
[in] Specifies the location of the shortcut menu.
Remarks
OnPaneContextMenu calls the docking manager, which maintains the list of panes that belong to the current
frame window. This method adds the names of the panes to a shortcut menu and displays it. The commands
on the menu show or hide individual panes.
Override this method to customize this behavior.

CBasePane::OnRemoveFromMiniFrame
Called by the framework when a pane is removed from its parent mini frame window.

virtual void OnRemoveFromMiniFrame(CPaneFrameWnd* pMiniFrame);

Parameters
pMiniFrame
[in] A pointer to a mini-frame window from which the pane is removed.
Remarks
The framework calls this method when a pane is removed from its parent mini-frame window (as a result of
docking, for example).
The default implementation does nothing.

CBasePane::OnSetAccData
CBasePane does not use this method.

virtual BOOL OnSetAccData(long lVal);

Parameters
lVal
[in] Not used.
Return Value
This method always returns TRUE.
Remarks

CBasePane::PaneFromPoint
Returns the pane that contains the given point.

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
bool bExactBar = false,
CRuntimeClass* pRTCBarType = NULL) const;

Parameters
point
[in] Specifies the point, in screen coordinates, to check.
nSensitivity
[in] Increase the search area by this amount. A pane will satisfy the search criteria if the given point falls in
the increased area.
bExactBar
[in] TRUE to ignore the nSensitivity parameter; otherwise, FALSE.
pRTCBarType
[in] If not NULL, the method searches only panes of the specified type.
Return Value
The CBasePane -derived object that contains the given point, or NULL if no pane was found.

CBasePane::RecalcLayout
CBasePane does not use this method.

virtual void RecalcLayout();

CBasePane::RemovePaneFromDockManager
Unregisters a pane and removes it from the list in the docking manager.

void RemovePaneFromDockManager(
CBasePane* pBar,
BOOL bDestroy = TRUE,
BOOL bAdjustLayout = FALSE,
BOOL bAutoHide = FALSE,
CBasePane* pBarReplacement = NULL);

Parameters
pBar
[in] A pointer to a pane to be removed.
bDestroy
[in] If TRUE, the removed pane is destroyed.
bAdjustLayout
[in] If TRUE, adjust the docking layout immediately.
bAutoHide
[in] If TRUE, the docking layout is related to the list of autohide bars. If FALSE, the docking layout is related to
the list of regular panes.
pBarReplacement
[in] A pointer to a pane that replaces the removed pane.

CBasePane::SaveState
Saves the pane's state to the registry.

virtual BOOL SaveState(


LPCTSTR lpszProfileName=NULL,
int nIndex=-1,
UINT uiID=(UINT)-1);

Parameters
lpszProfileName
[in] Profile name.
nIndex
[in] Profile index.
uiID
[in] Pane ID.
Return Value
TRUE if the state was saved successfully; otherwise FALSE.
Remarks
The framework calls this method when it saves the pane's state to the registry. Override SaveState in a
derived class to store additional information.

CBasePane::SelectDefaultFont
Selects the default font for a given device context.

CFont* SelectDefaultFont(CDC* pDC);

Parameters
pDC
[in] A device context.
Return Value
A pointer to the default CFont Class object.

CBasePane::SetControlBarStyle
Sets the control bar style.

virtual void SetControlBarStyle(DWORD dwNewStyle);

Parameters
dwNewStyle
[in] A bitwise-OR combination of the following possible values.

ST Y L E DESC RIP T IO N

AFX_CBRS_FLOAT Makes the control bar float.

AFX_CBRS_AUTOHIDE Enables auto-hide mode.

AFX_CBRS_RESIZE Enables resizing of the control bar. When this flag is set,
the control bar can be placed in a dockable pane.

AFX_CBRS_CLOSE Enables hiding of the control bar.

CBasePane::SetDockingMode
Sets the docking mode for the pane.

void SetDockingMode(AFX_DOCK_TYPE dockModeNew);

Parameters
dockModeNew
[in] Specifies the new docking mode for the pane.
Remarks
The framework supports two docking modes: standard and immediate.
In the standard docking mode, panes and mini-frame windows are moved around using a drag rectangle. In
the immediate docking mode, control bars and mini-frame windows are moved immediately with their
context.
Initially, the docking mode is defined globally by CDockingManager::m_dockModeGlobal. You can set the
docking mode for each pane individually using the SetDockingMode method.

CBasePane::SetPaneAlignment
Sets the alignment for the pane.

virtual void SetPaneAlignment(DWORD dwAlignment);

Parameters
dwAlignment
[in] Specifies the new alignment.
Remarks
Usually, the framework calls this method when a pane is docked from one side of the main frame to another.
The following table shows the possible values for dwAlignment:

VA L UE A L IGN M EN T

CBRS_ALIGN_LEFT Left alignment.


VA L UE A L IGN M EN T

CBRS_ALIGN_RIGHT Right alignment.

CBRS_ALIGN_TOP Top alignment.

CBRS_ALIGN_BOTTOM Bottom alignment.

CBasePane::SetPaneStyle
Sets the style of the pane.

virtual void SetPaneStyle(DWORD dwNewStyle);

Parameters
dwNewStyle
[in] Specifies the new style to set.
Remarks
This method can be used to set any of the CBRS_ styles that are defined in afxres.h. Because pane style and
pane alignment are stored together, set the new style by combining it with the current alignment as follows.
pPane->SetPaneStyle (pPane->GetCurrentAlignment() | CBRS_TOOLTIPS);

CBasePane::SetWindowPos
Changes the size, position, and Z-order of a pane.

virtual HDWP SetWindowPos(


const CWnd* pWndInsertAfter,
int x,
int y,
int cx,
int cy,
UINT nFlags,
HDWP hdwp = NULL);

Parameters
pWndInsertAfter
[in] Identifies the CWnd object that comes before this CWnd object in the Z-order. For more information, see
CWnd::SetWindowPos.
x
[in] Specifies the position of the left side of the window.
y
[in] Specifies the position of the top of the window.
cx
[in] Specifies the width of the window.
cy
[in] Specifies the height of the window.
nFlags
[in] Specifies size and position options. For more information, see CWnd::SetWindowPos.
hdwp
[in] Handle to a structure that contains size and position information for one or more windows.
Return Value
A handle to an updated deferred window position structure, or NULL.
Remarks
If pWndInsertAfter is NULL, this method calls CWnd::SetWindowPos. If pWndInsertAfter is non-NULL, this
method calls DeferWindowPos .

CBasePane::ShowPane
Shows or hides the pane.

virtual void ShowPane(


BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
bShow
[in] Specifies whether to show (TRUE) or hide (FALSE) a pane.
bDelay
[in] If TRUE, recalculating the docking layout is delayed.
bActivate
[in] If TRUE, the pane is active when shown.
Remarks
This method shows or hides a pane. Use this method instead of ShowWindow because this method notifies the
relevant docking managers about changes in the pane's visibility.
Use CBasePane::IsVisible to determine the current visibility of a pane.

CBasePane::StretchPane
Stretches a pane vertically or horizontally.

virtual CSize StretchPane(


int nLength,
BOOL bVert);

Parameters
nLength
[in] The length by which to stretch the pane.
bVert
[in] If TRUE, stretch the pane vertically. If FALSE, stretch the pane horizontally.
Return Value
The size of the stretched pane.

CBasePane::UndockPane
CBasePane::UndockPane
Removes the pane from the dock site, default slider, or mini-frame window where it is currently docked.

virtual void UndockPane(BOOL bDelay=FALSE);

Parameters
bDelay
If TRUE, the docking layout is not recalculated immediately.
Remarks
Call this method to manipulate the pane state or exclude the pane from the docking layout.
If you want to continue to use this pane, call either CBasePane::DockPane or CBasePane::FloatPane before
calling this method.

See also
Hierarchy Chart
Classes
CPane
CWnd Class
CBaseTabbedPane Class
4/21/2020 • 12 minutes to read • Edit Online

Extends the functionality of the CDockablePane Class to support the creation of tabbed windows.

Syntax
class CBaseTabbedPane : public CDockablePane

Members
Public Constructors
NAME DESC RIP T IO N

CBaseTabbedPane::CBaseTabbedPane Default constructor.

Public Methods
NAME DESC RIP T IO N

CBaseTabbedPane::AddTab Adds a new tab to a tabbed pane.

CBaseTabbedPane::AllowDestroyEmptyTabbedPane Specifies whether an empty tabbed pane can be destroyed.

CBaseTabbedPane::ApplyRestoredTabInfo Applies tab settings, which are loaded from the registry, to a
tabbed pane.

CBaseTabbedPane::CanFloat Determines whether the pane can float. (Overrides


CBasePane::CanFloat.)

CBaseTabbedPane::CanSetCaptionTextToTabName Determines whether the caption for the tabbed pane should
display the same text as the active tab.

CBaseTabbedPane::ConvertToTabbedDocument (Overrides CDockablePane::ConvertToTabbedDocument.)

CBaseTabbedPane::DetachPane Converts one or more dockable panes to MDI tabbed


documents.

CBaseTabbedPane::EnableSetCaptionTextToTabName Enables or disables the ability of the tabbed pane to


synchronize caption text with the label text on the active tab.

CBaseTabbedPane::FillDefaultTabsOrderArray Restores the internal tab order to a default state.

CBaseTabbedPane::FindBarByTabNumber Returns a pane that resides in a tab when the tab is identified
by a zero-based tab index.

CBaseTabbedPane::FindPaneByID Returns a pane that is identified by the pane ID.


NAME DESC RIP T IO N

CBaseTabbedPane::FloatTab Floats a pane, but only if the pane currently resides in a


detachable tab.

CBaseTabbedPane::GetDefaultTabsOrder Returns the default order of tabs in the pane.

CBaseTabbedPane::GetFirstVisibleTab Retrieves a pointer to the first displayed tab.

CBaseTabbedPane::GetMinSize Retrieves the minimum allowed size for the pane. (Overrides
CPane::GetMinSize.)

CBaseTabbedPane::GetPaneIcon Returns a handle to the pane icon. (Overrides


CBasePane::GetPaneIcon.)

CBaseTabbedPane::GetPaneList Returns a list of panes that are contained in the tabbed pane.

CBaseTabbedPane::GetTabArea Returns the bounding rectangles for the top and bottom tab
areas.

CBaseTabbedPane::GetTabsNum Returns the count of tabs in a tab window.

CBaseTabbedPane::GetUnderlyingWindow Gets the underlying (wrapped) tab window.

CBaseTabbedPane::GetVisibleTabsNum Returns the count of displayed tabs.

CBaseTabbedPane::HasAutoHideMode Determines whether the tabbed pane can be switched to


auto-hide mode.

CBaseTabbedPane::IsHideSingleTab Determines whether the tabbed pane is hidden if only one


tab is displayed.

CBaseTabbedPane::LoadSiblingPaneIDs Used internally during serialization.

CBaseTabbedPane::RecalcLayout Recalculates layout information for the pane. (Overrides


CPane::RecalcLayout.)

CBaseTabbedPane::RemovePane Removes a pane from the tabbed pane.

CBaseTabbedPane::SaveSiblingBarIDs Used internally during serialization.

CBaseTabbedPane::Serialize (Overrides CDockablePane::Serialize.)

CBaseTabbedPane::SerializeTabWindow Used internally during serialization.

CBaseTabbedPane::SetAutoDestroy Determines whether the tabbed control bar will be destroyed


automatically.

CBaseTabbedPane::SetAutoHideMode Toggles the docking pane between displayed and auto-hide


mode. (Overrides CDockablePane::SetAutoHideMode.)

CBaseTabbedPane::ShowTab Shows or hides a tab.


Remarks
This class is an abstract class and cannot be instantiated. It implements the services that are common to all kinds
of tabbed panes.
Currently, the library includes two derived tabbed pane classes: CTabbedPane Class and CMFCOutlookBar Class.
A CBaseTabbedPane object wraps a pointer to a CMFCBaseTabCtrl Class object. CMFCBaseTabCtrl Class then
becomes a child window of the tabbed pane.
For more information about how to create tabbed panes, see CDockablePane Class, CTabbedPane Class, and
CMFCOutlookBar Class.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CBasePane
CPane
CDockablePane
CBaseTabbedPane

Requirements
Header : afxBaseTabbedPane.h

CBaseTabbedPane::AddTab
Adds a new tab to a tabbed pane.

virtual BOOL AddTab(


CWnd* pNewBar,
BOOL bVisible = TRUE,
BOOL bSetActive = TRUE,
BOOL bDetachable = TRUE);

Parameters
pNewBar
[in, out] A pointer to the pane to add. This pointer may become invalid after you call this method. For more
information, see the Remarks section.
bVisible
[in] TRUE to make the tab visible; otherwise, FALSE.
bSetActive
[in] TRUE to make the tab the active tab; otherwise, FALSE.
bDetachable
[in] TRUE to make the tab detachable; otherwise, FALSE.
Return Value
TRUE if the pane was successfully added as a tab and was not destroyed in the process. FALSE if the pane being
added is an object of type CBaseTabbedPane . For more information, see the Remarks section.
Remarks
Call this method to add a pane as a new tab on a tabbed pane. If pNewBar points to an object of type
CBaseTabbedPane , all its tabs are copied onto the tabbed pane and then pNewBar is destroyed. Thus, pNewBar
becomes an invalid pointer and should not be used.

CBaseTabbedPane::AllowDestroyEmptyTabbedPane
Specifies whether an empty tabbed pane can be destroyed.

virtual BOOL AllowDestroyEmptyTabbedPane() const;

Return Value
TRUE if an empty tabbed pane can be destroyed; otherwise, FALSE. The default implementation always returns
TRUE.
Remarks
If an empty tabbed pane is not allowed to be destroyed, the framework hides the pane instead.

CBaseTabbedPane::ApplyRestoredTabInfo
Loads tab settings from the registry and applies them to a tabbed pane.

virtual void ApplyRestoredTabInfo(BOOL bUseTabIndexes = FALSE);

Parameters
bUseTabIndexes
[in] This parameter is used internally by the framework.
Remarks
This method is called by the framework when it reloads docking state information from the registry. The method
obtains information about tab order and tab names for a tabbed pane.

CBaseTabbedPane::CanFloat
Specifies whether the tabbed pane can float.

virtual BOOL CanFloat() const;

Return Value
TRUE if the pane can float; otherwise, FALSE.

CBaseTabbedPane::CanSetCaptionTextToTabName
Determines whether the caption for the tabbed pane should display the same text as the active tab.

virtual BOOL CanSetCaptionTextToTabName() const;

Return Value
TRUE if the caption text of the tabbed pane is set to the text of the active tab; otherwise, FALSE.
Remarks
The method is used to determine whether the text displayed on the tabbed pane caption duplicates the label of
the active tab. You can enable or disable this functionality by calling
CBaseTabbedPane::EnableSetCaptionTextToTabName.

CBaseTabbedPane::ConvertToTabbedDocument
Converts one or more dockable panes to MDI tabbed documents.

virtual void ConvertToTabbedDocument(BOOL bActiveTabOnly = TRUE);

Parameters
bActiveTabOnly
[in] When you convert a tabbed pane, specify TRUE to convert only the active tab. Specify FALSE to convert all
tabs in the pane.

CBaseTabbedPane::DetachPane
Detaches a pane from the tabbed pane.

virtual BOOL DetachPane(


CWnd* pBar,
BOOL bHide = FALSE);

Parameters
pBar
[in] Pointer to the pane to detach.
bHide
[in] Boolean parameter that specifies whether the framework hides the pane after it is detached.
Return Value
TRUE if the framework successfully detaches the pane; FALSE if pBar is NULL or refers to a pane that is not in the
tabbed pane.
Remarks
The framework floats the detached pane if possible. For more information, see CBasePane::CanFloat.

CBaseTabbedPane::EnableSetCaptionTextToTabName
Enables or disables the ability of the tabbed pane to synchronize caption text with the label text on the active tab.

virtual void EnableSetCaptionTextToTabName(BOOL bEnable);

Parameters
bEnable
[in] TRUE to synchronize the tabbed pane caption with the active tab caption; otherwise, FALSE.

CBaseTabbedPane::FillDefaultTabsOrderArray
Restores the internal tab order to a default state.

void FillDefaultTabsOrderArray();

Remarks
This method is called when the framework restores an Outlook bar to an initial state.

CBaseTabbedPane::FindPaneByID
Returns a pane identified by the pane ID.

virtual CWnd* FindPaneByID(UINT uBarID);

Parameters
uBarID
[in] Specifies the ID of the pane to find.
Return Value
A pointer to the pane if it was found; otherwise, NULL.
Remarks
This method compares all tabs in the pane and returns the one with the ID specified by the uBarID parameter.

CBaseTabbedPane::FindBarByTabNumber
Returns a pane that resides in a tab.

virtual CWnd* FindBarByTabNumber(


int nTabNum,
BOOL bGetWrappedBar = FALSE);

Parameters
nTabNum
[in] Specifies the zero-based index of the tab to retrieve.
bGetWrappedBar
[in] TRUE to return the underlying (wrapped) window of the pane instead of the pane itself; otherwise FALSE. This
only applies to panes derived from CDockablePaneAdapter.
Return Value
If the pane is found, then a valid pointer to the pane being searched for is returned; otherwise, NULL.
Remarks
Call this method to retrieve the pane residing in the tab specified by the nTabNum parameter.

CBaseTabbedPane::FloatTab
Floats a pane, but only if the pane currently resides in a detachable tab.
virtual BOOL FloatTab(
CWnd* pBar,
int nTabID,
AFX_DOCK_METHOD dockMethod,
BOOL bHide = FALSE);

Parameters
pBar
[in, out] A pointer to the pane to float.
nTabID
[in] Specifies the zero-based index of the tab to float.
dockMethod
[in] Specifies the method to use to make the pane float. For more information, see the Remarks section.
bHide
[in] TRUE to hide the pane before floating; otherwise, FALSE.
Return Value
TRUE if the pane floated; otherwise, FALSE.
Remarks
Call this method to float a pane that currently resides in a detachable tab.
If you want to detach a pane programmatically, specify DM_SHOW for the dockMethod parameter. If you want to
float the pane in the same position where it floated previously, specify DM_DBL_CLICK as the dockMethod
parameter.

CBaseTabbedPane::GetDefaultTabsOrder
Returns the default order of tabs in the pane.

const CArray<int,int>& GetDefaultTabsOrder();

Return Value
A CArray object that specifies the default order of tabs in the pane.
Remarks
The framework calls this method when an Outlook bar is reset to an initial state.

CBaseTabbedPane::GetFirstVisibleTab
Retrieves a pointer to the first displayed tab.

virtual CWnd* GetFirstVisibleTab(int& iTabNum);

Parameters
iTabNum
[in] A reference to an integer. This method writes the zero-based index of the first displayed tab to this parameter,
or -1 if no displayed tab is found.
Return Value
If successful, a pointer to the first displayed tab; otherwise, NULL.

CBaseTabbedPane::GetMinSize
Retrieves the minimum allowed size for the pane.

virtual void GetMinSize(CSize& size) const;

Parameters
size
[out] A CSize object that is filled with the minimum allowed size.
Remarks
If consistent handling of minimum pane sizes is active ( CPane::m_bHandleMinSize), size is filled with the
minimum allowed size for the active tab. Otherwise, size is filled with the return value of CPane::GetMinSize.

CBaseTabbedPane::GetPaneIcon
Retrieves the minimum allowed size for the pane.

virtual void GetMinSize(CSize& size) const;

Parameters
size
[out] A CSize object that is filled with the minimum allowed size.
Remarks
If consistent handling of minimum pane sizes is active ( CPane::m_bHandleMinSize), size is filled with the
minimum allowed size for the active tab. Otherwise, size is filled with the return value of CPane::GetMinSize.

CBaseTabbedPane::GetPaneList
Returns a list of panes that are contained in the tabbed pane.

virtual void GetPaneList(


CObList& lst,
CRuntimeClass* pRTCFilter = NULL);

Parameters
lst
[out] A CObList that is filled with the panes that are contained in the tabbed pane.
pRTCFilter
[in] If it is not NULL, the returned list contains only panes that are of the specified runtime class.

CBaseTabbedPane::GetTabArea
Returns the bounding rectangles for the top and bottom tab areas.
virtual void GetTabArea(
CRect& rectTabAreaTop,
CRect& rectTabAreaBottom) const = 0;

Parameters
rectTabAreaTop
[out] Receives the screen coordinates of the upper tab area.
rectTabAreaBottom
[out] Receives the screen coordinates of the lower tab area.
Remarks
Call this method to determine the bounding rectangles, in screen coordinates, for the upper and lower tab areas.

CBaseTabbedPane::GetTabsNum
Returns the count of tabs in a tab window.

virtual int GetTabsNum() const;

Return Value
The number of tabs in the tabbed pane.

CBaseTabbedPane::GetUnderlyingWindow
Gets the underlying (wrapped) tab window.

virtual CMFCBaseTabCtrl* GetUnderlyingWindow();

Return Value
A pointer to the underlying tab window.

CBaseTabbedPane::GetVisibleTabsNum
Returns the count of visible tabs.

virtual int GetVisibleTabsNum() const;

Return Value
The number of visible tabs, which will be greater than or equal to zero.
Remarks
Call this method to determine the number of visible tabs in the tabbed pane.

CBaseTabbedPane::HasAutoHideMode
Determines whether the tabbed pane can be switched to autohide mode.

virtual BOOL HasAutoHideMode() const;


Return Value
TRUE if the pane can be switched to autohide mode; otherwise, FALSE.
Remarks
If autohide mode is disabled, no pin button is displayed on the tabbed pane caption.

CBaseTabbedPane::IsHideSingleTab
Determines whether the tabbed pane is hidden if only one tab is displayed.

virtual BOOL IsHideSingleTab() const;

Return Value
TRUE if the tab window is not shown when there is only one visible tab; otherwise, FALSE.
Remarks
If the pane is not displayed because only one tab is open, you can call this method to determine whether the
tabbed pane is working correctly.

CBaseTabbedPane::RemovePane
Removes a pane from the tabbed pane.

virtual BOOL RemovePane(CWnd* pBar);

Parameters
pBar
[in, out] A pointer to the pane to remove from the tabbed pane.
Return Value
TRUE if the pane was successfully removed from the tabbed pane and if the tabbed pane is still valid. FALSE if the
last pane has been removed from the tabbed pane and the tabbed pane is about to be destroyed. If the return
value is FALSE, do not use the tabbed pane any more.
Remarks
Call this method to remove the pane specified by the pBar parameter from the tabbed pane.

CBaseTabbedPane::SetAutoDestroy
Determines whether the tabbed control bar will be destroyed automatically.

void SetAutoDestroy(BOOL bAutoDestroy = TRUE);

Parameters
bAutoDestroy
[in] TRUE if the tabbed pane was created dynamically and you are not controlling its lifetime; otherwise, FALSE.
Remarks
Set the auto-destroy mode to TRUE if you create a tabbed pane dynamically and if you are not controlling its
lifetime. If auto-destroy mode is TRUE, the tabbed pane will be destroyed automatically by the framework.
CBaseTabbedPane::ShowTab
Shows or hides a tab.

virtual BOOL ShowTab(


CWnd* pBar,
BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
pBar
[in] A pointer to the pane to show or hide.
bShow
[in] TRUE to show the pane; FALSE to hide the pane.
bDelay
[in] TRUE to delay the adjustment of the tab layout; otherwise, FALSE.
bActivate
[in] TRUE to make the tab the active tab; otherwise, FALSE.
Return Value
TRUE if the tab was either shown or hidden successfully; otherwise, FALSE.
Remarks
When you call this method, a pane is either shown or hidden, depending on the value of the bShow parameter. If
you hide a tab and it is the last visible tab in the underlying tab window, the tabbed pane is hidden. If you show a
tab when there were previously no tabs visible, the tabbed pane is shown.

CBaseTabbedPane::RecalcLayout
Recalculates layout information for the pane.

virtual void RecalcLayout();

Remarks
If the pane is floating, this method notifies the framework to resize the pane to the current size of the mini-frame.
If the pane is docked, this method does nothing.

CBaseTabbedPane::SetAutoHideMode
Sets the auto-hide mode for detachable panes in the tabbed pane.

virtual CMFCAutoHideToolBar* SetAutoHideMode(


BOOL bMode,
DWORD dwAlignment,
CMFCAutoHideToolBar* pCurrAutoHideBar = NULL,
BOOL bUseTimer = TRUE);

Parameters
bMode
[in] TRUE to enable auto-hide mode; FALSE to enable regular docking mode.
dwAlignment
[in] Specifies the alignment of the auto-hide pane that is to be created. For a list of possible values, see
CPane::MoveByAlignment.
pCurrAutoHideBar
[in, out] A pointer to the current auto-hide toolbar. Can be NULL.
bUseTimer
[in] Specifies whether to use the auto-hide effect when the user switches the pane to auto-hide mode, or to hide
the pane immediately.
Return Value
A pointer to the auto-hide toolbar that is created when switching to auto-hide mode, or NULL if no toolbar is
created.
Remarks
The framework calls this method when a user chooses the pin button to switch the tabbed pane to auto-hide
mode or to regular docking mode.
Auto-hide mode is set for each detachable pane in the tabbed pane. Panes that are non-detachable are ignored.
For more information, see CMFCBaseTabCtrl::EnableTabDetach.
Call this method to switch a tabbed pane to auto-hide mode programmatically. The pane must be docked to the
main frame window ( CDockablePane::GetDefaultPaneDivider must return a valid pointer to the CPaneDivider).

See also
Hierarchy Chart
Classes
CDockablePane Class
CBaseTransition Class
4/21/2020 • 5 minutes to read • Edit Online

Represents a basic transition.

Syntax
class CBaseTransition : public CObject;

Members
Public Enumerations
NAME DESC RIP T IO N

CBaseTransition::TRANSITION_TYPE Enumeration Defines the transition types currently supported by the MFC
implementation of Windows Animation API.

Public Constructors
NAME DESC RIP T IO N

CBaseTransition::CBaseTransition Constructs a base transition object.

CBaseTransition::~CBaseTransition The destructor. Called when a transition object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CBaseTransition::AddToStoryboard Adds a transition to a storyboard.

CBaseTransition::AddToStoryboardAtKeyframes Adds a transition to a storyboard.

CBaseTransition::Clear Releases encapsulated IUIAnimationTransition COM object.

CBaseTransition::Create Creates a COM transition.

CBaseTransition::GetEndKeyframe Returns start keyframe.

CBaseTransition::GetRelatedVariable Returns a pointer to related variable.

CBaseTransition::GetStartKeyframe Returns start keyframe.

CBaseTransition::GetTransition Overloaded. Returns a pointer to underlying COM transition


object.

CBaseTransition::GetType Returns transition type.


NAME DESC RIP T IO N

CBaseTransition::IsAdded Tells whether a transition has been added to a storyboard.

CBaseTransition::SetKeyframes Sets keyframes for a transition.

CBaseTransition::SetRelatedVariable Establishes a relationship between animation variable and


transition.

Protected Data Members


NAME DESC RIP T IO N

CBaseTransition::m_bAdded Specifies whether a transition has been added to a


storyboard.

CBaseTransition::m_pEndKeyframe Stores a pointer to the keyframe that specifies the end of the
transition.

CBaseTransition::m_pRelatedVariable A pointer to an animation variable, which is animated with


the transition stored in m_transition.

CBaseTransition::m_pStartKeyframe Stores a pointer to the keyframe that specifies the beginning


of the transition.

CBaseTransition::m_transition Stores a pointer to IUIAnimationTransition. NULL if a COM


transition object has not been created.

CBaseTransition::m_type Stores the transition type.

Remarks
This class encapsulates IUIAnimationTransition interface and serves as a base class for all transitions.

Inheritance Hierarchy
CObject
CBaseTransition

Requirements
Header : afxanimationcontroller.h

CBaseTransition::~CBaseTransition
The destructor. Called when a transition object is being destroyed.

virtual ~CBaseTransition();

CBaseTransition::AddToStoryboard
Adds a transition to a storyboard.
BOOL AddToStoryboard(IUIAnimationStoryboard* pStoryboard);

Parameters
pStoryboard
A pointer to storyboard, which will animate the related variable.
Return Value
TRUE, if transition was successfully added to a storyboard.
Remarks
Applies the transition to the related variable in the storyboard. If this is the first transition applied to this variable
in this storyboard, the transition begins at the start of the storyboard. Otherwise, the transition is appended to
the transition added most recently to the variable.

CBaseTransition::AddToStoryboardAtKeyframes
Adds a transition to a storyboard.

BOOL AddToStoryboardAtKeyframes(IUIAnimationStoryboard* pStoryboard);

Parameters
pStoryboard
A pointer to storyboard, which will animate the related variable.
Return Value
TRUE, if transition was successfully added to a storyboard.
Remarks
Applies the transition to the related variable in the storyboard. If the start keyframe was specified, the transition
begins at that keyframe. If the end keyframe was specified, the transition begins at the start keyframe and stops
at the end keyframe. If the transition was created with a duration parameter specified, that duration is
overwritten with the duration of time between the start and end keyframes. If no keyframe was specified, the
transition is appended to the transition added most recently to the variable.

CBaseTransition::CBaseTransition
Constructs a base transition object.

CBaseTransition();

CBaseTransition::Clear
Releases encapsulated IUIAnimationTransition COM object.

void Clear();

Remarks
This method should be called from a derived class's Create method in order to prevent IUITransition interface
leak.
CBaseTransition::Create
Creates a COM transition.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* pFactory) = 0;

Parameters
pLibrary
A pointer to transition library, which creates standard transitions. It can be NULL for custom transitions.
pFactory
A pointer to transition factory, which creates custom transitions. It can be NULL for standard transitions.
Return Value
TRUE if a transition COM object was created successfully; otherwise FALSE.
Remarks
This is a pure virtual function that must be overridden in a derived class. It's called by the framework to
instantiate the underlying COM transition object.

CBaseTransition::GetEndKeyframe
Returns start keyframe.

CBaseKeyFrame* GetEndKeyframe();

Return Value
A valid pointer to a keyframe, or NULL if a transition should not be inserted between keyframes.
Remarks
This method can be used to access a keyframe object that was previously set by SetKeyframes. It's called by top-
level code when transitions are being added to storyboard.

CBaseTransition::GetRelatedVariable
Returns a pointer to related variable.

CAnimationVariable* GetRelatedVariable();

Return Value
A valid pointer to animation variable, or NULL if an animation variable has not been set by SetRelatedVariable.
Remarks
This is an accessor to related animation variable.

CBaseTransition::GetStartKeyframe
Returns start keyframe.

CBaseKeyFrame* GetStartKeyframe();
Return Value
A valid pointer to a keyframe, or NULL if a transition should not start after a keyframe.
Remarks
This method can be used to access a keyframe object that was previously set by SetKeyframes. It's called by top-
level code when transitions are being added to storyboard.

CBaseTransition::GetTransition
Returns a pointer to underlying COM transition object.

IUIAnimationTransition* GetTransition(
IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* pFactory);

IUIAnimationTransition* GetTransition();

Parameters
pLibrary
A pointer to transition library, which creates standard transitions. It can be NULL for custom transitions.
pFactory
A pointer to transition factory, which creates custom transitions. It can be NULL for standard transitions.
Return Value
A valid pointer to IUIAnimationTransition or NULL if underlying transition can't be created.
Remarks
This method returns a pointer to underlying COM transition object and creates it if necessary.

CBaseTransition::GetType
Returns transition type.

TRANSITION_TYPE GetType() const;

Return Value
One of TRANSITION_TYPE enumerated values.
Remarks
This method can be used to identify a transition object by its type. The type is set in a constructor in a derived
class.

CBaseTransition::IsAdded
Tells whether a transition has been added to a storyboard.

BOOL IsAdded();

Return Value
Returns TRUE if a transition has been added to a storyboard, otherwise FALSE.
Remarks
This flag is set internally when the top-level code adds transitions to storyboard.

CBaseTransition::m_bAdded
Specifies whether a transition has been added to a storyboard.

BOOL m_bAdded;

CBaseTransition::m_pEndKeyframe
Stores a pointer to the keyframe that specifies the end of the transition.

CBaseKeyFrame* m_pEndKeyframe;

CBaseTransition::m_pRelatedVariable
A pointer to an animation variable, which is animated with the transition stored in m_transition.

CAnimationVariable* m_pRelatedVariable;

CBaseTransition::m_pStartKeyframe
Stores a pointer to the keyframe that specifies the beginning of the transition.

CBaseKeyFrame* m_pStartKeyframe;

CBaseTransition::m_transition
Stores a pointer to IUIAnimationTransition. NULL if a COM transition object has not been created.

ATL::CComPtr<IUIAnimationTransition> m_transition;

CBaseTransition::m_type
Stores the transition type.

TRANSITION_TYPE m_type;

CBaseTransition::SetKeyframes
Sets keyframes for a transition.

void SetKeyframes(
CBaseKeyFrame* pStart = NULL,
CBaseKeyFrame* pEnd = NULL);

Parameters
pStart
A keyframe that specifies the beginning of the transition.
pEnd
A keyframe that specifies the end of the transition.
Remarks
This method tells the transition to start after specified keyframe and, optionally, if pEnd is not NULL, end before
the specified keyframe. If the transition was created with a duration parameter specified, that duration is
overwritten with the duration of time between the start and end keyframes.

CBaseTransition::SetRelatedVariable
Establishes a relationship between animation variable and transition.

void SetRelatedVariable(CAnimationVariable* pVariable);

Parameters
pVariable
A pointer to related animation variable.
Remarks
Establishes a relationship between animation variable and transition. A transition can be applied only to one
variable.

CBaseTransition::TRANSITION_TYPE Enumeration
Defines the transition types currently supported by the MFC implementation of Windows Animation API.

enum TRANSITION_TYPE;

Remarks
A transition type is set in the constructor of specific transition. For example, CSinusoidalTransitionFromRange sets
its type to SINUSOIDAL_FROM_RANGE.

See also
Classes
CBitmap Class
3/27/2020 • 10 minutes to read • Edit Online

Encapsulates a Windows graphics device interface (GDI) bitmap and provides member functions to manipulate
the bitmap.

Syntax
class CBitmap : public CGdiObject

Members
Public Constructors
NAME DESC RIP T IO N

CBitmap::CBitmap Constructs a CBitmap object.

Public Methods
NAME DESC RIP T IO N

CBitmap::CreateBitmap Initializes the object with a device-dependent memory bitmap


that has a specified width, height, and bit pattern.

CBitmap::CreateBitmapIndirect Initializes the object with a bitmap with the width, height, and
bit pattern (if one is specified) given in a BITMAP structure.

CBitmap::CreateCompatibleBitmap Initializes the object with a bitmap so that it is compatible


with a specified device.

CBitmap::CreateDiscardableBitmap Initializes the object with a discardable bitmap that is


compatible with a specified device.

CBitmap::FromHandle Returns a pointer to a CBitmap object when given a handle


to a Windows HBITMAP bitmap.

CBitmap::GetBitmap Fills a BITMAP structure with information about the bitmap.

CBitmap::GetBitmapBits Copies the bits of the specified bitmap into the specified
buffer.

CBitmap::GetBitmapDimension Returns the width and height of the bitmap. The height and
width are assumed to have been set previously by the
SetBitmapDimension member function.

CBitmap::LoadBitmap Initializes the object by loading a named bitmap resource


from the application's executable file and attaching the bitmap
to the object.
NAME DESC RIP T IO N

CBitmap::LoadMappedBitmap Loads a bitmap and maps colors to current system colors.

CBitmap::LoadOEMBitmap Initializes the object by loading a predefined Windows bitmap


and attaching the bitmap to the object.

CBitmap::SetBitmapBits Sets the bits of a bitmap to the specified bit values.

CBitmap::SetBitmapDimension Assigns a width and height to a bitmap in 0.1-millimeter


units.

Public Operators
NAME DESC RIP T IO N

CBitmap::operator HBITMAP Returns the Windows handle attached to the CBitmap


object.

Remarks
To use a CBitmap object, construct the object, attach a bitmap handle to it with one of the initialization member
functions, and then call the object's member functions.
For more information on using graphic objects like CBitmap , see Graphic Objects.

Inheritance Hierarchy
CObject
CGdiObject
CBitmap

Requirements
Header : afxwin.h

CBitmap::CBitmap
Constructs a CBitmap object.

CBitmap();

Remarks
The resulting object must be initialized with one of the initialization member functions.

CBitmap::CreateBitmap
Initializes a device-dependent memory bitmap that has the specified width, height, and bit pattern.
BOOL CreateBitmap(
int nWidth,
int nHeight,
UINT nPlanes,
UINT nBitcount,
const void* lpBits);

Parameters
nWidth
Specifies the width (in pixels) of the bitmap.
nHeight
Specifies the height (in pixels) of the bitmap.
nPlanes
Specifies the number of color planes in the bitmap.
nBitcount
Specifies the number of color bits per display pixel.
lpBits
Points to an array of bytes that contains the initial bitmap bit values. If it is NULL, the new bitmap is left
uninitialized.
Return Value
Nonzero if successful; otherwise 0.
Remarks
For a color bitmap, either the nPlanes or nBitcount parameter should be set to 1. If both of these parameters are
set to 1, CreateBitmap creates a monochrome bitmap.
Although a bitmap cannot be directly selected for a display device, it can be selected as the current bitmap for a
"memory device context" by using CDC::SelectObject and copied to any compatible device context by using the
CDC::BitBlt function.
When you finish with the CBitmap object created by the CreateBitmap function, first select the bitmap out of the
device context, then delete the CBitmap object.
For more information, see the description of the bmBits field in the BITMAP structure. The BITMAP structure is
described under the CBitmap::CreateBitmapIndirect member function.

CBitmap::CreateBitmapIndirect
Initializes a bitmap that has the width, height, and bit pattern (if one is specified) given in the structure pointed to
by lpBitmap.

BOOL CreateBitmapIndirect(LPBITMAP lpBitmap);

Parameters
lpBitmap
Points to a BITMAP structure that contains information about the bitmap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Although a bitmap cannot be directly selected for a display device, it can be selected as the current bitmap for a
memory device context by using CDC::SelectObject and copied to any compatible device context by using the
CDC::BitBlt or CDC::StretchBlt function. (The CDC::PatBlt function can copy the bitmap for the current brush directly
to the display device context.)
If the BITMAP structure pointed to by the lpBitmap parameter has been filled in by using the GetObject function,
the bits of the bitmap are not specified and the bitmap is uninitialized. To initialize the bitmap, an application can
use a function such as CDC::BitBlt or SetDIBits to copy the bits from the bitmap identified by the first parameter of
CGdiObject::GetObject to the bitmap created by CreateBitmapIndirect .

When you finish with the CBitmap object created with CreateBitmapIndirect function, first select the bitmap out
of the device context, then delete the CBitmap object.

CBitmap::CreateCompatibleBitmap
Initializes a bitmap that is compatible with the device specified by pDC.

BOOL CreateCompatibleBitmap(
CDC* pDC,
int nWidth,
int nHeight);

Parameters
pDC
Specifies the device context.
nWidth
Specifies the width (in pixels) of the bitmap.
nHeight
Specifies the height (in pixels) of the bitmap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The bitmap has the same number of color planes or the same bits-per-pixel format as the specified device context.
It can be selected as the current bitmap for any memory device that is compatible with the one specified by pDC.
If pDC is a memory device context, the bitmap returned has the same format as the currently selected bitmap in
that device context. A "memory device context" is a block of memory that represents a display surface. It can be
used to prepare images in memory before copying them to the actual display surface of the compatible device.
When a memory device context is created, GDI automatically selects a monochrome stock bitmap for it.
Since a color memory device context can have either color or monochrome bitmaps selected, the format of the
bitmap returned by the CreateCompatibleBitmap function is not always the same; however, the format of a
compatible bitmap for a nonmemory device context is always in the format of the device.
When you finish with the CBitmap object created with the CreateCompatibleBitmap function, first select the bitmap
out of the device context, then delete the CBitmap object.

CBitmap::CreateDiscardableBitmap
Initializes a discardable bitmap that is compatible with the device context identified by pDC.
BOOL CreateDiscardableBitmap(
CDC* pDC,
int nWidth,
int nHeight);

Parameters
pDC
Specifies a device context.
nWidth
Specifies the width (in bits) of the bitmap.
nHeight
Specifies the height (in bits) of the bitmap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The bitmap has the same number of color planes or the same bits-per-pixel format as the specified device context.
An application can select this bitmap as the current bitmap for a memory device that is compatible with the one
specified by pDC.
Windows can discard a bitmap created by this function only if an application has not selected it into a display
context. If Windows discards the bitmap when it is not selected and the application later attempts to select it, the
CDC::SelectObject function will return NULL.
When you finish with the CBitmap object created with the CreateDiscardableBitmap function, first select the
bitmap out of the device context, then delete the CBitmap object.

CBitmap::FromHandle
Returns a pointer to a CBitmap object when given a handle to a Windows GDI bitmap.

static CBitmap* PASCAL FromHandle(HBITMAP hBitmap);

Parameters
hBitmap
Specifies a Windows GDI bitmap.
Return Value
A pointer to a CBitmap object if successful; otherwise NULL.
Remarks
If a CBitmap object is not already attached to the handle, a temporary CBitmap object is created and attached.
This temporary CBitmap object is valid only until the next time the application has idle time in its event loop, at
which time all temporary graphic objects are deleted. Another way of saying this is that the temporary object is
only valid during the processing of one window message.

CBitmap::GetBitmap
Retrieves image properties for the attached bitmap.
int GetBitmap(BITMAP* pBitMap);

Parameters
pBitMap
Pointer to a BITMAP structure that will receive the image properties. This parameter must not be NULL.
Return Value
Nonzero if the method was successful; otherwise 0.
Remarks

CBitmap::GetBitmapBits
Copies the bit pattern of the attached bitmap into the specified buffer.

DWORD GetBitmapBits(
DWORD dwCount,
LPVOID lpBits) const;

Parameters
dwCount
The number of bytes to copy to the buffer.
lpBits
Pointer to the buffer that will receive the bitmap.
Return Value
The number of bytes copied to the buffer if the method was successful; otherwise 0.
Remarks
Use CBitmap::GetBitmap to determine the required buffer size.

CBitmap::GetBitmapDimension
Returns the width and height of the bitmap.

CSize GetBitmapDimension() const;

Return Value
The width and height of the bitmap, measured in 0.1-millimeter units. The height is in the cy member of the
CSize object, and the width is in the cx member. If the bitmap width and height have not been set by using
SetBitmapDimension , the return value is 0.

Remarks
The height and width are assumed to have been set previously by using the SetBitmapDimension member
function.

CBitmap::LoadBitmap
Loads the bitmap resource named by lpszResourceName or identified by the ID number in nIDResource from the
application's executable file.
BOOL LoadBitmap(LPCTSTR lpszResourceName);
BOOL LoadBitmap(UINT nIDResource);

Parameters
lpszResourceName
Points to a null-terminated string that contains the name of the bitmap resource.
nIDResource
Specifies the resource ID number of the bitmap resource.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The loaded bitmap is attached to the CBitmap object.
If the bitmap identified by lpszResourceName does not exist or if there is insufficient memory to load the bitmap,
the function returns 0.
You can use the CGdiObject::DeleteObject function to delete bitmap loaded by the LoadBitmap function, or the
CBitmap destructor will delete the object for you.

Cau t i on

Before you delete the object, make sure it is not selected into a device context.
The following bitmaps were added to Windows versions 3.1 and later:
OBM_UPARRROWIOBM_DNARROWIOBM_RGARROWIOBM_LFARROWI
These bitmaps are not found in device drivers for Windows versions 3.0 and earlier. For a complete list of bitmaps
and a display of their appearance, see the Windows SDK.

CBitmap::LoadMappedBitmap
Call this member function to load a bitmap and map the colors to the current system colors.

BOOL LoadMappedBitmap(
UINT nIDBitmap,
UINT nFlags = 0,
LPCOLORMAP lpColorMap = NULL,
int nMapSize = 0);

Parameters
nIDBitmap
The ID of the bitmap resource.
nFlags
A flag for a bitmap. Can be zero or CMB_MASKED.
lpColorMap
A pointer to a COLORMAP structure that contains the color information needed to map the bitmaps. If this
parameter is NULL, the function uses the default color map.
nMapSize
The number of color maps pointed to by lpColorMap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
By default, LoadMappedBitmap will map colors commonly used in button glyphs.
For information about creating a mapped bitmap, see the Windows function CreateMappedBitmap and the
COLORMAP structure in the Windows SDK.

CBitmap::LoadOEMBitmap
Loads a predefined bitmap used by Windows.

BOOL LoadOEMBitmap(UINT nIDBitmap);

Parameters
nIDBitmap
ID number of the predefined Windows bitmap. The possible values are listed below from WINDOWS.H:

OBM_BTNCORNERS OBM_OLD_RESTORE

OBM_BTSIZE OBM_OLD_RGARROW

OBM_CHECK OBM_OLD_UPARROW

OBM_CHECKBOXES OBM_OLD_ZOOM

OBM_CLOSE OBM_REDUCE

OBM_COMBO OBM_REDUCED

OBM_DNARROW OBM_RESTORE

OBM_DNARROWD OBM_RESTORED

OBM_DNARROWI OBM_RGARROW

OBM_LFARROW OBM_RGARROWD

OBM_LFARROWD OBM_RGARROWI

OBM_LFARROWI OBM_SIZE

OBM_MNARROW OBM_UPARROW

OBM_OLD_CLOSE OBM_UPARROWD

OBM_OLD_DNARROW OBM_UPARROW

OBM_OLD_LFARROW OBM_ZOOM

OBM_OLD_REDUCE OBM_ZOOMD
Return Value
Nonzero if successful; otherwise 0.
Remarks
Bitmap names that begin with OBM_OLD represent bitmaps used by Windows versions prior to 3.0.
Note that the constant OEMRESOURCE must be defined before including WINDOWS.H in order to use any of the
OBM_ constants.

CBitmap::operator HBITMAP
Use this operator to get the attached Windows GDI handle of the CBitmap object.

operator HBITMAP() const;

Return Value
If successful, a handle to the Windows GDI object represented by the CBitmap object; otherwise NULL.
Remarks
This operator is a casting operator, which supports direct use of an HBITMAP object.
For more information about using graphic objects, see Graphic Objects in the Windows SDK.

CBitmap::SetBitmapBits
Sets the bits of a bitmap to the bit values given by lpBits.

DWORD SetBitmapBits(
DWORD dwCount,
const void* lpBits);

Parameters
dwCount
Specifies the number of bytes pointed to by lpBits.
lpBits
Points to the BYTE array that contains the pixel values to be copied to the CBitmap object. In order for the bitmap
to be able to render its image correctly, the values should be formatted to conform to the height, width and color
depth values that were specified when the CBitmap instance was created. For more information, see
CBitmap::CreateBitmap.
Return Value
The number of bytes used in setting the bitmap bits; 0 if the function fails.

CBitmap::SetBitmapDimension
Assigns a width and height to a bitmap in 0.1-millimeter units.

CSize SetBitmapDimension(
int nWidth,
int nHeight);

Parameters
nWidth
Specifies the width of the bitmap (in 0.1-millimeter units).
nHeight
Specifies the height of the bitmap (in 0.1-millimeter units).
Return Value
The previous bitmap dimensions. Height is in the cy member variable of the CSize object, and width is in the
cx member variable.

Remarks
The GDI does not use these values except to return them when an application calls the GetBitmapDimension
member function.

See also
MFC Sample MDI
CGdiObject Class
Hierarchy Chart
CBitmapButton Class
4/21/2020 • 5 minutes to read • Edit Online

Creates pushbutton controls labeled with bitmapped images instead of text.

Syntax
class CBitmapButton : public CButton

Members
Public Constructors
NAME DESC RIP T IO N

CBitmapButton::CBitmapButton Constructs a CBitmapButton object.

Public Methods
NAME DESC RIP T IO N

CBitmapButton::AutoLoad Associates a button in a dialog box with an object of the


CBitmapButton class, loads the bitmap(s) by name, and
sizes the button to fit the bitmap.

CBitmapButton::LoadBitmaps Initializes the object by loading one or more named bitmap


resources from the application's resource file and attaching
the bitmaps to the object.

CBitmapButton::SizeToContent Sizes the button to accommodate the bitmap.

Remarks
CBitmapButton objects contain up to four bitmaps, which contain images for the different states a button can
assume: up (or normal), down (or selected), focused, and disabled. Only the first bitmap is required; the others are
optional.
Bitmap-button images include the border around the image as well as the image itself. The border typically plays
a part in showing the state of the button. For example, the bitmap for the focused state usually is like the one for
the up state but with a dashed rectangle inset from the border or a thick solid line at the border. The bitmap for
the disabled state usually resembles the one for the up state but has lower contrast (like a dimmed or grayed
menu selection).
These bitmaps can be of any size, but all are treated as if they were the same size as the bitmap for the up state.
Various applications demand different combinations of bitmap images:

UP DO W N F O C USED DISA B L ED A P P L IC AT IO N
UP DO W N F O C USED DISA B L ED A P P L IC AT IO N

× Bitmap

× × Button without
WS_TABSTOP style

× × × × Dialog button with all


states

× × × Dialog button with


WS_TABSTOP style

When creating a bitmap-button control, set the BS_OWNERDRAW style to specify that the button is owner-drawn.
This causes Windows to send the WM_MEASUREITEM and WM_DRAWITEM messages for the button; the
framework handles these messages and manages the appearance of the button for you.
To create a bitmap-button control in a window's client area
1. Create one to four bitmap images for the button.
2. Construct the CBitmapButton object.
3. Call the Create function to create the Windows button control and attach it to the CBitmapButton object.
4. Call the LoadBitmaps member function to load the bitmap resources after the bitmap button is
constructed.
To include a bitmap-button control in a dialog box
1. Create one to four bitmap images for the button.
2. Create a dialog template with an owner-draw button positioned where you want the bitmap button. The
size of the button in the template does not matter.
3. Set the button's caption to a value such as " MYIMAGE" and define a symbol for the button such as
IDC_MYIMAGE.
4. In your application's resource script, give each of the images created for the button an ID constructed by
appending one of the letters "U," "D," "F," or "X" (for up, down, focused, and disabled) to the string used for
the button caption in step 3. For the button caption " MYIMAGE," for example, the IDs would be "
MYIMAGEU," " MYIMAGED," " MYIMAGEF," and " MYIMAGEX." You must specify the ID of your bitmaps
within double quotes. Otherwise the resource editor will assign an integer to the resource and MFC will fail
when loading the image.
5. In your application's dialog class (derived from CDialog ), add a CBitmapButton member object.
6. In the CDialog object's OnInitDialog routine, call the CBitmapButton object's AutoLoad function, using as
parameters the button's control ID and the CDialog object's this pointer.

If you want to handle Windows notification messages, such as BN_CLICKED, sent by a bitmap-button control to its
parent (usually a class derived from CDialog ), add to the CDialog -derived object a message-map entry and
message-handler member function for each message. The notifications sent by a CBitmapButton object are the
same as those sent by a CButton object.
The class CToolBar takes a different approach to bitmap buttons.
For more information on CBitmapButton , see Controls.
Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CButton
CBitmapButton

Requirements
Header : afxext.h

CBitmapButton::AutoLoad
Associates a button in a dialog box with an object of the CBitmapButton class, loads the bitmap(s) by name, and
sizes the button to fit the bitmap.

BOOL AutoLoad(
UINT nID,
CWnd* pParent);

Parameters
nID
The button's control ID.
pParent
Pointer to the object that owns the button.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use the AutoLoad function to initialize an owner-draw button in a dialog box as a bitmap button. Instructions for
using this function are in the remarks for the CBitmapButton class.
Example

CBitmapButton myButton;

// Initialize the owner-drawn button with the id IDC_MYBUTTON as a bitmap


// button. This code is used in the OnInitDialog handler of my dialog.
myButton.AutoLoad(IDC_MYBUTTON, this);

CBitmapButton::CBitmapButton
Creates a CBitmapButton object.

CBitmapButton();

Remarks
After creating the C++ CBitmapButton object, call CButton::Create to create the Windows button control and
attach it to the CBitmapButton object.
Example

// Declare a bitmap button object on the stack.


CBitmapButton myButton;

// Declare a bitmap button object on the heap.


CBitmapButton *pmyButton = new CBitmapButton;

CBitmapButton::LoadBitmaps
Use this function when you want to load bitmap images identified by their resource names or ID numbers, or
when you cannot use the AutoLoad function because, for example, you are creating a bitmap button that is not
part of a dialog box.

BOOL LoadBitmaps(
LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceSel = NULL,
LPCTSTR lpszBitmapResourceFocus = NULL,
LPCTSTR lpszBitmapResourceDisabled = NULL);

BOOL LoadBitmaps(
UINT nIDBitmapResource,
UINT nIDBitmapResourceSel = 0,
UINT nIDBitmapResourceFocus = 0,
UINT nIDBitmapResourceDisabled = 0);

Parameters
lpszBitmapResource
Points to the null-terminated string that contains the name of the bitmap for a bitmap button's normal or "up"
state. Required.
lpszBitmapResourceSel
Points to the null-terminated string that contains the name of the bitmap for a bitmap button's selected or "down"
state. May be NULL.
lpszBitmapResourceFocus
Points to the null-terminated string that contains the name of the bitmap for a bitmap button's focused state. May
be NULL.
lpszBitmapResourceDisabled
Points to the null-terminated string that contains the name of the bitmap for a bitmap button's disabled state. May
be NULL.
nIDBitmapResource
Specifies the resource ID number of the bitmap resource for a bitmap button's normal or "up" state. Required.
nIDBitmapResourceSel
Specifies the resource ID number of the bitmap resource for a bitmap button's selected or "down" state. May be 0.
nIDBitmapResourceFocus
Specifies the resource ID number of the bitmap resource for a bitmap button's focused state. May be 0.
nIDBitmapResourceDisabled
Specifies the resource ID number of the bitmap resource for a bitmap button's disabled state. May be 0.
Return Value
Nonzero if successful; otherwise 0.
Example

// Create the bitmap button (must include the BS_OWNERDRAW style).


pmyButton->Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
CRect(10, 10, 100, 100), pParentWnd, 1);

// Load the bitmaps for this button.


pmyButton->LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUS, IDB_DISABLE);

CBitmapButton::SizeToContent
Call this function to resize a bitmap button to the size of the bitmap.

void SizeToContent();

Example

CBitmapButton *pmyButton = new CBitmapButton();

// Create the bitmap button (must include the BS_OWNERDRAW style).


pmyButton->Create(NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
CRect(10, 10, 100, 100), pParentWnd, 1);

// Load the bitmaps for this button.


pmyButton->LoadBitmaps(IDB_UP, IDB_DOWN, IDB_FOCUS, IDB_DISABLE);

// Resize the button to be the size of the bitmaps.


pmyButton->SizeToContent();

See also
MFC Sample CTRLTEST
CButton Class
Hierarchy Chart
CBitmapRenderTarget Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1BitmapRenderTarget.

Syntax
class CBitmapRenderTarget : public CRenderTarget;

Members
Public Constructors
NAME DESC RIP T IO N

CBitmapRenderTarget::CBitmapRenderTarget Constructs a CBitmapRenderTarget object.

Public Methods
NAME DESC RIP T IO N

CBitmapRenderTarget::Attach Attaches existing render target interface to the object

CBitmapRenderTarget::Detach Detaches render target interface from the object

CBitmapRenderTarget::GetBitmap Retrieves the bitmap for this render target. The returned
bitmap can be used for drawing operations.

CBitmapRenderTarget::GetBitmapRenderTarget Returns ID2D1BitmapRenderTarget interface

Public Operators
NAME DESC RIP T IO N

CBitmapRenderTarget::operator ID2D1BitmapRenderTarget* Returns ID2D1BitmapRenderTarget interface

Protected Data Members


NAME DESC RIP T IO N

CBitmapRenderTarget::m_pBitmapRenderTarget A pointer to an ID2D1BitmapRenderTarget object.

Inheritance Hierarchy
CObject
CRenderTarget
CBitmapRenderTarget
Requirements
Header : afxrendertarget.h

CBitmapRenderTarget::Attach
Attaches existing render target interface to the object

void Attach(ID2D1BitmapRenderTarget* pTarget);

Parameters
pTarget
Existing render target interface. Cannot be NULL

CBitmapRenderTarget::CBitmapRenderTarget
Constructs a CBitmapRenderTarget object.

CBitmapRenderTarget();

CBitmapRenderTarget::Detach
Detaches render target interface from the object

ID2D1BitmapRenderTarget* Detach();

Return Value
Pointer to detached render target interface.

CBitmapRenderTarget::GetBitmap
Retrieves the bitmap for this render target. The returned bitmap can be used for drawing operations.

BOOL GetBitmap(CD2DBitmap& bitmap);

Parameters
bitmap
When this method returns, contains the valid bitmap for this render target. This bitmap can be used for drawing
operations.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CBitmapRenderTarget::GetBitmapRenderTarget
Returns ID2D1BitmapRenderTarget interface

ID2D1BitmapRenderTarget* GetBitmapRenderTarget();

Return Value
Pointer to an ID2D1BitmapRenderTarget interface or NULL if object is not initialized yet.

CBitmapRenderTarget::m_pBitmapRenderTarget
A pointer to an ID2D1BitmapRenderTarget object.

ID2D1BitmapRenderTarget* m_pBitmapRenderTarget;

CBitmapRenderTarget::operator ID2D1BitmapRenderTarget*
Returns ID2D1BitmapRenderTarget interface

operator ID2D1BitmapRenderTarget*();

Return Value
Pointer to an ID2D1BitmapRenderTarget interface or NULL if object is not initialized yet.

See also
Classes
CBrush Class
3/27/2020 • 11 minutes to read • Edit Online

Encapsulates a Windows graphics device interface (GDI) brush.

Syntax
class CBrush : public CGdiObject

Members
Public Constructors
NAME DESC RIP T IO N

CBrush::CBrush Constructs a CBrush object.

Public Methods
NAME DESC RIP T IO N

CBrush::CreateBrushIndirect Initializes a brush with the style, color, and pattern specified in
a LOGBRUSH structure.

CBrush::CreateDIBPatternBrush Initializes a brush with a pattern specified by a device-


independent bitmap (DIB).

CBrush::CreateHatchBrush Initializes a brush with the specified hatched pattern and


color.

CBrush::CreatePatternBrush Initializes a brush with a pattern specified by a bitmap.

CBrush::CreateSolidBrush Initializes a brush with the specified solid color.

CBrush::CreateSysColorBrush Creates a brush that is the default system color.

CBrush::FromHandle Returns a pointer to a CBrush object when given a handle


to a Windows HBRUSH object.

CBrush::GetLogBrush Gets a LOGBRUSH structure.

Public Operators
NAME DESC RIP T IO N

CBrush::operator HBRUSH Returns the Windows handle attached to the CBrush object.

Remarks
To use a CBrush object, construct a CBrush object and pass it to any CDC member function that requires a brush.
Brushes can be solid, hatched, or patterned.
For more information on CBrush , see Graphic Objects.

Inheritance Hierarchy
CObject
CGdiObject
CBrush

Requirements
Header : afxwin.h

CBrush::CBrush
Constructs a CBrush object.

CBrush();
CBrush(COLORREF crColor);
CBrush(int nIndex, COLORREF crColor);
explicit CBrush(CBitmap* pBitmap);

Parameters
crColor
Specifies the foreground color of the brush as an RGB color. If the brush is hatched, this parameter specifies the
color of the hatching.
nIndex
Specifies the hatch style of the brush. It can be any one of the following values:
HS_BDIAGONAL Downward hatch (left to right) at 45 degrees
HS_CROSS Horizontal and vertical crosshatch
HS_DIAGCROSS Crosshatch at 45 degrees
HS_FDIAGONAL Upward hatch (left to right) at 45 degrees
HS_HORIZONTAL Horizontal hatch
HS_VERTICAL Vertical hatch
pBitmap
Points to a CBitmap object that specifies a bitmap with which the brush paints.
Remarks
CBrush has four overloaded constructors.The constructor with no arguments constructs an uninitialized CBrush
object that must be initialized before it can be used.
If you use the constructor with no arguments, you must initialize the resulting CBrush object with
CreateSolidBrush, CreateHatchBrush, CreateBrushIndirect, CreatePatternBrush, or CreateDIBPatternBrush. If you
use one of the constructors that takes arguments, then no further initialization is necessary. The constructors with
arguments can throw an exception if errors are encountered, while the constructor with no arguments will always
succeed.
The constructor with a single COLORREF parameter constructs a solid brush with the specified color. The color
specifies an RGB value and can be constructed with the RGB macro in WINDOWS.H.
The constructor with two parameters constructs a hatch brush. The nIndex parameter specifies the index of a
hatched pattern. The crColor parameter specifies the color.
The constructor with a CBitmap parameter constructs a patterned brush. The parameter identifies a bitmap. The
bitmap is assumed to have been created by using CBitmap::CreateBitmap, CBitmap::CreateBitmapIndirect,
CBitmap::LoadBitmap, or CBitmap::CreateCompatibleBitmap. The minimum size for a bitmap to be used in a fill
pattern is 8 pixels by 8 pixels.
Example
// CBrush::CBrush.
CBrush brush1; // Must initialize!
brush1.CreateSolidBrush(RGB(0, 0, 255)); // Blue brush.

CRect rc;
GetClientRect(&rc);
ScreenToClient(&rc);

// Save original brush.


CBrush *pOrigBrush = (CBrush *)pDC->SelectObject(&brush1);

// Paint upper left corner with blue brush.


pDC->Rectangle(0, 0, rc.Width() / 2, rc.Height() / 2);

// These constructors throw resource exceptions.


try
{
// CBrush::CBrush(COLORREF crColor)
CBrush brush2(RGB(255, 0, 0)); // Solid red brush.

// CBrush::CBrush(int nIndex, COLORREF crColor)


// Hatched green brush.
CBrush brush3(HS_DIAGCROSS, RGB(0, 255, 0));

// CBrush::CBrush(CBitmap* pBitmap)
CBitmap bmp;
// Load a resource bitmap.
bmp.LoadBitmap(IDB_BRUSH);
CBrush brush4(&bmp);

pDC->SelectObject(&brush2);

// Paint upper right corner with red brush.


pDC->Rectangle(rc.Width() / 2, 0, rc.Width(),
rc.Height() / 2);

pDC->SelectObject(&brush3);

// Paint lower left corner with green hatched brush.


pDC->Rectangle(0, rc.Height() / 2, rc.Width() / 2,
rc.Height());

pDC->SelectObject(&brush4);

// Paint lower right corner with resource brush.


pDC->Rectangle(rc.Width() / 2, rc.Height() / 2,
rc.Width(), rc.Height());
}
catch (CResourceException *e)
{
e->ReportError();
e->Delete();
}

// Reselect original brush into device context.


pDC->SelectObject(pOrigBrush);

CBrush::CreateBrushIndirect
Initializes a brush with a style, color, and pattern specified in a LOGBRUSH structure.

BOOL CreateBrushIndirect(const LOGBRUSH* lpLogBrush);


Parameters
lpLogBrush
Points to a LOGBRUSH structure that contains information about the brush.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The brush can subsequently be selected as the current brush for any device context.
A brush created using a monochrome (1 plane, 1 bit per pixel) bitmap is drawn using the current text and
background colors. Pixels represented by a bit set to 0 will be drawn with the current text color. Pixels represented
by a bit set to 1 will be drawn with the current background color.
Example

// Initialize a LOGBRUSH structure.


LOGBRUSH logBrush;
logBrush.lbStyle = BS_HATCHED;
logBrush.lbColor = RGB(0, 192, 192);
logBrush.lbHatch = HS_CROSS;

// Declare an uninitialized CBrush ...


CBrush brush;
// ... and initialize it with the LOGBRUSH.
brush.CreateBrushIndirect(&logBrush);

// Select the brush (and perhaps a pen) into


// the device context.
CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brush);
CPen *pOldPen = (CPen *)pDC->SelectStockObject(BLACK_PEN);

// Have fun!
pDC->Pie(CRect(100, 100, 300, 300), CPoint(0, 0), CPoint(50, 200));

// Restore the original device context objects.


pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);

CBrush::CreateDIBPatternBrush
Initializes a brush with the pattern specified by a device-independent bitmap (DIB).

BOOL CreateDIBPatternBrush(
HGLOBAL hPackedDIB,
UINT nUsage);

BOOL CreateDIBPatternBrush(
const void* lpPackedDIB,
UINT nUsage);

Parameters
hPackedDIB
Identifies a global-memory object containing a packed device-independent bitmap (DIB).
nUsage
Specifies whether the bmiColors[] fields of the BITMAPINFO data structure (a part of the "packed DIB") contain
explicit RGB values or indices into the currently realized logical palette. The parameter must be one of the
following values:
DIB_PAL_COLORS The color table consists of an array of 16-bit indexes.
DIB_RGB_COLORS The color table contains literal RGB values.
lpPackedDIB
Points to a packed DIB consisting of a BITMAPINFO structure immediately followed by an array of bytes defining
the pixels of the bitmap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The brush can subsequently be selected for any device context that supports raster operations.
The two versions differ in the way you handle the DIB:
In the first version, to obtain a handle to the DIB you call the Windows GlobalAlloc function to allocate a
block of global memory and then fill the memory with the packed DIB.
In the second version, it is not necessary to call GlobalAlloc to allocate memory for the packed DIB.

A packed DIB consists of a BITMAPINFO data structure immediately followed by the array of bytes that defines the
pixels of the bitmap. Bitmaps used as fill patterns should be 8 pixels by 8 pixels. If the bitmap is larger, Windows
creates a fill pattern using only the bits corresponding to the first 8 rows and 8 columns of pixels in the upper-left
corner of the bitmap.
When an application selects a two-color DIB pattern brush into a monochrome device context, Windows ignores
the colors specified in the DIB and instead displays the pattern brush using the current text and background
colors of the device context. Pixels mapped to the first color (at offset 0 in the DIB color table) of the DIB are
displayed using the text color. Pixels mapped to the second color (at offset 1 in the color table) are displayed using
the background color.
For information about using the following Windows functions, see the Windows SDK:
CreateDIBPatternBrush (This function is provided only for compatibility with applications written for
versions of Windows earlier than 3.0; use the CreateDIBPatternBrushPt function.)
CreateDIBPatternBrushPt (This function should be used for Win32-based applications.)
GlobalAlloc
Example
// Resource handle to bitmap.
HRSRC hRes;
// Global handles to bitmap resource.
HGLOBAL hData;
void *hLockedData;
CBrush brush;

// Find the resource handle.


hRes = ::FindResource(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDB_BRUSH), RT_BITMAP);
if (hRes != NULL)
{
// Lock and Load (or Load and Lock).
if (((hData = ::LoadResource(AfxGetResourceHandle(),
hRes)) != NULL) &&
((hLockedData = ::LockResource(hData)) != NULL))
{
// Initialize the brush.
brush.CreateDIBPatternBrush((const void *)hLockedData,
DIB_RGB_COLORS);

// Select the brush into the device context.


CBrush *pOldBrush = pDC->SelectObject(&brush);

// Draw.
pDC->Rectangle(50, 50, 200, 200);

// Restore the original device context.


pDC->SelectObject(pOldBrush);

// Free the resource.


::FreeResource(hLockedData);
}
}

CBrush::CreateHatchBrush
Initializes a brush with the specified hatched pattern and color.

BOOL CreateHatchBrush(
int nIndex,
COLORREF crColor);

Parameters
nIndex
Specifies the hatch style of the brush. It can be any one of the following values:
HS_BDIAGONAL Downward hatch (left to right) at 45 degrees
HS_CROSS Horizontal and vertical crosshatch
HS_DIAGCROSS Crosshatch at 45 degrees
HS_FDIAGONAL Upward hatch (left to right) at 45 degrees
HS_HORIZONTAL Horizontal hatch
HS_VERTICAL Vertical hatch
crColor
Specifies the foreground color of the brush as an RGB color (the color of the hatches). See COLORREF in the
Windows SDK for more information.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The brush can subsequently be selected as the current brush for any device context.
Example

CBrush brush;
brush.CreateHatchBrush(HS_BDIAGONAL, RGB(255, 0, 0));

CBrush *pOldBrush;
CPen *pOldPen;

pOldBrush = (CBrush *)pDC->SelectObject(&brush);


pOldPen = (CPen *)pDC->SelectStockObject(NULL_PEN);
pDC->Ellipse(CRect(50, 50, 250, 250));

pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);

CBrush::CreatePatternBrush
Initializes a brush with a pattern specified by a bitmap.

BOOL CreatePatternBrush(CBitmap* pBitmap);

Parameters
pBitmap
Identifies a bitmap.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The brush can subsequently be selected for any device context that supports raster operations. The bitmap
identified by pBitmap is typically initialized by using the CBitmap::CreateBitmap, CBitmap::CreateBitmapIndirect,
CBitmap::LoadBitmap, or CBitmap::CreateCompatibleBitmap function.
Bitmaps used as fill patterns should be 8 pixels by 8 pixels. If the bitmap is larger, Windows will only use the bits
corresponding to the first 8 rows and columns of pixels in the upper-left corner of the bitmap.
A pattern brush can be deleted without affecting the associated bitmap. This means the bitmap can be used to
create any number of pattern brushes.
A brush created using a monochrome bitmap (1 color plane, 1 bit per pixel) is drawn using the current text and
background colors. Pixels represented by a bit set to 0 are drawn with the current text color. Pixels represented by
a bit set to 1 are drawn with the current background color.
For information about using CreatePatternBrush, a Windows function, see the Windows SDK.
Example
// Create a hatched bit pattern.
WORD HatchBits[8] = {0x11, 0x22, 0x44, 0x88, 0x11,
0x22, 0x44, 0x88};

// Use the bit pattern to create a bitmap.


CBitmap bm;
bm.CreateBitmap(8, 8, 1, 1, HatchBits);

// Create a pattern brush from the bitmap.


CBrush brush;
brush.CreatePatternBrush(&bm);

// Select the brush into a device context, and draw.


CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brush);
pDC->RoundRect(CRect(50, 50, 200, 200), CPoint(10, 10));

// Restore the original brush.


pDC->SelectObject(pOldBrush);

CBrush::CreateSolidBrush
Initializes a brush with a specified solid color.

BOOL CreateSolidBrush(COLORREF crColor);

Parameters
crColor
A COLORREF structure that specifies the color of the brush. The color specifies an RGB value and can be
constructed with the RGB macro in WINDOWS.H.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The brush can subsequently be selected as the current brush for any device context.
When an application has finished using the brush created by CreateSolidBrush , it should select the brush out of
the device context.
Example
See the example for CBrush::CBrush.

CBrush::CreateSysColorBrush
Initializes a brush color.

BOOL CreateSysColorBrush(int nIndex);

Parameters
nIndex
Specifies a color index. This value corresponds to the color used to paint one of the 21 window elements. See
GetSysColor in the Windows SDK for a list of values.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The brush can subsequently be selected as the current brush for any device context.
When an application has finished using the brush created by CreateSysColorBrush , it should select the brush out
of the device context.
Example

// Declare a CBrush and initialize to a system color.


CBrush brush;
brush.CreateSysColorBrush(COLOR_BTNFACE);

// Select the brush into the device context.


CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brush);

// Draw.
CRect rect(50, 50, 150, 150);
pDC->Rectangle(rect);

// Reselect the original brush.


pDC->SelectObject(pOldBrush);

CBrush::FromHandle
Returns a pointer to a CBrush object when given a handle to a Windows HBRUSH object.

static CBrush* PASCAL FromHandle(HBRUSH hBrush);

Parameters
hBrush
HANDLE to a Windows GDI brush.
Return Value
A pointer to a CBrush object if successful; otherwise NULL.
Remarks
If a CBrush object is not already attached to the handle, a temporary CBrush object is created and attached. This
temporary CBrush object is valid only until the next time the application has idle time in its event loop. At this
time, all temporary graphic objects are deleted. In other words, the temporary object is valid only during the
processing of one window message.
For more information about using graphic objects, see Graphic Objects in the Windows SDK.
Example
See the example for CBrush::CBrush.

CBrush::GetLogBrush
Call this member function to retrieve the LOGBRUSH structure.

int GetLogBrush(LOGBRUSH* pLogBrush);

Parameters
pLogBrush
Points to a LOGBRUSH structure that contains information about the brush.
Return Value
If the function succeeds, and pLogBrush is a valid pointer, the return value is the number of bytes stored into the
buffer.
If the function succeeds, and pLogBrush is NULL, the return value is the number of bytes required to hold the
information the function would store into the buffer.
If the function fails, the return value is 0.
Remarks
The LOGBRUSH structure defines the style, color, and pattern of a brush.
For example, call GetLogBrush to match the particular color or pattern of a bitmap.
Example

// Example for CBrush::GetLogBrush


LOGBRUSH logbrush;
brushExisting.GetLogBrush(&logbrush);
CBrush brushOther(logbrush.lbColor);

// Another example
// Declare a LOGBRUSH
LOGBRUSH logBrush;

// Using a bitmap for this example.


// The bitmap should be a project resource.
CBitmap bm;
bm.LoadBitmap(IDB_BRUSH);

try
{
// Create a brush
CBrush brush1(&bm);

// Use GetLogBrush to fill the LOGBRUSH structure


brush1.GetLogBrush(&logBrush);

// Create a second brush using the LOGBRUSH data


CBrush brush2;
brush2.CreateBrushIndirect(&logBrush);

// Use the first brush


CBrush *pOldBrush = (CBrush *)pDC->SelectObject(&brush1);
pDC->Rectangle(CRect(50, 50, 150, 150));

// The second brush has the specified characteristics


// of the first brush
pDC->SelectObject(&brush2);
pDC->Ellipse(200, 50, 300, 150);

// Reselect the original brush


pDC->SelectObject(pOldBrush);
}
catch (CResourceException *e)
{
e->ReportError();
e->Delete();
}

CBrush::operator HBRUSH
Use this operator to get the attached Windows GDI handle of the CBrush object.
operator HBRUSH() const;

Return Value
If successful, a handle to the Windows GDI object represented by the CBrush object; otherwise NULL.
Remarks
This operator is a casting operator, which supports direct use of an HBRUSH object.
For more information about using graphic objects, see Graphic Objects in the Windows SDK.
Example

RECT rc = {50, 50, 200, 200};

Rectangle(pDC->GetSafeHdc(), rc.left, rc.top, rc.right, rc.bottom);

// The Win32 call to FillRect requires an HBRUSH.


// The HBRUSH operator casts the CBrush object
// to the required type.
CBrush brush;
brush.CreateSysColorBrush(COLOR_BTNFACE);
FillRect(pDC->GetSafeHdc(), &rc, (HBRUSH)brush);

See also
MFC Sample PROPDLG
CGdiObject Class
Hierarchy Chart
CBitmap Class
CDC Class
CButton Class
4/21/2020 • 26 minutes to read • Edit Online

Provides the functionality of Windows button controls.

Syntax
class CButton : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CButton::CButton Constructs a CButton object.

Public Methods
NAME DESC RIP T IO N

CButton::Create Creates the Windows button control and attaches it to the


CButton object.

CButton::DrawItem Override to draw an owner-drawn CButton object.

CButton::GetBitmap Retrieves the handle of the bitmap previously set with


SetBitmap.

CButton::GetButtonStyle Retrieves information about the button control style.

CButton::GetCheck Retrieves the check state of a button control.

CButton::GetCursor Retrieves the handle of the cursor image previously set with
SetCursor.

CButton::GetIcon Retrieves the handle of the icon previously set with SetIcon.

CButton::GetIdealSize Retrieves the ideal size of the button control.

CButton::GetImageList Retrieves the image list of the button control.

CButton::GetNote Retrieves the note component of the current command link


control.

CButton::GetNoteLength Retrieves the length of the note text for the current
command link control.
NAME DESC RIP T IO N

CButton::GetSplitGlyph Retrieves the glyph associated with the current split button
control.

CButton::GetSplitImageList Retrieves the image list for the current split button control.

CButton::GetSplitInfo Retrieves information that defines the current split button


control.

CButton::GetSplitSize Retrieves the bounding rectangle of the drop-down


component of the current split button control.

CButton::GetSplitStyle Retrieves the split button styles that define the current split
button control.

CButton::GetState Retrieves the check state, highlight state, and focus state of
a button control.

CButton::GetTextMargin Retrieves the text margin of the button control.

CButton::SetBitmap Specifies a bitmap to be displayed on the button.

CButton::SetButtonStyle Changes the style of a button.

CButton::SetCheck Sets the check state of a button control.

CButton::SetCursor Specifies a cursor image to be displayed on the button.

CButton::SetDropDownState Sets the drop-down state of the current split button


control.

CButton::SetIcon Specifies an icon to be displayed on the button.

CButton::SetImageList Sets the image list of the button control.

CButton::SetNote Sets the note on the current command link control.

CButton::SetSplitGlyph Associates a specified glyph with the current split button


control.

CButton::SetSplitImageList Associates an image list with the current split button


control.

CButton::SetSplitInfo Specifies information that defines the current split button


control.

CButton::SetSplitSize Sets the bounding rectangle of the drop-down component


of the current split button control.

CButton::SetSplitStyle Sets the style of the current split button control.

CButton::SetState Sets the highlighting state of a button control.


NAME DESC RIP T IO N

CButton::SetTextMargin Sets the text margin of the button control.

Remarks
A button control is a small, rectangular child window that can be clicked on and off. Buttons can be used alone
or in groups and can either be labeled or appear without text. A button typically changes appearance when the
user clicks it.
Typical buttons are the check box, radio button, and pushbutton. A CButton object can become any of these,
according to the button style specified at its initialization by the Create member function.
In addition, the CBitmapButton class derived from CButton supports creation of button controls labeled with
bitmap images instead of text. A CBitmapButton can have separate bitmaps for a button's up, down, focused,
and disabled states.
You can create a button control either from a dialog template or directly in your code. In both cases, first call
the constructor CButton to construct the CButton object; then call the Create member function to create the
Windows button control and attach it to the CButton object.
Construction can be a one-step process in a class derived from CButton . Write a constructor for the derived
class and call Create from within the constructor.
If you want to handle Windows notification messages sent by a button control to its parent (usually a class
derived from CDialog), add a message-map entry and message-handler member function to the parent class
for each message.
Each message-map entry takes the following form:
ON_ Notification ( id, memberFxn )
where id specifies the child window ID of the control sending the notification and memberFxn is the name of
the parent member function you have written to handle the notification.
The parent's function prototype is as follows:
afx_msg void memberFxn();

Potential message-map entries are as follows:

M A P EN T RY SEN T TO PA REN T W H EN . . .

ON_BN_CLICKED The user clicks a button.

ON_BN_DOUBLECLICKED The user double-clicks a button.

If you create a CButton object from a dialog resource, the CButton object is automatically destroyed when the
user closes the dialog box.
If you create a CButton object within a window, you may need to destroy it. If you create the CButton object
on the heap by using the new function, you must call delete on the object to destroy it when the user closes
the Windows button control. If you create the CButton object on the stack, or it is embedded in the parent
dialog object, it is destroyed automatically.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CButton

Requirements
Header : afxwin.h

CButton::CButton
Constructs a CButton object.

CButton();

Example

// Declare a button object.


CButton myButton;

CButton::Create
Creates the Windows button control and attaches it to the CButton object.

virtual BOOL Create(


LPCTSTR lpszCaption,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
lpszCaption
Specifies the button control's text.
dwStyle
Specifies the button control's style. Apply any combination of button styles to the button.
rect
Specifies the button control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the button control's parent window, usually a CDialog . It must not be NULL.
nID
Specifies the button control's ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You construct a CButton object in two steps. First, call the constructor and then call Create , which creates the
Windows button control and attaches it to the CButton object.
If the WS_VISIBLE style is given, Windows sends the button control all the messages required to activate and
show the button.
Apply the following window styles to a button control:
WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
WS_GROUP To group controls
WS_TABSTOP To include the button in the tabbing order
Example

CButton myButton1, myButton2, myButton3, myButton4;

// Create a push button.


myButton1.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Create a radio button.


myButton2.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(10, 40, 100, 70), pParentWnd, 2);

// Create an auto 3-state button.


myButton3.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,
CRect(10, 70, 100, 100), pParentWnd, 3);

// Create an auto check box.


myButton4.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
CRect(10, 100, 100, 130), pParentWnd, 4);

CButton::DrawItem
Called by the framework when a visual aspect of an owner-drawn button has changed.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A long pointer to a DRAWITEMSTRUCT structure. The structure contains information about the item to be
drawn and the type of drawing required.
Remarks
An owner-drawn button has the BS_OWNERDRAW style set. Override this member function to implement
drawing for an owner-drawn CButton object. The application should restore all graphics device interface (GDI)
objects selected for the display context supplied in lpDrawItemStruct before the member function terminates.
Also see the BS_ style values.
Example
// NOTE: CMyButton is a class derived from CButton. The CMyButton
// object was created as follows:
//
// CMyButton myButton;
// myButton.Create(_T("My button"),
// WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|BS_OWNERDRAW,
// CRect(10,10,100,30), pParentWnd, 1);
//

// This example implements the DrawItem method for a CButton-derived


// class that draws the button's text using the color red.
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
UINT uStyle = DFCS_BUTTONPUSH;

// This code only works with buttons.


ASSERT(lpDrawItemStruct->CtlType == ODT_BUTTON);

// If drawing selected, add the pushed style to DrawFrameControl.


if (lpDrawItemStruct->itemState & ODS_SELECTED)
uStyle |= DFCS_PUSHED;

// Draw the button frame.


::DrawFrameControl(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem,
DFC_BUTTON, uStyle);

// Get the button's text.


CString strText;
GetWindowText(strText);

// Draw the button text using the text color red.


COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC, RGB(255, 0, 0));
::DrawText(lpDrawItemStruct->hDC, strText, strText.GetLength(),
&lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
::SetTextColor(lpDrawItemStruct->hDC, crOldColor);
}

CButton::GetBitmap
Call this member function to get the handle of a bitmap, previously set with SetBitmap, that is associated with
a button.

HBITMAP GetBitmap() const;

Return Value
A handle to a bitmap. NULL if no bitmap is previously specified.
Example

CButton myBitmapButton;

// Create a bitmap button.


myBitmapButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_BITMAP,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no bitmap is defined for the button, define the bitmap to the


// system close bitmap.
if (myBitmapButton.GetBitmap() == NULL)
myBitmapButton.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CLOSE)));
CButton::GetButtonStyle
Retrieves information about the button control style.

UINT GetButtonStyle() const;

Return Value
Returns the button styles for this CButton object. This function returns only the BS_ style values, not any of the
other window styles.
Example

CButton myRadioButton;

// Create a radio button.


myRadioButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Change the button style to use one of the "auto" styles; for
// push button, change to def push button.
UINT uStyle = myRadioButton.GetButtonStyle();
if (uStyle == BS_PUSHBUTTON)
uStyle = BS_DEFPUSHBUTTON;
else if (uStyle == BS_RADIOBUTTON)
uStyle = BS_AUTORADIOBUTTON;
else if (uStyle == BS_CHECKBOX)
uStyle = BS_AUTOCHECKBOX;
else if (uStyle == BS_3STATE)
uStyle = BS_AUTO3STATE;

// Change the button style to the one wanted.


myRadioButton.SetButtonStyle(uStyle);

CButton::GetCheck
Retrieves the check state of a radio button or check box.

int GetCheck() const;

Return Value
The return value from a button control created with the BS_AUTOCHECKBOX, BS_AUTORADIOBUTTON,
BS_AUTO3STATE, BS_CHECKBOX, BS_RADIOBUTTON, or BS_3STATE style is one of the following values:

VA L UE M EA N IN G

BST_UNCHECKED Button state is unchecked.

BST_CHECKED Button state is checked.

BST_INDETERMINATE Button state is indeterminate (applies only if the button has


the BS_3STATE or BS_AUTO3STATE style).

If the button has any other style, the return value is BST_UNCHECKED.
Example
CButton myA3Button;

// Create an auto 3-state button.


myA3Button.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Set the check state to the next state


// (i.e. BST_UNCHECKED changes to BST_CHECKED
// BST_CHECKED changes to BST_INDETERMINATE
// BST_INDETERMINATE changes to BST_UNCHECKED).
myA3Button.SetCheck(((myA3Button.GetCheck() + 1) % 3));

CButton::GetCursor
Call this member function to get the handle of a cursor, previously set with SetCursor, that is associated with a
button.

HCURSOR GetCursor();

Return Value
A handle to a cursor image. NULL if no cursor is previously specified.
Example

CButton myIconButton;

// Create an icon button.


myIconButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_ICON,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no image is defined for the button, define the image to the


// system arrow and question mark cursor.
if (myIconButton.GetCursor() == NULL)
myIconButton.SetCursor(::LoadCursor(NULL, IDC_HELP));

CButton::GetIcon
Call this member function to get the handle of an icon, previously set with SetIcon, that is associated with a
button.

HICON GetIcon() const;

Return Value
A handle to an icon. NULL if no icon is previously specified.
Example
CButton myIconButton2;

// Create an icon button.


myIconButton2.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_ICON,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no icon is defined for the button, define the icon to the


// system error icon.
if (myIconButton2.GetIcon() == NULL)
myIconButton2.SetIcon(::LoadIcon(NULL, IDI_ERROR));

CButton::GetIdealSize
Retrieves the ideal size for the button control.

BOOL GetIdealSize(SIZE* psize);

Parameters
psize
A pointer to the current size of the button.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function emulates the functionality of the BCM_GETIDEALSIZE message, as described in the
Buttons section of the Windows SDK.

CButton::GetImageList
Call this method to get the image list from the button control.

BOOL GetImageList(PBUTTON_IMAGELIST pbuttonImagelist);

Parameters
pbuttonImagelist
A pointer to the image list of the CButton object.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function emulates the functionality of the BCM_GETIMAGELIST message, as described in the
Buttons section of the Windows SDK.

CButton::GetNote
Retrieves the note text associated with the current command link control.
CString GetNote() const;

BOOL GetNote(
LPTSTR lpszNote,
UINT* cchNote) const;

Parameters
PA RA M ET ER DESC RIP T IO N

lpszNote [out] Pointer to a buffer, which the caller is responsible for


allocating and deallocating. If the return value is TRUE, the
buffer contains the note text that is associated with the
current command link control; otherwise, the buffer is
unchanged.

cchNote [in, out] A pointer to an unsigned integer variable.

When this method is called, the variable contains the size of


the buffer specified by the lpszNote parameter.

When this method returns, if the return value is TRUE the


variable contains the size of the note associated with the
current command link control. If the return value is FALSE,
the variable contains the buffer size required to contain the
note.

Return Value
In the first overload, a CString object that contains the note text associated with the current command link
control.
-or-
In the second overload, TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_COMMANDLINK or BS_DEFCOMMANDLINK.
This method sends the BCM_GETNOTE message, which is described in the Windows SDK.

CButton::GetNoteLength
Retrieves the length of the note text for the current command link control.

UINT GetNoteLength() const;

Return Value
The length of the note text, in 16-bit Unicode characters, for the current command link control.
Remarks
Use this method only with controls whose button style is BS_COMMANDLINK or BS_DEFCOMMANDLINK.
This method sends the BCM_GETNOTELENGTH message, which is described in the Windows SDK.

CButton::GetSplitGlyph
Retrieves the glyph associated with the current split button control.
TCHAR GetSplitGlyph() const;

Return Value
The glyph character associated with the current split button control.
Remarks
A glyph is the physical representation of a character in a particular font. For example, a split button control
might be decorated with the glyph of the Unicode check mark character (U+2713).
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_GLYPH flag, and
then sends that structure in the BCM_GETSPLITINFO message that is described in the Windows SDK. When the
message function returns, this method retrieves the glyph from the himlGlyph member of the structure.

CButton::GetSplitImageList
Retrieves the image list for the current split button control.

CImageList* GetSplitImageList() const;

Return Value
A pointer to a CImageList object.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_IMAGE flag, and
then sends that structure in the BCM_GETSPLITINFO message that is described in the Windows SDK. When the
message function returns, this method retrieves the image list from the himlGlyph member of the structure.

CButton::GetSplitInfo
Retrieves parameters that determine how Windows draws the current split button control.

BOOL GetSplitInfo(PBUTTON_SPLITINFO pInfo) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pInfo [out] Pointer to a BUTTON_SPLITINFO structure that


receives information about the current split button control.
The caller is responsible for allocating the structure.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
This method sends the BCM_GETSPLITINFO message, which is described in the Windows SDK.
CButton::GetSplitSize
Retrieves the bounding rectangle of the drop-down component of the current split button control.

BOOL GetSplitSize(LPSIZE pSize) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pSize [out] Pointer to a SIZE structure that receives the


description of a rectangle.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
When the split button control is expanded, it can display a drop-down component such as a list control or
pager control. This method retrieves the bounding rectangle that contains the drop-down component.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_SIZE flag, and
then sends that structure in the BCM_GETSPLITINFO message that is described in the Windows SDK. When the
message function returns, this method retrieves the bounding rectangle from the size member of the
structure.

CButton::GetSplitStyle
Retrieves the split button styles that define the current split button control.

UINT GetSplitStyle() const;

Return Value
A bitwise combination of split button styles. For more information, see the uSplitStyle member of the
BUTTON_SPLITINFO structure.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
The split button styles specify the alignment, aspect ratio, and graphical format with which Windows draws a
split button icon.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_STYLE flag, and
then sends that structure in the BCM_GETSPLITINFO message that is described in the Windows SDK. When the
message function returns, this method retrieves the split button styles from the uSplitStyle member of the
structure.

CButton::GetState
Retrieves the state of a button control.

UINT GetState() const;


Return Value
A bit field that contains the combination of values that indicate the current state of a button control. The
following table lists possible values.

B UT TO N STAT E VA L UE DESC RIP T IO N

BST_UNCHECKED 0x0000 The initial state.

BST_CHECKED 0x0001 The button control is checked.

BST_INDETERMINATE 0x0002 The state is indeterminate (only


possible when the button control has
three states).

BST_PUSHED 0x0004 The button control is pressed.

BST_FOCUS 0x0008 The button control has the focus.

Remarks
A button control with the BS_3STATE or BS_AUTO3STATE button style creates a check box that has a third state
that is named the indeterminate state. The indeterminate state indicates that the check box is neither checked
nor unchecked.
Example

CButton myPushButton;

// Create a push button.


myPushButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Invert the highlight state of the button.


myPushButton.SetState(!(myPushButton.GetState() & 0x0004));

CButton::GetTextMargin
Call this method to get the text margin of the CButton object.

BOOL GetTextMargin(RECT* pmargin);

Parameters
pmargin
A pointer to the text margin of the CButton object.
Return Value
Returns the text margin.
Remarks
Nonzero if successful; otherwise 0.
Remarks
This member function emulates the functionality of the BCM_GETTEXTMARGIN message, as described in the
Buttons section of the Windows SDK.
CButton::SetBitmap
Call this member function to associate a new bitmap with the button.

HBITMAP SetBitmap(HBITMAP hBitmap);

Parameters
hBitmap
The handle of a bitmap.
Return Value
The handle of a bitmap previously associated with the button.
Remarks
The bitmap will be automatically placed on the face of the button, centered by default. If the bitmap is too large
for the button, it will be clipped on either side. You can choose other alignment options, including the
following:
BS_TOP
BS_LEFT
BS_RIGHT
BS_CENTER
BS_BOTTOM
BS_VCENTER
Unlike CBitmapButton, which uses four bitmaps per button, SetBitmap uses only one bitmap per the button.
When the button is pressed, the bitmap appears to shift down and to the right.
You are responsible for releasing the bitmap when you are done with it.
Example

CButton myBitmapButton;

// Create a bitmap button.


myBitmapButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_BITMAP,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no bitmap is defined for the button, define the bitmap to the


// system close bitmap.
if (myBitmapButton.GetBitmap() == NULL)
myBitmapButton.SetBitmap(::LoadBitmap(NULL, MAKEINTRESOURCE(OBM_CLOSE)));

CButton::SetButtonStyle
Changes the style of a button.

void SetButtonStyle(
UINT nStyle,
BOOL bRedraw = TRUE);

Parameters
nStyle
Specifies the button style.
bRedraw
Specifies whether the button is to be redrawn. A nonzero value redraws the button. A 0 value does not redraw
the button. The button is redrawn by default.
Remarks
Use the GetButtonStyle member function to retrieve the button style. The low-order word of the complete
button style is the button-specific style.
Example

CButton myRadioButton;

// Create a radio button.


myRadioButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Change the button style to use one of the "auto" styles; for
// push button, change to def push button.
UINT uStyle = myRadioButton.GetButtonStyle();
if (uStyle == BS_PUSHBUTTON)
uStyle = BS_DEFPUSHBUTTON;
else if (uStyle == BS_RADIOBUTTON)
uStyle = BS_AUTORADIOBUTTON;
else if (uStyle == BS_CHECKBOX)
uStyle = BS_AUTOCHECKBOX;
else if (uStyle == BS_3STATE)
uStyle = BS_AUTO3STATE;

// Change the button style to the one wanted.


myRadioButton.SetButtonStyle(uStyle);

CButton::SetCheck
Sets or resets the check state of a radio button or check box.

void SetCheck(int nCheck);

Parameters
nCheck
Specifies the check state. This parameter can be one of the following:

VA L UE M EA N IN G

BST_UNCHECKED Set the button state to unchecked.

BST_CHECKED Set the button state to checked.

BST_INDETERMINATE Set the button state to indeterminate. This value can be


used only if the button has the BS_3STATE or
BS_AUTO3STATE style.

Remarks
This member function has no effect on a pushbutton.
Example

CButton myA3Button;

// Create an auto 3-state button.


myA3Button.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_AUTO3STATE,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Set the check state to the next state


// (i.e. BST_UNCHECKED changes to BST_CHECKED
// BST_CHECKED changes to BST_INDETERMINATE
// BST_INDETERMINATE changes to BST_UNCHECKED).
myA3Button.SetCheck(((myA3Button.GetCheck() + 1) % 3));

CButton::SetCursor
Call this member function to associate a new cursor with the button.

HCURSOR SetCursor(HCURSOR hCursor);

Parameters
hCursor
The handle of a cursor.
Return Value
The handle of a cursor previously associated with the button.
Remarks
The cursor will be automatically placed on the face of the button, centered by default. If the cursor is too large
for the button, it will be clipped on either side. You can choose other alignment options, including the
following:
BS_TOP
BS_LEFT
BS_RIGHT
BS_CENTER
BS_BOTTOM
BS_VCENTER
Unlike CBitmapButton, which uses four bitmaps per button, SetCursor uses only one cursor per the button.
When the button is pressed, the cursor appears to shift down and to the right.
Example
CButton myIconButton;

// Create an icon button.


myIconButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_ICON,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no image is defined for the button, define the image to the


// system arrow and question mark cursor.
if (myIconButton.GetCursor() == NULL)
myIconButton.SetCursor(::LoadCursor(NULL, IDC_HELP));

CButton::SetDropDownState
Sets the drop-down state of the current split button control.

BOOL SetDropDownState(BOOL fDropDown);

Parameters
PA RA M ET ER DESC RIP T IO N

fDropDown [in] TRUE to set BST_DROPDOWNPUSHED state; otherwise,


FALSE.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
A split button control has a style of BS_SPLITBUTTON or BS_DEFSPLITBUTTON and consists of a button and a
drop-down arrow to its right. For more information, see Button Styles. Usually, the drop-down state is set
when the user clicks the drop-down arrow. Use this method to programmatically set the drop-down state of
the control. The drop-down arrow is drawn shaded to indicate the state.
This method sends the BCM_SETDROPDOWNSTATE message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_splitButton, that is used to programmatically access the
split button control. This variable is used in the following example.

public:
// Variable to access programatically defined command link control.
CButton m_cmdLink;
// Variable to access programatically defined split button control.
CButton m_splitButton;

Example
The following code example sets the state of the split button control to indicate that the drop-down arrow is
pushed.

/* Set the state of the split button control to indicate that


the drop-down arrow is pushed. The arrow is drawn shaded to
indicate the state.
*/
m_splitButton.SetDropDownState(TRUE);
CButton::SetElevationRequired
Sets the state of the current button control to elevation required , which is necessary for the control to display
an elevated security icon.

BOOL SetElevationRequired(BOOL fElevationRequired);

Parameters
PA RA M ET ER DESC RIP T IO N

fElevationRequired [in] TRUE to set elevation required state; otherwise,


FALSE.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
If a button or command link control requires elevated security permission to perform an action, set the control
to elevation required state. Subsequently, Windows displays the User Account Control (UAC) shield icon on
the control. For more information, see "User Account Control" at MSDN.
This method sends the BCM_SETSHIELD message, which is described in the Windows SDK.

CButton::SetIcon
Call this member function to associate a new icon with the button.

HICON SetIcon(HICON hIcon);

Parameters
hIcon
The handle of an icon.
Return Value
The handle of an icon previously associated with the button.
Remarks
The icon will be automatically placed on the face of the button, centered by default. If the icon is too large for
the button, it will be clipped on either side. You can choose other alignment options, including the following:
BS_TOP
BS_LEFT
BS_RIGHT
BS_CENTER
BS_BOTTOM
BS_VCENTER
Unlike CBitmapButton, which uses four bitmaps per button, SetIcon uses only one icon per the button. When
the button is pressed, the icon appears to shift down and to the right.
Example

CButton myIconButton2;

// Create an icon button.


myIconButton2.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_ICON,
CRect(10, 10, 60, 50), pParentWnd, 1);

// If no icon is defined for the button, define the icon to the


// system error icon.
if (myIconButton2.GetIcon() == NULL)
myIconButton2.SetIcon(::LoadIcon(NULL, IDI_ERROR));

CButton::SetImageList
Call this method to set the image list of the CButton object.

BOOL SetImageList(PBUTTON_IMAGELIST pbuttonImagelist);

Parameters
pbuttonImagelist
A pointer to the new image list.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the BCM_SETIMAGELIST message, as described in the
Buttons section of the Windows SDK.

CButton::SetNote
Sets the note text for the current command link control.

BOOL SetNote(LPCTSTR lpszNote);

Parameters
PA RA M ET ER DESC RIP T IO N

lpszNote [in] Pointer to a Unicode string that is set as the note text
for the command link control.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_COMMANDLINK or BS_DEFCOMMANDLINK.
This method sends the BCM_SETNOTE message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_cmdLink, that is used to programmatically access the
command link control. This variable is used in the following example.
public:
// Variable to access programatically defined command link control.
CButton m_cmdLink;
// Variable to access programatically defined split button control.
CButton m_splitButton;

Example
The following code example sets the note text for the command link control.

// Set the command link text.


m_cmdLink.SetNote(_T("This is the command link note."));

CButton::SetSplitGlyph
Associates a specified glyph with the current split button control.

BOOL SetSplitGlyph(TCHAR chGlyph);

Parameters
PA RA M ET ER DESC RIP T IO N

chGlyph [in] A character that specifies the glyph to use as the split
button drop-down arrow.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls that have the button style BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
A glyph is the physical representation of a character in a particular font. The chGlyph parameter is not used as
the glyph, but is instead used to select a glyph from a set of system-defined glyphs. The default drop-down
arrow glyph is specified by a character '6', and resembles the Unicode character BLACK DOWN-POINTING
TRIANGLE (U+25BC).
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_GLYPH flag and
the himlGlyph member with the chGlyph parameter, and then sends that structure in the BCM_GETSPLITINFO
message that is described in the Windows SDK.

CButton::SetSplitImageList
Associates an image list with the current split button control.

BOOL SetSplitImageList(CImageList* pSplitImageList);

Parameters
PA RA M ET ER DESC RIP T IO N

pSplitImageList [in] Pointer to a CImageList object to assign to the current


split button control.
Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_IMAGE flag and
the himlGlyph member with the pSplitImageList parameter, and then sends that structure in the
BCM_GETSPLITINFO message that is described in the Windows SDK.

CButton::SetSplitInfo
Specifies parameters that determine how Windows draws the current split button control.

BOOL SetSplitInfo(PBUTTON_SPLITINFO pInfo);

Parameters
PA RA M ET ER DESC RIP T IO N

pInfo [in] Pointer to a BUTTON_SPLITINFO structure that defines


the current split button control.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
This method sends the BCM_SETSPLITINFO message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_splitButton , that is used to programmatically access the
split button control.

public:
// Variable to access programatically defined command link control.
CButton m_cmdLink;
// Variable to access programatically defined split button control.
CButton m_splitButton;

Example
The following code example changes the glyph that is used for the split button drop-down arrow. The example
substitutes an up-pointing triangle glyph for the default down-pointing triangle glyph. The glyph that is
displayed depends on the character that you specify in the himlGlyph member of the BUTTON_SPLITINFO
structure. The down-pointing triangle glyph is specified by a character '6' and the up-pointing triangle glyph is
specified by a character '5'. For comparison, see the convenience method, CButton::SetSplitGlyph.
/*
The drop-down arrow glyph is a function of the specified character.
The default "down" drop-down arrow glyph is specified by a
character '6'. Set the "up" arrow glyph, which is a character '5'.
See the convenience method, SetSplitGlyph(), for comparison.
*/
BUTTON_SPLITINFO bsInfo = {0};
bsInfo.mask = BCSIF_GLYPH;
TCHAR chGlyph = _T('5'); // "up" arrow glyph
bsInfo.himlGlyph = (HIMAGELIST)chGlyph;
bRC = m_splitButton.SetSplitInfo(&bsInfo);

CButton::SetSplitSize
Sets the bounding rectangle of the drop-down component of the current split button control.

BOOL SetSplitSize(LPSIZE pSize);

Parameters
PA RA M ET ER DESC RIP T IO N

pSize [in] Pointer to a SIZE structure that describes a bounding


rectangle.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
When the split button control is expanded, it can display a drop-down component such as a list control or
pager control. This method specifies the size of the bounding rectangle that contains the drop-down
component.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_SIZE flag and the
size member with the pSize parameter, and then sends that structure in the BCM_GETSPLITINFO message
that is described in the Windows SDK.
Example
The following code example defines the variable, m_splitButton , that is used to programmatically access the
split button control. This variable is used in the following example.

public:
// Variable to access programatically defined command link control.
CButton m_cmdLink;
// Variable to access programatically defined split button control.
CButton m_splitButton;

Example
The following code example doubles the size of the split button drop-down arrow.
// Double the size of the split button drop-down arrow.
SIZE sz;
bRC = m_splitButton.GetSplitSize(&sz); // current size
sz.cx = sz.cx * 2;
sz.cy = sz.cy * 2;
bRC = m_splitButton.SetSplitSize(&sz);

CButton::SetSplitStyle
Sets the style of the current split button control.

BOOL SetSplitStyle(UINT uSplitStyle);

Parameters
PA RA M ET ER DESC RIP T IO N

uSplitStyle [in] A bitwise combination of split button styles. For more


information, see the uSplitStyle member of the
BUTTON_SPLITINFO structure.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
Use this method only with controls whose button style is BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
The split button styles specify the alignment, aspect ratio, and graphical format with which Windows draws a
split button icon. For more information, see the uSplitStyle member of the BUTTON_SPLITINFO structure.
This method initializes the mask member of a BUTTON_SPLITINFO structure with the BCSIF_STYLE flag and
the uSplitStyle member with the uSplitStyle parameter, and then sends that structure in the
BCM_GETSPLITINFO message that is described in the Windows SDK.
Example
The following code example defines the variable, m_splitButton , that is used to programmatically access the
split button control.

public:
// Variable to access programatically defined command link control.
CButton m_cmdLink;
// Variable to access programatically defined split button control.
CButton m_splitButton;

Example
The following code example sets the style of the split button drop-down arrow. The BCSS_ALIGNLEFT style
displays the arrow on the left side of the button, and the BCSS_STRETCH style retains the drop-down arrow's
proportions when you resize the button.
/*
Set the style of the split button drop-down arrow: Display the
arrow on the left and retain the arrow's proportions when resizing
the control.
*/
bRC = m_splitButton.SetSplitStyle(BCSS_ALIGNLEFT | BCSS_STRETCH);

CButton::SetState
Sets whether a button control is highlighted or not.

void SetState(BOOL bHighlight);

Parameters
bHighlight
Specifies whether the button is to be highlighted. A nonzero value highlights the button; a 0 value removes
any highlighting.
Remarks
Highlighting affects the exterior of a button control. It has no effect on the check state of a radio button or
check box.
A button control is automatically highlighted when the user clicks and holds the left mouse button. The
highlighting is removed when the user releases the mouse button.
Example

CButton myPushButton;

// Create a push button.


myPushButton.Create(_T("My button"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
CRect(10, 10, 100, 30), pParentWnd, 1);

// Invert the highlight state of the button.


myPushButton.SetState(!(myPushButton.GetState() & 0x0004));

CButton::SetTextMargin
Call this method to set the text margin of the CButton object.

BOOL SetTextMargin(RECT* pmargin);

Parameters
pmargin
A pointer to the new text margin.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the BCM_SETTEXTMARGIN message, as described in the
Buttons section of the Windows SDK.
See also
CWnd Class
Hierarchy Chart
CWnd Class
CComboBox Class
CEdit Class
CListBox Class
CScrollBar Class
CStatic Class
CBitmapButton Class
CDialog Class
CByteArray Class
3/27/2020 • 2 minutes to read • Edit Online

Supports dynamic arrays of bytes.

Syntax
class CByteArray : public CObject

Members
The member functions of CByteArray are similar to the member functions of class CObArray. Because of this
similarity, you can use the CObArray reference documentation for member function specifics. Wherever you
see a CObject pointer as a function parameter or return value, substitute a BYTE.
CObject* CObArray::GetAt( int <nIndex> ) const;

for example, translates to


BYTE CByteArray::GetAt( int <nIndex> ) const;

Public Constructors
NAME DESC RIP T IO N

CByteArray::CByteArray Constructs an empty array.

Public Methods
NAME DESC RIP T IO N

CByteArray::Add Adds an element to the end of the array; grows the array if
necessary.

CByteArray::Append Appends another array to the array; grows the array if


necessary.

CByteArray::Copy Copies another array to the array; grows the array if


necessary.

CByteArray::ElementAt Returns a temporary reference to the byte within the array.

CByteArray::FreeExtra Frees all unused memory above the current upper bound.

CByteArray::GetAt Returns the value at a given index.

CByteArray::GetCount Gets the number of elements in this array.

CByteArray::GetData Allows access to elements in the array. Can be NULL.


NAME DESC RIP T IO N

CByteArray::GetSize Gets the number of elements in this array.

CByteArray::GetUpperBound Returns the largest valid index.

CByteArray::InsertAt Inserts an element (or all the elements in another array) at


a specified index.

CByteArray::IsEmpty Determines if the array is empty.

CByteArray::RemoveAll Removes all the elements from this array.

CByteArray::RemoveAt Removes an element at a specific index.

CByteArray::SetAt Sets the value for a given index; array not allowed to grow.

CByteArray::SetAtGrow Sets the value for a given index; grows the array if
necessary.

CByteArray::SetSize Sets the number of elements to be contained in this array.

Public Operators
NAME DESC RIP T IO N

CByteArray::operator [ ] Sets or gets the element at the specified index.

Remarks
CByteArray incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its elements.
If an array of bytes is stored to an archive, either with the overloaded insertion ( << ) operator or with the
Serialize member function, each element is, in turn, serialized.

NOTE
Before using an array, use SetSize to establish its size and allocate memory for it. If you do not use SetSize , adding
elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are
inefficient and can fragment memory.

If you need debug output from individual elements in the array, you must set the depth of the CDumpContext
object to 1 or greater.
For more information on using CByteArray , see the article Collections.

Inheritance Hierarchy
CObject
CByteArray

Requirements
Header : afxcoll.h
See also
CObject Class
Hierarchy Chart
CObArray Class
CCachedDataPathProperty Class
3/27/2020 • 2 minutes to read • Edit Online

Implements an OLE control property transferred asynchronously and cached in a memory file.

Syntax
class CCachedDataPathProperty : public CDataPathProperty

Members
Public Constructors
NAME DESC RIP T IO N

CCachedDataPathProperty::CCachedDataPathProperty Constructs a CCachedDataPathProperty object.

Public Data Members


NAME DESC RIP T IO N

CCachedDataPathProperty::m_Cache CMemFile object in which to cache data.

Remarks
A memory file is stored in RAM rather than on disk and is useful for fast temporary transfers.
Along with CAysncMonikerFile and CDataPathProperty , CCachedDataPathProperty provides functionality for the use
of asynchronous monikers in OLE controls. With CCachedDataPathProperty objects, you are able to transfer data
asynchronously from a URL or file source and store it in a memory file via the m_Cache public variable. All the data
is stored in the memory file, and there is no need to override OnDataAvailable unless you want to watch for
notifications and respond. For example, if you are transferring a large .GIF file and want to notify your control that
more data has arrived and it should redraw itself, override OnDataAvailable to make the notification.
The class CCachedDataPathProperty is derived from CDataPathProperty .
For more information about how to use asynchronous monikers and ActiveX controls in Internet applications, see
the following topics:
Internet First Steps: ActiveX Controls
Internet First Steps: Asynchronous Monikers

Inheritance Hierarchy
CObject
CFile
COleStreamFile
CMonikerFile
CAsyncMonikerFile
CDataPathProperty
CCachedDataPathProperty

Requirements
Header : afxctl.h

CCachedDataPathProperty::CCachedDataPathProperty
Constructs a CCachedDataPathProperty object.

CCachedDataPathProperty(COleControl* pControl = NULL);

CCachedDataPathProperty(
LPCTSTR lpszPath,
COleControl* pControl = NULL);

Parameters
pControl
A pointer to the ActiveX control object to be associated with this CCachedDataPathProperty object.
lpszPath
The path, which may be absolute or relative, used to create an asynchronous moniker that references the actual
absolute location of the property. CCachedDataPathProperty uses URLs, not filenames. If you want a
CCachedDataPathProperty object for a file, prepend file:// to the path.

Remarks
The COleControl object pointed to by pControl is used by Open and retrieved by derived classes. If pControl is
NULL, the control used with Open should be set with SetControl. If lpszPath is NULL, you can pass in the path
through Open or set it with SetPath.

CCachedDataPathProperty::m_Cache
Contains the class name of the memory file into which data is cached.

CMemFile m_Cache;

Remarks
A memory file is stored in RAM rather than on disk.

See also
CDataPathProperty Class
Hierarchy Chart
CDataPathProperty Class
CCheckListBox Class
4/21/2020 • 7 minutes to read • Edit Online

Provides the functionality of a Windows checklist box.

Syntax
class CCheckListBox : public CListBox

Members
Public Constructors
NAME DESC RIP T IO N

CCheckListBox::CCheckListBox Constructs a CCheckListBox object.

Public Methods
NAME DESC RIP T IO N

CCheckListBox::Create Creates the Windows checklist box and attaches it to the


CCheckListBox object.

CCheckListBox::DrawItem Called by the framework when a visual aspect of an owner-


draw list box changes.

CCheckListBox::Enable Enables or disables a checklist box item.

CCheckListBox::GetCheck Gets the state of an item's check box.

CCheckListBox::GetCheckStyle Gets the style of the control's check boxes.

CCheckListBox::IsEnabled Determines whether an item is enabled.

CCheckListBox::MeasureItem Called by the framework when a list box with an owner-draw


style is created.

CCheckListBox::OnGetCheckPosition Called by the framework to get the position of an item's check


box.

CCheckListBox::SetCheck Sets the state of an item's check box.

CCheckListBox::SetCheckStyle Sets the style of the control's check boxes.

Remarks
A "checklist box" displays a list of items, such as filenames. Each item in the list has a check box next to it that the
user can check or clear.
CCheckListBox is only for owner-drawn controls because the list contains more than text strings. At its simplest, a
checklist box contains text strings and check boxes, but you do not need to have text at all. For example, you could
have a list of small bitmaps with a check box next to each item.
To create your own checklist box, you must derive your own class from CCheckListBox . To derive your own class,
write a constructor for the derived class, then call Create .
If you want to handle Windows notification messages sent by a list box to its parent (usually a class derived from
CDialog), add a message-map entry and message-handler member function to the parent class for each message.
Each message-map entry takes the following form:
ON_ Notification ( id, memberFxn )
where id specifies the child window ID of the control sending the notification and memberFxn is the name of the
parent member function you have written to handle the notification.
The parent's function prototype is as follows:
afx_msg void memberFxn();

There is only one message-map entry that pertains specifically to CCheckListBox (but see also the message-map
entries for CListBox):
ON_CLBN_CHKCHANGE The user has changed the state of an item's checkbox.
If your checklist box is a default checklist box (a list of strings with the default-sized checkboxes to the left of each),
you can use the default CCheckListBox::DrawItem to draw the checklist box. Otherwise, you must override the
CListBox::CompareItem function and the CCheckListBox::DrawItem and CCheckListBox::MeasureItem functions.
You can create a checklist box either from a dialog template or directly in your code.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CListBox
CCheckListBox

Requirements
Header : afxwin.h

CCheckListBox::CCheckListBox
Constructs a CCheckListBox object.

CCheckListBox();

Remarks
You construct a CCheckListBox object in two steps. First define a class derived from CCheckListBox , then call
Create , which initializes the Windows checklist box and attaches it to the CCheckListBox object.
Example

CCheckListBox myCheckListBox;
myCheckListBox.Create(LBS_HASSTRINGS | LBS_OWNERDRAWFIXED,
CRect(10, 10, 100, 100), this, IDC_MYCHECKLISTBOX);

CCheckListBox::Create
Creates the Windows checklist box and attaches it to the CCheckListBox object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the style of the checklist box. The style must be LBS_HASSTRINGS and either LBS_OWNERDRAWFIXED
(all items in the list are the same height) or LBS_OWNERDRAWVARIABLE (items in the list are of varying heights).
This style can be combined with other list-box styles except LBS_USETABSTOPS.
rect
Specifies the checklist-box size and position. Can be either a CRect object or a RECT structure.
pParentWnd
Specifies the checklist box's parent window (usually a CDialog object). It must not be NULL.
nID
Specifies the checklist box's control ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You construct a CCheckListBox object in two steps. First, define a class derived from CcheckListBox and then call
Create , which initializes the Windows checklist box and attaches it to the CCheckListBox . See
CCheckListBox::CCheckListBox for a sample.
When Create executes, Windows sends the WM_NCCREATE, WM_CREATE, WM_NCCALCSIZE, and
WM_GETMINMAXINFO messages to the checklist-box control.
These messages are handled by default by the OnNcCreate, OnCreate, OnNcCalcSize, and OnGetMinMaxInfo
member functions in the CWnd base class. To extend the default message handling, add a message map to the
your derived class and override the preceding message-handler member functions. Override OnCreate , for
example, to perform needed initialization for a new class.
Apply the following window styles to a checklist-box control:
WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
WS_VSCROLL To add a vertical scroll bar
WS_HSCROLL To add a horizontal scroll bar
WS_GROUP To group controls
WS_TABSTOP To allow tabbing to this control

CCheckListBox::DrawItem
Called by the framework when a visual aspect of an owner-drawn checklist box changes.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A long pointer to a DRAWITEMSTRUCT structure that contains information about the type of drawing required.
Remarks
The itemAction and itemState members of the DRAWITEMSTRUCT structure define the drawing action that is to be
performed.
By default, this function draws a default checkbox list, consisting of a list of strings each with a default-sized
checkbox to the left. The checkbox list size is the one specified in Create.
Override this member function to implement drawing of owner-draw checklist boxes that are not the default, such
as checklist boxes with lists that aren't strings, with variable-height items, or with checkboxes that aren't on the left.
The application should restore all graphics device interface (GDI) objects selected for the display context supplied
in lpDrawItemStruct before the termination of this member function.
If checklist box items are not all the same height, the checklist box style (specified in Create ) must be
LBS_OWNERVARIABLE , and you must override the MeasureItem function.

CCheckListBox::Enable
Call this function to enable or disable a checklist box item.

void Enable(
int nIndex,
BOOL bEnabled = TRUE);

Parameters
nIndex
Index of the checklist box item to be enabled.
bEnabled
Specifies whether the item is enabled or disabled.

CCheckListBox::GetCheck
Retrieves the state of the specified check box.

int GetCheck(int nIndex);

Parameters
nIndex
Zero-based index of a check box that is contained in the list box.
Return Value
The state of the specified check box. The following table lists possible values.

VA L UE DESC RIP T IO N

BST_CHECKED The check box is checked.

BST_UNCHECKED The check box is not checked.

BST_INDETERMINATE The check box state is indeterminate.

CCheckListBox::GetCheckStyle
Call this function to get the checklist box's style.

UINT GetCheckStyle();

Return Value
The style of the control's check boxes.
Remarks
For information on possible styles, see SetCheckStyle.

CCheckListBox::IsEnabled
Call this function to determine whether an item is enabled.

BOOL IsEnabled(int nIndex);

Parameters
nIndex
Index of the item.
Return Value
Nonzero if the item is enabled; otherwise 0.

CCheckListBox::MeasureItem
Called by the framework when a checklist box with a nondefault style is created.

virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

Parameters
lpMeasureItemStruct
A long pointer to a MEASUREITEMSTRUCT structure.
Remarks
By default, this member function does nothing. Override this member function and fill in the MEASUREITEMSTRUCT
structure to inform Windows of the dimensions of checklist-box items. If the checklist box is created with the
LBS_OWNERDRAWVARIABLE style, the framework calls this member function for each item in the list box.
Otherwise, this member is called only once.

CCheckListBox::OnGetCheckPosition
The framework calls this function to get the position and size of the check box in an item.

virtual CRect OnGetCheckPosition(


CRect rectItem,
CRect rectCheckBox);

Parameters
rectItem
The position and size of the list item.
rectCheckBox
The default position and size of an item's check box.
Return Value
The position and size of an item's check box.
Remarks
The default implementation only returns the default position and size of the check box ( rectCheckBox ). By default,
a check box is aligned in the upper-left corner of an item and is the standard check box size. There may be cases
where you want the check boxes on the right, or want a larger or smaller check box. In these cases, override
OnGetCheckPosition to change the check box position and size within the item.

CCheckListBox::SetCheck
Sets the state of the specified check box.

void SetCheck(
int nIndex,
int nCheck);

Parameters
nIndex
Zero-based index of a check box that is contained in the list box.
nCheck
The button state for the specified check box. See the Remarks section for possible values.
Remarks
The following table lists possible values for the nCheck parameter.

VA L UE DESC RIP T IO N

BST_CHECKED Select the specified check box.

BST_UNCHECKED Clear the specified check box.


VA L UE DESC RIP T IO N

BST_INDETERMINATE Set the specified check box state to indeterminate.

This state is only available if the check box style is


BS_AUTO3STATE or BS_3STATE. For more information, see
Button Styles.

CCheckListBox::SetCheckStyle
Call this function to set the style of check boxes in the checklist box.

void SetCheckStyle(UINT nStyle);

Parameters
nStyle
Determines the style of check boxes in the checklist box.
Remarks
Valid styles are:
BS_CHECKBOX
BS_AUTOCHECKBOX
BS_AUTO3STATE
BS_3STATE
For information on these styles, see Button Styles.

See also
MFC Sample TSTCON
CListBox Class
Hierarchy Chart
CListBox Class
CClientDC Class
3/27/2020 • 2 minutes to read • Edit Online

Takes care of calling the Windows functions GetDC at construction time and ReleaseDC at destruction time.

Syntax
class CClientDC : public CDC

Members
Public Constructors
NAME DESC RIP T IO N

CClientDC::CClientDC Constructs a CClientDC object connected to the CWnd .

Protected Data Members


NAME DESC RIP T IO N

CClientDC::m_hWnd The HWND of the window for which this CClientDC is valid.

Remarks
This means that the device context associated with a CClientDC object is the client area of a window.
For more information on CClientDC , see Device Contexts.

Inheritance Hierarchy
CObject
CDC
CClientDC

Requirements
Header : afxwin.h

CClientDC::CClientDC
Constructs a CClientDC object that accesses the client area of the CWnd pointed to by pWnd.

explicit CClientDC(CWnd* pWnd);

Parameters
pWnd
The window whose client area the device context object will access.
Remarks
The constructor calls the Windows function GetDC.
An exception (of type CResourceException ) is thrown if the Windows GetDC call fails. A device context may not be
available if Windows has already allocated all of its available device contexts. Your application competes for the
five common display contexts available at any given time under Windows.
Example

void CDCView::DrawInClientDC(CDC *pDC)


{
UNREFERENCED_PARAMETER(pDC);
CClientDC clientDC(this);
clientDC.TextOut(10, 10, CString(_T("I used a client DC!")));
}

CClientDC::m_hWnd
The HWND of the CWnd pointer used to construct the CClientDC object.

HWND m_hWnd;

Remarks
m_hWnd is a protected variable.
Example
See the example for CClientDC::CClientDC.

See also
MFC Sample MDI
CDC Class
Hierarchy Chart
CDC Class
CCmdTarget Class
4/21/2020 • 14 minutes to read • Edit Online

The base class for the Microsoft Foundation Class Library message-map
architecture.

Syntax
class CCmdTarget : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CCmdTarget::CCmdTarget Constructs a CCmdTarget object.

Public Methods
NAME DESC RIP T IO N

CCmdTarget::BeginWaitCursor Displays the cursor as an hourglass cursor.

CCmdTarget::DoOleVerb Causes an action specified by an OLE verb to


be performed.

CCmdTarget::EnableAutomation Allows OLE automation for the CCmdTarget


object.

CCmdTarget::EnableConnections Enables event firing over connection points.

CCmdTarget::EnableTypeLib Enables an object's type library.

CCmdTarget::EndWaitCursor Returns to the previous cursor.

CCmdTarget::EnumOleVerbs Enumerates an object's OLE verbs.

CCmdTarget::FromIDispatch Returns a pointer to the CCmdTarget object


associated with the IDispatch pointer.

CCmdTarget::GetDispatchIID Gets the primary dispatch interface ID.

CCmdTarget::GetIDispatch Returns a pointer to the IDispatch object


associated with the CCmdTarget object.

CCmdTarget::GetTypeInfoCount Retrieves the number of type information


interfaces that an object provides.
NAME DESC RIP T IO N

CCmdTarget::GetTypeInfoOfGuid Retrieves the type description that


corresponds to the specified GUID.

CCmdTarget::GetTypeLib Gets a pointer to a type library.

CCmdTarget::GetTypeLibCache Gets the type library cache.

CCmdTarget::IsInvokeAllowed Enables automation method invocation.

CCmdTarget::IsResultExpected Returns nonzero if an automation function


should return a value.

CCmdTarget::OnCmdMsg Routes and dispatches command messages.

CCmdTarget::OnFinalRelease Cleans up after the last OLE reference is


released.

CCmdTarget::RestoreWaitCursor Restores the hourglass cursor.

Remarks
A message map routes commands or messages to the member functions you write
to handle them. (A command is a message from a menu item, command button, or
accelerator key.)
Key framework classes derived from CCmdTarget include CView, CWinApp,
CDocument, CWnd, and CFrameWnd. If you intend for a new class to handle
messages, derive the class from one of these CCmdTarget -derived classes. You will
rarely derive a class from CCmdTarget directly.
For an overview of command targets and OnCmdMsg routing, see Command Targets,
Command Routing, and Mapping Messages.
CCmdTarget includes member functions that handle the display of an hourglass
cursor. Display the hourglass cursor when you expect a command to take a
noticeable time interval to execute.
Dispatch maps, similar to message maps, are used to expose OLE automation
IDispatch functionality. By exposing this interface, other applications (such as Visual
Basic) can call into your application.

Inheritance Hierarchy
CObject
CCmdTarget

Requirements
Header : afxwin.h

CCmdTarget::BeginWaitCursor
Call this function to display the cursor as an hourglass when you expect a command
to take a noticeable time interval to execute.

void BeginWaitCursor();

Remarks
The framework calls this function to show the user that it is busy, such as when a
CDocument object loads or saves itself to a file.

The actions of BeginWaitCursor are not always effective outside of a single message
handler as other actions, such as OnSetCursor handling, could change the cursor.
Call EndWaitCursor to restore the previous cursor.
Example
// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.


void CMyView::OnBeginDlgRestore()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
// The dialog box will normally change the cursor to
// the standard arrow cursor, and leave the cursor in
// as the standard arrow cursor when the dialog box is
// closed.
CFileDialog dlg(TRUE);
dlg.DoModal();

// It is necessary to call RestoreWaitCursor here in order


// to change the cursor back to the hourglass cursor.
RestoreWaitCursor();
// do some more lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between


// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called. This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
// some processing ...
CFileDialog dlg(TRUE);
dlg.DoModal();
RestoreWaitCursor();

// some more processing ...


}

// If the dialog is invoked from a member function of


// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
CFileDialog dlg(TRUE);
dlg.DoModal();
AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

CCmdTarget::CCmdTarget
Constructs a CCmdTarget object.
CCmdTarget();

CCmdTarget::DoOleVerb
Causes an action specified by an OLE verb to be performed.

BOOL DoOleVerb(
LONG iVerb,
LPMSG lpMsg,
HWND hWndParent,
LPCRECT lpRect);

Parameters
iVerb
Numerical identifier of the verb.
lpMsg
Pointer to the MSG structure describing the event (such as a double-click) that
invoked the verb.
hWndParent
Handle of the document window containing the object.
lpRect
Pointer to the RECT structure containing the coordinates, in pixels, that define an
object's bounding rectangle in hwndParent.
Return Value
TRUE if successful, otherwise FALSE.
Remarks
This member function is basically an implementation of IOleObject::DoVerb. The
possible actions are enumerated by CCmdTarget::EnumOleVerbs.

CCmdTarget::EnableAutomation
Call this function to enable OLE automation for an object.

void EnableAutomation();

Remarks
This function is typically called from the constructor of your object and should only
be called if a dispatch map has been declared for the class. For more information on
automation see the articles Automation Clients and Automation Servers.

CCmdTarget::EnableConnections
Enables event firing over connection points.

void EnableConnections();

Remarks
To enable connection points, call this member function in the constructor of your
derived class.

CCmdTarget::EnableTypeLib
Enables an object's type library.

void EnableTypeLib();

Remarks
Call this member function in the constructor of your CCmdTarget -derived object if it
provides type information.

CCmdTarget::EndWaitCursor
Call this function after you have called the BeginWaitCursor member function to
return from the hourglass cursor to the previous cursor.

void EndWaitCursor();

Remarks
The framework also calls this member function after it has called the hourglass
cursor.
Example
// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.


void CMyView::OnBeginDlgRestore()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
// The dialog box will normally change the cursor to
// the standard arrow cursor, and leave the cursor in
// as the standard arrow cursor when the dialog box is
// closed.
CFileDialog dlg(TRUE);
dlg.DoModal();

// It is necessary to call RestoreWaitCursor here in order


// to change the cursor back to the hourglass cursor.
RestoreWaitCursor();
// do some more lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between


// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called. This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
// some processing ...
CFileDialog dlg(TRUE);
dlg.DoModal();
RestoreWaitCursor();

// some more processing ...


}

// If the dialog is invoked from a member function of


// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
CFileDialog dlg(TRUE);
dlg.DoModal();
AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

CCmdTarget::EnumOleVerbs
Enumerates an object's OLE verbs.
BOOL EnumOleVerbs(LPENUMOLEVERB* ppenumOleVerb);

Parameters
ppenumOleVerb
A pointer to a pointer to an IEnumOLEVERB interface.
Return Value
TRUE if the object supports at least one OLE verb (in which case * ppenumOleVerb
points to an IEnumOLEVERB enumerator interface), otherwise FALSE.
Remarks
This member function is basically an implementation of IOleObject::EnumVerbs.

CCmdTarget::FromIDispatch
Call this function to map an IDispatch pointer, received from automation member
functions of a class, into the CCmdTarget object that implements the interfaces of the
IDispatch object.

static CCmdTarget* PASCAL FromIDispatch(LPDISPATCH lpDispatch);

Parameters
lpDispatch
A pointer to an IDispatch object.
Return Value
A pointer to the CCmdTarget object associated with lpDispatch. This function returns
NULL if the IDispatch object is not recognized as a Microsoft Foundation Class
IDispatch object.

Remarks
The result of this function is the inverse of a call to the member function
GetIDispatch .

CCmdTarget::GetDispatchIID
Gets the primary dispatch interface ID.

virtual BOOL GetDispatchIID(IID* pIID);

Parameters
pIID
A pointer to an interface ID (a [GUID](/windows/win32/api/guiddef/ns-guiddef-guid.
Return Value
TRUE if successful, otherwise FALSE. If successful, * pIID is set to the primary
dispatch interface ID.
Remarks
Derived classes should override this member function (if not overridden,
GetDispatchIID returns FALSE). See COleControl.
CCmdTarget::GetIDispatch
Call this member function to retrieve the IDispatch pointer from an automation
method that either returns an IDispatch pointer or takes an IDispatch pointer by
reference.

LPDISPATCH GetIDispatch(BOOL bAddRef);

Parameters
bAddRef
Specifies whether to increment the reference count for the object.
Return Value
The IDispatch pointer associated with the object.
Remarks
For objects that call EnableAutomation in their constructors, making them
automation enabled, this function returns a pointer to the Foundation Class
implementation of IDispatch that is used by clients who communicate via the
IDispatch interface. Calling this function automatically adds a reference to the
pointer, so it is not necessary to make a call to IUnknown::AddRef.

CCmdTarget::GetTypeInfoCount
Retrieves the number of type information interfaces that an object provides.

virtual UINT GetTypeInfoCount();

Return Value
The number of type information interfaces.
Remarks
This member function basically implements IDispatch::GetTypeInfoCount.
Derived classes should override this function to return the number of type
information interfaces provided (either 0 or 1). If not overridden, GetTypeInfoCount
returns 0. To override, use the IMPLEMENT_OLETYPELIB macro, which also
implements GetTypeLib and GetTypeLibCache .

CCmdTarget::GetTypeInfoOfGuid
Retrieves the type description that corresponds to the specified GUID.

HRESULT GetTypeInfoOfGuid(
LCID lcid,
const GUID& guid,
LPTYPEINFO* ppTypeInfo);

Parameters
lcid
A locale identifier ( LCID ).
guid
The [GUID](/windows/win32/api/guiddef/ns-guiddef-guid of the type description.
ppTypeInfo
Pointer to a pointer to the ITypeInfo interface.
Return Value
An HRESULT indicating the success or failure of the call. If successful, * ppTypeInfo
points to the type information interface.

CCmdTarget::GetTypeLib
Gets a pointer to a type library.

virtual HRESULT GetTypeLib(


LCID lcid,
LPTYPELIB* ppTypeLib);

Parameters
lcid
A locale identifier (LCID).
ppTypeLib
A pointer to a pointer to the ITypeLib interface.
Return Value
An HRESULT indicating the success or failure of the call. If successful, * ppTypeLib
points to the type library interface.
Remarks
Derived classes should override this member function (if not overridden,
GetTypeLib returns TYPE_E_CANTLOADLIBRARY). Use the IMPLEMENT_OLETYPELIB
macro, which also implements GetTypeInfoCount and GetTypeLibCache .

CCmdTarget::GetTypeLibCache
Gets the type library cache.

virtual CTypeLibCache* GetTypeLibCache();

Return Value
A pointer to a CTypeLibCache object.
Remarks
Derived classes should override this member function (if not overridden,
GetTypeLibCache returns NULL). Use the IMPLEMENT_OLETYPELIB macro, which
also implements GetTypeInfoCount and GetTypeLib .

CCmdTarget::IsInvokeAllowed
This function is called by MFC's implementation of IDispatch::Invoke to determine
if a given automation method (identified by dispid) can be invoked.
virtual BOOL IsInvokeAllowed(DISPID dispid);

Parameters
dispid
A dispatch ID.
Return Value
TRUE if the method can be invoked, otherwise FALSE.
Remarks
If IsInvokeAllowed returns TRUE, Invoke proceeds to call the method; otherwise,
Invoke will fail, returning E_UNEXPECTED.

Derived classes can override this function to return appropriate values (if not
overridden, IsInvokeAllowed returns TRUE). See in particular
COleControl::IsInvokeAllowed.

CCmdTarget::IsResultExpected
Use IsResultExpected to ascertain whether a client expects a return value from its
call to an automation function.

BOOL IsResultExpected();

Return Value
Nonzero if an automation function should return a value; otherwise 0.
Remarks
The OLE interface supplies information to MFC about whether the client is using or
ignoring the result of a function call, and MFC in turn uses this information to
determine the result of a call to IsResultExpected . If production of a return value is
time- or resource-intensive, you can increase efficiency by calling this function
before computing the return value.
This function returns 0 only once so that you will get valid return values from other
automation functions if you call them from the automation function that the client
has called.
IsResultExpected returns a nonzero value if called when an automation function call
is not in progress.

CCmdTarget::OnCmdMsg
Called by the framework to route and dispatch command messages and to handle
the update of command user-interface objects.

virtual BOOL OnCmdMsg(


UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);

Parameters
nID
Contains the command ID.
nCode
Identifies the command notification code. See Remarks for more information about
values for nCode.
pExtra
Used according to the value of nCode. See Remarks for more information about
pExtra.
pHandlerInfo
If not NULL, OnCmdMsg fills in the pTarget and pmf members of the pHandlerInfo
structure instead of dispatching the command. Typically, this parameter should be
NULL.
Return Value
Nonzero if the message is handled; otherwise 0.
Remarks
This is the main implementation routine of the framework command architecture.
At run time, OnCmdMsg dispatches a command to other objects or handles the
command itself by calling the root class CCmdTarget::OnCmdMsg , which does the
actual message-map lookup. For a complete description of the default command
routing, see Message Handling and Mapping Topics.
On rare occasions, you may want to override this member function to extend the
framework's standard command routing. Refer to Technical Note 21 for advanced
details of the command-routing architecture.
If you override OnCmdMsg , you must supply the appropriate value for nCode, the
command notification code, and pExtra, which depends on the value of nCode. The
following table lists their corresponding values:

N C O DE VA L UE P EXT RA VA L UE

CN_COMMAND CCmdUI*

CN_EVENT AFX_EVENT*

CN_UPDATE_COMMAND_UI CCmdUI*

CN_OLECOMMAND COleCmdUI*

CN_OLE_UNREGISTER NULL

Example
// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view. This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits "shapes".
BOOL CMyView::OnCmdMsg(UINT nID,
int nCode,
void *pExtra,
AFX_CMDHANDLERINFO *pHandlerInfo)
{
// Extend the framework's command route from the view to
// the application-specific CMyShape that is currently selected
// in the view. m_pActiveShape is NULL if no shape object
// is currently selected in the view.
if ((m_pActiveShape != NULL) &&
m_pActiveShape->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;

// If the object(s) in the extended command route don't handle


// the command, then let the base class OnCmdMsg handle it.
return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

// The command handler for ID_SHAPE_COLOR (menu command to change


// the color of the currently selected shape) was added to the message
// map of CMyShape (note, not CMyView) using the Properties window.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL. It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
ON_COMMAND(ID_SHAPE_COLOR, &CMyShape::OnShapeColor)
END_MESSAGE_MAP()

CCmdTarget::OnFinalRelease
Called by the framework when the last OLE reference to or from the object is
released.

virtual void OnFinalRelease();

Remarks
Override this function to provide special handling for this situation. The default
implementation deletes the object.

CCmdTarget::RestoreWaitCursor
Call this function to restore the appropriate hourglass cursor after the system cursor
has changed (for example, after a message box has opened and then closed while in
the middle of a lengthy operation).

void RestoreWaitCursor();

Example
// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.


void CMyView::OnBeginDlgRestore()
{
BeginWaitCursor(); // display the hourglass cursor
// do some lengthy processing
// The dialog box will normally change the cursor to
// the standard arrow cursor, and leave the cursor in
// as the standard arrow cursor when the dialog box is
// closed.
CFileDialog dlg(TRUE);
dlg.DoModal();

// It is necessary to call RestoreWaitCursor here in order


// to change the cursor back to the hourglass cursor.
RestoreWaitCursor();
// do some more lengthy processing
Sleep(3000);
EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between


// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called. This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
// some processing ...
CFileDialog dlg(TRUE);
dlg.DoModal();
RestoreWaitCursor();

// some more processing ...


}

// If the dialog is invoked from a member function of


// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
CFileDialog dlg(TRUE);
dlg.DoModal();
AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

See also
MFC Sample ACDUAL
CObject Class
Hierarchy Chart
CCmdUI Class
CDocument Class
CDocTemplate Class
CWinApp Class
CWnd Class
CView Class
CFrameWnd Class
COleDispatchDriver Class
CCmdUI Class
4/21/2020 • 4 minutes to read • Edit Online

Is used only within an ON_UPDATE_COMMAND_UI handler in a CCmdTarget -derived class.

Syntax
class CCmdUI

Members
Public Methods
NAME DESC RIP T IO N

CCmdUI::ContinueRouting Tells the command-routing mechanism to continue routing


the current message down the chain of handlers.

CCmdUI::Enable Enables or disables the user-interface item for this command.

CCmdUI::SetCheck Sets the check state of the user-interface item for this
command.

CCmdUI::SetRadio Like the SetCheck member function, but operates on radio


groups.

CCmdUI::SetText Sets the text for the user-interface item for this command.

Public Data Members


NAME DESC RIP T IO N

CCmdUI::m_nID The ID of the user-interface object.

CCmdUI::m_nIndex The index of the user-interface object.

CCmdUI::m_pMenu Points to the menu represented by the CCmdUI object.

CCmdUI::m_pOther Points to the window object that sent the notification.

CCmdUI::m_pSubMenu Points to the contained sub-menu represented by the


CCmdUI object.

Remarks
CCmdUI does not have a base class.
When a user of your application pulls down a menu, each menu item needs to know whether it should be
displayed as enabled or disabled. The target of a menu command provides this information by implementing an
ON_UPDATE_COMMAND_UI handler. For each of the command user-interface objects in your application, use
the Class Wizard or Proper ties window (in Class View ) to create a message-map entry and function
prototype for each handler.
When the menu is pulled down, the framework searches for and calls each ON_UPDATE_COMMAND_UI handler,
each handler calls CCmdUI member functions such as Enable and Check , and the framework then
appropriately displays each menu item.
A menu item can be replaced with a control-bar button or other command user-interface object without
changing the code within the ON_UPDATE_COMMAND_UI handler.
The following table summarizes the effect CCmdUI 's member functions have on various command user-interface
items.

USER- IN T ERFA C E
IT EM EN A B L E SETC H EC K SET RA DIO SET T EXT

Menu item Enables or disables Checks or unchecks Checks using a dot Sets item text

Toolbar button Enables or disables Selects, unselects, or Same as SetCheck (Not applicable)
indeterminate

Status-bar pane Makes text visible or Sets pop-out or Same as SetCheck Sets pane text
invisible normal border

Normal button in Enables or disables Checks or unchecks Same as SetCheck Sets button text
CDialogBar check box

Normal control in Enables or disables (Not applicable) (Not applicable) Sets window text
CDialogBar

For more on the use of this class, see How to Update User-Interface Objects.

Inheritance Hierarchy
CCmdUI

Requirements
Header : afxwin.h

CCmdUI::ContinueRouting
Call this member function to tell the command-routing mechanism to continue routing the current message
down the chain of handlers.

void ContinueRouting();

Remarks
This is an advanced member function that should be used in conjunction with an ON_COMMAND_EX handler
that returns FALSE. For more information, see Technical Note 6.

CCmdUI::Enable
Call this member function to enable or disable the user-interface item for this command.
virtual void Enable(BOOL bOn = TRUE);

Parameters
bOn
TRUE to enable the item, FALSE to disable it.
Example

ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, &CMyDoc::OnUpdateFileSave)

void CMyDoc::OnUpdateFileSave(CCmdUI *pCmdUI)


{
// Enable the menu item if the file has been modified.
pCmdUI->Enable(m_bModified);
}

CCmdUI::m_nID
The ID of the menu item, toolbar button, or other user-interface object represented by the CCmdUI object.

UINT m_nID;

CCmdUI::m_nIndex
The index of the menu item, toolbar button, or other user-interface object represented by the CCmdUI object.

UINT m_nIndex;

CCmdUI::m_pMenu
Pointer (of CMenu type) to the menu represented by the CCmdUI object.

CMenu* m_pMenu;

Remarks
NULL if the item is not a menu.

CCmdUI::m_pSubMenu
Pointer (of CMenu type) to the contained sub-menu represented by the CCmdUI object.

CMenu* m_pSubMenu;

Remarks
NULL if the item is not a menu. If the sub menu is a pop-up, m_nID contains the ID of the first item in the pop-up
menu. For more information, see Technical Note 21.

CCmdUI::m_pOther
Pointer (of type CWnd ) to the window object, such as a tool or status bar, that sent the notification.

CWnd* m_pOther;

Remarks
NULL if the item is a menu or a non- CWnd object.

CCmdUI::SetCheck
Call this member function to set the user-interface item for this command to the appropriate check state.

virtual void SetCheck(int nCheck = 1);

Parameters
nCheck
Specifies the check state to set. If 0, unchecks; if 1, checks; and if 2, sets indeterminate.
Remarks
This member function works for menu items and toolbar buttons. The indeterminate state applies only to
toolbar buttons.

CCmdUI::SetRadio
Call this member function to set the user-interface item for this command to the appropriate check state.

virtual void SetRadio(BOOL bOn = TRUE);

Parameters
bOn
TRUE to enable the item; otherwise FALSE.
Remarks
This member function operates like SetCheck , except that it operates on user-interface items acting as part of a
radio group. Unchecking the other items in the group is not automatic unless the items themselves maintain the
radio-group behavior.

CCmdUI::SetText
Call this member function to set the text of the user-interface item for this command.

virtual void SetText(LPCTSTR lpszText);

Parameters
lpszText
A pointer to a text string.
Example
void CMyRichEditView::OnUpdateLineNumber(CCmdUI *pCmdUI)
{
int nLine = GetRichEditCtrl().LineFromChar(-1) + 1;

CString string;
string.Format(_T("Line %d"), nLine);
pCmdUI->Enable(TRUE);
pCmdUI->SetText(string);
}

See also
MFC Sample MDI
Hierarchy Chart
CCmdTarget Class
CColorDialog Class
4/21/2020 • 6 minutes to read • Edit Online

Allows you to incorporate a color-selection dialog box into your application.

Syntax
class CColorDialog : public CCommonDialog

Members
Public Constructors
NAME DESC RIP T IO N

CColorDialog::CColorDialog Constructs a CColorDialog object.

Public Methods
NAME DESC RIP T IO N

CColorDialog::DoModal Displays a color dialog box and allows the user to make a
selection.

CColorDialog::GetColor Returns a COLORREF structure containing the values of the


selected color.

CColorDialog::GetSavedCustomColors Retrieves custom colors created by the user.

CColorDialog::SetCurrentColor Forces the current color selection to the specified color.

Protected Methods
NAME DESC RIP T IO N

CColorDialog::OnColorOK Override to validate the color entered into the dialog box.

Public Data Members


NAME DESC RIP T IO N

CColorDialog::m_cc A structure used to customize the settings of the dialog box.

Remarks
A CColorDialog object is a dialog box with a list of colors that are defined for the display system. The user can
select or create a particular color from the list, which is then reported back to the application when the dialog box
exits.
To construct a CColorDialog object, use the provided constructor or derive a new class and use your own custom
constructor.
Once the dialog box has been constructed, you can set or modify any values in the m_cc structure to initialize the
values of the dialog box's controls. The m_cc structure is of type CHOOSECOLOR.
After initializing the dialog box's controls, call the DoModal member function to display the dialog box and allow
the user to select a color. DoModal returns the user's selection of either the dialog box's OK (IDOK) or Cancel
(IDCANCEL) button.
If DoModal returns IDOK, you can use one of CColorDialog 's member functions to retrieve the information input
by the user.
You can use the Windows CommDlgExtendedError function to determine whether an error occurred during
initialization of the dialog box and to learn more about the error.
CColorDialog relies on the COMMDLG.DLL file that ships with Windows versions 3.1 and later.
To customize the dialog box, derive a class from CColorDialog , provide a custom dialog template, and add a
message map to process the notification messages from the extended controls. Any unprocessed messages
should be passed to the base class.
Customizing the hook function is not required.

NOTE
On some installations the CColorDialog object will not display with a gray background if you have used the framework to
make other CDialog objects gray.

For more information on using CColorDialog , see Common Dialog Classes

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog
CColorDialog

Requirements
Header : afxdlgs.h

CColorDialog::CColorDialog
Constructs a CColorDialog object.

CColorDialog(
COLORREF clrInit = 0,
DWORD dwFlags = 0,
CWnd* pParentWnd = NULL);
Parameters
clrInit
The default color selection. If no value is specified, the default is RGB(0,0,0) (black).
dwFlags
A set of flags that customize the function and appearance of the dialog box. For more information, see the
CHOOSECOLOR structure in the Windows SDK.
pParentWnd
A pointer to the dialog box's parent or owner window.
Example

// Show the Color dialog with all the default settings.


CColorDialog dlg1;
dlg1.DoModal();

// Show the fully opened Color dialog with red as the selected color.
CColorDialog dlg2(RGB(255, 0, 0), CC_FULLOPEN);
dlg2.DoModal();

CColorDialog::DoModal
Call this function to display the Windows common color dialog box and allow the user to select a color.

virtual INT_PTR DoModal();

Return Value
IDOK or IDCANCEL. If IDCANCEL is returned, call the Windows CommDlgExtendedError function to determine
whether an error occurred.
IDOK and IDCANCEL are constants that indicate whether the user selected the OK or Cancel button.
Remarks
If you want to initialize the various color dialog-box options by setting members of the m_cc structure, you should
do this before calling DoModal but after the dialog-box object is constructed.
After calling DoModal , you can call other member functions to retrieve the settings or information input by the
user into the dialog box.
Example
See the example for CColorDialog::CColorDialog.

CColorDialog::GetColor
Call this function after calling DoModal to retrieve the information about the color the user selected.

COLORREF GetColor() const;

Return Value
A COLORREF value that contains the RGB information for the color selected in the color dialog box.
Example
// Get the selected color from the CColorDialog.
CColorDialog dlg;
if (dlg.DoModal() == IDOK)
{
COLORREF color = dlg.GetColor();
TRACE(_T("RGB value of the selected color - red = %u, ")
_T("green = %u, blue = %u\n"),
GetRValue(color), GetGValue(color), GetBValue(color));
}

CColorDialog::GetSavedCustomColors
CColorDialog objects permit the user, in addition to choosing colors, to define up to 16 custom colors.

static COLORREF* PASCAL GetSavedCustomColors();

Return Value
A pointer to an array of 16 RGB color values that stores custom colors created by the user.
Remarks
The GetSavedCustomColors member function provides access to these colors. These colors can be retrieved after
DoModal returns IDOK.
Each of the 16 RGB values in the returned array is initialized to RGB(255,255,255) (white). The custom colors
chosen by the user are saved only between dialog box invocations within the application. If you wish to save these
colors between invocations of the application, you must save them in some other manner, such as in an
initialization (.INI) file.
Example

// Get a pointer to an array of 16 RGB color values that stores


// custom colors created by the user from CColorDialog.
CColorDialog dlg;
if (dlg.DoModal() == IDOK)
{
COLORREF *ccolor = dlg.GetSavedCustomColors();
for (int i = 0; i < 16; i++)
{
TRACE(_T("RGB value of the selected color - red = %u, ")
_T("green = %u, blue = %u\n"),
GetRValue(ccolor[i]),
GetGValue(ccolor[i]),
GetBValue(ccolor[i]));
}
}

CColorDialog::m_cc
A structure of type CHOOSECOLOR, whose members store the characteristics and values of the dialog box.

CHOOSECOLOR m_cc;

Remarks
After constructing a CColorDialog object, you can use m_cc to set various aspects of the dialog box before calling
the DoModal member function.
Example

// The code below uses CColorDialog::m_cc data member to


// customize the settings of CColorDialog. The CColorDialog will
// be shown as full open and with red as the selected color.
CColorDialog dlg;
dlg.m_cc.Flags |= CC_FULLOPEN | CC_RGBINIT;
dlg.m_cc.rgbResult = RGB(255, 0, 0);
dlg.DoModal();

CColorDialog::OnColorOK
Override to validate the color entered into the dialog box.

virtual BOOL OnColorOK();

Return Value
Nonzero if the dialog box should not be dismissed; otherwise 0 to accept the color that was entered.
Remarks
Override this function only if you want to provide custom validation of the color the user selects in the color
dialog box.
The user can select a color by one of the following two methods:
Clicking a color on the color palette. The selected color's RGB values are then reflected in the appropriate
RGB edit boxes.
Entering values in the RGB edit boxes
Overriding OnColorOK allows you to reject a color the user enters into a common color dialog box for any
application-specific reason.
Normally, you do not need to use this function because the framework provides default validation of colors and
displays a message box if an invalid color is entered.
You can call SetCurrentColor from within OnColorOK to force a color selection. Once OnColorOK has been fired
(that is, the user clicks OK to accept the color change), you can call GetColor to get the RGB value of the new color.
Example
// Override OnColorOK to validate the color entered to the
// Red, Green, and Blue edit controls. If the color
// is BLACK (i.e. RGB(0, 0,0)), then force the current color
// selection to be the color initially selected when the
// dialog box is created. The color dialog won't close so
// user can enter a new color.
BOOL CMyColorDlg::OnColorOK()
{
// Value in Red edit control.
COLORREF clrref = GetColor();
if (RGB(0, 0, 0) == clrref)
{
AfxMessageBox(_T("BLACK is not an acceptable color. ")
_T("Please enter a color again"));

// GetColor() returns initially selected color.


SetCurrentColor(GetColor());

// Won't dismiss color dialog.


return TRUE;
}

// OK to dismiss color dialog.


return FALSE;
}

CColorDialog::SetCurrentColor
Call this function after calling DoModal to force the current color selection to the color value specified in clr.

void SetCurrentColor(COLORREF clr);

Parameters
clr
An RGB color value.
Remarks
This function is called from within a message handler or OnColorOK . The dialog box will automatically update the
user's selection based on the value of the clr parameter.
Example
See the example for CColorDialog::OnColorOK.

See also
MFC Sample MDI
MFC Sample DRAWCLI
CCommonDialog Class
Hierarchy Chart
CComboBox Class
4/21/2020 • 43 minutes to read • Edit Online

Provides the functionality of a Windows combo box.

Syntax
class CComboBox : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CComboBox::CComboBox Constructs a CComboBox object.

Public Methods
NAME DESC RIP T IO N

CComboBox::AddString Adds a string to the end of the list in the list box of a combo
box, or at the sorted position for list boxes with the
CBS_SORT style.

CComboBox::Clear Deletes (clears) the current selection, if any, in the edit


control.

CComboBox::CompareItem Called by the framework to determine the relative position


of a new list item in a sorted owner-drawn combo box.

CComboBox::Copy Copies the current selection, if any, onto the Clipboard in


CF_TEXT format.

CComboBox::Create Creates the combo box and attaches it to the CComboBox


object.

CComboBox::Cut Deletes (cuts) the current selection, if any, in the edit control
and copies the deleted text onto the Clipboard in CF_TEXT
format.

CComboBox::DeleteItem Called by the framework when a list item is deleted from an


owner-drawn combo box.

CComboBox::DeleteString Deletes a string from the list box of a combo box.

CComboBox::Dir Adds a list of file names to the list box of a combo box.

CComboBox::DrawItem Called by the framework when a visual aspect of an owner-


drawn combo box changes.
NAME DESC RIP T IO N

CComboBox::FindString Finds the first string that contains the specified prefix in the
list box of a combo box.

CComboBox::FindStringExact Finds the first list-box string (in a combo box) that matches
the specified string.

CComboBox::GetComboBoxInfo Retrieves information about the CComboBox object.

CComboBox::GetCount Retrieves the number of items in the list box of a combo box.

CComboBox::GetCueBanner Gets the cue text that is displayed for a combo box control.

CComboBox::GetCurSel Retrieves the index of the currently selected item, if any, in


the list box of a combo box.

CComboBox::GetDroppedControlRect Retrieves the screen coordinates of the visible (dropped


down) list box of a drop-down combo box.

CComboBox::GetDroppedState Determines whether the list box of a drop-down combo box


is visible (dropped down).

CComboBox::GetDroppedWidth Retrieves the minimum allowed width for the drop-down list-
box portion of a combo box.

CComboBox::GetEditSel Gets the starting and ending character positions of the


current selection in the edit control of a combo box.

CComboBox::GetExtendedUI Determines whether a combo box has the default user


interface or the extended user interface.

CComboBox::GetHorizontalExtent Returns the width in pixels that the list-box portion of the
combo box can be scrolled horizontally.

CComboBox::GetItemData Retrieves the application-supplied 32-bit value associated


with the specified combo-box item.

CComboBox::GetItemDataPtr Retrieves the application-supplied 32-bit pointer that is


associated with the specified combo-box item.

CComboBox::GetItemHeight Retrieves the height of list items in a combo box.

CComboBox::GetLBText Gets a string from the list box of a combo box.

CComboBox::GetLBTextLen Gets the length of a string in the list box of a combo box.

CComboBox::GetLocale Retrieves the locale identifier for a combo box.

CComboBox::GetMinVisible Gets the minimum number of visible items in the drop-down


list of the current combo box.

CComboBox::GetTopIndex Returns the index of the first visible item in the list-box
portion of the combo box.
NAME DESC RIP T IO N

CComboBox::InitStorage Preallocates blocks of memory for items and strings in the


list-box portion of the combo box.

CComboBox::InsertString Inserts a string into the list box of a combo box.

CComboBox::LimitText Limits the length of the text that the user can enter into the
edit control of a combo box.

CComboBox::MeasureItem Called by the framework to determine combo box


dimensions when an owner-drawn combo box is created.

CComboBox::Paste Inserts the data from the Clipboard into the edit control at
the current cursor position. Data is inserted only if the
Clipboard contains data in CF_TEXT format.

CComboBox::ResetContent Removes all items from the list box and edit control of a
combo box.

CComboBox::SelectString Searches for a string in the list box of a combo box and, if
the string is found, selects the string in the list box and
copies the string to the edit control.

CComboBox::SetCueBanner Sets the cue text that is displayed for a combo box control.

CComboBox::SetCurSel Selects a string in the list box of a combo box.

CComboBox::SetDroppedWidth Sets the minimum allowed width for the drop-down list-box
portion of a combo box.

CComboBox::SetEditSel Selects characters in the edit control of a combo box.

CComboBox::SetExtendedUI Selects either the default user interface or the extended user
interface for a combo box that has the CBS_DROPDOWN or
CBS_DROPDOWNLIST style.

CComboBox::SetHorizontalExtent Sets the width in pixels that the list-box portion of the
combo box can be scrolled horizontally.

CComboBox::SetItemData Sets the 32-bit value associated with the specified item in a
combo box.

CComboBox::SetItemDataPtr Sets the 32-bit pointer associated with the specified item in
a combo box.

CComboBox::SetItemHeight Sets the height of list items in a combo box or the height of
the edit-control (or static-text) portion of a combo box.

CComboBox::SetLocale Sets the locale identifier for a combo box.

CComboBox::SetMinVisibleItems Sets the minimum number of visible items in the drop-down


list of the current combo box.
NAME DESC RIP T IO N

CComboBox::SetTopIndex Tells the list-box portion of the combo box to display the
item with the specified index at the top.

CComboBox::ShowDropDown Shows or hides the list box of a combo box that has the
CBS_DROPDOWN or CBS_DROPDOWNLIST style.

Remarks
A combo box consists of a list box combined with either a static control or edit control. The list-box portion of
the control may be displayed at all times or may only drop down when the user selects the drop-down arrow
next to the control.
The currently selected item (if any) in the list box is displayed in the static or edit control. In addition, if the
combo box has the drop-down list style, the user can type the initial character of one of the items in the list, and
the list box, if visible, will highlight the next item with that initial character.
The following table compares the three combo-box styles.

ST Y L E W H EN IS L IST B O X VISIB L E STAT IC O R EDIT C O N T RO L

Simple Always Edit

Drop-down When dropped down Edit

Drop-down list When dropped down Static

You can create a CComboBox object from either a dialog template or directly in your code. In both cases, first call
the constructor CComboBox to construct the CComboBox object; then call the Create member function to create the
control and attach it to the CComboBox object.
If you want to handle Windows notification messages sent by a combo box to its parent (usually a class derived
from CDialog ), add a message-map entry and message-handler member function to the parent class for each
message.
Each message-map entry takes the following form:
ON_ Notification ( id, memberFxn )
where id specifies the child-window ID of the combo-box control sending the notification and memberFxn is
the name of the parent member function you have written to handle the notification.
The parent's function prototype is as follows:
afx_msg void memberFxn ( );
The order in which certain notifications will be sent cannot be predicted. In particular, a CBN_SELCHANGE
notification may occur either before or after a CBN_CLOSEUP notification.
Potential message-map entries are the following:
ON_CBN_CLOSEUP (Windows 3.1 and later.) The list box of a combo box has closed. This notification
message is not sent for a combo box that has the CBS_SIMPLE style.
ON_CBN_DBLCLK The user double-clicks a string in the list box of a combo box. This notification message
is only sent for a combo box with the CBS_SIMPLE style. For a combo box with the CBS_DROPDOWN or
CBS_DROPDOWNLIST style, a double-click cannot occur because a single click hides the list box.
ON_CBN_DROPDOWN The list box of a combo box is about to drop down (be made visible). This
notification message can occur only for a combo box with the CBS_DROPDOWN or
CBS_DROPDOWNLIST style.
ON_CBN_EDITCHANGE The user has taken an action that may have altered the text in the edit-control
portion of a combo box. Unlike the CBN_EDITUPDATE message, this message is sent after Windows
updates the screen. It is not sent if the combo box has the CBS_DROPDOWNLIST style.
ON_CBN_EDITUPDATE The edit-control portion of a combo box is about to display altered text. This
notification message is sent after the control has formatted the text but before it displays the text. It is not
sent if the combo box has the CBS_DROPDOWNLIST style.
ON_CBN_ERRSPACE The combo box cannot allocate enough memory to meet a specific request.
ON_CBN_SELENDCANCEL (Windows 3.1 and later.) Indicates the user's selection should be canceled. The
user clicks an item and then clicks another window or control to hide the list box of a combo box. This
notification message is sent before the CBN_CLOSEUP notification message to indicate that the user's
selection should be ignored. The CBN_SELENDCANCEL or CBN_SELENDOK notification message is sent
even if the CBN_CLOSEUP notification message is not sent (as in the case of a combo box with the
CBS_SIMPLE style).
ON_CBN_SELENDOK The user selects an item and then either presses the ENTER key or clicks the DOWN
ARROW key to hide the list box of a combo box. This notification message is sent before the
CBN_CLOSEUP message to indicate that the user's selection should be considered valid. The
CBN_SELENDCANCEL or CBN_SELENDOK notification message is sent even if the CBN_CLOSEUP
notification message is not sent (as in the case of a combo box with the CBS_SIMPLE style).
ON_CBN_KILLFOCUS The combo box is losing the input focus.
ON_CBN_SELCHANGE The selection in the list box of a combo box is about to be changed as a result of
the user either clicking in the list box or changing the selection by using the arrow keys. When processing
this message, the text in the edit control of the combo box can only be retrieved via GetLBText or another
similar function. GetWindowText cannot be used.
ON_CBN_SETFOCUS The combo box receives the input focus.
If you create a CComboBox object within a dialog box (through a dialog resource), the CComboBox object is
automatically destroyed when the user closes the dialog box.
If you embed a CComboBox object within another window object, you do not need to destroy it. If you create the
CComboBox object on the stack, it is destroyed automatically. If you create the CComboBox object on the heap by
using the new function, you must call delete on the object to destroy it when the Windows combo box is
destroyed.
Note If you want to handle WM_KEYDOWN and WM_CHAR messages, you have to subclass the combo box's
edit and list box controls, derive classes from CEdit and CListBox , and add handlers for those messages to the
derived classes. For more information, see CWnd::SubclassWindow.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CComboBox

Requirements
Header : afxwin.h

CComboBox::AddString
Adds a string to the list box of a combo box.

int AddString(LPCTSTR lpszString);

Parameters
lpszString
Points to the null-terminated string that is to be added.
Return Value
If the return value is greater than or equal to 0, it is the zero-based index to the string in the list box. The return
value is CB_ERR if an error occurs; the return value is CB_ERRSPACE if insufficient space is available to store the
new string.
Remarks
If the list box was not created with the CBS_SORT style, the string is added to the end of the list. Otherwise, the
string is inserted into the list, and the list is sorted.

NOTE
This function is not supported by the Windows ComboBoxEx control. For more information on this control, see
ComboBoxEx Controls in the Windows SDK.

To insert a string into a specific location within the list, use the InsertString member function.
Example

// Add 20 items to the combo box.


CString str;
for (int i = 0; i < 20; i++)
{
str.Format(_T("item string %d"), i);
m_pComboBox->AddString(str);
}

CComboBox::CComboBox
Constructs a CComboBox object.

CComboBox();

Example
// Declare a local CComboBox object.
CComboBox myComboBox;

// Declare a dynamic CComboBox object.


CComboBox *pmyComboBox = new CComboBox;

CComboBox::Clear
Deletes (clears) the current selection, if any, in the edit control of the combo box.

void Clear();

Remarks
To delete the current selection and place the deleted contents onto the Clipboard, use the Cut member function.
Example

// Delete all of the text from the combo box's edit control.
m_MyComboBox.SetEditSel(0, -1);
m_MyComboBox.Clear();

CComboBox::CompareItem
Called by the framework to determine the relative position of a new item in the list-box portion of a sorted
owner-draw combo box.

virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);

Parameters
lpCompareItemStruct
A long pointer to a COMPAREITEMSTRUCT structure.
Return Value
Indicates the relative position of the two items described in the COMPAREITEMSTRUCT structure. It can be any of the
following values:

VA L UE M EA N IN G

-1 Item 1 sorts before item 2.

0 Item 1 and item 2 sort the same.

1 Item 1 sorts after item 2.

See CWnd::OnCompareItem for a description of COMPAREITEMSTRUCT .


Remarks
By default, this member function does nothing. If you create an owner-draw combo box with the LBS_SORT
style, you must override this member function to assist the framework in sorting new items added to the list
box.
Example
// CMyComboBox is my owner-drawn combo box derived from CComboBox. This
// example compares two items using strcmp to sort items in reverse
// alphabetical order. The combo box control was created with the
// following code:
// pmyComboBox->Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// CBS_SORT|CBS_OWNERDRAWVARIABLE,
// myRect, pParentWnd, 1);
//
int CMyComboBox::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
int iComp = 0;
ASSERT(lpCompareItemStruct->CtlType == ODT_COMBOBOX);
LPCTSTR lpszText1 = (LPCTSTR)lpCompareItemStruct->itemData1;
ASSERT(lpszText1 != NULL);
LPCTSTR lpszText2 = (LPCTSTR)lpCompareItemStruct->itemData2;
ASSERT(lpszText2 != NULL);

if (NULL != lpszText1 && NULL != lpszText2)


{
iComp = _tcscmp(lpszText2, lpszText1);
}

return iComp;
}

CComboBox::Copy
Copies the current selection, if any, in the edit control of the combo box onto the Clipboard in CF_TEXT format.

void Copy();

Example

// Copy all of the text from the combo box's edit control
// to the clipboard.
m_MyComboBox.SetEditSel(0, -1);
m_MyComboBox.Copy();

CComboBox::Create
Creates the combo box and attaches it to the CComboBox object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the style of the combo box. Apply any combination of combo-box styles to the box.
rect
Points to the position and size of the combo box. Can be a RECT structure or a CRect object.
pParentWnd
Specifies the combo box's parent window (usually a CDialog ). It must not be NULL.
nID
Specifies the combo box's control ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You construct a CComboBox object in two steps. First, call the constructor and then call Create , which creates the
Windows combo box and attaches it to the CComboBox object.
When Create executes, Windows sends the WM_NCCREATE, WM_CREATE, WM_NCCALCSIZE, and
WM_GETMINMAXINFO messages to the combo box.
These messages are handled by default by the OnNcCreate, OnCreate, OnNcCalcSize, and OnGetMinMaxInfo
member functions in the CWnd base class. To extend the default message handling, derive a class from
CComboBox , add a message map to the new class, and override the preceding message-handler member
functions. Override OnCreate , for example, to perform needed initialization for a new class.
Apply the following window styles to a combo-box control. :
WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
WS_VSCROLL To add vertical scrolling for the list box in the combo box
WS_HSCROLL To add horizontal scrolling for the list box in the combo box
WS_GROUP To group controls
WS_TABSTOP To include the combo box in the tabbing order
Example

m_pComboBox->Create(
WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
CRect(10, 10, 200, 100), pParentWnd, 1);

CComboBox::Cut
Deletes (cuts) the current selection, if any, in the combo-box edit control and copies the deleted text onto the
Clipboard in CF_TEXT format.

void Cut();

Remarks
To delete the current selection without placing the deleted text onto the Clipboard, call the Clear member
function.
Example
// Delete all of the text from the combo box's edit control and copy it
// to the clipboard.
m_MyComboBox.SetEditSel(0, -1);
m_MyComboBox.Cut();

CComboBox::DeleteItem
Called by the framework when the user deletes an item from an owner-draw CComboBox object or destroys the
combo box.

virtual void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);

Parameters
lpDeleteItemStruct
A long pointer to a Windows DELETEITEMSTRUCT structure that contains information about the deleted item.
See CWnd::OnDeleteItem for a description of this structure.
Remarks
The default implementation of this function does nothing. Override this function to redraw the combo box as
needed.
Example

// CMyComboBox is my owner-drawn combo box derived from CComboBox. This


// example simply dumps the item's text. The combo box control was
// created with the following code:
// pmyComboBox->Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// CBS_SORT|CBS_OWNERDRAWVARIABLE,
// myRect, pParentWnd, 1);
//
void CMyComboBox::DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
{
ASSERT(lpDeleteItemStruct->CtlType == ODT_COMBOBOX);
LPTSTR lpszText = (LPTSTR)lpDeleteItemStruct->itemData;
ASSERT(lpszText != NULL);

AFXDUMP(lpszText);
}

CComboBox::DeleteString
Deletes the item in position nIndex from the combo box.

int DeleteString(UINT nIndex);

Parameters
nIndex
Specifies the index to the string that is to be deleted.
Return Value
If the return value is greater than or equal to 0, then it is a count of the strings remaining in the list. The return
value is CB_ERR if nIndex specifies an index greater than the number of items in the list.
Remarks
All items following nIndex now move down one position. For example, if a combo box contains two items,
deleting the first item will cause the remaining item to now be in the first position. nIndex=0 for the item in the
first position.
Example

// Delete every item from the combo box.


for (int i = m_pComboBox->GetCount() - 1; i >= 0; i--)
{
m_pComboBox->DeleteString(i);
}

CComboBox::Dir
Adds a list of filenames or drives to the list box of a combo box.

int Dir(
UINT attr,
LPCTSTR lpszWildCard);

Parameters
attr
Can be any combination of the enum values described in CFile::GetStatus or any combination of the following
values:
DDL_READWRITE File can be read from or written to.
DDL_READONLY File can be read from but not written to.
DDL_HIDDEN File is hidden and does not appear in a directory listing.
DDL_SYSTEM File is a system file.
DDL_DIRECTORY The name specified by lpszWildCard specifies a directory.
DDL_ARCHIVE File has been archived.
DDL_DRIVES Include all drives that match the name specified by lpszWildCard.
DDL_EXCLUSIVE Exclusive flag. If the exclusive flag is set, only files of the specified type are listed.
Otherwise, files of the specified type are listed in addition to "normal" files.
lpszWildCard
Points to a file-specification string. The string can contain wildcards (for example, *.*).
Return Value
If the return value is greater than or equal to 0, it is the zero-based index of the last filename added to the list.
The return value is CB_ERR if an error occurs; the return value is CB_ERRSPACE if insufficient space is available
to store the new strings.
Remarks
This function is not supported by the Windows ComboBoxEx control. For more information on this control, see
ComboBoxEx Controls in the Windows SDK.
Example
// Add all the files and directories in the windows directory.
TCHAR lpszWinPath[MAX_PATH], lpszOldPath[MAX_PATH];
VERIFY(0 < ::GetWindowsDirectory(lpszWinPath, MAX_PATH));

// Make the windows directory the current directory.


::GetCurrentDirectory(MAX_PATH, lpszOldPath);
::SetCurrentDirectory(lpszWinPath);

m_pComboBox->ResetContent();
m_pComboBox->Dir(DDL_READWRITE | DDL_DIRECTORY, _T("*.*"));

// Reset the current directory to its previous path.


::SetCurrentDirectory(lpszOldPath);

CComboBox::DrawItem
Called by the framework when a visual aspect of an owner-draw combo box changes.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A pointer to a DRAWITEMSTRUCT structure that contains information about the type of drawing required.
Remarks
The itemAction member of the DRAWITEMSTRUCT structure defines the drawing action that is to be performed.
See CWnd::OnDrawItem for a description of this structure.
By default, this member function does nothing. Override this member function to implement drawing for an
owner-draw CComboBox object. Before this member function terminates, the application should restore all
graphics device interface (GDI) objects selected for the display context supplied in lpDrawItemStruct.
Example
// CMyComboBox is my owner-drawn combo box derived from CComboBox. This
// example draws an item's text centered vertically and horizontally. The
// combo box control was created with the following code:
// pmyComboBox->Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// CBS_SORT|CBS_OWNERDRAWVARIABLE,
// myRect, pParentWnd, 1);
//
void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_COMBOBOX);
LPCTSTR lpszText = (LPCTSTR)lpDrawItemStruct->itemData;
ASSERT(lpszText != NULL);
CDC dc;

dc.Attach(lpDrawItemStruct->hDC);

// Save these value to restore them when done drawing.


COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();

// If this item is selected, set the background color


// and the text color to appropriate values. Erase
// the rect by filling it with the background color.
if ((lpDrawItemStruct->itemAction & ODA_SELECT) &&
(lpDrawItemStruct->itemState & ODS_SELECTED))
{
dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
dc.FillSolidRect(&lpDrawItemStruct->rcItem, ::GetSysColor(COLOR_HIGHLIGHT));
}
else
{
dc.FillSolidRect(&lpDrawItemStruct->rcItem, crOldBkColor);
}

// Draw the text.


dc.DrawText(
lpszText,
(int)_tcslen(lpszText),
&lpDrawItemStruct->rcItem,
DT_CENTER | DT_SINGLELINE | DT_VCENTER);

// Reset the background color and the text color back to their
// original values.
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);

dc.Detach();
}

CComboBox::FindString
Finds, but doesn't select, the first string that contains the specified prefix in the list box of a combo box.

int FindString(
int nStartAfter,
LPCTSTR lpszString) const;

Parameters
nStartAfter
Contains the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nStartAfter. If -1, the
entire list box is searched from the beginning.
lpszString
Points to the null-terminated string that contains the prefix to search for. The search is case independent, so this
string can contain any combination of uppercase and lowercase letters.
Return Value
If the return value is greater than or equal to 0, it is the zero-based index of the matching item. It is CB_ERR if the
search was unsuccessful.
Remarks
This function is not supported by the Windows ComboBoxEx control. For more information on this control, see
ComboBoxEx Controls in the Windows SDK.
Example

// The string to match.


LPCTSTR lpszmyString = _T("item");

// Delete all items that begin with the specified string.


int nItem = 0;
while ((nItem = m_pComboBox->FindString(nItem, lpszmyString)) != CB_ERR)
{
m_pComboBox->DeleteString(nItem);
}

CComboBox::FindStringExact
Call the FindStringExact member function to find the first list-box string (in a combo box) that matches the
string specified in lpszFind.

int FindStringExact(
int nIndexStart,
LPCTSTR lpszFind) const;

Parameters
nIndexStart
Specifies the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nIndexStart. If
nIndexStart is -1, the entire list box is searched from the beginning.
lpszFind
Points to the null-terminated string to search for. This string can contain a complete filename, including the
extension. The search is not case sensitive, so this string can contain any combination of uppercase and
lowercase letters.
Return Value
The zero-based index of the matching item, or CB_ERR if the search was unsuccessful.
Remarks
If the combo box was created with an owner-draw style but without the CBS_HASSTRINGS style,
FindStringExact attempts to match the doubleword value against the value of lpszFind.

Example
// The string to match.
LPCTSTR lpszmyExactString = _T("item 5");

// Delete all items that exactly match the specified string.


int nDex = 0;
while ((nDex = m_pComboBox->FindStringExact(nDex, lpszmyExactString)) != CB_ERR)
{
m_pComboBox->DeleteString(nDex);
}

CComboBox::GetComboBoxInfo
Retrieves information for the CComboBox object.

BOOL GetComboBoxInfo(PCOMBOBOXINFO pcbi) const;

Parameters
pcbi
A pointer to the COMBOBOXINFO structure.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the CB_GETCOMBOBOXINFO message, as described in the
Windows SDK.

CComboBox::GetCount
Call this member function to retrieve the number of items in the list-box portion of a combo box.

int GetCount() const;

Return Value
The number of items. The returned count is one greater than the index value of the last item (the index is zero-
based). It is CB_ERR if an error occurs.
Example

// Add 10 items to the combo box.


CString strItem;
for (int i = 0; i < 10; i++)
{
strItem.Format(_T("item %d"), i);
m_pComboBox->AddString(strItem);
}

// Verify the 10 items were added to the combo box.


ASSERT(m_pComboBox->GetCount() == 10);

CComboBox::GetCueBanner
Gets the cue text that is displayed for a combo box control.
CString GetCueBanner() const;

BOOL GetCueBanner(
LPTSTR lpszText,
int cchText) const;

Parameters
PA RA M ET ER DESC RIP T IO N

lpszText [out] Pointer to a buffer that receives the cue banner text.

cchText [in] Size of the buffer that the lpszText parameter points to.

Return Value
In the first overload, a CString object that contains the cue banner text if it exists; otherwise, a CString object
that has zero length.
-or-
In the second overload, TRUE if this method is successful; otherwise, FALSE.
Remarks
Cue text is a prompt that is displayed in the input area of the combo box control. The cue text is displayed until
the user provides input.
This method sends the CB_GETCUEBANNER message, which is described in the Windows SDK.

CComboBox::GetCurSel
Call this member function to determine which item in the combo box is selected.

int GetCurSel() const;

Return Value
The zero-based index of the currently selected item in the list box of a combo box, or CB_ERR if no item is
selected.
Remarks
GetCurSel returns an index into the list.
Example

// Select the next item of the currently selected item


// in the combo box.
int nIndex = m_pComboBox->GetCurSel();
int nCount = m_pComboBox->GetCount();
if ((nIndex != CB_ERR) && (nCount > 1))
{
if (++nIndex < nCount)
m_pComboBox->SetCurSel(nIndex);
else
m_pComboBox->SetCurSel(0);
}
CComboBox::GetDroppedControlRect
Call the GetDroppedControlRect member function to retrieve the screen coordinates of the visible (dropped-
down) list box of a drop-down combo box.

void GetDroppedControlRect(LPRECT lprect) const;

Parameters
lprect
Points to the RECT structure that is to receive the coordinates.
Example

// This example move a combo box so that the upper left


// corner of the combo box is at a specific point.

// The point to move the combo box to.


CPoint myPoint(30, 10);

CRect r;

m_pComboBox->GetDroppedControlRect(&r);

m_pComboBox->GetParent()->ScreenToClient(&r);
r.OffsetRect(myPoint - r.TopLeft());
m_pComboBox->MoveWindow(&r);

CComboBox::GetDroppedState
Call the GetDroppedState member function to determine whether the list box of a drop-down combo box is
visible (dropped down).

BOOL GetDroppedState() const;

Return Value
Nonzero if the list box is visible; otherwise 0.
Example

// Show the dropdown list box if it is not already dropped.


if (!m_pComboBox->GetDroppedState())
m_pComboBox->ShowDropDown(TRUE);

CComboBox::GetDroppedWidth
Call this function to retrieve the minimum allowable width, in pixels, of the list box of a combo box.

int GetDroppedWidth() const;

Return Value
If successful, the minimum allowable width, in pixels; otherwise, CB_ERR.
Remarks
This function only applies to combo boxes with the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
By default, the minimum allowable width of the drop-down list box is 0. The minimum allowable width can be
set by calling SetDroppedWidth. When the list-box portion of the combo box is displayed, its width is the larger
of the minimum allowable width or the combo box width.
Example
See the example for SetDroppedWidth.

CComboBox::GetEditSel
Gets the starting and ending character positions of the current selection in the edit control of a combo box.

DWORD GetEditSel() const;

Return Value
A 32-bit value that contains the starting position in the low-order word and the position of the first nonselected
character after the end of the selection in the high-order word. If this function is used on a combo box without
an edit control, CB_ERR is returned.
Example

DWORD dwSel;

// Set the selection to be all characters after the current selection.


if ((dwSel = m_MyComboBox.GetEditSel()) != CB_ERR)
{
m_MyComboBox.SetEditSel(HIWORD(dwSel), -1);
}

CComboBox::GetExtendedUI
Call the GetExtendedUI member function to determine whether a combo box has the default user interface or
the extended user interface.

BOOL GetExtendedUI() const;

Return Value
Nonzero if the combo box has the extended user interface; otherwise 0.
Remarks
The extended user interface can be identified in the following ways:
Clicking the static control displays the list box only for combo boxes with the CBS_DROPDOWNLIST style.
Pressing the DOWN ARROW key displays the list box (F4 is disabled).
Scrolling in the static control is disabled when the item list is not visible (arrow keys are disabled).
Example

// Use the extended UI if it is not already set.


if (!m_pComboBox->GetExtendedUI())
m_pComboBox->SetExtendedUI(TRUE);
CComboBox::GetHorizontalExtent
Retrieves from the combo box the width in pixels by which the list-box portion of the combo box can be scrolled
horizontally.

UINT GetHorizontalExtent() const;

Return Value
The scrollable width of the list-box portion of the combo box, in pixels.
Remarks
This is applicable only if the list-box portion of the combo box has a horizontal scroll bar.
Example

// Find the longest string in the combo box.


CString strText;
CSize sz;
UINT dxText = 0;
CDC *pDCCombo = m_pComboBox->GetDC();
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
m_pComboBox->GetLBText(i, strText);
sz = pDCCombo->GetTextExtent(strText);

if (sz.cx > (LONG)dxText)


dxText = sz.cx;
}
m_pComboBox->ReleaseDC(pDCCombo);

// Set the horizontal extent only if the current extent is not large enough.
if (m_pComboBox->GetHorizontalExtent() < dxText)
{
m_pComboBox->SetHorizontalExtent(dxText);
ASSERT(m_pComboBox->GetHorizontalExtent() == dxText);
}

CComboBox::GetItemData
Retrieves the application-supplied 32-bit value associated with the specified combo-box item.

DWORD_PTR GetItemData(int nIndex) const;

Parameters
nIndex
Contains the zero-based index of an item in the combo box's list box.
Return Value
The 32-bit value associated with the item, or CB_ERR if an error occurs.
Remarks
The 32-bit value can be set with the dwItemData parameter of a SetItemData member function call. Use the
GetItemDataPtr member function if the 32-bit value to be retrieved is a pointer (void * ).

Example
// If any item's data is equal to zero then reset it to -1.
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
if (m_pComboBox->GetItemData(i) == 0)
{
m_pComboBox->SetItemData(i, (DWORD)-1);
}
}

CComboBox::GetItemDataPtr
Retrieves the application-supplied 32-bit value associated with the specified combo-box item as a pointer (void
* ).

void* GetItemDataPtr(int nIndex) const;

Parameters
nIndex
Contains the zero-based index of an item in the combo box's list box.
Return Value
Retrieves a pointer, or -1 if an error occurs.
Example

LPVOID lpmyPtr = m_pComboBox->GetItemDataPtr(5);

// Check all the items in the combo box; if an item's


// data pointer is equal to my pointer then reset it to NULL.
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
if (m_pComboBox->GetItemDataPtr(i) == lpmyPtr)
{
m_pComboBox->SetItemDataPtr(i, NULL);
}
}

CComboBox::GetItemHeight
Call the GetItemHeight member function to retrieve the height of list items in a combo box.

int GetItemHeight(int nIndex) const;

Parameters
nIndex
Specifies the component of the combo box whose height is to be retrieved. If the nIndex parameter is -1, the
height of the edit-control (or static-text) portion of the combo box is retrieved. If the combo box has the
CBS_OWNERDRAWVARIABLE style, nIndex specifies the zero-based index of the list item whose height is to be
retrieved. Otherwise, nIndex should be set to 0.
Return Value
The height, in pixels, of the specified item in a combo box. The return value is CB_ERR if an error occurs.
Example
// Set the height of every item so the item
// is completely visible.
CString strLBText;
CSize size;
CDC *pDC = m_pComboBox->GetDC();
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
m_pComboBox->GetLBText(i, strLBText);
size = pDC->GetTextExtent(strLBText);

// Only want to set the item height if the current height


// is not big enough.
if (m_pComboBox->GetItemHeight(i) < size.cy)
m_pComboBox->SetItemHeight(i, size.cy);
}
m_pComboBox->ReleaseDC(pDC);

CComboBox::GetLBText
Gets a string from the list box of a combo box.

int GetLBText(
int nIndex,
LPTSTR lpszText) const;

void GetLBText(
int nIndex,
CString& rString) const;

Parameters
nIndex
Contains the zero-based index of the list-box string to be copied.
lpszText
Points to a buffer that is to receive the string. The buffer must have sufficient space for the string and a
terminating null character.
rString
A reference to a CString .
Return Value
The length (in bytes) of the string, excluding the terminating null character. If nIndex does not specify a valid
index, the return value is CB_ERR.
Remarks
The second form of this member function fills a CString object with the item's text.
Example
// Dump all of the items in the combo box.
CString str1, str2;
int n;
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
n = m_pComboBox->GetLBTextLen(i);
m_pComboBox->GetLBText(i, str1.GetBuffer(n));
str1.ReleaseBuffer();

str2.Format(_T("item %d: %s\r\n"), i, str1.GetBuffer(0));


AFXDUMP(str2);
}

CComboBox::GetLBTextLen
Gets the length of a string in the list box of a combo box.

int GetLBTextLen(int nIndex) const;

Parameters
nIndex
Contains the zero-based index of the list-box string.
Return Value
The length of the string in bytes, excluding the terminating null character. If nIndex does not specify a valid index,
the return value is CB_ERR.
Example
See the example for CComboBox::GetLBText.

CComboBox::GetLocale
Retrieves the locale used by the combo box.

LCID GetLocale() const;

Return Value
The locale identifier (LCID) value for the strings in the combo box.
Remarks
The locale is used, for example, to determine the sort order of the strings in a sorted combo box.
Example
See the example for CComboBox::SetLocale.

CComboBox::GetMinVisible
Gets the minimum number of visible items in the drop-down list of the current combo box control.

int GetMinVisible() const;

Return Value
The minimum number of visible items in the current drop-down list.
Remarks
This method sends the CB_GETMINVISIBLE message, which is described in the Windows SDK.

CComboBox::GetTopIndex
Retrieves the zero-based index of the first visible item in the list-box portion of the combo box.

int GetTopIndex() const;

Return Value
The zero-based index of the first visible item in the list-box portion of the combo box if successful, CB_ERR
otherwise.
Remarks
Initially, item 0 is at the top of the list box, but if the list box is scrolled, another item may be at the top.
Example

// Want an item in the bottom half to be the first visible item.


int nTop = m_pComboBox->GetCount() / 2;
if (m_pComboBox->GetTopIndex() < nTop)
{
m_pComboBox->SetTopIndex(nTop);
ASSERT(m_pComboBox->GetTopIndex() == nTop);
}

CComboBox::InitStorage
Allocates memory for storing list box items in the list-box portion of the combo box.

int InitStorage(
int nItems,
UINT nBytes);

Parameters
nItems
Specifies the number of items to add.
nBytes
Specifies the amount of memory, in bytes, to allocate for item strings.
Return Value
If successful, the maximum number of items that the list-box portion of the combo box can store before a
memory reallocation is needed, otherwise CB_ERRSPACE, meaning not enough memory is available.
Remarks
Call this function before adding a large number of items to the list-box portion of the CComboBox .
Windows 95/98 only: The wParam parameter is limited to 16-bit values. This means list boxes cannot contain
more than 32,767 items. Although the number of items is restricted, the total size of the items in a list box is
limited only by available memory.
This function helps speed up the initialization of list boxes that have a large number of items (more than 100). It
preallocates the specified amount of memory so that subsequent AddString, InsertString, and Dir functions take
the shortest possible time. You can use estimates for the parameters. If you overestimate, some extra memory is
allocated; if you underestimate, the normal allocation is used for items that exceed the preallocated amount.
Example

// Initialize the storage of the combo box to be 256 strings with


// about 10 characters per string, performance improvement.
int nAlloc = pmyComboBox->InitStorage(256, 10);
ASSERT(nAlloc != CB_ERRSPACE);

// Add 256 items to the combo box.


CString strAdd;
for (int i = 0; i < 256; i++)
{
strAdd.Format(_T("item string %d"), i);
m_pComboBox->AddString(strAdd);
}

CComboBox::InsertString
Inserts a string into the list box of a combo box.

int InsertString(
int nIndex,
LPCTSTR lpszString);

Parameters
nIndex
Contains the zero-based index to the position in the list box that will receive the string. If this parameter is -1, the
string is added to the end of the list.
lpszString
Points to the null-terminated string that is to be inserted.
Return Value
The zero-based index of the position at which the string was inserted. The return value is CB_ERR if an error
occurs. The return value is CB_ERRSPACE if insufficient space is available to store the new string.
Remarks
Unlike the AddString member function, the InsertString member function does not cause a list with the
CBS_SORT style to be sorted.

NOTE
This function is not supported by the Windows ComboBoxEx control. For more information on this control, see
ComboBoxEx Controls in the Windows SDK.

Example
// Insert items in between existing items.
CString strIns;
int nItems = m_pComboBox->GetCount();
for (int i = 0; i < nItems; i++)
{
strIns.Format(_T("item string %c"), (char)('A' + i));
m_pComboBox->InsertString(2 * i, strIns);
}

CComboBox::LimitText
Limits the length in bytes of the text that the user can enter into the edit control of a combo box.

BOOL LimitText(int nMaxChars);

Parameters
nMaxChars
Specifies the length (in bytes) of the text that the user can enter. If this parameter is 0, the text length is set to
65,535 bytes.
Return Value
Nonzero if successful. If called for a combo box with the style CBS_DROPDOWNLIST or for a combo box without
an edit control, the return value is CB_ERR.
Remarks
If the combo box does not have the style CBS_AUTOHSCROLL, setting the text limit to be larger than the size of
the edit control will have no effect.
LimitText only limits the text the user can enter. It has no effect on any text already in the edit control when the
message is sent, nor does it affect the length of the text copied to the edit control when a string in the list box is
selected.
Example

// Limit the number of characters in the combo box's edit control to


// be the maximum number visible.

// Get the text metrics for the combo box; needed for the
// average character width.
TEXTMETRIC tm;
CDC *pDCCB = m_pComboBox->GetDC();
pDCCB->GetTextMetrics(&tm);
m_pComboBox->ReleaseDC(pDCCB);

CRect rect;
m_pComboBox->GetClientRect(&rect);

m_pComboBox->LimitText(rect.Width() / tm.tmAveCharWidth);

CComboBox::MeasureItem
Called by the framework when a combo box with an owner-draw style is created.

virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);


Parameters
lpMeasureItemStruct
A long pointer to a MEASUREITEMSTRUCT structure.
Remarks
By default, this member function does nothing. Override this member function and fill in the MEASUREITEMSTRUCT
structure to inform Windows of the dimensions of the list box in the combo box. If the combo box is created
with the CBS_OWNERDRAWVARIABLE style, the framework calls this member function for each item in the list
box. Otherwise, this member is called only once.
Using the CBS_OWNERDRAWFIXED style in an owner-draw combo box created with the SubclassDlgItem
member function of CWnd involves further programming considerations. See the discussion in Technical Note
14.
See CWnd::OnMeasureItem for a description of the MEASUREITEMSTRUCT structure.
Example

// CMyComboBox is my owner-drawn combo box derived from CComboBox. This


// example measures an item and sets the height of the item to twice the
// vertical extent of its text. The combo box control was created with
// the following code:
// pmyComboBox->Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// CBS_SORT|CBS_OWNERDRAWVARIABLE,
// myRect, pParentWnd, 1);
//
void CMyComboBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
ASSERT(lpMeasureItemStruct->CtlType == ODT_COMBOBOX);

if (lpMeasureItemStruct->itemID != (UINT)-1)
{
LPCTSTR lpszText = (LPCTSTR)lpMeasureItemStruct->itemData;
ASSERT(lpszText != NULL);
CSize sz;
CDC *pDC = GetDC();

sz = pDC->GetTextExtent(lpszText);

ReleaseDC(pDC);

lpMeasureItemStruct->itemHeight = 2 * sz.cy;
}
}

CComboBox::Paste
Inserts the data from the Clipboard into the edit control of the combo box at the current cursor position.

void Paste();

Remarks
Data is inserted only if the Clipboard contains data in CF_TEXT format.
Example
// Replace all of the text in the combo box's edit control with the text
// in the clipboard.
m_MyComboBox.SetEditSel(0, -1);
m_MyComboBox.Paste();

CComboBox::ResetContent
Removes all items from the list box and edit control of a combo box.

void ResetContent();

Example

// Delete all the items from the combo box.


m_pComboBox->ResetContent();
ASSERT(m_pComboBox->GetCount() == 0);

CComboBox::SelectString
Searches for a string in the list box of a combo box, and if the string is found, selects the string in the list box and
copies it to the edit control.

int SelectString(
int nStartAfter,
LPCTSTR lpszString);

Parameters
nStartAfter
Contains the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nStartAfter. If -1, the
entire list box is searched from the beginning.
lpszString
Points to the null-terminated string that contains the prefix to search for. The search is case independent, so this
string can contain any combination of uppercase and lowercase letters.
Return Value
The zero-based index of the selected item if the string was found. If the search was unsuccessful, the return
value is CB_ERR and the current selection is not changed.
Remarks
A string is selected only if its initial characters (from the starting point) match the characters in the prefix string.
Note that the SelectString and FindString member functions both find a string, but the SelectString
member function also selects the string.
Example
// The string to match.
LPCTSTR lpszSelect = _T("item");

// Select the item that begins with the specified string.


int nSel = m_pComboBox->SelectString(0, lpszSelect);
ASSERT(nSel != CB_ERR);

CComboBox::SetCueBanner
Sets the cue text that is displayed for a combo box control.

BOOL SetCueBanner(LPCTSTR lpszText);

Parameters
PA RA M ET ER DESC RIP T IO N

lpszText [in] Pointer to a null-terminated buffer that contains the cue


text.

Return Value
TRUE if the method is successful; otherwise, FALSE.
Remarks
Cue text is a prompt that is displayed in the input area of the combo box control. The cue text is displayed until
the user provides input.
This method sends the CB_SETCUEBANNER message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_combobox, that is used to programmatically access the
combo box control. This variable is used in the next example.

// Variable to access the combo box control


CComboBox m_combobox;

Example
The following code example sets the cue banner for the combo box control.
// Add extra initialization here.

// Add 20 items to the combo box. The Resource Editor


// has already been used to set the style of the combo
// box to CBS_SORT.
CString str;
for (int i = 1; i <= 20; i++)
{
str.Format(_T("Item %2d"), i);
m_combobox.AddString(str);
}
// Set the minimum visible item
m_combobox.SetMinVisibleItems(10);
// Set the cue banner
m_combobox.SetCueBanner(_T("Select an item..."));

// End of extra initialization.

CComboBox::SetCurSel
Selects a string in the list box of a combo box.

int SetCurSel(int nSelect);

Parameters
nSelect
Specifies the zero-based index of the string to select. If -1, any current selection in the list box is removed and
the edit control is cleared.
Return Value
The zero-based index of the item selected if the message is successful. The return value is CB_ERR if nSelect is
greater than the number of items in the list or if nSelect is set to -1, which clears the selection.
Remarks
If necessary, the list box scrolls the string into view (if the list box is visible). The text in the edit control of the
combo box is changed to reflect the new selection. Any previous selection in the list box is removed.
Example

// Select the last item in the combo box.


int nLast = pmyComboBox->GetCount() - 1;
if (nLast >= 0)
m_pComboBox->SetCurSel(nLast);

CComboBox::SetDroppedWidth
Call this function to set the minimum allowable width, in pixels, of the list box of a combo box.

int SetDroppedWidth(UINT nWidth);

Parameters
nWidth
The minimum allowable width of the list-box portion of the combo box, in pixels.
Return Value
If successful, the new width of the list box, otherwise CB_ERR.
Remarks
This function only applies to combo boxes with the CBS_DROPDOWN or CBS_DROPDOWNLIST style.
By default, the minimum allowable width of the drop-down list box is 0. When the list-box portion of the combo
box is displayed, its width is the larger of the minimum allowable width or the combo box width.
Example

// Find the longest string in the combo box.


CString str;
CSize sz;
int dx = 0;
TEXTMETRIC tm;
CDC *pDC = m_pComboBox->GetDC();
CFont *pFont = m_pComboBox->GetFont();

// Select the listbox font, save the old font


CFont *pOldFont = pDC->SelectObject(pFont);
// Get the text metrics for avg char width
pDC->GetTextMetrics(&tm);

for (int i = 0; i < m_pComboBox->GetCount(); i++)


{
m_pComboBox->GetLBText(i, str);
sz = pDC->GetTextExtent(str);

// Add the avg width to prevent clipping


sz.cx += tm.tmAveCharWidth;

if (sz.cx > dx)


dx = sz.cx;
}
// Select the old font back into the DC
pDC->SelectObject(pOldFont);
m_pComboBox->ReleaseDC(pDC);

// Adjust the width for the vertical scroll bar and the left and right border.
dx += ::GetSystemMetrics(SM_CXVSCROLL) + 2 * ::GetSystemMetrics(SM_CXEDGE);

// Set the width of the list box so that every item is completely visible.
m_pComboBox->SetDroppedWidth(dx);

CComboBox::SetEditSel
Selects characters in the edit control of a combo box.

BOOL SetEditSel(
int nStartChar,
int nEndChar);

Parameters
nStartChar
Specifies the starting position. If the starting position is set to -1, then any existing selection is removed.
nEndChar
Specifies the ending position. If the ending position is set to -1, then all text from the starting position to the last
character in the edit control is selected.
Return Value
Nonzero if the member function is successful; otherwise 0. It is CB_ERR if CComboBox has the
CBS_DROPDOWNLIST style or does not have a list box.
Remarks
The positions are zero-based. To select the first character of the edit control, you specify a starting position of 0.
The ending position is for the character just after the last character to select. For example, to select the first four
characters of the edit control, you would use a starting position of 0 and an ending position of 4.

NOTE
This function is not supported by the Windows ComboBoxEx control. For more information on this control, see
ComboBoxEx Controls in the Windows SDK.

Example
See the example for CComboBox::GetEditSel.

CComboBox::SetExtendedUI
Call the SetExtendedUI member function to select either the default user interface or the extended user interface
for a combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

int SetExtendedUI(BOOL bExtended = TRUE);

Parameters
bExtended
Specifies whether the combo box should use the extended user interface or the default user interface. A value of
TRUE selects the extended user interface; a value of FALSE selects the standard user interface.
Return Value
CB_OKAY if the operation is successful, or CB_ERR if an error occurs.
Remarks
The extended user interface can be identified in the following ways:
Clicking the static control displays the list box only for combo boxes with the CBS_DROPDOWNLIST style.
Pressing the DOWN ARROW key displays the list box (F4 is disabled).
Scrolling in the static control is disabled when the item list is not visible (the arrow keys are disabled).
Example
See the example for CComboBox::GetExtendedUI.

CComboBox::SetHorizontalExtent
Sets the width, in pixels, by which the list-box portion of the combo box can be scrolled horizontally.

void SetHorizontalExtent(UINT nExtent);

Parameters
nExtent
Specifies the number of pixels by which the list-box portion of the combo box can be scrolled horizontally.
Remarks
If the width of the list box is smaller than this value, the horizontal scroll bar will horizontally scroll items in the
list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if
the combo box has the CBS_DISABLENOSCROLL style, disabled.
Example

// Find the longest string in the combo box.


CString str;
CSize sz;
int dx = 0;
TEXTMETRIC tm;
CDC *pDC = m_pComboBox->GetDC();
CFont *pFont = m_pComboBox->GetFont();

// Select the listbox font, save the old font


CFont *pOldFont = pDC->SelectObject(pFont);
// Get the text metrics for avg char width
pDC->GetTextMetrics(&tm);

for (int i = 0; i < m_pComboBox->GetCount(); i++)


{
m_pComboBox->GetLBText(i, str);
sz = pDC->GetTextExtent(str);

// Add the avg width to prevent clipping


sz.cx += tm.tmAveCharWidth;

if (sz.cx > dx)


dx = sz.cx;
}
// Select the old font back into the DC
pDC->SelectObject(pOldFont);
m_pComboBox->ReleaseDC(pDC);

// Set the horizontal extent so every character of all strings can


// be scrolled to.
m_pComboBox->SetHorizontalExtent(dx);

CComboBox::SetItemData
Sets the 32-bit value associated with the specified item in a combo box.

int SetItemData(
int nIndex,
DWORD_PTR dwItemData);

Parameters
nIndex
Contains a zero-based index to the item to set.
dwItemData
Contains the new value to associate with the item.
Return Value
CB_ERR if an error occurs.
Remarks
Use the SetItemDataPtr member function if the 32-bit item is to be a pointer.
Example

// Set the data of each item to be equal to its index.


for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
m_pComboBox->SetItemData(i, i);
}

CComboBox::SetItemDataPtr
Sets the 32-bit value associated with the specified item in a combo box to be the specified pointer (void * ).

int SetItemDataPtr(
int nIndex,
void* pData);

Parameters
nIndex
Contains a zero-based index to the item.
pData
Contains the pointer to associate with the item.
Return Value
CB_ERR if an error occurs.
Remarks
This pointer remains valid for the life of the combo box, even though the item's relative position within the
combo box might change as items are added or removed. Hence, the item's index within the box can change, but
the pointer remains reliable.
Example

// Set the data pointer of each item to be NULL.


for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
m_pComboBox->SetItemDataPtr(i, NULL);
}

CComboBox::SetItemHeight
Call the SetItemHeight member function to set the height of list items in a combo box or the height of the edit-
control (or static-text) portion of a combo box.

int SetItemHeight(
int nIndex,
UINT cyItemHeight);

Parameters
nIndex
Specifies whether the height of list items or the height of the edit-control (or static-text) portion of the combo
box is set.
If the combo box has the CBS_OWNERDRAWVARIABLE style, nIndex specifies the zero-based index of the list
item whose height is to be set; otherwise, nIndex must be 0 and the height of all list items will be set.
If nIndex is -1, the height of the edit-control or static-text portion of the combo box is to be set.
cyItemHeight
Specifies the height, in pixels, of the combo-box component identified by nIndex.
Return Value
CB_ERR if the index or height is invalid; otherwise 0.
Remarks
The height of the edit-control (or static-text) portion of the combo box is set independently of the height of the
list items. An application must ensure that the height of the edit-control (or static-text) portion is not smaller
than the height of a particular list-box item.
Example

// Set the height of every item to be the


// vertical size of the item's text extent.
CString str;
CSize sz;
CDC *pDC = m_pComboBox->GetDC();
for (int i = 0; i < m_pComboBox->GetCount(); i++)
{
m_pComboBox->GetLBText(i, str);
sz = pDC->GetTextExtent(str);

m_pComboBox->SetItemHeight(i, sz.cy);
}
m_pComboBox->ReleaseDC(pDC);

CComboBox::SetLocale
Sets the locale identifier for this combo box.

LCID SetLocale(LCID nNewLocale);

Parameters
nNewLocale
The new locale identifier (LCID) value to set for the combo box.
Return Value
The previous locale identifier (LCID) value for this combo box.
Remarks
If SetLocale is not called, the default locale is obtained from the system. This system default locale can be
modified by using Control Panel's Regional (or International) application.
Example

// My LCID to use.
LCID mylcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN),
SORT_DEFAULT);

// Force the list box to use my locale.


m_pComboBox->SetLocale(mylcid);
ASSERT(m_pComboBox->GetLocale() == mylcid);
CComboBox::SetMinVisibleItems
Sets the minimum number of visible items in the drop-down list of the current combo box control.

BOOL SetMinVisibleItems(int iMinVisible);

Parameters
PA RA M ET ER DESC RIP T IO N

iMinVisible [in] Specifies the minimum number of visible items.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the CB_SETMINVISIBLE message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_combobox, that is used to programmatically access the
combo box control. This variable is used in the next example.

// Variable to access the combo box control


CComboBox m_combobox;

Example
The following code example inserts 20 items into the drop-down list of a combo box control. Then it specifies
that a minimum of 10 items be displayed when a user presses the drop-down arrow.

// Add extra initialization here.

// Add 20 items to the combo box. The Resource Editor


// has already been used to set the style of the combo
// box to CBS_SORT.
CString str;
for (int i = 1; i <= 20; i++)
{
str.Format(_T("Item %2d"), i);
m_combobox.AddString(str);
}
// Set the minimum visible item
m_combobox.SetMinVisibleItems(10);
// Set the cue banner
m_combobox.SetCueBanner(_T("Select an item..."));

// End of extra initialization.

CComboBox::SetTopIndex
Ensures that a particular item is visible in the list-box portion of the combo box.

int SetTopIndex(int nIndex);

Parameters
nIndex
Specifies the zero-based index of the list-box item.
Return Value
Zero if successful, or CB_ERR if an error occurs.
Remarks
The system scrolls the list box until either the item specified by nIndex appears at the top of the list box or the
maximum scroll range has been reached.
Example

// Set the first visible item in the combo box to be the middle item
m_pComboBox->SetTopIndex(m_pComboBox->GetCount() / 2);

CComboBox::ShowDropDown
Shows or hides the list box of a combo box that has the CBS_DROPDOWN or CBS_DROPDOWNLIST style.

void ShowDropDown(BOOL bShowIt = TRUE);

Parameters
bShowIt
Specifies whether the drop-down list box is to be shown or hidden. A value of TRUE shows the list box. A value
of FALSE hides the list box.
Remarks
By default, a combo box of this style will show the list box.
This member function has no effect on a combo box created with the CBS_SIMPLE style.
Example
See the example for CComboBox::GetDroppedState.

See also
MFC Sample CTRLBARS
CWnd Class
Hierarchy Chart
CWnd Class
CButton Class
CEdit Class
CListBox Class
CScrollBar Class
CStatic Class
CDialog Class
CComboBoxEx Class
4/21/2020 • 9 minutes to read • Edit Online

Extends the combo box control by providing support for image lists.

Syntax
class CComboBoxEx : public CComboBox

Members
Public Constructors
NAME DESC RIP T IO N

CComboBoxEx::CComboBoxEx Constructs a CComboBoxEx object.

Public Methods
NAME DESC RIP T IO N

CComboBoxEx::Create Creates the combo box and attaches it to the CComboBoxEx


object.

CComboBoxEx::CreateEx Creates a combo box with the specified Windows extended


styles and attaches it to a ComboBoxEx object.

CComboBoxEx::DeleteItem Removes an item from a ComboBoxEx control.

CComboBoxEx::GetComboBoxCtrl Retrieves a pointer to the child combo box control.

CComboBoxEx::GetEditCtrl Retrieves the handle to the edit control portion of a


ComboBoxEx control.

CComboBoxEx::GetExtendedStyle Retrieves the extended styles that are in use for a


ComboBoxEx control.

CComboBoxEx::GetImageList Retrieves a pointer to the image list assigned to a


ComboBoxEx control.

CComboBoxEx::GetItem Retrieves item information for a given ComboBoxEx item.

CComboBoxEx::HasEditChanged Determines if the user has changed the contents of the


ComboBoxEx edit control by typing.

CComboBoxEx::InsertItem Inserts a new item in a ComboBoxEx control.

CComboBoxEx::SetExtendedStyle Sets extended styles within a ComboBoxEx control.


NAME DESC RIP T IO N

CComboBoxEx::SetImageList Sets an image list for a ComboBoxEx control.

CComboBoxEx::SetItem Sets the attributes for an item in a ComboBoxEx control.

CComboBoxEx::SetWindowTheme Sets the visual style of the extended combo box control.

Remarks
By using CComboBoxEx to create combo box controls, you no longer need to implement your own image drawing
code. Instead, use CComboBoxEx to access images from an image list.

Image List Support


In a standard combo box, the owner of the combo box is responsible for drawing an image by creating the combo
box as an owner-draw control. When you use CComboBoxEx , you do not need to set the drawing styles
CBS_OWNERDRAWFIXED and CBS_HASSTRINGS because they are implied. Otherwise, you must write code to
perform drawing operations. A CComboBoxEx control supports up to three images per item: one for a selected state,
one for an unselected state, and one for an overlay image.

Styles
CComboBoxEx supports the styles CBS_SIMPLE, CBS_DROPDOWN, CBS_DROPDOWNLIST, and WS_CHILD. All other
styles passed when you create the window are ignored by the control. After the window is created, you can
provide other combo box styles by calling the CComboBoxEx member function SetExtendedStyle. With these styles,
you can:
Set string searches in the list to be case-sensitive.
Create a combo box control that uses the slash ('/'), backslash ('\'), and period ('.') characters as word
delimiters. This allow users to jump from word to word, using the keyboard shortcut CTRL+ ARROW.
Set the combo box control to either display or not display an image. If no image is displayed, the combo
box can remove the text indent that accommodates an image.
Create a narrow combo box control, including sizing it so it clips the wider combo box it contains.
These style flags are described further in Using CComboBoxEx.

Item Retention and Callback Item Attributes


Item information, such as indexes for items and images, indentation values, and text strings, is stored in the Win32
structure COMBOBOXEXITEM, as described in the Windows SDK. The structure also contains members that
correspond to callback flags.
For a detailed, conceptual discussion, see Using CComboBoxEx.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CComboBox
CComboBoxEx

Requirements
Header : afxcmn.h

CComboBoxEx::CComboBoxEx
Call this member function to create a CComboBoxEx object.

CComboBoxEx();

CComboBoxEx::Create
Creates the combo box and attaches it to the CComboBoxEx object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the combination of combo box styles applied to the combo box. See Remarks below for more
information about styles.
rect
A reference to a CRect object or RECT structure, which is the position and size of the combo box.
pParentWnd
A pointer to a CWnd object that is the parent window of the combo box (usually a CDialog ). It must not be NULL.
nID
Specifies the combo box's control ID.
Return Value
Nonzero if the object was created successfully; otherwise 0.
Remarks
Create a CComboBoxEx object in two steps:
1. Call CComboBoxEx to construct a CComboBoxEx object.
2. Call this member function, which creates the extended Windows combo box and attaches it to the
CComboBoxEx object.

When you call Create , MFC initializes the common controls.


When you create the combo box, you can specify any or all of the following combo-box styles:
CBS_SIMPLE
CBS_DROPDOWN
CBS_DROPDOWNLIST
CBS_AUTOHSCROLL
WS_CHILD
All other styles passed when you create the window are ignored. The ComboBoxEx control also supports extended
styles that provide additional features. These styles are described in ComboBoxEx control extended styles, in the
Windows SDK. Set these styles by calling SetExtendedStyle.
If you want to use extended windows styles with your control, call CreateEx instead of Create .

CComboBoxEx::CreateEx
Call this function to create an extended combo box control (a child window) and associate it with the CComboBoxEx
object.

virtual BOOL CreateEx(


DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the dwExStyle
parameter for CreateWindowEx in the Windows SDK.
dwStyle
The combo box control's style. See Create for a list of styles.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client coordinates
of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended style
preface WS_EX_ .
CreateEx creates the control with the extended Windows styles specified by dwExStyle. You must set extended
styles specific to an extended combo box control using SetExtendedStyle. For example, use CreateEx to set such
styles as WS_EX_CONTEXTHELP, but use SetExtendedStyle to set such styles as CBES_EX_CASESENSITIVE. For
more information, see the styles described in the topic ComboBoxEx Control Extended Styles in the Windows SDK.

CComboBoxEx::DeleteItem
Removes an item from a ComboBoxEx control.
int DeleteItem(int iIndex);

Parameters
iIndex
Zero-based index of the item to be removed.
Return Value
The number of items remaining in the control. If iIndex is invalid, the function returns CB_ERR.
Remarks
This member function implements the functionality of the message CBEM_DELETEITEM, as described in the
Windows SDK. When you call DeleteItem, a WM_NOTIFY message with CBEN_DELETEITEM notification will be sent
to the parent window.

CComboBoxEx::GetComboBoxCtrl
Call this member function to get a pointer to a combo box control within a CComboBoxEx object.

CComboBox* GetComboBoxCtrl();

Return Value
A pointer to a CComboBox object.
Remarks
The CComboBoxEx control consists of a parent window, which encapsulates a CComboBox .
The CComboBox object pointed to by the return value is a temporary object and is destroyed during the next idle
processing time.

CComboBoxEx::GetEditCtrl
Call this member function to get a pointer to the edit control for a combo box.

CEdit* GetEditCtrl();

Return Value
A pointer to a CEdit object.
Remarks
A CComboBoxEx control uses an edit box when it is created with the CBS_DROPDOWN style.
The CEdit object pointed to by the return value is a temporary object and is destroyed during the next idle
processing time.

CComboBoxEx::GetExtendedStyle
Call this member function to get the extended styles used for a CComboBoxEx control.

DWORD GetExtendedStyle() const;

Return Value
The DWORD value that contains the extended styles that are used for the combo box control.
Remarks
See ComboBoxEx Control Extended Styles in the Windows SDK for more information about these styles.

CComboBoxEx::GetImageList
Call this member function to get a pointer to the image list used by a CComboBoxEx control.

CImageList* GetImageList() const;

Return Value
A pointer to a CImageList object. If it fails, this member function returns NULL.
Remarks
The CImageList object pointed to by the return value is a temporary object and is destroyed during the next idle
processing time.

CComboBoxEx::GetItem
Retrieves item information for a given ComboBoxEx item.

BOOL GetItem(COMBOBOXEXITEM* pCBItem);

Parameters
pCBItem
A pointer to a COMBOBOXEXITEM structure that will receive the item information.
Return Value
Nonzero if the operation was successful; otherwise 0.
Remarks
This member function implements the functionality of the message CBEM_GETITEM, as described in the Windows
SDK.

CComboBoxEx::HasEditChanged
Determines if the user has changed the contents of the ComboBoxEx edit control by typing.

BOOL HasEditChanged();

Return Value
Nonzero if the user has typed in the control's edit box; otherwise 0.
Remarks
This member function implements the functionality of the message CBEM_HASEDITCHANGED, as described in the
Windows SDK.

CComboBoxEx::InsertItem
Inserts a new item in a ComboBoxEx control.
int InsertItem(const COMBOBOXEXITEM* pCBItem);

Parameters
pCBItem
A pointer to a COMBOBOXEXITEM structure that will receive the item information. This structure contains callback
flag values for the item.
Return Value
The index at which the new item was inserted if successful; otherwise -1.
Remarks
When you call InsertItem , a WM_NOTIFY message with CBEN_INSERTITEM notification will be sent to the parent
window.

CComboBoxEx::SetExtendedStyle
Call this member function to set the extended styles used for a combo box extended control.

DWORD SetExtendedStyle(
DWORD dwExMask,
DWORD dwExStyles);

Parameters
dwExMask
A DWORD value that indicates which styles in dwExStyles are to be affected. Only the extended styles in dwExMask
will be changed. All other styles will be maintained as is. If this parameter is zero, then all of the styles in
dwExStyles will be affected.
dwExStyles
A DWORD value that contains the combo box control extended styles to set for the control.
Return Value
A DWORD value that contains the extended styles previously used for the control.
Remarks
See ComboBoxEx Control Extended Styles in the Windows SDK for more information about these styles.
To create a combo box extended control with extended windows styles, use CreateEx.

CComboBoxEx::SetImageList
Sets an image list for a ComboBoxEx control.

CImageList* SetImageList(CImageList* pImageList);

Parameters
pImageList
A pointer to a CImageList object containing the images to use with the CComboBoxEx control.
Return Value
A pointer to a CImageList object containing the images previously used by the CComboBoxEx control. NULL if no
image list was previously set.
Remarks
This member function implements the functionality of the message CBEM_SETIMAGELIST, as described in the
Windows SDK. If you change the height of the default edit control, call the Win32 function SetWindowPos to resize
your control after you call SetImageList , or it will not display properly.
The CImageList object pointed to by the return value is a temporary object and is destroyed during the next idle
processing time.

CComboBoxEx::SetItem
Sets the attributes for an item in a ComboBoxEx control.

BOOL SetItem(const COMBOBOXEXITEM* pCBItem);

Parameters
pCBItem
A pointer to a COMBOBOXEXITEM structure that will receive the item information.
Return Value
Nonzero if the operation was successful; otherwise 0.
Remarks
This member function implements the functionality of the message CBEM_SETITEM, as described in the Windows
SDK.

CComboBoxEx::SetWindowTheme
Sets the visual style of the extended combo box control.

HRESULT SetWindowTheme(LPCWSTR pszSubAppName);

Parameters
pszSubAppName
A pointer to a Unicode string that contains the extended combo box visual style to set.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the CBEM_SETWINDOWTHEME message, as described in the
Windows SDK.

See also
MFC Sample MFCIE
CComboBox Class
Hierarchy Chart
CComboBox Class
CCommandLineInfo Class
3/27/2020 • 6 minutes to read • Edit Online

Aids in parsing the command line at application startup.

Syntax
class CCommandLineInfo : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CCommandLineInfo::CCommandLineInfo Constructs a default CCommandLineInfo object.

Public Methods
NAME DESC RIP T IO N

CCommandLineInfo::ParseParam Override this callback to parse individual parameters.

Public Data Members


NAME DESC RIP T IO N

CCommandLineInfo::m_bRunAutomated Indicates the command-line /Automation option was found.

CCommandLineInfo::m_bRunEmbedded Indicates the command-line /Embedding option was found.

CCommandLineInfo::m_bShowSplash Indicates if a splash screen should be shown.

CCommandLineInfo::m_nShellCommand Indicates the shell command to be processed.

CCommandLineInfo::m_strDriverName Indicates the driver name if the shell command is Print To;
otherwise empty.

CCommandLineInfo::m_strFileName Indicates the file name to be opened or printed; empty if the


shell command is New or DDE.

CCommandLineInfo::m_strPortName Indicates the port name if the shell command is Print To;
otherwise empty.

CCommandLineInfo::m_strPrinterName Indicates the printer name if the shell command is Print To;
otherwise empty.

CCommandLineInfo::m_strRestartIdentifier Indicates the unique restart identifier for the restart manager
if the restart manager restarted the application.
Remarks
An MFC application will typically create a local instance of this class in the InitInstance function of its application
object. This object is then passed to CWinApp::ParseCommandLine, which repeatedly calls ParseParam to fill the
CCommandLineInfo object. The CCommandLineInfo object is then passed to CWinApp::ProcessShellCommand to
handle the command-line arguments and flags.
You can use this object to encapsulate the following command-line options and parameters:

C O M M A N D- L IN E A RGUM EN T C O M M A N D EXEC UT ED

app New file.

app filename Open file.

app /p filename Print file to default printer.

app /pt filename printer driver port Print file to the specified printer.

app /dde Start up and await DDE command.

app /Automation Start up as an OLE automation server.

app /Embedding Start up to edit an embedded OLE item.

app /Register Informs the application to perform any registration tasks.

app /Regserver

app /Unregister Informs the application to perform any un-registration tasks.

app /Unregserver

Derive a new class from CCommandLineInfo to handle other flags and parameter values. Override ParseParam to
handle the new flags.

Inheritance Hierarchy
CObject
CCommandLineInfo

Requirements
Header : afxwin.h

CCommandLineInfo::CCommandLineInfo
This constructor creates a CCommandLineInfo object with default values.

CCommandLineInfo();

Remarks
The default is to show the splash screen ( m_bShowSplash=TRUE ) and to execute the New command on the File menu
( m_nShellCommand =NewFile ).
The application framework calls ParseParam to fill data members of this object.
Example

CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

CCommandLineInfo::m_bRunAutomated
Indicates that the /Automation flag was found on the command line.

BOOL m_bRunAutomated;

Remarks
If TRUE, this means start up as an OLE automation server.

CCommandLineInfo::m_bRunEmbedded
Indicates that the /Embedding flag was found on the command line.

BOOL m_bRunEmbedded;

Remarks
If TRUE, this means start up for editing an embedded OLE item.

CCommandLineInfo::m_bShowSplash
Indicates that the splash screen should be displayed.

BOOL m_bShowSplash;

Remarks
If TRUE, this means the splash screen for this application should be displayed during startup. The default
implementation of ParseParam sets this data member to TRUE if m_nShellCommand is equal to
CCommandLineInfo::FileNew .

CCommandLineInfo::m_nShellCommand
Indicates the shell command for this instance of the application.

m_nShellCommand;

Remarks
The type for this data member is the following enumerated type, which is defined in the CCommandLineInfo class.
enum {
FileNew,
FileOpen,
FilePrint,
FilePrintTo,
FileDDE,
AppRegister,
AppUnregister,
RestartByRestartManager,
FileNothing = -1
};

For a brief description of these values, see the following list.


CCommandLineInfo::FileNew Indicates that no file name was found on the command line.
CCommandLineInfo::FileOpen Indicates that a file name was found on the command line and that none of the
following flags were found on the command line: /p , /pt , /dde .
CCommandLineInfo::FilePrint Indicates that the /p flag was found on the command line.
CCommandLineInfo::FilePrintTo Indicates that the /pt flag was found on the command line.
CCommandLineInfo::FileDDE Indicates that the /dde flag was found on the command line.
CCommandLineInfo::AppRegisterIndicates that the /Register or /Regserver flag was found on the
command line and the application was asked to register.
CCommandLineInfo::AppUnregister Indicates that the /Unregister or /Unregserver application was asked to
unregister.
CCommandLineInfo::RestartByRestartManager Indicates that the application was restarted by the restart
manager.
CCommandLineInfo::FileNothing Turns off the display of a new MDI child window on startup. By design,
Application Wizard-generated MDI applications display a new child window on startup. To turn off this
feature, an application can use CCommandLineInfo::FileNothing as the shell command when it calls
ProcessShellCommand. ProcessShellCommand is called by the InitInstance( ) of all CWinApp derived
classes.
Example

// From CMyWinApp::InitInstance

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

// DON'T display a new MDI child window during startup!!!


cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;

// Dispatch commands specified on the command line


if (!ProcessShellCommand(cmdInfo))
{
return FALSE;
}

CCommandLineInfo::m_strDriverName
Stores the value of the third non-flag parameter on the command line.
CString m_strDriverName;

Remarks
This parameter is typically the name of the printer driver for a Print To shell command. The default implementation
of ParseParam sets this data member only if the /pt flag was found on the command line.

CCommandLineInfo::m_strFileName
Stores the value of the first non-flag parameter on the command line.

CString m_strFileName;

Remarks
This parameter is typically the name of the file to open.

CCommandLineInfo::m_strPortName
Stores the value of the fourth non-flag parameter on the command line.

CString m_strPortName;

Remarks
This parameter is typically the name of the printer port for a Print To shell command. The default implementation
of ParseParam sets this data member only if the /pt flag was found on the command line.

CCommandLineInfo::m_strPrinterName
Stores the value of the second non-flag parameter on the command line.

CString m_strPrinterName;

Remarks
This parameter is typically the name of the printer for a Print To shell command. The default implementation of
ParseParam sets this data member only if the /pt flag was found on the command line.

CCommandLineInfo::m_strRestartIdentifier
The unique restart identifier on the command line.

CString m_strRestartIdentifier;

Remarks
The restart identifier is unique for each instance of the application.
If the restart manager exits the application and is configured to restart it, the restart manager executes the
application from the command line with the restart identifier as an optional parameter. When the restart manager
uses the restart identifier, the application can reopen the previously open documents and recover autosaved files.

CCommandLineInfo::ParseParam
The framework calls this function to parse/interpret individual parameters from the command line. The second
version differs from the first only in Unicode projects.

virtual void ParseParam(


const char* pszParam,
BOOL bFlag,
BOOL bLast);

virtual void ParseParam(


const TCHAR* pszParam,
BOOL bFlag,
BOOL bLast);

Parameters
pszParam
The parameter or flag.
bFlag
Indicates whether pszParam is a parameter or a flag.
bLast
Indicates if this is the last parameter or flag on the command line.
Remarks
CWinApp::ParseCommandLine calls ParseParam once for each parameter or flag on the command line, passing the
argument to pszParam. If the first character of the parameter is a ' - ' or a ' / ', then it is removed and bFlag is set to
TRUE. When parsing the final parameter, bLast is set to TRUE.
The default implementation of this function recognizes the following flags: /p , /pt , /dde , /Automation , and
/Embedding , as shown in the following table:

C O M M A N D- L IN E A RGUM EN T C O M M A N D EXEC UT ED

app New file.

app filename Open file.

app /p filename Print file to default printer.

app /pt filename printer driver port Print file to the specified printer.

app /dde Start up and await DDE command.

app /Automation Start up as an OLE automation server.

app /Embedding Start up to edit an embedded OLE item.

app /Register Informs the application to perform any registration tasks.

app /Regserver

app /Unregister Informs the application to perform any un-registration tasks.

app /Unregserver
This information is stored in m_bRunAutomated, m_bRunEmbedded, and m_nShellCommand. Flags are marked
by either a forward-slash ' / ' or hyphen ' - '.
The default implementation puts the first non-flag parameter into m_strFileName. In the case of the /pt flag, the
default implementation puts the second, third, and fourth non-flag parameters into m_strPrinterName,
m_strDriverName, and m_strPortName, respectively.
The default implementation also sets m_bShowSplash to TRUE only in the case of a new file. In the case of a new
file, the user has taken action involving the application itself. In any other case, including opening existing files
using the shell, the user action involves the file directly. In a document-centric standpoint, the splash screen does
not need to announce the application starting up.
Override this function in your derived class to handle other flag and parameter values.

See also
CObject Class
Hierarchy Chart
CWinApp::ParseCommandLine
CWinApp::ProcessShellCommand
CCommonDialog Class
3/27/2020 • 2 minutes to read • Edit Online

The base class for classes that encapsulate functionality of the Windows common dialogs.

Syntax
class CCommonDialog : public CDialog

Members
Public Constructors
NAME DESC RIP T IO N

CCommonDialog::CCommonDialog Constructs a CCommonDialog object.

Remarks
The following classes encapsulate the functionality of the Windows common dialogs:
CFileDialog
CFontDialog
CColorDialog
CPageSetupDialog
CPrintDialog
CPrintDialogEx
CFindReplaceDialog
COleDialog

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog

Requirements
Header : afxdlgs.h
CCommonDialog::CCommonDialog
Constructs a CCommonDialog object.

explicit CCommonDialog(CWnd* pParentWnd);

Parameters
pParentWnd
Points to the parent or owner window object (of type CWnd) to which the dialog object belongs. If it is NULL,
the dialog object's parent window is set to the main application window.
Remarks
See CDialog::CDialog for complete information.

See also
CDialog Class
Hierarchy Chart
CFileDialog Class
CFontDialog Class
CColorDialog Class
CPageSetupDialog Class
CPrintDialog Class
CFindReplaceDialog Class
COleDialog Class
CConnectionPoint Class
3/27/2020 • 5 minutes to read • Edit Online

Defines a special type of interface used to communicate with other OLE objects, called a "connection point."

Syntax
class CConnectionPoint : public CCmdTarget

Members
Public Constructors
NAME DESC RIP T IO N

CConnectionPoint::CConnectionPoint Constructs a CConnectionPoint object.

Public Methods
NAME DESC RIP T IO N

CConnectionPoint::GetConnections Retrieves all connection points in a connection map.

CConnectionPoint::GetContainer Retrieves the container of the control that owns the


connection map.

CConnectionPoint::GetIID Retrieves the interface ID of a connection point.

CConnectionPoint::GetMaxConnections Retrieves the maximum number of connection points


supported by a control.

CConnectionPoint::GetNextConnection Retrieves a pointer to the connection element at pos.

CConnectionPoint::GetStartPosition Starts a map iteration by returning a POSITION value that can


be passed to a GetNextConnection call.

CConnectionPoint::OnAdvise Called by the framework when establishing or breaking


connections.

CConnectionPoint::QuerySinkInterface Retrieves a pointer to the requested sink interface.

Remarks
Unlike normal OLE interfaces, which are used to implement and expose the functionality of an OLE control, a
connection point implements an outgoing interface that is able to initiate actions on other objects, such as firing
events and change notifications.
A connection consists of two parts: the object calling the interface, called the "source," and the object implementing
the interface, called the "sink." By exposing a connection point, a source allows sinks to establish connections to
itself. Through the connection point mechanism, a source object obtains a pointer 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.
By default, a COleControl -derived class implements two connection points: one for events and one for property
change notifications. These connections are used, respectively, for event firing and for notifying a sink (for
example, the control's container) when a property value has changed. Support is also provided for OLE controls to
implement additional connection points. For each additional connection point implemented in your control class,
you must declare a "connection part" that implements the connection point. If you implement one or more
connection points, you also need to declare a single "connection map" in your control class.
The following example demonstrates a simple connection map and one connection point for the Sample OLE
control, consisting of two fragments of code: the first portion declares the connection map and point; the second
implements this map and point. The first fragment is inserted into the declaration of the control class, under the
protected section:

// Connection point for ISample interface


BEGIN_CONNECTION_PART(CMyClass, SampleConnPt)
CONNECTION_IID(IID_ISampleSink)
END_CONNECTION_PART(SampleConnPt)

DECLARE_CONNECTION_MAP()

The BEGIN_CONNECTION_PART and END_CONNECTION_PART macros declare an embedded class, XSampleConnPt


(derived from CConnectionPoint ) that implements this particular connection point. If you want to override any
CConnectionPoint member functions, or add member functions of your own, declare them between these two
macros. For example, the CONNECTION_IID macro overrides the CConnectionPoint::GetIID member function
when placed between these two macros.
The second code fragment is inserted into the implementation file (.CPP) of your control class. This code
implements the connection map, which includes the additional connection point, SampleConnPt :

BEGIN_CONNECTION_MAP(CMyClass, CCmdTarget)
CONNECTION_PART(CMyClass, IID_ISampleSink, SampleConnPt)
END_CONNECTION_MAP()

Once these code fragments have been inserted, the Sample OLE control exposes a connection point for the
ISampleSink interface.

Typically, connection points support "multicasting", which is the ability to broadcast to multiple sinks connected to
the same interface. The following code fragment demonstrates how to accomplish multicasting by iterating
through each sink on a connection point:

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.
For more information on using CConnectionPoint , see the article Connection Points.

Inheritance Hierarchy
CObject
CCmdTarget
CConnectionPoint

Requirements
Header : afxdisp.h

CConnectionPoint::CConnectionPoint
Constructs a CConnectionPoint object.

CConnectionPoint();

CConnectionPoint::GetConnections
Call this function to retrieve all active connections for a connection point.

const CPtrArray* GetConnections();

Return Value
A pointer to an array of active connections (sinks). Some of the pointers in the array may be NULL. Each non-NULL
pointer in this array can be safely converted to a pointer to the sink interface using a cast operator.

CConnectionPoint::GetContainer
Called by the framework to retrieve the IConnectionPointContainer for the connection point.

virtual LPCONNECTIONPOINTCONTAINER GetContainer();

Return Value
If successful, a pointer to the container; otherwise NULL.
Remarks
This function is typically implemented by the BEGIN_CONNECTION_PART macro.

CConnectionPoint::GetIID
Called by the framework to retrieve the interface ID of a connection point.

virtual REFIID GetIID() = 0;


Return Value
A reference to the connection point's interface ID.
Remarks
Override this function to return the interface ID for this connection point.

CConnectionPoint::GetMaxConnections
Called by the framework to retrieve the maximum number of connections supported by the connection point.

virtual int GetMaxConnections();

Return Value
The maximum number of connections supported by the control, or -1 if no limit.
Remarks
The default implementation returns -1, indicating no limit.
Override this function if you want to limit the number of sinks that can connect to your control.

CConnectionPoint::GetNextConnection
Retrieves a pointer to the connection element at pos.

LPUNKNOWN GetNextConnection(POSITION& pos) const;

Parameters
pos
Specifies a reference to a POSITION value returned by a previous GetNextConnection or GetStartPosition call.
Return Value
A pointer to the connection element specified by pos, or NULL.
Remarks
This function is most useful for iterating through all the elements in the connection map. When iterating, skip any
NULLs returned from this function.
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();
}
}
}

CConnectionPoint::GetStartPosition
Starts a map iteration by returning a POSITION value that can be passed to a GetNextConnection call.

POSITION GetStartPosition() const;

Return Value
A POSITION value that indicates a starting position for iterating the map; or NULL if the map is empty.
Remarks
The iteration sequence is not predictable; therefore, the "first element in the map" has no special significance.
Example
See the example for CConnectionPoint::GetNextConnection.

CConnectionPoint::OnAdvise
Called by the framework when a connection is being established or broken.

virtual void OnAdvise(BOOL bAdvise);

Parameters
bAdvise
TRUE, if a connection is being established; otherwise FALSE.
Remarks
The default implementation does nothing.
Override this function if you want notification when sinks connect to or disconnect from your connection point.

CConnectionPoint::QuerySinkInterface
Retrieves a pointer to the requested sink interface.

virtual HRESULT QuerySinkInterface(


LPUNKNOWN pUnkSink,
void** ppInterface);

Parameters
pUnkSink
The identifier of the sink interface being requested.
ppInterface
A pointer to the interface pointer identified by pUnkSink. If the object does not support this interface, * ppInterface
is set to NULL.
Return Value
A standard HRESULT value.

See also
CCmdTarget Class
Hierarchy Chart
CConstantTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates a constant transition.

Syntax
class CConstantTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CConstantTransition::CConstantTransition Constructs a transition object and initializes its duration.

Public Methods
NAME DESC RIP T IO N

CConstantTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CConstantTransition::m_duration The duration of the transition.

Remarks
During a constant transition, the value of an animation variable remains at the initial value over the duration of the
transition. Because all transitions are cleared automatically, it's recommended to allocated them using operator
new. The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup,
until then it's NULL. Changing member variables after creation of this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CConstantTransition

Requirements
Header : afxanimationcontroller.h
CConstantTransition::CConstantTransition
Constructs a transition object and initializes its duration.

CConstantTransition (UI_ANIMATION_SECONDS duration);

Parameters
duration
The duration of the transition.

CConstantTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CConstantTransition::m_duration
The duration of the transition.

UI_ANIMATION_SECONDS m_duration;

See also
Classes
CContextMenuManager Class
4/21/2020 • 7 minutes to read • Edit Online

The CContextMenuManager object manages shortcut menus, also known as context menus.

Syntax
class CContextMenuManager : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CContextMenuManager::CContextMenuManager Constructs a CContextMenuManager object.

CContextMenuManager::~CContextMenuManager Destructor.

Public Methods
NAME DESC RIP T IO N

CContextMenuManager::AddMenu Adds a new shortcut menu.

CContextMenuManager::GetMenuById Returns a handle to the menu associated with the provided


resource ID.

CContextMenuManager::GetMenuByName Returns a handle to the menu that matches the provided


menu name.

CContextMenuManager::GetMenuNames Returns a list of menu names.

CContextMenuManager::LoadState Loads shortcut menus stored in the Windows registry.

CContextMenuManager::ResetState Clears the shortcut menus from the context menu manager.

CContextMenuManager::SaveState Saves shortcut menus to the Windows registry.

CContextMenuManager::SetDontCloseActiveMenu Controls whether the CContextMenuManager closes the


active shortcut menu when it shows a new shortcut menu.

CContextMenuManager::ShowPopupMenu Displays the specified shortcut menu.

CContextMenuManager::TrackPopupMenu Displays the specified shortcut menu. Returns the index of


the selected menu command.

Remarks
CContextMenuManager manages shortcut menus and makes sure that they have a consistent appearance.
You should not create a CContextMenuManager object manually. The framework of your application creates the
CContextMenuManager object. However, you should call CWinAppEx::InitContextMenuManager when your
application is initialized. After initializing the context manager, use the method
CWinAppEx::GetContextMenuManager to obtain a pointer to the context manager for your application.
You can create shortcut menus at runtime by calling AddMenu . If you want to show the menu without first
receiving user input, call ShowPopupMenu . TrackPopupMenu is used when you want to create a menu and wait for
user input. TrackPopupMenu returns the index of the selected command or 0 if the user exited without selecting
anything.
The CContextMenuManager can also save and load its state to the Windows registry.

Example
The following example demonstrates how to add a menu to a CContextMenuManager object, and how not to close
the active pop-up menu when the CContextMenuManager object displays a new pop-up menu. This code snippet is
part of the Custom Pages sample.

// The GetContextMenuManager method is inherited from the CWinAppEx class.


GetContextMenuManager()->AddMenu(_T("My menu"), IDR_CONTEXT_MENU);
GetContextMenuManager()->SetDontCloseActiveMenu(true);

Inheritance Hierarchy
CObject
CContextMenuManager

Requirements
Header : afxcontextmenumanager.h

CContextMenuManager::AddMenu
Adds a new shortcut menu to the CContextMenuManager.

BOOL AddMenu(
UINT uiMenuNameResId,
UINT uiMenuResId);

BOOL AddMenu(
LPCTSTR lpszName,
UINT uiMenuResId);

Parameters
uiMenuNameResId
[in] A resource ID for a string that contains the name for the new menu.
uiMenuResId
[in] The menu resource ID.
lpszName
[in] A string that contains the name for the new menu.
Return Value
Nonzero if the method was successful; 0 if the method fails.
Remarks
This method fails if uiMenuResId is invalid or if another menu with the same name already is in the
CContextMenuManager .

CContextMenuManager::CContextMenuManager
Constructs a CContextMenuManager object.

CContextMenuManager();

Remarks
In most cases, you should not create a CContextMenuManager manually. The framework of your application creates
the CContextMenuManager object. You should call CWinAppEx::InitContextMenuManager during the initialization of
your application. To get a pointer to the context manager, call CWinAppEx::GetContextMenuManager.

CContextMenuManager::GetMenuById
Returns a handle to the menu associated with a given resource ID.

HMENU GetMenuById(UINT nMenuResId) const;

Parameters
nMenuResId
[in] The resource ID for the menu.
Return Value
A handle to the associated menu or NULL if the menu is not found.

CContextMenuManager::GetMenuByName
Returns a handle to a specific menu.

HMENU GetMenuByName(
LPCTSTR lpszName,
UINT* puiOrigResID = NULL) const;

Parameters
lpszName
[in] A string that contains the name of the menu to retrieve.
puiOrigResID
[out] A pointer to an UINT. This parameter contains the resource ID of the specified menu, if found.
Return Value
A handle to the menu that matches the name that was specified by lpszName. NULL if there is no menu called
lpszName.
Remarks
If this method finds a menu that matches lpszName, GetMenuByName stores the menu resource ID in the
parameter puiOrigResID.

CContextMenuManager::GetMenuNames
Returns the list of menu names added to the CContextMenuManager.

void GetMenuNames(CStringList& listOfNames) const;

Parameters
listOfNames
[out] A reference to a CStringList parameter. This method writes the list of menu names to this parameter.

CContextMenuManager::LoadState
Loads information associated with the CContextMenuManager Class from the Windows registry.

virtual BOOL LoadState(LPCTSTR lpszProfileName = NULL);

Parameters
lpszProfileName
[in] A string that contains the relative path of a registry key.
Return Value
Nonzero if the method is successful; otherwise 0.
Remarks
The lpszProfileName parameter is not the absolute path for a registry entry. It is a relative path that is added to
the end of the default registry key for your application. To get or set the default registry key, use the methods
CWinAppEx::GetRegistryBase and CWinAppEx::SetRegistryBase respectively.
Use the method CContextMenuManager::SaveState to save the shortcut menus to the registry.

CContextMenuManager::ResetState
Clears all items from the shortcut menus associated with the CContextMenuManager Class.

virtual BOOL ResetState();

Return Value
TRUE if the method is successful; FALSE if a failure occurs.
Remarks
This method clears the pop-up menus and removes them from the CContextMenuManager .

CContextMenuManager::SaveState
Saves information associated with the CContextMenuManager Class to the Windows registry.

virtual BOOL SaveState(LPCTSTR lpszProfileName = NULL);

Parameters
lpszProfileName
[in] A string that contains the relative path of a registry key.
Return Value
Nonzero if the method is successful; otherwise 0.
Remarks
The lpszProfileName parameter is not the absolute path for a registry entry. It is a relative path that is added to
the end of the default registry key for your application. To get or set the default registry key, use the methods
CWinAppEx::GetRegistryBase and CWinAppEx::SetRegistryBase respectively.
Use the method CContextMenuManager::LoadState to load the shortcut menus from the registry.

CContextMenuManager::SetDontCloseActiveMenu
Controls whether the CContextMenuManager closes the active pop-up menu when it displays a new pop-up
menu.

void SetDontCloseActiveMenu (BOOL bSet = TRUE);

Parameters
bSet
[in] A Boolean parameter that controls whether to close the active pop-up menu. A value of TRUE indicates the
active pop-up menu is not closed. FALSE indicates that the active pop-up menu is closed.
Remarks
By default, the CContextMenuManager closes the active pop-up menu.

CContextMenuManager::ShowPopupMenu
Displays the specified shortcut menu.

virtual BOOL ShowPopupMenu(


UINT uiMenuResId,
int x,
int y,
CWnd* pWndOwner,
BOOL bOwnMessage = FALSE,
BOOL bRightAlign = FALSE);

virtual CMFCPopupMenu* ShowPopupMenu(


HMENU hmenuPopup,
int x,
int y,
CWnd* pWndOwner,
BOOL bOwnMessage = FALSE,
BOOL bAutoDestroy = TRUE,
BOOL bRightAlign = FALSE);

Parameters
uiMenuResId
[in] The resource ID of the menu that this method will display.
x
[in] The horizontal offset for the shortcut menu in client coordinates.
y
[in] The vertical offset for the shortcut menu in client coordinates
pWndOwner
[in] A pointer to the parent window of the shortcut menu.
bOwnMessage
[in] A Boolean parameter that indicates how messages are routed. If bOwnMessage is FALSE, standard MFC
routing is used. Otherwise, pWndOwner receives the messages.
hmenuPopup
[in] The handle of the menu that this method will display.
bAutoDestroy
[in] A Boolean parameter that indicates whether the menu will be automatically destroyed.
bRightAlign
[in] A Boolean parameter that indicates how the menu items are aligned. If bRightAlign is TRUE, the menu is
right-aligned for right-to-left reading order.
Return Value
The first method overload returns nonzero if the method shows the menu successfully; otherwise 0. The second
method overload returns a pointer to CMFCPopupMenu if the shortcut menu displays correctly; otherwise NULL.
Remarks
This method resembles the method CContextMenuManager::TrackPopupMenu in that both methods display a
shortcut menu. However, TrackPopupMenu returns the index of the selected menu command.
If the parameter bAutoDestroy is FALSE, you must manually call the inherited DestroyMenu method to release
memory resources. The default implementation of ShowPopupMenu does not use the parameter bAutoDestroy. It
is provided for future use or for custom classes derived from the CContextMenuManager class .

CContextMenuManager::TrackPopupMenu
Displays the specified shortcut menu and returns the index of the selected shortcut menu command.

virtual UINT TrackPopupMenu(


HMENU hmenuPopup,
int x,
int y,
CWnd* pWndOwner,
BOOL bRightAlign = FALSE);

Parameters
hmenuPopup
[in] The handle of the shortcut menu that this method displays.
x
[in] The horizontal offset for the shortcut menu in client coordinates.
y
[in] The vertical offset for the shortcut menu in client coordinates.
pWndOwner
[in] A pointer to the parent window of the shortcut menu.
bRightAlign
[in] A Boolean parameter that indicates how menu items are aligned. If bRightAlign is TRUE, the menu is right-
aligned for right-to-left reading order. If bRightAlign is FALSE, the menu is left-aligned for left-to-right reading
order.
Return Value
The menu command ID of the command that the user chooses; 0 if the user closes the shortcut menu without
selecting a menu command.
Remarks
This method functions as a modal call to display a shortcut menu. The application will not continue to the
following line in code until the user either closes the shortcut menu or selects a command. An alternative
method that you can use to display a shortcut menu is CContextMenuManager::ShowPopupMenu. That method
is not a modal call and will not return the ID of the selected command.

See also
Hierarchy Chart
Classes
CWinAppEx Class
CControlBar Class
4/21/2020 • 11 minutes to read • Edit Online

The base class for the control-bar classes CStatusBar, CToolBar, CDialogBar, CReBar, and COleResizeBar.

Syntax
class CControlBar : public CWnd

Members
Protected Constructors
NAME DESC RIP T IO N

CControlBar::CControlBar Constructs a CControlBar object.

Public Methods
NAME DESC RIP T IO N

CControlBar::CalcDynamicLayout Returns the size of a dynamic control bar as a CSize object.

CControlBar::CalcFixedLayout Returns the size of the control bar as a CSize object.

CControlBar::CalcInsideRect Returns the current dimensions of the control bar area;


including the borders.

CControlBar::DoPaint Renders the borders and gripper of the control bar.

CControlBar::DrawBorders Renders the borders of the control bar.

CControlBar::DrawGripper Renders the gripper of the control bar.

CControlBar::EnableDocking Allows a control bar to be docked or floating.

CControlBar::GetBarStyle Retrieves the control bar style settings.

CControlBar::GetBorders Retrieves the border values of the control bar.

CControlBar::GetCount Returns the number of non- HWND elements in the control


bar.

CControlBar::GetDockingFrame Returns a pointer to the frame to which a control bar is


docked.

CControlBar::IsFloating Returns a nonzero value if the control bar in question is a


floating control bar.
NAME DESC RIP T IO N

CControlBar::OnUpdateCmdUI Calls the Command UI handlers.

CControlBar::SetBarStyle Modifies the control bar style settings.

CControlBar::SetBorders Sets the border values of the control bar.

CControlBar::SetInPlaceOwner Changes the in-place owner of a control bar.

Public Data Members


NAME DESC RIP T IO N

CControlBar::m_bAutoDelete If nonzero, the CControlBar object is deleted when the


Windows control bar is destroyed.

CControlBar::m_pInPlaceOwner The in-place owner of the control bar.

Remarks
A control bar is a window that is usually aligned to the left or right of a frame window. It may contain child
items that are either HWND-based controls, which are windows that generate and respond to Windows
messages, or non- HWND-based items, which are not windows and are managed by application code or
framework code. List boxes and edit controls are examples of HWND-based controls; status-bar panes and
bitmap buttons are examples of non- HWND-based controls.
Control-bar windows are usually child windows of a parent frame window and are usually siblings to the client
view or MDI client of the frame window. A CControlBar object uses information about the parent window's
client rectangle to position itself. It then informs the parent window as to how much space remains unallocated
in the parent window's client area.
For more information on CControlBar , see:
Control Bars
Technical Note 31: Control Bars.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CControlBar

Requirements
Header : afxext.h

CControlBar::CalcDynamicLayout
The framework calls this member function to calculate the dimensions of a dynamic toolbar.
virtual CSize CalcDynamicLayout(
int nLength,
DWORD nMode);

Parameters
nLength
The requested dimension of the control bar, either horizontal or vertical, depending on dwMode.
nMode
The following predefined flags are used to determine the height and width of the dynamic control bar. Use the
bitwise-OR (|) operator to combine the flags.

L AY O UT M O DE F L A GS W H AT IT M EA N S

LM_STRETCH Indicates whether the control bar should be stretched to the


size of the frame. Set if the bar is not a docking bar (not
available for docking). Not set when the bar is docked or
floating (available for docking). If set, LM_STRETCH ignores
nLength and returns dimensions based on the LM_HORZ
state. LM_STRETCH works similarly to the bStretch
parameter used in CalcFixedLayout; see that member
function for more information about the relationship
between stretching and orientation.

LM_HORZ Indicates that the bar is horizontally or vertically oriented.


Set if the bar is horizontally oriented, and if it is vertically
oriented, it is not set. LM_HORZ works similarly to the bHorz
parameter used in CalcFixedLayout; see that member
function for more information about the relationship
between stretching and orientation.

LM_MRUWIDTH Most Recently Used Dynamic Width. Ignores nLength


parameter and uses the remembered most recently used
width.

LM_HORZDOCK Horizontal Docked Dimensions. Ignores nLength parameter


and returns the dynamic size with the largest width.

LM_VERTDOCK Vertical Docked Dimensions. Ignores nLength parameter


and returns the dynamic size with the largest height.

LM_LENGTHY Set if nLength indicates height (Y-direction) instead of width.

LM_COMMIT Resets LM_MRUWIDTH to current width of floating control


bar.

Return Value
The control bar size, in pixels, of a CSize object.
Remarks
Override this member function to provide your own dynamic layout in classes you derive from CControlBar .
MFC classes derived from CControlBar , such as CToolbar, override this member function and provide their own
implementation.

CControlBar::CalcFixedLayout
Call this member function to calculate the horizontal size of a control bar.

virtual CSize CalcFixedLayout(


BOOL bStretch,
BOOL bHorz);

Parameters
bStretch
Indicates whether the bar should be stretched to the size of the frame. The bStretch parameter is nonzero when
the bar is not a docking bar (not available for docking) and is 0 when it is docked or floating (available for
docking).
bHorz
Indicates that the bar is horizontally or vertically oriented. The bHorz parameter is nonzero if the bar is
horizontally oriented and is 0 if it is vertically oriented.
Return Value
The control bar size, in pixels, of a CSize object.
Remarks
Control bars such as toolbars can stretch horizontally or vertically to accommodate the buttons contained in the
control bar.
If bStretch is TRUE, stretch the dimension along the orientation provided by bHorz. In other words, if bHorz is
FALSE, the control bar is stretched vertically. If bStretch is FALSE, no stretch occurs. The following table shows
the possible permutations, and resulting control-bar styles, of bStretch and bHorz.

DO C K IN G/ N OT
B ST RETC H B H O RZ ST RETC H IN G O RIEN TAT IO N DO C K IN G

TRUE TRUE Horizontal stretching Horizontally oriented Not docking

TRUE FALSE Vertical stretching Vertically oriented Not docking

FALSE TRUE No stretching Horizontally oriented Docking


available

FALSE FALSE No stretching Vertically oriented Docking


available

CControlBar::CalcInsideRect
The framework calls this function to calculate the client area of the control bar.

virtual void CalcInsideRect(


CRect& rect,
BOOL bHorz) const;

Parameters
rect
Contains the current dimensions of the control bar; including the borders.
bHorz
Indicates that the bar is horizontally or vertically oriented. The bHorz parameter is nonzero if the bar is
horizontally oriented and is 0 if it is vertically oriented.
Remarks
This function is called before the control bar is painted.
Override this function to customize the rendering of the borders and gripper bar of the control bar.

CControlBar::CControlBar
Constructs a CControlBar object.

CControlBar();

CControlBar::DoPaint
Called by the framework to render the borders and gripper bar of the control bar.

virtual void DoPaint(CDC* pDC);

Parameters
pDC
Points to the device context to be used for rendering the borders and gripper of the control bar.
Remarks
Override this function to customize the drawing behavior of the control bar.
Another customization method is to override the DrawBorders and DrawGripper functions and add custom
drawing code for the borders and gripper. Because these methods are called by the default DoPaint method, an
override of DoPaint is not needed.

CControlBar::DrawBorders
Called by the framework to render the borders of the control bar.

virtual void DrawBorders(


CDC* pDC,
CRect& rect);

Parameters
pDC
Points to the device context to be used for rendering the borders of the control bar.
rect
A CRect object containing the dimensions of the control bar.
Remarks
Override this function to customize the appearance of the control bar borders.

CControlBar::DrawGripper
Called by the framework to render the gripper of the control bar.
virtual void DrawGripper(
CDC* pDC,
const CRect& rect);

Parameters
pDC
Points to the device context to be used for rendering the control bar gripper.
rect
A CRect object containing the dimensions of the control bar gripper.
Remarks
Override this function to customize the appearance of the control bar gripper.

CControlBar::EnableDocking
Call this function to enable a control bar to be docked.

void EnableDocking(DWORD dwDockStyle);

Parameters
dwDockStyle
Specifies whether the control bar supports docking and the sides of its parent window to which the control bar
can be docked, if supported. Can be one or more of the following:
CBRS_ALIGN_TOP Allows docking at the top of the client area.
CBRS_ALIGN_BOTTOM Allows docking at the bottom of the client area.
CBRS_ALIGN_LEFT Allows docking on the left side of the client area.
CBRS_ALIGN_RIGHT Allows docking on the right side of the client area.
CBRS_ALIGN_ANY Allows docking on any side of the client area.
CBRS_FLOAT_MULTI Allows multiple control bars to be floated in a single mini-frame window.
If 0 (that is, indicating no flags), the control bar will not dock.
Remarks
The sides specified must match one of the sides enabled for docking in the destination frame window, or the
control bar cannot be docked to that frame window.

CControlBar::GetBarStyle
Call this function to determine which CBRS_ (control bar styles) settings are currently set for the control bar.

DWORD GetBarStyle();

Return Value
The current CBRS_ (control bar styles) settings for the control bar. See CControlBar::SetBarStyle for the
complete list of available styles.
Remarks
Does not handle WS_ (window style) styles.

CControlBar::GetBorders
Returns the current border values for the control bar.

CRect GetBorders() const;

Return Value
A CRect object that contains the current width (in pixels) of each side of the control bar object. For example, the
value of the left member, of CRect object, is the width of the left hand border.

CControlBar::GetCount
Returns the number of non- HWND items on the CControlBar object.

int GetCount() const;

Return Value
The number of non- HWND items on the CControlBar object. This function returns 0 for a CDialogBar object.
Remarks
The type of the item depends on the derived object: panes for CStatusBar objects, and buttons and separators
for CToolBar objects.

CControlBar::GetDockingFrame
Call this member function to obtain a pointer to the current frame window to which your control bar is docked.

CFrameWnd* GetDockingFrame() const;

Return Value
A pointer to a frame window if successful; otherwise NULL.
If the control bar is not docked to a frame window (that is, if the control bar is floating), this function will return
a pointer to its parent CMiniFrameWnd.
Remarks
For more information about dockable control bars, see CControlBar::EnableDocking and
CFrameWnd::DockControlBar.

CControlBar::IsFloating
Call this member function to determine whether the control bar is floating or docked.

BOOL IsFloating() const;

Return Value
Nonzero if the control bar is floating; otherwise 0.
Remarks
To change the state of a control bar from docked to floating, call CFrameWnd::FloatControlBar.

CControlBar::m_bAutoDelete
If nonzero, the CControlBar object is deleted when the Windows control bar is destroyed.

BOOL m_bAutoDelete;

Remarks
m_bAutoDelete is a public variable of type BOOL.
A control-bar object is usually embedded in a frame-window object. In this case, m_bAutoDelete is 0 because
the embedded control-bar object is destroyed when the frame window is destroyed.
Set this variable to a nonzero value if you allocate a CControlBar object on the heap and you do not plan to call
delete .

CControlBar::m_pInPlaceOwner
The in-place owner of the control bar.

CWnd* m_pInPlaceOwner;

CControlBar::OnUpdateCmdUI
This member function is called by the framework to update the status of the toolbar or status bar.

virtual void OnUpdateCmdUI(


CFrameWnd* pTarget,
BOOL bDisableIfNoHndler) = 0;

Parameters
pTarget
Points to the main frame window of the application. This pointer is used for routing update messages.
bDisableIfNoHndler
Flag that indicates whether a control that has no update handler should be automatically displayed as disabled.
Remarks
To update an individual button or pane, use the ON_UPDATE_COMMAND_UI macro in your message map to set
an update handler appropriately. See ON_UPDATE_COMMAND_UI for more information about using this
macro.
OnUpdateCmdUI is called by the framework when the application is idle. The frame window to be updated must
be a child window, at least indirectly, of a visible frame window. OnUpdateCmdUI is an advanced overridable.

CControlBar::SetBarStyle
Call this function to set the desired CBRS_ styles for the control bar.

void SetBarStyle(DWORD dwStyle);


Parameters
dwStyle
The desired styles for the control bar. Can be one or more of the following:
CBRS_ALIGN_TOP Allows the control bar to be docked to the top of the client area of a frame window.
CBRS_ALIGN_BOTTOM Allows the control bar to be docked to the bottom of the client area of a frame
window.
CBRS_ALIGN_LEFT Allows the control bar to be docked to the left side of the client area of a frame
window.
CBRS_ALIGN_RIGHT Allows the control bar to be docked to the right side of the client area of a frame
window.
CBRS_ALIGN_ANY Allows the control bar to be docked to any side of the client area of a frame window.
CBRS_BORDER_TOP Causes a border to be drawn on the top edge of the control bar when it would be
visible.
CBRS_BORDER_BOTTOM Causes a border to be drawn on the bottom edge of the control bar when it
would be visible.
CBRS_BORDER_LEFT Causes a border to be drawn on the left edge of the control bar when it would be
visible.
CBRS_BORDER_RIGHT Causes a border to be drawn on the right edge of the control bar when it would
be visible.
CBRS_FLOAT_MULTI Allows multiple control bars to be floated in a single mini-frame window.
CBRS_TOOLTIPS Causes tool tips to be displayed for the control bar.
CBRS_FLYBY Causes message text to be updated at the same time as tool tips.
CBRS_GRIPPER Causes a gripper, similar to that used on bands in a CReBar object, to be drawn for any
CControlBar -derived class.

Remarks
Does not affect the WS_ (window style) settings.

CControlBar::SetBorders
Call this function to set the size of the control bar's borders.

void SetBorders(
int cxLeft = 0,
int cyTop = 0,
int cxRight = 0,
int cyBottom = 0);

void SetBorders(LPCRECT lpRect);

Parameters
cxLeft
The width (in pixels) of the control bar's left border.
cyTop
The height (in pixels) of the control bar's top border.
cxRight
The width (in pixels) of the control bar's right border.
cyBottom
The height (in pixels) of the control bar's bottom border.
lpRect
A pointer to a CRect object that contains the current width (in pixels)of each border of the control bar object.
Example
The following code example sets the top and bottom borders of the control bar to 5 pixels, and the left and right
borders to 2 pixels:

CControlBar &m_myControlBar = m_Rebar;


m_myControlBar.SetBorders(2, 5, 2, 5);

CControlBar::SetInPlaceOwner
Changes the in-place owner of a control bar.

void SetInPlaceOwner(CWnd* pWnd);

Parameters
pWnd
A pointer to a CWnd object.
Remarks

See also
MFC Sample CTRLBARS
CWnd Class
Hierarchy Chart
CToolBar Class
CDialogBar Class
CStatusBar Class
CReBar Class
CCreateContext Structure
3/27/2020 • 2 minutes to read • Edit Online

The framework uses the CCreateContext structure when it creates the frame windows and views that are
associated with a document.

Syntax
struct CCreateContext

Remarks
CCreateContext is a structure and does not have a base class.
When you create a window, the values in this structure provide the information used to connect the components
of a document to the view of its data. You only have to use CCreateContext if you are overriding parts of the
creation process.
A CCreateContext structure contains pointers to the document, the frame window, the view, and the document
template. It also contains a pointer to a CRuntimeClass that identifies the type of view to create. The run-time class
information and the current document pointer are used to create a new view dynamically. The following table
suggests how and when each CCreateContext member might be used:

M EM B ER TYPE W H AT IT IS F O R

m_pNewViewClass CRuntimeClass* CRuntimeClass of the new view to


create.

m_pCurrentDoc CDocument* The existing document to be associated


with the new view.

m_pNewDocTemplate CDocTemplate* The document template associated


with the creation of a new MDI frame
window.

m_pLastView CView* The original view on which additional


views are modeled, as in the creation of
splitter window views or the creation of
a second view on a document.

m_pCurrentFrame CFrameWnd* The frame window on which additional


frame windows are modeled, as in the
creation of a second frame window on
a document.

When a document template creates a document and its associated components, it validates the information
stored in the CCreateContext structure. For example, a view should not be created for a nonexistent document.
NOTE
All of the pointers in CCreateContext are optional and can be NULL if unspecified or unknown.

CCreateContext is used by the member functions listed under "See Also." Consult the descriptions of these
functions for specific information if you plan to override them.
Here are a few general guidelines:
When passed as an argument for window creation, as in CWnd::Create , CFrameWnd::Create , and
CFrameWnd::LoadFrame , the create context specifies what the new window should be connected to. For most
windows, the entire structure is optional and a NULL pointer can be passed.
For overridable member functions, such as CFrameWnd::OnCreateClient , the CCreateContext argument is
optional.
For member functions involved in view creation, you must provide enough information to create the view.
For example, for the first view in a splitter window, you must supply the view class information and the
current document.
In general, if you use the framework defaults, you can ignore CCreateContext . If you attempt more advanced
modifications, the Microsoft Foundation Class Library source code or the sample programs, such as VIEWEX, will
guide you. If you do forget a required parameter, a framework assertion will tell you what you forgot.
For more information on CCreateContext , see the MFC sample VIEWEX.

Requirements
Header : afxext.h

See also
Hierarchy Chart
CFrameWnd::Create
CFrameWnd::LoadFrame
CFrameWnd::OnCreateClient
CSplitterWnd::Create
CSplitterWnd::CreateView
CWnd::Create
CCriticalSection Class
3/27/2020 • 3 minutes to read • Edit Online

Represents a "critical section" — a synchronization object that allows one thread at a time to access a resource or
section of code.

Syntax
class CCriticalSection : public CSyncObject

Members
Public Constructors
NAME DESC RIP T IO N

CCriticalSection::CCriticalSection Constructs a CCriticalSection object.

Public Methods
NAME DESC RIP T IO N

CCriticalSection::Lock Use to gain access to the CCriticalSection object.

CCriticalSection::Unlock Releases the CCriticalSection object.

Public Operators
NAME DESC RIP T IO N

CCriticalSection::operator CRITICAL_SECTION* Retrieves a pointer to the internal CRITICAL_SECTION object.

Public Data Members


NAME DESC RIP T IO N

CCriticalSection::m_sect A CRITICAL_SECTION object.

Remarks
Critical sections are useful when only one thread at a time can be allowed to modify data or some other controlled
resource. For example, adding nodes to a linked list is a process that should only be allowed by one thread at a
time. By using a CCriticalSection object to control the linked list, only one thread at a time can gain access to the
list.

NOTE
The functionality of the CCriticalSection class is provided by an actual Win32 CRITICAL_SECTION object.
Critical sections are used instead of mutexes (see CMutex) when speed is critical and the resource will not be used
across process boundaries.
There are two methods for using a CCriticalSection object: stand-alone and embedded in a class.
Stand-alone method To use a stand-alone CCriticalSection object, construct the CCriticalSection object
when it is needed. After a successful return from the constructor, explicitly lock the object with a call to Lock.
Call Unlock when you are done accessing the critical section. This method, while clearer to someone reading
your source code, is more prone to error as you must remember to lock and unlock the critical section
before and after access.
A more preferable method is to use the CSingleLock class. It also has a Lock and Unlock method, but you
don't have to worry about unlocking the resource if an exception occurs.
Embedded method You can also share a class with multiple threads by adding a CCriticalSection -type
data member to the class and locking the data member when needed.
For more information on using CCriticalSection objects, see the article Multithreading: How to Use the
Synchronization Classes.

Inheritance Hierarchy
CObject
CSyncObject
CCriticalSection

Requirements
Header : afxmt.h

CCriticalSection::CCriticalSection
Constructs a CCriticalSection object.

CCriticalSection();

Remarks
To access or release a CCriticalSection object, create a CSingleLock object and call its Lock and Unlock member
functions. If the CCriticalSection object is being used stand-alone, call its Unlock member function to release it.
If the constructor fails to allocate the required system memory, a memory exception (of type CMemoryException)
is automatically thrown.
Example
See the example for CCriticalSection::Lock.

CCriticalSection::Lock
Call this member function to gain access to the critical section object.

BOOL Lock();
BOOL Lock(DWORD dwTimeout);
Parameters
dwTimeout
Lock ignores this parameter value.

Return Value
Nonzero if the function was successful; otherwise 0.
Remarks
Lock is a blocking call that will not return until the critical section object is signaled (becomes available).

If timed waits are necessary, you can use a CMutex object instead of a CCriticalSection object.
If Lock fails to allocate the necessary system memory, a memory exception (of type CMemoryException) is
automatically thrown.
Example
This example demonstrates the nested critical section approach by controlling access to a shared resource (the
static _strShared object) using a shared CCriticalSection object. The SomeMethod function demonstrates
updating a shared resource in a safe manner.

//Definition of critical section class


class CMyCritSectClass
{
static CString _strShared; //shared resource
static CCriticalSection _critSect;

public:
CMyCritSectClass(void) {}
~CMyCritSectClass(void) {}
void SomeMethod(void); //locks, modifies, and unlocks shared resource
};

//Declaration of static members and SomeMethod


CString CMyCritSectClass::_strShared;
CCriticalSection CMyCritSectClass::_critSect;

void CMyCritSectClass::SomeMethod()
{
_critSect.Lock();
if (_strShared == "")
_strShared = "<text>";
_critSect.Unlock();
}

CCriticalSection::m_sect
Contains a critical section object that is used by all CCriticalSection methods.

CRITICAL_SECTION m_sect;

CCriticalSection::operator CRITICAL_SECTION*
Retrieves a CRITICAL_SECTION object.

operator CRITICAL_SECTION*();

Remarks
Call this function to retrieve a pointer to the internal CRITICAL_SECTION object.

CCriticalSection::Unlock
Releases the CCriticalSection object for use by another thread.

BOOL Unlock();

Return Value
Nonzero if the CCriticalSection object was owned by the thread and the release was successful; otherwise 0.
Remarks
If the CCriticalSection is being used stand-alone, Unlock must be called immediately after completing use of the
resource controlled by the critical section. If a CSingleLock object is being used, CCriticalSection::Unlock will be
called by the lock object's Unlock member function.
Example
See the example for CCriticalSection::Lock.

See also
CSyncObject Class
Hierarchy Chart
CMutex Class
CCtrlView Class
3/27/2020 • 2 minutes to read • Edit Online

Adapts the document-view architecture to the common controls supported by Windows 98 and Windows NT
versions 3.51 and later.

Syntax
class CCtrlView : public CView

Members
Public Constructors
NAME DESC RIP T IO N

CCtrlView::CCtrlView Constructs a CCtrlView object.

Protected Methods
NAME DESC RIP T IO N

CCtrlView::OnDraw Called by the framework to draw using the specified device


context.

CCtrlView::PreCreateWindow Called before the creation of the Windows window attached


to this CCtrlView object.

Protected Data Members


NAME DESC RIP T IO N

CCtrlView::m_dwDefaultStyle Contains the default style for the view class.

CCtrlView::m_strClass Contains the Windows class name for the view class.

Remarks
The class CCtrlView and its derivatives, CEditView, CListView, CTreeView, and CRichEditView, adapt the
document-view architecture to the new common controls supported by Windows 95/98 and Windows NT
versions 3.51 and later. For more information on the document-view architecture, see Document/View
Architecture.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CCtrlView

Requirements
Header : afxwin.h

CCtrlView::CCtrlView
Constructs a CCtrlView object.

CCtrlView(
LPCTSTR lpszClass,
DWORD dwStyle);

Parameters
lpszClass
Windows class name of the view class.
dwStyle
Style of the view class.
Remarks
The framework calls the constructor when a new frame window is created or a window is split. Override
CView::OnInitialUpdate to initialize the view after the document is attached. Call CWnd::Create or
CWnd::CreateEx to create the Windows object.

CCtrlView::m_strClass
Contains the Windows class name for the view class.

CString m_strClass;

CCtrlView::m_dwDefaultStyle
Contains the default style for the view class.

DWORD m_dwDefaultStyle;

Remarks
This style is applied when a window is created.

CCtrlView::OnDraw
Called by the framework to draw the contents of the CCtrlView object using the specified device context.

virtual void OnDraw(CDC* pDC);

Parameters
pDC
A pointer to the device context in which the drawing occurs.
Remarks
OnDraw is typically called for screen display, passing a screen device context specified by pDC.

CCtrlView::PreCreateWindow
Called before the creation of the Windows window attached to this CWnd object.

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

Parameters
cs
A CREATESTRUCT structure.
Return Value
Nonzero if the window creation should continue; 0 to indicate creation failure.
Remarks
Never call this function directly.
The default implementation of this function checks for a NULL window class name and substitutes an
appropriate default. Override this member function to modify the CREATESTRUCT structure before the window is
created.
Each class derived from CCtrlView adds its own functionality to its override of PreCreateWindow . By design,
these derivations of PreCreateWindow are not documented. To determine the styles appropriate to each class and
the interdependencies between the styles, you can examine the MFC source code for your application's base
class. If you choose to override PreCreateWindow , you can determine whether the styles used in your
application's base class provide the functionality you need by using information gathered from the MFC source
code.
For more information on changing window styles, see the Changing the Styles of a Window Created by MFC.

See also
CView Class
Hierarchy Chart
CTreeView Class
CListView Class
CRichEditView Class
CCubicTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates a cubic transition.

Syntax
class CCubicTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CCubicTransition::CCubicTransition Constructs a transition object and initializes its parameters.

Public Methods
NAME DESC RIP T IO N

CCubicTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CCubicTransition::m_dblFinalValue The value of the animation variable at the end of the


transition.

CCubicTransition::m_dblFinalVelocity The velocity of the variable at the end of the transition.

CCubicTransition::m_duration The duration of the transition.

Remarks
During a cubic transition, the value of the animation variable changes from its initial value to a specified final value
over the duration of the transition, ending at a specified velocity. Because all transitions are cleared automatically,
it's recommended to allocated them using operator new. The encapsulated IUIAnimationTransition COM object is
created by CAnimationController::AnimateGroup, until then it's NULL. Changing member variables after creation of
this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CCubicTransition
Requirements
Header : afxanimationcontroller.h

CCubicTransition::CCubicTransition
Constructs a transition object and initializes its parameters.

CCubicTransition(
UI_ANIMATION_SECONDS duration,
DOUBLE finalValue,
DOUBLE finalVelocity);

Parameters
duration
The duration of the transition.
finalValue
The value of the animation variable at the end of the transition.
finalVelocity
The velocity of the variable at the end of the transition.

CCubicTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CCubicTransition::m_dblFinalValue
The value of the animation variable at the end of the transition.

DOUBLE m_dblFinalValue;

CCubicTransition::m_dblFinalVelocity
The velocity of the variable at the end of the transition.

DOUBLE m_dblFinalVelocity;

CCubicTransition::m_duration
The duration of the transition.

UI_ANIMATION_SECONDS m_duration;

See also
Classes
CCustomInterpolator Class
4/21/2020 • 3 minutes to read • Edit Online

Implements a basic interpolator.

Syntax
class CCustomInterpolator;

Members
Public Constructors
NAME DESC RIP T IO N

CCustomInterpolator::CCustomInterpolator Overloaded. Constructs a custom interpolator object and


initializes duration and velocity to specified values.

Public Methods
NAME DESC RIP T IO N

CCustomInterpolator::GetDependencies Gets the interpolator's dependencies.

CCustomInterpolator::GetDuration Gets the interpolator's duration.

CCustomInterpolator::GetFinalValue Gets the final value to which the interpolator leads.

CCustomInterpolator::Init Initializes duration and final value.

CCustomInterpolator::InterpolateValue Interpolates the value at a given offset.

CCustomInterpolator::InterpolateVelocity Interpolates the velocity at a given offset

CCustomInterpolator::SetDuration Sets the interpolator's duration.

CCustomInterpolator::SetInitialValueAndVelocity Sets the interpolator's initial value and velocity.

Protected Data Members


NAME DESC RIP T IO N

CCustomInterpolator::m_currentValue The interpolated value.

CCustomInterpolator::m_currentVelocity The interpolated velocity.

CCustomInterpolator::m_duration The duration of the transition.

CCustomInterpolator::m_finalValue The final value of a variable at the end of the transition.


NAME DESC RIP T IO N

CCustomInterpolator::m_initialValue The value of the variable at the start of the transition.

CCustomInterpolator::m_initialVelocity The velocity of the variable at the start of the transition.

Remarks
Derive a class from CCustomInterpolator and override all necessary methods in order to implement a custom
interpolation algorithm. A pointer to this class should be passed as a parameter to CCustomTransition.

Inheritance Hierarchy
CCustomInterpolator

Requirements
Header : afxanimationcontroller.h

CCustomInterpolator::CCustomInterpolator
Constructs a custom interpolator object and sets all values to default 0.

CCustomInterpolator();

CCustomInterpolator(
UI_ANIMATION_SECONDS duration,
DOUBLE finalValue);

Parameters
duration
The duration of the transition.
finalValue
Remarks
Use CCustomInterpolator::Init to initialize duration and final value later in the code.

CCustomInterpolator::GetDependencies
Gets the interpolator's dependencies.

virtual BOOL GetDependencies(


UI_ANIMATION_DEPENDENCIES* initialValueDependencies,
UI_ANIMATION_DEPENDENCIES* initialVelocityDependencies,
UI_ANIMATION_DEPENDENCIES* durationDependencies);

Parameters
initialValueDependencies
Output. Aspects of the interpolator that depend on the initial value passed to SetInitialValueAndVelocity.
initialVelocityDependencies
Output. Aspects of the interpolator that depend on the initial velocity passed to SetInitialValueAndVelocity.
durationDependencies
Output. Aspects of the interpolator that depend on the duration passed to SetDuration.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::GetDuration
Gets the interpolator's duration.

virtual BOOL GetDuration(UI_ANIMATION_SECONDS* duration);

Parameters
duration
Output. The duration of the transition, in seconds.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::GetFinalValue
Gets the final value to which the interpolator leads.

virtual BOOL GetFinalValue(DOUBLE* value);

Parameters
value
Output. The final value of a variable at the end of the transition.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::Init
Initializes duration and final value.

void Init(
UI_ANIMATION_SECONDS duration,
DOUBLE finalValue);

Parameters
duration
The duration of the transition.
finalValue
The final value of a variable at the end of the transition.
CCustomInterpolator::InterpolateValue
Interpolates the value at a given offset.

virtual BOOL InterpolateValue(


UI_ANIMATION_SECONDS */,
DOUBLE* value);

Parameters
value
Output. The interpolated value.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::InterpolateVelocity
Interpolates the velocity at a given offset

virtual BOOL InterpolateVelocity(


UI_ANIMATION_SECONDS */,
DOUBLE* velocity);

Parameters
velocity
Output. The velocity of the variable at the offset.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::m_currentValue
The interpolated value.

DOUBLE m_currentValue;

CCustomInterpolator::m_currentVelocity
The interpolated velocity.

DOUBLE m_currentVelocity;

CCustomInterpolator::m_duration
The duration of the transition.

UI_ANIMATION_SECONDS m_duration;
CCustomInterpolator::m_finalValue
The final value of a variable at the end of the transition.

DOUBLE m_finalValue;

CCustomInterpolator::m_initialValue
The value of the variable at the start of the transition.

DOUBLE m_initialValue;

CCustomInterpolator::m_initialVelocity
The velocity of the variable at the start of the transition.

DOUBLE m_initialVelocity;

CCustomInterpolator::SetDuration
Sets the interpolator's duration.

virtual BOOL SetDuration(UI_ANIMATION_SECONDS duration);

Parameters
duration
The duration of the transition.
Return Value
Basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail the
event.

CCustomInterpolator::SetInitialValueAndVelocity
Sets the interpolator's initial value and velocity.

virtual BOOL SetInitialValueAndVelocity(


DOUBLE initialValue,
DOUBLE initialVelocity);

Parameters
initialValue
The value of the variable at the start of the transition.
initialVelocity
The velocity of the variable at the start of the transition.
Return Value
The basic implementation always returns TRUE. Return FALSE from overridden implementation if you wish to fail
the event.
See also
Classes
CCustomTransition Class
4/21/2020 • 2 minutes to read • Edit Online

Implements a custom transition.

Syntax
class CCustomTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CCustomTransition::CCustomTransition Constructs a custom transition object.

Public Methods
NAME DESC RIP T IO N

CCustomTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

CCustomTransition::SetInitialValue Sets an initial value, which will be applied to an animation


variable associated with this transition.

CCustomTransition::SetInitialVelocity Sets an initial velocity, which will be applied to an animation


variable associated with this transition.

Protected Data Members


NAME DESC RIP T IO N

CCustomTransition::m_bInitialValueSpecified Specifies whether the initial value was specified with


SetInitialValue.

CCustomTransition::m_bInitialVelocitySpecified Specifies whether the initial velocity was specified with


SetInitialVelocity.

CCustomTransition::m_initialValue Stores the initial value.

CCustomTransition::m_initialVelocity Stores the initial velocity.

CCustomTransition::m_pInterpolator Stores a pointer to a custom interpolator.

Remarks
The CCustomTransitions class allows developers to implement custom transitions. It's created and used as a
standard transition, but its constructor accepts as parameter a pointer to a custom interpolator. Perform the
following steps to use custom transitions: 1. Derive a class from CCustomInterpolator and implement at least
InterpolateValue method. 2. Ensure that the lifetime of custom interpolator object must be longer than duration of
animation where it's used. 3. Instantiate (using operator new) a CCustomTransition object and pass a pointer to
custom interpolator in the constructor. 4. Call CCustomTransition::SetInitialValue and
CCustomTransition::SetInitialVelocity if these parameters are required for custom interpolation. 5. Pass the pointer
to custom transition to AddTransition method of animation object, whose value should be animated with the
custom algorithm. 6. When the value of animation object should change Windows Animation API will call
InterpolateValue (and other relevant methods) in CCustomInterpolator.

Inheritance Hierarchy
CObject
CBaseTransition
CCustomTransition

Requirements
Header : afxanimationcontroller.h

CCustomTransition::CCustomTransition
Constructs a custom transition object.

CCustomTransition(CCustomInterpolator* pInterpolator);

Parameters
pInterpolator
A pointer to custom interpolator.

CCustomTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* */,
IUIAnimationTransitionFactory* pFactory);

Parameters
pFactory
A pointer to transition factory, which is responsible for creation of custom transitions.
Return Value
Remarks
This method also can set initial value and initial velocity to be applied to an animation variable, which is associated
with this transition. For this purpose you have to call SetInitialValue and SetInitialVelocity before the framework
creates the encapsulated transition COM object (it happens when you call CAnimationController::AnimateGroup).

CCustomTransition::m_bInitialValueSpecified
Specifies whether the initial value was specified with SetInitialValue.
BOOL m_bInitialValueSpecified;

CCustomTransition::m_bInitialVelocitySpecified
Specifies whether the initial velocity was specified with SetInitialVelocity.

BOOL m_bInitialVelocitySpecified;

CCustomTransition::m_initialValue
Stores the initial value.

DOUBLE m_initialValue;

CCustomTransition::m_initialVelocity
Stores the initial velocity.

DOUBLE m_initialVelocity;

CCustomTransition::m_pInterpolator
Stores a pointer to a custom interpolator.

CCustomInterpolator* m_pInterpolator;

CCustomTransition::SetInitialValue
Sets an initial value, which will be applied to an animation variable associated with this transition.

void SetInitialValue(DOUBLE initialValue);

Parameters
initialValue

CCustomTransition::SetInitialVelocity
Sets an initial velocity, which will be applied to an animation variable associated with this transition.

void SetInitialVelocity(DOUBLE initialVelocity);

Parameters
initialVelocity

See also
Classes
CD2DBitmap Class
4/21/2020 • 4 minutes to read • Edit Online

A wrapper for ID2D1Bitmap.

Syntax
class CD2DBitmap : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DBitmap::CD2DBitmap Overloaded. Constructs a CD2DBitmap object from HBITMAP.

CD2DBitmap::~CD2DBitmap The destructor. Called when a D2D bitmap object is being


destroyed.

Protected Constructors
NAME DESC RIP T IO N

CD2DBitmap::CD2DBitmap Overloaded. Constructs a CD2DBitmap object.

Public Methods
NAME DESC RIP T IO N

CD2DBitmap::Attach Attaches existing resource interface to the object

CD2DBitmap::CopyFromBitmap Copies the specified region from the specified bitmap into the
current bitmap

CD2DBitmap::CopyFromMemory Copies the specified region from memory into the current
bitmap

CD2DBitmap::CopyFromRenderTarget Copies the specified region from the specified render target
into the current bitmap

CD2DBitmap::Create Creates a CD2DBitmap. (Overrides CD2DResource::Create.)

CD2DBitmap::Destroy Destroys a CD2DBitmap object. (Overrides


CD2DResource::Destroy.)

CD2DBitmap::Detach Detaches resource interface from the object

CD2DBitmap::Get Returns ID2D1Bitmap interface


NAME DESC RIP T IO N

CD2DBitmap::GetDPI Return the dots per inch (DPI) of the bitmap

CD2DBitmap::GetPixelFormat Retrieves the pixel format and alpha mode of the bitmap

CD2DBitmap::GetPixelSize Returns the size, in device-dependent units (pixels), of the


bitmap

CD2DBitmap::GetSize Returns the size, in device-independent pixels (DIPs), of the


bitmap

CD2DBitmap::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

Protected Methods
NAME DESC RIP T IO N

CD2DBitmap::CommonInit Initializes the object

Public Operators
NAME DESC RIP T IO N

CD2DBitmap::operator ID2D1Bitmap* Returns ID2D1Bitmap interface

Protected Data Members


NAME DESC RIP T IO N

CD2DBitmap::m_bAutoDestroyHBMP TRUE if m_hBmpSrc should be destroyed; otherwise FALSE.

CD2DBitmap::m_hBmpSrc Source bitmap handle.

CD2DBitmap::m_lpszType Resource type.

CD2DBitmap::m_pBitmap Stores a pointer to an ID2D1Bitmap object.

CD2DBitmap::m_sizeDest Bitmap destination size.

CD2DBitmap::m_strPath Botmap file path.

CD2DBitmap::m_uiResID Bitmap resource ID.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBitmap

Requirements
Header : afxrendertarget.h

CD2DBitmap::~CD2DBitmap
The destructor. Called when a D2D bitmap object is being destroyed.

virtual ~CD2DBitmap();

CD2DBitmap::Attach
Attaches existing resource interface to the object.

void Attach(ID2D1Bitmap* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL.

CD2DBitmap::CD2DBitmap
Constructs a CD2DBitmap object from resource.

CD2DBitmap(
CRenderTarget* pParentTarget,
UINT uiResID,
LPCTSTR lpszType = NULL,
CD2DSizeU sizeDest = CD2DSizeU(0, 0),
BOOL bAutoDestroy = TRUE);

CD2DBitmap(
CRenderTarget* pParentTarget,
LPCTSTR lpszPath,
CD2DSizeU sizeDest = CD2DSizeU(0, 0),
BOOL bAutoDestroy = TRUE);

CD2DBitmap(
CRenderTarget* pParentTarget,
HBITMAP hbmpSrc,
CD2DSizeU sizeDest = CD2DSizeU(0, 0),
BOOL bAutoDestroy = TRUE);

CD2DBitmap(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
uiResID
The resource ID number of the resource.
lpszType
Pointer to a null-terminated string that contains the resource type.
sizeDest
Destination size of the bitmap.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).
lpszPath
Pointer to a null-terminated string that contains the name of file.
hbmpSrc
Handle to the bitmap.

CD2DBitmap::CommonInit
Initializes the object.

void CommonInit();

CD2DBitmap::CopyFromBitmap
Copies the specified region from the specified bitmap into the current bitmap.

HRESULT CopyFromBitmap(
const CD2DBitmap* pBitmap,
const CD2DPointU* destPoint = NULL,
const CD2DRectU* srcRect = NULL);

Parameters
pBitmap
The bitmap to copy from.
destPoint
In the current bitmap, the upper-left corner of the area to which the region specified by srcRect is copied.
srcRect
The area of bitmap to copy.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DBitmap::CopyFromMemory
Copies the specified region from memory into the current bitmap.

HRESULT CopyFromMemory(
const void* srcData,
UINT32 pitch,
const CD2DRectU* destRect = NULL);

Parameters
srcData
The data to copy.
pitch
The stride, or pitch, of the source bitmap stored in srcData. The stride is the byte count of a scanline (one row of
pixels in memory). The stride can be computed from the following formula: pixel width * bytes per pixel + memory
padding.
destRect
In the current bitmap, the upper-left corner of the area to which the region specified by srcRect is copied.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DBitmap::CopyFromRenderTarget
Copies the specified region from the specified render target into the current bitmap.

HRESULT CopyFromRenderTarget(
const CRenderTarget* pRenderTarget,
const CD2DPointU* destPoint = NULL,
const CD2DRectU* srcRect = NULL);

Parameters
pRenderTarget
The render target that contains the region to copy.
destPoint
In the current bitmap, the upper-left corner of the area to which the region specified by srcRect is copied.
srcRect
The area of renderTarget to copy.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DBitmap::Create
Creates a CD2DBitmap.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DBitmap::Destroy
Destroys a CD2DBitmap object.

virtual void Destroy();

CD2DBitmap::Detach
Detaches resource interface from the object.

ID2D1Bitmap* Detach();
Return Value
Pointer to detached resource interface.

CD2DBitmap::Get
Returns ID2D1Bitmap interface.

ID2D1Bitmap* Get();

Return Value
Pointer to an ID2D1Bitmap interface or NULL if object is not initialized yet.

CD2DBitmap::GetDPI
Return the dots per inch (DPI) of the bitmap.

CD2DSizeF GetDPI() const;

Return Value
The horizontal and vertical DPI of the bitmap.

CD2DBitmap::GetPixelFormat
Retrieves the pixel format and alpha mode of the bitmap

D2D1_PIXEL_FORMAT GetPixelFormat() const;

Return Value
The pixel format and alpha mode of the bitmap.

CD2DBitmap::GetPixelSize
Returns the size, in device-dependent units (pixels), of the bitmap.

CD2DSizeU GetPixelSize() const;

Return Value
The size, in pixels, of the bitmap..

CD2DBitmap::GetSize
Returns the size, in device-independent pixels (DIPs), of the bitmap.

CD2DSizeF GetSize() const;

Return Value
The size, in DIPs, of the bitmap.

CD2DBitmap::IsValid
Checks resource validity.

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DBitmap::m_bAutoDestroyHBMP
TRUE if m_hBmpSrc should be destroyed; otherwise FALSE.

BOOL m_bAutoDestroyHBMP;

CD2DBitmap::m_hBmpSrc
Source bitmap handle.

HBITMAP m_hBmpSrc;

CD2DBitmap::m_lpszType
Resource type.

LPCTSTR m_lpszType;

CD2DBitmap::m_pBitmap
Stores a pointer to an ID2D1Bitmap object.

ID2D1Bitmap* m_pBitmap;

CD2DBitmap::m_sizeDest
Bitmap destination size.

CD2DSizeU m_sizeDest;

CD2DBitmap::m_strPath
Botmap file path.

CString m_strPath;

CD2DBitmap::m_uiResID
Bitmap resource ID.
UINT m_uiResID;

CD2DBitmap::operator ID2D1Bitmap*
Returns ID2D1Bitmap interface

operator ID2D1Bitmap*();

Return Value
Pointer to an ID2D1Bitmap interface or NULL if object is not initialized yet.

See also
Classes
CD2DBitmapBrush Class
4/21/2020 • 4 minutes to read • Edit Online

A wrapper for ID2D1BitmapBrush.

Syntax
class CD2DBitmapBrush : public CD2DBrush;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DBitmapBrush::CD2DBitmapBrush Overloaded. Constructs a CD2DBitmapBrush object from file.

CD2DBitmapBrush::~CD2DBitmapBrush The destructor. Called when a D2D bitmap brush object is


being destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DBitmapBrush::Attach Attaches existing resource interface to the object

CD2DBitmapBrush::Create Creates a CD2DBitmapBrush. (Overrides


CD2DResource::Create.)

CD2DBitmapBrush::Destroy Destroys a CD2DBitmapBrush object. (Overrides


CD2DBrush::Destroy.)

CD2DBitmapBrush::Detach Detaches resource interface from the object

CD2DBitmapBrush::Get Returns ID2D1BitmapBrush interface

CD2DBitmapBrush::GetBitmap Gets the bitmap source that this brush uses to paint

CD2DBitmapBrush::GetExtendModeX Gets the method by which the brush horizontally tiles those
areas that extend past its bitmap

CD2DBitmapBrush::GetExtendModeY Gets the method by which the brush vertically tiles those
areas that extend past its bitmap

CD2DBitmapBrush::GetInterpolationMode Gets the interpolation method used when the brush bitmap is
scaled or rotated

CD2DBitmapBrush::SetBitmap Specifies the bitmap source that this brush uses to paint
NAME DESC RIP T IO N

CD2DBitmapBrush::SetExtendModeX Specifies how the brush horizontally tiles those areas that
extend past its bitmap

CD2DBitmapBrush::SetExtendModeY Specifies how the brush vertically tiles those areas that extend
past its bitmap

CD2DBitmapBrush::SetInterpolationMode Specifies the interpolation mode used when the brush bitmap
is scaled or rotated

Protected Methods
NAME DESC RIP T IO N

CD2DBitmapBrush::CommonInit Initializes the object

Public Operators
NAME DESC RIP T IO N

CD2DBitmapBrush::operator ID2D1BitmapBrush* Returns ID2D1BitmapBrush interface

Protected Data Members


NAME DESC RIP T IO N

CD2DBitmapBrush::m_pBitmap Stores a pointer to a CD2DBitmap object.

CD2DBitmapBrush::m_pBitmapBrush Stores a pointer to an ID2D1BitmapBrush object.

CD2DBitmapBrush::m_pBitmapBrushProperties Bitmap brush properties.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush
CD2DBitmapBrush

Requirements
Header : afxrendertarget.h

CD2DBitmapBrush::~CD2DBitmapBrush
The destructor. Called when a D2D bitmap brush object is being destroyed.

virtual ~CD2DBitmapBrush();

CD2DBitmapBrush::Attach
Attaches existing resource interface to the object

void Attach(ID2D1BitmapBrush* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DBitmapBrush::CD2DBitmapBrush
Constructs a CD2DBitmapBrush object.

CD2DBitmapBrush(
CRenderTarget* pParentTarget,
D2D1_BITMAP_BRUSH_PROPERTIES* pBitmapBrushProperties = NULL,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

CD2DBitmapBrush(
CRenderTarget* pParentTarget,
UINT uiResID,
LPCTSTR lpszType = NULL,
CD2DSizeU sizeDest = CD2DSizeU(0, 0),
D2D1_BITMAP_BRUSH_PROPERTIES* pBitmapBrushProperties = NULL,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

CD2DBitmapBrush(
CRenderTarget* pParentTarget,
LPCTSTR lpszImagePath,
CD2DSizeU sizeDest = CD2DSizeU(0, 0),
D2D1_BITMAP_BRUSH_PROPERTIES* pBitmapBrushProperties = NULL,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
pBitmapBrushProperties
A pointer to the extend modes and the interpolation mode of a bitmap brush.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).
uiResID
The resource ID number of the resource.
lpszType
Pointer to a null-terminated string that contains the resource type.
sizeDest
Destination size of the bitmap.
lpszImagePath
Pointer to a null-terminated string that contains the name of file.
CD2DBitmapBrush::CommonInit
Initializes the object

void CommonInit(D2D1_BITMAP_BRUSH_PROPERTIES* pBitmapBrushProperties);

Parameters
pBitmapBrushProperties
A pointer to the bitmap brush properties.

CD2DBitmapBrush::Create
Creates a CD2DBitmapBrush.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DBitmapBrush::Destroy
Destroys a CD2DBitmapBrush object.

virtual void Destroy();

CD2DBitmapBrush::Detach
Detaches resource interface from the object

ID2D1BitmapBrush* Detach();

Return Value
Pointer to detached resource interface.

CD2DBitmapBrush::Get
Returns ID2D1BitmapBrush interface

ID2D1BitmapBrush* Get();

Return Value
Pointer to an ID2D1BitmapBrush interface or NULL if object is not initialized yet.

CD2DBitmapBrush::GetBitmap
Gets the bitmap source that this brush uses to paint
CD2DBitmap* GetBitmap();

Return Value
Pointer to an CD2DBitmap object or NULL if object is not initialized yet.

CD2DBitmapBrush::GetExtendModeX
Gets the method by which the brush horizontally tiles those areas that extend past its bitmap

D2D1_EXTEND_MODE GetExtendModeX() const;

Return Value
A value that specifies how the brush horizontally tiles those areas that extend past its bitmap

CD2DBitmapBrush::GetExtendModeY
Gets the method by which the brush vertically tiles those areas that extend past its bitmap

D2D1_EXTEND_MODE GetExtendModeY() const;

Return Value
A value that specifies how the brush vertically tiles those areas that extend past its bitmap

CD2DBitmapBrush::GetInterpolationMode
Gets the interpolation method used when the brush bitmap is scaled or rotated

D2D1_BITMAP_INTERPOLATION_MODE GetInterpolationMode() const;

Return Value
The interpolation method used when the brush bitmap is scaled or rotated

CD2DBitmapBrush::m_pBitmap
Stores a pointer to a CD2DBitmap object.

CD2DBitmap* m_pBitmap;

CD2DBitmapBrush::m_pBitmapBrush
Stores a pointer to an ID2D1BitmapBrush object.

ID2D1BitmapBrush* m_pBitmapBrush;

CD2DBitmapBrush::m_pBitmapBrushProperties
Bitmap brush properties.
D2D1_BITMAP_BRUSH_PROPERTIES* m_pBitmapBrushProperties;

CD2DBitmapBrush::operator ID2D1BitmapBrush*
Returns ID2D1BitmapBrush interface

operator ID2D1BitmapBrush*();

Return Value
Pointer to an ID2D1BitmapBrush interface or NULL if object is not initialized yet.

CD2DBitmapBrush::SetBitmap
Specifies the bitmap source that this brush uses to paint

void SetBitmap(CD2DBitmap* pBitmap);

Parameters
pBitmap
The bitmap source used by the brush

CD2DBitmapBrush::SetExtendModeX
Specifies how the brush horizontally tiles those areas that extend past its bitmap

void SetExtendModeX(D2D1_EXTEND_MODE extendModeX);

Parameters
extendModeX
A value that specifies how the brush horizontally tiles those areas that extend past its bitmap

CD2DBitmapBrush::SetExtendModeY
Specifies how the brush vertically tiles those areas that extend past its bitmap

void SetExtendModeY(D2D1_EXTEND_MODE extendModeY);

Parameters
extendModeY
A value that specifies how the brush vertically tiles those areas that extend past its bitmap

CD2DBitmapBrush::SetInterpolationMode
Specifies the interpolation mode used when the brush bitmap is scaled or rotated

void SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE interpolationMode);

Parameters
interpolationMode
The interpolation mode used when the brush bitmap is scaled or rotated

See also
Classes
CD2DBrush Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1Brush.

Syntax
class CD2DBrush : public CD2DResource;

Members
Protected Constructors
NAME DESC RIP T IO N

CD2DBrush::CD2DBrush Constructs a CD2DBrush object.

CD2DBrush::~CD2DBrush The destructor. Called when a D2D brush object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DBrush::Attach Attaches existing resource interface to the object

CD2DBrush::Destroy Destroys a CD2DBrush object. (Overrides


CD2DResource::Destroy.)

CD2DBrush::Detach Detaches resource interface from the object

CD2DBrush::Get Returns ID2D1Brush interface

CD2DBrush::GetOpacity Gets the degree of opacity of this brush

CD2DBrush::GetTransform Gets the current transform of the render target

CD2DBrush::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

CD2DBrush::SetOpacity Sets the degree of opacity of this brush

CD2DBrush::SetTransform Applies the specified transform to the render target, replacing


the existing transformation. All subsequent drawing
operations occur in the transformed space

Public Operators
NAME DESC RIP T IO N

CD2DBrush::operator ID2D1Brush* Returns ID2D1Brush interface

Protected Data Members


NAME DESC RIP T IO N

CD2DBrush::m_pBrush Stores a pointer to an ID2D1Brush object.

CD2DBrush::m_pBrushProperties Brush properties.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush

Requirements
Header : afxrendertarget.h

CD2DBrush::~CD2DBrush
The destructor. Called when a D2D brush object is being destroyed.

virtual ~CD2DBrush();

CD2DBrush::Attach
Attaches existing resource interface to the object.

void Attach(ID2D1Brush* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL.

CD2DBrush::CD2DBrush
Constructs a CD2DBrush object.

CD2DBrush(
CRenderTarget* pParentTarget,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DBrush::Destroy
Destroys a CD2DBrush object.

virtual void Destroy();

CD2DBrush::Detach
Detaches resource interface from the object.

ID2D1Brush* Detach();

Return Value
Pointer to detached resource interface.

CD2DBrush::Get
Returns ID2D1Brush interface

ID2D1Brush* Get();

Return Value
Pointer to an ID2D1Brush interface or NULL if object is not initialized yet.

CD2DBrush::GetOpacity
Gets the degree of opacity of this brush

FLOAT GetOpacity() const;

Return Value
A value between zero and 1 that indicates the opacity of the brush. This value is a constant multiplier that linearly
scales the alpha value of all pixels filled by the brush. The opacity values are clamped in the range 0 to 1 before
they are multiplied together.

CD2DBrush::GetTransform
Gets the current transform of the render target

void GetTransform(D2D1_MATRIX_3X2_F* transform) const;

Parameters
transform
When this returns, contains the current transform of the render target. This parameter is passed uninitialized.
CD2DBrush::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DBrush::m_pBrush
Stores a pointer to an ID2D1Brush object.

ID2D1Brush* m_pBrush;

CD2DBrush::m_pBrushProperties
Brush properties.

CD2DBrushProperties* m_pBrushProperties;

CD2DBrush::operator ID2D1Brush*
Returns ID2D1Brush interface

operator ID2D1Brush*();

Return Value
Pointer to an ID2D1Brush interface or NULL if object is not initialized yet.

CD2DBrush::SetOpacity
Sets the degree of opacity of this brush

void SetOpacity(FLOAT opacity);

Parameters
opacity
A value between zero and 1 that indicates the opacity of the brush. This value is a constant multiplier that linearly
scales the alpha value of all pixels filled by the brush. The opacity values are clamped in the range 0 to 1 before
they are multiplied together.

CD2DBrush::SetTransform
Applies the specified transform to the render target, replacing the existing transformation. All subsequent drawing
operations occur in the transformed space.

void SetTransform(const D2D1_MATRIX_3X2_F* transform);


Parameters
transform
The transform to apply to the render target

See also
Classes
CD2DBrushProperties Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_BRUSH_PROPERTIES .

Syntax
class CD2DBrushProperties : public D2D1_BRUSH_PROPERTIES;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DBrushProperties::CD2DBrushProperties Overloaded. Creates a CD2D_BRUSH_PROPERTIES structure

Protected Methods
NAME DESC RIP T IO N

CD2DBrushProperties::CommonInit Initializes the object

Inheritance Hierarchy
D2D1_BRUSH_PROPERTIES

CD2DBrushProperties

Requirements
Header : afxrendertarget.h

CD2DBrushProperties::CD2DBrushProperties
Creates a CD2D_BRUSH_PROPERTIES structure

CD2DBrushProperties();
CD2DBrushProperties(FLOAT _opacity);

CD2DBrushProperties(
D2D1_MATRIX_3X2_F _transform,
FLOAT _opacity = 1.);

Parameters
_opacity
The base opacity of the brush. The default value is 1.0.
_transform
The transformation to apply to the brush

CD2DBrushProperties::CommonInit
Initializes the object

void CommonInit();

See also
Classes
CD2DEllipse Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_ELLIPSE .

Syntax
class CD2DEllipse : public D2D1_ELLIPSE;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DEllipse::CD2DEllipse Overloaded. Constructs a CD2DEllipse object from


D2D1_ELLIPSE object.

Inheritance Hierarchy
D2D1_ELLIPSE

CD2DEllipse

Requirements
Header : afxrendertarget.h

CD2DEllipse::CD2DEllipse
Constructs a CD2DEllipse object from CD2DRectF object.

CD2DEllipse(const CD2DRectF& rect);


CD2DEllipse(const D2D1_ELLIPSE& ellipse);
CD2DEllipse(const D2D1_ELLIPSE* ellipse);

CD2DEllipse(
const CD2DPointF& ptCenter,
const CD2DSizeF& sizeRadius);

Parameters
rect
source rectangle
ellipse
source ellipse
ptCenter
The center point of the ellipse.
sizeRadius
The X-radius and Y-radius of the ellipse.

See also
Classes
CD2DGeometry Class
4/21/2020 • 9 minutes to read • Edit Online

A wrapper for ID2D1Geometry.

Syntax
class CD2DGeometry : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DGeometry::CD2DGeometry Constructs a CD2DGeometry object.

CD2DGeometry::~CD2DGeometry The destructor. Called when a D2D geometry object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DGeometry::Attach Attaches existing resource interface to the object

CD2DGeometry::CombineWithGeometry Combines this geometry with the specified geometry and


stores the result in an ID2D1SimplifiedGeometrySink.

CD2DGeometry::CompareWithGeometry Describes the intersection between this geometry and the


specified geometry. The comparison is performed using the
specified flattening tolerance.

CD2DGeometry::ComputeArea Computes the area of the geometry after it has been


transformed by the specified matrix and flattened using the
specified tolerance.

CD2DGeometry::ComputeLength Calculates the length of the geometry as though each


segment were unrolled into a line.

CD2DGeometry::ComputePointAtLength Calculates the point and tangent vector at the specified


distance along the geometry after it has been transformed by
the specified matrix and flattened using the specified
tolerance.

CD2DGeometry::Destroy Destroys a CD2DGeometry object. (Overrides


CD2DResource::Destroy.)

CD2DGeometry::Detach Detaches resource interface from the object


NAME DESC RIP T IO N

CD2DGeometry::FillContainsPoint Indicates whether the area filled by the geometry would


contain the specified point given the specified flattening
tolerance.

CD2DGeometry::Get Returns ID2D1Geometry interface

CD2DGeometry::GetBounds

CD2DGeometry::GetWidenedBounds Gets the bounds of the geometry after it has been widened
by the specified stroke width and style and transformed by
the specified matrix.

CD2DGeometry::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

CD2DGeometry::Outline Computes the outline of the geometry and writes the result
to an ID2D1SimplifiedGeometrySink.

CD2DGeometry::Simplify Creates a simplified version of the geometry that contains


only lines and (optionally) cubic Bezier curves and writes the
result to an ID2D1SimplifiedGeometrySink.

CD2DGeometry::StrokeContainsPoint Determines whether the geometry's stroke contains the


specified point given the specified stroke thickness, style, and
transform.

CD2DGeometry::Tessellate Creates a set of clockwise-wound triangles that cover the


geometry after it has been transformed using the specified
matrix and flattened using the specified tolerance.

CD2DGeometry::Widen Widens the geometry by the specified stroke and writes the
result to an ID2D1SimplifiedGeometrySink after it has been
transformed by the specified matrix and flattened using the
specified tolerance.

Public Operators
NAME DESC RIP T IO N

CD2DGeometry::operator ID2D1Geometry* Returns ID2D1Geometry interface

Protected Data Members


NAME DESC RIP T IO N

CD2DGeometry::m_pGeometry A pointer to an ID2D1Geometry.

Inheritance Hierarchy
CObject
CD2DResource
CD2DGeometry
Requirements
Header : afxrendertarget.h

CD2DGeometry::~CD2DGeometry
The destructor. Called when a D2D geometry object is being destroyed.

virtual ~CD2DGeometry();

CD2DGeometry::Attach
Attaches existing resource interface to the object

void Attach(ID2D1Geometry* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DGeometry::CD2DGeometry
Constructs a CD2DGeometry object.

CD2DGeometry(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DGeometry::CombineWithGeometry
Combines this geometry with the specified geometry and stores the result in an ID2D1SimplifiedGeometrySink.

BOOL CombineWithGeometry(
CD2DGeometry& inputGeometry,
D2D1_COMBINE_MODE combineMode,
const D2D1_MATRIX_3X2_F& inputGeometryTransform,
ID2D1SimplifiedGeometrySink* geometrySink,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
inputGeometry
The geometry to combine with this instance.
combineMode
The type of combine operation to perform.
inputGeometryTransform
The transform to apply to inputGeometry before combining.
geometrySink
The result of the combine operation.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometries. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::CompareWithGeometry
Describes the intersection between this geometry and the specified geometry. The comparison is performed using
the specified flattening tolerance.

D2D1_GEOMETRY_RELATION CompareWithGeometry(
CD2DGeometry& inputGeometry,
const D2D1_MATRIX_3X2_F& inputGeometryTransform,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
inputGeometry
The geometry to test.
inputGeometryTransform
The transform to apply to inputGeometry.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometries. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::ComputeArea
Computes the area of the geometry after it has been transformed by the specified matrix and flattened using the
specified tolerance.

BOOL ComputeArea(
const D2D1_MATRIX_3X2_F& worldTransform,
FLOAT& area,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
worldTransform
The transform to apply to this geometry before computing its area.
area
When this method returns, contains a pointer to the area of the transformed, flattened version of this geometry.
You must allocate storage for this parameter.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::ComputeLength
Calculates the length of the geometry as though each segment were unrolled into a line.

BOOL ComputeLength(
const D2D1_MATRIX_3X2_F& worldTransform,
FLOAT& length,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
worldTransform
The transform to apply to the geometry before calculating its length.
length
When this method returns, contains a pointer to the length of the geometry. For closed geometries, the length
includes an implicit closing segment. You must allocate storage for this parameter.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::ComputePointAtLength
Calculates the point and tangent vector at the specified distance along the geometry after it has been transformed
by the specified matrix and flattened using the specified tolerance.

BOOL ComputePointAtLength(
FLOAT length,
const D2D1_MATRIX_3X2_F& worldTransform,
CD2DPointF& point,
CD2DPointF& unitTangentVector,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
length
The distance along the geometry of the point and tangent to find. If this distance is less then 0, this method
calculates the first point in the geometry. If this distance is greater than the length of the geometry, this method
calculates the last point in the geometry.
worldTransform
The transform to apply to the geometry before calculating the specified point and tangent.
point
The location at the specified distance along the geometry. If the geometry is empty, this point contains NaN as its x
and y values.
unitTangentVector
When this method returns, contains a pointer to the tangent vector at the specified distance along the geometry. If
the geometry is empty, this vector contains NaN as its x and y values. You must allocate storage for this parameter.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::Destroy
Destroys a CD2DGeometry object.

virtual void Destroy();

CD2DGeometry::Detach
Detaches resource interface from the object

ID2D1Geometry* Detach();

Return Value
Pointer to detached resource interface.

CD2DGeometry::FillContainsPoint
Indicates whether the area filled by the geometry would contain the specified point given the specified flattening
tolerance.

BOOL FillContainsPoint(
CD2DPointF point,
const D2D1_MATRIX_3X2_F& worldTransform,
BOOL* contains,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
point
The point to test.
worldTransform
The transform to apply to the geometry prior to testing for containment.
contains
When this method returns, contains a bool value that is TRUE if the area filled by the geometry contains point;
otherwise, FALSE. You must allocate storage for this parameter.
flatteningTolerance
The numeric accuracy with which the precise geometric path and path intersection is calculated. Points missing the
fill by less than the tolerance are still considered inside. Smaller values produce more accurate results but cause
slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::Get
Returns ID2D1Geometry interface

ID2D1Geometry* Get();

Return Value
Pointer to an ID2D1Geometry interface or NULL if object is not initialized yet.

CD2DGeometry::GetBounds
BOOL GetBounds(
const D2D1_MATRIX_3X2_F& worldTransform,
CD2DRectF& bounds) const;

Parameters
worldTransform
bounds
Return Value

CD2DGeometry::GetWidenedBounds
Gets the bounds of the geometry after it has been widened by the specified stroke width and style and
transformed by the specified matrix.

BOOL GetWidenedBounds(
FLOAT strokeWidth,
ID2D1StrokeStyle* strokeStyle,
const D2D1_MATRIX_3X2_F& worldTransform,
CD2DRectF& bounds,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
strokeWidth
The amount by which to widen the geometry by stroking its outline.
strokeStyle
The style of the stroke that widens the geometry.
worldTransform
A transform to apply to the geometry after the geometry is transformed and after the geometry has been stroked.
bounds
When this method returns, contains the bounds of the widened geometry. You must allocate storage for this
parameter.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometries. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DGeometry::m_pGeometry
A pointer to an ID2D1Geometry.

ID2D1Geometry* m_pGeometry;

CD2DGeometry::operator ID2D1Geometry*
Returns ID2D1Geometry interface

operator ID2D1Geometry*();

Return Value
Pointer to an ID2D1Geometry interface or NULL if object is not initialized yet.

CD2DGeometry::Outline
Computes the outline of the geometry and writes the result to an ID2D1SimplifiedGeometrySink.

BOOL Outline(
const D2D1_MATRIX_3X2_F& worldTransform,
ID2D1SimplifiedGeometrySink* geometrySink,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
worldTransform
The transform to apply to the geometry outline.
geometrySink
The ID2D1SimplifiedGeometrySink to which the geometry transformed outline is appended.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::Simplify
Creates a simplified version of the geometry that contains only lines and (optionally) cubic Bezier curves and
writes the result to an ID2D1SimplifiedGeometrySink.

BOOL Simplify(
D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption,
const D2D1_MATRIX_3X2_F& worldTransform,
ID2D1SimplifiedGeometrySink* geometrySink,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
simplificationOption
A value that specifies whether the simplified geometry should contain curves.
worldTransform
The transform to apply to the simplified geometry.
geometrySink
The ID2D1SimplifiedGeometrySink to which the simplified geometry is appended.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::StrokeContainsPoint
Determines whether the geometry's stroke contains the specified point given the specified stroke thickness, style,
and transform.

BOOL StrokeContainsPoint(
CD2DPointF point,
FLOAT strokeWidth,
ID2D1StrokeStyle* strokeStyle,
const D2D1_MATRIX_3X2_F& worldTransform,
BOOL* contains,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
point
The point to test for containment.
strokeWidth
The thickness of the stroke to apply.
strokeStyle
The style of the stroke to apply.
worldTransform
The transform to apply to the stroked geometry.
contains
When this method returns, contains a boolean value set to TRUE if the geometry's stroke contains the specified
point; otherwise, FALSE. You must allocate storage for this parameter.
flatteningTolerance
The numeric accuracy with which the precise geometric path and path intersection is calculated. Points missing the
stroke by less than the tolerance are still considered inside. Smaller values produce more accurate results but cause
slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::Tessellate
Creates a set of clockwise-wound triangles that cover the geometry after it has been transformed using the
specified matrix and flattened using the specified tolerance.

BOOL Tessellate(
const D2D1_MATRIX_3X2_F& worldTransform,
ID2D1TessellationSink* tessellationSink,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
worldTransform
The transform to apply to this geometry, or NULL.
tessellationSink
The ID2D1TessellationSink to which the tessellated is appended.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CD2DGeometry::Widen
Widens the geometry by the specified stroke and writes the result to an ID2D1SimplifiedGeometrySink after it has
been transformed by the specified matrix and flattened using the specified tolerance.

BOOL Widen(
FLOAT strokeWidth,
ID2D1StrokeStyle* strokeStyle,
const D2D1_MATRIX_3X2_F& worldTransform,
ID2D1SimplifiedGeometrySink* geometrySink,
FLOAT flatteningTolerance = D2D1_DEFAULT_FLATTENING_TOLERANCE) const;

Parameters
strokeWidth
The amount by which to widen the geometry.
strokeStyle
The style of stroke to apply to the geometry, or NULL.
worldTransform
The transform to apply to the geometry after widening it.
geometrySink
The ID2D1SimplifiedGeometrySink to which the widened geometry is appended.
flatteningTolerance
The maximum bounds on the distance between points in the polygonal approximation of the geometry. Smaller
values produce more accurate results but cause slower execution.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

See also
Classes
CD2DGeometrySink Class
4/21/2020 • 4 minutes to read • Edit Online

A wrapper for ID2D1GeometrySink.

Syntax
class CD2DGeometrySink;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DGeometrySink::CD2DGeometrySink Constructs a CD2DGeometrySink object from


CD2DPathGeometry object.

CD2DGeometrySink::~CD2DGeometrySink The destructor. Called when a D2D geometry sink object is


being destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DGeometrySink::AddArc Adds a single arc to the path geometry

CD2DGeometrySink::AddBezier Creates a cubic Bezier curve between the current point and
the specified end point.

CD2DGeometrySink::AddBeziers Creates a sequence of cubic Bezier curves and adds them to


the geometry sink.

CD2DGeometrySink::AddLine Creates a line segment between the current point and the
specified end point and adds it to the geometry sink.

CD2DGeometrySink::AddLines Creates a sequence of lines using the specified points and


adds them to the geometry sink.

CD2DGeometrySink::AddQuadraticBezier Creates a quadratic Bezier curve between the current point


and the specified end point.

CD2DGeometrySink::AddQuadraticBeziers Adds a sequence of quadratic Bezier segments as an array in a


single call.

CD2DGeometrySink::BeginFigure Starts a new figure at the specified point.

CD2DGeometrySink::Close Closes the geometry sink

CD2DGeometrySink::EndFigure Ends the current figure; optionally, closes it.


NAME DESC RIP T IO N

CD2DGeometrySink::Get Returns ID2D1GeometrySink interface

CD2DGeometrySink::IsValid Checks geometry sink validity

CD2DGeometrySink::SetFillMode Specifies the method used to determine which points are


inside the geometry described by this geometry sink and
which points are outside.

CD2DGeometrySink::SetSegmentFlags Specifies stroke and join options to be applied to new


segments added to the geometry sink.

Public Operators
NAME DESC RIP T IO N

CD2DGeometrySink::operator ID2D1GeometrySink* Returns ID2D1GeometrySink interface

Protected Data Members


NAME DESC RIP T IO N

CD2DGeometrySink::m_pSink A pointer to an ID2D1GeometrySink.

Inheritance Hierarchy
CD2DGeometrySink

Requirements
Header : afxrendertarget.h

CD2DGeometrySink::~CD2DGeometrySink
The destructor. Called when a D2D geometry sink object is being destroyed.

virtual ~CD2DGeometrySink();

CD2DGeometrySink::AddArc
Adds a single arc to the path geometry

void AddArc(const D2D1_ARC_SEGMENT& arc);

Parameters
arc
The arc segment to add to the figure

CD2DGeometrySink::AddBezier
Creates a cubic Bezier curve between the current point and the specified end point.
void AddBezier(const D2D1_BEZIER_SEGMENT& bezier);

Parameters
bezier
A structure that describes the control points and end point of the Bezier curve to add.

CD2DGeometrySink::AddBeziers
Creates a sequence of cubic Bezier curves and adds them to the geometry sink.

void AddBeziers(
const CArray<D2D1_BEZIER_SEGMENT,
D2D1_BEZIER_SEGMENT>& beziers);

Parameters
beziers
An array of Bezier segments that describes the Bezier curves to create. A curve is drawn from the geometry sink's
current point (the end point of the last segment drawn or the location specified by BeginFigure) to the end point of
the first Bezier segment in the array. if the array contains additional Bezier segments, each subsequent Bezier
segment uses the end point of the preceding Bezier segment as its start point.

CD2DGeometrySink::AddLine
Creates a line segment between the current point and the specified end point and adds it to the geometry sink.

void AddLine(CD2DPointF point);

Parameters
point
The end point of the line to draw.

CD2DGeometrySink::AddLines
Creates a sequence of lines using the specified points and adds them to the geometry sink.

void AddLines(
const CArray<CD2DPointF,
CD2DPointF>& points);

Parameters
points
An array of one or more points that describe the lines to draw. A line is drawn from the geometry sink's current
point (the end point of the last segment drawn or the location specified by BeginFigure) to the first point in the
array. if the array contains additional points, a line is drawn from the first point to the second point in the array,
from the second point to the third point, and so on. An array of a sequence of the end points of the lines to draw.

CD2DGeometrySink::AddQuadraticBezier
Creates a quadratic Bezier curve between the current point and the specified end point.
void AddQuadraticBezier(const D2D1_QUADRATIC_BEZIER_SEGMENT& bezier);

Parameters
bezier
A structure that describes the control point and the end point of the quadratic Bezier curve to add.

CD2DGeometrySink::AddQuadraticBeziers
Adds a sequence of quadratic Bezier segments as an array in a single call.

void AddQuadraticBeziers(
const CArray<D2D1_QUADRATIC_BEZIER_SEGMENT,
D2D1_QUADRATIC_BEZIER_SEGMENT>& beziers);

Parameters
beziers
An array of a sequence of quadratic Bezier segments.

CD2DGeometrySink::BeginFigure
Starts a new figure at the specified point.

void BeginFigure(
CD2DPointF startPoint,
D2D1_FIGURE_BEGIN figureBegin);

Parameters
startPoint
The point at which to begin the new figure.
figureBegin
Whether the new figure should be hollow or filled.

CD2DGeometrySink::CD2DGeometrySink
Constructs a CD2DGeometrySink object from CD2DPathGeometry object.

CD2DGeometrySink(CD2DPathGeometry& pathGeometry);

Parameters
pathGeometry
An existing CD2DPathGeometry object.

CD2DGeometrySink::Close
Closes the geometry sink

BOOL Close();

Return Value
Nonzero if successful; otherwise FALSE.

CD2DGeometrySink::EndFigure
Ends the current figure; optionally, closes it.

void EndFigure(D2D1_FIGURE_END figureEnd);

Parameters
figureEnd
A value that indicates whether the current figure is closed. If the figure is closed, a line is drawn between the
current point and the start point specified by BeginFigure.

CD2DGeometrySink::Get
Returns ID2D1GeometrySink interface

ID2D1GeometrySink* Get();

Return Value
Pointer to an ID2D1GeometrySink interface or NULL if object is not initialized yet.

CD2DGeometrySink::IsValid
Checks geometry sink validity

BOOL IsValid() const;

Return Value
TRUE if geometry sink is valid; otherwise FALSE.

CD2DGeometrySink::m_pSink
A pointer to an ID2D1GeometrySink.

ID2D1GeometrySink* m_pSink;

CD2DGeometrySink::operator ID2D1GeometrySink*
Returns ID2D1GeometrySink interface

operator ID2D1GeometrySink*();

Return Value
Pointer to an ID2D1GeometrySink interface or NULL if object is not initialized yet.

CD2DGeometrySink::SetFillMode
Specifies the method used to determine which points are inside the geometry described by this geometry sink and
which points are outside.

void SetFillMode(D2D1_FILL_MODE fillMode);

Parameters
fillMode
The method used to determine whether a given point is part of the geometry.

CD2DGeometrySink::SetSegmentFlags
Specifies stroke and join options to be applied to new segments added to the geometry sink.

void SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags);

Parameters
vertexFlags
Stroke and join options to be applied to new segments added to the geometry sink.

See also
Classes
CD2DGradientBrush Class
3/27/2020 • 2 minutes to read • Edit Online

The base class of the CD2DLinearGradientBrush and the CD2DRadialGradientBrush classes.

Syntax
class CD2DGradientBrush : public CD2DBrush;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DGradientBrush::CD2DGradientBrush Constructs a CD2DGradientBrush object.

CD2DGradientBrush::~CD2DGradientBrush The destructor. Called when a D2D gradient brush object is


being destroyed.

Protected Methods
NAME DESC RIP T IO N

CD2DGradientBrush::Destroy Destroys a CD2DGradientBrush object. (Overrides


CD2DBrush::Destroy.)

Protected Data Members


NAME DESC RIP T IO N

CD2DGradientBrush::m_arGradientStops Array of the D2D1_GRADIENT_STOP structures.

CD2DGradientBrush::m_colorInterpolationGamma The space in which color interpolation between the gradient


stops is performed.

CD2DGradientBrush::m_extendMode The behavior of the gradient outside the [0,1] normalized


range.

CD2DGradientBrush::m_pGradientStops A pointer to an array of D2D1_GRADIENT_STOP structures.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush
CD2DGradientBrush
Requirements
Header : afxrendertarget.h

CD2DGradientBrush::~CD2DGradientBrush
The destructor. Called when a D2D gradient brush object is being destroyed.

virtual ~CD2DGradientBrush();

CD2DGradientBrush::CD2DGradientBrush
Constructs a CD2DGradientBrush object.

CD2DGradientBrush(
CRenderTarget* pParentTarget,
const D2D1_GRADIENT_STOP* gradientStops,
UINT gradientStopsCount,
D2D1_GAMMA colorInterpolationGamma = D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE extendMode = D2D1_EXTEND_MODE_CLAMP,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
gradientStops
A pointer to an array of D2D1_GRADIENT_STOP structures.
gradientStopsCount
A value greater than or equal to 1 that specifies the number of gradient stops in the gradientStops array.
colorInterpolationGamma
The space in which color interpolation between the gradient stops is performed.
extendMode
The behavior of the gradient outside the [0,1] normalized range.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DGradientBrush::Destroy
Destroys a CD2DGradientBrush object.

virtual void Destroy();

CD2DGradientBrush::m_arGradientStops
Array of the D2D1_GRADIENT_STOP structures.
CArray<D2D1_GRADIENT_STOP, D2D1_GRADIENT_STOP> m_arGradientStops;

CD2DGradientBrush::m_colorInterpolationGamma
The space in which color interpolation between the gradient stops is performed.

D2D1_GAMMA m_colorInterpolationGamma;

CD2DGradientBrush::m_extendMode
The behavior of the gradient outside the [0,1] normalized range.

D2D1_EXTEND_MODE m_extendMode;

CD2DGradientBrush::m_pGradientStops
A pointer to an array of D2D1_GRADIENT_STOP structures.

ID2D1GradientStopCollection* m_pGradientStops;

See also
Classes
CD2DLayer Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1Layer.

Syntax
class CD2DLayer : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DLayer::CD2DLayer Constructs a CD2DLayer object.

CD2DLayer::~CD2DLayer The destructor. Called when a D2D layer object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DLayer::Attach Attaches existing resource interface to the object

CD2DLayer::Create Creates a CD2DLayer. (Overrides CD2DResource::Create.)

CD2DLayer::Destroy Destroys a CD2DLayer object. (Overrides


CD2DResource::Destroy.)

CD2DLayer::Detach Detaches resource interface from the object

CD2DLayer::Get Returns ID2D1Layer interface

CD2DLayer::GetSize Returns the size of the render target in device-independent


pixels

CD2DLayer::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

Public Operators
NAME DESC RIP T IO N

CD2DLayer::operator ID2D1Layer* Returns ID2D1Layer interface

Protected Data Members


NAME DESC RIP T IO N

CD2DLayer::m_pLayer Stores a pointer to an ID2D1Layer object.

Inheritance Hierarchy
CObject
CD2DResource
CD2DLayer

Requirements
Header : afxrendertarget.h

CD2DLayer::~CD2DLayer
The destructor. Called when a D2D layer object is being destroyed.

virtual ~CD2DLayer();

CD2DLayer::Attach
Attaches existing resource interface to the object

void Attach(ID2D1Layer* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DLayer::CD2DLayer
Constructs a CD2DLayer object.

CD2DLayer(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DLayer::Create
Creates a CD2DLayer.
virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DLayer::Destroy
Destroys a CD2DLayer object.

virtual void Destroy();

CD2DLayer::Detach
Detaches resource interface from the object

ID2D1Layer* Detach();

Return Value
Pointer to detached resource interface.

CD2DLayer::Get
Returns ID2D1Layer interface

ID2D1Layer* Get();

Return Value
Pointer to an ID2D1Layer interface or NULL if object is not initialized yet.

CD2DLayer::GetSize
Returns the size of the render target in device-independent pixels

CD2DSizeF GetSize() const;

Return Value
The current size of the render target in device-independent pixels

CD2DLayer::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DLayer::m_pLayer
Stores a pointer to an ID2D1Layer object.

ID2D1Layer* m_pLayer;

CD2DLayer::operator ID2D1Layer*
Returns ID2D1Layer interface

operator ID2D1Layer* ();

Return Value
Pointer to an ID2D1Layer interface or NULL if object is not initialized yet.

See also
Classes
CD2DLinearGradientBrush Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1LinearGradientBrush.

Syntax
class CD2DLinearGradientBrush : public CD2DGradientBrush;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DLinearGradientBrush::CD2DLinearGradientBrush Constructs a CD2DLinearGradientBrush object.

CD2DLinearGradientBrush::~CD2DLinearGradientBrush The destructor. Called when a D2D linear gradient brush


object is being destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DLinearGradientBrush::Attach Attaches existing resource interface to the object

CD2DLinearGradientBrush::Create Creates a CD2DLinearGradientBrush. (Overrides


CD2DResource::Create.)

CD2DLinearGradientBrush::Destroy Destroys a CD2DLinearGradientBrush object. (Overrides


CD2DGradientBrush::Destroy.)

CD2DLinearGradientBrush::Detach Detaches resource interface from the object

CD2DLinearGradientBrush::Get Returns ID2D1LinearGradientBrush interface

CD2DLinearGradientBrush::GetEndPoint Retrieves the ending coordinates of the linear gradient

CD2DLinearGradientBrush::GetStartPoint Retrieves the starting coordinates of the linear gradient

CD2DLinearGradientBrush::SetEndPoint Sets the ending coordinates of the linear gradient in the


brush's coordinate space

CD2DLinearGradientBrush::SetStartPoint Sets the starting coordinates of the linear gradient in the


brush's coordinate space

Public Operators
NAME DESC RIP T IO N

CD2DLinearGradientBrush::operator Returns ID2D1LinearGradientBrush interface


ID2D1LinearGradientBrush*

Protected Data Members


NAME DESC RIP T IO N

CD2DLinearGradientBrush::m_LinearGradientBrushProperties The start and end points of the gradient.

CD2DLinearGradientBrush::m_pLinearGradientBrush A pointer to an ID2D1LinearGradientBrush.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush
CD2DGradientBrush
CD2DLinearGradientBrush

Requirements
Header : afxrendertarget.h

CD2DLinearGradientBrush::~CD2DLinearGradientBrush
The destructor. Called when a D2D linear gradient brush object is being destroyed.

virtual ~CD2DLinearGradientBrush();

CD2DLinearGradientBrush::Attach
Attaches existing resource interface to the object

void Attach(ID2D1LinearGradientBrush* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DLinearGradientBrush::CD2DLinearGradientBrush
Constructs a CD2DLinearGradientBrush object.
CD2DLinearGradientBrush(
CRenderTarget* pParentTarget,
const D2D1_GRADIENT_STOP* gradientStops,
UINT gradientStopsCount,
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES LinearGradientBrushProperties,
D2D1_GAMMA colorInterpolationGamma = D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE extendMode = D2D1_EXTEND_MODE_CLAMP,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
gradientStops
A pointer to an array of D2D1_GRADIENT_STOP structures.
gradientStopsCount
A value greater than or equal to 1 that specifies the number of gradient stops in the gradientStops array.
LinearGradientBrushProperties
The start and end points of the gradient.
colorInterpolationGamma
The space in which color interpolation between the gradient stops is performed.
extendMode
The behavior of the gradient outside the [0,1] normalized range.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DLinearGradientBrush::Create
Creates a CD2DLinearGradientBrush.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DLinearGradientBrush::Destroy
Destroys a CD2DLinearGradientBrush object.

virtual void Destroy();


CD2DLinearGradientBrush::Detach
Detaches resource interface from the object

ID2D1LinearGradientBrush* Detach();

Return Value
Pointer to detached resource interface.

CD2DLinearGradientBrush::Get
Returns ID2D1LinearGradientBrush interface

ID2D1LinearGradientBrush* Get();

Return Value
Pointer to an ID2D1LinearGradientBrush interface or NULL if object is not initialized yet.

CD2DLinearGradientBrush::GetEndPoint
Retrieves the ending coordinates of the linear gradient

CD2DPointF GetEndPoint() const;

Return Value
The ending two-dimensional coordinates of the linear gradient, in the brush's coordinate space

CD2DLinearGradientBrush::GetStartPoint
Retrieves the starting coordinates of the linear gradient

CD2DPointF GetStartPoint() const;

Return Value
The starting two-dimensional coordinates of the linear gradient, in the brush's coordinate space

CD2DLinearGradientBrush::m_LinearGradientBrushProperties
The start and end points of the gradient.

D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES m_LinearGradientBrushProperties;

CD2DLinearGradientBrush::m_pLinearGradientBrush
A pointer to an ID2D1LinearGradientBrush.

ID2D1LinearGradientBrush* m_pLinearGradientBrush;
CD2DLinearGradientBrush::operator ID2D1LinearGradientBrush*
Returns ID2D1LinearGradientBrush interface

operator ID2D1LinearGradientBrush*();

Return Value
Pointer to an ID2D1LinearGradientBrush interface or NULL if object is not initialized yet.

CD2DLinearGradientBrush::SetEndPoint
Sets the ending coordinates of the linear gradient in the brush's coordinate space

void SetEndPoint(CD2DPointF point);

Parameters
point
The ending two-dimensional coordinates of the linear gradient, in the brush's coordinate space

CD2DLinearGradientBrush::SetStartPoint
Sets the starting coordinates of the linear gradient in the brush's coordinate space

void SetStartPoint(CD2DPointF point);

Parameters
point
The starting two-dimensional coordinates of the linear gradient, in the brush's coordinate space

See also
Classes
CD2DMesh Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1Mesh.

Syntax
class CD2DMesh : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DMesh::CD2DMesh Constructs a CD2DMesh object.

CD2DMesh::~CD2DMesh The destructor. Called when a D2D mesh object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DMesh::Attach Attaches existing resource interface to the object

CD2DMesh::Create Creates a CD2DMesh. (Overrides CD2DResource::Create.)

CD2DMesh::Destroy Destroys a CD2DMesh object. (Overrides


CD2DResource::Destroy.)

CD2DMesh::Detach Detaches resource interface from the object

CD2DMesh::Get Returns ID2D1Mesh interface

CD2DMesh::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

CD2DMesh::Open Opens the mesh for population.

Public Operators
NAME DESC RIP T IO N

CD2DMesh::operator ID2D1Mesh* Returns ID2D1Mesh interface

Protected Data Members


NAME DESC RIP T IO N

CD2DMesh::m_pMesh A pointer to an ID2D1Mesh.

Inheritance Hierarchy
CObject
CD2DResource
CD2DMesh

Requirements
Header : afxrendertarget.h

CD2DMesh::~CD2DMesh
The destructor. Called when a D2D mesh object is being destroyed.

virtual ~CD2DMesh();

CD2DMesh::Attach
Attaches existing resource interface to the object

void Attach(ID2D1Mesh* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DMesh::CD2DMesh
Constructs a CD2DMesh object.

CD2DMesh(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DMesh::Create
Creates a CD2DMesh.
virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DMesh::Destroy
Destroys a CD2DMesh object.

virtual void Destroy();

CD2DMesh::Detach
Detaches resource interface from the object

ID2D1Mesh* Detach();

Return Value
Pointer to detached resource interface.

CD2DMesh::Get
Returns ID2D1Mesh interface

ID2D1Mesh* Get();

Return Value
Pointer to an ID2D1Mesh interface or NULL if object is not initialized yet.

CD2DMesh::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DMesh::m_pMesh
A pointer to an ID2D1Mesh.

ID2D1Mesh* m_pMesh;
CD2DMesh::Open
Opens the mesh for population.

ID2D1TessellationSink* Open();

Return Value
A pointer to an ID2D1TessellationSink that is used to populate the mesh.

CD2DMesh::operator ID2D1Mesh*
Returns ID2D1Mesh interface

operator ID2D1Mesh*();

Return Value
Pointer to an ID2D1Mesh interface or NULL if object is not initialized yet.

See also
Classes
CD2DPathGeometry Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1PathGeometry.

Syntax
class CD2DPathGeometry : public CD2DGeometry;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DPathGeometry::CD2DPathGeometry Constructs a CD2DPathGeometry object.

Public Methods
NAME DESC RIP T IO N

CD2DPathGeometry::Attach Attaches existing resource interface to the object

CD2DPathGeometry::Create Creates a CD2DPathGeometry. (Overrides


CD2DResource::Create.)

CD2DPathGeometry::Destroy Destroys a CD2DPathGeometry object. (Overrides


CD2DGeometry::Destroy.)

CD2DPathGeometry::Detach Detaches resource interface from the object

CD2DPathGeometry::GetFigureCount Retrieves tthe number of figures in the path geometry.

CD2DPathGeometry::GetSegmentCount Retrieves the number of segments in the path geometry.

CD2DPathGeometry::Open Retrieves the geometry sink that is used to populate the path
geometry with figures and segments.

CD2DPathGeometry::Stream Copies the contents of the path geometry to the specified


ID2D1GeometrySink.

Protected Data Members


NAME DESC RIP T IO N

CD2DPathGeometry::m_pPathGeometry A pointer to an ID2D1PathGeometry.

Inheritance Hierarchy
CObject
CD2DResource
CD2DGeometry
CD2DPathGeometry

Requirements
Header : afxrendertarget.h

CD2DPathGeometry::Attach
Attaches existing resource interface to the object

void Attach(ID2D1PathGeometry* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DPathGeometry::CD2DPathGeometry
Constructs a CD2DPathGeometry object.

CD2DPathGeometry(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DPathGeometry::Create
Creates a CD2DPathGeometry.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DPathGeometry::Destroy
Destroys a CD2DPathGeometry object.
virtual void Destroy();

CD2DPathGeometry::Detach
Detaches resource interface from the object

ID2D1PathGeometry* Detach();

Return Value
Pointer to detached resource interface.

CD2DPathGeometry::GetFigureCount
Retrieves tthe number of figures in the path geometry.

int GetFigureCount() const;

Return Value
Returns the number of figures in the path geometry.

CD2DPathGeometry::GetSegmentCount
Retrieves the number of segments in the path geometry.

int GetSegmentCount() const;

Return Value
Returns the number of segments in the path geometry.

CD2DPathGeometry::m_pPathGeometry
A pointer to an ID2D1PathGeometry.

ID2D1PathGeometry* m_pPathGeometry;

CD2DPathGeometry::Open
Retrieves the geometry sink that is used to populate the path geometry with figures and segments.

ID2D1GeometrySink* Open();

Return Value
A pointer to the ID2D1GeometrySink that is used to populate the path geometry with figures and segments.

CD2DPathGeometry::Stream
Copies the contents of the path geometry to the specified ID2D1GeometrySink.
BOOL Stream(ID2D1GeometrySink* geometrySink);

Parameters
geometrySink
The sink to which the path geometry's contents are copied. Modifying this sink does not change the contents of this
path geometry.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

See also
Classes
CD2DPointF Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_POINT_2F .

Syntax
class CD2DPointF : public D2D1_POINT_2F;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DPointF::CD2DPointF Overloaded. Constructs a CD2DPointF object from


D2D1_POINT_2F object.

Public Operators
NAME DESC RIP T IO N

CD2DPointF::operator CPoint Converts CD2DPointF to CPoint object.

Inheritance Hierarchy
D2D1_POINT_2F

CD2DPointF

Requirements
Header : afxrendertarget.h

CD2DPointF::CD2DPointF
Constructs a CD2DPointF object from CPoint object.

CD2DPointF(const CPoint& pt);


CD2DPointF(const D2D1_POINT_2F& pt);
CD2DPointF(const D2D1_POINT_2F* pt);
CD2DPointF(FLOAT fX = 0., FLOAT fY = 0.);

Parameters
pt
source point
fX
source X
fY
source Y

CD2DPointF::operator CPoint
Converts CD2DPointF to CPoint object.

operator CPoint();

Return Value
Current value of D2D point.

See also
Classes
CD2DPointU Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_POINT_2U .

Syntax
class CD2DPointU : public D2D1_POINT_2U;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DPointU::CD2DPointU Overloaded. Constructs a CD2DPointU from object


D2D1_POINT_2U object.

Public Operators
NAME DESC RIP T IO N

CD2DPointU::operator CPoint Converts CD2DPointU to CPoint object.

Inheritance Hierarchy
D2D1_POINT_2U

CD2DPointU

Requirements
Header : afxrendertarget.h

CD2DPointU::CD2DPointU
Constructs a CD2DPointU object from CPoint object.

CD2DPointU(const CPoint& pt);


CD2DPointU(const D2D1_POINT_2U& pt);
CD2DPointU(const D2D1_POINT_2U* pt);
CD2DPointU(UINT32 uX = 0, UINT32 uY = 0);

Parameters
pt
source point
uX
source X
uY
source Y

CD2DPointU::operator CPoint
Converts CD2DPointU to CPoint object.

operator CPoint();

Return Value
Current value of D2D point.

See also
Classes
CD2DRadialGradientBrush Class
4/21/2020 • 3 minutes to read • Edit Online

A wrapper for ID2D1RadialGradientBrush.

Syntax
class CD2DRadialGradientBrush : public CD2DGradientBrush;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DRadialGradientBrush::CD2DRadialGradientBrush Constructs a CD2DLinearGradientBrush object.

CD2DRadialGradientBrush::~CD2DRadialGradientBrush The destructor. Called when a D2D radial gradient brush


object is being destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DRadialGradientBrush::Attach Attaches existing resource interface to the object

CD2DRadialGradientBrush::Create Creates a CD2DRadialGradientBrush. (Overrides


CD2DResource::Create.)

CD2DRadialGradientBrush::Destroy Destroys a CD2DRadialGradientBrush object. (Overrides


CD2DGradientBrush::Destroy.)

CD2DRadialGradientBrush::Detach Detaches resource interface from the object

CD2DRadialGradientBrush::Get Returns ID2D1RadialGradientBrush interface

CD2DRadialGradientBrush::GetCenter Retrieves the center of the gradient ellipse

CD2DRadialGradientBrush::GetGradientOriginOffset Retrieves the offset of the gradient origin relative to the


gradient ellipse's center

CD2DRadialGradientBrush::GetRadiusX Retrieves the x-radius of the gradient ellipse

CD2DRadialGradientBrush::GetRadiusY Retrieves the y-radius of the gradient ellipse

CD2DRadialGradientBrush::SetCenter Specifies the center of the gradient ellipse in the brush's


coordinate space
NAME DESC RIP T IO N

CD2DRadialGradientBrush::SetGradientOriginOffset Specifies the offset of the gradient origin relative to the


gradient ellipse's center

CD2DRadialGradientBrush::SetRadiusX Specifies the x-radius of the gradient ellipse, in the brush's


coordinate space

CD2DRadialGradientBrush::SetRadiusY Specifies the y-radius of the gradient ellipse, in the brush's


coordinate space

Public Operators
NAME DESC RIP T IO N

CD2DRadialGradientBrush::operator Returns ID2D1RadialGradientBrush interface


ID2D1RadialGradientBrush*

Protected Data Members


NAME DESC RIP T IO N

CD2DRadialGradientBrush::m_pRadialGradientBrush A pointer to an ID2D1RadialGradientBrush.

CD2DRadialGradientBrush::m_RadialGradientBrushProperties The center, gradient origin offset, and x-radius and y-radius of
the brush's gradient.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush
CD2DGradientBrush
CD2DRadialGradientBrush

Requirements
Header : afxrendertarget.h

CD2DRadialGradientBrush::~CD2DRadialGradientBrush
The destructor. Called when a D2D radial gradient brush object is being destroyed.

virtual ~CD2DRadialGradientBrush();

CD2DRadialGradientBrush::Attach
Attaches existing resource interface to the object

void Attach(ID2D1RadialGradientBrush* pResource);


Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DRadialGradientBrush::CD2DRadialGradientBrush
Constructs a CD2DLinearGradientBrush object.

CD2DRadialGradientBrush(
CRenderTarget* pParentTarget,
const D2D1_GRADIENT_STOP* gradientStops,
UINT gradientStopsCount,
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES RadialGradientBrushProperties,
D2D1_GAMMA colorInterpolationGamma = D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE extendMode = D2D1_EXTEND_MODE_CLAMP,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
gradientStops
A pointer to an array of D2D1_GRADIENT_STOP structures.
gradientStopsCount
A value greater than or equal to 1 that specifies the number of gradient stops in the gradientStops array.
RadialGradientBrushProperties
The center, gradient origin offset, and x-radius and y-radius of the brush's gradient.
colorInterpolationGamma
The space in which color interpolation between the gradient stops is performed.
extendMode
The behavior of the gradient outside the [0,1] normalized range.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DRadialGradientBrush::Create
Creates a CD2DRadialGradientBrush.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
CD2DRadialGradientBrush::Destroy
Destroys a CD2DRadialGradientBrush object.

virtual void Destroy();

CD2DRadialGradientBrush::Detach
Detaches resource interface from the object

ID2D1RadialGradientBrush* Detach();

Return Value
Pointer to detached resource interface.

CD2DRadialGradientBrush::Get
Returns ID2D1RadialGradientBrush interface

ID2D1RadialGradientBrush* Get();

Return Value
Pointer to an ID2D1RadialGradientBrush interface or NULL if object is not initialized yet.

CD2DRadialGradientBrush::GetCenter
Retrieves the center of the gradient ellipse

CD2DPointF GetCenter() const;

Return Value
The center of the gradient ellipse. This value is expressed in the brush's coordinate space

CD2DRadialGradientBrush::GetGradientOriginOffset
Retrieves the offset of the gradient origin relative to the gradient ellipse's center

CD2DPointF GetGradientOriginOffset() const;

Return Value
The offset of the gradient origin from the center of the gradient ellipse. This value is expressed in the brush's
coordinate space

CD2DRadialGradientBrush::GetRadiusX
Retrieves the x-radius of the gradient ellipse

FLOAT GetRadiusX() const;


Return Value
The x-radius of the gradient ellipse. This value is expressed in the brush's coordinate space

CD2DRadialGradientBrush::GetRadiusY
Retrieves the y-radius of the gradient ellipse

FLOAT GetRadiusY() const;

Return Value
The y-radius of the gradient ellipse. This value is expressed in the brush's coordinate space

CD2DRadialGradientBrush::m_pRadialGradientBrush
A pointer to an ID2D1RadialGradientBrush.

ID2D1RadialGradientBrush* m_pRadialGradientBrush;

CD2DRadialGradientBrush::m_RadialGradientBrushProperties
The center, gradient origin offset, and x-radius and y-radius of the brush's gradient.

D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES m_RadialGradientBrushProperties;

CD2DRadialGradientBrush::operator ID2D1RadialGradientBrush*
Returns ID2D1RadialGradientBrush interface

operator ID2D1RadialGradientBrush*();

Return Value
Pointer to an ID2D1RadialGradientBrush interface or NULL if object is not initialized yet.

CD2DRadialGradientBrush::SetCenter
Specifies the center of the gradient ellipse in the brush's coordinate space

void SetCenter(CD2DPointF point);

Parameters
point
The center of the gradient ellipse, in the brush's coordinate space

CD2DRadialGradientBrush::SetGradientOriginOffset
Specifies the offset of the gradient origin relative to the gradient ellipse's center

void SetGradientOriginOffset(CD2DPointF gradientOriginOffset);


Parameters
gradientOriginOffset
The offset of the gradient origin from the center of the gradient ellipse

CD2DRadialGradientBrush::SetRadiusX
Specifies the x-radius of the gradient ellipse, in the brush's coordinate space

void SetRadiusX(FLOAT radiusX);

Parameters
radiusX
The x-radius of the gradient ellipse. This value is in the brush's coordinate space

CD2DRadialGradientBrush::SetRadiusY
Specifies the y-radius of the gradient ellipse, in the brush's coordinate space

void SetRadiusY(FLOAT radiusY);

Parameters
radiusY
The y-radius of the gradient ellipse. This value is in the brush's coordinate space

See also
Classes
CD2DRectF Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_RECT_F .

Syntax
class CD2DRectF : public D2D1_RECT_F;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DRectF::CD2DRectF Overloaded. Constructs a CD2DRectF object from


D2D1_RECT_F object.

Public Methods
NAME DESC RIP T IO N

CD2DRectF::IsNull Returns a boolean value that indicates whether an expression


contains no valid data (NULL).

Public Operators
NAME DESC RIP T IO N

CD2DRectF::operator CRect Converts CD2DRectF to CRect object.

Inheritance Hierarchy
D2D1_RECT_F

CD2DRectF

Requirements
Header : afxrendertarget.h

CD2DRectF::CD2DRectF
Constructs a CD2DRectF object from CRect object.
CD2DRectF(const CRect& rect);
CD2DRectF(const D2D1_RECT_F& rect);
CD2DRectF(const D2D1_RECT_F* rect);

CD2DRectF(
FLOAT fLeft = 0.,
FLOAT fTop = 0.,
FLOAT fRight = 0.,
FLOAT fBottom = 0.);

Parameters
rect
source rectangle
fLeft
source left coordinate
fTop
source top coordinate
fRight
source right coordinate
fBottom
source bottom coordinate

CD2DRectF::IsNull
Returns a Boolean value that indicates whether an expression contains no valid data (Null).

BOOL IsNull() const;

Return Value
TRUE if rectangle's top, left, bottom, and right values are all equal to 0; otherwise FALSE.

CD2DRectF::operator CRect
Converts CD2DRectF to CRect object.

operator CRect();

Return Value
Current value of D2D rectangle.

See also
Classes
CD2DRectU Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_RECT_U .

Syntax
class CD2DRectU : public D2D1_RECT_U;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DRectU::CD2DRectU Overloaded. Constructs a CD2DRectU object from


D2D1_RECT_U object.

Public Methods
NAME DESC RIP T IO N

CD2DRectU::IsNull Returns a boolean value that indicates whether an expression


contains no valid data (NULL).

Public Operators
NAME DESC RIP T IO N

CD2DRectU::operator CRect Converts CD2DRectU to CRect object.

Inheritance Hierarchy
D2D1_RECT_U

CD2DRectU

Requirements
Header : afxrendertarget.h

CD2DRectU::CD2DRectU
Constructs a CD2DRectU object from CRect object.
CD2DRectU(const CRect& rect);
CD2DRectU(const D2D1_RECT_U& rect);
CD2DRectU(const D2D1_RECT_U* rect);

CD2DRectU(
UINT32 uLeft = 0,
UINT32 uTop = 0,
UINT32 uRight = 0,
UINT32 uBottom = 0);

Parameters
rect
source rectangle
uLeft
source left coordinate
uTop
source top coordinate
uRight
source right coordinate
uBottom
source bottom coordinate

CD2DRectU::IsNull
Returns a Boolean value that indicates whether an expression contains no valid data (Null).

BOOL IsNull() const;

Return Value
TRUE if rectangle's top, left, bottom, and right values are all equal to 0; otherwise FALSE.

CD2DRectU::operator CRect
Converts CD2DRectU to CRect object.

operator CRect();

Return Value
Current value of D2D rectangle.

See also
Classes
CD2DResource Class
3/27/2020 • 2 minutes to read • Edit Online

An abstract class that provides an interface for creating and managing D2D resources such as brushes, layers,
and texts.

Syntax
class CD2DResource : public CObject;

Members
Protected Constructors
NAME DESC RIP T IO N

CD2DResource::CD2DResource Constructs a CD2DResource object.

CD2DResource::~CD2DResource The destructor. Called when a D2D resource object is being


destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DResource::Create Creates a CD2DResource.

CD2DResource::Destroy Destroys a CD2DResource object.

CD2DResource::IsValid Checks resource validity

Protected Methods
NAME DESC RIP T IO N

CD2DResource::IsAutoDestroy Check auto destroy flag.

CD2DResource::ReCreate Re-creates a CD2DResource.

Protected Data Members


NAME DESC RIP T IO N

CD2DResource::m_bIsAutoDestroy Resource will be destroyed by owner (CRenderTarget)

CD2DResource::m_pParentTarget Pointer to the parent CRenderTarget)

Inheritance Hierarchy
CObject
CD2DResource

Requirements
Header : afxrendertarget.h

CD2DResource::~CD2DResource
The destructor. Called when a D2D resource object is being destroyed.

virtual ~CD2DResource();

CD2DResource::CD2DResource
Constructs a CD2DResource object.

CD2DResource(
CRenderTarget* pParentTarget,
BOOL bAutoDestroy);

Parameters
pParentTarget
A pointer to the render target.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DResource::Create
Creates a CD2DResource.

virtual HRESULT Create(CRenderTarget* pRenderTarget) = 0;

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DResource::Destroy
Destroys a CD2DResource object.

virtual void Destroy() = 0;

CD2DResource::IsAutoDestroy
Check auto destroy flag.
BOOL IsAutoDestroy() const;

Return Value
TRUE if the object will be destroyed by its owner; otherwise FALSE.

CD2DResource::IsValid
Checks resource validity

virtual BOOL IsValid() const = 0;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DResource::m_bIsAutoDestroy
Resource will be destroyed by owner (CRenderTarget)

BOOL m_bIsAutoDestroy;

CD2DResource::m_pParentTarget
Pointer to the parent CRenderTarget)

CRenderTarget* m_pParentTarget;

CD2DResource::ReCreate
Re-creates a CD2DResource.

virtual HRESULT ReCreate(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

See also
Classes
CD2DRoundedRect Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_ROUNDED_RECT .

Syntax
class CD2DRoundedRect : public D2D1_ROUNDED_RECT;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DRoundedRect::CD2DRoundedRect Overloaded. Constructs a CD2DRoundedRect object from


D2D1_ROUNDED_RECT object.

Inheritance Hierarchy
D2D1_ROUNDED_RECT

CD2DRoundedRect

Requirements
Header : afxrendertarget.h

CD2DRoundedRect::CD2DRoundedRect
Constructs a CD2DRoundedRect object from CD2DRectF object.

CD2DRoundedRect(
const CD2DRectF& rectIn,
const CD2DSizeF& sizeRadius);

CD2DRoundedRect(const D2D1_ROUNDED_RECT& rectIn);


CD2DRoundedRect(const D2D1_ROUNDED_RECT* rectIn);

Parameters
rectIn
source rectangle
sizeRadius
radius size

See also
Classes
CD2DSizeF Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_SIZE_F.

Syntax
class CD2DSizeF : public D2D1_SIZE_F;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DSizeF::CD2DSizeF Overloaded. Constructs a CD2DSizeF object from


D2D1_SIZE_F object.

Public Methods
NAME DESC RIP T IO N

CD2DSizeF::IsNull Returns a boolean value that indicates whether an expression


contains no valid data (NULL).

Public Operators
NAME DESC RIP T IO N

CD2DSizeF::operator CSize Converts CD2DSizeF to CSize object.

Inheritance Hierarchy
D2D1_SIZE_F

CD2DSizeF

Requirements
Header : afxrendertarget.h

CD2DSizeF::CD2DSizeF
Constructs a CD2DSizeF object from CSize object.
CD2DSizeF(const CSize& size);
CD2DSizeF(const D2D1_SIZE_F& size);
CD2DSizeF(const D2D1_SIZE_F* size);

CD2DSizeF(
FLOAT cx = 0.,
FLOAT cy = 0.);

Parameters
size
source size
cx
source width
cy
source height

CD2DSizeF::IsNull
Returns a Boolean value that indicates whether an expression contains no valid data (Null).

BOOL IsNull() const;

Return Value
TRUE if width and height are empty; otherwise FALSE.

CD2DSizeF::operator CSize
Converts CD2DSizeF to CSize object.

operator CSize();

Return Value
Current value of D2D size.

See also
Classes
CD2DSizeU Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for D2D1_SIZE_U.

Syntax
class CD2DSizeU : public D2D1_SIZE_U;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DSizeU::CD2DSizeU Overloaded. Constructs a CD2DSizeU object from


D2D1_SIZE_U object.

Public Methods
NAME DESC RIP T IO N

CD2DSizeU::IsNull Returns a boolean value that indicates whether an expression


contains no valid data (NULL).

Public Operators
NAME DESC RIP T IO N

CD2DSizeU::operator CSize Converts CD2DSizeU to CSize object.

Inheritance Hierarchy
D2D1_SIZE_U

CD2DSizeU

Requirements
Header : afxrendertarget.h

CD2DSizeU::CD2DSizeU
Constructs a CD2DSizeU object from CSize object.
CD2DSizeU(const CSize& size);
CD2DSizeU(const D2D1_SIZE_U& size);
CD2DSizeU(const D2D1_SIZE_U* size);

CD2DSizeU(
UINT32 cx = 0,
UINT32 cy = 0);

Parameters
size
source size
cx
source width
cy
source height

CD2DSizeU::IsNull
Returns a Boolean value that indicates whether an expression contains no valid data (Null).

BOOL IsNull() const;

Return Value
TRUE if width and height are empty; otherwise FALSE.

CD2DSizeU::operator CSize
Converts CD2DSizeU to CSize object.

operator CSize();

Return Value
Current value of D2D size.

See also
Classes
CD2DSolidColorBrush Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1SolidColorBrush.

Syntax
class CD2DSolidColorBrush : public CD2DBrush;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DSolidColorBrush::CD2DSolidColorBrush Overloaded. Constructs a CD2DSolidColorBrush object.

CD2DSolidColorBrush::~CD2DSolidColorBrush The destructor. Called when a D2D solid brush object is being
destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DSolidColorBrush::Attach Attaches existing resource interface to the object

CD2DSolidColorBrush::Create Creates a CD2DSolidColorBrush. (Overrides


CD2DResource::Create.)

CD2DSolidColorBrush::Destroy Destroys a CD2DSolidColorBrush object. (Overrides


CD2DBrush::Destroy.)

CD2DSolidColorBrush::Detach Detaches resource interface from the object

CD2DSolidColorBrush::Get Returns ID2D1SolidColorBrush interface

CD2DSolidColorBrush::GetColor Retrieves the color of the solid color brush

CD2DSolidColorBrush::SetColor Specifies the color of this solid color brush

Public Operators
NAME DESC RIP T IO N

CD2DSolidColorBrush::operator ID2D1SolidColorBrush* Returns ID2D1SolidColorBrush interface

Protected Data Members


NAME DESC RIP T IO N

CD2DSolidColorBrush::m_colorSolid Brush solid color.

CD2DSolidColorBrush::m_pSolidColorBrush Stores a pointer to an ID2D1SolidColorBrush object.

Inheritance Hierarchy
CObject
CD2DResource
CD2DBrush
CD2DSolidColorBrush

Requirements
Header : afxrendertarget.h

CD2DSolidColorBrush::~CD2DSolidColorBrush
The destructor. Called when a D2D solid brush object is being destroyed.

virtual ~CD2DSolidColorBrush();

CD2DSolidColorBrush::Attach
Attaches existing resource interface to the object

void Attach(ID2D1SolidColorBrush* pResource);

Parameters
pResource
Existing resource interface. Cannot be NULL

CD2DSolidColorBrush::CD2DSolidColorBrush
Constructs a CD2DSolidColorBrush object.

CD2DSolidColorBrush(
CRenderTarget* pParentTarget,
D2D1_COLOR_F color,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

CD2DSolidColorBrush(
CRenderTarget* pParentTarget,
COLORREF color,
int nAlpha = 255,
CD2DBrushProperties* pBrushProperties = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
color
The red, green, blue, and alpha values of the brush's color.
pBrushProperties
A pointer to the opacity and transformation of a brush.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).
nAlpha
The opacity of the brush's color.

CD2DSolidColorBrush::Create
Creates a CD2DSolidColorBrush.

virtual HRESULT Create(CRenderTarget* pRenderTarget);

Parameters
pRenderTarget
A pointer to the render target.
Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DSolidColorBrush::Destroy
Destroys a CD2DSolidColorBrush object.

virtual void Destroy();

CD2DSolidColorBrush::Detach
Detaches resource interface from the object

ID2D1SolidColorBrush* Detach();

Return Value
Pointer to detached resource interface.

CD2DSolidColorBrush::Get
Returns ID2D1SolidColorBrush interface

ID2D1SolidColorBrush* Get();

Return Value
Pointer to an ID2D1SolidColorBrush interface or NULL if object is not initialized yet.
CD2DSolidColorBrush::GetColor
Retrieves the color of the solid color brush

D2D1_COLOR_F GetColor() const;

Return Value
The color of this solid color brush

CD2DSolidColorBrush::m_colorSolid
Brush solid color.

D2D1_COLOR_F m_colorSolid;

CD2DSolidColorBrush::m_pSolidColorBrush
Stores a pointer to an ID2D1SolidColorBrush object.

ID2D1SolidColorBrush* m_pSolidColorBrush;

CD2DSolidColorBrush::operator ID2D1SolidColorBrush*
Returns ID2D1SolidColorBrush interface

operator ID2D1SolidColorBrush*();

Return Value
Pointer to an ID2D1SolidColorBrush interface or NULL if object is not initialized yet.

CD2DSolidColorBrush::SetColor
Specifies the color of this solid color brush

void SetColor(D2D1_COLOR_F color);

Parameters
color
The color of this solid color brush

See also
Classes
CD2DTextFormat Class
3/27/2020 • 2 minutes to read • Edit Online

A wrapper for IDWriteTextFormat.

Syntax
class CD2DTextFormat : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DTextFormat::CD2DTextFormat Constructs a CD2DTextFormat object.

CD2DTextFormat::~CD2DTextFormat The destructor. Called when a D2D text format object is being
destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DTextFormat::Create Creates a CD2DTextFormat. (Overrides CD2DResource::Create.)

CD2DTextFormat::Destroy Destroys a CD2DTextFormat object. (Overrides


CD2DResource::Destroy.)

CD2DTextFormat::Get Returns IDWriteTextFormat interface

CD2DTextFormat::GetFontFamilyName Gets a copy of the font family name.

CD2DTextFormat::GetLocaleName Gets a copy of the locale name.

CD2DTextFormat::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

CD2DTextFormat::ReCreate Re-creates a CD2DTextFormat. (Overrides


CD2DResource::ReCreate.)

Public Operators
NAME DESC RIP T IO N

CD2DTextFormat::operator IDWriteTextFormat* Returns IDWriteTextFormat interface

Protected Data Members


NAME DESC RIP T IO N

CD2DTextFormat::m_pTextFormat A pointer to an IDWriteTextFormat.

Inheritance Hierarchy
CObject
CD2DResource
CD2DTextFormat

Requirements
Header : afxrendertarget.h

CD2DTextFormat::~CD2DTextFormat
The destructor. Called when a D2D text format object is being destroyed.

virtual ~CD2DTextFormat();

CD2DTextFormat::CD2DTextFormat
Constructs a CD2DTextFormat object.

CD2DTextFormat(
CRenderTarget* pParentTarget,
const CString& strFontFamilyName,
FLOAT fontSize,
DWRITE_FONT_WEIGHT fontWeight = DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE fontStyle = DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH fontStretch = DWRITE_FONT_STRETCH_NORMAL,
const CString& strFontLocale = _T(""),
IDWriteFontCollection* pFontCollection = NULL,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
strFontFamilyName
A CString object that contains the name of the font family.
fontSize
The logical size of the font in DIP ("device-independent pixel") units. A DIPequals 1/96 inch.
fontWeight
A value that indicates the font weight for the text object.
fontStyle
A value that indicates the font style for the text object.
fontStretch
A value that indicates the font stretch for the text object.
strFontLocale
A CString object that contains the locale name.
pFontCollection
A pointer to a font collection object. When this is NULL, indicates the system font collection.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).

CD2DTextFormat::Create
Creates a CD2DTextFormat.

virtual HRESULT Create(CRenderTarget* */);

Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DTextFormat::Destroy
Destroys a CD2DTextFormat object.

virtual void Destroy();

CD2DTextFormat::Get
Returns IDWriteTextFormat interface

IDWriteTextFormat* Get();

Return Value
Pointer to an IDWriteTextFormat interface or NULL if object is not initialized yet.

CD2DTextFormat::GetFontFamilyName
Gets a copy of the font family name.

CString GetFontFamilyName() const;

Return Value
CString object that contains the current font family name.

CD2DTextFormat::GetLocaleName
Gets a copy of the locale name.

CString GetLocaleName() const;

Return Value
CString object that contains the current locale name.
CD2DTextFormat::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DTextFormat::m_pTextFormat
A pointer to an IDWriteTextFormat.

IDWriteTextFormat* m_pTextFormat;

CD2DTextFormat::operator IDWriteTextFormat*
Returns IDWriteTextFormat interface

operator IDWriteTextFormat*();

Return Value
Pointer to an IDWriteTextFormat interface or NULL if object is not initialized yet.

CD2DTextFormat::ReCreate
Re-creates a CD2DTextFormat.

virtual HRESULT ReCreate(CRenderTarget* */);

Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

See also
Classes
CD2DTextLayout Class
3/27/2020 • 3 minutes to read • Edit Online

A wrapper for IDWriteTextLayout.

Syntax
class CD2DTextLayout : public CD2DResource;

Members
Public Constructors
NAME DESC RIP T IO N

CD2DTextLayout::CD2DTextLayout Constructs a CD2DTextLayout object.

CD2DTextLayout::~CD2DTextLayout The destructor. Called when a D2D text layout object is being
destroyed.

Public Methods
NAME DESC RIP T IO N

CD2DTextLayout::Create Creates a CD2DTextLayout. (Overrides CD2DResource::Create.)

CD2DTextLayout::Destroy Destroys a CD2DTextLayout object. (Overrides


CD2DResource::Destroy.)

CD2DTextLayout::Get Returns IDWriteTextLayout interface

CD2DTextLayout::GetFontFamilyName Copies the font family name of the text at the specified
position.

CD2DTextLayout::GetLocaleName Gets the locale name of the text at the specified position.

CD2DTextLayout::IsValid Checks resource validity (Overrides CD2DResource::IsValid.)

CD2DTextLayout::ReCreate Re-creates a CD2DTextLayout. (Overrides


CD2DResource::ReCreate.)

CD2DTextLayout::SetFontFamilyName Sets null-terminated font family name for text within a


specified text range

CD2DTextLayout::SetLocaleName Sets the locale name for text within a specified text range

Public Operators
NAME DESC RIP T IO N

CD2DTextLayout::operator IDWriteTextLayout* Returns IDWriteTextLayout interface

Protected Data Members


NAME DESC RIP T IO N

CD2DTextLayout::m_pTextLayout A pointer to an IDWriteTextLayout.

Inheritance Hierarchy
CObject
CD2DResource
CD2DTextLayout

Requirements
Header : afxrendertarget.h

CD2DTextLayout::~CD2DTextLayout
The destructor. Called when a D2D text layout object is being destroyed.

virtual ~CD2DTextLayout();

CD2DTextLayout::CD2DTextLayout
Constructs a CD2DTextLayout object.

CD2DTextLayout(
CRenderTarget* pParentTarget,
const CString& strText,
CD2DTextFormat& textFormat,
const CD2DSizeF& sizeMax,
BOOL bAutoDestroy = TRUE);

Parameters
pParentTarget
A pointer to the render target.
strText
A CString object that contains the string to create a new CD2DTextLayout object from.
textFormat
A CString object that contains the format to apply to the string.
sizeMax
The size of the layout box.
bAutoDestroy
Indicates that the object will be destroyed by owner (pParentTarget).
CD2DTextLayout::Create
Creates a CD2DTextLayout.

virtual HRESULT Create(CRenderTarget* */);

Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DTextLayout::Destroy
Destroys a CD2DTextLayout object.

virtual void Destroy();

CD2DTextLayout::Get
Returns IDWriteTextLayout interface

IDWriteTextLayout* Get();

Return Value
Pointer to an IDWriteTextLayout interface or NULL if object is not initialized yet.

CD2DTextLayout::GetFontFamilyName
Copies the font family name of the text at the specified position.

CString GetFontFamilyName(
UINT32 currentPosition,
DWRITE_TEXT_RANGE* textRange = NULL) const;

Parameters
currentPosition
The position of the text to examine.
textRange
The range of text that has the same formatting as the text at the position specified by currentPosition. This means
the run has the exact formatting as the position specified, including but not limited to the font family name.
Return Value
CString object that contains the current font family name.

CD2DTextLayout::GetLocaleName
Gets the locale name of the text at the specified position.

CString GetLocaleName(
UINT32 currentPosition,
DWRITE_TEXT_RANGE* textRange = NULL) const;
Parameters
currentPosition
The position of the text to inspect.
textRange
The range of text that has the same formatting as the text at the position specified by currentPosition. This means
the run has the exact formatting as the position specified, including but not limited to the locale name.
Return Value
CString object that contains the current locale name.

CD2DTextLayout::IsValid
Checks resource validity

virtual BOOL IsValid() const;

Return Value
TRUE if resource is valid; otherwise FALSE.

CD2DTextLayout::m_pTextLayout
A pointer to an IDWriteTextLayout.

IDWriteTextLayout* m_pTextLayout;

CD2DTextLayout::operator IDWriteTextLayout*
Returns IDWriteTextLayout interface

operator IDWriteTextLayout*();

Return Value
Pointer to an IDWriteTextLayout interface or NULL if object is not initialized yet.

CD2DTextLayout::ReCreate
Re-creates a CD2DTextLayout.

virtual HRESULT ReCreate(CRenderTarget* */);

Return Value
If the method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.

CD2DTextLayout::SetFontFamilyName
Sets null-terminated font family name for text within a specified text range
BOOL SetFontFamilyName(
LPCWSTR pwzFontFamilyName,
DWRITE_TEXT_RANGE textRange);

Parameters
pwzFontFamilyName
The font family name that applies to the entire text string within the range specified by textRange
textRange
Text range to which this change applies
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE

CD2DTextLayout::SetLocaleName
Sets the locale name for text within a specified text range

BOOL SetLocaleName(
LPCWSTR pwzLocaleName,
DWRITE_TEXT_RANGE textRange);

Parameters
pwzLocaleName
A null-terminated locale name string
textRange
Text range to which this change applies
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE

See also
Classes
CDaoDatabase Class
4/21/2020 • 28 minutes to read • Edit Online

Represents a connection to an Access database using Data Access Objects (DAO). DAO is supported through
Office 2013. DAO 3.6 is the final version, and it is considered obsolete.

Syntax
class CDaoDatabase : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDaoDatabase::CDaoDatabase Constructs a CDaoDatabase object. Call Open to connect


the object to a database.

Public Methods
NAME DESC RIP T IO N

CDaoDatabase::CanTransact Returns nonzero if the database supports transactions.

CDaoDatabase::CanUpdate Returns nonzero if the CDaoDatabase object is updatable


(not read-only).

CDaoDatabase::Close Closes the database connection.

CDaoDatabase::Create Creates the underlying DAO database object and initializes


the CDaoDatabase object.

CDaoDatabase::CreateRelation Defines a new relation among the tables in the database.

CDaoDatabase::DeleteQueryDef Deletes a querydef object saved in the database's


QueryDefs collection.

CDaoDatabase::DeleteRelation Deletes an existing relation between tables in the database.

CDaoDatabase::DeleteTableDef Deletes the definition of a table in the database. This deletes


the actual table and all of its data.

CDaoDatabase::Execute Executes an action query. Calling Execute for a query that


returns results throws an exception.

CDaoDatabase::GetConnect Returns the connection string used to connect the


CDaoDatabase object to a database. Used for ODBC.
NAME DESC RIP T IO N

CDaoDatabase::GetName Returns the name of the database currently in use.

CDaoDatabase::GetQueryDefCount Returns the number of queries defined for the database.

CDaoDatabase::GetQueryDefInfo Returns information about a specified query defined in the


database.

CDaoDatabase::GetQueryTimeout Returns the number of seconds after which database query


operations will time out. Affects all subsequent open, add
new, update, and edit operations and other operations on
ODBC data sources (only) such as Execute calls.

CDaoDatabase::GetRecordsAffected Returns the number of records affected by the last update,


edit, or add operation or by a call to Execute .

CDaoDatabase::GetRelationCount Returns the number of relations defined between tables in


the database.

CDaoDatabase::GetRelationInfo Returns information about a specified relation defined


between tables in the database.

CDaoDatabase::GetTableDefCount Returns the number of tables defined in the database.

CDaoDatabase::GetTableDefInfo Returns information about a specified table in the database.

CDaoDatabase::GetVersion Returns the version of the database engine associated with


the database.

CDaoDatabase::IsOpen Returns nonzero if the CDaoDatabase object is currently


connected to a database.

CDaoDatabase::Open Establishes a connection to a database.

CDaoDatabase::SetQueryTimeout Sets the number of seconds after which database query


operations (on ODBC data sources only) will time out.
Affects all subsequent open, add new, update, and delete
operations.

Public Data Members


NAME DESC RIP T IO N

CDaoDatabase::m_pDAODatabase A pointer to the underlying DAO database object.

CDaoDatabase::m_pWorkspace A pointer to the CDaoWorkspace object that contains the


database and defines its transaction space.

Remarks
For information about the database formats supported, see the GetName member function. You can have one
or more CDaoDatabase objects active at a time in a given "workspace," represented by a CDaoWorkspace object.
The workspace maintains a collection of open database objects, called the Databases collection.
Usage
You can create database objects implicitly, when you create recordset objects. But you can also create database
objects explicitly. To use an existing database explicitly with CDaoDatabase , do either of the following:
Construct a CDaoDatabase object, passing a pointer to an open CDaoWorkspace object.
Or construct a CDaoDatabase object without specifying the workspace (MFC creates a temporary
workspace object).
To create a new Microsoft Jet (.MDB) database, construct a CDaoDatabase object and call its Create member
function. Do not call Open after Create .
To open an existing database, construct a CDaoDatabase object and call its Open member function.
Any of these techniques appends the DAO database object to the workspace's Databases collection and opens a
connection to the data. When you then construct CDaoRecordset, CDaoTableDef, or CDaoQueryDef objects for
operating on the connected database, pass the constructors for these objects a pointer to your CDaoDatabase
object. When you finish using the connection, call the Close member function and destroy the CDaoDatabase
object. Close closes any recordsets you have not closed previously.

Transactions
Database transaction processing is supplied at the workspace level — see the BeginTrans, CommitTrans, and
Rollback member functions of class CDaoWorkspace .

ODBC Connections
The recommended way to work with ODBC data sources is to attach external tables to a Microsoft Jet (.MDB)
database.

Collections
Each database maintains its own collections of tabledef, querydef, recordset, and relation objects. Class
CDaoDatabase supplies member functions for manipulating these objects.

NOTE
The objects are stored in DAO, not in the MFC database object. MFC supplies classes for tabledef, querydef, and
recordset objects but not for relation objects.

Inheritance Hierarchy
CObject
CDaoDatabase

Requirements
Header : afxdao.h

CDaoDatabase::CanTransact
Call this member function to determine whether the database allows transactions.
BOOL CanTransact();

Return Value
Nonzero if the database supports transactions; otherwise 0.
Remarks
Transactions are managed in the database's workspace.

CDaoDatabase::CanUpdate
Call this member function to determine whether the CDaoDatabase object allows updates.

BOOL CanUpdate();

Return Value
Nonzero if the CDaoDatabase object allows updates; otherwise 0, indicating either that you passed TRUE in
bReadOnly when you opened the CDaoDatabase object or that the database itself is read-only. See the Open
member function.
Remarks
For information about database updatability, see the topic "Updatable Property" in DAO Help.

CDaoDatabase::CDaoDatabase
Constructs a CDaoDatabase object.

CDaoDatabase(CDaoWorkspace* pWorkspace = NULL);

Parameters
pWorkspace
A pointer to the CDaoWorkspace object that will contain the new database object. If you accept the default value
of NULL, the constructor creates a temporary CDaoWorkspace object that uses the default DAO workspace. You
can get a pointer to the workspace object via the m_pWorkspace data member.
Remarks
After constructing the object, if you are creating a new Microsoft Jet (.MDB) database, call the object's Create
member function. If you are, instead, opening an existing database, call the object's Open member function.
When you finish with the object, you should call its Close member function and then destroy the CDaoDatabase
object.
You might find it convenient to embed the CDaoDatabase object in your document class.

NOTE
A CDaoDatabase object is also created implicitly if you open a CDaoRecordset object without passing a pointer to an
existing CDaoDatabase object. This database object is closed when you close the recordset object.

CDaoDatabase::Close
Call this member function to disconnect from a database and close any open recordsets, tabledefs, and
querydefs associated with the database.

virtual void Close();

Remarks
It is good practice to close these objects yourself before you call this member function. Closing a CDaoDatabase
object removes it from the Databases collection in the associated workspace. Because Close does not destroy
the CDaoDatabase object, you can reuse the object by opening the same database or a different database.
Cau t i on

Call the Update member function (if there are pending edits) and the Close member function on all open
recordset objects before you close a database. If you exit a function that declares CDaoRecordset or
CDaoDatabase objects on the stack, the database is closed, any unsaved changes are lost, all pending
transactions are rolled back, and any pending edits to your data are lost.
Cau t i on

If you try to close a database object while any recordset objects are open, or if you try to close a workspace
object while any database objects belonging to that specific workspace are open, those recordset objects will be
closed and any pending updates or edits will be rolled back. If you try to close a workspace object while any
database objects belonging to it are open, the operation closes all database objects belonging to that specific
workspace object, which may result in unclosed recordset objects being closed. If you do not close your
database object, MFC reports an assertion failure in debug builds.
If the database object is defined outside the scope of a function, and you exit the function without closing it, the
database object will remain open until explicitly closed or the module in which it is defined is out of scope.

CDaoDatabase::Create
To create a new Microsoft Jet (.MDB) database, call this member function after you construct a CDaoDatabase
object.

virtual void Create(


LPCTSTR lpszName,
LPCTSTR lpszLocale = dbLangGeneral,
int dwOptions = 0);

Parameters
lpszName
A string expression that is the name of the database file that you are creating. It can be the full path and
filename, such as "C:\\MYDB.MDB". You must supply a name. If you do not supply a filename extension, .MDB is
appended. If your network supports the uniform naming convention (UNC), you can also specify a network
path, such as "\\\\MYSERVER\\MYSHARE\\MYDIR\\MYDB". Only Microsoft Jet (.MDB) database files can be
created using this member function. (Double backslashes are required in string literals because "\" is the C++
escape character.)
lpszLocale
A string expression used to specify collating order for creating the database. The default value is dbLangGeneral
. Possible values are:
dbLangGeneral English, German, French, Portuguese, Italian, and Modern Spanish
dbLangArabic Arabic
dbLangCyrillic Russian
dbLangCzech Czech
dbLangDutch Dutch
dbLangGreek Greek
dbLangHebrew Hebrew
dbLangHungarian Hungarian
dbLangIcelandic Icelandic
dbLangNordic Nordic languages (Microsoft Jet database engine version 1.0 only)
dbLangNorwdan Norwegian and Danish
dbLangPolish Polish
dbLangSpanish Traditional Spanish
dbLangSwedfin Swedish and Finnish
dbLangTurkish Turkish

dwOptions
An integer that indicates one or more options. Possible values are:
dbEncrypt Create an encrypted database.
dbVersion10 Create a database with Microsoft Jet database version 1.0.
dbVersion11 Create a database with Microsoft Jet database version 1.1.
dbVersion20 Create a database with Microsoft Jet database version 2.0.
dbVersion30 Create a database with Microsoft Jet database version 3.0.

If you omit the encryption constant, an unencrypted database is created. You can specify only one version
constant. If you omit a version constant, a database that uses the Microsoft Jet database version 3.0 is created.
Cau t i on

If a database is not encrypted, it is possible, even if you implement user/password security, to directly read the
binary disk file that constitutes the database.
Remarks
Create creates the database file and the underlying DAO database object and initializes the C++ object. The
object is appended to the associated workspace's Databases collection. The database object is in an open state;
do not call Open* after Create .

NOTE
With Create , you can create only Microsoft Jet (.MDB) databases. You cannot create ISAM databases or ODBC
databases.

CDaoDatabase::CreateRelation
Call this member function to establish a relation between one or more fields in a primary table in the database
and one or more fields in a foreign table (another table in the database).
void CreateRelation(
LPCTSTR lpszName,
LPCTSTR lpszTable,
LPCTSTR lpszForeignTable,
long lAttributes,
LPCTSTR lpszField,
LPCTSTR lpszForeignField);

void CreateRelation(CDaoRelationInfo& relinfo);

Parameters
lpszName
The unique name of the relation object. The name must start with a letter and can contain a maximum of 40
characters. It can include numbers and underscore characters but cannot include punctuation or spaces.
lpszTable
The name of the primary table in the relation. If the table does not exist, MFC throws an exception of type
CDaoException.
lpszForeignTable
The name of the foreign table in the relation. If the table does not exist, MFC throws an exception of type
CDaoException .

lAttributes
A long value that contains information about the relationship type. You can use this value to enforce referential
integrity, among other things. You can use the bitwise-OR operator ( | ) to combine any of the following values
(as long as the combination makes sense):
dbRelationUnique Relationship is one-to-one.
dbRelationDontEnforce Relationship is not enforced (no referential integrity).
dbRelationInherited Relationship exists in a noncurrent database that contains the two attached tables.
dbRelationUpdateCascade Updates will cascade (for more on cascades, see Remarks).
dbRelationDeleteCascade Deletions will cascade.

lpszField
A pointer to a null-terminated string containing the name of a field in the primary table (named by lpszTable).
lpszForeignField
A pointer to a null-terminated string containing the name of a field in the foreign table (named by
lpszForeignTable).
relinfo
A reference to a CDaoRelationInfo object that contains information about the relation you want to create.
Remarks
The relationship cannot involve a query or an attached table from an external database.
Use the first version of the function when the relation involves one field in each of the two tables. Use the
second version when the relation involves multiple fields. The maximum number of fields in a relation is 14.
This action creates an underlying DAO relation object, but this is an MFC implementation detail since MFC's
encapsulation of relation objects is contained within class CDaoDatabase . MFC does not supply a class for
relations.
If you set the relation object's attributes to activate cascade operations, the database engine automatically
updates or deletes records in one or more other tables when changes are made to related primary key tables.
For example, suppose you establish a cascade delete relationship between a Customers table and an Orders
table. When you delete records from the Customers table, records in the Orders table related to that customer
are also deleted. In addition, if you establish cascade delete relationships between the Orders table and other
tables, records from those tables are automatically deleted when you delete records from the Customers table.
For related information, see the topic "CreateRelation Method" in DAO Help.

CDaoDatabase::DeleteQueryDef
Call this member function to delete the specified querydef — saved query — from the CDaoDatabase object's
QueryDefs collection.

void DeleteQueryDef(LPCTSTR lpszName);

Parameters
lpszName
The name of the saved query to delete.
Remarks
Afterwards, that query is no longer defined in the database.
For information about creating querydef objects, see class CDaoQueryDef. A querydef object becomes
associated with a particular CDaoDatabase object when you construct the CDaoQueryDef object, passing it a
pointer to the database object.

CDaoDatabase::DeleteRelation
Call this member function to delete an existing relation from the database object's Relations collection.

void DeleteRelation(LPCTSTR lpszName);

Parameters
lpszName
The name of the relation to delete.
Remarks
Afterwards, the relation no longer exists.
For related information, see the topic "Delete Method" in DAO Help.

CDaoDatabase::DeleteTableDef
Call this member function to delete the specified table and all of its data from the CDaoDatabase object's
TableDefs collection.

void DeleteTableDef(LPCTSTR lpszName);

Parameters
lpszName
The name of the tabledef to delete.
Remarks
Afterwards, that table is no longer defined in the database.

NOTE
Be very careful not to delete system tables.

For information about creating tabledef objects, see class CDaoTableDef. A tabledef object becomes associated
with a particular CDaoDatabase object when you construct the CDaoTableDef object, passing it a pointer to the
database object.
For related information, see the topic "Delete Method" in DAO Help.

CDaoDatabase::Execute
Call this member function to run an action query or execute a SQL statement on the database.

void Execute(
LPCTSTR lpszSQL,
int nOptions = dbFailOnError);

Parameters
lpszSQL
Pointer to a null-terminated string containing a valid SQL command to execute.
nOptions
An integer that specifies options relating to the integrity of the query. You can use the bitwise-OR operator ( | )
to combine any of the following constants (provided the combination makes sense — for example, you would
not combine dbInconsistent with dbConsistent ):
dbDenyWrite Deny write permission to other users.
dbInconsistent (Default) Inconsistent updates.
dbConsistent Consistent updates.
dbSQLPassThrough SQL pass-through. Causes the SQL statement to be passed to an ODBC data source
for processing.
dbFailOnError Roll back updates if an error occurs.
dbSeeChanges Generate a run-time error if another user is changing data you are editing.

NOTE
If both dbInconsistent and dbConsistent are included or if neither is included, the result is the default. For an
explanation of these constants, see the topic "Execute Method" in DAO Help.

Remarks
Execute works only for action queries or SQL pass-through queries that do not return results. It does not work
for select queries, which return records.
For a definition and information about action queries, see the topics "Action Query" and "Execute Method" in
DAO Help.
TIP
Given a syntactically correct SQL statement and proper permissions, the Execute member function will not fail even if
not a single row can be modified or deleted. Therefore, always use the dbFailOnError option when using the
Execute member function to run an update or delete query. This option causes MFC to throw an exception of type
CDaoException and rolls back all successful changes if any of the records affected are locked and cannot be updated or
deleted. Note that you can always call GetRecordsAffected to see how many records were affected.

Call the GetRecordsAffected member function of the database object to determine the number of records
affected by the most recent Execute call. For example, GetRecordsAffected returns information about the
number of records deleted, updated, or inserted when executing an action query. The count returned will not
reflect changes in related tables when cascade updates or deletes are in effect.
Execute does not return a recordset. Using Execute on a query that selects records causes MFC to throw an
exception of type CDaoException . (There is no ExecuteSQL member function analogous to
CDatabase::ExecuteSQL .)

CDaoDatabase::GetConnect
Call this member function to retrieve the connection string used to connect the CDaoDatabase object to an
ODBC or ISAM database.

CString GetConnect();

Return Value
The connection string if Open has been called successfully on an ODBC data source; otherwise, an empty string.
For a Microsoft Jet (.MDB) database, the string is always empty unless you set it for use with the
dbSQLPassThrough option used with the Execute member function or used in opening a recordset.

Remarks
The string provides information about the source of an open database or a database used in a pass-through
query. The connection string is composed of a database type specifier and zero or more parameters separated
by semicolons.

NOTE
Using the MFC DAO classes to connect to a data source via ODBC is less efficient than connecting via an attached table.

NOTE
The connection string is used to pass additional information to ODBC and certain ISAM drivers as needed. It is not used
for .MDB databases. For Microsoft Jet database base tables, the connection string is an empty string ("") except when
you use it for a SQL pass-through query as described under Return Value above.

See the Open member function for a description of how the connection string is created. Once the connection
string has been set in the Open call, you can later use it to check the setting to determine the type, path, user ID,
Password, or ODBC data source of the database.

CDaoDatabase::GetName
Call this member function to retrieve the name of the currently open database, which is the name of an existing
database file or the name of a registered ODBC data source.

CString GetName();

Return Value
The full path and file name of the database if successful; otherwise, an empty CString.
Remarks
If your network supports the uniform naming convention (UNC), you can also specify a network path—for
example, "\\\\MYSERVER\\MYSHARE\\MYDIR\\MYDB.MDB". (Double backslashes are required in string literals
because "\" is the C++ escape character.)
You might, for example, want to display this name in a heading. If an error occurs while the name is being
retrieved, MFC throws an exception of type CDaoException.

NOTE
For better performance when external databases are being accessed, we recommend that you attach external database
tables to a Microsoft Jet database (.MDB) rather than connecting directly to the data source.

The database type is indicated by the file or directory that the path points to, as follows:

PAT H N A M E P O IN T S TO. . DATA B A SE T Y P E

.MDB file Microsoft Jet database (Microsoft Access)

Directory that contains .DBF file(s) dBASE database

Directory that contains .XLS file Microsoft Excel database

Directory that contains .PDX file(s) Paradox database

Directory that contains appropriately formatted text Text format database


database files

For ODBC databases such as SQL Server and Oracle, the database's connection string identifies a data source
name (DSN) that's registered by ODBC.

CDaoDatabase::GetQueryDefCount
Call this member function to retrieve the number of queries defined in the database's QueryDefs collection.

short GetQueryDefCount();

Return Value
The number of queries defined in the database.
Remarks
GetQueryDefCount is useful if you need to loop through all querydefs in the QueryDefs collection. To obtain
information about a given query in the collection, see GetQueryDefInfo.

CDaoDatabase::GetQueryDefInfo
Call this member function to obtain various kinds of information about a query defined in the database.

void GetQueryDefInfo(
int nIndex,
CDaoQueryDefInfo& querydefinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetQueryDefInfo(
LPCTSTR lpszName,
CDaoQueryDefInfo& querydefinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The index of the predefined query in the database's QueryDefs collection, for lookup by index.
querydefinfo
A reference to a CDaoQueryDefInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the recordset to retrieve. The available options are listed here
along with what they cause the function to return about the recordset:
AFX_DAO_PRIMARY_INFO (Default) Name, Type
AFX_DAO_SECONDARY_INFO Primary information plus: Date Created, Date of Last Update, Returns
Records, Updatable
AFX_DAO_ALL_INFO Primary and secondary information plus: SQL, Connect, ODBCTimeout
lpszName
A string containing the name of a query defined in the database, for lookup by name.
Remarks
Two versions of the function are supplied so you can select a query either by index in the database's QueryDefs
collection or by the name of the query.
For a description of the information returned in querydefinfo, see the CDaoQueryDefInfo structure. This
structure has members that correspond to the items of information listed above in the description of
dwInfoOptions. If you request one level of information, you get any prior levels of information as well.

CDaoDatabase::GetQueryTimeout
Call this member function to retrieve the current number of seconds to allow before subsequent operations on
the connected database are timed out.

short GetQueryTimeout();

Return Value
A short integer containing the timeout value in seconds.
Remarks
An operation might time out due to network access problems, excessive query processing time, and so on.
While the setting is in effect, it affects all open, add new, update, and delete operations on any recordsets
associated with this CDaoDatabase object. You can change the current timeout setting by calling
SetQueryTimeout. Changing the query timeout value for a recordset after opening does not change the value
for the recordset. For example, subsequent Move operations do not use the new value. The default value is
initially set when the database engine is initialized.
The default value for query timeouts is taken from the Windows registry. If there is no registry setting, the
default is 60 seconds. Not all databases support the ability to set a query timeout value. If you set a query
timeout value of 0, no timeout occurs; and communication with the database may stop responding. This
behavior may be useful during development. If the call fails, MFC throws an exception of type CDaoException.
For related information, see the topic "QueryTimeout Property" in DAO Help.

CDaoDatabase::GetRecordsAffected
Call this member function to determine the number of records affected by the most recent call of the Execute
member function.

long GetRecordsAffected();

Return Value
A long integer containing the number of records affected.
Remarks
The value returned includes the number of records deleted, updated, or inserted by an action query run with
Execute . The count returned will not reflect changes in related tables when cascade updates or deletes are in
effect.
For related information, see the topic "RecordsAffected Property" in DAO Help.

CDaoDatabase::GetRelationCount
Call this member function to obtain the number of relations defined between tables in the database.

short GetRelationCount();

Return Value
The number of relations defined between tables in the database.
Remarks
GetRelationCount is useful if you need to loop through all defined relations in the database's Relations
collection. To obtain information about a given relation in the collection, see GetRelationInfo.
To illustrate the concept of a relation, consider a Suppliers table and a Products table, which might have a one-
to-many relationship. In this relationship, one supplier can supply more than one product. Other relations are
one-to-one and many-to-many.

CDaoDatabase::GetRelationInfo
Call this member function to obtain information about a specified relation in the database's Relations collection.
void GetRelationInfo(
int nIndex,
CDaoRelationInfo& relinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetRelationInfo(
LPCTSTR lpszName,
CDaoRelationInfo& relinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The index of the relation object in the database's Relations collection, for lookup by index.
relinfo
A reference to a CDaoRelationInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the relation to retrieve. The available options are listed here along
with what they cause the function to return about the relation:
AFX_DAO_PRIMARY_INFO (Default) Name, Table, Foreign Table
AFX_DAO_SECONDARY_INFO Attributes, Field Information
The Field Information is a CDaoRelationFieldInfo object containing the fields from the primary table involved in
the relation.
lpszName
A string containing the name of the relation object, for lookup by name.
Remarks
Two versions of this function provide access either by index or by name. For a description of the information
returned in relinfo, see the CDaoRelationInfo structure. This structure has members that correspond to the
items of information listed above in the description of dwInfoOptions. If you request information at one level,
you also get information at any prior levels as well.

NOTE
If you set the relation object's attributes to activate cascade operations ( dbRelationUpdateCascades or
dbRelationDeleteCascades ), the Microsoft Jet database engine automatically updates or deletes records in one or
more other tables when changes are made to related primary key tables. For example, suppose you establish a cascade
delete relationship between a Customers table and an Orders table. When you delete records from the Customers table,
records in the Orders table related to that customer are also deleted. In addition, if you establish cascade delete
relationships between the Orders table and other tables, records from those tables are automatically deleted when you
delete records from the Customers table.

CDaoDatabase::GetTableDefCount
Call this member function to retrieve the number of tables defined in the database.

short GetTableDefCount();

Return Value
The number of tabledefs defined in the database.
Remarks
GetTableDefCount is useful if you need to loop through all tabledefs in the database's TableDefs collection. To
obtain information about a given table in the collection, see GetTableDefInfo.

CDaoDatabase::GetTableDefInfo
Call this member function to obtain various kinds of information about a table defined in the database.

void GetTableDefInfo(
int nIndex,
CDaoTableDefInfo& tabledefinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetTableDefInfo(
LPCTSTR lpszName,
CDaoTableDefInfo& tabledefinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The index of the tabledef object in the database's TableDefs collection, for lookup by index.
tabledefinfo
A reference to a CDaoTableDefInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the table to retrieve. The available options are listed here along
with what they cause the function to return about the relation:
AFX_DAO_PRIMARY_INFO (Default) Name, Updatable, Attributes
AFX_DAO_SECONDARY_INFO Primary information plus: Date Created, Date Last Updated, Source Table
Name, Connect
AFX_DAO_ALL_INFO Primary and secondary information plus: Validation Rule, Validation Text, Record
Count
lpszName
The name of the tabledef object, for lookup by name.
Remarks
Two versions of the function are supplied so you can select a table either by index in the database's TableDefs
collection or by the name of the table.
For a description of the information returned in tabledefinfo, see the CDaoTableDefInfo structure. This structure
has members that correspond to the items of information listed above in the description of dwInfoOptions. If
you request information at one level, you get information for any prior levels as well.

NOTE
The AFX_DAO_ALL_INFO option provides information that can be slow to obtain. In this case, counting the records in
the table could be very time consuming if there are many records.

CDaoDatabase::GetVersion
Call this member function to determine the version of the Microsoft Jet database file.
CString GetVersion();

Return Value
A CString that indicates the version of the database file associated with the object.
Remarks
The value returned represents the version number in the form "major.minor"; for example, "3.0". The product
version number (for example, 3.0) consists of the version number (3), a period, and the release number (0). The
versions to date are 1.0, 1.1, 2.0, and 3.0.
For related information, see the topic "Version Property" in DAO Help.

CDaoDatabase::IsOpen
Call this member function to determine whether the CDaoDatabase object is currently open on a database.

BOOL IsOpen() const;

Return Value
Nonzero if the CDaoDatabase object is currently open; otherwise 0.
Remarks

CDaoDatabase::m_pDAODatabase
Contains a pointer to the OLE interface for the DAO database object underlying the CDaoDatabase object.
Remarks
Use this pointer if you need to access the DAO interface directly.
For information about calling DAO directly, see Technical Note 54.

CDaoDatabase::m_pWorkspace
Contains a pointer to the CDaoWorkspace object that contains the database object.
Remarks
Use this pointer if you need to access the workspace directly — for example, to obtain pointers to other
database objects in the workspace's Databases collection.

CDaoDatabase::Open
You must call this member function to initialize a newly constructed CDaoDatabase object that represents an
existing database.

virtual void Open(


LPCTSTR lpszName,
BOOL bExclusive = FALSE,
BOOL bReadOnly = FALSE,
LPCTSTR lpszConnect = _T(""));

Parameters
lpszName
A string expression that is the name of an existing Microsoft Jet (.MDB) database file. If the filename has an
extension, it is required. If your network supports the uniform naming convention (UNC), you can also specify a
network path, such as "\\\\MYSERVER\\MYSHARE\\MYDIR\\MYDB.MDB". (Double backslashes are required in
string literals because "\" is the C++ escape character.)
Some considerations apply when using lpszName. If it:
Refers to a database that is already open for exclusive access by another user, MFC throws an exception
of type CDaoException. Trap that exception to let your user know that the database is unavailable.
Is an empty string ("") and lpszConnect is "ODBC;", a dialog box listing all registered ODBC data source
names is displayed so the user can select a database. You should avoid direct connections to ODBC data
sources; use an attached table instead.
Otherwise does not refer to an existing database or valid ODBC data source name, MFC throws an
exception of type CDaoException .

NOTE
For details about DAO error codes, see the DAOERR.H file. For related information, see the topic "Trappable Data Access
Errors" in DAO Help.

bExclusive
A Boolean value that is TRUE if the database is to be opened for exclusive (nonshared) access and FALSE if the
database is to be opened for shared access. If you omit this argument, the database is opened for shared
access.
bReadOnly
A Boolean value that is TRUE if the database is to be opened for read-only access and FALSE if the database is
to be opened for read/write access. If you omit this argument, the database is opened for read/write access. All
dependent recordsets inherit this attribute.
lpszConnect
A string expression used for opening the database. This string constitutes the ODBC connect arguments. You
must supply the exclusive and read-only arguments to supply a source string. If the database is a Microsoft Jet
database (.MDB), this string is empty (""). The syntax for the default value — _T ("") — provides portability for
Unicode as well as ANSI builds of your application.
Remarks
Open associates the database with the underlying DAO object. You cannot use the database object to construct
recordset, tabledef, or querydef objects until it is initialized. Open appends the database object to the
associated workspace's Databases collection.
Use the parameters as follows:
If you are opening a Microsoft Jet (.MDB) database, use the lpszName parameter and pass an empty
string for the lpszConnect parameter or pass a password string of the form ";PWD=password" if the
database is password-protected (.MDB databases only).
If you are opening an ODBC data source, pass a valid ODBC connection string in lpszConnect and an
empty string in lpszName.
For related information, see the topic "OpenDatabase Method" in DAO Help.
NOTE
For better performance when accessing external databases, including ISAM databases and ODBC data sources, it is
recommended that you attach external database tables to a Microsoft Jet engine database (.MDB) rather than
connecting directly to the data source.

It is possible for a connection attempt to time out if, for example, the DBMS host is unavailable. If the
connection attempt fails, Open throws an exception of type CDaoException.
The remaining remarks apply only to ODBC databases:
If the database is an ODBC database and the parameters in your Open call do not contain enough information
to make the connection, the ODBC driver opens a dialog box to obtain the necessary information from the user.
When you call Open , your connection string, lpszConnect, is stored privately and is available by calling the
GetConnect member function.
If you wish, you can open your own dialog box before you call Open to get information from the user, such as a
password, then add that information to the connection string you pass to Open . Or you might want to save the
connection string you pass (perhaps in the Windows registry) so you can reuse it the next time your application
calls Open on a CDaoDatabase object.
You can also use the connection string for multiple levels of login authorization (each for a different
CDaoDatabase object) or to convey other database-specific information.

CDaoDatabase::SetQueryTimeout
Call this member function to override the default number of seconds to allow before subsequent operations on
the connected database time out.

void SetQueryTimeout(short nSeconds);

Parameters
nSeconds
The number of seconds to allow before a query attempt times out.
Remarks
An operation might time out because of network access problems, excessive query processing time, and so on.
Call SetQueryTimeout before opening your recordset or before calling the recordset's AddNew, Update, or
Delete member functions if you want to change the query timeout value. The setting affects all subsequent
Open, AddNew , Update , and Delete calls to any recordsets associated with this CDaoDatabase object. Changing
the query timeout value for a recordset after opening does not change the value for the recordset. For example,
subsequent Move operations do not use the new value.
The default value for query timeouts is 60 seconds. Not all databases support the ability to set a query timeout
value. If you set a query timeout value of 0, no timeout occurs; the communication with the database may stop
responding. This behavior may be useful during development.
For related information, see the topic "QueryTimeout Property" in DAO Help.

See also
CObject Class
Hierarchy Chart
CDaoWorkspace Class
CDaoRecordset Class
CDaoTableDef Class
CDaoQueryDef Class
CDatabase Class
CDaoException Class
CDaoException Class
4/21/2020 • 6 minutes to read • Edit Online

Represents an exception condition arising from the MFC database classes based on data access objects (DAO).
DAO 3.6 is the final version, and it is considered obsolete.

Syntax
class CDaoException : public CException

Members
Public Constructors
NAME DESC RIP T IO N

CDaoException::CDaoException Constructs a CDaoException object.

Public Methods
NAME DESC RIP T IO N

CDaoException::GetErrorCount Returns the number of errors in the database engine's


Errors collection.

CDaoException::GetErrorInfo Returns error information about a particular error object in


the Errors collection.

Public Data Members


NAME DESC RIP T IO N

CDaoException::m_nAfxDaoError Contains an extended error code for any error in the MFC
DAO classes.

CDaoException::m_pErrorInfo A pointer to a CDaoErrorInfo object that contains


information about one DAO error object.

CDaoException::m_scode The SCODE value associated with the error.

Remarks
The class includes public data members you can use to determine the cause of the exception. CDaoException
objects are constructed and thrown by member functions of the DAO database classes.
NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity (ODBC).
All DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the DAO classes. In
general, the MFC classes based on DAO are more capable than the MFC classes based on ODBC; the DAO-based
classes can access data, including through ODBC drivers, via their own database engine. The DAO-based classes also
support Data Definition Language (DDL) operations, such as adding tables via the classes, without having to call DAO
directly. For information on exceptions thrown by the ODBC classes, see CDBException.

You can access exception objects within the scope of a CATCH expression. You can also throw CDaoException
objects from your own code with the AfxThrowDaoException global function.
In MFC, all DAO errors are expressed as exceptions, of type CDaoException . When you catch an exception of
this type, you can use CDaoException member functions to retrieve information from any DAO error objects
stored in the database engine's Errors collection. As each error occurs, one or more error objects are placed in
the Errors collection. (Normally the collection contains only one error object; if you are using an ODBC data
source, you are more likely to get multiple error objects.) When another DAO operation generates an error,
the Errors collection is cleared, and the new error object is placed in the Errors collection. DAO operations that
do not generate an error have no effect on the Errors collection.
For DAO error codes, see the file DAOERR.H. For related information, see the topic "Trappable Data Access
Errors" in DAO Help.
For more information about exception handling in general, or about CDaoException objects, see the articles
Exception Handling (MFC) and Exceptions: Database Exceptions. The second article contains example code that
illustrates exception handling in DAO.

Inheritance Hierarchy
CObject
CException
CDaoException

Requirements
Header : afxdao.h

CDaoException::CDaoException
Constructs a CDaoException object.

CDaoException();

Remarks
Ordinarily, the framework creates exception objects when its code throws an exception. You seldom need to
construct an exception object explicitly. If you want to throw a CDaoException from your own code, call the
global function AfxThrowDaoException.
However, you might want to explicitly create an exception object if you are making direct calls to DAO via the
DAO interface pointers that MFC classes encapsulate. In that case, you might need to retrieve error
information from DAO. Suppose an error occurs in DAO when you call a DAO method via the DAODatabases
interface to a workspace's Databases collection.
To r e t r i e v e t h e D A O e r r o r i n fo r m a t i o n

1. Construct a CDaoException object.


2. Call the exception object's GetErrorCount member function to determine how many error objects are in
the database engine's Errors collection. (Normally only one, unless you are using an ODBC data source.)
3. Call the exception object's GetErrorInfo member function to retrieve one specific error object at a time,
by index in the collection, via the exception object. Think of the exception object as a proxy for one DAO
error object.
4. Examine the current CDaoErrorInfo structure that GetErrorInfo returns in the m_pErrorInfo data
member. Its members provide information on the DAO error.
5. In the case of an ODBC data source, repeat steps 3 and 4 as needed, for more error objects.
6. If you constructed the exception object on the heap, delete it with the delete operator when you finish.
For more information about handling errors in the MFC DAO classes, see the article Exceptions: Database
Exceptions.

CDaoException::GetErrorCount
Call this member function to retrieve the number of DAO error objects in the database engine's Errors
collection.

short GetErrorCount();

Return Value
The number of DAO error objects in the database engine's Errors collection.
Remarks
This information is useful for looping through the Errors collection to retrieve each of the one or more DAO
error objects in the collection. To retrieve an error object by index or by DAO error number, call the
GetErrorInfo member function.

NOTE
Normally there is only one error object in the Errors collection. If you are working with an ODBC data source, however,
there could be more than one.

CDaoException::GetErrorInfo
Returns error information about a particular error object in the Errors collection.

void GetErrorInfo(int nIndex);

Parameters
nIndex
The index of the error information in the database engine's Errors collection, for lookup by index.
Remarks
Call this member function to obtain the following kinds of information about the exception:
Error code
Source
Description
Help file
Help context
GetErrorInfo stores the information in the exception object's m_pErrorInfo data member. For a brief
description of the information returned, see m_pErrorInfo. If you catch an exception of type CDaoException
thrown by MFC, the m_pErrorInfo member will already be filled in. If you choose to call DAO directly, you
must call the exception object's GetErrorInfo member function yourself to fill m_pErrorInfo . For a more
detailed description, see the CDaoErrorInfo structure.
For information about DAO exceptions, and example code, see the article Exceptions: Database Exceptions.

CDaoException::m_nAfxDaoError
Contains an MFC extended error code.
Remarks
This code is supplied in cases where a specific component of the MFC DAO classes has erred.
Possible values are:
NO_AFX_DAO_ERROR The most recent operation did not result in an MFC extended error. However, the
operation could have produced other errors from DAO or OLE, so you should check m_pErrorInfo and
possibly m_scode.
AFX_DAO_ERROR_ENGINE_INITIALIZATION MFC could not initialize the Microsoft Jet database engine.
OLE might have failed to initialize, or it might have been impossible to create an instance of the DAO
database engine object. These problems usually suggest a bad installation of either DAO or OLE.
AFX_DAO_ERROR_DFX_BIND An address used in a DAO record field exchange (DFX) function call does
not exist or is invalid (the address was not used to bind data). You might have passed a bad address in a
DFX call, or the address might have become invalid between DFX operations.
AFX_DAO_ERROR_OBJECT_NOT_OPEN You attempted to open a recordset based on a querydef or a
tabledef object that was not in an open state.

CDaoException::m_pErrorInfo
Contains a pointer to a CDaoErrorInfo structure that provides information on the DAO error object that you
last retrieved by calling GetErrorInfo.
Remarks
This object contains the following information:

C DA O ERRO RIN F O M EM B ER IN F O RM AT IO N M EA N IN G

m_lErrorCode Error Code The DAO error code

m_strSource Source The name of the object or application


that originally generated the error

m_strDescription Description A descriptive string associated with


the error
C DA O ERRO RIN F O M EM B ER IN F O RM AT IO N M EA N IN G

m_strHelpFile Help File A path to a Windows Help file in


which the user can get information
about the problem

m_lHelpContext Help Context The context ID for a topic in the DAO


Help file

For full details about the information contained in the CDaoErrorInfo object, see the CDaoErrorInfo structure.

CDaoException::m_scode
Contains a value of type SCODE that describes the error.
Remarks
This is an OLE code. You will seldom need to use this value because, in almost all cases, more specific MFC or
DAO error information is available in the other CDaoException data members.
For information about SCODE, see the topic Structure of OLE Error Codes in the Windows SDK. The SCODE
data type maps to the HRESULT data type.

See also
CException Class
Hierarchy Chart
CException Class
CDaoFieldExchange Class
4/21/2020 • 4 minutes to read • Edit Online

Supports the DAO record field exchange (DFX) routines used by the DAO database classes.
DAO is supported through Office 2013. DAO 3.6 is the final version, and it is considered obsolete.

Syntax
class CDaoFieldExchange

Members
Public Methods
NAME DESC RIP T IO N

CDaoFieldExchange::IsValidOperation Returns nonzero if the current operation is appropriate for


the type of field being updated.

CDaoFieldExchange::SetFieldType Specifies the type of recordset data member — column or


parameter — represented by all subsequent calls to DFX
functions until the next call to SetFieldType .

Public Data Members


NAME DESC RIP T IO N

CDaoFieldExchange::m_nOperation The DFX operation being performed by the current call to the
recordset's DoFieldExchange member function.

CDaoFieldExchange::m_prs A pointer to the recordset on which DFX operations are


being performed.

Remarks
CDaoFieldExchange does not have a base class.
Use this class if you are writing data exchange routines for custom data types; otherwise, you will not directly use
this class. DFX exchanges data between the field data members of your CDaoRecordset object and the
corresponding fields of the current record on the data source. DFX manages the exchange in both directions,
from the data source and to the data source. See Technical Note 53 for information about writing custom DFX
routines.
NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity (ODBC). All
DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the DAO classes. In
general, the MFC classes based on DAO are more capable than the MFC classes based on ODBC. The DAO-based classes
can access data, including through ODBC drivers, via their own database engine. They also support Data Definition
Language (DDL) operations, such as adding tables via the classes instead of having to call DAO yourself.

NOTE
DAO record field exchange (DFX) is very similar to record field exchange (RFX) in the ODBC-based MFC database classes (
CDatabase , CRecordset ). If you understand RFX, you will find it easy to use DFX.

A CDaoFieldExchange object provides the context information needed for DAO record field exchange to take
place. CDaoFieldExchange objects support a number of operations, including binding parameters and field data
members and setting various flags on the fields of the current record. DFX operations are performed on
recordset-class data members of types defined by the enum FieldType in CDaoFieldExchange . Possible
FieldType values are:
CDaoFieldExchange::outputColumn for field data members.
CDaoFieldExchange::param for parameter data members.

The IsValidOperation member function is provided for writing your own custom DFX routines. You will use
SetFieldType frequently in your CDaoRecordset::DoFieldExchange functions. For details about the DFX global
functions, see Record Field Exchange Functions. For information about writing custom DFX routines for your own
data types, see Technical Note 53.

Inheritance Hierarchy
CDaoFieldExchange

Requirements
Header : afxdao.h

CDaoFieldExchange::IsValidOperation
If you write your own DFX function, call IsValidOperation at the beginning of your function to determine
whether the current operation can be performed on a particular field data member type (a
CDaoFieldExchange::outputColumn or a CDaoFieldExchange::param ).

BOOL IsValidOperation();

Return Value
Nonzero if the current operation is appropriate for the type of field being updated.
Remarks
Some of the operations performed by the DFX mechanism apply only to one of the possible field types. Follow
the model of the existing DFX functions.
For additional information on writing custom DFX routines, see Technical Note 53.
CDaoFieldExchange::m_nOperation
Identifies the operation to be performed on the CDaoRecordset object associated with the field exchange object.
Remarks
The CDaoFieldExchange object supplies the context for a number of different DFX operations on the recordset.

NOTE
The PSEUDONULL value described under the MarkForAddNew and SetFieldNull operations below is a value used to mark
fields Null. The DAO record field exchange mechanism (DFX) uses this value to determine which fields have been explicitly
marked Null. PSEUDONULL is not required for COleDateTime and COleCurrency fields.

Possible values of m_nOperation are:

O P ERAT IO N DESC RIP T IO N

AddToParameterList Builds the PARAMETERS clause of the SQL statement.

AddToSelectList Builds the SELECT clause of the SQL statement.

BindField Binds a field in the database to a memory location in your


application.

BindParam Sets parameter values for the recordset's query.

Fixup Sets the Null status for a field.

AllocCache Allocates the cache used to check for "dirty" fields in the
recordset.

StoreField Saves the current record to the cache.

LoadField Restores the cached data member variables in the recordset.

FreeCache Frees the cache used to check for "dirty" fields in the
recordset.

SetFieldNull Sets a field's status to Null and value to PSEUDONULL.

MarkForAddNew Marks fields "dirty" if not PSEUDONULL.

MarkForEdit Marks fields "dirty" if they do not match the cache.

SetDirtyField Sets field values marked as "dirty."

DumpField Dumps a field's contents (debug only).

MaxDFXOperation Used for input checking.

CDaoFieldExchange::m_prs
Contains a pointer to the CDaoRecordset object associated with the CDaoFieldExchange object.
Remarks

CDaoFieldExchange::SetFieldType
Call SetFieldType in your CDaoRecordset class's DoFieldExchange override.

void SetFieldType(UINT nFieldType);

Parameters
nFieldType
A value of the enum FieldType , declared in CDaoFieldExchange , which can be either of the following:
CDaoFieldExchange::outputColumn

CDaoFieldExchange::param

Remarks
Normally, ClassWizard writes this call for you. If you write your own function and are using the wizard to write
your DoFieldExchange function, add calls to your own function outside the field map. If you do not use the wizard,
there will not be a field map. The call precedes calls to DFX functions, one for each field data member of your
class, and identifies the field type as CDaoFieldExchange::outputColumn .
If you parameterize your recordset class, you should add DFX calls for all parameter data members (outside the
field map) and precede these calls with a call to SetFieldType . Pass the value CDaoFieldExchange::param . (You can,
instead, use a CDaoQueryDef and set its parameter values.)
In general, each group of DFX function calls associated with field data members or parameter data members
must be preceded by a call to SetFieldType . The nFieldType parameter of each SetFieldType call identifies the
type of the data members represented by the DFX function calls that follow the SetFieldType call.

See also
Hierarchy Chart
CDaoRecordset Class
CDaoQueryDef Class
4/21/2020 • 21 minutes to read • Edit Online

Represents a query definition, or "querydef," usually one saved in a database.

Syntax
class CDaoQueryDef : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDaoQueryDef::CDaoQueryDef Constructs a CDaoQueryDef object. Next call Open or


Create , depending on your needs.

Public Methods
NAME DESC RIP T IO N

CDaoQueryDef::Append Appends the querydef to the database's QueryDefs


collection as a saved query.

CDaoQueryDef::CanUpdate Returns nonzero if the query can update the database.

CDaoQueryDef::Close Closes the querydef object. Destroy the C++ object when
you finish with it.

CDaoQueryDef::Create Creates the underlying DAO querydef object. Use the


querydef as a temporary query, or call Append to save it in
the database.

CDaoQueryDef::Execute Executes the query defined by the querydef object.

CDaoQueryDef::GetConnect Returns the connection string associated with the querydef.


The connection string identifies the data source. (For SQL
pass-through queries only; otherwise an empty string.)

CDaoQueryDef::GetDateCreated Returns the date the saved query was created.

CDaoQueryDef::GetDateLastUpdated Returns the date the saved query was last updated.

CDaoQueryDef::GetFieldCount Returns the number of fields defined by the querydef.

CDaoQueryDef::GetFieldInfo Returns information about a specified field defined in the


query.
NAME DESC RIP T IO N

CDaoQueryDef::GetName Returns the name of the querydef.

CDaoQueryDef::GetODBCTimeout Returns the timeout value used by ODBC (for an ODBC


query) when the querydef is executed. This determines how
long to allow for the query's action to complete.

CDaoQueryDef::GetParameterCount Returns the number of parameters defined for the query.

CDaoQueryDef::GetParameterInfo Returns information about a specified parameter to the


query.

CDaoQueryDef::GetParamValue Returns the value of a specified parameter to the query.

CDaoQueryDef::GetRecordsAffected Returns the number of records affected by an action query.

CDaoQueryDef::GetReturnsRecords Returns nonzero if the query defined by the querydef


returns records.

CDaoQueryDef::GetSQL Returns the SQL string that specifies the query defined by
the querydef.

CDaoQueryDef::GetType Returns the query type: delete, update, append, make-table,


and so on.

CDaoQueryDef::IsOpen Returns nonzero if the querydef is open and can be


executed.

CDaoQueryDef::Open Opens an existing querydef stored in the database's


QueryDefs collection.

CDaoQueryDef::SetConnect Sets the connection string for a SQL pass-through query on


an ODBC data source.

CDaoQueryDef::SetName Sets the name of the saved query, replacing the name in use
when the querydef was created.

CDaoQueryDef::SetODBCTimeout Sets the timeout value used by ODBC (for an ODBC query)
when the querydef is executed.

CDaoQueryDef::SetParamValue Sets the value of a specified parameter to the query.

CDaoQueryDef::SetReturnsRecords Specifies whether the querydef returns records. Setting this


attribute to TRUE is only valid for SQL pass-through queries.

CDaoQueryDef::SetSQL Sets the SQL string that specifies the query defined by the
querydef.

Public Data Members


NAME DESC RIP T IO N

CDaoQueryDef::m_pDAOQueryDef A pointer to the OLE interface for the underlying DAO


querydef object.
NAME DESC RIP T IO N

CDaoQueryDef::m_pDatabase A pointer to the CDaoDatabase object with which the


querydef is associated. The querydef might be saved in the
database or not.

Remarks
A querydef is a data access object that contains the SQL statement that describes a query, and its properties,
such as "Date Created" and "ODBC Timeout." You can also create temporary querydef objects without saving
them, but it is convenient — and much more efficient — to save commonly reused queries in a database. A
CDaoDatabase object maintains a collection, called the QueryDefs collection, that contains its saved querydefs.

NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity (ODBC). All
DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the DAO classes. In
general, the MFC classes based on DAO are more capable than the MFC classes based on ODBC; the DAO-based classes
can access data, including through ODBC drivers, via their own database engine. The DAO-based classes also support
Data Definition Language (DDL) operations, such as adding tables via the classes, without having to call DAO directly.

Usage
Use querydef objects either to work with an existing saved query or to create a new saved query or temporary
query:
1. In all cases, first construct a CDaoQueryDef object, supplying a pointer to the CDaoDatabase object to
which the query belongs.
2. Then do the following, depending on what you want:
To use an existing saved query, call the querydef object's Open member function, supplying the
name of the saved query.
To create a new saved query, call the querydef object's Create member function, supplying the
name of the query. Then call Append to save the query by appending it to the database's
QueryDefs collection. Create puts the querydef into an open state, so after calling Create you do
not call Open .
To create a temporary querydef, call Create . Pass an empty string for the query name. Do not call
Append .

When you finish using a querydef object, call its Close member function; then destroy the querydef object.

TIP
The easiest way to create saved queries is to create them and store them in your database using Microsoft Access. Then
you can open and use them in your MFC code.

Purposes
You can use a querydef object for any of the following purposes:
To create a CDaoRecordset object
To call the object's Execute member function to directly execute an action query or a SQL pass-through
query
You can use a querydef object for any type of query, including select, action, crosstab, delete, update, append,
make-table, data definition, SQL pass-through, union, and bulk queries. The query's type is determined by the
content of the SQL statement that you supply. For information about query types, see the Execute and GetType
member functions. Recordsets are commonly used for row-returning queries, usually those using the SELECT ...
FROM keywords. Execute is most commonly used for bulk operations. For more information, see Execute and
CDaoRecordset.

Querydefs and Recordsets


To use a querydef object to create a CDaoRecordset object, you typically create or open a querydef as described
above. Then construct a recordset object, passing a pointer to your querydef object when you call
CDaoRecordset::Open. The querydef you pass must be in an open state. For more information, see class
CDaoRecordset.
You cannot use a querydef to create a recordset (the most common use for a querydef) unless it is in an open
state. Put the querydef into an open state by calling either Open or Create .

External Databases
Querydef objects are the preferred way to use the native SQL dialect of an external database engine. For
example, you can create a Transact SQL query (as used on Microsoft SQL Server) and store it in a querydef
object. When you need to use a SQL query not based on the Microsoft Jet database engine, you must provide a
connection string that points to the external data source. Queries with valid connection strings bypass the
database engine and pass the query directly to the external database server for processing.

TIP
The preferred way to work with ODBC tables is to attach them to a Microsoft Jet (.MDB) database.

For related information, see the topics "QueryDef Object", "QueryDefs Collection", and "CdbDatabase Object" in
the DAO SDK.

Inheritance Hierarchy
CObject
CDaoQueryDef

Requirements
Header : afxdao.h

CDaoQueryDef::Append
Call this member function after you call Create to create a new querydef object.

virtual void Append();

Remarks
Append saves the querydef in the database by appending the object to the database's QueryDefs collection. You
can use the querydef as a temporary object without appending it, but if you want it to persist, you must call
Append .

If you attempt to append a temporary querydef object, MFC throws an exception of type CDaoException.

CDaoQueryDef::CanUpdate
Call this member function to determine whether you can modify the querydef — such as changing its name or
SQL string.

BOOL CanUpdate();

Return Value
Nonzero if you are permitted to modify the querydef; otherwise 0.
Remarks
You can modify the querydef if:
It is not based on a database that is open read-only.
You have update permissions for the database.
This depends on whether you have implemented security features. MFC does not provide support for
security; you must implement it yourself by calling DAO directly or by using Microsoft Access. See the
topic "Permissions Property" in DAO Help.

CDaoQueryDef::CDaoQueryDef
Constructs a CDaoQueryDef object.

CDaoQueryDef(CDaoDatabase* pDatabase);

Parameters
pDatabase
A pointer to an open CDaoDatabase object.
Remarks
The object can represent an existing querydef stored in the database's QueryDefs collection, a new query to be
stored in the collection, or a temporary query, not to be stored. Your next step depends on the type of querydef:
If the object represents an existing querydef, call the object's Open member function to initialize it.
If the object represents a new querydef to be saved, call the object's Create member function. This adds
the object to the database's QueryDefs collection. Then call CDaoQueryDef member functions to set the
object's attributes. Finally, call Append.
If the object represents a temporary querydef (not to be saved in the database), call Create , passing an
empty string for the query's name. After calling Create , initialize the querydef by directly setting its
attributes. Do not call Append .

To set the attributes of the querydef, you can use the SetName, SetSQL, SetConnect, SetODBCTimeout, and
SetReturnsRecords member functions.
When you finish with the querydef object, call its Close member function. If you have a pointer to the querydef,
use the delete operator to destroy the C++ object.
CDaoQueryDef::Close
Call this member function when you finish using the querydef object.

virtual void Close();

Remarks
Closing the querydef releases the underlying DAO object but does not destroy the saved DAO querydef object
or the C++ CDaoQueryDef object. This is not the same as CDaoDatabase::DeleteQueryDef, which deletes the
querydef from the database's QueryDefs collection in DAO (if not a temporary querydef).

CDaoQueryDef::Create
Call this member function to create a new saved query or a new temporary query.

virtual void Create(


LPCTSTR lpszName = NULL,
LPCTSTR lpszSQL = NULL);

Parameters
lpszName
The unique name of the query saved in the database. For details about the string, see the topic "CreateQueryDef
Method" in DAO Help. If you accept the default value, an empty string, a temporary querydef is created. Such a
query is not saved in the QueryDefs collection.
lpszSQL
The SQL string that defines the query. If you accept the default value of NULL, you must later call SetSQL to set
the string. Until then, the query is undefined. You can, however, use the undefined query to open a recordset; see
Remarks for details. The SQL statement must be defined before you can append the querydef to the QueryDefs
collection.
Remarks
If you pass a name in lpszName, you can then call Append to save the querydef in the database's QueryDefs
collection. Otherwise, the object is a temporary querydef and is not saved. In either case, the querydef is in an
open state, and you can either use it to create a CDaoRecordset object or call the querydef's Execute member
function.
If you do not supply a SQL statement in lpszSQL, you cannot run the query with Execute but you can use it to
create a recordset. In that case, MFC uses the recordset's default SQL statement.

CDaoQueryDef::Execute
Call this member function to run the query defined by the querydef object.

virtual void Execute(int nOptions = dbFailOnError);

Parameters
nOptions
An integer that determines the characteristics of the query. For related information, see the topic "Execute
Method" in DAO Help. You can use the bitwise-OR operator ( | ) to combine the following constants for this
argument:
dbDenyWrite Deny write permission to other users.
dbInconsistent Inconsistent updates.
dbConsistent Consistent updates.
dbSQLPassThrough SQL pass-through. Causes the SQL statement to be passed to an ODBC database for
processing.
dbFailOnError Default value. Roll back updates if an error occurs and report the error to the user.
dbSeeChanges Generate a run-time error if another user is changing data you are editing.

NOTE
For an explanation of the terms "inconsistent" and "consistent," see the topic "Execute Method" in DAO Help.

Remarks
Querydef objects used for execution in this manner can only represent one of the following query types:
Action queries
SQL pass-through queries
Execute does not work for queries that return records, such as select queries. Execute is commonly used for
bulk operation queries, such as UPDATE , INSERT , or SELECT INTO , or for data definition language (DDL)
operations.

TIP
The preferred way to work with ODBC data sources is to attach tables to a Microsoft Jet (.MDB) database. For more
information, see the topic "Accessing External Databases with DAO" in DAO Help.

Call the GetRecordsAffected member function of the querydef object to determine the number of records
affected by the most recent Execute call. For example, GetRecordsAffected returns information about the
number of records deleted, updated, or inserted when executing an action query. The count returned will not
reflect changes in related tables when cascade updates or deletes are in effect.
If you include both dbInconsistent and dbConsistent or if you include neither, the result is the default,
dbInconsistent .

Execute does not return a recordset. Using Execute on a query that selects records causes MFC to throw an
exception of type CDaoException.

CDaoQueryDef::GetConnect
Call this member function to get the connection string associated with the querydef's data source.

CString GetConnect();

Return Value
A CString containing the connection string for the querydef.
Remarks
This function is used only with ODBC data sources and certain ISAM drivers. It is not used with Microsoft Jet
(.MDB) databases; in this case, GetConnect returns an empty string. For more information, see SetConnect.

TIP
The preferred way to work with ODBC tables is to attach them to an .MDB database. For more information, see the topic
"Accessing External Databases with DAO" in DAO Help.

For information about connection strings, see the topic "Connect Property" in DAO Help.

CDaoQueryDef::GetDateCreated
Call this member function to get the date the querydef object was created.

COleDateTime GetDateCreated();

Return Value
A COleDateTime object containing the date and time the querydef was created.
Remarks
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.

CDaoQueryDef::GetDateLastUpdated
Call this member function to get the date the querydef object was last updated — when any of its properties
were changed, such as its name, its SQL string, or its connection string.

COleDateTime GetDateLastUpdated();

Return Value
A COleDateTime object containing the date and time the querydef was last updated.
Remarks
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.

CDaoQueryDef::GetFieldCount
Call this member function to retrieve the number of fields in the query.

short GetFieldCount();

Return Value
The number of fields defined in the query.
Remarks
GetFieldCount is useful for looping through all fields in the querydef. For that purpose, use GetFieldCount in
conjunction with GetFieldInfo.

CDaoQueryDef::GetFieldInfo
Call this member function to obtain various kinds of information about a field defined in the querydef.
void GetFieldInfo(
int nIndex,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetFieldInfo(
LPCTSTR lpszName,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index of the desired field in the querydef's Fields collection, for lookup by index.
fieldinfo
A reference to a CDaoFieldInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the field to retrieve. The available options are listed here along
with what they cause the function to return:
AFX_DAO_PRIMARY_INFO (Default) Name, Type, Size, Attributes
AFX_DAO_SECONDARY_INFO Primary information plus: Ordinal Position, Required, Allow Zero Length,
Source Field, Foreign Name, Source Table, Collating Order
AFX_DAO_ALL_INFO Primary and secondary information plus: Default Value, Validation Text, Validation
Rule
lpszName
A string containing the name of the desired field, for lookup by name. You can use a CString.
Remarks
For a description of the information returned in fieldinfo, see the CDaoFieldInfo structure. This structure has
members that correspond to the descriptive information under dwInfoOptions above. If you request one level of
information, you get any prior levels of information as well.

CDaoQueryDef::GetName
Call this member function to retrieve the name of the query represented by the querydef.

CString GetName();

Return Value
The name of the query.
Remarks
Querydef names are unique user-defined names. For more information about querydef names, see the topic
"Name Property" in DAO Help.

CDaoQueryDef::GetODBCTimeout
Call this member function to retrieve the current time limit before a query to an ODBC data source times out.
short GetODBCTimeout();

Return Value
The number of seconds before a query times out.
Remarks
For information about this time limit, see the topic "ODBCTimeout Property" in DAO Help.

TIP
The preferred way to work with ODBC tables is to attach them to a Microsoft Jet (.MDB) database. For more information,
see the topic "Accessing External Databases with DAO" in DAO Help.

CDaoQueryDef::GetParameterCount
Call this member function to retrieve the number of parameters in the saved query.

short GetParameterCount();

Return Value
The number of parameters defined in the query.
Remarks
GetParameterCount is useful for looping through all parameters in the querydef. For that purpose, use
GetParameterCount in conjunction with GetParameterInfo.
For related information, see the topics "Parameter Object", "Parameters Collection", and "PARAMETERS
Declaration (SQL)" in DAO Help.

CDaoQueryDef::GetParameterInfo
Call this member function to obtain information about a parameter defined in the querydef.

void GetParameterInfo(
int nIndex,
CDaoParameterInfo& paraminfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetParameterInfo(
LPCTSTR lpszName,
CDaoParameterInfo& paraminfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index of the desired parameter in the querydef's Parameters collection, for lookup by index.
paraminfo
A reference to a CDaoParameterInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the parameter to retrieve. The available option is listed here along
with what it causes the function to return:
AFX_DAO_PRIMARY_INFO (Default) Name, Type
lpszName
A string containing the name of the desired parameter, for lookup by name. You can use a CString.
Remarks
For a description of the information returned in paraminfo, see the CDaoParameterInfo structure. This structure
has members that correspond to the descriptive information under dwInfoOptions above.
For related information, see the topic "PARAMETERS Declaration (SQL)" in DAO Help.

CDaoQueryDef::GetParamValue
Call this member function to retrieve the current value of the specified parameter stored in the querydef's
Parameters collection.

virtual COleVariant GetParamValue(LPCTSTR lpszName);


virtual COleVariant GetParamValue(int nIndex);

Parameters
lpszName
The name of the parameter whose value you want, for lookup by name.
nIndex
The zero-based index of the parameter in the querydef's Parameters collection, for lookup by index. You can
obtain this value with calls to GetParameterCount and GetParameterInfo.
Return Value
An object of class COleVariant that contains the parameter's value.
Remarks
You can access the parameter either by name or by its ordinal position in the collection.
For related information, see the topic "PARAMETERS Declaration (SQL)" in DAO Help.

CDaoQueryDef::GetRecordsAffected
Call this member function to determine how many records were affected by the last call of Execute.

long GetRecordsAffected();

Return Value
The number of records affected.
Remarks
The count returned will not reflect changes in related tables when cascade updates or deletes are in effect.
For related information see the topic "RecordsAffected Property" in DAO Help.

CDaoQueryDef::GetReturnsRecords
Call this member function to determine whether the querydef is based on a query that returns records.
BOOL GetReturnsRecords();

Return Value
Nonzero if the querydef is based on a query that returns records; otherwise 0.
Remarks
This member function is only used for SQL pass-through queries. For more information about SQL queries, see
the Execute member function. For more information about working with SQL pass-through queries, see the
SetReturnsRecords member function.
For related information, see the topic "ReturnsRecords Property" in DAO Help.

CDaoQueryDef::GetSQL
Call this member function to retrieve the SQL statement that defines the query on which the querydef is based.

CString GetSQL();

Return Value
The SQL statement that defines the query on which the querydef is based.
Remarks
You will then probably parse the string for keywords, table names, and so on.
For related information, see the topics "SQL Property", "Comparison of Microsoft Jet Database Engine SQL and
ANSI SQL", and "Querying a Database with SQL in Code" in DAO Help.

CDaoQueryDef::GetType
Call this member function to determine the query type of the querydef.

short GetType();

Return Value
The type of the query defined by the querydef. For values, see Remarks.
Remarks
The query type is set by what you specify in the querydef's SQL string when you create the querydef or call an
existing querydef's SetSQL member function. The query type returned by this function can be one of the
following values:
dbQSelect Select
dbQAction Action
dbQCrosstab Crosstab
dbQDelete Delete
dbQUpdate Update
dbQAppend Append
dbQMakeTable Make-table
dbQDDL Data-definition
dbQSQLPassThrough Pass-through
dbQSetOperation Union
dbQSPTBulk Used with dbQSQLPassThrough to specify a query that does not return records.

NOTE
To create a SQL pass-through query, don't set the dbSQLPassThrough constant. This is set automatically by the Microsoft
Jet database engine when you create a querydef object and set the connection string.

For information about SQL strings, see GetSQL. For information about query types, see Execute.

CDaoQueryDef::IsOpen
Call this member function to determine whether the CDaoQueryDef object is currently open.

BOOL IsOpen() const;

Return Value
Nonzero if the CDaoQueryDef object is currently open; otherwise 0.
Remarks
A querydef must be in an open state before you use it to call Execute or to create a CDaoRecordset object. To put
a querydef into an open state call either Create (for a new querydef) or Open (for an existing querydef).

CDaoQueryDef::m_pDatabase
Contains a pointer to the CDaoDatabase object associated with the querydef object.
Remarks
Use this pointer if you need to access the database directly — for example, to obtain pointers to other querydef
or recordset objects in the database's collections.

CDaoQueryDef::m_pDAOQueryDef
Contains a pointer to the OLE interface for the underlying DAO querydef object.
Remarks
This pointer is provided for completeness and consistency with the other classes. However, because MFC rather
fully encapsulates DAO querydefs, you are unlikely to need it. If you do use it, do so cautiously — in particular,
do not change the value of the pointer unless you know what you are doing.

CDaoQueryDef::Open
Call this member function to open a querydef previously saved in the database's QueryDefs collection.

virtual void Open(LPCTSTR lpszName = NULL);

Parameters
lpszName
A string that contains the name of the saved querydef to open. You can use a CString.
Remarks
Once the querydef is open, you can call its Execute member function or use the querydef to create a
CDaoRecordset object.

CDaoQueryDef::SetConnect
Call this member function to set the querydef object's connection string.

void SetConnect(LPCTSTR lpszConnect);

Parameters
lpszConnect
A string that contains a connection string for the associated CDaoDatabase object.
Remarks
The connection string is used to pass additional information to ODBC and certain ISAM drivers as needed. It is
not used for Microsoft Jet (.MDB) databases.

TIP
The preferred way to work with ODBC tables is to attach them to an .MDB database.

Before executing a querydef that represents a SQL pass-through query to an ODBC data source, set the
connection string with SetConnect and call SetReturnsRecords to specify whether the query returns records.
For more information about the connection string's structure and examples of connection string components,
see the topic "Connect Property" in DAO Help.

CDaoQueryDef::SetName
Call this member function if you want to change the name of a querydef that is not temporary.

void SetName(LPCTSTR lpszName);

Parameters
lpszName
A string that contains the new name for a nontemporary query in the associated CDaoDatabase object.
Remarks
Querydef names are unique, user-defined names. You can call SetName before the querydef object is appended
to the QueryDefs collection.

CDaoQueryDef::SetODBCTimeout
Call this member function to set the time limit before a query to an ODBC data source times out.

void SetODBCTimeout(short nODBCTimeout);

Parameters
nODBCTimeout
The number of seconds before a query times out.
Remarks
This member function lets you override the default number of seconds before subsequent operations on the
connected data source "time out." An operation might time out due to network access problems, excessive query
processing time, and so on. Call SetODBCTimeout prior to executing a query with this querydef if you want to
change the query timeout value. (As ODBC reuses connections, the timeout value is the same for all clients on
the same connection.)
The default value for query timeouts is 60 seconds.

CDaoQueryDef::SetParamValue
Call this member function to set the value of a parameter in the querydef at run time.

virtual void SetParamValue(


LPCTSTR lpszName,
const COleVariant& varValue);

virtual void SetParamValue(


int nIndex,
const COleVariant& varValue);

Parameters
lpszName
The name of the parameter whose value you want to set.
varValue
The value to set; see Remarks.
nIndex
The ordinal position of the parameter in the querydef's Parameters collection. You can obtain this value with calls
to GetParameterCount and GetParameterInfo.
Remarks
The parameter must already have been established as part of the querydef's SQL string. You can access the
parameter either by name or by its ordinal position in the collection.
Specify the value to set as a COleVariant object. For information about setting the desired value and type in
your COleVariant object, see class COleVariant.

CDaoQueryDef::SetReturnsRecords
Call this member function as part of the process of setting up a SQL pass-through query to an external database.

void SetReturnsRecords(BOOL bReturnsRecords);

Parameters
bReturnsRecords
Pass TRUE if the query on an external database returns records; otherwise, FALSE.
Remarks
In such a case, you must create the querydef and set its properties using other CDaoQueryDef member functions.
For a description of external databases, see SetConnect.
CDaoQueryDef::SetSQL
Call this member function to set the SQL statement that the querydef executes.

void SetSQL(LPCTSTR lpszSQL);

Parameters
lpszSQL
A string containing a complete SQL statement, suitable for execution. The syntax of this string depends on the
DBMS that your query targets. For a discussion of syntax used in the Microsoft Jet database engine, see the topic
"Building SQL Statements in Code" in DAO Help.
Remarks
A typical use of SetSQL is setting up a querydef object for use in a SQL pass-through query. (For the syntax of
SQL pass-through queries on your target DBMS, see the documentation for your DBMS.)

See also
CObject Class
Hierarchy Chart
CDaoRecordset Class
CDaoDatabase Class
CDaoTableDef Class
CDaoException Class
CDaoRecordset Class
4/21/2020 • 93 minutes to read • Edit Online

Represents a set of records selected from a data source.

Syntax
class CDaoRecordset : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDaoRecordset::CDaoRecordset Constructs a CDaoRecordset object.

Public Methods
NAME DESC RIP T IO N

CDaoRecordset::AddNew Prepares for adding a new record. Call Update to


complete the addition.

CDaoRecordset::CanAppend Returns nonzero if new records can be added to the


recordset via the AddNew member function.

CDaoRecordset::CanBookmark Returns nonzero if the recordset supports bookmarks.

CDaoRecordset::CancelUpdate Cancels any pending updates due to an Edit or AddNew


operation.

CDaoRecordset::CanRestart Returns nonzero if Requery can be called to run the


recordset's query again.

CDaoRecordset::CanScroll Returns nonzero if you can scroll through the records.

CDaoRecordset::CanTransact Returns nonzero if the data source supports transactions.

CDaoRecordset::CanUpdate Returns nonzero if the recordset can be updated (you can


add, update, or delete records).

CDaoRecordset::Close Closes the recordset.

CDaoRecordset::Delete Deletes the current record from the recordset. You must
explicitly scroll to another record after the deletion.
NAME DESC RIP T IO N

CDaoRecordset::DoFieldExchange Called to exchange data (in both directions) between the


field data members of the recordset and the
corresponding record on the data source. Implements
DAO record field exchange (DFX).

CDaoRecordset::Edit Prepares for changes to the current record. Call Update


to complete the edit.

CDaoRecordset::FillCache Fills all or a part of a local cache for a recordset object


that contains data from an ODBC data source.

CDaoRecordset::Find Locates the first, next, previous, or last location of a


particular string in a dynaset-type recordset that satisfies
the specified criteria and makes that record the current
record.

CDaoRecordset::FindFirst Locates the first record in a dynaset-type or snapshot-


type recordset that satisfies the specified criteria and
makes that record the current record.

CDaoRecordset::FindLast Locates the last record in a dynaset-type or snapshot-


type recordset that satisfies the specified criteria and
makes that record the current record.

CDaoRecordset::FindNext Locates the next record in a dynaset-type or snapshot-


type recordset that satisfies the specified criteria and
makes that record the current record.

CDaoRecordset::FindPrev Locates the previous record in a dynaset-type or


snapshot-type recordset that satisfies the specified
criteria and makes that record the current record.

CDaoRecordset::GetAbsolutePosition Returns the record number of a recordset object's current


record.

CDaoRecordset::GetBookmark Returns a value that represents the bookmark on a


record.

CDaoRecordset::GetCacheSize Returns a value that specifies the number of records in a


dynaset-type recordset containing data to be locally
cached from an ODBC data source.

CDaoRecordset::GetCacheStart Returns a value that specifies the bookmark of the first


record in the recordset to be cached.

CDaoRecordset::GetCurrentIndex Returns a CString containing the name of the index


most recently used on an indexed, table-type
CDaoRecordset .

CDaoRecordset::GetDateCreated Returns the date and time the base table underlying a
CDaoRecordset object was created
NAME DESC RIP T IO N

CDaoRecordset::GetDateLastUpdated Returns the date and time of the most recent change
made to the design of a base table underlying a
CDaoRecordset object.

CDaoRecordset::GetDefaultDBName Returns the name of the default data source.

CDaoRecordset::GetDefaultSQL Called to get the default SQL string to execute.

CDaoRecordset::GetEditMode Returns a value that indicates the state of editing for the
current record.

CDaoRecordset::GetFieldCount Returns a value that represents the number of fields in a


recordset.

CDaoRecordset::GetFieldInfo Returns specific kinds of information about the fields in


the recordset.

CDaoRecordset::GetFieldValue Returns the value of a field in a recordset.

CDaoRecordset::GetIndexCount Retrieves the number of indexes in a table underlying a


recordset.

CDaoRecordset::GetIndexInfo Returns various kinds of information about an index.

CDaoRecordset::GetLastModifiedBookmark Used to determine the most recently added or updated


record.

CDaoRecordset::GetLockingMode Returns a value that indicates the type of locking that is


in effect during editing.

CDaoRecordset::GetName Returns a CString containing the name of the


recordset.

CDaoRecordset::GetParamValue Retrieves the current value of the specified parameter


stored in the underlying DAOParameter object.

CDaoRecordset::GetPercentPosition Returns the position of the current record as a


percentage of the total number of records.

CDaoRecordset::GetRecordCount Returns the number of records accessed in a recordset


object.

CDaoRecordset::GetSQL Gets the SQL string used to select records for the
recordset.

CDaoRecordset::GetType Called to determine the type of a recordset: table-type,


dynaset-type, or snapshot-type.

CDaoRecordset::GetValidationRule Returns a CString containing the value that validates


data as it is entered into a field.

CDaoRecordset::GetValidationText Retrieves the text that is displayed when a validation rule


is not satisfied.
NAME DESC RIP T IO N

CDaoRecordset::IsBOF Returns nonzero if the recordset has been positioned


before the first record. There is no current record.

CDaoRecordset::IsDeleted Returns nonzero if the recordset is positioned on a


deleted record.

CDaoRecordset::IsEOF Returns nonzero if the recordset has been positioned


after the last record. There is no current record.

CDaoRecordset::IsFieldDirty Returns nonzero if the specified field in the current record


has been changed.

CDaoRecordset::IsFieldNull Returns nonzero if the specified field in the current record


is Null (having no value).

CDaoRecordset::IsFieldNullable Returns nonzero if the specified field in the current record


can be set to Null (having no value).

CDaoRecordset::IsOpen Returns nonzero if Open has been called previously.

CDaoRecordset::Move Positions the recordset to a specified number of records


from the current record in either direction.

CDaoRecordset::MoveFirst Positions the current record on the first record in the


recordset.

CDaoRecordset::MoveLast Positions the current record on the last record in the


recordset.

CDaoRecordset::MoveNext Positions the current record on the next record in the


recordset .

CDaoRecordset::MovePrev Positions the current record on the previous record in the


recordset.

CDaoRecordset::Open Creates a new recordset from a table, dynaset, or


snapshot.

CDaoRecordset::Requery Runs the recordset's query again to refresh the selected


records.

CDaoRecordset::Seek Locates the record in an indexed table-type recordset


object that satisfies the specified criteria for the current
index and makes that record the current record.

CDaoRecordset::SetAbsolutePosition Sets the record number of a recordset object's current


record.

CDaoRecordset::SetBookmark Positions the recordset on a record containing the


specified bookmark.

CDaoRecordset::SetCacheSize Sets a value that specifies the number of records in a


dynaset-type recordset containing data to be locally
cached from an ODBC data source.
NAME DESC RIP T IO N

CDaoRecordset::SetCacheStart Sets a value that specifies the bookmark of the first


record in the recordset to be cached.

CDaoRecordset::SetCurrentIndex Called to set an index on a table-type recordset.

CDaoRecordset::SetFieldDirty Marks the specified field in the current record as


changed.

CDaoRecordset::SetFieldNull Sets the value of the specified field in the current record
to Null (having no value).

CDaoRecordset::SetFieldValue Sets the value of a field in a recordset.

CDaoRecordset::SetFieldValueNull Sets the value of a field in a recordset to Null. (having no


value).

CDaoRecordset::SetLockingMode Sets a value that indicates the type of locking to put into
effect during editing.

CDaoRecordset::SetParamValue Sets the current value of the specified parameter stored


in the underlying DAOParameter object

CDaoRecordset::SetParamValueNull Sets the current value of the specified parameter to Null


(having no value).

CDaoRecordset::SetPercentPosition Sets the position of the current record to a location


corresponding to a percentage of the total number of
records in a recordset.

CDaoRecordset::Update Completes an AddNew or Edit operation by saving


the new or edited data on the data source.

Public Data Members


NAME DESC RIP T IO N

CDaoRecordset::m_bCheckCacheForDirtyFields Contains a flag indicating whether fields are automatically


marked as changed.

CDaoRecordset::m_nFields Contains the number of field data members in the


recordset class and the number of columns selected by
the recordset from the data source.

CDaoRecordset::m_nParams Contains the number of parameter data members in the


recordset class — the number of parameters passed with
the recordset's query

CDaoRecordset::m_pDAORecordset A pointer to the DAO interface underlying the recordset


object.

CDaoRecordset::m_pDatabase Source database for this result set. Contains a pointer to


a CDaoDatabase object.
NAME DESC RIP T IO N

CDaoRecordset::m_strFilter Contains a string used to construct a SQL WHERE


statement.

CDaoRecordset::m_strSort Contains a string used to construct a SQL ORDER BY


statement.

Remarks
Known as "recordsets," CDaoRecordset objects are available in the following three forms:
Table-type recordsets represent a base table that you can use to examine, add, change, or delete
records from a single database table.
Dynaset-type recordsets are the result of a query that can have updateable records. These
recordsets are a set of records that you can use to examine, add, change, or delete records from an
underlying database table or tables. Dynaset-type recordsets can contain fields from one or more
tables in a database.
Snapshot-type recordsets are a static copy of a set of records that you can use to find data or
generate reports. These recordsets can contain fields from one or more tables in a database but
cannot be updated.
Each form of recordset represents a set of records fixed at the time the recordset is opened. When you
scroll to a record in a table-type recordset or a dynaset-type recordset, it reflects changes made to the
record after the recordset is opened, either by other users or by other recordsets in your application. (A
snapshot-type recordset cannot be updated.) You can use CDaoRecordset directly or derive an application-
specific recordset class from CDaoRecordset . You can then:
Scroll through the records.
Set an index and quickly look for records using Seek (table-type recordsets only).
Find records based on a string comparison: "<", "<=", "=", ">=", or ">" (dynaset-type and snapshot-
type recordsets).
Update the records and specify a locking mode (except snapshot-type recordsets).
Filter the recordset to constrain which records it selects from those available on the data source.
Sort the recordset.
Parameterize the recordset to customize its selection with information not known until run time.
Class CDaoRecordset supplies an interface similar to that of class CRecordset . The main difference is that
class CDaoRecordset accesses data through a Data Access Object (DAO) based on OLE. Class CRecordset
accesses the DBMS through Open Database Connectivity (ODBC) and an ODBC driver for that DBMS.

NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity
(ODBC). All DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the
DAO classes; the DAO classes generally offer superior capabilities because they are specific to the Microsoft Jet
database engine.

You can either use CDaoRecordset directly or derive a class from CDaoRecordset . To use a recordset class in
either case, open a database and construct a recordset object, passing the constructor a pointer to your
CDaoDatabase object. You can also construct a CDaoRecordset object and let MFC create a temporary
CDaoDatabase object for you. Then call the recordset's Open member function, specifying whether the
object is a table-type recordset, a dynaset-type recordset, or a snapshot-type recordset. Calling Open
selects data from the database and retrieves the first record.
Use the object's member functions and data members to scroll through the records and operate on them.
The operations available depend on whether the object is a table-type recordset, a dynaset-type recordset,
or a snapshot-type recordset, and whether it is updateable or read-only — this depends on the capability
of the database or Open Database Connectivity (ODBC) data source. To refresh records that may have
been changed or added since the Open call, call the object's Requery member function. Call the object's
Close member function and destroy the object when you finish with it.

CDaoRecordset uses DAO record field exchange (DFX) to support reading and updating of record fields
through type-safe C++ members of your CDaoRecordset or CDaoRecordset -derived class. You can also
implement dynamic binding of columns in a database without using the DFX mechanism using
GetFieldValue and SetFieldValue.
For related information, see the topic "Recordset Object" in DAO Help.

Inheritance Hierarchy
CObject
CDaoRecordset

Requirements
Header : afxdao.h

CDaoRecordset::AddNew
Call this member function to add a new record to a table-type or dynaset-type recordset.

virtual void AddNew();

Remarks
The record's fields are initially Null. (In database terminology, Null means "having no value" and is not the
same as NULL in C++.) To complete the operation, you must call the Update member function. Update
saves your changes to the data source.
Cau t i on

If you edit a record and then scroll to another record without calling Update , your changes are lost
without warning.
If you add a record to a dynaset-type recordset by calling AddNew, the record is visible in the recordset
and included in the underlying table where it becomes visible to any new CDaoRecordset objects.
The position of the new record depends on the type of recordset:
In a dynaset-type recordset, where the new record is inserted is not guaranteed. This behavior changed
with Microsoft Jet 3.0 for reasons of performance and concurrency. If your goal is to make the newly
added record the current record, get the bookmark of the last modified record and move to that
bookmark:
rs.SetBookmark(rs.GetLastModifiedBookmark());

In a table-type recordset for which an index has been specified, records are returned in their proper
place in the sort order. If no index has been specified, new records are returned at the end of the
recordset.
The record that was current before you used AddNew remains current. If you want to make the new record
current and the recordset supports bookmarks, call SetBookmark to the bookmark identified by the
LastModified property setting of the underlying DAO recordset object. Doing so is useful for determining
the value for counter (auto-increment) fields in an added record. For more information, see
GetLastModifiedBookmark.
If the database supports transactions, you can make your AddNew call part of a transaction. For more
information about transactions, see class CDaoWorkspace. Note that you should call
CDaoWorkspace::BeginTrans before calling AddNew .
It is illegal to call AddNew for a recordset whose Open member function has not been called. A
CDaoException is thrown if you call AddNew for a recordset that cannot be appended. You can determine
whether the recordset is updateable by calling CanAppend.
The framework marks changed field data members to ensure they will be written to the record on the data
source by the DAO record field exchange (DFX) mechanism. Changing the value of a field generally sets
the field dirty automatically, so you will seldom need to call SetFieldDirty yourself, but you might
sometimes want to ensure that columns will be explicitly updated or inserted regardless of what value is
in the field data member. The DFX mechanism also employs the use of PSEUDO NULL . For more
information, see CDaoFieldExchange::m_nOperation.
If the double-buffering mechanism is not being used, then changing the value of the field does not
automatically set the field as dirty. In this case, it will be necessary to explicitly set the field dirty. The flag
contained in m_bCheckCacheForDirtyFields controls this automatic field checking.

NOTE
If records are double-buffered (that is, automatic field checking is enabled), calling CancelUpdate will restore the
member variables to the values they had before AddNew or Edit was called.

For related information, see the topics "AddNew Method", "CancelUpdate Method", "LastModified
Property", and "EditMode Property" in DAO Help.

CDaoRecordset::CanAppend
Call this member function to determine whether the previously opened recordset allows you to add new
records by calling the AddNew member function.

BOOL CanAppend() const;

Return Value
Nonzero if the recordset allows adding new records; otherwise 0. CanAppend will return 0 if you opened
the recordset as read-only.
Remarks
For related information, see the topic "Append Method" in DAO Help.
CDaoRecordset::CanBookmark
Call this member function to determine whether the previously opened recordset allows you to
individually mark records using bookmarks.

BOOL CanBookmark();

Return Value
Nonzero if the recordset supports bookmarks, otherwise 0.
Remarks
If you are using recordsets based entirely on Microsoft Jet database engine tables, bookmarks can be used
except on snapshot-type recordsets flagged as forward-only scrolling recordsets. Other database products
(external ODBC data sources) may not support bookmarks.
For related information, see the topic "Bookmarkable Property" in DAO Help.

CDaoRecordset::CancelUpdate
The CancelUpdate member function cancels any pending updates due to an Edit or AddNew operation.

virtual void CancelUpdate();

Remarks
For example, if an application calls the Edit or AddNew member function and has not called Update,
CancelUpdate cancels any changes made after Edit or AddNew was called.

NOTE
If records are double-buffered (that is, automatic field checking is enabled), calling CancelUpdate will restore the
member variables to the values they had before AddNew or Edit was called.

If there is no Edit or AddNew operation pending, CancelUpdate causes MFC to throw an exception. Call
the GetEditMode member function to determine if there is a pending operation that can be canceled.
For related information, see the topic "CancelUpdate Method" in DAO Help.

CDaoRecordset::CanRestart
Call this member function to determine whether the recordset allows restarting its query (to refresh its
records) by calling the Requery member function.

BOOL CanRestart();

Return Value
Nonzero if Requery can be called to run the recordset's query again, otherwise 0.
Remarks
Table-type recordsets do not support Requery .
If Requery is not supported, call Close then Open to refresh the data. You can call Requery to update a
recordset object's underlying parameter query after the parameter values have been changed.
For related information, see the topic "Restartable Property" in DAO Help.

CDaoRecordset::CanScroll
Call this member function to determine whether the recordset allows scrolling.

BOOL CanScroll() const;

Return Value
Nonzero if you can scroll through the records, otherwise 0.
Remarks
If you call Open with dbForwardOnly , the recordset can only scroll forward.
For related information, see the topic "Positioning the Current Record Pointer with DAO" in DAO Help.

CDaoRecordset::CanTransact
Call this member function to determine whether the recordset allows transactions.

BOOL CanTransact();

Return Value
Nonzero if the underlying data source supports transactions, otherwise 0.
Remarks
For related information, see the topic "Transactions Property" in DAO Help.

CDaoRecordset::CanUpdate
Call this member function to determine whether the recordset can be updated.

BOOL CanUpdate() const;

Return Value
Nonzero if the recordset can be updated (add, update, and delete records), otherwise 0.
Remarks
A recordset might be read-only if the underlying data source is read-only or if you specified dbReadOnly
for nOptions when you called Open for the recordset.
For related information, see the topics "AddNew Method", "Edit Method", "Delete Method", "Update
Method", and "Updatable Property" in DAO Help.

CDaoRecordset::CDaoRecordset
Constructs a CDaoRecordset object.

CDaoRecordset(CDaoDatabase* pDatabase = NULL);

Parameters
pDatabase
Contains a pointer to a CDaoDatabase object or the value NULL. If not NULL and the CDaoDatabase
object's Open member function has not been called to connect it to the data source, the recordset
attempts to open it for you during its own Open call. If you pass NULL, a CDaoDatabase object is
constructed and connected for you using the data source information you specified if you derived your
recordset class from CDaoRecordset .
Remarks
You can either use CDaoRecordset directly or derive an application-specific class from CDaoRecordset . You
can use ClassWizard to derive your recordset classes.

NOTE
If you derive a CDaoRecordset class, your derived class must supply its own constructor. In the constructor of
your derived class, call the constructor CDaoRecordset::CDaoRecordset , passing the appropriate parameters
along to it.

Pass NULL to your recordset constructor to have a CDaoDatabase object constructed and connected for
you automatically. This is a useful shortcut that does not require you to construct and connect a
CDaoDatabase object prior to constructing your recordset. If the CDaoDatabase object is not open, a
CDaoWorkspace object will also be created for you that uses the default workspace. For more information,
see CDaoDatabase::CDaoDatabase.

CDaoRecordset::Close
Closing a CDaoRecordset object removes it from the collection of open recordsets in the associated
database.

virtual void Close();

Remarks
Because Close does not destroy the CDaoRecordset object, you can reuse the object by calling Open on
the same data source or a different data source.
All pending AddNew or Edit statements are canceled, and all pending transactions are rolled back. If you
want to preserve pending additions or edits, call Update before you call Close for each recordset.
You can call Open again after calling Close . This lets you reuse the recordset object. A better alternative is
to call Requery, if possible.
For related information, see the topic "Close Method" in DAO Help.

CDaoRecordset::Delete
Call this member function to delete the current record in an open dynaset-type or table-type recordset
object.

virtual void Delete();

Remarks
After a successful deletion, the recordset's field data members are set to a Null value, and you must
explicitly call one of the recordset navigation member functions ( Move, Seek, SetBookmark, and so on) in
order to move off the deleted record. When you delete records from a recordset, there must be a current
record in the recordset before you call Delete ; otherwise, MFC throws an exception.
Delete removes the current record and makes it inaccessible. Although you cannot edit or use the
deleted record, it remains current. Once you move to another record, however, you cannot make the
deleted record current again.
Cau t i on

The recordset must be updatable and there must be a valid record current in the recordset when you call
Delete . For example, if you delete a record but do not scroll to a new record before you call Delete
again, Delete throws a CDaoException.
You can undelete a record if you use transactions and you call the CDaoWorkspace::Rollback member
function. If the base table is the primary table in a cascade delete relationship, deleting the current record
may also delete one or more records in a foreign table. For more information, see the definition "cascade
delete" in DAO Help.
Unlike AddNew and Edit , a call to Delete is not followed by a call to Update .
For related information, see the topics "AddNew Method", "Edit Method", "Delete Method", "Update
Method", and "Updatable Property" in DAO Help.

CDaoRecordset::DoFieldExchange
The framework calls this member function to automatically exchange data between the field data
members of your recordset object and the corresponding columns of the current record on the data
source.

virtual void DoFieldExchange(CDaoFieldExchange* pFX);

Parameters
pFX
Contains a pointer to a CDaoFieldExchange object. The framework will already have set up this object to
specify a context for the field exchange operation.
Remarks
It also binds your parameter data members, if any, to parameter placeholders in the SQL statement string
for the recordset's selection. The exchange of field data, called DAO record field exchange (DFX), works in
both directions: from the recordset object's field data members to the fields of the record on the data
source, and from the record on the data source to the recordset object. If you are binding columns
dynamically, you are not required to implement DoFieldExchange .
The only action you must normally take to implement DoFieldExchange for your derived recordset class is
to create the class with ClassWizard and specify the names and data types of the field data members. You
might also add code to what ClassWizard writes to specify parameter data members. If all fields are to be
bound dynamically, this function will be inactive unless you specify parameter data members.
When you declare your derived recordset class with ClassWizard, the wizard writes an override of
DoFieldExchange for you, which resembles the following example:
void CCustSet::DoFieldExchange(CDaoFieldExchange *pFX)
{
pFX->SetFieldType(CDaoFieldExchange::param);
DFX_Text(pFX, _T("Param"), m_strParam);
pFX->SetFieldType(CDaoFieldExchange::outputColumn);
DFX_Short(pFX, _T("EmployeeID"), m_EmployeeID);
DFX_Text(pFX, _T("LastName"), m_LastName);
DFX_Short(pFX, _T("Age"), m_Age);
DFX_DateTime(pFX, _T("hire_date"), m_hire_date);
DFX_DateTime(pFX, _T("termination_date"), m_termination_date);

CDaoRecordset::DoFieldExchange(pFX);
}

CDaoRecordset::Edit
Call this member function to allow changes to the current record.

virtual void Edit();

Remarks
Once you call the Edit member function, changes made to the current record's fields are copied to the
copy buffer. After you make the desired changes to the record, call Update to save your changes. Edit
saves the values of the recordset's data members. If you call Edit , make changes, then call Edit again,
the record's values are restored to what they were before the first Edit call.
Cau t i on

If you edit a record and then perform any operation that moves to another record without first calling
Update , your changes are lost without warning. In addition, if you close the recordset or the parent
database, your edited record is discarded without warning.
In some cases, you may want to update a column by making it Null (containing no data). To do so, call
SetFieldNull with a parameter of TRUE to mark the field Null; this also causes the column to be updated.
If you want a field to be written to the data source even though its value has not changed, call
SetFieldDirty with a parameter of TRUE. This works even if the field had the value Null.

The framework marks changed field data members to ensure they will be written to the record on the data
source by the DAO record field exchange (DFX) mechanism. Changing the value of a field generally sets
the field dirty automatically, so you will seldom need to call SetFieldDirty yourself, but you might
sometimes want to ensure that columns will be explicitly updated or inserted regardless of what value is
in the field data member. The DFX mechanism also employs the use of PSEUDO NULL . For more
information, see CDaoFieldExchange::m_nOperation.
If the double-buffering mechanism is not being used, then changing the value of the field does not
automatically set the field as dirty. In this case, it will be necessary to explicitly set the field dirty. The flag
contained in m_bCheckCacheForDirtyFields controls this automatic field checking.
When the recordset object is pessimistically locked in a multiuser environment, the record remains locked
from the time Edit is used until the updating is complete. If the recordset is optimistically locked, the
record is locked and compared with the pre-edited record just before it is updated in the database. If the
record has changed since you called Edit , the Update operation fails and MFC throws an exception. You
can change the locking mode with SetLockingMode .
NOTE
Optimistic locking is always used on external database formats, such as ODBC and installable ISAM.

The current record remains current after you call Edit . To call Edit , there must be a current record. If
there is no current record or if the recordset does not refer to an open table-type or dynaset-type
recordset object, an exception occurs. Calling Edit causes a CDaoException to be thrown under the
following conditions:
There is no current record.
The database or recordset is read-only.
No fields in the record are updatable.
The database or recordset was opened for exclusive use by another user.
Another user has locked the page containing your record.
If the data source supports transactions, you can make the Edit call part of a transaction. Note that you
should call CDaoWorkspace::BeginTrans before calling Edit and after the recordset has been opened. Also
note that calling CDaoWorkspace::CommitTrans is not a substitute for calling Update to complete the Edit
operation. For more information about transactions, see class CDaoWorkspace .
For related information, see the topics "AddNew Method", "Edit Method", "Delete Method", "Update
Method", and "Updatable Property" in DAO Help.

CDaoRecordset::FillCache
Call this member function to cache a specified number of records from the recordset.

void FillCache(
long* pSize = NULL,
COleVariant* pBookmark = NULL);

Parameters
pSize
Specifies the number of rows to fill in the cache. If you omit this parameter, the value is determined by the
CacheSize property setting of the underlying DAO object.
pBookmark
A COleVariant specifying a bookmark. The cache is filled starting from the record indicated by this
bookmark. If you omit this parameter, the cache is filled starting from the record indicated by the
CacheStart property of the underlying DAO object.
Remarks
Caching improves the performance of an application that retrieves, or fetches, data from a remote server.
A cache is space in local memory that holds the data most recently fetched from the server on the
assumption that the data will probably be requested again while the application is running. When data is
requested, the Microsoft Jet database engine checks the cache for the data first rather than fetching it
from the server, which takes more time. Using data caching on non-ODBC data sources has no effect as
the data is not saved in the cache.
Rather than waiting for the cache to be filled with records as they are fetched, you can explicitly fill the
cache at any time by calling the FillCache member function. This is a faster way to fill the cache because
FillCache fetches several records at once instead of one at a time. For example, while each screenful of
records is being displayed, you can have your application call FillCache to fetch the next screenful of
records.
Any ODBC database accessed with recordset objects can have a local cache. To create the cache, open a
recordset object from the remote data source, and then call the SetCacheSize and SetCacheStart
member functions of the recordset. If lSize and lBookmark create a range that is partly or wholly outside
the range specified by SetCacheSize and SetCacheStart , the portion of the recordset outside this range is
ignored and is not loaded into the cache. If FillCache requests more records than remain in the remote
data source, only the remaining records are fetched, and no exception is thrown.
Records fetched from the cache do not reflect changes made concurrently to the source data by other
users.
FillCache fetches only records not already cached. To force an update of all the cached data, call the
SetCacheSize member function with an lSize parameter equal to 0, call SetCacheSize again with the lSize
parameter equal to the size of the cache you originally requested, and then call FillCache .
For related information, see the topic "FillCache Method" in DAO Help.

CDaoRecordset::Find
Call this member function to locate a particular string in a dynaset- or snapshot-type recordset using a
comparison operator.

virtual BOOL Find(


long lFindType,
LPCTSTR lpszFilter);

Parameters
lFindType
A value indicating the type of Find operation desired. The possible values are:
AFX_DAO_NEXT Find the next location of a matching string.
AFX_DAO_PREV Find the previous location of a matching string.
AFX_DAO_FIRST Find the first location of a matching string.
AFX_DAO_LAST Find the last location of a matching string.
lpszFilter
A string expression (like the WHERE clause in a SQL statement without the word WHERE ) used to locate
the record. For example:

rs.Find(AFX_DAO_FIRST, _T("EmployeeID = 7"));


rs.Find(AFX_DAO_NEXT, _T("LastName = 'Jones'"));

Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
You can find the first, next, previous, or last instance of the string. Find is a virtual function, so you can
override it and add your own implementation. The FindFirst , FindLast , FindNext , and FindPrev
member functions call the Find member function, so you can use Find to control the behavior of all
Find operations.
To locate a record in a table-type recordset, call the Seek member function.

TIP
The smaller the set of records you have, the more effective Find will be. In general, and especially with ODBC
data, it is better to create a new query that retrieves just the records you want.

For related information, see the topic "FindFirst, FindLast, FindNext, FindPrevious Methods" in DAO Help.

CDaoRecordset::FindFirst
Call this member function to find the first record that matches a specified condition.

BOOL FindFirst(LPCTSTR lpszFilter);

Parameters
lpszFilter
A string expression (like the WHERE clause in a SQL statement without the word WHERE ) used to locate
the record.
Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
The FindFirst member function begins its search from the beginning of the recordset and searches to
the end of the recordset.
If you want to include all the records in your search (not just those that meet a specific condition) use one
of the Move operations to move from record to record. To locate a record in a table-type recordset, call the
Seek member function.

If a record matching the criteria is not located, the current record pointer is undetermined, and FindFirst
returns zero. If the recordset contains more than one record that satisfies the criteria, FindFirst locates
the first occurrence, FindNext locates the next occurrence, and so on.
Cau t i on

If you edit the current record, be sure to save the changes by calling the Update member function before
you move to another record. If you move to another record without updating, your changes are lost
without warning.
The Find member functions search from the location and in the direction specified in the following table:

F IN D O P ERAT IO N S B EGIN SEA RC H DIREC T IO N

FindFirst Beginning of recordset End of recordset

FindLast End of recordset Beginning of recordset

FindNext Current record End of recordset

FindPrevious Current record Beginning of recordset


NOTE
When you call FindLast , the Microsoft Jet database engine fully populates your recordset before beginning the
search, if this has not already been done. The first search may take longer than subsequent searches.

Using one of the Find operations is not the same as calling MoveFirst or MoveNext , however, which
simply makes the first or next record current without specifying a condition. You can follow a Find
operation with a Move operation.
Keep the following in mind when using the Find operations:
If Find returns nonzero, the current record is not defined. In this case, you must position the
current record pointer back to a valid record.
You cannot use a Find operation with a forward-only scrolling snapshot-type recordset.
You should use the U.S. date format (month-day-year) when you search for fields containing dates,
even if you are not using the U.S. version of the Microsoft Jet database engine; otherwise, matching
records may not be found.
When working with ODBC databases and large dynasets, you may discover that using the Find
operations is slow, especially when working with large recordsets. You can improve performance by
using SQL queries with customized ORDERBY or WHERE clauses, parameter queries, or
CDaoQuerydef objects that retrieve specific indexed records.

For related information, see the topic "FindFirst, FindLast, FindNext, FindPrevious Methods" in DAO Help.

CDaoRecordset::FindLast
Call this member function to find the last record that matches a specified condition.

BOOL FindLast(LPCTSTR lpszFilter);

Parameters
lpszFilter
A string expression (like the WHERE clause in a SQL statement without the word WHERE ) used to locate
the record.
Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
The FindLast member function begins its search at the end of the recordset and searches backward
towards the beginning of the recordset.
If you want to include all the records in your search (not just those that meet a specific condition) use one
of the Move operations to move from record to record. To locate a record in a table-type recordset, call the
Seek member function.

If a record matching the criteria is not located, the current record pointer is undetermined, and FindLast
returns zero. If the recordset contains more than one record that satisfies the criteria, FindFirst locates
the first occurrence, FindNext locates the next occurrence after the first occurrence, and so on.
Cau t i on

If you edit the current record, be sure you save the changes by calling the Update member function
before you move to another record. If you move to another record without updating, your changes are
lost without warning.
Using one of the Find operations is not the same as calling MoveFirst or MoveNext , however, which
simply makes the first or next record current without specifying a condition. You can follow a Find
operation with a Move operation.
Keep the following in mind when using the Find operations:
If Find returns nonzero, the current record is not defined. In this case, you must position the
current record pointer back to a valid record.
You cannot use a Find operation with a forward-only scrolling snapshot-type recordset.
You should use the U.S. date format (month-day-year) when you search for fields containing dates,
even if you are not using the U.S. version of the Microsoft Jet database engine; otherwise, matching
records may not be found.
When working with ODBC databases and large dynasets, you may discover that using the Find
operations is slow, especially when working with large recordsets. You can improve performance by
using SQL queries with customized ORDERBY or WHERE clauses, parameter queries, or
CDaoQuerydef objects that retrieve specific indexed records.

For related information, see the topic "FindFirst, FindLast, FindNext, FindPrevious Methods" in DAO Help.

CDaoRecordset::FindNext
Call this member function to find the next record that matches a specified condition.

BOOL FindNext(LPCTSTR lpszFilter);

Parameters
lpszFilter
A string expression (like the WHERE clause in a SQL statement without the word WHERE ) used to locate
the record.
Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
The FindNext member function begins its search at the current record and searches to the end of the
recordset.
If you want to include all the records in your search (not just those that meet a specific condition) use one
of the Move operations to move from record to record. To locate a record in a table-type recordset, call the
Seek member function.

If a record matching the criteria is not located, the current record pointer is undetermined, and FindNext
returns zero. If the recordset contains more than one record that satisfies the criteria, FindFirst locates
the first occurrence, FindNext locates the next occurrence, and so on.
Cau t i on

If you edit the current record, be sure you save the changes by calling the Update member function
before you move to another record. If you move to another record without updating, your changes are
lost without warning.
Using one of the Find operations is not the same as calling MoveFirst or MoveNext , however, which
simply makes the first or next record current without specifying a condition. You can follow a Find
operation with a Move operation.
Keep the following in mind when using the Find operations:
If Find returns nonzero, the current record is not defined. In this case, you must position the
current record pointer back to a valid record.
You cannot use a Find operation with a forward-only scrolling snapshot-type recordset.
You should use the U.S. date format (month-day-year) when you search for fields containing dates,
even if you are not using the U.S. version of the Microsoft Jet database engine; otherwise, matching
records may not be found.
When working with ODBC databases and large dynasets, you may discover that using the Find
operations is slow, especially when working with large recordsets. You can improve performance by
using SQL queries with customized ORDERBY or WHERE clauses, parameter queries, or
CDaoQuerydef objects that retrieve specific indexed records.

For related information, see the topic "FindFirst, FindLast, FindNext, FindPrevious Methods" in DAO Help.

CDaoRecordset::FindPrev
Call this member function to find the previous record that matches a specified condition.

BOOL FindPrev(LPCTSTR lpszFilter);

Parameters
lpszFilter
A string expression (like the WHERE clause in a SQL statement without the word WHERE ) used to locate
the record.
Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
The FindPrev member function begins its search at the current record and searches backward towards
the beginning of the recordset.
If you want to include all the records in your search (not just those that meet a specific condition) use one
of the Move operations to move from record to record. To locate a record in a table-type recordset, call the
Seek member function.

If a record matching the criteria is not located, the current record pointer is undetermined, and FindPrev
returns zero. If the recordset contains more than one record that satisfies the criteria, FindFirst locates
the first occurrence, FindNext locates the next occurrence, and so on.
Cau t i on

If you edit the current record, be sure you save the changes by calling the Update member function
before you move to another record. If you move to another record without updating, your changes are
lost without warning.
Using one of the Find operations is not the same as calling MoveFirst or MoveNext , however, which
simply makes the first or next record current without specifying a condition. You can follow a Find
operation with a Move operation.
Keep the following in mind when using the Find operations:
If Find returns nonzero, the current record is not defined. In this case, you must position the
current record pointer back to a valid record.
You cannot use a Find operation with a forward-only scrolling snapshot-type recordset.
You should use the U.S. date format (month-day-year) when you search for fields containing dates,
even if you are not using the U.S. version of the Microsoft Jet database engine; otherwise, matching
records may not be found.
When working with ODBC databases and large dynasets, you may discover that using the Find
operations is slow, especially when working with large recordsets. You can improve performance by
using SQL queries with customized ORDERBY or WHERE clauses, parameter queries, or
CDaoQuerydef objects that retrieve specific indexed records.

For related information, see the topic "FindFirst, FindLast, FindNext, FindPrevious Methods" in DAO Help.

CDaoRecordset::GetAbsolutePosition
Returns the record number of a recordset object's current record.

long GetAbsolutePosition();

Return Value
An integer from 0 to the number of records in the recordset. Corresponds to the ordinal position of the
current record in the recordset.
Remarks
The AbsolutePosition property value of the underlying DAO object is zero-based; a setting of 0 refers to
the first record in the recordset. You can determine the number of populated records in the recordset by
calling GetRecordCount. Calling GetRecordCount may take some time because it must access all records to
determine the count.
If there is no current record, as when there are no records in the recordset, - 1 is returned. If the current
record is deleted, the AbsolutePosition property value is not defined, and MFC throws an exception if it is
referenced. For dynaset-type recordsets, new records are added to the end of the sequence.

NOTE
This property is not intended to be used as a surrogate record number. Bookmarks are still the recommended way
of retaining and returning to a given position and are the only way to position the current record across all types
of recordset objects. In particular, the position of a given record changes when record(s) preceding it are deleted.
There is also no assurance that a given record will have the same absolute position if the recordset is re-created
again because the order of individual records within a recordset is not guaranteed unless it is created with a SQL
statement using an ORDERBY clause.

NOTE
This member function is valid only for dynaset-type and snapshot-type recordsets.

For related information, see the topic "AbsolutePosition Property" in DAO Help.

CDaoRecordset::GetBookmark
Call this member function to obtain the bookmark value in a particular record.
COleVariant GetBookmark();

Return Value
Returns a value representing the bookmark on the current record.
Remarks
When a recordset object is created or opened, each of its records already has a unique bookmark if it
supports them. Call CanBookmark to determine whether a recordset supports bookmarks.
You can save the bookmark for the current record by assigning the value of the bookmark to a
COleVariant object. To quickly return to that record at any time after moving to a different record, call
SetBookmark with a parameter corresponding to the value of that COleVariant object.

NOTE
Calling Requery changes DAO bookmarks.

For related information, see the topic "Bookmark Property" in DAO Help.

CDaoRecordset::GetCacheSize
Call this member function to obtain the number of records cached.

long GetCacheSize();

Return Value
A value that specifies the number of records in a dynaset-type recordset containing data to be locally
cached from an ODBC data source.
Remarks
Data caching improves the performance of an application that retrieves data from a remote server
through dynaset-type recordset objects. A cache is a space in local memory that holds the data most
recently retrieved from the server in the event that the data will be requested again while the application
is running. When data is requested, the Microsoft Jet database engine checks the cache for the requested
data first rather than retrieving it from the server, which takes more time. Data that does not come from
an ODBC data source is not saved in the cache.
Any ODBC data source, such as an attached table, can have a local cache.
For related information, see the topic "CacheSize, CacheStart Properties" in DAO Help.

CDaoRecordset::GetCacheStart
Call this member function to obtain the bookmark value of the first record in the recordset to be cached.

COleVariant GetCacheStart();

Return Value
A COleVariant that specifies the bookmark of the first record in the recordset to be cached.
Remarks
The Microsoft Jet database engine requests records within the cache range from the cache, and it requests
records outside the cache range from the server.

NOTE
Records retrieved from the cache do not reflect changes made concurrently to the source data by other users.

For related information, see the topic "CacheSize, CacheStart Properties" in DAO Help.

CDaoRecordset::GetCurrentIndex
Call this member function to determine the index currently in use in an indexed table-type CDaoRecordset
object.

CString GetCurrentIndex();

Return Value
A CString containing the name of the index currently in use with a table-type recordset. Returns an
empty string if no index has been set.
Remarks
This index is the basis for ordering records in a table-type recordset, and is used by the Seek member
function to locate records.
A CDaoRecordset object can have more than one index but can use only one index at a time (although a
CDaoTableDef object may have several indexes defined on it).
For related information, see the topic "Index Object" and the definition "current index" in DAO Help.

CDaoRecordset::GetDateCreated
Call this member function to retrieve the date and time a base table was created.

COleDateTime GetDateCreated();

Return Value
A COleDateTime object containing the date and time the base table was created.
Remarks
Date and time settings are derived from the computer on which the base table was created.
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.

CDaoRecordset::GetDateLastUpdated
Call this member function to retrieve the date and time the schema was last updated.

COleDateTime GetDateLastUpdated();

Return Value
A COleDateTime object containing the date and time the base table structure (schema) was last updated.
Remarks
Date and time settings are derived from the computer on which the base table structure (schema) was last
updated.
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.

CDaoRecordset::GetDefaultDBName
Call this member function to determine the name of the database for this recordset.

virtual CString GetDefaultDBName();

Return Value
A CString that contains the path and name of the database from which this recordset is derived.
Remarks
If a recordset is created without a pointer to a CDaoDatabase, then this path is used by the recordset to
open the default database. By default, this function returns an empty string. When ClassWizard derives a
new recordset from CDaoRecordset , it will create this function for you.
The following example illustrates the use of the double backslash (\\) in the string, as is required for the
string to be interpreted correctly.

CString CCustSet::GetDefaultDBName()
{
return _T("c:\\mydir\\datasrc.mdb");
}

CDaoRecordset::GetDefaultSQL
The framework calls this member function to get the default SQL statement on which the recordset is
based.

virtual CString GetDefaultSQL();

Return Value
A CString that contains the default SQL statement.
Remarks
This might be a table name or a SQL SELECT statement.
You indirectly define the default SQL statement by declaring your recordset class with ClassWizard, and
ClassWizard performs this task for you.
If you pass a null SQL string to Open, then this function is called to determine the table name or SQL for
your recordset.

CDaoRecordset::GetEditMode
Call this member function to determine the state of editing, which is one of the following values:

short GetEditMode();
Return Value
Returns a value that indicates the state of editing for the current record.
Remarks
VA L UE DESC RIP T IO N

dbEditNone No editing operation is in progress.

dbEditInProgress Edit has been called.

dbEditAdd AddNew has been called.

For related information, see the topic "EditMode Property" in DAO Help.

CDaoRecordset::GetFieldCount
Call this member function to retrieve the number of fields (columns) defined in the recordset.

short GetFieldCount();

Return Value
The number of fields in the recordset.
Remarks
For related information, see the topic "Count Property" in DAO Help.

CDaoRecordset::GetFieldInfo
Call this member function to obtain information about the fields in a recordset.

void GetFieldInfo(
int nIndex,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetFieldInfo(
LPCTSTR lpszName,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index of the predefined field in the recordset's Fields collection, for lookup by index.
fieldinfo
A reference to a CDaoFieldInfo structure.
dwInfoOptions
Options that specify which information about the recordset to retrieve. The available options are listed
here along with what they cause the function to return. For best performance, retrieve only the level of
information you need:
AFX_DAO_PRIMARY_INFO (Default) Name, Type, Size, Attributes
AFX_DAO_SECONDARY_INFO Primary information, plus: Ordinal Position, Required, Allow Zero Length,
Collating Order, Foreign Name, Source Field, Source Table
AFX_DAO_ALL_INFO Primary and secondary information, plus: Default Value, Validation Rule,
Validation Text
lpszName
The name of the field.
Remarks
One version of the function lets you look up a field by index. The other version lets you look up a field by
name.
For a description of the information returned, see the CDaoFieldInfo structure. This structure has members
that correspond to the items of information listed above in the description of dwInfoOptions. When you
request information at one level, you get information for any prior levels as well.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoRecordset::GetFieldValue
Call this member function to retrieve data in a recordset.

virtual void GetFieldValue(


LPCTSTR lpszName,
COleVariant& varValue);

virtual void GetFieldValue(


int nIndex,
COleVariant& varValue);

virtual COleVariant GetFieldValue(LPCTSTR lpszName);


virtual COleVariant GetFieldValue(int nIndex);

Parameters
lpszName
A pointer to a string that contains the name of a field.
varValue
A reference to a COleVariant object that will store the value of a field.
nIndex
A zero-based index of the field in the recordset's Fields collection, for lookup by index.
Return Value
The two versions of GetFieldValue that return a value return a COleVariant object that contains the value
of a field.
Remarks
You can look up a field by name or by ordinal position.

NOTE
It is more efficient to call one of the versions of this member function that takes a COleVariant object reference
as a parameter, rather than calling a version that returns a COleVariant object. The latter versions of this
function are kept for backward compatibility.
Use GetFieldValue and SetFieldValue to dynamically bind fields at run time rather than statically binding
columns using the DoFieldExchange mechanism.
GetFieldValue and the mechanism can be combined to improve performance. For
DoFieldExchange
example, use GetFieldValue to retrieve a value that you need only on demand, and assign that call to a
"More Information" button in the interface.
For related information, see the topics "Field Object" and "Value Property" in DAO Help.

CDaoRecordset::GetIndexCount
Call this member function to determine the number of indexes available on the table-type recordset.

short GetIndexCount();

Return Value
The number of indexes in the table-type recordset.
Remarks
GetIndexCount is useful for looping through all indexes in the recordset. For that purpose, use
GetIndexCount in conjunction with GetIndexInfo. If you call this member function on dynaset-type or
snapshot-type recordsets, MFC throws an exception.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoRecordset::GetIndexInfo
Call this member function to obtain various kinds of information about an index defined in the base table
underlying a recordset.

void GetIndexInfo(
int nIndex,
CDaoIndexInfo& indexinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetIndexInfo(
LPCTSTR lpszName,
CDaoIndexInfo& indexinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index in the table's Indexes collection, for lookup by numerical position.
indexinfo
A reference to a CDaoIndexInfo structure.
dwInfoOptions
Options that specify which information about the index to retrieve. The available options are listed here
along with what they cause the function to return. For best performance, retrieve only the level of
information you need:
AFX_DAO_PRIMARY_INFO (Default) Name, Field Info, Fields
AFX_DAO_SECONDARY_INFO Primary information, plus: Primary, Unique, Clustered, IgnoreNulls,
Required, Foreign
AFX_DAO_ALL_INFO Primary and secondary information, plus: Distinct Count
lpszName
A pointer to the name of the index object, for lookup by name.
Remarks
One version of the function lets you look up a index by its position in the collection. The other version lets
you look up an index by name.
For a description of the information returned, see the CDaoIndexInfo structure. This structure has
members that correspond to the items of information listed above in the description of dwInfoOptions.
When you request information at one level, you get information for any prior levels as well.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoRecordset::GetLastModifiedBookmark
Call this member function to retrieve the bookmark of the most recently added or updated record.

COleVariant GetLastModifiedBookmark();

Return Value
A COleVariant containing a bookmark that indicates the most recently added or changed record.
Remarks
When a recordset object is created or opened, each of its records already has a unique bookmark if it
supports them. Call GetBookmark to determine if the recordset supports bookmarks. If the recordset does
not support bookmarks, a CDaoException is thrown.
When you add a record, it appears at the end of the recordset, and is not the current record. To make the
new record current, call GetLastModifiedBookmark and then call SetBookmark to return to the newly added
record.
For related information, see the topic "LastModified Property" in DAO Help.

CDaoRecordset::GetLockingMode
Call this member function to determine the type of locking in effect for the recordset.

BOOL GetLockingMode();

Return Value
Nonzero if the type of locking is pessimistic, otherwise 0 for optimistic record locking.
Remarks
When pessimistic locking is in effect, the data page containing the record you are editing is locked as soon
as you call the Edit member function. The page is unlocked when you call the Update or Close member
function or any of the Move or Find operations.
When optimistic locking is in effect, the data page containing the record is locked only while the record is
being updated with the Update member function.
When working with ODBC data sources, the locking mode is always optimistic.
For related information, see the topics "LockEdits Property" and "Locking Behavior in Multiuser
Applications" in DAO Help.

CDaoRecordset::GetName
Call this member function to retrieve the name of the recordset.

CString GetName();

Return Value
A CString containing the name of the recordset.
Remarks
The name of the recordset must start with a letter and can contain a maximum of 40 characters. It can
include numbers and underscore characters but can't include punctuation or spaces.
For related information, see the topic "Name Property" in DAO Help.

CDaoRecordset::GetParamValue
Call this member function to retrieve the current value of the specified parameter stored in the underlying
DAOParameter object.

virtual COleVariant GetParamValue(int nIndex);


virtual COleVariant GetParamValue(LPCTSTR lpszName);

Parameters
nIndex
The numerical position of the parameter in the underlying DAOParameter object.
lpszName
The name of the parameter whose value you want.
Return Value
An object of class COleVariant that contains the parameter's value.
Remarks
You can access the parameter either by name or by its numerical position in the collection.
For related information, see the topic "Parameter Object" in DAO Help.

CDaoRecordset::GetPercentPosition
When working with a dynaset-type or snapshot-type recordset, if you call GetPercentPosition before fully
populating the recordset, the amount of movement is relative to the number of records accessed as
indicated by calling GetRecordCount.

float GetPercentPosition();

Return Value
A number between 0 and 100 that indicates the approximate location of the current record in the
recordset object based on a percentage of the records in the recordset.
Remarks
You can move to the last record by calling MoveLast to complete the population of all recordsets, but this
may take a significant amount of time.
You can call GetPercentPosition on all three types of recordset objects, including tables without indexes.
However, you cannot call GetPercentPosition on forward-only scrolling snapshots, or on a recordset
opened from a pass-through query against an external database. If there is no current record, or he
current record has been deleted, a CDaoException is thrown.
For related information, see the topic "PercentPosition Property" in DAO Help.

CDaoRecordset::GetRecordCount
Call this member function to find out how many records in a recordset have been accessed.

long GetRecordCount();

Return Value
Returns the number of records accessed in a recordset object.
Remarks
GetRecordCount does not indicate how many records are contained in a dynaset-type or snapshot-type
recordset until all records have been accessed. This member function call may take a significant amount of
time to complete.
Once the last record has been accessed, the return value indicates the total number of undeleted records
in the recordset. To force the last record to be accessed, call the MoveLast or FindLast member function
for the recordset. You can also use a SQL Count to determine the approximate number of records your
query will return.
As your application deletes records in a dynaset-type recordset, the return value of GetRecordCount
decreases. However, records deleted by other users are not reflected by GetRecordCount until the current
record is positioned to a deleted record. If you execute a transaction that affects the record count and
subsequently roll back the transaction, GetRecordCount will not reflect the actual number of remaining
records.
The value of GetRecordCount from a snapshot-type recordset is not affected by changes in the underlying
tables.
The value of GetRecordCount from a table-type recordset reflects the approximate number of records in
the table and is affected immediately as table records are added and deleted.
A recordset with no records returns a value of 0. When working with attached tables or ODBC databases,
GetRecordCount always returns - 1. Calling the Requery member function on a recordset resets the value
of GetRecordCount just as if the query were re-executed.
For related information, see the topic "RecordCount Property" in DAO Help.

CDaoRecordset::GetSQL
Call this member function to get the SQL statement that was used to select the recordset's records when it
was opened.

CString GetSQL() const;


Return Value
A CString that contains the SQL statement.
Remarks
This will generally be a SQL SELECT statement.
The string returned by GetSQL is typically different from any string you may have passed to the recordset
in the lpszSQL parameter to the Open member function. This is because the recordset constructs a full
SQL statement based on what you passed to Open , what you specified with ClassWizard, and what you
may have specified in the m_strFilter and m_strSort data members.

NOTE
Call this member function only after calling Open .

For related information, see the topic "SQL Property" in DAO Help.

CDaoRecordset::GetType
Call this member function after opening the recordset to determine the type of the recordset object.

short GetType();

Return Value
One of the following values that indicates the type of a recordset:
dbOpenTable Table-type recordset
dbOpenDynaset Dynaset-type recordset
dbOpenSnapshot Snapshot-type recordset
Remarks
For related information, see the topic "Type Property" in DAO Help.

CDaoRecordset::GetValidationRule
Call this member function to determine the rule used to validate data.

CString GetValidationRule();

Return Value
A CString object containing a value that validates the data in a record as it is changed or added to a table.
Remarks
This rule is text-based, and is applied each time the underlying table is changed. If the data is not legal,
MFC throws an exception. The returned error message is the text of the ValidationText property of the
underlying field object, if specified, or the text of the expression specified by the ValidationRule property
of the underlying field object. You can call GetValidationText to obtain the text of the error message.
For example, a field in a record that requires the day of the month might have a validation rule such as
"DAY BETWEEN 1 AND 31."
For related information, see the topic "ValidationRule Property" in DAO Help.
CDaoRecordset::GetValidationText
Call this member function to retrieve the text of the ValidationText property of the underlying field object.

CString GetValidationText();

Return Value
A CString object containing the text of the message that is displayed if the value of a field does not
satisfy the validation rule of the underlying field object.
Remarks
For related information, see the topic "ValidationText Property" in DAO Help.

CDaoRecordset::IsBOF
Call this member function before you scroll from record to record to learn whether you have gone before
the first record of the recordset.

BOOL IsBOF() const;

Return Value
Nonzero if the recordset contains no records or if you have scrolled backward before the first record;
otherwise 0.
Remarks
You can also call IsBOF along with IsEOF to determine whether the recordset contains any records or is
empty. Immediately after you call Open , if the recordset contains no records, IsBOF returns nonzero.
When you open a recordset that has at least one record, the first record is the current record and IsBOF
returns 0.
If the first record is the current record and you call MovePrev , IsBOF will subsequently return nonzero. If
IsBOF returns nonzero and you call MovePrev , an exception is thrown. If IsBOF returns nonzero, the
current record is undefined, and any action that requires a current record will result in an exception.
Effect of specific methods on IsBOF and IsEOF settings:
Calling Open* internally makes the first record in the recordset the current record by calling
MoveFirst . Therefore, calling Open on an empty set of records causes IsBOF and IsEOF to return
nonzero. (See the following table for the behavior of a failed MoveFirst or MoveLast call.)
All Move operations that successfully locate a record cause both IsBOF and IsEOF to return 0.
An AddNew call followed by an Update call that successfully inserts a new record will cause IsBOF
to return 0, but only if IsEOF is already nonzero. The state of IsEOF will always remain
unchanged. As defined by the Microsoft Jet database engine, the current record pointer of an
empty recordset is at the end of a file, so any new record is inserted after the current record.
Any Delete call, even if it removes the only remaining record from a recordset, will not change the
value of IsBOF or IsEOF .

This table shows which Move operations are allowed with different combinations of IsBOF / IsEOF .
M O VEP REV, M O VEN EXT,
M O VEF IRST,
M O VEL A ST M O VE < 0 M O VE 0 M O VE > 0

IsBOF =nonzero, Allowed Exception Exception Allowed

IsEOF =0

IsBOF =0, Allowed Allowed Exception Exception

IsEOF =nonzero

Both nonzero Exception Exception Exception Exception

Both 0 Allowed Allowed Allowed Allowed

Allowing a Move operation does not mean that the operation will successfully locate a record. It merely
indicates that an attempt to perform the specified Move operation is allowed and will not generate an
exception. The value of the IsBOF and IsEOF member functions may change as a result of the attempted
move.
The effect of Move operations that do not locate a record on the value of IsBOF and IsEOF settings is
shown in the following table.

ISB O F ISEO F

MoveFirst , MoveLast Nonzero Nonzero

Move 0 No change No change

MovePrev , Move <0 Nonzero No change

MoveNext , Move >0 No change Nonzero

For related information, see the topic "BOF, EOF Properties" in DAO Help.

CDaoRecordset::IsDeleted
Call this member function to determine whether the current record has been deleted.

BOOL IsDeleted() const;

Return Value
Nonzero if the recordset is positioned on a deleted record; otherwise 0.
Remarks
If you scroll to a record and IsDeleted returns TRUE (nonzero), then you must scroll to another record
before you can perform any other recordset operations.
NOTE
You don't need to check the deleted status for records in a snapshot or table-type recordset. Because records
cannot be deleted from a snapshot, there is no need to call IsDeleted . For table-type recordsets, deleted records
are actually removed from the recordset. Once a record has been deleted, either by you, another user, or in
another recordset, you cannot scroll back to that record. Therefore, there is no need to call IsDeleted .

When you delete a record from a dynaset, it is removed from the recordset and you cannot scroll back to
that record. However, if a record in a dynaset is deleted either by another user or in another recordset
based on the same table, IsDeleted will return TRUE when you later scroll to that record.
For related information, see the topics "Delete Method", "LastModified Property", and "EditMode
Property" in DAO Help.

CDaoRecordset::IsEOF
Call this member function as you scroll from record to record to learn whether you have gone beyond the
last record of the recordset.

BOOL IsEOF() const;

Return Value
Nonzero if the recordset contains no records or if you have scrolled beyond the last record; otherwise 0.
Remarks
You can also call IsEOF to determine whether the recordset contains any records or is empty. Immediately
after you call Open , if the recordset contains no records, IsEOF returns nonzero. When you open a
recordset that has at least one record, the first record is the current record and IsEOF returns 0.
If the last record is the current record when you call MoveNext , IsEOF will subsequently return nonzero. If
IsEOF returns nonzero and you call MoveNext , an exception is thrown. If IsEOF returns nonzero, the
current record is undefined, and any action that requires a current record will result in an exception.
Effect of specific methods on IsBOF and IsEOF settings:
Calling Open internally makes the first record in the recordset the current record by calling
MoveFirst . Therefore, calling Open on an empty set of records causes IsBOF and IsEOF to return
nonzero. (See the following table for the behavior of a failed MoveFirst call.)
All Move operations that successfully locate a record cause both IsBOF and IsEOF to return 0.
An AddNew call followed by an Update call that successfully inserts a new record will cause IsBOF
to return 0, but only if IsEOF is already nonzero. The state of IsEOF will always remain
unchanged. As defined by the Microsoft Jet database engine, the current record pointer of an
empty recordset is at the end of a file, so any new record is inserted after the current record.
Any Delete call, even if it removes the only remaining record from a recordset, will not change the
value of IsBOF or IsEOF .

This table shows which Move operations are allowed with different combinations of IsBOF / IsEOF .
M O VEP REV, M O VEN EXT,
M O VEF IRST,
M O VEL A ST M O VE < 0 M O VE 0 M O VE > 0

IsBOF =nonzero, Allowed Exception Exception Allowed

IsEOF =0

IsBOF =0, Allowed Allowed Exception Exception

IsEOF =nonzero

Both nonzero Exception Exception Exception Exception

Both 0 Allowed Allowed Allowed Allowed

Allowing a Move operation does not mean that the operation will successfully locate a record. It merely
indicates that an attempt to perform the specified Move operation is allowed and will not generate an
exception. The value of the IsBOF and IsEOF member functions may change as a result of the attempted
Move.
The effect of Move operations that do not locate a record on the value of IsBOF and IsEOF settings is
shown in the following table.

ISB O F ISEO F

MoveFirst , MoveLast Nonzero Nonzero

Move 0 No change No change

MovePrev , Move <0 Nonzero No change

MoveNext , Move >0 No change Nonzero

For related information, see the topic "BOF, EOF Properties" in DAO Help.

CDaoRecordset::IsFieldDirty
Call this member function to determine whether the specified field data member of a dynaset has been
flagged as "dirty" (changed).

BOOL IsFieldDirty(void* pv);

Parameters
pv
A pointer to the field data member whose status you want to check, or NULL to determine if any of the
fields are dirty.
Return Value
Nonzero if the specified field data member is flagged as dirty; otherwise 0.
Remarks
The data in all dirty field data members will be transferred to the record on the data source when the
current record is updated by a call to the Update member function of CDaoRecordset (following a call to
Edit or AddNew ). With this knowledge, you can take further steps, such as unflagging the field data
member to mark the column so it will not be written to the data source.
IsFieldDirty is implemented through DoFieldExchange .

CDaoRecordset::IsFieldNull
Call this member function to determine whether the specified field data member of a recordset has been
flagged as Null.

BOOL IsFieldNull(void* pv);

Parameters
pv
A pointer to the field data member whose status you want to check, or NULL to determine if any of the
fields are Null.
Return Value
Nonzero if the specified field data member is flagged as Null; otherwise 0.
Remarks
(In database terminology, Null means "having no value" and is not the same as NULL in C++.) If a field
data member is flagged as Null, it is interpreted as a column of the current record for which there is no
value.

NOTE
In certain situations, using IsFieldNull can be inefficient, as the following code example illustrates:

COleVariant varValue;
void *pField = &(rs.m_Age);
int nField = 2;

// this code is inefficient because data


// must be retrieved for both IsFieldNull
// and GetFieldValue
if (!rs.IsFieldNull(pField))
rs.GetFieldValue(nField, varValue);

// this code is more efficient


rs.GetFieldValue(nField, varValue);
if (varValue.vt == VT_NULL)
varValue.Attach(varNewVal); // do something

NOTE
If you are using dynamic record binding, without deriving from CDaoRecordset , be sure to use VT_NULL as
shown in the example.

CDaoRecordset::IsFieldNullable
Call this member function to determine whether the specified field data member is "nullable" (can be set
to a Null value; C++ NULL is not the same as Null, which, in database terminology, means "having no
value").

BOOL IsFieldNullable(void* pv);

Parameters
pv
A pointer to the field data member whose status you want to check, or NULL to determine if any of the
fields are Null.
Return Value
Nonzero if the specified field data member can be made Null; otherwise 0.
Remarks
A field that cannot be Null must have a value. If you attempt to set such a field to Null when adding or
updating a record, the data source rejects the addition or update, and Update will throw an exception. The
exception occurs when you call Update , not when you call SetFieldNull .

CDaoRecordset::IsOpen
Call this member function to determine if the recordset is open.

BOOL IsOpen() const;

Return Value
Nonzero if the recordset object's Open or Requery member function has previously been called and the
recordset has not been closed; otherwise 0.
Remarks

CDaoRecordset::m_bCheckCacheForDirtyFields
Contains a flag indicating whether cached fields are automatically marked as dirty (changed) and Null.
Remarks
The flag defaults to TRUE. The setting in this data member controls the entire double-buffering
mechanism. If you set the flag to TRUE, you can turn off the caching on a field-by-field basis using the DFX
mechanism. If you set the flag to FALSE, you must call SetFieldDirty and SetFieldNull yourself.
Set this data member before calling Open . This mechanism is primarily for ease-of-use. Performance may
be slower because of the double-buffering of fields as changes are made.

CDaoRecordset::m_nFields
Contains the number of field data members in the recordset class and the number of columns selected by
the recordset from the data source.
Remarks
The constructor for the recordset class must initialize m_nFields with the correct number of statically
bound fields. ClassWizard writes this initialization for you when you use it to declare your recordset class.
You can also write it manually.
The framework uses this number to manage interaction between the field data members and the
corresponding columns of the current record on the data source.
NOTE
This number must correspond to the number of output columns registered in DoFieldExchange after a call to
SetFieldType with the parameter CDaoFieldExchange::outputColumn .

You can bind columns dynamically by way of CDaoRecordset::GetFieldValue and


CDaoRecordset::SetFieldValue . If you do so, you do not need to increment the count in m_nFields to
reflect the number of DFX function calls in your DoFieldExchange member function.

CDaoRecordset::m_nParams
Contains the number of parameter data members in the recordset class — the number of parameters
passed with the recordset's query.
Remarks
If your recordset class has any parameter data members, the constructor for the class must initialize
m_nParams with the correct number. The value of m_nParams defaults to 0. If you add parameter data
members — which you must do manually — you must also manually add an initialization in the class
constructor to reflect the number of parameters (which must be at least as large as the number of ''
placeholders in your m_strFilter or m_strSort string).
The framework uses this number when it parameterizes the recordset's query.

NOTE
This number must correspond to the number of "params" registered in DoFieldExchange after a call to
SetFieldType with the parameter CFieldExchange::param .

For related information, see the topic "Parameter Object" in DAO Help.

CDaoRecordset::m_pDAORecordset
Contains a pointer to the OLE interface for the DAO recordset object underlying the CDaoRecordset object.
Remarks
Use this pointer if you need to access the DAO interface directly.
For related information, see the topic "Recordset Object" in DAO Help.

CDaoRecordset::m_pDatabase
Contains a pointer to the CDaoDatabase object through which the recordset is connected to a data source.
Remarks
This variable is set in two ways. Typically, you pass a pointer to an already open CDaoDatabase object when
you construct the recordset object. If you pass NULL instead, CDaoRecordset creates a CDaoDatabase
object for you and opens it. In either case, CDaoRecordset stores the pointer in this variable.
Normally you will not directly need to use the pointer stored in m_pDatabase . If you write your own
extensions to CDaoRecordset , however, you might need to use the pointer. For example, you might need
the pointer if you throw your own CDaoException (s).
For related information, see the topic "Database Object" in DAO Help.
CDaoRecordset::m_strFilter
Contains a string that is used to construct the WHERE clause of a SQL statement.
Remarks
It does not include the reserved word WHERE to filter the recordset. The use of this data member is not
applicable to table-type recordsets. The use of m_strFilter has no effect when opening a recordset using
a CDaoQueryDef pointer.
Use the U.S. date format (month-day-year) when you filter fields containing dates, even if you are not
using the U.S. version of the Microsoft Jet database engine; otherwise, the data may not be filtered as you
expect.
For related information, see the topic "Filter Property" in DAO Help.

CDaoRecordset::m_strSort
Contains a string containing the ORDERBY clause of a SQL statement without the reserved words
ORDERBY .
Remarks
You can sort on dynaset- and snapshot-type recordset objects.
You cannot sort table-type recordset objects. To determine the sort order of a table-type recordset, call
SetCurrentIndex.
The use of m_strSort has no effect when opening a recordset using a CDaoQueryDef pointer.
For related information, see the topic "Sort Property" in DAO Help.

CDaoRecordset::Move
Call this member function to position the recordset lRows records from the current record.

virtual void Move(long lRows);

Parameters
lRows
The number of records to move forward or backward. Positive values move forward, toward the end of
the recordset. Negative values move backward, toward the beginning.
Remarks
You can move forward or backward. Move( 1 ) is equivalent to MoveNext , and Move( -1 ) is equivalent
to MovePrev .
Cau t i on

Calling any of the Move functions throws an exception if the recordset has no records. In general, call both
IsBOF and IsEOF before a Move operation to determine whether the recordset has any records. After
you call Open or Requery , call either IsBOF or IsEOF .

NOTE
If you have scrolled past the beginning or end of the recordset ( IsBOF or IsEOF returns nonzero), a call to
Move throws a CDaoException .
NOTE
If you call any of the Move functions while the current record is being updated or added, the updates are lost
without warning.

When you call Move on a forward-only scrolling snapshot, the lRows parameter must be a positive
integer and bookmarks are not allowed, so you can move forward only.
To make the first, last, next, or previous record in a recordset the current record, call the MoveFirst ,
MoveLast , MoveNext , or MovePrev member function.

For related information, see the topics "Move Method" and "MoveFirst, MoveLast, MoveNext,
MovePrevious Methods" in DAO Help.

CDaoRecordset::MoveFirst
Call this member function to make the first record in the recordset (if any) the current record.

void MoveFirst();

Remarks
You do not have to call MoveFirst immediately after you open the recordset. At that time, the first record
(if any) is automatically the current record.
Cau t i on

Calling any of the Move functions throws an exception if the recordset has no records. In general, call both
IsBOF and IsEOF before a Move operation to determine whether the recordset has any records. After
you call Open or Requery , call either IsBOF or IsEOF .

NOTE
If you call any of the Move functions while the current record is being updated or added, the updates are lost
without warning.

Use the Move functions to move from record to record without applying a condition. Use the Find
operations to locate records in a dynaset-type or snapshot-type recordset object that satisfy a certain
condition. To locate a record in a table-type recordset object, call Seek .
If the recordset refers to a table-type recordset, movement follows the table's current index. You can set
the current index by using the Index property of the underlying DAO object. If you do not set the current
index, the order of returned records is undefined.
If you call MoveLast on a recordset object based on a SQL query or querydef, the query is forced to
completion and the recordset object is fully populated.
You cannot call the MoveFirst or MovePrev member function with a forward-only scrolling snapshot.
To move the position of the current record in a recordset object a specific number of records forward or
backward, call Move .
For related information, see the topics "Move Method" and "MoveFirst, MoveLast, MoveNext,
MovePrevious Methods" in DAO Help.

CDaoRecordset::MoveLast
Call this member function to make the last record (if any) in the recordset the current record.

void MoveLast();

Remarks
Cau t i on

Calling any of the Move functions throws an exception if the recordset has no records. In general, call both
IsBOF and IsEOF before a Move operation to determine whether the recordset has any records. After
you call Open or Requery , call either IsBOF or IsEOF .

NOTE
If you call any of the Move functions while the current record is being updated or added, the updates are lost
without warning.

Use the Move functions to move from record to record without applying a condition. Use the Find
operations to locate records in a dynaset-type or snapshot-type recordset object that satisfy a certain
condition. To locate a record in a table-type recordset object, call Seek .
If the recordset refers to a table-type recordset, movement follows the table's current index. You can set
the current index by using the Index property of the underlying DAO object. If you do not set the current
index, the order of returned records is undefined.
If you call MoveLast on a recordset object based on a SQL query or querydef, the query is forced to
completion and the recordset object is fully populated.
To move the position of the current record in a recordset object a specific number of records forward or
backward, call Move .
For related information, see the topics "Move Method" and "MoveFirst, MoveLast, MoveNext,
MovePrevious Methods" in DAO Help.

CDaoRecordset::MoveNext
Call this member function to make the next record in the recordset the current record.

void MoveNext();

Remarks
It is recommended that you call IsBOF before you attempt to move to the previous record. A call to
MovePrev will throw a CDaoException if IsBOF returns nonzero, indicating either that you have already
scrolled before the first record or that no records were selected by the recordset.
Cau t i on

Calling any of the Move functions throws an exception if the recordset has no records. In general, call both
IsBOF and IsEOF before a Move operation to determine whether the recordset has any records. After
you call Open or Requery , call either IsBOF or IsEOF .

NOTE
If you call any of the Move functions while the current record is being updated or added, the updates are lost
without warning.
Use the Move functions to move from record to record without applying a condition. Use the Find
operations to locate records in a dynaset-type or snapshot-type recordset object that satisfy a certain
condition. To locate a record in a table-type recordset object, call Seek .
If the recordset refers to a table-type recordset, movement follows the table's current index. You can set
the current index by using the Index property of the underlying DAO object. If you do not set the current
index, the order of returned records is undefined.
To move the position of the current record in a recordset object a specific number of records forward or
backward, call Move .
For related information, see the topics "Move Method" and "MoveFirst, MoveLast, MoveNext,
MovePrevious Methods" in DAO Help.

CDaoRecordset::MovePrev
Call this member function to make the previous record in the recordset the current record.

void MovePrev();

Remarks
It is recommended that you call IsBOF before you attempt to move to the previous record. A call to
MovePrev will throw a CDaoException if IsBOF returns nonzero, indicating either that you have already
scrolled before the first record or that no records were selected by the recordset.
Cau t i on

Calling any of the Move functions throws an exception if the recordset has no records. In general, call both
IsBOF and IsEOF before a Move operation to determine whether the recordset has any records. After
you call Open or Requery , call either IsBOF or IsEOF .

NOTE
If you call any of the Move functions while the current record is being updated or added, the updates are lost
without warning.

Use the Move functions to move from record to record without applying a condition. Use the Find
operations to locate records in a dynaset-type or snapshot-type recordset object that satisfy a certain
condition. To locate a record in a table-type recordset object, call Seek .
If the recordset refers to a table-type recordset, movement follows the table's current index. You can set
the current index by using the Index property of the underlying DAO object. If you do not set the current
index, the order of returned records is undefined.
You cannot call the MoveFirst or MovePrev member function with a forward-only scrolling snapshot.
To move the position of the current record in a recordset object a specific number of records forward or
backward, call Move .
For related information, see the topics "Move Method" and "MoveFirst, MoveLast, MoveNext,
MovePrevious Methods" in DAO Help.

CDaoRecordset::Open
You must call this member function to retrieve the records for the recordset.
virtual void Open(
int nOpenType = AFX_DAO_USE_DEFAULT_TYPE,
LPCTSTR lpszSQL = NULL,
int nOptions = 0);

virtual void Open(


CDaoTableDef* pTableDef,
int nOpenType = dbOpenTable,
int nOptions = 0);

virtual void Open(


CDaoQueryDef* pQueryDef,
int nOpenType = dbOpenDynaset,
int nOptions = 0);

Parameters
nOpenType
One of the following values:
dbOpenDynaset A dynaset-type recordset with bidirectional scrolling. This is the default.
dbOpenTable A table-type recordset with bidirectional scrolling.
dbOpenSnapshot A snapshot-type recordset with bidirectional scrolling.
lpszSQL
A string pointer containing one of the following:
A NULL pointer.
The name of one or more tabledefs and/or querydefs (comma-separated).
A SQL SELECT statement (optionally with a SQL WHERE or ORDERBY clause).
A pass-through query.
nOptions
One or more of the options listed below. The default value is 0. Possible values are as follows:
dbAppendOnly You can only append new records (dynaset-type recordset only). This option means
literally that records may only be appended. The MFC ODBC database classes have an append-only
option that allows records to be retrieved and appended.
dbForwardOnly The recordset is a forward-only scrolling snapshot.
dbSeeChanges Generate an exception if another user is changing data you are editing.
dbDenyWrite Other users cannot modify or add records.
dbDenyRead Other users cannot view records (table-type recordset only).
dbReadOnly You can only view records; other users can modify them.
dbInconsistent Inconsistent updates are allowed (dynaset-type recordset only).
dbConsistent Only consistent updates are allowed (dynaset-type recordset only).
NOTE
The constants dbConsistent and dbInconsistent are mutually exclusive. You can use one or the other, but not
both in a given instance of Open .

pTableDef
A pointer to a CDaoTableDef object. This version is valid only for table-type recordsets. When using this
option, the CDaoDatabase pointer used to construct the CDaoRecordset is not used; rather, the database in
which the tabledef resides is used.
pQueryDef
A pointer to a CDaoQueryDef object. This version is valid only for dynaset-type and snapshot-type
recordsets. When using this option, the CDaoDatabase pointer used to construct the CDaoRecordset is not
used; rather, the database in which the querydef resides is used.
Remarks
Before calling Open , you must construct the recordset object. There are several ways to do this:
When you construct the recordset object, pass a pointer to a CDaoDatabase object that is already
open.
When you construct the recordset object, pass a pointer to a CDaoDatabase object that is not open.
The recordset opens a CDaoDatabase object, but will not close it when the recordset object closes.
When you construct the recordset object, pass a NULL pointer. The recordset object calls
GetDefaultDBName to get the name of the Microsoft Access .MDB file to open. The recordset then
opens a CDaoDatabase object and keeps it open as long as the recordset is open. When you call
Close on the recordset, the CDaoDatabase object is also closed.

NOTE
When the recordset opens the CDaoDatabase object, it opens the data source with nonexclusive access.

For the version of Open that uses the lpszSQL parameter, once the recordset is open you can retrieve
records in one of several ways. The first option is to have DFX functions in your DoFieldExchange . The
second option is to use dynamic binding by calling the GetFieldValue member function. These options
can be implemented separately or in combination. If they are combined, you will have to pass in the SQL
statement yourself on the call to Open .
When you use the second version of Open where you pass in a CDaoTableDef object, the resulting
columns will be available for you to bind via DoFieldExchange and the DFX mechanism, and/or bind
dynamically via GetFieldValue .

NOTE
You can only call Open using a CDaoTableDef object for table-type recordsets.

When you use the third version of Open where you pass in a CDaoQueryDef object, that query will be
executed, and the resulting columns will be available for you to bind via DoFieldExchange and the DFX
mechanism, and/or bind dynamically via GetFieldValue .
NOTE
You can only call Open using a CDaoQueryDef object for dynaset-type and snapshot-type recordsets.

For the first version of Open that uses the lpszSQL parameter, records are selected based on criteria
shown in the following table.

REC O RDS SEL EC T ED A RE


VA L UE O F T H E LPSZSQL PA RA M ET ER DET ERM IN ED B Y EXA M P L E

NULL The string returned by


GetDefaultSQL .

A comma-separated list of one or All columns represented in the "Customer"


more tabledefs and/or querydef DoFieldExchange .
names.

SELECT column-list FROM table- The specified columns from the "SELECT CustId, CustName
list specified tabledef(s) and/or
querydef(s). FROM Customer"

The usual procedure is to pass NULL to Open ; in that case, Open calls GetDefaultSQL , an overridable
member function that ClassWizard generates when creating a CDaoRecordset -derived class. This value
gives the tabledef(s) and/or querydef name(s) you specified in ClassWizard. You can instead specify other
information in the lpszSQL parameter.
Whatever you pass, Open constructs a final SQL string for the query (the string may have SQL WHERE
and ORDERBY clauses appended to the lpszSQL string you passed) and then executes the query. You can
examine the constructed string by calling GetSQL after calling Open .
The field data members of your recordset class are bound to the columns of the data selected. If any
records are returned, the first record becomes the current record.
If you want to set options for the recordset, such as a filter or sort, set m_strSort or m_strFilter after
you construct the recordset object but before you call Open . If you want to refresh the records in the
recordset after the recordset is already open, call Requery .
If you call Open on a dynaset-type or snapshot-type recordset, or if the data source refers to a SQL
statement or a tabledef that represents an attached table, you cannot use dbOpenTable for the type
argument; if you do, MFC throws an exception. To determine whether a tabledef object represents an
attached table, create a CDaoTableDef object and call its GetConnect member function.
Use the dbSeeChanges flag if you wish to trap changes made by another user or another program on your
machine when you are editing or deleting the same record. For example, if two users start editing the
same record, the first user to call the Update member function succeeds. When Update is called by the
second user, a CDaoException is thrown. Similarly, if the second user tries to call Delete to delete the
record, and it has already been changed by the first user, a CDaoException occurs.
Typically, if the user gets this CDaoException while updating, your code should refresh the contents of the
fields and retrieve the newly modified values. If the exception occurs in the process of deleting, your code
could display the new record data to the user and a message indicating that the data has recently
changed. At this point, your code can request a confirmation that the user still wants to delete the record.
TIP
Use the forward-only scrolling option ( dbForwardOnly ) to improve performance when your application makes a
single pass through a recordset opened from an ODBC data source.

For related information, see the topic "OpenRecordset Method" in DAO Help.

CDaoRecordset::Requery
Call this member function to rebuild (refresh) a recordset.

virtual void Requery();

Remarks
If any records are returned, the first record becomes the current record.
In order for the recordset to reflect the additions and deletions that you or other users are making to the
data source, you must rebuild the recordset by calling Requery . If the recordset is a dynaset, it
automatically reflects updates that you or other users make to its existing records (but not additions). If
the recordset is a snapshot, you must call Requery to reflect edits by other users as well as additions and
deletions.
For either a dynaset or a snapshot, call Requery any time you want to rebuild the recordset using
parameter values. Set the new filter or sort by setting m_strFilter and m_strSort before calling Requery .
Set new parameters by assigning new values to parameter data members before calling Requery .
If the attempt to rebuild the recordset fails, the recordset is closed. Before you call Requery , you can
determine whether the recordset can be requeried by calling the CanRestart member function.
CanRestart does not guarantee that Requery will succeed.

Cau t i on

Call Requery only after you have called Open .

NOTE
Calling Requery changes DAO bookmarks.

You can't call Requery on a dynaset-type or snapshot-type recordset if calling CanRestart returns 0, nor
can you use it on a table-type recordset.
If both IsBOF and IsEOF return nonzero after you call Requery , the query didn't return any records and
the recordset will contain no data.
For related information, see the topic "Requery Method" in DAO Help.

CDaoRecordset::Seek
Call this member function to locate the record in an indexed table-type recordset object that satisfies the
specified criteria for the current index and make that record the current record.
BOOL Seek(
LPCTSTR lpszComparison,
COleVariant* pKey1,
COleVariant* pKey2 = NULL,
COleVariant* pKey3 = NULL);

BOOL Seek(
LPCTSTR lpszComparison,
COleVariant* pKeyArray,
WORD nKeys);

Parameters
lpszComparison
One of the following string expressions: "<", "<=", "=", ">=", or ">".
pKey1
A pointer to a COleVariant whose value corresponds to the first field in the index. Required.
pKey2
A pointer to a COleVariant whose value corresponds to the second field in the index, if any. Defaults to
NULL.
pKey3
A pointer to a COleVariant whose value corresponds to the third field in the index, if any. Defaults to
NULL.
pKeyArray
A pointer to an array of variants. The array size corresponds to the number of fields in the index.
nKeys
An integer corresponding to the size of the array, which is the number of fields in the index.

NOTE
Do not specify wildcards in the keys. Wildcards will cause Seek to return no matching records.

Return Value
Nonzero if matching records are found, otherwise 0.
Remarks
Use the second (array) version of Seek to handle indexes of four fields or more.
Seek enables high-performance index searching on table-type recordsets. You must set the current index
by calling SetCurrentIndex before calling Seek . If the index identifies a nonunique key field or fields,
Seek locates the first record that satisfies the criteria. If you do not set an index, an exception is thrown.

Note that if you are not creating a UNICODE recordset, the COleVariant objects must be explicitly
declared ANSI. This can be done by using the COleVariant::COleVariant( lpszSrc , vtSrc ) form of
constructor with vtSrc set to VT_BSTRT (ANSI) or by using the COleVariant function SetString( lpszSrc ,
vtSrc ) with vtSrc set to VT_BSTRT .
When you call Seek , you pass one or more key values and a comparison operator ("<", "<=", "=", ">=",
or ">"). Seek searches through the specified key fields and locates the first record that satisfies the
criteria specified by lpszComparison and pKey1. Once found, Seek returns nonzero, and makes that
record current. If Seek fails to locate a match, Seek returns zero, and the current record is undefined.
When using DAO directly, you must explicitly check the NoMatch property.
If lpszComparison is "=", ">=", or ">", Seek starts at the beginning of the index. If lpszComparison is "<"
or "<=", Seek starts at the end of the index and searches backward unless there are duplicate index
entries at the end. In this case, Seek starts at an arbitrary entry among the duplicate index entries at the
end of the index.
There does not have to be a current record when you use Seek .
To locate a record in a dynaset-type or snapshot-type recordset that satisfies a specific condition, use the
Find operations. To include all records, not just those that satisfy a specific condition, use the Move
operations to move from record to record.
You cannot call Seek on an attached table of any type because attached tables must be opened as
dynaset-type or snapshot-type recordsets. However, if you call CDaoDatabase::Open to directly open an
installable ISAM database, you can call Seek on tables in that database, although the performance may be
slow.
For related information, see the topic "Seek Method" in DAO Help.

CDaoRecordset::SetAbsolutePosition
Sets the relative record number of a recordset object's current record.

void SetAbsolutePosition(long lPosition);

Parameters
lPosition
Corresponds to the ordinal position of the current record in the recordset.
Remarks
Calling SetAbsolutePosition enables you to position the current record pointer to a specific record based
on its ordinal position in a dynaset-type or snapshot-type recordset. You can also determine the current
record number by calling GetAbsolutePosition.

NOTE
This member function is valid only for dynaset-type and snapshot-type recordsets.

The AbsolutePosition property value of the underlying DAO object is zero-based; a setting of 0 refers to
the first record in the recordset. Setting a value greater than the number of populated records causes MFC
to throw an exception. You can determine the number of populated records in the recordset by calling the
GetRecordCount member function.

If the current record is deleted, the AbsolutePosition property value is not defined, and MFC throws an
exception if it is referenced. New records are added to the end of the sequence.

NOTE
This property is not intended to be used as a surrogate record number. Bookmarks are still the recommended way
of retaining and returning to a given position and are the only way to position the current record across all types
of recordset objects that support bookmarks. In particular, the position of a given record changes when record(s)
preceding it are deleted. There is also no assurance that a given record will have the same absolute position if the
recordset is re-created again because the order of individual records within a recordset is not guaranteed unless it
is created with a SQL statement using an ORDERBY clause.
For related information, see the topic "AbsolutePosition Property" in DAO Help.

CDaoRecordset::SetBookmark
Call this member function to position the recordset on the record containing the specified bookmark.

void SetBookmark(COleVariant varBookmark);

Parameters
varBookmark
A COleVariant object containing the bookmark value for a specific record.
Remarks
When a recordset object is created or opened, each of its records already has a unique bookmark. You can
retrieve the bookmark for the current record by calling GetBookmark and saving the value to a
COleVariant object. You can later return to that record by calling SetBookmark using the saved bookmark
value.

NOTE
Calling Requery changes DAO bookmarks.

Note that if you are not creating a UNICODE recordset, the COleVariant object must be explicitly declared
ANSI. This can be done by using the COleVariant::COleVariant( lpszSrc , vtSrc ) form of constructor with
vtSrc set to VT_BSTRT (ANSI) or by using the COleVariant function SetString( lpszSrc , vtSrc ) with vtSrc
set to VT_BSTRT .
For related information, see the topics "Bookmark Property" and Bookmarkable Property" in DAO Help.

CDaoRecordset::SetCacheSize
Call this member function to set the number of records to be cached.

void SetCacheSize(long lSize);

Parameters
lSize
Specifies the number of records. A typical value is 100. A setting of 0 turns off caching. The setting must
be between 5 and 1200 records. The cache may use a considerable amount of memory.
Remarks
A cache is a space in local memory that holds the data most recently retrieved from the server in the
event that the data will be requested again while the application is running. Data caching improves the
performance of an application that retrieves data from a remote server through dynaset-type recordset
objects. When data is requested, the Microsoft Jet database engine checks the cache for the requested
data first rather than retrieving it from the server, which takes more time. Data that does not come from
an ODBC data source is not saved in the cache.
Any ODBC data source, such as an attached table, can have a local cache. To create the cache, open a
recordset object from the remote data source, call the SetCacheSize and SetCacheStart member
functions, and then call the FillCache member function or step through the records by using one of the
Move operations. The lSize parameter of the SetCacheSize member function can be based on the number
of records your application can work with at one time. For example, if you are using a recordset as the
source of the data to be displayed on screen, you could pass the SetCacheSize lSize parameter as 20 to
display 20 records at one time.
For related information, see the topic "CacheSize, CacheStart Properties" in DAO Help.

CDaoRecordset::SetCacheStart
Call this member function to specify the bookmark of the first record in the recordset to be cached.

void SetCacheStart(COleVariant varBookmark);

Parameters
varBookmark
A COleVariant that specifies the bookmark of the first record in the recordset to be cached.
Remarks
You can use the bookmark value of any record for the varBookmark parameter of the SetCacheStart
member function. Make the record you want to start the cache with the current record, establish a
bookmark for that record using SetBookmark, and pass the bookmark value as the parameter for the
SetCacheStart member function.

The Microsoft Jet database engine requests records within the cache range from the cache, and it requests
records outside the cache range from the server.
Records retrieved from the cache do not reflect changes made concurrently to the source data by other
users.
To force an update of all the cached data, pass the lSize parameter of SetCacheSize as 0, call SetCacheSize
again with the size of the cache you originally requested, and then call the FillCache member function.
Note that if you are not creating a UNICODE recordset, the COleVariant object must be explicitly declared
ANSI. This can be done by using the COleVariant::COleVariant( lpszSrc , vtSrc ) form of constructor with
vtSrc set to VT_BSTRT (ANSI) or by using the COleVariant function SetString( lpszSrc , vtSrc ) with vtSrc
set to VT_BSTRT .
For related information, see the topic CacheSize, CacheStart Properties" in DAO Help.

CDaoRecordset::SetCurrentIndex
Call this member function to set an index on a table-type recordset.

void SetCurrentIndex(LPCTSTR lpszIndex);

Parameters
lpszIndex
A pointer containing the name of the index to be set.
Remarks
Records in base tables are not stored in any particular order. Setting an index changes the order of records
returned from the database, but it does not affect the order in which the records are stored. The specified
index must already be defined. If you try to use an index object that does not exist, or if the index is not set
when you call Seek, MFC throws an exception.
You can create a new index for the table by calling CDaoTableDef::CreateIndex and appending the new
index to the Indexes collection of the underlying tabledef by calling CDaoTableDef::Append, and then
reopening the recordset.
Records returned from a table-type recordset can be ordered only by the indexes defined for the
underlying tabledef. To sort records in some other order, you can open a dynaset-type or snapshot-type
recordset using a SQL ORDERBY clause stored in CDaoRecordset::m_strSort.
For related information, see the topic "Index Object" and the definition "current index" in DAO Help.

CDaoRecordset::SetFieldDirty
Call this member function to flag a field data member of the recordset as changed or as unchanged.

void SetFieldDirty(
void* pv,
BOOL bDirty = TRUE);

Parameters
pv
Contains the address of a field data member in the recordset or NULL. If NULL, all field data members in
the recordset are flagged. (C++ NULL is not the same as Null in database terminology, which means
"having no value.")
bDirty
TRUE if the field data member is to be flagged as "dirty" (changed). Otherwise FALSE if the field data
member is to be flagged as "clean" (unchanged).
Remarks
Marking fields as unchanged ensures the field is not updated.
The framework marks changed field data members to ensure they will be written to the record on the data
source by the DAO record field exchange (DFX) mechanism. Changing the value of a field generally sets
the field dirty automatically, so you will seldom need to call SetFieldDirty yourself, but you might
sometimes want to ensure that columns will be explicitly updated or inserted regardless of what value is
in the field data member. The DFX mechanism also employs the use of PSEUDONULL. For more
information, see CDaoFieldExchange::m_nOperation.
If the double-buffering mechanism is not being used, then changing the value of the field does not
automatically set the field as dirty. In this case, it will be necessary to explicitly set the field as dirty. The
flag contained in m_bCheckCacheForDirtyFields controls this automatic field checking.

NOTE
Call this member function only after you have called Edit or AddNew.

Using NULL for the first argument of the function will apply the function to all outputColumn fields, not
param fields in CDaoFieldExchange . For instance, the call

SetFieldDirty(NULL);

will set only outputColumn fields to NULL; param fields will be unaffected.
To work on a param , you must supply the actual address of the individual param you want to work on,
such as:

SetFieldDirty(&m_strParam);

This means you cannot set all param fields to NULL, as you can with outputColumn fields.
SetFieldDirty is implemented through DoFieldExchange .

CDaoRecordset::SetFieldNull
Call this member function to flag a field data member of the recordset as Null (specifically having no
value) or as non-Null.

void SetFieldNull(
void* pv,
BOOL bNull = TRUE);

Parameters
pv
Contains the address of a field data member in the recordset or NULL. If NULL, all field data members in
the recordset are flagged. (C++ NULL is not the same as Null in database terminology, which means
"having no value.")
bNull
Nonzero if the field data member is to be flagged as having no value (Null). Otherwise 0 if the field data
member is to be flagged as non-Null.
Remarks
SetFieldNull is used for fields bound in the DoFieldExchange mechanism.
When you add a new record to a recordset, all field data members are initially set to a Null value and
flagged as "dirty" (changed). When you retrieve a record from a data source, its columns either already
have values or are Null. If it is not appropriate to make a field Null, a CDaoException is thrown.
If you are using the double-buffering mechanism, for example, if you specifically wish to designate a field
of the current record as not having a value, call SetFieldNull with bNull set to TRUE to flag it as Null. If a
field was previously marked Null and you now want to give it a value, simply set its new value. You do not
have to remove the Null flag with SetFieldNull . To determine whether the field is allowed to be Null, call
IsFieldNullable.
If you are not using the double-buffering mechanism, then changing the value of the field does not
automatically set the field as dirty and non-Null. You must specifically set the fields dirty and non-Null.
The flag contained in m_bCheckCacheForDirtyFields controls this automatic field checking.
The DFX mechanism employs the use of PSEUDONULL. For more information, see
CDaoFieldExchange::m_nOperation.

NOTE
Call this member function only after you have called Edit or AddNew.

Using NULL for the first argument of the function will apply the function only to outputColumn fields, not
param fields in CDaoFieldExchange . For instance, the call
SetFieldNull(NULL);

will set only outputColumn fields to NULL; param fields will be unaffected.

CDaoRecordset::SetFieldValue
Call this member function to set the value of a field, either by ordinal position or by changing the value of
the string.

virtual void SetFieldValue(


LPCTSTR lpszName,
const COleVariant& varValue);

virtual void SetFieldValue(


int nIndex,
const COleVariant& varValue);

void SetFieldValue(
LPCTSTR lpszName,
LPCTSTR lpszValue);

void SetFieldValue(
int nIndex,
LPCTSTR lpszValue);

Parameters
lpszName
A pointer to a string containing the name of a field.
varValue
A reference to a COleVariant object containing the value of the field's contents.
nIndex
An integer that represents the ordinal position of the field in the recordset's Fields collection (zero-based).
lpszValue
A pointer to a string containing the value of the field's contents.
Remarks
Use SetFieldValue and GetFieldValue to dynamically bind fields at run time rather than statically binding
columns using the DoFieldExchange mechanism.
Note that if you are not creating a UNICODE recordset, you must either use a form of SetFieldValue that
does not contain a COleVariant parameter, or the COleVariant object must be explicitly declared ANSI.
This can be done by using the COleVariant::COleVariant( lpszSrc , vtSrc ) form of constructor with vtSrc set
to VT_BSTRT (ANSI) or by using the COleVariant function SetString( lpszSrc , vtSrc ) with vtSrc set to
VT_BSTRT .

For related information, see the topics "Field Object" and "Value Property" in DAO Help.

CDaoRecordset::SetFieldValueNull
Call this member function to set the field to a Null value.

void SetFieldValueNull(int nIndex);


void SetFieldValueNull(LPCTSTR lpszName);
Parameters
nIndex
The index of the field in the recordset, for lookup by zero-based index.
lpszName
The name of the field in the recordset, for lookup by name.
Remarks
C++ NULL is not the same as Null, which, in database terminology, means "having no value."
For related information, see the topics "Field Object" and "Value Property" in DAO Help.

CDaoRecordset::SetLockingMode
Call this member function to set the type of locking for the recordset.

void SetLockingMode(BOOL bPessimistic);

Parameters
bPessimistic
A flag that indicates the type of locking.
Remarks
When pessimistic locking is in effect, the 2K page containing the record you are editing is locked as soon
as you call the Edit member function. The page is unlocked when you call the Update or Close
member function or any of the Move or Find operations.
When optimistic locking is in effect, the 2K page containing the record is locked only while the record is
being updated with the Update member function.
If a page is locked, no other user can edit records on the same page. If you call SetLockingMode and pass a
nonzero value and another user already has the page locked, an exception is thrown when you call Edit .
Other users can read data from locked pages.
If you call SetLockingMode with a zero value and later call Update while the page is locked by another
user, an exception occurs. To see the changes made to your record by another user (and lose your
changes), call the SetBookmark member function with the bookmark value of the current record.
When working with ODBC data sources, the locking mode is always optimistic.

CDaoRecordset::SetParamValue
Call this member function to set the value of a parameter in the recordset at run time.

virtual void SetParamValue(


int nIndex,
const COleVariant& varValue);

virtual void SetParamValue(


LPCTSTR lpszName,
const COleVariant& varValue);

Parameters
nIndex
The numerical position of the parameter in the querydef's Parameters collection.
var
The value to set; see Remarks.
lpszName
The name of the parameter whose value you want to set.
Remarks
The parameter must already have been established as part of the recordset's SQL string. You can access
the parameter either by name or by its index position in the collection.
Specify the value to set as a COleVariant object. For information about setting the desired value and type
in your COleVariant object, see class COleVariant. Note that if you are not creating a UNICODE recordset,
the COleVariant object must be explicitly declared ANSI. This can be done by using the
COleVariant::COleVariant( lpszSrc , vtSrc ) form of constructor with vtSrc set to VT_BSTRT (ANSI) or by
using the COleVariant function SetString( lpszSrc , vtSrc ) with vtSrc set to VT_BSTRT .

CDaoRecordset::SetParamValueNull
Call this member function to set the parameter to a Null value.

void SetParamValueNull(int nIndex);


void SetParamValueNull(LPCTSTR lpszName);

Parameters
nIndex
The index of the field in the recordset, for lookup by zero-based index.
lpszName
The name of the field in the recordset, for lookup by name.
Remarks
C++ NULL is not the same as Null, which, in database terminology, means "having no value."

CDaoRecordset::SetPercentPosition
Call this member function to set a value that changes the approximate location of the current record in the
recordset object based on a percentage of the records in the recordset.

void SetPercentPosition(float fPosition);

Parameters
fPosition
A number between 0 and 100.
Remarks
When working with a dynaset-type or snapshot-type recordset, first populate the recordset by moving to
the last record before you call SetPercentPosition . If you call SetPercentPosition before fully populating
the recordset, the amount of movement is relative to the number of records accessed as indicated by the
value of GetRecordCount. You can move to the last record by calling MoveLast .
Once you call SetPercentPosition , the record at the approximate position corresponding to that value
becomes current.
NOTE
Calling SetPercentPosition to move the current record to a specific record in a recordset is not recommended.
Call the SetBookmark member function instead.

For related information, see the topic "PercentPosition Property" in DAO Help.

CDaoRecordset::Update
Call this member function after a call to the AddNew or Edit member function.

virtual void Update();

Remarks
This call is required to complete the AddNew or Edit operation.
Both AddNew and Edit prepare an edit buffer in which the added or edited data is placed for saving to
the data source. Update saves the data. Only those fields marked or detected as changed are updated.
If the data source supports transactions, you can make the Update call (and its corresponding AddNew or
Edit call) part of a transaction.

Cau t i on

If you call Update without first calling either AddNew or Edit , Update throws a CDaoException . If you call
AddNew or Edit , you must call Update before you call MoveNext or close either the recordset or the data
source connection. Otherwise, your changes are lost without notification.
When the recordset object is pessimistically locked in a multiuser environment, the record remains locked
from the time Edit is used until the updating is complete. If the recordset is optimistically locked, the
record is locked and compared with the pre-edited record just before it is updated in the database. If the
record has changed since you called Edit , the Update operation fails and MFC throws an exception. You
can change the locking mode with SetLockingMode .

NOTE
Optimistic locking is always used on external database formats, such as ODBC and installable ISAM.

For related information, see the topics "AddNew Method", "CancelUpdate Method", "Delete Method",
"LastModified Property", "Update Method", and "EditMode Property" in DAO Help.

See also
CObject Class
Hierarchy Chart
CDaoTableDef Class
CDaoWorkspace Class
CDaoDatabase Class
CDaoQueryDef Class
CDaoRecordView Class
3/27/2020 • 7 minutes to read • Edit Online

A view that displays database records in controls.

Syntax
class AFX_NOVTABLE CDaoRecordView : public CFormView

Members
Protected Constructors
NAME DESC RIP T IO N

CDaoRecordView::CDaoRecordView Constructs a CDaoRecordView object.

Public Methods
NAME DESC RIP T IO N

CDaoRecordView::IsOnFirstRecord Returns nonzero if the current record is the first record in


the associated recordset.

CDaoRecordView::IsOnLastRecord Returns nonzero if the current record is the last record in


the associated recordset.

CDaoRecordView::OnGetRecordset Returns a pointer to an object of a class derived from


CDaoRecordset . ClassWizard overrides this function for
you and creates the recordset if necessary.

CDaoRecordView::OnMove If the current record has changed, updates it on the data


source, then moves to the specified record (next, previous,
first, or last).

Remarks
The view is a form view directly connected to a CDaoRecordset object. The view is created from a dialog
template resource and displays the fields of the CDaoRecordset object in the dialog template's controls. The
CDaoRecordView object uses dialog data exchange (DDX) and DAO record field exchange (DFX) to automate the
movement of data between the controls on the form and the fields of the recordset. CDaoRecordView also
supplies a default implementation for moving to the first, next, previous, or last record and an interface for
updating the record currently in view.
NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity (ODBC).
All DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the DAO classes; the
DAO classes generally offer superior capabilities because they use the Microsoft Jet database engine.

The most common way to create your record view is with the Application Wizard. The Application Wizard
creates both the record view class and its associated recordset class as part of your skeleton starter
application.
If you simply need a single form, the Application Wizard approach is easier. ClassWizard lets you decide to use
a record view later in the development process. If you don't create the record view class with the Application
Wizard, you can create it later with ClassWizard. Using ClassWizard to create a record view and a recordset
separately and then connect them is the most flexible approach because it gives you more control in naming
the recordset class and its .H/.CPP files. This approach also lets you have multiple record views on the same
recordset class.
To make it easy for end-users to move from record to record in the record view, the Application Wizard creates
menu (and optionally toolbar) resources for moving to the first, next, previous, or last record. If you create a
record view class with ClassWizard, you need to create these resources yourself with the menu and bitmap
editors.
For information about the default implementation for moving from record to record, see IsOnFirstRecord and
IsOnLastRecord and the article Using a Record View, which applies to both CRecordView and CDaoRecordView .

CDaoRecordView keeps track of the user's position in the recordset so that the record view can update the user
interface. When the user moves to either end of the recordset, the record view disables user interface objects
— such as menu items or toolbar buttons — for moving further in the same direction.
For more information about declaring and using your record view and recordset classes, see "Designing and
Creating a Record View" in the article Record Views. For more information about how record views work and
how to use them, see the article Using a Record View. All the articles mentioned above apply to both
CRecordView and CDaoRecordView .

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CScrollView
CFormView
CDaoRecordView

Requirements
Header : afxdao.h

CDaoRecordView::CDaoRecordView
When you create an object of a type derived from CDaoRecordView , call either form of the constructor to
initialize the view object and identify the dialog resource on which the view is based.

explicit CDaoRecordView(LPCTSTR lpszTemplateName);


explicit CDaoRecordView(UINT nIDTemplate);

Parameters
lpszTemplateName
Contains a null-terminated string that is the name of a dialog template resource.
nIDTemplate
Contains the ID number of a dialog template resource.
Remarks
You can either identify the resource by name (pass a string as the argument to the constructor) or by its ID
(pass an unsigned integer as the argument). Using a resource ID is recommended.

NOTE
Your derived class must supply its own constructor. In the constructor of your derived class, call the constructor
CDaoRecordView::CDaoRecordView with the resource name or ID as an argument.

CDaoRecordView::OnInitialUpdate calls , which calls CWnd::DoDataExchange . This initial call to


CWnd::UpdateData
DoDataExchange connects CDaoRecordView controls (indirectly) to CDaoRecordset field data members created
by ClassWizard. These data members cannot be used until after you call the base class
CFormView::OnInitialUpdate member function.

NOTE
If you use ClassWizard, the wizard defines an enum value CDaoRecordView::IDD in the class declaration and uses it in
the member initialization list for the constructor.

CMyDaoRecordView::CMyDaoRecordView()
: CDaoRecordView(CMyDaoRecordView::IDD)
{
m_pSet = NULL;
// TODO: add construction code here
}

CDaoRecordView::IsOnFirstRecord
Call this member function to determine whether the current record is the first record in the recordset object
associated with this record view.

BOOL IsOnFirstRecord();

Return Value
Nonzero if the current record is the first record in the recordset; otherwise 0.
Remarks
This function is useful for writing your own implementations of the default command update handlers written
by ClassWizard.
If the user moves to the first record, the framework disables any user interface objects (for example, menu
items or toolbar buttons) you have for moving to the first or the previous record.

CDaoRecordView::IsOnLastRecord
Call this member function to determine whether the current record is the last record in the recordset object
associated with this record view.

BOOL IsOnLastRecord();

Return Value
Nonzero if the current record is the last record in the recordset; otherwise 0.
Remarks
This function is useful for writing your own implementations of the default command update handlers that
ClassWizard writes to support a user interface for moving from record to record.
Cau t i on

The result of this function is reliable except that the view may not be able to detect the end of the recordset
until the user has moved past it. The user might have to move beyond the last record before the record view
can tell that it must disable any user interface objects for moving to the next or last record. If the user moves
past the last record and then moves back to the last record (or before it), the record view can track the user's
position in the recordset and disable user interface objects correctly.

CDaoRecordView::OnGetRecordset
Returns a pointer to the CDaoRecordset -derived object associated with the record view.

virtual CDaoRecordset* OnGetRecordset() = 0;

Return Value
A pointer to a CDaoRecordset -derived object if the object was successfully created; otherwise a NULL pointer.
Remarks
You must override this member function to construct or obtain a recordset object and return a pointer to it. If
you declare your record view class with ClassWizard, the wizard writes a default override for you.
ClassWizard's default implementation returns the recordset pointer stored in the record view if one exists. If
not, it constructs a recordset object of the type you specified with ClassWizard and calls its Open member
function to open the table or run the query, and then returns a pointer to the object.
For more information and examples, see the article Record Views: Using a Record View.

CDaoRecordView::OnMove
Call this member function to move to a different record in the recordset and display its fields in the controls of
the record view.

virtual BOOL OnMove(UINT nIDMoveCommand);

Parameters
nIDMoveCommand
One of the following standard command ID values:
ID_RECORD_FIRST Move to the first record in the recordset.
ID_RECORD_LAST Move to the last record in the recordset.
ID_RECORD_NEXT Move to the next record in the recordset.
ID_RECORD_PREV Move to the previous record in the recordset.
Return Value
Nonzero if the move was successful; otherwise 0 if the move request was denied.
Remarks
The default implementation calls the appropriate Move member function of the CDaoRecordset object
associated with the record view.
By default, OnMove updates the current record on the data source if the user has changed it in the record view.
The Application Wizard creates a menu resource with First Record, Last Record, Next Record, and Previous
Record menu items. If you select the Initial Toolbar option, the Application Wizard also creates a toolbar with
buttons corresponding to these commands.
If you move past the last record in the recordset, the record view continues to display the last record. If you
move backward past the first record, the record view continues to display the first record.
Cau t i on

Calling OnMove throws an exception if the recordset has no records. Call the appropriate user interface update
handler function — OnUpdateRecordFirst , OnUpdateRecordLast , OnUpdateRecordNext , or OnUpdateRecordPrev —
before the corresponding move operation to determine whether the recordset has any records.

See also
CFormView Class
Hierarchy Chart
CDaoRecordset Class
CDaoTableDef Class
CDaoQueryDef Class
CDaoDatabase Class
CDaoWorkspace Class
CFormView Class
CDaoTableDef Class
4/21/2020 • 25 minutes to read • Edit Online

Represents the stored definition of a base table or an attached table.

Syntax
class CDaoTableDef : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDaoTableDef::CDaoTableDef Constructs a CDaoTableDef object.

Public Methods
NAME DESC RIP T IO N

CDaoTableDef::Append Adds a new table to the database.

CDaoTableDef::CanUpdate Returns nonzero if the table can be updated (you can modify
the definition of fields or the table properties).

CDaoTableDef::Close Closes an open tabledef.

CDaoTableDef::Create Creates a table which can be added to the database using


Append.

CDaoTableDef::CreateField Called to create a field for a table.

CDaoTableDef::CreateIndex Called to create an index for a table.

CDaoTableDef::DeleteField Called to delete a field from a table.

CDaoTableDef::DeleteIndex Called to delete an index from a table.

CDaoTableDef::GetAttributes Returns a value that indicates one or more characteristics of


a CDaoTableDef object.

CDaoTableDef::GetConnect Returns a value that provides information about the source


of a table.

CDaoTableDef::GetDateCreated Returns the date and time the base table underlying a
CDaoTableDef object was created.
NAME DESC RIP T IO N

CDaoTableDef::GetDateLastUpdated Returns the date and time of the most recent change made
to the design of the base table.

CDaoTableDef::GetFieldCount Returns a value that represents the number of fields in the


table.

CDaoTableDef::GetFieldInfo Returns specific kinds of information about the fields in the


table.

CDaoTableDef::GetIndexCount Returns the number of indexes for the table.

CDaoTableDef::GetIndexInfo Returns specific kinds of information about the indexes for


the table.

CDaoTableDef::GetName Returns the user-defined name of the table.

CDaoTableDef::GetRecordCount Returns the number of records in the table.

CDaoTableDef::GetSourceTableName Returns a value that specifies the name of the attached table
in the source database.

CDaoTableDef::GetValidationRule Returns a value that validates the data in a field as it is


changed or added to a table.

CDaoTableDef::GetValidationText Returns a value that specifies the text of the message that
your application displays if the value of a Field object does
not satisfy the specified validation rule.

CDaoTableDef::IsOpen Returns nonzero if the table is open.

CDaoTableDef::Open Opens an existing tabledef stored in the database's


TableDef's collection.

CDaoTableDef::RefreshLink Updates the connection information for an attached table.

CDaoTableDef::SetAttributes Sets a value that indicates one or more characteristics of a


CDaoTableDef object.

CDaoTableDef::SetConnect Sets a value that provides information about the source of a


table.

CDaoTableDef::SetName Sets the name of the table.

CDaoTableDef::SetSourceTableName Sets a value that specifies the name of an attached table in


the source database.

CDaoTableDef::SetValidationRule Sets a value that validates the data in a field as it is changed


or added to a table.

CDaoTableDef::SetValidationText Sets a value that specifies the text of the message that your
application displays if the value of a Field object does not
satisfy the specified validation rule.
Public Data Members
NAME DESC RIP T IO N

CDaoTableDef::m_pDAOTableDef A pointer to the DAO interface underlying the tabledef


object.

CDaoTableDef::m_pDatabase Source database for this table.

Remarks
Each DAO database object maintains a collection, called TableDefs, that contains all saved DAO tabledef objects.
You manipulate a table definition using a CDaoTableDef object. For example, you can:
Examine the field and index structure of any local, attached, or external table in a database.
Call the SetConnect and SetSourceTableName member functions for attached tables, and use the
RefreshLink member function to update connections to attached tables.
Call the CanUpdate member function to determine if you can edit field definitions in the table.
Get or set validation conditions using the GetValidationRule and SetValidationRule , and the
GetValidationText and SetValidationText member functions.

Use the Open member function to create a table-, dynaset-, or snapshot-type CDaoRecordset object.

NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity
(ODBC). All DAO database class names have the "CDao" prefix. You can still access ODBC data sources with the
DAO classes; the DAO classes generally offer superior capabilities because they are specific to the Microsoft Jet
database engine.

To use tabledef objects either to work with an existing table or to create a new table
1. In all cases, first construct a CDaoTableDef object, supplying a pointer to a CDaoDatabase object to which
the table belongs.
2. Then do the following, depending on what you want:
To use an existing saved table, call the tabledef object's Open member function, supplying the
name of the saved table.
To create a new table, call the tabledef object's Create member function, supplying the name of the
table. Call CreateField and CreateIndex to add fields and indexes to the table.
Call Append to save the table by appending it to the database's TableDefs collection. Create puts
the tabledef into an open state, so after calling Create you do not call Open .

TIP
The easiest way to create saved tables is to create them and store them in your database using Microsoft
Access. Then you can open and use them in your MFC code.

To use the tabledef object you have opened or created, create and open a CDaoRecordset object, specifying the
name of the tabledef with a dbOpenTable value in the nOpenType parameter.
To use a tabledef object to create a CDaoRecordset object, you typically create or open a tabledef as described
above, then construct a recordset object, passing a pointer to your tabledef object when you call
CDaoRecordset::Open. The tabledef you pass must be in an open state. For more information, see class
CDaoRecordset.
When you finish using a tabledef object, call its Close member function; then destroy the tabledef object.

Inheritance Hierarchy
CObject
CDaoTableDef

Requirements
Header : afxdao.h

CDaoTableDef::Append
Call this member function after you call Create to create a new tabledef object to save the tabledef in the
database.

virtual void Append();

Remarks
The function appends the object to the database's TableDefs collection. You can use the tabledef as a temporary
object while defining it by not appending it, but if you want to save and use it, you must call Append .

NOTE
If you attempt to append an unnamed tabledef (containing a null or empty string), MFC throws an exception.

For related information, see the topic "Append Method" in DAO Help.

CDaoTableDef::CanUpdate
Call this member function to determine whether the definition of the table underlying a CDaoTableDef object
can be changed.

BOOL CanUpdate();

Return Value
Nonzero if the table structure (schema) can be modified (add or delete fields and indexes), otherwise 0.
Remarks
By default, a newly created table underlying a CDaoTableDef object can be updated, and an attached table
underlying a CDaoTableDef object cannot be updated. A CDaoTableDef object may be updatable, even if the
resulting recordset is not updatable.
For related information, see the topic "Updatable Property" in DAO Help.

CDaoTableDef::CDaoTableDef
Constructs a CDaoTableDef object.

CDaoTableDef(CDaoDatabase* pDatabase);

Parameters
pDatabase
A pointer to a CDaoDatabase object.
Remarks
After constructing the object, you must call the Create or Open member function. When you finish with the
object, you must call its Close member function and destroy the CDaoTableDef object.

CDaoTableDef::Close
Call this member function to close and release the tabledef object.

virtual void Close();

Remarks
Usually after calling Close , you delete the tabledef object if it was allocated with new .
You can call Open again after calling Close . This lets you reuse the tabledef object.
For related information, see the topic "Close Method" in DAO Help.

CDaoTableDef::Create
Call this member function to create a new saved table.

virtual void Create(


LPCTSTR lpszName,
long lAttributes = 0,
LPCTSTR lpszSrcTable = NULL,
LPCTSTR lpszConnect = NULL);

Parameters
lpszName
A pointer to a string containing the name of the table.
lAttributes
A value corresponding to characteristics of the table represented by the tabledef object. You can use the bitwise-
OR to combine any of the following constants:

C O N STA N T DESC RIP T IO N

dbAttachExclusive For databases that use the Microsoft Jet database engine,
indicates the table is an attached table opened for exclusive
use.

dbAttachSavePWD For databases that use the Microsoft Jet database engine,
indicates that the user ID and password for the attached
table are saved with the connection information.
C O N STA N T DESC RIP T IO N

dbSystemObject Indicates the table is a system table provided by the


Microsoft Jet database engine.

dbHiddenObject Indicates the table is a hidden table provided by the


Microsoft Jet database engine.

lpszSrcTable
A pointer to a string containing the source table name. By default this value is initialized as NULL.
lpszConnect
A pointer to a string containing the default connection string. By default this value is initialized as NULL.
Remarks
Once you have named the tabledef, you can then call Append to save the tabledef in the database's TableDefs
collection. After calling Append , the tabledef is in an open state, and you can use it to create a CDaoRecordset
object.
For related information, see the topic "CreateTableDef Method" in DAO Help.

CDaoTableDef::CreateField
Call this member function to add a field to the table.

void CreateField(
LPCTSTR lpszName,
short nType,
long lSize,
long lAttributes = 0);

void CreateField(CDaoFieldInfo& fieldinfo);

Parameters
lpszName
A pointer to a string expression specifying the name of this field.
nType
A value indicating the data type of the field. The setting can be one of these values:

TYPE SIZ E ( B Y T ES) DESC RIP T IO N

dbBoolean 1 byte BOOL

dbByte BYTE

dbInteger 2 int

dbLong 4 long

dbCurrency 8 Currency ( COleCurrency)

dbSingle 4 float
TYPE SIZ E ( B Y T ES) DESC RIP T IO N

dbDouble 8 double

dbDate 8 Date/Time ( COleDateTime)

dbText 1 - 255 Text ( CString)

dbLongBinary 0 Long Binary (OLE Object),


CLongBinary or CByteArray

dbMemo 0 Memo ( CString)

lSize
A value that indicates the maximum size, in bytes, of a field that contains text, or the fixed size of a field that
contains text or numeric values. The lSize parameter is ignored for all but text fields.
lAttributes
A value corresponding to characteristics of the field and that can be combined using a bitwise-OR.

C O N STA N T DESC RIP T IO N

dbFixedField The field size is fixed (default for Numeric fields).

dbVariableField The field size is variable (Text fields only).

dbAutoIncrField The field value for new records is automatically incremented


to a unique long integer that cannot be changed. Only
supported for Microsoft Jet database tables.

dbUpdatableField The field value can be changed.

dbDescending The field is sorted in descending (Z - A or 100 - 0) order


(applies only to a Field object in a Fields collection of an
Index object). If you omit this constant, the field is sorted in
ascending (A - Z or 0 - 100) order (default).

fieldinfo
A reference to a CDaoFieldInfo structure.
Remarks
A DAOField (OLE) object is created and appended to the Fields collection of the DAOTableDef (OLE) object.
Besides its use for examining object properties, you can also use CDaoFieldInfo to construct an input
parameter for creating new fields in a tabledef. The first version of CreateField is simpler to use, but if you
want finer control, you can use the second version of CreateField , which takes a CDaoFieldInfo parameter.
If you use the version of CreateField that takes a CDaoFieldInfo parameter, you must carefully set each of the
following members of the CDaoFieldInfo structure:
m_strName

m_nType

m_lSize
m_lAttributes

m_bAllowZeroLength

The remaining members of CDaoFieldInfo should be set to 0 , FALSE, or an empty string, as appropriate for the
member, or a CDaoException may occur.
For related information, see the topic "CreateField Method" in DAO Help.

CDaoTableDef::CreateIndex
Call this function to add an index to a table.

void CreateIndex(CDaoIndexInfo& indexinfo);

Parameters
indexinfo
A reference to a CDaoIndexInfo structure.
Remarks
Indexes specify the order of records accessed from database tables and whether or not duplicate records are
accepted. Indexes also provide efficient access to data.
You do not have to create indexes for tables, but in large, unindexed tables, accessing a specific record or
creating a recordset can take a long time. On the other hand, creating too many indexes slows down update,
append, and delete operations as all indexes are automatically updated. Consider these factors as you decide
which indexes to create.
The following members of the CDaoIndexInfo structure must be set:
m_strName A name must be supplied.
m_pFieldInfos Must point to an array of CDaoIndexFieldInfo structures.
m_nFields Must specify the number of fields in the array of CDaoFieldInfo structures.

The remaining members will be ignored if set to FALSE. In addition, the m_lDistinctCount member is ignored
during creation of the index.

CDaoTableDef::DeleteField
Call this member function to remove a field and make it inaccessible.

void DeleteField(LPCTSTR lpszName);


void DeleteField(int nIndex);

Parameters
lpszName
A pointer to a string expression that is the name of an existing field.
nIndex
The index of the field in the table's zero-based Fields collection, for lookup by index.
Remarks
You can use this member function on a new object that has not been appended to the database or when
CanUpdate returns nonzero.
For related information, see the topic "Delete Method" in DAO Help.

CDaoTableDef::DeleteIndex
Call this member function to delete an index in an underlying table.

void DeleteIndex(LPCTSTR lpszName);


void DeleteIndex(int nIndex);

Parameters
lpszName
A pointer to a string expression that is the name of an existing index.
nIndex
The array index of the index object in the database's zero-based TableDefs collection, for lookup by index.
Remarks
You can use this member function on a new object that hasn't been appended to the database or when
CanUpdate returns nonzero.
For related information, see the topic "Delete Method" in DAO Help.

CDaoTableDef::GetAttributes
For a CDaoTableDef object, the return value specifies characteristics of the table represented by the
CDaoTableDef object and can be a sum of these constants:

long GetAttributes();

Return Value
Returns a value that indicates one or more characteristics of a CDaoTableDef object.
Remarks
C O N STA N T DESC RIP T IO N

dbAttachExclusive For databases that use the Microsoft Jet database engine,
indicates the table is an attached table opened for exclusive
use.

dbAttachSavePWD For databases that use the Microsoft Jet database engine,
indicates that the user ID and password for the attached
table are saved with the connection information.

dbSystemObject Indicates the table is a system table provided by the


Microsoft Jet database engine.

dbHiddenObject Indicates the table is a hidden table provided by the


Microsoft Jet database engine.

dbAttachedTable Indicates the table is an attached table from a non-ODBC


database, such as a Paradox database.
C O N STA N T DESC RIP T IO N

dbAttachedODBC Indicates the table is an attached table from an ODBC


database, such as Microsoft SQL Server.

A system table is a table created by the Microsoft Jet database engine to contain various internal information.
A hidden table is a table created for temporary use by the Microsoft Jet database engine.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoTableDef::GetConnect
Call this member function to obtain the connection string for a data source.

CString GetConnect();

Return Value
A CString object containing the path and database type for the table.
Remarks
For a CDaoTableDef object that represents an attached table, the CString object consists of one or two parts (a
database type specifier and a path to the database).
The path as shown in the table below is the full path for the directory containing the database files and must be
preceded by the identifier "DATABASE=". In some cases (as with Microsoft Jet and Microsoft Excel databases), a
specific filename is included in the database path argument.
The table in CDaoTableDef::SetConnect shows possible database types and their corresponding database
specifiers and paths:
For Microsoft Jet database base tables, the specifier is a empty string ("").
If a password is required but not provided, the ODBC driver displays a login dialog box the first time a table is
accessed and again if the connection is closed and reopened. If an attached table has the dbAttachSavePWD
attribute, the login prompt will not appear when the table is reopened.
For related information, see the topic "Connect Property" in DAO Help.

CDaoTableDef::GetDateCreated
Call this function to determine the date and time the table underlying the CDaoTableDef object was created.

COleDateTime GetDateCreated();

Return Value
A value containing the date and time of the creation of the table underlying the CDaoTableDef object.
Remarks
The date and time settings are derived from the computer on which the base table was created or last updated.
In a multiuser environment, users should get these settings directly from the file server to avoid discrepancies;
that is, all clients should use a "standard" time source — perhaps from one server.
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.
CDaoTableDef::GetDateLastUpdated
Call this function to determine the date and time the table underlying the CDaoTableDef object was last
updated.

COleDateTime GetDateLastUpdated();

Return Value
A value that contains the date and time the table underlying the CDaoTableDef object was last updated.
Remarks
The date and time settings are derived from the computer on which the base table was created or last updated.
In a multiuser environment, users should get these settings directly from the file server to avoid discrepancies;
that is, all clients should use a "standard" time source — perhaps from one server.
For related information, see the topic "DateCreated, LastUpdated Properties" in DAO Help.

CDaoTableDef::GetFieldCount
Call this member function to retrieve the number of fields defined in the table.

short GetFieldCount();

Return Value
The number of fields in the table.
Remarks
If its value is 0, there are no objects in the collection.
For related information, see the topic "Count Property" in DAO Help.

CDaoTableDef::GetFieldInfo
Call this member function to obtain various kinds of information about a field defined in the tabledef.

void GetFieldInfo(
int nIndex,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetFieldInfo(
LPCTSTR lpszName,
CDaoFieldInfo& fieldinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The index of the field object in the table's zero-based Fields collection, for lookup by index.
fieldinfo
A reference to a CDaoFieldInfo structure.
dwInfoOptions
Options that specify which information about the field to retrieve. The available options are listed here along
with what they cause the function to return:
AFX_DAO_PRIMARY_INFO (Default) Name, Type, Size, Attributes. Use this option for fastest performance.
AFX_DAO_SECONDARY_INFO Primary information, plus: Ordinal Position, Required, Allow Zero Length,
Collating Order, Foreign Name, Source Field, Source Table
AFX_DAO_ALL_INFO Primary and secondary information, plus: Validation Rule, Validation Text, Default
Value
lpszName
A pointer to the name of the field object, for lookup by name. The name is a string with up to 64 characters that
uniquely names the field.
Remarks
One version of the function lets you look up a field by index. The other version lets you look up a field by name.
For a description of the information returned, see the CDaoFieldInfo structure. This structure has members that
correspond to the items of information listed above in the description of dwInfoOptions. When you request
information at one level, you get information for any prior levels as well.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoTableDef::GetIndexCount
Call this member function to obtain the number of indexes for a table.

short GetIndexCount();

Return Value
The number of indexes for the table.
Remarks
If its value is 0, there are no indexes in the collection.
For related information, see the topic "Count Property" in DAO Help.

CDaoTableDef::GetIndexInfo
Call this member function to obtain various kinds of information about an index defined in the tabledef.

void GetIndexInfo(
int nIndex,
CDaoIndexInfo& indexinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetIndexInfo(
LPCTSTR lpszName,
CDaoIndexInfo& indexinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The numeric index of the Index object in the table's zero-based Indexes collection, for lookup by its position in
the collection.
indexinfo
A reference to a CDaoIndexInfo structure.
dwInfoOptions
Options that specify which information about the index to retrieve. The available options are listed here along
with what they cause the function to return:
AFX_DAO_PRIMARY_INFO Name, Field Info, Fields. Use this option for fastest performance.
AFX_DAO_SECONDARY_INFO Primary information, plus: Primary, Unique, Clustered, Ignore Nulls, Required,
Foreign
AFX_DAO_ALL_INFO Primary and secondary information, plus: Distinct Count
lpszName
A pointer to the name of the index object, for lookup by name.
Remarks
One version of the function lets you look up an index by its position in the collection. The other version lets you
look up an index by name.
For a description of the information returned, see the CDaoIndexInfo structure. This structure has members that
correspond to the items of information listed above in the description of dwInfoOptions. When you request
information at one level, you get information for any prior levels as well.
For related information, see the topic "Attributes Property" in DAO Help.

CDaoTableDef::GetName
Call this member function to obtain the user-defined name of the underlying table.

CString GetName();

Return Value
A user-defined name for a table.
Remarks
This name starts with a letter and can contain a maximum of 64 characters. It can include numbers and
underscore characters but cannot include punctuation or spaces.
For related information, see the topic "Name Property" in DAO Help.

CDaoTableDef::GetRecordCount
Call this member function to find out how many records are in a CDaoTableDef object.

long GetRecordCount();

Return Value
The number of records accessed in a tabledef object.
Remarks
Calling GetRecordCount for a table-type CDaoTableDef object reflects the approximate number of records in the
table and is affected immediately as table records are added and deleted. Rolled back transactions will appear
as part of the record count until you call CDaoWorkSpace::CompactDatabase. A CDaoTableDef object with no
records has a record count property setting of 0. When working with attached tables or ODBC databases,
GetRecordCount always returns -1.
For related information, see the topic "RecordCount Property" in DAO Help.

CDaoTableDef::GetSourceTableName
Call this member function to retrieve the name of an attached table in a source database.

CString GetSourceTableName();

Return Value
A CString object that specifies the source name of an attached table, or an empty string if a native data table.
Remarks
An attached table is a table in another database linked to a Microsoft Jet database. Data for attached tables
remains in the external database, where it can be manipulated by other applications.
For related information, see the topic "SourceTableName Property" in DAO Help.

CDaoTableDef::GetValidationRule
Call this member function to retrieve the validation rule for a tabledef.

CString GetValidationRule();

Return Value
A CString object that validates the data in a field as it is changed or added to a table.
Remarks
Validation rules are used in connection with update operations. If a tabledef contains a validation rule, updates
to that tabledef must match predetermined criteria before the data is changed. If the change does not match the
criteria, an exception containing the value of GetValidationText is thrown. For a CDaoTableDef object, this
CString is read-only for an attached table and read/write for a base table.

For related information, see the topic "ValidationRule Property" in DAO Help.

CDaoTableDef::GetValidationText
Call this function to retrieve the string to display when a user enters data that does not match the validation
rule.

CString GetValidationText();

Return Value
A CString object that specifies the text displayed if the user enters data that does not match the validation rule.
Remarks
For a CDaoTableDef object, this CString is read-only for an attached table and read/write for a base table.
For related information, see the topic "ValidationText Property" in DAO Help.

CDaoTableDef::IsOpen
Call this member function to determine whether the CDaoTableDef object is currently open.
BOOL IsOpen() const;

Return Value
Nonzero if the CDaoTableDef object is open; otherwise 0.
Remarks

CDaoTableDef::m_pDatabase
Contains a pointer to the CDaoDatabase object for this table.
Remarks

CDaoTableDef::m_pDAOTableDef
Contains a pointer to the OLE interface for the DAO tabledef object underlying the CDaoTableDef object.
Remarks
Use this pointer if you need to access the DAO interface directly.

CDaoTableDef::Open
Call this member function to open a tabledef previously saved in the database's TableDef's collection.

virtual void Open(LPCTSTR lpszName);

Parameters
lpszName
A pointer to a string that specifies a table name.
Remarks

CDaoTableDef::RefreshLink
Call this member function to update the connection information for an attached table.

void RefreshLink();

Remarks
You change the connection information for an attached table by calling SetConnect on the corresponding
CDaoTableDef object and then using the RefreshLink member function to update the information. When you
call RefreshLink , the attached table's properties are not changed.
To force the modified connect information to take effect, all open CDaoRecordset objects based on this tabledef
must be closed.
For related information, see the topic "RefreshLink Method" in DAO Help.

CDaoTableDef::SetAttributes
Sets a value that indicates one or more characteristics of a CDaoTableDef object.
void SetAttributes(long lAttributes);

Parameters
lAttributes
Characteristics of the table represented by the CDaoTableDef object and can be a sum of these constants:

C O N STA N T DESC RIP T IO N

dbAttachExclusive For databases that use the Microsoft Jet database engine,
indicates the table is an attached table opened for exclusive
use.

dbAttachSavePWD For databases that use the Microsoft Jet database engine,
indicates that the user ID and password for the attached
table are saved with the connection information.

dbSystemObject Indicates the table is a system table provided by the


Microsoft Jet database engine.

dbHiddenObject Indicates the table is a hidden table provided by the


Microsoft Jet database engine.

Remarks
When setting multiple attributes, you can combine them by summing the appropriate constants using the
bitwise-OR operator. Setting dbAttachExclusive on a nonattached table produces an exception. Combining the
following values also produce an exception:
dbAttachExclusive | dbAttachedODBC
dbAttachSavePWD | dbAttachedTable
For related information, see the topic "Attributes Property" in DAO Help.

CDaoTableDef::SetConnect
For a CDaoTableDef object that represents an attached table, the string object consists of one or two parts (a
database type specifier and a path to the database).

void SetConnect(LPCTSTR lpszConnect);

Parameters
lpszConnect
A pointer to a string expression that specifies additional parameters to pass to ODBC or installable ISAM
drivers.
Remarks
The path as shown in the table below is the full path for the directory containing the database files and must be
preceded by the identifier "DATABASE=". In some cases (as with Microsoft Jet and Microsoft Excel databases), a
specific filename is included in the database path argument.
NOTE
Do not include whitespace around the equal sign in path statements of the form "DATABASE=drive:\\path". This will
result in an exception being thrown and the connection failing.

The following table shows possible database types and their corresponding database specifiers and paths:

DATA B A SE T Y P E SP EC IF IER PAT H

Database using the Jet database "[ database ];" " drive :\\ path\\ filename.MDB"
engine

dBASE III "dBASE III;" " drive :\\ path"

dBASE IV "dBASE IV;" " drive :\\ path"

dBASE 5 "dBASE 5.0;" " drive :\\ path"

Paradox 3.x "Paradox 3.x;" " drive :\\ path"

Paradox 4.x "Paradox 4.x;" " drive :\\ path"

Paradox 5.x "Paradox 5.x;" " drive :\\ path"

Excel 3.0 "Excel 3.0;" " drive :\\ path\\ filename.XLS"

Excel 4.0 "Excel 4.0;" " drive :\\ path\\ filename.XLS"

Excel 5.0 or Excel 95 "Excel 5.0;" " drive :\\ path\\ filename.XLS"

Excel 97 "Excel 8.0;" " drive :\\ path\ filename.XLS"

HTML Import "HTML Import;" " drive :\\ path\ filename"

HTML Export "HTML Export;" " drive :\\ path"

Text "Text;" "drive:\\path"

ODBC "ODBC; DATABASE= database ; UID= None


user;PWD= password; DSN=
datasourcename; LOGINTIMEOUT=
seconds;" (This may not be a complete
connection string for all servers; it is
just an example. It is very important
not to have spaces between the
parameters.)
DATA B A SE T Y P E SP EC IF IER PAT H

Exchange "Exchange; "drive:\\ path\\ filename.MDB"

MAPILEVEL= folderpath;

[TABLETYPE={ 0 | 1 };]

[PROFILE= profile;]

[PWD= password;]

[DATABASE= database ;]"

NOTE
Btrieve is no longer supported as of DAO 3.5.

You must use a double backslash (\\) in the connection strings. If you have modified the properties of an
existing connection using SetConnect , you must subsequently call RefreshLink. If you are initializing the
connection properties using SetConnect , you need not call RefreshLink , but should you choose to do so, first
append the tabledef.
If a password is required but not provided, the ODBC driver displays a login dialog box the first time a table is
accessed and again if the connection is closed and reopened.
You can set the connection string for a CDaoTableDef object by providing a source argument to the Create
member function. You can check the setting to determine the type, path, user ID, password, or ODBC data
source of the database. For more information, see the documentation for the specific driver.
For related information, see the topic "Connect Property" in DAO Help.

CDaoTableDef::SetName
Call this member function to set a user-defined name for a table.

void SetName(LPCTSTR lpszName);

Parameters
lpszName
A pointer to a string expression that specifies a name for a table.
Remarks
The name must start with a letter and can contain a maximum of 64 characters. It can include numbers and
underscore characters but cannot include punctuation or spaces.
For related information, see the topic "Name Property" in DAO Help.

CDaoTableDef::SetSourceTableName
Call this member function to specify the name of an attached table or the name of the base table on which the
CDaoTableDef object is based, as it exists in the original source of the data.

void SetSourceTableName(LPCTSTR lpszSrcTableName);


Parameters
lpszSrcTableName
A pointer to a string expression that specifies a table name in the external database. For a base table, the setting
is an empty string ("").
Remarks
You must then call RefreshLink. This property setting is empty for a base table and read/write for an attached
table or an object not appended to a collection.
For related information, see the topic "SourceTableName Property" in DAO Help.

CDaoTableDef::SetValidationRule
Call this member function to set a validation rule for a tabledef.

void SetValidationRule(LPCTSTR lpszValidationRule);

Parameters
lpszValidationRule
A pointer to a string expression that validates an operation.
Remarks
Validation rules are used in connection with update operations. If a tabledef contains a validation rule, updates
to that tabledef must match predetermined criteria before the data is changed. If the change does not match the
criteria, an exception containing the text of GetValidationText is displayed.
Validation is supported only for databases that use the Microsoft Jet database engine. The expression cannot
refer to user-defined functions, domain aggregate functions, SQL aggregate functions, or queries. A validation
rule for a CDaoTableDef object can refer to multiple fields in that object.
For example, for fields named hire_date and termination_date, a validation rule might be:

myTableDef.SetValidationRule(_T("termination_date > hire_date"));

For related information, see the topic "ValidationRule Property" in DAO Help.

CDaoTableDef::SetValidationText
Call this member function to set the exception text of a validation rule for a CDaoTableDef object with an
underlying base table supported by the Microsoft Jet database engine.

void SetValidationText(LPCTSTR lpszValidationText);

Parameters
lpszValidationText
A pointer to a string expression that specifies the text displayed if entered data is invalid.
Remarks
You cannot set the validation text of an attached table.
For related information, see the topic "ValidationText Property" in DAO Help.
See also
CObject Class
Hierarchy Chart
CDaoDatabase Class
CDaoRecordset Class
CDaoWorkspace Class
4/21/2020 • 29 minutes to read • Edit Online

Manages a named, password-protected database session from login to logoff, by a single user. DAO is
supported through Office 2013. DAO 3.6 is the final version, and it is considered obsolete.

Syntax
class CDaoWorkspace : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDaoWorkspace::CDaoWorkspace Constructs a workspace object. Afterwards, call Create or


Open .

Public Methods
NAME DESC RIP T IO N

CDaoWorkspace::Append Appends a newly created workspace to the database


engine's Workspaces collection.

CDaoWorkspace::BeginTrans Begins a new transaction, which applies to all databases


open in the workspace.

CDaoWorkspace::Close Closes the workspace and all of the objects it contains.


Pending transactions are rolled back.

CDaoWorkspace::CommitTrans Completes the current transaction and saves the changes.

CDaoWorkspace::CompactDatabase Compacts (or duplicates) a database.

CDaoWorkspace::Create Creates a new DAO workspace object.

CDaoWorkspace::GetDatabaseCount Returns the number of DAO database objects in the


workspace's Databases collection.

CDaoWorkspace::GetDatabaseInfo Returns information about a specified DAO database defined


in the workspace's Databases collection.

CDaoWorkspace::GetIniPath Returns the location of the Microsoft Jet database engine's


initialization settings in the Windows registry.

CDaoWorkspace::GetIsolateODBCTrans Returns a value that indicates whether multiple transactions


that involve the same ODBC data source are isolated via
forced multiple connections to the data source.
NAME DESC RIP T IO N

CDaoWorkspace::GetLoginTimeout Returns the number of seconds before an error occurs when


the user attempts to log in to an ODBC database.

CDaoWorkspace::GetName Returns the user-defined name for the workspace object.

CDaoWorkspace::GetUserName Returns the user name specified when the workspace was
created. This is the name of the workspace owner.

CDaoWorkspace::GetVersion Returns a string that contains the version of the database


engine associated with the workspace.

CDaoWorkspace::GetWorkspaceCount Returns the number of DAO workspace objects in the


database engine's Workspaces collection.

CDaoWorkspace::GetWorkspaceInfo Returns information about a specified DAO workspace


defined in the database engine's Workspaces collection.

CDaoWorkspace::Idle Allows the database engine to perform background tasks.

CDaoWorkspace::IsOpen Returns nonzero if the workspace is open.

CDaoWorkspace::Open Explicitly opens a workspace object associated with DAO's


default workspace.

CDaoWorkspace::RepairDatabase Attempts to repair a damaged database.

CDaoWorkspace::Rollback Ends the current transaction and does not save the changes.

CDaoWorkspace::SetDefaultPassword Sets the password that the database engine uses when a
workspace object is created without a specific password.

CDaoWorkspace::SetDefaultUser Sets the user name that the database engine uses when a
workspace object is created without a specific user name.

CDaoWorkspace::SetIniPath Sets the location of the Microsoft Jet database engine's


initialization settings in the Windows registry.

CDaoWorkspace::SetIsolateODBCTrans Specifies whether multiple transactions that involve the


same ODBC data source are isolated by forcing multiple
connections to the data source.

CDaoWorkspace::SetLoginTimeout Sets the number of seconds before an error occurs when the
user attempts to log in to an ODBC data source.

Public Data Members


NAME DESC RIP T IO N

CDaoWorkspace::m_pDAOWorkspace Points to the underlying DAO workspace object.

Remarks
In most cases, you will not need multiple workspaces, and you will not need to create explicit workspace objects;
when you open database and recordset objects, they use DAO's default workspace. However, if needed, you can
run multiple sessions at a time by creating additional workspace objects. Each workspace object can contain
multiple open database objects in its own Databases collection. In MFC, a workspace is primarily a transaction
manager, specifying a set of open databases all in the same "transaction space."

NOTE
The DAO database classes are distinct from the MFC database classes based on Open Database Connectivity (ODBC). All
DAO database class names have a "CDao" prefix. In general, the MFC classes based on DAO are more capable than the
MFC classes based on ODBC. The DAO-based classes access data through the Microsoft Jet database engine, including
ODBC drivers. They also support Data Definition Language (DDL) operations, such as creating databases and adding
tables and fields via the classes, without having to call DAO directly.

Capabilities
Class CDaoWorkspace provides the following:
Explicit access, if needed, to a default workspace, created by initializing the database engine. Usually you
use DAO's default workspace implicitly by creating database and recordset objects.
A transaction space in which transactions apply to all databases open in the workspace. You can create
additional workspaces to manage separate transaction spaces.
An interface to many properties of the underlying Microsoft Jet database engine (see the static member
functions). Opening or creating a workspace, or calling a static member function before open or create,
initializes the database engine.
Access to the database engine's Workspaces collection, which stores all active workspaces that have been
appended to it. You can also create and work with workspaces without appending them to the collection.

Security
MFC does not implement the Users and Groups collections in DAO, which are used for security control. If you
need those aspects of DAO, you must program them yourself via direct calls to DAO interfaces. For information,
see Technical Note 54.

Usage
You can use class CDaoWorkspace to:
Explicitly open the default workspace.
Usually your use of the default workspace is implicit — when you open new CDaoDatabase or
CDaoRecordset objects. But you might need to access it explicitly — for example, to access database
engine properties or the Workspaces collection. See "Implicit Use of the Default Workspace" below.
Create new workspaces. Call Append if you want to add them to the Workspaces collection.
Open an existing workspace in the Workspaces collection.
Creating a new workspace that does not already exist in the Workspaces collection is described under the
Create member function. Workspace objects do not persist in any way between datababase engine sessions. If
your application links MFC statically, ending the application uninitializes the database engine. If your application
links with MFC dynamically, the database engine is uninitialized when the MFC DLL is unloaded.
Explicitly opening the default workspace, or opening an existing workspace in the Workspaces collection, is
described under the Open member function.
End a workspace session by closing the workspace with the Close member function. Close closes any
databases you have not closed previously, rolling back any uncommitted transactions.

Transactions
DAO manages transactions at the workspace level; hence, transactions on a workspace with multiple open
databases apply to all of the databases. For example, if two databases have uncommitted updates and you call
CommitTrans, all of the updates are committed. If you want to limit transactions to a single database, you need
a separate workspace object for it.

Implicit Use of the Default Workspace


MFC uses DAO's default workspace implicitly under the following circumstances:
If you create a new CDaoDatabase object but do not do so through an existing CDaoWorkspace object, MFC
creates a temporary workspace object for you, which corresponds to DAO's default workspace. If you do
so for multiple databases, all of the database objects are associated with the default workspace. You can
access a database's workspace through a CDaoDatabase data member.
Similarly, if you create a CDaoRecordset object without supplying a pointer to a CDaoDatabase object,
MFC creates a temporary database object and, by extension, a temporary workspace object. You can
access a recordset's database, and indirectly its workspace, through a CDaoRecordset data member.

Other Operations
Other database operations are also provided, such as repairing a corrupted database or compacting a database.
For information about calling DAO directly and about DAO security, see Technical Note 54.

Inheritance Hierarchy
CObject
CDaoWorkspace

Requirements
Header : afxdao.h

CDaoWorkspace::Append
Call this member function after you call Create.

virtual void Append();

Remarks
Append appends a newly created workspace object to the database engine's Workspaces collection.
Workspaces do not persist between database engine sessions; they are stored only in memory, not on disk. You
do not have to append a workspace; if you do not, you can still use it.
An appended workspace remains in the Workspaces collection, in an active, open state, until you call its Close
member function.
For related information, see the topic "Append Method" in DAO Help.
CDaoWorkspace::BeginTrans
Call this member function to initiate a transaction.

void BeginTrans();

Remarks
After you call BeginTrans , updates you make to your data or database structure take effect when you commit
the transaction. Because the workspace defines a single transaction space, the transaction applies to all open
databases in the workspace. There are two ways to complete the transaction:
Call the CommitTrans member function to commit the transaction and save changes to the data source.
Or call the Rollback member function to cancel the transaction.
Closing the workspace object or a database object while a transaction is pending rolls back all pending
transactions.
If you need to isolate transactions on one ODBC data source from those on another ODBC data source, see the
SetIsolateODBCTrans member function.

CDaoWorkspace::CDaoWorkspace
Constructs a CDaoWorkspace object.

CDaoWorkspace();

Remarks
After constructing the C++ object, you have two options:
Call the object's Open member function to open the default workspace or to open an existing object in
the Workspaces collection.
Or call the object's Create member function to create a new DAO workspace object. This explicitly starts a
new workspace session, which you can refer to via the CDaoWorkspace object. After calling Create , you
can call Append if you want to add the workspace to the database engine's Workspaces collection.
See the class overview for CDaoWorkspace for information about when you need to explicitly create a
CDaoWorkspace object. Usually, you use workspaces created implicitly when you open a CDaoDatabase object
without specifying a workspace or when you open a CDaoRecordset object without specifying a database
object. MFC DAO objects created in this way use DAO's default workspace, which is created once and reused.
To release a workspace and its contained objects, call the workspace object's Close member function.

CDaoWorkspace::Close
Call this member function to close the workspace object.

virtual void Close();

Remarks
Closing an open workspace object releases the underlying DAO object and, if the workspace is a member of the
Workspaces collection, removes it from the collection. Calling Close is good programming practice.
Cau t i on

Closing a workspace object closes any open databases in the workspace. This results in any recordsets open in
the databases being closed as well, and any pending edits or updates are rolled back. For related information,
see the CDaoDatabase::Close, CDaoRecordset::Close, CDaoTableDef::Close, and CDaoQueryDef::Close member
functions.
Workspace objects are not permanent; they only exist while references to them exist. This means that when the
database engine session ends, the workspace and its Databases collection do not persist. You must re-create
them for the next session by opening your workspace and database(s) again.
For related information, see the topic "Close Method" in DAO Help.

CDaoWorkspace::CommitTrans
Call this member function to commit a transaction — save a group of edits and updates to one or more
databases in the workspace.

void CommitTrans();

Remarks
A transaction consists of a series of changes to the database's data or its structure, beginning with a call to
BeginTrans. When you complete the transaction, either commit it or roll it back (cancel the changes) with
Rollback. By default, without transactions, updates to records are committed immediately. Calling BeginTrans
causes commitment of updates to be delayed until you call CommitTrans .
Cau t i on

Within one workspace, transactions are always global to the workspace and are not limited to only one
database or recordset. If you perform operations on more than one database or recordset within a workspace
transaction, CommitTrans commits all pending updates, and Rollback restores all operations on those
databases and recordsets.
When you close a database or workspace with pending transactions, the transactions are all rolled back.

NOTE
This is not a two-phase commit mechanism. If one update fails to commit, others still will commit.

CDaoWorkspace::CompactDatabase
Call this member function to compact a specified Microsoft Jet (.MDB) database.

static void PASCAL CompactDatabase(


LPCTSTR lpszSrcName,
LPCTSTR lpszDestName,
LPCTSTR lpszLocale = dbLangGeneral,
int nOptions = 0);

static void PASCAL CompactDatabase(


LPCTSTR lpszSrcName,
LPCTSTR lpszDestName,
LPCTSTR lpszLocale,
int nOptions,
LPCTSTR lpszPassword);

Parameters
lpszSrcName
The name of an existing, closed database. It can be a full path and filename, such as "C:\\MYDB.MDB". If the
filename has an extension, you must specify it. If your network supports the uniform naming convention (UNC),
you can also specify a network path, such as "\\\\MYSERVER\\MYSHARE\\MYDIR\\MYDB.MDB". (Double
backslashes are required in the path strings because "\" is the C++ escape character.)
lpszDestName
The full path of the compacted database that you are creating. You can also specify a network path as with
lpszSrcName. You cannot use the lpszDestName argument to specify the same database file as lpszSrcName.
lpszPassword
A password, used when you want to compact a password-protected database. Note that if you use the version
of CompactDatabase that takes a password, you must supply all parameters. Also, because this is a connect
parameter, it requires special formatting, as follows: ;PWD= lpszPassword. For example: ;PWD="Happy". (The
leading semicolon is required.)
lpszLocale
A string expression used to specify collating order for creating lpszDestName. If you omit this argument by
accepting the default value of dbLangGeneral (see below), the locale of the new database is the same as that of
the old database. Possible values are:
dbLangGeneral English, German, French, Portuguese, Italian, and Modern Spanish
dbLangArabic Arabic
dbLangCyrillic Russian
dbLangCzech Czech
dbLangDutch Dutch
dbLangGreek Greek
dbLangHebrew Hebrew
dbLangHungarian Hungarian
dbLangIcelandic Icelandic
dbLangNordic Nordic languages (Microsoft Jet database engine version 1.0 only)
dbLangNorwdan Norwegian and Danish
dbLangPolish Polish
dbLangSpanish Traditional Spanish
dbLangSwedfin Swedish and Finnish
dbLangTurkish Turkish

nOptions
Indicates one or more options for the target database, lpszDestName. If you omit this argument by accepting
the default value, the lpszDestName will have the same encryption and the same version as lpszSrcName. You
can combine the dbEncrypt or dbDecrypt option with one of the version options using the bitwise-OR
operator. Possible values, which specify a database format, not a database engine version, are:
dbEncrypt Encrypt the database while compacting.
dbDecrypt Decrypt the database while compacting.
dbVersion10 Create a database that uses the Microsoft Jet database engine version 1.0 while
compacting.
dbVersion11 Create a database that uses the Microsoft Jet database engine version 1.1 while
compacting.
dbVersion20 Create a database that uses the Microsoft Jet database engine version 2.0 while
compacting.
dbVersion30 Create a database that uses the Microsoft Jet database engine version 3.0 while
compacting.
You can use dbEncrypt or dbDecrypt in the options argument to specify whether to encrypt or to decrypt the
database as it is compacted. If you omit an encryption constant or if you include both dbDecrypt and
dbEncrypt , lpszDestName will have the same encryption as lpszSrcName. You can use one of the version
constants in the options argument to specify the version of the data format for the compacted database. This
constant affects only the version of the data format of lpszDestName. You can specify only one version constant.
If you omit a version constant, lpszDestName will have the same version as lpszSrcName. You can compact
lpszDestName only to a version that is the same or later than that of lpszSrcName.
Cau t i on

If a database is not encrypted, it is possible, even if you implement user/password security, to directly read the
binary disk file that constitutes the database.
Remarks
As you change data in a database, the database file can become fragmented and use more disk space than
necessary. Periodically, you should compact your database to defragment the database file. The compacted
database is usually smaller. You can also choose to change the collating order, the encryption, or the version of
the data format while you copy and compact the database.
Cau t i on

The CompactDatabase member function will not correctly convert a complete Microsoft Access database from
one version to another. Only the data format is converted. Microsoft Access-defined objects, such as forms and
reports, are not converted. However, the data is correctly converted.

TIP
You can also use CompactDatabase to copy a database file.

For more information about compacting databases, see the topic "CompactDatabase Method" in DAO Help.

CDaoWorkspace::Create
Call this member function to create a new DAO workspace object and associate it with the MFC CDaoWorkspace
object.

virtual void Create(


LPCTSTR lpszName,
LPCTSTR lpszUserName,
LPCTSTR lpszPassword);

Parameters
lpszName
A string with up to 14 characters that uniquely names the new workspace object. You must supply a name. For
related information, see the topic "Name Property" in DAO Help.
lpszUserName
The user name of the workspace's owner. For requirements, see the lpszDefaultUser parameter to the
SetDefaultUser member function. For related information, see the topic "UserName Property" in DAO Help.
lpszPassword
The password for the new workspace object. A password can be up to 14 characters long and can contain any
character except ASCII 0 (null). Passwords are case-sensitive. For related information, see the topic "Password
Property" in DAO Help.
Remarks
The overall creation process is:
1. Construct a CDaoWorkspace object.
2. Call the object's Create member function to create the underlying DAO workspace. You must specify a
workspace name.
3. Optionally call Append if you want to add the workspace to the database engine's Workspaces collection.
You can work with the workspace without appending it.
After the Create call, the workspace object is in an open state, ready for use. You do not call Open after Create
. You do not call Create if the workspace already exists in the Workspaces collection. Create initializes the
database engine if it has not already been initialized for your application.

CDaoWorkspace::GetDatabaseCount
Call this member function to retrieve the number of DAO database objects in the workspace's Databases
collection — the number of open databases in the workspace.

short GetDatabaseCount();

Return Value
The number of open databases in the workspace.
Remarks
GetDatabaseCount is useful if you need to loop through all defined databases in the workspace's Databases
collection. To obtain information about a given database in the collection, see GetDatabaseInfo. Typical usage is
to call GetDatabaseCount for the number of open databases, then use that number as a loop index for repeated
calls to GetDatabaseInfo .

CDaoWorkspace::GetDatabaseInfo
Call this member function to obtain various kinds of information about a database open in the workspace.

void GetDatabaseInfo(
int nIndex,
CDaoDatabaseInfo& dbinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetDatabaseInfo(
LPCTSTR lpszName,
CDaoDatabaseInfo& dbinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index of the database object in the workspace's Databases collection, for lookup by index.
dbinfo
A reference to a CDaoDatabaseInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the database to retrieve. The available options are listed here
along with what they cause the function to return:
AFX_DAO_PRIMARY_INFO (Default) Name, Updatable, Transactions
AFX_DAO_SECONDARY_INFO Primary information plus: Version, Collating Order, Query Timeout
AFX_DAO_ALL_INFO Primary and secondary information plus: Connect
lpszName
The name of the database object, for lookup by name. The name is a string with up to 14 characters that
uniquely names the new workspace object.
Remarks
One version of the function lets you look up a database by index. The other version lets you look up a database
by name.
For a description of the information returned in dbinfo, see the CDaoDatabaseInfo structure. This structure has
members that correspond to the items of information listed above in the description of dwInfoOptions. When
you request information at one level, you get information for any prior levels as well.

CDaoWorkspace::GetIniPath
Call this member function to obtain the location of the Microsoft Jet database engine's initialization settings in
the Windows registry.

static CString PASCAL GetIniPath();

Return Value
A CString containing the registry location.
Remarks
You can use the location to obtain information about settings for the database engine. The information returned
is actually the name of a registry subkey.
For related information, see the topics "IniPath Property" and "Customizing Windows Registry Settings for Data
Access" in DAO Help.

CDaoWorkspace::GetIsolateODBCTrans
Call this member function to get the current value of the DAO IsolateODBCTrans property for the workspace.

BOOL GetIsolateODBCTrans();

Return Value
Nonzero if ODBC transactions are isolated; otherwise 0.
Remarks
In some situations, you might need to have multiple simultaneous transactions pending on the same ODBC
database. To do this, you need to open a separate workspace for each transaction. Keep in mind that although
each workspace can have its own ODBC connection to the database, this slows system performance. Because
transaction isolation is not normally required, ODBC connections from multiple workspace objects opened by
the same user are shared by default.
Some ODBC servers, such as Microsoft SQL Server, do not allow simultaneous transactions on a single
connection. If you need to have more than one transaction at a time pending against such a database, set the
IsolateODBCTrans property to TRUE on each workspace as soon as you open it. This forces a separate ODBC
connection for each workspace.
For related information, see the topic "IsolateODBCTrans Property" in DAO Help.

CDaoWorkspace::GetLoginTimeout
Call this member function to get the current value of the DAO LoginTimeout property for the workspace.

static short PASCAL GetLoginTimeout();

Return Value
The number of seconds before an error occurs when you attempt to log in to an ODBC database.
Remarks
This value represents the number of seconds before an error occurs when you attempt to log in to an ODBC
database. The default LoginTimeout setting is 20 seconds. When LoginTimeout is set to 0, no timeout occurs
and the communication with the data source might stop responding.
When you are attempting to log in to an ODBC database, such as Microsoft SQL Server, the connection may fail
as a result of network errors or because the server is not running. Rather than waiting for the default 20
seconds to connect, you can specify how long the database engine waits before it produces an error. Logging in
to the server happens implicitly as part of a number of different events, such as running a query on an external
server database.
For related information, see the topic "LoginTimeout Property" in DAO Help.

CDaoWorkspace::GetName
Call this member function to get the user-defined name of the DAO workspace object underlying the
CDaoWorkspace object.

CString GetName();

Return Value
A CString containing the user-defined name of the DAO workspace object.
Remarks
The name is useful for accessing the DAO workspace object in the database engine's Workspaces collection by
name.
For related information, see the topic "Name Property" in DAO Help.

CDaoWorkspace::GetUserName
Call this member function to obtain the name of the owner of the workspace.
CString GetUserName();

Return Value
A CString that represents the owner of the workspace object.
Remarks
To get or set the permissions for the workspace owner, call DAO directly to check the Permissions property
setting; this determines what permissions that user has. To work with permissions, you need a SYSTEM.MDA
file.
For information about calling DAO directly, see Technical Note 54. For related information, see the topic
"UserName Property" in DAO Help.

CDaoWorkspace::GetVersion
Call this member function to determine the version of the Microsoft Jet database engine in use.

static CString PASCAL GetVersion();

Return Value
A CString that indicates the version of the database engine associated with the object.
Remarks
The value returned represents the version number in the form "major.minor"; for example, "3.0". The product
version number (for example, 3.0) consists of the version number (3), a period, and the release number (0).
For related information, see the topic "Version Property" in DAO Help.

CDaoWorkspace::GetWorkspaceCount
Call this member function to retrieve the number of DAO workspace objects in the database engine's
Workspaces collection.

short GetWorkspaceCount();

Return Value
The number of open workspaces in the Workspaces collection.
Remarks
This count does not include any open workspaces not appended to the collection. GetWorkspaceCount is useful if
you need to loop through all defined workspaces in the Workspaces collection. To obtain information about a
given workspace in the collection, see GetWorkspaceInfo. Typical usage is to call GetWorkspaceCount for the
number of open workspaces, then use that number as a loop index for repeated calls to GetWorkspaceInfo .

CDaoWorkspace::GetWorkspaceInfo
Call this member function to obtain various kinds of information about a workspace open in the session.
void GetWorkspaceInfo(
int nIndex,
CDaoWorkspaceInfo& wkspcinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

void GetWorkspaceInfo(
LPCTSTR lpszName,
CDaoWorkspaceInfo& wkspcinfo,
DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);

Parameters
nIndex
The zero-based index of the database object in the Workspaces collection, for lookup by index.
wkspcinfo
A reference to a CDaoWorkspaceInfo object that returns the information requested.
dwInfoOptions
Options that specify which information about the workspace to retrieve. The available options are listed here
along with what they cause the function to return:
AFX_DAO_PRIMARY_INFO (Default) Name
AFX_DAO_SECONDARY_INFO Primary information plus: User Name
AFX_DAO_ALL_INFO Primary and secondary information plus: Isolate ODBCTrans
lpszName
The name of the workspace object, for lookup by name. The name is a string with up to 14 characters that
uniquely names the new workspace object.
Remarks
For a description of the information returned in wkspcinfo, see the CDaoWorkspaceInfo structure. This structure
has members that correspond to the items of information listed above in the description of dwInfoOptions.
When you request information at one level, you get information for prior levels as well.

CDaoWorkspace::Idle
Call Idle to provide the database engine with the opportunity to perform background tasks that may not be
up-to-date because of intense data processing.

static void PASCAL Idle(int nAction = dbFreeLocks);

Parameters
nAction
An action to take during the idle processing. Currently the only valid action is dbFreeLocks .
Remarks
This is often true in multiuser, multitasking environments in which there is not enough background processing
time to keep all records in a recordset current.

NOTE
Calling Idle is not necessary with databases created with version 3.0 of the Microsoft Jet database engine. Use Idle
only for databases created with earlier versions.
Usually, read locks are removed and data in local dynaset-type recordset objects is updated only when no other
actions (including mouse movements) are occurring. If you periodically call Idle , you provide the database
engine with time to catch up on background processing tasks by releasing unneeded read locks. Specifying the
dbFreeLocks constant as an argument delays processing until all read locks are released.

This member function is not needed in single-user environments unless multiple instances of an application are
running. The Idle member function may increase performance in a multiuser environment because it forces
the database engine to flush data to disk, releasing locks on memory. You can also release read locks by making
operations part of a transaction.
For related information, see the topic "Idle Method" in DAO Help.

CDaoWorkspace::IsOpen
Call this member function to determine whether the CDaoWorkspace object is open — that is, whether the MFC
object has been initialized by a call to Open or a call to Create.

BOOL IsOpen() const;

Return Value
Nonzero if the workspace object is open; otherwise 0.
Remarks
You can call any of the member functions of a workspace that is in an open state.

CDaoWorkspace::m_pDAOWorkspace
A pointer to the underlying DAO workspace object.
Remarks
Use this data member if you need direct access to the underlying DAO object. You can call the DAO object's
interfaces through this pointer.
For information about accessing DAO objects directly, see Technical Note 54.

CDaoWorkspace::Open
Explicitly opens a workspace object associated with DAO's default workspace.

virtual void Open(LPCTSTR lpszName = NULL);

Parameters
lpszName
The name of the DAO workspace object to open — a string with up to 14 characters that uniquely names the
workspace. Accept the default value NULL to explicitly open the default workspace. For naming requirements,
see the lpszName parameter for Create. For related information, see the topic "Name Property" in DAO Help.
Remarks
After constructing a CDaoWorkspace object, call this member function to do one of the following:
Explicitly open the default workspace. Pass NULL for lpszName.
Open an existing CDaoWorkspace object, a member of the Workspaces collection, by name. Pass a valid
name for an existing workspace object.
Open puts the workspace object into an open state and also initializes the database engine if it has not already
been initialized for your application.
Although many CDaoWorkspace member functions can only be called after the workspace has been opened, the
following member functions, which operate on the database engine, are available after construction of the C++
object but before a call to Open :

Create GetVersion SetDefaultUser

GetIniPath Idle SetIniPath

GetLoginTimeout SetDefaultPassword SetLoginTimeout

CDaoWorkspace::RepairDatabase
Call this member function if you need to attempt to repair a corrupted database that accesses the Microsoft Jet
database engine.

static void PASCAL RepairDatabase(LPCTSTR lpszName);

Parameters
lpszName
The path and filename for an existing Microsoft Jet engine database file. If you omit the path, only the current
directory is searched. If your system supports the uniform naming convention (UNC), you can also specify a
network path, such as: "\\\\MYSERVER\\MYSHARE\\MYDIR\\MYDB.MDB". (Double backslashes are required in
the path string because "\" is the C++ escape character.)
Remarks
You must close the database specified by lpszName before you repair it. In a multiuser environment, other users
cannot have lpszName open while you are repairing it. If lpszName is not closed or is not available for exclusive
use, an error occurs.
This member function attempts to repair a database that was marked as possibly corrupt by an incomplete
write operation. This can occur if an application using the Microsoft Jet database engine is closed unexpectedly
because of a power outage or computer hardware problem. If you complete the operation and call the Close
member function or you quit the application in a usual way, the database will not be marked as possibly
corrupt.

NOTE
After repairing a database, it is also a good idea to compact it using the CompactDatabase member function to
defragment the file and to recover disk space.

For more information about repairing databases, see the topic "RepairDatabase Method" in DAO Help.

CDaoWorkspace::Rollback
Call this member function to end the current transaction and restore all databases in the workspace to their
condition before the transaction was begun.
void Rollback();

Remarks
Cau t i on

Within one workspace object, transactions are always global to the workspace and are not limited to only one
database or recordset. If you perform operations on more than one database or recordset within a workspace
transaction, Rollback restores all operations on all of those databases and recordsets.
If you close a workspace object without saving or rolling back any pending transactions, the transactions are
automatically rolled back. If you call CommitTrans or Rollback without first calling BeginTrans, an error occurs.

NOTE
When you begin a transaction, the database engine records its operations in a file kept in the directory specified by the
TEMP environment variable on the workstation. If the transaction log file exhausts the available storage on your TEMP
drive, the database engine will cause MFC to throw a CDaoException (DAO error 2004). At this point, if you call
CommitTrans , an indeterminate number of operations are committed but the remaining uncompleted operations are
lost, and the operation has to be restarted. Calling Rollback releases the transaction log and rolls back all operations in
the transaction.

CDaoWorkspace::SetDefaultPassword
Call this member function to set the default password that the database engine uses when a workspace object
is created without a specific password.

static void PASCAL SetDefaultPassword(LPCTSTR lpszPassword);

Parameters
lpszPassword
The default password. A password can be up to 14 characters long and can contain any character except ASCII 0
(null). Passwords are case-sensitive.
Remarks
The default password that you set applies to new workspaces you create after the call. When you create
subsequent workspaces, you do not need to specify a password in the Create call.
To use this member function:
1. Construct a CDaoWorkspace object but do not call Create .
2. Call SetDefaultPassword and, if you like, SetDefaultUser.
3. Call Create for this workspace object or subsequent ones, without specifying a password.
By default, the DefaultUser property is set to "admin" and the DefaultPassword property is set to an empty
string ("").
For more about security, see the topic "Permissions Property" in DAO Help. For related information, see the
topics "DefaultPassword Property" and "DefaultUser Property" in DAO Help.

CDaoWorkspace::SetDefaultUser
Call this member function to set the default user name that the database engine uses when a workspace object
is created without a specific user name.
static void PASCAL SetDefaultUser(LPCTSTR lpszDefaultUser);

Parameters
lpszDefaultUser
The default user name. A user name can be 1 - 20 characters long and include alphabetic characters, accented
characters, numbers, spaces, and symbols except for: " (quotation marks), / (forward slash), \ (backslash), [ ]
(brackets), : (colon), | (pipe), < (less-than sign), > (greater-than sign), + (plus sign), = (equal sign), ; (semicolon), ,
( comma), (question mark), * (asterisk), leading spaces, and control characters (ASCII 00 to ASCII 31). For related
information, see the topic "UserName Property" in DAO Help.
Remarks
The default user name that you set applies to new workspaces you create after the call. When you create
subsequent workspaces, you do not need to specify a user name in the Create call.
To use this member function:
1. Construct a CDaoWorkspace object but do not call Create .
2. Call SetDefaultUser and, if you like, SetDefaultPassword.
3. Call Create for this workspace object or subsequent ones, without specifying a user name.

By default, the DefaultUser property is set to "admin" and the DefaultPassword property is set to an empty
string ("").
For related information, see the topics "DefaultUser Property" and "DefaultPassword Property" in DAO Help.

CDaoWorkspace::SetIniPath
Call this member function to specify the location of Windows registry settings for the Microsoft Jet database
engine.

static void PASCAL SetIniPath(LPCTSTR lpszRegistrySubKey);

Parameters
lpszRegistrySubkey
A string containing the name of a Windows registry subkey for the location of Microsoft Jet database engine
settings or parameters needed for installable ISAM databases.
Remarks
Call SetIniPath only if you need to specify special settings. For more information, see the topic "IniPath
Property" in DAO Help.

NOTE
Call SetIniPath during application installation, not when the application runs. SetIniPath must be called before you
open any workspaces, databases, or recordsets; otherwise, MFC throws an exception.

You can use this mechanism to configure the database engine with user-provided registry settings. The scope of
this attribute is limited to your application and cannot be changed without restarting your application.

CDaoWorkspace::SetIsolateODBCTrans
Call this member function to set the value of the DAO IsolateODBCTrans property for the workspace.

void SetIsolateODBCTrans(BOOL bIsolateODBCTrans);

Parameters
bIsolateODBCTrans
Pass TRUE if you want to begin isolating ODBC transactions. Pass FALSE if you want to stop isolating ODBC
transactions.
Remarks
In some situations, you might need to have multiple simultaneous transactions pending on the same ODBC
database. To do this, you need to open a separate workspace for each transaction. Although each workspace can
have its own ODBC connection to the database, this slows system performance. Because transaction isolation is
not normally required, ODBC connections from multiple workspace objects opened by the same user are
shared by default.
Some ODBC servers, such as Microsoft SQL Server, do not allow simultaneous transactions on a single
connection. If you need to have more than one transaction at a time pending against such a database, set the
IsolateODBCTrans property to TRUE on each workspace as soon as you open it. This forces a separate ODBC
connection for each workspace.

CDaoWorkspace::SetLoginTimeout
Call this member function to set the value of the DAO LoginTimeout property for the workspace.

static void PASCAL SetLoginTimeout(short nSeconds);

Parameters
nSeconds
The number of seconds before an error occurs when you attempt to log in to an ODBC database.
Remarks
This value represents the number of seconds before an error occurs when you attempt to log in to an ODBC
database. The default LoginTimeout setting is 20 seconds. When LoginTimeout is set to 0, no timeout occurs
and the communication with the data source might stop responding.
When you are attempting to log in to an ODBC database, such as Microsoft SQL Server, the connection may fail
as a result of network errors or because the server is not running. Rather than waiting for the default 20
seconds to connect, you can specify how long the database engine waits before it produces an error. Logging on
to the server happens implicitly as part of a number of different events, such as running a query on an external
server database. The timeout value is determined by the current setting of the LoginTimeout property.
For related information, see the topic "LoginTimeout Property" in DAO Help.

See also
CObject Class
Hierarchy Chart
CDaoDatabase Class
CDaoRecordset Class
CDaoTableDef Class
CDaoQueryDef Class
CDaoException Class
CDatabase Class
4/21/2020 • 21 minutes to read • Edit Online

Represents a connection to a data source, through which you can operate on the data source.

Syntax
class CDatabase : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDatabase::CDatabase Constructs a CDatabase object. You must initialize the


object by calling OpenEx or Open .

Public Methods
NAME DESC RIP T IO N

CDatabase::BeginTrans Starts a "transaction" — a series of reversible calls to the


AddNew , Edit , Delete , and Update member functions
of class CRecordset — on the connected data source. The
data source must support transactions for BeginTrans to
have any effect.

CDatabase::BindParameters Allows you to bind parameters before calling


CDatabase::ExecuteSQL .

CDatabase::Cancel Cancels an asynchronous operation or a process from a


second thread.

CDatabase::CanTransact Returns nonzero if the data source supports transactions.

CDatabase::CanUpdate Returns nonzero if the CDatabase object is updatable (not


read-only).

CDatabase::Close Closes the data source connection.

CDatabase::CommitTrans Completes a transaction begun by BeginTrans . Commands


in the transaction that alter the data source are carried out.

CDatabase::ExecuteSQL Executes a SQL statement. No data records are returned.

CDatabase::GetBookmarkPersistence Identifies the operations through which bookmarks persist


on recordset objects.
NAME DESC RIP T IO N

CDatabase::GetConnect Returns the ODBC connection string used to connect the


CDatabase object to a data source.

CDatabase::GetCursorCommitBehavior Identifies the effect of committing a transaction on an open


recordset object.

CDatabase::GetCursorRollbackBehavior Identifies the effect of rolling back a transaction on an open


recordset object.

CDatabase::GetDatabaseName Returns the name of the database currently in use.

CDatabase::IsOpen Returns nonzero if the CDatabase object is currently


connected to a data source.

CDatabase::OnSetOptions Called by the framework to set standard connection options.


The default implementation sets the query timeout value.
You can establish these options ahead of time by calling
SetQueryTimeout .

CDatabase::Open Establishes a connection to a data source (through an ODBC


driver).

CDatabase::OpenEx Establishes a connection to a data source (through an ODBC


driver).

CDatabase::Rollback Reverses changes made during the current transaction. The


data source returns to its previous state, as defined at the
BeginTrans call, unaltered.

CDatabase::SetLoginTimeout Sets the number of seconds after which a data source


connection attempt will time out.

CDatabase::SetQueryTimeout Sets the number of seconds after which database query


operations will time out. Affects all subsequent recordset
Open , AddNew , Edit , and Delete calls.

Public Data Members


NAME DESC RIP T IO N

CDatabase::m_hdbc Open Database Connectivity (ODBC) connection handle to a


data source. Type HDBC.

Remarks
A data source is a specific instance of data hosted by some database management system (DBMS). Examples
include Microsoft SQL Server, Microsoft Access, Borland dBASE, and xBASE. You can have one or more CDatabase
objects active at a time in your application.
NOTE
If you are working with the Data Access Objects (DAO) classes rather than the Open Database Connectivity (ODBC) classes,
use class CDaoDatabase instead. For more information, see the article Overview: Database Programming.

To use CDatabase , construct a CDatabase object and call its OpenEx member function. This opens a connection.
When you then construct CRecordset objects for operating on the connected data source, pass the recordset
constructor a pointer to your CDatabase object. When you finish using the connection, call the Close member
function and destroy the CDatabase object. Close closes any recordsets you have not closed previously.
For more information about CDatabase , see the articles Data Source (ODBC) and Overview: Database
Programming.

Inheritance Hierarchy
CObject
CDatabase

Requirements
Header : afxdb.h

CDatabase::BeginTrans
Call this member function to begin a transaction with the connected data source.

BOOL BeginTrans();

Return Value
Nonzero if the call was successful and changes are committed only manually; otherwise 0.
Remarks
A transaction consists of one or more calls to the AddNew , Edit , Delete , and Update member functions of a
CRecordset object. Before beginning a transaction, the CDatabase object must already have been connected to
the data source by calling its OpenEx or Open member function. To end the transaction, call CommitTrans to
accept all changes to the data source (and carry them out) or call Rollback to abort the entire transaction. Call
BeginTrans after you open any recordsets involved in the transaction and as close to the actual update
operations as possible.
Cau t i on

Depending on your ODBC driver, opening a recordset before calling BeginTrans may cause problems when
calling Rollback . You should check the specific driver you are using. For example, when using the Microsoft
Access driver included in the Microsoft ODBC Desktop Driver Pack 3.0, you must account for the Jet database
engine's requirement that you should not begin a transaction on any database that has an open cursor. In the
MFC database classes, an open cursor means an open CRecordset object. For more information, see Technical
Note 68.
BeginTrans may also lock data records on the server, depending on the requested concurrency and the
capabilities of the data source. For information about locking data, see the article Recordset: Locking Records
(ODBC).
User-defined transactions are explained in the article Transaction (ODBC).
BeginTrans establishes the state to which the sequence of transactions can be rolled back (reversed). To establish
a new state for rollbacks, commit any current transaction, then call BeginTrans again.
Cau t i on

Calling BeginTrans again without calling CommitTrans or Rollback is an error.


Call the CanTransact member function to determine whether your driver supports transactions for a given
database. You should also call GetCursorCommitBehavior and GetCursorRollbackBehavior to determine the
support for cursor preservation.
For more information about transactions, see the article Transaction (ODBC).
Example
See the article Transaction: Performing a Transaction in a Recordset (ODBC).

CDatabase::BindParameters
Override BindParameters when you need to bind parameters before calling CDatabase::ExecuteSQL.

virtual void BindParameters(HSTMT hstmt);

Parameters
hstmt
The ODBC statement handle for which you want to bind parameters.
Remarks
This approach is useful when you do not need the result set from a stored procedure.
In your override, call SQLBindParameters and related ODBC functions to bind the parameters. MFC calls your
override before your call to ExecuteSQL . You do not need to call SQLPrepare ; ExecuteSQL calls SQLExecDirect
and destroys the hstmt, which is used only once.

CDatabase::Cancel
Call this member function to request that the data source cancel either an asynchronous operation in progress or
a process from a second thread.

void Cancel();

Remarks
Note that the MFC ODBC classes no longer use asynchronous processing; to perform an asynchronous operation,
you must directly call the ODBC API function SQLSetConnectOption. For more information, see Asynchronous
Execution.

CDatabase::CanTransact
Call this member function to determine whether the database allows transactions.

BOOL CanTransact() const;

Return Value
Nonzero if recordsets using this CDatabase object allow transactions; otherwise 0.
Remarks
For information about transactions, see the article Transaction (ODBC).

CDatabase::CanUpdate
Call this member function to determine whether the CDatabase object allows updates.

BOOL CanUpdate() const;

Return Value
Nonzero if the CDatabase object allows updates; otherwise 0, indicating either that you passed TRUE in
bReadOnly when you opened the CDatabase object or that the data source itself is read-only. The data source is
read-only if a call to the ODBC API function SQLGetInfo for SQL_DATASOURCE_READ_ONLY returns "y".
Remarks
Not all drivers support updates.

CDatabase::CDatabase
Constructs a CDatabase object.

CDatabase();

Remarks
After constructing the object, you must call its OpenEx or Open member function to establish a connection to a
specified data source.
You may find it convenient to embed the CDatabase object in your document class.
Example
This example illustrates using CDatabase in a CDocument -derived class.

// This fragment is taken from the declaration for CMyDatabaseDoc


// CMyDatabaseDoc is derived from CDocument.
public:
// Declare a CDatabase embedded in the document
CDatabase m_dbCust;

// Initialize when needed


CDatabase *CMyDatabaseDoc::GetDatabase()
{
// Connect the object to a data source
if (!m_dbCust.IsOpen() && !m_dbCust.OpenEx(NULL))
return NULL;

return &m_dbCust;
}

CDatabase::Close
Call this member function if you want to disconnect from a data source.
virtual void Close();

Remarks
You must close any recordsets associated with the CDatabase object before you call this member function.
Because Close does not destroy the CDatabase object, you can reuse the object by opening a new connection to
the same data source or a different data source.
All pending AddNew or Edit statements of recordsets using the database are canceled, and all pending
transactions are rolled back. Any recordsets dependent on the CDatabase object are left in an undefined state.
Example

// Close the current connection


m_dbCust.Close();

// Perhaps connect the object to a


// different data source
m_dbCust.OpenEx(_T("DSN=MFC_ODBCTest;UID=JOES"));

CDatabase::CommitTrans
Call this member function upon completing transactions.

BOOL CommitTrans();

Return Value
Nonzero if the updates were successfully committed; otherwise 0. If CommitTrans fails, the state of the data
source is undefined. You must check the data to determine its state.
Remarks
A transaction consists of a series of calls to the AddNew , Edit , Delete , and Update member functions of a
CRecordset object that began with a call to the BeginTrans member function. CommitTrans commits the
transaction. By default, updates are committed immediately; calling BeginTrans causes commitment of updates
to be delayed until CommitTrans is called.
Until you call CommitTrans to end a transaction, you can call the Rollback member function to abort the
transaction and leave the data source in its original state. To begin a new transaction, call BeginTrans again.
For more information about transactions, see the article Transaction (ODBC).
Example
See the article Transaction: Performing a Transaction in a Recordset (ODBC).

CDatabase::ExecuteSQL
Call this member function when you need to execute a SQL command directly.

void ExecuteSQL(LPCTSTR lpszSQL);

Parameters
lpszSQL
Pointer to a null-terminated string containing a valid SQL command to execute. You can pass a CString.
Remarks
Create the command as a null-terminated string. ExecuteSQL does not return data records. If you want to operate
on records, use a recordset object instead.
Most of your commands for a data source are issued through recordset objects, which support commands for
selecting data, inserting new records, deleting records, and editing records. However, not all ODBC functionality is
directly supported by the database classes, so you may at times need to make a direct SQL call with ExecuteSQL .
Example

try
{
m_dbCust.ExecuteSQL(
_T("UPDATE Taxes ")
_T("SET Rate = '36' ")
_T("WHERE Name = 'Federal'"));
}
catch (CDBException *pe)
{
// The error code is in pe->m_nRetCode
pe->ReportError();
pe->Delete();
}

CDatabase::GetBookmarkPersistence
Call this member function to determine the persistence of bookmarks on a recordset object after certain
operations.

DWORD GetBookmarkPersistence() const;

Return Value
A bitmask that identifies the operations through which bookmarks persist on a recordset object. For details, see
Remarks.
Remarks
For example, if you call CRecordset::GetBookmark and then call CRecordset::Requery , the bookmark obtained from
GetBookmark may no longer be valid. You should call GetBookmarkPersistence before calling
CRecordset::SetBookmark .

The following table lists the bitmask values that can be combined for the return value of GetBookmarkPersistence .

B IT M A SK VA L UE B O O K M A RK P ERSIST EN C E

SQL_BP_CLOSE Bookmarks are valid after a Requery operation.

SQL_BP_DELETE The bookmark for a row is valid after a Delete operation on


that row.

SQL_BP_DROP Bookmarks are valid after a Close operation.

SQL_BP_SCROLL Bookmarks are valid after any Move operation. This simply
identifies if bookmarks are supported on the recordset, as
returned by CRecordset::CanBookmark .
B IT M A SK VA L UE B O O K M A RK P ERSIST EN C E

SQL_BP_TRANSACTION Bookmarks are valid after a transaction is committed or rolled


back.

SQL_BP_UPDATE The bookmark for a row is valid after an Update operation


on that row.

SQL_BP_OTHER_HSTMT Bookmarks associated with one recordset object are valid on


a second recordset.

For more information about this return value, see the ODBC API function SQLGetInfo in the Windows SDK. For
more information about bookmarks, see the article Recordset: Bookmarks and Absolute Positions (ODBC).

CDatabase::GetConnect
Call this member function to retrieve the connection string used during the call to OpenEx or Open that
connected the CDatabase object to a data source.

const CString GetConnect() const;

Return Value
A const CString containing the connection string if OpenEx or Open has been called; otherwise, an empty string.
Remarks
See CDatabase::Open for a description of how the connection string is created.

CDatabase::GetCursorCommitBehavior
Call this member function to determine how a CommitTrans operation affects cursors on open recordset objects.

int GetCursorCommitBehavior() const;

Return Value
A value indicating the effect of transactions on open recordset objects. For details, see Remarks.
Remarks
The following table lists the possible return values for GetCursorCommitBehavior and the corresponding effect on
the open recordset.

RET URN VA L UE EF F EC T O N C REC O RDSET O B JEC T S

SQL_CB_CLOSE Call CRecordset::Requery immediately following the


transaction commit.

SQL_CB_DELETE Call CRecordset::Close immediately following the


transaction commit.

SQL_CB_PRESERVE Proceed normally with CRecordset operations.

For more information about this return value, see the ODBC API function SQLGetInfo in the Windows SDK. For
more information about transactions, see the article Transaction (ODBC).
CDatabase::GetCursorRollbackBehavior
Call this member function to determine how a Rollback operation affects cursors on open recordset objects.

int GetCursorRollbackBehavior() const;

Return Value
A value indicating the effect of transactions on open recordset objects. For details, see Remarks.
Remarks
The following table lists the possible return values for GetCursorRollbackBehavior and the corresponding effect
on the open recordset.

RET URN VA L UE EF F EC T O N C REC O RDSET O B JEC T S

SQL_CB_CLOSE Call CRecordset::Requery immediately following the


transaction rollback.

SQL_CB_DELETE Call CRecordset::Close immediately following the


transaction rollback.

SQL_CB_PRESERVE Proceed normally with CRecordset operations.

For more information about this return value, see the ODBC API function SQLGetInfo in the Windows SDK. For
more information about transactions, see the article Transaction (ODBC).

CDatabase::GetDatabaseName
Call this member function to retrieve the name of the currently connected database (provided that the data
source defines a named object called "database").

CString GetDatabaseName() const;

Return Value
A CString containing the database name if successful; otherwise, an empty CString .
Remarks
This is not the same as the data source name (DSN) specified in the OpenEx or Open call. What GetDatabaseName
returns depends on ODBC. In general, a database is a collection of tables. If this entity has a name,
GetDatabaseName returns it.

You might, for example, want to display this name in a heading. If an error occurs while retrieving the name from
ODBC, GetDatabaseName returns an empty CString .

CDatabase::IsOpen
Call this member function to determine whether the CDatabase object is currently connected to a data source.

BOOL IsOpen() const;

Return Value
Nonzero if the CDatabase object is currently connected; otherwise 0.

CDatabase::m_hdbc
Contains a public handle to an ODBC data source connection — a "connection handle."
Remarks
Normally, you will have no need to access this member variable directly. Instead, the framework allocates the
handle when you call OpenEx or Open . The framework deallocates the handle when you call the delete operator
on the CDatabase object. Note that the Close member function does not deallocate the handle.
Under some circumstances, however, you may need to use the handle directly. For example, if you need to call
ODBC API functions directly rather than through class CDatabase , you may need a connection handle to pass as a
parameter. See the code example below.
Example

// Using m_hdbc for a direct ODBC API call.


// m_dbCust is the CDatabase object; m_hdbc is
// its HDBC member variable
nRetCode = ::SQLGetInfo(m_dbCust.m_hdbc, SQL_ODBC_SQL_CONFORMANCE,
&nValue, sizeof(nValue), &cbValue);

CDatabase::OnSetOptions
The framework calls this member function when directly executing a SQL statement with the ExecuteSQL
member function.

virtual void OnSetOptions(HSTMT hstmt);

Parameters
hstmt
The ODBC statement handle for which options are being set.
Remarks
CRecordset::OnSetOptions also calls this member function.
OnSetOptions sets the login timeout value. If there have been previous calls to the SetQueryTimeout and member
function, OnSetOptions reflects the current values; otherwise, it sets default values.

NOTE
Prior to MFC 4.2, OnSetOptions also set the processing mode to either snychronous or asynchronous. Beginning with
MFC 4.2, all operations are synchronous. To perform an asynchronous operation, you must make a direct call to the ODBC
API function SQLSetPos .

You do not need to override OnSetOptions to change the timeout value. Instead, to customize the query timeout
value, call SetQueryTimeout before creating a recordset; OnSetOptions will use the new value. The values set apply
to subsequent operations on all recordsets or direct SQL calls.
Override OnSetOptions if you want to set additional options. Your override should call the base class
OnSetOptions either before or after you call the ODBC API function SQLSetStmtOption . Follow the method
illustrated in the framework's default implementation of OnSetOptions .
CDatabase::Open
Call this member function to initialize a newly constructed CDatabase object.

virtual BOOL Open(


LPCTSTR lpszDSN,
BOOL bExclusive = FALSE,
BOOL bReadOnly = FALSE,
LPCTSTR lpszConnect = _T("ODBC;"),
BOOL bUseCursorLib = TRUE);

Parameters
lpszDSN
Specifies a data source name — a name registered with ODBC through the ODBC Administrator program. If a
DSN value is specified in lpszConnect (in the form "DSN=<data-source>"), it must not be specified again in
lpszDSN. In this case, lpszDSN should be NULL. Otherwise, you can pass NULL if you want to present the user
with a Data Source dialog box in which the user can select a data source. For further information, see Remarks.
bExclusive
Not supported in this version of the class library. Currently, an assertion fails if this parameter is TRUE. The data
source is always opened as shared (not exclusive).
bReadOnly
TRUE if you intend the connection to be read-only and to prohibit updates to the data source. All dependent
recordsets inherit this attribute. The default value is FALSE.
lpszConnect
Specifies a connection string. The connection string concatenates information, possibly including a data source
name, a user ID valid on the data source, a user authentication string (password, if the data source requires one),
and other information. The whole connection string must be prefixed by the string "ODBC;" (uppercase or
lowercase). The "ODBC;" string is used to indicate that the connection is to an ODBC data source; this is for
upward compatibility when future versions of the class library might support non-ODBC data sources.
bUseCursorLib
TRUE if you want the ODBC Cursor Library DLL to be loaded. The cursor library masks some functionality of the
underlying ODBC driver, effectively preventing the use of dynasets (if the driver supports them). The only cursors
supported if the cursor library is loaded are static snapshots and forward-only cursors. The default value is TRUE.
If you plan to create a recordset object directly from CRecordset without deriving from it, you should not load the
cursor library.
Return Value
Nonzero if the connection is successfully made; otherwise 0 if the user chooses Cancel when presented a dialog
box asking for more connection information. In all other cases, the framework throws an exception.
Remarks
Your database object must be initialized before you can use it to construct a recordset object.

NOTE
Calling the OpenEx member function is the preferred way to connect to a data source and initialize your database object.

If the parameters in your Open call do not contain enough information to make the connection, the ODBC driver
opens a dialog box to obtain the necessary information from the user. When you call Open , your connection
string, lpszConnect, is stored privately in the CDatabase object and is available by calling the GetConnect member
function.
If you wish, you can open your own dialog box before you call Open to get information from the user, such as a
password, then add that information to the connection string you pass to Open . Or you might want to save the
connection string you pass so you can reuse it the next time your application calls Open on a CDatabase object.
You can also use the connection string for multiple levels of login authorization (each for a different CDatabase
object) or to convey other data source-specific information. For more information about connection strings, see
Chapter 5 in the Windows SDK.
It is possible for a connection attempt to time out if, for example, the DBMS host is unavailable. If the connection
attempt fails, Open throws a CDBException .
Example

// m_dbCust is a CDatabase object embedded in a CDocument class

if (bDefault)
{
// Connect the object to a data source (no password)
// the ODBC connection dialog box will always remain hidden
m_dbCust.Open(_T("MFC_ODBCTest"), FALSE, FALSE, _T("ODBC;UID=JOES"));
}
else
{
// ...Or, query the user for all connection information
m_dbCust.Open(NULL);
}

CDatabase::OpenEx
Call this member function to initialize a newly constructed CDatabase object.

virtual BOOL OpenEx(


LPCTSTR lpszConnectString,
DWORD dwOptions = 0);

Parameters
lpszConnectString
Specifies an ODBC connection string. This includes the data source name as well as other optional information,
such as a user ID and password. For example, "DSN=SQLServer_Source;UID=SA;PWD=abc123" is a possible
connection string. Note that if you pass NULL for lpszConnectString, a Data Source dialog box will prompt the
user to select a data source.
dwOptions
A bitmask which specifies a combination of the following values. The default value is 0, meaning that the
database will be opened as shared with write access, the ODBC Cursor Library DLL will not be loaded, and the
ODBC connection dialog box will display only if there is not enough information to make the connection.
CDatabase::openExclusive Not supported in this version of the class library. A data source is always
opened as shared (not exclusive). Currently, an assertion fails if you specify this option.
CDatabase::openReadOnly Open the data source as read-only.
CDatabase::useCursorLib Load the ODBC Cursor Library DLL. The cursor library masks some functionality
of the underlying ODBC driver, effectively preventing the use of dynasets (if the driver supports them). The
only cursors supported if the cursor library is loaded are static snapshots and forward-only cursors. If you
plan to create a recordset object directly from CRecordset without deriving from it, you should not load
the cursor library.
CDatabase::noOdbcDialog Do not display the ODBC connection dialog box, regardless of whether enough
connection information is supplied.
CDatabase::forceOdbcDialog Always display the ODBC connection dialog box.
Return Value
Nonzero if the connection is successfully made; otherwise 0 if the user chooses Cancel when presented a dialog
box asking for more connection information. In all other cases, the framework throws an exception.
Remarks
Your database object must be initialized before you can use it to construct a recordset object.
If the lpszConnectString parameter in your OpenEx call does not contain enough information to make the
connection, the ODBC driver opens a dialog box to obtain the necessary information from the user, provided you
have not set CDatabase::noOdbcDialog or CDatabase::forceOdbcDialog in the dwOptions parameter. When you call
OpenEx , your connection string, lpszConnectString, is stored privately in the CDatabase object and is available by
calling the GetConnect member function.
If you wish, you can open your own dialog box before you call OpenEx to get information from the user, such as a
password, and then add that information to the connection string you pass to OpenEx . Or you might want to save
the connection string you pass so you can reuse it the next time your application calls OpenEx on a CDatabase
object.
You can also use the connection string for multiple levels of login authorization (each for a different CDatabase
object) or to convey other data source-specific information. For more information about connection strings, see
Chapter 6 in the ODBC Programmer's Reference.
It is possible for a connection attempt to time out if, for example, the DBMS host is unavailable. If the connection
attempt fails, OpenEx throws a CDBException .
Example

// m_dbCust is a CDatabase object embedded in a CDocument class.

// Connect the object to a read-only data source where


// the ODBC connection dialog box will always remain hidden
m_dbCust.OpenEx(_T("DSN=MFC_ODBCTest;UID=JOES"),
CDatabase::openReadOnly | CDatabase::noOdbcDialog);

CDatabase::Rollback
Call this member function to reverse the changes made during a transaction.

BOOL Rollback();

Return Value
Nonzero if the transaction was successfully reversed; otherwise 0. If a Rollback call fails, the data source and
transaction states are undefined. If Rollback returns 0, you must check the data source to determine its state.
Remarks
All CRecordset AddNew , Edit , Delete , and Update calls executed since the last BeginTrans are rolled back to the
state that existed at the time of that call.
After a call to Rollback , the transaction is over, and you must call BeginTrans again for another transaction. The
record that was current before you called BeginTrans becomes the current record again after Rollback .
After a rollback, the record that was current before the rollback remains current. For details about the state of the
recordset and the data source after a rollback, see the article Transaction (ODBC).
Example
See the article Transaction: Performing a Transaction in a Recordset (ODBC).

CDatabase::SetLoginTimeout
Call this member function — before you call OpenEx or Open — to override the default number of seconds
allowed before an attempted data source connection times out.

void SetLoginTimeout(DWORD dwSeconds);

Parameters
dwSeconds
The number of seconds to allow before a connection attempt times out.
Remarks
A connection attempt might time out if, for example, the DBMS is not available. Call SetLoginTimeout after you
construct the uninitialized CDatabase object but before you call OpenEx or Open .
The default value for login timeouts is 15 seconds. Not all data sources support the ability to specify a login
timeout value. If the data source does not support timeout, you get trace output but not an exception. A value of 0
means "infinite."

CDatabase::SetQueryTimeout
Call this member function to override the default number of seconds to allow before subsequent operations on
the connected data source time out.

void SetQueryTimeout(DWORD dwSeconds);

Parameters
dwSeconds
The number of seconds to allow before a query attempt times out.
Remarks
An operation might time out due to network access problems, excessive query processing time, and so on. Call
SetQueryTimeout prior to opening your recordset or prior to calling the recordset's AddNew , Update or Delete
member functions if you want to change the query timeout value. The setting affects all subsequent Open ,
AddNew , Update , and Delete calls to any recordsets associated with this CDatabase object. Changing the query
timeout value for a recordset after opening does not change the value for the recordset. For example, subsequent
Move operations do not use the new value.

The default value for query timeouts is 15 seconds. Not all data sources support the ability to set a query timeout
value. If you set a query timeout value of 0, no timeout occurs; the communication with the data source may stop
responding. This behavior may be useful during development. If the data source does not support timeout, you
get trace output but not an exception.
See also
CObject Class
Hierarchy Chart
CRecordset Class
CDataExchange Class
4/21/2020 • 5 minutes to read • Edit Online

Supports the dialog data exchange (DDX) and dialog data validation (DDV) routines used by the Microsoft
Foundation classes.

Syntax
class CDataExchange

Members
Public Constructors
NAME DESC RIP T IO N

CDataExchange::CDataExchange Constructs a CDataExchange object.

Public Methods
NAME DESC RIP T IO N

CDataExchange::Fail Called when validation fails. Resets focus to the previous


control and throws an exception.

CDataExchange::PrepareCtrl Prepares the specified control for data exchange or


validation. Use for nonedit controls.

CDataExchange::PrepareEditCtrl Prepares the specified edit control for data exchange or


validation.

CDataExchange::PrepareOleCtrl Prepares the specified OLE control for data exchange or


validation. Use for nonedit controls.

Public Data Members


NAME DESC RIP T IO N

CDataExchange::m_bSaveAndValidate Flag for the direction of DDX and DDV.

CDataExchange::m_pDlgWnd The dialog box or window where the data exchange takes
place.

Remarks
CDataExchange does not have a base class.
Use this class if you are writing data exchange routines for custom data types or controls, or if you are writing
your own data validation routines. For more information on writing your own DDX and DDV routines, see
Technical Note 26. For an overview of DDX and DDV, see Dialog Data Exchange and Validation and Dialog
Boxes.
A CDataExchange object provides the context information needed for DDX and DDV to take place. The flag
m_bSaveAndValidate is FALSE when DDX is used to fill the initial values of dialog controls from data
members. The flag m_bSaveAndValidate is TRUE when DDX is used to set the current values of dialog controls
into data members and when DDV is used to validate the data values. If the DDV validation fails, the DDV
procedure will display a message box explaining the input error. The DDV procedure will then call Fail to
reset the focus to the offending control and throw an exception to stop the validation process.

Inheritance Hierarchy
CDataExchange

Requirements
Header : afxwin.h

CDataExchange::CDataExchange
Call this member function to construct a CDataExchange object.

CDataExchange(
CWnd* pDlgWnd,
BOOL bSaveAndValidate);

Parameters
pDlgWnd
A pointer to the parent window that contains the control. Usually this is a CDialog-derived object.
bSaveAndValidate
If TRUE, this object validates data, then writes data from the controls to the members. If FALSE, this object will
move data from members to controls.
Remarks
Construct a CDataExchange object yourself to store extra information in the data exchange object to pass to
your window's CWnd::DoDataExchange member function.
Example

CYourDataExchange dx(this, FALSE);


try
{
DoDataExchange(&dx);
}
catch (CUserException *pe)
{
// some part of the exchange went wrong
// but the user has already been notified
pe->Delete();
}

CDataExchange::Fail
The framework calls this member function when a dialog data validation (DDV) operation fails.
void Fail();

Remarks
Fail restores the focus and selection to the control whose validation failed (if there is a control to restore).
Fail then throws an exception of type CUserException to stop the validation process. The exception causes a
message box explaining the error to be displayed. After DDV validation fails, the user can reenter data in the
offending control.
Implementors of custom DDV routines can call Fail from their routines when a validation fails.
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

CDataExchange::m_bSaveAndValidate
This flag indicates the direction of a dialog data exchange (DDX) operation.

BOOL m_bSaveAndValidate;

Remarks
The flag is nonzero if the CDataExchange object is being used to move data from the dialog controls to dialog-
class data members after the user edits the controls. The flag is zero if the object is being used to initialize
dialog controls from dialog-class data members.
The flag is also nonzero during dialog data validation (DDV).
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

CDataExchange::m_pDlgWnd
Contains a pointer to the CWnd object for which dialog data exchange (DDX) or validation (DDV) is taking
place.

CWnd* m_pDlgWnd;

Remarks
This object is usually a CDialog object. Implementors of custom DDX or DDV routines can use this pointer to
obtain access to the dialog window that contains the controls they are operating on.
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

CDataExchange::PrepareCtrl
The framework calls this member function to prepare the specified control for dialog data exchange (DDX)
and validation (DDV).

HWND PrepareCtrl(int nIDC);

Parameters
nIDC
The ID of the control to be prepared for DDX or DDV.
Return Value
The HWND of the control being prepared for DDX or DDV.
Remarks
Use PrepareEditCtrl instead for edit controls; use this member function for all other controls.
Preparation consists of storing the control's HWND in the CDataExchange class. The framework uses this
handle to restore the focus to the previously focused control in the event of a DDX or DDV failure.
Implementors of custom DDX or DDV routines should call PrepareCtrl for all non-edit controls for which
they are exchanging data via DDX or validating data via DDV.
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

CDataExchange::PrepareEditCtrl
The framework calls this member function to prepare the specified edit control for dialog data exchange
(DDX) and validation (DDV).

HWND PrepareEditCtrl(int nIDC);

Parameters
nIDC
The ID of the edit control to be prepared for DDX or DDV.
Return Value
The HWND of the edit control being prepared for DDX or DDV.
Remarks
Use PrepareCtrl instead for all non-edit controls.
Preparation consists of two things. First, PrepareEditCtrl stores the control's HWND in the CDataExchange
class. The framework uses this handle to restore the focus to the previously focused control in the event of a
DDX or DDV failure. Second, PrepareEditCtrl sets a flag in the CDataExchange class to indicate that the
control whose data is being exchanged or validated is an edit control.
Implementors of custom DDX or DDV routines should call PrepareEditCtrl for all edit controls for which they
are exchanging data via DDX or validating data via DDV.
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

CDataExchange::PrepareOleCtrl
The framework calls this member function to prepare the specified OLE control for dialog data exchange
(DDX) and validation (DDV).

COleControlSite* PrepareOleCtrl(int nIDC);

Parameters
nIDC
The ID of the OLE control to be prepared for DDX or DDV.
Return Value
A pointer to the OLE control site.
Remarks
Use PrepareEditCtrl instead for edit controls or PrepareCtrl for all other non-OLE controls.
Implementors of custom DDX or DDV routines should call PrepareOleCtrl for all OLE controls for which they
are exchanging data via DDX or validating data via DDV.
For more information on writing your own DDX and DDV routines, see Technical Note 26. For an overview of
DDX and DDV, see Dialog Data Exchange and Validation and Dialog Box Topics.

See also
MFC Sample VIEWEX
Hierarchy Chart
CWnd::DoDataExchange
CWnd::UpdateData
CDataPathProperty Class
4/21/2020 • 3 minutes to read • Edit Online

Implements an OLE control property that can be loaded asynchronously.

Syntax
class CDataPathProperty : public CAsyncMonikerFile

Members
Public Constructors
NAME DESC RIP T IO N

CDataPathProperty::CDataPathProperty Constructs a CDataPathProperty object.

Public Methods
NAME DESC RIP T IO N

CDataPathProperty::GetControl Retrieves the asynchronous OLE control associated with the


CDataPathProperty object.

CDataPathProperty::GetPath Retrieves the pathname of the property.

CDataPathProperty::Open Initiates loading of the asynchronous property for the


associated ActiveX (OLE) control.

CDataPathProperty::ResetData Calls CAsyncMonikerFile::OnDataAvailable to notify the


container that the control properties have changed.

CDataPathProperty::SetControl Sets the asynchronous ActiveX (OLE) control associated with


the property.

CDataPathProperty::SetPath Sets the pathname of the property.

Remarks
Asynchronous properties are loaded after synchronous initiation.
The class CDataPathProperty is derived from CAysncMonikerFile . To implement asynchronous properties in your
OLE controls, derive a class from CDataPathProperty , and override OnDataAvailable.
For more information about how to use asynchronous monikers and ActiveX controls in Internet applications,
see the following articles:
Internet First Steps: ActiveX Controls
Internet First Steps: Asynchronous Monikers
Inheritance Hierarchy
CObject
CFile
COleStreamFile
CMonikerFile
CAsyncMonikerFile
CDataPathProperty

Requirements
Header : afxctl.h

CDataPathProperty::CDataPathProperty
Constructs a CDataPathProperty object.

CDataPathProperty(COleControl* pControl = NULL);


CDataPathProperty(LPCTSTR lpszPath, COleControl* pControl = NULL);

Parameters
pControl
A pointer to the OLE control object to be associated with this CDataPathProperty object.
lpszPath
The path, which may be absolute or relative, used to create an asynchronous moniker that references the actual
absolute location of the property. CDataPathProperty uses URLs, not filenames. If you want a CDataPathProperty
object for a file, prepend file:// to the path.
Remarks
The COleControl object pointed to by pControl is used by Open and retrieved by derived classes. If pControl is
NULL, the control used with Open should be set with SetControl . If lpszPath is NULL, you can pass in the path
through Open or set it with SetPath .

CDataPathProperty::GetControl
Call this member function to retrieve the COleControl object associated with the CDataPathProperty object.

COleControl* GetControl();

Return Value
Returns a pointer to the OLE control associated with the CDataPathProperty object. NULL if not control is
associated.

CDataPathProperty::GetPath
Call this member function to retrieve the path, set when the CDataPathProperty object was constructed, or
specified in Open , or specified in a previous call to the SetPath member function.
CString GetPath() const;

Return Value
Returns the pathname to the property itself. Can be empty if no path has been specified.

CDataPathProperty::Open
Call this member function to initiate loading of the asynchronous property for the associated control.

virtual BOOL Open(


COleControl* pControl,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszPath,
COleControl* pControl,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszPath,
CFileException* pError = NULL);

virtual BOOL Open(CFileException* pError = NULL);

Parameters
pControl
A pointer to the OLE control object to be associated with this CDataPathProperty object.
pError
A pointer to a file exception. In the event of an error, will be set to the cause.
lpszPath
The path, which may be absolute or relative, used to create an asynchronous moniker that references the actual
absolute location of the property. CDataPathProperty uses URLs, not filenames. If you want a CDataPathProperty
object for a file, prepend file:// to the path.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The function attempts to obtain the IBindHost interface from the control.
Before calling Open without a path, the value for the property's path must be set. This can be done when the
object is constructed, or by calling the SetPath member function.
Before calling Open without a control, an ActiveX control (formerly known as an OLE control) can be associated
with the object. This can be done when the object is constructed, or by calling SetControl .
All overloads of CAsyncMonikerFile::Open are also available from CDataPathProperty .

CDataPathProperty::ResetData
Call this function to get CAsyncMonikerFile::OnDataAvailable to notify the container that the control properties
have changed, and all the information loaded asynchronously is no longer useful.
virtual void ResetData();

Remarks
Opening should be restarted. Derived classes can override this function for different defaults.

CDataPathProperty::SetControl
Call this member function to associate an asynchronous OLE control with the CDataPathProperty object.

void SetControl(COleControl* pControl);

Parameters
pControl
A pointer to the asynchronous OLE control to be associated with the property.

CDataPathProperty::SetPath
Call this member function to set the pathname of the property.

void SetPath(LPCTSTR lpszPath);

Parameters
lpszPath
A path, which may be absolute or relative, to the property being loaded asynchronously. CDataPathProperty uses
URLs, not filenames. If you want a CDataPathProperty object for a file, prepend file:// to the path.

See also
MFC Sample Image
CAsyncMonikerFile Class
Hierarchy Chart
CAsyncMonikerFile Class
CDataRecoveryHandler Class
3/27/2020 • 13 minutes to read • Edit Online

The CDataRecoveryHandler autosaves documents and restores them if an application unexpectedly exits.

Syntax
class CDataRecoveryHandler : public CObject

Members
Constructors

CDataRecoveryHandler::CDataRecoveryHandler Constructs a CDataRecoveryHandler object.

Methods

CDataRecoveryHandler::AutosaveAllDocumentInfo Autosaves each file registered with the


CDataRecoveryHandler class.

CDataRecoveryHandler::AutosaveDocumentInfo Autosaves the specified document.

CDataRecoveryHandler::CreateDocumentInfo Adds a document to the list of open documents.

CDataRecoveryHandler::DeleteAllAutosavedFiles Deletes all the current autosaved files.

CDataRecoveryHandler::DeleteAutosavedFile Deletes the specified autosaved file.

CDataRecoveryHandler::GenerateAutosaveFileName Generates the name for an autosave file associated with the
supplied document file name.

CDataRecoveryHandler::GetAutosaveInterval Returns the interval between autosave tries.

CDataRecoveryHandler::GetAutosavePath Returns the path of the autosaved files.

CDataRecoveryHandler::GetDocumentListName Retrieves the document name from a CDocument object.

CDataRecoveryHandler::GetNormalDocumentTitle Retrieves the normal title for the specified document.

CDataRecoveryHandler::GetRecoveredDocumentTitle Creates and returns the title for the recovered document.

CDataRecoveryHandler::GetRestartIdentifier Retrieves the unique restart identifier for the application.

CDataRecoveryHandler::GetSaveDocumentInfoOnIdle Indicates whether the CDataRecoveryHandler performs an


autosave on the current idle loop.
CDataRecoveryHandler::GetShutdownByRestartManager Indicates whether the restart manager caused the application
to exit.

CDataRecoveryHandler::Initialize Initializes the CDataRecoveryHandler .

CDataRecoveryHandler::QueryRestoreAutosavedDocuments Displays a dialog box to the user for each document that the
CDataRecoveryHandler autosaved. The dialog box
determines whether the user wants to restore the autosaved
document.

CDataRecoveryHandler::ReadOpenDocumentList Loads the open document list from the registry.

CDataRecoveryHandler::RemoveDocumentInfo Removes the supplied document from the open document


list.

CDataRecoveryHandler::ReopenPreviousDocuments Opens the previously open documents.

CDataRecoveryHandler::RestoreAutosavedDocuments Restores the autosaved documents based on user input.

CDataRecoveryHandler::SaveOpenDocumentList Saves the current list of open documents to the Windows


registry.

CDataRecoveryHandler::SetAutosaveInterval Sets the time between autosave cycles in milliseconds.

CDataRecoveryHandler::SetAutosavePath Sets the directory where autosaved files are stored.

CDataRecoveryHandler::SetRestartIdentifier Sets the unique restart identifier for this instance of the
CDataRecoveryHandler .

CDataRecoveryHandler::SetSaveDocumentInfoOnIdle Sets whether the CDataRecoveryHandler saves the open


document information to the Windows registry during the
current idle cycle.

CDataRecoveryHandler::SetShutdownByRestartManager Sets whether the previous exit of the application was caused
by the restart manager.

CDataRecoveryHandler::UpdateDocumentInfo Updates the information for a document because the user


saved it.

Data Members

m_bRestoringPreviousOpenDocs Indicates whether the data recovery handler reopens


previously open documents.

m_bSaveDocumentInfoOnIdle Indicates whether the data recovery handler autosaves


documents on the next idle loop.

m_bShutdownByRestartManager Indicates whether the restart manager causes the application


to exit.

m_dwRestartManagerSupportFlags Flags that indicate what support the restart manager


provides for the application.
m_lstAutosavesToDelete A list of autosaved files that were not deleted when the
original documents were closed. When the application exits,
the restart manager retries deleting the files.

m_mapDocNameToAutosaveName A map of the document names to the autosaved file names.

m_mapDocNameToDocumentPtr A map of the document names to the CDocument pointers.

m_mapDocNameToRestoreBool A map of the document names to a Boolean parameter that


indicates whether to restore the autosaved document.

m_mapDocumentPtrToDocName A map of the CDocument pointers to the document names.

m_mapDocumentPtrToDocTitle A map of the CDocument pointers to the document titles.


These titles are used for saving files.

m_nAutosaveInterval Time in milliseconds between autosaves.

m_nTimerID The identifier for the autosave timer.

m_strAutosavePath The location where the autosaved documents are stored.

m_strRestartIdentifier The string representation of a GUID for the restart manager.

Remarks
The restart manager uses the CDataRecoveryHandler class to keep track of all open documents and to autosave
them as necessary. To enable autosave, use the CDataRecoveryHandler::SetSaveDocumentInfoOnIdle method. This
method directs the CDataRecoveryHandler to perform an autosave on the next idle loop. The restart manager calls
SetSaveDocumentInfoOnIdle when the CDataRecoveryHandler should perform an autosave.

All of the methods of the CDataRecoveryHandler class are virtual. Override the methods in this class to create your
own custom data recovery handler. Unless you create your own data recovery handler or restart manager, do not
instantiate a CDataRecoveryHandler. The CWinApp Class creates a CDataRecoveryHandler object as it is required.
Before you can use a CDataRecoveryHandler object, you must call CDataRecoveryHandler::Initialize.
Because the CDataRecoveryHandler class is closely connected to the restart manager, CDataRecoveryHandler
depends on the global parameter m_dwRestartManagerSupportFlags . This parameter determines what permissions
the restart manager has and how it interacts with your application. To incorporate the restart manager into an
existing application, you have to assign m_dwRestartManagerSupportFlags the appropriate value in the constructor
of your main application. For more information about how to use the restart manager, see How to: Add Restart
Manager Support.

Requirements
Header : afxdatarecovery.h

CDataRecoveryHandler::AutosaveAllDocumentInfo
Autosaves each file registered with the CDataRecoveryHandler class.
virtual BOOL AutosaveAllDocumentInfo();

Return Value
TRUE if the CDataRecoveryHandler saved all the documents; FALSE if any document was not saved.
Remarks
This method returns TRUE if there are no documents that must be saved. It also returns TRUE without saving any
documents if retrieving the CWinApp or CDocManager for the application generates an error.
To use this method, either AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART or
AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL must be set in m_dwRestartManagerSupportFlags . For more
information, see How to: Add Restart Manager Support.

CDataRecoveryHandler::AutosaveDocumentInfo
Autosaves the specified document.

virtual BOOL AutosaveDocumentInfo(


CDocument* pDocument,
BOOL bResetModifiedFlag = TRUE);

Parameters

Parameter Description

pDocument [in] A pointer to the CDocument to save.

bResetModifiedFlag [in] TRUE indicates that the CDataRecoveryHandler


considers pDocument to be modified; FALSE indicates that the
framework considers pDocument to be unmodified. See the
Remarks section for more information about the effect of this
flag.

Return Value
TRUE if the appropriate flags are set and pDocument is a valid CDocument object.
Remarks
Each CDocument object has a flag that indicates if it has changed since the last save. Use CDocument::IsModified to
determine the state of this flag. If a CDocument has not changed since the last save, AutosaveDocumentInfo deletes
any autosaved files for that document. If a document has changed since the last save, closing it prompts the user
to save the document before closing.

NOTE
Using bResetModifiedFlag to change the state of the document to unmodified may cause the user to lose unsaved data. If
the framework considers a document unmodified, closing it does not prompt the user to save.

This method throws an exception with the ASSERT macro if pDocument is not a valid CDocument object.
To use this method, either AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART or
AFX_RESTARTMANAGER_AUTOSAVE_AT_INTERVAL must be set in m_dwRestartManagerSupportFlags.
CDataRecoveryHandler::CDataRecoveryHandler
Constructs a CDataRecoveryHandler object.

CDataRecoveryHandler(
DWORD dwRestartManagerSupportFlags,
int nAutosaveInterval);

Parameters

Parameter Description

dwRestartManagerSupportFlags [in] Indicates which options of the restart manager are


supported.

nAutosaveInterval [in] The time between autosaves. This parameter is in


milliseconds.

Remarks
The MFC framework automatically creates a CDataRecoveryHandler object for your application when you use the
New Project wizard. Unless you are customizing the data recovery behavior or the restart manager, you should
not create a CDataRecoveryHandler object.

CDataRecoveryHandler::CreateDocumentInfo
Adds a document to the list of open documents.

virtual BOOL CreateDocumentInfo(CDocument* pDocument);

Parameters

Parameter Description

pDocument [in] A pointer to a CDocument . This method creates the


document information for this CDocument .

Return Value
The default implementation returns TRUE.
Remarks
This method checks if pDocument is already in the list of documents before it adds the document. If pDocument is
already in the list, this method deletes the autosaved file associated with pDocument.
To use this method, either AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART or
AFX_RESTARTMANAGER_AUTOSAVE_AT_INTERVAL must be set in m_dwRestartManagerSupportFlags.

CDataRecoveryHandler::DeleteAllAutosavedFiles
Deletes all the current autosaved files.
virtual BOOL DeleteAllAutosavedFiles();

Return Value
The default implementation always returns TRUE.

CDataRecoveryHandler::DeleteAutosavedFile
Deletes the specified autosaved file.

virtual BOOL DeleteAutosavedFile(const CString& strAutosavedFile);

Parameters

Parameter Description

strAutosavedFile [in] A string that contains the autosaved file name.

Return Value
The default implementation always return TRUE.
Remarks
If this method cannot delete the autosaved file, it saves the name of the file in a list. The destructor for the
CDataRecoveryHandler tries to delete each autosaved file specified in that list.

CDataRecoveryHandler::GenerateAutosaveFileName
Generates the name for an autosave file associated with the supplied document file name.

virtual CString GenerateAutosaveFileName(const CString& strDocumentName) const;

Parameters
strDocumentName
[in] A string that contains the document name. GenerateAutosaveFileName uses this document name to generate a
corresponding autosave file name.
Return Value
The autosave file name generated from strDocumentName.
Remarks
Each document name has a one-to-one mapping with an autosave file name.

CDataRecoveryHandler::GetAutosaveInterval
Returns the interval between autosave tries.

virtual int GetAutosaveInterval() const;

Return Value
The number of milliseconds between autosave tries.
CDataRecoveryHandler::GetAutosavePath
Returns the path of the autosaved files.

virtual CString GetAutosavePath() const;

Return Value
The location where the autosaved documents are stored.

CDataRecoveryHandler::GetDocumentListName
Retrieves the document name from a CDocument object.

virtual CString GetDocumentListName(CDocument* pDocument) const;

Parameters

Parameter Description

pDocument [in] A pointer to a CDocument . GetDocumentListName


retrieves the document name from this CDocument .

Return Value
The document name from pDocument.
Remarks
The CDataRecoveryHandler uses the document name as the key in m_mapDocNameToAutosaveName,
m_mapDocNameToDocumentPtr, and m_mapDocNameToRestoreBool. These parameter enable the
CDataRecoveryHandler to monitor CDocument objects, the autosave file name, and the autosave settings.

CDataRecoveryHandler::GetNormalDocumentTitle
Retrieves the normal title for the specified document.

virtual CString GetNormalDocumentTitle(CDocument* pDocument);

Parameters

Parameter Description

pDocument [in] A pointer to a CDocument .

Return Value
The normal title for the specified document.
Remarks
The normal title of a document is usually the file name of the document without the path. This is the title in the
File name field of the Save As dialog box.
CDataRecoveryHandler::GetRecoveredDocumentTitle
Creates and returns the title for the recovered document.

virtual CString GetRecoveredDocumentTitle(const CString& strDocumentTitle) const;

Parameters
strDocumentTitle
[in] The normal title for the document.
Return Value
The recovered document title.
Remarks
By default, the recovered title of a document is the normal title with [recovered] appended to it. The recovered
title is displayed to the user when the CDataRecoveryHandler queries the user to restore autosaved documents.

CDataRecoveryHandler::GetRestartIdentifier
Retrieves the unique restart identifier for the application.

virtual CString GetRestartIdentifier() const;

Return Value
The unique restart identifier.
Remarks
The restart identifier is unique for each execution of the application.
The CDataRecoveryHandler stores information in the registry about the currently open documents. When the
restart manager exits an application and restarts it, it supplies the restart identifier to the CDataRecoveryHandler .
The CDataRecoveryHandler uses the restart identifier to retrieve the list of previously open documents. This
enables the CDataRecoveryHandler to try to find and restore autosaved files.

CDataRecoveryHandler::GetSaveDocumentInfoOnIdle
Indicates whether the CDataRecoveryHandler performs an autosave on the current idle loop.

virtual BOOL GetSaveDocumentInfoOnIdle() const;

Return Value
TRUE indicates the CDataRecoveryHandler autosaves on the current idle loop; FALSE indicates it does not.

CDataRecoveryHandler::GetShutdownByRestartManager
Indicates whether the restart manager caused the application to exit.

virtual BOOL GetShutdownByRestartManager() const;

Return Value
TRUE indicates the restart manager caused the application to exit; FALSE indicates it did not.
CDataRecoveryHandler::Initialize
Initializes the CDataRecoveryHandler .

virtual BOOL Initialize();

Return Value
TRUE if the initialization is successful; otherwise FALSE.
Remarks
The initialization process loads the path for storing autosave files from the registry. If the Initialize method
cannot find this directory or if the path is NULL, Initialize fails and returns FALSE .
Use CDataRecoveryHandler::SetAutosavePath to change the autosave path after your application initializes the
CDataRecoveryHandler .

The Initialize method also starts a timer to monitor when the next autosave occurs. Use
CDataRecoveryHandler::SetAutosaveInterval to change the autosave interval after your application initializes the
CDataRecoveryHandler .

CDataRecoveryHandler::QueryRestoreAutosavedDocuments
Displays a dialog box to the user for each document that the CDataRecoveryHandler autosaved. The dialog box
determines whether the user wants to restore the autosaved document.

virtual void QueryRestoreAutosavedDocuments();

Remarks
If your application is Unicode, this method displays a CTaskDialog to the user. Otherwise, the framework uses
AfxMessageBox to query the user.
After QueryRestoreAutosavedDocuments gathers all the responses from the user, it stores the information in the
member variable m_mapDocNameToRestoreBool. This method does not restore the autosaved documents.

CDataRecoveryHandler::ReadOpenDocumentList
Loads the open document list from the registry.

virtual BOOL ReadOpenDocumentList();

Return Value
TRUE indicates that ReadOpenDocumentList loaded the information for at least one document from the registry;
FALSE indicates no document information was loaded.
Remarks
This function loads the open document information from the registry and stores it in the member variable
m_mapDocNameToAutosaveName.
After ReadOpenDocumentList loads all the data, it deletes the document information from the registry.

CDataRecoveryHandler::RemoveDocumentInfo
Removes the supplied document from the open document list.

virtual BOOL RemoveDocumentInfo(CDocument* pDocument);

Parameters

Parameter Description

pDocument [in] A pointer to the document to remove.

Return Value
TRUE if pDocument was removed from the list; FALSE if an error occurred.
Remarks
When the user closes a document, the framework uses this method to remove it from the list of open documents.
If RemoveDocumentInfo cannot find pDocument in the list of open documents, it does nothing and returns TRUE.
To use this method, AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES must be set in
m_dwRestartManagerSupportFlags.

CDataRecoveryHandler::ReopenPreviousDocuments
Opens the previously open documents.

virtual BOOL ReopenPreviousDocuments();

Return Value
TRUE if at least one document was opened; otherwise FALSE.
Remarks
This method opens the most recent save of the previously open documents. If a document was not saved or
autosaved, ReopenPreviousDocuments opens a blank document based on the template for that file type.
To use this method, AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES must be set in
m_dwRestartManagerSupportFlags. If this parameter is not set, ReopenPreviousDocuments does nothing and
returns FALSE.
If there are no documents stored in the list of previously open documents, ReopenPreviousDocuments does nothing
and returns FALSE.

CDataRecoveryHandler::RestoreAutosavedDocuments
Restores the autosaved documents based on user input.

virtual BOOL RestoreAutosavedDocuments();

Return Value
TRUE if this method successfully restores the documents.
Remarks
This method calls CDataRecoveryHandler::QueryRestoreAutosavedDocuments to determine which documents the
user wants to restore. If a user decides not to restore an autosaved document, RestoreAutosavedDocuments deletes
the autosave file. Otherwise, RestoreAutosavedDocuments replaces the open document with the autosaved version.
To use this method, either AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES or
AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES must be set in m_dwRestartManagerSupportFlags .

CDataRecoveryHandler::SaveOpenDocumentList
Saves the current list of open documents to the Windows registry.

virtual BOOL SaveOpenDocumentList();

Return Value
TRUE if there are no open documents to save or if they were saved successfully. FALSE if there are documents to
save to the registry, but they were not saved because an error occurred.
Remarks
The restart manager calls SaveOpenDocumentList when the application exits unexpectedly or when it exits for an
upgrade. When the application restarts, it uses CDataRecoveryHandler::ReadOpenDocumentList to retrieve the list
of open documents.
This method saves only the list of open documents. The method CDataRecoveryHandler::AutosaveDocumentInfo
is responsible for saving the documents themselves.

CDataRecoveryHandler::SetAutosaveInterval
Sets the time between autosave cycles in milliseconds.

Virtual void SetAutosaveInterval(int nAutosaveInterval);

Parameters
nAutosaveInterval
[in] The new autosave interval in milliseconds.

CDataRecoveryHandler::SetAutosavePath
Sets the directory where autosaved files are stored.

virtual void SetAutosavePath(const CString& strAutosavePath);

Parameters

Parameter Description

strAutosavePath [in] The path where autosave files are stored.

Remarks
Changing the autosave directory does not move currently autosaved files.

CDataRecoveryHandler::SetRestartIdentifier
Sets the unique restart identifier for this instance of the CDataRecoveryHandler .

virtual void SetRestartIdentifier(const CString& strRestartIdentifier);

Parameters

Parameter Description

strRestartIdentifier [in] The unique identifier for the restart manager.

Remarks
The restart manager records information about the open documents in the registry. This information is stored
with the unique restart identifier as the key. Because the restart identifier is unique for each instance of an
application, multiple instances of an application may exit unexpectedly and the restart manager can recover each
of them.

CDataRecoveryHandler::SetSaveDocumentInfoOnIdle
Sets whether the CDataRecoveryHandler saves the open document information to the Windows registry during the
current idle cycle.

virtual void SetSaveDocumentInfoOnIdle(BOOL bSaveOnIdle);

Parameters

Parameter Description

bSaveOnIdle [in] TRUE to save document information during the current


idle cycle; FALSE to not perform a save.

CDataRecoveryHandler::SetShutdownByRestartManager
Sets whether the previous exit of the application was caused by the restart manager.

virtual void SetShutdownByRestartManager(BOOL bShutdownByRestartManager);

Parameters

Parameter Description

bShutdownByRestartManager [in] TRUE to indicate that the restart manager caused the
application to exit; FALSE to indicate that the application
exited for another reason.

Remarks
The framework behaves differently based on whether the previous exit was unexpected or whether it was initiated
by the restart manager.
CDataRecoveryHandler::UpdateDocumentInfo
Updates the information for a document because the user saved it.

virtual BOOL UpdateDocumentInfo(CDocument* pDocument);

Parameters

Parameter Description

pDocument [in] A pointer to the saved document.

Return Value
TRUE if this method deleted the autosaved document and updated the document information; FALSE if an error
occurred.
Remarks
When a user saves a document, the application removes the autosaved file because it is no longer needed.
UpdateDocumentInfo deletes the autosaved file by calling CDataRecoveryHandler::RemoveDocumentInfo.
UpdateDocumentInfo then adds the information from pDocument to the list of currently open documents because
RemoveDocumentInfo deletes that information, but the saved document is still open.

To use this method, AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES must be set in


m_dwRestartManagerSupportFlags.

See also
Classes
Hierarchy Chart
CObject Class
How to: Add Restart Manager Support
CDateTimeCtrl Class
4/21/2020 • 16 minutes to read • Edit Online

Encapsulates the functionality of a date and time picker control.

Syntax
class CDateTimeCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CDateTimeCtrl::CDateTimeCtrl Constructs a CDateTimeCtrl object.

Public Methods
NAME DESC RIP T IO N

CDateTimeCtrl::CloseMonthCal Closes the current date and time picker control.

CDateTimeCtrl::Create Creates the date and time picker control and attaches it to
the CDateTimeCtrl object.

CDateTimeCtrl::GetDateTimePickerInfo Retrieves information about the current date and time picker
control.

CDateTimeCtrl::GetIdealSize Returns the ideal size of the date and time picker control that
is required to display the current date or time.

CDateTimeCtrl::GetMonthCalColor Retrieves the color for a given portion of the month calendar
within the date and time picker control.

CDateTimeCtrl::GetMonthCalCtrl Retrieves the CMonthCalCtrl object associated with the


date and time picker control.

CDateTimeCtrl::GetMonthCalFont Retrieves the font currently used by the date and time picker
control's child month calendar control.

CDateTimeCtrl::GetMonthCalStyle Gets the style of the current date and time picker control.

CDateTimeCtrl::GetRange Retrieves the current minimum and maximum allowed system


times for a date and time picker control.

CDateTimeCtrl::GetTime Retrieves the currently selected time from a date and time
picker control and puts it in a specified SYSTEMTIME
structure.
NAME DESC RIP T IO N

CDateTimeCtrl::SetFormat Sets the display of a date and time picker control in


accordance with a given format string.

CDateTimeCtrl::SetMonthCalColor Sets the color for a given portion of the month calendar
within a date and time picker control.

CDateTimeCtrl::SetMonthCalFont Sets the font that the date and time picker control's child
month calendar control will use.

CDateTimeCtrl::SetMonthCalStyle Sets the style of the current date and time picker control.

CDateTimeCtrl::SetRange Sets the minimum and maximum allowed system times for a
date and time picker control.

CDateTimeCtrl::SetTime Sets the time in a date and time picker control.

Remarks
The date and time picker control (DTP control) provides a simple interface to exchange date and time information
with a user. This interface contains fields, each of which displays a part of the date and time information stored in
the control. The user can change the information stored in the control by changing the content of the string in a
given field. The user can move from field to field using the mouse or the keyboard.
You can customize the date and time picker control by applying a variety of styles to the object when you create it.
See Date and Time Picker Control Styles in the Windows SDK for more information about styles specific to the
date and time picker control. You can set the display format of the DTP control using format styles. These format
styles are described under "Format Styles" in the Windows SDK topic Date and Time Picker Control Styles.
The date and time picker control also uses notifications and callbacks, which are described in Using
CDateTimeCtrl.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDateTimeCtrl

Requirements
Header : afxdtctl.h

CDateTimeCtrl::CDateTimeCtrl
Constructs a CDateTimeCtrl object.

CDateTimeCtrl();

CDateTimeCtrl::CloseMonthCal
Closes the current date and time picker control.

void CloseMonthCal() const;

Remarks
This method sends the DTM_CLOSEMONTHCAL message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_dateTimeCtrl, that is used to programmatically access the
date and time picker control. This variable is used in the next example.

// Variable to access date-time control.


CDateTimeCtrl m_dateTimeCtrl;
// Variable to access the splitbutton control
CSplitButton m_splitbutton;

Example
The following code example closes the drop-down calendar for the current date and time picker control.

void CCDateTimeCtrl_s1Dlg::OnXClosemonthcal()
{
// Close the month calendar control dropdown.
m_dateTimeCtrl.CloseMonthCal();
}

CDateTimeCtrl::Create
Creates the date and time picker control and attaches it to the CDateTimeCtrl object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the combination of date time control styles. See Date and Time Picker Control Styles in the Windows
SDK for more information about date and time picker styles.
rect
A reference to a RECT structure, which is the position and size of the date and time picker control.
pParentWnd
A pointer to a CWnd object that is the parent window of the date and time picker control. It must not be NULL.
nID
Specifies the date and time picker control's control ID.
Return Value
Nonzero if creation was successful; otherwise 0.
Remarks
To c r e a t e a d a t e a n d t i m e p i c k e r c o n t r o l
1. Call CDateTimeCtrl to construct a CDateTimeCtrl object.
2. Call this member function, which creates the Windows date and time picker control and attaches it to the
CDateTimeCtrl object.

When you call Create , the common controls are initialized.


Example

// choose an arbitrary rectangle for creation


CRect rect(20, 20, 120, 45);
m_DateTimeCtrl.Create(WS_VISIBLE | WS_CHILD | WS_TABSTOP | DTS_SHOWNONE |
DTS_SHORTDATEFORMAT,
rect, this, IDC_DATETIMECTRL);

CDateTimeCtrl::GetDateTimePickerInfo
Retrieves information about the current date and time picker control.

BOOL GetDateTimePickerInfo(LPDATETIMEPICKERINFO pDateTimePickerInfo) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pDateTimePickerInfo [out] A pointer to a DATETIMEPICKERINFO structure that


receives a description of the current date and time picker
control.

The caller is responsible for allocating this structure. However,


this method initializes the cbSize member of the structure.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the DTM_GETDATETIMEPICKERINFO message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_dateTimeCtrl, that is used to programmatically access the
date and time picker control. This variable is used in the next example.

// Variable to access date-time control.


CDateTimeCtrl m_dateTimeCtrl;
// Variable to access the splitbutton control
CSplitButton m_splitbutton;

Example
The following code example indicates whether it successfully retrieves information about the current date and
time picker control.
void CCDateTimeCtrl_s1Dlg::OnXGetdatetimepickerinfo()
{
// Get information about the date-time picker control.
DATETIMEPICKERINFO dtpi = {0};
dtpi.cbSize = sizeof(DATETIMEPICKERINFO);
BOOL rc = m_dateTimeCtrl.GetDateTimePickerInfo(&dtpi);
if (rc == TRUE)
AfxMessageBox(_T("Information retrieved"),
MB_ICONEXCLAMATION);
else
AfxMessageBox(_T("Information was not retrieved"));
}

CDateTimeCtrl::GetMonthCalColor
Retrieves the color for a given portion of the month calendar within the date and time picker control.

COLORREF GetMonthCalColor(int iColor) const;

Parameters
iColor
An int value specifying which color area of the month calendar to retrieve. For a list of values, see the iColor
parameter for SetMonthCalColor.
Return Value
A COLORREF value that represents the color setting for the specified portion of the month calendar control if
successful. The function returns -1 if unsuccessful.
Remarks
This member function implements the behavior of the Win32 message DTM_GETMCCOLOR, as described in the
Windows SDK.
Example

// Set the color for the text in the control and


// assure it was set properly. Unlike the GetMonthCalCtrl() member,
// GetMonthCalColor() and SetMonthCalColor() can be used at any time.
m_DateTimeCtrl.SetMonthCalColor(MCSC_TEXT, RGB(255, 0, 0));
VERIFY(m_DateTimeCtrl.GetMonthCalColor(MCSC_TEXT) == RGB(255, 0, 0));

CDateTimeCtrl::GetMonthCalCtrl
Retrieves the CMonthCalCtrl object associated with the date and time picker control.

CMonthCalCtrl* GetMonthCalCtrl() const;

Return Value
A pointer to a CMonthCalCtrl object, or NULL if unsuccessful or if the window is not visible.
Remarks
Date and time picker controls create a child month calendar control when the user clicks the drop-down arrow.
When the CMonthCalCtrl object is no longer needed, it is destroyed, so your application must not rely on storing
the object representing the date time picker control's child month calendar.
Example

void CDateTimeDlg::OnDropDownDateTimeCtrl(NMHDR *pNMHDR, LRESULT *pResult)


{
UNREFERENCED_PARAMETER(pNMHDR);

// note that GetMonthCalCtrl() will only return a pointer to the


// month calendar control while the control actually exists--that is,
// while it has been dropped-down by the user. Otherwise, the function
// returns NULL. One appropriate time to get the control is while
// handling the DTN_DROPDOWN notification for the date time picker
// control.

// get the control


CMonthCalCtrl *pMoCalCtrl = m_DateTimeCtrl.GetMonthCalCtrl();
ASSERT(pMoCalCtrl != NULL);

// now, pMoCalCtrl is useful...

*pResult = 0;
}

CDateTimeCtrl::GetMonthCalFont
Gets the font currently used by the date and time picker control's month calendar control.

CFont* GetMonthCalFont() const;

Return Value
A pointer to a CFont object, or NULL if unsuccessful.
Remarks
The CFont object pointed to by the return value is a temporary object and is destroyed during the next idle
processing time.

CDateTimeCtrl::GetMonthCalStyle
Gets the style of the drop-down month calendar control that is associated with the current date and time picker
control.

DWORD GetMonthCalStyle() const;

Return Value
The style of the drop-down month calendar control, which is a bitwise combination (OR) of date and time picker
control styles. For more information, see Month Calendar Control Styles.
Remarks
This method sends the DTM_GETMCSTYLE message, which is described in the Windows SDK.

CDateTimeCtrl::GetRange
Retrieves the current minimum and maximum allowed system times for a date and time picker control.
DWORD GetRange(
COleDateTime* pMinRange,
COleDateTime* pMaxRange) const;

DWORD GetRange(
CTime* pMinRange,
CTime* pMaxRange) const;

Parameters
pMinRange
A pointer to a COleDateTime object or a CTime object containing the earliest time allowed in the CDateTimeCtrl
object.
pMaxRange
A pointer to a COleDateTime object or a CTime object containing the latest time allowed in the CDateTimeCtrl
object.
Return Value
A DWORD value containing flags that indicate which ranges are set. If
return value & GDTR_MAX == 0
then the second parameter is valid. Similarly, if
return value & GDTR_MIN == 0
then the first parameter is valid.
Remarks
This member function implements the behavior of the Win32 message DTM_GETRANGE, as described in the
Windows SDK. In MFC's implementation, you can specify either COleDateTime or CTime usages.
Example
// This function will set several ranges in the control, then
// call the ShowRange() function to show the set ranges to the
// user.
void CDateTimeDlg::OnBnClickedRangesbutton()
{
// Set minimum of January 1st, 1995 with no maximum.
COleDateTime dtMin;
COleDateTime dtMax;

dtMin = COleDateTime(1995, 1, 1, 0, 0, 0);


dtMax.SetStatus(COleDateTime::null);
m_DateTimeCtrl.SetRange(&dtMin, &dtMax);
ShowRange(&m_DateTimeCtrl);

// Set no minimum and maximum of September 30th, 1997.


dtMin.SetStatus(COleDateTime::null);
dtMax = COleDateTime(1997, 9, 30, 0, 0, 0);
m_DateTimeCtrl.SetRange(&dtMin, &dtMax);
ShowRange(&m_DateTimeCtrl);

// Set minimum of April 15, 1992 and maximum of June 5, 2002.


dtMin = COleDateTime(1992, 4, 15, 0, 0, 0);
dtMax = COleDateTime(2002, 6, 5, 0, 0, 0);
m_DateTimeCtrl.SetRange(&dtMin, &dtMax);
ShowRange(&m_DateTimeCtrl);
}

void CDateTimeDlg::ShowRange(CDateTimeCtrl *pCtrl)


{
ASSERT(pCtrl != NULL);
CString strMessage;
COleDateTime dtMinimum;
COleDateTime dtMaximum;

// Get the range.


DWORD dwResult = pCtrl->GetRange(&dtMinimum, &dtMaximum);

// If a minimum was specified, format it.


// Otherwise, indicate that there is no lower bound.
if (dwResult & GDTR_MIN)
strMessage += dtMinimum.Format(_T("Minimum range is %x %X.\r\n"));
else
strMessage += _T("No minimum range.\r\n");

// Treat maximum similarly.


if (dwResult & GDTR_MAX)
strMessage += dtMaximum.Format(_T("Maximum range is %x %X.\r\n"));
else
strMessage += _T("No maximum range.\r\n");

// Show the user.


AfxMessageBox(strMessage);
}

CDateTimeCtrl::GetTime
Retrieves the currently selected time from a date and time picker control and puts it in a specified SYSTEMTIME
structure.

BOOL GetTime(COleDateTime& timeDest) const;


DWORD GetTime(CTime& timeDest) const;
DWORD GetTime(LPSYSTEMTIME pTimeDest) const;
Parameters
timeDest
In the first version, a reference to a COleDateTime object that will receive the system time information. In the
second version, a reference to a CTime object that will receive the system time information.
pTimeDest
A pointer to the SYSTEMTIME structure to receive the system time information. Must not be NULL.
Return Value
In the first version, nonzero if the time is successfully written to the COleDateTime object; otherwise 0. In the
second and third versions, a DWORD value equal to the dwFlag member set in the NMDATETIMECHANGE
structure. See the Remarks section below for more information.
Remarks
This member function implements the behavior of the Win32 message DTM_GETSYSTEMTIME, as described in the
Windows SDK. In the MFC implementation of GetTime , you can use COleDateTime or CTime classes, or you can
use a SYSTEMTIME structure, to store the time information.
The return value DWORD in the second and third versions, above, indicates whether or not the date and time
picker control is set to the "no date" status, as indicated in the NMDATETIMECHANGE structure member dwFlags.
If the value returned equals GDT_NONE, the control is set to "no date" status, and uses the DTS_SHOWNONE
style. If the value returned equals GDT_VALID, the system time is successfully stored in the destination location.
Example

void CDateTimeDlg::OnBnClickedTimebutton()
{
// get as a CTime
CTime timeTime;
DWORD dwResult = m_DateTimeCtrl.GetTime(timeTime);
if (dwResult == GDT_VALID)
{
// the user checked the box and specified data
CString str;

// is it a time-only control, or a date-only control?


if ((m_DateTimeCtrl.GetStyle() & DTS_TIMEFORMAT) == DTS_TIMEFORMAT)
str = timeTime.Format(_T("%X"));
else
str = timeTime.Format(_T("%x"));
AfxMessageBox(str);
}
else
{
// the user unmarked the "none" box
AfxMessageBox(_T("Time not set!"));
}

// Calling as SYSTIME is much the same, but calling for a COleDateTime


// has us test the state of the COleDateTime object for validity to
// see if the user did or didn't check the "none" box.
}

CDateTimeCtrl::GetIdealSize
Returns the ideal size of the date and time picker control that is required to display the current date or time.

BOOL GetIdealSize(LPSIZE psize) const;


Parameters
PA RA M ET ER DESC RIP T IO N

psize [out] Pointer to a SIZE structure that contains the ideal size
for the control.

Return Value
The return value is always TRUE.
Remarks
This method sends the DTM_GETIDEALSIZE message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_dateTimeCtrl, that is used to programmatically access the
date and time picker control. This variable is used in the next example.

// Variable to access date-time control.


CDateTimeCtrl m_dateTimeCtrl;
// Variable to access the splitbutton control
CSplitButton m_splitbutton;

Example
The following code example retrieves the ideal size to display the date and time picker control.

// Add extra initialization here

// Associate a menu with the splitbutton control.


m_splitbutton.SetDropDownMenu(IDR_MENU1, 0);

// Resize the date-time picker control.


SIZE sz;
m_dateTimeCtrl.GetIdealSize(&sz);
if ((sz.cx != 0) && (sz.cy != 0))
{
m_dateTimeCtrl.SetWindowPos(
this,
0, 0, sz.cx, sz.cy,
(SWP_NOMOVE | SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOACTIVATE));
}

// End of extra initialization

CDateTimeCtrl::SetFormat
Sets the display of a date and time picker control in accordance with a given format string.

BOOL SetFormat(LPCTSTR pstrFormat);

Parameters
pstrFormat
A pointer to a zero-terminated format string that defines the desired display. Setting this parameter to NULL will
reset the control to the default format string for the current style.
Return Value
Nonzero if successful; otherwise 0.
NOTE
User input does not determine success or failure for this call.

Remarks
This member function implements the behavior of the Win32 message DTM_SETFORMAT, as described in the
Windows SDK.
Example

// The control will create itself with a format that matches the
// locale setting in Control Panel. But we can force a particular
// format with a call to SetFormat(). This call forces the format
// dd-MMM-yy, which would show 03-APR-98 for April 3rd, 1998.
m_DateTimeCtrl.SetFormat(_T("dd-MMM-yy"));

CDateTimeCtrl::SetMonthCalColor
Sets the color for a given portion of the month calendar within a date and time picker control.

COLORREF SetMonthCalColor(
int iColor,
COLORREF ref);

Parameters
iColor
int value specifying which area of the month calendar control to set. This value can be one of the following.

VA L UE M EA N IN G

MCSC_BACKGROUND Set the background color displayed between months.

MCSC_MONTHBK Set the background color displayed within a month.

MCSC_TEXT Set the color used to display text within a month.

MCSC_TITLEBK Set the background color displayed in the calendar's title.

MCSC_TITLETEXT Set the color used to display text within the calendar's title.

MCSC_TRAILINGTEXT Set the color used to display header and trailing-day text.
Header and trailing days are the days from the previous and
following months that appear on the current calendar.

ref
A COLORREF value representing the color that will be set for the specified area of the month calendar.
Return Value
A COLORREF value that represents the previous color setting for the specified portion of the month calendar
control if successful. Otherwise, the message returns -1.
Remarks
This member function implements the behavior of the Win32 message DTM_SETMCCOLOR, as described in the
Windows SDK.
Example
See the example for CDateTimeCtrl::GetMonthCalColor.

CDateTimeCtrl::SetMonthCalFont
Sets the font that the date and time picker control's child month calendar control will use.

void SetMonthCalFont(
HFONT hFont,
BOOL bRedraw = TRUE);

Parameters
hFont
Handle to the font that will be set.
bRedraw
Specifies whether the control should be redrawn immediately upon setting the font. Setting this parameter to
TRUE causes the control to redraw itself.
Remarks
This member function implements the behavior of the Win32 message DTM_SETMCFONT, as described in the
Windows SDK.
Example

// The following code example would most likely appear


// in the OnInitDialog function of your dialog class.
// It creates a font (Arial, 10 pixels high) and if successful,
// stores the result in m_MonthFont, a member of your
// dialog class declared as follows:
// CFont m_MonthFont;
// SetMonthCalFont is then called passing in the new font,
// causing the month calendar control to display all
// text and dates with an Arial font.

//initializing the necessary members of the LOGFONT


// structure

LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = 10;
_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"));

if (m_MonthFont.CreateFontIndirect(&lf))
{
// if successful, set the month calendar font
m_DateTimeCtrl.SetMonthCalFont((HFONT)m_MonthFont);
}

NOTE
If you use this code, you'll want to make a member of your CDialog -derived class called m_MonthFont of type CFont .

CDateTimeCtrl::SetMonthCalStyle
Sets the style of the drop-down month calendar control that is associated with the current date and time picker
control.

DWORD SetMonthCalStyle(DWORD dwStyle);

Parameters
PA RA M ET ER DESC RIP T IO N

dwStyle [in] A new month calendar control style, which is a bitwise


combination (OR) of month calendar control styles. For more
information, see Month Calendar Control Styles.

Return Value
The previous style of the drop-down month calendar control.
Remarks
This method sends the DTM_SETMCSTYLE message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_dateTimeCtrl, that is used to programmatically access the
date and time picker control. This variable is used in the next example.

// Variable to access date-time control.


CDateTimeCtrl m_dateTimeCtrl;
// Variable to access the splitbutton control
CSplitButton m_splitbutton;

Example
The following code example sets the date and time picker control to display week numbers, abbreviated names of
days of the week, and no today indicator.

// Set the style of the month-calendar control dropdown.


void CCDateTimeCtrl_s1Dlg::OnSetmonthcalstyleWeeknumber()
{
m_dateTimeCtrl.SetMonthCalStyle(MCS_WEEKNUMBERS);
}

void CCDateTimeCtrl_s1Dlg::OnSetmonthcalstyleNotoday()
{
m_dateTimeCtrl.SetMonthCalStyle(MCS_NOTODAY);
}

void CCDateTimeCtrl_s1Dlg::OnSetmonthcalstyleShortdaysofweek()
{
m_dateTimeCtrl.SetMonthCalStyle(MCS_SHORTDAYSOFWEEK);
}

CDateTimeCtrl::SetRange
Sets the minimum and maximum allowed system times for a date and time picker control.
BOOL SetRange(
const COleDateTime* pMinRange,
const COleDateTime* pMaxRange);

BOOL SetRange(
const CTime* pMinRange,
const CTime* pMaxRange);

Parameters
pMinRange
A pointer to a COleDateTime object or a CTime object containing the earliest time allowed in the CDateTimeCtrl
object.
pMaxRange
A pointer to a COleDateTime object or a CTime object containing the latest time allowed in the CDateTimeCtrl
object.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function implements the behavior of the Win32 message DTM_SETRANGE, as described in the
Windows SDK. In MFC's implementation, you can specify either COleDateTime or CTime usages. If the
COleDateTime object has a NULL status, the range will be removed. If the CTime pointer or the COleDateTime
pointer is NULL, the range will be removed.
Example
See the example for CDateTimeCtrl::GetRange.

CDateTimeCtrl::SetTime
Sets the time in a date and time picker control.

BOOL SetTime(const COleDateTime& timeNew);


BOOL SetTime(const CTime* pTimeNew);
BOOL SetTime(LPSYSTEMTIME pTimeNew = NULL);

Parameters
timeNew
A reference to a COleDateTime object containing the to which the control will be set.
pTimeNew
In the second version above, a pointer to a CTime object containing the time to which the control will be set. In the
third version above, a pointer to a SYSTEMTIME structure containing the time to which the control will be set.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function implements the behavior of the Win32 message DTM_SETSYSTEMTIME, as described in the
Windows SDK. In the MFC implementation of SetTime , you can use the COleDateTime or CTime classes, or you
can use a SYSTEMTIME structure, to set the time information.
Example
// set with a CTime
CTime timeTime(1998, 4, 3, 0, 0, 0);
VERIFY(m_DateTimeCtrl.SetTime(&timeTime));

// set with a COleDateTime object


COleDateTime oletimeTime(1998, 4, 3, 0, 0, 0);
VERIFY(m_DateTimeCtrl.SetTime(oletimeTime));

// set using the SYSTEMTIME


SYSTEMTIME sysTime;
memset(&sysTime, 0, sizeof(sysTime));
sysTime.wYear = 1998;
sysTime.wMonth = 4;
sysTime.wDay = 3;
VERIFY(m_DateTimeCtrl.SetTime(&sysTime));

See also
MFC Sample CMNCTRL1
CWnd Class
Hierarchy Chart
CMonthCalCtrl Class
CDBException Class
3/27/2020 • 5 minutes to read • Edit Online

Represents an exception condition arising from the database classes.

Syntax
class CDBException : public CException

Members
Public Data Members
NAME DESC RIP T IO N

CDBException::m_nRetCode Contains an Open Database Connectivity (ODBC) return


code, of type RETCODE.

CDBException::m_strError Contains a string that describes the error in alphanumeric


terms.

CDBException::m_strStateNativeOrigin Contains a string describing the error in terms of the error


codes returned by ODBC.

Remarks
The class includes two public data members you can use to determine the cause of the exception or to display a
text message describing the exception. CDBException objects are constructed and thrown by member functions
of the database classes.

NOTE
This class is one of MFC's Open Database Connectivity (ODBC) classes. If you are instead using the newer Data Access
Objects (DAO) classes, use CDaoException instead. All DAO class names have "CDao" as a prefix. For more information, see
the article Overview: Database Programming.

Exceptions are cases of abnormal execution involving conditions outside the program's control, such as data
source or network I/O errors. Errors that you might expect to see in the normal course of executing your
program are usually not considered exceptions.
You can access these objects within the scope of a CATCH expression. You can also throw CDBException objects
from your own code with the AfxThrowDBException global function.
For more information about exception handling in general, or about CDBException objects, see the articles
Exception Handling (MFC) and Exceptions: Database Exceptions.

Inheritance Hierarchy
CObject
CException
CDBException

Requirements
Header : afxdb.h

CDBException::m_nRetCode
Contains an ODBC error code of type RETCODE returned by an ODBC application programming interface (API)
function.
Remarks
This type includes SQL-prefixed codes defined by ODBC and AFX_SQL-prefixed codes defined by the database
classes. For a CDBException , this member will contain one of the following values:
AFX_SQL_ERROR_API_CONFORMANCE The driver for a CDatabase::OpenEx or CDatabase::Open call does
not conform to required ODBC API Conformance level 1 ( SQL_OAC_LEVEL1).
AFX_SQL_ERROR_CONNECT_FAIL Connection to the data source failed. You passed a NULL CDatabase
pointer to your recordset constructor and the subsequent attempt to create a connection based on
GetDefaultConnect failed.

AFX_SQL_ERROR_DATA_TRUNCATED You requested more data than you have provided storage for. For
information on increasing the provided data storage for CString or CByteArray data types, see the
nMaxLength argument for RFX_Text and RFX_Binary under "Macros and Globals."

AFX_SQL_ERROR_DYNASET_NOT_SUPPORTED A call to CRecordset::Open requesting a dynaset failed.


Dynasets are not supported by the driver.
AFX_SQL_ERROR_EMPTY_COLUMN_LIST You attempted to open a table (or what you gave could not be
identified as a procedure call or SELECT statement) but there are no columns identified in record field
exchange (RFX) function calls in your DoFieldExchange override.
AFX_SQL_ERROR_FIELD_SCHEMA_MISMATCH The type of an RFX function in your DoFieldExchange
override is not compatible with the column data type in the recordset.
AFX_SQL_ERROR_ILLEGAL_MODE You called CRecordset::Update without previously calling
CRecordset::AddNew or CRecordset::Edit .

AFX_SQL_ERROR_LOCK_MODE_NOT_SUPPORTED Your request to lock records for update could not be


fulfilled because your ODBC driver does not support locking.
AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED You called CRecordset::Update or Delete for a table with
no unique key and changed multiple records.
AFX_SQL_ERROR_NO_CURRENT_RECORD You attempted to edit or delete a previously deleted record.
You must scroll to a new current record after a deletion.
AFX_SQL_ERROR_NO_POSITIONED_UPDATES Your request for a dynaset could not be fulfilled because
your ODBC driver does not support positioned updates.
AFX_SQL_ERROR_NO_ROWS_AFFECTED You called CRecordset::Update or Delete , but when the
operation began the record could no longer be found.
AFX_SQL_ERROR_ODBC_LOAD_FAILED An attempt to load the ODBC.DLL failed; Windows could not find
or could not load this DLL. This error is fatal.
AFX_SQL_ERROR_ODBC_V2_REQUIRED Your request for a dynaset could not be fulfilled because a Level
2-compliant ODBC driver is required.
AFX_SQL_ERROR_RECORDSET_FORWARD_ONLY An attempt to scroll did not succeed because the data
source does not support backward scrolling.
AFX_SQL_ERROR_SNAPSHOT_NOT_SUPPORTED A call to CRecordset::Open requesting a snapshot failed.
Snapshots are not supported by the driver. (This should only occur when the ODBC cursor library
ODBCCURS.DLL is not present.)
AFX_SQL_ERROR_SQL_CONFORMANCE The driver for a CDatabase::OpenEx or CDatabase::Open call does
not conform to the required ODBC SQL Conformance level of "Minimum" (SQL_OSC_MINIMUM).
AFX_SQL_ERROR_SQL_NO_TOTAL The ODBC driver was unable to specify the total size of a CLongBinary
data value. The operation probably failed because a global memory block could not be preallocated.
AFX_SQL_ERROR_RECORDSET_READONLY You attempted to update a read-only recordset, or the data
source is read-only. No update operations can be performed with the recordset or the CDatabase object it
is associated with.
SQL_ERROR Function failed. The error message returned by the ODBC function SQLError is stored in the
m_strError data member.

SQL_INVALID_HANDLE Function failed due to an invalid environment handle, connection handle, or


statement handle. This indicates a programming error. No additional information is available from the
ODBC function SQLError .
The SQL-prefixed codes are defined by ODBC. The AFX-prefixed codes are defined in AFXDB.H, found in
MFC\INCLUDE.

CDBException::m_strError
Contains a string describing the error that caused the exception.
Remarks
The string describes the error in alphanumeric terms. For more detailed information and an example, see
m_strStateNativeOrigin .

CDBException::m_strStateNativeOrigin
Contains a string describing the error that caused the exception.
Remarks
The string is of the form "State:%s,Native:%ld,Origin:%s", where the format codes, in order, are replaced by values
that describe:
The SQLSTATE, a null-terminated string containing a five-character error code returned in the szSqlState
parameter of the ODBC function SQLError . SQLSTATE values are listed in Appendix A, ODBC Error Codes,
in the ODBC Programmer's Reference. Example: "S0022".
The native error code, specific to the data source, returned in the pfNativeError parameter of the SQLError
function. Example: 207.
The error message text returned in the szErrorMsg parameter of the SQLError function. This message
consists of several bracketed names. As an error is passed from its source to the user, each ODBC
component (data source, driver, Driver Manager) appends its own name. This information helps to
pinpoint the origin of the error. Example: [Microsoft][ODBC SQL Server Driver][SQL Server]
The framework interprets the error string and puts its components into m_strStateNativeOrigin ; if
m_strStateNativeOrigin contains information for more than one error, the errors are separated by newlines. The
framework puts the alphanumeric error text into m_strError .
For additional information about the codes used to make up this string, see the SQLError function in the ODBC
Programmer's Reference.
Example
From ODBC: "State:S0022,Native:207,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server] Invalid column
name 'ColName'"
In m_strStateNativeOrigin : "State:S0022,Native:207,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server]"
In m_strError : "Invalid column name 'ColName'"

See also
CException Class
Hierarchy Chart
CDatabase Class
CRecordset Class
CFieldExchange Class
CRecordset::Update
CRecordset::Delete
CException Class
CDBVariant Class
4/21/2020 • 4 minutes to read • Edit Online

Represents a variant data type for the MFC ODBC classes.

Syntax
class CDBVariant

Members
Public Constructors
NAME DESC RIP T IO N

CDBVariant::CDBVariant Constructs a CDBVariant object.

Public Methods
NAME DESC RIP T IO N

CDBVariant::Clear Clears the CDBVariant object.

Public Data Members


NAME DESC RIP T IO N

CDBVariant::m_dwType Contains the data type of the currently stored value. Type
DWORD .

Public Union Members


NAME DESC RIP T IO N

CDBVariant::m_boolVal Contains a value of type BOOL .

CDBVariant::m_chVal Contains a value of type unsigned char .

CDBVariant::m_dblVal Contains a value of type double .

CDBVariant::m_fltVal Contains a value of type float .

CDBVariant::m_iVal Contains a value of type shor t .

CDBVariant::m_lVal Contains a value of type long .

CDBVariant::m_pbinary Contains a pointer to an object of type CLongBinary .


NAME DESC RIP T IO N

CDBVariant::m_pdate Contains a pointer to an object of type


TIMESTAMP_STRUCT .

CDBVariant::m_pstring Contains a pointer to an object of type CString .

CDBVariant::m_pstringA Stores a pointer to an ASCII CString object.

CDBVariant::m_pstringW Stores a pointer to a wide CString object.

Remarks
CDBVariant does not have a base class.
CDBVariant is similar to COleVariant; however, CDBVariant does not use OLE. CDBVariant allows you to store a
value without worrying about the value's data type. CDBVariant tracks the data type of the current value, which is
stored in a union.
Class CRecordset utilizes CDBVariant objects in three member functions: GetFieldValue , GetBookmark , and
SetBookmark . For example, GetFieldValue allows you to dynamically fetch data in a column. Because the data type
of the column may not be known at run time, GetFieldValue uses a CDBVariant object to store the column's data.

Inheritance Hierarchy
CDBVariant

Requirements
Header : afxdb.h

CDBVariant::CDBVariant
Creates a NULL CDBVariant object.

CDBVariant();

Remarks
Sets the m_dwType data member to DBVT_NULL.

CDBVariant::Clear
Call this member function to clear the CDBVariant object.

void Clear();

Remarks
If the value of the m_dwType data member is DBVT_DATE, DBVT_STRING, or DBVT_BINARY, Clear frees the
memory associated with the union pointer member. Clear sets m_dwType to DBVT_NULL.
The CDBVariant destructor calls Clear .
CDBVariant::m_boolVal
Stores a value of type BOOL.
Remarks
The m_boolVal data member belongs to a union. Before accessing m_boolVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_BOOL, then m_boolVal will contain a valid value; otherwise,
accessing m_boolVal will produce unreliable results.

CDBVariant::m_chVal
Stores a value of type unsigned char .
Remarks
The m_chVal data member belongs to a union. Before accessing m_chVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_UCHAR, then m_chVal contains a valid value; otherwise,
accessing m_chVal will produce unreliable results.

CDBVariant::m_dblVal
Stores a value of type double .
Remarks
The m_dblVal data member belongs to a union. Before accessing m_dblVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_DOUBLE, then m_dblVal contains a valid value; otherwise,
accessing m_dblVal will produce unreliable results.

CDBVariant::m_dwType
This data member contains the data type for the value that is currently stored in the CDBVariant object's union
data member.
Remarks
Before accessing this union, you must check the value of m_dwType in order to determine which union data
member to access. The following table lists the possible values for m_dwType and the corresponding union data
member.

M _DW T Y P E UN IO N DATA M EM B ER

DBVT_NULL No union member is valid for access.

DBVT_BOOL m_boolVal

DBVT_UCHAR m_chVal

DBVT_SHORT m_iVal

DBVT_LONG m_lVal

DBVT_SINGLE m_fltVal

DBVT_DOUBLE m_dblVal
M _DW T Y P E UN IO N DATA M EM B ER

DBVT_DATE m_pdate

DBVT_STRING m_pstring

DBVT_BINARY m_pbinary

DBVT_ASTRING m_pstringA

DBVT_WSTRING m_pstringW

CDBVariant::m_fltVal
Stores a value of type float .
Remarks
The m_fltVal data member belongs to a union. Before accessing m_fltVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_SINGLE, then m_fltVal contains a valid value; otherwise,
accessing m_fltVal will produce unreliable results.

CDBVariant::m_iVal
Stores a value of type shor t .
Remarks
The m_iVal data member belongs to a union. Before accessing m_iVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_SHORT, then m_iVal contains a valid value; otherwise,
accessing m_iVal will produce unreliable results.

CDBVariant::m_lVal
Stores a value of type long .
Remarks
The m_lVal data member belongs to a union. Before accessing m_lVal , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_LONG, then m_lVal contains a valid value; otherwise,
accessing m_lVal will produce unreliable results.

CDBVariant::m_pbinary
Stores a pointer to an object of type CLongBinary.
Remarks
The m_pbinary data member belongs to a union. Before accessing m_pbinary , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_BINARY, then m_pbinary contains a valid pointer; otherwise,
accessing m_pbinary will produce unreliable results.

CDBVariant::m_pdate
Stores a pointer to an object of type TIMESTAMP_STRUCT.
Remarks
The m_pdate data member belongs to a union. Before accessing m_pdate , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_DATE, then m_pdate contains a valid pointer; otherwise,
accessing m_pdate will produce unreliable results.
For more information about the TIMESTAMP_STRUCT data type, see the topic C Data Types in Appendix D of the
ODBC Programmer's Reference in the Windows SDK.

CDBVariant::m_pstring
Stores a pointer to an object of type CString.
Remarks
The m_pstring data member belongs to a union. Before accessing m_pstring , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_STRING, then m_pstring contains a valid pointer; otherwise,
accessing m_pstring will produce unreliable results.

CDBVariant::m_pstringA
Stores a pointer to an ASCII CString object.
Remarks
The m_pstringA data member belongs to a union. Before accessing m_pstringA , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_ASTRING, then m_pstringA contains a valid pointer; otherwise,
accessing m_pstringA will produce unreliable results.

CDBVariant::m_pstringW
Stores a pointer to a wide CString object.
Remarks
The m_pstringW data member belongs to a union. Before accessing m_pstringW , first check the value of
CDBVariant::m_dwType. If m_dwType is set to DBVT_WSTRING, then m_pstringW contains a valid pointer; otherwise,
accessing m_pstringW will produce unreliable results.

See also
Hierarchy Chart
CRecordset Class
CDC Class
4/21/2020 • 187 minutes to read • Edit Online

Defines a class of device-context objects.

Syntax
class CDC : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDC::CDC Constructs a CDC object.

Public Methods
NAME DESC RIP T IO N

CDC::AbortDoc Terminates the current print job, erasing everything the


application has written to the device since the last call of
the StartDoc member function.

CDC::AbortPath Closes and discards any paths in the device context.

CDC::AddMetaFileComment Copies the comment from a buffer into a specified


enhanced-format metafile.

CDC::AlphaBlend Displays bitmaps that have transparent or


semitransparent pixels.

CDC::AngleArc Draws a line segment and an arc, and moves the current
position to the ending point of the arc.

CDC::Arc Draws an elliptical arc.

CDC::ArcTo Draws an elliptical arc. This function is similar to Arc ,


except that the current position is updated.

CDC::Attach Attaches a Windows device context to this CDC object.

CDC::BeginPath Opens a path bracket in the device context.

CDC::BitBlt Copies a bitmap from a specified device context.

CDC::Chord Draws a chord (a closed figure bounded by the


intersection of an ellipse and a line segment).
NAME DESC RIP T IO N

CDC::CloseFigure Closes an open figure in a path.

CDC::CreateCompatibleDC Creates a memory-device context that is compatible with


another device context. You can use it to prepare images
in memory.

CDC::CreateDC Creates a device context for a specific device.

CDC::CreateIC Creates an information context for a specific device. This


provides a fast way to get information about the device
without creating a device context.

CDC::DeleteDC Deletes the Windows device context associated with this


CDC object.

CDC::DeleteTempMap Called by the CWinApp idle-time handler to delete any


temporary CDC object created by FromHandle . Also
detaches the device context.

CDC::Detach Detaches the Windows device context from this CDC


object.

CDC::DPtoHIMETRIC Converts device units into HIMETRIC units.

CDC::DPtoLP Converts device units into logical units.

CDC::Draw3dRect Draws a three-dimensional rectangle.

CDC::DrawDragRect Erases and redraws a rectangle as it is dragged.

CDC::DrawEdge Draws the edges of a rectangle.

CDC::DrawEscape Accesses drawing capabilities of a video display that are


not directly available through the graphics device
interface (GDI).

CDC::DrawFocusRect Draws a rectangle in the style used to indicate focus.

CDC::DrawFrameControl Draw a frame control.

CDC::DrawIcon Draws an icon.

CDC::DrawState Displays an image and applies a visual effect to indicate a


state.

CDC::DrawText Draws formatted text in the specified rectangle.

CDC::DrawTextEx Draws formatted text in the specified rectangle using


additional formats.

CDC::Ellipse Draws an ellipse.


NAME DESC RIP T IO N

CDC::EndDoc Ends a print job started by the StartDoc member


function.

CDC::EndPage Informs the device driver that a page is ending.

CDC::EndPath Closes a path bracket and selects the path defined by the
bracket into the device context.

CDC::EnumObjects Enumerates the pens and brushes available in a device


context.

CDC::Escape Allows applications to access facilities that are not directly


available from a particular device through GDI. Also
allows access to Windows escape functions. Escape calls
made by an application are translated and sent to the
device driver.

CDC::ExcludeClipRect Creates a new clipping region that consists of the existing


clipping region minus the specified rectangle.

CDC::ExcludeUpdateRgn Prevents drawing within invalid areas of a window by


excluding an updated region in the window from a
clipping region.

CDC::ExtFloodFill Fills an area with the current brush. Provides more


flexibility than the CDC::FloodFill member function.

CDC::ExtTextOut Writes a character string within a rectangular region


using the currently selected font.

CDC::FillPath Closes any open figures in the current path and fills the
path's interior by using the current brush and polygon-
filling mode.

CDC::FillRect Fills a given rectangle by using a specific brush.

CDC::FillRgn Fills a specific region with the specified brush.

CDC::FillSolidRect Fills a rectangle with a solid color.

CDC::FlattenPath Transforms any curves in the path selected into the


current device context, and turns each curve into a
sequence of lines.

CDC::FloodFill Fills an area with the current brush.

CDC::FrameRect Draws a border around a rectangle.

CDC::FrameRgn Draws a border around a specific region using a brush.


NAME DESC RIP T IO N

CDC::FromHandle Returns a pointer to a CDC object when given a handle


to a device context. If a CDC object is not attached to
the handle, a temporary CDC object is created and
attached.

CDC::GetArcDirection Returns the current arc direction for the device context.

CDC::GetAspectRatioFilter Retrieves the setting for the current aspect-ratio filter.

CDC::GetBkColor Retrieves the current background color.

CDC::GetBkMode Retrieves the background mode.

CDC::GetBoundsRect Returns the current accumulated bounding rectangle for


the specified device context.

CDC::GetBrushOrg Retrieves the origin of the current brush.

CDC::GetCharABCWidths Retrieves the widths, in logical units, of consecutive


characters in a given range from the current font.

CDC::GetCharABCWidthsI Retrieves the widths, in logical units, of consecutive glyph


indices in a specified range from the current TrueType
font.

CDC::GetCharacterPlacement Retrieves various types of information on a character


string.

CDC::GetCharWidth Retrieves the fractional widths of consecutive characters


in a given range from the current font.

CDC::GetCharWidthI Retrieves the widths, in logical coordinates, of consecutive


glyph indices in a specified range from the current font.

CDC::GetClipBox Retrieves the dimensions of the tightest bounding


rectangle around the current clipping boundary.

CDC::GetColorAdjustment Retrieves the color adjustment values for the device


context.

CDC::GetCurrentBitmap Returns a pointer to the currently selected CBitmap


object.

CDC::GetCurrentBrush Returns a pointer to the currently selected CBrush


object.

CDC::GetCurrentFont Returns a pointer to the currently selected CFont object.

CDC::GetCurrentPalette Returns a pointer to the currently selected CPalette


object.

CDC::GetCurrentPen Returns a pointer to the currently selected CPen object.


NAME DESC RIP T IO N

CDC::GetCurrentPosition Retrieves the current position of the pen (in logical


coordinates).

CDC::GetDCBrushColor Retrieves the current brush color.

CDC::GetDCPenColor Retrieves the current pen color.

CDC::GetDeviceCaps Retrieves a specified kind of device-specific information


about a given display device's capabilities.

CDC::GetFontData Retrieves font metric information from a scalable font file.


The information to retrieve is identified by specifying an
offset into the font file and the length of the information
to return.

CDC::GetFontLanguageInfo Returns information about the currently selected font for


the specified display context.

CDC::GetGlyphOutline Retrieves the outline curve or bitmap for an outline


character in the current font.

CDC::GetGraphicsMode Retrieves the current graphics mode for the specified


device context.

CDC::GetHalftoneBrush Retrieves a halftone brush.

CDC::GetKerningPairs Retrieves the character kerning pairs for the font that is
currently selected in the specified device context.

CDC::GetLayout Retrieves the layout of a device context (DC). The layout


can be either left to right (default) or right to left
(mirrored).

CDC::GetMapMode Retrieves the current mapping mode.

CDC::GetMiterLimit Returns the miter limit for the device context.

CDC::GetNearestColor Retrieves the closest logical color to a specified logical


color that the given device can represent.

CDC::GetOutlineTextMetrics Retrieves font metric information for TrueType fonts.

CDC::GetOutputCharWidth Retrieves the widths of individual characters in a


consecutive group of characters from the current font
using the output device context.

CDC::GetOutputTabbedTextExtent Computes the width and height of a character string on


the output device context.

CDC::GetOutputTextExtent Computes the width and height of a line of text on the


output device context using the current font to
determine the dimensions.
NAME DESC RIP T IO N

CDC::GetOutputTextMetrics Retrieves the metrics for the current font from the output
device context.

CDC::GetPath Retrieves the coordinates defining the endpoints of lines


and the control points of curves found in the path that is
selected into the device context.

CDC::GetPixel Retrieves the RGB color value of the pixel at the specified
point.

CDC::GetPolyFillMode Retrieves the current polygon-filling mode.

CDC::GetROP2 Retrieves the current drawing mode.

CDC::GetSafeHdc Returns CDC::m_hDC, the output device context.

CDC::GetStretchBltMode Retrieves the current bitmap-stretching mode.

CDC::GetTabbedTextExtent Computes the width and height of a character string on


the attribute device context.

CDC::GetTextAlign Retrieves the text-alignment flags.

CDC::GetTextCharacterExtra Retrieves the current setting for the amount of


intercharacter spacing.

CDC::GetTextColor Retrieves the current text color.

CDC::GetTextExtent Computes the width and height of a line of text on the


attribute device context using the current font to
determine the dimensions.

CDC::GetTextExtentExPointI Retrieves the number of characters in a specified string


that will fit within a specified space and fills an array with
the text extent for each of those characters.

CDC::GetTextExtentPointI Retrieves the width and height of the specified array of


glyph indices.

CDC::GetTextFace Copies the typeface name of the current font into a


buffer as a null-terminated string.

CDC::GetTextMetrics Retrieves the metrics for the current font from the
attribute device context.

CDC::GetViewportExt Retrieves the x- and y-extents of the viewport.

CDC::GetViewportOrg Retrieves the x- and y-coordinates of the viewport origin.

CDC::GetWindow Returns the window associated with the display device


context.

CDC::GetWindowExt Retrieves the x- and y-extents of the associated window.


NAME DESC RIP T IO N

CDC::GetWindowOrg Retrieves the x- and y-coordinates of the origin of the


associated window.

CDC::GetWorldTransform Retrieves the current world-space to page-space


transformation.

CDC::GradientFill Fills rectangle and triangle structures with a gradating


color.

CDC::GrayString Draws dimmed (grayed) text at the given location.

CDC::HIMETRICtoDP Converts HIMETRIC units into device units.

CDC::HIMETRICtoLP Converts HIMETRIC units into logical units.

CDC::IntersectClipRect Creates a new clipping region by forming the intersection


of the current region and a rectangle.

CDC::InvertRect Inverts the contents of a rectangle.

CDC::InvertRgn Inverts the colors in a region.

CDC::IsPrinting Determines whether the device context is being used for


printing.

CDC::LineTo Draws a line from the current position up to, but not
including, a point.

CDC::LPtoDP Converts logical units into device units.

CDC::LPtoHIMETRIC Converts logical units into HIMETRIC units.

CDC::MaskBlt Combines the color data for the source and destination
bitmaps using the given mask and raster operation.

CDC::ModifyWorldTransform Changes the world transformation for a device context


using the specified mode.

CDC::MoveTo Moves the current position.

CDC::OffsetClipRgn Moves the clipping region of the given device.

CDC::OffsetViewportOrg Modifies the viewport origin relative to the coordinates


of the current viewport origin.

CDC::OffsetWindowOrg Modifies the window origin relative to the coordinates of


the current window origin.

CDC::PaintRgn Fills a region with the selected brush.

CDC::PatBlt Creates a bit pattern.


NAME DESC RIP T IO N

CDC::Pie Draws a pie-shaped wedge.

CDC::PlayMetaFile Plays the contents of the specified metafile on the given


device. The enhanced version of PlayMetaFile displays
the picture stored in the given enhanced-format metafile.
The metafile can be played any number of times.

CDC::PlgBlt Performs a bit-block transfer of the bits of color data


from the specified rectangle in the source device context
to the specified parallelogram in the given device context.

CDC::PolyBezier Draws one or more Bzier splines. The current position is


neither used nor updated.

CDC::PolyBezierTo Draws one or more Bzier splines, and moves the current
position to the ending point of the last Bzier spline.

CDC::PolyDraw Draws a set of line segments and Bzier splines. This


function updates the current position.

CDC::Polygon Draws a polygon consisting of two or more points


(vertices) connected by lines.

CDC::Polyline Draws a set of line segments connecting the specified


points.

CDC::PolylineTo Draws one or more straight lines and moves the current
position to the ending point of the last line.

CDC::PolyPolygon Creates two or more polygons that are filled using the
current polygon-filling mode. The polygons may be
disjoint or they may overlap.

CDC::PolyPolyline Draws multiple series of connected line segments. The


current position is neither used nor updated by this
function.

CDC::PtVisible Specifies whether the given point is within the clipping


region.

CDC::RealizePalette Maps palette entries in the current logical palette to the


system palette.

CDC::Rectangle Draws a rectangle using the current pen and fills it using
the current brush.

CDC::RectVisible Determines whether any part of the given rectangle lies


within the clipping region.

CDC::ReleaseAttribDC Releases m_hAttribDC , the attribute device context.

CDC::ReleaseOutputDC Releases m_hDC , the output device context.


NAME DESC RIP T IO N

CDC::ResetDC Updates the m_hAttribDC device context.

CDC::RestoreDC Restores the device context to a previous state saved


with SaveDC .

CDC::RoundRect Draws a rectangle with rounded corners using the


current pen and filled using the current brush.

CDC::SaveDC Saves the current state of the device context.

CDC::ScaleViewportExt Modifies the viewport extent relative to the current


values.

CDC::ScaleWindowExt Modifies the window extents relative to the current


values.

CDC::ScrollDC Scrolls a rectangle of bits horizontally and vertically.

CDC::SelectClipPath Selects the current path as a clipping region for the


device context, combining the new region with any
existing clipping region by using the specified mode.

CDC::SelectClipRgn Combines the given region with the current clipping


region by using the specified mode.

CDC::SelectObject Selects a GDI drawing object such as a pen.

CDC::SelectPalette Selects the logical palette.

CDC::SelectStockObject Selects one of the predefined stock pens, brushes, or


fonts provided by Windows.

CDC::SetAbortProc Sets a programmer-supplied callback function that


Windows calls if a print job must be aborted.

CDC::SetArcDirection Sets the drawing direction to be used for arc and


rectangle functions.

CDC::SetAttribDC Sets m_hAttribDC , the attribute device context.

CDC::SetBkColor Sets the current background color.

CDC::SetBkMode Sets the background mode.

CDC::SetBoundsRect Controls the accumulation of bounding-rectangle


information for the specified device context.

CDC::SetBrushOrg Specifies the origin for the next brush selected into a
device context.

CDC::SetColorAdjustment Sets the color adjustment values for the device context
using the specified values.
NAME DESC RIP T IO N

CDC::SetDCBrushColor Sets the current brush color.

CDC::SetDCPenColor Sets the current pen color.

CDC::SetGraphicsMode Sets the current graphics mode for the specified device
context.

CDC::SetLayout Changes the layout of a device context (DC).

CDC::SetMapMode Sets the current mapping mode.

CDC::SetMapperFlags Alters the algorithm that the font mapper uses when it
maps logical fonts to physical fonts.

CDC::SetMiterLimit Sets the limit for the length of miter joins for the device
context.

CDC::SetOutputDC Sets m_hDC , the output device context.

CDC::SetPixel Sets the pixel at the specified point to the closest


approximation of the specified color.

CDC::SetPixelV Sets the pixel at the specified coordinates to the closest


approximation of the specified color. SetPixelV is faster
than SetPixel because it does not need to return the
color value of the point actually painted.

CDC::SetPolyFillMode Sets the polygon-filling mode.

CDC::SetROP2 Sets the current drawing mode.

CDC::SetStretchBltMode Sets the bitmap-stretching mode.

CDC::SetTextAlign Sets the text-alignment flags.

CDC::SetTextCharacterExtra Sets the amount of intercharacter spacing.

CDC::SetTextColor Sets the text color.

CDC::SetTextJustification Adds space to the break characters in a string.

CDC::SetViewportExt Sets the x- and y-extents of the viewport.

CDC::SetViewportOrg Sets the viewport origin.

CDC::SetWindowExt Sets the x- and y-extents of the associated window.

CDC::SetWindowOrg Sets the window origin of the device context.

CDC::SetWorldTransform Sets the current world-space to page-space


transformation.
NAME DESC RIP T IO N

CDC::StartDoc Informs the device driver that a new print job is starting.

CDC::StartPage Informs the device driver that a new page is starting.

CDC::StretchBlt Moves a bitmap from a source rectangle and device into


a destination rectangle, stretching or compressing the
bitmap if necessary to fit the dimensions of the
destination rectangle.

CDC::StrokeAndFillPath Closes any open figures in a path, strikes the outline of


the path by using the current pen, and fills its interior by
using the current brush.

CDC::StrokePath Renders the specified path by using the current pen.

CDC::TabbedTextOut Writes a character string at a specified location,


expanding tabs to the values specified in an array of tab-
stop positions.

CDC::TextOut Writes a character string at a specified location using the


currently selected font.

CDC::TransparentBlt Transfers a bit-block of color data from the specified


source device context into a destination device context,
rendering a specified color transparent in the transfer.

CDC::UpdateColors Updates the client area of the device context by matching


the current colors in the client area to the system palette
on a pixel-by-pixel basis.

CDC::WidenPath Redefines the current path as the area that would be


painted if the path were stroked using the pen currently
selected into the device context.

Public Operators
NAME DESC RIP T IO N

CDC::operator HDC Retrieves the handle of the device context.

Public Data Members


NAME DESC RIP T IO N

CDC::m_hAttribDC The attribute-device context used by this CDC object.

CDC::m_hDC The output-device context used by this CDC object.

Remarks
The CDC object provides member functions for working with a device context, such as a display or printer,
as well as members for working with a display context associated with the client area of a window.
Do all drawing through the member functions of a CDC object. The class provides member functions for
device-context operations, working with drawing tools, type-safe graphics device interface (GDI) object
selection, and working with colors and palettes. It also provides member functions for getting and setting
drawing attributes, mapping, working with the viewport, working with the window extent, converting
coordinates, working with regions, clipping, drawing lines, and drawing simple shapes, ellipses, and
polygons. Member functions are also provided for drawing text, working with fonts, using printer escapes,
scrolling, and playing metafiles.
To use a CDC object, construct it, and then call its member functions that parallel Windows functions that
use device contexts.

NOTE
Under Windows 95/98, all screen coordinates are limited to 16 bits. Therefore, an int passed to a CDC member
function must lie in the range -32768 to 32767.

For specific uses, the Microsoft Foundation Class Library provides several classes derived from CDC .
CPaintDC encapsulates calls to BeginPaint and EndPaint . CClientDC manages a display context
associated with a window's client area. CWindowDC manages a display context associated with an entire
window, including its frame and controls. CMetaFileDC associates a device context with a metafile.
CDC provides two member functions, GetLayout and SetLayout, for reversing the layout of a device
context, which does not inherit its layout from a window. Such right-to-left orientation is necessary for
applications written for cultures, such as Arabic or Hebrew, where the character layout is not the European
standard.
CDC contains two device contexts, m_hDC and m_hAttribDC, which, on creation of a CDC object, refer to
the same device. CDC directs all output GDI calls to m_hDC and most attribute GDI calls to m_hAttribDC .
(An example of an attribute call is GetTextColor , while SetTextColor is an output call.)
For example, the framework uses these two device contexts to implement a CMetaFileDC object that will
send output to a metafile while reading attributes from a physical device. Print preview is implemented in
the framework in a similar fashion. You can also use the two device contexts in a similar way in your
application-specific code.
There are times when you may need text-metric information from both the m_hDC and m_hAttribDC
device contexts. The following pairs of functions provide this capability:

USES M _H AT T RIB DC USES M _H DC

GetTextExtent GetOutputTextExtent

GetTabbedTextExtent GetOutputTabbedTextExtent

GetTextMetrics GetOutputTextMetrics

GetCharWidth GetOutputCharWidth

For more information on CDC , see Device Contexts.

Inheritance Hierarchy
CObject
CDC

Requirements
Header : afxwin.h

CDC::AbortDoc
Terminates the current print job and erases everything the application has written to the device since the
last call to the StartDoc member function.

int AbortDoc();

Return Value
A value greater than or equal to 0 if successful, or a negative value if an error has occurred. The following
list shows common error values and their meanings:
SP_ERROR General error.
SP_OUTOFDISK Not enough disk space is currently available for spooling, and no more space will
become available.
SP_OUTOFMEMORY Not enough memory is available for spooling.
SP_USERABORT User terminated the job through the Print Manager.
Remarks
This member function replaces the ABORTDOC printer escape.
AbortDoc should be used to terminate the following:
Printing operations that do not specify an abort function using SetAbortProc.
Printing operations that have not yet reached their first NEWFRAME or NEXTBAND escape call.
If an application encounters a printing error or a canceled print operation, it must not attempt to terminate
the operation by using either the EndDoc or AbortDoc member functions of class CDC . GDI automatically
terminates the operation before returning the error value.
If the application displays a dialog box to allow the user to cancel the print operation, it must call
AbortDoc before destroying the dialog box.

If Print Manager was used to start the print job, calling AbortDoc erases the entire spool job — the printer
receives nothing. If Print Manager was not used to start the print job, the data may have been sent to the
printer before AbortDoc was called. In this case, the printer driver would have reset the printer (when
possible) and closed the print job.
Example
See the example for CDC::StartDoc.

CDC::AbortPath
Closes and discards any paths in the device context.

BOOL AbortPath();
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
If there is an open path bracket in the device context, the path bracket is closed and the path is discarded. If
there is a closed path in the device context, the path is discarded.

CDC::AddMetaFileComment
Copies the comment from a buffer into a specified enhanced-format metafile.

BOOL AddMetaFileComment(
UINT nDataSize,
const BYTE* pCommentData);

Parameters
nDataSize
Specifies the length of the comment buffer, in bytes.
pCommentData
Points to the buffer that contains the comment.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
A comment may include any private information — for example, the source of the picture and the date it
was created. A comment should begin with an application signature, followed by the data. Comments
should not contain position-specific data. Position-specific data specifies the location of a record, and it
should not be included because one metafile may be embedded within another metafile. This function can
only be used with enhanced metafiles.

CDC::AlphaBlend
Call this member function to display bitmaps that have transparent or semitransparent pixels.

BOOL AlphaBlend(
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight,
BLENDFUNCTION blend);

Parameters
xDest
Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
yDest
Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
nDestWidth
Specifies the width, in logical units, of the destination rectangle.
nDestHeight
Specifies the height, in logical units, of the destination rectangle.
pSrcDC
A pointer to the source device context.
xSrc
Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.
ySrc
Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.
nSrcWidth
Specifies the width, in logical units, of the source rectangle.
nSrcHeight
Specifies the height, in logical units, of the source rectangle.
blend
Specifies a BLENDFUNCTION structure.
Return Value
TRUE if successful; otherwise FALSE.
Remarks
See AlphaBlend in the Windows SDK for more information.

CDC::AngleArc
Draws a line segment and an arc.

BOOL AngleArc(
int x,
int y,
int nRadius,
float fStartAngle,
float fSweepAngle);

Parameters
x
Specifies the logical x-coordinate of the center of the circle.
y
Specifies the logical y-coordinate of the center of the circle.
nRadius
Specifies the radius of the circle in logical units. This value must be positive.
fStartAngle
Specifies the starting angle in degrees relative to the x-axis.
fSweepAngle
Specifies the sweep angle in degrees relative to the starting angle.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The line segment is drawn from the current position to the beginning of the arc. The arc is drawn along
the perimeter of a circle with the given radius and center. The length of the arc is defined by the given start
and sweep angles.
AngleArc moves the current position to the ending point of the arc. The arc drawn by this function may
appear to be elliptical, depending on the current transformation and mapping mode. Before drawing the
arc, this function draws the line segment from the current position to the beginning of the arc. The arc is
drawn by constructing an imaginary circle with the specified radius around the specified center point. The
starting point of the arc is determined by measuring counterclockwise from the x-axis of the circle by the
number of degrees in the start angle. The ending point is similarly located by measuring counterclockwise
from the starting point by the number of degrees in the sweep angle.
If the sweep angle is greater than 360 degrees the arc is swept multiple times. This function draws lines by
using the current pen. The figure is not filled.

CDC::Arc
Draws an elliptical arc.

BOOL Arc(
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4);

BOOL Arc(
LPCRECT lpRect,
POINT ptStart,
POINT ptEnd);

Parameters
x1
Specifies the x-coordinate of the upper-left corner of the bounding rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the bounding rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the bounding rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the bounding rectangle (in logical units).
x3
Specifies the x-coordinate of the point that defines the arc's starting point (in logical units). This point does
not have to lie exactly on the arc.
y3
Specifies the y-coordinate of the point that defines the arc's starting point (in logical units). This point does
not have to lie exactly on the arc.
x4
Specifies the x-coordinate of the point that defines the arc's endpoint (in logical units). This point does not
have to lie exactly on the arc.
y4
Specifies the y-coordinate of the point that defines the arc's endpoint (in logical units). This point does not
have to lie exactly on the arc.
lpRect
Specifies the bounding rectangle (in logical units). You can pass either an LPRECT or a CRect object for this
parameter.
ptStart
Specifies the x- and y-coordinates of the point that defines the arc's starting point (in logical units). This
point does not have to lie exactly on the arc. You can pass either a POINT structure or a CPoint object for
this parameter.
ptEnd
Specifies the x- and y-coordinates of the point that defines the arc's ending point (in logical units). This
point does not have to lie exactly on the arc. You can pass either a POINT structure or a CPoint object for
this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The arc drawn by using the function is a segment of the ellipse defined by the specified bounding
rectangle.
The actual starting point of the arc is the point at which a ray drawn from the center of the bounding
rectangle through the specified starting point intersects the ellipse. The actual ending point of the arc is
the point at which a ray drawn from the center of the bounding rectangle through the specified ending
point intersects the ellipse. The arc is drawn in a counterclockwise direction. Since an arc is not a closed
figure, it is not filled. Both the width and height of the rectangle must be greater than 2 units and less than
32,767 units.
Example
void CDCView::DrawArc(CDC *pDC)
{
// Fill the client area with a thin circle. The circle's
// interior is not filled. The circle's perimeter is
// blue from 6 o'clock to 3 o'clock and red from 3
// o'clock to 6 o'clock.

// Get the client area.


CRect rectClient;
GetClientRect(rectClient);

// Make a couple of pens.


CPen penBlue;
CPen penRed;
CPen *pOldPen;

penBlue.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(0, 0, 255));


penRed.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(255, 0, 0));

// Draw from 3 o'clock to 6 o'clock, counterclockwise,


// in a blue pen.

pOldPen = pDC->SelectObject(&penBlue);

pDC->Arc(rectClient,
CPoint(rectClient.right, rectClient.CenterPoint().y),
CPoint(rectClient.CenterPoint().x, rectClient.right));

// Draw from 6 o'clock to 3 o'clock, counterclockwise,


// in a red pen.
pDC->SelectObject(&penRed);

// Keep the same parameters, but reverse start


// and end points.
pDC->Arc(rectClient,
CPoint(rectClient.CenterPoint().x, rectClient.right),
CPoint(rectClient.right, rectClient.CenterPoint().y));

// Restore the previous pen.


pDC->SelectObject(pOldPen);
}

CDC::ArcTo
Draws an elliptical arc.

BOOL ArcTo(
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4);

BOOL ArcTo(
LPCRECT lpRect,
POINT ptStart,
POINT ptEnd);

Parameters
x1
Specifies the x-coordinate of the upper-left corner of the bounding rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the bounding rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the bounding rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the bounding rectangle (in logical units).
x3
Specifies the x-coordinate of the point that defines the arc's starting point (in logical units). This point does
not have to lie exactly on the arc.
y3
Specifies the y-coordinate of the point that defines the arc's starting point (in logical units). This point does
not have to lie exactly on the arc.
x4
Specifies the x-coordinate of the point that defines the arc's endpoint (in logical units). This point does not
have to lie exactly on the arc.
y4
Specifies the y-coordinate of the point that defines the arc's endpoint (in logical units). This point does not
have to lie exactly on the arc.
lpRect
Specifies the bounding rectangle (in logical units). You can pass either a pointer to a RECT data structure or
a CRect object for this parameter.
ptStart
Specifies the x- and y-coordinates of the point that defines the arc's starting point (in logical units). This
point does not have to lie exactly on the arc. You can pass either a POINT data structure or a CPoint object
for this parameter.
ptEnd
Specifies the x- and y-coordinates of the point that defines the arc's ending point (in logical units). This
point does not have to lie exactly on the arc. You can pass either a POINT data structure or a CPoint
object for this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This function is similar to CDC::Arc , except that the current position is updated. The points ( x1, y1) and (
x2, y2) specify the bounding rectangle. An ellipse formed by the given bounding rectangle defines the
curve of the arc. The arc extends counterclockwise (the default arc direction) from the point where it
intersects the radial line from the center of the bounding rectangle to ( x3, y3). The arc ends where it
intersects the radial line from the center of the bounding rectangle to ( x4, y4). If the starting point and
ending point are the same, a complete ellipse is drawn.
A line is drawn from the current position to the starting point of the arc. If no error occurs, the current
position is set to the ending point of the arc. The arc is drawn using the current pen; it is not filled.

CDC::Attach
Use this member function to attach an hDC to the CDC object.

BOOL Attach(HDC hDC);

Parameters
hDC
A Windows device context.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The hDC is stored in both m_hDC , the output device context, and in m_hAttribDC , the attribute device
context.

CDC::BeginPath
Opens a path bracket in the device context.

BOOL BeginPath();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
After a path bracket is open, an application can begin calling GDI drawing functions to define the points
that lie in the path. An application can close an open path bracket by calling the EndPath member
function. When an application calls BeginPath , any previous paths are discarded.
See BeginPath in the Windows SDK for a list of the drawing functions that define points in a path.
Example

// This implementation uses GDI paths to draw the outline of


// some text in a TrueType font. The path is used to record the way
// the TrueType font would be drawn. Then, the function uses the data
// returned from CDC::GetPath() to draw the font--without filling it.
void CDCView::DrawPath(CDC *pDC)
{
// Describe a 24-point truetype font of normal weight
LOGFONT lf;
memset(&lf, 0, sizeof(lf));
lf.lfHeight = -MulDiv(24, pDC->GetDeviceCaps(LOGPIXELSY), 72);
lf.lfWeight = FW_NORMAL;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;

// create and select it


CFont newFont;
if (!newFont.CreateFontIndirect(&lf))
return;
CFont *pOldFont = pDC->SelectObject(&newFont);

// use a path to record how the text was drawn


pDC->BeginPath();
pDC->TextOut(10, 10, _T("Outline this!"));
pDC->EndPath();

// Find out how many points are in the path. Note that
// for long strings or complex fonts, this number might be
// for long strings or complex fonts, this number might be
// gigantic!
int nNumPts = pDC->GetPath(NULL, NULL, 0);
if (nNumPts == 0)
return;

// Allocate memory to hold points and stroke types from


// the path.
LPPOINT lpPoints = NULL;
LPBYTE lpTypes = NULL;
try
{
lpPoints = new POINT[nNumPts];
lpTypes = new BYTE[nNumPts];
}
catch (CException *pe)
{
delete[] lpPoints;
lpPoints = NULL;
delete[] lpTypes;
lpTypes = NULL;
pe->Delete();
}
if (lpPoints == NULL || lpTypes == NULL)
return;

// Now that we have the memory, really get the path data.
nNumPts = pDC->GetPath(lpPoints, lpTypes, nNumPts);

// If it worked, draw the lines. Windows 98 doesn't support


// the PolyDraw API, so we use our own member function to do
// similar work. If you're targeting only later versions of
// Windows, you can use the PolyDraw() API and avoid the
// COutlineView::PolyDraw() member function.

if (nNumPts != -1)
pDC->PolyDraw(lpPoints, lpTypes, nNumPts);

// Release the memory we used


delete[] lpPoints;
delete[] lpTypes;

// Put back the old font


pDC->SelectObject(pOldFont);

return;
}

CDC::BitBlt
Copies a bitmap from the source device context to this current device context.

BOOL BitBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
DWORD dwRop);

Parameters
x
Specifies the logical x-coordinate of the upper-left corner of the destination rectangle.
y
Specifies the logical y-coordinate of the upper-left corner of the destination rectangle.
nWidth
Specifies the width (in logical units) of the destination rectangle and source bitmap.
nHeight
Specifies the height (in logical units) of the destination rectangle and source bitmap.
pSrcDC
Pointer to a CDC object that identifies the device context from which the bitmap will be copied. It must be
NULL if dwRop specifies a raster operation that does not include a source.
xSrc
Specifies the logical x-coordinate of the upper-left corner of the source bitmap.
ySrc
Specifies the logical y-coordinate of the upper-left corner of the source bitmap.
dwRop
Specifies the raster operation to be performed. Raster-operation codes define how the GDI combines
colors in output operations that involve a current brush, a possible source bitmap, and a destination
bitmap. See BitBlt in the Windows SDK for a list of the raster-operation codes for dwRop and their
descriptions
For a complete list of raster-operation codes, see About Raster Operation Codes in the Windows SDK.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The application can align the windows or client areas on byte boundaries to ensure that the BitBlt
operations occur on byte-aligned rectangles. (Set the CS_BYTEALIGNWINDOW or CS_BYTEALIGNCLIENT
flags when you register the window classes.)
BitBlt operations on byte-aligned rectangles are considerably faster than BitBlt operations on
rectangles that are not byte aligned. If you want to specify class styles such as byte-alignment for your
own device context, you will have to register a window class rather than relying on the Microsoft
Foundation classes to do it for you. Use the global function AfxRegisterWndClass.
GDI transforms nWidth and nHeight, once by using the destination device context, and once by using the
source device context. If the resulting extents do not match, GDI uses the Windows StretchBlt function to
compress or stretch the source bitmap as necessary.
If destination, source, and pattern bitmaps do not have the same color format, the BitBlt function
converts the source and pattern bitmaps to match the destination. The foreground and background colors
of the destination bitmap are used in the conversion.
When the BitBlt function converts a monochrome bitmap to color, it sets white bits (1) to the
background color and black bits (0) to the foreground color. The foreground and background colors of the
destination device context are used. To convert color to monochrome, BitBlt sets pixels that match the
background color to white and sets all other pixels to black. BitBlt uses the foreground and background
colors of the color device context to convert from color to monochrome.
Note that not all device contexts support BitBlt . To check whether a given device context does support
BitBlt , use the GetDeviceCaps member function and specify the RASTERCAPS index.
Example
See the example for CDC::CreateCompatibleDC.

CDC::CDC
Constructs a CDC object.

CDC();

CDC::Chord
Draws a chord (a closed figure bounded by the intersection of an ellipse and a line segment).

BOOL Chord(
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4);

BOOL Chord(
LPCRECT lpRect,
POINT ptStart,
POINT ptEnd);

Parameters
x1
Specifies the x-coordinate of the upper-left corner of the chord's bounding rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the chord's bounding rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the chord's bounding rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the chord's bounding rectangle (in logical units).
x3
Specifies the x-coordinate of the point that defines the chord's starting point (in logical units).
y3
Specifies the y-coordinate of the point that defines the chord's starting point (in logical units).
x4
Specifies the x-coordinate of the point that defines the chord's endpoint (in logical units).
y4
Specifies the y-coordinate of the point that defines the chord's endpoint (in logical units).
lpRect
Specifies the bounding rectangle (in logical units). You can pass either a LPRECT or a CRect object for this
parameter.
ptStart
Specifies the x- and y-coordinates of the point that defines the chord's starting point (in logical units). This
point does not have to lie exactly on the chord. You can pass either a POINT structure or a CPoint object
for this parameter.
ptEnd
Specifies the x- and y-coordinates of the point that defines the chord's ending point (in logical units). This
point does not have to lie exactly on the chord. You can pass either a POINT structure or a CPoint object for
this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The ( x1, y1) and ( x2, y2) parameters specify the upper-left and lower-right corners, respectively, of a
rectangle bounding the ellipse that is part of the chord. The ( x3, y3) and ( x4, y4) parameters specify the
endpoints of a line that intersects the ellipse. The chord is drawn by using the selected pen and filled by
using the selected brush.
The figure drawn by the Chord function extends up to, but does not include the right and bottom
coordinates. This means that the height of the figure is y2 - y1 and the width of the figure is x2 - x1.
Example
void CDCView::DrawChord(CDC *pDC)
{
// Fill the client area with a circle. The circle is
// blue and filled with blue, but has a chord cut out
// of it from 3 o'clock to 6 o'clock. That chord is
// red and filled with a red diagonal hatch.

// Get the client area.


CRect rectClient;
GetClientRect(rectClient);

// Make a couple of pens and similar brushes.


CPen penBlue, penRed;
CBrush brushBlue, brushRed;
CBrush *pOldBrush;
CPen *pOldPen;

brushBlue.CreateSolidBrush(RGB(0, 0, 255));
brushRed.CreateHatchBrush(HS_FDIAGONAL, RGB(255, 0, 0));
penBlue.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(0, 0, 255));
penRed.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(255, 0, 0));

// Draw from 3 o'clock to 6 o'clock, counterclockwise,


// in a blue pen with a solid blue fill.
pOldPen = pDC->SelectObject(&penBlue);
pOldBrush = pDC->SelectObject(&brushBlue);

pDC->Chord(rectClient,
CPoint(rectClient.right, rectClient.CenterPoint().y),
CPoint(rectClient.CenterPoint().x, rectClient.right));

// Draw the remaining quarter chord from 6 o'clock


// to 3 o'clock, counterclockwise, in a red pen
// with the hatched brush.
pDC->SelectObject(&penRed);
pDC->SelectObject(&brushRed);

// Keep the same parameters, but reverse start and


// end points.
pDC->Chord(rectClient,
CPoint(rectClient.CenterPoint().x, rectClient.right),
CPoint(rectClient.right, rectClient.CenterPoint().y));

// Restore the previous pen.


pDC->SelectObject(pOldPen);
}

CDC::CloseFigure
Closes an open figure in a path.

BOOL CloseFigure();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The function closes the figure by drawing a line from the current position to the first point of the figure
(usually, the point specified by the most recent call to the MoveTo member function) and connects the
lines by using the line join style. If a figure is closed by using the LineTo member function instead of
CloseFigure , end caps are used to create the corner instead of a join. CloseFigure should only be called if
there is an open path bracket in the device context.
A figure in a path is open unless it is explicitly closed by using this function. (A figure can be open even if
the current point and the starting point of the figure are the same.) Any line or curve added to the path
after CloseFigure starts a new figure.

CDC::CreateCompatibleDC
Creates a memory device context that is compatible with the device specified by pDC.

BOOL CreateCompatibleDC(CDC* pDC);

Parameters
pDC
A pointer to a device context. If pDC is NULL, the function creates a memory device context that is
compatible with the system display.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
A memory device context is a block of memory that represents a display surface. It can be used to prepare
images in memory before copying them to the actual device surface of the compatible device.
When a memory device context is created, GDI automatically selects a 1-by-1 monochrome stock bitmap
for it. GDI output functions can be used with a memory device context only if a bitmap has been created
and selected into that context.
This function can only be used to create compatible device contexts for devices that support raster
operations. See the CDC::BitBlt member function for information regarding bit-block transfers between
device contexts. To determine whether a device context supports raster operations, see the RC_BITBLT
raster capability in the member function CDC::GetDeviceCaps .
Example
// This handler loads a bitmap from system resources,
// centers it in the view, and uses BitBlt() to paint the bitmap
// bits.
void CDCView::DrawBitmap(CDC *pDC)
{
// load IDB_BITMAP1 from our resources
CBitmap bmp;
if (bmp.LoadBitmap(IDB_BITMAP1))
{
// Get the size of the bitmap
BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo);

// Create an in-memory DC compatible with the


// display DC we're using to paint
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);

// Select the bitmap into the in-memory DC


CBitmap *pOldBitmap = dcMemory.SelectObject(&bmp);

// Find a centerpoint for the bitmap in the client area


CRect rect;
GetClientRect(&rect);
int nX = rect.left + (rect.Width() - bmpInfo.bmWidth) / 2;
int nY = rect.top + (rect.Height() - bmpInfo.bmHeight) / 2;

// Copy the bits from the in-memory DC into the on-


// screen DC to actually do the painting. Use the centerpoint
// we computed for the target offset.
pDC->BitBlt(nX, nY, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMemory,
0, 0, SRCCOPY);

dcMemory.SelectObject(pOldBitmap);
}
else
{
TRACE0("ERROR: Where's IDB_BITMAP1?\n");
}
}

CDC::CreateDC
Creates a device context for the specified device.

BOOL CreateDC(
LPCTSTR lpszDriverName,
LPCTSTR lpszDeviceName,
LPCTSTR lpszOutput,
const void* lpInitData);

Parameters
lpszDriverName
Points to a null-terminated string that specifies the filename (without extension) of the device driver (for
example, "EPSON"). You can also pass a CString object for this parameter.
lpszDeviceName
Points to a null-terminated string that specifies the name of the specific device to be supported (for
example, "EPSON FX-80"). The lpszDeviceName parameter is used if the module supports more than one
device. You can also pass a CString object for this parameter.
lpszOutput
Points to a null-terminated string that specifies the file or device name for the physical output medium
(file or output port). You can also pass a CString object for this parameter.
lpInitData
Points to a DEVMODE structure containing device-specific initialization data for the device driver. The
Windows DocumentProperties function retrieves this structure filled in for a given device. The lpInitData
parameter must be NULL if the device driver is to use the default initialization (if any) specified by the user
through the Control Panel.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The PRINT.H header file is required if the DEVMODE structure is used.
Device names follow these conventions: an ending colon (:) is recommended, but optional. Windows strips
the terminating colon so that a device name ending with a colon is mapped to the same port as the same
name without a colon. The driver and port names must not contain leading or trailing spaces. GDI output
functions cannot be used with information contexts.

CDC::CreateIC
Creates an information context for the specified device.

BOOL CreateIC(
LPCTSTR lpszDriverName,
LPCTSTR lpszDeviceName,
LPCTSTR lpszOutput,
const void* lpInitData);

Parameters
lpszDriverName
Points to a null-terminated string that specifies the filename (without extension) of the device driver (for
example, "EPSON"). You can pass a CString object for this parameter.
lpszDeviceName
Points to a null-terminated string that specifies the name of the specific device to be supported (for
example, "EPSON FX-80"). The lpszDeviceName parameter is used if the module supports more than one
device. You can pass a CString object for this parameter.
lpszOutput
Points to a null-terminated string that specifies the file or device name for the physical output medium
(file or port). You can pass a CString object for this parameter.
lpInitData
Points to device-specific initialization data for the device driver. The lpInitData parameter must be NULL if
the device driver is to use the default initialization (if any) specified by the user through the Control Panel.
See CreateDC for the data format for device-specific initialization.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The information context provides a fast way to get information about the device without creating a device
context.
Device names follow these conventions: an ending colon (:) is recommended, but optional. Windows strips
the terminating colon so that a device name ending with a colon is mapped to the same port as the same
name without a colon. The driver and port names must not contain leading or trailing spaces. GDI output
functions cannot be used with information contexts.

CDC::DeleteDC
In general, do not call this function; the destructor will do it for you.

BOOL DeleteDC();

Return Value
Nonzero if the function completed successfully; otherwise 0.
Remarks
The DeleteDC member function deletes the Windows device contexts that are associated with m_hDC in
the current CDC object. If this CDC object is the last active device context for a given device, the device is
notified and all storage and system resources used by the device are released.
An application should not call DeleteDC if objects have been selected into the device context. Objects must
first be selected out of the device context before it is deleted.
An application must not delete a device context whose handle was obtained by calling CWnd::GetDC.
Instead, it must call CWnd::ReleaseDC to free the device context. The CClientDC and CWindowDC classes
are provided to wrap this functionality.
The DeleteDC function is generally used to delete device contexts created with CreateDC, CreateIC, or
CreateCompatibleDC.
Example
See the example for CPrintDialog::GetPrinterDC.

CDC::DeleteTempMap
Called automatically by the CWinApp idle-time handler, DeleteTempMap deletes any temporary CDC objects
created by FromHandle , but does not destroy the device context handles ( hDC s) temporarily associated
with the CDC objects.

static void PASCAL DeleteTempMap();

CDC::Detach
Call this function to detach m_hDC (the output device context) from the CDC object and set both m_hDC
and m_hAttribDC to NULL.

HDC Detach();

Return Value
A Windows device context.
CDC::DPtoHIMETRIC
Use this function when you give HIMETRIC sizes to OLE, converting pixels to HIMETRIC.

void DPtoHIMETRIC(LPSIZE lpSize) const;

Parameters
lpSize
Points to a SIZE structure or CSize object.
Remarks
If the mapping mode of the device context object is MM_LOENGLISH, MM_HIENGLISH, MM_LOMETRIC, or
MM_HIMETRIC, then the conversion is based on the number of pixels in the physical inch. If the mapping
mode is one of the other non-constrained modes (e.g., MM_TEXT), then the conversion is based on the
number of pixels in the logical inch.

CDC::DPtoLP
Converts device units into logical units.

void DPtoLP(
LPPOINT lpPoints,
int nCount = 1) const;

void DPtoLP(LPRECT lpRect) const;


void DPtoLP(LPSIZE lpSize) const;

Parameters
lpPoints
Points to an array of POINT structures or CPoint objects.
nCount
The number of points in the array.
lpRect
Points to a RECT structure or CRect object. This parameter is used for the simple case of converting one
rectangle from device points to logical points.
lpSize
Points to a SIZE structure or CSize object.
Remarks
The function maps the coordinates of each point, or dimension of a size, from the device coordinate
system into GDI's logical coordinate system. The conversion depends on the current mapping mode and
the settings of the origins and extents for the device's window and viewport.

CDC::Draw3dRect
Call this member function to draw a three-dimensional rectangle.
void Draw3dRect(
LPCRECT lpRect,
COLORREF clrTopLeft,
COLORREF clrBottomRight);

void Draw3dRect(
int x,
int y,
int cx,
int cy,
COLORREF clrTopLeft,
COLORREF clrBottomRight);

Parameters
lpRect
Specifies the bounding rectangle (in logical units). You can pass either a pointer to a RECT structure or a
CRect object for this parameter.
clrTopLeft
Specifies the color of the top and left sides of the three-dimensional rectangle.
clrBottomRight
Specifies the color of the bottom and right sides of the three-dimensional rectangle.
x
Specifies the logical x-coordinate of the upper-left corner of the three-dimensional rectangle.
y
Specifies the logical y-coordinate of the upper-left corner of the three-dimensional rectangle.
cx
Specifies the width of the three-dimensional rectangle.
cy
Specifies the height of the three-dimensional rectangle.
Remarks
The rectangle will be drawn with the top and left sides in the color specified by clrTopLeft and the bottom
and right sides in the color specified by clrBottomRight.
Example
void CDCView::Draw3dRect(CDC *pDC)
{
// get the client area
CRect rect;
GetClientRect(rect);

// shrink our rect 20 pixels on all sides


rect.DeflateRect(20, 20);

// draw a rectangle with red top and left sides, and


// green right and bottom sides.
pDC->Draw3dRect(rect, RGB(255, 0, 0), RGB(0, 255, 0));

// This call to the four-integer override would draw


// the same rectangle with a little less convenience:

// pDC->Draw3dRect(rect.left, rect.top, rect.Width(), rect.Height(),


// RGB(255, 0, 0), RGB(0, 255, 0));
}

CDC::DrawDragRect
Call this member function repeatedly to redraw a drag rectangle.

void DrawDragRect(
LPCRECT lpRect,
SIZE size,
LPCRECT lpRectLast,
SIZE sizeLast,
CBrush* pBrush = NULL,
CBrush* pBrushLast = NULL);

Parameters
lpRect
Points to a RECT structure or a CRect object that specifies the logical coordinates of a rectangle — in this
case, the end position of the rectangle being redrawn.
size
Specifies the displacement from the top-left corner of the outer border to the top-left corner of the inner
border (that is, the thickness of the border) of a rectangle.
lpRectLast
Points to a RECT structure or a CRect object that specifies the logical coordinates of the position of a
rectangle — in this case, the original position of the rectangle being redrawn.
sizeLast
Specifies the displacement from the top-left corner of the outer border to the top-left corner of the inner
border (that is, the thickness of the border) of the original rectangle being redrawn.
pBrush
Pointer to a brush object. Set to NULL to use the default halftone brush.
pBrushLast
Pointer to the last brush object used. Set to NULL to use the default halftone brush.
Remarks
Call it in a loop as you sample mouse position, in order to give visual feedback. When you call
DrawDragRect , the previous rectangle is erased and a new one is drawn. For example, as the user drags a
rectangle across the screen, DrawDragRect will erase the original rectangle and redraw a new one in its
new position. By default, DrawDragRect draws the rectangle by using a halftone brush to eliminate flicker
and to create the appearance of a smoothly moving rectangle.
The first time you call DrawDragRect , the lpRectLast parameter should be NULL.

CDC::DrawEdge
Call this member function to draw the edges of a rectangle of the specified type and style.

BOOL DrawEdge(
LPRECT lpRect,
UINT nEdge,
UINT nFlags);

Parameters
lpRect
A pointer to a RECT structure that contains the logical coordinates of the rectangle.
nEdge
Specifies the type of inner and outer edge to draw. This parameter must be a combination of one inner-
border flag and one outer-border flag. See DrawEdge in the Windows SDK for a table of the parameter's
types.
nFlags
The flags that specify the type of border to be drawn. See DrawEdge in the Windows SDK for a table of the
parameter's values. For diagonal lines, the BF_RECT flags specify the end point of the vector bounded by
the rectangle parameter.
Return Value
Nonzero if successful; otherwise 0.

CDC::DrawEscape
Accesses drawing capabilities of a video display that are not directly available through the graphics device
interface (GDI).

int DrawEscape(
int nEscape,
int nInputSize,
LPCSTR lpszInputData);

Parameters
nEscape
Specifies the escape function to be performed.
nInputSize
Specifies the number of bytes of data pointed to by the lpszInputData parameter.
lpszInputData
Points to the input structure required for the specified escape.
Return Value
Specifies the outcome of the function. Greater than zero if successful, except for the QUERYESCSUPPORT
draw escape, which checks for implementation only; or zero if the escape is not implemented; or less than
zero if an error occurred.
Remarks
When an application calls DrawEscape , the data identified by nInputSize and lpszInputData is passed
directly to the specified display driver.

CDC::DrawFocusRect
Draws a rectangle in the style used to indicate that the rectangle has the focus.

void DrawFocusRect(LPCRECT lpRect);

Parameters
lpRect
Points to a RECT structure or a CRect object that specifies the logical coordinates of the rectangle to be
drawn.
Remarks
Since this is a Boolean XOR function, calling this function a second time with the same rectangle removes
the rectangle from the display. The rectangle drawn by this function cannot be scrolled. To scroll an area
containing a rectangle drawn by this function, first call DrawFocusRect to remove the rectangle from the
display, then scroll the area, and then call DrawFocusRect again to draw the rectangle in the new position.
Cau t i on

DrawFocusRect works only in MM_TEXT mode. In other modes, this function does not draw the focus
rectangle correctly, but it does not return error values.

CDC::DrawFrameControl
Call this member function to draw a frame control of the specified type and style.

BOOL DrawFrameControl(
LPRECT lpRect,
UINT nType,
UINT nState);

Parameters
lpRect
A pointer to a RECT structure that contains the logical coordinates of the rectangle.
nType
Specifies the type of frame control to draw. See the uType parameter in DrawFrameControl in the
Windows SDK for a list of this parameter's possible values.
nState
Specifies the initial state of the frame control. Can be one or more of the values described for the uState
parameter in DrawFrameControl in the Windows SDK. Use the nState value DFCS_ADJUSTRECT to adjust
the bounding rectangle to exclude the surrounding edge of the push button.
Return Value
Nonzero if successful; otherwise 0.
Remarks
In several cases, nState depends on the nType parameter. The following list shows the relationship
between the four nType values and nState:
DFC_BUTTON
DFCS_BUTTON3STATE Three-state button
DFCS_BUTTONCHECK Check box
DFCS_BUTTONPUSH Push button
DFCS_BUTTONRADIO Radio button
DFCS_BUTTONRADIOIMAGE Image for radio button (nonsquare needs image)
DFCS_BUTTONRADIOMASK Mask for radio button (nonsquare needs mask)
DFC_CAPTION
DFCS_CAPTIONCLOSE Close button
DFCS_CAPTIONHELP Help button
DFCS_CAPTIONMAX Maximize button
DFCS_CAPTIONMIN Minimize button
DFCS_CAPTIONRESTORE Restore button
DFC_MENU
DFCS_MENUARROW Submenu arrow
DFCS_MENUBULLET Bullet
DFCS_MENUCHECK Check mark
DFC_SCROLL
DFCS_SCROLLCOMBOBOX Combo box scroll bar
DFCS_SCROLLDOWN Down arrow of scroll bar
DFCS_SCROLLLEFT Left arrow of scroll bar
DFCS_SCROLLRIGHT Right arrow of scroll bar
DFCS_SCROLLSIZEGRIP Size grip in bottom-right corner of window
DFCS_SCROLLUP Up arrow of scroll bar
Example
This code draws the size gripper in the bottom-right corner of your window. It's appropriate for the
OnPaint handler of a dialog box, which has no styles and normally doesn't contain other controls (like a
status bar) that may give it a size gripper.
void CDCView::DrawFC(CDC *pDC)
{
CRect rc;
GetClientRect(&rc);

rc.left = rc.right - ::GetSystemMetrics(SM_CXHSCROLL);


rc.top = rc.bottom - ::GetSystemMetrics(SM_CYVSCROLL);

pDC->DrawFrameControl(rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);


}

CDC::DrawIcon
Draws an icon on the device represented by the current CDC object.

BOOL DrawIcon(
int x,
int y,
HICON hIcon);

BOOL DrawIcon(
POINT point,
HICON hIcon);

Parameters
x
Specifies the logical x-coordinate of the upper-left corner of the icon.
y
Specifies the logical y-coordinate of the upper-left corner of the icon.
hIcon
Identifies the handle of the icon to be drawn.
point
Specifies the logical x- and y-coordinates of the upper-left corner of the icon. You can pass a POINT
structure or a CPoint object for this parameter.
Return Value
Nonzero if the function completed successfully; otherwise 0.
Remarks
The function places the icon's upper-left corner at the location specified by x and y. The location is subject
to the current mapping mode of the device context.
The icon resource must have been previously loaded by using the functions CWinApp::LoadIcon ,
CWinApp::LoadStandardIcon , or CWinApp::LoadOEMIcon . The MM_TEXT mapping mode must be selected prior
to using this function.
Example
See the example for CWnd::IsIconic.

CDC::DrawState
Call this member function to display an image and apply a visual effect to indicate a state, such as a
disabled or default state.
NOTE
For all nFlag states except DSS_NORMAL, the image is converted to monochrome before the visual effect is
applied.
BOOL DrawState(
CPoint pt,
CSize size,
HBITMAP hBitmap,
UINT nFlags,
HBRUSH hBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
CBitmap* pBitmap,
UINT nFlags,
CBrush* pBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
HICON hIcon,
UINT nFlags,
HBRUSH hBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
HICON hIcon,
UINT nFlags,
CBrush* pBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
LPCTSTR lpszText,
UINT nFlags,
BOOL bPrefixText = TRUE,
int nTextLen = 0,
HBRUSH hBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
LPCTSTR lpszText,
UINT nFlags,
BOOL bPrefixText = TRUE,
int nTextLen = 0,
CBrush* pBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
DRAWSTATEPROC lpDrawProc,
LPARAM lData,
UINT nFlags,
HBRUSH hBrush = NULL);

BOOL DrawState(
CPoint pt,
CSize size,
DRAWSTATEPROC lpDrawProc,
LPARAM lData,
UINT nFlags,
CBrush* pBrush = NULL);

Parameters
pt
Specifies the location of the image.
size
Specifies the size of the image.
hBitmap
A handle to a bitmap.
nFlags
Flags that specify the image type and state. See DrawState in the Windows SDK for the possible nFlags
types and states.
hBrush
A handle to a brush.
pBitmap
A pointer to a CBitmap object.
pBrush
A pointer to a CBrush object.
hIcon
A handle to an icon.
lpszText
A pointer to text.
bPrefixText
Text that may contain an accelerator mnemonic. The lData parameter specifies the address of the string,
and the nTextLen parameter specifies the length. If nTextLen is 0, the string is assumed to be null-
terminated.
nTextLen
Length of the text string pointed to by lpszText. If nTextLen is 0, the string is assumed to be null-terminated.
lpDrawProc
A pointer to a callback function used to render an image. This parameter is required if the image type in
nFlags is DST_COMPLEX. It is optional and can be NULL if the image type is DST_TEXT. For all other image
types, this parameter is ignored. For more information about the callback function, see the DrawStateProc
function in the Windows SDK.
lData
Specifies information about the image. The meaning of this parameter depends on the image type.
Return Value
Nonzero if successful; otherwise 0.

CDC::DrawText
Call this member function to format text in the given rectangle. To specify additional formatting options,
use CDC::DrawTextEx.
virtual int DrawText(
LPCTSTR lpszString,
int nCount,
LPRECT lpRect,
UINT nFormat);

int DrawText(
const CString& str,
LPRECT lpRect,
UINT nFormat);

Parameters
lpszString
Points to the string to be drawn. If nCount is -1, the string must be null-terminated.
nCount
Specifies the number of chars in the string. If nCount is -1, then lpszString is assumed to be a long pointer
to a null-terminated string and DrawText computes the character count automatically.
lpRect
Points to a RECT structure or CRect object that contains the rectangle (in logical coordinates) in which the
text is to be formatted.
str
A CString object that contains the specified characters to be drawn.
nFormat
Specifies the method of formatting the text. It can be any combination of the values described for the
uFormat parameter in DrawText in the Windows SDK. (combine using the bitwise OR operator):

NOTE
Some uFormat flag combinations can cause the passed string to be modified. Using DT_MODIFYSTRING with either
DT_END_ELLIPSIS or DT_PATH_ELLIPSIS may cause the string to be modified, causing an assertion in the CString
override. The values DT_CALCRECT, DT_EXTERNALLEADING, DT_INTERNAL, DT_NOCLIP, and DT_NOPREFIX cannot
be used with the DT_TABSTOP value.

Return Value
The height of the text if the function is successful.
Remarks
It formats text by expanding tabs into appropriate spaces, aligning text to the left, right, or center of the
given rectangle, and breaking text into lines that fit within the given rectangle. The type of formatting is
specified by nFormat.
This member function uses the device context's selected font, text color, and background color to draw the
text. Unless the DT_NOCLIP format is used, DrawText clips the text so that the text does not appear outside
the given rectangle. All formatting is assumed to have multiple lines unless the DT_SINGLELINE format is
given.
If the selected font is too large for the specified rectangle, the DrawText member function does not
attempt to substitute a smaller font.
If the DT_CALCRECT flag is specified, the rectangle specified by lpRect will be updated to reflect the width
and height needed to draw the text.
If the TA_UPDATECP text-alignment flag has been set (see CDC::SetTextAlign), DrawText will display text
starting at the current position, rather than at the left of the given rectangle. DrawText will not wrap text
when the TA_UPDATECP flag has been set (that is, the DT_WORDBREAK flag will have no effect).
The text color may be set by CDC::SetTextColor.

CDC::DrawTextEx
Formats text in the given rectangle.

virtual int DrawTextEx(


LPTSTR lpszString,
int nCount,
LPRECT lpRect,
UINT nFormat,
LPDRAWTEXTPARAMS lpDTParams);

int DrawTextEx(
const CString& str,
LPRECT lpRect,
UINT nFormat,
LPDRAWTEXTPARAMS lpDTParams);

Parameters
lpszString
Points to the string to be drawn. If nCount is -1, the string must be null terminated.
nCount
Specifies the number of chars in the string. If nCount is -1, then lpszString is assumed to be a long pointer
to a null-terminated string and DrawText computes the character count automatically.
lpRect
Points to a RECT structure or CRect object that contains the rectangle (in logical coordinates) in which the
text is to be formatted.
str
A CString object that contains the specified characters to be drawn.
nFormat
Specifies the method of formatting the text. It can be any combination of the values described for the
uFormat parameter in DrawText in the Windows SDK. (Combine using the bitwise OR operator):

NOTE
Some uFormat flag combinations can cause the passed string to be modified. Using DT_MODIFYSTRING with either
DT_END_ELLIPSIS or DT_PATH_ELLIPSIS may cause the string to be modified, causing an assertion in the CString
override. The values DT_CALCRECT, DT_EXTERNALLEADING, DT_INTERNAL, DT_NOCLIP, and DT_NOPREFIX cannot
be used with the DT_TABSTOP value.

lpDTParams
Pointer to a DRAWTEXTPARAMS structure that specifies additional formatting options. This parameter can
be NULL.
Remarks
It formats text by expanding tabs into appropriate spaces, aligning text to the left, right, or center of the
given rectangle, and breaking text into lines that fit within the given rectangle. The type of formatting is
specified by nFormat and lpDTParams. For more information, see CDC::DrawText and DrawTextEx in the
Windows SDK.
The text color may be set by CDC::SetTextColor.

CDC::Ellipse
Draws an ellipse.

BOOL Ellipse(
int x1,
int y1,
int x2,
int y2);

BOOL Ellipse(LPCRECT lpRect);

Parameters
x1
Specifies the logical x-coordinate of the upper-left corner of the ellipse's bounding rectangle.
y1
Specifies the logical y-coordinate of the upper-left corner of the ellipse's bounding rectangle.
x2
Specifies the logical x-coordinate of the lower-right corner of the ellipse's bounding rectangle.
y2
Specifies the logical y-coordinate of the lower-right corner of the ellipse's bounding rectangle.
lpRect
Specifies the ellipse's bounding rectangle. You can also pass a CRect object for this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The center of the ellipse is the center of the bounding rectangle specified by x1, y1, x2, and y2, or lpRect.
The ellipse is drawn with the current pen, and its interior is filled with the current brush.
The figure drawn by this function extends up to, but does not include, the right and bottom coordinates.
This means that the height of the figure is y2 - y1 and the width of the figure is x2 - x1.
If either the width or the height of the bounding rectangle is 0, no ellipse is drawn.

CDC::EndDoc
Ends a print job started by a call to the StartDoc member function.

int EndDoc();

Return Value
Greater than or equal to 0 if the function is successful, or a negative value if an error occurred.
Remarks
This member function replaces the ENDDOC printer escape, and should be called immediately after
finishing a successful print job.
If an application encounters a printing error or a canceled print operation, it must not attempt to terminate
the operation by using either EndDoc or AbortDoc. GDI automatically terminates the operation before
returning the error value.
This function should not be used inside metafiles.
Example
See the example for CDC::StartDoc.

CDC::EndPage
Informs the device that the application has finished writing to a page.

int EndPage();

Return Value
Greater than or equal to 0 if the function is successful, or a negative value if an error occurred.
Remarks
This member function is typically used to direct the device driver to advance to a new page.
This member function replaces the NEWFRAME printer escape. Unlike NEWFRAME, this function is always
called after printing a page.
Example
See the example for CDC::StartDoc.

CDC::EndPath
Closes a path bracket and selects the path defined by the bracket into the device context.

BOOL EndPath();

Return Value
Nonzero if the function is successful; otherwise 0.
Example
See the example for CDC::BeginPath.

CDC::EnumObjects
Enumerates the pens and brushes available in a device context.

int EnumObjects(
int nObjectType,
int (CALLBACK* lpfn)(
LPVOID,
LPARAM),
LPARAM lpData);

Parameters
nObjectType
Specifies the object type. It can have the values OBJ_BRUSH or OBJ_PEN.
lpfn
Is the procedure-instance address of the application-supplied callback function. See the "Remarks" section
below.
lpData
Points to the application-supplied data. The data is passed to the callback function along with the object
information.
Return Value
Specifies the last value returned by the callback function. Its meaning is user-defined.
Remarks
For each object of a given type, the callback function that you pass is called with the information for that
object. The system calls the callback function until there are no more objects or the callback function
returns 0.
Note that new features of Microsoft Visual C++ let you use an ordinary function as the function passed to
EnumObjects . The address passed to EnumObjects is a pointer to a function exported with EXPORT and
with the Pascal calling convention. In protect-mode applications, you do not have to create this function
with the Windows MakeProcInstance function or free the function after use with the FreeProcInstance
Windows function.
You also do not have to export the function name in an EXPORTS statement in your application's module-
definition file. You can instead use the EXPORT function modifier, as in
int CALLBACK EXPORT AFunction (LPSTR , LPSTR);
to cause the compiler to emit the proper export record for export by name without aliasing. This works for
most needs. For some special cases, such as exporting a function by ordinal or aliasing the export, you still
need to use an EXPORTS statement in a module-definition file.
For compiling Microsoft Foundation programs, you will normally use the /GA and /GEs compiler options.
The /Gw compiler option is not used with the Microsoft Foundation classes. (If you do use the Windows
function MakeProcInstance , you will need to explicitly cast the returned function pointer from FARPROC to
the type needed in this API.) Callback registration interfaces are now type-safe (you must pass in a
function pointer that points to the right kind of function for the specific callback).
Also note that all callback functions must trap Microsoft Foundation exceptions before returning to
Windows, since exceptions cannot be thrown across callback boundaries. For more information about
exceptions, see the article Exceptions.
Example
// print some info about a pen we're ready to enumerate
BOOL CALLBACK EnumObjectHandler(LPVOID lpLogObject, LPARAM /* lpData */)
{
LOGPEN *pPen = (LOGPEN *)lpLogObject;

switch (pPen->lopnStyle)
{
case PS_SOLID:
TRACE0("PS_SOLID: ");
break;
case PS_DASH:
TRACE0("PS_DASH: ");
break;
case PS_DOT:
TRACE0("PS_DOT: ");
break;
case PS_DASHDOT:
TRACE0("PS_DASHDOT: ");
break;
case PS_DASHDOTDOT:
TRACE0("PS_DASHDOTDOT: ");
break;
case PS_NULL:
TRACE0("PS_NULL: ");
break;
case PS_INSIDEFRAME:
TRACE0("PS_INSIDEFRAME:");
break;
default:
TRACE0("unk style:");
}

TRACE2("Color: 0x%8.8X, Width: %d\n", pPen->lopnColor, pPen->lopnWidth);


return TRUE;
}

// get the default printer and enumerate the pens it has


void CDCView::OnEnumPens()
{
CPrintDialog dlg(FALSE);
dlg.GetDefaults();
HDC hdc = dlg.GetPrinterDC();

if (hdc != NULL)
{
CDC dc;
dc.Attach(hdc);
VERIFY(dc.EnumObjects(OBJ_PEN, EnumObjectHandler, 0));
}
}

CDC::Escape
This member function is practically obsolete for Win32 programming.
virtual int Escape(
int nEscape,
int nCount,
LPCSTR lpszInData,
LPVOID lpOutData);

int Escape(
int nEscape,
int nInputSize,
LPCSTR lpszInputData,
int nOutputSize,
LPSTR lpszOutputData);

Parameters
nEscape
Specifies the escape function to be performed.
For a complete list of escape functions, see Escape in the Windows SDK.
nCount
Specifies the number of bytes of data pointed to by lpszInData.
lpszInData
Points to the input data structure required for this escape.
lpOutData
Points to the structure that is to receive output from this escape. The lpOutData parameter is NULL if no
data is returned.
nInputSize
Specifies the number of bytes of data pointed to by the lpszInputData parameter.
lpszInputData
Points to the input structure required for the specified escape.
nOutputSize
Specifies the number of bytes of data pointed to by the lpszOutputData parameter.
lpszOutputData
Points to the structure that receives output from this escape. This parameter should be NULL if no data is
returned.
Return Value
A positive value is returned if the function is successful, except for the QUERYESCSUPPORT escape, which
only checks for implementation. Zero is returned if the escape is not implemented. A negative value is
returned if an error occurred. The following are common error values:
SP_ERROR General error.
SP_OUTOFDISK Not enough disk space is currently available for spooling, and no more space will
become available.
SP_OUTOFMEMORY Not enough memory is available for spooling.
SP_USERABORT User ended the job through the Print Manager.
Remarks
Of the original printer escapes, only QUERYESCSUPPORT is supported for Win32 applications. All other
printer escapes are obsolete and are supported only for compatibility with 16-bit applications.
For Win32 programming, CDC now provides six member functions that supersede their corresponding
printer escapes:
CDC::AbortDoc
CDC::EndDoc
CDC::EndPage
CDC::SetAbortProc
CDC::StartDoc
CDC::StartPage
In addition, CDC::GetDeviceCaps supports Win32 indexes that supersede other printer escapes. See
GetDeviceCaps in the Windows SDK for more information.
This member function allows applications to access facilities of a particular device that are not directly
available through GDI.
Use the first version if your application uses predefined escape values. Use the second version if your
application defines private escape values. See ExtEscape in the Windows SDK for more information about
the second version.

CDC::ExcludeClipRect
Creates a new clipping region that consists of the existing clipping region minus the specified rectangle.

int ExcludeClipRect(
int x1,
int y1,
int x2,
int y2);

int ExcludeClipRect(LPCRECT lpRect);

Parameters
x1
Specifies the logical x-coordinate of the upper-left corner of the rectangle.
y1
Specifies the logical y-coordinate of the upper-left corner of the rectangle.
x2
Specifies the logical x-coordinate of the lower-right corner of the rectangle.
y2
Specifies the logical y-coordinate of the lower-right corner of the rectangle.
lpRect
Specifies the rectangle. Can also be a CRect object.
Return Value
Specifies the new clipping region's type. It can be any of the following values:
COMPLEXREGION The region has overlapping borders.
ERROR No region was created.
NULLREGION The region is empty.
SIMPLEREGION The region has no overlapping borders.
Remarks
The width of the rectangle, specified by the absolute value of x2 - x1, must not exceed 32,767 units. This
limit applies to the height of the rectangle as well.

CDC::ExcludeUpdateRgn
Prevents drawing within invalid areas of a window by excluding an updated region in the window from
the clipping region associated with the CDC object.

int ExcludeUpdateRgn(CWnd* pWnd);

Parameters
pWnd
Points to the window object whose window is being updated.
Return Value
The type of excluded region. It can be any one of the following values:
COMPLEXREGION The region has overlapping borders.
ERROR No region was created.
NULLREGION The region is empty.
SIMPLEREGION The region has no overlapping borders.

CDC::ExtFloodFill
Fills an area of the display surface with the current brush.

BOOL ExtFloodFill(
int x,
int y,
COLORREF crColor,
UINT nFillType);

Parameters
x
Specifies the logical x-coordinate of the point where filling begins.
y
Specifies the logical y-coordinate of the point where filling begins.
crColor
Specifies the color of the boundary or of the area to be filled. The interpretation of crColor depends on the
value of nFillType.
nFillType
Specifies the type of flood fill to be performed. It must be either of the following values:
FLOODFILLBORDER The fill area is bounded by the color specified by crColor. This style is identical
to the filling performed by FloodFill .
FLOODFILLSURFACE The fill area is defined by the color specified by crColor. Filling continues
outward in all directions as long as the color is encountered. This style is useful for filling areas with
multicolored boundaries.
Return Value
Nonzero if the function is successful; otherwise 0 if the filling could not be completed, if the given point
has the boundary color specified by crColor (if FLOODFILLBORDER was requested), if the given point does
not have the color specified by crColor (if FLOODFILLSURFACE was requested), or if the point is outside
the clipping region.
Remarks
This member function offers more flexibility than FloodFill because you can specify a fill type in
nFillType.
If nFillType is set to FLOODFILLBORDER, the area is assumed to be completely bounded by the color
specified by crColor. The function begins at the point specified by x and y and fills in all directions to the
color boundary.
If nFillType is set to FLOODFILLSURFACE, the function begins at the point specified by x and y and
continues in all directions, filling all adjacent areas containing the color specified by crColor.
Only memory-device contexts and devices that support raster-display technology support ExtFloodFill .
For more information, see the GetDeviceCaps member function.

CDC::ExtTextOut
Call this member function to write a character string within a rectangular region using the currently
selected font.

virtual BOOL ExtTextOut(


int x,
int y,
UINT nOptions,
LPCRECT lpRect,
LPCTSTR lpszString,
UINT nCount,
LPINT lpDxWidths);

BOOL ExtTextOut(
int x,
int y,
UINT nOptions,
LPCRECT lpRect,
const CString& str,
LPINT lpDxWidths);

Parameters
x
Specifies the logical x-coordinate of the character cell for the first character in the specified string.
y
Specifies the logical y-coordinate of the top of the character cell for the first character in the specified
string.
nOptions
Specifies the rectangle type. This parameter can be one, both, or neither of the following values:
ETO_CLIPPED Specifies that text is clipped to the rectangle.
ETO_OPAQUE Specifies that the current background color fills the rectangle. (You can set and query
the current background color with the SetBkColor and GetBkColor member functions.)
lpRect
Points to a RECT structure that determines the dimensions of the rectangle. This parameter can be NULL.
You can also pass a CRect object for this parameter.
lpszString
Points to the specified character string to be drawn. You can also pass a CString object for this parameter.
nCount
Specifies the number of characters in the string.
lpDxWidths
Points to an array of values that indicate the distance between origins of adjacent character cells. For
instance, lpDxWidths[ i] logical units will separate the origins of character cell i and character cell i + 1. If
lpDxWidths is NULL, ExtTextOut uses the default spacing between characters.
str
A CString object that contains the specified characters to be drawn.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The rectangular region can be opaque (filled with the current background color), and it can be a clipping
region.
If nOptions is 0 and lpRect is NULL, the function writes text to the device context without using a
rectangular region. By default, the current position is not used or updated by the function. If an application
needs to update the current position when it calls ExtTextOut , the application can call the CDC member
function SetTextAlign with nFlags set to TA_UPDATECP. When this flag is set, Windows ignores x and y on
subsequent calls to ExtTextOut and uses the current position instead. When an application uses
TA_UPDATECP to update the current position, ExtTextOut sets the current position either to the end of the
previous line of text or to the position specified by the last element of the array pointed to by lpDxWidths,
whichever is greater.

CDC::FillPath
Closes any open figures in the current path and fills the path's interior by using the current brush and
polygon-filling mode.

BOOL FillPath();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
After its interior is filled, the path is discarded from the device context.

CDC::FillRect
Call this member function to fill a given rectangle using the specified brush.
void FillRect(
LPCRECT lpRect,
CBrush* pBrush);

Parameters
lpRect
Points to a RECT structure that contains the logical coordinates of the rectangle to be filled. You can also
pass a CRect object for this parameter.
pBrush
Identifies the brush used to fill the rectangle.
Remarks
The function fills the complete rectangle, including the left and top borders, but it does not fill the right
and bottom borders.
The brush needs to either be created using the CBrush member functions CreateHatchBrush,
CreatePatternBrush, and CreateSolidBrush, or retrieved by the GetStockObject Windows function.
When filling the specified rectangle, FillRect does not include the rectangle's right and bottom sides. GDI
fills a rectangle up to, but does not include, the right column and bottom row, regardless of the current
mapping mode. FillRect compares the values of the top , bottom , left , and right members of the
specified rectangle. If bottom is less than or equal to top , or if right is less than or equal to left , the
rectangle is not drawn.
FillRect is similar to CDC::FillSolidRect; however, FillRect takes a brush and therefore can be used to
fill a rectangle with a solid color, a dithered color, hatched brushes, or a pattern. FillSolidRect uses only
solid colors (indicated by a COLORREF parameter). FillRect usually is slower than FillSolidRect .

CDC::FillRgn
Fills the region specified by pRgn with the brush specified by pBrush.

BOOL FillRgn(
CRgn* pRgn,
CBrush* pBrush);

Parameters
pRgn
A pointer to the region to be filled. The coordinates for the given region are specified in logical units.
pBrush
Identifies the brush to be used to fill the region.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The brush must either be created using the CBrush member functions CreateHatchBrush ,
CreatePatternBrush , CreateSolidBrush , or be retrieved by GetStockObject .

Example
See the example for CRgn::CreateRoundRectRgn.
CDC::FillSolidRect
Call this member function to fill the given rectangle with the specified solid color.

void FillSolidRect(
LPCRECT lpRect,
COLORREF clr);

void FillSolidRect(
int x,
int y,
int cx,
int cy,
COLORREF clr);

Parameters
lpRect
Specifies the bounding rectangle (in logical units). You can pass either a pointer to a RECT data structure or
a CRect object for this parameter.
clr Specifies the color to be used to fill the rectangle.
x
Specifies the logical x-coordinate of the upper-left corner of the rectangle.
y
Specifies the logical y-coordinate of the upper-left corner of the destination rectangle.
cx
Specifies the width of the rectangle.
cy
Specifies the height of the rectangle.
Remarks
FillSolidRect is very similar to CDC::FillRect; however, FillSolidRect uses only solid colors (indicated by
the COLORREF parameter), while FillRect takes a brush and therefore can be used to fill a rectangle with
a solid color, a dithered color, hatched brushes, or a pattern. FillSolidRect usually is faster than FillRect
.

NOTE
When you call FillSolidRect , the background color, which was previously set using SetBkColor, is set to the
color indicated by clr.

CDC::FlattenPath
Transforms any curves in the path selected into the current device context, and turns each curve into a
sequence of lines.

BOOL FlattenPath();

Return Value
Nonzero if the function is successful; otherwise 0.
CDC::FloodFill
Fills an area of the display surface with the current brush.

BOOL FloodFill(
int x,
int y,
COLORREF crColor);

Parameters
x
Specifies the logical x-coordinate of the point where filling begins.
y
Specifies the logical y-coordinate of the point where filling begins.
crColor
Specifies the color of the boundary.
Return Value
Nonzero if the function is successful; otherwise 0 is returned if the filling could not be completed, the
given point has the boundary color specified by crColor, or the point is outside the clipping region.
Remarks
The area is assumed to be bounded as specified by crColor. The FloodFill function begins at the point
specified by x and y and continues in all directions to the color boundary.
Only memory-device contexts and devices that support raster-display technology support the FloodFill
member function. For information about RC_BITBLT capability, see the GetDeviceCaps member function.
The ExtFloodFill function provides similar capability but greater flexibility.

CDC::FrameRect
Draws a border around the rectangle specified by lpRect.

void FrameRect(
LPCRECT lpRect,
CBrush* pBrush);

Parameters
lpRect
Points to a RECT structure or CRect object that contains the logical coordinates of the upper-left and lower-
right corners of the rectangle. You can also pass a CRect object for this parameter.
pBrush
Identifies the brush to be used for framing the rectangle.
Remarks
The function uses the given brush to draw the border. The width and height of the border is always 1
logical unit.
If the rectangle's bottom coordinate is less than or equal to top , or if right is less than or equal to left
, the rectangle is not drawn.
The border drawn by FrameRect is in the same position as a border drawn by the Rectangle member
function using the same coordinates (if Rectangle uses a pen that is 1 logical unit wide). The interior of
the rectangle is not filled by FrameRect .

CDC::FrameRgn
Draws a border around the region specified by pRgn using the brush specified by pBrush.

BOOL FrameRgn(
CRgn* pRgn,
CBrush* pBrush,
int nWidth,
int nHeight);

Parameters
pRgn
Points to the CRgn object that identifies the region to be enclosed in a border. The coordinates for the
given region are specified in logical units.
pBrush
Points to the CBrush object that identifies the brush to be used to draw the border.
nWidth
Specifies the width of the border in vertical brush strokes in device units.
nHeight
Specifies the height of the border in horizontal brush strokes in device units.
Return Value
Nonzero if the function is successful; otherwise 0.
Example
See the example for CRgn::CombineRgn.

CDC::FromHandle
Returns a pointer to a CDC object when given a handle to a device context.

static CDC* PASCAL FromHandle(HDC hDC);

Parameters
hDC
Contains a handle to a Windows device context.
Return Value
The pointer may be temporary and should not be stored beyond immediate use.
Remarks
If a CDC object is not attached to the handle, a temporary CDC object is created and attached.
Example
See the example for CPrintDialog::GetPrinterDC.

CDC::GetArcDirection
Returns the current arc direction for the device context.

int GetArcDirection() const;

Return Value
Specifies the current arc direction, if successful. Following are the valid return values:
AD_COUNTERCLOCKWISE Arcs and rectangles drawn counterclockwise.
AD_CLOCKWISE Arcs and rectangles drawn clockwise.
If an error occurs, the return value is zero.
Remarks
Arc and rectangle functions use the arc direction.

CDC::GetAspectRatioFilter
Retrieves the setting for the current aspect-ratio filter.

CSize GetAspectRatioFilter() const;

Return Value
A CSize object representing the aspect ratio used by the current aspect ratio filter.
Remarks
The aspect ratio is the ratio formed by a device's pixel width and height. Information about a device's
aspect ratio is used in the creation, selection, and display of fonts. Windows provides a special filter, the
aspect-ratio filter, to select fonts designed for a particular aspect ratio from all of the available fonts. The
filter uses the aspect ratio specified by the SetMapperFlags member function.

CDC::GetBkColor
Returns the current background color.

COLORREF GetBkColor() const;

Return Value
An RGB color value.
Remarks
If the background mode is OPAQUE, the system uses the background color to fill the gaps in styled lines,
the gaps between hatched lines in brushes, and the background in character cells. The system also uses
the background color when converting bitmaps between color and monochrome device contexts.

CDC::GetBkMode
Returns the background mode.

int GetBkMode() const;

Return Value
The current background mode, which can be OPAQUE or TRANSPARENT.
Remarks
The background mode defines whether the system removes existing background colors on the drawing
surface before drawing text, hatched brushes, or any pen style that is not a solid line.

CDC::GetBoundsRect
Returns the current accumulated bounding rectangle for the specified device context.

UINT GetBoundsRect(
LPRECT lpRectBounds,
UINT flags);

Parameters
lpRectBounds
Points to a buffer that will receive the current bounding rectangle. The rectangle is returned in logical
coordinates.
flags
Specifies whether the bounding rectangle is to be cleared after it is returned. This parameter should be
zero or set to the following value:
DCB_RESET Forces the bounding rectangle to be cleared after it is returned.
Return Value
Specifies the current state of the bounding rectangle if the function is successful. It can be a combination
of the following values:
DCB_ACCUMULATE Bounding rectangle accumulation is occurring.
DCB_RESET Bounding rectangle is empty.
DCB_SET Bounding rectangle is not empty.
DCB_ENABLE Bounding accumulation is on.
DCB_DISABLE Bounding accumulation is off.

CDC::GetBrushOrg
Retrieves the origin (in device units) of the brush currently selected for the device context.

CPoint GetBrushOrg() const;

Return Value
The current origin of the brush (in device units) as a CPoint object.
Remarks
The initial brush origin is at (0,0) of the client area. The return value specifies this point in device units
relative to the origin of the desktop window.

CDC::GetCharacterPlacement
Retrieves various types of information on a character string.
DWORD GetCharacterPlacement(
LPCTSTR lpString,
int nCount,
int nMaxExtent,
LPGCP_RESULTS lpResults,
DWORD dwFlags) const;

DWORD GetCharacterPlacement(
CString& str,
int nMaxExtent,
LPGCP_RESULTS lpResults,
DWORD dwFlags) const;

Parameters
lpString
A pointer to the character string to process.
nCount
Specifies the length of the string. For the ANSI version, it is a BYTE count and for the Unicode function it is
a WORD count. For more information, see GetCharacterPlacement.
nMaxExtent
Specifies the maximum extent (in logical units) to which the string is processed. Characters that, if
processed, would exceed this extent are ignored. Computations for any required ordering or glyph arrays
apply only to the included characters. This parameter is used only if the GCP_MAXEXTENT value is
specified in the dwFlags parameter. As the function processes the input string, each character and its
extent is added to the output, extent, and other arrays only if the total extent has not yet exceeded the
maximum. Once the limit is reached, processing will stop.
lpResults
Pointer to a GCP_Results structure that receives the results of the function.
dwFlags
Specifies how to process the string into the required arrays. This parameter can be one or more of the
values listed in the dwFlags section of the GetCharacterPlacement topic.
str
A pointer to a CString object to process.
Return Value
If the function succeeds, the return value is the width and height of the string in logical units.
If the function fails, the return value is zero.
Remarks
This member function emulates the functionality of the function GetCharacterPlacement, as described in
the Windows SDK.

CDC::GetCharABCWidths
Retrieves the widths of consecutive characters in a specified range from the current TrueType font.
BOOL GetCharABCWidths(
UINT nFirstChar,
UINT nLastChar,
LPABC lpabc) const;

BOOL GetCharABCWidths(
UINT nFirstChar,
UINT nLastChar,
LPABCFLOAT lpABCF) const;

Parameters
nFirstChar
Specifies the first character in the range of characters from the current font for which character widths are
returned.
nLastChar
Specifies the last character in the range of characters from the current font for which character widths are
returned.
lpabc
Points to an array of ABC structures that receive the character widths when the function returns. This array
must contain at least as many ABC structures as there are characters in the range specified by the
nFirstChar and nLastChar parameters.
lpABCF
Points to an application-supplied buffer with an array of ABCFLOAT structures to receive the character
widths when the function returns. The widths returned by this function are in the IEEE floating-point
format.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The widths are returned in logical units. This function succeeds only with TrueType fonts.
The TrueType rasterizer provides "ABC" character spacing after a specific point size has been selected. "A"
spacing is the distance that is added to the current position before placing the glyph. "B" spacing is the
width of the black part of the glyph. "C" spacing is added to the current position to account for the white
space to the right of the glyph. The total advanced width is given by A + B + C.
When the GetCharABCWidths member function retrieves negative "A" or "C" widths for a character, that
character includes underhangs or overhangs.
To convert the ABC widths to font design units, an application should create a font whose height (as
specified in the lfHeight member of the LOGFONT structure) is equal to the value stored in the
ntmSizeEM member of the NEWTEXTMETRIC structure. (The value of the ntmSizeEM member can be
retrieved by calling the EnumFontFamilies Windows function.)
The ABC widths of the default character are used for characters that are outside the range of the currently
selected font.
To retrieve the widths of characters in non-TrueType fonts, applications should use the GetCharWidth
Windows function.

CDC::GetCharABCWidthsI
Retrieves the widths, in logical units, of consecutive glyph indices in a specified range from the current
TrueType font.

BOOL GetCharABCWidthsI(
UINT giFirst,
UINT cgi,
LPWORD pgi,
LPABC lpabc) const;

Parameters
giFirst
Specifies the first glyph index in the group of consecutive glyph indices from the current font. This
parameter is only used if the pgi parameter is NULL.
cgi
Specifies the number of glyph indices.
pgi
A pointer to an array containing glyph indices. If the value is NULL, the giFirst parameter is used instead.
The cgi parameter specifies the number of glyph indices in this array.
lpabc
Pointer to an array of ABC structures receiving the character widths. This array must contain at least as
many ABC structures as there are glyph indices specified by the cgi parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This member function emulates the functionality of the function GetCharABCWidthsI, as described in the
Windows SDK.

CDC::GetCharWidth
Retrieves the widths of individual characters in a consecutive group of characters from the current font,
using m_hAttribDC , the input device context.

BOOL GetCharWidth(
UINT nFirstChar,
UINT nLastChar,
LPINT lpBuffer) const;

BOOL GetCharWidth(
UINT nFirstChar,
UINT nLastChar,
float* lpFloatBuffer) const;

Parameters
nFirstChar
Specifies the first character in a consecutive group of characters in the current font.
nLastChar
Specifies the last character in a consecutive group of characters in the current font.
lpBuffer
Points to a buffer that will receive the width values for a consecutive group of characters in the current
font.
lpFloatBuffer
Points to a buffer to receive the character widths. The returned widths are in the 32-bit IEEE floating-point
format. (The widths are measured along the base line of the characters.)
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
For example, if nFirstChar identifies the letter 'a' and nLastChar identifies the letter 'z', the function
retrieves the widths of all lowercase characters.
The function stores the values in the buffer pointed to by lpBuffer. This buffer must be large enough to
hold all of the widths. That is, there must be at least 26 entries in the example given.
If a character in the consecutive group of characters does not exist in a particular font, it will be assigned
the width value of the default character.

CDC::GetCharWidthI
Retrieves the widths, in logical coordinates, of consecutive glyph indices in a specified range from the
current font.

BOOL GetCharWidthI(
UINT giFirst,
UINT cgi,
LPWORD pgi,
LPINT lpBuffer) const;

Parameters
giFirst
Specifies the first glyph index in the group of consecutive glyph indices from the current font. This
parameter is only used if the pgi parameter is NULL.
cgi
Specifies the number of glyph indices.
pgi
A pointer to an array containing glyph indices. If the value is NULL, the giFirst parameter is used instead.
The cgi parameter specifies the number of glyph indices in this array.
lpBuffer
A pointer to a buffer that receives the widths.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This member function emulates the functionality of the function GetCharWidthI, as described in the
Windows SDK.

CDC::GetClipBox
Retrieves the dimensions of the tightest bounding rectangle around the current clipping boundary.

virtual int GetClipBox(LPRECT lpRect) const;


Parameters
lpRect
Points to the RECT structure or CRect object that is to receive the rectangle dimensions.
Return Value
The clipping region's type. It can be any of the following values:
COMPLEXREGION Clipping region has overlapping borders.
ERROR Device context is not valid.
NULLREGION Clipping region is empty.
SIMPLEREGION Clipping region has no overlapping borders.
Remarks
The dimensions are copied to the buffer pointed to by lpRect.

CDC::GetColorAdjustment
Retrieves the color adjustment values for the device context.

BOOL GetColorAdjustment(LPCOLORADJUSTMENT lpColorAdjust) const;

Parameters
lpColorAdjust
Points to a COLORADJUSTMENT data structure to receive the color adjustment values.
Return Value
Nonzero if the function is successful; otherwise 0.

CDC::GetCurrentBitmap
Returns a pointer to the currently selected CBitmap object.

CBitmap* GetCurrentBitmap() const;

Return Value
Pointer to a CBitmap object, if successful; otherwise NULL.
Remarks
This member function may return temporary objects.

CDC::GetCurrentBrush
Returns a pointer to the currently selected CBrush object.

CBrush* GetCurrentBrush() const;

Return Value
Pointer to a CBrush object, if successful; otherwise NULL.
Remarks
This member function may return temporary objects.

CDC::GetCurrentFont
Returns a pointer to the currently selected CFont object.

CFont* GetCurrentFont() const;

Return Value
Pointer to a CFont object, if successful; otherwise NULL.
Remarks
This member function may return temporary objects.

CDC::GetCurrentPalette
Returns a pointer to the currently selected CPalette object.

CPalette* GetCurrentPalette() const;

Return Value
Pointer to a CPalette object, if successful; otherwise NULL.
Remarks
This member function may return temporary objects.

CDC::GetCurrentPen
Returns a pointer to the currently selected CPen object.

CPen* GetCurrentPen() const;

Return Value
Pointer to a CPen object, if successful; otherwise NULL.
Remarks
This member function may return temporary objects.

CDC::GetCurrentPosition
Retrieves the current position (in logical coordinates).

CPoint GetCurrentPosition() const;

Return Value
The current position as a CPoint object.
Remarks
The current position can be set with the MoveTo member function.
CDC::GetDCBrushColor
Retrieves the current brush color.

COLORREF GetDCBrushColor() const;

Return Value
If the function succeeds, the return value is the COLORREF value for the current brush color.
If the function fails, the return value is CLR_INVALID.
Remarks
This member function emulates the functionality of the function GetDCBrushColor, as described in the
Windows SDK.

CDC::GetDCPenColor
Retrieves the current pen color.

COLORREF GetDCPenColor() const;

Return Value
If the function succeeds, the return value is the COLORREF value for the current pen color.
If the function fails, the return value is CLR_INVALID.
Remarks
This member function utilizes the Win32 function GetDCPenColor, as described in the Windows SDK.

CDC::GetDeviceCaps
Retrieves a wide range of device-specific information about the display device.

int GetDeviceCaps(int nIndex) const;

Parameters
nIndex
Specifies the type of information to return. See GetDeviceCaps in the Windows SDK for a list of values.
Return Value
The value of the requested capability if the function is successful.
Example
See the example for CPrintDialog::GetDefaults.

CDC::GetFontData
Retrieves font-metric information from a scalable font file.
DWORD GetFontData(
DWORD dwTable,
DWORD dwOffset,
LPVOID lpData,
DWORD cbData) const;

Parameters
dwTable
Specifies the name of the metric table to be returned. This parameter can be one of the metric tables
documented in the TrueType Font Files specification published by Microsoft Corporation. If this parameter
is 0, the information is retrieved starting at the beginning of the font file.
dwOffset
Specifies the offset from the beginning of the table at which to begin retrieving information. If this
parameter is 0, the information is retrieved starting at the beginning of the table specified by the dwTable
parameter. If this value is greater than or equal to the size of the table, GetFontData returns 0.
lpData
Points to a buffer that will receive the font information. If this value is NULL, the function returns the size
of the buffer required for the font data specified in the dwTable parameter.
cbData
Specifies the length, in bytes, of the information to be retrieved. If this parameter is 0, GetFontData returns
the size of the data specified in the dwTable parameter.
Return Value
Specifies the number of bytes returned in the buffer pointed to by lpData if the function is successful;
otherwise -1.
Remarks
The information to retrieve is identified by specifying an offset into the font file and the length of the
information to return.
An application can sometimes use the GetFontData member function to save a TrueType font with a
document. To do this, the application determines whether the font can be embedded and then retrieves
the entire font file, specifying 0 for the dwTable, dwOffset, and cbData parameters.
Applications can determine whether a font can be embedded by checking the otmfsType member of the
OUTLINETEXTMETRIC structure. If bit 1 of otmfsType is set, embedding is not permitted for the font. If bit
1 is clear, the font can be embedded. If bit 2 is set, the embedding is read only.
If an application attempts to use this function to retrieve information for a non-TrueType font, the
GetFontData member function returns -1.

CDC::GetFontLanguageInfo
Returns information about the currently selected font for the specified display context.

DWORD GetFontLanguageInfo() const;

Return Value
The return value identifies characteristics of the currently selected font. For a complete listing of possible
values, see GetFontLanguageInfo.
Remarks
This member function emulates the functionality of the function GetFontLanguageInfo, as described in the
Windows SDK.

CDC::GetGlyphOutline
Retrieves the outline curve or bitmap for an outline character in the current font.

DWORD GetGlyphOutline(
UINT nChar,
UINT nFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpBuffer,
const MAT2* lpmat2) const;

Parameters
nChar
Specifies the character for which information is to be returned.
nFormat
Specifies the format in which the function is to return information. It can be one of the following values, or
0:

VA L UE M EA N IN G

GGO_BITMAP Returns the glyph bitmap. When the function returns, the
buffer pointed to by lpBuffer contains a 1-bit-per-pixel
bitmap whose rows start on doubleword boundaries.

GGO_NATIVE Returns the curve data points in the rasterizer's native


format, using device units. When this value is specified,
any transformation specified in lpmat2 is ignored.

When the value of nFormat is 0, the function fills in a GLYPHMETRICS structure but does not return glyph-
outline data.
lpgm
Points to a GLYPHMETRICS structure that describes the placement of the glyph in the character cell.
cbBuffer
Specifies the size of the buffer into which the function copies information about the outline character. If
this value is 0 and the nFormat parameter is either the GGO_BITMAP or GGO_NATIVE values, the function
returns the required size of the buffer.
lpBuffer
Points to a buffer into which the function copies information about the outline character. If nFormat
specifies the GGO_NATIVE value, the information is copied in the form of TTPOLYGONHEADER and
TTPOLYCURVE structures. If this value is NULL and nFormat is either the GGO_BITMAP or GGO_NATIVE
value, the function returns the required size of the buffer.
lpmat2
Points to a MAT2 structure that contains a transformation matrix for the character. This parameter cannot
be NULL, even when the GGO_NATIVE value is specified for nFormat.
Return Value
The size, in bytes, of the buffer required for the retrieved information if cbBuffer is 0 or lpBuffer is NULL.
Otherwise, it is a positive value if the function is successful, or -1 if there is an error.
Remarks
An application can rotate characters retrieved in bitmap format by specifying a 2-by-2 transformation
matrix in the structure pointed to by lpmat2.
A glyph outline is returned as a series of contours. Each contour is defined by a TTPOLYGONHEADER
structure followed by as many TTPOLYCURVE structures as are required to describe it. All points are
returned as POINTFX structures and represent absolute positions, not relative moves. The starting point
given by the pfxStart member of the TTPOLYGONHEADER structure is the point at which the outline for
a contour begins. The TTPOLYCURVE structures that follow can be either polyline records or spline
records. Polyline records are a series of points; lines drawn between the points describe the outline of the
character. Spline records represent the quadratic curves used by TrueType (that is, quadratic b-splines).

CDC::GetGraphicsMode
Retrieves the current graphics mode for the specified device context.

int GetGraphicsMode() const;

Return Value
Returns the current graphics mode on success. For a list of the values that this method can return, see
GetGraphicsMode.
Returns 0 on failure.
To get extended error information, call GetLastError.
Remarks
This method wraps the Windows GDI function GetGraphicsMode.

CDC::GetHalftoneBrush
Call this member function to retrieve a halftone brush.

static CBrush* PASCAL GetHalftoneBrush();

Return Value
A pointer to a CBrush object if successful; otherwise NULL.
Remarks
A halftone brush shows pixels that are alternately foreground and background colors to create a dithered
pattern. The following is an example of a dithered pattern created by a halftone brush.

CDC::GetKerningPairs
Retrieves the character kerning pairs for the font that is currently selected in the specified device context.
int GetKerningPairs(
int nPairs,
LPKERNINGPAIR lpkrnpair) const;

Parameters
nPairs
Specifies the number of KERNINGPAIR structures pointed to by lpkrnpair. The function will not copy more
kerning pairs than specified by nPairs.
lpkrnpair
Points to an array of KERNINGPAIR structures that receive the kerning pairs when the function returns. This
array must contain at least as many structures as specified by nPairs. If this parameter is NULL, the
function returns the total number of kerning pairs for the font.
Return Value
Specifies the number of kerning pairs retrieved or the total number of kerning pairs in the font, if the
function is successful. Zero is returned if the function fails or there are no kerning pairs for the font.

CDC::GetLayout
Call this member function to determine the layout of the text and graphics for a device context, such as a
printer or a metafile.

DWORD GetLayout() const;

Return Value
If successful, the layout flags for the current device context. Otherwise, GDI_ERROR. For extended error
information, call GetLastError. For a list of the layout flags, see CDC::SetLayout.
Remarks
The default layout is left to right.

CDC::GetMapMode
Retrieves the current mapping mode.

int GetMapMode() const;

Return Value
The mapping mode.
Remarks
For a description of the mapping modes, see the SetMapMode member function.

NOTE
If you call SetLayout to change the DC to right-to-left layout, SetLayout automatically changes the mapping
mode to MM_ISOTROPIC. Consequently, any subsequent call to GetMapMode will return MM_ISOTROPIC.

CDC::GetMiterLimit
Returns the miter limit for the device context.

float GetMiterLimit() const;

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The miter limit is used when drawing geometric lines that have miter joins.

CDC::GetNearestColor
Returns the solid color that best matches a specified logical color.

COLORREF GetNearestColor(COLORREF crColor) const;

Parameters
crColor
Specifies the color to be matched.
Return Value
An RGB (red, green, blue) color value that defines the solid color closest to the crColor value that the
device can represent.
Remarks
The given device must be able to represent this color.

CDC::GetOutlineTextMetrics
Retrieves metric information for TrueType fonts.

UINT GetOutlineTextMetrics(
UINT cbData,
LPOUTLINETEXTMETRIC lpotm) const;

Parameters
lpotm
Points to an array of OUTLINETEXTMETRIC structures. If this parameter is NULL, the function returns the
size of the buffer required for the retrieved metric data.
cbData
Specifies the size, in bytes, of the buffer to which information is returned.
lpotm
Points to an OUTLINETEXTMETRIC structure. If this parameter is NULL, the function returns the size of the
buffer required for the retrieved metric information.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The OUTLINETEXTMETRIC structure contains most of the font metric information provided with the
TrueType format, including a TEXTMETRIC structure. The last four members of the OUTLINETEXTMETRIC
structure are pointers to strings. Applications should allocate space for these strings in addition to the
space required for the other members. Because there is no system-imposed limit to the size of the strings,
the simplest method for allocating memory is to retrieve the required size by specifying NULL for lpotm in
the first call to the GetOutlineTextMetrics function.

CDC::GetOutputCharWidth
Uses the output device context, m_hDC , and retrieves the widths of individual characters in a consecutive
group of characters from the current font.

BOOL GetOutputCharWidth(
UINT nFirstChar,
UINT nLastChar,
LPINT lpBuffer) const;

Parameters
nFirstChar
Specifies the first character in a consecutive group of characters in the current font.
nLastChar
Specifies the last character in a consecutive group of characters in the current font.
lpBuffer
Points to a buffer that will receive the width values for a consecutive group of characters in the current
font.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
For example, if nFirstChar identifies the letter 'a' and nLastChar identifies the letter 'z', the function
retrieves the widths of all lowercase characters.
The function stores the values in the buffer pointed to by lpBuffer. This buffer must be large enough to
hold all of the widths; that is, there must be at least 26 entries in the example given.
If a character in the consecutive group of characters does not exist in a particular font, it will be assigned
the width value of the default character.

CDC::GetOutputTabbedTextExtent
Call this member function to compute the width and height of a character string using m_hDC, the output
device context.

CSize GetOutputTabbedTextExtent(
LPCTSTR lpszString,
int nCount,
int nTabPositions,
LPINT lpnTabStopPositions) const;

CSize GetOutputTabbedTextExtent(
const CString& str,
int nTabPositions,
LPINT lpnTabStopPositions) const;

Parameters
lpszString
Points to a character string to be measured. You can also pass a CString object for this parameter.
nCount
Specifies the length of the string pointed to by lpszString.
nTabPositions
Specifies the number of tab-stop positions in the array pointed to by lpnTabStopPositions.
lpnTabStopPositions
Points to an array of integers containing the tab-stop positions in logical units. The tab stops must be
sorted in increasing order; the smallest x-value should be the first item in the array. Back tabs are not
allowed.
str
A CString object that contains the specified characters to be measured.
Return Value
The dimensions of the string (in logical units) in a CSize object.
Remarks
If the string contains one or more tab characters, the width of the string is based upon the tab stops
specified by lpnTabStopPositions. The function uses the currently selected font to compute the dimensions
of the string.
The current clipping region does not offset the width and height returned by the
GetOutputTabbedTextExtent function.

Since some devices do not place characters in regular cell arrays (that is, they kern the characters), the
sum of the extents of the characters in a string may not be equal to the extent of the string.
If nTabPositions is 0 and lpnTabStopPositions is NULL, tabs are expanded to eight average character
widths. If nTabPositions is 1, the tab stops will be separated by the distance specified by the first value in
the array to which lpnTabStopPositions points. If lpnTabStopPositions points to more than a single value, a
tab stop is set for each value in the array, up to the number specified by nTabPositions.

CDC::GetOutputTextExtent
Call this member function to use the output device context, m_hDC, and compute the width and height of
a line of text, using the current font.

CSize GetOutputTextExtent(
LPCTSTR lpszString,
int nCount) const;

CSize GetOutputTextExtent(const CString& str) const;

Parameters
lpszString
Points to a string of characters. You can also pass a CString object for this parameter.
nCount
Specifies the length of the string pointed to by lpszString.
str
A CString object that contains the specified characters to be measured.
Return Value
The dimensions of the string (in logical units) returned in a CSize object.
Remarks
The current clipping region does not affect the width and height returned by GetOutputTextExtent .
Since some devices do not place characters in regular cell arrays (that is, they carry out kerning), the sum
of the extents of the characters in a string may not be equal to the extent of the string.

CDC::GetOutputTextMetrics
Retrieves the metrics for the current font using m_hDC , the output device context.

BOOL GetOutputTextMetrics(LPTEXTMETRIC lpMetrics) const;

Parameters
lpMetrics
Points to the TEXTMETRIC structure that receives the metrics.
Return Value
Nonzero if the function is successful; otherwise 0.

CDC::GetPath
Retrieves the coordinates defining the endpoints of lines and the control points of curves found in the
path that is selected into the device context.

int GetPath(
LPPOINT lpPoints,
LPBYTE lpTypes,
int nCount) const;

Parameters
lpPoints
Points to an array of POINT data structures or CPoint objects where the line endpoints and curve control
points are placed.
lpTypes
Points to an array of bytes where the vertex types are placed. Values are one of the following:
PT_MOVETO Specifies that the corresponding point in lpPoints starts a disjoint figure.
PT_LINETO Specifies that the previous point and the corresponding point in lpPoints are the
endpoints of a line.
PT_BEZIERTO Specifies that the corresponding point in lpPoints is a control point or ending point
for a Bzier curve.
PT_BEZIERTO types always occur in sets of three. The point in the path immediately preceding them
defines the starting point for the Bzier curve. The first two PT_BEZIERTO points are the control points, and
the third PT_BEZIERTO point is the end point (if hard-coded).
A PT_LINETO or PT_BEZIERTO type may be combined with the following flag (by using the bitwise operator
OR ) to indicate that the corresponding point is the last point in a figure and that the figure should be
closed:
PT_CLOSEFIGURE Specifies that the figure is automatically closed after the corresponding line or curve
is drawn. The figure is closed by drawing a line from the line or curve endpoint to the point
corresponding to the last PT_MOVETO.
nCount
Specifies the total number of POINT data structures that may be placed in the lpPoints array. This value
must be the same as the number of bytes that may be placed in the lpTypes array.
Return Value
If the nCount parameter is nonzero, the number of points enumerated. If nCount is 0, the total number of
points in the path (and GetPath writes nothing to the buffers). If nCount is nonzero and is less than the
number of points in the path, the return value is -1.
Remarks
The device context must contain a closed path. The points of the path are returned in logical coordinates.
Points are stored in the path in device coordinates, so GetPath changes the points from device
coordinates to logical coordinates by using the inverse of the current transformation. The FlattenPath
member function may be called before GetPath , to convert all curves in the path into line segments.
Example
See the example for CDC::BeginPath.

CDC::GetPixel
Retrieves the RGB color value of the pixel at the point specified by x and y.

COLORREF GetPixel(
int x,
int y) const;

COLORREF GetPixel(POINT point) const;

Parameters
x
Specifies the logical x-coordinate of the point to be examined.
y
Specifies the logical y-coordinate of the point to be examined.
point
Specifies the logical x- and y-coordinates of the point to be examined.
Return Value
For either version of the function, an RGB color value for the color of the given point. It is -1 if the
coordinates do not specify a point in the clipping region.
Remarks
The point must be in the clipping region. If the point is not in the clipping region, the function has no effect
and returns -1.
Not all devices support the GetPixel function. For more information, see the RC_BITBLT raster capability
under the GetDeviceCaps member function.
The GetPixel member function has two forms. The first takes two coordinate values; the second takes
either a POINT structure or a CPoint object.
CDC::GetPolyFillMode
Retrieves the current polygon-filling mode.

int GetPolyFillMode() const;

Return Value
The current polygon-filled mode, ALTERNATE or WINDING, if the function is successful.
Remarks
See the SetPolyFillMode member function for a description of the polygon-filling modes.

CDC::GetROP2
Retrieves the current drawing mode.

int GetROP2() const;

Return Value
The drawing mode. For a list of the drawing mode values, see the SetROP2 member function.
Remarks
The drawing mode specifies how the colors of the pen and the interior of filled objects are combined with
the color already on the display surface.

CDC::GetSafeHdc
Call this member function to get m_hDC, the output device context.

HDC GetSafeHdc() const;

Return Value
A device context handle.
Remarks
This member function also works with null pointers.

CDC::GetStretchBltMode
Retrieves the current bitmap-stretching mode.

int GetStretchBltMode() const;

Return Value
The return value specifies the current bitmap-stretching mode — STRETCH_ANDSCANS,
STRETCH_DELETESCANS, or STRETCH_ORSCANS — if the function is successful.
Remarks
The bitmap-stretching mode defines how information is removed from bitmaps that are stretched or
compressed by the StretchBlt member function.
The STRETCH_ANDSCANS and STRETCH_ORSCANS modes are typically used to preserve foreground
pixels in monochrome bitmaps. The STRETCH_DELETESCANS mode is typically used to preserve color in
color bitmaps.

CDC::GetTabbedTextExtent
Call this member function to compute the width and height of a character string using m_hAttribDC, the
attribute device context.

CSize GetTabbedTextExtent(
LPCTSTR lpszString,
int nCount,
int nTabPositions,
LPINT lpnTabStopPositions) const;

CSize GetTabbedTextExtent(
const CString& str,
int nTabPositions,
LPINT lpnTabStopPositions) const;

Parameters
lpszString
Points to a character string. You can also pass a CString object for this parameter.
nCount
Specifies the length of the string pointed to by lpszString.
nTabPositions
Specifies the number of tab-stop positions in the array pointed to by lpnTabStopPositions.
lpnTabStopPositions
Points to an array of integers containing the tab-stop positions in logical units. The tab stops must be
sorted in increasing order; the smallest x-value should be the first item in the array. Back tabs are not
allowed.
str
A CString object that contains the specified characters to be drawn.
Return Value
The dimensions of the string (in logical units) in a CSize object.
Remarks
If the string contains one or more tab characters, the width of the string is based upon the tab stops
specified by lpnTabStopPositions. The function uses the currently selected font to compute the dimensions
of the string.
The current clipping region does not offset the width and height returned by the GetTabbedTextExtent
function.
Since some devices do not place characters in regular cell arrays (that is, they kern the characters), the
sum of the extents of the characters in a string may not be equal to the extent of the string.
If nTabPositions is 0 and lpnTabStopPositions is NULL, tabs are expanded to eight times the average
character width. If nTabPositions is 1, the tab stops will be separated by the distance specified by the first
value in the array to which lpnTabStopPositions points. If lpnTabStopPositions points to more than a single
value, a tab stop is set for each value in the array, up to the number specified by nTabPositions.
CDC::GetTextAlign
Retrieves the status of the text-alignment flags for the device context.

UINT GetTextAlign() const;

Return Value
The status of the text-alignment flags. The return value is one or more of the following values:
TA_BASELINE Specifies alignment of the x-axis and the baseline of the chosen font within the
bounding rectangle.
TA_BOTTOM Specifies alignment of the x-axis and the bottom of the bounding rectangle.
TA_CENTER Specifies alignment of the y-axis and the center of the bounding rectangle.
TA_LEFT Specifies alignment of the y-axis and the left side of the bounding rectangle.
TA_NOUPDATECP Specifies that the current position is not updated.
TA_RIGHT Specifies alignment of the y-axis and the right side of the bounding rectangle.
TA_TOP Specifies alignment of the x-axis and the top of the bounding rectangle.
TA_UPDATECP Specifies that the current position is updated.
Remarks
The text-alignment flags determine how the TextOut and ExtTextOut member functions align a string of
text in relation to the string's starting point. The text-alignment flags are not necessarily single-bit flags
and may be equal to 0. To test whether a flag is set, an application should follow these steps:
1. Apply the bitwise OR operator to the flag and its related flags, grouped as follows:
TA_LEFT, TA_CENTER, and TA_RIGHT
TA_BASELINE, TA_BOTTOM, and TA_TOP
TA_NOUPDATECP and TA_UPDATECP
2. Apply the bitwise-AND operator to the result and the return value of GetTextAlign .
3. Test for the equality of this result and the flag.

CDC::GetTextCharacterExtra
Retrieves the current setting for the amount of intercharacter spacing.

int GetTextCharacterExtra() const;

Return Value
The amount of the intercharacter spacing.
Remarks
GDI adds this spacing to each character, including break characters, when it writes a line of text to the
device context.
The default value for the amount of intercharacter spacing is 0.
CDC::GetTextColor
Retrieves the current text color.

COLORREF GetTextColor() const;

Return Value
The current text color as an RGB color value.
Remarks
The text color is the foreground color of characters drawn by using the GDI text-output member functions
TextOut, ExtTextOut, and TabbedTextOut.

CDC::GetTextExtent
Call this member function to compute the width and height of a line of text using the current font to
determine the dimensions.

CSize GetTextExtent(
LPCTSTR lpszString,
int nCount) const;

CSize GetTextExtent(const CString& str) const;

Parameters
lpszString
Points to a string of characters. You can also pass a CString object for this parameter.
nCount
Specifies the number of characters in the string.
str
A CString object that contains the specified characters.
Return Value
The dimensions of the string (in logical units) in a CSize object.
Remarks
The information is retrieved from m_hAttribDC, the attribute device context.
By default, GetTextExtent assumes the text for which it retrieves the dimension is set along a horizontal
line (that is, the escapement is 0). If you create a font specifying a non-zero escapement, you must convert
the angle of the text explicitly to get the dimensions of the string.
The current clipping region does not affect the width and height returned by GetTextExtent .
Since some devices do not place characters in regular cell arrays (that is, they carry out kerning), the sum
of the extents of the characters in a string may not be equal to the extent of the string.

CDC::GetTextExtentExPointI
Retrieves the number of characters in a specified string that will fit within a specified space and fills an
array with the text extent for each of those characters.
BOOL GetTextExtentExPointI(
LPWORD pgiIn,
int cgi,
int nMaxExtent,
LPINT lpnFit,
LPINT alpDx,
LPSIZE lpSize) const;

Parameters
pgiIn
A pointer to an array of glyph indices for which extents are to be retrieved.
cgi
Specifies the number of glyphs in the array pointed to by pgiIn.
nMaxExtent
Specifies the maximum allowable width, in logical units, of the formatted string.
lpnFit
A pointer to an integer that receives a count of the maximum number of characters that will fit in the
space specified by nMaxExtent. When lpnFit is NULL, nMaxExtent is ignored.
alpDx
A pointer to an array of integers that receives partial glyph extents. Each element in the array gives the
distance, in logical units, between the beginning of the glyph indices array and one of the glyphs that fits
in the space specified by nMaxExtent. Although this array should have at least as many elements as glyph
indices specified by cgi, the function fills the array with extents only for as many glyph indices as are
specified by lpnFit. If lpnDx is NULL, the function does not compute partial string widths.
lpSize
Pointer to a SIZE structure that receives the dimensions of the glyph indices array, in logical units. This
value cannot be NULL.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This member function emulates the functionality of the function GetTextExtentExPointI, as described in the
Windows SDK.

CDC::GetTextExtentPointI
Retrieves the width and height of the specified array of glyph indices.

BOOL GetTextExtentPointI(
LPWORD pgiIn,
int cgi,
LPSIZE lpSize) const;

Parameters
pgiIn
A pointer to an array of glyph indices for which extents are to be retrieved.
cgi
Specifies the number of glyphs in the array pointed to by pgiIn.
lpSize
Pointer to a SIZE structure that receives the dimensions of the glyph indices array, in logical units. This
value cannot be NULL.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This member function emulates the functionality of the function GetTextExtentPointI, as described in the
Windows SDK.

CDC::GetTextFace
Call this member function to copy the typeface name of the current font into a buffer.

int GetTextFace(
int nCount,
LPTSTR lpszFacename) const;

int GetTextFace(CString& rString) const;

Parameters
nCount
Specifies the size of the buffer (in bytes). If the typeface name is longer than the number of bytes specified
by this parameter, the name is truncated.
lpszFacename
Points to the buffer for the typeface name.
rString
A reference to a CString object.
Return Value
The number of bytes copied to the buffer, not including the terminating null character. It is 0 if an error
occurs.
Remarks
The typeface name is copied as a null-terminated string.

CDC::GetTextMetrics
Retrieves the metrics for the current font using the attribute device context.

BOOL GetTextMetrics(LPTEXTMETRIC lpMetrics) const;

Parameters
lpMetrics
Points to the TEXTMETRIC structure that receives the metrics.
Return Value
Nonzero if the function is successful; otherwise 0.

CDC::GetViewportExt
Retrieves the x- and y-extents of the device context's viewport.

CSize GetViewportExt() const;

Return Value
The x- and y-extents (in device units) as a CSize object.

CDC::GetViewportOrg
Retrieves the x- and y-coordinates of the origin of the viewport associated with the device context.

CPoint GetViewportOrg() const;

Return Value
The origin of the viewport (in device coordinates) as a CPoint object.

CDC::GetWindow
Returns the window associated with the display device context.

CWnd* GetWindow() const;

Return Value
Pointer to a CWnd object if successful; otherwise NULL.
Remarks
This is an advanced function. For example, this member function may not return the view window when
printing or in print preview. It always returns the window associated with output. Output functions that
use the given DC draw into this window.

CDC::GetWindowExt
Retrieves the x- and y-extents of the window associated with the device context.

CSize GetWindowExt() const;

Return Value
The x- and y-extents (in logical units) as a CSize object.

CDC::GetWindowOrg
Retrieves the x- and y-coordinates of the origin of the window associated with the device context.

CPoint GetWindowOrg() const;

Return Value
The origin of the window (in logical coordinates) as a CPoint object.

CDC::GetWorldTransform
Retrieves the current world-space to page-space transformation.

BOOL GetWorldTransform(XFORM& rXform) const;

Parameters
rXform
Reference to an XFORM structure that receives the current world-space to page-space transformation.
Return Value
Returns a nonzero value on success.
Returns 0 on failure.
To get extended error information, call GetLastError.
Remarks
This method wraps the Windows GDI function GetWorldTransform.

CDC::GradientFill
Call this member function to fill rectangle and triangle structures with color that smoothly fades from one
side to the other.

BOOL GradientFill(
TRIVERTEX* pVertices,
ULONG nVertices,
void* pMesh,
ULONG nMeshElements,
DWORD dwMode);

Parameters
pVertices
Pointer to an array of TRIVERTEX structures that each define a triangle vertex.
nVertices
The number of vertices.
pMesh
Array of GRADIENT_TRIANGLE structures in triangle mode, or an array of GRADIENT_RECT structures in
rectangle mode.
nMeshElements
The number of elements (triangles or rectangles) in pMesh.
dwMode
Specifies gradient fill mode. For a list of possible values, see GradientFill in the Windows SDK.
Return Value
TRUE if successful; otherwise FALSE.
Remarks
For more information, see GradientFill in the Windows SDK.

CDC::GrayString
Draws dimmed (gray) text at the given location by writing the text in a memory bitmap, dimming the
bitmap, and then copying the bitmap to the display.

virtual BOOL GrayString(


CBrush* pBrush,
BOOL (CALLBACK* lpfnOutput)(
HDC,
LPARAM,
int),
LPARAM lpData,
int nCount,
int x,
int y,
int nWidth,
int nHeight);

Parameters
pBrush
Identifies the brush to be used for dimming (graying).
lpfnOutput
Specifies the procedure-instance address of the application-supplied callback function that will draw the
string. For more information, see the description of the Windows OutputFunc callback function. If this
parameter is NULL, the system uses the Windows TextOut function to draw the string, and lpData is
assumed to be a long pointer to the character string to be output.
lpData
Specifies a far pointer to data to be passed to the output function. If lpfnOutput is NULL, lpData must be a
long pointer to the string to be output.
nCount
Specifies the number of characters to be output. If this parameter is 0, GrayString calculates the length of
the string (assuming that lpData is a pointer to the string). If nCount is 1 and the function pointed to by
lpfnOutput returns 0, the image is shown but not dimmed.
x
Specifies the logical x-coordinate of the starting position of the rectangle that encloses the string.
y
Specifies the logical y-coordinate of the starting position of the rectangle that encloses the string.
nWidth
Specifies the width (in logical units) of the rectangle that encloses the string. If nWidth is 0, GrayString
calculates the width of the area, assuming lpData is a pointer to the string.
nHeight
Specifies the height (in logical units) of the rectangle that encloses the string. If nHeight is 0, GrayString
calculates the height of the area, assuming lpData is a pointer to the string.
Return Value
Nonzero if the string is drawn, or 0 if either the TextOut function or the application-supplied output
function returned 0, or if there was insufficient memory to create a memory bitmap for dimming.
Remarks
The function dims the text regardless of the selected brush and background. The GrayString member
function uses the currently selected font. The MM_TEXT mapping mode must be selected before using this
function.
An application can draw dimmed (grayed) strings on devices that support a solid gray color without
calling the GrayString member function. The system color COLOR_GRAYTEXT is the solid-gray system
color used to draw disabled text. The application can call the GetSysColor Windows function to retrieve
the color value of COLOR_GRAYTEXT. If the color is other than 0 (black), the application can call the
SetTextColor member function to set the text color to the color value and then draw the string directly. If
the retrieved color is black, the application must call GrayString to dim (gray) the text.
If lpfnOutput is NULL, GDI uses the Windows TextOut function, and lpData is assumed to be a far pointer
to the character to be output. If the characters to be output cannot be handled by the TextOut member
function (for example, the string is stored as a bitmap), the application must supply its own output
function.
Also note that all callback functions must trap Microsoft Foundation exceptions before returning to
Windows, since exceptions cannot be thrown across callback boundaries. For more information about
exceptions, see the article Exceptions.
The callback function passed to GrayString must use the __stdcall calling convention and must be
exported with __declspec .
When the framework is in preview mode, a call to the GrayString member function is translated to a
TextOut call, and the callback function is not called.

CDC::HIMETRICtoDP
Use this function when you convert HIMETRIC sizes from OLE to pixels.

void HIMETRICtoDP(LPSIZE lpSize) const;

Parameters
lpSize
Points to a SIZE structure or CSize object.
Remarks
If the mapping mode of the device context object is MM_LOENGLISH, MM_HIENGLISH, MM_LOMETRIC or
MM_HIMETRIC, then the conversion is based on the number of pixels in the physical inch. If the mapping
mode is one of the other non-constrained modes (e.g., MM_TEXT), then the conversion is based on the
number of pixels in the logical inch.

CDC::HIMETRICtoLP
Call this function to convert HIMETRIC units into logical units.

void HIMETRICtoLP(LPSIZE lpSize) const;

Parameters
lpSize
Points to a SIZE structure or CSize object.
Remarks
Use this function when you get HIMETRIC sizes from OLE and wish to convert them to your application's
natural mapping mode.
The conversion is accomplished by first converting the HIMETRIC units into pixels and then converting
these units into logical units using the device context's current mapping units. Note that the extents of the
device's window and viewport will affect the result.

CDC::IntersectClipRect
Creates a new clipping region by forming the intersection of the current region and the rectangle specified
by x1, y1, x2, and y2.

int IntersectClipRect(
int x1,
int y1,
int x2,
int y2);

int IntersectClipRect(LPCRECT lpRect);

Parameters
x1
Specifies the logical x-coordinate of the upper-left corner of the rectangle.
y1
Specifies the logical y-coordinate of the upper-left corner of the rectangle.
x2
Specifies the logical x-coordinate of the lower-right corner of the rectangle.
y2
Specifies the logical y-coordinate of the lower-right corner of the rectangle.
lpRect
Specifies the rectangle. You can pass either a CRect object or a pointer to a RECT structure for this
parameter.
Return Value
The new clipping region's type. It can be any one of the following values:
COMPLEXREGION New clipping region has overlapping borders.
ERROR Device context is not valid.
NULLREGION New clipping region is empty.
SIMPLEREGION New clipping region has no overlapping borders.
Remarks
GDI clips all subsequent output to fit within the new boundary. The width and height must not exceed
32,767.

CDC::InvertRect
Inverts the contents of the given rectangle.

void InvertRect(LPCRECT lpRect);

Parameters
lpRect
Points to a RECT that contains the logical coordinates of the rectangle to be inverted. You can also pass a
CRect object for this parameter.
Remarks
Inversion is a logical NOT operation and flips the bits of each pixel. On monochrome displays, the function
makes white pixels black and black pixels white. On color displays, the inversion depends on how colors
are generated for the display. Calling InvertRect twice with the same rectangle restores the display to its
previous colors.
If the rectangle is empty, nothing is drawn.
Example

void CDCView::DoInvertRect(CDC *pDC)


{
// invert rect from 20,20 to 50,50
CRect rect(20, 20, 50, 50);
pDC->InvertRect(rect);

// inverting again restores to normal


::Sleep(1000);
pDC->InvertRect(rect);
}

CDC::InvertRgn
Inverts the colors in the region specified by pRgn.

BOOL InvertRgn(CRgn* pRgn);

Parameters
pRgn
Identifies the region to be inverted. The coordinates for the region are specified in logical units.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
On monochrome displays, the function makes white pixels black and black pixels white. On color displays,
the inversion depends on how the colors are generated for the display.

CDC::IsPrinting
Determines whether the device context is being used for printing.

BOOL IsPrinting() const;

Return Value
Nonzero if the CDC object is a printer DC; otherwise 0.

CDC::LineTo
Draws a line from the current position up to, but not including, the point specified by x and y (or point).
BOOL LineTo(
int x,
int y);

BOOL LineTo(POINT point);

Parameters
x
Specifies the logical x-coordinate of the endpoint for the line.
y
Specifies the logical y-coordinate of the endpoint for the line.
point
Specifies the endpoint for the line. You can pass either a POINT structure or a CPoint object for this
parameter.
Return Value
Nonzero if the line is drawn; otherwise 0.
Remarks
The line is drawn with the selected pen. The current position is set to x, y or to point.
Example
See the example for CRect::CenterPoint.

CDC::LPtoDP
Converts logical units into device units.

void LPtoDP(
LPPOINT lpPoints,
int nCount = 1) const;

void LPtoDP(LPRECT lpRect) const;


void LPtoDP(LPSIZE lpSize) const;

Parameters
lpPoints
Points to an array of points. Each point in the array is a POINT structure or a CPoint object.
nCount
The number of points in the array.
lpRect
Points to a RECT structure or a CRect object. This parameter is used for the common case of mapping a
rectangle from logical to device units.
lpSize
Points to a SIZE structure or a CSize object.
Remarks
The function maps the coordinates of each point, or dimensions of a size, from GDI's logical coordinate
system into a device coordinate system. The conversion depends on the current mapping mode and the
settings of the origins and extents of the device's window and viewport.
The x- and y-coordinates of points are 2-byte signed integers in the range -32,768 through 32,767. In
cases where the mapping mode would result in values larger than these limits, the system sets the values
to -32,768 and 32,767, respectively.

CDC::LPtoHIMETRIC
Call this function to convert logical units into HIMETRIC units.

void LPtoHIMETRIC(LPSIZE lpSize) const;

Parameters
lpSize
Points to a SIZE structure or a CSize object.
Remarks
Use this function when you give HIMETRIC sizes to OLE, converting from your application's natural
mapping mode. Note that the extents of the device's window and viewport will affect the result.
The conversion is accomplished by first converting the logical units into pixels using the device context's
current mapping units and then converting these units into HIMETRIC units.

CDC::m_hAttribDC
The attribute device context for this CDC object.

HDC m_hAttribDC;

Remarks
By default, this device context is equal to m_hDC . In general, CDC GDI calls that request information from
the device context are directed to m_hAttribDC . See the CDC class description for more on the use of these
two device contexts.

CDC::m_hDC
The output device context for this CDC object.

HDC m_hDC;

Remarks
By default, m_hDC is equal to m_hAttribDC , the other device context wrapped by CDC . In general, CDC GDI
calls that create output go to the m_hDC device context. You can initialize m_hDC and m_hAttribDC to point
to different devices. See the CDC class description for more on the use of these two device contexts.

CDC::MaskBlt
Combines the color data for the source and destination bitmaps using the given mask and raster
operation.
BOOL MaskBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
CBitmap& maskBitmap,
int xMask,
int yMask,
DWORD dwRop);

Parameters
x
Specifies the logical x-coordinate of the upper-left corner of the destination rectangle.
y
Specifies the logical y-coordinate of the upper-left corner of the destination rectangle.
nWidth
Specifies the width, in logical units, of the destination rectangle and source bitmap.
nHeight
Specifies the height, in logical units, of the destination rectangle and source bitmap.
pSrcDC
Identifies the device context from which the bitmap is to be copied. It must be zero if the dwRop parameter
specifies a raster operation that does not include a source.
xSrc
Specifies the logical x-coordinate of the upper-left corner of the source bitmap.
ySrc
Specifies the logical y-coordinate of the upper-left corner of the source bitmap.
maskBitmap
Identifies the monochrome mask bitmap combined with the color bitmap in the source device context.
xMask
Specifies the horizontal pixel offset for the mask bitmap specified by the maskBitmap parameter.
yMask
Specifies the vertical pixel offset for the mask bitmap specified by the maskBitmap parameter.
dwRop
Specifies both foreground and background ternary raster operation codes, which the function uses to
control the combination of source and destination data. The background raster operation code is stored in
the high byte of the high word of this value; the foreground raster operation code is stored in the low byte
of the high word of this value; the low word of this value is ignored, and should be zero. The macro
MAKEROP4 creates such combinations of foreground and background raster operation codes. See the
Remarks section for a discussion of foreground and background in the context of this function. See the
BitBlt member function for a list of common raster operation codes.

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
A value of 1 in the mask specified by maskBitmap indicates that the foreground raster operation code
specified by dwRop should be applied at that location. A value of 0 in the mask indicates that the
background raster operation code specified by dwRop should be applied at that location. If the raster
operations require a source, the mask rectangle must cover the source rectangle. If it does not, the
function will fail. If the raster operations do not require a source, the mask rectangle must cover the
destination rectangle. If it does not, the function will fail.
If a rotation or shear transformation is in effect for the source device context when this function is called,
an error occurs. However, other types of transformations are allowed.
If the color formats of the source, pattern, and destination bitmaps differ, this function converts the pattern
or source format, or both, to match the destination format. If the mask bitmap is not a monochrome
bitmap, an error occurs. When an enhanced metafile is being recorded, an error occurs (and the function
returns 0) if the source device context identifies an enhanced-metafile device context. Not all devices
support MaskBlt . An application should call GetDeviceCaps to determine whether a device supports this
function. If no mask bitmap is supplied, this function behaves exactly like BitBlt , using the foreground
raster operation code. The pixel offsets in the mask bitmap map to the point (0,0) in the source device
context's bitmap. This is useful for cases in which a mask bitmap contains a set of masks; an application
can easily apply any one of them to a mask-blitting task by adjusting the pixel offsets and rectangle sizes
sent to MaskBlt .

CDC::ModifyWorldTransform
Changes the world transformation for a device context using the specified mode.

BOOL ModifyWorldTransform(
const XFORM& rXform,
DWORD iMode);

Parameters
rXform
Reference to an XFORM structure used to modify the world transformation for the given device context.
iMode
Specifies how the transformation data modifies the current world transformation. For a list of the values
that this parameter can take, see ModifyWorldTransform.
Return Value
Returns a nonzero value on success.
Returns 0 on failure.
To get extended error information, call GetLastError.
Remarks
This method wraps the Windows GDI function ModifyWorldTransform.

CDC::MoveTo
Moves the current position to the point specified by x and y (or by point).
CPoint MoveTo(
int x,
int y);

CPoint MoveTo(POINT point);

Parameters
x
Specifies the logical x-coordinate of the new position.
y
Specifies the logical y-coordinate of the new position.
point
Specifies the new position. You can pass either a POINT structure or a CPoint object for this parameter.
Return Value
The x- and y-coordinates of the previous position as a CPoint object.
Example
See the example for CRect::CenterPoint.

CDC::OffsetClipRgn
Moves the clipping region of the device context by the specified offsets.

int OffsetClipRgn(
int x,
int y);

int OffsetClipRgn(SIZE size);

Parameters
x
Specifies the number of logical units to move left or right.
y
Specifies the number of logical units to move up or down.
size
Specifies the amount to offset.
Return Value
The new region's type. It can be any one of the following values:
COMPLEXREGION Clipping region has overlapping borders.
ERROR Device context is not valid.
NULLREGION Clipping region is empty.
SIMPLEREGION Clipping region has no overlapping borders.
Remarks
The function moves the region x units along the x-axis and y units along the y-axis.
CDC::OffsetViewportOrg
Modifies the coordinates of the viewport origin relative to the coordinates of the current viewport origin.

virtual CPoint OffsetViewportOrg(


int nWidth,
int nHeight);

Parameters
nWidth
Specifies the number of device units to add to the current origin's x-coordinate.
nHeight
Specifies the number of device units to add to the current origin's y-coordinate.
Return Value
The previous viewport origin (in device coordinates) as a CPoint object.

CDC::OffsetWindowOrg
Modifies the coordinates of the window origin relative to the coordinates of the current window origin.

CPoint OffsetWindowOrg(
int nWidth,
int nHeight);

Parameters
nWidth
Specifies the number of logical units to add to the current origin's x-coordinate.
nHeight
Specifies the number of logical units to add to the current origin's y-coordinate.
Return Value
The previous window origin (in logical coordinates) as a CPoint object.

CDC::operator HDC
Use this operator to retrieve the device context handle of the CDC object.

operator HDC() const;

Return Value
If successful, the handle of the device context object; otherwise, NULL.
Remarks
You can use the handle to call Windows APIs directly.

CDC::PaintRgn
Fills the region specified by pRgn using the current brush.
BOOL PaintRgn(CRgn* pRgn);

Parameters
pRgn
Identifies the region to be filled. The coordinates for the given region are specified in logical units.
Return Value
Nonzero if the function is successful; otherwise 0.

CDC::PatBlt
Creates a bit pattern on the device.

BOOL PatBlt(
int x,
int y,
int nWidth,
int nHeight,
DWORD dwRop);

Parameters
x
Specifies the logical x-coordinate of the upper-left corner of the rectangle that is to receive the pattern.
y
Specifies the logical y-coordinate of the upper-left corner of the rectangle that is to receive the pattern.
nWidth
Specifies the width (in logical units) of the rectangle that is to receive the pattern.
nHeight
Specifies the height (in logical units) of the rectangle that is to receive the pattern.
dwRop
Specifies the raster-operation code. Raster-operation codes (ROPs) define how GDI combines colors in
output operations that involve a current brush, a possible source bitmap, and a destination bitmap. This
parameter can be one of the following values:
PATCOPY Copies pattern to destination bitmap.
PATINVERT Combines destination bitmap with pattern using the Boolean XOR operator.
DSTINVERT Inverts the destination bitmap.
BLACKNESS Turns all output black.
WHITENESS Turns all output white.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The pattern is a combination of the selected brush and the pattern already on the device. The raster-
operation code specified by dwRop defines how the patterns are to be combined. The raster operations
listed for this function are a limited subset of the full 256 ternary raster-operation codes; in particular, a
raster-operation code that refers to a source cannot be used.
Not all device contexts support the PatBlt function. To determine whether a device context supports
PatBlt , call the GetDeviceCaps member function with the RASTERCAPS index and check the return value
for the RC_BITBLT flag.

CDC::Pie
Draws a pie-shaped wedge by drawing an elliptical arc whose center and two endpoints are joined by
lines.

BOOL Pie(
int x1,
int y1,
int x2,
int y2,
int x3,
int y3,
int x4,
int y4);

BOOL Pie(
LPCRECT lpRect,
POINT ptStart,
POINT ptEnd);

Parameters
x1
Specifies the x-coordinate of the upper-left corner of the bounding rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the bounding rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the bounding rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the bounding rectangle (in logical units).
x3
Specifies the x-coordinate of the arc's starting point (in logical units). This point does not have to lie exactly
on the arc.
y3
Specifies the y-coordinate of the arc's starting point (in logical units). This point does not have to lie
exactly on the arc.
x4
Specifies the x-coordinate of the arc's endpoint (in logical units). This point does not have to lie exactly on
the arc.
y4
Specifies the y-coordinate of the arc's endpoint (in logical units). This point does not have to lie exactly on
the arc.
lpRect
Specifies the bounding rectangle. You can pass either a CRect object or a pointer to a RECT structure for
this parameter.
ptStart
Specifies the starting point of the arc. This point does not have to lie exactly on the arc. You can pass either
a POINT structure or a CPoint object for this parameter.
ptEnd
Specifies the endpoint of the arc. This point does not have to lie exactly on the arc. You can pass either a
POINT structure or a CPoint object for this parameter.

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The center of the arc is the center of the bounding rectangle specified by x1, y1, x2, and y2 (or by lpRect).
The starting and ending points of the arc are specified by x3, y3, x4, and y4 (or by ptStart and ptEnd).
The arc is drawn with the selected pen, moving in a counterclockwise direction. Two additional lines are
drawn from each endpoint to the arc's center. The pie-shaped area is filled with the current brush. If x3
equals x4 and y3 equals y4, the result is an ellipse with a single line from the center of the ellipse to the
point ( x3, y3) or ( x4, y4).
The figure drawn by this function extends up to but does not include the right and bottom coordinates.
This means that the height of the figure is y2 - y1 and the width of the figure is x2 - x1. Both the width and
the height of the bounding rectangle must be greater than 2 units and less than 32,767 units.
Example
void CDCView::DrawPie(CDC *pDC)
{
// Fill the client area with a simple pie chart. A
// big blue slice covers 75% of the pie, from
// 6 o'clock to 3 o'clock. This portion is filled
// with blue and has a blue edge. The remaining 25%
// is filled with a red, diagonal hatch and has
// a red edge.

// Get the client area.


CRect rectClient;
GetClientRect(rectClient);

// Make a couple of pens and similar brushes.


CPen penBlue, penRed;
CBrush brushBlue, brushRed;
CBrush *pOldBrush;
CPen *pOldPen;

brushBlue.CreateSolidBrush(RGB(0, 0, 255));
brushRed.CreateHatchBrush(HS_FDIAGONAL, RGB(255, 0, 0));
penBlue.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(0, 0, 255));
penRed.CreatePen(PS_SOLID | PS_COSMETIC, 1, RGB(255, 0, 0));

// Draw from 3 o'clock to 6 o'clock, counterclockwise,


// in a blue pen with a solid blue fill.

pOldPen = pDC->SelectObject(&penBlue);
pOldBrush = pDC->SelectObject(&brushBlue);

pDC->Pie(rectClient,
CPoint(rectClient.right, rectClient.CenterPoint().y),
CPoint(rectClient.CenterPoint().x, rectClient.right));

// Draw the remaining quarter slice from 6 o'clock


// to 3 o'clock, counterclockwise, in a red pen with
// the hatched brush.
pDC->SelectObject(&penRed);
pDC->SelectObject(&brushRed);

// Same parameters, but reverse start and end points.


pDC->Pie(rectClient,
CPoint(rectClient.CenterPoint().x, rectClient.right),
CPoint(rectClient.right, rectClient.CenterPoint().y));

// Restore the previous pen.


pDC->SelectObject(pOldPen);
}

CDC::PlayMetaFile
Plays the contents of the specified metafile on the device context.

BOOL PlayMetaFile(HMETAFILE hMF);

BOOL PlayMetaFile(
HENHMETAFILE hEnhMetaFile,
LPCRECT lpBounds);

Parameters
hMF
Identifies the metafile to be played.
hEnhMetaFile
Identifies the enhanced metafile.
lpBounds
Points to a RECT structure or a CRect object that contains the coordinates of the bounding rectangle used
to display the picture. The coordinates are specified in logical units.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The metafile can be played any number of times.
The second version of PlayMetaFile displays the picture stored in the given enhanced-format metafile.
When an application calls the second version of PlayMetaFile , Windows uses the picture frame in the
enhanced-metafile header to map the picture onto the rectangle pointed to by the lpBounds parameter.
(This picture may be sheared or rotated by setting the world transform in the output device before calling
PlayMetaFile .) Points along the edges of the rectangle are included in the picture. An enhanced-metafile
picture can be clipped by defining the clipping region in the output device before playing the enhanced
metafile.
If an enhanced metafile contains an optional palette, an application can achieve consistent colors by
setting up a color palette on the output device before calling the second version of PlayMetaFile . To
retrieve the optional palette, use the GetEnhMetaFilePaletteEntries Windows function. An enhanced
metafile can be embedded in a newly created enhanced metafile by calling the second version of
PlayMetaFile and playing the source enhanced metafile into the device context for the new enhanced
metafile.
The states of the output device context are preserved by this function. Any object created but not deleted
in the enhanced metafile is deleted by this function. To stop this function, an application can call the
CancelDC Windows function from another thread to terminate the operation. In this case, the function
returns zero.

CDC::PlgBlt
Performs a bit-block transfer of the bits of color data from the specified rectangle in the source device
context to the specified parallelogram in the given device context.

BOOL PlgBlt(
LPPOINT lpPoint,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nWidth,
int nHeight,
CBitmap& maskBitmap,
int xMask,
int yMask);

Parameters
lpPoint
Points to an array of three points in logical space that identifies three corners of the destination
parallelogram. The upper-left corner of the source rectangle is mapped to the first point in this array, the
upper-right corner to the second point in this array, and the lower-left corner to the third point. The lower-
right corner of the source rectangle is mapped to the implicit fourth point in the parallelogram.
pSrcDC
Identifies the source device context.
xSrc
Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.
ySrc
Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.
nWidth
Specifies the width, in logical units, of the source rectangle.
nHeight
Specifies the height, in logical units, of the source rectangle.
maskBitmap
Identifies an optional monochrome bitmap that is used to mask the colors of the source rectangle.
xMask
Specifies the x-coordinate of the upper-left corner of the monochrome bitmap.
yMask
Specifies the y-coordinate of the upper-left corner of the monochrome bitmap.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
If the given bitmask handle identifies a valid monochrome bitmap, the function uses this bitmap to mask
the bits of color data from the source rectangle.
The fourth vertex of the parallelogram (D) is defined by treating the first three points (A, B, and C) as
vectors and computing D = B + C - A.
If the bitmask exists, a value of 1 in the mask indicates that the source pixel color should be copied to the
destination. A value of 0 in the mask indicates that the destination pixel color is not to be changed.
If the mask rectangle is smaller than the source and destination rectangles, the function replicates the
mask pattern.
Scaling, translation, and reflection transformations are allowed in the source device context; however,
rotation and shear transformations are not. If the mask bitmap is not a monochrome bitmap, an error
occurs. The stretching mode for the destination device context is used to determine how to stretch or
compress the pixels, if that is necessary. When an enhanced metafile is being recorded, an error occurs if
the source device context identifies an enhanced-metafile device context.
The destination coordinates are transformed according to the destination device context; the source
coordinates are transformed according to the source device context. If the source transformation has a
rotation or shear, an error is returned. If the destination and source rectangles do not have the same color
format, PlgBlt converts the source rectangle to match the destination rectangle. Not all devices support
PlgBlt . For more information, see the description of the RC_BITBLT raster capability in the
CDC::GetDeviceCaps member function.

If the source and destination device contexts represent incompatible devices, PlgBlt returns an error.

CDC::PolyBezier
Draws one or more Bzier splines.
BOOL PolyBezier(
const POINT* lpPoints,
int nCount);

Parameters
lpPoints
Points to an array of POINT data structures that contain the endpoints and control points of the spline(s).
nCount
Specifies the number of points in the lpPoints array. This value must be one more than three times the
number of splines to be drawn, because each Bzier spline requires two control points and an endpoint,
and the initial spline requires an additional starting point.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This function draws cubic Bzier splines by using the endpoints and control points specified by the lpPoints
parameter. The first spline is drawn from the first point to the fourth point by using the second and third
points as control points. Each subsequent spline in the sequence needs exactly three more points: the end
point of the previous spline is used as the starting point, the next two points in the sequence are control
points, and the third is the end point.
The current position is neither used nor updated by the PolyBezier function. The figure is not filled. This
function draws lines by using the current pen.

CDC::PolyBezierTo
Draws one or more Bzier splines.

BOOL PolyBezierTo(
const POINT* lpPoints,
int nCount);

Parameters
lpPoints
Points to an array of POINT data structures that contains the endpoints and control points.
nCount
Specifies the number of points in the lpPoints array. This value must be three times the number of splines
to be drawn, because each Bzier spline requires two control points and an end point.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This function draws cubic Bzier splines by using the control points specified by the lpPoints parameter. The
first spline is drawn from the current position to the third point by using the first two points as control
points. For each subsequent spline, the function needs exactly three more points, and uses the end point of
the previous spline as the starting point for the next. PolyBezierTo moves the current position to the end
point of the last Bzier spline. The figure is not filled. This function draws lines by using the current pen.
Example
See the example for CDC::BeginPath.
CDC::PolyDraw
Draws a set of line segments and Bzier splines.

BOOL PolyDraw(
const POINT* lpPoints,
const BYTE* lpTypes,
int nCount);

Parameters
lpPoints
Points to an array of POINT data structures that contains the endpoints for each line segment and the
endpoints and control points for each Bzier spline.
lpTypes
Points to an array that specifies how each point in the lpPoints array is used. Values can be one of the
following:
PT_MOVETO Specifies that this point starts a disjoint figure. This point becomes the new current
position.
PT_LINETO Specifies that a line is to be drawn from the current position to this point, which then
becomes the new current position.
PT_BEZIERTO Specifies that this point is a control point or ending point for a Bzier spline.
PT_BEZIERTO types always occur in sets of three. The current position defines the starting point for the
Bzier spline. The first two PT_BEZIERTO points are the control points, and the third PT_BEZIERTO point is
the ending point. The ending point becomes the new current position. If there are not three consecutive
PT_BEZIERTO points, an error results.
A PT_LINETO or PT_BEZIERTO type can be combined with the following constant by using the bitwise
operator OR to indicate that the corresponding point is the last point in a figure and the figure is closed:
PT_CLOSEFIGURE Specifies that the figure is automatically closed after the PT_LINETO or
PT_BEZIERTO type for this point is done. A line is drawn from this point to the most recent
PT_MOVETO or MoveTo point.
This flag is combined with the PT_LINETO type for a line, or with the PT_BEZIERTO type of ending
point for a Bzier spline, by using the bitwise OR operator. The current position is set to the ending
point of the closing line.
nCount
Specifies the total number of points in the lpPoints array, the same as the number of bytes in the lpTypes
array.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This function can be used to draw disjoint figures in place of consecutive calls to CDC::MoveTo ,
CDC::LineTo , and CDC::PolyBezierTo member functions. The lines and splines are drawn using the current
pen, and figures are not filled. If there is an active path started by calling the CDC::BeginPath member
function, PolyDraw adds to the path. The points contained in the lpPoints array and in lpTypes indicate
whether each point is part of a CDC::MoveTo , a CDC::LineTo , or a CDC::BezierTo operation. It is also
possible to close figures. This function updates the current position.
Example
See the example for CDC::BeginPath.

CDC::Polygon
Draws a polygon consisting of two or more points (vertices) connected by lines, using the current pen.

BOOL Polygon(
LPPOINT lpPoints,
int nCount);

Parameters
lpPoints
Points to an array of points that specifies the vertices of the polygon. Each point in the array is a POINT
structure or a CPoint object.
nCount
Specifies the number of vertices in the array.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The system closes the polygon automatically, if necessary, by drawing a line from the last vertex to the
first.
The current polygon-filling mode can be retrieved or set by using the GetPolyFillMode and
SetPolyFillMode member functions.

Example
void CDCView::DrawPolygon(CDC *pDC)
{
// find the client area
CRect rect;
GetClientRect(rect);

// draw with a thick blue pen


CPen penBlue(PS_SOLID, 5, RGB(0, 0, 255));
CPen *pOldPen = pDC->SelectObject(&penBlue);

// and a solid red brush


CBrush brushRed(RGB(255, 0, 0));
CBrush *pOldBrush = pDC->SelectObject(&brushRed);

// Find the midpoints of the top, right, left, and bottom


// of the client area. They will be the vertices of our polygon.
CPoint pts[4];
pts[0].x = rect.left + rect.Width() / 2;
pts[0].y = rect.top;

pts[1].x = rect.right;
pts[1].y = rect.top + rect.Height() / 2;

pts[2].x = pts[0].x;
pts[2].y = rect.bottom;

pts[3].x = rect.left;
pts[3].y = pts[1].y;

// Calling Polygon() on that array will draw three lines


// between the points, as well as an additional line to
// close the shape--from the last point to the first point
// we specified.
pDC->Polygon(pts, 4);

// Put back the old objects.


pDC->SelectObject(pOldPen);
pDC->SelectObject(pOldBrush);
}

CDC::Polyline
Draws a set of line segments connecting the points specified by lpPoints.

BOOL Polyline(
LPPOINT lpPoints,
int nCount);

Parameters
lpPoints
Points to an array of POINT structures or CPoint objects to be connected.
nCount
Specifies the number of points in the array. This value must be at least 2.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The lines are drawn from the first point through subsequent points using the current pen. Unlike the
LineTo member function, the Polyline function neither uses nor updates the current position.
For more information, see PolyLine in the Windows SDK.

CDC::PolylineTo
Draws one or more straight lines.

BOOL PolylineTo(
const POINT* lpPoints,
int nCount);

Parameters
lpPoints
Points to an array of POINT data structures that contains the vertices of the line.
nCount
Specifies the number of points in the array.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
A line is drawn from the current position to the first point specified by the lpPoints parameter by using the
current pen. For each additional line, the function draws from the ending point of the previous line to the
next point specified by lpPoints. PolylineTo moves the current position to the ending point of the last line.
If the line segments drawn by this function form a closed figure, the figure is not filled.

CDC::PolyPolygon
Creates two or more polygons that are filled using the current polygon-filling mode.

BOOL PolyPolygon(
LPPOINT lpPoints,
LPINT lpPolyCounts,
int nCount);

Parameters
lpPoints
Points to an array of POINT structures or CPoint objects that define the vertices of the polygons.
lpPolyCounts
Points to an array of integers, each of which specifies the number of points in one of the polygons in the
lpPoints array.
nCount
The number of entries in the lpPolyCounts array. This number specifies the number of polygons to be
drawn. This value must be at least 2.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The polygons may be disjoint or overlapping.
Each polygon specified in a call to the PolyPolygon function must be closed. Unlike polygons created by
the Polygon member function, the polygons created by PolyPolygon are not closed automatically.
The function creates two or more polygons. To create a single polygon, an application should use the
Polygon member function.

The current polygon-filling mode can be retrieved or set by using the GetPolyFillMode and
SetPolyFillMode member functions.

CDC::PolyPolyline
Draws multiple series of connected line segments.

BOOL PolyPolyline(
const POINT* lpPoints,
const DWORD* lpPolyPoints,
int nCount);

Parameters
lpPoints
Points to an array of structures that contains the vertices of the polylines. The polylines are specified
consecutively.
lpPolyPoints
Points to an array of variables specifying the number of points in the lpPoints array for the corresponding
polygon. Each entry must be greater than or equal to 2.
nCount
Specifies the total number of counts in the lpPolyPoints array.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The line segments are drawn by using the current pen. The figures formed by the segments are not filled.
The current position is neither used nor updated by this function.

CDC::PtVisible
Determines whether the given point is within the clipping region of the device context.

virtual BOOL PtVisible(


int x,
int y) const;

BOOL PtVisible(POINT point) const;

Parameters
x
Specifies the logical x-coordinate of the point.
y
Specifies the logical y-coordinate of the point.
point
Specifies the point to check in logical coordinates. You can pass either a POINT structure or a CPoint
object for this parameter.
Return Value
Nonzero if the specified point is within the clipping region; otherwise 0.

CDC::QueryAbort
Calls the abort function installed by the SetAbortProc member function for a printing application and
queries whether the printing should be terminated.

BOOL QueryAbort() const;

Return Value
The return value is nonzero if printing should continue or if there is no abort procedure. It is 0 if the print
job should be terminated. The return value is supplied by the abort function.

CDC::RealizePalette
Maps entries from the current logical palette to the system palette.

UINT RealizePalette();

Return Value
Indicates how many entries in the logical palette were mapped to different entries in the system palette.
This represents the number of entries that this function remapped to accommodate changes in the system
palette since the logical palette was last realized.
Remarks
A logical color palette acts as a buffer between color-intensive applications and the system, allowing an
application to use as many colors as needed without interfering with its own displayed colors or with
colors displayed by other windows.
When a window has the input focus and calls RealizePalette , Windows ensures that the window will
display all the requested colors, up to the maximum number simultaneously available on the screen.
Windows also displays colors not found in the window's palette by matching them to available colors.
In addition, Windows matches the colors requested by inactive windows that call the function as closely as
possible to the available colors. This significantly reduces undesirable changes in the colors displayed in
inactive windows.

CDC::Rectangle
Draws a rectangle using the current pen.

BOOL Rectangle(
int x1,
int y1,
int x2,
int y2);

BOOL Rectangle(LPCRECT lpRect);


Parameters
x1
Specifies the x-coordinate of the upper-left corner of the rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the rectangle (in logical units).
lpRect
Specifies the rectangle in logical units. You can pass either a CRect object or a pointer to a RECT structure
for this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The interior of the rectangle is filled using the current brush.
The rectangle extends up to, but does not include, the right and bottom coordinates. This means that the
height of the rectangle is y2 - y1 and the width of the rectangle is x2 - x1. Both the width and the height of
a rectangle must be greater than 2 units and less than 32,767 units.
Example

void CDCView::DrawRectangle(CDC *pDC)


{
// create and select a solid blue brush
CBrush brushBlue(RGB(0, 0, 255));
CBrush *pOldBrush = pDC->SelectObject(&brushBlue);

// create and select a thick, black pen


CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
CPen *pOldPen = pDC->SelectObject(&penBlack);

// get our client rectangle


CRect rect;
GetClientRect(rect);

// shrink our rect 20 pixels in each direction


rect.DeflateRect(20, 20);

// draw a thick black rectangle filled with blue


pDC->Rectangle(rect);

// put back the old objects


pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}

CDC::RectVisible
Determines whether any part of the given rectangle lies within the clipping region of the display context.
virtual BOOL RectVisible(LPCRECT lpRect) const;

Parameters
lpRect
Points to a RECT structure or a CRect object that contains the logical coordinates of the specified
rectangle.
Return Value
Nonzero if any portion of the given rectangle lies within the clipping region; otherwise 0.

CDC::ReleaseAttribDC
Call this member function to set m_hAttribDC to NULL.

virtual void ReleaseAttribDC();

Remarks
This does not cause a Detach to occur. Only the output device context is attached to the CDC object, and
only it can be detached.

CDC::ReleaseOutputDC
Call this member function to set the m_hDC member to NULL.

virtual void ReleaseOutputDC();

Remarks
This member function cannot be called when the output device context is attached to the CDC object. Use
the Detach member function to detach the output device context.

CDC::ResetDC
Call this member function to update the device context wrapped by the CDC object.

BOOL ResetDC(const DEVMODE* lpDevMode);

Parameters
lpDevMode
A pointer to a Windows DEVMODE structure.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The device context is updated from the information specified in the Windows DEVMODE structure. This
member function only resets the attribute device context.
An application will typically use the ResetDC member function when a window processes a
WM_DEVMODECHANGE message. You can also use this member function to change the paper orientation or
paper bins while printing a document.
You cannot use this member function to change the driver name, device name, or output port. When the
user changes the port connection or device name, you must delete the original device context and create a
new device context with the new information.
Before you call this member function, you must ensure that all objects (other than stock objects) that had
been selected into the device context have been selected out.

CDC::RestoreDC
Restores the device context to the previous state identified by nSavedDC.

virtual BOOL RestoreDC(int nSavedDC);

Parameters
nSavedDC
Specifies the device context to be restored. It can be a value returned by a previous SaveDC function call. If
nSavedDC is -1, the most recently saved device context is restored.
Return Value
Nonzero if the specified context was restored; otherwise 0.
Remarks
RestoreDC restores the device context by popping state information off a stack created by earlier calls to
the SaveDC member function.
The stack can contain the state information for several device contexts. If the context specified by
nSavedDC is not at the top of the stack, RestoreDC deletes all state information between the device
context specified by nSavedDC and the top of the stack. The deleted information is lost.

CDC::RoundRect
Draws a rectangle with rounded corners using the current pen.

BOOL RoundRect(
int x1,
int y1,
int x2,
int y2,
int x3,
int y3);

BOOL RoundRect(
LPCRECT lpRect,
POINT point);

Parameters
x1
Specifies the x-coordinate of the upper-left corner of the rectangle (in logical units).
y1
Specifies the y-coordinate of the upper-left corner of the rectangle (in logical units).
x2
Specifies the x-coordinate of the lower-right corner of the rectangle (in logical units).
y2
Specifies the y-coordinate of the lower-right corner of the rectangle (in logical units).
x3
Specifies the width of the ellipse used to draw the rounded corners (in logical units).
y3
Specifies the height of the ellipse used to draw the rounded corners (in logical units).
lpRect
Specifies the bounding rectangle in logical units. You can pass either a CRect object or a pointer to a
RECT structure for this parameter.

point
The x-coordinate of point specifies the width of the ellipse to draw the rounded corners (in logical units).
The y-coordinate of point specifies the height of the ellipse to draw the rounded corners (in logical units).
You can pass either a POINT structure or a CPoint object for this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The interior of the rectangle is filled using the current brush.
The figure this function draws extends up to but does not include the right and bottom coordinates. This
means that the height of the figure is y2 - y1 and the width of the figure is x2 - x1. Both the height and the
width of the bounding rectangle must be greater than 2 units and less than 32,767 units.
Example

void CDCView::DrawRoundRect(CDC *pDC)


{
// create and select a solid blue brush
CBrush brushBlue(RGB(0, 0, 255));
CBrush *pOldBrush = pDC->SelectObject(&brushBlue);

// create and select a thick, black pen


CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
CPen *pOldPen = pDC->SelectObject(&penBlack);

// get our client rectangle


CRect rect;
GetClientRect(rect);

// shrink our rect 20 pixels in each direction


rect.DeflateRect(20, 20);

// Draw a thick black rectangle filled with blue


// corners rounded at a 17-unit radius. Note that
// a radius of three or less is not noticeable because
// the pen is three units wide.
pDC->RoundRect(rect, CPoint(17, 17));

// put back the old objects


pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}

CDC::SaveDC
Saves the current state of the device context by copying state information (such as clipping region,
selected objects, and mapping mode) to a context stack maintained by Windows.

virtual int SaveDC();

Return Value
An integer identifying the saved device context. It is 0 if an error occurs. This return value can be used to
restore the device context by calling RestoreDC .
Remarks
The saved device context can later be restored by using RestoreDC .
SaveDC can be used any number of times to save any number of device-context states.

CDC::ScaleViewportExt
Modifies the viewport extents relative to the current values.

virtual CSize ScaleViewportExt(


int xNum,
int xDenom,
int yNum,
int yDenom);

Parameters
xNum
Specifies the amount by which to multiply the current x-extent.
xDenom
Specifies the amount by which to divide the result of multiplying the current x-extent by the value of the
xNum parameter.
yNum
Specifies the amount by which to multiply the current y-extent.
yDenom
Specifies the amount by which to divide the result of multiplying the current y-extent by the value of the
yNum parameter.
Return Value
The previous viewport extents (in device units) as a CSize object.
Remarks
The formulas are written as follows:
xNewVE = ( xOldVE * xNum ) / xDenom

yNewVE = ( yOldVE * yNum ) / yDenom

The new viewport extents are calculated by multiplying the current extents by the given numerator and
then dividing by the given denominator.

CDC::ScaleWindowExt
Modifies the window extents relative to the current values.
virtual CSize ScaleWindowExt(
int xNum,
int xDenom,
int yNum,
int yDenom);

Parameters
xNum
Specifies the amount by which to multiply the current x-extent.
xDenom
Specifies the amount by which to divide the result of multiplying the current x-extent by the value of the
xNum parameter.
yNum
Specifies the amount by which to multiply the current y-extent.
yDenom
Specifies the amount by which to divide the result of multiplying the current y-extent by the value of the
yNum parameter.
Return Value
The previous window extents (in logical units) as a CSize object.
Remarks
The formulas are written as follows:
xNewWE = ( xOldWE * xNum ) / xDenom

yNewWE = ( yOldWE * yNum ) / yDenom

The new window extents are calculated by multiplying the current extents by the given numerator and
then dividing by the given denominator.

CDC::ScrollDC
Scrolls a rectangle of bits horizontally and vertically.

BOOL ScrollDC(
int dx,
int dy,
LPCRECT lpRectScroll,
LPCRECT lpRectClip,
CRgn* pRgnUpdate,
LPRECT lpRectUpdate);

Parameters
dx
Specifies the number of horizontal scroll units.
dy
Specifies the number of vertical scroll units.
lpRectScroll
Points to the RECT structure or CRect object that contains the coordinates of the scrolling rectangle.
lpRectClip
Points to the RECT structure or CRect object that contains the coordinates of the clipping rectangle.
When this rectangle is smaller than the original one pointed to by lpRectScroll, scrolling occurs only in the
smaller rectangle.
pRgnUpdate
Identifies the region uncovered by the scrolling process. The ScrollDC function defines this region; it is
not necessarily a rectangle.
lpRectUpdate
Points to the RECT structure or CRect object that receives the coordinates of the rectangle that bounds
the scrolling update region. This is the largest rectangular area that requires repainting. The values in the
structure or object when the function returns are in client coordinates, regardless of the mapping mode
for the given device context.
Return Value
Nonzero if scrolling is executed; otherwise 0.
Remarks
If lpRectUpdate is NULL, Windows does not compute the update rectangle. If both pRgnUpdate and
lpRectUpdate are NULL, Windows does not compute the update region. If pRgnUpdate is not NULL,
Windows assumes that it contains a valid pointer to the region uncovered by the scrolling process
(defined by the ScrollDC member function). The update region returned in lpRectUpdate can be passed to
CWnd::InvalidateRgn if required.

An application should use the ScrollWindow member function of class CWnd when it is necessary to scroll
the entire client area of a window. Otherwise, it should use ScrollDC .

CDC::SelectClipPath
Selects the current path as a clipping region for the device context, combining the new region with any
existing clipping region by using the specified mode.

BOOL SelectClipPath(int nMode);

Parameters
nMode
Specifies the way to use the path. The following values are allowed:
RGN_AND The new clipping region includes the intersection (overlapping areas) of the current
clipping region and the current path.
RGN_COPY The new clipping region is the current path.
RGN_DIFF The new clipping region includes the areas of the current clipping region, and those of
the current path are excluded.
RGN_OR The new clipping region includes the union (combined areas) of the current clipping
region and the current path.
RGN_XOR The new clipping region includes the union of the current clipping region and the
current path, but without the overlapping areas.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The device context identified must contain a closed path.

CDC::SelectClipRgn
Selects the given region as the current clipping region for the device context.

int SelectClipRgn(CRgn* pRgn);

int SelectClipRgn(
CRgn* pRgn,
int nMode);

Parameters
pRgn
Identifies the region to be selected.
For the first version of this function, if this value is NULL, the entire client area is selected and
output is still clipped to the window.
For the second version of this function, this handle can be NULL only when the RGN_COPY mode is
specified.
nMode
Specifies the operation to be performed. It must be one of the following values:
RGN_AND The new clipping region combines the overlapping areas of the current clipping region
and the region identified by pRgn.
RGN_COPY The new clipping region is a copy of the region identified by pRgn. This is functionality
is identical to the first version of SelectClipRgn . If the region identified by pRgn is NULL, the new
clipping region becomes the default clipping region (a null region).
RGN_DIFF The new clipping region combines the areas of the current clipping region with those
areas excluded from the region identified by pRgn.
RGN_OR The new clipping region combines the current clipping region and the region identified by
pRgn.
RGN_XOR The new clipping region combines the current clipping region and the region identified
by pRgn but excludes any overlapping areas.
Return Value
The region's type. It can be any of the following values:
COMPLEXREGION New clipping region has overlapping borders.
ERROR Device context or region is not valid.
NULLREGION New clipping region is empty.
SIMPLEREGION New clipping region has no overlapping borders.
Remarks
Only a copy of the selected region is used. The region itself can be selected for any number of other device
contexts, or it can be deleted.
The function assumes that the coordinates for the given region are specified in device units. Some printer
devices support text output at a higher resolution than graphics output in order to retain the precision
needed to express text metrics. These devices report device units at the higher resolution, that is, in text
units. These devices then scale coordinates for graphics so that several reported device units map to only
1 graphic unit. You should always call the SelectClipRgn function using text units.
Applications that must take the scaling of graphics objects in the GDI can use the GETSCALINGFACTOR
printer escape to determine the scaling factor. This scaling factor affects clipping. If a region is used to clip
graphics, GDI divides the coordinates by the scaling factor. If the region is used to clip text, GDI makes no
scaling adjustment. A scaling factor of 1 causes the coordinates to be divided by 2; a scaling factor of 2
causes the coordinates to be divided by 4; and so on.

CDC::SelectObject
Selects an object into the device context.

CPen* SelectObject(CPen* pPen);


CBrush* SelectObject(CBrush* pBrush);
virtual CFont* SelectObject(CFont* pFont);
CBitmap* SelectObject(CBitmap* pBitmap);
int SelectObject(CRgn* pRgn);
CGdiObject* SelectObject(CGdiObject* pObject);

Parameters
pPen
A pointer to a CPen object to be selected.
pBrush
A pointer to a CBrush object to be selected.
pFont
A pointer to a CFont object to be selected.
pBitmap
A pointer to a CBitmap object to be selected.
pRgn
A pointer to a CRgn object to be selected.
pObject
A pointer to a CGdiObject object to be selected.
Return Value
A pointer to the object being replaced. This is a pointer to an object of one of the classes derived from
CGdiObject , such as CPen , depending on which version of the function is used. The return value is NULL
if there is an error. This function may return a pointer to a temporary object. This temporary object is only
valid during the processing of one Windows message. For more information, see CGdiObject::FromHandle .
The version of the member function that takes a region parameter performs the same task as the
SelectClipRgn member function. Its return value can be any of the following:

COMPLEXREGION New clipping region has overlapping borders.


ERROR Device context or region is not valid.
NULLREGION New clipping region is empty.
SIMPLEREGION New clipping region has no overlapping borders.
Remarks
Class CDC provides five versions specialized for particular kinds of GDI objects, including pens, brushes,
fonts, bitmaps, and regions. The newly selected object replaces the previous object of the same type. For
example, if pObject of the general version of SelectObject points to a CPen object, the function replaces
the current pen with the pen specified by pObject.
An application can select a bitmap into memory device contexts only and into only one memory device
context at a time. The format of the bitmap must either be monochrome or compatible with the device
context; if it is not, SelectObject returns an error.
For Windows 3.1 and later, the SelectObject function returns the same value whether it is used in a
metafile or not. Under previous versions of Windows, SelectObject returned a nonzero value for success
and 0 for failure when it was used in a metafile.

CDC::SelectPalette
Selects the logical palette that is specified by pPalette as the selected palette object of the device context.

CPalette* SelectPalette(
CPalette* pPalette,
BOOL bForceBackground);

Parameters
pPalette
Identifies the logical palette to be selected. This palette must already have been created with the CPalette
member function CreatePalette.
bForceBackground
Specifies whether the logical palette is forced to be a background palette. If bForceBackground is nonzero,
the selected palette is always a background palette, regardless of whether the window has the input focus.
If bForceBackground is 0 and the device context is attached to a window, the logical palette is a foreground
palette when the window has the input focus.
Return Value
A pointer to a CPalette object identifying the logical palette replaced by the palette specified by pPalette.
It is NULL if there is an error.
Remarks
The new palette becomes the palette object used by GDI to control colors displayed in the device context
and replaces the previous palette.
An application can select a logical palette into more than one device context. However, changes to a logical
palette will affect all device contexts for which it is selected. If an application selects a palette into more
than one device context, the device contexts must all belong to the same physical device.

CDC::SelectStockObject
Selects a CGdiObject object that corresponds to one of the predefined stock pens, brushes, or fonts.

virtual CGdiObject* SelectStockObject(int nIndex);

Parameters
nIndex
Specifies the kind of stock object desired. It can be one of the following values:
BLACK_BRUSH Black brush.
DKGRAY_BRUSH Dark gray brush.
GRAY_BRUSH Gray brush.
HOLLOW_BRUSH Hollow brush.
LTGRAY_BRUSH Light gray brush.
NULL_BRUSH Null brush.
WHITE_BRUSH White brush.
BLACK_PEN Black pen.
NULL_PEN Null pen.
WHITE_PEN White pen.
ANSI_FIXED_FONT ANSI fixed system font.
ANSI_VAR_FONT ANSI variable system font.
DEVICE_DEFAULT_FONT Device-dependent font.
OEM_FIXED_FONT OEM-dependent fixed font.
SYSTEM_FONT The system font. By default, Windows uses the system font to draw menus, dialog-
box controls, and other text. It is best, however, not to rely on SYSTEM_FONT to obtain the font used
by dialogs and windows. Instead, use the SystemParametersInfo function with the
SPI_GETNONCLIENTMETRICS parameter to retrieve the current font. SystemParametersInfo takes
into account the current theme and provides font information for captions, menus, and message
dialogs.
SYSTEM_FIXED_FONT The fixed-width system font used in Windows prior to version 3.0. This object
is available for compatibility with earlier versions of Windows.
DEFAULT_PALETTE Default color palette. This palette consists of the 20 static colors in the system
palette.
Return Value
A pointer to the CGdiObject object that was replaced if the function is successful. The actual object pointed
to is a CPen, CBrush, or CFont object. If the call is unsuccessful, the return value is NULL.

CDC::SetAbortProc
Installs the abort procedure for the print job.

int SetAbortProc(BOOL (CALLBACK* lpfn)(HDC, int));

Parameters
lpfn
A pointer to the abort function to install as the abort procedure. For more about the callback function, see
Callback Function for CDC::SetAbortProc.
Return Value
Specifies the outcome of the SetAbortProc function. Some of the following values are more probable than
others, but all are possible.
SP_ERROR General error.
SP_OUTOFDISK Not enough disk space is currently available for spooling, and no more space will
become available.
SP_OUTOFMEMORY Not enough memory is available for spooling.
SP_USERABORT User ended the job through the Print Manager.
Remarks
If an application is to allow the print job to be canceled during spooling, it must set the abort function
before the print job is started with the StartDoc member function. The Print Manager calls the abort
function during spooling to allow the application to cancel the print job or to process out-of-disk-space
conditions. If no abort function is set, the print job will fail if there is not enough disk space for spooling.
Note that the features of Microsoft Visual C++ simplify the creation of the callback function passed to
SetAbortProc . The address passed to the EnumObjects member function is a pointer to a function
exported with __declspec(dllexport) and with the __stdcall calling convention.
You also do not have to export the function name in an EXPORTS statement in your application's module-
definition file. You can instead use the EXPORT function modifier, as in
BOOL CALLBACK EXPORT AFunction( HDC , int );
to cause the compiler to emit the proper export record for export by name without aliasing. This works for
most needs. For some special cases, such as exporting a function by ordinal or aliasing the export, you still
need to use an EXPORTS statement in a module-definition file.
Callback registration interfaces are now type-safe (you must pass in a function pointer that points to the
right kind of function for the specific callback).
Also note that all callback functions must trap Microsoft Foundation exceptions before returning to
Windows, since exceptions cannot be thrown across callback boundaries. For more information about
exceptions, see the article Exceptions.

CDC::SetArcDirection
Sets the drawing direction to be used for arc and rectangle functions.

int SetArcDirection(int nArcDirection);

Parameters
nArcDirection
Specifies the new arc direction. This parameter can be either of the following values:
AD_COUNTERCLOCKWISE Figures drawn counterclockwise.
AD_CLOCKWISE Figures drawn clockwise.
Return Value
Specifies the old arc direction, if successful; otherwise 0.
Remarks
The default direction is counterclockwise. The SetArcDirection function specifies the direction in which
the following functions draw:
A RC P IE

ArcTo Rectangle

Chord RoundRect

Ellipse

CDC::SetAttribDC
Call this function to set the attribute device context, m_hAttribDC .

virtual void SetAttribDC(HDC hDC);

Parameters
hDC
A Windows device context.
Remarks
This member function does not attach the device context to the CDC object. Only the output device
context is attached to a CDC object.

CDC::SetBkColor
Sets the current background color to the specified color.

virtual COLORREF SetBkColor(COLORREF crColor);

Parameters
crColor
Specifies the new background color.
Return Value
The previous background color as an RGB color value. If an error occurs, the return value is 0x80000000.
Remarks
If the background mode is OPAQUE, the system uses the background color to fill the gaps in styled lines,
the gaps between hatched lines in brushes, and the background in character cells. The system also uses
the background color when converting bitmaps between color and monochrome device contexts.
If the device cannot display the specified color, the system sets the background color to the nearest
physical color.

CDC::SetBkMode
Sets the background mode.

int SetBkMode(int nBkMode);

Parameters
nBkMode
Specifies the mode to be set. This parameter can be either of the following values:
OPAQUE Background is filled with the current background color before the text, hatched brush, or
pen is drawn. This is the default background mode.
TRANSPARENT Background is not changed before drawing.
Return Value
The previous background mode.
Remarks
The background mode defines whether the system removes existing background colors on the drawing
surface before drawing text, hatched brushes, or any pen style that is not a solid line.
Example
See the example for CWnd::OnCtlColor.

CDC::SetBoundsRect
Controls the accumulation of bounding-rectangle information for the specified device context.

UINT SetBoundsRect(
LPCRECT lpRectBounds,
UINT flags);

Parameters
lpRectBounds
Points to a RECT structure or CRect object that is used to set the bounding rectangle. Rectangle
dimensions are given in logical coordinates. This parameter can be NULL.
flags
Specifies how the new rectangle will be combined with the accumulated rectangle. This parameter can be
a combination of the following values:
DCB_ACCUMULATE Add the rectangle specified by lpRectBounds to the bounding rectangle (using
a rectangle-union operation).
DCB_DISABLE Turn off bounds accumulation.
DCB_ENABLE Turn on bounds accumulation. (The default setting for bounds accumulation is
disabled.)
Return Value
The current state of the bounding rectangle, if the function is successful. Like flags, the return value can be
a combination of DCB_ values:
DCB_ACCUMULATE The bounding rectangle is not empty. This value will always be set.
DCB_DISABLE Bounds accumulation is off.
DCB_ENABLE Bounds accumulation is on.
Remarks
Windows can maintain a bounding rectangle for all drawing operations. This rectangle can be queried and
reset by the application. The drawing bounds are useful for invalidating bitmap caches.

CDC::SetBrushOrg
Specifies the origin that GDI will assign to the next brush that the application selects into the device
context.

CPoint SetBrushOrg(
int x,
int y);

CPoint SetBrushOrg(POINT point);

Parameters
x
Specifies the x-coordinate (in device units) of the new origin. This value must be in the range 0-7.
y
Specifies the y-coordinate (in device units) of the new origin. This value must be in the range 0-7.
point
Specifies the x- and y-coordinates of the new origin. Each value must be in the range 0-7. You can pass
either a POINT structure or a CPoint object for this parameter.
Return Value
The previous origin of the brush in device units.
Remarks
The default coordinates for the brush origin are (0, 0). To alter the origin of a brush, call the
UnrealizeObject function for the CBrush object, call SetBrushOrg , and then call the SelectObject
member function to select the brush into the device context.
Do not use SetBrushOrg with stock CBrush objects.

CDC::SetColorAdjustment
Sets the color adjustment values for the device context using the specified values.

BOOL SetColorAdjustment(const COLORADJUSTMENT* lpColorAdjust);

Parameters
lpColorAdjust
Points to a COLORADJUSTMENT data structure containing the color adjustment values.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The color adjustment values are used to adjust the input color of the source bitmap for calls to the
CDC::StretchBlt member function when HALFTONE mode is set.

CDC::SetDCBrushColor
Sets the current device context (DC) brush color to the specified color value.

COLORREF SetDCBrushColor(COLORREF crColor);

Parameters
crColor
Specifies the new brush color.
Return Value
If the function succeeds, the return value specifies the previous DC brush color as a COLORREF value.
If the function fails, the return value is CLR_INVALID.
Remarks
This method emulates the functionality of the function SetDCBrushColor, as described in the Windows
SDK.

CDC::SetDCPenColor
Sets the current device context (DC) pen color to the specified color value.

COLORREF SetDCPenColor(COLORREF crColor);

Parameters
crColor
Specifies the new pen color.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This member function utilizes the Win32 function SetDCPenColor, as described in the Windows SDK.

CDC::SetGraphicsMode
Sets the graphics mode for the specified device context.

int SetGraphicsMode(int iMode);

Parameters
iMode
Specifies the graphics mode. For a list of the values that this parameter can take, see SetGraphicsMode.
Return Value
Returns the old graphics mode on success.
Returns 0 on failure. To get extended error information, call GetLastError.
Remarks
This method wraps the Windows GDI function SetGraphicsMode.

CDC::SetLayout
Call this member function to change the layout of the text and graphics for a device context to right to left,
the standard layout for cultures such as Arabic and Hebrew.

DWORD SetLayout(DWORD dwLayout);


Parameters
dwLayout
Device context layout and bitmap control flags. It can be a combination of the following values.

VA L UE M EA N IN G

LAYOUT_BITMAPORIENTATIONPRESERVED Disables any reflection for calls to CDC::BitBlt and


CDC::StretchBlt.

LAYOUT_RTL Sets the default horizontal layout to be right to left.

LAYOUT_LTR Sets the default layout to be left to right.

Return Value
If successful, the previous layout of the device context.
If unsuccessful, GDI_ERROR. To get extended error information, call GetLastError.
Remarks
Normally, you would not call SetLayout for a window. Rather, you control the right-to-left layout in a
window by setting the extended window styles such as WS_EX_RTLREADING. A device context, such as a
printer or a metafile, does not inherit this layout. The only way to set the device context for a right-to-left
layout is by calling SetLayout .
If you call SetLayout(L AYOUT_RTL ), SetLayout automatically changes the mapping mode to
MM_ISOTROPIC. As a result, a subsequent call to GetMapMode will return MM_ISOTROPIC instead of
MM_TEXT.
In some cases, such as with many bitmaps, you may want to preserve the left-to-right layout. In these
cases, render the image by calling BitBlt or StretchBlt , then set the bitmap control flag for dwLayout to
LAYOUT_BITMAPORIENTATIONPRESERVED.
Once you change the layout with the LAYOUT_RTL flag, the flags normally specifying right or left are
reversed. To avoid confusion, you may want to define alternate names for the standard flags. For a list of
suggested alternate flag names, see SetLayout in the Windows SDK.

CDC::SetMapMode
Sets the mapping mode.

virtual int SetMapMode(int nMapMode);

Parameters
nMapMode
Specifies the new mapping mode. It can be any one of the following values:
MM_ANISOTROPIC Logical units are converted to arbitrary units with arbitrarily scaled axes.
Setting the mapping mode to MM_ANISOTROPIC does not change the current window or viewport
settings. To change the units, orientation, and scaling, call the SetWindowExt and SetViewportExt
member functions.
MM_HIENGLISH Each logical unit is converted to 0.001 inch. Positive x is to the right; positive y is
up.
MM_HIMETRIC Each logical unit is converted to 0.01 millimeter. Positive x is to the right; positive y
is up.
MM_ISOTROPIC Logical units are converted to arbitrary units with equally scaled axes; that is, 1
unit along the x-axis is equal to 1 unit along the y-axis. Use the SetWindowExt and SetViewportExt
member functions to specify the desired units and the orientation of the axes. GDI makes
adjustments as necessary to ensure that the x and y units remain the same size.
MM_LOENGLISH Each logical unit is converted to 0.01 inch. Positive x is to the right; positive y is up.
MM_LOMETRIC Each logical unit is converted to 0.1 millimeter. Positive x is to the right; positive y is
up.
MM_TEXT Each logical unit is converted to 1 device pixel. Positive x is to the right; positive y is
down.
MM_TWIPS Each logical unit is converted to 1/20 of a point. (Because a point is 1/72 inch, a twip is
1/1440 inch.) Positive x is to the right; positive y is up.
Return Value
The previous mapping mode.
Remarks
The mapping mode defines the unit of measure used to convert logical units to device units; it also defines
the orientation of the device's x- and y-axes. GDI uses the mapping mode to convert logical coordinates
into the appropriate device coordinates. The MM_TEXT mode allows applications to work in device pixels,
where 1 unit is equal to 1 pixel. The physical size of a pixel varies from device to device.
The MM_HIENGLISH, MM_HIMETRIC, MM_LOENGLISH, MM_LOMETRIC, and MM_TWIPS modes are useful
for applications that must draw in physically meaningful units (such as inches or millimeters). The
MM_ISOTROPIC mode ensures a 1:1 aspect ratio, which is useful when it is important to preserve the
exact shape of an image. The MM_ANISOTROPIC mode allows the x- and y-coordinates to be adjusted
independently.

NOTE
If you call SetLayout to change the DC (device context) to right-to-left layout, SetLayout automatically changes
the mapping mode to MM_ISOTROPIC.

Example
See the example for CView::OnPrepareDC.

CDC::SetMapperFlags
Changes the method used by the font mapper when it converts a logical font to a physical font.

DWORD SetMapperFlags(DWORD dwFlag);

Parameters
dwFlag
Specifies whether the font mapper attempts to match a font's aspect height and width to the device. When
this value is ASPECT_FILTERING, the mapper selects only fonts whose x-aspect and y-aspect exactly match
those of the specified device.
Return Value
The previous value of the font-mapper flag.
Remarks
An application can use SetMapperFlags to cause the font mapper to attempt to choose only a physical font
that exactly matches the aspect ratio of the specified device.
An application that uses only raster fonts can use the SetMapperFlags function to ensure that the font
selected by the font mapper is attractive and readable on the specified device. Applications that use
scalable (TrueType) fonts typically do not use SetMapperFlags .
If no physical font has an aspect ratio that matches the specification in the logical font, GDI chooses a new
aspect ratio and selects a font that matches this new aspect ratio.

CDC::SetMiterLimit
Sets the limit for the length of miter joins for the device context.

BOOL SetMiterLimit(float fMiterLimit);

Parameters
fMiterLimit
Specifies the new miter limit for the device context.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The miter length is defined as the distance from the intersection of the line walls on the inside of the join
to the intersection of the line walls on the outside of the join. The miter limit is the maximum allowed ratio
of the miter length to the line width. The default miter limit is 10.0.

CDC::SetOutputDC
Call this member function to set the output device context, m_hDC .

virtual void SetOutputDC(HDC hDC);

Parameters
hDC
A Windows device context.
Remarks
This member function can only be called when a device context has not been attached to the CDC object.
This member function sets m_hDC but does not attach the device context to the CDC object.

CDC::SetPixel
Sets the pixel at the point specified to the closest approximation of the color specified by crColor.
COLORREF SetPixel(
int x,
int y,
COLORREF crColor);

COLORREF SetPixel(
POINT point,
COLORREF crColor);

Parameters
x
Specifies the logical x-coordinate of the point to be set.
y
Specifies the logical y-coordinate of the point to be set.
crColor
A COLORREF RGB value that specifies the color used to paint the point. See COLORREF in the Windows
SDK for a description of this value.
point
Specifies the logical x- and y-coordinates of the point to be set. You can pass either a POINT structure or a
CPoint object for this parameter.

Return Value
An RGB value for the color that the point is actually painted. This value can be different from that specified
by crColor if an approximation of that color is used. If the function fails (if the point is outside the clipping
region), the return value is -1.
Remarks
The point must be in the clipping region. If the point is not in the clipping region, the function does
nothing.
Not all devices support the SetPixel function. To determine whether a device supports SetPixel , call the
GetDeviceCaps member function with the RASTERCAPS index and check the return value for the
RC_BITBLT flag.

CDC::SetPixelV
Sets the pixel at the specified coordinates to the closest approximation of the specified color.

BOOL SetPixelV(
int x,
int y,
COLORREF crColor);

BOOL SetPixelV(
POINT point,
COLORREF crColor);

Parameters
x
Specifies the x-coordinate, in logical units, of the point to be set.
y
Specifies the y-coordinate, in logical units, of the point to be set.
crColor
Specifies the color to be used to paint the point.
point
Specifies the logical x- and y-coordinates of the point to be set. You can pass either a POINT data structure
or a CPoint object for this parameter.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The point must be in both the clipping region and the visible part of the device surface. Not all devices
support the member function. For more information, see the RC_BITBLT capability in the
CDC::GetDeviceCaps member function. SetPixelV is faster than SetPixel because it does not need to
return the color value of the point actually painted.

CDC::SetPolyFillMode
Sets the polygon-filling mode.

int SetPolyFillMode(int nPolyFillMode);

Parameters
nPolyFillMode
Specifies the new filling mode. This value may be either ALTERNATE or WINDING. The default mode set in
Windows is ALTERNATE.
Return Value
The previous filling mode, if successful; otherwise 0.
Remarks
When the polygon-filling mode is ALTERNATE, the system fills the area between odd-numbered and even-
numbered polygon sides on each scan line. That is, the system fills the area between the first and second
side, between the third and fourth side, and so on. This mode is the default.
When the polygon-filling mode is WINDING, the system uses the direction in which a figure was drawn to
determine whether to fill an area. Each line segment in a polygon is drawn in either a clockwise or a
counterclockwise direction. Whenever an imaginary line drawn from an enclosed area to the outside of a
figure passes through a clockwise line segment, a count is incremented. When the line passes through a
counterclockwise line segment, the count is decremented. The area is filled if the count is nonzero when
the line reaches the outside of the figure.

CDC::SetROP2
Sets the current drawing mode.

int SetROP2(int nDrawMode);

Parameters
nDrawMode
Specifies the new drawing mode. It can be any of the following values:
R2_BLACK Pixel is always black.
R2_WHITE Pixel is always white.
R2_NOP Pixel remains unchanged.
R2_NOT Pixel is the inverse of the screen color.
R2_COPYPEN Pixel is the pen color.
R2_NOTCOPYPEN Pixel is the inverse of the pen color.
R2_MERGEPENNOT Pixel is a combination of the pen color and the inverse of the screen color (final
pixel = (NOT screen pixel) OR pen).
R2_MASKPENNOT Pixel is a combination of the colors common to both the pen and the inverse of
the screen (final pixel = (NOT screen pixel) AND pen).
R2_MERGENOTPEN Pixel is a combination of the screen color and the inverse of the pen color (final
pixel = (NOT pen) OR screen pixel).
R2_MASKNOTPEN Pixel is a combination of the colors common to both the screen and the inverse
of the pen (final pixel = (NOT pen) AND screen pixel).
R2_MERGEPEN Pixel is a combination of the pen color and the screen color (final pixel = pen OR
screen pixel).
R2_NOTMERGEPEN Pixel is the inverse of the R2_MERGEPEN color (final pixel = NOT(pen OR
screen pixel)).
R2_MASKPEN Pixel is a combination of the colors common to both the pen and the screen (final
pixel = pen AND screen pixel).
R2_NOTMASKPEN Pixel is the inverse of the R2_MASKPEN color (final pixel = NOT(pen AND screen
pixel)).
R2_XORPEN Pixel is a combination of the colors that are in the pen or in the screen, but not in both
(final pixel = pen XOR screen pixel).
R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color (final pixel = NOT(pen XOR screen
pixel)).
Return Value
The previous drawing mode.
It can be any of the values given in the Windows SDK.
Remarks
The drawing mode specifies how the colors of the pen and the interior of filled objects are combined with
the color already on the display surface.
The drawing mode is for raster devices only; it does not apply to vector devices. Drawing modes are
binary raster-operation codes representing all possible Boolean combinations of two variables, using the
binary operators AND, OR, and XOR (exclusive OR), and the unary operation NOT.

CDC::SetStretchBltMode
Sets the bitmap-stretching mode for the StretchBlt member function.

int SetStretchBltMode(int nStretchMode);


Parameters
nStretchMode
Specifies the stretching mode. It can be any of the following values:

VA L UE DESC RIP T IO N

BLACKONWHITE Performs a Boolean AND operation using the color values


for the eliminated and existing pixels. If the bitmap is a
monochrome bitmap, this mode preserves black pixels at
the expense of white pixels.

COLORONCOLOR Deletes the pixels. This mode deletes all eliminated lines
of pixels without trying to preserve their information.

HALFTONE Maps pixels from the source rectangle into blocks of


pixels in the destination rectangle. The average color over
the destination block of pixels approximates the color of
the source pixels.

After setting the HALFTONE stretching mode, an


application must call the Win32 function SetBrushOrgEx
to set the brush origin. If it fails to do so, brush
misalignment occurs.

STRETCH_ANDSCANS Windows 95/98 : Same as BLACKONWHITE

STRETCH_DELETESCANS Windows 95/98 : Same as COLORONCOLOR

STRETCH_HALFTONE Windows 95/98 : Same as HALFTONE.

STRETCH_ORSCANS Windows 95/98 : Same as WHITEONBLACK

WHITEONBLACK Performs a Boolean OR operation using the color values


for the eliminated and existing pixels. If the bitmap is a
monochrome bitmap, this mode preserves white pixels at
the expense of black pixels.

Return Value
The previous stretching mode. It can be STRETCH_ANDSCANS, STRETCH_DELETESCANS, or
STRETCH_ORSCANS.
Remarks
The bitmap-stretching mode defines how information is removed from bitmaps that are compressed by
using the function.
The BLACKONWHITE ( STRETCH_ANDSCANS) and WHITEONBLACK ( STRETCH_ORSCANS) modes are
typically used to preserve foreground pixels in monochrome bitmaps. The COLORONCOLOR (
STRETCH_DELETESCANS) mode is typically used to preserve color in color bitmaps.
The HALFTONE mode requires more processing of the source image than the other three modes; it is
slower than the others, but produces higher quality images. Also note that SetBrushOrgEx must be called
after setting the HALFTONE mode to avoid brush misalignment.
Additional stretching modes might also be available depending on the capabilities of the device driver.

CDC::SetTextAlign
Sets the text-alignment flags.

UINT SetTextAlign(UINT nFlags);

Parameters
nFlags
Specifies text-alignment flags. The flags specify the relationship between a point and a rectangle that
bounds the text. The point can be either the current position or coordinates specified by a text-output
function. The rectangle that bounds the text is defined by the adjacent character cells in the text string. The
nFlags parameter can be one or more flags from the following three categories. Choose only one flag
from each category. The first category affects text alignment in the x-direction:
TA_CENTER Aligns the point with the horizontal center of the bounding rectangle.
TA_LEFT Aligns the point with the left side of the bounding rectangle. This is the default setting.
TA_RIGHT Aligns the point with the right side of the bounding rectangle.
The second category affects text alignment in the y-direction:
TA_BASELINE Aligns the point with the base line of the chosen font.
TA_BOTTOM Aligns the point with the bottom of the bounding rectangle.
TA_TOP Aligns the point with the top of the bounding rectangle. This is the default setting.
The third category determines whether the current position is updated when text is written:
TA_NOUPDATECP Does not update the current position after each call to a text-output function. This
is the default setting.
TA_UPDATECP Updates the current x-position after each call to a text-output function. The new
position is at the right side of the bounding rectangle for the text. When this flag is set, the
coordinates specified in calls to the TextOut member function are ignored.
Return Value
The previous text-alignment setting, if successful. The low-order byte contains the horizontal setting and
the high-order byte contains the vertical setting; otherwise 0.
Remarks
The TextOut and ExtTextOut member functions use these flags when positioning a string of text on a
display or device. The flags specify the relationship between a specific point and a rectangle that bounds
the text. The coordinates of this point are passed as parameters to the TextOut member function. The
rectangle that bounds the text is formed by the adjacent character cells in the text string.

CDC::SetTextCharacterExtra
Sets the amount of intercharacter spacing.

int SetTextCharacterExtra(int nCharExtra);

Parameters
nCharExtra
Specifies the amount of extra space (in logical units) to be added to each character. If the current mapping
mode is not MM_TEXT , nCharExtra is transformed and rounded to the nearest pixel.
Return Value
The amount of the previous intercharacter spacing.
Remarks
GDI adds this spacing to each character, including break characters, when it writes a line of text to the
device context. The default value for the amount of intercharacter spacing is 0.

CDC::SetTextColor
Sets the text color to the specified color.

virtual COLORREF SetTextColor(COLORREF crColor);

Parameters
crColor
Specifies the color of the text as an RGB color value.
Return Value
An RGB value for the previous text color.
Remarks
The system will use this text color when writing text to this device context and also when converting
bitmaps between color and monochrome device contexts.
If the device cannot represent the specified color, the system sets the text color to the nearest physical
color. The background color for a character is specified by the SetBkColor and SetBkMode member
functions.
Example
See the example for CWnd::OnCtlColor.

CDC::SetTextJustification
Adds space to the break characters in a string.

int SetTextJustification(
int nBreakExtra,
int nBreakCount);

Parameters
nBreakExtra
Specifies the total extra space to be added to the line of text (in logical units). If the current mapping mode
is not MM_TEXT , the value given by this parameter is converted to the current mapping mode and rounded
to the nearest device unit.
nBreakCount
Specifies the number of break characters in the line.
Return Value
One if the function is successful; otherwise 0.
Remarks
An application can use the GetTextMetrics member functions to retrieve a font's break character.
After the SetTextJustification member function is called, a call to a text-output function (such as
TextOut ) distributes the specified extra space evenly among the specified number of break characters.
The break character is usually the space character (ASCII 32), but may be defined by a font as some other
character.
The member function GetTextExtent is typically used with SetTextJustification . GetTextExtent
computes the width of a given line before alignment. An application can determine how much space to
specify in the nBreakExtra parameter by subtracting the value returned by GetTextExtent from the width
of the string after alignment.
The SetTextJustification function can be used to align a line that contains multiple runs in different
fonts. In this case, the line must be created piecemeal by aligning and writing each run separately.
Because rounding errors can occur during alignment, the system keeps a running error term that defines
the current error. When aligning a line that contains multiple runs, GetTextExtent automatically uses this
error term when it computes the extent of the next run. This allows the text-output function to blend the
error into the new run.
After each line has been aligned, this error term must be cleared to prevent it from being incorporated
into the next line. The term can be cleared by calling SetTextJustification with nBreakExtra set to 0.

CDC::SetViewportExt
Sets the x- and y-extents of the viewport of the device context.

virtual CSize SetViewportExt(


int cx,
int cy);

CSize SetViewportExt(SIZE size);

Parameters
cx
Specifies the x-extent of the viewport (in device units).
cy
Specifies the y-extent of the viewport (in device units).
size
Specifies the x- and y-extents of the viewport (in device units).
Return Value
The previous extents of the viewport as a CSize object. When an error occurs, the x- and y-coordinates of
the returned CSize object are both set to 0.
Remarks
The viewport, along with the device-context window, defines how GDI maps points in the logical
coordinate system to points in the coordinate system of the actual device. In other words, they define how
GDI converts logical coordinates into device coordinates.
When the following mapping modes are set, calls to SetWindowExt and SetViewportExt are ignored:

M M _H IEN GL ISH M M _LO M ET RIC

MM_HIMETRIC MM_TEXT
M M _H IEN GL ISH M M _LO M ET RIC

MM_LOENGLISH MM_TWIPS

When MM_ISOTROPIC mode is set, an application must call the SetWindowExt member function before it
calls SetViewportExt .
Example
See the example for CView::OnPrepareDC.

CDC::SetViewportOrg
Sets the viewport origin of the device context.

virtual CPoint SetViewportOrg(


int x,
int y);

CPoint SetViewportOrg(POINT point);

Parameters
x
Specifies the x-coordinate (in device units) of the origin of the viewport. The value must be within the
range of the device coordinate system.
y
Specifies the y-coordinate (in device units) of the origin of the viewport. The value must be within the
range of the device coordinate system.
point
Specifies the origin of the viewport. The values must be within the range of the device coordinate system.
You can pass either a POINT structure or a CPoint object for this parameter.
Return Value
The previous origin of the viewport (in device coordinates) as a CPoint object.
Remarks
The viewport, along with the device-context window, defines how GDI maps points in the logical
coordinate system to points in the coordinate system of the actual device. In other words, they define how
GDI converts logical coordinates into device coordinates.
The viewport origin marks the point in the device coordinate system to which GDI maps the window
origin, a point in the logical coordinate system specified by the SetWindowOrg member function. GDI maps
all other points by following the same process required to map the window origin to the viewport origin.
For example, all points in a circle around the point at the window origin will be in a circle around the point
at the viewport origin. Similarly, all points in a line that passes through the window origin will be in a line
that passes through the viewport origin.
Example
See the example for CView::OnPrepareDC.

CDC::SetWindowExt
Sets the x- and y-extents of the window associated with the device context.
virtual CSize SetWindowExt(
int cx,
int cy);

CSize SetWindowExt(SIZE size);

Parameters
cx
Specifies the x-extent (in logical units) of the window.
cy
Specifies the y-extent (in logical units) of the window.
size
Specifies the x- and y-extents (in logical units) of the window.
Return Value
The previous extents of the window (in logical units) as a CSize object. If an error occurs, the x- and y-
coordinates of the returned CSize object are both set to 0.
Remarks
The window, along with the device-context viewport, defines how GDI maps points in the logical
coordinate system to points in the device coordinate system.
When the following mapping modes are set, calls to SetWindowExt and SetViewportExt functions are
ignored:
MM_HIENGLISH
MM_HIMETRIC
MM_LOENGLISH
MM_LOMETRIC
MM_TEXT
MM_TWIPS
When MM_ISOTROPIC mode is set, an application must call the SetWindowExt member function before
calling SetViewportExt .
Example
See the example for CView::OnPrepareDC.

CDC::SetWindowOrg
Sets the window origin of the device context.

CPoint SetWindowOrg(
int x,
int y);

CPoint SetWindowOrg(POINT point);

Parameters
x
Specifies the logical x-coordinate of the new origin of the window.
y
Specifies the logical y-coordinate of the new origin of the window.
point
Specifies the logical coordinates of the new origin of the window. You can pass either a POINT structure or
a CPoint object for this parameter.
Return Value
The previous origin of the window as a CPoint object.
Remarks
The window, along with the device-context viewport, defines how GDI maps points in the logical
coordinate system to points in the device coordinate system.
The window origin marks the point in the logical coordinate system from which GDI maps the viewport
origin, a point in the device coordinate system specified by the SetWindowOrg function. GDI maps all other
points by following the same process required to map the window origin to the viewport origin. For
example, all points in a circle around the point at the window origin will be in a circle around the point at
the viewport origin. Similarly, all points in a line that passes through the window origin will be in a line
that passes through the viewport origin.

CDC::SetWorldTransform
Sets a two-dimensional linear transformation between world space and page space for the specified
device context. This transformation can be used to scale, rotate, shear, or translate graphics output.

BOOL SetWorldTransform(const XFORM& rXform);

Parameters
rXform
Reference to an XFORM structure that contains the transformation data.
Return Value
Returns a nonzero value on success.
Returns 0 on failure.
To get extended error information, call GetLastError.
Remarks
This method wraps the Windows GDI function SetWorldTransform.

CDC::StartDoc
Informs the device driver that a new print job is starting and that all subsequent StartPage and EndPage
calls should be spooled under the same job until an EndDoc call occurs.

int StartDoc(LPDOCINFO lpDocInfo);


int StartDoc(LPCTSTR lpszDocName);

Parameters
lpDocInfo
Points to a DOCINFO structure containing the name of the document file and the name of the output file.
lpszDocName
Pointer to a string containing the name of the document file.
Return Value
If the function succeeds, the return value is greater than zero. This value is the print job identifier for the
document.
If the function fails, the return value is less than or equal to zero.
Remarks
This ensures that documents longer than one page will not be interspersed with other jobs.
For Windows versions 3.1 and later, this function replaces the STARTDOC printer escape. Using this
function ensures that documents containing more than one page are not interspersed with other print
jobs.
StartDoc should not be used inside metafiles.
Example
This code fragment gets the default printer, opens a print job, and spools one page with "Hello, World!" on
it. Because the text printed by this code isn't scaled to the printer's logical units, the output text may be in
such small letters that the result is unreadable. The CDC scaling functions, such as SetMapMode ,
SetViewportOrg , and SetWindowExt , can be used to fix the scaling.
void CDCView::DoStartDoc()
{
// get the default printer
CPrintDialog dlg(FALSE);
dlg.GetDefaults();

// is a default printer set up?


HDC hdcPrinter = dlg.GetPrinterDC();
if (hdcPrinter == NULL)
{
MessageBox(_T("Buy a printer!"));
}
else
{
// create a CDC and attach it to the default printer
CDC dcPrinter;
dcPrinter.Attach(hdcPrinter);

// call StartDoc() to begin printing


DOCINFO docinfo;
memset(&docinfo, 0, sizeof(docinfo));
docinfo.cbSize = sizeof(docinfo);
docinfo.lpszDocName = _T("CDC::StartDoc() Code Fragment");

// if it fails, complain and exit gracefully


if (dcPrinter.StartDoc(&docinfo) < 0)
{
MessageBox(_T("Printer wouldn't initialize"));
}
else
{
// start a page
if (dcPrinter.StartPage() < 0)
{
MessageBox(_T("Could not start page"));
dcPrinter.AbortDoc();
}
else
{
// actually do some printing
CGdiObject *pOldFont = dcPrinter.SelectStockObject(SYSTEM_FONT);

dcPrinter.TextOut(50, 50, _T("Hello World!"), 12);

dcPrinter.EndPage();
dcPrinter.EndDoc();
dcPrinter.SelectObject(pOldFont);
}
}
}
}

CDC::StartPage
Call this member function to prepare the printer driver to receive data.

int StartPage();

Return Value
Greater than or equal to 0 if the function is successful, or a negative value if an error occurred.
Remarks
StartPage supersedes the NEWFRAME and BANDINFO escapes.
For an overview of the sequence of printing calls, see the StartDoc member function.
The system disables the ResetDC member function between calls to StartPage and EndPage .
Example
See the example for CDC::StartDoc.

CDC::StretchBlt
Copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the
bitmap if necessary to fit the dimensions of the destination rectangle.

BOOL StretchBlt(
int x,
int y,
int nWidth,
int nHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight,
DWORD dwRop);

Parameters
x
Specifies the x-coordinate (in logical units) of the upper-left corner of the destination rectangle.
y
Specifies the y-coordinate (in logical units) of the upper-left corner of the destination rectangle.
nWidth
Specifies the width (in logical units) of the destination rectangle.
nHeight
Specifies the height (in logical units) of the destination rectangle.
pSrcDC
Specifies the source device context.
xSrc
Specifies the x-coordinate (in logical units) of the upper-left corner of the source rectangle.
ySrc
Specifies the y-coordinate (in logical units) of the upper-left corner of the source rectangle.
nSrcWidth
Specifies the width (in logical units) of the source rectangle.
nSrcHeight
Specifies the height (in logical units) of the source rectangle.
dwRop
Specifies the raster operation to be performed. Raster operation codes define how GDI combines colors in
output operations that involve a current brush, a possible source bitmap, and a destination bitmap. This
parameter may be one of the following values:
BLACKNESS Turns all output black.
DSTINVERT Inverts the destination bitmap.
MERGECOPY Combines the pattern and the source bitmap using the Boolean AND operator.
MERGEPAINT Combines the inverted source bitmap with the destination bitmap using the Boolean
OR operator.
NOTSRCCOPY Copies the inverted source bitmap to the destination.
NOTSRCERASE Inverts the result of combining the destination and source bitmaps using the
Boolean OR operator.
PATCOPY Copies the pattern to the destination bitmap.
PATINVERT Combines the destination bitmap with the pattern using the Boolean XOR operator.
PATPAINT Combines the inverted source bitmap with the pattern using the Boolean OR operator.
Combines the result of this operation with the destination bitmap using the Boolean OR operator.
SRCAND Combines pixels of the destination and source bitmaps using the Boolean AND operator.
SRCCOPY Copies the source bitmap to the destination bitmap.
SRCERASE Inverts the destination bitmap and combines the result with the source bitmap using the
Boolean AND operator.
SRCINVERT Combines pixels of the destination and source bitmaps using the Boolean XOR
operator.
SRCPAINT Combines pixels of the destination and source bitmaps using the Boolean OR operator.
WHITENESS Turns all output white.
Return Value
Nonzero if the bitmap is drawn; otherwise 0.
Remarks
The function uses the stretching mode of the destination device context (set by SetStretchBltMode ) to
determine how to stretch or compress the bitmap.
The StretchBlt function moves the bitmap from the source device given by pSrcDC to the destination
device represented by the device-context object whose member function is being called. The xSrc, ySrc,
nSrcWidth, and nSrcHeight parameters define the upper-left corner and dimensions of the source
rectangle. The x, y, nWidth, and nHeight parameters give the upper-left corner and dimensions of the
destination rectangle. The raster operation specified by dwRop defines how the source bitmap and the bits
already on the destination device are combined.
The StretchBlt function creates a mirror image of a bitmap if the signs of the nSrcWidth and nWidth or
nSrcHeight and nHeight parameters differ. If nSrcWidth and nWidth have different signs, the function
creates a mirror image of the bitmap along the x-axis. If nSrcHeight and nHeight have different signs, the
function creates a mirror image of the bitmap along the y-axis.
The StretchBlt function stretches or compresses the source bitmap in memory and then copies the
result to the destination. If a pattern is to be merged with the result, it is not merged until the stretched
source bitmap is copied to the destination. If a brush is used, it is the selected brush in the destination
device context. The destination coordinates are transformed according to the destination device context;
the source coordinates are transformed according to the source device context.
If the destination, source, and pattern bitmaps do not have the same color format, StretchBlt converts
the source and pattern bitmaps to match the destination bitmaps. The foreground and background colors
of the destination device context are used in the conversion.
If StretchBlt must convert a monochrome bitmap to color, it sets white bits (1) to the background color
and black bits (0) to the foreground color. To convert color to monochrome, it sets pixels that match the
background color to white (1) and sets all other pixels to black (0). The foreground and background colors
of the device context with color are used.
Not all devices support the StretchBlt function. To determine whether a device supports StretchBlt , call
the GetDeviceCaps member function with the RASTERCAPS index and check the return value for the
RC_STRETCHBLT flag.

CDC::StrokeAndFillPath
Closes any open figures in a path, strokes the outline of the path by using the current pen, and fills its
interior by using the current brush.

BOOL StrokeAndFillPath();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The device context must contain a closed path. The StrokeAndFillPath member function has the same
effect as closing all the open figures in the path, and stroking and filling the path separately, except that
the filled region will not overlap the stroked region even if the pen is wide.

CDC::StrokePath
Renders the specified path by using the current pen.

BOOL StrokePath();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
The device context must contain a closed path.

CDC::TabbedTextOut
Call this member function to write a character string at the specified location, expanding tabs to the values
specified in the array of tab-stop positions.
virtual CSize TabbedTextOut(
int x,
int y,
LPCTSTR lpszString,
int nCount,
int nTabPositions,
LPINT lpnTabStopPositions,
int nTabOrigin);

CSize TabbedTextOut(
int x,
int y,
const CString& str,
int nTabPositions,
LPINT lpnTabStopPositions,
int nTabOrigin);

Parameters
x
Specifies the logical x-coordinate of the starting point of the string.
y
Specifies the logical y-coordinate of the starting point of the string.
lpszString
Points to the character string to draw. You can pass either a pointer to an array of characters or a CString
object for this parameter.
nCount
Specifies the length of the string pointed to by lpszString.
nTabPositions
Specifies the number of values in the array of tab-stop positions.
lpnTabStopPositions
Points to an array containing the tab-stop positions (in logical units). The tab stops must be sorted in
increasing order; the smallest x-value should be the first item in the array.
nTabOrigin
Specifies the x-coordinate of the starting position from which tabs are expanded (in logical units).
str
A CString object that contains the specified characters.
Return Value
The dimensions of the string (in logical units) as a CSize object.
Remarks
Text is written in the currently selected font. If nTabPositions is 0 and lpnTabStopPositions is NULL, tabs are
expanded to eight times the average character width.
If nTabPositions is 1, the tab stops are separated by the distance specified by the first value in the
lpnTabStopPositions array. If the lpnTabStopPositions array contains more than one value, a tab stop is set
for each value in the array, up to the number specified by nTabPositions. The nTabOrigin parameter allows
an application to call the TabbedTextOut function several times for a single line. If the application calls the
function more than once with the nTabOrigin set to the same value each time, the function expands all
tabs relative to the position specified by nTabOrigin.
By default, the current position is not used or updated by the function. If an application needs to update
the current position when it calls the function, the application can call the SetTextAlign member function
with nFlags set to TA_UPDATECP. When this flag is set, Windows ignores the x and y parameters on
subsequent calls to TabbedTextOut , using the current position instead.

CDC::TextOut
Writes a character string at the specified location using the currently selected font.

virtual BOOL TextOut(


int x,
int y,
LPCTSTR lpszString,
int nCount);

BOOL TextOut(
int x,
int y,
const CString& str);

Parameters
x
Specifies the logical x-coordinate of the starting point of the text.
y
Specifies the logical y-coordinate of the starting point of the text.
lpszString
Points to the character string to be drawn.
nCount
Specifies the number of characters in the string.
str
A CString object that contains the characters to be drawn.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
Character origins are at the upper-left corner of the character cell. By default, the current position is not
used or updated by the function.
If an application needs to update the current position when it calls TextOut , the application can call the
SetTextAlign member function with nFlags set to TA_UPDATECP. When this flag is set, Windows ignores
the x and y parameters on subsequent calls to TextOut , using the current position instead.
Example
See the example for CDC::BeginPath.

CDC::TransparentBlt
Call this member function to transfer a bit-block of the color data, which corresponds to a rectangle of
pixels from the specified source device context, into a destination device context.
BOOL TransparentBlt(
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
CDC* pSrcDC,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight,
UINT clrTransparent);

Parameters
xDest
Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
yDest
Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
nDestWidth
Specifies the width, in logical units, of the destination rectangle.
nDestHeight
Specifies the height, in logical units, of the destination rectangle.
pSrcDC
Pointer to the source device context.
xSrc
Specifies the x-coordinate, in logical units, of the source rectangle.
ySrc
Specifies the y-coordinate, in logical units, of the source rectangle.
nSrcWidth
Specifies the width, in logical units, of the source rectangle.
nSrcHeight
Specifies the height, in logical units, of the source rectangle.
clrTransparent
The RGB color in the source bitmap to treat as transparent.
Return Value
TRUE if successful; otherwise FALSE.
Remarks
TransparentBlt allows for transparency; that is, the RGB color indicated by clrTransparent is rendered
transparent for the transfer.
For more information, see TransparentBlt in the Windows SDK.

CDC::UpdateColors
Updates the client area of the device context by matching the current colors in the client area to the
system palette on a pixel-by-pixel basis.
void UpdateColors();

Remarks
An inactive window with a realized logical palette may call UpdateColors as an alternative to redrawing its
client area when the system palette changes.
For more information about using color palettes, see UpdateColors in the Windows SDK.
The UpdateColors member function typically updates a client area faster than redrawing the area.
However, because the function performs the color translation based on the color of each pixel before the
system palette changed, each call to this function results in the loss of some color accuracy.

CDC::WidenPath
Redefines the current path as the area that would be painted if the path were stroked using the pen
currently selected into the device context.

BOOL WidenPath();

Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
This function is successful only if the current pen is a geometric pen created by the second version of
CreatePen member function, or if the pen is created with the first version of CreatePen and has a width,
in device units, of greater than 1. The device context must contain a closed path. Any Bzier curves in the
path are converted to sequences of straight lines approximating the widened curves. As such, no Bzier
curves remain in the path after WidenPath is called.

See also
CObject Class
Hierarchy Chart
CPaintDC Class
CWindowDC Class
CClientDC Class
CMetaFileDC Class
CDCRenderTarget Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1DCRenderTarget.

Syntax
class CDCRenderTarget : public CRenderTarget;

Members
Public Constructors
NAME DESC RIP T IO N

CDCRenderTarget::CDCRenderTarget Constructs a CDCRenderTarget object.

Public Methods
NAME DESC RIP T IO N

CDCRenderTarget::Attach Attaches existing render target interface to the object

CDCRenderTarget::BindDC Binds the render target to the device context to which it issues
drawing commands

CDCRenderTarget::Create Creates a CDCRenderTarget.

CDCRenderTarget::Detach Detaches render target interface from the object

CDCRenderTarget::GetDCRenderTarget Returns ID2D1DCRenderTarget interface

Public Operators
NAME DESC RIP T IO N

CDCRenderTarget::operator ID2D1DCRenderTarget* Returns ID2D1DCRenderTarget interface

Protected Data Members


NAME DESC RIP T IO N

CDCRenderTarget::m_pDCRenderTarget A pointer to an ID2D1DCRenderTarget object.

Inheritance Hierarchy
CObject
CRenderTarget
CDCRenderTarget

Requirements
Header : afxrendertarget.h

CDCRenderTarget::Attach
Attaches existing render target interface to the object

void Attach(ID2D1DCRenderTarget* pTarget);

Parameters
pTarget
Existing render target interface. Cannot be NULL

CDCRenderTarget::BindDC
Binds the render target to the device context to which it issues drawing commands

BOOL BindDC(
const CDC& dc,
const CRect& rect);

Parameters
dc
The device context to which the render target issues drawing commands
rect
The dimensions of the handle to a device context (HDC) to which the render target is bound
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CDCRenderTarget::CDCRenderTarget
Constructs a CDCRenderTarget object.

CDCRenderTarget();

CDCRenderTarget::Create
Creates a CDCRenderTarget.

BOOL Create(const D2D1_RENDER_TARGET_PROPERTIES& props);

Parameters
props
The rendering mode, pixel format, remoting options, DPI information, and the minimum DirectX support required
for hardware rendering.
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CDCRenderTarget::Detach
Detaches render target interface from the object

ID2D1DCRenderTarget* Detach();

Return Value
Pointer to detached render target interface.

CDCRenderTarget::GetDCRenderTarget
Returns ID2D1DCRenderTarget interface

ID2D1DCRenderTarget* GetDCRenderTarget();

Return Value
Pointer to an ID2D1DCRenderTarget interface or NULL if object is not initialized yet.

CDCRenderTarget::m_pDCRenderTarget
A pointer to an ID2D1DCRenderTarget object.

ID2D1DCRenderTarget* m_pDCRenderTarget;

CDCRenderTarget::operator ID2D1DCRenderTarget*
Returns ID2D1DCRenderTarget interface

operator ID2D1DCRenderTarget*();

Return Value
Pointer to an ID2D1DCRenderTarget interface or NULL if object is not initialized yet.

See also
Classes
CDHtmlDialog Class
4/21/2020 • 20 minutes to read • Edit Online

Is used to create dialog boxes that use HTML rather than dialog resources to implement their user interface.

Syntax
class CDHtmlDialog : public CDialog, public CDHtmlEventSink

Members
Public Constructors
NAME DESC RIP T IO N

CDHtmlDialog::CDHtmlDialog Constructs a CDHtmlDialog object.

CDHtmlDialog::~CDHtmlDialog Destroys a CDHtmlDialog object.

Public Methods
NAME DESC RIP T IO N

CDHtmlDialog::CanAccessExternal Overridable that is called as an access check to see whether


scripting objects on the loaded page can access the external
dispatch of the control site. Checks to make sure the dispatch
is either safe for scripting or the current zone allows for
objects that are not safe for scripting.

CDHtmlDialog::CreateControlSite Overridable used to create a control site instance to host the


WebBrowser control on the dialog.

CDHtmlDialog::DDX_DHtml_AxControl Exchanges data between a member variable and the property


value of an ActiveX control on an HTML page.

CDHtmlDialog::DDX_DHtml_CheckBox Exchanges data between a member variable and a check box


on an HTML page.

CDHtmlDialog::DDX_DHtml_ElementText Exchanges data between a member variable and any HTML


element property on an HTML page.

CDHtmlDialog::DDX_DHtml_Radio Exchanges data between a member variable and a radio


button on an HTML page.

CDHtmlDialog::DDX_DHtml_SelectIndex Gets or sets the index of a list box on an HTML page.

CDHtmlDialog::DDX_DHtml_SelectString Gets or sets the display text of a list box entry (based on the
current index) on an HTML page.
NAME DESC RIP T IO N

CDHtmlDialog::DDX_DHtml_SelectValue Gets or sets the value of a list box entry (based on the
current index) on an HTML page.

CDHtmlDialog::DestroyModeless Destroys a modeless dialog box.

CDHtmlDialog::EnableModeless Enables modeless dialog boxes.

CDHtmlDialog::FilterDataObject Allows the dialog to filter clipboard data objects created by


the hosted browser.

CDHtmlDialog::GetControlDispatch Retrieves the IDispatch interface on an ActiveX control


embedded in the HTML document.

CDHtmlDialog::GetControlProperty Retrieves the requested property of the specified ActiveX


control.

CDHtmlDialog::GetCurrentUrl Retrieves the Uniform Resource Locator (URL) associated with


the current document.

CDHtmlDialog::GetDHtmlDocument Retrieves the IHTMLDocument2 interface on the currently


loaded HTML document.

CDHtmlDialog::GetDropTarget Called by the contained WebBrowser control when it is being


used as a drop target to allow the dialog to supply an
alternative IDropTarget.

CDHtmlDialog::GetElement Gets an interface on an HTML element.

CDHtmlDialog::GetElementHtml Retrieves the innerHTML property of an HTML element.

CDHtmlDialog::GetElementInterface Retrieves the requested interface pointer from an HTML


element.

CDHtmlDialog::GetElementProperty Retrieves the value of an HTML element's property.

CDHtmlDialog::GetElementText Retrieves the innerText property of an HTML element.

CDHtmlDialog::GetEvent Gets the IHTMLEventObj pointer to the current event


object.

CDHtmlDialog::GetExternal Gets the host's IDispatch interface.

CDHtmlDialog::GetHostInfo Retrieves the host's UI capabilities.

CDHtmlDialog::GetOptionKeyPath Retrieves the registry key under which user preferences are
stored.

CDHtmlDialog::HideUI Hides the host's UI.

CDHtmlDialog::IsExternalDispatchSafe Indicates whether the host's IDispatch interface is safe for


scripting.
NAME DESC RIP T IO N

CDHtmlDialog::LoadFromResource Loads the specified resource into the WebBrowser control.

CDHtmlDialog::Navigate Navigates to the specified URL.

CDHtmlDialog::OnBeforeNavigate Called by the framework before a navigation event is fired.

CDHtmlDialog::OnDocumentComplete Called by the framework to notify an application when a


document has reached the READYSTATE_COMPLETE state.

CDHtmlDialog::OnDocWindowActivate Called by the framework when the document window is


activated or deactivated.

CDHtmlDialog::OnFrameWindowActivate Called by the framework when the frame window is activated


or deactivated.

CDHtmlDialog::OnInitDialog Called in response to the WM_INITDIALOG message.

CDHtmlDialog::OnNavigateComplete Called by the framework after a navigation event is


completed.

CDHtmlDialog::ResizeBorder Alerts the object that it needs to resize its border space.

CDHtmlDialog::SetControlProperty Sets the property of an ActiveX control to a new value.

CDHtmlDialog::SetElementHtml Sets the innerHTML property of an HTML element.

CDHtmlDialog::SetElementProperty Sets a property of an HTML element.

CDHtmlDialog::SetElementText Sets the innerText property of an HTML element.

CDHtmlDialog::SetExternalDispatch Sets the host's IDispatch interface.

CDHtmlDialog::SetHostFlags Sets the host's UI flags.

CDHtmlDialog::ShowContextMenu Called when a context menu is about to be displayed.

CDHtmlDialog::ShowUI Shows the host's UI.

CDHtmlDialog::TranslateAccelerator Called to process menu accelerator-key messages.

CDHtmlDialog::TranslateUrl Called to modify the URL to be loaded.

CDHtmlDialog::UpdateUI Called to notify the host that the command state has
changed.

Public Data Members


NAME DESC RIP T IO N

CDHtmlDialog::m_bUseHtmlTitle Indicates whether to use the HTML document's title as the


dialog caption.
NAME DESC RIP T IO N

CDHtmlDialog::m_nHtmlResID Resource ID of HTML resource to be displayed.

CDHtmlDialog::m_pBrowserApp A pointer to a Web browser application.

CDHtmlDialog::m_spHtmlDoc A pointer to an HTML document.

CDHtmlDialog::m_strCurrentUrl The current URL.

CDHtmlDialog::m_szHtmlResID String version of the HTML resource ID.

Remarks
CDHtmlDialog can load the HTML to be displayed from either an HTML resource or a URL.
CDHtmlDialog can also do data exchange with HTML controls and handle events from HTML controls, such as
button clicks.

Inheritance Hierarchy
CObject
CDHtmlSinkHandlerBase2

CDHtmlSinkHandlerBase1

CCmdTarget
CDHtmlSinkHandler

CWnd
CDHtmlEventSink

CDialog
CDHtmlDialog

Requirements
Header : afxdhtml.h

DDX_DHtml Helper Macros


The DDX_DHtml helper macros allow easy access to the commonly used properties of controls on an HTML page.
Data Exchange Macros

DDX_DHtml_ElementValue Sets or retrieves the Value property from the selected control.

DDX_DHtml_ElementInnerText Sets or retrieves the text between the start and end tags of
the current element.
DDX_DHtml_ElementInnerHtml Sets or retrieves the HTML between the start and end tags of
the current element.

DDX_DHtml_Anchor_Href Sets or retrieves the destination URL or anchor point.

DDX_DHtml_Anchor_Target Sets or retrieves the target window or frame.

DDX_DHtml_Img_Src Sets or retrieves the name of an image or a video clip in the


document.

DDX_DHtml_Frame_Src Sets or retrieves the URL of the associated frame.

DDX_DHtml_IFrame_Src Sets or retrieves the URL of the associated frame.

CDHtmlDialog::CanAccessExternal
Overridable that is called as an access check to see whether scripting objects on the loaded page can access the
external dispatch of the control site. Checks to make sure the dispatch is either safe for scripting or the current
zone allows for objects that are not safe for scripting.

virtual BOOL CanAccessExternal();

Return Value
Nonzero if successful; otherwise 0.

CDHtmlDialog::CDHtmlDialog
Constructs a resource-based dynamic HTML dialog box.

CDHtmlDialog();

CDHtmlDialog(
LPCTSTR lpszTemplateName,
LPCTSTR szHtmlResID,
CWnd *pParentWnd = NULL);

CDHtmlDialog(
UINT nIDTemplate,
UINT nHtmlResID = 0,
CWnd *pParentWnd = NULL);

Parameters
lpszTemplateName
The null-terminated string that is the name of a dialog-box template resource.
szHtmlResID
The null-terminated string that is the name of an HTML resource.
pParentWnd
A pointer to the parent or owner window object (of type CWnd) to which the dialog object belongs. If it is NULL,
the dialog object's parent window is set to the main application window.
nIDTemplate
Contains the ID number of a dialog-box template resource.
nHtmlResID
Contains the ID number of an HTML resource.
Remarks
The second form of the constructor provides access to the dialog resource through the template name. The third
form of the constructor provides access to the dialog resource through the ID of the resource template. Usually,
the ID begins with the IDD_ prefix.

CDHtmlDialog::~CDHtmlDialog
Destroys a CDHtmlDialog object.

virtual ~CDHtmlDialog();

Remarks
The CWnd::DestroyWindow member function must be used to destroy modeless dialog boxes that are created by
CDialog::Create.

CDHtmlDialog::CreateControlSite
Overridable used to create a control site instance to host the WebBrowser control on the dialog.

virtual BOOL CreateControlSite(


COleControlContainer* pContainer,
COleControlSite** ppSite,
UINT /* nID */,
REFCLSID /* clsid */);

Parameters
pContainer
A pointer to the COleControlContainer object
ppSite
A pointer to a pointer to a COleControlSite.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You can override this member function to return an instance of your own control site class.

CDHtmlDialog::DDX_DHtml_AxControl
Exchanges data between a member variable and the property value of an ActiveX control on an HTML page.
void DDX_DHtml_AxControl(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
VARIANT& var);

void DDX_DHtml_AxControl(
CDataExchange* pDX,
LPCTSTR szId,
LPCTSTR szPropName,
VARIANT& var);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value of the object tag's ID parameter in the HTML source for the ActiveX control.
dispId
The dispatch ID of the property with which you want to exchange data.
szPropName
The name of the property.
var
The data member, of type VARIANT, COleVariant, or CComVariant, that holds the value exchanged with the ActiveX
control property.
Example

// COleVariant m_varSliderValue;
DDX_DHtml_AxControl(pDX, _T("slider1"), 0x0b /* Value */, m_varSliderValue);

CDHtmlDialog::DDX_DHtml_CheckBox
Exchanges data between a member variable and a check box on an HTML page.

void DDX_DHtml_CheckBox(
CDataExchange* pDX,
LPCTSTR szId,
int& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's ID parameter.
value
The value being exchanged.
Example
// int m_nItalic;
DDX_DHtml_CheckBox(pDX, L"italic", m_nItalic);

CDHtmlDialog::DDX_DHtml_ElementText
Exchanges data between a member variable and any HTML element property on an HTML page.

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
CString& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
short& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
int& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
long& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
DWORD& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
float& value);

void DDX_DHtml_ElementText(
CDataExchange* pDX,
LPCTSTR szId,
DISPID dispId,
double& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's ID parameter.
dispId
The dispatch ID of the HTML element with which you want to exchange data.
value
The value being exchanged.
CDHtmlDialog::DDX_DHtml_Radio
Exchanges data between a member variable and a radio button on an HTML page.

void DDX_DHtml_Radio(
CDataExchange* pDX,
LPCTSTR szId,
long& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's ID parameter.
value
The value being exchanged.

CDHtmlDialog::DDX_DHtml_SelectIndex
Gets or sets the index of a list box on an HTML page.

void DDX_DHtml_SelectIndex(
CDataExchange* pDX,
LPCTSTR szId,
long& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's id parameter.
value
The value being exchanged.

CDHtmlDialog::DDX_DHtml_SelectString
Gets or sets the display text of a list box entry (based on the current index) on an HTML page.

void DDX_DHtml_SelectString(
CDataExchange* pDX,
LPCTSTR szId,
CString& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's ID parameter.
value
The value being exchanged.

CDHtmlDialog::DDX_DHtml_SelectValue
Gets or sets the value of a list box entry (based on the current index) on an HTML page.

void DDX_DHtml_SelectValue(
CDataExchange* pDX,
LPCTSTR szId,
CString& value);

Parameters
pDX
A pointer to a CDataExchange object.
szId
The value that you specified for the HTML control's ID parameter.
value
The value being exchanged.
Example

// CString m_strBlurDir;
DDX_DHtml_SelectValue(pDX, L"blurDir", m_strBlurDir);

CDHtmlDialog::DestroyModeless
Detaches a modeless dialog box from the CDHtmlDialog object and destroys the object.

void DestroyModeless();

CDHtmlDialog::EnableModeless
Enables modeless dialog boxes.

STDMETHOD(EnableModeless)(BOOL fEnable);

Parameters
fEnable
See fEnable in IDocHostUIHandler::EnableModeless in the Windows SDK.
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::EnableModeless, as described in
the Windows SDK.

CDHtmlDialog::FilterDataObject
Allows the dialog to filter clipboard data objects created by the hosted browser.
STDMETHOD(FilterDataObject)(
IDataObject* pDO,
IDataObject** ppDORet);

Parameters
pDO
See pDO in IDocHostUIHandler::FilterDataObject in the Windows SDK.
ppDORet
See ppDORet in IDocHostUIHandler::FilterDataObject in the Windows SDK.
Return Value
Returns S_FALSE.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::FilterDataObject, as described in
the Windows SDK.

CDHtmlDialog::GetControlDispatch
Retrieves the IDispatch interface on an ActiveX control embedded in the HTML document returned by
GetDHtmlDocument.

HRESULT GetControlDispatch(
LPCTSTR szId,
IDispatch** ppdisp);

Parameters
szId
The HTML ID of an ActiveX control.
ppdisp
The IDispatch interface of the control if found in the Web page.
Return Value
A standard HRESULT value.

CDHtmlDialog::GetControlProperty
Retrieves the requested property of the specified ActiveX control.

VARIANT GetControlProperty(
LPCTSTR szId,
LPCTSTR szPropName);

VARIANT GetControlProperty(
LPCTSTR szId,
DISPID dispId);

VARIANT GetControlProperty(
IDispatch* pdispControl,
DISPID dispId);

Parameters
szId
The HTML ID of an ActiveX control.
szPropName
The name of a property in the default locale of the current user.
pdispControl
The IDispatch pointer of an ActiveX control.
dispId
The dispatch ID of a property.
Return Value
A variant containing the requested property or an empty variant if the control or property could not be found.
Remarks
The overloads are listed from least efficient at the top to most efficient at the bottom.

CDHtmlDialog::GetCurrentUrl
Retrieves the Uniform Resource Locator (URL) associated with the current document.

void GetCurrentUrl(CString& szUrl);

Parameters
szUrl
A CString object containing the URL to retrieve.

CDHtmlDialog::GetDHtmlDocument
Retrieves the IHTMLDocument2 interface on the currently loaded HTML document.

HRESULT GetDHtmlDocument(IHTMLDocument2 **pphtmlDoc);

Parameters
**pphtmlDoc A pointer to a pointer to an HTML document.
Return Value
A standard HRESULT. Returns S_OK if successful.

CDHtmlDialog::GetDropTarget
Called by the contained WebBrowser control when it is being used as a drop target to allow the dialog to supply
an alternative IDropTarget.

STDMETHOD(GetDropTarget)(
IDropTarget* pDropTarget,
IDropTarget** ppDropTarget);

Parameters
pDropTarget
See pDropTarget in IDocHostUIHandler::GetDropTarget in the Windows SDK.
ppDropTarget
See ppDropTarget in IDocHostUIHandler::GetDropTarget in the Windows SDK.
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::GetDropTarget, as described in
the Windows SDK.

CDHtmlDialog::GetElement
Returns an interface on the HTML element specified by szElementId.

HRESULT GetElement(
LPCTSTR szElementId,
IDispatch** ppdisp,
BOOL* pbCollection = NULL);

HRESULT GetElement(
LPCTSTR szElementId,
IHTMLElement** pphtmlElement);

Parameters
szElementId
The ID of an HTML element.
ppdisp
An IDispatch pointer to the requested element or collection of elements.
pbCollection
A BOOL indicating whether the object represented by ppdisp is a single element or a collection of elements.
pphtmlElement
An IHTMLElement pointer to the requested element.
Return Value
A standard HRESULT value.
Remarks
Use the first overload if you need to handle conditions in which there may be more than one element with the
specified ID. You can use the last parameter to find out whether the returned interface pointer is to a collection or
a single item. If the interface pointer is on a collection, you can query for the IHTMLElementCollection and use its
item property to refer to the elements by ordinal position.

The second overload will fail if there is more than one element with the same ID in the page.

CDHtmlDialog::GetElementHtml
Retrieves the innerHTML property of the HTML element identified by szElementId.

BSTR GetElementHtml(LPCTSTR szElementId);

Parameters
szElementId
The ID of an HTML element.
Return Value
The innerHTML property of the HTML element identified by szElementId or NULL if the element could not be
found.

CDHtmlDialog::GetElementInterface
Retrieves the requested interface pointer from the HTML element identified by szElementId.

template <class Q> HRESULT GetElementInterface(


LPCTSTR szElementId,
Q** ppvObj);

HRESULT GetElementInterface(
LPCTSTR szElementId,
REFIID refiid,
void** ppvObj);

Parameters
szElementId
The ID of an HTML element.
ppvObj
Address of a pointer that will be filled with the requested interface pointer if the element is found and the query
succeeds.
refiid
The interface ID (IID) of the requested interface.
Return Value
A standard HRESULT value.
Example

CComPtr<IHTMLInputButtonElement> spBtn1;
CComPtr<IHTMLInputButtonElement> spBtn2;
HRESULT hr = S_OK;

// Use the template overload


hr = GetElementInterface(L"Button1", &spBtn1);

// Use the nontemplate overload


hr = GetElementInterface(L"Button1", IID_IHTMLInputButtonElement,
reinterpret_cast<void **>(&spBtn2));

CDHtmlDialog::GetElementProperty
Retrieves the value of the property identified by dispId from the HTML element identified by szElementId.

VARIANT GetElementProperty(
LPCTSTR szElementId,
DISPID dispId);

Parameters
szElementId
The ID of an HTML element.
dispId
The dispatch ID of a property.
Return Value
The value of the property or an empty variant if the property or element could not be found.

CDHtmlDialog::GetElementText
Retrieves the innerText property of the HTML element identified by szElementId.

BSTR GetElementText(LPCTSTR szElementId);

Parameters
szElementId
The ID of an HTML element.
Return Value
The innerText property of the HTML element identified by szElementId or NULL if the property or element could
not be found.

CDHtmlDialog::GetEvent
Returns the IHTMLEventObj pointer to the current event object.

HRESULT GetEvent(IHTMLEventObj** ppEventObj);

Parameters
ppEventObj
Address of a pointer that will be filled with the IHTMLEventObj interface pointer.
Return Value
A standard HRESULT value.
Remarks
This function should only be called from within a DHTML event handler.

CDHtmlDialog::GetExternal
Gets the host's IDispatch interface.

STDMETHOD(GetExternal)(IDispatch** ppDispatch);

Parameters
ppDispatch
See ppDispatch in IDocHostUIHandler::GetExternal in the Windows SDK.
Return Value
Returns S_OK on success or E_NOTIMPL on failure.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::GetExternal, as described in the
Windows SDK.
CDHtmlDialog::GetHostInfo
Retrieves the host's UI capabilities.

STDMETHOD(GetHostInfo)(DOCHOSTUIINFO* pInfo);

Parameters
pInfo
See pInfo in IDocHostUIHandler::GetHostInfo in the Windows SDK.
Return Value
Returns S_OK.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::GetHostInfo, as described in the
Windows SDK.

CDHtmlDialog::GetOptionKeyPath
Retrieves the registry key under which user preferences are stored.

STDMETHOD(GetOptionKeyPath)(
LPOLESTR* pchKey,
DWORD dw);

Parameters
pchKey
See pchKey in IDocHostUIHandler::GetOptionKeyPath in the Windows SDK.
dw
See dw in IDocHostUIHandler::GetOptionKeyPath in the Windows SDK.
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::GetOptionKeyPath, as described
in the Windows SDK.

CDHtmlDialog::HideUI
Hides the host's UI.

STDMETHOD(HideUI)(void);

Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::HideUI, as described in the
Windows SDK.
CDHtmlDialog::IsExternalDispatchSafe
Indicates whether the host's IDispatch interface is safe for scripting.

virtual BOOL IsExternalDispatchSafe();

Return Value
Returns FALSE.

CDHtmlDialog::LoadFromResource
Loads the specified resource into the WebBrowser control in the DHTML dialog.

BOOL LoadFromResource(LPCTSTR lpszResource);


BOOL LoadFromResource(UINT nRes);

Parameters
lpszResource
A pointer to a string containing the name of the resource to load.
nRes
The ID of the resource to load.
Return Value
TRUE if successful; otherwise FALSE.

CDHtmlDialog::m_bUseHtmlTitle
Indicates whether to use the HTML document's title as the dialog caption.

BOOL m_bUseHtmlTitle;

Remarks
If m _ bUseHtmlTitle is TRUE, the dialog caption is set equal to the title of the HTML document; otherwise, the
caption in the dialog resource is used.

CDHtmlDialog::m_nHtmlResID
Resource ID of HTML resource to be displayed.

UINT m_nHtmlResID;

Example

CDHtmlDialog mydialog(IDD_MYDHTMLDLG);
mydialog.m_nHtmlResID = IDR_HTML_MYDHTMLDLG;
mydialog.DoModal();

CDHtmlDialog::m_pBrowserApp
A pointer to a Web browser application.
CComPtr <IWebBrowser2> m_pBrowserApp;

CDHtmlDialog::m_spHtmlDoc
A pointer to an HTML document.

CComPtr<IHTMLDocument2> m_spHtmlDoc;

CDHtmlDialog::m_strCurrentUrl
The current URL.

CString m_strCurrentUrl;

CDHtmlDialog::m_szHtmlResID
String version of the HTML resource ID.

LPTSTR m_szHtmlResID;

Example

CDHtmlDialog mydialog(IDD_MYDHTMLDLG);
TCHAR szResID[] = _T("HTML_PAGE");
mydialog.m_szHtmlResID = szResID;
mydialog.DoModal();

CDHtmlDialog::Navigate
Navigates to the resource identified by the URL that is specified by lpszURL.

void Navigate(
LPCTSTR lpszURL,
DWORD dwFlags = 0,
LPCTSTR lpszTargetFrameName = NULL,
LPCTSTR lpszHeaders = NULL,
LPVOID lpvPostData = NULL,
DWORD dwPostDataLen = 0);

Parameters
lpszURL
A pointer to a string containing the URL to be targeted.
dwFlags
The flags of a variable that specifies whether to add the resource to the history list, whether to read to the cache
or write from the cache, and whether to display the resource in a new window. The variable can be a combination
of the values defined by the BrowserNavConstants enumeration.
lpszTargetFrameName
A pointer to a string that contains the name of the frame in which to display the resource.
lpszHeaders
A pointer to a value that specifies the HTTP headers to send to the server. These headers are added to the default
Internet Explorer headers. The headers can specify such information as the action required of the server, the type
of data being passed to the server, or a status code. This parameter is ignored if the URL is not an HTTP URL.
lpvPostData
A pointer to the data to send with the HTTP POST transaction. For example, the POST transaction is used to send
data gathered by an HTML form. If this parameter does not specify any post data, Navigate issues an HTTP GET
transaction. This parameter is ignored if the URL is not an HTTP URL.
dwPostDataLen
Data to send with the HTTP POST transaction. For example, the POST transaction is used to send data gathered by
an HTML form. If this parameter does not specify any post data, Navigate issues an HTTP GET transaction. This
parameter is ignored if URL is not an HTTP URL.

CDHtmlDialog::OnBeforeNavigate
Called by the framework to cause an event to fire before a navigation occurs.

virtual void OnBeforeNavigate(


LPDISPATCH pDisp,
LPCTSTR szUrl);

Parameters
pDisp
A pointer to an IDispatch object.
szUrl
A pointer to a string containing the URL to navigate to.

CDHtmlDialog::OnDocumentComplete
Called by the framework to notify an application when a document has achieved the READYSTATE_COMPLETE
state.

virtual void OnDocumentComplete(


LPDISPATCH pDisp,
LPCTSTR szUrl);

Parameters
pDisp
A pointer to an IDispatch object.
szUrl
A pointer to a string containing the URL that was navigated to.

CDHtmlDialog::OnDocWindowActivate
Called by the framework when the document window is activated or deactivated.

STDMETHOD(OnDocWindowActivate)(BOOL fActivate);

Parameters
fActivate
See fActivate in IDocHostUIHandler::OnDocWindowActivate in the Windows SDK.
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::OnDocWindowActivate, as
described in the Windows SDK.

CDHtmlDialog::OnFrameWindowActivate
Called by the framework when the frame window is activated or deactivated.

STDMETHOD(OnFrameWindowActivate)(BOOL fActivate);

Parameters
fActivate
See fActivate in IDocHostUIHandler::OnFrameWindowActivate in the Windows SDK.
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::OnFrameWindowActivate, as
described in the Windows SDK.

CDHtmlDialog::OnInitDialog
Called in response to the WM_INITDIALOG message.

virtual BOOL OnInitDialog();

Return Value
The default implementation returns TRUE.
Remarks
This message is sent to the dialog box during the Create , CreateIndirect , or DoModal calls, which occur
immediately before the dialog box is displayed.
Override this member function if you need to perform special processing when the dialog box is initialized. In the
overridden version, first call the base class OnInitDialog but disregard its return value. You will normally return
TRUE from your overridden member function.
Windows calls the OnInitDialog function through the standard global dialog-box procedure common to all
Microsoft Foundation Class Library dialog boxes, rather than through your message map, so you do not need a
message-map entry for this member function.

CDHtmlDialog::OnNavigateComplete
Called by the framework after navigation to the specified URL is completed.
virtual void OnNavigateComplete(
LPDISPATCH pDisp,
LPCTSTR szUrl);

Parameters
pDisp
A pointer to an IDispatch object.
szUrl
A pointer to a string containing the URL that was navigated to.

CDHtmlDialog::ResizeBorder
Alerts the object that it needs to resize its border space.

STDMETHOD(ResizeBorder)(
LPCRECT prcBorder,
IOleInPlaceUIWindow* pUIWindow,
BOOL fRameWindow);

Parameters
prcBorder
See prcBorder in IDocHostUIHandler::ResizeBorder in the Windows SDK.
pUIWindow
See pUIWindow in IDocHostUIHandler::ResizeBorder in the Windows SDK.
fFrameWindow
See fFrameWindow in IDocHostUIHandler::ResizeBorder in the Windows SDK.
Return Value
Returns E_NOTIMPL.

CDHtmlDialog::SetControlProperty
Sets the property of an ActiveX control to a new value.

void SetControlProperty(
LPCTSTR szElementId,
DISPID dispId,
VARIANT* pVar);

void SetControlProperty(
IDispatch* pdispControl,
DISPID dispId,
VARIANT* pVar);

void SetControlProperty(
LPCTSTR szElementId,
LPCTSTR szPropName,
VARIANT* pVar);

Parameters
szElementId
The HTML ID of an ActiveX control.
dispId
The dispatch ID of the property to set.
pVar
Pointer to a VARIANT containing the new property value.
pdispControl
Pointer to an ActiveX control's IDispatch interface.
szPropName
String containing the name of the property to set.

CDHtmlDialog::SetElementHtml
Sets the innerHTML property of an HTML element.

void SetElementHtml(
LPCTSTR szElementId,
BSTR bstrText);

void SetElementHtml(
IUnknown* punkElem,
BSTR bstrText);

Parameters
szElementId
The ID of an HTML element.
bstrText
The new value of the innerHTML property.
punkElem
The IUnknown pointer of an HTML element.

CDHtmlDialog::SetElementProperty
Sets a property of an HTML element.

void SetElementProperty(
LPCTSTR szElementId,
DISPID dispId,
VARIANT* pVar);

Parameters
szElementId
The ID of an HTML element.
dispId
The dispatch ID of the property to set.
pVar
The new value of the property.

CDHtmlDialog::SetElementText
Sets the innerText property of an HTML element.
void SetElementText(
LPCTSTR szElementId,
BSTR bstrText);

void SetElementText(
IUnknown* punkElem,
BSTR bstrText);

Parameters
szElementId
The ID of an HTML element.
bstrText
The new value of the innerText property.
punkElem
The IUnknown pointer of an HTML element.

CDHtmlDialog::SetExternalDispatch
Sets the host's IDispatch interface.

void SetExternalDispatch(IDispatch* pdispExternal);

Parameters
pdispExternal
The new IDispatch interface.

CDHtmlDialog::SetHostFlags
Sets the host UI flags.

void SetHostFlags(DWORD dwFlags);

Parameters
dwFlags
For possible values, see DOCHOSTUIFLAG in the Windows SDK.

CDHtmlDialog::ShowContextMenu
Called when a context menu is about to be displayed.

STDMETHOD(ShowContextMenu)(
DWORD dwID,
POINT* ppt,
IUnknown* pcmdtReserved,
IDispatch* pdispReserved);

Parameters
dwID
See dwID in IDocHostUIHandler::ShowContextMenu in the Windows SDK.
ppt
See ppt in IDocHostUIHandler::ShowContextMenu in the Windows SDK.
pcmdtReserved
See pcmdtReserved in IDocHostUIHandler::ShowContextMenu in the Windows SDK.
pdispReserved
See pdispReserved in IDocHostUIHandler::ShowContextMenu in the Windows SDK.
Return Value
Returns S_FALSE.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::ShowContextMenu, as described
in the Windows SDK.

CDHtmlDialog::ShowUI
Shows the host's UI.

STDMETHOD(ShowUI)(
DWORD dwID,
IOleInPlaceActiveObject* pActiveObject,
IOleCommandTarget* pCommandTarget,
IOleInPlaceFrame* pFrame,
IOleInPlaceUIWindow* pDoc);

Parameters
dwID
See dwID in IDocHostUIHandler::ShowUI in the Windows SDK.
pActiveObject
See d pActiveObject in IDocHostUIHandler::ShowUI in the Windows SDK.
pCommandTarget
See pCommandTarget in IDocHostUIHandler::ShowUI in the Windows SDK.
pFrame
See pFrame in IDocHostUIHandler::ShowUI in the Windows SDK.
pDoc
See pDoc in IDocHostUIHandler::ShowUI in the Windows SDK.
Return Value
Returns S_FALSE.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::ShowUI, as described in the
Windows SDK.

CDHtmlDialog::TranslateAccelerator
Called to process menu accelerator-key messages.
STDMETHOD(TranslateAccelerator)(
LPMSG lpMsg,
const GUID* pguidCmdGroup,
DWORD nCmdID);

Parameters
lpMsg
See lpMsg in IDocHostUIHandler::TranslateAccelerator in the Windows SDK.
pguidCmdGroup
See pguidCmdGroup in IDocHostUIHandler::TranslateAccelerator in the Windows SDK.
nCmdID
See nCmdID in IDocHostUIHandler::TranslateAccelerator in the Windows SDK.
Return Value
Returns S_FALSE.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::TranslateAccelerator, as
described in the Windows SDK.

CDHtmlDialog::TranslateUrl
Called to modify the URL to be loaded.

STDMETHOD(TranslateUrl)(
DWORD dwTranslate,
OLECHAR* pchURLIn,
OLECHAR** ppchURLOut);

Parameters
dwTranslate
See dwTranslate in IDocHostUIHandler::TranslateUrl in the Windows SDK.
pchURLIn
See pchURLIn in IDocHostUIHandler::TranslateUrl in the Windows SDK.
ppchURLOut
See ppchURLOut in IDocHostUIHandler::TranslateUrl in the Windows SDK.
Return Value
Returns S_FALSE.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::TranslateUrl, as described in the
Windows SDK.

CDHtmlDialog::UpdateUI
Called to notify the host that the command state has changed.

STDMETHOD(UpdateUI)(void);
Return Value
Returns E_NOTIMPL.
Remarks
This member function is CDHtmlDialog's implementation of IDocHostUIHandler::UpdateUI, as described in the
Windows SDK.

See also
MFC Sample DHtmlExplore
DDX_DHtml Helper Macros
Hierarchy Chart
DDX_DHtml Helper Macros
3/27/2020 • 3 minutes to read • Edit Online

The DDX_DHtml helper macros allow easy access to the commonly used properties of controls on an HTML page.
Data Exchange Macros

DDX_DHtml_ElementValue Sets or retrieves the Value property from the selected control.

DDX_DHtml_ElementInnerText Sets or retrieves the text between the start and end tags of
the current element.

DDX_DHtml_ElementInnerHtml Sets or retrieves the HTML between the start and end tags of
the current element.

DDX_DHtml_Anchor_Href Sets or retrieves the destination URL or anchor point.

DDX_DHtml_Anchor_Target Sets or retrieves the target window or frame.

DDX_DHtml_Img_Src Sets or retrieves the name of an image or a video clip in the


document.

DDX_DHtml_Frame_Src Sets or retrieves the URL of the associated frame.

DDX_DHtml_IFrame_Src Sets or retrieves the URL of the associated frame.

Requirements
Header : afxdhtml.h

DDX_DHtml_Anchor_Href
Sets or retrieves the destination URL or anchor point.

DDX_DHtml_Anchor_Href(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the
DISPID_IHTMLANCHORELEMENT_HREF dispatch ID.

DDX_DHtml_Anchor_Target
Sets or retrieves the target window or frame.

DDX_DHtml_Anchor_Target(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the
DISPID_IHTMLANCHORELEMENT_TARGET dispatch ID.

DDX_DHtml_ElementInnerHtml
Sets or retrieves the HTML between the start and end tags of the current element.

DDX_DHtml_ElementInnerHtml(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the
DISPID_IHTMLELEMENT_INNERHTML dispatch ID.

DDX_DHtml_ElementInnerText
Sets or retrieves the text between the start and end tags of the current element.
DDX_DHtml_ElementInnerText(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the
DISPID_IHTMLELEMENT_INNERTEXT dispatch ID.

DDX_DHtml_ElementValue
Sets or retrieves the Value property from the selected control.

DDX_DHtml_ElementValue(
CDataExchange* dx,
LPCTSTR name,
var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged. See value in CDHtmlDialog::DDX_DHtml_ElementText.

Remarks
This macro will only succeed when run on controls that have a Value property. Controls that have a Value property
include edit boxes, list boxes, and combo boxes.
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the DISPID_A_VALUE dispatch ID.

DDX_DHtml_Frame_Src
Sets or retrieves the URL of the associated frame.

DDX_DHtml_Frame_Src(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the DISPID_IHTMLFRAMEBASE_SRC
dispatch ID.

DDX_DHtml_IFrame_Src
Sets or retrieves the URL of the associated frame.

DDX_DHtml_IFrame_Src(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.

Remarks
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the DISPID_IHTMLFRAMEBASE_SRC
dispatch ID.

DDX_DHtml_Img_Src
Gets or retrieves the name of an image or a video clip in the document.

DDX_DHtml_Img_Src(
CDataExchange* dx,
LPCTSTR name,
CString& var)

Parameters
dx
A pointer to a CDataExchange object.
name
The value that you specified for the HTML control's ID parameter.
var
The value being exchanged.
Remarks
When using the DDX_DHtml_Img_Src macro to retrieve the src property for an IMAGE element, the Internet
Explorer image object will return the fully escaped URL for the image source. For example, if you use the
DDX_DHtml_Img_Src macro to set the src property of an IMAGE element to the string "some interesting picture,"
when you retrieve that property, Internet Explorer will return the string
"res://d:\myapplication\myapp.exe/some%20interesting%20picture."
This macro calls the CDHtmlDialog::DDX_DHtml_ElementText function using the DISPID_IHTMLIMGELEMENT_SRC
dispatch ID.

See also
CDHtmlDialog Class
CDialog Class
4/21/2020 • 18 minutes to read • Edit Online

The base class used for displaying dialog boxes on the screen.

Syntax
class CDialog : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CDialog::CDialog Constructs a CDialog object.

Public Methods
NAME DESC RIP T IO N

CDialog::Create Initializes the CDialog object. Creates a modeless


dialog box and attaches it to the CDialog object.

CDialog::CreateIndirect Creates a modeless dialog box from a dialog-box


template in memory (not resource-based).

CDialog::DoModal Calls a modal dialog box and returns when done.

CDialog::EndDialog Closes a modal dialog box.

CDialog::GetDefID Gets the ID of the default pushbutton control for a


dialog box.

CDialog::GotoDlgCtrl Moves the focus to a specified dialog-box control in


the dialog box.

CDialog::InitModalIndirect Creates a modal dialog box from a dialog-box template


in memory (not resource-based). The parameters are
stored until the function DoModal is called.

CDialog::MapDialogRect Converts the dialog-box units of a rectangle to screen


units.

CDialog::NextDlgCtrl Moves the focus to the next dialog-box control in the


dialog box.

CDialog::OnInitDialog Override to augment dialog-box initialization.


NAME DESC RIP T IO N

CDialog::OnSetFont Override to specify the font that a dialog-box control is


to use when it draws text.

CDialog::PrevDlgCtrl Moves the focus to the previous dialog-box control in


the dialog box.

CDialog::SetDefID Changes the default pushbutton control for a dialog


box to a specified pushbutton.

CDialog::SetHelpID Sets a context-sensitive help ID for the dialog box.

Protected Methods
NAME DESC RIP T IO N

CDialog::OnCancel Override to perform the Cancel button or ESC key


action. The default closes the dialog box and DoModal
returns IDCANCEL.

CDialog::OnOK Override to perform the OK button action in a modal


dialog box. The default closes the dialog box and
DoModal returns IDOK.

Remarks
Dialog boxes are of two types: modal and modeless. A modal dialog box must be closed by the user
before the application continues. A modeless dialog box allows the user to display the dialog box and
return to another task without canceling or removing the dialog box.
A CDialog object is a combination of a dialog template and a CDialog -derived class. Use the dialog
editor to create the dialog template and store it in a resource, then use the Add Class wizard to create
a class derived from CDialog .
A dialog box, like any other window, receives messages from Windows. In a dialog box, you are
particularly interested in handling notification messages from the dialog box's controls since that is
how the user interacts with your dialog box. Use the Class Wizard to select which messages you wish
to handle and it will add the appropriate message-map entries and message-handler member
functions to the class for you. You only need to write application-specific code in the handler member
functions.
If you prefer, you can always write message-map entries and member functions manually.
In all but the most trivial dialog box, you add member variables to your derived dialog class to store
data entered in the dialog box's controls by the user or to display data for the user. You can use the
Add Variable wizard to create member variables and associate them with controls. At the same time,
you choose a variable type and permissible range of values for each variable. The code wizard adds
the member variables to your derived dialog class.
A data map is generated to automatically handle the exchange of data between the member variables
and the dialog box's controls. The data map provides functions that initialize the controls in the dialog
box with the proper values, retrieve the data, and validate the data.
To create a modal dialog box, construct an object on the stack using the constructor for your derived
dialog class and then call DoModal to create the dialog window and its controls. If you wish to create a
modeless dialog, call Create in the constructor of your dialog class.
You can also create a template in memory by using a DLGTEMPLATE data structure as described in the
Windows SDK. After you construct a CDialog object, call CreateIndirect to create a modeless dialog
box, or call InitModalIndirect and DoModal to create a modal dialog box.
The exchange and validation data map is written in an override of CWnd::DoDataExchange that is added
to your new dialog class. See the DoDataExchange member function in CWnd for more on the
exchange and validation functionality.
Both the programmer and the framework call DoDataExchange indirectly through a call to
CWnd::UpdateData.
The framework calls UpdateData when the user clicks the OK button to close a modal dialog box. (The
data is not retrieved if the Cancel button is clicked.) The default implementation of OnInitDialog also
calls UpdateData to set the initial values of the controls. You typically override OnInitDialog to further
initialize controls. OnInitDialog is called after all the dialog controls are created and just before the
dialog box is displayed.
You can call CWnd::UpdateData at any time during the execution of a modal or modeless dialog box.
If you develop a dialog box by hand, you add the necessary member variables to the derived dialog-
box class yourself, and you add member functions to set or get these values.
A modal dialog box closes automatically when the user presses the OK or Cancel buttons or when
your code calls the EndDialog member function.
When you implement a modeless dialog box, always override the OnCancel member function and call
DestroyWindow from within it. Don't call the base class CDialog::OnCancel , because it calls EndDialog ,
which will make the dialog box invisible but will not destroy it. You should also override
PostNcDestroy for modeless dialog boxes in order to delete this , since modeless dialog boxes are
usually allocated with new . Modal dialog boxes are usually constructed on the frame and do not need
PostNcDestroy cleanup.

For more information on CDialog , see Dialog Boxes.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog

Requirements
Header : afxwin.h

CDialog::CDialog
To construct a resource-based modal dialog box, call either public form of the constructor.
explicit CDialog(
LPCTSTR lpszTemplateName,
CWnd* pParentWnd = NULL);

explicit CDialog(
UINT nIDTemplate,
CWnd* pParentWnd = NULL);

CDialog();

Parameters
lpszTemplateName
Contains a null-terminated string that is the name of a dialog-box template resource.
nIDTemplate
Contains the ID number of a dialog-box template resource.
pParentWnd
Points to the parent or owner window object (of type CWnd) to which the dialog object belongs. If it is
NULL, the dialog object's parent window is set to the main application window.
Remarks
One form of the constructor provides access to the dialog resource by template name. The other
constructor provides access by template ID number, usually with an IDD_ prefix (for example,
IDD_DIALOG1).
To construct a modal dialog box from a template in memory, first invoke the parameterless, protected
constructor and then call InitModalIndirect .
After you construct a modal dialog box with one of the above methods, call DoModal .
To construct a modeless dialog box, use the protected form of the CDialog constructor. The
constructor is protected because you must derive your own dialog-box class to implement a modeless
dialog box. Construction of a modeless dialog box is a two-step process. First call the constructor; then
call the Create member function to create a resource-based dialog box, or call CreateIndirect to
create the dialog box from a template in memory.

CDialog::Create
Call Create to create a modeless dialog box using a dialog-box template from a resource.

virtual BOOL Create(


LPCTSTR lpszTemplateName,
CWnd* pParentWnd = NULL);

virtual BOOL Create(


UINT nIDTemplate,
CWnd* pParentWnd = NULL);

Parameters
lpszTemplateName
Contains a null-terminated string that is the name of a dialog-box template resource.
pParentWnd
Points to the parent window object (of type CWnd) to which the dialog object belongs. If it is NULL, the
dialog object's parent window is set to the main application window.
nIDTemplate
Contains the ID number of a dialog-box template resource.
Return Value
Both forms return nonzero if dialog-box creation and initialization were successful; otherwise 0.
Remarks
You can put the call to Create inside the constructor or call it after the constructor is invoked.
Two forms of the Create member function are provided for access to the dialog-box template
resource by either template name or template ID number (for example, IDD_DIALOG1).
For either form, pass a pointer to the parent window object. If pParentWnd is NULL, the dialog box will
be created with its parent or owner window set to the main application window.
The Create member function returns immediately after it creates the dialog box.
Use the WS_VISIBLE style in the dialog-box template if the dialog box should appear when the parent
window is created. Otherwise, you must call ShowWindow . For further dialog-box styles and their
application, see the DLGTEMPLATE structure in the Windows SDK and Window Styles in the MFC
Reference.
Use the CWnd::DestroyWindow function to destroy a dialog box created by the Create function.
Example

void CMyDialog::OnMenuShowSimpleDialog()
{
//m_pSimpleDialog initialized to NULL in the constructor of CMyDialog class
m_pSimpleDlg = new CSimpleDlg();
//Check if new succeeded and we got a valid pointer to a dialog object
if (m_pSimpleDlg != NULL)
{
BOOL ret = m_pSimpleDlg->Create(IDD_SIMPLEDIALOG, this);

if (!ret) //Create failed.


{
AfxMessageBox(_T("Error creating Dialog"));
}

m_pSimpleDlg->ShowWindow(SW_SHOW);
}
else
{
AfxMessageBox(_T("Error Creating Dialog Object"));
}
}

CDialog::CreateIndirect
Call this member function to create a modeless dialog box from a dialog-box template in memory.

virtual BOOL CreateIndirect(


LPCDLGTEMPLATE lpDialogTemplate,
CWnd* pParentWnd = NULL,
void* lpDialogInit = NULL);

virtual BOOL CreateIndirect(


HGLOBAL hDialogTemplate,
CWnd* pParentWnd = NULL);
Parameters
lpDialogTemplate
Points to memory that contains a dialog-box template used to create the dialog box. This template is
in the form of a DLGTEMPLATE structure and control information, as described in the Windows SDK.
pParentWnd
Points to the dialog object's parent window object (of type CWnd). If it is NULL, the dialog object's
parent window is set to the main application window.
lpDialogInit
Points to a DLGINIT resource.
hDialogTemplate
Contains a handle to global memory containing a dialog-box template. This template is in the form of
a DLGTEMPLATE structure and data for each control in the dialog box.
Return Value
Nonzero if the dialog box was created and initialized successfully; otherwise 0.
Remarks
The CreateIndirect member function returns immediately after it creates the dialog box.
Use the WS_VISIBLE style in the dialog-box template if the dialog box should appear when the parent
window is created. Otherwise, you must call ShowWindow to cause it to appear. For more information
on how you can specify other dialog-box styles in the template, see the DLGTEMPLATE structure in the
Windows SDK.
Use the CWnd::DestroyWindow function to destroy a dialog box created by the CreateIndirect function.
Dialog boxes that contain ActiveX controls require additional information provided in a DLGINIT
resource.

CDialog::DoModal
Call this member function to invoke the modal dialog box and return the dialog-box result when done.

virtual INT_PTR DoModal();

Return Value
An int value that specifies the value of the nResult parameter that was passed to the
CDialog::EndDialog member function, which is used to close the dialog box. The return value is -1 if
the function could not create the dialog box, or IDABORT if some other error occurred, in which case
the output window will contain error information from GetLastError.
Remarks
This member function handles all interaction with the user while the dialog box is active. This is what
makes the dialog box modal; that is, the user cannot interact with other windows until the dialog box
is closed.
If the user clicks one of the pushbuttons in the dialog box, such as OK or Cancel, a message-handler
member function, such as OnOK or OnCancel, is called to attempt to close the dialog box. The default
OnOK member function will validate and update the dialog-box data and close the dialog box with
result IDOK, and the default OnCancel member function will close the dialog box with result
IDCANCEL without validating or updating the dialog-box data. You can override these message-
handler functions to alter their behavior.
NOTE
PreTranslateMessage is now called for modal dialog box message processing.

Example

void CMyDialog::OnMenuShowAboutDialog()
{
// Construct the dialog box passing the
// ID of the dialog template resource
CDialog aboutDlg(IDD_ABOUTBOX);

// Create and show the dialog box


INT_PTR nRet = -1;
nRet = aboutDlg.DoModal();

// Handle the return value from DoModal


switch (nRet)
{
case -1:
AfxMessageBox(_T("Dialog box could not be created!"));
break;
case IDABORT:
// Do something
break;
case IDOK:
// Do something
break;
case IDCANCEL:
// Do something
break;
default:
// Do something
break;
};
}

CDialog::EndDialog
Call this member function to terminate a modal dialog box.

void EndDialog(int nResult);

Parameters
nResult
Contains the value to be returned from the dialog box to the caller of DoModal .
Remarks
This member function returns nResult as the return value of DoModal . You must use the EndDialog
function to complete processing whenever a modal dialog box is created.
You can call EndDialog at any time, even in OnInitDialog, in which case you should close the dialog
box before it is shown or before the input focus is set.
EndDialog does not close the dialog box immediately. Instead, it sets a flag that directs the dialog box
to close as soon as the current message handler returns.
Example
void CMyDialog::OnMenuShowSimpleModal()
{
CSimpleDlg myDlg;
INT_PTR nRet = myDlg.DoModal();

if (nRet == IDOK || nRet == 5)


{
AfxMessageBox(_T("Dialog closed successfully"));
}
}

void CSimpleDlg::OnRButtonUp(UINT nFlags, CPoint point)


{
UNREFERENCED_PARAMETER(nFlags);
// Do something

int nRet = point.x; // Just any value would do!


EndDialog(nRet); // This value is returned by DoModal!

// Do something

return; // Dialog closed and DoModal returns only here!


}

CDialog::GetDefID
Call the GetDefID member function to get the ID of the default pushbutton control for a dialog box.

DWORD GetDefID() const;

Return Value
A 32-bit value ( DWORD ). If the default pushbutton has an ID value, the high-order word contains
DC_HASDEFID and the low-order word contains the ID value. If the default pushbutton does not have
an ID value, the return value is 0.
Remarks
This is usually an OK button.

CDialog::GotoDlgCtrl
Moves the focus to the specified control in the dialog box.

void GotoDlgCtrl(CWnd* pWndCtrl);

Parameters
pWndCtrl
Identifies the window (control) that is to receive the focus.
Remarks
To get a pointer to the control (child window) to pass as pWndCtrl, call the CWnd::GetDlgItem member
function, which returns a pointer to a CWnd object.
Example
See the example for CWnd::GetDlgItem.
CDialog::InitModalIndirect
Call this member function to initialize a modal dialog object using a dialog-box template that you
construct in memory.

BOOL InitModalIndirect(
LPCDLGTEMPLATE lpDialogTemplate,
CWnd* pParentWnd = NULL,
void* lpDialogInit = NULL);

BOOL InitModalIndirect(
HGLOBAL hDialogTemplate,
CWnd* pParentWnd = NULL);

Parameters
lpDialogTemplate
Points to memory that contains a dialog-box template used to create the dialog box. This template is
in the form of a DLGTEMPLATE structure and control information, as described in the Windows SDK.
hDialogTemplate
Contains a handle to global memory containing a dialog-box template. This template is in the form of
a DLGTEMPLATE structure and data for each control in the dialog box.
pParentWnd
Points to the parent or owner window object (of type CWnd) to which the dialog object belongs. If it is
NULL, the dialog object's parent window is set to the main application window.
lpDialogInit
Points to a DLGINIT resource.
Return Value
Nonzero if the dialog object was created and initialized successfully; otherwise 0.
Remarks
To create a modal dialog box indirectly, first allocate a global block of memory and fill it with the
dialog box template. Then call the empty CDialog constructor to construct the dialog-box object. Next,
call InitModalIndirect to store your handle to the in-memory dialog-box template. The Windows
dialog box is created and displayed later, when the DoModal member function is called.
Dialog boxes that contain ActiveX controls require additional information provided in a DLGINIT
resource.

CDialog::MapDialogRect
Call to convert the dialog-box units of a rectangle to screen units.

void MapDialogRect(LPRECT lpRect) const;

Parameters
lpRect
Points to a RECT structure or CRect object that contains the dialog-box coordinates to be converted.
Remarks
Dialog-box units are stated in terms of the current dialog-box base unit derived from the average
width and height of characters in the font used for dialog-box text. One horizontal unit is one-fourth
of the dialog-box base-width unit, and one vertical unit is one-eighth of the dialog-box base height
unit.
The GetDialogBaseUnits Windows function returns size information for the system font, but you can
specify a different font for each dialog box if you use the DS_SETFONT style in the resource-definition
file. The MapDialogRect Windows function uses the appropriate font for this dialog box.
The MapDialogRect member function replaces the dialog-box units in lpRect with screen units (pixels)
so that the rectangle can be used to create a dialog box or position a control within a box.

CDialog::NextDlgCtrl
Moves the focus to the next control in the dialog box.

void NextDlgCtrl() const;

Remarks
If the focus is at the last control in the dialog box, it moves to the first control.

CDialog::OnCancel
The framework calls this method when the user clicks Cancel or presses the ESC key in a modal or
modeless dialog box.

virtual void OnCancel();

Remarks
Override this method to perform actions (such as restoring old data) when a user closes the dialog
box by clicking Cancel or hitting the ESC key. The default closes a modal dialog box by calling
EndDialog and causing DoModal to return IDCANCEL.
If you implement the Cancel button in a modeless dialog box, you must override the OnCancel
method and call DestroyWindow inside it. Do not call the base-class method, because it calls
EndDialog , which will make the dialog box invisible but not destroy it.

NOTE
You cannot override this method when you use a CFileDialog object in a program that is compiled under
Windows XP. For more information about CFileDialog , see CFileDialog Class.

Example
void CSimpleDlg::OnCancel()
{
// TODO: Add extra cleanup here

// Ensure that you reset all the values back to the


// ones before modification. This handler is called
// when the user doesn't want to save the changes.

if (AfxMessageBox(_T("Are you sure you want to abort the changes?"),


MB_YESNO) == IDNO)
{
// Give the user a chance if he has unknowingly hit the
// Cancel button. If he says No, return. Don't reset. If
// Yes, go ahead and reset the values and close the dialog.
return;
}

m_nMyValue = m_nPrevValue;
m_pMyString = NULL;

CDialog::OnCancel();
}

CDialog::OnInitDialog
This method is called in response to the WM_INITDIALOG message.

virtual BOOL OnInitDialog();

Return Value
Specifies whether the application has set the input focus to one of the controls in the dialog box. If
OnInitDialog returns nonzero, Windows sets the input focus to the default location, the first control in
the dialog box. The application can return 0 only if it has explicitly set the input focus to one of the
controls in the dialog box.
Remarks
Windows sends the WM_INITDIALOG message to the dialog box during the Create, CreateIndirect, or
DoModal calls, which occur immediately before the dialog box is displayed.
Override this method if you want to perform special processing when the dialog box is initialized. In
the overridden version, first call the base class OnInitDialog but ignore its return value. You will
typically return TRUE from your overridden method.
Windows calls the OnInitDialog function by using the standard global dialog-box procedure common
to all Microsoft Foundation Class Library dialog boxes. It does not call this function through your
message map, and therefore you do not need a message map entry for this method.

NOTE
You cannot override this method when you use a CFileDialog object in a program that is compiled under
Windows Vista or later operating systems. For more information about changes to CFileDialog under
Windows Vista and later, see CFileDialog Class.

Example
BOOL CSimpleDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// TODO: Add extra initialization here


m_cMyEdit.SetWindowText(_T("My Name")); // Initialize control values
m_cMyList.ShowWindow(SW_HIDE); // Show or hide a control, etc.

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}

CDialog::OnOK
Called when the user clicks the OK button (the button with an ID of IDOK).

virtual void OnOK();

Remarks
Override this method to perform actions when the OK button is activated. If the dialog box includes
automatic data validation and exchange, the default implementation of this method validates the
dialog box data and updates the appropriate variables in your application.
If you implement the OK button in a modeless dialog box, you must override the OnOK method and
call DestroyWindow inside it. Do not call the base-class method, because it calls EndDialog which
makes the dialog box invisible but does not destroy it.

NOTE
You cannot override this method when you use a CFileDialog object in a program that is compiled under
Windows XP. For more information about CFileDialog , see CFileDialog Class.

Example

void CSimpleDlg::OnOK()
{
// TODO: Add extra validation here

// Ensure that your UI got the necessary input


// from the user before closing the dialog. The
// default OnOK will close this.
if (m_nMyValue == 0) // Is a particular field still empty?
{
// Inform the user that he can't close the dialog without
// entering the necessary values and don't close the
// dialog.
AfxMessageBox(_T("Please enter a value for MyValue"));
return;
}

CDialog::OnOK(); // This will close the dialog and DoModal will return.
}

CDialog::OnSetFont
Specifies the font a dialog-box control will use when drawing text.
Virtual void OnSetFont(CFont* pFont);

Parameters
pFont
[in] Specifies a pointer to the font that will be used as the default font for all controls in this dialog box.
Remarks
The dialog box will use the specified font as the default for all its controls.
The dialog editor typically sets the dialog-box font as part of the dialog-box template resource.

NOTE
You cannot override this method when you use a CFileDialog object in a program that is compiled under
Windows Vista or later operating systems. For more information about changes to CFileDialog under
Windows Vista and later, see CFileDialog Class.

CDialog::PrevDlgCtrl
Sets the focus to the previous control in the dialog box.

void PrevDlgCtrl() const;

Remarks
If the focus is at the first control in the dialog box, it moves to the last control in the box.

CDialog::SetDefID
Changes the default pushbutton control for a dialog box.

void SetDefID(UINT nID);

Parameters
nID
Specifies the ID of the pushbutton control that will become the default.

CDialog::SetHelpID
Sets a context-sensitive help ID for the dialog box.

void SetHelpID(UINT nIDR);

Parameters
nIDR
Specifies the context-sensitive help ID.

See also
MFC Sample DLGCBR32
MFC Sample DLGTEMPL
CWnd Class
Hierarchy Chart
CDialogBar Class
3/27/2020 • 2 minutes to read • Edit Online

Provides the functionality of a Windows modeless dialog box in a control bar.

Syntax
class CDialogBar : public CControlBar

Members
Public Constructors
NAME DESC RIP T IO N

CDialogBar::CDialogBar Constructs a CDialogBar object.

Public Methods
NAME DESC RIP T IO N

CDialogBar::Create Creates a Windows dialog bar and attaches it to the


CDialogBar object.

Remarks
A dialog bar resembles a dialog box in that it contains standard Windows controls that the user can tab between.
Another similarity is that you create a dialog template to represent the dialog bar.
Creating and using a dialog bar is similar to creating and using a CFormView object. First, use the dialog editor to
define a dialog template with the style WS_CHILD and no other style. The template must not have the style
WS_VISIBLE. In your application code, call the constructor to construct the CDialogBar object, then call Create
to create the dialog-bar window and attach it to the CDialogBar object.
For more information on CDialogBar , see the article Dialog Bars and Technical Note 31, Control Bars.

NOTE
In the current release, a CDialogBar object cannot host Windows Forms controls. For more information about Windows
Forms controls in Visual C++, see Using a Windows Form User Control in MFC.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CControlBar
CDialogBar

Requirements
Header : afxext.h

CDialogBar::CDialogBar
Constructs a CDialogBar object.

CDialogBar();

CDialogBar::Create
Loads the dialog-box resource template specified by lpszTemplateName or nIDTemplate , creates the dialog-bar
window, sets its style, and associates it with the CDialogBar object.

virtual BOOL Create(


CWnd* pParentWnd,
LPCTSTR lpszTemplateName,
UINT nStyle,
UINT nID);

virtual BOOL Create(


CWnd* pParentWnd,
UINT nIDTemplate,
UINT nStyle,
UINT nID);

Parameters
pParentWnd
A pointer to the parent CWnd object.
lpszTemplateName
A pointer to the name of the CDialogBar object's dialog-box resource template.
nStyle
The toolbar style. Additional toolbar styles supported are:
CBRS_TOP Control bar is at top of the frame window.
CBRS_BOTTOM Control bar is at bottom of the frame window.
CBRS_NOALIGN Control bar is not repositioned when the parent is resized.
CBRS_TOOLTIPS Control bar displays tool tips.
CBRS_SIZE_DYNAMIC Control bar is dynamic.
CBRS_SIZE_FIXED Control bar is fixed.
CBRS_FLOATING Control bar is floating.
CBRS_FLYBY Status bar displays information about the button.
CBRS_HIDE_INPLACE Control bar is not displayed to the user.
nID
The control ID of the dialog bar.
nIDTemplate
The resource ID of the CDialogBar object's dialog-box template.
Return Value
Nonzero if successful; otherwise 0.
Remarks
If you specify the CBRS_TOP or CBRS_BOTTOM alignment style, the dialog bar's width is that of the frame
window and its height is that of the resource specified by nIDTemplate. If you specify the CBRS_LEFT or
CBRS_RIGHT alignment style, the dialog bar's height is that of the frame window and its width is that of the
resource specified by nIDTemplate.
Example

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)


{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

EnableDocking(CBRS_ALIGN_ANY);

// m_wndDlgBar is a CDialogBar member of CMainFrame


// IDD_DIALOGBAR - Resource ID of the dialog
// template. This dialog template should be created
// with the style WS_CHILD and no other style.
// The template must not have the style WS_VISIBLE.
if (!m_wndDlgBar.Create(this, IDD_DIALOGBAR,
CBRS_LEFT | CBRS_TOOLTIPS | CBRS_FLYBY, IDD_DIALOGBAR))
{
TRACE0("Failed to create DlgBar\n");
return -1; // Fail to create.
}

return 0;
}

See also
MFC Sample CTRLBARS
CControlBar Class
Hierarchy Chart
CFormView Class
CControlBar Class
CDialogEx Class
4/21/2020 • 2 minutes to read • Edit Online

The CDialogEx class specifies the background color and background image of a dialog box.

Syntax
class CDialogEx : public CDialog

Members
Public Constructors
NAME DESC RIP T IO N

CDialogEx::CDialogEx Constructs a CDialogEx object.

CDialogEx::~CDialogEx Destructor.

Public Methods
NAME DESC RIP T IO N

CDialogEx::SetBackgroundColor Sets the background color of the dialog box.

CDialogEx::SetBackgroundImage Sets the background image of the dialog box.

Remarks
To use the CDialogEx class, derive your dialog box class from the CDialogEx class instead of the CDialog class.
Dialog box images are stored in a resource file. The framework automatically deletes any image that is loaded
from the resource file. To programmatically delete the current background image, call the
CDialogEx::SetBackgroundImage method or implement an OnDestroy event handler. When you call the
CDialogEx::SetBackgroundImage method, pass in an HBITMAP parameter as the image handle. The CDialogEx
object will take ownership of the image and delete it if the m_bAutoDestroyBmp flag is TRUE .
A CDialogEx object can be a parent of a CMFCPopupMenu Class object. The CMFCPopupMenu Class object calls
the CDialogEx::SetActiveMenu method when the CMFCPopupMenu Class object opens. Afterward, the CDialogEx
object handles any menu event until the CMFCPopupMenu Class object is closed.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CDialogEx

Requirements
Header : afxdialogex.h

CDialogEx::CDialogEx
Constructs a CDialogEx object.

CDialogEx(
UINT nIDTemplate,
CWnd* pParent=NULL);

CDialogEx(
LPCTSTR lpszTemplateName,
CWnd* pParentWnd=NULL);

Parameters
nIDTemplate
[in] The resource ID of a dialog box template.
lpszTemplateName
[in] The resource name of a dialog box template.
pParent
[in] A pointer to the parent window. The default value is NULL.
pParentWnd
[in] A pointer to the parent window. The default value is NULL.
Return Value
Remarks

CDialogEx::SetBackgroundColor
Sets the background color of the dialog box.

void SetBackgroundColor(
COLORREF color,
BOOL bRepaint=TRUE);

Parameters
color
[in] An RGB color value.
bRepaint
[in] TRUE to immediately update the screen; otherwise, FALSE. The default value is TRUE.
Remarks

CDialogEx::SetBackgroundImage
Sets the background image of the dialog box.
void SetBackgroundImage(
HBITMAP hBitmap,
BackgroundLocation location=BACKGR_TILE,
BOOL bAutoDestroy=TRUE,
BOOL bRepaint=TRUE);

BOOL SetBackgroundImage(
UINT uiBmpResId,
BackgroundLocation location=BACKGR_TILE,
BOOL bRepaint=TRUE);

Parameters
hBitmap
[in] A handle to the background image.
uiBmpResId
[in] The resource ID of the background image.
location
[in] One of the CDialogEx::BackgroundLocation values that specify the location of the image. Valid values include
BACKGR_TILE, BACKGR_TOPLEFT, BACKGR_TOPRIGHT, BACKGR_BOTTOMLEFT, and BACKGR_BOTTOMRIGHT. The
default value is BACKGR_TILE.
bAutoDestroy
[in] TRUE to automatically destroy the background image; otherwise, FALSE.
bRepaint
[in] TRUE to immediately redraw the dialog box; otherwise, FALSE.
Return Value
In the second method overload syntax, TRUE if the method is successful; otherwise, FALSE.
Remarks
The image that you specify is not stretched to fit the dialog box client area.

See also
Hierarchy Chart
Classes
CMFCPopupMenu Class
CContextMenuManager Class
CDiscreteTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates a discrete transition.

Syntax
class CDiscreteTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CDiscreteTransition::CDiscreteTransition Constructs a discrete transition object and initializes its


parameters.

Public Methods
NAME DESC RIP T IO N

CDiscreteTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CDiscreteTransition::m_dblFinalValue The value of the animation variable at the end of the


transition.

CDiscreteTransition::m_delay The amount of time by which to delay the instantaneous


switch to the final value.

CDiscreteTransition::m_hold The amount of time by which to hold the variable at its final
value.

Remarks
During a discrete transition, the animation variable remains at the initial value for a specified delay time, then
switches instantaneously to a specified final value and remains at that value for a given hold time. Because all
transitions are cleared automatically, it's recommended to allocated them using operator new. The encapsulated
IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then it's NULL.
Changing member variables after creation of this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CDiscreteTransition

Requirements
Header : afxanimationcontroller.h

CDiscreteTransition::CDiscreteTransition
Constructs a discrete transition object and initializes its parameters.

CDiscreteTransition(
UI_ANIMATION_SECONDS delay,
DOUBLE dblFinalValue,
UI_ANIMATION_SECONDS hold);

Parameters
delay
The amount of time by which to delay the instantaneous switch to the final value.
dblFinalValue
The value of the animation variable at the end of the transition.
hold
The amount of time by which to hold the variable at its final value.

CDiscreteTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CDiscreteTransition::m_dblFinalValue
The value of the animation variable at the end of the transition.

DOUBLE m_dblFinalValue;

CDiscreteTransition::m_delay
The amount of time by which to delay the instantaneous switch to the final value.

UI_ANIMATION_SECONDS m_delay;
CDiscreteTransition::m_hold
The amount of time by which to hold the variable at its final value.

UI_ANIMATION_SECONDS m_hold;

See also
Classes
CDocItem Class
3/27/2020 • 2 minutes to read • Edit Online

The base class for document items, which are components of a document's data.

Syntax
class CDocItem : public CCmdTarget

Members
Public Methods
NAME DESC RIP T IO N

CDocItem::GetDocument Returns the document that contains the item.

CDocItem::IsBlank Determines whether the item contains any information.

Remarks
CDocItem objects are used to represent OLE items in both client and server documents.
For more information, see the article Containers: Implementing a Container.

Inheritance Hierarchy
CObject
CCmdTarget
CDocItem

Requirements
Header : afxole.h

CDocItem::GetDocument
Call this function to get the document that contains the item.

CDocument* GetDocument() const;

Return Value
A pointer to the document that contains the item; NULL, if the item is not part of a document.
Remarks
This function is overridden in the derived classes COleClientItem and COleServerItem, returning a pointer to
either a COleDocument, a COleLinkingDoc, or a COleServerDoc object.
CDocItem::IsBlank
Called by the framework when default serialization occurs.

virtual BOOL IsBlank() const;

Return Value
Nonzero if the item contains no information; otherwise 0.
Remarks
By default, CDocItem objects are not blank. COleClientItem objects are sometimes blank because they derive
directly from CDocItem . However, COleServerItem objects are always blank. By default, OLE applications
containing COleClientItem objects that have no x or y extent are serialized. This is done by returning TRUE from
an override of IsBlank when the item has no x or y extent.
Override this function if you want to implement other actions during serialization.

See also
CCmdTarget Class
Hierarchy Chart
COleDocument Class
COleServerItem Class
COleClientItem Class
CDockablePane Class
4/21/2020 • 33 minutes to read • Edit Online

Implements a pane that can either be docked in a dock site or included in a tabbed pane.

Syntax
class CDockablePane : public CPane

Members
Public Constructors
NAME DESC RIP T IO N

CDockablePane::CDockablePane Constructs and initializes a CDockablePane object.

Public Methods
NAME DESC RIP T IO N

CDockablePane::AttachToTabWnd Attaches a pane to another pane. This creates a tabbed


pane.

CDockablePane::CalcFixedLayout Returns the size of the pane rectangle.

CDockablePane::CanAcceptMiniFrame Determines whether the specified mini frame can be


docked to the pane.

CDockablePane::CanAcceptPane Determines whether another pane can be docked to the


current pane.

CDockablePane::CanAutoHide Determines whether the pane supports auto-hide mode.


(Overrides CBasePane::CanAutoHide.)

CDockablePane::CanBeAttached Determines whether the current pane can be docked to


another pane.

CDockablePane::ConvertToTabbedDocument Converts one or more dockable panes to MDI tabbed


documents.

CDockablePane::CopyState Copies the state of a dockable pane.

CDockablePane::Create Creates the Windows control and attaches it to the


CDockablePane object.

CDockablePane::CreateDefaultPaneDivider Creates a default divider for the pane as it is being


docked to a frame window.
NAME DESC RIP T IO N

CDockablePane::CreateEx Creates the Windows control and attaches it to the


CDockablePane object.

CDockablePane::CreateTabbedPane Creates a tabbed pane from the current pane.

CDockablePane::DockPaneContainer Docks a container to the pane.

CDockablePane::DockPaneStandard Docks a pane by using outline (standard) docking.

CDockablePane::DockToFrameWindow Used internally. To dock a pane, use CPane::DockPane or


CDockablePane::DockToWindow.

CDockablePane::DockToRecentPos Docks a pane to its stored recent docking position.

CDockablePane::DockToWindow Docks one docking pane to another docking pane.

CDockablePane::EnableAutohideAll Enables or disables auto-hide mode for this pane


together with other panes in the container.

CDockablePane::EnableGripper Shows or hides the caption (gripper).

CDockablePane::GetAHRestoredRect Specifies the position of the pane when visible in auto-


hide mode.

CDockablePane::GetAHSlideMode Retrieves the auto hide slide mode for the pane.

CDockablePane::GetAutoHideButton Used internally.

CDockablePane::GetAutoHideToolBar Used internally.

CDockablePane::GetCaptionHeight Returns the height of the current caption.

CDockablePane::GetDefaultPaneDivider Returns the default pane divider for the pane's container.

CDockablePane::GetDockingStatus Determines the ability of a pane to be docked based on


the provided pointer location.

CDockablePane::GetDragSensitivity Returns the drag sensitivity of a docking pane.

CDockablePane::GetLastPercentInPaneContainer Retrieves the percentage of space that a pane occupies


within its container.

CDockablePane::GetTabArea Retrieves the tab area for the pane.

CDockablePane::GetTabbedPaneRTC Returns the runtime class information about a tabbed


window that is created when another pane docks to the
current pane.

CDockablePane::HasAutoHideMode Specifies whether a docking pane can be switched to


auto-hide mode.
NAME DESC RIP T IO N

CDockablePane::HitTest Specifies the specific location in a pane where the user


clicks a mouse.

CDockablePane::IsAccessibilityCompatible Used internally.

CDockablePane::IsAutohideAllEnabled Indicates whether the docking pane and all other panes
in the container can be placed in auto-hide mode.

CDockablePane::IsAutoHideMode Determines whether a pane is in auto-hide mode.

CDockablePane::IsChangeState Used internally.

CDockablePane::IsDocked Determines whether the current pane is docked.

CDockablePane::IsHideInAutoHideMode Determines the behavior of a pane that is in auto-hide


mode if it is shown (or hidden) by calling ShowPane .

CDockablePane::IsInFloatingMultiPaneFrameWnd Specifies whether the pane is in a multi-pane frame


window.

CDockablePane::IsResizable Specifies whether the pane is resizable.

CDockablePane::IsTabLocationBottom Specifies whether tabs are located at the top or bottom


of the pane.

CDockablePane::IsTracked Specifies whether a pane is being dragged by the user.

CDockablePane::IsVisible Determines whether the current pane is visible.

CDockablePane::LoadState Used internally.

CDockablePane::OnAfterChangeParent Called by the framework when the parent of a pane has


changed. (Overrides CPane::OnAfterChangeParent.)

CDockablePane::OnAfterDockFromMiniFrame Called by the framework when a floating docking bar


docks at a frame window.

CDockablePane::OnBeforeChangeParent Called by the framework when the parent of the pane is


about to change. (Overrides
CPane::OnBeforeChangeParent.)

CDockablePane::OnBeforeFloat Called by the framework when a pane is about to float.


(Overrides CPane::OnBeforeFloat.)

CDockablePane::RemoveFromDefaultPaneDividier The framework calls this method when a pane is being


undocked.

CDockablePane::ReplacePane Replaces the pane with a specified pane.

CDockablePane::RestoreDefaultPaneDivider The framework calls this method as a pane is deserialized


to restore the default pane divider.
NAME DESC RIP T IO N

CDockablePane::SaveState Used internally.

CDockablePane::Serialize Serializes the pane. (Overrides CBasePane::Serialize .)

CDockablePane::SetAutoHideMode Toggles the docking pane between visible and auto-hide


mode.

CDockablePane::SetAutoHideParents Sets the auto-hide button and auto-hide toolbar for the
pane.

CDockablePane::SetDefaultPaneDivider Used internally.

CDockablePane::SetLastPercentInPaneContainer Sets the percentage of space that a pane occupies within


its container.

CDockablePane::SetResizeMode Used internally.

CDockablePane::SetRestoredDefaultPaneDivider Sets the restored default pane divider.

CDockablePane::SetTabbedPaneRTC Sets the runtime class information for a tabbed window


that is created when two panes dock together.

CDockablePane::ShowPane Shows or hides a pane.

CDockablePane::Slide Shows or hides a pane with a sliding animation which


displays only when the pane is in auto-hide mode.

CDockablePane::ToggleAutoHide Toggles auto-hide mode. (Overrides


CPane::ToggleAutoHide .)

CDockablePane::UndockPane Undocks a pane from either the main frame window or a


miniframe window container.

CDockablePane::UnSetAutoHideMode Used internally. To set the auto-hide mode, use


CDockablePane::SetAutoHideMode

Protected Methods
NAME DESC RIP T IO N

CDockablePane::CheckAutoHideCondition Determines whether the docking pane is hidden (in auto-


hide mode).

CDockablePane::CheckStopSlideCondition Determines when an auto-hide docking pane should stop


sliding.

CDockablePane::DrawCaption Draws the docking pane caption (gripper).

CDockablePane::OnPressButtons Called when the user presses a caption button other than
the AFX_HTCLOSE and AFX_HTMAXBUTTON buttons.
NAME DESC RIP T IO N

CDockablePane::OnSlide Called by the framework to render the auto-hide slide


effect when the pane is either shown or hidden.

Data Members
NAME DESC RIP T IO N

CDockablePane::m_bDisableAnimation Specifies whether auto-hide animation of the dockable


pane is disabled.

CDockablePane::m_bHideInAutoHideMode Determines the behavior of the pane when the pane is in


auto-hide mode.

CDockablePane::m_nSlideSteps Specifies the animation speed of the pane when it is


being shown or hidden when in auto-hide mode.

Remarks
CDockablePane implements the following functionality:
Docking a pane to a main frame window.
Switching a pane to auto-hide mode.
Attaching a pane to a tabbed window.
Floating a pane in a miniframe window.
Docking a pane to another pane that is floating in a miniframe window.
Resizing a pane.
Loading and saving state for a docking pane.

NOTE
State information is saved to the Windows registry.

Creating a pane with or without a caption. The caption can have a text label and it can be filled with
a gradient color.
Dragging a pane while displaying the contents of the pane
Dragging a pane while displaying a drag rectangle.
To use a docking pane in your application, derive your pane class from the CDockablePane class. Either
embed the derived object into the main frame window object or into a window object that controls the
instance of your pane. Then call the CDockablePane::Create method or the CDockablePane::CreateEx
method when you process the WM_CREATE message in the main frame window. Finally, set up the pane
object by calling CBasePane::EnableDocking, CBasePane::DockPane, or CDockablePane::AttachToTabWnd.

Customization Tips
The following tips apply to CDockablePane objects:
If you call CDockablePane::AttachToTabWnd for two non-tabbed, dockable panes, a pointer to a
tabbed window will be returned in the ppTabbedControlBar parameter. You can continue to add
tabs to the tabbed window by using this parameter.
The kind of tabbed pane that is created by CDockablePane::AttachToTabWnd is determined by the
CDockablePane object in the pTabControlBarAttachTo parameter. You can call
CDockablePane::SetTabbedPaneRTC to set the kind of tabbed pane that the CDockablePane will
create. The default type is determined by the dwTabbedStyle of CDockablePane::Create when you
first create the CDockablePane . If dwTabbedStyle is AFX_CBRS_OUTLOOK_TABS the default type is
CMFCOutlookBar Class; if dwTabbedStyle is AFX_CBRS_REGULAR_TABS the default type is
CTabbedPane Class.
If you want to dock one dockable pane to another, call the CDockablePane::DockToWindow method.
The original pane must be docked somewhere before you call this method.
The member variable CDockablePane::m_bHideInAutoHideMode controls how dockable panes
behave in auto hide mode when you call CDockablePane::ShowPane. If this member variable is set
to TRUE, dockable panes and their auto hide buttons will be hidden. Otherwise, they will slide in
and out.
You can disable auto-hide animation by setting the CDockablePane::m_bDisableAnimation member
variable to TRUE.

Example
The following example demonstrates how to configure a CDockablePane object by using various methods
in the CDockablePane class. The example illustrates how to enable the auto-hide all feature for the
dockable pane, enable the caption or the gripper, enable the auto-hide mode, show the pane, and animate
a pane that is in auto-hide mode. This code snippet is part of the Visual Studio Demo sample.

// GetOwner is an inherited method.


CDockablePane *pParentBar = DYNAMIC_DOWNCAST(CDockablePane, GetOwner());

pParentBar->EnableAutohideAll();
pParentBar->EnableGripper(true);
pParentBar->SetAutoHideMode(true, CBRS_ALIGN_LEFT);
pParentBar->ShowPane(true, false, true);
pParentBar->Slide(true);

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CBasePane
CPane
CDockablePane

Requirements
Header : afxDockablePane.h
CDockablePane::AttachToTabWnd
Attaches the current pane to a target pane, creating a tabbed pane.

virtual CDockablePane* AttachToTabWnd(


CDockablePane* pTabControlBarAttachTo,
AFX_DOCK_METHOD dockMethod,
BOOL bSetActive= TRUE,
CDockablePane** ppTabbedControlBar = NULL);

Parameters
pTabControlBarAttachTo
[in, out] Specifies the target pane that the current pane attaches to. The target pane must be a dockable
pane.
dockMethod
[in] Specifies the docking method.
bSetActive
[in] TRUE to activate the tabbed pane after the attach operation; otherwise, FALSE.
ppTabbedControlBar
[out] Contains the tabbed pane that results from the attach operation.
Return Value
A pointer to the current pane, if it is not a tabbed pane; otherwise a pointer to the tabbed pane that results
from the attach operation. The return value is NULL if the current pane cannot be attached, or if an error
occurs.
Remarks
When one dockable pane attaches to another pane using this method, the following occurs:
1. The framework checks whether the target pane pTabControlBarAttachTo is a regular docking pane
or if it is derived from CBaseTabbedPane.
2. If the target pane is a tabbed pane, the framework adds the current pane to it as a tab.
3. If the target pane is a regular docking pane, the framework creates a tabbed pane.
The framework calls pTabControlBarAttachTo->CreateTabbedPane . The style of the new tabbed
pane depends on the m_pTabbedControlBarRTC member. By default, this member is set to the
runtime class of CTabbedPane. If you pass the AFX_CBRS_OUTLOOK_TABS style as the
dwTabbedStyle parameter to the CDockablePane::Create method, the runtime class object is
set to the runtime class of CMFCOutlookBar. You can change this member at any time to
change the style of the new pane.
When this method creates a tabbed pane, the framework replaces the pointer to
pTabControlBarAttachTo (if the pane is docked or floating in a multi-miniframe window) with
a pointer to the new tabbed pane.
The framework adds the pTabControlBarAttachTo pane to the tabbed pane as the first tab.
The framework then adds the current pane as a second tab.
4. If the current pane is derived from CBaseTabbedPane , all of its tabs are moved to
pTabControlBarAttachTo and the current pane is destroyed. Therefore, be careful when you call this
method, because a pointer to the current pane may be invalid when the method returns.
If you attach one pane to another when building a docking layout, set dockMethod to DM_SHOW.
You should dock the first pane before you attach another pane to it.

CDockablePane::CalcFixedLayout
Returns the size of the pane rectangle.

virtual CSize CalcFixedLayout(


BOOL bStretch,
BOOL bHorz);

Parameters
bStretch
[in] Not used.
bHorz
[in] Not used.
Return Value
A CSize object that contains the size of the pane rectangle.

CDockablePane::CanAcceptMiniFrame
Determines whether the specified mini-frame can be docked to the pane.

virtual BOOL CanAcceptMiniFrame(CPaneFrameWnd* pMiniFrame) const;

Parameters
pMiniFrame
[in] Pointer to a CPaneFrameWnd object.
Return Value
TRUE if pMiniFrame can be docked to the pane; otherwise, FALSE.

CDockablePane::CanAcceptPane
Determines whether another pane can be docked to the current pane.

virtual BOOL CanAcceptPane(const CBasePane* pBar) const;

Parameters
pBar
[in] Specifies the pane to dock to the current pane.
Return Value
TRUE if the specified pane can be docked to this pane; otherwise, FALSE.
Remarks
The framework calls this method before a pane is docked to the current pane.
Override this function in a derived class to enable or disable docking to a specific pane.
By default, this method returns TRUE if either pBar or its parent is of type CDockablePane .

CDockablePane::CanAutoHide
Determines whether the pane can auto-hide.

virtual BOOL CanAutoHide() const;

Return Value
TRUE if the pane can auto-hide; otherwise, FALSE.
Remarks
CDockablePane::CanAutoHide returns FALSE in any of the following situations:
The pane has no parent.
The docking manager does not allow panes to auto-hide.
The pane is not docked.

CDockablePane::CanBeAttached
Determines whether the current pane can be docked to another pane.

virtual BOOL CanBeAttached() const;

Return Value
TRUE if the dockable pane can be docked to another pane or to the main frame window; otherwise, FALSE.
Remarks
By default, this method always returns TRUE. Override this method in a derived class to enable or disable
docking without calling CBasePane::EnableDocking.

CDockablePane::CDockablePane
Constructs and initializes a CDockablePane object.

CDockablePane();

Remarks
After you construct a dockable pane object, call CDockablePane::Create or CDockablePane::CreateEx to
create it.

CDockablePane::ConvertToTabbedDocument
Converts one or more dockable panes to MDI tabbed documents.

virtual void ConvertToTabbedDocument(BOOL bActiveTabOnly = TRUE);

Parameters
bActiveTabOnly
[in] When you convert a CTabbedPane , specify TRUE to convert only the active tab. Specify FALSE to
convert all tabs in the pane.

CDockablePane::CheckAutoHideCondition
Determines whether the docking pane is hidden (also known as autohide mode).

virtual BOOL CheckAutoHideCondition();

Return Value
TRUE if the hide condition is met; otherwise, FALSE.
Remarks
The framework uses a timer to periodically check whether to hide an autohide dockable pane. The method
returns TRUE when the pane is not active, the pane is not being resized, and the mouse pointer is not over
the pane.
If all the previous conditions are met, the framework calls CDockablePane::Slide to hide the pane.

CDockablePane::CheckStopSlideCondition
Determines when an autohide docking pane should stop sliding.

virtual BOOL CheckStopSlideCondition(BOOL bDirection);

Parameters
bDirection
[in] TRUE if the pane is visible; FALSE if the pane is hidden.
Return Value
TRUE if the stop condition is met; otherwise, FALSE.
Remarks
When a dockable pane is set to autohide mode, the framework uses sliding effects to show or hide the
pane. The framework calls this function when the pane is sliding. CheckStopSlideCondition returns TRUE
when the pane is fully visible or when it is fully hidden.
Override this method in a derived class to implement custom autohide effects.

CDockablePane::CopyState
Copies the state of a dockable pane.

virtual void CopyState(CDockablePane* pOrgBar);

Parameters
pOrgBar
[in] A pointer to a dockable pane.
Remarks
CDockablePane::CopyState copies the state of pOrgBar to the current pane by calling the following
methods:
CPane::CopyState
CDockablePane::GetAHRestoredRect
CDockablePane::GetAHSlideMode
CDockablePane::GetLastPercentInPaneContainer
CDockablePane::IsAutohideAllEnabled

CDockablePane::Create
Creates the Windows control and attaches it to the CDockablePane object.

virtual BOOL Create(


LPCTSTR lpszCaption,
CWnd* pParentWnd,
const RECT& rect,
BOOL bHasGripper,
UINT nID,
DWORD dwStyle,
DWORD dwTabbedStyle = AFX_CBRS_REGULAR_TABS,
DWORD dwControlBarStyle = AFX_DEFAULT_DOCKING_PANE_STYLE,
CCreateContext* pContext = NULL);

virtual BOOL Create(


LPCTSTR lpszWindowName,
CWnd* pParentWnd,
CSize sizeDefault,
BOOL bHasGripper,
UINT nID,
DWORD dwStyle = WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_HIDE_INPLACE,
DWORD dwTabbedStyle = AFX_CBRS_REGULAR_TABS,
DWORD dwControlBarStyle = AFX_DEFAULT_DOCKING_PANE_STYLE);

Parameters
lpszCaption
[in] Specifies the window name.
pParentWnd
[in, out] Specifies the parent window.
rect
[in] Specifies the size and position of the window, in client coordinates of pParentWnd.
bHasGripper
[in] TRUE to create the pane with a caption; otherwise, FALSE.
nID
[in] Specifies the ID of the child window. This value must be unique if you want to save docking state for
this docking pane.
dwStyle
[in] Specifies the window style attributes.
dwTabbedStyle
[in] Specifies the tabbed style of a tabbed window that is created when the user drags a pane on the
caption of this pane.
dwControlBarStyle
[in] Specifies additional style attributes.
pContext
[in, out] Specifies the create context of the window.
lpszWindowName
[in] Specifies the window name.
sizeDefault
[in] Specifies the size of the window.
Return Value
TRUE if the dockable pane is successfully created; otherwise, FALSE.
Remarks
Creates a Windows pane and attaches it to the CDockablePane object.
If the dwStyle window style has the CBRS_FLOAT_MULTI flag, the miniframe window can float with other
panes in the miniframe window. By default, docking panes can only float individually.
If the dwTabbedStyle parameter has the AFX_CBRS_OUTLOOK_TABS flag specified, the pane creates
Outlook-style tabbed panes when another pane is attached to this pane using the
CDockablePane::AttachToTabWnd method. By default, dockable panes create regular tabbed panes of type
CTabbedPane.

CDockablePane::CreateDefaultPaneDivider
Creates a default divider for the pane as it is being docked to a frame window.

static CPaneDivider* __stdcall CreateDefaultPaneDivider(


DWORD dwAlignment,
CWnd* pParent,
CRuntimeClass* pSliderRTC = NULL);

Parameters
dwAlignment
[in] Specifies the side of the main frame to which the pane is being docked. If dwAlignment contains the
CBRS_ALIGN_LEFT or CBRS_ALIGN_RIGHT flag, this method creates a vertical ( CPaneDivider::SS_VERT )
divider; otherwise, this method creates a horizontal ( CPaneDivider::SS_HORZ ) divider.
pParent
[in] Pointer to the parent frame.
pSliderRTC
[in] Not used.
Return Value
This method returns a pointer to the newly-created divider, or NULL if divider creation fails.
Remarks
dwAlignment can be any of the following values:

VA L UE DESC RIP T IO N

CBRS_ALIGN_TOP The pane is being docked to the top of the client area of
a frame window.

CBRS_ALIGN_BOTTOM The pane is being docked to the bottom of the client area
of a frame window.
VA L UE DESC RIP T IO N

CBRS_ALIGN_LEFT The pane is being docked to the left side of the client
area of a frame window.

CBRS_ALIGN_RIGHT The pane is being docked to the right side of the client
area of a frame window.

CDockablePane::CreateEx
Creates the Windows control and attaches it to the CDockablePane object.

virtual BOOL CreateEx(


DWORD dwStyleEx,
LPCTSTR lpszCaption,
CWnd* pParentWnd,
const RECT& rect,
BOOL bHasGripper,
UINT nID,
DWORD dwStyle,
DWORD dwTabbedStyle = AFX_CBRS_REGULAR_TABS,
DWORD dwControlBarStyle = AFX_DEFAULT_DOCKING_PANE_STYLE,
CCreateContext* pContext = NULL);

Parameters
dwStyleEx
[in] Specifies the extended style attributes for the new window.
lpszCaption
[in] Specifies the window name.
pParentWnd
[in, out] Specifies the parent window.
rect
[in] Specifies the size and position of the window, in client coordinates of pParentWnd.
bHasGripper
[in] TRUE to create the pane with a caption; otherwise, FALSE.
nID
[in] Specifies the ID of the child window. This value must be unique if you want to save the docking state
for this docking pane.
dwStyle
[in] Specifies the window style attributes.
dwTabbedStyle
[in] Specifies the tabbed style of a tabbed window that is created when the user drags a pane on the
caption of this pane.
dwControlBarStyle
[in] Specifies the additional style attributes.
pContext
[in, out] Specifies the create context of the window.
Return Value
TRUE if the dockable pane is successfully created; otherwise, FALSE.
Remarks
Creates a Windows pane and attaches it to the CDockablePane object.
If the dwStyle window style has the CBRS_FLOAT_MULTI flag, the miniframe window can float with other
panes in the miniframe window. By default, docking panes can only float individually.
If the dwTabbedStyle parameter has the AFX_CBRS_OUTLOOK_TABS flag specified, the pane creates
Outlook-style tabbed panes when another pane is attached to this pane using the
CDockablePane::AttachToTabWnd method. By default, dockable panes create regular tabbed panes of type
CTabbedPane.

CDockablePane::CreateTabbedPane
Creates a tabbed pane from the current pane.

virtual CTabbedPane* CreateTabbedPane();

Return Value
The new tabbed pane, or NULL if the create operation failed.
Remarks
The framework calls this method when it creates a tabbed pane to replace this pane. For more
information, see CDockablePane::AttachToTabWnd.
Override this method in a derived class to customize how tabbed panes are created and initialized.
The tabbed pane is created according to the runtime class information stored in the
m_pTabbedControlBarRTC member, which is initialized by the CDockablePane::CreateEx method.

CDockablePane::DockPaneContainer
Docks a container to the pane.

virtual BOOL DockPaneContainer(


CPaneContainerManager& barContainerManager,
DWORD dwAlignment,
AFX_DOCK_METHOD dockMethod);

Parameters
barContainerManager
[in] A reference to the container manager of the container that is being docked.
dwAlignment
[in] DWORD that specifies the side of the pane to which the container is being docked.
dockMethod
[in] Not used.
Return Value
TRUE if the container was successfully docked to the pane; otherwise, FALSE.
Remarks
dwAlignment can be any of the following values:
VA L UE DESC RIP T IO N

CBRS_ALIGN_TOP The container is being docked to the top of the pane.

CBRS_ALIGN_BOTTOM The container is being docked to the bottom of the pane.

CBRS_ALIGN_LEFT The container is being docked to the left of the pane.

CBRS_ALIGN_RIGHT The container is being docked to the right of the pane.

CDockablePane::DockPaneStandard
Docks a pane by using outline (standard) docking.

virtual CPane* DockPaneStandard(BOOL& bWasDocked);

Parameters
bWasDocked
[in] When the method returns, this value contains TRUE if the pane was successfully docked; otherwise, it
contains FALSE.
Return Value
If the pane was docked to a tabbed window, or if a tabbed window was created as a result of docking, this
method returns a pointer to the tabbed window. If the pane was otherwise successfully docked, this
method returns the this pointer. If docking failed, this method returns NULL.

CDockablePane::DockToRecentPos
Docks a pane to its stored docking position.

BOOL CDockablePane::DockToRecentPos();

Return Value
TRUE if the pane is successfully docked; otherwise, FALSE.
Remarks
Dockable panes store recent docking information in a CRecentDockSiteInfo object.

CDockablePane::DockToWindow
Docks one docking pane to another docking pane.

virtual BOOL DockToWindow(


CDockablePane* pTargetWindow,
DWORD dwAlignment,
LPCRECT lpRect = NULL);

Parameters
pTargetWindow
[in, out] Specifies the dockable pane to dock this pane to.
dwAlignment
[in] Specifies the docking alignment for the pane. May be one of CBRS_ALIGN_LEFT, CBRS_ALIGN_TOP,
CBRS_ALIGN_RIGHT, CBRS_ALIGN_BOTTOM or CBRS_ALIGN_ANY. (Defined in afxres.h.)
lpRect
[in] Specifies the docking rectangle for the pane.
Return Value
TRUE if the pane was docked successfully; otherwise, FALSE.
Remarks
Call this method to dock one pane to another pane with the alignment specified by dwAlignment.

CDockablePane::DrawCaption
Draws the caption (also called the gripper) of a docking pane.

virtual void DrawCaption(


CDC* pDC,
CRect rectCaption);

Parameters
pDC
[in] Represents the device context used for drawing.
rectCaption
[in] Specifies the bounding rectangle of the pane's caption.
Remarks
The framework calls this method to draw the caption of a dockable pane.
Override this method in a derived class to customize the appearance of the caption.

CDockablePane::EnableAutohideAll
Enables or disables autohide mode for this pane and for other panes in the container.

void EnableAutohideAll(BOOL bEnable = TRUE);

Parameters
bEnable
[in] TRUE to enable the autohide all feature for the dockable pane; otherwise, FALSE.
Remarks
When a user holds the Ctrl key and clicks the pin button to switch a pane to autohide mode, all other
panes in the same container are also switched to autohide mode.
Call this method with bEnable set to FALSE to disable this feature for a particular pane.

CDockablePane::EnableGripper
Shows or hides the caption (also called the gripper).

virtual void EnableGripper(BOOL bEnable);


Parameters
bEnable
[in] TRUE to enable the caption; otherwise, FALSE.
Remarks
When the framework creates dockable panes, they do not have the WS_STYLE window style, even if
specified. This means that the pane's caption is a non-client area that is controlled by the framework, but
this area differs from the standard window caption.
You can show or hide the caption at any time. The framework hides the caption when a pane is added as a
tab to a tabbed window or when a pane is floated in a miniframe window.

CDockablePane::GetAHRestoredRect
Specifies the position of the pane when in auto-hide mode.

CRect GetAHRestoredRect() const;

Return Value
A CRect object that contains the position of the pane when it is in auto-hide mode.
Remarks

CDockablePane::GetAHSlideMode
Retrieves the auto-hide slide mode for the pane.

virtual UINT GetAHSlideMode() const;

Return Value
A UINT that specifies the auto-hide slide mode for the pane. The return value can be either
AFX_AHSM_MOVE or AFX_AHSM_STRETCH, but the implementation only uses AFX_AHSM_MOVE.
Remarks

CDockablePane::GetCaptionHeight
Returns the height, in pixels, of the current caption.

virtual int GetCaptionHeight() const;

Return Value
The height of the caption, in pixels.
Remarks
The caption height is 0 if the caption was hidden by the CDockablePane::EnableGripper method, or if the
pane does not have a caption.

CDockablePane::GetDefaultPaneDivider
Returns the default pane divider for the pane's container.
CPaneDivider* GetDefaultPaneDivider() const;

Return Value
A valid CPaneDivider object if the dockable pane is docked to the main frame window, or NULL if the
dockable pane is not docked or if it is floating.
Remarks
For more information about pane dividers, see CPaneDivider Class.

CDockablePane::GetDockingStatus
Determines the ability of a pane to be docked based on the provided pointer location.

virtual AFX_CS_STATUS GetDockingStatus(


CPoint pt,
int nSensitivity);

Parameters
pt
[in] The location of the pointer in screen coordinates.
nSensitivity
[in] The distance, in pixels, away from the edge of a rectangle the pointer must be to enable docking.
Return Value
One of the following status values:

A F X_C S_STAT US VA L UE M EA N IN G

CS_NOTHING The pointer is not over a dock site. The framework does
not dock the pane.

CS_DOCK_IMMEDIATELY The pointer is located over the dock site in immediate


mode (the pane uses the DT_IMMEDIATE docking mode).
The framework docks the pane immediately.

CS_DELAY_DOCK The pointer is over a dock site that is another docking


pane or is an edge of the main frame. The framework
docks the pane after a delay. See the Remarks section for
more information about this delay.

CS_DELAY_DOCK_TO_TAB The pointer is located over a dock site that causes the
pane to be docked in a tabbed window. This occurs when
the pointer is located over the caption of another
docking pane or over the tab area of a tabbed pane.

Remarks
The framework calls this method to handle docking of a floating pane.
For floating toolbars or docking panes that use the DT_IMMEDIATE docking mode, the framework delays
the dock command to enable the user to move the window out of the client area of the parent frame
before docking occurs. The length of the delay is measured in milliseconds and is controlled by the
CDockingManager::m_nTimeOutBeforeToolBarDock data member.. The default value of
CDockingManager::m_nTimeOutBeforeToolBarDock is 200. This behavior emulates the docking behavior
of Microsoft Word 2007.
For delayed docking states (CS_DELAY_DOCK and CS_DELAY_DOCK_TO_TAB), the framework does not
perform docking until the user releases the mouse button. If a pane uses the DT_STANDARD docking
mode, the framework displays a rectangle at the projected docking location. If a pane uses the DT_SMART
docking mode, the framework displays smart docking markers and semi-transparent rectangles at the
projected docking location. To specify the docking mode for your pane, call the
CBasePane::SetDockingMode method. For more information about smart docking, see
CDockingManager::GetSmartDockingParams.

CDockablePane::GetDragSensitivity
Returns the drag sensitivity of a docking pane.

static const CSize& GetDragSensitivity();

Return Value
A CSize object that contains the width and height, in pixels, of a rectangle centered on a drag point. The
drag operation does not begin until the mouse pointer moves outside this rectangle.

CDockablePane::GetLastPercentInPaneContainer
Retrieves the percentage of space that a pane occupies in its container ( CPaneContainer Class).

int GetLastPercentInPaneContainer() const;

Return Value
An int that specifies the percentage of space that the pane occupies in its container.
Remarks
This method is used when the container adjusts its layout.

CDockablePane::GetTabArea
Retrieves the tab area for the pane.

virtual void GetTabArea(


CRect& rectTabAreaTop,
CRect& rectTabAreaBottom) const;

Parameters
rectTabAreaTop
[in] GetTabArea fills this variable with the tab area if tabs are located at the top of the pane. If tabs are
located at the bottom of the pane, this variable is filled with an empty rectangle.
rectTabAreaBottom
[in] GetTabArea fills this variable with the tab area if tabs are located at the bottom of the pane. If tabs are
located at the top of the pane, this variable is filled with an empty rectangle.
Remarks
This method is used only in classes that are derived from CDockablePane and have tabs. For more
information, see CTabbedPane::GetTabArea and CMFCOutlookBar::GetTabArea.
CDockablePane::GetTabbedPaneRTC
Returns the runtime class information about a tabbed window that is created when another pane docks to
the current pane.

CRuntimeClass* GetTabbedPaneRTC() const;

Return Value
The runtime class information for the dockable pane.
Remarks
Call this method to retrieve the runtime class information for tabbed panes that are created dynamically.
This can occur when a user drags one pane to the caption of another pane, or if you call the
CDockablePane::AttachToTabWnd method to programmatically create a tabbed pane from two dockable
panes.
You can set the runtime class information by calling the CDockablePane::SetTabbedPaneRTC method.

CDockablePane::HasAutoHideMode
Specifies whether a docking pane can be switched to autohide mode.

virtual BOOL HasAutoHideMode() const;

Return Value
TRUE if the dockable pane can be switched to autohide mode; otherwise, FALSE.
Remarks
Override this method in a derived class to disable autohide mode for a specific dockable pane.

CDockablePane::HitTest
Specifies the location in a pane where the user clicks a mouse.

virtual int HitTest(


CPoint point,
BOOL bDetectCaption = FALSE);

Parameters
point
[in] Specifies the point to test.
bDetectCaption
[in] TRUE if HTCAPTION should be returned if the point is on the pane's caption; otherwise, FALSE.
Return Value
One of the following values:
HTNOWHERE if point is not in the dockable pane.
HTCLIENT if point is in the client area of the dockable pane.
HTCAPTION if point is in the caption area of the dockable pane.
AFX_HTCLOSE if point is on the close button.
HTMAXBUTTON if point is on the pin button.

CDockablePane::IsAutohideAllEnabled
Indicates whether the docking pane and all other panes in the container can be switched to autohide
mode.

virtual BOOL IsAutohideAllEnabled() const;

Return Value
TRUE if the dockable pane, and all other panes in the container, can be switched to autohide mode;
otherwise, FALSE.
Remarks
A user enables autohide mode by clicking the docking pin button while holding the Ctrl key
To enable or disable this behavior, call the CDockablePane::EnableAutohideAll method.

CDockablePane::IsAutoHideMode
Determines whether a pane is in autohide mode.

virtual BOOL IsAutoHideMode() const;

Return Value
TRUE if the dockable pane is in autohide mode; otherwise, FALSE.

CDockablePane::IsDocked
Determines whether the current pane is docked.

virtual BOOL IsDocked() const;

Return Value
TRUE if the dockable pane does not belong to a miniframe window or if it is floating in a miniframe
window with another pane. FALSE if the pane is a child of a miniframe window and there are no other
panes that belong to the miniframe window.
Remarks
To determine whether the pane is docked to the main frame window, call
CDockablePane::GetDefaultPaneDivider. If the method returns a non-NULL pointer, the pane is docked at
the main frame window.

CDockablePane::IsHideInAutoHideMode
Determines the behavior of a pane that is in autohide mode if it is shown (or hidden) by calling
CDockablePane::ShowPane.

virtual BOOL IsHideInAutoHideMode() const;


Return Value
TRUE if the dockable pane should be hidden when in autohide mode; otherwise, FALSE.
Remarks
When a dockable pane is in autohide mode, it behaves differently when you call ShowPane to hide or show
the pane. This behavior is controlled by the static member CDockablePane::m_bHideInAutoHideMode. If
this member is TRUE, the dockable pane and its related autohide toolbar or autohide button is hidden or
shown when you call ShowPane . Otherwise, the dockable pane is activated or deactivated, and its related
autohide toolbar or autohide button is always visible.
Override this method in a derived class to change the default behavior for individual panes.
The default value for m_bHideInAutoHideMode is FALSE.

CDockablePane::IsInFloatingMultiPaneFrameWnd
Specifies whether the pane is in a multi-pane frame window ( CMultiPaneFrameWnd Class).

virtual BOOL IsInFloatingMultiPaneFrameWnd() const;

Return Value
TRUE if the pane is in a multi-pane frame window; otherwise, FALSE.
Remarks

CDockablePane::IsResizable
Specifies whether the pane is resizable.

virtual BOOL IsResizable() const;

Return Value
TRUE if the pane is resizable; otherwise, FALSE.
Remarks
By default, dockable panes are resizable. To prevent resizing, override this method in a derived class and
return FALSE. Note that a FALSE value leads to a failed ASSERT in CPane::DockPane. Use
CDockingManager::AddPane instead to dock a pane within a parent frame.
Panes that cannot be resized can neither float nor enter auto-hide mode and are always located at the
outer edge of the parent frame.

CDockablePane::IsTabLocationBottom
Specifies whether tabs are located at the top or bottom of the pane.

virtual BOOL IsTabLocationBottom() const;

Return Value
TRUE if tabs are located at the bottom of the pane; FALSE if tabs are located at the top of the pane.
Remarks
For more information, see CTabbedPane::IsTabLocationBottom.
CDockablePane::IsTracked
Specifies whether a pane is being moved by the user.

BOOL IsTracked() const;

Return Value
TRUE if the pane is being moved; otherwise, FALSE.

CDockablePane::IsVisible
Determines whether the current pane is visible.

virtual BOOL IsVisible() const;

Return Value
TRUE if the dockable pane is visible; otherwise, FALSE.
Remarks
Call this method to determine whether a dockable pane is visible. You can use this method instead of
calling CWnd::IsWindowVisible or testing for the WS_VISIBLE style. The returned visibility state depends
on whether autohide mode is enabled or disabled and on the value of the
CDockablePane::IsHideInAutoHideMode property.
If the dockable pane is in autohide mode and IsHideInAutoHideMode returns FALSE the visibility state is
always FALSE.
If the dockable pane is in autohide mode and IsHideInAutoHideMode returns TRUE the visibility state
depends on the visibility state of the related autohide toolbar.
If the dockable pane is not in autohide mode, the visibility state is determined by the CBasePane::IsVisible
method.

## CDockablePane::LoadState
For internal use only. For more detail see the source code located in the VC\atlmfc\src\mfc folder of your
Visual Studio installation.

virtual BOOL LoadState(


LPCTSTR lpszProfileName = NULL,
int nIndex = -1,
UINT uiID = (UINT) -1
);

CDockablePane::m_bDisableAnimation
Specifies whether autohide animation of the dockable pane is disabled.

AFX_IMPORT_DATA static BOOL m_bDisableAnimation;

CDockablePane::m_bHideInAutoHideMode
Determines the behavior of the pane when the pane is in autohide mode.

AFX_IMPORT_DATA static BOOL m_bHideInAutoHideMode;

Remarks
This value affects all docking panes in the application.
If you set this member to TRUE, dockable panes are hidden or shown with their related autohide toolbars
and buttons when you call CDockablePane::ShowPane.
If you set this member to FALSE, dockable panes are activated or deactivated when you call
CDockablePane::ShowPane.

CDockablePane::m_nSlideSteps
Specifies the animation speed of the pane when it is in autohide mode.

AFX_IMPORT_DATA static int m_nSlideSteps;

Remarks
For a faster animation effect, decrease this value. For a slower animation effect, increase this value.

CDockablePane::OnAfterChangeParent
For more detail see the source code located in the VC\atlmfc\src\mfc folder of your Visual Studio
installation.

virtual void OnAfterChangeParent(CWnd* pWndOldParent);

Parameters
[in] pWndOldParent
Remarks

CDockablePane::OnAfterDockFromMiniFrame
Called by the framework when a floating docking bar docks at a frame window.

virtual void OnAfterDockFromMiniFrame();

Remarks
By default, this method does nothing.

CDockablePane::OnBeforeChangeParent
The framework calls this method before it changes the parent of the pane.

virtual void OnBeforeChangeParent(


CWnd* pWndNewParent,
BOOL bDelay = FALSE);
Parameters
pWndNewParent
[in] A pointer to the new parent window.
bDelay
[in] BOOL that specifies whether to delay recalculation of the docking layout if the pane is undocked. For
more information, see CDockablePane::UndockPane.
Remarks
If the pane is docked and the new parent does not allow docking, this method undocks the pane.
If the pane is being converted to a tabbed document, this method stores its recent docking position. The
framework uses the recent docking position to restore the position of the pane when it is converted back
to a docked state.

CDockablePane::OnBeforeFloat
The framework calls this method before a pane transitions to a floating state.

virtual BOOL OnBeforeFloat(


CRect& rectFloat,
AFX_DOCK_METHOD dockMethod);

Parameters
rectFloat
[in] Specifies the position and size of the pane when it is in a floating state.
dockMethod
[in] Specifies the docking method. See CPane::DockPane for a list of possible values.
Return Value
TRUE if the pane can be floated; otherwise, FALSE.
Remarks
This method is called by the framework when a pane is about to float. You can override this method in a
derived class if you want to perform any processing before the pane floats.

CDockablePane::OnPressButtons
Called when the user presses a caption button other than the AFX_HTCLOSE and AFX_HTMAXBUTTON
buttons.

virtual void OnPressButtons(UINT nHit);

Parameters
nHit
[in] This parameter is not used.
Remarks
If you add a custom button to the caption of a dockable pane, override this method to receive notifications
when a user presses the button.

CDockablePane::OnSlide
Called by the framework to animate the pane when it is in autohide mode.

virtual void OnSlide(BOOL bSlideOut);

Parameters
bSlideOut
[in] TRUE to show the pane; FALSE to hide the pane.
Remarks
Override this method in a derived class to implement custom autohide effects.

CDockablePane::RemoveFromDefaultPaneDividier
The framework calls this method when a pane is being undocked.

void RemoveFromDefaultPaneDividier();

Remarks
This method sets the default pane divider to NULL and removes the pane from its container.

CDockablePane::ReplacePane
Replaces the pane with a specified pane.

BOOL ReplacePane(
CDockablePane* pBarToReplaceWith,
AFX_DOCK_METHOD dockMethod,
BOOL bRegisterWithFrame = FALSE);

Parameters
pBarToReplaceWith
[in] A pointer to a dockable pane.
dockMethod
[in] Not used.
bRegisterWithFrame
[in] If TRUE, the new pane is registered with the docking manager of the parent of the old pane. The new
pane is inserted at the index of the old pane in the list of panes that is maintained by the docking manager.
Return Value
TRUE if the replacement is successful; otherwise, FALSE.

CDockablePane::RestoreDefaultPaneDivider
When a pane is deserialized, the framework calls this method to restore the default pane divider.

void RestoreDefaultPaneDivider();

Remarks
The restored default pane divider replaces the current default pane divider, if it exists.
CDockablePane::SetAutoHideMode
Toggles the docking pane between visible and autohide mode.

virtual CMFCAutoHideBar* SetAutoHideMode(


BOOL bMode,
DWORD dwAlignment,
CMFCAutoHideBar* pCurrAutoHideBar = NULL,
BOOL bUseTimer = TRUE);

Parameters
bMode
[in] TRUE to enable autohide mode; FALSE to enable regular docking mode.
dwAlignment
[in] Specifies the alignment of the autohide pane to create.
pCurrAutoHideBar
[in, out] A pointer to the current autohide toolbar. Can be NULL.
bUseTimer
[in] Specifies whether to use the autohide effect when the user switches the pane to autohide mode or to
hide the pane immediately.
Return Value
The autohide toolbar that was created as a result of switching to autohide mode, or NULL.
Remarks
The framework calls this method when a user clicks the pin button to switch the dockable pane to
autohide mode or to regular docking mode.
Call this method to switch a dockable pane to autohide mode programmatically. The pane must be docked
to the main frame window ( CDockablePane::GetDefaultPaneDivider must return a valid pointer to the
CPaneDivider).

CDockablePane::SetAutoHideParents
Sets the auto-hide button and auto-hide toolbar for the pane.

void SetAutoHideParents(
CMFCAutoHideBar* pToolBar,
CMFCAutoHideButton* pBtn);

Parameters
pToolBar
[in] Pointer to an auto-hide toolbar.
pBtn
[in] Pointer to an auto-hide button.

CDockablePane::SetLastPercentInPaneContainer
Sets the percentage of space that a pane occupies in its container.
void SetLastPercentInPaneContainer(int n);

Parameters
n
[in] An int that specifies the percentage of space that the pane occupies in its container.
Remarks
The framework adjusts the pane to use the new value when the layout is recalculated.

CDockablePane::SetRestoredDefaultPaneDivider
Sets the restored default pane divider.

void SetRestoredDefaultPaneDivider(HWND hRestoredSlider);

Parameters
hRestoredSlider
[in] A handle to a pane divider (slider).
Remarks
A restored default pane divider is obtained when a pane is deserialized. For more information, see
CDockablePane::RestoreDefaultPaneDivider.

CDockablePane::SetTabbedPaneRTC
Sets the runtime class information for a tabbed window that is created when two panes dock together.

void SetTabbedPaneRTC(CRuntimeClass* pRTC);

Parameters
pRTC
[in] The runtime class information for the tabbed pane.
Remarks
Call this method to set the runtime class information for tabbed panes that are created dynamically. This
can occur when a user drags one pane to the caption of another pane, or if you call the
CDockablePane::AttachToTabWnd method to programmatically create a tabbed pane from two dockable
panes.
The default runtime class is set according to the dwTabbedStyle parameter of CDockablePane::Create and
CDockablePane::CreateEx. To customize the new tabbed panes, derive your class from one of the following
classes:
CBaseTabbedPane Class
CTabbedPane Class
CMFCOutlookBar Class.
Then, call this method with the pointer to its runtime class information.

CDockablePane::ShowPane
Shows or hides a pane.

virtual void ShowPane(


BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
bShow
[in] TRUE to show the pane; FALSE to hide the pane.
bDelay
[in] TRUE to delay adjusting the docking layout; FALSE to adjust the docking layout immediately.
bActivate
[in] TRUE to activate the pane when shown; otherwise, FALSE.
Remarks
Call this method instead of the CWnd::ShowWindow when showing or hiding dockable panes.

CDockablePane::Slide
Animates a pane that is in autohide mode.

virtual void Slide(


BOOL bSlideOut,
BOOL bUseTimer = TRUE);

Parameters
bSlideOut
[in] TRUE to show the pane; FALSE to hide the pane.
bUseTimer
[in] TRUE to show or hide the pane with the autohide effect; FALSE to show or hide the pane immediately.
Remarks
The framework calls this method to animate a pane that is in autohide mode.
This method uses the CDockablePane::m_nSlideDefaultTimeOut value to determine the time out for the slide
effect. The default value for the time out is 1. If you customize the autohide algorithm, modify this member
to change the time out.

CDockablePane::ToggleAutoHide
Toggles the pane between always visible and auto-hide mode.

virtual void ToggleAutoHide();

Remarks
This method toggles auto-hide mode for the pane by calling CDockablePane::SetAutoHideMode.

CDockablePane::UndockPane
Undocks a pane from either the main frame window or a miniframe window container.
virtual void UndockPane(BOOL bDelay = FALSE);

Parameters
bDelay
[in] TRUE to delay calculating the docking layout; FALSE to recalculate the docking layout immediately.
Remarks
Call this method to undock a pane from the main frame window or from a multi-miniframe window
container (a pane that is floating in a single miniframe window with other panes).
You must undock a pane before you perform any external operation that is not performed by the
CDockingManager. For example, you must undock a pane to move it programmatically from one location
to another.
The framework automatically undocks panes before they are destroyed.

See also
Hierarchy Chart
Classes
CPane Class
CDockablePaneAdapter Class
3/27/2020 • 2 minutes to read • Edit Online

Provides docking support for CWnd -derived panes.

Syntax
class CDockablePaneAdapter : public CDockablePane

Members
Public Methods
NAME DESC RIP T IO N

CDockablePaneAdapter::GetWrappedWnd Returns the wrapped window.

CDockablePaneAdapter::LoadState (Overrides CDockablePane::LoadState.)

CDockablePaneAdapter::SaveState (Overrides CDockablePane::SaveState.)

CDockablePaneAdapter::SetWrappedWnd

Remarks
Usually, the framework instantiates objects of this class when you use the CMFCBaseTabCtrl::AddTab or
CMFCBaseTabCtrl::InsertTab methods.
If you want to customize the CDockablePaneAdapter behavior, just derive a new class from it and set the runtime
class information to a tabbed window by using CMFCBaseTabCtrl::SetDockingBarWrapperRTC.

Inheritance Hierarchy
CObject
└ CCmdTarget
└ CWnd
└ CBasePane
└ CPane
└ CDockablePane
└ CDockablePaneAdapter

Requirements
Header : afxDockablePaneAdapter.h

CDockablePaneAdapter::GetWrappedWnd
Returns the underlying window for the dockable pane adapter.
virtual CWnd* GetWrappedWnd() const;

Return Value
A pointer to the wrapped window.
Remarks
Use this function to access the wrapped window.

CDockablePaneAdapter::LoadState
Loads the state of the pane from the registry.

virtual BOOL LoadState(


LPCTSTR lpszProfileName = NULL,
int nIndex = -1,
UINT uiID = (UINT) -1);

Parameters
lpszProfileName
[in] The profile name.
nIndex
[in] The profile index.
uiID
[in] The pane ID.
Return Value
Remarks

CDockablePaneAdapter::SaveState
Saves the state of the pane to the registry.

virtual BOOL SaveState(


LPCTSTR lpszProfileName = NULL,
int nIndex = -1,
UINT uiID = (UINT) -1);

Parameters
lpszProfileName
[in] The profile name.
nIndex
[in] The profile index (defaults to the control ID of the window).
uiID
[in] The pane ID.
Return Value
Remarks

CDockablePaneAdapter::SetWrappedWnd
Sets the underlying window for the dockable pane adapter.

virtual BOOL SetWrappedWnd(CWnd* pWnd);

Parameters
pWnd
[in] A pointer to the window for the pane adapter to wrap.
Return Value
Remarks

See also
Hierarchy Chart
Classes
CDockablePane Class
CDockingManager Class
4/21/2020 • 26 minutes to read • Edit Online

Implements the core functionality that controls docking layout in a main frame window.

Syntax
class CDockingManager : public CObject

Members
Public Methods
NAME DESC RIP T IO N

CDockingManager::AddDockSite Creates a dock pane and adds it to the list of control bars.

CDockingManager::AddHiddenMDITabbedBar Adds a handle to a bar pane to the list of hidden MDI


tabbed bar panes.

CDockingManager::AddMiniFrame Adds a frame to the list of mini frames.

CDockingManager::AddPane Registers a pane with the docking manager.

CDockingManager::AdjustDockingLayout Recalculates and adjusts the layout of all panes in a frame


window.

CDockingManager::AdjustPaneFrames Causes the WM_NCCALCSIZE message to be sent to all


panes and CPaneFrameWnd windows.

CDockingManager::AdjustRectToClientArea Adjusts the alignment of a rectangle.

CDockingManager::AlignAutoHidePane Resizes a docking pane in autohide mode so that it takes the


full width or height of the frame’s client area surrounded by
dock sites.

CDockingManager::AutoHidePane Creates an autohide toolbar.

CDockingManager::BringBarsToTop Brings the docked bars that have the specified alignment to
the top.

CDockingManager::BuildPanesMenu Adds names of docking panes and toolbars to a menu.

CDockingManager::CalcExpectedDockedRect Calculates the expected rectangle of a docked window.

CDockingManager::Create Creates a docking manager.

CDockingManager::DeterminePaneAndStatus Determines the pane that contains a given point and its
docking status.
NAME DESC RIP T IO N

CDockingManager::DisableRestoreDockState Enables or disables loading of docking layout from the


registry.

CDockingManager::DockPane Docks a pane to another pane or to a frame window.

CDockingManager::DockPaneLeftOf Docks a pane to the left of another pane.

CDockingManager::EnableAutoHidePanes Enables docking of the pane to the main frame, creates a


dock pane, and adds it to the list of control bars.

CDockingManager::EnableDocking Creates a dock pane and enables docking of the pane to the
main frame.

CDockingManager::EnableDockSiteMenu Displays an additional button that opens a pop-up menu on


the captions of all docking panes.

CDockingManager::EnablePaneContextMenu Tells the library to display a special context menu that has a
list of application toolbars and docking panes when the user
clicks the right mouse button and the library is processing
the WM_CONTEXTMENU message.

CDockingManager::FindDockSite Retrieves the bar pane that is at the specified position and
that has the specified alignment.

CDockingManager::FindDockSiteByPane Returns the bar pane that has the id of the target bar pane.

CDockingManager::FindPaneByID Finds a pane by the specified control ID.

CDockingManager::FixupVirtualRects Commits all current toolbar positions to virtual rectangles.

CDockingManager::FrameFromPoint Returns the frame that contains the given point.

CDockingManager::GetClientAreaBounds Gets the rectangle that contains the bounds of the client
area.

CDockingManager::GetDockingMode Returns the current docking mode.

CDockingManager::GetDockSiteFrameWnd Gets a pointer to the parent window frame.

CDockingManager::GetEnabledAutoHideAlignment Returns the enabled alignment of the panes.

CDockingManager::GetMiniFrames Gets a list of miniframes.

CDockingManager::GetOuterEdgeBounds Gets a rectangle that contains the outer edges of the frame.

CDockingManager::GetPaneList Returns a list of panes that belong to the docking manager.


This includes all floating panes.

CDockingManager::GetSmartDockingManager Retrieves a pointer to the smart docking manager.

CDockingManager::GetSmartDockingManagerPermanent Retrieves a pointer to the smart docking manager.


NAME DESC RIP T IO N

CDockingManager::GetSmartDockingParams Returns the smart docking parameters for the docking


manager.

CDockingManager::GetSmartDockingTheme A static method that returns a theme used to display smart


docking markers.

CDockingManager::HideAutoHidePanes Hides a pane that is in autohide mode.

CDockingManager::InsertDockSite Creates a dock pane and inserts it into the list of control
bars.

CDockingManager::InsertPane Inserts a control pane into the list of control bars.

CDockingManager::IsDockSiteMenu Specifies whether a pop-up menu is displayed on the


captions of all panes.

CDockingManager::IsInAdjustLayout Determines if the layouts of all panes are adjusted.

CDockingManager::IsOLEContainerMode Specifies whether the docking manager is in OLE container


mode.

CDockingManager::IsPointNearDockSite Determines whether a specified point is near the dock site.

CDockingManager::IsPrintPreviewValid Determines if the print preview mode is set.

CDockingManager::LoadState Loads the docking manager's state from the registry.

CDockingManager::LockUpdate Locks the given window.

CDockingManager::OnActivateFrame Called by the framework when the frame window is made


active or is deactivated.

CDockingManager::OnClosePopupMenu Called by the framework when an active pop-up menu


processes a WM_DESTROY message.

CDockingManager::OnMoveMiniFrame Called by the framework to move a mini-frame window.

CDockingManager::OnPaneContextMenu Called by the framework when it builds a menu that has a


list of panes.

CDockingManager::PaneFromPoint Returns the pane that contains the given point.

CDockingManager::ProcessPaneContextMenuCommand Called by the framework to select or to clear a check box for


the specified command and recalculate the layout of a shown
pane.

CDockingManager::RecalcLayout Recalculates the internal layout of the controls present in the


list of controls.

CDockingManager::ReleaseEmptyPaneContainers Releases the empty pane containers.

CDockingManager::RemoveHiddenMDITabbedBar Removes the specified hidden bar pane.


NAME DESC RIP T IO N

CDockingManager::RemoveMiniFrame Removes a specified frame from the list of mini frames.

CDockingManager::RemovePaneFromDockManager Unregisters a pane and removes it from the list in the


docking manager.

CDockingManager::ReplacePane Replaces one pane with another.

CDockingManager::ResortMiniFramesForZOrder Resorts the frames in the list of mini frames.

CDockingManager::SaveState Saves the docking manager's state to the registry.

CDockingManager::SendMessageToMiniFrames Sends the specified message to all mini frames.

CDockingManager::Serialize Writes the docking manager to an archive. (Overrides


CObject::Serialize.)

CDockingManager::SetAutohideZOrder Sets the size, width, and height of the control bars and the
specified pane.

CDockingManager::SetDockingMode Sets the docking mode.

CDockingManager::SetDockState Sets the docking state of the control bars, the mini frames,
and the autohide bars.

CDockingManager::SetPrintPreviewMode Sets the print preview mode of the bars that are displayed in
the print preview.

CDockingManager::SetSmartDockingParams Sets the parameters that define the behavior of smart


docking.

CDockingManager::ShowDelayShowMiniFrames Shows or hides the windows of the mini frames.

CDockingManager::ShowPanes Shows or hides the panes of the control and autohide bars.

CDockingManager::StartSDocking Starts the smart docking of the specified window according


to the alignment of the smart docking manager.

CDockingManager::StopSDocking Stops smart docking.

Data Members
NAME DESC RIP T IO N

CDockingManager::m_bHideDockingBarsInContainerMode Specifies whether the docking manager hides panes in OLE


container mode.

CDockingManager::m_dockModeGlobal Specifies the global docking mode.

CDockingManager::m_nDockSensitivity Specifies the docking sensitivity.

CDockingManager::m_nTimeOutBeforeDockingBarDock Specifies the time, in milliseconds, before a docking pane is


docked in immediate docking mode.
NAME DESC RIP T IO N

CDockingManager::m_nTimeOutBeforeToolBarDock Specifies the time, in milliseconds, before a toolbar is docked


to the main frame window.

Remarks
The main frame window creates and initializes this class automatically.
The docking manager object holds a list of all panes that are in the docking layout, and also a list of all
CPaneFrameWnd windows that belong to the main frame window.
The CDockingManager class implements some services that you can use to find a pane or a CPaneFrameWnd
window. You usually do not call these services directly because they are wrapped in the main frame window
object. For more information, see CPaneFrameWnd Class.

Customization Tips
The following tips apply to CDockingManager objects:
CDockingManager Class supports these docking modes:
AFX_DOCK_TYPE::DT_IMMEDIATE

AFX_DOCK_TYPE::DT_STANDARD

AFX_DOCK_TYPE::DT_SMART

These docking modes are defined by CDockingManager::m_dockModeGlobal and are set by calling
CDockingManager::SetDockingMode.
If you want to create a non-floating, non-resizable pane, call the CDockingManager::AddPane method.
This method registers the pane with the docking manager, which is responsible for the layout of the pane.

Example
The following example demonstrates how to use various methods in the CDockingManager class to configure a
CDockingManager object. The example shows how to display an additional button that opens a pop-up menu on
the captions of all docking panes and how to set the docking mode of the object. This code snippet is part of the
Visual Studio Demo sample.

CDockingManager *pDockManager = GetDockingManager();


ASSERT_VALID(pDockManager);
pDockManager->AdjustPaneFrames();
pDockManager->EnableDockSiteMenu();
pDockManager->SetDockingMode(DT_STANDARD);

Inheritance Hierarchy
CObject
CDockingManager

Requirements
Header : afxDockingManager.h
CDockingManager::AddDockSite
Creates a dock pane and adds it to the list of control bars.

BOOL AddDockSite(
const AFX_DOCKSITE_INFO& info,
CDockSite** ppDockBar = NULL);

Parameters
info
[in] A reference to an info structure that contains dock pane alignment.
ppDockBar
[out] A pointer to a pointer to the new dock pane.
Return Value
TRUE if the dock pane was created successfully; FALSE otherwise.

CDockingManager::AddHiddenMDITabbedBar
Adds a handle to a bar pane to the list of hidden MDI tabbed bar panes.

void AddHiddenMDITabbedBar(CDockablePane* pBar);

Parameters
pBar
[in] A pointer to a bar pane

CDockingManager::AddPane
Registers a pane with the docking manager.

BOOL AddPane(
CBasePane* pWnd,
BOOL bTail = TRUE,
BOOL bAutoHide = FALSE,
BOOL bInsertForOuterEdge = FALSE);

Parameters
pWnd
[in, out] Specifies the pane to add to the docking manager.
bTail
[in] TRUE to add the pane to the end of the list of panes for the docking manager; otherwise, FALSE.
bAutoHide
[in] For internal use only. Always use the default value FALSE.
bInsertForOuterEdge
[in] For internal use only. Always use the default value FALSE.
Return Value
TRUE if the pane was successfully registered with the docking manager; otherwise, FALSE.
Remarks
Call this method to register non-floating, non-resizable panes with the docking manager. If you do not register
the panes, they will not appear correctly when the docking manager is laid out.

CDockingManager::AdjustDockingLayout
Recalculates and adjusts the layout of all panes in a frame window.

virtual void AdjustDockingLayout(HDWP hdwp = NULL);

Parameters
hdwp
[in] Specifies the deferred window position structure. For more information, see Windows Data Types.
Remarks

CDockingManager::AddMiniFrame
Adds a frame to the list of mini frames.

virtual BOOL AddMiniFrame(CPaneFrameWnd* pWnd);

Parameters
pWnd
[in] A pointer to a frame.
Return Value
TRUE if the frame is not in the list of mini frames and was added successfully; FALSE otherwise.

CDockingManager::AdjustPaneFrames
Causes the WM_NCCALCSIZE message to be sent to all panes and CPaneFrameWnd windows.

virtual void AdjustPaneFrames();

Remarks

CDockingManager::AdjustRectToClientArea
Adjusts the alignment of a rectangle.

virtual BOOL AdjustRectToClientArea(


CRect& rectResult,
DWORD dwAlignment);

Parameters
rectResult
[in] A reference to a CRect object
dwAlignment
[in] The alignment of the CRect object
Return Value
TRUE if the alignment of the CRect object was adjusted; FALSE otherwise.
Remarks
The dwAlignment parameter can have one of the following values:
CBRS_ALIGN_TOP
CBRS_ALIGN_BOTTOM
CBRS_ALIGN_LEFT
CBRS_ALIGN_RIGHT

CDockingManager::AlignAutoHidePane
Resizes a docking pane in autohide mode so that it takes the full width or height of the frame’s client area
surrounded by dock sites.

void AlignAutoHidePane(
CPaneDivider* pDefaultSlider,
BOOL bIsVisible = TRUE);

Parameters
pDefaultSlider
[in] The docking slider pane.
bIsVisible
[in] TRUE if the docking pane is visible; FALSE otherwise.

CDockingManager::AutoHidePane
Creates an autohide toolbar.

CMFCAutoHideToolBar* AutoHidePane(
CDockablePane* pBar,
CMFCAutoHideToolBar* pCurrAutoHideToolBar = NULL);

Parameters
pBar
[in] A pointer to the bar pane.
pCurrAutoHideToolBar
[in] A pointer to an auto hide toolbar.
Return Value
NULL if the auto hide toolbar was not created; otherwise a pointer to the new toolbar.

CDockingManager::BringBarsToTop
Brings the docked bars that have the specified alignment to the top.

void BringBarsToTop(
DWORD dwAlignment = 0,
BOOL bExcludeDockedBars = TRUE);
Parameters
dwAlignment
[in] The alignment of the dock bars that are brought to the top of other windows.
bExcludeDockedBars
[in] TRUE to exclude the docked bars from being on top; otherwise FALSE.

CDockingManager::BuildPanesMenu
Adds names of docking panes and toolbars to a menu.

void BuildPanesMenu(
CMenu& menu,
BOOL bToolbarsOnly);

Parameters
menu
[in] A menu to add the names of docking panes and toolbars to.
bToolbarsOnly
[in] TRUE to add only toolbar names to the menu; FALSE otherwise.

CDockingManager::CalcExpectedDockedRect
Calculates the expected rectangle of a docked window.

void CalcExpectedDockedRect(
CWnd* pWnd,
CPoint ptMouse,
CRect& rectResult,
BOOL& bDrawTab,
CDockablePane** ppTargetBar);

Parameters
pWnd
[in] A pointer to the window to dock.
ptMouse
[in] The mouse location.
rectResult
[out] The calculated rectangle.
bDrawTab
[in] TRUE to draw a tab; otherwise FALSE.
ppTargetBar
[out] A pointer to a pointer to the target pane.
Remarks
This method calculates the rectangle that a window would occupy if a user dragged the window to the point
specified by ptMouse and docked it there.

CDockingManager::Create
Creates a docking manager.
BOOL Create(CFrameWnd* pParentWnd);

Parameters
pParentWnd
[in] A pointer to the parent frame of the docking manager. This value must not be NULL.
Return Value
TRUE always.

CDockingManager::DeterminePaneAndStatus
Determines the pane that contains a given point and its docking status.

virtual AFX_CS_STATUS DeterminePaneAndStatus(


CPoint pt,
int nSensitivity,
DWORD dwEnabledAlignment,
CBasePane** ppTargetBar,
const CBasePane* pBarToIgnore,
const CBasePane* pBarToDock);

Parameters
pt
[in] The location of the pane to check.
nSensitivity
[in] The value to increase the window rectangle of each checked pane. A pane satisfies the search criteria if the
given point is in this increased region.
dwEnabledAlignment
[in] The alignment of the docking pane.
ppTargetBar
[out] A pointer to a pointer to the target pane.
pBarToIgnore
[in] The pane that the method ignores.
pBarToDock
[in] The pane that is docked.
Return Value
The docking status.
Remarks
The docking status can be one of the following values:

A F X_C S_STAT US VA L UE M EA N IN G

CS_NOTHING The pointer is not over a dock site. Therefore, keep the pane
floating.

CS_DOCK_IMMEDIATELY The pointer is over the dock site in the immediate mode
(DT_IMMEDIATE style is enabled), so the pane must be
docked immediately.
A F X_C S_STAT US VA L UE M EA N IN G

CS_DELAY_DOCK The pointer is over a dock site that is another docking pane
or is an edge of the main frame.

CS_DELAY_DOCK_TO_TAB The pointer is over a dock site that causes the pane to be
docked in a tabbed window. This occurs when the mouse is
over a caption of another docking pane or over a tab area of
a tabbed pane.

CDockingManager::DisableRestoreDockState
Enables or disables loading of docking layout from the registry.

void DisableRestoreDockState(BOOL bDisable = TRUE);

Parameters
bDisable
[in] TRUE to disable loading of docking layout from the registry; otherwise, FALSE.
Remarks
Call this method when you must preserve the current layout of docking panes and toolbars when the
application state is loading.

CDockingManager::DockPane
Docks a pane to another pane or to a frame window.

void DockPane(
CBasePane* pBar,
UINT nDockBarID = 0,
LPCRECT lpRect = NULL);

Parameters
pBar
[in] A pointer to a bar pane to dock to.
nDockBarID
[in] The id of the bar to dock.
lpRect
[in] The destination rectangle.

CDockingManager::DockPaneLeftOf
Docks a pane to the left of another pane.

BOOL DockPaneLeftOf(
CPane* pBarToDock,
CPane* pTargetBar);

Parameters
pBarToDock
[in] A pointer to the pane to be docked to the left of pTargetBar.
pTargetBar
[in] A pointer to the target pane.
Return Value
TRUE if the pane was docked successfully; otherwise, FALSE.

CDockingManager::EnableAutoHidePanes
Enables docking of the pane to the main frame, creates a dock pane, and adds it to the list of control bars.

BOOL EnableAutoHidePanes(DWORD dwStyle);

Parameters
dwStyle
[in] The docking alignment.
Return Value
TRUE if the dock pane was created successfully; FALSE otherwise.

CDockingManager::EnableDocking
Creates a dock pane and enables docking of the pane to the main frame.

BOOL EnableDocking(DWORD dwStyle);

Parameters
dwStyle
[in] The docking alignment.
Return Value
TRUE if the dock pane was created successfully; FALSE otherwise.

CDockingManager::EnableDockSiteMenu
Displays an additional button that opens a pop-up menu on the captions of all docking panes.

static void EnableDockSiteMenu(BOOL bEnable = TRUE);

Parameters
bEnable
[in] TRUE to enable the dock site menu; otherwise, FALSE.
Remarks
The dock site menu displays the following options for changing the docking state of the pane:
Floating - Floats a pane
Docking - Docks a pane at the main frame at the location where the pane was last docked
AutoHide - Switches the pane to autohide mode
Hide - Hides a pane
By default, this menu is not displayed.

CDockingManager::EnablePaneContextMenu
Tells the library to display a special context menu that has a list of application toolbars and docking panes when
the user clicks the right mouse button and the library is processing the WM_CONTEXTMENU message.

void EnablePaneContextMenu(
BOOL bEnable,
UINT uiCustomizeCmd,
const CString& strCustomizeText,
BOOL bToolbarsOnly = FALSE);

Parameters
bEnable
[in] If TRUE, the library turns on the support for automatic context menu; if FALSE the library turns off the
support for automatic context menu.
uiCustomizeCmd
[in] A command id for the Customize item in the menu.
strCustomizeText
[in] The text of the Customize item.
bToolbarsOnly
[in] If TRUE, the menu displays only a list of application toolbars; if FALSE, the library adds application docking
panes to this list.

CDockingManager::FindDockSite
Retrieves the bar pane that is at the specified position and that has the specified alignment.

virtual CDockSite* FindDockSite(


DWORD dwAlignment,
BOOL bOuter);

Parameters
dwAlignment
[in] The alignment of the bar pane.
bOuter
[in] If TRUE, retrieve the bar in the head position in the list of control bars. Otherwise, retrieve the bar in the tail
position in the list of control bars.
Return Value
The docking pane that has the specified alignment; NULL otherwise.

CDockingManager::FindPaneByID
Finds a pane by the specified control ID.
virtual CBasePane* FindPaneByID(
UINT uBarID,
BOOL bSearchMiniFrames = FALSE);

Parameters
uBarID
[in] Specifies the control ID of the pane to find.
bSearchMiniFrames
[in] TRUE to include all floating panes in the search. FALSE to include only the docked panes.
Return Value
The CBasePane object that has the specified control ID, or NULL if the specified pane cannot be found.
Remarks

CDockingManager::FindDockSiteByPane
Returns the bar pane that has the id of the target bar pane.

virtual CDockSite* FindDockSiteByPane(CPane* pTargetBar);

Parameters
pTargetBar
[in] A pointer to the target bar pane.
Return Value
The bar pane that has the id of the target bar pane; NULL if no such bar pane exists.

CDockingManager::FixupVirtualRects
Commits all current toolbar positions to virtual rectangles.

virtual void FixupVirtualRects();

Remarks
When the user starts to drag a toolbar, the application remembers its original position in the virtual rectangle.
When the user moves a toolbar across its dock site, the toolbar may shift other toolbars. The original positions
of the other toolbars are stored in the corresponding virtual rectangles.

CDockingManager::FrameFromPoint
Returns the frame that contains the given point.

virtual CPaneFrameWnd* FrameFromPoint(


CPoint pt,
CPaneFrameWnd* pFrameToExclude,
BOOL bFloatMultiOnly) const;

Parameters
pt
[in] Specifies the point, in screen coordinates, to check.
pFrameToExclude
[in] A pointer to a frame to exclude.
bFloatMultiOnly
[in] TRUE to exclude frames that are not instances of CMultiPaneFrameWnd ; FALSE otherwise.
Return Value
The frame that contains the given point; NULL otherwise.

CDockingManager::GetClientAreaBounds
Gets the rectangle that contains the bounds of the client area.

CRect GetClientAreaBounds() const;

void GetClientAreaBounds(CRect& rcClient);

Parameters
rcClient
[out] A reference to the rectangle that contains the bounds of the client area.
Return Value
The rectangle that contains the bounds of the client area.

CDockingManager::GetDockingMode
Returns the current docking mode.

static AFX_DOCK_TYPE GetDockingMode();

Return Value
An enumerator value that represents the current docking mode. It can be one of the following values:
DT_STANDARD
DT_IMMEDIATE
DT_SMART
Remarks
To set the docking mode, call CDockingManager::SetDockingMode.

CDockingManager::GetDockSiteFrameWnd
Gets a pointer to the parent window frame.

CFrameWnd* GetDockSiteFrameWnd() const;

Return Value
A pointer to the parent window frame.

CDockingManager::GetEnabledAutoHideAlignment
Returns the enabled alignment of the panes.
DWORD GetEnabledAutoHideAlignment() const;

Return Value
A bitwise combination of CBRS_ALIGN_ flags, or 0 if autohide panes are not enabled. For more information, see
CFrameWnd::EnableDocking.
Remarks
The method returns the enabled alignment for autohide control bars. To enable autohide bars, call
CFrameWndEx::EnableAutoHidePanes.

CDockingManager::GetMiniFrames
Gets a list of miniframes.

const CObList& GetMiniFrames() const;

Return Value
A list of miniframes that contain the control bars that belong to the docking manager.

CDockingManager::GetOuterEdgeBounds
Gets a rectangle that contains the outer edges of the frame.

CRect GetOuterEdgeBounds() const;

Return Value
A rectangle that contains the outer edges of the frame.

CDockingManager::GetPaneList
Returns a list of panes that belong to the docking manager. This includes all floating panes.

void GetPaneList(
CObList& lstBars,
BOOL bIncludeAutohide = FALSE,
CRuntimeClass* pRTCFilter = NULL,
BOOL bIncludeTabs = FALSE);

Parameters
lstBars
[in, out] Contains all the panes of the current docking manager.
bIncludeAutohide
[in] TRUE to include the panes that are in autohide mode; otherwise, FALSE.
pRTCFilter
[in] If not NULL, the returned list contains panes only of the specified runtime class.
bIncludeTabs
[in] TRUE to include tabs; otherwise, FALSE.
Remarks
If there are any tabbed panes in the docking manager, the method returns pointers to CBaseTabbedPane Class
objects and you must enumerate the tabs explicitly.
Use pRTCFilter to obtain a particular class of panes. For example, you can obtain only toolbars by setting this
value appropriately.

CDockingManager::GetSmartDockingManager
Retrieves a pointer to the smart docking manager.

CSmartDockingManager* GetSmartDockingManager();

Return Value
A pointer to the smart docking manager.

CDockingManager::GetSmartDockingManagerPermanent
Retrieves a pointer to the smart docking manager.

CSmartDockingManager* GetSmartDockingManagerPermanent() const;

Return Value
A pointer to the smart docking manager.

CDockingManager::GetSmartDockingParams
Returns the smart docking parameters for the docking manager.

static CSmartDockingInfo& GetSmartDockingParams();

Return Value
The class that contains the smart docking parameters for the current docking manager. For more information,
see CSmartDockingInfo Class.
Remarks

CDockingManager::HideAutoHidePanes
Hides a pane that is in autohide mode.

void HideAutoHidePanes(
CDockablePane* pBarToExclude = NULL,
BOOL bImmediately = FALSE);

Parameters
pBarToExclude
[in] A pointer to a bar to exclude from hiding.
bImmediately
[in] TRUE to hide the pane immediately; FALSE to hide the pane with the autohide effect.
CDockingManager::InsertDockSite
Creates a dock pane and inserts it into the list of control bars.

BOOL InsertDockSite(
const AFX_DOCKSITE_INFO& info,
DWORD dwAlignToInsertAfter,
CDockSite** ppDockBar = NULL);

Parameters
info
[in] A structure that contains the alignment information about the dock pane.
dwAlignToInsertAfter
[in] Alignment of the dock pane.
ppDockBar
[out] A pointer to a pointer to a dock pane.
Return Value
TRUE if the dock pane was created successfully; FALSE otherwise.

CDockingManager::InsertPane
Inserts a control pane into the list of control bars.

BOOL InsertPane(
CBasePane* pControlBar,
CBasePane* pTarget,
BOOL bAfter = TRUE);

Parameters
pControlBar
[in] A pointer to a control pane.
pTarget
[in] A pointer to a target pane.
bAfter
[in] TRUE to insert the pane after the position of the target pane; FALSE otherwise.
Return Value
TRUE if the control pane is successfully added to the list of control bars; FALSE otherwise.
Remarks
This method returns false if the control pane is already in the list of control bars or if the target pane does not
exist in the list of control bars.

CDockingManager::IsDockSiteMenu
Specifies whether a pop-up menu is displayed on the captions of all panes.

static BOOL IsDockSiteMenu();

Return Value
TRUE if a dock site menu is displayed on the captions of all docking panes; otherwise FALSE.
Remarks
You can enable the dock site menu by calling CDockingManager::EnableDockSiteMenu.

CDockingManager::IsInAdjustLayout
Determines if the layouts of all panes are adjusted.

BOOL IsInAdjustLayout() const;

Return Value
TRUE if the layouts of all panes are adjusted; FALSE otherwise.

CDockingManager::IsOLEContainerMode
Specifies whether the docking manager is in OLE container mode.

BOOL IsOLEContainerMode() const;

Return Value
TRUE if the docking manager is in OLE container mode; otherwise, FALSE.
Remarks
In OLE container mode, all docking panes and application toolbars are hidden. The panes are also hidden in this
mode if you have set CDockingManager::m_bHideDockingBarsInContainerMode to TRUE.

CDockingManager::IsPointNearDockSite
Determines whether a specified point is near the dock site.

BOOL IsPointNearDockSite(
CPoint point,
DWORD& dwBarAlignment,
BOOL& bOuterEdge) const;

Parameters
point
[in] The specified point.
dwBarAlignment
[out] Specifies which edge the point is near. Possible values are CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT,
CBRS_ALIGN_TOP, and CBRS_ALIGN_BOTTOM.
bOuterEdge
[out] TRUE if the point is near the outer border of the dock site; FALSE otherwise.
Return Value
TRUE if the point is near the dock site; otherwise FALSE.

CDockingManager::IsPrintPreviewValid
Determines if the print preview mode is set.
BOOL IsPrintPreviewValid() const;

Return Value
TRUE if the print preview mode is set; FALSE otherwise.

CDockingManager::LoadState
Loads the docking manager's state from the registry.

virtual BOOL LoadState(


LPCTSTR lpszProfileName = NULL,
UINT uiID = (UINT) -1);

Parameters
lpszProfileName
[in] Profile name.
uiID
[in] The id of the docking manager.
Return Value
TRUE if the docking manager state was loaded successfully; otherwise FALSE.

CDockingManager::LockUpdate
Locks the given window.

void LockUpdate(BOOL bLock);

Parameters
bLock
[in] TRUE if the window is locked; FALSE otherwise.
Remarks
When a window is locked, it cannot be moved and it cannot be redrawn.

CDockingManager::m_bHideDockingBarsInContainerMode
Specifies whether the docking manager hides panes in OLE container mode.

AFX_IMPORT_DATA static BOOL m_bHideDockingBarsInContainerMode;

Remarks
Set this value to FALSE if you want to keep all panes docked to the main frame visible when the application is in
OLE container mode. By default, this value is TRUE.

CDockingManager::m_dockModeGlobal
Specifies the global docking mode.
AFX_IMPORT_DATA static AFX_DOCK_TYPE m_dockModeGlobal;

Remarks
By default, each docking pane uses this docking mode. For more information about the values that this field can
be set to, see CBasePane::GetDockingMode.

CDockingManager::m_nDockSensitivity
Specifies the docking sensitivity.

AFX_IMPORT_DATA static int m_nDockSensitivity;

Remarks
The docking sensitivity defines how close a floating pane can approach a docking pane, docking site, or another
pane before the framework changes its state to docked.

CDockingManager::m_nTimeOutBeforeDockingBarDock
Specifies the time, in milliseconds, before a docking pane is docked in immediate docking mode.

static UINT m_nTimeOutBeforeDockingBarDock;

Remarks
Before a pane is docked, the framework waits the specified length of time. This prevents the pane from being
accidentally docked to a location while the user is still dragging it.

CDockingManager::m_nTimeOutBeforeToolBarDock
Specifies the time, in milliseconds, before a toolbar is docked to the main frame window.

static UINT m_nTimeOutBeforeToolBarDock;

Remarks
Before a toolbar is docked, the framework waits the specified length of time. This prevents the toolbar from
being accidentally docked to a location while the user is still dragging it.

CDockingManager::OnActivateFrame
Called by the framework when the frame window is made active or is deactivated.

virtual void OnActivateFrame(BOOL bActivate);

Parameters
bActivate
[in] If TRUE, the frame window is made active; if FALSE, the frame window is deactivated.

CDockingManager::OnClosePopupMenu
Called by the framework when an active pop-up menu processes a WM_DESTROY message.
void OnClosePopupMenu();

Remarks
The framework sends a WM_DESTROY message when it is about to close the current main window. Override
this method to handle notifications from CMFCPopupMenu objects that belong to the frame window when a
CMFCPopupMenu object processes a WM_DESTROY message.

CDockingManager::OnMoveMiniFrame
Called by the framework to move a mini-frame window.

virtual BOOL OnMoveMiniFrame(CWnd* pFrame);

Parameters
pFrame
[in] A pointer to a mini-frame window.
Return Value
TRUE if the method succeeds; otherwise FALSE.

CDockingManager::OnPaneContextMenu
Called by the framework when it builds a menu that has a list of panes.

void OnPaneContextMenu(CPoint point);

Parameters
point
[in] Specifies the location of the menu.

CDockingManager::PaneFromPoint
Returns the pane that contains the given point.

virtual CBasePane* PaneFromPoint(


CPoint point,
int nSensitivity,
bool bExactBar = false,
CRuntimeClass* pRTCBarType = NULL,
BOOL bCheckVisibility = FALSE,
const CBasePane* pBarToIgnore = NULL) const;

virtual CBasePane* PaneFromPoint(


CPoint point,
int nSensitivity,
DWORD& dwAlignment,
CRuntimeClass* pRTCBarType = NULL,
const CBasePane* pBarToIgnore = NULL) const;

Parameters
point
[in] Specifies the point, in screen coordinates, to check.
nSensitivity
[in] The value to inflate the window rectangle of each checked pane. A pane satisfies the search criteria if the
given point is in this inflated region.
bExactBar
[in] TRUE to ignore the nSensitivity parameter; otherwise, FALSE.
pRTCBarType
[in] If not NULL, the method searches only the panes of the specified type.
bCheckVisibility
[in] TRUE to check only visible panes; otherwise, FALSE.
dwAlignment
[out] If a pane is found at the specified point, this parameter contains the side of the pane that was closest to the
specified point. For more information, see the Remarks section.
pBarToIgnore
[in] If not NULL, the method ignores panes specified by this parameter.
Return Value
The CBasePane-derived object that contains the given point, or NULL if no pane was found.
Remarks
When the function returns and a pane was found, dwAlignment contains the alignment of the specified point.
For example, if the point was closest to the top of the pane, dwAlignment is set to CBRS_ALIGN_TOP.

CDockingManager::ProcessPaneContextMenuCommand
Called by the framework to select or to clear a check box for the specified command and recalculate the layout
of a shown pane.

BOOL ProcessPaneContextMenuCommand(
UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);

Parameters
nID
[in] The id of a control bar in the menu.
nCode
[in] The command notification code.
pExtra
[in] A pointer to void that is casted to a pointer to CCmdUI if nCode is CN_UPDATE_COMMAND_UI.
pHandlerInfo
[in] A pointer to an info structure. This parameter is not used.
Return Value
TRUE if pEXtra is not NULL and nCode equals CN_UPDATE_COMMAND_UI, or if there is a control bar with the
specified nID.

CDockingManager::RecalcLayout
Recalculates the internal layout of the controls present in the list of controls.

virtual void RecalcLayout(BOOL bNotify = TRUE);

Parameters
bNotify
[in] This parameter is not used.

CDockingManager::ReleaseEmptyPaneContainers
Releases the empty pane containers.

void ReleaseEmptyPaneContainers();

CDockingManager::RemoveHiddenMDITabbedBar
Removes the specified hidden bar pane.

void RemoveHiddenMDITabbedBar(CDockablePane* pBar);

Parameters
pBar
[in] A pointer to a bar pane to remove.

CDockingManager::RemoveMiniFrame
Removes a specified frame from the list of mini frames.

virtual BOOL RemoveMiniFrame(CPaneFrameWnd* pWnd);

Parameters
pWnd
[in] A pointer to a frame to remove.
Return Value
TRUE if the specified frame is removed; FALSE otherwise.

CDockingManager::RemovePaneFromDockManager
Unregisters a pane and removes it from the list in the docking manager.

void RemovePaneFromDockManager(
CBasePane* pWnd,
BOOL bDestroy,
BOOL bAdjustLayout,
BOOL bAutoHide = FALSE,
CBasePane* pBarReplacement = NULL);

Parameters
pWnd
[in] A pointer to a pane to be removed.
bDestroy
[in] If TRUE, the removed pane is destroyed.
bAdjustLayout
[in] If TRUE, adjust the docking layout immediately.
bAutoHide
[in] If TRUE, the pane is removed from the list of autohide bars. If FALSE, the pane is removed from the list of
regular panes.
pBarReplacement
[in] A pointer to a pane that replaces the removed pane.

CDockingManager::ReplacePane
Replaces one pane with another.

BOOL ReplacePane(
CDockablePane* pOriginalBar,
CDockablePane* pNewBar);

Parameters
pOriginalBar
[in] A pointer to the original pane.
pNewBar
[in] A pointer to the pane that replaces the original pane.
Return Value
TRUE if the pane is successfully replaced; FALSE otherwise.

CDockingManager::ResortMiniFramesForZOrder
Resorts the frames in the list of mini frames.

void ResortMiniFramesForZOrder();

CDockingManager::SaveState
Saves the docking manager's state to the registry.

virtual BOOL SaveState(


LPCTSTR lpszProfileName = NULL,
UINT uiID = (UINT) -1);

Parameters
lpszProfileName
[in] A path to a registry key.
uiID
[in] The docking manager ID.
Return Value
TRUE if the state was saved successfully; otherwise FALSE.
Remarks
Saving the docking manager's state to the registry involves saving the states of the control bars, the states of the
autohide bars, and the states of the mini frames present in the docking manager.

CDockingManager::SendMessageToMiniFrames
Sends the specified message to all mini frames.

BOOL SendMessageToMiniFrames(
UINT uMessage,
WPARAM wParam = 0,
LPARAM lParam = 0);

Parameters
uMessage
[in] The message to be sent.
wParam
[in] Additional message dependent information.
lParam
[in] Additional message dependent information.
Return Value
TRUE always.

CDockingManager::Serialize
Writes the docking manager to an archive.

void Serialize(CArchive& ar);

Parameters
ar
[in] A reference to an archive object.
Remarks
Writing the docking manager to an archive involves determining the number of docking control bars and
sliders, and writing the control bars, the mini frames, the autohide bars, and the MDI tabbed bars to the archive.

CDockingManager::SetAutohideZOrder
Sets the size, width, and height of the control bars and the specified pane.

void SetAutohideZOrder(CDockablePane* pAHDockingBar);

Parameters
pAHDockingBar
[in] A pointer to a dockable pane.
CDockingManager::SetDockingMode
Sets the docking mode.

static void SetDockingMode(


AFX_DOCK_TYPE dockMode,
AFX_SMARTDOCK_THEME theme = AFX_SDT_DEFAULT);

Parameters
dockMode
Specifies the new docking mode. For more information, see the Remarks section.
theme
Specifies the theme to be used for smart docking markers. It can be one of the following enumerated values:
AFX_SDT_DEFAULT, AFX_SDT_VS2005, AFX_SDT_VS2008.
Remarks
Call this static method to set the docking mode.
dockMode can be one of following values:
DT_STANDARD - Standard docking mode as implemented in Visual Studio .NET 2003. Panes are dragged
without a dragging context.
DT_IMMEDIATE - Immediate docking mode as implemented in Microsoft Visio. Panes are dragged with a
dragging context, but no markers are displayed.
DT_SMART - Smart docking mode as implemented in Visual Studio 2005. Panes are dragged with a
dragging context and smart markers are displayed that show where the pane can be docked.

CDockingManager::SetDockState
Sets the docking state of the control bars, the mini frames, and the autohide bars.

virtual void SetDockState();

CDockingManager::SetPrintPreviewMode
Sets the print preview mode of the bars that are displayed in the print preview.

void SetPrintPreviewMode(
BOOL bPreview,
CPrintPreviewState* pState);

Parameters
bPreview
[in] TRUE if print preview mode is set; FALSE otherwise.
pState
[in] A pointer to a preview state. This parameter is not used.

CDockingManager::SetSmartDockingParams
Sets the parameters that define the behavior of smart docking.
static void SetSmartDockingParams(CSmartDockingInfo& params);

Parameters
params
[in, out] Defines the parameters for smart docking.
Remarks
Call this method if you want to customize the appearance, color, or shape of the smart docking markers.
To use the default look for smart docking markers, pass an uninitialized instance of CSmartDockingInfo Class to
params.

CDockingManager::ShowDelayShowMiniFrames
Shows or hides the windows of the mini frames.

void ShowDelayShowMiniFrames(BOOL bshow);

Parameters
bShow
[in] TRUE to make the window of the shown frame active; FALSE to hide the window of the frame.

CDockingManager::ShowPanes
Shows or hides the panes of the control and autohide bars.

virtual BOOL ShowPanes(BOOL bShow);

Parameters
bShow
[in] TRUE to show the panes; FALSE to hide the panes.
Return Value
Always FALSE.

CDockingManager::StartSDocking
Starts the smart docking of the specified window according to the alignment of the smart docking manager.

void StartSDocking(CWnd* pDockingWnd);

Parameters
pDockingWnd
[in] A pointer to a window to dock.

CDockingManager::StopSDocking
Stops smart docking.
void StopSDocking();

CDockingManager::GetSmartDockingTheme
A static method that returns a theme used to display smart docking markers.

static AFX_SMARTDOCK_THEME __stdcall GetSmartDockingTheme();

Return Value
Returns one of the following enumerated values: AFX_SDT_DEFAULT, AFX_SDT_VS2005, AFX_SDT_VS2008.
Remarks

See also
Hierarchy Chart
Classes
CObject Class
CFrameWndEx Class
CDockablePane Class
CPaneFrameWnd Class
CDockingPanesRow Class
4/21/2020 • 3 minutes to read • Edit Online

Manages a list of panes that are located in the same horizontal or vertical row (column) of a dock site.
For more detail see the source code located in the VC\atlmfc\src\mfc folder of your Visual Studio installation.

Syntax
class CDockingPanesRow : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDockingPanesRow::CDockingPanesRow Default constructor.

Public Methods
NAME DESC RIP T IO N

CDockingPanesRow::AddPane

CDockingPanesRow::AddPaneFromRow

CDockingPanesRow::ArrangePanes Arranges the panes in a row according to the specified


margin and spacing parameters.

CDockingPanesRow::CalcFixedLayout

CDockingPanesRow::Create

CDockingPanesRow::ExpandStretchedPanes

CDockingPanesRow::ExpandStretchedPanesRect

CDockingPanesRow::FixupVirtualRects

CDockingPanesRow::GetAvailableLength

CDockingPanesRow::GetAvailableSpace

CDockingPanesRow::GetClientRect

CDockingPanesRow::GetDockSite

CDockingPanesRow::GetExtraSpace
NAME DESC RIP T IO N

CDockingPanesRow::GetGroupFromPane

CDockingPanesRow::GetID

CDockingPanesRow::GetMaxPaneSize

CDockingPanesRow::GetPaneCount

CDockingPanesRow::GetPaneList

CDockingPanesRow::GetRowAlignment

CDockingPanesRow::GetRowHeight

CDockingPanesRow::GetRowOffset

CDockingPanesRow::GetVisibleCount

CDockingPanesRow::GetWindowRect

CDockingPanesRow::HasPane

CDockingPanesRow::IsEmpty

CDockingPanesRow::IsExclusiveRow

CDockingPanesRow::IsHorizontal

CDockingPanesRow::IsVisible

CDockingPanesRow::Move

CDockingPanesRow::MovePane

CDockingPanesRow::OnResizePane

CDockingPanesRow::RedrawAll

CDockingPanesRow::RemovePane

CDockingPanesRow::ReplacePane

CDockingPanesRow::RepositionPanes

CDockingPanesRow::Resize

CDockingPanesRow::ResizeByPaneDivider

CDockingPanesRow::ScreenToClient
NAME DESC RIP T IO N

CDockingPanesRow::SetExtra

CDockingPanesRow::ShowDockSiteRow

CDockingPanesRow::ShowPane

CDockingPanesRow::UpdateVisibleState

Remarks
CDockingPanesRow objects are created internally by dock site objects.

Example
The following example demonstrates how to get a CDockingPanesRow object from a CMFCAutoHideBar object.

CMFCAutoHideBar *pParentBar = new CMFCAutoHideBar();


CDockingPanesRow *pParentRow = pParentBar->GetDockSiteRow();

Inheritance Hierarchy
CObject
CDockingPanesRow

Requirements
Header : afxDockingPanesRow.h

CDockingPanesRow::AddPane
virtual void AddPane(
CPane* pControlBar,
AFX_DOCK_METHOD dockMethod,
LPCRECT lpRect = NULL,
BOOL bAddLast = FALSE);

Parameters
[in] pControlBar
[in] dockMethod
[in] lpRect
[in] bAddLast
Remarks

CDockingPanesRow::AddPaneFromRow
virtual void AddPaneFromRow(
CPane* pControlBar,
AFX_DOCK_METHOD dockMethod);

Parameters
[in] pControlBar
[in] dockMethod
Remarks

CDockingPanesRow::ArrangePanes
Arranges docking panes in a row according to the specified margin and spacing parameters.

virtual void ArrangePanes(


int nMargin,
int nSpacing);

Parameters
nMargin
[in] Specifies the offset, in pixels, of the first pane from the upper-left corner of the row.
nSpacing
[in] Specifies the spacing, in pixels, between panes.
Remarks
Call this method to arrange panes in the row where they will dock. After calling this method, you must call
CDockingPanesRow::FixupVirtualRects(FALSE, NULL) .

CDockingPanesRow::CalcFixedLayout
virtual CSize CalcFixedLayout(
BOOL bStretch,
BOOL bHorz);

Parameters
[in] bStretch
[in] bHorz
Return Value
Remarks

CDockingPanesRow::CDockingPanesRow
CDockingPanesRow(
CDockSite* pParentDockBar,
int nOffset,
int nHeight);

Parameters
[in] pParentDockBar
[in] nOffset
[in] nHeight
Remarks

CDockingPanesRow::Create
virtual BOOL Create();

Return Value
Remarks

CDockingPanesRow::ExpandStretchedPanes
void ExpandStretchedPanes();

Remarks

CDockingPanesRow::ExpandStretchedPanesRect
void ExpandStretchedPanesRect();

Remarks

CDockingPanesRow::FixupVirtualRects
void FixupVirtualRects(
bool bMoveBackToVirtualRect,
CPane* pBarToExclude = NULL);

Parameters
[in] bMoveBackToVirtualRect
[in] pBarToExclude
Remarks

CDockingPanesRow::GetAvailableLength
virtual int GetAvailableLength(BOOL bUseVirtualRect = FALSE) const;

Parameters
[in] bUseVirtualRect
Return Value
Remarks

CDockingPanesRow::GetAvailableSpace
virtual void GetAvailableSpace(CRect& rect);

Parameters
[in] rect
Remarks

CDockingPanesRow::GetClientRect
void GetClientRect(CRect& rect) const;

Parameters
[in] rect
Remarks

CDockingPanesRow::GetDockSite
CDockSite* GetDockSite() const;

Return Value
Remarks

CDockingPanesRow::GetExtraSpace
int GetExtraSpace() const;

Return Value
Remarks

CDockingPanesRow::GetGroupFromPane
void GetGroupFromPane(
CPane* pBar,
CObList& lst);

Parameters
[in] pBar
[in] lst
Remarks

CDockingPanesRow::GetID
int GetID() const;

Return Value
Remarks

CDockingPanesRow::GetMaxPaneSize
int GetMaxPaneSize(BOOL bSkipHiddenBars = TRUE) const;

Parameters
[in] bSkipHiddenBars
Return Value
Remarks

CDockingPanesRow::GetPaneCount
int GetPaneCount() const;

Return Value
Remarks

CDockingPanesRow::GetPaneList
const CObList& GetPaneList() const;

Return Value
Remarks

CDockingPanesRow::GetRowAlignment
DWORD GetRowAlignment() const;

Return Value
Remarks

CDockingPanesRow::GetRowHeight
int GetRowHeight() const;

Return Value
Remarks

CDockingPanesRow::GetRowOffset
int GetRowOffset() const;

Return Value
Remarks
CDockingPanesRow::GetVisibleCount
virtual int GetVisibleCount();

Return Value
Remarks

CDockingPanesRow::GetWindowRect
void GetWindowRect(CRect& rect) const;

Parameters
[in] rect
Remarks

CDockingPanesRow::HasPane
BOOL HasPane(CBasePane* pControlBar);

Parameters
[in] pControlBar
Return Value
Remarks

CDockingPanesRow::IsEmpty
virtual BOOL IsEmpty() const;

Return Value
Remarks

CDockingPanesRow::IsExclusiveRow
virtual BOOL IsExclusiveRow() const;

Return Value
Remarks

CDockingPanesRow::IsHorizontal
bool IsHorizontal() const;

Return Value
Remarks
CDockingPanesRow::IsVisible
virtual BOOL IsVisible() const;

Return Value
Remarks

CDockingPanesRow::Move
virtual void Move(int nOffset);

Parameters
[in] nOffset
Remarks

CDockingPanesRow::MovePane
void MovePane(
CPane* pControlBar,
CPoint ptOffset,
BOOL bSwapControlBars,
HDWP& hdwp);

void MovePane(
CPane* pControlBar,
CRect rectTarget,
HDWP& hdwp);

void MovePane(
CPane* pControlBar,
int nOffset,
bool bForward,
HDWP& hdwp);

void MovePane(
CPane* pControlBar,
int nAbsolutOffset,
HDWP& hdwp);

Parameters
[in] pControlBar
[in] ptOffset
[in] bSwapControlBars
[in] hdwp
[in] rectTarget
[in] nOffset
[in] bForward
[in] nAbsolutOffset
Remarks
CDockingPanesRow::OnResizePane
virtual void OnResizePane(CBasePane* pControlBar);

Parameters
[in] pControlBar
Remarks

CDockingPanesRow::RedrawAll
void RedrawAll();

Remarks

CDockingPanesRow::RemovePane
virtual void RemovePane(CPane* pControlBar);

Parameters
[in] pControlBar
Remarks

CDockingPanesRow::ReplacePane
virtual BOOL ReplacePane(
CPane* pBarOld,
CPane* pBarNew);

Parameters
[in] pBarOld
[in] pBarNew
Return Value
Remarks

CDockingPanesRow::RepositionPanes
virtual void RepositionPanes(
CRect& rectNewParentBarArea,
UINT nSide = (UINT)-1,
BOOL bExpand = FALSE,
int nOffset = 0);

Parameters
[in] rectNewParentBarArea
[in] nSide
[in] bExpand
[in] nOffset
Remarks

CDockingPanesRow::Resize
virtual int Resize(int nOffset);

Parameters
[in] nOffset
Return Value
Remarks

CDockingPanesRow::ResizeByPaneDivider
virtual int ResizeByPaneDivider(int /*ignored*/);

Parameters
[in] ignored
Return Value
Remarks

CDockingPanesRow::ScreenToClient
void ScreenToClient(CRect& rect) const;

Parameters
[in] rect
Remarks

CDockingPanesRow::SetExtra
void SetExtra(
int nExtraSpace,
AFX_ROW_ALIGNMENT rowExtraAlign);

Parameters
[in] nExtraSpace
[in] rowExtraAlign
Remarks

CDockingPanesRow::ShowDockSiteRow
virtual void ShowDockSiteRow(
BOOL bShow,
BOOL bDelay);

Parameters
[in] bShow
[in] bDelay
Remarks

CDockingPanesRow::ShowPane
virtual BOOL ShowPane(
CPane* pControlBar,
BOOL bShow,
BOOL bDelay = FALSE);

Parameters
[in] pControlBar
[in] bShow
[in] bDelay
Return Value
Remarks

CDockingPanesRow::UpdateVisibleState
virtual void UpdateVisibleState(BOOL bDelay);

Parameters
[in] bDelay
Remarks

See also
Hierarchy Chart
Classes
CObject Class
CDockSite Class
CPane Class
CDockSite Class
4/21/2020 • 5 minutes to read • Edit Online

For more detail see the source code located in the VC\atlmfc\src\mfc folder of your Visual Studio installation.
Provides functionality for arranging panes that are derived from the CPane Class into sets of rows.

Syntax
class CDockSite: public CBasePane

Members
Public Methods
NAME DESC RIP T IO N

CDockSite::AddRow

CDockSite::AdjustDockingLayout (Overrides CBasePane::AdjustDockingLayout.)

CDockSite::AdjustLayout (Overrides CBasePane::AdjustLayout.)

CDockSite::AlignDockSite

CDockSite::CalcFixedLayout (Overrides CBasePane::CalcFixedLayout.)

CDockSite::CanAcceptPane (Overrides CBasePane::CanAcceptPane.)

CDockSite::CreateEx (Overrides CBasePane::CreateEx.)

CDockSite::CreateRow

CDockSite::DockPane (Overrides CBasePane::DockPane.)

CDockSite::DoesAllowDynInsertBefore (Overrides CBasePane::DoesAllowDynInsertBefore.)

CDockSite::FindRowIndex

CDockSite::FixupVirtualRects

CDockSite::GetDockSiteID

CDockSite::GetDockSiteRowsList

CDockSite::IsAccessibilityCompatible (Overrides CBasePane::IsAccessibilityCompatible .)

CDockSite::IsDragMode
NAME DESC RIP T IO N

CDockSite::IsLastRow

CDockSite::IsRectWithinDockSite

CDockSite::IsResizable (Overrides CBasePane::IsResizable.)

CDockSite::MovePane

CDockSite::OnInsertRow

CDockSite::OnRemoveRow

CDockSite::OnResizeRow

CDockSite::OnSetWindowPos

CDockSite::OnShowRow

CDockSite::OnSizeParent

CDockSite::PaneFromPoint Returns a pane that is docked in the dock site at the point
specified by the given parameter.

CDockSite::DockPaneLeftOf Docks a pane to the left of another pane.

CDockSite::FindPaneByID Returns the pane that is identified by the given ID.

CDockSite::GetPaneList Returns a list of panes that are docked at the dock site.

CDockSite::RectSideFromPoint

CDockSite::RemovePane

CDockSite::RemoveRow

CDockSite::ReplacePane

CDockSite::RepositionPanes

CDockSite::ResizeDockSite

CDockSite::ResizeRow

CDockSite::ShowPane Shows the pane.

CDockSite::ShowRow

CDockSite::SwapRows

Remarks
The framework creates CDockSite objects automatically when you call CFrameWndEx::EnableDocking. Dock site
windows are positioned at the edge of the client area on the main frame window.
You usually do not have to call the services provided by the dock site because CFrameWndEx Class handles these
services.

Example
The following example demonstrates how to create an object of the CDockSite class.

AFX_DOCKSITE_INFO info;
CDockSite *pDockBar = (CDockSite*)info.pDockBarRTC->CreateObject();

Inheritance Hierarchy
CObject
└ CCmdTarget
└ CWnd
└ CBasePane
└ CDockSite

Requirements
Header : afxDockSite.h

CDockSite::AddRow
CDockingPanesRow* AddRow(
POSITION pos,
int nHeight);

Parameters
[in] pos
[in] nHeight
Return Value
Remarks

CDockSite::AdjustDockingLayout
virtual void AdjustDockingLayout();

Remarks

CDockSite::AdjustLayout
virtual void AdjustLayout();

Remarks
CDockSite::AlignDockSite
void AlignDockSite(
const CRect& rectToAlignBy,
CRect& rectResult,
BOOL bMoveImmediately);

Parameters
[in] rectToAlignBy
[in] rectResult
[in] bMoveImmediately
Remarks

CDockSite::CalcFixedLayout
virtual CSize CalcFixedLayout(
BOOL bStretch,
BOOL bHorz);

Parameters
[in] bStretch
[in] bHorz
Return Value
Remarks

CDockSite::CanAcceptPane
virtual BOOL CanAcceptPane(const CBasePane* pBar) const;

Parameters
[in] pBar
Return Value
Remarks

CDockSite::CreateEx
virtual BOOL CreateEx(
DWORD dwStyleEx,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
DWORD dwControlBarStyle,
CCreateContext* pContext = NULL);

Parameters
[in] dwStyleEx
[in] dwStyle
[in] rect
[in] pParentWnd
[in] dwControlBarStyle
[in] pContext
Return Value
Remarks

CDockSite::CreateRow
virtual CDockingPanesRow* CreateRow(
CDockSite* pParentDockBar,
int nOffset,
int nRowHeight);

Parameters
[in] pParentDockBar
[in] nOffset
[in] nRowHeight
Return Value
Remarks

CDockSite::DockPane
virtual void DockPane(
CPane* pWnd,
AFX_DOCK_METHOD dockMethod,
LPCRECT lpRect = NULL);

Parameters
[in] pWnd
[in] dockMethod
[in] lpRect
Remarks

CDockSite::DockPaneLeftOf
Docks a pane to the left of another pane.

virtual BOOL DockPaneLeftOf(


CPane* pBarToDock,
CPane* pTargetBar);

Parameters
pBarToDock
[in, out] A pointer to the pane to be docked to the left of pTargetBar.
pTargetBar
[in, out] A pointer to the target pane.
Return Value
TRUE if the pane is docked successfully; otherwise, FALSE.
Remarks

CDockSite::DoesAllowDynInsertBefore
virtual BOOL DoesAllowDynInsertBefore() const;

Return Value
Remarks

CDockSite::FindPaneByID
Returns the pane with the given ID.

CPane* FindPaneByID(UINT nID);

Parameters
nID
[in] The command ID of the pane to be found.
Return Value
A pointer to the pane with the specified command ID, or NULL if the pane is not found.
Remarks

CDockSite::FindRowIndex
int FindRowIndex(CDockingPanesRow* pRow);

Parameters
[in] pRow
Return Value
Remarks

CDockSite::FixupVirtualRects
virtual void FixupVirtualRects();

Remarks

CDockSite::GetDockSiteID
virtual UINT GetDockSiteID() const;

Return Value
Remarks

CDockSite::GetDockSiteRowsList
const CObList& GetDockSiteRowsList() const;

Return Value
Remarks

CDockSite::GetPaneList
Returns a list of panes that are docked in the dock site.

const CObList& GetPaneList() const;

Return Value
A read-only reference to the list of panes currently docked in the docking bar.

CDockSite::IsAccessibilityCompatible
virtual BOOL IsAccessibilityCompatible();

Return Value
Remarks

CDockSite::IsDragMode
virtual BOOL IsDragMode() const;

Return Value
Remarks

CDockSite::IsLastRow
bool IsLastRow(CDockingPanesRow* pRow) const;

Parameters
[in] pRow
Return Value
Remarks

CDockSite::IsRectWithinDockSite
BOOL IsRectWithinDockSite(
CRect rect,
CPoint& ptDelta);

Parameters
[in] rect
[in] ptDelta
Return Value
Remarks

CDockSite::IsResizable
virtual BOOL IsResizable() const;

Return Value
Remarks

CDockSite::MovePane
virtual BOOL MovePane(
CPane* pWnd,
UINT nFlags,
CPoint ptOffset);

Parameters
[in] pWnd
[in] nFlags
[in] ptOffset
Return Value
Remarks

CDockSite::OnInsertRow
virtual void OnInsertRow(POSITION pos);

Parameters
[in] pos
Remarks

CDockSite::OnRemoveRow
virtual void OnRemoveRow(
POSITION pos,
BOOL bByShow = FALSE);
Parameters
[in] pos
[in] bByShow
Remarks

CDockSite::OnResizeRow
virtual int OnResizeRow(
CDockingPanesRow* pRowToResize,
int nOffset);

Parameters
[in] pRowToResize
[in] nOffset
Return Value
Remarks

CDockSite::OnSizeParent
virtual void OnSizeParent(
CRect& rectAvailable,
UINT nSide,
BOOL bExpand,
int nOffset);

Parameters
[in] rectAvailable
[in] nSide
[in] bExpand
[in] nOffset
Remarks

CDockSite::OnSetWindowPos
virtual BOOL OnSetWindowPos(
const CWnd* pWndInsertAfter,
const CRect& rectWnd,
UINT nFlags);

Parameters
[in] pWndInsertAfter
[in] rectWnd
[in] nFlags
Return Value
Remarks
CDockSite::OnShowRow
virtual void OnShowRow(
POSITION pos,
BOOL bShow);

Parameters
[in] pos
[in] bShow
Remarks

CDockSite::PaneFromPoint
Returns a pane that is docked in the dock site at the point specified by the given parameter.

virtual CPane* PaneFromPoint(CPoint pt);

Parameters
pt
[in] A point, in screen coordinates, for the pane to retrieve.
Return Value
A pointer to the pane located at the specified point or NULL if no pane was present at the specified point.
Remarks

CDockSite::RectSideFromPoint
static int __stdcall RectSideFromPoint(
const CRect& rect,
const CPoint& point);

Parameters
[in] rect
[in] point
Return Value
Remarks

CDockSite::RemovePane
virtual void RemovePane(
CPane* pWnd,
AFX_DOCK_METHOD dockMethod);

Parameters
[in] pWnd
[in] dockMethod
Remarks

CDockSite::RemoveRow
void RemoveRow(CDockingPanesRow* pRow);

Parameters
[in] pRow
Remarks

CDockSite::ReplacePane
BOOL ReplacePane(
CPane* pOldBar,
CPane* pNewBar);

Parameters
[in] pOldBar
[in] pNewBar
Return Value
Remarks

CDockSite::RepositionPanes
virtual void RepositionPanes(CRect& rectNewClientArea);

Parameters
[in] rectNewClientArea
Remarks

CDockSite::ResizeDockSite
void ResizeDockSite(
int nNewWidth,
int nNewHeight);

Parameters
[in] nNewWidth
[in] nNewHeight
Remarks

CDockSite::ResizeRow
int ResizeRow(
CDockingPanesRow* pRow,
int nNewSize,
BOOL bAdjustLayout = TRUE);

Parameters
[in] pRow
[in] nNewSize
[in] bAdjustLayout
Return Value
Remarks

CDockSite::ShowPane
Shows the pane.

virtual BOOL ShowPane(


CBasePane* pBar,
BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
pBar
[in, out] A pointer to the pane to be shown or hidden.
bShow
[in] TRUE to specify that the pane is to be shown; FALSE to specify that the pane is to be hidden.
bDelay
[in] TRUE to specify that the layout of the pane should be delayed until after the pane is shown; otherwise, FALSE.
bActivate
[in] This parameter is not used.
Return Value
TRUE if the pane was shown or hidden successfully. FALSE if the specified pane does not belong to this dock site.
Remarks
Call this method to show or hide docked panes. Normally, you do not have to call CDockSite::ShowPane directly,
because it is called by the parent frame window or by the base pane.

CDockSite::ShowRow
void ShowRow(
CDockingPanesRow* pRow,
BOOL bShow,
BOOL bAdjustLayout);

Parameters
[in] pRow
[in] bShow
[in] bAdjustLayout
Remarks

CDockSite::SwapRows
void SwapRows(
CDockingPanesRow* pFirstRow,
CDockingPanesRow* pSecondRow);

Parameters
[in] pFirstRow
[in] pSecondRow
Remarks

See also
Hierarchy Chart
Classes
CBasePane Class
CDockState Class
4/21/2020 • 3 minutes to read • Edit Online

A serialized CObject class that loads, unloads, or clears the state of one or more docking control bars in persistent
memory (a file).

Syntax
class CDockState : public CObject

Members
Public Methods
NAME DESC RIP T IO N

CDockState::Clear Clears the dock state information.

CDockState::GetVersion Retrieves the version number of the stored bar state.

CDockState::LoadState Retrieves state information from the registry or .INI file.

CDockState::SaveState Saves state information to the registry or INI file.

Public Data Members


NAME DESC RIP T IO N

CDockState::m_arrBarInfo Array of pointers to the stored dock state information with


one entry for each control bar.

Remarks
The dock state includes the size and position of the bar and whether or not it is docked. When retrieving the stored
dock state, CDockState checks the bar's position and, if the bar is not visible with the current screen settings,
CDockState scales the bar's position so that it is visible. The main purpose of CDockState is to hold the entire state
of a number of control bars and to allow that state to be saved and loaded either to the registry, the application's
.INI file, or in binary form as part of a CArchive object's contents.
The bar can be any dockable control bar, including a toolbar, status bar, or dialog bar. CDockState objects are
written and read to or from a file via a CArchive object.
CFrameWnd::GetDockState retrieves the state information of all the frame window's CControlBar objects and puts
it into the CDockState object. You can then write the contents of the CDockState object to storage with Serialize or
CDockState::SaveState. If you later want to restore the state of the control bars in the frame window, you can load
the state with Serialize or CDockState::LoadState, then use CFrameWnd::SetDockState to apply the saved state to
the frame window's control bars.
For more information on docking control bars, see the articles Control Bars, Toolbars: Docking and Floating, and
Frame Windows.

Inheritance Hierarchy
CObject
CDockState

Requirements
Header : afxadv.h

CDockState::Clear
Call this function to clear all docking information stored in the CDockState object.

void Clear();

Remarks
This includes not only whether the bar is docked or not, but the bar's size and position and whether or not it is
visible.

CDockState::GetVersion
Call this function to retrieve the version number of the stored bar state.

DWORD GetVersion();

Return Value
1 if the stored bar information is older than current bar state; 2 if the stored bar information is the same as the
current bar state.
Remarks
Version support enables a revised bar to add new persistent properties and still be able to detect and load the
persistent state created by an earlier version of the bar.

CDockState::LoadState
Call this function to retrieve state information from the registry or .INI file.

void LoadState(LPCTSTR lpszProfileName);

Parameters
lpszProfileName
Points to a null-teminated string that specifies the name of a section in the initialization file or a key in the
Windows registry where state information is stored.
Remarks
The profile name is the section of the application's .INI file or the registry that contains the bars' state information.
You can save control bar state information to the registry or .INI file with SaveState .
CDockState::m_arrBarInfo
A CPtrArray object that is an array of pointers to the stored control bar information for each control bar that has
saved state information in the CDockState object.

CPtrArray m_arrBarInfo;

CDockState::SaveState
Call this function to save the state information to the registry or .INI file.

void SaveState(LPCTSTR lpszProfileName);

Parameters
lpszProfileName
Points to a null-teminated string that specifies the name of a section in the initialization file or a key in the
Windows registry where state information is stored.
Remarks
The profile name is the section of the application's .INI file or the registry that contains the control bar's state
information. SaveState also saves the current screen size. You can retrieve control bar information from the
registry or .INI file with LoadState .

See also
CObject Class
Hierarchy Chart
CDocObjectServer Class
4/21/2020 • 3 minutes to read • Edit Online

Implements the additional OLE interfaces needed to make a normal COleDocument server into a full DocObject
server: IOleDocument , IOleDocumentView , IOleCommandTarget , and IPrint .

Syntax
class CDocObjectServer : public CCmdTarget

Members
Public Constructors
NAME DESC RIP T IO N

CDocObjectServer::CDocObjectServer Constructs a CDocObjectServer object.

Public Methods
NAME DESC RIP T IO N

CDocObjectServer::ActivateDocObject Activates the document object server, but does not show it.

Protected Methods
NAME DESC RIP T IO N

CDocObjectServer::OnActivateView Displays the DocObject view.

CDocObjectServer::OnApplyViewState Restores the state of the DocObject view.

CDocObjectServer::OnSaveViewState Saves the state of the DocObject view.

Remarks
CDocObjectServer is derived from CCmdTarget and works closely with COleServerDoc to expose the interfaces.
A DocObject server document can contain CDocObjectServerItem objects, which represent the server interface to
DocObject items.
To customize your DocObject server, derive your own class from CDocObjectServer and override its view setup
functions, OnActivateView, OnApplyViewState, and OnSaveViewState. You will need to provide a new instance of
your class in response to framework calls.
For further information on DocObjects, see CDocObjectServerItem and COleCmdUI in the MFC Reference.

Inheritance Hierarchy
CObject
CCmdTarget
CDocObjectServer

Requirements
Header : afxdocob.h

CDocObjectServer::ActivateDocObject
Call this function to activate (but not show) the document object server.

void ActivateDocObject();

Remarks
ActivateDocObject calls IOleDocumentSite 's ActivateMe method, but does not show the view because it waits for
specific instructions on how to set up and display the view, given in the call to
CDocObjectServer::OnActivateView.
Together, ActivateDocObject and OnActivateView activate and display the DocObject view. DocObject activation
differs from other kinds of OLE in-place activation. DocObject activation bypasses displaying in-place hatch
borders and object adornments (such as sizing handles), ignores object extent functions, and draws scroll bars
within the view rectangle as opposed to drawing them outside that rectangle (as in normal in-place activation).

CDocObjectServer::CDocObjectServer
Constructs and initializes a CDocObjectServer object.

explicit CDocObjectServer(
COleServerDoc* pOwner,
LPOLEDOCUMENTSITE pDocSite = NULL);

Parameters
pOwner
A pointer to the client site document that is the client for the DocObject server.
pDocSite
A pointer to the IOleDocumentSite interface implemented by the container.
Remarks
When a DocObject is active, the client site OLE interface ( IOleDocumentSite ) is what allows the DocObject server
to communicate with its client (the container). When a DocObject server is activated, it first checks that the
container implements the IOleDocumentSite interface. If so, COleServerDoc::GetDocObjectServer is called to see if
the container supports DocObjects. By default, GetDocObjectServer returns NULL. You must override
COleServerDoc::GetDocObjectServer to construct a new CDocObjectServer object or a derived object of your own,
with pointers to the COleServerDoc container and its IOleDocumentSite interface as arguments to the constructor.

CDocObjectServer::OnActivateView
Call this function to display the DocObject view.
virtual HRESULT OnActivateView();

Return Value
Returns an error or warning value. By default, returns NOERROR if successful; otherwise, E_FAIL.
Remarks
This function creates an in-place frame window, draws scrollbars within the view, sets up the menus the server
shares with its container, adds frame controls, sets the active object, then finally shows the in-place frame window
and sets the focus.

CDocObjectServer::OnApplyViewState
Override this function to restore the state of the DocObject view.

virtual void OnApplyViewState(CArchive& ar);

Parameters
ar
A CArchive object from which to serialize the view state.
Remarks
This function is called when the view is being displayed for the first time after its instantiation. OnApplyViewState
instructs a view to reinitialize itself according to the data in the CArchive object previously saved with
OnSaveViewState. The view must validate the data in the CArchive object because the container does not
attempt to interpret the view state data in any way.
You can use OnSaveViewState to store persistent information specific to your view's state. If you override
OnSaveViewState to store information, you will want to override OnApplyViewState to read that information and
apply it to your view when it is newly activated.

CDocObjectServer::OnSaveViewState
Override this function to save extra state information about your DocObject view.

virtual void OnSaveViewState(CArchive& ar);

Parameters
ar
A CArchive object to which the view state is serialized.
Remarks
Your state might include properties like the view type, zoom factor, insertion and selection point, and so on. The
container typically calls this function before deactivating the view. The saved state can later be restored through
OnApplyViewState.
You can use OnSaveViewState to store persistent information specific to your view's state. If you override
OnSaveViewState to store information, you will want to override OnApplyViewState to read that information and
apply it to your view when it is newly activated.

See also
CCmdTarget Class
Hierarchy Chart
CDocObjectServerItem Class
CDocObjectServerItem Class
3/27/2020 • 2 minutes to read • Edit Online

Implements OLE server verbs specifically for DocObject servers.

Syntax
class CDocObjectServerItem : public COleServerItem

Members
Protected Constructors
NAME DESC RIP T IO N

CDocObjectServerItem::CDocObjectServerItem Constructs a CDocObjectServerItem object.

Public Methods
NAME DESC RIP T IO N

CDocObjectServerItem::GetDocument Retrieves a pointer to the document that contains the item.

Protected Methods
NAME DESC RIP T IO N

CDocObjectServerItem::OnDoVerb Called to execute a verb.

CDocObjectServerItem::OnHide Throws an exception if the framework tries to hide a


DocObject item.

CDocObjectServerItem::OnShow Called by the framework to make the DocObject item in-


place active. If the item is not a DocObject, calls
COleServerItem::OnShow.

Remarks
CDocObjectServerItem defines overridable member functions: OnHide, OnDoVerb, and OnShow.
To use CDocObjectServerItem , assure that the OnGetEmbeddedItem override in your COleServerDoc -derived class
returns a new CDocObjectServerItem object. If you need to change any functionality in your item, you can create a
new instance of your own CDocObjectServerItem -derived class.
For further information on DocObjects, see CDocObjectServer and COleCmdUI in the MFC Reference.

Inheritance Hierarchy
CObject
CCmdTarget
CDocItem
COleServerItem
CDocObjectServerItem

Requirements
Header : afxdocob.h

CDocObjectServerItem::CDocObjectServerItem
Constructs a CDocObjectServerItem object.

CDocObjectServerItem(COleServerDoc* pServerDoc, BOOL bAutoDelete);

Parameters
pServerDoc
A pointer to the document that will contain the new DocObject item.
bAutoDelete
Indicates whether the object can be deleted when a link to it is released. Set the argument to FALSE if the
CDocObjectServerItem object is an integral part of your document's data. Set it to TRUE if the object is a
secondary structure used to identify a range in your document's data that can be deleted by the framework.

CDocObjectServerItem::GetDocument
Retrieves a pointer to the document that contains the item.

COleServerDoc* GetDocument() const;

Return Value
A pointer to the document that contains the item; NULL if the item is not part of a document.
Remarks
This allows access to the server document that you passed as an argument to the CDocObjectServerItem
constructor.

CDocObjectServerItem::OnDoVerb
Called by the framework to execute the specified verb.

virtual void OnDoVerb(LONG iVerb);

Parameters
iVerb
Specifies the verb to execute. For possible values, see IOleObject::DoVerb in the Windows SDK.
Remarks
The default implementation calls the OnShow member function if the item is a DocObject and the
OLEIVERB_INPLACEACTIVATE or OLEIVERB_SHOW is specified. If the item is not a DocObject or a different verb is
specified, the default implementation calls COleServerItem::OnDoVerb.

CDocObjectServerItem::OnHide
Called by the framework to hide the item.

virtual void OnHide();

Remarks
The default implementation throws an exception if the item is a DocObject. You cannot hide an active DocObject
item because it takes the whole view. You must deactivate the DocObject item to make it disappear. If the item is
not a DocObject, the default implementation calls COleServerItem::OnHide.

CDocObjectServerItem::OnShow
Called by the framework to instruct the server application to make the DocObject item in-place active.

virtual void OnShow();

Remarks
If the item is not a DocObject, the default implementation calls COleServerItem::OnShow. Override this function if
you want to perform special processing when opening a DocObject item.

See also
COleServerItem Class
Hierarchy Chart
CDocObjectServer Class
COleDocObjectItem Class
CDocTemplate Class
4/21/2020 • 15 minutes to read • Edit Online

An abstract base class that defines the basic functionality for document templates.

Syntax
class CDocTemplate : public CCmdTarget

Members
Protected Constructors
NAME DESC RIP T IO N

CDocTemplate::CDocTemplate Constructs a CDocTemplate object.

Public Methods
NAME DESC RIP T IO N

CDocTemplate::AddDocument Adds a document to a template.

CDocTemplate::CloseAllDocuments Closes all documents associated with this template.

CDocTemplate::CreateNewDocument Creates a new document.

CDocTemplate::CreateNewFrame Creates a new frame window containing a document and


view.

CDocTemplate::CreateOleFrame Creates an OLE-enabled frame window.

CDocTemplate::CreatePreviewFrame Creates a child frame used for Rich Preview.

CDocTemplate::GetDocString Retrieves a string associated with the document type.

CDocTemplate::GetFirstDocPosition Retrieves the position of the first document associated with


this template.

CDocTemplate::GetNextDoc Retrieves a document and the position of the next one.

CDocTemplate::InitialUpdateFrame Initializes the frame window, and optionally makes it visible.

CDocTemplate::LoadTemplate Loads the resources for a given CDocTemplate or derived


class.

CDocTemplate::MatchDocType Determines the degree of confidence in the match between


a document type and this template.
NAME DESC RIP T IO N

CDocTemplate::OpenDocumentFile Opens a file specified by a pathname.

CDocTemplate::RemoveDocument Removes a document from a template.

CDocTemplate::SaveAllModified Saves all documents associated with this template which


have been modified.

CDocTemplate::SetContainerInfo Determines the resources for OLE containers when editing


an in-place OLE item.

CDocTemplate::SetDefaultTitle Displays the default title in the document window's title bar.

CDocTemplate::SetPreviewInfo Setups out of process preview handler.

CDocTemplate::SetServerInfo Determines the resources and classes when the server


document is embedded or edited in-place.

Remarks
You usually create one or more document templates in the implementation of your application's InitInstance
function. A document template defines the relationships among three types of classes:
A document class, which you derive from CDocument .
A view class, which displays data from the document class listed above. You can derive this class from
CView , CScrollView , CFormView , or CEditView . (You can also use CEditView directly.)

A frame window class, which contains the view. For a single document interface (SDI) application, you
derive this class from CFrameWnd . For a multiple document interface (MDI) application, you derive this
class from CMDIChildWnd . If you don't need to customize the behavior of the frame window, you can use
CFrameWnd or CMDIChildWnd directly without deriving your own class.

Your application has one document template for each type of document that it supports. For example, if your
application supports both spreadsheets and text documents, the application has two document template
objects. Each document template is responsible for creating and managing all the documents of its type.
The document template stores pointers to the CRuntimeClass objects for the document, view, and frame
window classes. These CRuntimeClass objects are specified when constructing a document template.
The document template contains the ID of the resources used with the document type (such as menu, icon, or
accelerator table resources). The document template also has strings containing additional information about
its document type. These include the name of the document type (for example, "Worksheet") and the file
extension (for example, ".xls"). Optionally, it can contain other strings used by the application's user interface,
the Windows File Manager, and Object Linking and Embedding (OLE) support.
If your application is an OLE container and/or server, the document template also defines the ID of the menu
used during in-place activation. If your application is an OLE server, the document template defines the ID of
the toolbar and menu used during in-place activation. You specify these additional OLE resources by calling
SetContainerInfo and SetServerInfo .

Because CDocTemplate is an abstract class, you cannot use the class directly. A typical application uses one of
the two CDocTemplate -derived classes provided by the Microsoft Foundation Class Library:
CSingleDocTemplate , which implements SDI, and CMultiDocTemplate , which implements MDI. See those classes
for more information on using document templates.
If your application requires a user-interface paradigm that is fundamentally different from SDI or MDI, you can
derive your own class from CDocTemplate .
For more information on CDocTemplate , see Document Templates and the Document/View Creation Process.

Inheritance Hierarchy
CObject
CCmdTarget
CDocTemplate

Requirements
Header : afxwin.h

CDocTemplate::AddDocument
Use this function to add a document to a template.

virtual void AddDocument(CDocument* pDoc);

Parameters
pDoc
A pointer to the document to be added.
Remarks
The derived classes CMultiDocTemplate and CSingleDocTemplate override this function. If you derive your own
document-template class from CDocTemplate , your derived class must override this function.

CDocTemplate::CDocTemplate
Constructs a CDocTemplate object.

CDocTemplate (
UINT nIDResource,
CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass,
CRuntimeClass* pViewClass);

Parameters
nIDResource
Specifies the ID of the resources used with the document type. This may include menu, icon, accelerator table,
and string resources.
The string resource consists of up to seven substrings separated by the '\n' character (the '\n' character is
needed as a place holder if a substring is not included; however, trailing '\n' characters are not necessary);
these substrings describe the document type. For information on the substrings, see GetDocString. This string
resource is found in the application's resource file. For example:
// MYCALC.RC
STRINGTABLE PRELOAD DISCARDABLE
BEGIN
IDR_SHEETTYPE "\nSheet\nWorksheet\nWorksheets (*.myc)\n.myc\n MyCalcSheet\nMyCalc Worksheet"
END

Note that the string begins with a '\n' character; this is because the first substring is not used for MDI
applications and so is not included. You can edit this string using the string editor; the entire string appears as
a single entry in the String Editor, not as seven separate entries.
pDocClass
Points to the CRuntimeClass object of the document class. This class is a CDocument -derived class you define to
represent your documents.
pFrameClass
Points to the CRuntimeClass object of the frame window class. This class can be a CFrameWnd -derived class, or
it can be CFrameWnd itself if you want default behavior for your main frame window.
pViewClass
Points to the CRuntimeClass object of the view class. This class is a CView -derived class you define to display
your documents.
Remarks
Use this member function to construct a CDocTemplate object. Dynamically allocate a CDocTemplate object and
pass it to CWinApp::AddDocTemplate from the InitInstance member function of your application class.

CDocTemplate::CloseAllDocuments
Call this member function to close all open documents.

virtual void CloseAllDocuments(BOOL bEndSession);

Parameters
bEndSession
Not used.
Remarks
This member function is typically used as part of the File Exit command. The default implementation of this
function calls the CDocument::DeleteContents member function to delete the document's data and then closes
the frame windows for all the views attached to the document.
Override this function if you want to require the user to perform special cleanup processing before the
document is closed. For example, if the document represents a record in a database, you may want to override
this function to close the database.

CDocTemplate::CreateNewDocument
Call this member function to create a new document of the type associated with this document template.

virtual CDocument* CreateNewDocument();

Return Value
A pointer to the newly created document, or NULL if an error occurs.
CDocTemplate::CreateNewFrame
Creates a new frame window containing a document and view.

virtual CFrameWnd* CreateNewFrame(


CDocument* pDoc,
CFrameWnd* pOther);

Parameters
pDoc
The document to which the new frame window should refer. Can be NULL.
pOther
The frame window on which the new frame window is to be based. Can be NULL.
Return Value
A pointer to the newly created frame window, or NULL if an error occurs.
Remarks
CreateNewFrame uses the CRuntimeClass objects passed to the constructor to create a new frame window with
a view and document attached. If the pDoc parameter is NULL, the framework outputs a TRACE message.
The pOther parameter is used to implement the Window New command. It provides a frame window on which
to model the new frame window. The new frame window is usually created invisible. Call this function to create
frame windows outside the standard framework implementation of File New and File Open.

CDocTemplate::CreateOleFrame
Creates an OLE frame window.

CFrameWnd* CreateOleFrame(
CWnd* pParentWnd,
CDocument* pDoc,
BOOL bCreateView);

Parameters
pParentWnd
A pointer to the frame's parent window.
pDoc
A pointer to the document to which the new OLE frame window should refer.
bCreateView
Determines whether a view is created along with the frame.
Return Value
A pointer to a frame window if successful; otherwise NULL.
Remarks
If bCreateView is zero, an empty frame is created.

CDocTemplate::GetDocString
Retrieves a string associated with the document type.
virtual BOOL GetDocString(
CString& rString,
enum DocStringIndex index) const;

Parameters
rString
A reference to a CString object that will contain the string when the function returns.
index
An index of the substring being retrieved from the string that describes the document type. This parameter can
have one of the following values:
CDocTemplate::windowTitle Name that appears in the application window's title bar (for example,
"Microsoft Excel"). Present only in the document template for SDI applications.
CDocTemplate::docName Root for the default document name (for example, "Sheet"). This root, plus a
number, is used for the default name of a new document of this type whenever the user chooses the
New command from the File menu (for example, "Sheet1" or "Sheet2"). If not specified, "Untitled" is
used as the default.
CDocTemplate::fileNewName Name of this document type. If the application supports more than one type
of document, this string is displayed in the File New dialog box (for example, "Worksheet"). If not
specified, the document type is inaccessible using the File New command.
CDocTemplate::filterName Description of the document type and a wildcard filter matching documents
of this type. This string is displayed in the List Files Of Type drop-down list in the File Open dialog box
(for example, "Worksheets (*.xls)"). If not specified, the document type is inaccessible using the File
Open command.
CDocTemplate::filterExt Extension for documents of this type (for example, ".xls"). If not specified, the
document type is inaccessible using the File Open command.
CDocTemplate::regFileTypeId Identifier for the document type to be stored in the registration database
maintained by Windows. This string is for internal use only (for example, "ExcelWorksheet"). If not
specified, the document type cannot be registered with the Windows File Manager.
CDocTemplate::regFileTypeName Name of the document type to be stored in the registration database.
This string may be displayed in dialog boxes of applications that access the registration database (for
example, "Microsoft Excel Worksheet").
Return Value
Nonzero if the specified substring was found; otherwise 0.
Remarks
Call this function to retrieve a specific substring describing the document type. The string containing these
substrings is stored in the document template and is derived from a string in the resource file for the
application. The framework calls this function to get the strings it needs for the application's user interface. If
you have specified a filename extension for your application's documents, the framework also calls this
function when adding an entry to the Windows registration database; this allows documents to be opened
from the Windows File Manager.
Call this function only if you are deriving your own class from CDocTemplate .

CDocTemplate::GetFirstDocPosition
Retrieves the position of the first document associated with this template.
virtual POSITION GetFirstDocPosition() const = 0;

Return Value
A POSITION value that can be used to iterate through the list of documents associated with this document
template; or NULL if the list is empty.
Remarks
Use this function to get the position of the first document in the list of documents associated with this
template. Use the POSITION value as an argument to CDocTemplate::GetNextDoc to iterate through the list of
documents associated with the template.
CSingleDocTemplate and CMultiDocTemplate both override this pure virtual function. Any class you derive
from CDocTemplate must also override this function.

CDocTemplate::GetNextDoc
Retrieves the list element identified by rPos, then sets rPos to the POSITION value of the next entry in the list.

virtual CDocument* GetNextDoc(POSITION& rPos) const = 0;

Return Value
A pointer to the next document in the list of documents associated with this template.
Parameters
rPos
A reference to a POSITION value returned by a previous call to GetFirstDocPosition or GetNextDoc .
Remarks
If the retrieved element is the last in the list, then the new value of rPos is set to NULL.
You can use GetNextDoc in a forward iteration loop if you establish the initial position with a call to
GetFirstDocPosition.
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.

CDocTemplate::InitialUpdateFrame
Initializes the frame window, and optionally makes it visible.

virtual void InitialUpdateFrame(


CFrameWnd* pFrame,
CDocument* pDoc,
BOOL bMakeVisible = TRUE);

Parameters
pFrame
The frame window that needs the initial update.
pDoc
The document to which the frame is associated. Can be NULL.
bMakeVisible
Indicates whether the frame should become visible and active.
Remarks
Call IntitialUpdateFrame after creating a new frame with CreateNewFrame . Calling this function causes the
views in that frame window to receive their OnInitialUpdate calls. Also, if there was not previously an active
view, the primary view of the frame window is made active; the primary view is a view with a child ID of
AFX_IDW_PANE_FIRST. Finally, the frame window is made visible if bMakeVisible is non-zero. If bMakeVisible is
zero, the current focus and visible state of the frame window will remain unchanged.
It is not necessary to call this function when using the framework's implementation of File New and File Open.

CDocTemplate::LoadTemplate
Loads the resources for a given CDocTemplate or derived class.

virtual void LoadTemplate();

Remarks
This member function is called by the framework to load the resources for a given CDocTemplate or derived
class. Normally it is called during construction, except when the template is being constructed globally. In that
case, the call to LoadTemplate is delayed until CWinApp::AddDocTemplate is called.

CDocTemplate::MatchDocType
Determines the degree of confidence in the match between a document type and this template.

virtual Confidence MatchDocType(


LPCTSTR lpszPathName,
CDocument*& rpDocMatch);

Parameters
lpszPathName
Pathname of the file whose type is to be determined.
rpDocMatch
Pointer to a document that is assigned the matching document, if the file specified by lpszPathName is already
open.
Return Value
A value from the Confidence enumeration, which is defined as follows:

enum Confidence
{
noAttempt,
maybeAttemptForeign,
maybeAttemptNative,
yesAttemptForeign,
yesAttemptNative,
yesAlreadyOpen
};

Remarks
Use this function to determine the type of document template to use for opening a file. If your application
supports multiple file types, for example, you can use this function to determine which of the available
document templates is appropriate for a given file by calling MatchDocType for each template in turn, and
choosing a template according to the confidence value returned.
If the file specified by lpszPathName is already open, this function returns CDocTemplate::yesAlreadyOpen and
copies the file's CDocument object into the object at rpDocMatch.
If the file is not open but the extension in lpszPathName matches the extension specified by
CDocTemplate::filterExt , this function returns CDocTemplate::yesAttemptNative and sets rpDocMatch to NULL.
For more information on CDocTemplate::filterExt , see CDocTemplate::GetDocString.
If neither case is true, the function returns CDocTemplate::yesAttemptForeign .
The default implementation does not return CDocTemplate::maybeAttemptForeign or
CDocTemplate::maybeAttemptNative . Override this function to implement type-matching logic appropriate to
your application, perhaps using these two values from the Confidence enumeration.

CDocTemplate::OpenDocumentFile
Opens a file specified by a path.

virtual CDocument* OpenDocumentFile(LPCTSTR lpszPathName) = 0;

virtual CDocument* OpenDocumentFile(


LPCTSTR lpszPathName,
BOOL bAddToMRU) = 0;

Parameters
lpszPathName
[in] Pointer to the path of the file that contains the document to be opened.
bAddToMRU
[in] TRUE indicates the document is one of the most recent files; FALSE indicates the document is not one of
the most recent files.
Return Value
A pointer to the document whose file is named by lpszPathName; NULL if unsuccessful.
Remarks
Opens the file whose path is specified by lpszPathName. If lpszPathName is NULL, a new file that contains a
document of the type associated with this template is created.

CDocTemplate::RemoveDocument
Removes the document pointed to by pDoc from the list of documents associated with this template.

virtual void RemoveDocument(CDocument* pDoc);

Parameters
pDoc
Pointer to the document to be removed.
Remarks
The derived classes CMultiDocTemplate and CSingleDocTemplate override this function. If you derive your own
document-template class from CDocTemplate , your derived class must override this function.
CDocTemplate::SaveAllModified
Saves all documents that have been modified.

virtual BOOL SaveAllModified();

Return Value
Non-zero if successful; otherwise 0.

CDocTemplate::SetContainerInfo
Determines the resources for OLE containers when editing an in-place OLE item.

void SetContainerInfo(UINT nIDOleInPlaceContainer);

Parameters
nIDOleInPlaceContainer
The ID of the resources used when an embedded object is activated.
Remarks
Call this function to set the resources to be used when an OLE object is in-place activated. These resources may
include menus and accelerator tables. This function is usually called in the CWinApp::InitInstance function of
your application.
The menu associated with nIDOleInPlaceContainer contains separators that allow the menu of the activated in-
place item to merge with the menu of the container application. For more information about merging server
and container menus, see the article Menus and Resources (OLE).

CDocTemplate::SetDefaultTitle
Call this function to load the document's default title and display it in the document's title bar.

virtual void SetDefaultTitle(CDocument* pDocument) = 0;

Parameters
pDocument
Pointer to the document whose title is to be set.
Remarks
For information on the default title, see the description of CDocTemplate::docName in
CDocTemplate::GetDocString.

CDocTemplate::SetServerInfo
Determines the resources and classes when the server document is embedded or edited in-place.

void SetServerInfo(
UINT nIDOleEmbedding,
UINT nIDOleInPlaceServer = 0,
CRuntimeClass* pOleFrameClass = NULL,
CRuntimeClass* pOleViewClass = NULL);
Parameters
nIDOleEmbedding
The ID of the resources used when an embedded object is opened in a separate window.
nIDOleInPlaceServer
The ID of the resources used when an embedded object is activated in-place.
pOleFrameClass
Pointer to a CRuntimeClass structure containing class information for the frame window object created when
in-place activation occurs.
pOleViewClass
Pointer to a CRuntimeClass structure containing class information for the view object created when in-place
activation occurs.
Remarks
Call this member function to identify resources that will be used by the server application when the user
requests activation of an embedded object. These resources consist of menus and accelerator tables. This
function is usually called in the InitInstance of your application.
The menu associated with nIDOleInPlaceServer contains separators that allow the server menu to merge with
the menu of the container. For more information about merging server and container menus, see the article
Menus and Resources (OLE).

CDocTemplate::CreatePreviewFrame
Creates a child frame used for Rich Preview.

CFrameWnd* CreatePreviewFrame(
CWnd* pParentWnd,
CDocument* pDoc);

Parameters
pParentWnd
A pointer to a parent window (usually provided by the Shell).
pDoc
A pointer to a document object, whose content will be previewed.
Return Value
A valid pointer to a CFrameWnd object, or NULL if the creation fails.
Remarks

CDocTemplate::SetPreviewInfo
Sets up the out of process preview handler.

void SetPreviewInfo(
UINT nIDPreviewFrame,
CRuntimeClass* pPreviewFrameClass = NULL,
CRuntimeClass* pPreviewViewClass = NULL);

Parameters
nIDPreviewFrame
Specifies a resource ID of the preview frame.
pPreviewFrameClass
Specifies a pointer to a runtime class information structure of the preview frame.
pPreviewViewClass
Specifies a pointer to a runtime class information structure of the preview view.
Remarks

See also
CCmdTarget Class
Hierarchy Chart
CSingleDocTemplate Class
CMultiDocTemplate Class
CDocument Class
CView Class
CScrollView Class
CEditView Class
CFormView Class
CFrameWnd Class
CMDIChildWnd Class
CDocument Class
4/21/2020 • 29 minutes to read • Edit Online

Provides the basic functionality for user-defined document classes.

Syntax
class CDocument : public CCmdTarget

Members
Public Constructors
NAME DESC RIP T IO N

CDocument::CDocument Constructs a CDocument object.

Public Methods
NAME DESC RIP T IO N

CDocument::AddView Attaches a view to the document.

CDocument::BeginReadChunks Initializes chunk reading.

CDocument::CanCloseFrame Advanced overridable; called before closing a frame


window viewing this document.

CDocument::ClearChunkList Clears the chunk list.

CDocument::ClearPathName Clears the path of the document object.

CDocument::DeleteContents Called to perform cleanup of the document.

CDocument::FindChunk Looks for a chunk with specified GUID.

CDocument::GetAdapter Returns a pointer to object implementing IDocument


interface.

CDocument::GetDocTemplate Returns a pointer to the document template that


describes the type of the document.

CDocument::GetFile Returns a pointer to the desired CFile object.

CDocument::GetFirstViewPosition Returns the position of the first in the list of views; used
to begin iteration.

CDocument::GetNextView Iterates through the list of views associated with the


document.
NAME DESC RIP T IO N

CDocument::GetPathName Returns the path of the document's data file.

CDocument::GetThumbnail Called to create a bitmap to be used by thumbnail


provider to display thumbnail.

CDocument::GetTitle Returns the document's title.

CDocument::InitializeSearchContent Called to initialize search content for Search Handler.

CDocument::IsModified Indicates whether the document has been modified since


it was last saved.

CDocument::IsSearchAndOrganizeHandler Tells whether this instance of CDocument object was


created for Search & Organize handler.

CDocument::LoadDocumentFromStream Called to load document data from stream.

CDocument::OnBeforeRichPreviewFontChanged Called before Rich Preview font is changed.

CDocument::OnChangedViewList Called after a view is added to or removed from the


document.

CDocument::OnCloseDocument Called to close the document.

CDocument::OnCreatePreviewFrame Called by the framework when it needs to create a


preview frame for Rich Preview.

CDocument::OnDocumentEvent Called by the framework in response to a document


event.

CDocument::OnDrawThumbnail Override this method in a derived class to draw content


of thumbnail.

CDocument::OnLoadDocumentFromStream Called by the framework when it needs to load the


document data from stream.

CDocument::OnNewDocument Called to create a new document.

CDocument::OnOpenDocument Called to open an existing document.

CDocument::OnPreviewHandlerQueryFocus Directs the preview handler to return the HWND from


calling the GetFocus Function.

CDocument::OnPreviewHandlerTranslateAccelerator Directs the preview handler to handle a keystroke passed


up from the message pump of the process in which the
preview handler is running.

CDocument::OnRichPreviewBackColorChanged Called when Rich Preview background color has changed.

CDocument::OnRichPreviewFontChanged Called when Rich Preview font has changed.

CDocument::OnRichPreviewSiteChanged Called when Rich Preview site has changed.


NAME DESC RIP T IO N

CDocument::OnRichPreviewTextColorChanged Called when Rich Preview text color has changed.

CDocument::OnSaveDocument Called to save the document to disk.

CDocument::OnUnloadHandler Called by the framework when the preview handler is


being unloaded.

CDocument::PreCloseFrame Called before the frame window is closed.

CDocument::ReadNextChunkValue Reads next chunk value.

CDocument::ReleaseFile Releases a file to make it available for use by other


applications.

CDocument::RemoveChunk Removes a chunk with specified GUID.

CDocument::RemoveView Detaches a view from the document.

CDocument::ReportSaveLoadException Advanced overridable; called when an open or save


operation cannot be completed because of an exception.

CDocument::SaveModified Advanced overridable; called to ask the user whether the


document should be saved.

CDocument::SetChunkValue Sets a chunk value.

CDocument::SetModifiedFlag Sets a flag indicating that you have modified the


document since it was last saved.

CDocument::SetPathName Sets the path of the data file used by the document.

CDocument::SetTitle Sets the document's title.

CDocument::UpdateAllViews Notifies all views that document has been modified.

Protected Methods
NAME DESC RIP T IO N

CDocument::OnFileSendMail Sends a mail message with the document attached.

CDocument::OnUpdateFileSendMail Enables the Send Mail command if mail support is


present.

Public Data Members


NAME DESC RIP T IO N

CDocument::m_bGetThumbnailMode Specifies that CDocument object was created by dllhost


for thumbnails. Should be checked in CView::OnDraw .
NAME DESC RIP T IO N

CDocument::m_bPreviewHandlerMode Specifies that CDocument object was created by prevhost


for Rich Preview . Should be checked in
CView::OnDraw .

CDocument::m_bSearchMode Specifies that CDocument object was created by indexer


or other search application.

CDocument::m_clrRichPreviewBackColor Specifies background color of Rich Preview window. This


color is set by host.

CDocument::m_clrRichPreviewTextColor Specifies foreground color of Rich Preview window. This


color is set by host.

CDocument::m_lfRichPreviewFont Specifies text font for Rich Preview window. This font
information is set by host.

Remarks
A document represents the unit of data that the user typically opens with the File Open command and
saves with the File Save command.
CDocument supports standard operations such as creating a document, loading it, and saving it. The
framework manipulates documents using the interface defined by CDocument .
An application can support more than one type of document; for example, an application might support
both spreadsheets and text documents. Each type of document has an associated document template; the
document template specifies what resources (for example, menu, icon, or accelerator table) are used for
that type of document. Each document contains a pointer to its associated CDocTemplate object.
Users interact with a document through the CView object(s) associated with it. A view renders an image of
the document in a frame window and interprets user input as operations on the document. A document
can have multiple views associated with it. When the user opens a window on a document, the framework
creates a view and attaches it to the document. The document template specifies what type of view and
frame window are used to display each type of document.
Documents are part of the framework's standard command routing and consequently receive commands
from standard user-interface components (such as the File Save menu item). A document receives
commands forwarded by the active view. If the document doesn't handle a given command, it forwards the
command to the document template that manages it.
When a document's data is modified, each of its views must reflect those modifications. CDocument
provides the UpdateAllViews member function for you to notify the views of such changes, so the views
can repaint themselves as necessary. The framework also prompts the user to save a modified file before
closing it.
To implement documents in a typical application, you must do the following:
Derive a class from CDocument for each type of document.
Add member variables to store each document's data.
Implement member functions for reading and modifying the document's data. The document's
views are the most important users of these member functions.
Override the CObject::Serialize member function in your document class to write and read the
document's data to and from disk.
CDocument supports sending your document via mail if mail support (MAPI) is present. See the articles
MAPI and MAPI Support in MFC.
For more information on CDocument , see Serialization, Document/View Architecture Topics, and
Document/View Creation.

Inheritance Hierarchy
CObject
CCmdTarget
CDocument

Requirements
Header : afxwin.h

CDocument::AddView
Call this function to attach a view to the document.

void AddView(CView* pView);

Parameters
pView
Points to the view being added.
Remarks
This function adds the specified view to the list of views associated with the document; the function also
sets the view's document pointer to this document. The framework calls this function when attaching a
newly created view object to a document; this occurs in response to a File New, File Open, or New Window
command or when a splitter window is split.
Call this function only if you are manually creating and attaching a view. Typically you will let the
framework connect documents and views by defining a CDocTemplate object to associate a document class,
view class, and frame window class.
Example

// The following example toggles two views in an SDI (single document


// interface) frame window. A design decision must be made as to
// whether to leave the inactive view connected to the document,
// such that the inactive view continues to receive OnUpdate
// notifications from the document. It is usually desirable to
// keep the inactive view continuously in sync with the document, even
// though it is inactive. However, doing so incurs a performance cost,
// as well as the programming cost of implementing OnUpdate hints.
// It may be less expensive, in terms of performance and/or programming,
// to re-sync the inactive view with the document only with it is
// reactivated. This example illustrates this latter approach, by
// reconnecting the newly active view and disconnecting the newly
// inactive view, via calls to CDocument::AddView and RemoveView.

void CMainFrame::OnViewChange(UINT nCmdID)


// There is an ON_COMMAND_RANGE message map entry associated with
// OnViewChange:
// OnViewChange:
// ON_COMMAND_RANGE(ID_VIEW_CHANGE1, ID_VIEW_CHANGE2, &OnViewChange)
{
CView *pViewAdd;
CView *pViewRemove;
CDocument *pDoc = GetActiveDocument();

// cvView1 and cvView2 are enum members defined in my CMainFrame class


if ((nCmdID == ID_VIEW_CHANGE1) && (m_currentView == cvView1))
return;
if ((nCmdID == ID_VIEW_CHANGE2) && (m_currentView == cvView2))
return;

if (nCmdID == ID_VIEW_CHANGE2)
{
if (m_pView2 == NULL)
{
m_pView1 = GetActiveView();
m_pView2 = new CMyView2;

//Note that if OnSize has been overridden in CMyView2


//and GetDocument() is used in this override it can
//cause assertions and, if the assertions are ignored,
//cause access violation.

m_pView2->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, rectDefault, this,


AFX_IDW_PANE_FIRST + 1, NULL);
}
pViewAdd = m_pView2;
pViewRemove = m_pView1;
m_currentView = cvView2;
}
else
{
pViewAdd = m_pView1;
pViewRemove = m_pView2;
m_currentView = cvView1;
}

// Set the child i.d. of the active view to AFX_IDW_PANE_FIRST,


// so that CFrameWnd::RecalcLayout will allocate to this
// "first pane" that portion of the frame window's client area
// not allocated to control bars. Set the child i.d. of the
// other view to anything other than AFX_IDW_PANE_FIRST; this
// examples switches the child id's of the two views.

int nSwitchChildID = pViewAdd->GetDlgCtrlID();


pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pViewRemove->SetDlgCtrlID(nSwitchChildID);

// Show the newly active view and hide the inactive view.

pViewAdd->ShowWindow(SW_SHOW);
pViewRemove->ShowWindow(SW_HIDE);

// Connect the newly active view to the document, and


// disconnect the inactive view.
pDoc->AddView(pViewAdd);
pDoc->RemoveView(pViewRemove);

SetActiveView(pViewAdd);
RecalcLayout();
}

CDocument::BeginReadChunks
Initializes chunk reading.
virtual void BeginReadChunks ();

Remarks

CDocument::CanCloseFrame
Called by the framework before a frame window displaying the document is closed.

virtual BOOL CanCloseFrame(CFrameWnd* pFrame);

Parameters
pFrame
Points to the frame window of a view attached to the document.
Return Value
Nonzero if it is safe to close the frame window; otherwise 0.
Remarks
The default implementation checks if there are other frame windows displaying the document. If the
specified frame window is the last one that displays the document, the function prompts the user to save
the document if it has been modified. Override this function if you want to perform special processing
when a frame window is closed. This is an advanced overridable.

CDocument::CDocument
Constructs a CDocument object.

CDocument();

Remarks
The framework handles document creation for you. Override the OnNewDocument member function to
perform initialization on a per-document basis; this is particularly important in single document interface
(SDI) applications.

CDocument::ClearChunkList
Clears the chunk list.

virtual void ClearChunkList ();

Remarks

CDocument::ClearPathName
Clears the path of the document object.

virtual void ClearPathName();

Remarks
Clearing the path from a CDocument object causes the application to prompt the user when the document is
next saved. This makes a Save command behave like a Save As command.

CDocument::DeleteContents
Called by the framework to delete the document's data without destroying the CDocument object itself.

virtual void DeleteContents();

Remarks
It is called just before the document is to be destroyed. It is also called to ensure that a document is empty
before it is reused. This is particularly important for an SDI application, which uses only one document; the
document is reused whenever the user creates or opens another document. Call this function to implement
an "Edit Clear All" or similar command that deletes all of the document's data. The default implementation
of this function does nothing. Override this function to delete the data in your document.
Example

// This example is the handler for an Edit Clear All command.


void CExampleDoc::OnEditClearAll()
{
DeleteContents();
UpdateAllViews(NULL);
}

void CExampleDoc::DeleteContents()
{
// Re-initialize document data here.
}

CDocument::FindChunk
Looks for a chunk with a specified GUID.

virtual POSITION FindChunk(


REFCLSID guid,
DWORD pid);

Parameters
guid
Specifies the GUID of a chunk to find.
pid
Specifies a PID of a chunk to find.
Return Value
Position in the internal chunk list if successful. Otherwise NULL.
Remarks

CDocument::GetAdapter
Returns a pointer to an object implementing the IDocument interface.

virtual ATL::IDocument* GetAdapter();


Return Value
A pointer to an object implementing the IDocument interface.
Remarks

CDocument::GetDocTemplate
Call this function to get a pointer to the document template for this document type.

CDocTemplate* GetDocTemplate() const;

Return Value
A pointer to the document template for this document type, or NULL if the document is not managed by a
document template.
Example

// This example accesses the doc template object to construct


// a default document name such as SHEET.XLS, where "sheet"
// is the base document name and ".xls" is the file extension
// for the document type.
CString strDefaultDocName, strBaseName, strExt;
CDocTemplate *pDocTemplate = GetDocTemplate();
if (!pDocTemplate->GetDocString(strBaseName, CDocTemplate::docName) || !pDocTemplate-
>GetDocString(strExt, CDocTemplate::filterExt))
{
AfxThrowUserException(); // These doc template strings will
// be available if you created the application using AppWizard
// and specified the file extension as an option for
// the document class produced by AppWizard.
}
strDefaultDocName = strBaseName + strExt;

CDocument::GetFile
Call this member function to get a pointer to a CFile object.

virtual CFile* GetFile(


LPCTSTR lpszFileName,
UINT nOpenFlags,
CFileException* pError);

Parameters
lpszFileName
A string that is the path to the desired file. The path may be relative or absolute.
pError
A pointer to an existing file-exception object that indicates the completion status of the operation.
nOpenFlags
Sharing and access mode. Specifies the action to take when opening the file. You can combine options
listed in the CFile constructor CFile::CFile by using the bitwise OR (|) operator. One access permission and
one share option are required; the modeCreate and modeNoInherit modes are optional.
Return Value
A pointer to a CFile object.
CDocument::GetFirstViewPosition
Call this function to get the position of the first view in the list of views associated with the document.

virtual POSITION GetFirstViewPosition() const;

Return Value
A POSITION value that can be used for iteration with the GetNextView member function.
Example

//To get the first view in the list of views:


//To get the first view in the list of views:
// POSITION pos = GetFirstViewPosition();
// CView* pFirstView = GetNextView(pos);
//
// This example uses CDocument::GetFirstViewPosition
// and GetNextView to repaint each view.
// An easier way to accomplish the same result is to call
// UpdateAllViews(NULL);
void CExampleDoc::OnRepaintAllViews()
{
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView *pView = GetNextView(pos);
pView->UpdateWindow();
}
}

CDocument::GetNextView
Call this function to iterate through all of the document's views.

virtual CView* GetNextView(POSITION& rPosition) const;

Parameters
rPosition
A reference to a POSITION value returned by a previous call to the GetNextView or GetFirstViewPosition
member functions. This value must not be NULL.
Return Value
A pointer to the view identified by rPosition.
Remarks
The function returns the view identified by rPosition and then sets rPosition to the POSITION value of the
next view in the list. If the retrieved view is the last in the list, then rPosition is set to NULL.
Example
//To get the first view in the list of views:
//To get the first view in the list of views:
// POSITION pos = GetFirstViewPosition();
// CView* pFirstView = GetNextView(pos);
//
// This example uses CDocument::GetFirstViewPosition
// and GetNextView to repaint each view.
// An easier way to accomplish the same result is to call
// UpdateAllViews(NULL);
void CExampleDoc::OnRepaintAllViews()
{
POSITION pos = GetFirstViewPosition();
while (pos != NULL)
{
CView *pView = GetNextView(pos);
pView->UpdateWindow();
}
}

CDocument::GetPathName
Call this function to get the fully qualified path of the document's disk file.

const CString& GetPathName() const;

Return Value
The document's fully qualified path. This string is empty if the document has not been saved or does not
have a disk file associated with it.

CDocument::GetThumbnail
Creates a bitmap to be used by the thumbnail provider to display the thumbnail.

virtual BOOL GetThumbnail(


UINT cx,
HBITMAP* phbmp,
DWORD* pdwAlpha);

Parameters
cx
Specifies the width and height of the bitmap.
phbmp
Contains a handle to a bitmap, when the function returns successfully.
pdwAlpha
Contains a DWORD specifying the alpha channel value, when the function returns successfully.
Return Value
Returns TRUE if a bitmap for the thumbnail was created successfully; otherwise FALSE.
Remarks

CDocument::GetTitle
Call this function to get the document's title, which is usually derived from the document's filename.
const CString& GetTitle() const;

Return Value
The document's title.

CDocument::InitializeSearchContent
Called to initialize search content for the Search Handler.

virtual void InitializeSearchContent ();

Remarks
Override this method in a derived class to initialize search content. The content should be a string with
parts delimited by ";". For example, "point; rectangle; ole item".

CDocument::IsModified
Call this function to determine whether the document has been modified since it was last saved.

virtual BOOL IsModified();

Return Value
Nonzero if the document has been modified since it was last saved; otherwise 0.

CDocument::IsSearchAndOrganizeHandler
Tells whether this instance of CDocument was created for the Search & Organize handler.

BOOL IsSearchAndOrganizeHandler() const;

Return Value
Returns TRUE if this instance of CDocument was created for the Search & Organize handler.
Remarks
Currently this function returns TRUE only for Rich Preview handlers implemented in an out of process
server. You can set the appropriate flags (m_bPreviewHandlerMode, m_bSearchMode,
m_bGetThumbnailMode) at your application level to make this function return TRUE.

CDocument::LoadDocumentFromStream
Called to load document data from a stream.

virtual HRESULT LoadDocumentFromStream(


IStream* pStream,
DWORD dwGrfMode);

Parameters
pStream
A pointer to a stream. This stream is supplied by the Shell.
dwGrfMode
Access mode to the stream.
Return Value
S_OK if the load operation succeeds, otherwise HRESULT with an error code.
Remarks
You can override this method in a derived class to customize how to load data from the stream.

CDocument::m_bGetThumbnailMode
Specifies that the CDocument object was created by dllhost for thumbnails. Should be checked in
CView::OnDraw .

BOOL m_bGetThumbnailMode;

Remarks
TRUE indicates that the document was created by dllhost for thumbnails.

CDocument::m_bPreviewHandlerMode
Specifies that the CDocument object was created by prevhost for Rich Preview. Should be checked in
CView::OnDraw .

BOOL m_bPreviewHandlerMode;

Remarks
TRUE indicates that the document was created by prevhost for Rich Preview.

CDocument::m_bSearchMode
Specifies that the CDocument object was created by indexer or by another search application.

BOOL m_bSearchMode;

Remarks
TRUE indicates that the document was created by indexer or by another search application.

CDocument::m_clrRichPreviewBackColor
Specifies the background color of the Rich Preview window. This color is set by host.

COLORREF m_clrRichPreviewBackColor;

Remarks

CDocument::m_clrRichPreviewTextColor
Specifies the foreground color of the Rich Preview window. This color is set by host.
COLORREF m_clrRichPreviewTextColor;

Remarks

CDocument::m_lfRichPreviewFont
Specifies the text font for the Rich Preview window. This font information is set by host.

CFont m_lfRichPreviewFont;

Remarks

CDocument::OnBeforeRichPreviewFontChanged
Called before the Rich Preview font is changed.

virtual void OnBeforeRichPreviewFontChanged();

Remarks

CDocument::OnChangedViewList
Called by the framework after a view is added to or removed from the document.

virtual void OnChangedViewList();

Remarks
The default implementation of this function checks whether the last view is being removed and, if so,
deletes the document. Override this function if you want to perform special processing when the
framework adds or removes a view. For example, if you want a document to remain open even when there
are no views attached to it, override this function.

CDocument::OnCloseDocument
Called by the framework when the document is closed, typically as part of the File Close command.

virtual void OnCloseDocument();

Remarks
The default implementation of this function destroys all of the frames used for viewing the document,
closes the view, cleans up the document's contents, and then calls the DeleteContents member function to
delete the document's data.
Override this function if you want to perform special cleanup processing when the framework closes a
document. For example, if the document represents a record in a database, you may want to override this
function to close the database. You should call the base class version of this function from your override.

CDocument::OnCreatePreviewFrame
Called by the framework when it needs to create a preview frame for Rich Preview.
virtual BOOL OnCreatePreviewFrame();

Return Value
Returns TRUE if the frame is created successfully; otherwise FALSE.
Remarks

CDocument::OnDocumentEvent
Called by the framework in response to a document event.

virtual void OnDocumentEvent(DocumentEvent deEvent);

Parameters
deEvent
[in] An enumerated data type that describes the type of event.
Remarks
Document events may affect multiple classes. This method is responsible for handling document events
that affect classes other than the CDocument Class. Currently, the only class that must respond to
document events is the CDataRecoveryHandler Class. The CDocument class has other overrideable methods
responsible for handling the effect on the CDocument .
The following table lists the possible values for deEvent and the events that they correspond to.

VA L UE C O RRESP O N DIN G EVEN T

onAfterNewDocument A new document was created.

onAfterOpenDocument A new document was opened.

onAfterSaveDocument The document was saved.

onAfterCloseDocument The document was closed.

CDocument::OnDrawThumbnail
Override this method in a derived class to draw the thumbnail.

virtual void OnDrawThumbnail(


CDC& dc,
LPRECT lprcBounds);

Parameters
dc
A reference to a device context.
lprcBounds
Specifies a bounding rectangle of the area where the thumbnail should be drawn.
Remarks
CDocument::OnFileSendMail
Sends a message via the resident mail host (if any) with the document as an attachment.

void OnFileSendMail();

Remarks
OnFileSendMail calls OnSaveDocument to serialize (save) untitled and modified documents to a temporary
file, which is then sent via electronic mail. If the document has not been modified, a temporary file is not
needed; the original is sent. OnFileSendMail loads MAPI32.DLL if it has not already been loaded.
A special implementation of OnFileSendMail for COleDocument handles compound files correctly.
CDocument supports sending your document via mail if mail support (MAPI) is present. See the articles
MAPI Topics and MAPI Support in MFC.

CDocument::OnLoadDocumentFromStream
Called by the framework when it needs to load the document data from a stream.

virtual HRESULT OnLoadDocumentFromStream(


IStream* pStream,
DWORD grfMode);

Parameters
pStream
A pointer to an incoming stream.
grfMode
Access mode to the stream.
Return Value
S_OK if the load is successful; otherwise an error code.
Remarks

CDocument::OnNewDocument
Called by the framework as part of the File New command.

virtual BOOL OnNewDocument();

Return Value
Nonzero if the document was successfully initialized; otherwise 0.
Remarks
The default implementation of this function calls the DeleteContents member function to ensure that the
document is empty and then marks the new document as clean. Override this function to initialize the data
structure for a new document. You should call the base class version of this function from your override.
If the user chooses the File New command in an SDI application, the framework uses this function to
reinitialize the existing document, rather than creating a new one. If the user chooses File New in a multiple
document interface (MDI) application, the framework creates a new document each time and then calls this
function to initialize it. You must place your initialization code in this function instead of in the constructor
for the File New command to be effective in SDI applications.
Note that there are cases where OnNewDocument is called twice. This occurs when the document is
embedded as an ActiveX Document Server. The function is first called by the CreateInstance method
(exposed by the COleObjectFactory -derived class) and a second time by the InitNew method (exposed by
the COleServerDoc -derived class).
Example
The following examples illustrate alternative methods of initializing a document object.

// Method 1: In an MDI application, the simplest place to do


// initialization is in the document constructor. The framework
// always creates a new document object for File New or File Open.
CExampleDoc::CExampleDoc()
{
// Do initialization of MDI document here.
}

// Method 2: In an SDI or MDI application, do all initialization


// in an override of OnNewDocument, if you are certain that
// the initialization is effectively saved upon File Save
// and fully restored upon File Open, via serialization.
BOOL CMyDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
{
return FALSE;
}

// Do initialization of new document here.

return TRUE;
}

// Method 3: If the initialization of your document is not


// effectively saved and restored by serialization (during File Save
// and File Open), then implement the initialization in single
// function (named InitMyDocument in this example). Call the
// shared initialization function from overrides of both
// OnNewDocument and OnOpenDocument.
BOOL CExampleDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
{
return FALSE;
}

InitMyDocument(); // call your shared initialization function

// If your new document object requires additional initialization


// not necessary when the document is deserialized via File Open,
// then perform that additional initialization here.

return TRUE;
}

CDocument::OnOpenDocument
Called by the framework as part of the File Open command.
virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);

Parameters
lpszPathName
Points to the path of the document to be opened.
Return Value
Nonzero if the document was successfully loaded; otherwise 0.
Remarks
The default implementation of this function opens the specified file, calls the DeleteContents member
function to ensure that the document is empty, calls CObject::Serialize to read the file's contents, and then
marks the document as clean. Override this function if you want to use something other than the archive
mechanism or the file mechanism. For example, you might write an application where documents
represent records in a database rather than separate files.
If the user chooses the File Open command in an SDI application, the framework uses this function to
reinitialize the existing CDocument object, rather than creating a new one. If the user chooses File Open in
an MDI application, the framework constructs a new CDocument object each time and then calls this
function to initialize it. You must place your initialization code in this function instead of in the constructor
for the File Open command to be effective in SDI applications.
Example
The following examples illustrate alternative methods of initializing a document object.

// Method 1: In an MDI application, the simplest place to do


// initialization is in the document constructor. The framework
// always creates a new document object for File New or File Open.
CExampleDoc::CExampleDoc()
{
// Do initialization of MDI document here.
}

// Method 2: In an SDI or MDI application, do all initialization


// in an override of OnNewDocument, if you are certain that
// the initialization is effectively saved upon File Save
// and fully restored upon File Open, via serialization.
BOOL CMyDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
{
return FALSE;
}

// Do initialization of new document here.

return TRUE;
}
// Method 3: If the initialization of your document is not
// effectively saved and restored by serialization (during File Save
// and File Open), then implement the initialization in single
// function (named InitMyDocument in this example). Call the
// shared initialization function from overrides of both
// OnNewDocument and OnOpenDocument.
BOOL CExampleDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
{
return FALSE;
}

InitMyDocument(); // call your shared initialization function

// If your new document object requires additional initialization


// not necessary when the document is deserialized via File Open,
// then perform that additional initialization here.

return TRUE;
}

// Additional example of OnOpenDocument()


BOOL CExampleDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
{
return FALSE;
}

InitMyDocument(); // call your shared initialization function

return TRUE;
}

CDocument::OnPreviewHandlerQueryFocus
Directs the preview handler to return the HWND retrieved from calling the GetFocus function.

virtual HRESULT OnPreviewHandlerQueryFocus(HWND* phwnd);

Parameters
phwnd
[out] When this method returns, contains a pointer to the HWND returned from calling the GetFocus
function from the preview handler's foreground thread.
Return Value
Returns S_OK if successful; or an error value otherwise.
Remarks

CDocument::OnPreviewHandlerTranslateAccelerator
Directs the preview handler to handle a keystroke passed up from the message pump of the process in
which the preview handler is running.

virtual HRESULT OnPreviewHandlerTranslateAccelerator(MSG* pmsg);


Parameters
pmsg
[in] A pointer to a window message.
Return Value
If the keystroke message can be processed by the preview handler, the handler processes it and returns
S_OK. If the preview handler cannot process the keystroke message, it offers it to the host via
IPreviewHandlerFrame::TranslateAccelerator . If the host processes the message, this method returns S_OK.
If the host does not process the message, this method returns S_FALSE.
Remarks

CDocument::OnRichPreviewBackColorChanged
Called when the Rich Preview background color has changed.

virtual void OnRichPreviewBackColorChanged();

Remarks

CDocument::OnRichPreviewFontChanged
Called when the Rich Preview font has changed.

virtual void OnRichPreviewFontChanged();

Remarks

CDocument::OnRichPreviewSiteChanged
Called when the Rich Preview site has changed.

virtual void OnRichPreviewSiteChanged();

Remarks

CDocument::OnRichPreviewTextColorChanged
Called when the Rich Preview text color has changed.

virtual void OnRichPreviewTextColorChanged();

Remarks

CDocument::OnSaveDocument
Called by the framework as part of the File Save or File Save As command.

virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);

Parameters
lpszPathName
Points to the fully qualified path to which the file should be saved.
Return Value
Nonzero if the document was successfully saved; otherwise 0.
Remarks
The default implementation of this function opens the specified file, calls CObject::Serialize to write the
document's data to the file, and then marks the document as clean. Override this function if you want to
perform special processing when the framework saves a document. For example, you might write an
application where documents represent records in a database rather than separate files.

CDocument::OnUnloadHandler
Called by the framework when the preview handler is unloaded.

virtual void OnUnloadHandler();

Remarks

CDocument::OnUpdateFileSendMail
Enables the ID_FILE_SEND_MAIL command if mail support (MAPI) is present.

void OnUpdateFileSendMail(CCmdUI* pCmdUI);

Parameters
pCmdUI
A pointer to the CCmdUI object associated with the ID_FILE_SEND_MAIL command.
Remarks
Otherwise the function removes the ID_FILE_SEND_MAIL command from the menu, including separators
above or below the menu item as appropriate. MAPI is enabled if MAPI32.DLL is present in the path and, in
the [Mail] section of the WIN.INI file, MAPI=1. Most applications put this command on the File menu.
CDocument supports sending your document via mail if mail support (MAPI) is present. See the articles
MAPI Topics and MAPI Support in MFC.

CDocument::PreCloseFrame
This member function is called by the framework before the frame window is destroyed.

virtual void PreCloseFrame(CFrameWnd* pFrame);

Parameters
pFrame
Pointer to the CFrameWnd that holds the associated CDocument object.
Remarks
It can be overridden to provide custom cleanup, but be sure to call the base class as well.
The default of PreCloseFrame does nothing in CDocument . The CDocument -derived classes COleDocument
and CRichEditDoc use this member function.

CDocument::ReadNextChunkValue
Reads the next chunk value.

virtual BOOL ReadNextChunkValue(IFilterChunkValue** ppValue);

Parameters
ppValue
[out] When the function returns, ppValue contains the value that was read.
Return Value
Nonzero if successful; otherwise 0.
Remarks

CDocument::ReleaseFile
This member function is called by the framework to release a file, making it available for use by other
applications.

virtual void ReleaseFile(


CFile* pFile,
BOOL bAbort);

Parameters
pFile
A pointer to the CFile object to be released.
bAbort
Specifies whether the file is to be released by using either CFile::Close or CFile::Abort . FALSE if the file
is to be released using CFile::Close; TRUE if the file is to be released using CFile::Abort.
Remarks
If bAbort is TRUE, ReleaseFile calls CFile::Abort , and the file is released. CFile::Abort will not throw an
exception.
If bAbort is FALSE, ReleaseFile calls CFile::Close and the file is released.
Override this member function to require an action by the user before the file is released.

CDocument::RemoveChunk
Removes a chunk with the specified GUID.

virtual void RemoveChunk(


REFCLSID guid,
DWORD pid);

Parameters
Guid
Specifies the GUID of a chunk to be removed.
Pid
Specifies the PID of a chunk to be removed.
Remarks

CDocument::RemoveView
Call this function to detach a view from a document.

void RemoveView(CView* pView);

Parameters
pView
Points to the view being removed.
Remarks
This function removes the specified view from the list of views associated with the document; it also sets
the view's document pointer to NULL. This function is called by the framework when a frame window is
closed or a pane of a splitter window is closed.
Call this function only if you are manually detaching a view. Typically you will let the framework detach
documents and views by defining a CDocTemplate object to associate a document class, view class, and
frame window class.
See the example at AddView for a sample implementation.

CDocument::ReportSaveLoadException
Called if an exception is thrown (typically a CFileException or CArchiveException) while saving or loading
the document.

virtual void ReportSaveLoadException(


LPCTSTR lpszPathName,
CException* e,
BOOL bSaving,
UINT nIDPDefault);

Parameters
lpszPathName
Points to name of document that was being saved or loaded.
e
Points to the exception that was thrown. May be NULL.
bSaving
Flag indicating what operation was in progress; nonzero if the document was being saved, 0 if the
document was being loaded.
nIDPDefault
Identifier of the error message to be displayed if the function does not specify a more specific one.
Remarks
The default implementation examines the exception object and looks for an error message that specifically
describes the cause. If a specific message is not found or if e is NULL, the general message specified by the
nIDPDefault parameter is used. The function then displays a message box containing the error message.
Override this function if you want to provide additional, customized failure messages. This is an advanced
overridable.

CDocument::SaveModified
Called by the framework before a modified document is to be closed.

virtual BOOL SaveModified();

Return Value
Nonzero if it is safe to continue and close the document; 0 if the document should not be closed.
Remarks
The default implementation of this function displays a message box asking the user whether to save the
changes to the document, if any have been made. Override this function if your program requires a
different prompting procedure. This is an advanced overridable.

CDocument::SetChunkValue
Sets a chunk value.

virtual BOOL SetChunkValue (IFilterChunkValue* pValue);

Parameters
pValue
Specifies a chunk value to set.
Return Value
Nonzero if successful; otherwise 0.
Remarks

CDocument::SetModifiedFlag
Call this function after you have made any modifications to the document.

virtual void SetModifiedFlag(BOOL bModified = TRUE);

Parameters
bModified
Flag indicating whether the document has been modified.
Remarks
By calling this function consistently, you ensure that the framework prompts the user to save changes
before closing a document. Typically you should use the default value of TRUE for the bModified parameter.
To mark a document as clean (unmodified), call this function with a value of FALSE.

CDocument::SetPathName
Call this function to specify the fully qualified path of the document's disk file.
virtual void SetPathName(
LPCTSTR lpszPathName,
BOOL bAddToMRU = TRUE);

Parameters
lpszPathName
Points to the string to be used as the path for the document.
bAddToMRU
Determines whether the filename is added to the most recently used (MRU) file list. If TRUE, the filename is
added; if FALSE, it is not added.
Remarks
Depending on the value of bAddToMRU the path is added, or not added, to the MRU list maintained by the
application. Note that some documents are not associated with a disk file. Call this function only if you are
overriding the default implementation for opening and saving files used by the framework.

CDocument::SetTitle
Call this function to specify the document's title (the string displayed in the title bar of a frame window).

virtual void SetTitle(LPCTSTR lpszTitle);

Parameters
lpszTitle
Points to the string to be used as the document's title.
Remarks
Calling this function updates the titles of all frame windows that display the document.

CDocument::UpdateAllViews
Call this function after the document has been modified.

void UpdateAllViews(
CView* pSender,
LPARAM lHint = 0L,
CObject* pHint = NULL);

Parameters
pSender
Points to the view that modified the document, or NULL if all views are to be updated.
lHint
Contains information about the modification.
pHint
Points to an object storing information about the modification.
Remarks
You should call this function after you call the SetModifiedFlag member function. This function informs
each view attached to the document, except for the view specified by pSender, that the document has been
modified. You typically call this function from your view class after the user has changed the document
through a view.
This function calls the CView::OnUpdate member function for each of the document's views except the
sending view, passing pHint and lHint. Use these parameters to pass information to the views about the
modifications made to the document. You can encode information using lHint and/or you can define a
CObject-derived class to store information about the modifications and pass an object of that class using
pHint. Override the CView::OnUpdate member function in your CView-derived class to optimize the
updating of the view's display based on the information passed.
Example

void CExampleDoc::OnUpdateAllViews()
{
UpdateAllViews(NULL);
}

See also
MFC Sample MDIDOCVW
MFC Sample SNAPVW
MFC Sample NPP
CCmdTarget Class
Hierarchy Chart
CCmdTarget Class
CView Class
CDocTemplate Class
CDragListBox Class
3/27/2020 • 3 minutes to read • Edit Online

In addition to providing the functionality of a Windows list box, the CDragListBox class allows the user to move list
box items, such as filenames, within the list box.

Syntax
class CDragListBox : public CListBox

Members
Public Constructors
NAME DESC RIP T IO N

CDragListBox::CDragListBox Constructs a CDragListBox object.

Public Methods
NAME DESC RIP T IO N

CDragListBox::BeginDrag Called by the framework when a drag operation starts.

CDragListBox::CancelDrag Called by the framework when a drag operation has been


canceled.

CDragListBox::Dragging Called by the framework during a drag operation.

CDragListBox::DrawInsert Draws the insertion guide of the drag list box.

CDragListBox::Dropped Called by the framework after the item has been dropped.

CDragListBox::ItemFromPt Returns the coordinates of the item being dragged.

Remarks
List boxes with this capability allow users to order the items in a list in whatever manner is most useful to them. By
default, the list box will move the item to the new location in the list. However, CDragListBox objects can be
customized to copy items instead of moving them.
The list box control associated with the CDragListBox class must not have the LBS_SORT or the
LBS_MULTIPLESELECT style. For a description of list box styles, see List-Box Styles.
To use a drag list box in an existing dialog box of your application, add a list box control to your dialog template
using the dialog editor and then assign a member variable (of Category Control and Variable Type CDragListBox )
corresponding to the list box control in your dialog template.
For more information on assigning controls to member variables, see Shortcut for Defining Member Variables for
Dialog Controls.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CListBox
CDragListBox

Requirements
Header : afxcmn.h

CDragListBox::BeginDrag
Called by the framework when an event occurs that could begin a drag operation, such as pressing the left mouse
button.

virtual BOOL BeginDrag(CPoint pt);

Parameters
pt
A CPoint object that contains the coordinates of the item being dragged.
Return Value
Nonzero if dragging is allowed, otherwise 0.
Remarks
Override this function if you want to control what happens when a drag operation begins. The default
implementation captures the mouse and stays in drag mode until the user clicks the left or right mouse button or
presses ESC, at which time the drag operation is canceled.

CDragListBox::CancelDrag
Called by the framework when a drag operation has been canceled.

virtual void CancelDrag(CPoint pt);

Parameters
pt
A CPoint object that contains the coordinates of the item being dragged.
Remarks
Override this function to handle any special processing for your list box control.

CDragListBox::CDragListBox
Constructs a CDragListBox object.
CDragListBox();

CDragListBox::Dragging
Called by the framework when a list box item is being dragged within the CDragListBox object.

virtual UINT Dragging(CPoint pt);

Parameters
pt
A CPoint object that contains the x and y screen coordinates of the cursor.
Return Value
The resource ID of the cursor to be displayed. The following values are possible:
DL_COPYCURSOR Indicates that the item will be copied.
DL_MOVECURSOR Indicates that the item will be moved.
DL_STOPCURSOR Indicates that the current drop target is not acceptable.
Remarks
The default behavior returns DL_MOVECURSOR. Override this function if you want to provide additional
functionality.

CDragListBox::DrawInsert
Called by the framework to draw the insertion guide before the item with the indicated index.

virtual void DrawInsert(int nItem);

Parameters
nItem
Zero-based index of the insertion point.
Remarks
A value of - 1 clears the insertion guide. Override this function to modify the appearance or behavior of the
insertion guide.

CDragListBox::Dropped
Called by the framework when an item is dropped within a CDragListBox object.

virtual void Dropped(


int nSrcIndex,
CPoint pt);

Parameters
nSrcIndex
Specifies the zero-based index of the dropped string.
pt
A CPoint object that contains the coordinates of the drop site.
Remarks
The default behavior copies the list box item and its data to the new location and then deletes the original item.
Override this function to customize the default behavior, such as enabling copies of list box items to be dragged to
other locations within the list.

CDragListBox::ItemFromPt
Call this function to retrieve the zero-based index of the list box item located at pt.

int ItemFromPt(
CPoint pt,
BOOL bAutoScroll = TRUE) const;

Parameters
pt
A CPoint object containing the coordinates of a point within the list box.
bAutoScroll
Nonzero if scrolling is allowed, otherwise 0.
Return Value
Zero-based index of the drag list box item.

See also
MFC Sample TSTCON
CListBox Class
Hierarchy Chart
CListBox Class
CDrawingManager Class
4/21/2020 • 19 minutes to read • Edit Online

The CDrawingManager class implements complex drawing algorithms.

Syntax
class CDrawingManager : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CDrawingManager::CDrawingManager Constructs a CDrawingManager object.

CDrawingManager::~CDrawingManager Destructor.

Public Methods
NAME DESC RIP T IO N

CDrawingManager::CreateBitmap_32 Creates a 32-bit device-independent bitmap (DIB) that


applications can write to directly.

CDrawingManager::DrawAlpha Displays bitmaps that have transparent or semitransparent


pixels.

CDrawingManager::DrawRotated Rotates a source DC content inside the given rectangle by +/-


90 degrees

CDrawingManager::DrawEllipse Draws an ellipse with the supplied fill and border colors.

CDrawingManager::DrawGradientRing Draws a ring and fills it with a color gradient.

CDrawingManager::DrawLine, CDrawingManager::DrawLineA Draws a line.

CDrawingManager::DrawRect Draws a rectangle with the supplied fill and border colors.

CDrawingManager::DrawShadow Draws a shadow for a rectangular area.

CDrawingManager::Fill4ColorsGradient Fills a rectangular area with two color gradients.

CDrawingManager::FillGradient Fills a rectangular area with a specified color gradient.

CDrawingManager::FillGradient2 Fills a rectangular area with a specified color gradient. The


direction of the gradient's color change is also specified.
NAME DESC RIP T IO N

CDrawingManager::GrayRect Fills a rectangle with a specified gray color.

CDrawingManager::HighlightRect Highlights a rectangular area.

CDrawingManager::HLStoRGB_ONE Converts a color from a HLS representation to a RGB


representation.

CDrawingManager::HLStoRGB_TWO Converts a color from a HLS representation to a RGB


representation.

CDrawingManager::HSVtoRGB Converts a color from a HSV representation to a RGB


representation.

CDrawingManager::HuetoRGB Helper method that converts a hue value to a red, green, or


blue component.

CDrawingManager::MirrorRect Flips a rectangular area.

CDrawingManager::PixelAlpha Helper method that determines the final color for a


semitransparent pixel.

CDrawingManager::PrepareShadowMask Creates a bitmap that can be used as a shadow.

CDrawingManager::RGBtoHSL Converts a color from a RGB representation to a HSL


representation.

CDrawingManager::RGBtoHSV Converts a color from a RGB representation to a HSV


representation.

CDrawingManager::SetAlphaPixel Helper method that colors a partially transparent pixel in a


bitmap.

CDrawingManager::SetPixel Helper method that changes a single pixel in a bitmap to the


specified color.

CDrawingManager::SmartMixColors Combines two colors based on a weighted ratio.

Remarks
The CDrawingManager class provides functions for drawing shadows, color gradients, and highlighted rectangles. It
also performs alpha-blending. You can use this class to directly change your application's UI.

Inheritance Hierarchy
CObject
CDrawingManager

Requirements
Header : afxdrawmanager.h

CDrawingManager::CDrawingManager
Constructs a CDrawingManager object.

CDrawingManager(CDC& dc);

Parameters
dc
[in] A reference to a device context. The CDrawingManager uses this context for drawing.

CDrawingManager::CreateBitmap_32
Creates a 32-bit device-independent bitmap (DIB) that applications can write to directly.

static HBITMAP __stdcall CreateBitmap_32(


const CSize& size,
void** pBits);

static HBITMAP __stdcall CreateBitmap_32(


HBITMAP bitmap,
COLORREF clrTransparent = -1);

Parameters

Parameter Description

size [in] A CSize parameter that indicates the size of the bitmap.

pBits [out] A pointer to a data pointer that receives the location of


the DIB's bit values.

bitmap A handle to the original bitmap

clrTransparent An RGB value specifying transparent color of the original


bitmap.

Return Value
A handle to the newly created DIB bitmap if this method is successful; otherwise NULL.
Remarks
For more information about how to create a DIB bitmap, see CreateDIBSection.

CDrawingManager::DrawAlpha
Displays bitmaps that have transparent or semitransparent pixels.

void DrawAlpha(
CDC* pDstDC,
const CRect& rectDst,
CDC* pSrcDC,
const CRect& rectSrc);

Parameters
pDstDC
[in] A pointer to the device context for the destination.
rectDst
[in] The destination rectangle.
pSrcDC
[in] A pointer to the device context for the source.
rectSrc
[in] The source rectangle.
Remarks
This method performs alpha-blending for two bitmaps. For more information about alpha-blending, see
AlphaBlend in the Windows SDK.

CDrawingManager::DrawEllipse
Draws an ellipse with the supplied fill and border colors.

void DrawEllipse(
const CRect& rect,
COLORREF clrFill,
COLORREF clrLine);

Parameters
rect
[in] The bounding rectangle for the ellipse.
clrFill
[in] The color this method uses to fill the ellipse.
clrLine
[in] The color this method uses as the border of the ellipse.
Remarks
This method returns without drawing an ellipse if either color is set to -1. It also returns without drawing an ellipse
if either dimension of the bounding rectangle is 0.

CDrawingManager::DrawGradientRing
Draws a ring and fills it with a color gradient.

BOOL DrawGradientRing(
CRect rect,
COLORREF colorStart,
COLORREF colorFinish,
COLORREF colorBorder,
int nAngle,
int nWidth,
COLORREF clrFace = (COLORREF)-1);

Parameters
rect
[in] A CRect parameter that specifies the boundary for the gradient ring.
colorStart
[in] The first color for the gradient.
colorFinish
[in] The last color for the gradient.
colorBorder
[in] The color of the border.
nAngle
[in] A parameter that specifies the initial gradient drawing angle. This value should be between 0 and 360.
nWidth
[in] The width of the border for the ring.
clrFace
[in] The color of the interior of the ring.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The rectangle defined by rect must be at least 5 pixels wide and 5 pixels high.

CDrawingManager::DrawLine, CDrawingManager::DrawLineA
Draws a line.

void DrawLine(
int x1,
int y1,
int x2,
int y2,
COLORREF clrLine);

void DrawLineA(
double x1,
double y1,
double x2,
double y2,
COLORREF clrLine);

Parameters

Parameter Description

x1 [in] The x coordinate where the line starts.

y1 [in] The y coordinate where the line starts.

x2 [in] The x coordinate where the line ends.

y2 [in] The y coordinate where the line ends.

clrLine [in] The color of the line.

Remarks
This method fails if clrLine equals -1.
CDrawingManager::DrawRect
Draws a rectangle with the supplied fill and border colors.

void DrawRect(
const CRect& rect,
COLORREF clrFill,
COLORREF clrLine);

Parameters
rect
[in] The boundaries for the rectangle.
clrFill
[in] The color this method uses to fill the rectangle.
clrLine
[in] The color this method uses for the border of the rectangle.
Remarks
This method returns without drawing a rectangle if either color is set to -1. It also returns if either dimension of the
rectangle is 0.

CDrawingManager::DrawShadow
Draws a shadow for a rectangular area.

BOOL DrawShadow(
CRect rect,
int nDepth,
int iMinBrightness = 100,
int iMaxBrightness = 50,
CBitmap* pBmpSaveBottom = NULL,
CBitmap* pBmpSaveRight = NULL,
COLORREF clrBase = (COLORREF)-1,
BOOL bRightShadow = TRUE);

Parameters
rect
[in] A rectangular area in your application. The drawing manager will draw a shadow underneath this area.
nDepth
[in] The width and height of the shadow.
iMinBrightness
[in] The minimum brightness of the shadow.
iMaxBrightness
[in] The maximum brightness of the shadow.
pBmpSaveBottom
[in] A pointer to a bitmap that contains the image for the bottom part of the shadow.
pBmpSaveRight
[in] A pointer to a bitmap that contains the image for the shadow that is drawn on the right side of the rectangle.
clrBase
[in] The color of the shadow.
bRightShadow
[in] A Boolean parameter that indicates how the shadow is drawn. If bRightShadow is TRUE , DrawShadow draws a
shadow on the right side of the rectangle.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You can provide two valid bitmaps for the bottom and right shadows by using the parameters pBmpSaveBottom
and pBmpSaveRight. If these CBitmap objects have an attached GDI object, DrawShadow will use those bitmaps as
the shadows. If the CBitmap parameters do not have an attached GDI object, DrawShadow draws the shadow and
attaches the bitmaps to the parameters. In future calls to DrawShadow , you can provide these bitmaps to speed up
the drawing process. For more information about the CBitmap class and GDI objects, see Graphic Objects.
If either of these parameters is NULL , DrawShadow will automatically draw the shadow.
If you set bRightShadow to FALSE, the shadow will be drawn underneath and to the left of the rectangular area.
Example
The following example demonstrates how to use the DrawShadow method of the CDrawingManager class. This code
snippet is part of the Prop Sheet Demo sample.

// CDC* pDC
// CRect rectHeader
CDrawingManager dm(*pDC);
// Draw a shadow for a rectangular area.
// second parameter is the depth of the shadow
dm.DrawShadow(rectHeader, 2);

CDrawingManager::Fill4ColorsGradient
Fills a rectangular area with two color gradients.

void Fill4ColorsGradient(
CRect rect,
COLORREF colorStart1,
COLORREF colorFinish1,
COLORREF colorStart2,
COLORREF colorFinish2,
BOOL bHorz = TRUE,
int nPercentage = 50);

Parameters
rect
[in] The rectangle to fill.
colorStart1
[in] The initial color for the first color gradient.
colorFinish1
[in] The final color for the first color gradient.
colorStart2
[in] The initial color for the second color gradient.
colorFinish2
[in] The final color for the second color gradient.
bHorz
[in] A Boolean parameter that indicates whether Fill4ColorsGradient colors a horizontal or vertical gradient. TRUE
indicates a horizontal gradient.
nPercentage
[in] An integer from 0-100. This value indicates the percentage of the rectangle to fill with the first color gradient.
Remarks
When a rectangle is filled with two color gradients, they are either located above each other or next to each other,
depending on the value of bHorz. Each color gradient is calculated independently with the method
CDrawingManager::FillGradient.
This method generates an assertion failure if nPercentage is less than 0 or more than 100.

CDrawingManager::FillGradient
Fills a rectangular area with the specified color gradient.

void FillGradient(
CRect rect,
COLORREF colorStart,
COLORREF colorFinish,
BOOL bHorz = TRUE,
int nStartFlatPercentage = 0,
int nEndFlatPercentage = 0);

Parameters
rect
[in] The rectangular area to fill.
colorStart
[in] The first color for the gradient.
colorFinish
[in] The final color for the gradient.
bHorz
[in] A Boolean parameter that specifies whether FillGradient should draw a horizontal or vertical gradient.
nStartFlatPercentage
[in] The percentage of the rectangle that FillGradient fills with colorStart before it starts the gradient.
nEndFlatPercentage
[in] The percentage of the rectangle that FillGradient fills with colorFinish after it finishes the gradient.
Example
The following example demonstrates how to use the FillGradient method of the CDrawingManager class. This code
snippet is part of the MS Office 2007 Demo sample.

// CRect rectScreen
// CDrawingManager dm
dm.FillGradient(rectScreen, RGB(114, 125, 152), RGB(178, 185, 202), TRUE);

CDrawingManager::FillGradient2
CDrawingManager::FillGradient2
Fills a rectangular area with a specified color gradient.

void FillGradient2 (
CRect rect,
COLORREF colorStart,
COLORREF colorFinish,
int nAngle = 0);

Parameters
rect
[in] The rectangular area to fill.
colorStart
[in] The first color of the gradient.
colorFinish
[in] The last color of the gradient.
nAngle
[in] An integer between 0 and 360. This parameter specifies the direction of the color gradient.
Remarks
Use nAngle to specify the direction of the color gradient. When you specify the direction of the color gradient, you
also specify where the color gradient starts. A value of 0 for nAngle indicates the gradient starts from the top of the
rectangle. As nAngle increases, the starting location for the gradient moves in a counter-clockwise direction based
on the angle.
Example
The following example demonstrates how to use the FillGradient2 method of the CDrawingManager class. This
code snippet is part of the New Controls sample.

// CRect rect
// CDC* pDC
CDrawingManager dm(*pDC);
// The last parameter is the angle that specifies the direction of the color gradient.
dm.FillGradient2(rect, RGB(102, 200, 238), RGB(0, 129, 185), 45);

CDrawingManager::GrayRect
Fills a rectangle with a specified gray color.

BOOL GrayRect(
CRect rect,
int nPercentage = -1,
COLORREF clrTransparent = (COLORREF)-1,
COLORREF clrDisabled = (COLORREF)-1);

Parameters
rect
[in] The rectangular area to fill.
nPercentage
[in] The percentage of gray you want in the rectangle.
clrTransparent
[in] The transparent color.
clrDisabled
[in] The color that this method uses for de-saturation if nPercentage is set to -1.
Return Value
TRUE if the method was successful; otherwise FALSE.
Remarks
For the parameter nPercentage, a lower value indicates a darker color.
The maximum value for nPercentage is 200. A value larger than 200 does not change the appearance of the
rectangle. If the value is -1, this method uses clrDisabled to limit the saturation of the rectangle.

CDrawingManager::HighlightRect
Highlights a rectangular area.

BOOL HighlightRect(
CRect rect,
int nPercentage = -1,
COLORREF clrTransparent = (COLORREF)-1,
int nTolerance = 0,
COLORREF clrBlend = (COLORREF)-1);

Parameters
rect
[in] A rectangular area to highlight.
nPercentage
[in] A percentage that indicates how transparent the highlight should be.
clrTransparent
[in] The transparent color.
nTolerance
[in] An integer between 0 and 255 that indicates the color tolerance.
clrBlend
[in] The base color for blending.
Return Value
TRUE if the method is successful; otherwise FALSE.
Remarks
If nPercentage is between 0 and 99, HighlightRect uses the alpha blending algorithm. For more information about
alpha blending, see Alpha Blending Lines and Fills. If nPercentage is -1, this method uses the default highlight level.
If nPercentage is 100, this method does nothing and returns TRUE.
The method uses the parameter nTolerance to determine whether to highlight the rectangular area. To highlight the
rectangle, the difference between the background color of your application and clrTransparent must be less than
nTolerance in each color component (red, green, and blue).

CDrawingManager::HLStoRGB_ONE
Converts a color from a HLS representation to a RGB representation.
static COLORREF __stdcall HLStoRGB_ONE(
double H,
double L,
double S);

Parameters
H
[in] A number between 0 and 1 that represents the hue for the color.
L
[in] A number between 0 and 1 that indicates the luminosity for the color.
S
[in] A number between 0 and 1 that indicates the saturation for the color.
Return Value
The RGB representation of the HLS color provided.
Remarks
A color can be represented as HSV (hue, saturation, and value), HSL (hue, saturation, and luminosity), or RGB (red,
green, and blue). For more information about the different representations of color, see Color.
This method and the CDrawingManager::HLStoRGB_TWO method perform the same operation, but require different
values for the H parameter. In this method, H is a percentage of the circle. In the CDrawingManager::HLStoRGB_TWO
method, H is a degree value between 0 and 360, which both represent red. For example, with HLStoRGB_ONE , a
value of 0.25 for H is equivalent to a value of 90 with HLStoRGB_TWO .

CDrawingManager::HLStoRGB_TWO
Converts a color from a HLS representation to a RGB representation.

static COLORREF __stdcall HLStoRGB_TWO(


double H,
double L,
double S);

Parameters
H
[in] A number between 0 and 360 that represents the hue for the color.
L
[in] A number between 0 and 1 that indicates the luminosity for the color.
S
[in] A number between 0 and 1 that indicates the saturation for the color.
Return Value
The RGB representation of the HLS color provided.
Remarks
A color can be represented as HSV (hue, saturation, and value), HSL (hue, saturation, and luminosity), or RGB (red,
green, and blue). For more information about the different representations of color, see Color.
This method and the CDrawingManager::HLStoRGB_ONE method perform the same operation, but require
different values for the H parameter. In this method, H is a degree value between 0 and 360, which both represent
red. In the CDrawingManager::HLStoRGB_ONE method, H is a percentage of the circle. For example, with
HLStoRGB_ONE , a value of 0.25 for H is equivalent to a value of 90 with HLStoRGB_TWO .

CDrawingManager::HSVtoRGB
Converts a color from a HSV representation to a RGB representation.

static COLORREF __stdcall HSVtoRGB(


double H,
double S,
double V);

Parameters

Parameter Description

H [in] A number between 0 and 360 that indicates the hue for
the color.

S [in] A number between 0 and 1 that indicates the saturation


for the color.

V [in] A number between 0 and 1 that indicates the value for the
color.

Return Value
The RGB representation of the HSV color provided.
Remarks
A color can be represented as HSV (hue, saturation, and value), HSL (hue, saturation, and luminosity), or RGB (red,
green, and blue). For more information about the different representations of color, see Color.

CDrawingManager::HuetoRGB
Converts a hue value to a red, green, or blue component.

static double __stdcall HuetoRGB(


double m1,
double m2,
double h);

static BYTE __stdcall HueToRGB(


float rm1,
float rm2,
float rh);

Parameters
m1
[in] See Remarks.
m2
[in] See Remarks.
h
[in] See Remarks.
rm1
[in] See Remarks.
rm2
[in] See Remarks.
rh
[in] See Remarks.
Return Value
The individual red, green, or blue component for the provided hue.
Remarks
This method is a helper method that the CDrawingManager class uses to compute the individual red, green, and blue
components of a color in a HSV or HSL representation. This method is not designed to be called directly by the
programmer. The input parameters are values that depend on the conversion algorithm.
To convert a HSV or HSL color to a RGB representation, call one of the following methods:
CDrawingManager::HSVtoRGB
CDrawingManager::HLStoRGB_ONE
CDrawingManager::HLStoRGB_TWO

CDrawingManager::MirrorRect
Flips a rectangular area.

void MirrorRect(
CRect rect,
BOOL bHorz = TRUE);

Parameters
rect
[in] The bounding rectangle of the area to flip.
bHorz
[in] A Boolean parameter that indicates whether the rectangle flips horizontally or vertically.
Remarks
This method can flip any area of the device context owned by the CDrawingManager class. If bHorz is set to TRUE,
this method flips the area horizontally. Otherwise, it flips the area vertically.

CDrawingManager::PixelAlpha
Calculates the final color for a semitransparent pixel.
static COLORREF __stdcall PixelAlpha(
COLORREF srcPixel,
int percent);

static COLORREF __stdcall PixelAlpha(


COLORREF srcPixel,
double percentR,
double percentG,
double percentB);

static COLORREF __stdcall PixelAlpha(


COLORREF srcPixel,
COLORREF dstPixel,
int percent);

Parameters
srcPixel
[in] The initial color for the pixel.
percent
[in] A number between 0 and 100 that represents the percentage of transparency. A value of 100 indicates that the
initial color is completely transparent.
percentR
[in] A number between 0 and 100 that represents the percentage of transparency for the red component.
percentG
[in] A number between 0 and 100 that represents the percentage of transparency for the green component.
percentB
[in] A number between 0 and 100 that represents the percentage of transparency for the blue component.
dstPixel
[in] The base color for the pixel.
Return Value
The final color for the semitransparent pixel.
Remarks
This is a helper class for coloring semitransparent bitmaps and is not designed to be called directly by the
programmer.
When you use the version of the method that has dstPixel, the final color is a combination of dstPixel and srcPixel.
The srcPixel color is the partially transparent color over the base color of dstPixel.

CDrawingManager::PrepareShadowMask
Creates a bitmap that can be used as a shadow.

static HBITMAP __stdcall PrepareShadowMask (


int nDepth,
COLORREF clrBase,
int iMinBrightness = 0,
int iMaxBrightness = 100);

Parameters
nDepth
[in] The width and height of the shadow.
clrBase
[in] The color of the shadow.
iMinBrightness
[in] The minimum brightness of the shadow.
iMaxBrightness
[in] The maximum brightness of the shadow.
Return Value
A handle to the created bitmap if this method is successful; otherwise NULL.
Remarks
If nDepth is set to 0, this method exits and returns NULL. If nDepth is less than 3, the width and height of the
shadow are set to 3 pixels.

CDrawingManager::RGBtoHSL
Converts a color from a red, green, and blue (RGB) representation to a hue, saturation, and lightness (HSL)
representation.

static void __stdcall RGBtoHSL(


COLORREF rgb,
double* H,
double* S,
double* L);

Parameters

Parameter Description

rgb [in] The color in RGB values.

H [out] A pointer to a double where the method stores the hue


for the color.

S [out] A pointer to a double where the method stores the


saturation for the color.

L [out] A pointer to a double where the method stores the


lightness for the color.

Remarks
A color can be represented as HSV (hue, saturation, and value), HSL (hue, saturation, and luminosity), or RGB (red,
green, and blue). For more information about the different representations of color, see Color.
The returned value for H is represented as a fraction between 0 and 1 where both 0 and 1 represent red. The
returned values for S and L are numbers between 0 and 1.

CDrawingManager::RGBtoHSV
Converts a color from a RGB representation to a HSV representation.
static void __stdcall RGBtoHSV(
COLORREF rgb,
double* H,
double* S,
double* V);

Parameters
rgb
[in] The color to convert in a RGB representation.
H
[out] A pointer to a double where this method stores the resulting hue for the color.
S
[out] A pointer to a double where this method stores the resulting saturation for the color.
V
[out] A pointer to a double where this method stores the resulting value for the color.
Remarks
A color can be represented as HSV (hue, saturation, and value), HSL (hue, saturation, and luminosity), or RGB (red,
green, and blue). For more information about the different representations of color, see Color.
The returned value for H is a number between 0 and 360 where both 0 and 360 indicate red. The return values for
S and V are numbers between 0 and 1.

CDrawingManager::SetAlphaPixel
Colors a transparent pixel in a bitmap.

static void __stdcall SetAlphaPixel(


COLORREF* pBits,
CRect rect,
int x,
int y,
int percent,
int iShadowSize,
COLORREF clrBase = (COLORREF)-1,
BOOL bIsRight = TRUE);

Parameters
pBits
[in] A pointer to the bit values for the bitmap.
rect
[in] A rectangular area in your application. The drawing manager draws a shadow underneath and to the right of
this area.
x
[in] The horizontal coordinate of the pixel to color.
y
[in] The vertical coordinate of the pixel to color.
percent
[in] The percentage of transparency.
iShadowSize
[in] The width and height of the shadow.
clrBase
[in] The color of the shadow.
bIsRight
[in] A Boolean parameter that indicates which pixel to color. See the Remarks section for more information.
Remarks
This method is a helper method that is used by the CDrawingManager::DrawShadow method. We recommend that
if you want to draw a shadow, call CDrawingManager::DrawShadow instead.
If bIsRight is set to TRUE, the pixel to color is measured x pixels from the right edge of rect. If it is FALSE, the pixel to
color is measured x pixels from the left edge of rect.

CDrawingManager::SetPixel
Changes a single pixel in a bitmap to the specified color.

static void __stdcall SetPixel(


COLORREF* pBits,
int cx,
int cy,
int x,
int y,
COLORREF color);

Parameters

Parameter Description

pBits [in] A pointer to the bit values of the bitmap.

cx [in] The total width of the bitmap.

cy [in] The total height of the bitmap.

x [in] The x-coordinate of the pixel in the bitmap to change.

y [in] The y-coordinate of the pixel in the bitmap to change.

color [in] The new color for the pixel identified by the supplied
coordinates.

CDrawingManager::SmartMixColors
Combines two colors based on a weighted ratio.
static COLORREF __stdcall SmartMixColors(
COLORREF color1,
COLORREF color2,
double dblLumRatio = 1.,
int k1 = 1,
int k2 = 1);

Parameters

Parameter Description

color1 [in] The first color to mix.

color2 [in] The second color to mix.

dblLumRatio [in] The ratio for the new color's luminosity. SmartMixColors
multiplies the luminosity of the mixed color by this ratio
before determining a final color.

k1 [in] The weighted ratio for the first color.

k2 [in] The weighted ratio for the second color.

Return Value
A color that represents a weighted mixture of the supplied colors.
Remarks
This method fails with an error if either k1 or k2 is less than zero. If both of these parameters are set to 0, the
method returns RGB(0, 0, 0) .
The weighted ratio is calculated with the following formula: (color1 * k1 + color2 * k2)/(k1 + k2). After the
weighted ratio is determined, the method calculates the luminosity for the mixed color. It then multiplies the
luminosity by dblLumRatio. If the value is larger than 1.0, the method sets the luminosity for the mixed color to the
new value. Otherwise, the luminosity is set to 1.0.

CDrawingManager::DrawRotated
Rotates a source DC content inside the given rectangle by 90 degrees.

void DrawRotated(
CRect rectDest,
CDC& dcSrc,
BOOL bClockWise);

Parameters
rectDest
Destination rectangle.
dcSrc
The source device context.
bClockWise
TRUE indicates rotate +90 degrees; FALSE indicates rotate -90 degrees.
Remarks

See also
Hierarchy Chart
Classes
CDumpContext Class
4/21/2020 • 5 minutes to read • Edit Online

Supports stream-oriented diagnostic output in the form of human-readable text.

Syntax
class CDumpContext

Members
Public Constructors
NAME DESC RIP T IO N

CDumpContext::CDumpContext Constructs a CDumpContext object.

Public Methods
NAME DESC RIP T IO N

CDumpContext::DumpAsHex Dumps the indicated item in hexadecimal format.

CDumpContext::Flush Flushes any data in the dump context buffer.

CDumpContext::GetDepth Gets an integer corresponding to the depth of the dump.

CDumpContext::HexDump Dumps bytes contained in an array in hexadecimal format.

CDumpContext::SetDepth Sets the depth of the dump.

Public Operators
NAME DESC RIP T IO N

CDumpContext::operator << Inserts variables and objects into the dump context.

Remarks
CDumpContext does not have a base class.
You can use afxDump, a predeclared CDumpContext object, for most of your dumping. The afxDump object is
available only in the Debug version of the Microsoft Foundation Class Library.
Several of the memory diagnostic services use afxDump for their output.
Under the Windows environment, the output from the predefined afxDump object, conceptually similar to the
cerr stream, is routed to the debugger via the Windows function OutputDebugString .

The CDumpContext class has an overloaded insertion ( << ) operator for CObject pointers that dumps the object's
data. If you need a custom dump format for a derived object, override CObject::Dump. Most Microsoft Foundation
classes implement an overridden Dump member function.
Classes that are not derived from CObject , such as CString , CTime , and CTimeSpan , have their own overloaded
CDumpContext insertion operators, as do often-used structures such as CFileStatus , CPoint , and CRect .

If you use the IMPLEMENT_DYNAMIC or IMPLEMENT_SERIAL macro in the implementation of your class, then
CObject::Dump will print the name of your CObject -derived class. Otherwise, it will print CObject .

The CDumpContext class is available with both the Debug and Release versions of the library, but the Dump
member function is defined only in the Debug version. Use #ifdef _DEBUG / #endif statements to bracket your
diagnostic code, including your custom Dump member functions.
Before you create your own CDumpContext object, you must create a CFile object that serves as the dump
destination.
For more information on CDumpContext , see Debugging MFC Applications.
#define _DEBUG

Inheritance Hierarchy
CDumpContext

Requirements
Header : afx.h

CDumpContext::CDumpContext
Constructs an object of class CDumpContext .

CDumpContext(CFile* pFile = NULL);

Parameters
pFile
A pointer to the CFile object that is the dump destination.
Remarks
The afxDump object is constructed automatically.
Do not write to the underlying CFile while the dump context is active; otherwise, you will interfere with the
dump. Under the Windows environment, the output is routed to the debugger via the Windows function
OutputDebugString .

Example

CFile f;
if (!f.Open(_T("dump.txt"), CFile::modeCreate | CFile::modeWrite))
{
AFXDUMP(_T("Unable to open file\n"));
exit(1);
}
CDumpContext dc(&f);
CDumpContext::DumpAsHex
Dumps the specified type formatted as hexadecimal numbers.

CDumpContext& DumpAsHex(BYTE b);


CDumpContext& DumpAsHex(DWORD dw);
CDumpContext& DumpAsHex(int n);
CDumpContext& DumpAsHex(LONG l);
CDumpContext& DumpAsHex(LONGLONG n);
CDumpContext& DumpAsHex(UINT u);
CDumpContext& DumpAsHex(ULONGLONG n);
CDumpContext& DumpAsHex(WORD w);

Return Value
A reference to a CDumpContext object.
Remarks
Call this member function to dump the item of the specified type as a hexadecimal number. To dump an array, call
CDumpContext::HexDump.
Example

#if _DEBUG
afxDump.DumpAsHex(115);
#endif

CDumpContext::Flush
Forces any data remaining in buffers to be written to the file attached to the dump context.

void Flush();

Example

#if _DEBUG
afxDump.Flush();
#endif

CDumpContext::GetDepth
Determines whether a deep or shallow dump is in process.

int GetDepth() const;

Return Value
The depth of the dump as set by SetDepth .
Example
See the example for SetDepth.

CDumpContext::HexDump
Dumps an array of bytes formatted as hexadecimal numbers.
void HexDump(
LPCTSTR lpszLine,
BYTE* pby,
int nBytes,
int nWidth);

Parameters
lpszLine
A string to output at the start of a new line.
pby
A pointer to a buffer containing the bytes to dump.
nBytes
The number of bytes to dump.
nWidth
Maximum number of bytes dumped per line (not the width of the output line).
Remarks
To dump a single, specific item type as a hexadecimal number, call CDumpContext::DumpAsHex.
Example

#if _DEBUG
TCHAR test[] = _T("This is a test of CDumpContext::HexDump\n");
afxDump.HexDump(_T("."), (BYTE *)test, sizeof(test), 20);
#endif

CDumpContext::operator <<
Outputs the specified data to the dump context.

CDumpContext& operator<<(const CObject* pOb);


CDumpContext& operator<<(const CObject& ob);
CDumpContext& operator<<(LPCTSTR lpsz);
CDumpContext& operator<<(const void* lp);
CDumpContext& operator<<(BYTE by);
CDumpContext& operator<<(WORD w);
CDumpContext& operator<<(DWORD dw);
CDumpContext& operator<<(int n);
CDumpContext& operator<<(double d);
CDumpContext& operator<<(float f);
CDumpContext& operator<<(LONG l);
CDumpContext& operator<<(UINT u);
CDumpContext& operator<<(LPCWSTR lpsz);
CDumpContext& operator<<(LPCSTR lpsz);
CDumpContext& operator<<(LONGLONG n);
CDumpContext& operator<<(ULONGLONG n);
CDumpContext& operator<<(HWND h);
CDumpContext& operator<<(HDC h);
CDumpContext& operator<<(HMENU h);
CDumpContext& operator<<(HACCEL h);
CDumpContext& operator<<(HFONT h);

Return Value
A CDumpContext reference. Using the return value, you can write multiple insertions on a single line of source
code.
Remarks
The insertion operator is overloaded for CObject pointers as well as for most primitive types. A pointer to
character results in a dump of string contents; a pointer to void results in a hexadecimal dump of the address
only. A LONGLONG results in a dump of a 64-bit signed integer; A ULONGLONG results in a dump of a 64-bit
unsigned integer.
If you use the IMPLEMENT_DYNAMIC or IMPLEMENT_SERIAL macro in the implementation of your class, then the
insertion operator, through CObject::Dump , will print the name of your CObject -derived class. Otherwise, it will
print CObject . If you override the Dump function of the class, then you can provide a more meaningful output of
the object's contents instead of a hexadecimal dump.
Example

#if _DEBUG
CStringList li;
li.AddHead(_T("item 0"));
li.AddHead(_T("item 1"));
CString s = _T("test");
int i = 7;
long lo = 1000000000L;
LONGLONG lolo = 12345678901234i64;
afxDump << _T("list=") << &li << _T("string=")
<< s << _T("int=") << i << _T("long=") << lo
<< _T("LONGLONG=") << lolo << _T("\n");
#endif

CDumpContext::SetDepth
Sets the depth for the dump.

void SetDepth(int nNewDepth);

Parameters
nNewDepth
The new depth value.
Remarks
If you are dumping a primitive type or simple CObject that contains no pointers to other objects, then a value of
0 is sufficient. A value greater than 0 specifies a deep dump where all objects are dumped recursively. For
example, a deep dump of a collection will dump all elements of the collection. You may use other specific depth
values in your derived classes.

NOTE
Circular references are not detected in deep dumps and can result in infinite loops.

Example

#if _DEBUG
afxDump.SetDepth(1); // Specifies deep dump
ASSERT(afxDump.GetDepth() == 1);
#endif

See also
Hierarchy Chart
CFile Class
CObject Class
CDWordArray Class
3/27/2020 • 2 minutes to read • Edit Online

Supports arrays of 32-bit doublewords.

Syntax
class CDWordArray : public CObject

Members
The member functions of CDWordArray are similar to the member functions of class CObArray. Because of this
similarity, you can use the CObArray reference documentation for member function specifics. Wherever you see
a CObject pointer as a function parameter or return value, substitute a DWORD .
CObject* CObArray::GetAt( int <nIndex> ) const;

for example, translates to


DWORD CDWordArray::GetAt( int <nIndex> ) const;

Public Constructors
NAME DESC RIP T IO N

CDWordArray::CDWordArray Constructs an empty array.

Public Methods
NAME DESC RIP T IO N

CDWordArray::Add Adds an element to the end of the array; grows the array if
necessary.

CDWordArray::Append Appends another array to the array; grows the array if


necessary.

CDWordArray::Copy Copies another array to the array; grows the array if


necessary.

CDWordArray::ElementAt Returns a temporary reference to the byte within the array.

CDWordArray::FreeExtra Frees all unused memory above the current upper bound.

CDWordArray::GetAt Returns the value at a given index.

CDWordArray::GetCount Gets the number of elements in this array.

CDWordArray::GetData Allows access to elements in the array. Can be NULL.


NAME DESC RIP T IO N

CDWordArray::GetSize Gets the number of elements in this array.

CDWordArray::GetUpperBound Returns the largest valid index.

CDWordArray::InsertAt Inserts an element (or all the elements in another array) at a


specified index.

CDWordArray::IsEmpty Determines if the array is empty.

CDWordArray::RemoveAll Removes all the elements from this array.

CDWordArray::RemoveAt Removes an element at a specific index.

CDWordArray::SetAt Sets the value for a given index; array not allowed to grow.

CDWordArray::SetAtGrow Sets the value for a given index; grows the array if necessary.

CDWordArray::SetSize Sets the number of elements to be contained in this array.

Public Operators
NAME DESC RIP T IO N

CDWordArray::operator [ ] Sets or gets the element at the specified index.

Remarks
CDWordArray incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its elements. If
an array of doublewords is stored to an archive, either with the overloaded insertion ( << ) operator or with the
Serialize member function, each element is, in turn, serialized.

NOTE
Before using an array, use SetSize to establish its size and allocate memory for it. If you do not use SetSize , adding
elements to your array causes it to be frequently reallocated and copied. Frequent reallocation and copying are inefficient
and can fragment memory.

If you need debug output from individual elements in the array, you must set the depth of the CDumpContext
object to 1 or greater.
For more information on using CDWordArray , see the article Collections.

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CObArray Class
CEdit Class
4/21/2020 • 37 minutes to read • Edit Online

Provides the functionality of a Windows edit control.

Syntax
class CEdit : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CEdit::CEdit Constructs a CEdit control object.

Public Methods
NAME DESC RIP T IO N

CEdit::CanUndo Determines whether an edit-control operation can be


undone.

CEdit::CharFromPos Retrieves the line and character indexes for the character
closest to a specified position.

CEdit::Clear Deletes (clears) the current selection (if any) in the edit
control.

CEdit::Copy Copies the current selection (if any) in the edit control to
the Clipboard in CF_TEXT format.

CEdit::Create Creates the Windows edit control and attaches it to the


CEdit object.

CEdit::Cut Deletes (cuts) the current selection (if any) in the edit
control and copies the deleted text to the Clipboard in
CF_TEXT format.

CEdit::EmptyUndoBuffer Resets (clears) the undo flag of an edit control.

CEdit::FmtLines Sets the inclusion of soft line-break characters on or off


within a multiple-line edit control.

CEdit::GetCueBanner Retrieves the text that is displayed as the text cue, or tip, in
an edit control when the control is empty and does not
have focus.

CEdit::GetFirstVisibleLine Determines the topmost visible line in an edit control.


NAME DESC RIP T IO N

CEdit::GetHandle Retrieves a handle to the memory that is currently


allocated for a multiple-line edit control.

CEdit::GetHighlight Gets the indexes of the starting and ending characters in a


range of text that is highlighted in the current edit control.

CEdit::GetLimitText Gets the maximum amount of text this CEdit can


contain.

CEdit::GetLine Retrieves a line of text from an edit control.

CEdit::GetLineCount Retrieves the number of lines in a multiple-line edit control.

CEdit::GetMargins Gets the left and right margins for this CEdit .

CEdit::GetModify Determines whether the contents of an edit control have


been modified.

CEdit::GetPasswordChar Retrieves the password character displayed in an edit


control when the user enters text.

CEdit::GetRect Gets the formatting rectangle of an edit control.

CEdit::GetSel Gets the first and last character positions of the current
selection in an edit control.

CEdit::HideBalloonTip Hides any balloon tip associated with the current edit
control.

CEdit::LimitText Limits the length of the text that the user can enter into an
edit control.

CEdit::LineFromChar Retrieves the line number of the line that contains the
specified character index.

CEdit::LineIndex Retrieves the character index of a line within a multiple-line


edit control.

CEdit::LineLength Retrieves the length of a line in an edit control.

CEdit::LineScroll Scrolls the text of a multiple-line edit control.

CEdit::Paste Inserts the data from the Clipboard into the edit control at
the current cursor position. Data is inserted only if the
Clipboard contains data in CF_TEXT format.

CEdit::PosFromChar Retrieves the coordinates of the upper-left corner of a


specified character index.

CEdit::ReplaceSel Replaces the current selection in an edit control with the


specified text.
NAME DESC RIP T IO N

CEdit::SetCueBanner Sets the text that is displayed as the text cue, or tip, in an
edit control when the control is empty and does not have
focus.

CEdit::SetHandle Sets the handle to the local memory that will be used by a
multiple-line edit control.

CEdit::SetHighlight Highlights a range of text that is displayed in the current


edit control.

CEdit::SetLimitText Sets the maximum amount of text this CEdit can contain.

CEdit::SetMargins Sets the left and right margins for this CEdit .

CEdit::SetModify Sets or clears the modification flag for an edit control.

CEdit::SetPasswordChar Sets or removes a password character displayed in an edit


control when the user enters text.

CEdit::SetReadOnly Sets the read-only state of an edit control.

CEdit::SetRect Sets the formatting rectangle of a multiple-line edit control


and updates the control.

CEdit::SetRectNP Sets the formatting rectangle of a multiple-line edit control


without redrawing the control window.

CEdit::SetSel Selects a range of characters in an edit control.

CEdit::SetTabStops Sets the tab stops in a multiple-line edit control.

CEdit::ShowBalloonTip Displays a balloon tip that is associated with the current


edit control.

CEdit::Undo Reverses the last edit-control operation.

Remarks
An edit control is a rectangular child window in which the user can enter text.
You can create an edit control either from a dialog template or directly in your code. In both cases, first call the
constructor CEdit to construct the CEdit object, then call the Create member function to create the
Windows edit control and attach it to the CEdit object.
Construction can be a one-step process in a class derived from CEdit . Write a constructor for the derived
class and call Create from within the constructor.
CEdit inherits significant functionality from CWnd . To set and retrieve text from a CEdit object, use the
CWnd member functions SetWindowText and GetWindowText, which set or get the entire contents of an edit
control, even if it is a multiline control. Text lines in a multiline control are separated by '\r\n' character
sequences. Also, if an edit control is multiline, get and set part of the control's text by calling the CEdit
member functions GetLine, SetSel, GetSel, and ReplaceSel.
If you want to handle Windows notification messages sent by an edit control to its parent (usually a class
derived from CDialog ), add a message-map entry and message-handler member function to the parent class
for each message.
Each message-map entry takes the following form:
ON_ NOTIFICATION( id, memberFxn )
where id specifies the child window ID of the edit control sending the notification, and memberFxn is the
name of the parent member function you have written to handle the notification.
The parent's function prototype is as follows:
afx_msg void memberFxn ( );
Following is a list of potential message-map entries and a description of the cases in which they would be
sent to the parent:
ON_EN_CHANGE The user has taken an action that may have altered text in an edit control. Unlike the
EN_UPDATE notification message, this notification message is sent after Windows updates the display.
ON_EN_ERRSPACE The edit control cannot allocate enough memory to meet a specific request.
ON_EN_HSCROLL The user clicks an edit control's horizontal scroll bar. The parent window is notified
before the screen is updated.
ON_EN_KILLFOCUS The edit control loses the input focus.
ON_EN_MAXTEXT The current insertion has exceeded the specified number of characters for the edit
control and has been truncated. Also sent when an edit control does not have the ES_AUTOHSCROLL
style and the number of characters to be inserted would exceed the width of the edit control. Also sent
when an edit control does not have the ES_AUTOVSCROLL style and the total number of lines resulting
from a text insertion would exceed the height of the edit control.
ON_EN_SETFOCUS Sent when an edit control receives the input focus.
ON_EN_UPDATE The edit control is about to display altered text. Sent after the control has formatted
the text but before it screens the text so that the window size can be altered, if necessary.
ON_EN_VSCROLL The user clicks an edit control's vertical scroll bar. The parent window is notified
before the screen is updated.
If you create a CEdit object within a dialog box, the CEdit object is automatically destroyed when the user
closes the dialog box.
If you create a CEdit object from a dialog resource using the dialog editor, the CEdit object is automatically
destroyed when the user closes the dialog box.
If you create a CEdit object within a window, you may also need to destroy it. If you create the CEdit object
on the stack, it is destroyed automatically. If you create the CEdit object on the heap by using the new
function, you must call delete on the object to destroy it when the user terminates the Windows edit control.
If you allocate any memory in the CEdit object, override the CEdit destructor to dispose of the allocations.
To modify certain styles in an edit control (such as ES_READONLY) you must send specific messages to the
control instead of using ModifyStyle. See Edit Control Styles in the Windows SDK.
For more information on CEdit , see Controls.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CEdit

Requirements
Header : afxwin.h

CEdit::CanUndo
Call this function to determine if the last edit operation can be undone.

BOOL CanUndo() const;

Return Value
Nonzero if the last edit operation can be undone by a call to the Undo member function; 0 if it cannot be
undone.
Remarks
For more information, see EM_CANUNDO in the Windows SDK.
Example
See the example for CEdit::Undo.

CEdit::CEdit
Constructs a CEdit object.

CEdit();

Remarks
Use Create to construct the Windows edit control.
Example

// Declare a local CEdit object.


CEdit myEdit;

// Declare a dynamic CEdit object.


CEdit *pmyEdit = new CEdit;

CEdit::CharFromPos
Call this function to retrieve the zero-based line and character indices of the character nearest the specified
point in this CEdit control

int CharFromPos(CPoint pt) const;

Parameters
pt
The coordinates of a point in the client area of this CEdit object.
Return Value
The character index in the low-order WORD, and the line index in the high-order WORD.
Remarks

NOTE
This member function is available beginning with Windows 95 and Windows NT 4.0.

For more information, see EM_CHARFROMPOS in the Windows SDK.


Example

// CMyEdit inherits from CEdit


void CMyEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
int n = CharFromPos(point);
int nLineIndex = HIWORD(n);
int nCharIndex = LOWORD(n);
TRACE(_T("nLineIndex = %d, nCharIndex = %d\r\n"), nLineIndex, nCharIndex);

CEdit::OnLButtonDown(nFlags, point);
}

CEdit::Clear
Call this function to delete (clear) the current selection (if any) in the edit control.

void Clear();

Remarks
The deletion performed by Clear can be undone by calling the Undo member function.
To delete the current selection and place the deleted contents into the Clipboard, call the Cut member
function.
For more information, see WM_CLEAR in the Windows SDK.
Example

// Delete all of the text.


m_myEdit.SetSel(0, -1);
m_myEdit.Clear();

CEdit::Copy
Call this function to coy the current selection (if any) in the edit control to the Clipboard in CF_TEXT format.

void Copy();

Remarks
For more information, see WM_COPY in the Windows SDK.
Example

// Copy all of the text to the clipboard.


m_myEdit.SetSel(0, -1);
m_myEdit.Copy();

CEdit::Create
Creates the Windows edit control and attaches it to the CEdit object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the edit control's style. Apply any combination of edit styles to the control.
rect
Specifies the edit control's size and position. Can be a CRect object or RECT structure.
pParentWnd
Specifies the edit control's parent window (usually a CDialog ). It must not be NULL.
nID
Specifies the edit control's ID.
Return Value
Nonzero if initialization is successful; otherwise 0.
Remarks
You construct a CEdit object in two steps. First, call the CEdit constructor and then call Create , which
creates the Windows edit control and attaches it to the CEdit object.
When Create executes, Windows sends the WM_NCCREATE, WM_NCCALCSIZE, WM_CREATE, and
WM_GETMINMAXINFO messages to the edit control.
These messages are handled by default by the OnNcCreate, OnNcCalcSize, OnCreate, and OnGetMinMaxInfo
member functions in the CWnd base class. To extend the default message handling, derive a class from CEdit
, add a message map to the new class, and override the above message-handler member functions. Override
OnCreate , for example, to perform needed initialization for the new class.

Apply the following window styles to an edit control.


WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
WS_GROUP To group controls
WS_TABSTOP To include edit control in the tabbing order
Example
// dynamically create an edit control
CEdit *pEdit = new CEdit;
pEdit->Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER,
CRect(10, 10, 100, 100), this, 1);

CEdit::Cut
Call this function to delete (cut) the current selection (if any) in the edit control and copy the deleted text to
the Clipboard in CF_TEXT format.

void Cut();

Remarks
The deletion performed by Cut can be undone by calling the Undo member function.
To delete the current selection without placing the deleted text into the Clipboard, call the Clear member
function.
For more information, see WM_CUT in the Windows SDK.
Example

// Delete all of the text and copy it to the clipboard.


m_myEdit.SetSel(0, -1);
m_myEdit.Cut();

CEdit::EmptyUndoBuffer
Call this function to reset (clear) the undo flag of an edit control.

void EmptyUndoBuffer();

Remarks
The edit control will now be unable to undo the last operation. The undo flag is set whenever an operation
within the edit control can be undone.
The undo flag is automatically cleared whenever the SetWindowText or SetHandle CWnd member functions
are called.
For more information, see EM_EMPTYUNDOBUFFER in the Windows SDK.
Example

// Clear the undo buffer.


if (m_myEdit.CanUndo())
{
m_myEdit.EmptyUndoBuffer();
ASSERT(!m_myEdit.CanUndo());
}

CEdit::FmtLines
Call this function to set the inclusion of soft line-break characters on or off within a multiple-line edit control.
BOOL FmtLines(BOOL bAddEOL);

Parameters
bAddEOL
Specifies whether soft line-break characters are to be inserted. A value of TRUE inserts the characters; a value
of FALSE removes them.
Return Value
Nonzero if any formatting occurs; otherwise 0.
Remarks
A soft line break consists of two carriage returns and a line feed inserted at the end of a line that is broken
because of word wrapping. A hard line break consists of one carriage return and a line feed. Lines that end
with a hard line break are not affected by FmtLines .
Windows will only respond if the CEdit object is a multiple-line edit control.
FmtLines only affects the buffer returned by GetHandle and the text returned by WM_GETTEXT. It has no
impact on the display of the text within the edit control.
For more information, see EM_FMTLINES in the Windows SDK.
Example

CString strText;

// Add soft line-break breaks.


m_myEdit.FmtLines(TRUE);

// Dump the text of the edit control.


m_myEdit.GetWindowText(strText);
AFXDUMP(strText);

// Remove soft line-break breaks.


m_myEdit.FmtLines(FALSE);

CEdit::GetCueBanner
Retrieves the text that is displayed as the text cue, or tip, in an edit control when the control is empty.

BOOL GetCueBanner(
LPWSTR lpszText,
int cchText) const;

CString GetCueBanner() const;

Parameters
lpszText
[out] A pointer to a string that contains the cue text.
cchText
[in] The number of characters that can be received. This number includes the terminating NULL character.
Return Value
For the first overload, TRUE if the method is successful; otherwise FALSE.
For the second overload, a CString that contains the cue text if the method is successful; otherwise, the empty
string ("").
Remarks
This method sends the EM_GETCUEBANNER message, which is described in the Windows SDK. For more
information, see the Edit_GetCueBannerText macro.

CEdit::GetFirstVisibleLine
Call this function to determine the topmost visible line in an edit control.

int GetFirstVisibleLine() const;

Return Value
The zero-based index of the topmost visible line. For single-line edit controls, the return value is 0.
Remarks
For more information, see EM_GETFIRSTVISIBLELINE in the Windows SDK.
Example

int nFirstVisible = m_myEdit.GetFirstVisibleLine();

// Scroll the edit control so that the first visible line


// is the first line of text.
if (nFirstVisible > 0)
{
m_myEdit.LineScroll(-nFirstVisible, 0);
}

CEdit::GetHandle
Call this function to retrieve a handle to the memory currently allocated for a multiple-line edit control.

HLOCAL GetHandle() const;

Return Value
A local memory handle that identifies the buffer holding the contents of the edit control. If an error occurs,
such as sending the message to a single-line edit control, the return value is 0.
Remarks
The handle is a local memory handle and may be used by any of the Local Windows memory functions that
take a local memory handle as a parameter.
GetHandle is processed only by multiple-line edit controls.
Call GetHandle for a multiple-line edit control in a dialog box only if the dialog box was created with the
DS_LOCALEDIT style flag set. If the DS_LOCALEDIT style is not set, you will still get a nonzero return value, but
you will not be able to use the returned value.
NOTE
GetHandle will not work with Windows 95/98. If you call GetHandle in Windows 95/98, it will return NULL.
GetHandle will work as documented under Windows NT, versions 3.51 and later.

For more information, see EM_GETHANDLE in the Windows SDK.


Example

HLOCAL h = m_myEdit.GetHandle();
LPCTSTR lpszText = (LPCTSTR)::LocalLock(h);

// Dump the text of the edit control.


AFXDUMP(lpszText);

::LocalUnlock(h);

CEdit::GetHighlight
Gets the indexes of the first and last characters in a range of text that is highlighted in the current edit control.

BOOL GetHighlight(
int* pichStart,
int* pichEnd) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pichStart [out] Zero-based index of the first character in the range of


text that is highlighted.

pichEnd [out] Zero-based index of the last character in the range of


text that is highlighted.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the EM_GETHILITE message, which is described in the Windows SDK. Both SetHighlight
and GetHighlight are currently enabled for UNICODE builds only.

CEdit::GetLimitText
Call this member function to get the text limit for this CEdit object.

UINT GetLimitText() const;

Return Value
The current text limit, in TCHARs, for this CEdit object.
Remarks
The text limit is the maximum amount of text, in TCHARs, that the edit control can accept.
NOTE
This member function is available beginning with Windows 95 and Windows NT 4.0.

For more information, see EM_GETLIMITTEXT in the Windows SDK.


Example

CString strText(_T("I'm an edit control!"));


UINT nLength = strText.GetLength() * sizeof(TCHAR);

// Want the text limit to be at least the size of the new string.
if (m_myEdit.GetLimitText() < nLength)
m_myEdit.SetLimitText(nLength);

m_myEdit.SetWindowText(strText);

CEdit::GetLine
Call this function to retrieve a line of text from an edit control and places it in lpszBuffer.

int GetLine(
int nIndex,
LPTSTR lpszBuffer) const;

int GetLine(
int nIndex,
LPTSTR lpszBuffer,
int nMaxLength) const;

Parameters
nIndex
Specifies the line number to retrieve from a multiple-line edit control. Line numbers are zero-based; a value
of 0 specifies the first line. This parameter is ignored by a single-line edit control.
lpszBuffer
Points to the buffer that receives a copy of the line. The first word of the buffer must specify the maximum
number of TCHARs that can be copied to the buffer.
nMaxLength
Specifies the maximum number of TCHAR characters that can be copied to the buffer. GetLine places this
value in the first word of lpszBuffer before making the call to Windows.
Return Value
The number of characters actually copied. The return value is 0 if the line number specified by nIndex is
greater than the number of lines in the edit control.
Remarks
The copied line does not contain a null-termination character.
For more information, see EM_GETLINE in the Windows SDK.
Example
See the example for CEdit::GetLineCount.
CEdit::GetLineCount
Call this function to retrieve the number of lines in a multiple-line edit control.

int GetLineCount() const;

Return Value
An integer containing the number of lines in the multiple-line edit control. If no text has been entered into the
edit control, the return value is 1.
Remarks
GetLineCount is only processed by multiple-line edit controls.
For more information, see EM_GETLINECOUNT in the Windows SDK.
Example

int i, nLineCount = m_myEdit.GetLineCount();


CString strText, strLine;
// Dump every line of text of the edit control.
for (i = 0; i < nLineCount; i++)
{
// length of line i:
int len = m_myEdit.LineLength(m_myEdit.LineIndex(i));
m_myEdit.GetLine(i, strText.GetBuffer(len), len);
strText.ReleaseBuffer(len);
strLine.Format(_T("line %d: '%s'\n"), i, strText);
AFXDUMP(strLine);
}

CEdit::GetMargins
Call this member function to retrieve the left and right margins of this edit control.

DWORD GetMargins() const;

Return Value
The width of the left margin in the low-order WORD and the width of the right margin in the high-order
WORD.
Remarks
Margins are measured in pixels.

NOTE
This member function is available beginning with Windows 95 and Windows NT 4.0.

For more information, see EM_GETMARGINS in the Windows SDK.


Example
See the example for CEditView::GetEditCtrl.

CEdit::GetModify
Call this function to determine whether the contents of an edit control have been modified.

BOOL GetModify() const;

Return Value
Nonzero if the edit-control contents have been modified; 0 if they have remained unchanged.
Remarks
Windows maintains an internal flag indicating whether the contents of the edit control have been changed.
This flag is cleared when the edit control is first created and may also be cleared by calling the SetModify
member function.
For more information, see EM_GETMODIFY in the Windows SDK.
Example

// Reset the modified state only if my edit has been modified.


if (m_myEdit.GetModify())
m_myEdit.SetModify(FALSE);

CEdit::GetPasswordChar
Call this function to retrieve the password character that is displayed in an edit control when the user enters
text.

TCHAR GetPasswordChar() const;

Return Value
Specifies the character to be displayed instead of the character that the user typed. The return value is NULL if
no password character exists.
Remarks
If you create the edit control with the ES_PASSWORD style, the DLL that supports the control determines the
default password character. The manifest or the InitCommonControlsEx method determines which DLL
supports the edit control. If user32.dll supports the edit control, the default password character is ASTERISK
('*', U+002A). If comctl32.dll version 6 supports the edit control, the default character is BLACK CIRCLE ('●',
U+25CF). For more information about which DLL and version supports the common controls, see Shell and
Common Controls Versions.
This method sends the EM_GETPASSWORDCHAR message, which is described in the Windows SDK.
Example

// Turn on the password mode.


m_myEdit.SetPasswordChar('*');
ASSERT(m_myEdit.GetStyle() & ES_PASSWORD);
ASSERT(m_myEdit.GetPasswordChar() == '*');

CEdit::GetRect
Call this function to get the formatting rectangle of an edit control.
void GetRect(LPRECT lpRect) const;

Parameters
lpRect
Points to the RECT structure that receives the formatting rectangle.
Remarks
The formatting rectangle is the limiting rectangle of the text, which is independent of the size of the edit-
control window.
The formatting rectangle of a multiple-line edit control can be modified by the SetRect and SetRectNP
member functions.
For more information, see EM_GETRECT in the Windows SDK.
Example
See the example for CEdit::LimitText.

CEdit::GetSel
Call this function to get the starting and ending character positions of the current selection (if any) in an edit
control, using either the return value or the parameters.

DWORD GetSel() const;

void GetSel(
int& nStartChar,
int& nEndChar) const;

Parameters
nStartChar
Reference to an integer that will receive the position of the first character in the current selection.
nEndChar
Reference to an integer that will receive the position of the first nonselected character past the end of the
current selection.
Return Value
The version that returns a DWORD returns a value that contains the starting position in the low-order word
and the position of the first nonselected character after the end of the selection in the high-order word.
Remarks
For more information, see EM_GETSEL in the Windows SDK.
Example

// Set the selection to be all characters after the current selection.


DWORD dwSel = m_myEdit.GetSel();
m_myEdit.SetSel(HIWORD(dwSel), -1);

CEdit::HideBalloonTip
Hides any balloon tip associated with the current edit control.
BOOL HideBalloonTip();

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This function sends the EM_HIDEBALLOONTIP message, which is described in the Windows SDK.

CEdit::LimitText
Call this function to limit the length of the text that the user may enter into an edit control.

void LimitText(int nChars = 0);

Parameters
nChars
Specifies the length (in TCHARs) of the text that the user can enter. If this parameter is 0, the text length is set
to UINT_MAX bytes. This is the default behavior.
Remarks
Changing the text limit restricts only the text the user can enter. It has no effect on any text already in the edit
control, nor does it affect the length of the text copied to the edit control by the SetWindowText member
function in CWnd . If an application uses the SetWindowText function to place more text into an edit control
than is specified in the call to LimitText , the user can delete any of the text within the edit control. However,
the text limit will prevent the user from replacing the existing text with new text, unless deleting the current
selection causes the text to fall below the text limit.

NOTE
In Win32 (Windows NT and Windows 95/98), SetLimitText replaces this function.

For more information, see EM_LIMITTEXT in the Windows SDK.


Example

// Limit the number of characters to be the maximum number visible.

// Get the text metrics for the edit; needed for the
// average character width.
TEXTMETRIC tm;
CDC *pDC = m_myEdit.GetDC();
pDC->GetTextMetrics(&tm);
m_myEdit.ReleaseDC(pDC);

CRect r;
m_myEdit.GetRect(&r);
m_myEdit.LimitText(r.Width() / tm.tmAveCharWidth);

CEdit::LineFromChar
Call this function to retrieve the line number of the line that contains the specified character index.
int LineFromChar(int nIndex = -1) const;

Parameters
nIndex
Contains the zero-based index value for the desired character in the text of the edit control, or contains -1. If
nIndex is -1, it specifies the current line, that is, the line that contains the caret.
Return Value
The zero-based line number of the line containing the character index specified by nIndex. If nIndex is -1, the
number of the line that contains the first character of the selection is returned. If there is no selection, the
current line number is returned.
Remarks
A character index is the number of characters from the beginning of the edit control.
This member function is only used by multiple-line edit controls.
For more information, see EM_LINEFROMCHAR in the Windows SDK.
Example

// The index of the char to get information on.


int nIndex = 4;
CString strText;

m_myEdit.GetWindowText(strText);
strText = strText.Mid(nIndex, 1);

// Get the text extent of the character.


CDC *pDC = m_myEdit.GetDC();
CSize sz = pDC->GetTextExtent(strText);
m_myEdit.ReleaseDC(pDC);

CPoint pt = m_myEdit.PosFromChar(nIndex);

// Dump the index, character, line number, and character bounds.


TRACE(_T("nIndex = %d, character = %c, line = %d, bounds = ")
_T("{%d, %d, %d, %d}\r\n"),
nIndex, strText[0], m_myEdit.LineFromChar(nIndex),
pt.x /* left */, pt.y /* top */,
pt.x + sz.cx /* right */, pt.y + sz.cy /* bottom */);

CEdit::LineIndex
Call this function to retrieve the character index of a line within a multiple-line edit control.

int LineIndex(int nLine = -1) const;

Parameters
nLine
Contains the index value for the desired line in the text of the edit control, or contains -1. If nLine is -1, it
specifies the current line, that is, the line that contains the caret.
Return Value
The character index of the line specified in nLine or -1 if the specified line number is greater than the number
of lines in the edit control.
Remarks
The character index is the number of characters from the beginning of the edit control to the specified line.
This member function is only processed by multiple-line edit controls.
For more information, see EM_LINEINDEX in the Windows SDK.
Example

// The string for replacing.


CString strString(_T("Hi, we're the replacements."));
int nBegin, nEnd;

// Replace the second line, if it exists, of the edit control


// with the text strString.
if ((nBegin = m_myEdit.LineIndex(1)) != -1)
{
nEnd = nBegin + m_myEdit.LineLength(nBegin);
m_myEdit.SetSel(nBegin, nEnd);
m_myEdit.ReplaceSel(strString);
}

CEdit::LineLength
Retrieves the length of a line in an edit control.

int LineLength(int nLine = -1) const;

Parameters
nLine
The zero-based index of a character in the line whose length is to be retrieved. The default value is -1.
Return Value
For single-line edit controls, the return value is the length, in TCHARs, of the text in the edit control.
For multiline edit controls, the return value is the length, in TCHARs, of the line specified by the nLine
parameter. For ANSI text, the length is the number of bytes in the line; for Unicode text, the length is the
number of characters in the line. The length does not include the carriage-return character at the end of the
line.
If the nLine parameter is more than the number of characters in the control, the return value is zero.
If the nLine parameter is -1, the return value is the number of unselected characters in the lines that contain
selected characters. For example, if the selection extends from the fourth character of one line through the
eighth character from the end of the next line, the return value is 10. That is, three characters on the first line
and seven on the next.
For more information about the TCHAR type, see the TCHAR row in the table in Windows Data Types.
Remarks
This method is supported by the EM_LINELENGTH message, which is described in the Windows SDK.
Example
See the example for CEdit::LineIndex.

CEdit::LineScroll
Call this function to scroll the text of a multiple-line edit control.

void LineScroll(
int nLines,
int nChars = 0);

Parameters
nLines
Specifies the number of lines to scroll vertically.
nChars
Specifies the number of character positions to scroll horizontally. This value is ignored if the edit control has
either the ES_RIGHT or ES_CENTER style.
Remarks
This member function is processed only by multiple-line edit controls.
The edit control does not scroll vertically past the last line of text in the edit control. If the current line plus the
number of lines specified by nLines exceeds the total number of lines in the edit control, the value is adjusted
so that the last line of the edit control is scrolled to the top of the edit-control window.
LineScroll can be used to scroll horizontally past the last character of any line.
For more information, see EM_LINESCROLL in the Windows SDK.
Example
See the example for CEdit::GetFirstVisibleLine.

CEdit::Paste
Call this function to insert the data from the Clipboard into the CEdit at the insertion point.

void Paste();

Remarks
Data is inserted only if the Clipboard contains data in CF_TEXT format.
For more information, see WM_PASTE in the Windows SDK.
Example

// Replace all of the text with the text in the clipboard.


m_myEdit.SetSel(0, -1);
m_myEdit.Paste();

CEdit::PosFromChar
Call this function to get the position (top-left corner) of a given character within this CEdit object.

CPoint PosFromChar(UINT nChar) const;

Parameters
nChar
The zero-based index of the specified character.
Return Value
The coordinates of the top-left corner of the character specified by nChar.
Remarks
The character is specified by giving its zero-based index value. If nChar is greater than the index of the last
character in this CEdit object, the return value specifies the coordinates of the character position just past
the last character in this CEdit object.

NOTE
This member function is available beginning with Windows 95 and Windows NT 4.0.

For more information, see EM_POSFROMCHAR in the Windows SDK.


Example
See the example for CEdit::LineFromChar.

CEdit::ReplaceSel
Call this function to replace the current selection in an edit control with the text specified by lpszNewText.

void ReplaceSel(LPCTSTR lpszNewText, BOOL bCanUndo = FALSE);

Parameters
lpszNewText
Points to a null-terminated string containing the replacement text.
bCanUndo
To specify that this function can be undone, set the value of this parameter to TRUE . The default value is
FALSE.
Remarks
Replaces only a portion of the text in an edit control. If you want to replace all of the text, use the
CWnd::SetWindowText member function.
If there is no current selection, the replacement text is inserted at the current cursor location.
For more information, see EM_REPLACESEL in the Windows SDK.
Example
See the example for CEdit::LineIndex.

CEdit::SetCueBanner
Sets the text that is displayed as the text cue, or tip, in an edit control when the control is empty.

BOOL SetCueBanner(LPCWSTR lpszText);

BOOL SetCueBanner(
LPCWSTR lpszText,
BOOL fDrawWhenFocused = FALSE);

Parameters
lpszText
[in] Pointer to a string that contains the cue to display in the edit control.
fDrawWhenFocused
[in] If FALSE, the cue banner is not drawn when the user clicks in the edit control and gives the control the
focus.
If TRUE, the cue banner is drawn even when the control has focus. The cue banner disappears when the user
starts to type in the control.
The default value is FALSE.
Return Value
TRUE if the method is successful; otherwise FALSE.
Remarks
This method sends the EM_SETCUEBANNER message, which is described in the Windows SDK. For more
information, see the Edit_SetCueBannerTextFocused macro.
Example
The following example demonstrates the CEdit::SetCueBanner method.

m_cedit.SetCueBanner(_T("First, enter text here..."), TRUE);

CEdit::SetHandle
Call this function to set the handle to the local memory that will be used by a multiple-line edit control.

void SetHandle(HLOCAL hBuffer);

Parameters
hBuffer
Contains a handle to the local memory. This handle must have been created by a previous call to the
LocalAlloc Windows function using the LMEM_MOVEABLE flag. The memory is assumed to contain a null-
terminated string. If this is not the case, the first byte of the allocated memory should be set to 0.
Remarks
The edit control will then use this buffer to store the currently displayed text instead of allocating its own
buffer.
This member function is processed only by multiple-line edit controls.
Before an application sets a new memory handle, it should use the GetHandle member function to get the
handle to the current memory buffer and free that memory using the LocalFree Windows function.
SetHandle clears the undo buffer (the CanUndo member function then returns 0) and the internal
modification flag (the GetModify member function then returns 0). The edit-control window is redrawn.
You can use this member function in a multiple-line edit control in a dialog box only if you have created the
dialog box with the DS_LOCALEDIT style flag set.
NOTE
GetHandle will not work with Windows 95/98. If you call GetHandle in Windows 95/98, it will return NULL.
GetHandle will work as documented under Windows NT, versions 3.51 and later.

For more information, see EM_SETHANDLE, LocalAlloc, and LocalFree in the Windows SDK.
Example

// The string to set in the edit control.


CString strString(_T("George Frideric"));

// Initialize the new local handle.


size_t cbSize = (strString.GetLength() + 1) * sizeof(TCHAR);
HLOCAL h = ::LocalAlloc(LHND, cbSize);
LPTSTR lpszText = (LPTSTR)::LocalLock(h);
_tcsncpy_s(lpszText, cbSize / sizeof(TCHAR), strString, _TRUNCATE);
::LocalUnlock(h);

// Free the current text handle of the edit control.


::LocalFree(m_myEdit.GetHandle());

// Set the new text handle.


m_myEdit.SetHandle(h);

CEdit::SetHighlight
Highlights a range of text that is displayed in the current edit control.

void SetHighlight(
int ichStart,
int ichEnd);

Parameters
PA RA M ET ER DESC RIP T IO N

ichStart [in] Zero-based index of the first character in the range of


text to highlight.

ichEnd [in] Zero-based index of the last character in the range of


text to highlight.

Remarks
This method sends the EM_SETHILITE message, which is described in the Windows SDK. This method sends
the EM_SETHILITE message, which is described in the Windows SDK. Both SetHighlight and GetHighlight
are enabled for UNICODE builds only.

CEdit::SetLimitText
Call this member function to set the text limit for this CEdit object.

void SetLimitText(UINT nMax);

Parameters
nMax
The new text limit, in characters.
Remarks
The text limit is the maximum amount of text, in characters, that the edit control can accept.
Changing the text limit restricts only the text the user can enter. It has no effect on any text already in the edit
control, nor does it affect the length of the text copied to the edit control by the SetWindowText member
function in CWnd . If an application uses the SetWindowText function to place more text into an edit control
than is specified in the call to LimitText , the user can delete any of the text within the edit control. However,
the text limit will prevent the user from replacing the existing text with new text, unless deleting the current
selection causes the text to fall below the text limit.
This function replaces LimitText in Win32.
For more information, see EM_SETLIMITTEXT in the Windows SDK.
Example
See the example for CEditView::GetEditCtrl.

CEdit::SetMargins
Call this method to set the left and right margins of this edit control.

void SetMargins(
UINT nLeft,
UINT nRight);

Parameters
nLeft
The width of the new left margin, in pixels.
nRight
The width of the new right margin, in pixels.
Remarks

NOTE
This member function is available beginning with Windows 95 and Windows NT 4.0.

For more information, see EM_SETMARGINS in the Windows SDK.


Example
See the example for CEditView::GetEditCtrl.

CEdit::SetModify
Call this function to set or clear the modified flag for an edit control.

void SetModify(BOOL bModified = TRUE);

Parameters
bModified
A value of TRUE indicates that the text has been modified, and a value of FALSE indicates it is unmodified. By
default, the modified flag is set.
Remarks
The modified flag indicates whether or not the text within the edit control has been modified. It is
automatically set whenever the user changes the text. Its value may be retrieved with the GetModify member
function.
For more information, see EM_SETMODIFY in the Windows SDK.
Example
See the example for CEdit::GetModify.

CEdit::SetPasswordChar
Call this function to set or remove a password character displayed in an edit control when the user types text.

void SetPasswordChar(TCHAR ch);

Parameters
ch
Specifies the character to be displayed in place of the character typed by the user. If ch is 0, the actual
characters typed by the user are displayed.
Remarks
When a password character is set, that character is displayed for each character the user types.
This member function has no effect on a multiple-line edit control.
When the SetPasswordChar member function is called, CEdit will redraw all visible characters using the
character specified by ch.
If the edit control is created with the ES_PASSWORD style, the default password character is set to an asterisk
( * ). This style is removed if SetPasswordChar is called with ch set to 0.
For more information, see EM_SETPASSWORDCHAR in the Windows SDK.
Example

// Turn off the password mode.


m_myEdit.SetPasswordChar(0);
ASSERT(!(m_myEdit.GetStyle() & ES_PASSWORD));

CEdit::SetReadOnly
Calls this function to set the read-only state of an edit control.

BOOL SetReadOnly(BOOL bReadOnly = TRUE);

Parameters
bReadOnly
Specifies whether to set or remove the read-only state of the edit control. A value of TRUE sets the state to
read-only; a value of FALSE sets the state to read/write.
Return Value
Nonzero if the operation is successful, or 0 if an error occurs.
Remarks
The current setting can be found by testing the ES_READONLY flag in the return value of CWnd::GetStyle.
For more information, see EM_SETREADONLY in the Windows SDK.
Example

// Set the edit control to be read-only.


m_myEdit.SetReadOnly(TRUE);
ASSERT(m_myEdit.GetStyle() & ES_READONLY);

CEdit::SetRect
Call this function to set the dimensions of a rectangle using the specified coordinates.

void SetRect(LPCRECT lpRect);

Parameters
lpRect
Points to the RECT structure or CRect object that specifies the new dimensions of the formatting rectangle.
Remarks
This member is processed only by multiple-line edit controls.
Use SetRect to set the formatting rectangle of a multiple-line edit control. The formatting rectangle is the
limiting rectangle of the text, which is independent of the size of the edit-control window. When the edit
control is first created, the formatting rectangle is the same as the client area of the edit-control window. By
using the SetRect member function, an application can make the formatting rectangle larger or smaller than
the edit-control window.
If the edit control has no scroll bar, text will be clipped, not wrapped, if the formatting rectangle is made larger
than the window. If the edit control contains a border, the formatting rectangle is reduced by the size of the
border. If you adjust the rectangle returned by the GetRect member function, you must remove the size of
the border before you pass the rectangle to SetRect .
When SetRect is called, the edit control's text is also reformatted and redisplayed.
For more information, see EM_SETRECT in the Windows SDK.
Example
// Flag indicating whether to redraw the edit control.
bool fRedraw = TRUE;

CRect r;

m_myEdit.GetRect(&r);

// Reduce the formatting rect of the edit control by


// 10 pixels on each side.
if ((r.Width() > 20) && (r.Height() > 20))
{
r.DeflateRect(10, 10);

if (fRedraw)
m_myEdit.SetRect(&r);
else
m_myEdit.SetRectNP(&r);
}

CEdit::SetRectNP
Call this function to set the formatting rectangle of a multiple-line edit control.

void SetRectNP(LPCRECT lpRect);

Parameters
lpRect
Points to a RECT structure or CRect object that specifies the new dimensions of the rectangle.
Remarks
The formatting rectangle is the limiting rectangle of the text, which is independent of the size of the edit-
control window.
SetRectNP is identical to the SetRect member function except that the edit-control window is not redrawn.
When the edit control is first created, the formatting rectangle is the same as the client area of the edit-control
window. By calling the SetRectNP member function, an application can make the formatting rectangle larger
or smaller than the edit-control window.
If the edit control has no scroll bar, text will be clipped, not wrapped, if the formatting rectangle is made larger
than the window.
This member is processed only by multiple-line edit controls.
For more information, see EM_SETRECTNP in the Windows SDK.
Example
See the example for CEdit::SetRect.

CEdit::SetSel
Call this function to select a range of characters in an edit control.
void SetSel(
DWORD dwSelection,
BOOL bNoScroll = FALSE);

void SetSel(
int nStartChar,
int nEndChar,
BOOL bNoScroll = FALSE);

Parameters
dwSelection
Specifies the starting position in the low-order word and the ending position in the high-order word. If the
low-order word is 0 and the high-order word is -1, all the text in the edit control is selected. If the low-order
word is -1, any current selection is removed.
bNoScroll
Indicates whether the caret should be scrolled into view. If FALSE, the caret is scrolled into view. If TRUE, the
caret is not scrolled into view.
nStartChar
Specifies the starting position. If nStartChar is 0 and nEndChar is -1, all the text in the edit control is selected.
If nStartChar is -1, any current selection is removed.
nEndChar
Specifies the ending position.
Remarks
For more information, see EM_SETSEL in the Windows SDK.
Example
See the example for CEdit::GetSel.

CEdit::SetTabStops
Call this function to set the tab stops in a multiple-line edit control.

void SetTabStops();
BOOL SetTabStops(const int& cxEachStop);

BOOL SetTabStops(
int nTabStops,
LPINT rgTabStops);

Parameters
cxEachStop
Specifies that tab stops are to be set at every cxEachStop dialog units.
nTabStops
Specifies the number of tab stops contained in rgTabStops. This number must be greater than 1.
rgTabStops
Points to an array of unsigned integers specifying the tab stops in dialog units. A dialog unit is a horizontal or
vertical distance. One horizontal dialog unit is equal to one-fourth of the current dialog base width unit, and 1
vertical dialog unit is equal to one-eighth of the current dialog base height unit. The dialog base units are
computed based on the height and width of the current system font. The GetDialogBaseUnits Windows
function returns the current dialog base units in pixels.
Return Value
Nonzero if the tabs were set; otherwise 0.
Remarks
When text is copied to a multiple-line edit control, any tab character in the text will cause space to be
generated up to the next tab stop.
To set tab stops to the default size of 32 dialog units, call the parameterless version of this member function.
To set tab stops to a size other than 32, call the version with the cxEachStop parameter. To set tab stops to an
array of sizes, use the version with two parameters.
This member function is only processed by multiple-line edit controls.
SetTabStops does not automatically redraw the edit window. If you change the tab stops for text already in
the edit control, call CWnd::InvalidateRect to redraw the edit window.
For more information, see EM_SETTABSTOPS and GetDialogBaseUnits in the Windows SDK.
Example
See the example for CEditView::SetTabStops.

CEdit::ShowBalloonTip
Displays a balloon tip that is associated with the current edit control.

BOOL ShowBalloonTip(PEDITBALLOONTIP pEditBalloonTip);

BOOL ShowBalloonTip(
LPCWSTR lpszTitle,
LPCWSTR lpszText,
INT ttiIcon = TTI_NONE);

Parameters
PA RA M ET ER DESC RIP T IO N

pEditBalloonTip [in] Pointer to an EDITBALLOONTIP structure that describes


the balloon tip.

lpszTitle [in] Pointer to a Unicode string that contains the title of the
balloon tip.

lpszText [in] Pointer to a Unicode string that contains the balloon


tip text.

ttiIcon [in] An INT that specifies the type of icon to associate with
the balloon tip. The default value is TTI_NONE. For more
information, see the ttiIcon member of the
EDITBALLOONTIP structure.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This function sends the EM_SHOWBALLOONTIP message, which is described in the Windows SDK. For more
information, see the Edit_ShowBalloonTip macro.
Example
The following code example defines a variable, m_cedit , that is used to access the current edit control. This
variable is used in the next example.

public:
// Variable to access the edit control.
CEdit m_cedit;

Example
The following code example displays a balloon tip for an edit control. The CEdit::ShowBalloonTip method
specifies a title and balloon tip text.

m_cedit.ShowBalloonTip(
_T("CEdit Balloon Tip"), // title
_T("Here's a tip!"), // text
TTI_INFO);

CEdit::Undo
Call this function to undo the last edit-control operation.

BOOL Undo();

Return Value
For a single-line edit control, the return value is always nonzero. For a multiple-line edit control, the return
value is nonzero if the undo operation is successful, or 0 if the undo operation fails.
Remarks
An undo operation can also be undone. For example, you can restore deleted text with the first call to Undo .
As long as there is no intervening edit operation, you can remove the text again with a second call to Undo .
For more information, see EM_UNDO in the Windows SDK.
Example

// Undo the last operation, if possible.


if (m_myEdit.CanUndo())
m_myEdit.Undo();

See also
MFC Sample CALCDRIV
MFC Sample CMNCTRL2
CWnd Class
Hierarchy Chart
CWnd Class
CButton Class
CComboBox Class
CListBox Class
CScrollBar Class
CStatic Class
CDialog Class
CEditView Class
4/21/2020 • 11 minutes to read • Edit Online

A type of view class that provides the functionality of a Windows edit control and can be used to implement
simple text-editor functionality.

Syntax
class CEditView : public CCtrlView

Members
Public Constructors
NAME DESC RIP T IO N

CEditView::CEditView Constructs an object of type CEditView .

Public Methods
NAME DESC RIP T IO N

CEditView::FindText Searches for a string within the text.

CEditView::GetBufferLength Obtains the length of the character buffer.

CEditView::GetEditCtrl Provides access to the CEdit portion of a CEditView


object (the Windows edit control).

CEditView::GetPrinterFont Retrieves the current printer font.

CEditView::GetSelectedText Retrieves the current text selection.

CEditView::LockBuffer Locks the buffer.

CEditView::PrintInsideRect Renders text inside a given rectangle.

CEditView::SerializeRaw Serializes a CEditView object to disk as raw text.

CEditView::SetPrinterFont Sets a new printer font.

CEditView::SetTabStops Sets tab stops for both screen display and printing.

CEditView::UnlockBuffer Unlocks the buffer.

Protected Methods
NAME DESC RIP T IO N

CEditView::OnFindNext Finds next occurrence of a text string.

CEditView::OnReplaceAll Replaces all occurrences of a given string with a new string.

CEditView::OnReplaceSel Replaces current selection.

CEditView::OnTextNotFound Called when a find operation fails to match any further text.

Public Data Members


NAME DESC RIP T IO N

CEditView::dwStyleDefault Default style for objects of type CEditView .

Remarks
The CEditView class provides the following additional functions:
Print.
Find and replace.
Because class CEditView is a derivative of class CView , objects of class CEditView can be used with documents
and document templates.
Each CEditView control's text is kept in its own global memory object. Your application can have any number of
CEditView objects.
Create objects of type CEditView if you want an edit window with the added functionality listed above, or if you
want simple text-editor functionality. A CEditView object can occupy the entire client area of a window. Derive
your own classes from CEditView to add or modify the basic functionality, or to declare classes that can be
added to a document template.
The default implementation of class CEditView handles the following commands: ID_EDIT_SELECT_ALL,
ID_EDIT_FIND, ID_EDIT_REPLACE, ID_EDIT_REPEAT, and ID_FILE_PRINT.
The default character limit for CEditView is (1024 * 1024 - 1 = 1048575). This can be changed by calling the
EM_LIMITTEXT function of the underlying edit control. However, the limits are different depending on the
operating system and the type of edit control (single or multiline). For more information on these limits, see
EM_LIMITTEXT.
To change this limit in your control, override the OnCreate() function for your CEditView class and insert the
following line of code:

GetEditCtrl().SetLimitText(nNewVal); //nNewVal, the new character limit

Objects of type CEditView (or of types derived from CEditView ) have the following limitations:
CEditView does not implement true what you see is what you get (WYSIWYG) editing. Where there is a
choice between readability on the screen and matching printed output, CEditView opts for screen
readability.
CEditView can display text in only a single font. No special character formatting is supported. See class
CRichEditView for greater capabilities.
The amount of text a CEditView can contain is limited. The limits are the same as for the CEdit control.

For more information on CEditView , see Derived View Classes Available in MFC.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CCtrlView
CEditView

Requirements
Header : afxext.h

CEditView::CEditView
Constructs an object of type CEditView .

CEditView();

Remarks
After constructing the object, you must call the CWnd::Create function before the edit control is used. If you
derive a class from CEditView and add it to the template using CWinApp::AddDocTemplate , the framework calls
both this constructor and the Create function.

CEditView::dwStyleDefault
Contains the default style of the CEditView object.

static const DWORD dwStyleDefault;

Remarks
Pass this static member as the dwStyle parameter of the Create function to obtain the default style for the
CEditView object.

CEditView::FindText
Call the FindText function to search the CEditView object's text buffer.

BOOL FindText(
LPCTSTR lpszFind,
BOOL bNext = TRUE,
BOOL bCase = TRUE);
Parameters
lpszFind
The text to be found.
bNext
Specifies the direction of the search. If TRUE, the search direction is toward the end of the buffer. If FALSE, the
search direction is toward the beginning of the buffer.
bCase
Specifies whether the search is case sensitive. If TRUE, the search is case sensitive. If FALSE, the search is not case
sensitive.
Return Value
Nonzero if the search text is found; otherwise 0.
Remarks
This function searches the text in the buffer for the text specified by lpszFind, starting at the current selection, in
the direction specified by bNext, and with case sensitivity specified by bCase. If the text is found, it sets the
selection to the found text and returns a nonzero value. If the text is not found, the function returns 0.
You normally do not need to call the FindText function unless you override OnFindNext , which calls FindText .

CEditView::GetBufferLength
Call this member function to obtain the number of characters currently in the edit control's buffer, not including
the null terminator.

UINT GetBufferLength() const;

Return Value
The length of the string in the buffer.

CEditView::GetEditCtrl
Call GetEditCtrl to get a reference to the edit control used by the edit view.

CEdit& GetEditCtrl() const;

Return Value
A reference to a CEdit object.
Remarks
This control is of type CEdit, so you can manipulate the Windows edit control directly using the CEdit member
functions.
Cau t i on

Using the CEdit object can change the state of the underlying Windows edit control. For example, you should
not change the tab settings using the CEdit::SetTabStops function because CEditView caches these settings for
use both in the edit control and in printing. Instead, use CEditView::SetTabStops.
Example
void CMyEditView::OnInitialUpdate()
{
CEditView::OnInitialUpdate();

// get the edit control and set some initial properties for it
CEdit &theEdit = GetEditCtrl();

// adjust the left margin without changing the right margin


DWORD dwMargins = theEdit.GetMargins();
theEdit.SetMargins(20, HIWORD(dwMargins));

// only accept 10k of text


theEdit.SetLimitText(10 * 1024);
}

CEditView::GetPrinterFont
Call GetPrinterFont to get a pointer to a CFont object that describes the current printer font.

CFont* GetPrinterFont() const;

Return Value
A pointer to a CFont object that specifies the current printer font; NULL if the printer font has not been set. The
pointer may be temporary and should not be stored for later use.
Remarks
If the printer font has not been set, the default printing behavior of the CEditView class is to print using the
same font used for display.
Use this function to determine the current printer font. If it is not the desired printer font, use
CEditView::SetPrinterFont to change it.

CEditView::GetSelectedText
Call GetSelectedText to copy the selected text into a CString object, up to the end of the selection or the
character preceding the first carriage-return character in the selection.

void GetSelectedText(CString& strResult) const;

Parameters
strResult
A reference to the CString object that is to receive the selected text.

CEditView::LockBuffer
Call this member function to obtain a pointer to the buffer. The buffer should not be modified.

LPCTSTR LockBuffer() const;

Return Value
A pointer to the edit control's buffer.
CEditView::OnFindNext
Searches the text in the buffer for the text specified by lpszFind, in the direction specified by bNext, with case
sensitivity specified by bCase.

virtual void OnFindNext(


LPCTSTR lpszFind,
BOOL bNext,
BOOL bCase);

Parameters
lpszFind
The text to be found.
bNext
Specifies the direction of the search. If TRUE, the search direction is toward the end of the buffer. If FALSE, the
search direction is toward the beginning of the buffer.
bCase
Specifies whether the search is case sensitive. If TRUE, the search is case sensitive. If FALSE, the search is not case
sensitive.
Remarks
The search starts at the beginning of the current selection and is accomplished through a call to FindText. In the
default implementation, OnFindNext calls OnTextNotFound if the text is not found.
Override OnFindNext to change the way a CEditView -derived object searches text. CEditView calls OnFindNext
when the user chooses the Find Next button in the standard Find dialog box.

CEditView::OnReplaceAll
CEditView calls OnReplaceAll when the user selects the Replace All button in the standard Replace dialog box.

virtual void OnReplaceAll(


LPCTSTR lpszFind,
LPCTSTR lpszReplace,
BOOL bCase);

Parameters
lpszFind
The text to be found.
lpszReplace
The text to replace the search text.
bCase
Specifies whether search is case sensitive. If TRUE, the search is case sensitive. If FALSE, the search is not case
sensitive.
Remarks
OnReplaceAll searches the text in the buffer for the text specified by lpszFind, with case sensitivity specified by
bCase. The search starts at the beginning of the current selection. Each time the search text is found, this
function replaces that occurrence of the text with the text specified by lpszReplace. The search is accomplished
through a call to FindText. In the default implementation, OnTextNotFound is called if the text is not found.
If the current selection does not match lpszFind, the selection is updated to the first occurrence of the text
specified by lpszFind and a replace is not performed. This allows the user to confirm that this is what they want
to do when the selection does not match the text to be replaced.
Override OnReplaceAll to change the way a CEditView -derived object replaces text.

CEditView::OnReplaceSel
CEditView calls OnReplaceSel when the user selects the Replace button in the standard Replace dialog box.

virtual void OnReplaceSel(


LPCTSTR lpszFind,
BOOL bNext,
BOOL bCase,
LPCTSTR lpszReplace);

Parameters
lpszFind
The text to be found.
bNext
Specifies the direction of the search. If TRUE, the search direction is toward the end of the buffer. If FALSE, the
search direction is toward the beginning of the buffer.
bCase
Specifies whether the search is case sensitive. If TRUE, the search is case sensitive. If FALSE, the search is not case
sensitive.
lpszReplace
The text to replace the found text.
Remarks
After replacing the selection, this function searches the text in the buffer for the next occurrence of the text
specified by lpszFind, in the direction specified by bNext, with case sensitivity specified by bCase. The search is
accomplished through a call to FindText. If the text is not found, OnTextNotFound is called.
Override OnReplaceSel to change the way a CEditView -derived object replaces the selected text.

CEditView::OnTextNotFound
Override this function to change the default implementation, which calls the Windows function MessageBeep .

virtual void OnTextNotFound(LPCTSTR lpszFind);

Parameters
lpszFind
The text to be found.

CEditView::PrintInsideRect
Call PrintInsideRect to print text in the rectangle specified by rectLayout.
UINT PrintInsideRect(
CDC *pDC,
RECT& rectLayout,
UINT nIndexStart,
UINT nIndexStop);

Parameters
pDC
Pointer to the printer device context.
rectLayout
Reference to a CRect object or RECT structure specifying the rectangle in which the text is to be rendered.
nIndexStart
Index within the buffer of the first character to be rendered.
nIndexStop
Index within the buffer of the character following the last character to be rendered.
Return Value
The index of the next character to be printed (that is, the character following the last character rendered).
Remarks
If the CEditView control does not have the style ES_AUTOHSCROLL, text is wrapped within the rendering
rectangle. If the control does have the style ES_AUTOHSCROLL, the text is clipped at the right edge of the
rectangle.
The rect.bottom element of the rectLayout object is changed so that the rectangle's dimensions define the part
of the original rectangle that is occupied by the text.

CEditView::SerializeRaw
Call SerializeRaw to have a CArchive object read or write the text in the CEditView object to a text file.

void SerializeRaw(CArchive& ar);

Parameters
ar
Reference to the CArchive object that stores the serialized text.
Remarks
SerializeRaw differs from CEditView 's internal implementation of Serialize in that it reads and writes only
the text, without preceding object-description data.

CEditView::SetPrinterFont
Call SetPrinterFont to set the printer font to the font specified by pFont.

void SetPrinterFont(CFont* pFont);

Parameters
pFont
A pointer to an object of type CFont . If NULL, the font used for printing is based on the display font.
Remarks
If you want your view to always use a particular font for printing, include a call to SetPrinterFont in your class's
OnPreparePrinting function. This virtual function is called before printing occurs, so the font change takes place
before the view's contents are printed.

CEditView::SetTabStops
Call this function to set the tab stops used for display and printing.

void SetTabStops(int nTabStops);

Parameters
nTabStops
Width of each tab stop, in dialog units.
Remarks
Only a single tab-stop width is supported. ( CEdit objects support multiple tab widths.) Widths are in dialog
units, which equal one-fourth of the average character width (based on uppercase and lowercase alphabetic
characters only) of the font used at the time of printing or displaying. You should not use CEdit::SetTabStops
because CEditView must cache the tab-stop value.
This function modifies only the tabs of the object for which it is called. To change the tab stops for each
CEditView object in your application, call each object's SetTabStops function.

Example
This code fragment sets the tab stops in the control to every fourth character by carefully measuring the font the
control uses.

// gain a reference to the edit control


CEdit &theEdit = GetEditCtrl();

// get the font the control is using


CFont *pFont = theEdit.GetFont();
TEXTMETRIC tm;

// get the control's DC, too


CDC *pDC = theEdit.GetDC();

// Select the font that the control uses by default into the DC.
// We must do this because the control may or may not be using
// that font at this exact moment
CFont *pOldFont = pDC->SelectObject(pFont);

// Retrieve text metrics for that font and return the previously
// selected font.
pDC->GetTextMetrics(&tm);
pDC->SelectObject(pOldFont);

// Get an identity rectangle and map it to dialog units


CRect rect(0, 0, 100, 1);
::MapDialogRect((HWND)this, rect);

// We now know that 100 dialog units are rect.Width() screen units,
// so we can multiply screen units by 100 and divide by rect.Width()
// to find dialog units from screen units. tm.tmAveCharWidth is
// the width of _one_ character, so setting the tabs at every
// four characters means we also multiply by four.
SetTabStops((4 * tm.tmAveCharWidth * 100) / rect.Width());
CEditView::UnlockBuffer
Call this member function to unlock the buffer.

void UnlockBuffer() const;

Remarks
Call UnlockBuffer after you have finished using the pointer returned by LockBuffer.

See also
MFC Sample SUPERPAD
CCtrlView Class
Hierarchy Chart
CEdit Class
CDocument Class
CDocTemplate Class
CCtrlView Class
CRichEditView Class
CEvent Class
3/27/2020 • 8 minutes to read • Edit Online

Represents an event, which is a synchronization object that enables one thread to notify another that an event has
occurred.

Syntax
class CEvent : public CSyncObject

Members
Public Constructors
NAME DESC RIP T IO N

CEvent::CEvent Constructs a CEvent object.

Public Methods
NAME DESC RIP T IO N

CEvent::PulseEvent Sets the event to available (signaled), releases waiting threads,


and sets the event to unavailable (nonsignaled).

CEvent::ResetEvent Sets the event to unavailable (nonsignaled).

CEvent::SetEvent Sets the event to available (signaled) and releases any waiting
threads.

CEvent::Unlock Releases the event object.

Remarks
Events are useful when a thread must know when to perform its task. For example, a thread that copies data to a
data archive must be notified when new data is available. By using a CEvent object to notify the copy thread when
new data is available, the thread can perform its task as soon as possible.
CEvent objects have two types: manual and automatic.
An automatic CEvent object automatically returns to a non-signaled (unavailable) state after at least one thread is
released. By default, a CEvent object is automatic unless you pass TRUE for the bManualReset parameter during
construction.
A manual CEvent object stays in the state set by SetEvent or ResetEvent until the other function is called. To create
a manual CEvent object, pass TRUE for the bManualReset parameter during construction.
To use a CEvent object, construct the CEvent object when it is required. Specify the name of the event you want to
wait on, and also specify that your application should initially own it. You can then access the event when the
constructor returns. Call SetEvent to signal (make available) the event object and then call Unlock when you are
done accessing the controlled resource.
An alternative method for using CEvent objects is to add a variable of type CEvent as a data member to the class
you want to control. During construction of the controlled object, call the constructor of the CEvent data member
and specify whether the event is initially signaled, and also specifythe type of event object you want, the name of
the event (if it will be used across process boundaries), and any security attributes you want.
To access a resource controlled by a CEvent object in this manner, first create a variable of either type CSingleLock
or type CMultiLock in the access method of your resource. Then call the Lock method of the lock object (for
example, CMultiLock::Lock). At this point, your thread will either gain access to the resource, wait for the resource
to be released and gain access, or wait for the resource to be released, time out, and fail to gain access to the
resource. In any case, your resource has been accessed in a thread-safe manner. To release the resource, call
SetEvent to signal the event object, and then use the Unlock method of the lock object (for example,
CMultiLock::Unlock), or let the lock object fall out of scope.
For more information about how to use CEvent objects, see Multithreading: How to Use the Synchronization
Classes.

Example
// The following demonstrates trivial usage of the CEvent class.
// A CEvent object is created and passed as a parameter to another
// thread. The other thread will wait for the event to be signaled
// and then exit

UINT __cdecl MyThreadProc(LPVOID lpParameter)


{
CEvent *pEvent = (CEvent *)(lpParameter);
VERIFY(pEvent != NULL);

// Wait for the event to be signaled


::WaitForSingleObject(pEvent->m_hObject, INFINITE);

// Terminate the thread


::AfxEndThread(0, FALSE);
return 0L;
}

void CEvent_Test()
{
// Create the CEvent object that will be passed to the thread routine
CEvent *pEvent = new CEvent(FALSE, FALSE);

// Create a thread that will wait on the event


CWinThread *pThread;
pThread = ::AfxBeginThread(&MyThreadProc, pEvent, 0, 0, CREATE_SUSPENDED, NULL);
pThread->m_bAutoDelete = FALSE;
pThread->ResumeThread();

// Signal the thread to do the next work item


pEvent->SetEvent();

// Wait for the thread to consume the event and return


::WaitForSingleObject(pThread->m_hThread, INFINITE);
delete pThread;
delete pEvent;
}

// This example builds upon the previous one.


// A second thread is created to calculate prime numbers.
// The main thread will signal the second thread to calculate the next
// prime number in the series. The second thread signals the first
// prime number in the series. The second thread signals the first
// after each number is calculated. Finally, after several iterations
// the worker thread is signaled to terminate.

class CPrimeTest
{
public:
CPrimeTest()
: m_pCalcNext(new CEvent(FALSE, FALSE)),
m_pCalcFinished(new CEvent(FALSE, FALSE)),
m_pTerminateThread(new CEvent(FALSE, FALSE)),
m_iCurrentPrime(0)
{
// Create a thread that will calculate the prime numbers
CWinThread *pThread;
pThread = ::AfxBeginThread(&PrimeCalcProc,
this, 0, 0, CREATE_SUSPENDED, NULL);
pThread->m_bAutoDelete = FALSE;
pThread->ResumeThread();

// Calcuate the first 10 prime numbers in the series on the thread


for (UINT i = 0; i < 10; i++)
{
// Signal the thread to do the next work item
m_pCalcNext->SetEvent();
// Wait for the thread to complete the current task
::WaitForSingleObject(m_pCalcFinished->m_hObject, INFINITE);
// Print the result
TRACE(_T("The value of m_iCurrentPrime is: %d\n"), m_iCurrentPrime);
}

// Notify the worker thread to exit and wait for it to complete


m_pTerminateThread->SetEvent();
::WaitForSingleObject(pThread->m_hThread, INFINITE);
delete pThread;
}
~CPrimeTest()
{
delete m_pCalcNext;
delete m_pCalcFinished;
delete m_pTerminateThread;
}

private:
// Determines whether the given number is a prime number
static BOOL IsPrime(INT ThisPrime)
{
if (ThisPrime < 2)
return FALSE;

for (INT n = 2; n < ThisPrime; n++)


{
if (ThisPrime % n == 0)
return FALSE;
}
return TRUE;
}

// Calculates the next prime number in the series


static INT NextPrime(INT ThisPrime)
{
while (TRUE)
{
if (IsPrime(++ThisPrime))
{
return ThisPrime;
}
}
}
// Worker thread responsible for calculating the next prime
// number in the series
static UINT __cdecl PrimeCalcProc(LPVOID lpParameter)
{
CPrimeTest *pThis = static_cast<CPrimeTest *>(lpParameter);
VERIFY(pThis != NULL);

VERIFY(pThis->m_pCalcNext != NULL);
VERIFY(pThis->m_pCalcFinished != NULL);
VERIFY(pThis->m_pTerminateThread != NULL);

// Create a CMultiLock object to wait on the various events


// WAIT_OBJECT_0 refers to the first event in the array,
// WAIT_OBJECT_0+1 refers to the second
CSyncObject *pWaitObjects[] = {pThis->m_pCalcNext,
pThis->m_pTerminateThread};
CMultiLock MultiLock(pWaitObjects, 2L);
while (MultiLock.Lock(INFINITE, FALSE) == WAIT_OBJECT_0)
{
// Calculate next prime
pThis->m_iCurrentPrime = NextPrime(pThis->m_iCurrentPrime);
// Notify main thread calculation is complete
pThis->m_pCalcFinished->SetEvent();
}

// Terminate the thread


::AfxEndThread(0, FALSE);
return 0L;
}

CEvent *m_pCalcNext; // notifies worker thread to calculate next prime


CEvent *m_pCalcFinished; // notifies main thread current calculation is complete
CEvent *m_pTerminateThread; // notifies worker thread to terminate

INT m_iCurrentPrime; // current calculated prime number


};

Inheritance Hierarchy
CObject
CSyncObject
CEvent

Requirements
Header : afxmt.h

CEvent::CEvent
Constructs a named or unnamed CEvent object.

CEvent(
BOOL bInitiallyOwn = FALSE,
BOOL bManualReset = FALSE,
LPCTSTR lpszName = NULL,
LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);

Parameters
bInitiallyOwn
If TRUE, the thread for the CMultilock or CSingleLock object is enabled. Otherwise, all threads wanting to access
the resource must wait.
bManualReset
If TRUE, specifies that the event object is a manual event, otherwise the event object is an automatic event.
lpszName
Name of the CEvent object. Must be supplied if the object will be used across process boundaries. If the name
matches an existing event, the constructor builds a new CEvent object which references the event of that name. If
the name matches an existing synchronization object that is not an event, the construction will fail. If NULL, the
name will be null.
lpsaAttribute
Security attributes for the event object. For a full description of this structure, see SECURITY_ATTRIBUTES in the
Windows SDK.
Remarks
To access or release a CEvent object, create a CMultiLock or CSingleLock object and call its Lock and Unlock
member functions.
To change the state of a CEvent object to signaled (threads do not have to wait), call SetEvent or PulseEvent. To set
the state of a CEvent object to nonsignaled (threads must wait), call ResetEvent.

IMPORTANT
After creating the CEvent object, use GetLastError to ensure that the mutex didn't already exist. If the mutex did exist
unexpectedly, it may indicate a rogue process is squatting and may be intending to use the mutex maliciously. In this case,
the recommended security-conscious procedure is to close the handle and continue as if there was a failure in creating the
object.

CEvent::PulseEvent
Sets the state of the event to signaled (available), releases any waiting threads, and resets it to nonsignaled
(unavailable) automatically.

BOOL PulseEvent();

Return Value
Nonzero if the function was successful; otherwise 0.
Remarks
If the event is manual, all waiting threads are released, the event is set to nonsignaled, and PulseEvent returns. If
the event is automatic, a single thread is released, the event is set to nonsignaled, and PulseEvent returns.
If no threads are waiting, or no threads can be released immediately, PulseEvent sets the state of the event to
nonsignaled and returns.
PulseEvent uses the underlying Win32 PulseEvent function, which can be momentarily removed from the wait
state by a kernel-mode asynchronous procedure call. Therefore, PulseEvent is unreliable and should not be used
by new applications. For more information, see the PulseEvent function.

CEvent::ResetEvent
Sets the state of the event to nonsignaled until explicitly set to signaled by the SetEvent member function.
BOOL ResetEvent();

Return Value
Nonzero if the function was successful; otherwise 0.
Remarks
This causes all threads wishing to access this event to wait.
This member function is not used by automatic events.

CEvent::SetEvent
Sets the state of the event to signaled, releasing any waiting threads.

BOOL SetEvent();

Return Value
Nonzero if the function was successful, otherwise 0.
Remarks
If the event is manual, the event will remain signaled until ResetEvent is called. More than one thread can be
released in this case. If the event is automatic, the event will remain signaled until a single thread is released. The
system will then set the state of the event to nonsignaled. If no threads are waiting, the state remains signaled until
one thread is released.

CEvent::Unlock
Releases the event object.

BOOL Unlock();

Return Value
Nonzero if the thread owned the event object and the event is an automatic event; otherwise 0.
Remarks
This member function is called by threads that currently own an automatic event to release it after they are done, if
their lock object is to be reused. If the lock object is not to be reused, this function will be called by the lock object's
destructor.

See also
CSyncObject Class
Hierarchy Chart
CException Class
4/21/2020 • 5 minutes to read • Edit Online

The base class for all exceptions in the Microsoft Foundation Class Library.

Syntax
class AFX_NOVTABLE CException : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CException::CException Constructs a CException object.

Public Methods
NAME DESC RIP T IO N

CException::Delete Deletes a CException object.

CException::ReportError Reports an error message in a message box to the user.

Remarks
Because CException is an abstract base class you cannot create CException objects directly; you must
create objects of derived classes. If you need to create your own CException -style class, use one of the
derived classes listed above as a model. Make sure that your derived class also uses IMPLEMENT_DYNAMIC .
The derived classes and their descriptions are listed below:

CSimpleException A base class for resource-critical MFC exceptions

CInvalidArgException Invalid argument exception condition

CMemoryException Out-of-memory exception

CNotSupportedException Request for an unsupported operation

CArchiveException Archive-specific exception

CFileException File-specific exception

CResourceException Windows resource not found or not creatable


COleException OLE exception

CDBException Database exception (that is, exception conditions arising


for MFC database classes based on Open Database
Connectivity)

COleDispatchException OLE dispatch (automation) exception

CUserException Exception that indicates that a resource could not be


found

CDaoException Data access object exception (that is, exception conditions


arising for DAO classes)

CInternetException Internet exception (that is, exception conditions arising for


Internet classes).

These exceptions are intended to be used with the THROW, THROW_LAST, try, catch, and_catch, and
end_catch macros. For more information on exceptions, see Exception Processing, or see the article
Exception Handling (MFC).
To catch a specific exception, use the appropriate derived class. To catch all types of exceptions, use
CException , and then use CObject::IsKindOf to differentiate among CException -derived classes. Note that
CObject::IsKindOf works only for classes declared with the IMPLEMENT_DYNAMIC macro, in order to take
advantage of dynamic type checking. Any CException -derived class that you create should use the
IMPLEMENT_DYNAMIC macro, too.

You can report details about exceptions to the user by calling GetErrorMessage or ReportError, two member
functions that work with any of CException 's derived classes.
If an exception is caught by one of the macros, the CException object is deleted automatically; do not delete
it yourself. If an exception is caught by using a catch keyword, it is not automatically deleted. See the article
Exception Handling (MFC) for more information about when to delete an exeption object.

Inheritance Hierarchy
CObject
CException

Requirements
Header : afx.h

CException::CException
This member function constructs a CException object.

explicit CException(BOOL bAutoDelete);

Parameters
b_AutoDelete
Specify TRUE if the memory for the CException object has been allocated on the heap. This will cause the
CException object to be deleted when the Delete member function is called to delete the exception. Specify
FALSE if the CException object is on the stack or is a global object. In this case, the CException object will
not be deleted when the Delete member function is called.
Remarks
You would normally never need to call this constructor directly. A function that throws an exception should
create an instance of a CException -derived class and call its constructor, or it should use one of the MFC
throw functions, such as AfxThrowFileException, to throw a predefined type. This documentation is provided
only for completeness.

CException::Delete
This function checks to see if the CException object was created on the heap, and if so, it calls the delete
operator on the object.

void Delete();

Remarks
When deleting a CException object, use the Delete member function to delete the exception. Do not use
the delete operator directly, because the CException object may be a global object or have been created on
the stack.
You can specify whether the object should be deleted when the object is constructed. For more information,
see CException::CException.
You only need to call Delete if you are using the C++ tr y - catch mechanism. If you are using the MFC
macros TRY and CATCH , then these macros will automatically call this function.
Example
CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception, and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
// Note that this example performs the same actions as the
// example for CATCH, but uses C++ try/catch syntax instead
// of using the MFC TRY/CATCH macros. This sample must use
// CException::Delete() to delete the exception objects
// before closing the catch block, while the CATCH example
// implicitly performs the deletion via the macros.
try
{
pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
CFile::modeRead | CFile::shareDenyNone);
ULONGLONG ullLength = pFile->GetLength();
CString str;
str.Format(_T("Your SYSTEM.INI file is %u bytes long."), ullLength);
AfxMessageBox(str);
}
catch(CFileException* pEx)
{
// Simply show an error message to the user.
pEx->ReportError();
pEx->Delete();
}
catch(CMemoryException* pEx)
{
// We can't recover from this memory exception, so we'll
// just terminate the app without any cleanup. Normally, an
// an application should do everything it possibly can to
// clean up properly and _not_ call AfxAbort().
pEx->Delete();
AfxAbort();
}
// If an exception occurrs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our clean-up code needs to test for NULL.
if (pFile != NULL)
{
pFile->Close();
delete pFile;
}

CException::ReportError
Call this member function to report error text in a message box to the user.

virtual int ReportError(


UINT nType = MB_OK,
UINT nMessageID = 0);

Parameters
nType
Specifies the style of the message box. Apply any combination of the message-box styles to the box. If you
don't specify this parameter, the default is MB_OK.
nMessageID
Specifies the resource ID (string table entry) of a message to display if the exception object does not have an
error message. If 0, the message "No error message is available" is displayed.
Return Value
An AfxMessageBox value; otherwise 0 if there is not enough memory to display the message box. See
AfxMessageBox for the possible return values.
Example
Here is an example of the use of CException::ReportError . For another example, see the example for CATCH.

CFile fileInput;
CFileException ex;

// try to open a file for reading.


// The file will certainly not
// exist because there are too many explicit
// directories in the name.

// if the call to Open() fails, ex will be


// initialized with exception
// information. the call to ex.ReportError() will
// display an appropriate
// error message to the user, such as
// "\Too\Many\Bad\Dirs.DAT contains an
// invalid path." The error message text will be
// appropriate for the
// file name and error condition.

if (!fileInput.Open(_T("\\Too\\Many\\Bad\\Dirs.DAT"), CFile::modeRead, &ex))


{
ex.ReportError();
}
else
{
// the file was opened, so do whatever work
// with fileInput we were planning...

fileInput.Close();
}

See also
CObject Class
Hierarchy Chart
Exception Processing
How Do I: Create my Own Custom Exception Classes
CFieldExchange Class
4/21/2020 • 4 minutes to read • Edit Online

Supports the record field exchange (RFX) and bulk record field exchange (Bulk RFX) routines used by the
database classes.

Syntax
class CFieldExchange

Members
Public Methods
NAME DESC RIP T IO N

CFieldExchange::IsFieldType Returns nonzero if the current operation is appropriate for


the type of field being updated.

CFieldExchange::SetFieldType Specifies the type of recordset data member — column or


parameter — represented by all following calls to RFX
functions until the next call to SetFieldType .

Remarks
CFieldExchange does not have a base class.
Use this class if you are writing data exchange routines for custom data types or when you are implementing
bulk row fetching; otherwise, you will not directly use this class. RFX and Bulk RFX exchanges data between the
field data members of your recordset object and the corresponding fields of the current record on the data
source.

NOTE
If you are working with the Data Access Objects (DAO) classes rather than the Open Database Connectivity (ODBC)
classes, use class CDaoFieldExchange instead. For more information, see the article Overview:Database Programming.

A CFieldExchange object provides the context information needed for record field exchange or bulk record field
exchange to take place. CFieldExchange objects support a number of operations, including binding parameters
and field data members and setting various flags on the fields of the current record. RFX and Bulk RFX
operations are performed on recordset-class data members of types defined by the enum FieldType in
CFieldExchange . Possible FieldType values are:

CFieldExchange::outputColumn for field data members.


CFieldExchange::inputParam or CFieldExchange::param for input parameter data members.
CFieldExchange::outputParam for output parameter data members.
CFieldExchange::inoutParam for input/output parameter data members.
Most of the class's member functions and data members are provided for writing your own custom RFX
routines. You will use SetFieldType frequently. For more information, see the articles Record Field Exchange
(RFX) and Recordset (ODBC). For information about bulk row fetching, see the article Recordset: Fetching
Records in Bulk (ODBC). For details about the RFX and Bulk RFX global functions, see Record Field Exchange
Functions in the MFC Macros and Globals section of this reference.

Inheritance Hierarchy
CFieldExchange

Requirements
Header : afxdb.h

CFieldExchange::IsFieldType
If you write your own RFX function, call IsFieldType at the beginning of your function to determine whether
the current operation can be performed on a particular field or parameter data member type (a
CFieldExchange::outputColumn , CFieldExchange::inputParam , CFieldExchange::param ,
CFieldExchange::outputParam , or CFieldExchange::inoutParam ).

BOOL IsFieldType(UINT* pnField);

Parameters
pnField
The sequential number of the field or parameter data member is returned in this parameter. This number
corresponds to the data member's order in the CRecordset::DoFieldExchange or
CRecordset::DoBulkFieldExchange function.
Return Value
Nonzero if the current operation can be performed on the current field or parameter type.
Remarks
Follow the model of the existing RFX functions.

CFieldExchange::SetFieldType
You need a call to SetFieldType in your recordset class's DoFieldExchange or DoBulkFieldExchange override.

void SetFieldType(UINT nFieldType);

Parameters
nFieldType
A value of the enum FieldType , declared in CFieldExchange , which can be one of the following:
CFieldExchange::outputColumn

CFieldExchange::inputParam

CFieldExchange::param

CFieldExchange::outputParam
CFieldExchange::inoutParam

Remarks
For field data members, you must call SetFieldType with a parameter of CFieldExchange::outputColumn ,
followed by calls to the RFX or Bulk RFX functions. If you have not implemented bulk row fetching, then
ClassWizard places this SetFieldType call for you in the field map section of DoFieldExchange .
If you parameterize your recordset class, you must call SetFieldType again, outside any field map section,
followed by RFX calls for all the parameter data members. Each type of parameter data member must have its
own SetFieldType call. The following table distinguishes the different values you can pass to SetFieldType to
represent the parameter data members of your class:

SET F IEL DT Y P E PA RA M ET ER VA L UE T Y P E O F PA RA M ET ER DATA M EM B ER

CFieldExchange::inputParam Input parameter. A value that is passed into the recordset's


query or stored procedure.

CFieldExchange::param same as CFieldExchange::inputParam .

CFieldExchange::outputParam Output parameter. A return value of the recordset's stored


procedure.

CFieldExchange::inoutParam Input/output parameter. A value that is passed into and


returned from the recordset's stored procedure.

In general, each group of RFX function calls associated with field data members or parameter data members
must be preceded by a call to SetFieldType . The nFieldType parameter of each SetFieldType call identifies the
type of the data members represented by the RFX function calls that follow the SetFieldType call.
For more information about handling output and input/output parameters, see the CRecordset member
function FlushResultSet. For more information about the RFX and Bulk RFX functions, see the topic Record Field
Exchange Functions. For related information about bulk row fetching, see the article Recordset: Fetching Records
in Bulk (ODBC).
Example
This example shows several calls to RFX functions with accompanying calls to SetFieldType . Note that
SetFieldType is called through the pFX pointer to a CFieldExchange object.

void CSections::DoFieldExchange(CFieldExchange *pFX)


{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, _T("[CourseID]"), m_CourseID);
RFX_Text(pFX, _T("[InstructorID]"), m_InstructorID);
RFX_Text(pFX, _T("[RoomNo]"), m_RoomNo);
RFX_Text(pFX, _T("[Schedule]"), m_Schedule);

// output parameter
pFX->SetFieldType(CFieldExchange::outputParam);
RFX_Long(pFX, _T("Instructor_Count"), m_nCountParam);

// input parameter
pFX->SetFieldType(CFieldExchange::inputParam);
RFX_Text(pFX, _T("Department_Name"), m_strNameParam);
}

See also
Hierarchy Chart
CRecordset Class
CFile Class
4/21/2020 • 22 minutes to read • Edit Online

The base class for Microsoft Foundation Class file classes.

Syntax
class CFile : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CFile::CFile Constructs a CFile object from a path or file handle.

Public Methods
NAME DESC RIP T IO N

CFile::Abort Closes a file ignoring all warnings and errors.

CFile::Close Closes a file and deletes the object.

CFile::Duplicate Constructs a duplicate object based on this file.

CFile::Flush Flushes any data yet to be written.

CFile::GetFileName Retrieves the filename of the selected file.

CFile::GetFilePath Retrieves the full file path of the selected file.

CFile::GetFileTitle Retrieves the title of the selected file.

CFile::GetLength Retrieves the length of the file.

CFile::GetPosition Retrieves the current file pointer.

CFile::GetStatus Retrieves the status of the open file, or in the static


version, retrieves the status of the specified file (static,
virtual function).

CFile::LockRange Locks a range of bytes in a file.

CFile::Open Safely opens a file with an error-testing option.

CFile::Read Reads (unbuffered) data from a file at the current file


position.
NAME DESC RIP T IO N

CFile::Remove Deletes the specified file (static function).

CFile::Rename Renames the specified file (static function).

CFile::Seek Positions the current file pointer.

CFile::SeekToBegin Positions the current file pointer at the beginning of the


file.

CFile::SeekToEnd Positions the current file pointer at the end of the file.

CFile::SetFilePath Sets the full file path of the selected file.

CFile::SetLength Changes the length of the file.

CFile::SetStatus Sets the status of the specified file (static, virtual


function).

CFile::UnlockRange Unlocks a range of bytes in a file.

CFile::Write Writes (unbuffered) data in a file to the current file


position.

Public Operators
NAME DESC RIP T IO N

CFile::operator HANDLE A handle to a CFile object.

Public Data Members


NAME DESC RIP T IO N

CFile::hFileNull Determines if the CFile object has a valid handle.

CFile::m_hFile Usually contains the operating-system file handle.

Protected Data Members


NAME DESC RIP T IO N

CFile::m_pTM Pointer to CAtlTransactionManager object.

Remarks
It directly provides unbuffered, binary disk input/output services, and it indirectly supports text files and
memory files through its derived classes. CFile works in conjunction with the CArchive class to support
serialization of Microsoft Foundation Class objects.
The hierarchical relationship between this class and its derived classes allows your program to operate on
all file objects through the polymorphic CFile interface. A memory file, for example, behaves like a disk
file.
Use CFile and its derived classes for general-purpose disk I/O. Use ofstream or other Microsoft
iostream classes for formatted text sent to a disk file.
Normally, a disk file is opened automatically on CFile construction and closed on destruction. Static
member functions permit you to interrogate a file's status without opening the file.
For more information on using CFile , see the articles Files in MFC and File Handling in the Run-Time
Library Reference.

Inheritance Hierarchy
CObject
CFile

Requirements
Header : afx.h

CFile::Abort
Closes the file associated with this object and makes the file unavailable for reading or writing.

virtual void Abort();

Remarks
If you haven't closed the file before destroying the object, the destructor closes it for you.
When handling exceptions, CFile::Abort differs from CFile::Close in two important ways. First, the
Abort function won't throw an exception on failures, because failures are ignored by Abort . Second,
Abort won't ASSERT if the file hasn't been opened, or was closed previously.

If you used new to allocate the CFile object on the heap, then you must delete it after closing the file.
Abort sets m_hFile to CFile::hFileNull .

Example

CStdioFile fileTest;
TCHAR* pszFileName = _T("Abort_File.dat");

// do stuff that may cause exceptions


CFileException ex;
if (!fileTest.Open(pszFileName, CFile::modeWrite, &ex))
{
ex.ReportError();
fileTest.Abort(); // close file safely and quietly
}

CFile::CFile
Constructs and initializes a CFile object.
CFile();
CFile(CAtlTransactionManager* pTM);
CFile(HANDLE hFile);

CFile(
LPCTSTR lpszFileName,
UINT nOpenFlags);

CFile(
LPCTSTR lpszFileName,
UINT nOpenFlags,
CAtlTransactionManager* pTM);

Parameters
hFile
Handle of a file to attach to the CFile object.
lpszFileName
Relative or full path of a file to attach to the CFile object.
nOpenFlags
Bitwise combination (OR) of file access options for the specified file. See the Remarks section for possible
options.
pTM
Pointer to CAtlTransactionManager object
Remarks
The following five tables list the possible options for the nOpenFlags parameter.
Choose only one of the following file access mode options. The default file access mode is
CFile::modeRead , which is read only.

VA L UE DESC RIP T IO N

CFile::modeRead Requests read access only.

CFile::modeWrite Requests write access only.

CFile::modeReadWrite Requests read and write access.

Choose one of the following character mode options.

VA L UE DESC RIP T IO N

CFile::typeBinary Sets binary mode (used in derived classes only).

CFile::typeText Sets text mode with special processing for carriage


return-line feed pairs (used in derived classes only).

CFile::typeUnicode Sets Unicode mode (used in derived classes only). Text is


written to the file in Unicode format when the application
is built in a Unicode configuration. No BOM is written to
the file.

Choose only one of the following file share mode options. The default file share mode is
CFile::shareExclusive , which is exclusive.

VA L UE DESC RIP T IO N

CFile::shareDenyNone No sharing restrictions.

CFile::shareDenyRead Denies read access to all others.

CFile::shareDenyWrite Denies write access to all others.

CFile::shareExclusive Denies read and write access to all others.

Choose the first, or both, of the following file creation mode options. The default creation mode is
CFile::modeNoTruncate , which is open existing.

VA L UE DESC RIP T IO N

CFile::modeCreate Creates a new file if no file exists. If the file already exists,
it's overwritten and initially set to zero length.

CFile::modeNoTruncate Creates a new file if no file exists; otherwise, if the file


already exists, it's attached to the CFile object.

Choose the following file caching options as described. By default, the system uses a general-purpose
caching scheme that isn't available as an option.

VA L UE DESC RIP T IO N

CFile::osNoBuffer The system doesn't use an intermediate cache for the file.
This option cancels the following 2 options.

CFile::osRandomAccess The file cache is optimized for random access. Don't use
both this option and the sequential scan option.

CFile::osSequentialScan The file cache is optimized for sequential access. Don't use
both this option and the random access option.

CFile::osWriteThrough Write operations are done without delay.

Choose the following security option to prevent the file handle from being inherited. By default, any new
child processes can use the file handle.

VA L UE DESC RIP T IO N

CFile::modeNoInherit Prevents any child processes from using the file handle.

The default constructor initializes members but doesn't attach a file to the CFile object. After using this
constructor, use the CFile::Open method to open a file and attach it to the CFile object.
The constructor with one parameter initializes members and attaches an existing file to the CFile object.
The constructor with two parameters initializes members and tries to open the specified file. If this
constructor successfully opens the specified file, the file is attached to the CFile object; otherwise, this
constructor throws a pointer to a CInvalidArgException object. For more information about how to handle
exceptions, see Exceptions.
If a CFile object successfully opens a specified file, it will close this file automatically when the CFile
object is destroyed; otherwise, you must explicitly close the file after it's no longer attached to the CFile
object.
Example
The following code shows how to use a CFile .

HANDLE hFile = CreateFile(_T("CFile_File.dat"),


GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Couldn't create the file!"));
}
else
{
// Attach a CFile object to the handle we have.
CFile myFile(hFile);

static const TCHAR sz[] = _T("I love CFile!");

// write string
myFile.Write(sz, sizeof(sz));

// We need to call Close() explicitly. Note that there's no need to


// call CloseHandle() on the handle returned by the API because
// Close() automatically calls CloseHandle() for us.
myFile.Close();

CFile::Close
Closes the file associated with this object and makes the file unavailable for reading or writing.

virtual void Close();

Remarks
If you haven't closed the file before destroying the object, the destructor closes it for you.
If you used new to allocate the CFile object on the heap, then you must delete it after closing the file.
Close sets m_hFile to CFile::hFileNull .

Example
See the example for CFile::CFile.

CFile::Duplicate
Constructs a duplicate CFile object for a given file.

virtual CFile* Duplicate() const;

Return Value
A pointer to a duplicate CFile object.
Remarks
This function is equivalent to the C run-time function _dup .

CFile::Flush
Forces any data remaining in the file buffer to be written to the file.

virtual void Flush();

Remarks
The use of Flush doesn't guarantee flushing of CArchive buffers. If you're using an archive, call
CArchive::Flush first.
Example
See the example for CFile::SetFilePath.

CFile::GetFileName
Call this member function to retrieve the name of a specified file.

virtual CString GetFileName() const;

Return Value
The name of the file.
Remarks
For example, when you call to generate a message to the user about the file
GetFileName
c:\windows\write\myfile.wri , the filename, myfile.wri , is returned.

To return the entire path of the file, including the name, call GetFilePath. To return the title of the file (
myfile ), call GetFileTitle.

Example
This code fragment opens the SYSTEM.INI file in your WINDOWS directory. If found, the example will print
out the name and path and title, as shown under Output:
try
{
// try to open the file
CFile sysFile(_T("C:\\WINDOWS\\SYSTEM.INI"), CFile::modeRead);

// print out path name and title information


_tprintf_s(_T("Path is : \"%s\"\n"),
(LPCTSTR) sysFile.GetFilePath());
_tprintf_s(_T("Name is : \"%s\"\n"),
(LPCTSTR) sysFile.GetFileName());
_tprintf_s(_T("Title is: \"%s\"\n"),
(LPCTSTR) sysFile.GetFileTitle());

// close the file handle


sysFile.Close();
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
}

CFile::GetFilePath
Call this member function to retrieve the full path of a specified file.

virtual CString GetFilePath() const;

Return Value
The full path of the specified file.
Remarks
For example, when you call GetFilePathto generate a message to the user about the file
c:\windows\write\myfile.wri , the file path, c:\windows\write\myfile.wri , is returned.

To return just the name of the file ( myfile.wri ), call GetFileName. To return the title of the file ( myfile ),
call GetFileTitle.
Example
See the example for GetFileName.

CFile::GetFileTitle
Call this member function to retrieve the file title (the display name) for the file.

virtual CString GetFileTitle() const;

Return Value
The title of the underlying file.
Remarks
This method calls GetFileTitle to retrieve the title of the file. If successful, the method returns the string that
the system would use to display the file name to the user. Otherwise, the method calls PathFindFileName
to retrieve the file name (including the file extension) of the underlying file. That means the file extension
isn't always included in the returned file title string. For more information, see GetFileTitle and
PathFindFileName in the Windows SDK.
To return the entire path of the file, including the name, call GetFilePath. To return just the name of the file,
call GetFileName.
Example
See the example for GetFileName.

CFile::GetLength
Obtains the current logical length of the file in bytes.

virtual ULONGLONG GetLength() const;

Return Value
The length of the file.
Example

CFile* pFile = NULL;


// Constructing a CFile object with this override may throw
// a CFile exception, and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
try
{
pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
CFile::modeRead | CFile::shareDenyNone);
ULONGLONG dwLength = pFile->GetLength();
CString str;
str.Format(_T("Your SYSTEM.INI file is %I64u bytes long."), dwLength);
AfxMessageBox(str);
}
catch (CFileException* pEx)
{
// Simply show an error message to the user.
pEx->ReportError();
pEx->Delete();
}
catch(CMemoryException* pEx)
{
pEx->ReportError();
pEx->Delete();
// We can't recover from this memory exception, so we'll
// just terminate the app without any cleanup. Normally,
// an application should do everything it possibly can to
// clean up properly and _not_ call AfxAbort().
AfxAbort();
}

// If an exception occurs in the CFile constructor,


// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our clean-up code needs to test for NULL.
if (pFile != NULL)
{
pFile->Close();
delete pFile;
}
CFile::GetPosition
Obtains the current value of the file pointer, which can be used in later calls to Seek .

virtual ULONGLONG GetPosition() const;

Return Value
The file pointer.
Example

CFile cfile;
cfile.Open(_T("Seek_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
LONGLONG lOffset = 1000;
ULONGLONG lActual;
lActual = cfile.Seek(lOffset, CFile::begin);
ASSERT(cfile.GetPosition() == lActual);

CFile::GetStatus
This method retrieves status information related to a given CFile object instance or a given file path.

BOOL GetStatus(CFileStatus& rStatus) const;

static BOOL PASCAL GetStatus(


LPCTSTR lpszFileName,
CFileStatus& rStatus,
CAtlTransactionManager* pTM = NULL);

Parameters
rStatus
A reference to a user-supplied CFileStatus structure that will receive the status information. The
CFileStatus structure has the following fields:

CTime m_ctime The date and time the file was created.
CTime m_mtime The date and time the file was last modified.
CTime m_atime The date and time the file was last accessed for reading.
ULONGLONG m_size The logical size of the file in bytes, as reported by the DIR command.
BYTE m_attribute The attribute byte of the file.
char m_szFullName[_MAX_PATH] The absolute filename in the Windows character set.

lpszFileName
A string in the Windows character set that is the path to the desired file. The path can be relative or
absolute, or it can contain a network path name.
pTM
Pointer to CAtlTransactionManager object
Return Value
TRUE if the status information for the specified file is successfully obtained; otherwise, FALSE.
Remarks
The non-static version of GetStatus retrieves status information of the open file associated with the given
CFile object. The static version of GetStatus obtains the file status from a given file path without actually
opening the file. This version is useful for testing the existence and access rights of a file.
The m_attribute member of the CFileStatus structure refers to the file attribute set. The CFile class
provides the Attribute enumeration type so file attributes can be specified symbolically:

enum Attribute {
normal = 0x00,
readOnly = 0x01,
hidden = 0x02,
system = 0x04,
volume = 0x08,
directory = 0x10,
archive = 0x20
};

Example

CFile cfile;
cfile.Open(_T("SetLength_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
ULONGLONG dwNewLength = 10000;
cfile.SetLength(dwNewLength);
CFileStatus status;
if(cfile.GetStatus(status)) // virtual member function
{
TRACE(_T("File size = %u\n"), status.m_size);
}
TCHAR* pszFileName = _T("SetLength_File.dat");
if(CFile::GetStatus(pszFileName, status)) // static function
{
TRACE(_T("Full file name = %s\n"), status.m_szFullName);
}

CFile::hFileNull
Determines the presence of a valid file handle for the CFile object.

static AFX_DATA const HANDLE hFileNull;

Remarks
This constant is used to determine if the CFile object has a valid file handle.
The following example demonstrates this operation:

if (myFile.m_hFile != CFile::hFileNull)
;//perform operations on the file
else
;//indicate the presence of an invalid handle

CFile::LockRange
Locks a range of bytes in an open file, throwing an exception if the file is already locked.
virtual void LockRange(
ULONGLONG dwPos,
ULONGLONG dwCount);

Parameters
dwPos
The byte offset of the start of the byte range to lock.
dwCount
The number of bytes in the range to lock.
Remarks
Locking bytes in a file prevents access to those bytes by other processes. You can lock more than one
region of a file, but no overlapping regions are allowed.
When you unlock the region using the UnlockRange member function, the byte range must correspond
exactly to the region that was previously locked. The LockRange function doesn't merge adjacent regions. If
two locked regions are adjacent, you must unlock each region separately.

NOTE
This function isn't available for the CMemFile -derived class.

Example

CFile cfile;
cfile.Open(_T("LockRange_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
ULONGLONG dwPos = 10;
ULONGLONG dwCount = 100;
cfile.LockRange(dwPos, dwCount);

// do something with the file

cfile.UnlockRange(dwPos, dwCount);

CFile::m_hFile
Contains the operating-system file handle for an open file.

HANDLE m_hFile;

Remarks
m_hFile is a public variable of type UINT. It contains CFile::hFileNull , an operating-system-independent
empty file indicator, if the handle hasn't been assigned.
Use of m_hFileisn't recommended, because the member's meaning depends on the derived class.
m_hFile is made a public member for convenience in supporting nonpolymorphic use of the class.

CFile::m_pTM
Pointer to a CAtlTransactionManager object.
CAtlTransactionManager* m_pTM;

Remarks

CFile::Open
Overloaded. Open is designed for use with the default CFile constructor.

virtual BOOL Open(


LPCTSTR lpszFileName,
UINT nOpenFlags,
CFileException* pError = NULL);

virtual BOOL Open(


LPCTSTR lpszFileName,
UINT nOpenFlags,
CAtlTransactionManager* pTM,
CFileException* pError = NULL);

Parameters
lpszFileName
A string that contains the path to the desired file. The path can be relative, absolute, or a network name
(UNC).
nOpenFlags
A UINT that defines the file's sharing and access mode. It specifies the action to take when opening the file.
You can combine options by using the bitwise-OR ( | ) operator. One access permission and one share
option are required; the modeCreate and modeNoInherit modes are optional. See the CFile constructor for
a list of mode options.
pError
A pointer to an existing file-exception object that will receive the status of a failed operation.
pTM
Pointer to CAtlTransactionManager object
Return Value
Nonzero if the open was successful; otherwise 0. The pError parameter is meaningful only if 0 is returned.
Remarks
The two Open functions are "safe" methods for opening a file, where a failure is a normal, expected
condition.
While the CFile constructor throws an exception in an error condition, Open returns FALSE for error
conditions. Open can still initialize a CFileException object to describe the error, however. If you don't
supply the pError parameter, or if you pass NULL for pError, Open returns FALSE and doesn't throw a
CFileException . If you pass a pointer to an existing CFileException , and Open encounters an error, the
function fills it with information describing that error. Open doesn't throw an exception in either case.
The following table describes the possible results of Open .

C F IL EEXC EP T IO N
PERROR ERRO R EN C O UN T ERED RET URN VA L UE C O N T EN T

NULL No TRUE n/a


C F IL EEXC EP T IO N
PERROR ERRO R EN C O UN T ERED RET URN VA L UE C O N T EN T

ptr to CFileException No TRUE unchanged

NULL Yes FALSE n/a

ptr to CFileException Yes FALSE initialized to describe error

Example

CFile f;
CFileException e;
TCHAR* pszFileName = _T("Open_File.dat");
if(!f.Open(pszFileName, CFile::modeCreate | CFile::modeWrite, &e))
{
TRACE(_T("File could not be opened %d\n"), e.m_cause);
}
//A second example for CFile::Open.
//This function uses CFile to copy binary files.
bool BinaryFileCopy(LPCTSTR pszSource, LPCTSTR pszDest)
{
// constructing these file objects doesn't open them
CFile sourceFile;
CFile destFile;

// we'll use a CFileException object to get error information


CFileException ex;

// open the source file for reading


if (!sourceFile.Open(pszSource,
CFile::modeRead | CFile::shareDenyWrite, &ex))
{
// complain if an error happened
// no need to delete the ex object

TCHAR szError[1024];
ex.GetErrorMessage(szError, 1024);
_tprintf_s(_T("Couldn't open source file: %1024s"), szError);
return false;
}
else
{
if (!destFile.Open(pszDest, CFile::modeWrite |
CFile::shareExclusive | CFile::modeCreate, &ex))
{
TCHAR szError[1024];
ex.GetErrorMessage(szError, 1024);
_tprintf_s(_T("Couldn't open source file: %1024s"), szError);

sourceFile.Close();
return false;
}

BYTE buffer[4096];
DWORD dwRead;

// Read in 4096-byte blocks,


// remember how many bytes were actually read,
// and try to write that many out. This loop ends
// when there are no more bytes to read.
do
{
dwRead = sourceFile.Read(buffer, 4096);
destFile.Write(buffer, dwRead);
}
while (dwRead > 0);

// Close both files

destFile.Close();
sourceFile.Close();
}

return true;
}

CFile::operator HANDLE
Use this operator to pass a handle to a CFile object to functions such as ReadFileEx and GetFileTime that
expect a HANDLE .
operator HANDLE() const;

CFile::Read
Reads data into a buffer from the file associated with the CFile object.

virtual UINT Read(


void* lpBuf,
UINT nCount);

Parameters
lpBuf
Pointer to the user-supplied buffer that is to receive the data read from the file.
nCount
The maximum number of bytes to be read from the file. For text-mode files, carriage return-line feed pairs
are counted as single characters.
Return Value
The number of bytes transferred to the buffer. For all CFile classes, the return value may be less than
nCount if the end of file was reached.
Example

CFile cfile;
cfile.Open(_T("Write_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
char pbufWrite[100];
memset(pbufWrite, 'a', sizeof(pbufWrite));
cfile.Write(pbufWrite, 100);
cfile.Flush();
cfile.SeekToBegin();
char pbufRead[100];
cfile.Read(pbufRead, sizeof(pbufRead));
ASSERT(0 == memcmp(pbufWrite, pbufRead, sizeof(pbufWrite)));

For another example, see CFile::Open.

CFile::Remove
This static function deletes the file specified by the path.

static void PASCAL Remove(


LPCTSTR lpszFileName,
CAtlTransactionManager* pTM = NULL);

Parameters
lpszFileName
A string that is the path to the desired file. The path can be relative or absolute, and can contain a network
name.
pTM
Pointer to CAtlTransactionManager object
Remarks
Remove won't remove a directory.
The Remove member function throws an exception if the connected file is open or if the file can't be
removed. This function is equivalent to the DEL command.
Example

//example for CFile::Remove


TCHAR* pFileName = _T("Remove_File.dat");
try
{
CFile::Remove(pFileName);
}
catch (CFileException* pEx)
{
TRACE(_T("File %20s cannot be removed\n"), pFileName);
pEx->Delete();
}

CFile::Rename
This static function renames the specified file.

static void PASCAL Rename(


LPCTSTR lpszOldName,
LPCTSTR lpszNewName,
CAtlTransactionManager* pTM = NULL);

Parameters
lpszOldName
The old path.
lpszNewName
The new path.
pTM
Pointer to CAtlTransactionManager object
Remarks
Directories can't be renamed. This function is equivalent to the REN command.
Example

TCHAR* pOldName = _T("Oldname_File.dat");


TCHAR* pNewName = _T("Renamed_File.dat");

try
{
CFile::Rename(pOldName, pNewName);
}
catch(CFileException* pEx )
{
TRACE(_T("File %20s not found, cause = %d\n"), pOldName,
pEx->m_cause);
pEx->Delete();
}

CFile::Seek
Repositions the file pointer in an open file.

virtual ULONGLONG Seek(


LONGLONG lOff,
UINT nFrom);

Parameters
lOff
Number of bytes to move the file pointer. Positive values move the file pointer towards the end of the file;
negative values move the file pointer towards the start of the file.
nFrom
Position to seek from. See the Remarks section for possible values.
Return Value
The position of the file pointer if the method was successful; otherwise, the return value is undefined and a
pointer to a CFileException exception is thrown.
Remarks
The following table lists possible values for the nFrom parameter.

VA L UE DESC RIP T IO N

CFile::begin Seek from the start of the file.

CFile::current Seek from the current location of the file pointer.

CFile::end Seek from the end of the file.

When a file is opened, the file pointer is positioned at 0, the start of the file.
You can set the file pointer to a position beyond the end of a file. If you do, the size of the file doesn't
increase until you write to the file.
The exception handler for this method must delete the exception object after the exception is processed.
Example

CFile cfile;
cfile.Open(_T("Seek_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
LONGLONG lOffset = 1000;
ULONGLONG lActual;
lActual = cfile.Seek(lOffset, CFile::begin);

CFile::SeekToBegin
Sets the value of the file pointer to the beginning of the file.

void SeekToBegin();

Remarks
SeekToBegin() is equivalent to Seek( 0L, CFile::begin ) .
Example

CFile f;
f.Open(_T("Seeker_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
f.SeekToBegin();
ULONGLONG ullEnd = f.SeekToEnd();

CFile::SeekToEnd
Sets the value of the file pointer to the logical end of the file.

ULONGLONG SeekToEnd();

Return Value
The length of the file in bytes.
Remarks
SeekToEnd() is equivalent to CFile::Seek( 0L, CFile::end ) .
Example

CFile f;
f.Open(_T("Seeker_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
f.SeekToBegin();
ULONGLONG ullEnd = f.SeekToEnd();

CFile::SetFilePath
Call this function to specify the path of the file. For example, if the path of a file isn't available when a CFile
object is constructed, call SetFilePath to provide it.

virtual void SetFilePath(LPCTSTR lpszNewName);

Parameters
lpszNewName
Pointer to a string specifying the new path.
Remarks

NOTE
SetFilePath does not open the file or create the file; it simply associates the CFile object with a path name,
which can then be used.

Example
TCHAR* pstrName = _T("C:\\test\\SetPath_File.dat");

// open a file
HANDLE hFile = ::CreateFile(pstrName, GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, 0, NULL);

if (hFile != INVALID_HANDLE_VALUE)
{
// attach a CFile object to it
CFile myFile(hFile);

// At this point, myFile doesn't know the path name for the file
// it owns because Windows doesn't associate that information
// with the handle. Any CFileExceptions thrown by this object
// won't have complete information.

// Calling SetFilePath() remedies that problem by letting CFile


// know the name of the file that's associated with the object.

myFile.SetFilePath(pstrName);

// write something to the file and flush it immediately


DWORD dwValue = 1234;
myFile.Write(&dwValue, sizeof(dwValue));
myFile.Flush();

// destroying the CObject here will call ::CloseHandle() on the file


}

CFile::SetLength
Call this function to change the length of the file.

virtual void SetLength(ULONGLONG dwNewLen);

Parameters
dwNewLen
Desired length of the file in bytes. This value can be larger or smaller than the current length of the file. The
file will be extended or truncated as appropriate.
Remarks

NOTE
With CMemFile , this function could throw a CMemoryException object.

Example

CFile cfile;
cfile.Open(_T("SetLength_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
ULONGLONG dwNewLength = 10000;
cfile.SetLength(dwNewLength);

CFile::SetStatus
Sets the status of the file associated with this file location.
static void PASCAL SetStatus(
LPCTSTR lpszFileName,
const CFileStatus& status,
CAtlTransactionManager* pTM = NULL);

Parameters
lpszFileName
A string that is the path to the desired file. The path can be relative or absolute, and can contain a network
name.
status
The buffer containing the new status information. Call the GetStatus member function to prefill the
CFileStatus structure with current values, then make changes as required. If a value is 0, then the
corresponding status item isn't updated. See the GetStatus member function for a description of the
CFileStatus structure.

pTM
Pointer to CAtlTransactionManager object
Remarks
To set the time, modify the m_mtime field of status.
When you make a call to SetStatus in an attempt to change only the attributes of the file, and the
m_mtime member of the file status structure is nonzero, the attributes may also be affected (changing the
time stamp may have side effects on the attributes). If you want to only change the attributes of the file,
first set the m_mtime member of the file status structure to zero and then make a call to SetStatus .
Example

TCHAR* pFileName = _T("ReadOnly_File.dat");


CFileStatus status;
CFile::GetStatus(pFileName, status);
status.m_attribute |= CFile::readOnly;
CFile::SetStatus(pFileName, status);

CFile::UnlockRange
Unlocks a range of bytes in an open file.

virtual void UnlockRange(


ULONGLONG dwPos,
ULONGLONG dwCount);

Parameters
dwPos
The byte offset of the start of the byte range to unlock.
dwCount
The number of bytes in the range to unlock.
Remarks
See the description of the LockRange member function for details.
NOTE
This function is not available for the CMemFile -derived class.

Example

CFile cfile;
cfile.Open(_T("LockRange_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
ULONGLONG dwPos = 10;
ULONGLONG dwCount = 100;
cfile.LockRange(dwPos, dwCount);

// do something with the file

cfile.UnlockRange(dwPos, dwCount);

CFile::Write
Writes data from a buffer to the file associated with the CFile object.

virtual void Write(


const void* lpBuf,
UINT nCount);

Parameters
lpBuf
A pointer to the user-supplied buffer that contains the data to be written to the file.
nCount
The number of bytes to be transferred from the buffer. For text-mode files, carriage return-line feed pairs
are counted as single characters.
Remarks
Write throws an exception in response to several conditions, including the disk-full condition.

Example

CFile cfile;
cfile.Open(_T("Write_File.dat"), CFile::modeCreate |
CFile::modeReadWrite);
char pbufWrite[100];
memset(pbufWrite, 'a', sizeof(pbufWrite));
cfile.Write(pbufWrite, 100);
cfile.Flush();

Also see the examples for CFile::CFile and CFile::Open.

See also
MFC Sample DRAWCLI
CObject Class
Hierarchy Chart
CStdioFile Class
CMemFile Class
CFileDialog Class
4/21/2020 • 37 minutes to read • Edit Online

Encapsulates the common dialog box that is used for file open or file save operations.

Syntax
class CFileDialog : public CCommonDialog

Members
Public Constructors
NAME DESC RIP T IO N

CFileDialog::CFileDialog Constructs a CFileDialog object.

Public Methods
NAME DESC RIP T IO N

CFileDialog::AddCheckButton Adds a check button to the dialog.

CFileDialog::AddComboBox Adds a combo box to the dialog.

CFileDialog::AddControlItem Adds an item to a container control in the dialog.

CFileDialog::AddEditBox Adds an edit box to the dialog.

CFileDialog::AddMenu Adds a menu to the dialog.

CFileDialog::AddPlace Overloaded. Adds a folder to the list of places available for


the user to open or save items.

CFileDialog::AddPushButton Adds a button to the dialog.

CFileDialog::AddRadioButtonList Adds an option button (also known as radio button) group


to the dialog.

CFileDialog::AddSeparator Adds a separator to the dialog.

CFileDialog::AddText Adds text content to the dialog.

CFileDialog::ApplyOFNToShellDialog Updates the state of the CFileDialog to match the


parameters and flags stored in the m_ofn member
variable.

CFileDialog::DoModal Displays the dialog box and enables the user to make a
selection.
NAME DESC RIP T IO N

CFileDialog::EnableOpenDropDown Enables a drop-down list on the Open or Save button in


the dialog.

CFileDialog::EndVisualGroup Stops the addition of elements to a visual group in the


dialog.

CFileDialog::GetCheckButtonState Gets the current state of a check button (check box) in the
dialog.

CFileDialog::GetControlItemState Gets the current state of an item in a container control


found in the dialog.

CFileDialog::GetControlState Gets the current visibility and enabled states of a given


control.

CFileDialog::GetEditBoxText Gets the current text in an edit box control.

CFileDialog::GetFileExt Returns the extension of the selected file.

CFileDialog::GetFileName Returns the file name of the selected file.

CFileDialog::GetFileTitle Returns the title of the selected file.

CFileDialog::GetFolderPath Retrieves the path of the currently open folder or directory


for an Explorer-style Open or Save As common dialog box.

CFileDialog::GetIFileDialogCustomize Retrieves the internal COM object for a customized


CFileDialog object.

CFileDialog::GetIFileOpenDialog Retrieves the internal COM object for a CFileDialog that


is used as an Open file dialog box.

CFileDialog::GetIFileSaveDialog Retrieves the internal COM object for a CFileDialog that


is used as a Save file dialog box.

CFileDialog::GetNextPathName Returns the full path of the next selected file.

CFileDialog::GetOFN Retrieves the OPENFILENAME structure of the


CFileDialog object.

CFileDialog::GetPathName Returns the full path of the selected file.

CFileDialog::GetReadOnlyPref Returns the read-only status of the selected file.

CFileDialog::GetResult Gets the choice that the user made in the dialog.

CFileDialog::GetResults Gets the user's choices in a dialog that allows multiple


selection.

CFileDialog::GetSelectedControlItem Gets a particular item from specified container controls in


the dialog.
NAME DESC RIP T IO N

CFileDialog::GetStartPosition Returns the position of the first element of the file name list.

CFileDialog::HideControl Hides the specified control in an Explorer-style Open or


Save As common dialog box.

CFileDialog::IsPickFoldersMode Determines if the current dialog in folder picker mode.

CFileDialog::MakeProminent Places a control in the dialog so that it stands out


compared to other added controls.

CFileDialog::RemoveControlItem Removes an item from a container control in the dialog.

CFileDialog::SetCheckButtonState Sets the current state of a check button (check box) in the
dialog.

CFileDialog::SetControlItemState Sets the current state of an item in a container control


found in the dialog.

CFileDialog::SetControlItemText Sets the text of a control item. For example, the text that
accompanies a radio button or an item in a menu.

CFileDialog::SetControlLabel Sets the text associated with a control, such as button text
or an edit box label.

CFileDialog::SetControlState Sets the current visibility and enabled states of a given


control.

CFileDialog::SetControlText Sets the text for the specified control in an Explorer-style


Open or Save As common dialog box.

CFileDialog::SetDefExt Sets the default file name extension for an Explorer-style


Open or Save As common dialog box.

CFileDialog::SetEditBoxText Sets the current text in an edit box control.

CFileDialog::SetProperties Provides a property store that defines the default values to


be used for the item being saved.

CFileDialog::SetSelectedControlItem Sets the selected state of a particular item in an option


button group or a combo box found in the dialog.

CFileDialog::SetTemplate Sets the dialog box template for the CFileDialog object.

CFileDialog::StartVisualGroup Declares a visual group in the dialog. Subsequent calls to


any "add" method add those elements to this group.

CFileDialog::UpdateOFNFromShellDialog Updates the data stored in the m_ofn member variable to


match the current state of the file dialog box.

Protected Methods
NAME DESC RIP T IO N

CFileDialog::OnButtonClicked Called when the button is clicked.

CFileDialog::OnCheckButtonToggled Called when the check box is checked/unchecked.

CFileDialog::OnControlActivating Called when the control is being active.

CFileDialog::OnFileNameChange Handles the WM_NOTIFY CDN_SELCHANGE message.

CFileDialog::OnFileNameOK Validates the file name entered in the dialog box.

CFileDialog::OnFolderChange Handles the WM_NOTIFY CDN_FOLDERCHANGE message.

CFileDialog::OnInitDone Handles the WM_NOTIFY CDN_INITDONE message.

CFileDialog::OnItemSelected Called when the container item is being selected.

CFileDialog::OnLBSelChangedNotify Allows you to perform custom actions when the file


selection changes.

CFileDialog::OnShareViolation Handles share violations.

CFileDialog::OnTypeChange Handles the WM_NOTIFY CDN_TYPECHANGE message.

Public Data Members


NAME DESC RIP T IO N

CFileDialog::m_ofn The Windows OPENFILENAME structure. Provides access to


basic file dialog box parameters.

Remarks
Common file dialog boxes let you implement file-selection dialog boxes, for example, Open File and Save As ,
in a manner that is consistent with Windows standards.
You can use CFileDialogas is with the constructor provided, or you can derive your own dialog box class from
CFileDialog and write a constructor to suit your needs. In either case, these dialog boxes will behave like
standard MFC dialog boxes because they are derived from the CCommonDialog Class. CFileDialog relies on
the COMMDLG.DLL file that is included in Windows.
Both the appearance and the functionality of the CFileDialog with Windows Vista or later differ from the
earlier versions of Windows. The default CFileDialog automatically uses the new Windows Vista or later style
without code changes if a program is compiled and run under Windows Vista or later. Use the bVistaStyle
parameter in the constructor to manually override this automatic update. The exception to the automatic
update is customized dialog boxes. They will not be converted to the new style. For more information about
the constructor, see CFileDialog::CFileDialog.
NOTE
The control ID system differs in Windows Vista or later from earlier versions of Windows when you use a CFileDialog .
You must update all references to CFileDialog controls in code before you can port your project from an earlier
version of Windows.

Some CFileDialog methods are not supported under Windows Vista or later. Check the individual method
topic for information about whether the method is supported. In addition, the following inherited functions are
not supported under Windows Vista or later:
CDialog::OnInitDialog
CDialog::OnSetFont
The windows messages for the CFileDialog class vary based on what operating system you are using. For
example, Windows XP does not support CDialog::OnCancel and CDialog::OnOK for the CFileDialog class.
However, Windows Vista and later operating systems do support them. For more information about the
different messages that are generated and the order in which they are received, see CFileDialog Sample:
Logging Event Order.
To use a CFileDialog object, first create the object by using the CFileDialog constructor. After the dialog box
has been constructed, you can set or modify any values in the CFileDialog::m_ofn structure to initialize the
values or states of the dialog box controls. The m_ofn structure is of type OPENFILENAME . For more information,
see the OPENFILENAME structure in the Windows SDK.
After you initialize the dialog box controls, call the CFileDialog::DoModal method to display the dialog box so
that the user can type the path and file name. DoModal returns whether the user clicked the OK (IDOK) or the
Cancel (IDCANCEL) button. If DoModal returns IDOK, you can use one of the CFileDialog public member
functions to retrieve the information put in by the user.

NOTE
Under Windows Vista or later, multiple calls to IFileDialog::SetFileTypes causes an error. The second call to
SetFileTypes for any instance of a CFileDialog will return E_UNEXPECTED in Windows Vista or later. Some
CFileDialog method functions call SetFileTypes . For example, two calls to CFileDialog::DoModal for the same
instance of a CFileDialog generates ASSERT.

CFileDialog includes several protected members that let you do custom handling of share violations, file
name validation, and list-box change notification. These protected members are callback functions that most
applications do not have to use because default handling is performed automatically. Message-map entries for
these functions are not required because they are standard virtual functions.
You can use the Windows CommDlgExtendedError function to determine whether an error occurred during
initialization of the dialog box and to learn more about the error.
The destruction of CFileDialog objects is handled automatically. You do not have to call CDialog::EndDialog.
To let the user select multiple files, set the OFN_ALLOWMULTISELECT flag before you call DoModal . You must
supply your own file name buffer to accommodate the returned list of multiple file names. Do this by replacing
m_ofn.lpstrFile with a pointer to a buffer you have allocated, after you construct the CFileDialog , but before
you call DoModal .
Additionally, you must set m_ofn.nMaxFile by using the number of characters in the buffer pointed to by
m_ofn.lpstrFile . If you set the maximum number of files to be selected to n , the required buffer size is
n * (_MAX_PATH + 1) + 1 . The first item returned in the buffer is the path to the folder where the files were
selected. For Windows Vista or later-style dialog boxes, the directory and file name strings are null-terminated,
with an extra null character after the last file name. This format enables the Explorer-style dialog boxes to
return long file names that include spaces. For old-style dialog boxes, the directory and file name strings are
separated by spaces and the function uses short file names for file names with spaces.
The following example demonstrates how to use a buffer to retrieve and list multiple file names.

#define MAX_CFileDialog_FILE_COUNT 99
#define FILE_LIST_BUFFER_SIZE ((MAX_CFileDialog_FILE_COUNT * (MAX_PATH + 1)) + 1)

CString fileName;
wchar_t* p = fileName.GetBuffer( FILE_LIST_BUFFER_SIZE );
CFileDialog dlgFile(TRUE);
OPENFILENAME& ofn = dlgFile.GetOFN( );
ofn.Flags |= OFN_ALLOWMULTISELECT;
ofn.lpstrFile = p;
ofn.nMaxFile = FILE_LIST_BUFFER_SIZE;

dlgFile.DoModal();
fileName.ReleaseBuffer();

wchar_t* pBufEnd = p + FILE_LIST_BUFFER_SIZE - 2;


wchar_t* start = p;
while( ( p < pBufEnd ) && ( *p ) )
p++;
if( p > start )
{
_tprintf(_T("Path to folder where files were selected: %s\r\n\r\n"), start );
p++;

int fileCount = 1;
while( ( p < pBufEnd ) && ( *p ) )
{
start = p;
while( ( p < pBufEnd ) && ( *p ) )
p++;
if( p > start )
_tprintf(_T("%2d. %s\r\n"), fileCount, start );
p++;
fileCount++;
}
}

To change the buffer size in response to the user selecting multiple file names, you must derive a new class
from CFileDialog and override the CFileDialog::OnFileNameChange method.
If you derive a new class from CFileDialog , you can use a message map to handle any messages. To extend
the default message handling, derive a class from CFileDialog , add a message map to the new class, and
provide member functions for the new messages. You do not have to provide a hook function to customize the
dialog box.
To customize the dialog box, derive a class from CFileDialog , provide a custom dialog box template, and add a
message map to process the notification messages from the extended controls. Pass any unprocessed
messages to the base class. You do not have to customize the hook function.
When you are using the Windows Vista or later style of the CFileDialog , you cannot use message maps and
dialog box templates. Instead, you must use the COM interfaces for similar functionality.
For more information about how to use CFileDialog , see Common Dialog Classes.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog
CFileDialog

Requirements
Header : afxdlgs.h

CFileDialog::AddCheckButton
Adds a check button to the dialog.

HRESULT AddCheckButton(
DWORD dwIDCtl,
const CString& strLabel,
BOOL bChecked);

Parameters
dwIDCtl
The ID of the check button to add.
strLabel
The check button name.
bChecked
A Boolean indicating the current state of the check button. TRUE if checked; FALSE otherwise
Remarks

CFileDialog::AddComboBox
Adds a combo box to the dialog.

HRESULT AddComboBox(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the combo box to add.
Remarks

CFileDialog::AddControlItem
Adds an item to a container control in the dialog.
HRESULT AddControlItem(
DWORD dwIDCtl,
DWORD dwIDItem,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the container control to add the item to.
dwIDItem
The ID of the item.
strLabel
Item's text.
Remarks

CFileDialog::AddEditBox
Adds an edit box to the dialog.

HRESULT AddEditBox(
DWORD dwIDCtl,
const CString& strText);

Parameters
dwIDCtl
The ID of the edit box to add.
strText
The edit box name.
Remarks

CFileDialog::AddMenu
Adds a menu to the dialog.

HRESULT AddMenu(
DWORD dwIDCtl,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the menu to add.
strLabel
The menu name.
Remarks

CFileDialog::AddPlace
Adds a folder to the list of places available for the user to open or save items.
void AddPlace(
LPCWSTR lpszFolder,
FDAP fdap = FDAP_TOP) throw();

void AddPlace(
IShellItem* psi,
FDAP fdap = FDAP_TOP) throw();

Parameters
lpszFolder
A path to the folder to be made available to the user. This can only be a folder.
fdap
Specifies where the folder is placed within the list.
psi
A pointer to an IShellItem that represents the folder to be made available to the user. This can only be a folder.
Remarks

CFileDialog::AddPushButton
Adds a button to the dialog.

HRESULT AddPushButton(
DWORD dwIDCtl,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the button to add.
strLabel
The button name.
Remarks

CFileDialog::AddRadioButtonList
Adds an option button (also known as radio button) group to the dialog.

HRESULT AddRadioButtonList(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the option button group to add.
Remarks

CFileDialog::AddSeparator
Adds a separator to the dialog.

HRESULT AddSeparator(DWORD dwIDCtl);


Parameters
dwIDCtl
The ID of the separator add.
Remarks

CFileDialog::AddText
Adds text to the dialog.

HRESULT AddText(
DWORD dwIDCtl,
const CString& strText);

Parameters
dwIDCtl
The ID of the text to add.
strText
The text name.
Remarks

CFileDialog::ApplyOFNToShellDialog
Updates the current state of the CFileDialog based on the values stored in the m_ofn data structure.

void ApplyOFNToShellDialog();

Remarks
In versions of Windows before Windows Vista, the member OPENFILENAME data structure was continuously
synchronized with the state of the CFileDialog . Any changes to the m_ofn member variable were immediately
reflected in the state of the dialog box. Also, any changes to the state of the dialog box immediately update the
m_ofn member variable.

In Windows Vista or later, the values in the m_ofn member variable and state of the CFileDialog are not
guaranteed to be synchronized. This function forces the state of the CFileDialog to be updated to match the
m_ofn structure. Windows calls this function automatically during CFileDialog::DoModal.

For more information about how to use the CFileDialog class under Windows Vista or later, see CFileDialog
Class.
Example
See the example for CFileDialog::UpdateOFNFromShellDialog.

CFileDialog::CFileDialog
Call this function to construct a standard Windows file dialog box.
explicit CFileDialog(
BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE);

Parameters
bOpenFileDialog
[in] The parameter that specifies what type of dialog box to create. Set it to TRUE to construct a File Open
dialog box. Set it to FALSE to construct a File Save As dialog box.
lpszDefExt
[in] The default file name extension. If the user does not include a known extension (one that has an association
on the user’s computer) in the Filename box, the extension specified by lpszDefExt is automatically appended
to the file name. If this parameter is NULL, no extension is appended.
lpszFileName
[in] The initial file name that appears in the Filename box. If NULL, no initial file name appears.
dwFlags
[in] A combination of one or more flags that you can use to customize the dialog box. For a description of
these flags, see the OPENFILENAME structure in the Windows SDK. If you modify the m_ofn.Flags structure
member, use a bitwise-OR operator in your changes to keep the default behavior intact.
lpszFilter
[in] A series of string pairs that specify filters you can apply to the file. If you specify file filters, only files that
match filter criteria will appear in the Files list. See the Remarks section for more information about how to
work with file filters.
pParentWnd
[in] A pointer to the parent or owner window of the file dialog box.
dwSize
[in] The size of the OPENFILENAME structure. This value depends on the operating system version. MFC used this
parameter to determine the appropriate kind of dialog box to create. The default size of 0 means that the MFC
code will determine the correct dialog box size to use based on the operating system version on which the
program is run.
bVistaStyle
[in] Note This parameter is available in Visual Studio 2008 and later and causes the new-style dialog to be
used only if you are running in Windows Vista or later.
The parameter that specifies the style of the file dialog. Set it to TRUE to use the new Vista style file dialogs.
Otherwise, the old style of dialog boxes will be used. See the Remarks section for more information about
running under Vista.
Remarks
Either a File Open or File Save As dialog box is constructed, depending on the value of bOpenFileDialog.
Specifying a default extension using lpszDefExt may not produce the behavior that you expect, because it is
seldom predictable what extensions have file associations on the user’s computer. If you need more control
over the appending of a default extension, you can derive your own class from CFileDialog , and override the
CFileDialog::OnFileNameOK method to perform your own extension handling.
To enable the user to select multiple files, set the OFN_ALLOWMULTISELECT flag before you call DoModal. You
must supply your own file name buffer to store the returned list of multiple file names. Do this by replacing
m_ofn.lpstrFile with a pointer to a buffer you have allocated, after you construct the CFileDialog, but before
you call DoModal . Additionally, you must set m_ofn.nMaxFile with the number of characters in the buffer
pointed to by m_ofn.lpstrFile . If you set the maximum number of files to be selected to n, the necessary
buffer size is n *(_MAX_PATH + 1) + 1. For example:

#define MAX_CFileDialog_FILE_COUNT 99
#define FILE_LIST_BUFFER_SIZE ((MAX_CFileDialog_FILE_COUNT * (MAX_PATH + 1)) + 1)

CString fileName;
wchar_t* p = fileName.GetBuffer( FILE_LIST_BUFFER_SIZE );
CFileDialog dlgFile(TRUE);
OPENFILENAME& ofn = dlgFile.GetOFN( );
ofn.Flags |= OFN_ALLOWMULTISELECT;
ofn.lpstrFile = p;
ofn.nMaxFile = FILE_LIST_BUFFER_SIZE;

dlgFile.DoModal();
fileName.ReleaseBuffer();

wchar_t* pBufEnd = p + FILE_LIST_BUFFER_SIZE - 2;


wchar_t* start = p;
while( ( p < pBufEnd ) && ( *p ) )
p++;
if( p > start )
{
_tprintf(_T("Path to folder where files were selected: %s\r\n\r\n"), start );
p++;

int fileCount = 1;
while( ( p < pBufEnd ) && ( *p ) )
{
start = p;
while( ( p < pBufEnd ) && ( *p ) )
p++;
if( p > start )
_tprintf(_T("%2d. %s\r\n"), fileCount, start );
p++;
fileCount++;
}
}

To enable the user to resize an Explorer-style dialog box by using either the mouse or keyboard, set the
OFN_ENABLESIZING flag. Setting this flag is necessary only if you provide a hook procedure or custom
template. The flag works only with an Explorer-style dialog box; old-style dialog boxes cannot be resized.
The lpszFilter parameter is used to determine the type of file name a file must have to be displayed in the file
list. The first string in the string pair describes the filter; the second string indicates the file name extension to
use. Multiple extensions may be specified by using a semicolon (the ';' character) as the delimiter. The string
ends with two '|' characters, followed by a NULL character. You can also use a CString object for this parameter.
For example, Microsoft Excel allows users to open files that have extensions .xlc (chart) or .xls (worksheet),
among others. The filter for Excel could be written as:

static TCHAR BASED_CODE szFilter[] = _T("Chart Files (*.xlc)|*.xlc|")


_T("Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|")
_T("*.xlc; *.xls|All Files (*.*)|*.*||");

However, if you plan to use this string to directly update the OPENFILENAME structure, you should delimit your
strings with the null character, '\0', instead of the vertical bars ('|').
The bVistaStyle parameter is applicable only when running under Windows Vista or later. Under earlier
versions of Windows, this parameter is ignored. If bVistaStyle is set to TRUE, when you compile a program with
Visual Studio 2008 or later, the new Vista style File Dialog will be used. Otherwise, the previous MFC style
File Dialog will be used.
Dialog templates are not supported on dialogs based on bVistaStyle
Example
See the example for CFileDialog::DoModal.

CFileDialog::DoModal
Call this function to display the Windows common file dialog box and allow the user to browse files and
directories and enter a filename.

virtual INT_PTR DoModal();

Return Value
IDOK or IDCANCEL. If IDCANCEL is returned, call the Windows CommDlgExtendedError function to determine
whether an error occurred.
IDOK and IDCANCEL are constants that indicate whether the user selected the OK or Cancel button.
Remarks
If you want to initialize the various file dialog-box options by setting members of the m_ofn structure, you
should do this before calling DoModal , but after the dialog object is constructed.
For example, if you want to allow the user to select multiple files, set the OFN_ALLOWMULTISELECT flag before
calling DoModal , as shown in the code example in this topic.
When the user clicks the dialog box's OK or Cancel buttons, or selects the Close option from the dialog box's
control menu, control is returned to your application. You can then call other member functions to retrieve the
settings or information the user inputs into the dialog box.
DoModal is a virtual function overridden from class CDialog .
Example
void CMyClass::OnFileOpen()
{
// szFilters is a text string that includes two file name filters:
// "*.my" for "MyType Files" and "*.*' for "All Files."
TCHAR szFilters[]= _T("MyType Files (*.my)|*.my|All Files (*.*)|*.*||");

// Create an Open dialog; the default file name extension is ".my".


CFileDialog fileDlg(TRUE, _T("my"), _T("*.my"),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

// Display the file dialog. When user clicks OK, fileDlg.DoModal()


// returns IDOK.
if(fileDlg.DoModal() == IDOK)
{
CString pathName = fileDlg.GetPathName();

// Implement opening and reading file in here.

//Change the window's title to the opened file's title.


CString fileName = fileDlg.GetFileTitle();

SetWindowText(fileName);
}
}

CFileDialog::EnableOpenDropDown
Enables a drop-down list on the Open or Save button in the dialog.

HRESULT EnableOpenDropDown(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the drop-down list.
Remarks

CFileDialog::EndVisualGroup
Stops the addition of elements to a visual group in the dialog.

HRESULT EndVisualGroup();

Return Value
Returns S_OK if successful; an error value otherwise.
Remarks

CFileDialog::GetCheckButtonState
Retrieves the current state of a check button (check box) in the dialog.

HRESULT GetCheckButtonState(
DWORD dwIDCtl,
BOOL& bChecked);
Parameters
dwIDCtl
The ID of the check box.
bChecked
The state of the check box. TRUE indicates checked; FALSE indicates unchecked.
Remarks

CFileDialog::GetControlItemState
Retrieves the current state of an item in a container control found in the dialog.

HRESULT GetControlItemState(
DWORD dwIDCtl,
DWORD dwIDItem,
CDCONTROLSTATEF& dwState);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item.
dwState
A reference to a variable that receives one of more values from the CDCONTROLSTATE enumeration that
indicates the current state of the control.
Remarks

CFileDialog::GetControlState
Retrieves the current visibility and enabled states of a given control.

HRESULT GetControlState(
DWORD dwIDCtl,
CDCONTROLSTATEF& dwState);

Parameters
dwIDCtl
The ID of the control.
dwState
A reference to a variable that receives one or more values from the CDCONTROLSTATE enumeration that
indicates the current state of the control.
Remarks

CFileDialog::GetEditBoxText
Retrieves the current text in an edit box control.
HRESULT GetEditBoxText(
DWORD dwIDCtl,
CString& strText);

Parameters
dwIDCtl
The ID of the edit box.
strText
The text value.
Remarks

CFileDialog::GetFileExt
Call this function to retrieve the extension of the filename entered into the dialog box.

CString GetFileExt() const;

Return Value
The extension of the filename.
Remarks
For example, if the name of the file entered is DATA.TXT, GetFileExt returns "TXT".
If m_ofn.Flags has the OFN_ALLOWMULTISELECT flag set, this string contains a sequence of null-terminated
strings, with the first string being the directory path of the file group selected, followed by the names of all files
selected by the user. To retrieve file pathnames, use the GetStartPosition and GetNextPathName member
functions.

CFileDialog::GetFileName
Call this function to retrieve the name of the filename entered in the dialog box.

CString GetFileName() const;

Return Value
The name of the file.
Remarks
The name of the file includes both the prefix and the extension. For example, GetFileName will return
"TEXT.DAT" for the file C:\FILES\TEXT.DAT.
If m_ofn.Flags has the OFN_ALLOWMULTISELECT flag set, you should call GetStartPosition and GetNextPathName
to retrieve a file pathname.

CFileDialog::GetFileTitle
Call this function to retrieve the title of the file entered in the dialog box.

CString GetFileTitle() const;


Return Value
The title of the file.
Remarks
The title of the file includes only its prefix, without the path or the extension. For example, GetFileTitle will
return "TEXT" for the file C:\FILES\TEXT.DAT.
If m_ofn.Flags has the OFN_ALLOWMULTISELECT flag set, this string contains a sequence of null-terminated
strings, with the first string being the directory path of the file group selected, followed by the names of all files
selected by the user. For this reason, use the GetStartPosition and GetNextPathName member functions to
retrieve the next file name in the list.
Example
See the example for CFileDialog::DoModal.

CFileDialog::GetFolderPath
Call this member function to retrieve the path of the currently open folder or directory for an Explorer-style
Open or Save As common dialog box.

CString GetFolderPath() const;

Return Value
A CString object containing the currently open folder or directory.
Remarks
The dialog box must have been created with the OFN_EXPLORER style; otherwise, the method will fail with an
assertion.
You can call this method only while the dialog box is being displayed. After the dialog box has been closed, this
function will no longer work, and the method will fail with an assertion.

CFileDialog::GetIFileDialogCustomize
Retrieves a pointer to the internal COM object for a given CFileDialog.

IFileDialogCustomize* GetIFileDialogCustomize();

Return Value
The pointer to the internal COM object for the CFileDialog . It is your responsibility to release this pointer
appropriately.
Remarks
Use this function only under Windows Vista or later with an object that has bVistaStyle set to TRUE. If you use
this function when bVistaStyle is FALSE, it will return NULL in release mode and throw an assertion in debug
mode.
For more information about the IFileDialogCustomize interface, see IFileDialogCustomize.
Example
This example retrieves the internal COM object. To run this code example, you must compile it under Windows
Vista or later.
// Get the interface pointer
IFileDialogCustomize *customDlgPtr = m_myFileDialogPtr->GetIFileDialogCustomize();

// Make sure that it is not null


if (customDlgPtr != NULL)
{
//
// Perform any interface functionality here
//

// Release the pointer


customDlgPtr->Release();
}

CFileDialog::GetIFileOpenDialog
Retrieves a pointer to the internal COM object for a given CFileDialog .

IFileOpenDialog* GetIFileOpenDialog();

Return Value
The pointer to the internal COM object for the CFileDialog . It is your responsibility to release this pointer
appropriately.
Remarks
Use this function only under Windows Vista or later with an object that has bVistaStyle set to TRUE. This
function returns NULL if the CFileDialog is not an Open dialog box or if bVistaStyle is set to FALSE. In this
final case, the function only returns NULL in release mode - in debug mode it will throw an assertion.
For more information about the IFileOpenDialog interface, see IFileOpenDialog.
Example
This example retrieves the internal COM object. To run this code, you must compile it under Windows Vista or
later.

// Get the interface pointer


IFileOpenDialog * openDlgPtr = m_myFileDialogPtr->GetIFileOpenDialog();

// Make sure that it is not null


if ( openDlgPtr != NULL )
{
//
// Perform any interface functionality here
//

// Release the pointer


openDlgPtr->Release();
}

CFileDialog::GetIFileSaveDialog
Retrieves a pointer to the internal COM object for a given CFileDialog .

IFileSaveDialog* GetIFileSaveDialog();
Return Value
The pointer to the internal COM object for the CFileDialog . It is your responsibility to release this pointer
appropriately.
Remarks
Use this function only under Windows Vista or later with an object that has bVistaStyle set to TRUE. This
function will return NULL if the CFileDialog is not a Save dialog box or if bVistaStyle is set to FALSE. In this
final case, the function only returns NULL in release mode - in debug mode it will throw an assertion.
For more information about the IFileSaveDialog interface, see IFileSaveDialog.
Example
This example retrieves the internal COM object. To run this code example, you must compile it under Windows
Vista or later.

// Get the interface pointer


IFileSaveDialog *saveDlgPtr = m_myFileDialogPtr->GetIFileSaveDialog();

// Make sure that it is not null


if (saveDlgPtr != NULL)
{
//
// Perform any interface functionality here
//

// Release the pointer


saveDlgPtr->Release();
}

CFileDialog::GetNextPathName
Call this function to retrieve the next filename from the group selected in the dialog box.

CString GetNextPathName(POSITION& pos) const;

Parameters
pos
A reference to a POSITION value returned by a previous GetNextPathName or GetStartPosition function call.
NULL if the end of the list has been reached.
Return Value
The full path of the file.
Remarks
The path of the filename includes the file's title plus the entire directory path. For example, GetNextPathName
will return "C:\FILES\TEXT.DAT" for the file C:\FILES\TEXT.DAT. You can use GetNextPathName in a forward
iteration loop if you establish the initial position with a call to GetStartPosition .
If the selection consists of only one file, that file name will be returned.

CFileDialog::GetOFN
Retrieves the associated OPENFILENAME structure.
const OPENFILENAME& GetOFN() const;

OPENFILENAME& GetOFN();

Return Value
An OPENFILENAME structure.
Remarks
Use the second version of this function to initialize the appearance of a File Open or File Save As dialog box
after it is constructed but before it is displayed with the DoModal member function. For example, you can set
the lpstrTitle member of m_ofn to the caption you want the dialog box to have.

CFileDialog::GetPathName
Call this function to retrieve the full path of the file entered in the dialog box.

CString GetPathName() const;

Return Value
The full path of the file.
Remarks
The path of the filename includes the file's title plus the entire directory path. For example, GetPathName will
return "C:\FILES\TEXT.DAT" for the file C:\FILES\TEXT.DAT.
If m_ofn.Flags has the OFN_ALLOWMULTISELECT flag set, this string contains a sequence of null-teminated
strings, with the first string being the directory path of the file group selected, followed by the names of all files
selected by the user. For this reason, use the GetStartPosition and GetNextPathName member functions to
retrieve the next file name in the list.
Example
See the example for CFileDialog::DoModal.

CFileDialog::GetReadOnlyPref
Call this function to determine whether the Read Only check box has been selected in the Windows standard
File Open and File Save As dialog boxes.

BOOL GetReadOnlyPref() const;

Return Value
Non-zero if the Read Only check box in the dialog box is selected; otherwise 0.
Remarks
You can hide the Read Only check box by setting the OFN_HIDEREADONLY style in the CFileDialog
constructor.

NOTE
Windows Vista or later style CFileDialog objects do not support this function. Attempting to use this function on a
Windows Vista or later style CFileDialog will throw CNotSupportedException.
CFileDialog::GetResult
Retrieves the choice that the user made in the dialog.

IShellItem* GetResult() throw();

Return Value
A pointer to an IShellItem that represents the user's choice.
Remarks

CFileDialog::GetResults
Retrieves the user's choices in a dialog that allows multiple selection.

IShellItemArray* GetResults() throw();

Return Value
A pointer to an IShellItemArray through which the items selected in the dialog can be accessed.
Remarks

CFileDialog::GetSelectedControlItem
Retrieves a particular item from the specified container control in the dialog.

HRESULT GetSelectedControlItem(
DWORD dwIDCtl,
DWORD& dwIDItem);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item that the user selected in the control.
Remarks

CFileDialog::GetStartPosition
Call this member function to retrieve the position of the first file pathname in the list, if m_ofn.Flags has the
OFN_ALLOWMULTISELECT flag set.

POSITION GetStartPosition() const;

Return Value
A POSITION value that can be used for iteration; NULL if the list is empty.

CFileDialog::HideControl
Call this member function to hide the specified control in an Explorer-style Open or Save As common dialog
box.
void HideControl(int nID);

Parameters
nID
The ID of the control to hide.
Remarks
The dialog box must have been created with the OFN_EXPLORER style; otherwise, the function will fail with an
assertion.

CFileDialog::IsPickFoldersMode
Determines if the current dialog is in folder picker mode.

BOOL IsPickFoldersMode() const;

Return Value
TRUE if the dialog is in folder picker mode; otherwise FALSE.
Remarks

CFileDialog::m_ofn
m_ofn is a structure of type OPENFILENAME . The data in this structure represents the current state of the
CFileDialog .

Remarks
Use this structure to initialize the appearance of a File Open or File Save As dialog box after you construct it
but before you display it with the DoModal method. For example, you can set the lpstrTitle member of m_ofn
to the caption you want the dialog box to have.
With the Windows Vista or later style of CFileDialog, m_ofn is not guaranteed to always match the state of the
dialog box. It is synchronized with the dialog box in earlier versions of Windows. See
CFileDialog::ApplyOFNToShellDialog and CFileDialog::UpdateOFNFromShellDialog for more information about
synchronizing the m_ofn structure and the CFileDialog state under Windows Vista or later.
Windows Vista or later style file dialogs do not support certain members and flags of the CFileDialog . As a
result, these will have no effect.
The following is a list of the members that are not supported by Windows Vista or later:
lpstrCustomFilter

lpstrInitialDir

lCustData

lpfnHook

lpTemplateName

The following flags are not supported and therefore have no effect when you use the Windows Vista or later
style of CFileDialog :
OFN_ENABLEHOOK
OFN_ENABLEINCLUDENOTIFY
OFN_ENABLETEMPLATE
OFN_ENABLETEMPLATEHANDLE
OFN_EXPLORER
OFN_EXTENSIONDIFFERENT
OFN_HIDEREADONLY
OFN_LONGNAMES - effectively always on in Windows Vista or later
OFN_NOLONGNAMES - effectively always off in Windows Vista or later
OFN_NONETWORKBUTTON - effectively always on in Windows Vista or later
OFN_READONLY
OFN_SHOWHELP
For more information about this structure, see the OPENFILENAME structure in the Windows SDK.

CFileDialog::MakeProminent
Places a control in the dialog so that it stands out compared to other controls.

HRESULT MakeProminent(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the control.
Remarks

CFileDialog::OnButtonClicked
Called when the button is clicked.

virtual void OnButtonClicked(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the button.
Remarks

CFileDialog::OnCheckButtonToggled
Called when the check box is checked or unchecked.

virtual void OnCheckButtonToggled(


DWORD dwIDCtl,
BOOL bChecked);

Parameters
dwIDCtl
The ID of the check box.
bChecked
Checked or unchecked.
Remarks

CFileDialog::OnControlActivating
Called when the control is activated.

virtual void OnControlActivating(DWORD dwIDCtl);

Parameters
dwIDCtl
The ID of the control.
Remarks

CFileDialog::OnFileNameChange
Override this method if you want to handle the WM_NOTIFY CDN_SELCHANGE message.

virtual void OnFileNameChange();

Remarks
The system sends the CDN_SELCHANGE message when the user selects a new file or folder in the file list of the
Open or Save As dialog box. Override this method if you want to perform any actions in response to this
message.
The system sends this message only if the dialog box was created with the OFN_EXPLORER flag turned on. For
more information about the notification, see CDN_SELCHANGE. For information about the OFN_EXPLORER
flag, see the OPENFILENAME structure and Open and Save As Dialog Boxes.

CFileDialog::OnFileNameOK
Override this function only if you want to provide custom validation of filenames that are entered into a
common file dialog box.

virtual BOOL OnFileNameOK();

Return Value
1 if the filename is not a valid filename; otherwise 0.
Remarks
This function allows you to reject a filename for any application-specific reason. Normally, you do not need to
use this function because the framework provides default validation of filenames and displays a message box
if an invalid filename is entered.
If 1 is returned, the dialog box will remain displayed for the user to enter another filename. The dialog
procedure dismisses the dialog if the return is 0. Other nonzero return values are currently reserved and
should not be used.
CFileDialog::OnFolderChange
Override this function to handle the WM_NOTIFYCDN_FOLDERCHANGE message.

virtual void OnFolderChange();

Remarks
The notification message is sent when a new folder is opened in the Open or Save As dialog box.
Notification is sent only if the dialog box was created with the OFN_EXPLORER style. For more information
about the notification, see CDN_FOLDERCHANGE. For information about the OFN_EXPLORER style, see the
OPENFILENAME structure and Open and Save As Dialog Boxes.

CFileDialog::OnInitDone
Override this function to handle the WM_NOTIFY CDN_INITDONE message.

virtual void OnInitDone();

Remarks
The system sends this notification message when the system has finished arranging controls in the Open or
Save As dialog box to make room for the controls of the child dialog box.
The system sends this only if the dialog box was created with the OFN_EXPLORER style. For more information
about the notification, see CDN_INITDONE. For information about the OFN_EXPLORER style, see the
OPENFILENAME structure and Open and Save As Dialog Boxes.

NOTE
Windows Vista or later style file dialogs do not support this function. Attempting to use this function on a Windows
Vista or later style file dialog will throw CNotSupportedException.

CFileDialog::OnItemSelected
Called when the container item is selected.

virtual void OnItemSelected(


DWORD dwIDCtl,
DWORD dwIDItem);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item.
Remarks

CFileDialog::OnLBSelChangedNotify
This function is called whenever the current selection in a list box is about to change.
virtual void OnLBSelChangedNotify(
UINT nIDBox,
UINT iCurSel,
UINT nCode);

Parameters
nIDBox
The ID of the list box or combo box in which the selection occurred.
iCurSel
The index of the current selection.
nCode
The control notification code. This parameter must have one of the following values:
CD_LBSELCHANGE Specifies iCurSel is the selected item in a single-selection list box.
CD_LBSELSUB Specifies that iCurSel is no longer selected in a multiselection list box.
CD_LBSELADD Specifies that iCurSel is selected in a multiselection list box.
CD_LBSELNOITEMS Specifies that no selection exists in a multiselection list box.
Remarks
Override this function to provide custom handling of selection changes in the list box. For example, you can
use this function to display the access rights or date-last-modified of each file the user selects.

CFileDialog::OnShareViolation
Override this function to provide custom handling of share violations.

virtual UINT OnShareViolation(LPCTSTR lpszPathName);

Parameters
lpszPathName
The path of the file on which the share violation occurred.
Return Value
One of the following values:
OFN_SHAREFALLTHROUGH The filename is returned from the dialog box.
OFN_SHARENOWARN No further action needs to be taken.
OFN_SHAREWARN The user receives the standard warning message for this error.
Remarks
Normally, you do not need to use this function because the framework provides default checking of share
violations and displays a message box if a share violation occurs.
If you want to disable share violation checking, use the bitwise OR operator to combine the flag
OFN_SHAREAWARE with m_ofn.Flags .

CFileDialog::OnTypeChange
Override this function to handle the WM_NOTIFYCDN_TYPECHANGE message.
virtual void OnTypeChange();

Remarks
The notification message is sent when the user selects a new file type from the list of file types in the Open or
Save As dialog box.
Notification is sent only if the dialog box was created with the OFN_EXPLORER style. For more information
about the notification, see CDN_TYPECHANGE. For information about the OFN_EXPLORER style, see the
OPENFILENAME structure and Open and Save As Dialog Boxes.

CFileDialog::RemoveControlItem
Removes an item from a container control in the dialog.

HRESULT RemoveControlItem(
DWORD dwIDCtl,
DWORD dwIDItem);

Parameters
dwIDCtl
The ID of the container control to remove the item from.
dwIDItem
The ID of the item.
Remarks

CFileDialog::SetCheckButtonState
Sets the current state of a check button (check box) in the dialog.

HRESULT SetCheckButtonState(
DWORD dwIDCtl,
BOOL bChecked);

Parameters
dwIDCtl
The ID of the check box.
bChecked
The state of the check box. TRUE indicates checked; FALSE indicates Unchecked.
Remarks

CFileDialog::SetControlItemState
Sets the current state of an item in a container control found in the dialog.

HRESULT SetControlItemState(
DWORD dwIDCtl,
DWORD dwIDItem,
CDCONTROLSTATEF dwState);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item.
dwState
One or more values from the CDCONTROLSTATE enumeration that indicate the new state of the control.
Remarks

CFileDialog::SetControlItemText
Sets the text of a control item. For example, the text that accompanies a radio button or an item in a menu.

HRESULT SetControlItemText(
DWORD dwIDCtl,
DWORD dwIDItem,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item.
strLabel
Item's text.
Remarks

CFileDialog::SetControlLabel
Sets the text associated with a control, such as button text or an edit box label.

HRESULT SetControlLabel(
DWORD dwIDCtl,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the control.
strLabel
The control name.
Remarks

CFileDialog::SetControlState
Sets the current visibility and enabled states of a given control.

HRESULT SetControlState(
DWORD dwIDCtl,
CDCONTROLSTATEF dwState);
Parameters
dwIDCtl
The ID of the control.
dwState
One or more values from the CDCONTROLSTATE enumeration that indicate the current state of the control.
Remarks

CFileDialog::SetControlText
Call this method to set the text for the specified control in an Explorer-style Open or Save As dialog box.

void SetControlText(
int nID,
LPCSTR lpsz);

void SetControlText(
int nID,
const wchar_t *lpsz);

Parameters
nID
[in] The ID of the control for which to set the text.
lpsz
[in] A pointer to the string that contains the text to set for the control.
Remarks
Both versions of this function are valid for applications that use Unicode. However, only the version with the
LPCSTR type is valid for applications that use ANSI.
To use this method, you must create the dialog box with the OFN_EXPLORER style. Otherwise, the function will
fail with an assertion.

CFileDialog::SetDefExt
Call this function to set the default file name extension for an Explorer-style Open or Save As common dialog
box.

void SetDefExt(LPCSTR lpsz);

Parameters
lpsz
A pointer to a string containing the default extension to use for the dialog box object. This string must not
contain a period (.).
Remarks
The dialog box must have been created with the OFN_EXPLORER style; otherwise, the function will fail with an
assertion.

CFileDialog::SetEditBoxText
Sets the current text in an edit box control.
HRESULT SetEditBoxText(
DWORD dwIDCtl,
const CString& strText);

Parameters
dwIDCtl
The ID of the edit box.
strText
The text value.
Remarks

CFileDialog::SetProperties
Provides a property store that defines the default values to be used for the item being saved.

BOOL SetProperties(LPCWSTR lpszPropList);

Parameters
lpszPropList
A list of predefined properties separated by ";". For a list of the flags, see the Flags section of OPENFILENAME.
Remarks

CFileDialog::SetSelectedControlItem
Sets the selected state of a particular item in an option button group or a combo box found in the dialog.

HRESULT SetSelectedControlItem(
DWORD dwIDCtl,
DWORD dwIDItem);

Parameters
dwIDCtl
The ID of the container control.
dwIDItem
The ID of the item that the user selected in the control.
Remarks

CFileDialog::SetTemplate
Sets the dialog box template for the CFileDialog object.

void SetTemplate(
UINT nWin3ID,
UINT nWin4ID);

void SetTemplate(
LPCTSTR lpWin3ID,
LPCTSTR lpWin4ID);

Parameters
nWin3ID
[in] Contains the ID number of the template resource for the non-Explorer CFileDialog object. This template is
only used on Windows NT 3.51 or when the OFN_EXPLORER style is not present.
nWin4ID
[in] Contains the ID number of the template resource for the Explorer CFileDialog object. This template is
used only on Windows NT 4.0 and later versions, Windows 95 and later versions, or when the OFN_EXPLORER
style is present.
lpWin3ID
[in] Contains the name of the template resource for the non-Explorer CFileDialog object. This template is only
used on Windows NT 3.51 or when the OFN_EXPLORER style is not present.
lpWin4ID
[in] Contains the name of the template resource of the Explorer CFileDialog object. This template is used only
on Windows NT 4.0 and later versions, Windows 95 and later versions, or when the OFN_EXPLORER style is
present.
Remarks
The system will use only one of the specified templates. The system determines which template to use based
on the presence of the OFN_EXPLORER style and the operating system that the application is running on. By
specifying both a non-Explorer and Explorer-style template, it is easy to support Windows NT 3.51, Windows
NT 4.0 and later versions, and Windows 95 and later versions.

NOTE
Windows Vista or later style file dialog boxes do not support this function. Attempting to use this function on a
Windows Vista or later style file dialog box will throw CNotSupportedException. An alternative is to use a customized
dialog. For more information about using a custom CFileDialog , see IFileDialogCustomize.

CFileDialog::StartVisualGroup
Declares a visual group in the dialog. Subsequent calls to any "add" method add those elements to this group.

HRESULT StartVisualGroup(
DWORD dwIDCtl,
const CString& strLabel);

Parameters
dwIDCtl
The ID of the visual group.
strLabel
The group name.
Remarks

CFileDialog::UpdateOFNFromShellDialog
Updates the m_ofn data structure of the CFileDialog based on the current state of the internal object.

void UpdateOFNFromShellDialog();

Remarks
In versions of Windows before Windows Vista, the member OPENFILENAME data structure was continuously
synchronized with the state of the CFileDialog . Any changes to the m_ofn member variable directly affected
the state of the dialog box. Also, any changes to the state of the dialog immediately updated the m_ofn
member variable.
In Windows Vista or later, the m_ofn data structure is not automatically updated. To guarantee the accuracy of
the data in the m_ofn member variable, you should call the UpdateOFNFromShellDialog function before
accessing the data. Windows calls this function automatically during the processing of IFileDialog::OnFileOK.
For more information about how to use the CFileDialog class under Windows Vista or later, see CFileDialog
Class.
Example
This example updates the CFileDialog before displaying it. Before updating the m_ofn member variable, we
need to synchronize it to the current state of the dialog box.

// Update the m_ofn variable


m_myFileDialogPtr->UpdateOFNFromShellDialog();

// Change the title


m_myFileDialogPtr->m_ofn.lpstrTitle = L"New Dialog Title";

// Apply the changes


m_myFileDialogPtr->ApplyOFNToShellDialog();

// Show the window


LRESULT result = m_myFileDialogPtr->DoModal();

See also
CCommonDialog Class
Hierarchy Chart
CFileException Class
3/27/2020 • 5 minutes to read • Edit Online

Represents a file-related exception condition.

Syntax
class CFileException : public CException

Members
Public Constructors
NAME DESC RIP T IO N

CFileException::CFileException Constructs a CFileException object.

Public Methods
NAME DESC RIP T IO N

CFileException::ErrnoToException Returns cause code corresponding to a run-time error


number.

CFileException::GetErrorMessage Retrieves the message describing an exception.

CFileException::OsErrorToException Returns a cause code corresponding to an operating system


error code.

CFileException::ThrowErrno Throws a file exception based on a runtime error number.

CFileException::ThrowOsError Throws a file exception based on an operating system error


number.

Public Data Members


NAME DESC RIP T IO N

CFileException::m_cause Contains portable code corresponding to the exception


cause.

CFileException::m_lOsError Contains the related operating-system error number.

CFileException::m_strFileName Contains the name of the file for this exception.

Remarks
The CFileException class includes public data members that hold the portable cause code and the operating-
system-specific error number. The class also provides static member functions for throwing file exceptions and
for returning cause codes for both operating-system errors and C run-time errors.
CFileException objects are constructed and thrown in CFile member functions and in member functions of
derived classes. You can access these objects within the scope of a CATCH expression. For portability, use only
the cause code to get the reason for an exception. For more information about exceptions, see the article
Exception Handling (MFC).

Inheritance Hierarchy
CObject
CException
CFileException

Requirements
Header : afx.h

CFileException::CFileException
Constructs a CFileException object that stores the cause code and the operating-system code in the object.

CFileException(
int cause = CFileException::none,
LONG lOsError = -1,
LPCTSTR lpszArchiveName = NULL);

Parameters
cause
An enumerated type variable that indicates the reason for the exception. See CFileException::m_cause for a list of
the possible values.
lOsError
An operating-system-specific reason for the exception, if available. The lOsError parameter provides more
information than cause does.
lpszArchiveName
Points to a string containing the name of the CFile object causing the exception.
Remarks
Do not use this constructor directly, but rather call the global function AfxThrowFileException.

NOTE
The variable lOsError applies only to CFile and CStdioFile objects. The CMemFile class does not handle this error
code.

CFileException::ErrnoToException
Converts a given run-time library error value to a CFileException enumerated error value.

static int PASCAL ErrnoToException(int nErrno);


Parameters
nErrno
An integer error code as defined in the run-time include file ERRNO.H.
Return Value
Enumerated value that corresponds to a given run-time library error value.
Remarks
See CFileException::m_cause for a list of the possible enumerated values.
Example

ASSERT(CFileException::ErrnoToException(EACCES) ==
CFileException::accessDenied);

CFileException::GetErrorMessage
Retrieves text that describes an exception.

virtual BOOL GetErrorMessage(


LPTSTR lpszError,
UINT nMaxError,
PUINT pnHelpContext = NULL) const;

Parameters
lpszError
[in, out] Pointer to a buffer that receives an error message.
nMaxError
[in] The maximum number of characters the specified buffer can hold. This includes the terminating null
character.
pnHelpContext
[in, out] Pointer to an unsigned integer that receives the help context ID. If NULL , no ID is returned.
Return Value
TRUE if the method was successful; otherwise FALSE.
Remarks
If the specified buffer is too small, the error message is truncated.
Example
The following example uses CFileException::GetErrorMessage .
CFile fileInput;
CFileException ex;

// try to open a file for reading.


// The file will certainly not
// exist because there are too many explicit
// directories in the name.

// if the call to Open() fails, ex will be


// initialized with exception
// information. the call to ex.GetErrorMessage()
// will retrieve an appropriate message describing
// the error, and we'll add our own text
// to make sure the user is perfectly sure what
// went wrong.

if (!fileInput.Open(_T("\\Too\\Many\\Bad\\Dirs.DAT"), CFile::modeRead, &ex))


{
TCHAR szCause[255];
CString strFormatted;

ex.GetErrorMessage(szCause, 255);

// (in real life, it's probably more


// appropriate to read this from
// a string resource so it would be easy to
// localize)

strFormatted = _T("The data file could not be opened because of this error: ");
strFormatted += szCause;

AfxMessageBox(strFormatted);
}
else
{
// the file was opened, so do whatever work
// with fileInput
// we were planning...

fileInput.Close();
}

CFileException::m_cause
Contains values defined by a CFileException enumerated type.

int m_cause;

Remarks
This data member is a public variable of type int . The enumerators and their meanings are as follows:
CFileException::none 0: No error occurred.
CFileException::genericException 1: An unspecified error occurred.
CFileException::fileNotFound 2: The file could not be located.
CFileException::badPath 3: All or part of the path is invalid.
CFileException::tooManyOpenFiles 4: The permitted number of open files was exceeded.
CFileException::accessDenied 5: The file could not be accessed.
CFileException::invalidFile 6: There was an attempt to use an invalid file handle.
CFileException::removeCurrentDir 7: The current working directory cannot be removed.
CFileException::directoryFull 8: There are no more directory entries.
CFileException::badSeek 9: There was an error trying to set the file pointer.
CFileException::hardIO 10: There was a hardware error.
CFileException::sharingViolation 11: SHARE.EXE was not loaded, or a shared region was locked.
CFileException::lockViolation 12: There was an attempt to lock a region that was already locked.
CFileException::diskFull 14: The disk is full.
CFileException::endOfFile 15: The end of file was reached.

NOTE
These CFileException cause enumerators are distinct from the CArchiveException cause enumerators.

NOTE
CArchiveException::generic is deprecated. Use genericException instead. If generic is used in an
application and built with /clr, the resulting syntax errors are not easy to decipher.

Example

try
{
CFile f(_T("M_Cause_File.dat"), CFile::modeWrite);
}
catch(CFileException* e)
{
if( e->m_cause == CFileException::fileNotFound)
TRACE(_T("ERROR: File not found\n"));
e->Delete();
}

CFileException::m_lOsError
Contains the operating-system error code for this exception.

LONG m_lOsError;

Remarks
See your operating-system technical manual for a listing of error codes. This data member is a public variable of
type LONG.

CFileException::m_strFileName
Contains the name of the file for this exception condition.

CString m_strFileName;
CFileException::OsErrorToException
Returns an enumerator that corresponds to a given lOsError value. If the error code is unknown, then the
function returns CFileException::generic .

static int PASCAL OsErrorToException(LONG lOsError);

Parameters
lOsError
An operating-system-specific error code.
Return Value
Enumerated value that corresponds to a given operating-system error value.
Example

ASSERT(CFileException::OsErrorToException(ERROR_ACCESS_DENIED) ==
CFileException::accessDenied);

CFileException::ThrowErrno
Constructs a CFileException object corresponding to a given nErrno value, then throws the exception.

static void PASCAL ThrowErrno(int nErrno, LPCTSTR lpszFileName = NULL);

Parameters
nErrno
An integer error code as defined in the run-time include file ERRNO.H.
lpszFileName
A pointer to the string containing the name of the file that caused the exception, if available.
Example

CFileException::ThrowErrno(EACCES); // "access denied"

CFileException::ThrowOsError
Throws a CFileException corresponding to a given lOsError value. If the error code is unknown, then the
function throws an exception coded as CFileException::generic .

static void PASCAL ThrowOsError(LONG lOsError, LPCTSTR lpszFileName = NULL);

Parameters
lOsError
An operating-system-specific error code.
lpszFileName
A pointer to the string containing the name of the file that caused the exception, if available.
Example
CFileException::ThrowOsError(ERROR_ACCESS_DENIED); // "access denied"

See also
CException Class
Hierarchy Chart
Exception Processing
CFileFind Class
4/21/2020 • 17 minutes to read • Edit Online

Performs local file searches and is the base class for CGopherFileFind and CFtpFileFind, which perform Internet
file searches.

Syntax
class CFileFind : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CFileFind::CFileFind Constructs a CFileFind object.

Public Methods
NAME DESC RIP T IO N

CFileFind::Close Closes the search request.

CFileFind::FindFile Searches a directory for a specified file name.

CFileFind::FindNextFile Continues a file search from a previous call to FindFile.

CFileFind::GetCreationTime Gets the time the file was created.

CFileFind::GetFileName Gets the name, including the extension, of the found file

CFileFind::GetFilePath Gets the whole path of the found file.

CFileFind::GetFileTitle Gets the title of the found file. The title does not include the
extension.

CFileFind::GetFileURL Gets the URL, including the file path, of the found file.

CFileFind::GetLastAccessTime Gets the time that the file was last accessed.

CFileFind::GetLastWriteTime Gets the time the file was last changed and saved.

CFileFind::GetLength Gets the length of the found file, in bytes.

CFileFind::GetRoot Gets the root directory of the found file.

CFileFind::IsArchived Determines if the found file is archived.


NAME DESC RIP T IO N

CFileFind::IsCompressed Determines if the found file is compressed.

CFileFind::IsDirectory Determines if the found file is a directory.

CFileFind::IsDots Determines if the name of the found file has the name "." or
"..", indicating that is actually a directory.

CFileFind::IsHidden Determines if the found file is hidden.

CFileFind::IsNormal Determines if the found file is normal (in other words, has no
other attributes).

CFileFind::IsReadOnly Determines if the found file is read-only.

CFileFind::IsSystem Determines if the found file is a system file.

CFileFind::IsTemporary Determines if the found file is temporary.

CFileFind::MatchesMask Indicates the desired file attributes of the file to be found.

Protected Methods
NAME DESC RIP T IO N

CFileFind::CloseContext Closes the file specified by the current search handle.

Protected Data Members


NAME DESC RIP T IO N

CFileFind::m_pTM Pointer to a CAtlTransactionManager object.

Remarks
CFileFind includes member functions that begin a search, locate a file, and return the title, name, or path of the
file. For Internet searches, the member function GetFileURL returns the file's URL.
CFileFind is the base class for two other MFC classes designed to search particular server types:
CGopherFileFind works specifically with gopher servers, and CFtpFileFind works specifically with FTP servers.
Together, these three classes provide a seamless mechanism for the client to find files, regardless of the server
protocol, the file type, or location, on either a local machine or a remote server.
The following code will enumerate all the files in the current directory, printing the name of each file:

CFileFind finder;
BOOL bWorking = finder.FindFile(_T("*.*"));
while (bWorking)
{
bWorking = finder.FindNextFile();
TRACE(_T("%s\n"), (LPCTSTR)finder.GetFileName());
}
To keep the example simple, this code uses the C++ Standard Library cout class. The cout line could be
replaced with a call to CListBox::AddString , for example, in a program with a graphical user interface.
For more information about how to use CFileFind and the other WinInet classes, see the article Internet
Programming with WinInet.

Inheritance Hierarchy
CObject
CFileFind

Requirements
Header : afx.h

CFileFind::CFileFind
This member function is called when a CFileFind object is constructed.

CFileFind();
CFileFind(CAtlTransactionManager* pTM);

Parameters
pTM
Pointer to CAtlTransactionManager object
Example
See the example for CFileFind::GetFileName.

CFileFind::Close
Call this member function to end the search, reset the context, and release all resources.

void Close();

Remarks
After calling Close , you do not have to create a new CFileFind instance before calling FindFile to begin a new
search.
Example
See the example for CFileFind::GetFileName.

CFileFind::CloseContext
Closes the file specified by the current search handle.

virtual void CloseContext();

Remarks
Closes the file specified by the current value of the search handle. Override this function to change the default
behavior.
You must call the FindFile or FindNextFile functions at least once to retrieve a valid search handle. The FindFile
and FindNextFile functions use the search handle to locate files with names that match a given name.

CFileFind::FindFile
Call this member function to open a file search.

virtual BOOL FindFile(


LPCTSTR pstrName = NULL,
DWORD dwUnused = 0);

Parameters
pstrName
A pointer to a string containing the name of the file to find. If you pass NULL for pstrName, FindFile does a
wildcard (*.*) search.
dwUnused
Reserved to make FindFile polymorphic with derived classes. Must be 0.
Return Value
Nonzero if successful; otherwise 0. To get extended error information, call the Win32 function GetLastError.
Remarks
After calling FindFile to begin the file search, call FindNextFile to retrieve subsequent files. You must call
FindNextFile at least once before calling any of the following attribute member functions:
GetCreationTime
GetFileName
GetFileTitle
GetFilePath
GetFileURL
GetLastAccessTime
GetLastWriteTime
GetLength
GetRoot
IsArchived
IsCompressed
IsDirectory
IsDots
IsHidden
IsNormal
IsReadOnly
IsSystem
IsTemporary
MatchesMask
Example
See the example for CFileFind::IsDirectory.

CFileFind::FindNextFile
Call this member function to continue a file search from a previous call to FindFile.

virtual BOOL FindNextFile();

Return Value
Nonzero if there are more files; zero if the file found is the last one in the directory or if an error occurred. To get
extended error information, call the Win32 function GetLastError. If the file found is the last file in the directory,
or if no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.
Remarks
You must call FindNextFile at least once before calling any of the following attribute member functions:
GetCreationTime
GetFileName
GetFileTitle
GetFilePath
GetFileURL
GetLastAccessTime
GetLastWriteTime
GetLength
GetRoot
IsArchived
IsCompressed
IsDirectory
IsDots
IsHidden
IsNormal
IsReadOnly
IsSystem
IsTemporary
MatchesMask
FindNextFile wraps the Win32 function FindNextFile.
Example
See the example for CFileFind::IsDirectory.

CFileFind::GetCreationTime
Call this member function to get the time the specified file was created.

virtual BOOL GetCreationTime(FILETIME* pTimeStamp) const;


virtual BOOL GetCreationTime(CTime& refTime) const;

Parameters
pTimeStamp
A pointer to a FILETIME structure containing the time the file was created.
refTime
A reference to a CTime object.
Return Value
Nonzero if successful; 0 if unsuccessful. GetCreationTime returns 0 only if FindNextFile has never been called on
this CFileFind object.
Remarks
You must call FindNextFile at least once before calling GetCreationTime .

NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operation
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

Example
See the example for CFileFind::GetLength.

CFileFind::GetFileName
Call this member function to get the name of the found file.

virtual CString GetFileName() const;

Return Value
The name of the most-recently-found file.
Remarks
You must call FindNextFile at least once before calling GetFileName.
GetFileName is one of three CFileFind member functions that return some form of the file name. The following
list describes the three and how they vary:
GetFileNamereturns the file name, including the extension. For example, calling GetFileName to generate
a user message about the file c:\myhtml\myfile.txt returns the file name myfile.txt.
GetFilePath returns the entire path for the file. For example, calling GetFilePath to generate a user
message about the file c:\myhtml\myfile.txt returns the file path c:\myhtml\myfile.txt.
GetFileTitle returns the file name, excluding the file extension. For example, calling GetFileTitle to
generate a user message about the file c:\myhtml\myfile.txt returns the file title myfile.
Example

CFileFind finder;
static const TCHAR szFileToFind[] = _T("C:\\WINDOWS\\SYSTEM.INI");

BOOL bResult = finder.FindFile(szFileToFind);

if (bResult)
{
finder.FindNextFile();

TRACE(_T("Root of %s is %s\n"), szFileToFind,


(LPCTSTR)finder.GetRoot());

TRACE(_T("Title of %s is %s\n"), szFileToFind,


(LPCTSTR)finder.GetFileTitle());

TRACE(_T("Path of %s is %s\n"), szFileToFind,


(LPCTSTR)finder.GetFilePath());

TRACE(_T("URL of %s is %s\n"), szFileToFind,


(LPCTSTR)finder.GetFileURL());

TRACE(_T("Name of %s is %s\n"), szFileToFind,


(LPCTSTR)finder.GetFileName());

finder.Close();
}
else
{
TRACE(_T("You have no %s file.\n"), szFileToFind);
}

CFileFind::GetFilePath
Call this member function to get the full path of the specified file.

virtual CString GetFilePath() const;

Return Value
The path of the specified file.
Remarks
You must call FindNextFile at least once before calling GetFilePath .
GetFilePath is one of three CFileFind member functions that return some form of the file name. The following
list describes the three and how they vary:
GetFileName returns the file name, including the extension. For example, calling GetFileName to generate
a user message about the file c:\myhtml\myfile.txt returns the file name myfile.txt.
returns the entire path for the file. For example, calling GetFilePath to generate a user
GetFilePath
message about the file c:\myhtml\myfile.txt returns the file path c:\myhtml\myfile.txt .
GetFileTitle returns the file name, excluding the file extension. For example, calling GetFileTitle to
generate a user message about the file c:\myhtml\myfile.txt returns the file title myfile.
Example
See the example for CFileFind::GetFileName.

CFileFind::GetFileTitle
Call this member function to get the title of the found file.

virtual CString GetFileTitle() const;

Return Value
The title of the file.
Remarks
You must call FindNextFile at least once before calling GetFileTitle .
GetFileTitle is one of three CFileFind member functions that return some form of the file name. The following
list describes the three and how they vary:
GetFileName returns the file name, including the extension. For example, calling GetFileName to generate
a user message about the file c:\myhtml\myfile.txt returns the file name myfile.txt.
GetFilePath returns the entire path for the file. For example, calling GetFilePath to generate a user
message about the file c:\myhtml\myfile.txt returns the file path c:\myhtml\myfile.txt.
GetFileTitle returns the file name, excluding the file extension. For example, calling GetFileTitle to
generate a user message about the file c:\myhtml\myfile.txt returns the file title myfile.
Example
See the example for CFileFind::GetFileName.

CFileFind::GetFileURL
Call this member function to retrieve the specified URL.

virtual CString GetFileURL() const;

Return Value
The complete URL.
Remarks
You must call FindNextFile at least once before calling GetFileURL .
GetFileURL is similar to the member function GetFilePath, except that it returns the URL in the form file://path
. For example, calling GetFileURL to get the complete URL for myfile.txt returns the URL
file://c:\myhtml\myfile.txt .

Example
See the example for CFileFind::GetFileName.

CFileFind::GetLastAccessTime
Call this member function to get the time that the specified file was last accessed.

virtual BOOL GetLastAccessTime(CTime& refTime) const;


virtual BOOL GetLastAccessTime(FILETIME* pTimeStamp) const;

Parameters
refTime
A reference to a CTime object.
pTimeStamp
A pointer to a FILETIME structure containing the time the file was last accessed.
Return Value
Nonzero if successful; 0 if unsuccessful. GetLastAccessTime returns 0 only if FindNextFile has never been called
on this CFileFind object.
Remarks
You must call FindNextFile at least once before calling GetLastAccessTime .

NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operation
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

Example
See the example for CFileFind::GetLength.

CFileFind::GetLastWriteTime
Call this member function to get the last time the file was changed.

virtual BOOL GetLastWriteTime(FILETIME* pTimeStamp) const;


virtual BOOL GetLastWriteTime(CTime& refTime) const;

Parameters
pTimeStamp
A pointer to a FILETIME structure containing the time the file was last written to.
refTime
A reference to a CTime object.
Return Value
Nonzero if successful; 0 if unsuccessful. GetLastWriteTime returns 0 only if FindNextFile has never been called on
this CFileFind object.
Remarks
You must call FindNextFile at least once before calling GetLastWriteTime .
NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operation
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

Example
See the example for CFileFind::GetLength.

CFileFind::GetLength
Call this member function to get the length of the found file, in bytes.

ULONGLONG GetLength() const;

Return Value
The length of the found file, in bytes.
Remarks
You must call FindNextFile at least once before calling GetLength .
GetLength uses the Win32 structure WIN32_FIND_DATA to get and return the value of the file size, in bytes.

NOTE
As of MFC 7.0, GetLength supports 64-bit integer types. Previously existing code built with this newer version of the
library may result in truncation warnings.

Example
// This code fragment prints out a very verbose directory
// listing for all the files in the root directory on the
// C: drive. After the file's name, each attribute of the
// file is printed, as are the creation, last access, and
// last write times.

CFileFind finder;

BOOL bWorking = finder.FindFile(_T("C:\\*.*"));

while (bWorking)
{
bWorking = finder.FindNextFile();

_tprintf_s(_T("%s\n\t"), (LPCTSTR)finder.GetFileName());
_tprintf_s(_T("%c"), finder.IsArchived() ? 'A' : 'a');
_tprintf_s(_T("%c"), finder.IsCompressed() ? 'C' : 'c');
_tprintf_s(_T("%c"), finder.IsHidden() ? 'H' : 'h');
_tprintf_s(_T("%c"), finder.IsNormal() ? 'N' : 'n');
_tprintf_s(_T("%c"), finder.IsReadOnly() ? 'R' : 'r');
_tprintf_s(_T("%c"), finder.IsSystem() ? 'S' : 's');
_tprintf_s(_T("%c"), finder.IsTemporary() ? 'T' : 't');

_tprintf_s(_T("\t%I64u byte(s)\n"), finder.GetLength());

CTime tempTime;
CString str;

_tprintf_s(_T("\tCreated : "));
if (finder.GetCreationTime(tempTime))
{
str = tempTime.Format(_T("%c"));
_tprintf_s(_T("%s\n"), (LPCTSTR) str);
}
else
{
_tprintf_s(_T("(unavailable)\n"));
}

_tprintf_s(_T("\tLast Access: "));


if (finder.GetLastAccessTime(tempTime))
{
str = tempTime.Format(_T("%c"));
_tprintf_s(_T("%s\n"), (LPCTSTR) str);
}
else
{
_tprintf_s(_T("(unavailable)\n"));
}

_tprintf_s(_T("\tLast Write : "));


if (finder.GetLastWriteTime(tempTime))
{
str = tempTime.Format(_T("%c"));
_tprintf_s(_T("%s\n"), (LPCTSTR) str);
}
else
{
_tprintf_s(_T("(unavailable)\n"));
}

_tprintf_s(_T("\n"));
}

CFileFind::GetRoot
Call this member function to get the root of the found file.

virtual CString GetRoot() const;

Return Value
The root of the active search.
Remarks
You must call FindNextFile at least once before calling GetRoot .
This member function returns the drive specifier and path name used to start a search. For example, calling
FindFile with *.dat results in GetRoot returning an empty string. Passing a path, such as
c:\windows\system\*.dll , to FindFile results GetRoot returning c:\windows\system\ .

Example
See the example for CFileFind::GetFileName.

CFileFind::IsArchived
Call this member function to determine if the found file is archived.

BOOL IsArchived() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
Applications mark an archive file, which is to be backed up or removed, with FILE_ATTRIBUTE_ARCHIVE, a file
attribute identified in the WIN32_FIND_DATA structure.
You must call FindNextFile at least once before calling IsArchived .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsCompressed
Call this member function to determine if the found file is compressed.

BOOL IsCompressed() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
A compressed file is marked with FILE_ATTRIBUTE_COMPRESSED, a file attribute identified in the
WIN32_FIND_DATA structure. For a file, this attribute indicates that all of the data in the file is compressed. For a
directory, this attribute indicates that compression is the default for newly created files and subdirectories.
You must call FindNextFile at least once before calling IsCompressed .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsDirectory
Call this member function to determine if the found file is a directory.

BOOL IsDirectory() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
A file that is a directory is marked with FILE_ATTRIBUTE_DIRECTORY a file attribute identified in the
WIN32_FIND_DATA structure.
You must call FindNextFile at least once before calling IsDirectory .
See the member function MatchesMask for a complete list of file attributes.
Example
This small program recurses every directory on the C:\ drive and prints the name of the directory.
void Recurse(LPCTSTR pstr)
{
CFileFind finder;

// build a string with wildcards


CString strWildcard(pstr);
strWildcard += _T("\\*.*");

// start working for files


BOOL bWorking = finder.FindFile(strWildcard);

while (bWorking)
{
bWorking = finder.FindNextFile();

// skip . and .. files; otherwise, we'd


// recur infinitely!

if (finder.IsDots())
continue;

// if it's a directory, recursively search it

if (finder.IsDirectory())
{
CString str = finder.GetFilePath();
TRACE(_T("%s\n"), (LPCTSTR)str);
Recurse(str);
}
}

finder.Close();
}

void PrintDirs()
{
Recurse(_T("C:"));
}

CFileFind::IsDots
Call this member function to test for the current directory and parent directory markers while iterating through
files.

virtual BOOL IsDots() const;

Return Value
Nonzero if the found file has the name "." or "..", which indicates that the found file is actually a directory.
Otherwise 0.
Remarks
You must call FindNextFile at least once before calling IsDots .
Example
See the example for CFileFind::IsDirectory.

CFileFind::IsHidden
Call this member function to determine if the found file is hidden.
BOOL IsHidden() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
Hidden files, which are marked with FILE_ATTRIBUTE_HIDDEN, a file attribute identified in the WIN32_FIND_DATA
structure. A hidden file is not included in an ordinary directory listing.
You must call FindNextFile at least once before calling IsHidden .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsNormal
Call this member function to determine if the found file is a normal file.

BOOL IsNormal() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
Files marked with FILE_ATTRIBUTE_NORMAL, a file attribute identified in the WIN32_FIND_DATA structure. A
normal file has no other attributes set. All other file attributes override this attribute.
You must call FindNextFile at least once before calling IsNormal .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsReadOnly
Call this member function to determine if the found file is read-only.

BOOL IsReadOnly() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
A read-only file is marked with FILE_ATTRIBUTE_READONLY, a file attribute identified in the WIN32_FIND_DATA
structure. Applications can read such a file, but they cannot write to it or delete it.
You must call FindNextFile at least once before calling IsReadOnly .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsSystem
Call this member function to determine if the found file is a system file.

BOOL IsSystem() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
A system file is marked with FILE_ATTRIBUTE_SYSTEM, , a file attribute identified in the WIN32_FIND_DATA
structure. A system file is part of, or is used exclusively by, the operating system.
You must call FindNextFile at least once before calling IsSystem .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::IsTemporary
Call this member function to determine if the found file is a temporary file.

BOOL IsTemporary() const;

Return Value
Nonzero if successful; otherwise 0.
Remarks
A temporary file is marked with FILE_ATTRIBUTE_TEMPORARY, a file attribute identified in the WIN32_FIND_DATA
structure. A temporary file is used for temporary storage. Applications should write to the file only if absolutely
necessary. Most of the file's data remains in memory without being flushed to the media because the file will
soon be deleted.
You must call FindNextFile at least once before calling IsTemporary .
See the member function MatchesMask for a complete list of file attributes.
Example
See the example for CFileFind::GetLength.

CFileFind::m_pTM
Pointer to a CAtlTransactionManager object.

CAtlTransactionManager* m_pTM;

Remarks

CFileFind::MatchesMask
Call this member function to test the file attributes on the found file.

virtual BOOL MatchesMask(DWORD dwMask) const;

Parameters
dwMask
Specifies one or more file attributes, identified in the WIN32_FIND_DATA structure, for the found file. To search
for multiple attributes, use the bitwise OR (|) operator. Any combination of the following attributes is acceptable:
FILE_ATTRIBUTE_ARCHIVE The file is an archive file. Applications use this attribute to mark files for backup
or removal.
FILE_ATTRIBUTE_COMPRESSED The file or directory is compressed. For a file, this means that all of the
data in the file is compressed. For a directory, this means that compression is the default for newly created
files and subdirectories.
FILE_ATTRIBUTE_DIRECTORY The file is a directory.
FILE_ATTRIBUTE_NORMAL The file has no other attributes set. This attribute is valid only if used alone. All
other file attributes override this attribute.
FILE_ATTRIBUTE_HIDDEN The file is hidden. It is not to be included in an ordinary directory listing.
FILE_ATTRIBUTE_READONLY The file is read only. Applications can read the file but cannot write to it or
delete it.
FILE_ATTRIBUTE_SYSTEM The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary storage. Applications should write to
the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to the
media because the file will soon be deleted.
Return Value
Nonzero if successful; otherwise 0. To get extended error information, call the Win32 function GetLastError.
Remarks
You must call FindNextFile at least once before calling MatchesMask .
Example

// This code fragment shows all of the files in the root directory
// of drive C: which have either the hidden attribute or the system
// attribute, or both.

CFileFind finder;

BOOL bWorking = finder.FindFile(_T("C:\\*.*"));

while (bWorking)
{
bWorking = finder.FindNextFile();

if (finder.MatchesMask(FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_SYSTEM))
{
_tprintf_s(_T("%s\n"), (LPCTSTR) finder.GetFileName());
}
}
See also
CObject Class
Hierarchy Chart
CFtpFileFind Class
CGopherFileFind Class
CInternetFile Class
CGopherFile Class
CHttpFile Class
CFindReplaceDialog Class
3/27/2020 • 8 minutes to read • Edit Online

Allows you to implement standard string Find/Replace dialog boxes in your application.

Syntax
class CFindReplaceDialog : public CCommonDialog

Members
Public Constructors
NAME DESC RIP T IO N

CFindReplaceDialog::CFindReplaceDialog Call this function to construct a CFindReplaceDialog object.

Public Methods
NAME DESC RIP T IO N

CFindReplaceDialog::Create Creates and displays a CFindReplaceDialog dialog box.

CFindReplaceDialog::FindNext Call this function to determine whether the user wants to find
the next occurrence of the find string.

CFindReplaceDialog::GetFindString Call this function to retrieve the current find string.

CFindReplaceDialog::GetNotifier Call this function to retrieve the FINDREPLACE structure in


your registered message handler.

CFindReplaceDialog::GetReplaceString Call this function to retrieve the current replace string.

CFindReplaceDialog::IsTerminating Call this function to determine whether the dialog box is


terminating.

CFindReplaceDialog::MatchCase Call this function to determine whether the user wants to


match the case of the find string exactly.

CFindReplaceDialog::MatchWholeWord Call this function to determine whether the user wants to


match entire words only.

CFindReplaceDialog::ReplaceAll Call this function to determine whether the user wants all
occurrences of the string to be replaced.

CFindReplaceDialog::ReplaceCurrent Call this function to determine whether the user wants the
current word to be replaced.
NAME DESC RIP T IO N

CFindReplaceDialog::SearchDown Call this function to determine whether the user wants the
search to proceed in a downward direction.

Public Data Members


NAME DESC RIP T IO N

CFindReplaceDialog::m_fr A structure used to customize a CFindReplaceDialog


object.

Remarks
Unlike the other Windows common dialog boxes, CFindReplaceDialog objects are modeless, allowing users to
interact with other windows while they are on screen. There are two kinds of CFindReplaceDialog objects: Find
dialog boxes and Find/Replace dialog boxes. Although the dialog boxes allow the user to input search and
search/replace strings, they do not perform any of the searching or replacing functions. You must add these to the
application.
To construct a CFindReplaceDialog object, use the provided constructor (which has no arguments). Since this is a
modeless dialog box, allocate the object on the heap using the new operator, rather than on the stack.
Once a CFindReplaceDialog object has been constructed, you must call the Create member function to create and
display the dialog box.
Use the m_fr structure to initialize the dialog box before calling Create . The m_fr structure is of type
FINDREPLACE. For more information on this structure, see the Windows SDK.
In order for the parent window to be notified of find/replace requests, you must use the Windows
RegisterWindowMessage function and use the ON_REGISTERED_MESSAGE message-map macro in your frame
window that handles this registered message.
You can determine whether the user has decided to terminate the dialog box with the IsTerminating member
function.
CFindReplaceDialog relies on the COMMDLG.DLL file that ships with Windows versions 3.1 and later.
To customize the dialog box, derive a class from CFindReplaceDialog , provide a custom dialog template, and add a
message map to process the notification messages from the extended controls. Any unprocessed messages
should be passed to the base class.
Customizing the hook function is not required.
For more information on using CFindReplaceDialog , see Common Dialog Classes.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog
CFindReplaceDialog

Requirements
Header : afxdlgs.h

CFindReplaceDialog::CFindReplaceDialog
Constructs a CFindReplaceDialog object.

CFindReplaceDialog();

Remarks
Because the CFindReplaceDialog object is a modeless dialog box, you must construct it on the heap by using the
new operator.
During destruction, the framework tries to perform a delete this on the pointer to the dialog box. If you created
the dialog box on the stack, the this pointer does not exist and undefined behavior may result.
For more information on the construction of CFindReplaceDialog objects, see the CFindReplaceDialog overview.
Use the CFindReplaceDialog::Create member function to display the dialog box.
Example

// m_pFRDlg is a pointer to a class derived from CFindReplaceDialog


// which defines variables used by the FINDREPLACE structure.
// InitFindReplaceDlg creates a CFindReplaceDialog and initializes
// the m_fr with the data members from the derived class
void CMyRichEditView::InitFindReplaceDlg()
{
if (NULL == m_pFRDlg)
{
m_pFRDlg = new CMyFindReplaceDialog(); // Must be created on the heap

m_pFRDlg->Create(TRUE, _T(""), _T(""), FR_DOWN, this);

m_pFRDlg->m_fr.lStructSize = sizeof(FINDREPLACE);
m_pFRDlg->m_fr.hwndOwner = this->m_hWnd;
m_pFRDlg->m_fr.lpstrFindWhat = m_pFRDlg->GetFindWhatStr();
m_pFRDlg->m_fr.lpstrReplaceWith = m_pFRDlg->GetReplaceWithStr();
m_pFRDlg->m_fr.wFindWhatLen = m_pFRDlg->GetFindWhatStrLen();
m_pFRDlg->m_fr.wReplaceWithLen = m_pFRDlg->GetReplaceWithStrLen();
}
}

CFindReplaceDialog::Create
Creates and displays either a Find or Find/Replace dialog box object, depending on the value of bFindDialogOnly .

virtual BOOL Create(


BOOL bFindDialogOnly,
LPCTSTR lpszFindWhat,
LPCTSTR lpszReplaceWith = NULL,
DWORD dwFlags = FR_DOWN,
CWnd* pParentWnd = NULL);

Parameters
bFindDialogOnly
Set this parameter to TRUE to display a Find dialog box. Set it to FALSE to display a Find/Replace dialog box.
lpszFindWhat
Pointer to the default search string when the dialog box appears. If NULL, the dialog box does not contain a
default search string.
lpszReplaceWith
Pointer to the default replacement string when the dialog box appears. If NULL, the dialog box does not contain a
default replacement string.
dwFlags
One or more flags you can use to customize the settings of the dialog box, combined using the bitwise OR
operator. The default value is FR_DOWN, which specifies that the search is to proceed in a downward direction.
See the FINDREPLACE structure in the Windows SDK for more information on these flags.
pParentWnd
A pointer to the dialog box's parent or owner window. This is the window that will receive the special message
indicating that a find/replace action is requested. If NULL, the main window of the application is used.
Return Value
Nonzero if the dialog box object was successfully created; otherwise 0.
Remarks
In order for the parent window to be notified of find/replace requests, you must use the Windows
RegisterWindowMessage function whose return value is a message number unique to the application's instance.
Your frame window should have a message map entry that declares the callback function ( OnFindReplace in the
example that follows) that handles this registered message. The following code fragment is an example of how to
do this for a frame window class named CMyRichEditView :

// Message handler declared in CMyRichEditView class declaration


protected:
afx_msg LONG OnFindReplace(WPARAM wParam, LPARAM lParam);

// Register FindReplace window message.


static UINT WM_FINDREPLACE = ::RegisterWindowMessage(FINDMSGSTRING);

// Message map entry to map from message to handler function.


ON_REGISTERED_MESSAGE(WM_FINDREPLACE, &CMyRichEditView::OnFindReplace)

Within your OnFindReplace function, you interpret the intentions of the user by using the
CFindReplaceDialog::FindNext and CFindReplaceDialog::IsTerminating methods and you create the code for the
find/replace operations.
Example
See the example for CFindReplaceDialog::CFindReplaceDialog.

CFindReplaceDialog::FindNext
Call this function from your callback function to determine whether the user wants to find the next occurrence of
the search string.
BOOL FindNext() const;

Return Value
Nonzero if the user wants to find the next occurrence of the search string; otherwise 0.

CFindReplaceDialog::GetFindString
Call this function from your callback function to retrieve the default string to find.

CString GetFindString() const;

Return Value
The default string to find.
Example

LRESULT CMyRichEditView::OnFindReplace(WPARAM wparam, LPARAM lparam)


{
UNREFERENCED_PARAMETER(wparam);

CFindReplaceDialog *pDlg = CFindReplaceDialog::GetNotifier(lparam);

if (NULL != pDlg)
{
// Use pDlg as a pointer to the existing FindReplace dlg to
// call CFindReplaceDialog member functions
if (pDlg->IsTerminating())
{
CString csFindString;
CString csReplaceString;

csFindString = pDlg->GetFindString();
csReplaceString = pDlg->GetReplaceString();

VERIFY(AfxGetApp()->WriteProfileString(AfxGetApp()->m_pszAppName,
_T("FindString"), csFindString));
VERIFY(AfxGetApp()->WriteProfileString(AfxGetApp()->m_pszAppName,
_T("ReplaceString"), csReplaceString));

VERIFY(pDlg->DestroyWindow());
}
}

return 0;
}

CFindReplaceDialog::GetNotifier
Call this function to retrieve a pointer to the current Find Replace dialog box.

static CFindReplaceDialog* PASCAL GetNotifier(LPARAM lParam);

Parameters
lParam
The lparam value passed to the frame window's OnFindReplace member function.
Return Value
A pointer to the current dialog box.
Remarks
It should be used within your callback function to access the current dialog box, call its member functions, and
access the m_fr structure.
Example
See CFindReplaceDialog::Create for an example of how to register the OnFindReplace handler to receive
notifications from the Find Replace dialog box.

LRESULT CMyRichEditView::OnFindReplace(WPARAM wparam, LPARAM lparam)


{
UNREFERENCED_PARAMETER(wparam);

CFindReplaceDialog *pDlg = CFindReplaceDialog::GetNotifier(lparam);

if (NULL != pDlg)
{
// Use pDlg as a pointer to the existing FindReplace dlg to
// call CFindReplaceDialog member functions
if (pDlg->IsTerminating())
{
CString csFindString;
CString csReplaceString;

csFindString = pDlg->GetFindString();
csReplaceString = pDlg->GetReplaceString();

VERIFY(AfxGetApp()->WriteProfileString(AfxGetApp()->m_pszAppName,
_T("FindString"), csFindString));
VERIFY(AfxGetApp()->WriteProfileString(AfxGetApp()->m_pszAppName,
_T("ReplaceString"), csReplaceString));

VERIFY(pDlg->DestroyWindow());
}
}

return 0;
}

CFindReplaceDialog::GetReplaceString
Call this function to retrieve the current replace string.

CString GetReplaceString() const;

Return Value
The default string with which to replace found strings.
Example
See the example for CFindReplaceDialog::GetFindString.

CFindReplaceDialog::IsTerminating
Call this function within your callback function to determine whether the user has decided to terminate the dialog
box.
BOOL IsTerminating() const;

Return Value
Nonzero if the user has decided to terminate the dialog box; otherwise 0.
Remarks
If this function returns nonzero, you should call the DestroyWindow member function of the current dialog box and
set any dialog box pointer variable to NULL. Optionally, you can also store the find/replace text last entered and
use it to initialize the next find/replace dialog box.
Example
See the example for CFindReplaceDialog::GetFindString.

CFindReplaceDialog::m_fr
Used to customize a CFindReplaceDialog object.

FINDREPLACE m_fr;

Remarks
m_fr is a structure of type FINDREPLACE. Its members store the characteristics of the dialog-box object. After
constructing a CFindReplaceDialog object, you can use m_fr to modify various values in the dialog box.
For more information on this structure, see the FINDREPLACE structure in the Windows SDK.
Example
See the example for CFindReplaceDialog::CFindReplaceDialog.

CFindReplaceDialog::MatchCase
Call this function to determine whether the user wants to match the case of the find string exactly.

BOOL MatchCase() const;

Return Value
Nonzero if the user wants to find occurrences of the search string that exactly match the case of the search string;
otherwise 0.

CFindReplaceDialog::MatchWholeWord
Call this function to determine whether the user wants to match entire words only.

BOOL MatchWholeWord() const;

Return Value
Nonzero if the user wants to match only the entire words of the search string; otherwise 0.

CFindReplaceDialog::ReplaceAll
Call this function to determine whether the user wants all occurrences of the string to be replaced.
BOOL ReplaceAll() const;

Return Value
Nonzero if the user has requested that all strings matching the replace string be replaced; otherwise 0.

CFindReplaceDialog::ReplaceCurrent
Call this function to determine whether the user wants the current word to be replaced.

BOOL ReplaceCurrent() const;

Return Value
Nonzero if the user has requested that the currently selected string be replaced with the replace string; otherwise
0.

CFindReplaceDialog::SearchDown
Call this function to determine whether the user wants the search to proceed in a downward direction.

BOOL SearchDown() const;

Return Value
Nonzero if the user wants the search to proceed in a downward direction; 0 if the user wants the search to
proceed in an upward direction.

See also
CCommonDialog Class
Hierarchy Chart
CFolderPickerDialog Class
3/27/2020 • 2 minutes to read • Edit Online

CFolderPickerDialog class implements CFileDialog in the folder picker mode.

Syntax
class CFolderPickerDialog : public CFileDialog;

Members
Public Constructors
NAME DESC RIP T IO N

CFolderPickerDialog::~CFolderPickerDialog Destructor.

CFolderPickerDialog::CFolderPickerDialog Constructor.

Remarks
Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog
CFileDialog
CFolderPickerDialog

Requirements
Header : afxdlgs.h

CFolderPickerDialog::CFolderPickerDialog
Constructor.

explicit CFolderPickerDialog(
LPCTSTR lpszFolder = NULL,
DWORD dwFlags = 0,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0);
Parameters
lpszFolder
Initial folder.
dwFlags
A combination of one or more flags that allow you to customize the dialog box.
pParentWnd
A pointer to the dialog box object's parent or owner window.
dwSize
The size of the OPENFILENAME structure.
Remarks

CFolderPickerDialog::~CFolderPickerDialog
Destructor.

virtual ~CFolderPickerDialog();

Remarks

See also
Classes
CFont Class
3/27/2020 • 12 minutes to read • Edit Online

Encapsulates a Windows graphics device interface (GDI) font and provides member functions for manipulating
the font.

Syntax
class CFont : public CGdiObject

Members
Public Constructors
NAME DESC RIP T IO N

CFont::CFont Constructs a CFont object.

Public Methods
NAME DESC RIP T IO N

CFont::CreateFont Initializes a CFont with the specified characteristics.

CFont::CreateFontIndirect Initializes a CFont object with the characteristics given in a


LOGFONT structure.

CFont::CreatePointFont Initializes a CFont with the specified height, measured in


tenths of a point, and typeface.

CFont::CreatePointFontIndirect Same as CreateFontIndirect except that the font height is


measured in tenths of a point rather than logical units.

CFont::FromHandle Returns a pointer to a CFont object when given a Windows


HFONT.

CFont::GetLogFont Fills a LOGFONT with information about the logical font


attached to the CFont object.

Public Operators
NAME DESC RIP T IO N

CFont::operator HFONT Returns the Windows GDI font handle attached to the
CFont object.

Remarks
To use a CFont object, construct a CFont object and attach a Windows font to it with CreateFont,
CreateFontIndirect, CreatePointFont, or CreatePointFontIndirect, and then use the object's member functions to
manipulate the font.
The CreatePointFont and CreatePointFontIndirect functions are often easier to use than CreateFont or
CreateFontIndirect since they do the conversion for the height of the font from a point size to logical units
automatically.
For more information on CFont , see Graphic Objects.

Inheritance Hierarchy
CObject
CGdiObject
CFont

Requirements
Header : afxwin.h

CFont::CFont
Constructs a CFont object.

CFont();

Remarks
The resulting object must be initialized with CreateFont , CreateFontIndirect , CreatePointFont , or
CreatePointFontIndirect before it can be used.

Example

CFont font;

CFont::CreateFont
Initializes a CFont object with the specified characteristics.

BOOL CreateFont(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename);

Parameters
nHeight
Specifies the desired height (in logical units) of the font. See the lfHeight member of the LOGFONTstructure in
the Windows SDK for a description. The absolute value of nHeight must not exceed 16,384 device units after it is
converted. For all height comparisons, the font mapper looks for the largest font that does not exceed the
requested size or the smallest font if all the fonts exceed the requested size.
nWidth
Specifies the average width (in logical units) of characters in the font. If nWidth is 0, the aspect ratio of the device
will be matched against the digitization aspect ratio of the available fonts to find the closest match, which is
determined by the absolute value of the difference.
nEscapement
Specifies the angle (in 0.1-degree units) between the escapement vector and the x-axis of the display surface. The
escapement vector is the line through the origins of the first and last characters on a line. The angle is measured
counterclockwise from the x-axis. See the lfEscapement member in the LOGFONT structure in the Windows SDK
for more information.
nOrientation
Specifies the angle (in 0.1-degree units) between the baseline of a character and the x-axis. The angle is
measured counterclockwise from the x-axis for coordinate systems in which the y-direction is down and
clockwise from the x-axis for coordinate systems in which the y-direction is up.
nWeight
Specifies the font weight (in inked pixels per 1000). See the lfWeight member in the LOGFONT structure in the
Windows SDK for more information. The described values are approximate; the actual appearance depends on
the typeface. Some fonts have only FW_NORMAL, FW_REGULAR, and FW_BOLD weights. If FW_DONTCARE is
specified, a default weight is used.
bItalic
Specifies whether the font is italic.
bUnderline
Specifies whether the font is underlined.
cStrikeOut
Specifies whether characters in the font are struck out. Specifies a strikeout font if set to a nonzero value.
nCharSet
Specifies the font's character setSee the lfCharSet member in the LOGFONT structure in the Windows SDK for a
list of values.
The OEM character set is system-dependent.
Fonts with other character sets may exist in the system. An application that uses a font with an unknown
character set must not attempt to translate or interpret strings that are to be rendered with that font. Instead, the
strings should be passed directly to the output device driver.
The font mapper does not use the DEFAULT_CHARSET value. An application can use this value to allow the name
and size of a font to fully describe the logical font. If a font with the specified name does not exist, a font from
any character set can be substituted for the specified font. To avoid unexpected results, applications should use
the DEFAULT_CHARSET value sparingly.
nOutPrecision
Specifies the desired output precision. The output precision defines how closely the output must match the
requested font's height, width, character orientation, escapement, and pitch. See the lfOutPrecision member in
the LOGFONT structure in the Windows SDK for a list of values and more information.
nClipPrecision
Specifies the desired clipping precision. The clipping precision defines how to clip characters that are partially
outside the clipping region. See the lfClipPrecision member in the LOGFONT structure in the Windows SDK for
a list of values.
To use an embedded read-only font, an application must specify CLIP_ENCAPSULATE.
To achieve consistent rotation of device, TrueType, and vector fonts, an application can use the OR operator to
combine the CLIP_LH_ANGLES value with any of the other nClipPrecision values. If the CLIP_LH_ANGLES bit is
set, the rotation for all fonts depends on whether the orientation of the coordinate system is left-handed or right-
handed. (For more information about the orientation of coordinate systems, see the description of the
nOrientation parameter.) If CLIP_LH_ANGLES is not set, device fonts always rotate counterclockwise, but the
rotation of other fonts is dependent on the orientation of the coordinate system.
nQuality
Specifies the font's output quality, which defines how carefully the GDI must attempt to match the logical-font
attributes to those of an actual physical font. See the lfQuality member in the LOGFONT structure in the
Windows SDK for a list of values.
nPitchAndFamily
Specifies the pitch and family of the font. See the lfPitchAndFamily member in the LOGFONT structure in the
Windows SDK for a list of values and more information.
lpszFacename
A CString or pointer to a null-terminated string that specifies the typeface name of the font. The length of this
string must not exceed 30 characters. The Windows EnumFontFamilies function can be used to enumerate all
currently available fonts. If lpszFacename is NULL, the GDI uses a device-independent typeface.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The font can subsequently be selected as the font for any device context.
The CreateFont function does not create a new Windows GDI font. It merely selects the closest match from the
physical fonts available to the GDI.
Applications can use the default settings for most parameters when creating a logical font. The parameters that
should always be given specific values are nHeight and lpszFacename. If nHeight and lpszFacename are not set
by the application, the logical font that is created is device-dependent.
When you finish with the CFont object created by the CreateFont function, use CDC::SelectObject to select a
different font into the device context, then delete the CFont object that is no longer needed.
Example
// The code fragment shows how to create a font object,
// select the font object into a DC (device context) for text
// drawing, and finally delete the font object.

// Initializes a CFont object with the specified characteristics.


CFont font;
VERIFY(font.CreateFont(
12, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial"))); // lpszFacename

// Do something with the font just created...


CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font.DeleteObject();

CFont::CreateFontIndirect
Initializes a CFont object with the characteristics given in a LOGFONTstructure.

BOOL CreateFontIndirect(const LOGFONT* lpLogFont);

Parameters
lpLogFont
Points to a LOGFONT structure that defines the characteristics of the logical font.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The font can subsequently be selected as the current font for any device.
This font has the characteristics specified in the LOGFONT structure. When the font is selected by using the
CDC::SelectObject member function, the GDI font mapper attempts to match the logical font with an existing
physical font. If the font mapper fails to find an exact match for the logical font, it provides an alternative font
whose characteristics match as many of the requested characteristics as possible.
When you no longer need the CFont object created by the CreateFontIndirect function, use CDC::SelectObject
to select a different font into the device context, then delete the CFont object that is no longer needed.
Example
// The code fragment shows how to create a font object,
// select the font object into a DC (device context) for text
// drawing, and finally delete the font object.

// Initializes a CFont object with the characteristics given


// in a LOGFONT structure.
CFont font;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT)); // zero out structure
lf.lfHeight = 12; // request a 12-pixel-height font
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE,
_T("Arial"), 7); // request a face name "Arial"
VERIFY(font.CreateFontIndirect(&lf)); // create the font

// Do something with the font just created...


CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font.DeleteObject();

CFont::CreatePointFont
This function provides a simple way to create a font of a specified typeface and point size.

BOOL CreatePointFont(
int nPointSize,
LPCTSTR lpszFaceName,
CDC* pDC = NULL);

Parameters
nPointSize
Requested font height in tenths of a point. (For instance, pass 120 to request a 12-point font.)
lpszFaceName
A CString or pointer to a null-terminated string that specifies the typeface name of the font. The length of this
string must not exceed 30 characters. The Windows `EnumFontFamilies function can be used to enumerate all
currently available fonts. If lpszFaceName is NULL, the GDI uses a device-independent typeface.
pDC
Pointer to the CDC object to be used to convert the height in nPointSize to logical units. If NULL, a screen device
context is used for the conversion.
Return Value
Nonzero if successful, otherwise 0.
Remarks
It automatically converts the height in nPointSize to logical units using the CDC object pointed to by pDC.
When you finish with the CFont object created by the CreatePointFont function, first select the font out of the
device context, then delete the CFont object.
Example
// The code fragment shows how to create a font object,
// select the font object into a DC (device context) for text
// drawing, and finally delete the font object.

CClientDC dc(this);

CFont font;
VERIFY(font.CreatePointFont(120, _T("Arial"), &dc));

// Do something with the font just created...


CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font.DeleteObject();

CFont::CreatePointFontIndirect
This function is the same as CreateFontIndirect except that the lfHeight member of the LOGFONT is interpreted
in tenths of a point rather than device units.

BOOL CreatePointFontIndirect(
const LOGFONT* lpLogFont,
CDC* pDC = NULL);

Parameters
lpLogFont
Points to a LOGFONT structure that defines the characteristics of the logical font. The lfHeight member of the
LOGFONT structure is measured in tenths of a point rather than logical units. (For instance, set lfHeight to 120
to request a 12-point font.)
pDC
Pointer to the CDC object to be used to convert the height in lfHeight to logical units. If NULL, a screen device
context is used for the conversion.
Return Value
Nonzero if successful, otherwise 0.
Remarks
This function automatically converts the height in lfHeight to logical units using the CDC object pointed to by
pDC before passing the LOGFONT structure on to Windows.
When you finish with the CFont object created by the CreatePointFontIndirect function, first select the font out
of the device context, then delete the CFont object.
Example
// The code fragment shows how to create a font object,
// select the font object into a DC (device context) for text
// drawing, and finally delete the font object.
LOGFONT lf;

// clear out structure.


memset(&lf, 0, sizeof(LOGFONT));

// request a 12-pixel-height font


lf.lfHeight = 120;

// request a face name "Arial".


_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);

CClientDC dc(this);

CFont font;
VERIFY(font.CreatePointFontIndirect(&lf, &dc));

// Do something with the font just created...


CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font.DeleteObject();

CFont::FromHandle
Returns a pointer to a CFont object when given an HFONT handle to a Windows GDI font object.

static CFont* PASCAL FromHandle(HFONT hFont);

Parameters
hFont
An HFONT handle to a Windows font.
Return Value
A pointer to a CFont object if successful; otherwise NULL.
Remarks
If a CFont object is not already attached to the handle, a temporary CFont object is created and attached. This
temporary CFont object is valid only until the next time the application has idle time in its event loop, at which
time all temporary graphic objects are deleted. Another way of saying this is that the temporary object is valid
only during the processing of one window message.
Example
// The code fragment shows how to create a font object using
// Windows API CreateFontIndirect(), convert the HFONT to a
// CFont* before selecting the font object into a DC (device
// context) for text drawing, and finally delete the font object.

// Initialize a CFont object with the characteristics given


// in a LOGFONT structure.
LOGFONT lf;

// clear out structure


memset(&lf, 0, sizeof(LOGFONT));
// request a 12-pixel-height font
lf.lfHeight = 12;
// request a face name "Arial"
_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);
// create the font
HFONT hfont = ::CreateFontIndirect(&lf);

// Convert the HFONT to CFont*.


CFont *pfont = CFont::FromHandle(hfont);

// Do something with the font just created...


CClientDC dc(this);
CFont *def_font = dc.SelectObject(pfont);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


::DeleteObject(hfont);

CFont::GetLogFont
Call this function to retrieve a copy of the LOGFONT structure for CFont .

int GetLogFont(LOGFONT* pLogFont);

Parameters
pLogFont
Pointer to the LOGFONT structure to receive the font information.
Return Value
Nonzero if the function succeeds, otherwise 0.
Example

// The code fragment shows how to retrieve a copy of the


// LOGFONT structure for a currently selected font of a window.

CFont *pFont = pWnd->GetFont();


if (NULL != pFont)
{
LOGFONT lf;
pFont->GetLogFont(&lf);
TRACE(_T("Typeface name of font = %s\n"), lf.lfFaceName);
}

CFont::operator HFONT
Use this operator to get the Windows GDI handle of the font attached to the CFont object.
operator HFONT() const;

Return Value
The handle of the Windows GDI font object attached to CFont if successful; otherwise NULL.
Remarks
Since this operator is automatically used for conversions from CFont to Fonts and Text, you can pass CFont
objects to functions that expect HFONTs.
For more information about using graphic objects, see Graphic Objects in the Windows SDK.
Example

// The code fragment shows the usage of CFont::operator HFONT.

// Initialize a CFont object with the characteristics given


// in a LOGFONT structure.
LOGFONT lf;

// clear out structure


memset(&lf, 0, sizeof(LOGFONT));

// request a 12-pixel-height font


lf.lfHeight = 12;

// request a face name "Arial"


_tcsncpy_s(lf.lfFaceName, LF_FACESIZE, _T("Arial"), 7);

CFont font1;
font1.CreateFontIndirect(&lf); // create the font

// CFont::operator HFONT automatically converts font1 from


// CFont* to HFONT.
CFont *font2 = CFont::FromHandle(font1);

// Do something with the font just created...


CClientDC dc(this);
CFont *def_font = dc.SelectObject(font2);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font1.DeleteObject();

See also
MFC Sample HIERSVR
CGdiObject Class
Hierarchy Chart
CFontDialog Class
4/21/2020 • 8 minutes to read • Edit Online

Allows you to incorporate a font-selection dialog box into your application.

Syntax
class CFontDialog : public CCommonDialog

Members
Public Constructors
NAME DESC RIP T IO N

CFontDialog::CFontDialog Constructs a CFontDialog object.

Public Methods
NAME DESC RIP T IO N

CFontDialog::DoModal Displays the dialog and allows the user to make a selection.

CFontDialog::GetCharFormat Retrieves the character formatting of the selected font.

CFontDialog::GetColor Returns the color of the selected font.

CFontDialog::GetCurrentFont Assigns the characteristics of the currently selected font to a


LOGFONT structure.

CFontDialog::GetFaceName Returns the face name of the selected font.

CFontDialog::GetSize Returns the point size of the selected font.

CFontDialog::GetStyleName Returns the style name of the selected font.

CFontDialog::GetWeight Returns the weight of the selected font.

CFontDialog::IsBold Determines whether the font is bold.

CFontDialog::IsItalic Determines whether the font is italic.

CFontDialog::IsStrikeOut Determines whether the font is displayed with strikeout.

CFontDialog::IsUnderline Determines whether the font is underlined.

Public Data Members


NAME DESC RIP T IO N

CFontDialog::m_cf A structure used to customize a CFontDialog object.

Remarks
A CFontDialog object is a dialog box with a list of fonts that are currently installed in the system. The user can
select a particular font from the list, and this selection is then reported back to the application.
To construct a CFontDialog object, use the provided constructor or derive a new subclass and use your own
custom constructor.
Once a CFontDialog object has been constructed, you can use the m_cf structure to initialize the values or states
of controls in the dialog box. The m_cf structure is of type CHOOSEFONT. For more information on this structure,
see the Windows SDK.
After initializing the dialog object's controls, call the DoModal member function to display the dialog box and
allow the user to select a font. DoModal returns whether the user selected the OK (IDOK) or Cancel (IDCANCEL)
button.
If DoModal returns IDOK, you can use one of CFontDialog 's member functions to retrieve the information input
by the user.
You can use the Windows CommDlgExtendedError function to determine whether an error occurred during
initialization of the dialog box and to learn more about the error. For more information on this function, see the
Windows SDK.
CFontDialog relies on the COMMDLG.DLL file that ships with Windows versions 3.1 and later.
To customize the dialog box, derive a class from CFontDialog , provide a custom dialog template, and add a
message-map to process the notification messages from the extended controls. Any unprocessed messages
should be passed to the base class.
Customizing the hook function is not required.
For more information on using CFontDialog , see Common Dialog Classes.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CDialog
CCommonDialog
CFontDialog

Requirements
Header : afxdlgs.h

CFontDialog::CFontDialog
Constructs a CFontDialog object.
CFontDialog(
LPLOGFONT lplfInitial = NULL,
DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
CDC* pdcPrinter = NULL,
CWnd* pParentWnd = NULL);

CFontDialog(
const CHARFORMAT& charformat,
DWORD dwFlags = CF_SCREENFONTS,
CDC* pdcPrinter = NULL,
CWnd* pParentWnd = NULL);

Parameters
plfInitial
A pointer to a LOGFONT data structure that allows you to set some of the font's characteristics.
charFormat
A pointer to a CHARFORMAT data structure that allows you to set some of the font's characteristics in a rich edit
control.
dwFlags
Specifies one or more choose-font flags. One or more preset values can be combined using the bitwise OR
operator. If you modify the m_cf.Flag s structure member, be sure to use a bitwise OR operator in your changes
to keep the default behavior intact. For details on each of these flags, see the description of the CHOOSEFONT
structure in the Windows SDK.
pdcPrinter
A pointer to a printer-device context. If supplied, this parameter points to a printer-device context for the printer
on which the fonts are to be selected.
pParentWnd
A pointer to the font dialog box's parent or owner window.
Remarks
Note that the constructor automatically fills in the members of the CHOOSEFONT structure. You should only change
these if you want a font dialog different than the default.

NOTE
The first version of this function only exists when there is no rich edit control support.

Example

// Show the font dialog with all the default settings.


CFontDialog dlg;
dlg.DoModal();

// Show the font dialog with 12 point "Times New Roman" as the
// selected font.
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));

CClientDC dc(this); // expects a CWnd that has already been initialized


lf.lfHeight = -MulDiv(12, dc.GetDeviceCaps(LOGPIXELSY), 72);
_tcscpy_s(lf.lfFaceName, LF_FACESIZE, _T("Times New Roman"));

CFontDialog fdlg(&lf);
fdlg.DoModal();
CFontDialog::DoModal
Call this function to display the Windows common font dialog box and allow the user to choose a font.

virtual INT_PTR DoModal();

Return Value
IDOK or IDCANCEL. If IDCANCEL is returned, call the Windows CommDlgExtendedError function to determine
whether an error occurred.
IDOK and IDCANCEL are constants that indicate whether the user selected the OK or Cancel button.
Remarks
If you want to initialize the various font dialog controls by setting members of the m_cf structure, you should do
this before calling DoModal , but after the dialog object is constructed.
If DoModal returns IDOK, you can call other member functions to retrieve the settings or information input by the
user into the dialog box.
Example
See the examples for CFontDialog::CFontDialog and CFontDialog::GetColor.

CFontDialog::GetCharFormat
Retrieves the character formatting of the selected font.

void GetCharFormat(CHARFORMAT& cf) const;

Parameters
cf
A CHARFORMAT structure containing information about the character formatting of the selected font.

CFontDialog::GetColor
Call this function to retrieve the selected font color.

COLORREF GetColor() const;

Return Value
The color of the selected font.
Example

// Get the color of the selected font, if any.


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
COLORREF color = dlg.GetColor();
TRACE(_T("Color of the selected font = %8x\n"), color);
}

CFontDialog::GetCurrentFont
Call this function to assign the characteristics of the currently selected font to the members of a LOGFONT
structure.

void GetCurrentFont(LPLOGFONT lplf);

Parameters
lplf
A pointer to a LOGFONT structure.
Remarks
Other CFontDialog member functions are provided to access individual characteristics of the current font.
If this function is called during a call to DoModal, it returns the current selection at the time (what the user sees or
has changed in the dialog). If this function is called after a call to DoModal (only if DoModal returns IDOK), it
returns what the user actually selected.
Example

// Get the characteristics of the currently selected font, if any.


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
LOGFONT lf;
dlg.GetCurrentFont(&lf);
TRACE(_T("Face name of the selected font = %s\n"), lf.lfFaceName);
}

CFontDialog::GetFaceName
Call this function to retrieve the face name of the selected font.

CString GetFaceName() const;

Return Value
The face name of the font selected in the CFontDialog dialog box.
Example

// Get the face name of the selected font, if any.


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
CString facename = dlg.GetFaceName();
TRACE(_T("Face name of the selected font = %s\n"), facename);
}

CFontDialog::GetSize
Call this function to retrieve the size of the selected font.

int GetSize() const;

Return Value
The font's size, in tenths of a point.
Example

// Get the size of the selected font, if any.


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
int size = dlg.GetSize();
TRACE(_T("The size of the selected font = %d\n"), size);
}

CFontDialog::GetStyleName
Call this function to retrieve the style name of the selected font.

CString GetStyleName() const;

Return Value
The style name of the font.
Example

// Get the style name of the selected font, if any.


CFontDialog dlg;
dlg.m_cf.Flags |= CF_USESTYLE;
if (dlg.DoModal() == IDOK)
{
CString stylename = dlg.GetStyleName();
TRACE(_T("Style name of the selected font = %s\n"), stylename);
}

CFontDialog::GetWeight
Call this function to retrieve the weight of the selected font.

int GetWeight() const;

Return Value
The weight of the selected font.
Remarks
For more information on the weight of a font, see CFont::CreateFont.
Example

// Get the weight of the selected font, if any.


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
int weight = dlg.GetWeight();
TRACE(_T("Weight of the selected font = %d\n"), weight);
}
CFontDialog::IsBold
Call this function to determine if the selected font is bold.

BOOL IsBold() const;

Return Value
Nonzero if the selected font has the Bold characteristic enabled; otherwise 0.
Example

// Is the selected font bold?


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
BOOL bold = dlg.IsBold();
TRACE(_T("Is the selected font bold? %d\n"), bold);
}

CFontDialog::IsItalic
Call this function to determine if the selected font is italic.

BOOL IsItalic() const;

Return Value
Nonzero if the selected font has the Italic characteristic enabled; otherwise 0.
Example

// Is the selected font italic?


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
BOOL italic = dlg.IsItalic();
TRACE(_T("Is the selected font italic? %d\n"), italic);
}

CFontDialog::IsStrikeOut
Call this function to determine if the selected font is displayed with strikeout.

BOOL IsStrikeOut() const;

Return Value
Nonzero if the selected font has the Strikeout characteristic enabled; otherwise 0.
Example
// Is the selected font displayed with strikeout?

CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
BOOL strikeout = dlg.IsStrikeOut();
TRACE(_T("Is the selected font strikeout? %d\n"), strikeout);
}

CFontDialog::IsUnderline
Call this function to determine if the selected font is underlined.

BOOL IsUnderline() const;

Return Value
Nonzero if the selected font has the Underline characteristic enabled; otherwise 0.
Example

// Is the selected font underlined?


CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
BOOL underline = dlg.IsUnderline();
TRACE(_T("Is the selected font underlined? %d\n"), underline);
}

CFontDialog::m_cf
A structure whose members store the characteristics of the dialog object.

CHOOSEFONT m_cf;

Remarks
After constructing a CFontDialog object, you can use m_cf to modify various aspects of the dialog box before
calling the DoModal member function. For more information on this structure, see CHOOSEFONT in the Windows
SDK.
Example
// The code fragment creates a font based on the information
// we got from CFontDialog::m_cf variable.

CFontDialog dlg;
if (dlg.DoModal() == IDOK)
{
// Create the font using the selected font from CFontDialog.
LOGFONT lf;
memcpy(&lf, dlg.m_cf.lpLogFont, sizeof(LOGFONT));

CFont font;
VERIFY(font.CreateFontIndirect(&lf));

// Do something with the font just created...


CClientDC dc(this);
CFont *def_font = dc.SelectObject(&font);
dc.TextOut(5, 5, _T("Hello"), 5);
dc.SelectObject(def_font);

// Done with the font. Delete the font object.


font.DeleteObject();
}

See also
MFC Sample HIERSVR
CCommonDialog Class
Hierarchy Chart
CFontHolder Class
4/21/2020 • 3 minutes to read • Edit Online

Implements the stock Font property and encapsulates the functionality of a Windows font object and the IFont
interface.

Syntax
class CFontHolder

Members
Public Constructors
NAME DESC RIP T IO N

CFontHolder::CFontHolder Constructs a CFontHolder object.

Public Methods
NAME DESC RIP T IO N

CFontHolder::GetDisplayString Retrieves the string displayed in a container's property


browser.

CFontHolder::GetFontDispatch Returns the font's IDispatch interface.

CFontHolder::GetFontHandle Returns a handle to a Windows font.

CFontHolder::InitializeFont Initializes a CFontHolder object.

CFontHolder::QueryTextMetrics Retrieves information for the related font.

CFontHolder::ReleaseFont Disconnects the CFontHolder object from the IFont and


IFontNotification interfaces.

CFontHolder::Select Selects a font resource into a device context.

CFontHolder::SetFont Connects the CFontHolder object to an IFont interface.

Public Data Members


NAME DESC RIP T IO N

CFontHolder::m_pFont A pointer to the CFontHolder object's IFont interface.

Remarks
CFontHolder does not have a base class.
Use this class to implement custom font properties for your control. For information on creating such properties,
see the article ActiveX Controls: Using Fonts.

Inheritance Hierarchy
CFontHolder

Requirements
Header : afxctl.h

CFontHolder::CFontHolder
Constructs a CFontHolder object.

explicit CFontHolder(LPPROPERTYNOTIFYSINK pNotify);

Parameters
pNotify
Pointer to the font's IPropertyNotifySink interface.
Remarks
You must call InitializeFont to initialize the resulting object before using it.

CFontHolder::GetDisplayString
Retrieves a string that can be displayed in a container's property browser.

BOOL GetDisplayString(CString& strValue);

Parameters
strValue
Reference to the CString that is to hold the display string.
Return Value
Nonzero if the string is successfully retrieved; otherwise 0.

CFontHolder::GetFontDispatch
Call this function to retrieve a pointer to the font's dispatch interface.

LPFONTDISP GetFontDispatch();

Return Value
A pointer to the CFontHolder object's IFontDisp interface. Note that the function that calls GetFontDispatch must
call IUnknown::Release on this interface pointer when done with it.
Remarks
Call InitializeFont before calling GetFontDispatch .
CFontHolder::GetFontHandle
Call this function to get a handle to a Windows font.

HFONT GetFontHandle();

HFONT GetFontHandle(
long cyLogical,
long cyHimetric);

Parameters
cyLogical
Height, in logical units, of the rectangle in which the control is drawn.
cyHimetric
Height, in MM_HIMETRIC units, of the control.
Return Value
A handle to the Font object; otherwise NULL.
Remarks
The ratio of cyLogical and cyHimetric is used to calculate the proper display size, in logical units, for the font's
point size expressed in MM_HIMETRIC units:
Display size = ( cyLogical / cyHimetric) X font size
The version with no parameters returns a handle to a font sized correctly for the screen.

CFontHolder::InitializeFont
Initializes a CFontHolder object.

void InitializeFont(
const FONTDESC* pFontDesc = NULL,
LPDISPATCH pFontDispAmbient = NULL);

Parameters
pFontDesc
Pointer to a font description structure ( FONTDESC) that specifies the font's characteristics.
pFontDispAmbient
Pointer to the container's ambient Font property.
Remarks
If pFontDispAmbient is not NULL, the CFontHolder object is connected to a clone of the IFont interface used by
the container's ambient Font property.
If pFontDispAmbient is NULL, a new Font object is created either from the font description pointed to by
pFontDesc or, if pFontDesc is NULL, from a default description.
Call this function after constructing a CFontHolder object.

CFontHolder::m_pFont
A pointer to the CFontHolder object's IFont interface.
LPFONT m_pFont;

CFontHolder::QueryTextMetrics
Retrieves information on the physical font represented by the CFontHolder object.

void QueryTextMetrics(LPTEXTMETRIC lptm);

Parameters
lptm
A pointer to a TEXTMETRIC structure that will receive the information.

CFontHolder::ReleaseFont
This function disconnects the CFontHolder object from its IFont interface.

void ReleaseFont();

CFontHolder::Select
Call this function to select your control's font into the specified device context.

CFont* Select(
CDC* pDC,
long cyLogical,
long cyHimetric);

Parameters
pDC
Device context into which the font is selected.
cyLogical
Height, in logical units, of the rectangle in which the control is drawn.
cyHimetric
Height, in MM_HIMETRIC units, of the control.
Return Value
A pointer to the font that is being replaced.
Remarks
See GetFontHandle for a discussion of the cyLogical and cyHimetric parameters.

CFontHolder::SetFont
Releases any existing font and connects the CFontHolder object to an IFont interface.

void SetFont(LPFONT pNewFont);

Parameters
pNewFont
Pointer to the new IFont interface.

See also
Hierarchy Chart
CPropExchange Class
CFormView Class
3/27/2020 • 2 minutes to read • Edit Online

The base class used for form views.

Syntax
class CFormView : public CScrollView

Members
Protected Constructors
NAME DESC RIP T IO N

CFormView::CFormView Constructs a CFormView object.

Public Methods
NAME DESC RIP T IO N

CFormView::IsInitDlgCompleted Used for synchronization during initialization.

Remarks
A form view is essentially a view that contains controls. These controls are laid out based on a dialog-
template resource. Use CFormView if you want forms in your application. These views support scrolling, as
needed, using the CScrollView functionality.
When you are Creating a Forms-Based Application, you can base its view class on CFormView , making it a
forms-based application.
You can also insert new Form Topics into document-view-based applications. Even if your application did not
initially support forms, Visual C++ will add this support when you insert a new form.
The MFC Application Wizard and the Add Class command are the preferred methods for creating forms-
based applications. If you need to create a forms-based application without using these methods, see
Creating a Forms-Based Application.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CScrollView
CFormView

Requirements
Header : afxext.h

CFormView::CFormView
Constructs a CFormView object.

CFormView(LPCTSTR lpszTemplateName);
CFormView(UINT nIDTemplate);

Parameters
lpszTemplateName
Contains a null-terminated string that is the name of a dialog-template resource.
nIDTemplate
Contains the ID number of a dialog-template resource.
Remarks
When you create an object of a type derived from CFormView , invoke one of the constructors to create the
view object and identify the dialog resource on which the view is based. You can identify the resource either
by name (pass a string as the argument to the constructor) or by its ID (pass an unsigned integer as the
argument).
The form-view window and child controls are not created until CWnd::Create is called. CWnd::Create is called
by the framework as part of the document and view creation process, which is driven by the document
template.

NOTE
Your derived class must supply its own constructor. In the constructor, invoke the constructor,
CFormView::CFormView , with the resource name or ID as an argument as shown in the preceding class overview.

Example
// MyFormView.h

// CMyFormView form view

class CMyFormView : public CFormView


{
DECLARE_DYNCREATE(CMyFormView)

protected:
CMyFormView(); // protected constructor used by dynamic creation
virtual ~CMyFormView();

public:
enum
{
IDD = IDD_MYFORMVIEW
};
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext &dc) const;
#endif
#endif

protected:
virtual void DoDataExchange(CDataExchange *pDX); // DDX/DDV support

DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

// MyFormView.cpp

#include "MyFormView.h"

// CMyFormView

IMPLEMENT_DYNCREATE(CMyFormView, CFormView)

CMyFormView::CMyFormView()
: CFormView(CMyFormView::IDD)
{
}

CFormView::IsInitDlgCompleted
Used by MFC to ensure that initialization is completed before performing other operations.

BOOL IsInitDlgCompleted() const;

Return Value
True if the initialization function for this dialog has completed.

See also
MFC Sample SNAPVW
MFC Sample VIEWEX
CScrollView Class
Hierarchy Chart
CDialog Class
CScrollView Class
CFrameWnd Class
4/21/2020 • 29 minutes to read • Edit Online

Provides the functionality of a Windows single document interface (SDI) overlapped or pop-up frame
window, along with members for managing the window.

Syntax
class CFrameWnd : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CFrameWnd::CFrameWnd Constructs a CFrameWnd object.

Public Methods
NAME DESC RIP T IO N

CFrameWnd::ActivateFrame Makes the frame visible and available to the user.

CFrameWnd::BeginModalState Sets the frame window to modal.

CFrameWnd::Create Call to create and initialize the Windows frame window


associated with the CFrameWnd object.

CFrameWnd::CreateView Creates a view within a frame that is not derived from


CView .

CFrameWnd::DockControlBar Docks a control bar.

CFrameWnd::EnableDocking Allows a control bar to be docked.

CFrameWnd::EndModalState Ends the frame window's modal state. Enables all of the
windows disabled by BeginModalState .

CFrameWnd::FloatControlBar Floats a control bar.

CFrameWnd::GetActiveDocument Returns the active CDocument object.

CFrameWnd::GetActiveFrame Returns the active CFrameWnd object.

CFrameWnd::GetActiveView Returns the active CView object.

CFrameWnd::GetControlBar Retrieves the control bar.


NAME DESC RIP T IO N

CFrameWnd::GetDockState Retrieves the dock state of a frame window.

CFrameWnd::GetMenuBarState Retrieves the display state of the menu in the current


MFC application.

CFrameWnd::GetMenuBarVisibility Indicates whether the default behavior of the menu in


the current MFC application is either hidden or visible.

CFrameWnd::GetMessageBar Returns a pointer to the status bar belonging to the


frame window.

CFrameWnd::GetMessageString Retrieves message corresponding to a command ID.

CFrameWnd::GetTitle Retrieves the title of the related control bar.

CFrameWnd::InitialUpdateFrame Causes the OnInitialUpdate member function


belonging to all views in the frame window to be called.

CFrameWnd::InModalState Returns a value indicating whether or not a frame


window is in a modal state.

CFrameWnd::IsTracking Determines if splitter bar is currently being moved.

CFrameWnd::LoadAccelTable Call to load an accelerator table.

CFrameWnd::LoadBarState Call to restore control bar settings.

CFrameWnd::LoadFrame Call to dynamically create a frame window from


resource information.

CFrameWnd::NegotiateBorderSpace Negotiates border space in the frame window.

CFrameWnd::OnBarCheck Called whenever an action is performed on the specified


control bar.

CFrameWnd::OnContextHelp Handles SHIFT+F1 Help for in-place items.

CFrameWnd::OnSetPreviewMode Sets the application's main frame window into and out
of print-preview mode.

CFrameWnd::OnUpdateControlBarMenu Called by the framework when the associated menu is


updated.

CFrameWnd::RecalcLayout Repositions the control bars of the CFrameWnd object.

CFrameWnd::SaveBarState Call to save control bar settings.

CFrameWnd::SetActivePreviewView Designates the specified view to be the active view for


Rich Preview.

CFrameWnd::SetActiveView Sets the active CView object.


NAME DESC RIP T IO N

CFrameWnd::SetDockState Call to dock the frame window in the main window.

CFrameWnd::SetMenuBarState Sets the display state of the menu in the current MFC
application to hidden or displayed.

CFrameWnd::SetMenuBarVisibility Sets the default behavior of the menu in the current


MFC application to be either hidden or visible.

CFrameWnd::SetMessageText Sets the text of a standard status bar.

CFrameWnd::SetProgressBarPosition Sets current position for Windows 7 progress bar


displayed on taskbar.

CFrameWnd::SetProgressBarRange Sets range for Windows 7 progress bar displayed on


taskbar.

CFrameWnd::SetProgressBarState Sets the type and state of the progress indicator


displayed on a taskbar button.

CFrameWnd::SetTaskbarOverlayIcon Overloaded. Applies an overlay to a taskbar button to


indicate application status or a notification to the user.

CFrameWnd::SetTitle Sets the title of the related control bar.

CFrameWnd::ShowControlBar Call to show the control bar.

CFrameWnd::ShowOwnedWindows Shows all windows that are descendants of the


CFrameWnd object.

Protected Methods
NAME DESC RIP T IO N

CFrameWnd::OnCreateClient Creates a client window for the frame.

CFrameWnd::OnHideMenuBar Called before the menu in the current MFC application


is hidden.

CFrameWnd::OnShowMenuBar Called before the menu in the current MFC application


is displayed.

Public Data Members


NAME DESC RIP T IO N

CFrameWnd::m_bAutoMenuEnable Controls automatic enable and disable functionality for


menu items.

CFrameWnd::rectDefault Pass this static CRect as a parameter when creating a


CFrameWnd object to allow Windows to choose the
window's initial size and position.
Remarks
To create a useful frame window for your application, derive a class from CFrameWnd . Add member
variables to the derived class to store data specific to your application. Implement message-handler
member functions and a message map in the derived class to specify what happens when messages
are directed to the window.
There are three ways to construct a frame window:
Directly construct it using Create.
Directly construct it using LoadFrame.
Indirectly construct it using a document template.
Before you call either Create or LoadFrame , you must construct the frame-window object on the heap
using the C++ new operator. Before calling Create , you can also register a window class with the
AfxRegisterWndClass global function to set the icon and class styles for the frame.
Use the Create member function to pass the frame's creation parameters as immediate arguments.
LoadFrame requires fewer arguments than Create , and instead retrieves most of its default values
from resources, including the frame's caption, icon, accelerator table, and menu. To be accessible by
LoadFrame , all these resources must have the same resource ID (for example, IDR_MAINFRAME).

When a CFrameWnd object contains views and documents, they are created indirectly by the framework
instead of directly by the programmer. The CDocTemplate object orchestrates the creation of the frame,
the creation of the containing views, and the connection of the views to the appropriate document. The
parameters of the CDocTemplate constructor specify the CRuntimeClass of the three classes involved
(document, frame, and view). A CRuntimeClass object is used by the framework to dynamically create
new frames when specified by the user (for example, by using the File New command or the multiple
document interface (MDI) Window New command).
A frame-window class derived from CFrameWnd must be declared with DECLARE_DYNCREATE in order
for the above RUNTIME_CLASS mechanism to work correctly.
A CFrameWnd contains default implementations to perform the following functions of a main window in
a typical application for Windows:
A CFrameWnd frame window keeps track of a currently active view that is independent of the
Windows active window or the current input focus. When the frame is reactivated, the active
view is notified by calling CView::OnActivateView .
Command messages and many common frame-notification messages, including those handled
by the OnSetFocus , OnHScroll , and OnVScroll functions of CWnd , are delegated by a CFrameWnd
frame window to the currently active view.
The currently active view (or currently active MDI child frame window in the case of an MDI
frame) can determine the caption of the frame window. This feature can be disabled by turning
off the FWS_ADDTOTITLE style bit of the frame window.
A CFrameWnd frame window manages the positioning of the control bars, views, and other child
windows inside the frame window's client area. A frame window also does idle-time updating of
toolbar and other control-bar buttons. A CFrameWnd frame window also has default
implementations of commands for toggling on and off the toolbar and status bar.
A CFrameWnd frame window manages the main menu bar. When a pop-up menu is displayed,
the frame window uses the UPDATE_COMMAND_UI mechanism to determine which menu
items should be enabled, disabled, or checked. When the user selects a menu item, the frame
window updates the status bar with the message string for that command.
A CFrameWnd frame window has an optional accelerator table that automatically translates
keyboard accelerators.
A CFrameWnd frame window has an optional help ID set with LoadFrame that is used for context-
sensitive help. A frame window is the main orchestrator of semimodal states such as context-
sensitive help (SHIFT+F1) and print-preview modes.
A CFrameWnd frame window will open a file dragged from the File Manager and dropped on the
frame window. If a file extension is registered and associated with the application, the frame
window responds to the dynamic data exchange (DDE) open request that occurs when the user
opens a data file in the File Manager or when the ShellExecute Windows function is called.
If the frame window is the main application window (that is, CWinThread::m_pMainWnd ), when the
user closes the application, the frame window prompts the user to save any modified
documents (for OnClose and OnQueryEndSession ).
If the frame window is the main application window, the frame window is the context for
running WinHelp. Closing the frame window will shut down WINHELP.EXE if it was launched for
help for this application.
Do not use the C++ delete operator to destroy a frame window. Use CWnd::DestroyWindow instead. The
CFrameWnd implementation of PostNcDestroy will delete the C++ object when the window is
destroyed. When the user closes the frame window, the default OnClose handler will call
DestroyWindow .

For more information on CFrameWnd , see Frame Windows.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd

Requirements
Header : afxwin.h

CFrameWnd::ActivateFrame
Call this member function to activate and restore the frame window so that it is visible and available to
the user.

virtual void ActivateFrame(int nCmdShow = -1);

Parameters
nCmdShow
Specifies the parameter to pass to CWnd::ShowWindow. By default, the frame is shown and correctly
restored.
Remarks
This member function is usually called after a non-user interface event such as a DDE, OLE, or other
event that may show the frame window or its contents to the user.
The default implementation activates the frame and brings it to the top of the Z-order and, if necessary,
carries out the same steps for the application's main frame window.
Override this member function to change how a frame is activated. For example, you can force MDI
child windows to be maximized. Add the appropriate functionality, then call the base class version with
an explicit nCmdShow .
Example

void CChildFrame::ActivateFrame(int nCmdShow)


{
// Create the child frame window maximized
nCmdShow = SW_MAXIMIZE;

CMDIChildWnd::ActivateFrame(nCmdShow);
}

CFrameWnd::BeginModalState
Call this member function to make a frame window modal.

virtual void BeginModalState();

CFrameWnd::CFrameWnd
Constructs a CFrameWnd object, but does not create the visible frame window.

CFrameWnd();

Remarks
Call Create to create the visible window.

CFrameWnd::Create
Call to create and initialize the Windows frame window associated with the CFrameWnd object.

virtual BOOL Create(


LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle = WS_OVERLAPPEDWINDOW,
const RECT& rect = rectDefault,
CWnd* pParentWnd = NULL,
LPCTSTR lpszMenuName = NULL,
DWORD dwExStyle = 0,
CCreateContext* pContext = NULL);

Parameters
lpszClassName
Points to a null-terminated character string that names the Windows class. The class name can be any
name registered with the AfxRegisterWndClass global function or the RegisterClass Windows
function. If NULL, uses the predefined default CFrameWnd attributes.
lpszWindowName
Points to a null-terminated character string that represents the window name. Used as text for the title
bar.
dwStyle
Specifies the window style attributes. Include the FWS_ADDTOTITLE style if you want the title bar to
automatically display the name of the document represented in the window.
rect
Specifies the size and position of the window. The rectDefault value allows Windows to specify the size
and position of the new window.
pParentWnd
Specifies the parent window of this frame window. This parameter should be NULL for top-level frame
windows.
lpszMenuName
Identifies the name of the menu resource to be used with the window. Use MAKEINTRESOURCE if the
menu has an integer ID instead of a string. This parameter can be NULL.
dwExStyle
Specifies the window extended style attributes.
pContext
Specifies a pointer to a CCreateContext structure. This parameter can be NULL.
Return Value
Nonzero if initialization is successful; otherwise 0.
Remarks
Construct a CFrameWnd object in two steps. First, invoke the constructor, which constructs the
CFrameWnd object, and then call Create , which creates the Windows frame window and attaches it to
the CFrameWnd object. Create initializes the window's class name and window name and registers
default values for its style, parent, and associated menu.
Use LoadFrame rather than Create to load the frame window from a resource instead of specifying its
arguments.

CFrameWnd::CreateView
Call CreateView to create a view within a frame.

CWnd* CreateView(
CCreateContext* pContext,
UINT nID = AFX_IDW_PANE_FIRST);

Parameters
pContext
Specifies the type of view and document.
nID
The ID number of a view.
Return Value
Pointer to a CWnd object if successful; otherwise NULL.
Remarks
Use this member function to create "views" that are not CView -derived within a frame. After calling
CreateView , you must manually set the view to active and set it to be visible; these tasks are not
automatically performed by CreateView .

CFrameWnd::DockControlBar
Causes a control bar to be docked to the frame window.

void DockControlBar(
CControlBar* pBar,
UINT nDockBarID = 0,
LPCRECT lpRect = NULL);

Parameters
pBar
Points to the control bar to be docked.
nDockBarID
Determines which sides of the frame window to consider for docking. It can be 0, or one or more of the
following:
AFX_IDW_DOCKBAR_TOP Dock to the top side of the frame window.
AFX_IDW_DOCKBAR_BOTTOM Dock to the bottom side of the frame window.
AFX_IDW_DOCKBAR_LEFT Dock to the left side of the frame window.
AFX_IDW_DOCKBAR_RIGHT Dock to the right side of the frame window.
If 0, the control bar can be docked to any side enabled for docking in the destination frame window.
lpRect
Determines, in screen coordinates, where the control bar will be docked in the nonclient area of the
destination frame window.
Remarks
The control bar will be docked to one of the sides of the frame window specified in the calls to both
CControlBar::EnableDocking and CFrameWnd::EnableDocking. The side chosen is determined by
nDockBarID.

CFrameWnd::EnableDocking
Call this function to enable dockable control bars in a frame window.

void EnableDocking(DWORD dwDockStyle);

Parameters
dwDockStyle
Specifies which sides of the frame window can serve as docking sites for control bars. It can be one or
more of the following:
CBRS_ALIGN_TOP Allows docking at the top of the client area.
CBRS_ALIGN_BOTTOM Allows docking at the bottom of the client area.
CBRS_ALIGN_LEFT Allows docking on the left side of the client area.
CBRS_ALIGN_RIGHT Allows docking on the right side of the client area.
CBRS_ALIGN_ANY Allows docking on any side of the client area.
Remarks
By default, control bars will be docked to a side of the frame window in the following order: top,
bottom, left, right.
Example
See the example for CToolBar::Create.

CFrameWnd::EndModalState
Call this member function to change a frame window from modal to modeless.

virtual void EndModalState();

Remarks
EndModalState enables all of the windows disabled by BeginModalState.

CFrameWnd::FloatControlBar
Call this function to cause a control bar to not be docked to the frame window.

void FloatControlBar(
CControlBar* pBar,
CPoint point,
DWORD dwStyle = CBRS_ALIGN_TOP);

Parameters
pBar
Points to the control bar to be floated.
point
The location, in screen coordinates, where the top left corner of the control bar will be placed.
dwStyle
Specifies whether to align the control bar horizontally or vertically within its new frame window. It can
be any one of the following:
CBRS_ALIGN_TOP Orients the control bar vertically.
CBRS_ALIGN_BOTTOM Orients the control bar vertically.
CBRS_ALIGN_LEFT Orients the control bar horizontally.
CBRS_ALIGN_RIGHT Orients the control bar horizontally.
If styles are passed specifying both horizontal and vertical orientation, the toolbar will be oriented
horizontally.
Remarks
Typically, this is done at application startup when the program is restoring settings from the previous
execution.
This function is called by the framework when the user causes a drop operation by releasing the left
mouse button while dragging the control bar over a location that is not available for docking.

CFrameWnd::GetActiveDocument
Call this member function to obtain a pointer to the current CDocument attached to the current active
view.

virtual CDocument* GetActiveDocument();

Return Value
A pointer to the current CDocument. If there is no current document, returns NULL.

CFrameWnd::GetActiveFrame
Call this member function to obtain a pointer to the active multiple document interface (MDI) child
window of an MDI frame window.

virtual CFrameWnd* GetActiveFrame();

Return Value
A pointer to the active MDI child window. If the application is an SDI application, or the MDI frame
window has no active document, the implicit this pointer will be returned.
Remarks
If there is no active MDI child or the application is a single document interface (SDI), the implicit this
pointer is returned.

CFrameWnd::GetActiveView
Call this member function to obtain a pointer to the active view (if any) attached to a frame window (
CFrameWnd ).

CView* GetActiveView() const;

Return Value
A pointer to the current CView. If there is no current view, returns NULL.
Remarks
This function returns NULL when called for an MDI main frame window ( CMDIFrameWnd ). In an MDI
application, the MDI main frame window does not have a view associated with it. Instead, each
individual child window ( CMDIChildWnd ) has one or more associated views. The active view in an MDI
application can be obtained by first finding the active MDI child window and then finding the active
view for that child window. The active MDI child window can be found by calling the function
MDIGetActive or GetActiveFrame as demonstrated in the following:
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->GetMainWnd();

// Get the active MDI child window.


CMDIChildWnd *pChild = (CMDIChildWnd*)pFrame->GetActiveFrame();

// or CMDIChildWnd *pChild = pFrame->MDIGetActive();

// Get the active view attached to the active MDI child window.
CMyView *pView = (CMyView*)pChild->GetActiveView();

CFrameWnd::GetControlBar
Call GetControlBar to gain access to the control bar that is associated with the ID.

CControlBar* GetControlBar(UINT nID);

Parameters
nID
The ID number of a control bar.
Return Value
A pointer to the control bar that is associated with the ID.
Remarks
The nID parameter refers to the unique identifier passed to the Create method of the control bar. For
more information on control bars, refer to the topic entitled Control Bars.
GetControlBar will return the control bar even if it is floating and thus is not currently a child window
of the frame.

CFrameWnd::GetDockState
Call this member function to store state information about the frame window's control bars in a
CDockState object.

void GetDockState(CDockState& state) const;

Parameters
state
Contains the current state of the frame window's control bars upon return.
Remarks
You can then write the contents of CDockState to storage using CDockState::SaveState or Serialize . If
you later want to restore the control bars to a previous state, load the state with CDockState::LoadState
or Serialize , then call SetDockState to apply the previous state to the frame window's control bars.

CFrameWnd::GetMenuBarState
Retrieves the display state of the menu in the current MFC application.

virtual DWORD GetMenuBarState();


Return Value
The return value can have the following values:
AFX_MBS_VISIBLE (0x01) - The menu is visible.
AFX_MBS_HIDDEN (0x02) - The menu is hidden.
Remarks
If a runtime error occurs, this method asserts in Debug mode and raises an exception derived from the
CException class.

CFrameWnd::GetMenuBarVisibility
Indicates whether the default state of the menu in the current MFC application is hidden or visible.

virtual DWORD CFrameWnd::GetMenuBarVisibility();

Return Value
This method returns one of the following values:
AFX_MBV_KEEPVISIBLE (0x01) - The menu is displayed at all times, and by default does not have
the focus.
AFX_MBV_DISPLAYONFOCUS (0x02) - The menu is hidden by default. If the menu is hidden,
press the ALT key to display the menu and give it the focus. If the menu is displayed, press the
ALT or ESC key to hide it.
AFX_MBV_ DISPLAYONFOCUS (0x02) | AFX_MBV_DISPLAYONF10 (0x04) (bitwise combination
(OR)) - The menu is hidden by default. If the menu is hidden, press the F10 key to display the
menu and give it the focus. If the menu is displayed, press the F10 key to toggle the focus on or
off the menu. The menu is displayed until you press the ALT or ESC key to hide it.
Remarks
If a runtime error occurs, this method asserts in Debug mode and raises an exception derived from the
CException class.

CFrameWnd::GetMessageBar
Call this member function to get a pointer to the status bar.

virtual CWnd* GetMessageBar();

Return Value
Pointer to the status-bar window.

CFrameWnd::GetMessageString
Override this function to provide custom strings for command IDs.

virtual void GetMessageString(


UINT nID,
CString& rMessage) const;

Parameters
nID
Resource ID of the desired message.
rMessage
CString object into which to place the message.

Remarks
The default implementation simply loads the string specified by nID from the resource file. This
function is called by the framework when the message string in the status bar needs updating.

CFrameWnd::GetTitle
Retrieves the title of the window object.

CString GetTitle() const;

Return Value
A CString object containing the current title of the window object.

CFrameWnd::InitialUpdateFrame
Call IntitialUpdateFrame after creating a new frame with Create .

void InitialUpdateFrame(
CDocument* pDoc,
BOOL bMakeVisible);

Parameters
pDoc
Points to the document to which the frame window is associated. Can be NULL.
bMakeVisible
If TRUE, indicates that the frame should become visible and active. If FALSE, no descendants are made
visible.
Remarks
This causes all views in that frame window to receive their OnInitialUpdate calls.
Also, if there was not previously an active view, the primary view of the frame window is made active.
The primary view is a view with a child ID of AFX_IDW_PANE_FIRST. Finally, the frame window is made
visible if bMakeVisible is nonzero. If bMakeVisible is 0, the current focus and visible state of the frame
window will remain unchanged. It is not necessary to call this function when using the framework's
implementation of File New and File Open.

CFrameWnd::InModalState
Call this member function to check if a frame window is modal or modeless.

BOOL InModalState() const;

Return Value
Nonzero if yes; otherwise 0.
CFrameWnd::IsTracking
Call this member function to determine if the splitter bar in the window is currently being moved.

BOOL IsTracking() const;

Return Value
Nonzero if a splitter operation is in progress; otherwise 0.

CFrameWnd::LoadAccelTable
Call to load the specified accelerator table.

BOOL LoadAccelTable(LPCTSTR lpszResourceName);

Parameters
lpszResourceName
Identifies the name of the accelerator resource. Use MAKEINTRESOURCE if the resource is identified
with an integer ID.
Return Value
Nonzero if the accelerator table was successfully loaded; otherwise 0.
Remarks
Only one table can be loaded at a time.
Accelerator tables loaded from resources are freed automatically when the application terminates.
If you call LoadFrame to create the frame window, the framework loads an accelerator table along with
the menu and icon resources, and a subsequent call to this member function is then unnecessary.

CFrameWnd::LoadBarState
Call this function to restore the settings of each control bar owned by the frame window.

void LoadBarState(LPCTSTR lpszProfileName);

Parameters
lpszProfileName
Name of a section in the initialization (INI) file or a key in the Windows registry where state
information is stored.
Remarks
Information restored includes visibility, horizontal/vertical orientation, docking state, and control-bar
position.
The settings you want to restore must be written to the registry before you call LoadBarState . Write
the information to the registry by calling CWinApp::SetRegistryKey. Write the information to the INI file
by calling SaveBarState.

CFrameWnd::LoadFrame
Call to dynamically create a frame window from resource information.
virtual BOOL LoadFrame(
UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);

Parameters
nIDResource
The ID of shared resources associated with the frame window.
dwDefaultStyle
The frame's style. Include the FWS_ADDTOTITLE style if you want the title bar to automatically display
the name of the document represented in the window.
pParentWnd
A pointer to the frame's parent.
pContext
A pointer to a CCreateContext structure. This parameter can be NULL.
Remarks
Construct a CFrameWnd object in two steps. First, invoke the constructor, which constructs the
CFrameWnd object, and then call LoadFrame , which loads the Windows frame window and associated
resources and attaches the frame window to the CFrameWnd object. The nIDResource parameter
specifies the menu, the accelerator table, the icon, and the string resource of the title for the frame
window.
Use the Create member function rather than LoadFrame when you want to specify all of the frame
window's creation parameters.
The framework calls LoadFrame when it creates a frame window using a document template object.
The framework uses the pContext argument to specify the objects to be connected to the frame
window, including any contained view objects. You can set the pContext argument to NULL when you
call LoadFrame .

CFrameWnd::m_bAutoMenuEnable
When this data member is enabled (which is the default), menu items that do not have
ON_UPDATE_COMMAND_UI or ON_COMMAND handlers will be automatically disabled when the user
pulls down a menu.

BOOL m_bAutoMenuEnable;

Remarks
Menu items that have an ON_COMMAND handler but no ON_UPDATE_COMMAND_UI handler will be
automatically enabled.
When this data member is set, menu items are automatically enabled in the same way that toolbar
buttons are enabled.

NOTE
m_bAutoMenuEnable has no effect on top-level menu items.
This data member simplifies the implementation of optional commands based on the current selection
and reduces the need to write ON_UPDATE_COMMAND_UI handlers for enabling and disabling menu
items.
Example

// CMainFrame is application-defined object of type CFrameWnd


CMainFrame::CMainFrame()
: m_hDrawMenu(NULL), m_hDrawAccel(NULL), m_bCheck(false), m_nWindowTimer(0),
m_nCallbackTimer(0)
{
// Set to FALSE so no ON_UPDATE_COMMAND_UI
// or ON_COMMAND handlers are needed, and
// CMenu::EnableMenuItem() will work as expected.
m_bAutoMenuEnable = FALSE;
}

CFrameWnd::NegotiateBorderSpace
Call this member function to negotiate border space in a frame window during OLE inplace activation.

virtual BOOL NegotiateBorderSpace(


UINT nBorderCmd,
LPRECT lpRectBorder);

Parameters
nBorderCmd
Contains one of the following values from the enum BorderCmd :
borderGet =1
borderRequest =2
borderSet =3

lpRectBorder
Pointer to a RECT structure or a CRect object that specifies the coordinates of the border.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function is the CFrameWnd implementation of OLE border space negotiation.

CFrameWnd::OnBarCheck
Called whenever an action is performed on the specified control bar.

afx_msg BOOL OnBarCheck(UINT nID);

Parameters
nID
The ID of the control bar being shown.
Return Value
Nonzero if the control bar existed; otherwise 0.
CFrameWnd::OnContextHelp
Handles SHIFT+F1 Help for in-place items.

afx_msg void OnContextHelp();

Remarks
To enable context-sensitive help, you must add an

ON_COMMAND(ID_CONTEXT_HELP, &CMainFrame::OnContextHelp)

statement to your CFrameWnd class message map and also add an accelerator-table entry, typically
SHIFT+F1, to enable this member function.
If your application is an OLE Container, OnContextHelp puts all in-place items contained within the
frame window object into Help mode. The cursor changes to an arrow and a question mark, and the
user can then move the mouse pointer and press the left mouse button to select a dialog box, window,
menu, or command button. This member function calls the Windows function WinHelp with the Help
context of the object under the cursor.

CFrameWnd::OnCreateClient
Called by the framework during the execution of OnCreate .

virtual BOOL OnCreateClient(


LPCREATESTRUCT lpcs,
CCreateContext* pContext);

Parameters
lpcs
A pointer to a Windows CREATESTRUCT structure.
pContext
A pointer to a CCreateContext structure.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Never call this function.
The default implementation of this function creates a CView object from the information provided in
pContext, if possible.
Override this function to override values passed in the CCreateContext object or to change the way
controls in the main client area of the frame window are created. The CCreateContext members you
can override are described in the CCreateContext class.
NOTE
Do not replace values passed in the CREATESTRUCT structure. They are for informational use only. If you want
to override the initial window rectangle, for example, override the CWnd member function PreCreateWindow.

CFrameWnd::OnHideMenuBar
This function is called when the system is about to hide the menu bar in the current MFC application.

virtual void OnHideMenuBar();

Remarks
This event handler enables your application to perform custom actions when the system is about to
hide the menu. You cannot prevent the menu from being hidden, but you can, for example, call other
methods to retrieve the menu style or state.

CFrameWnd::OnSetPreviewMode
Call this member function to set the application's main frame window into and out of print-preview
mode.

virtual void OnSetPreviewMode(


BOOL bPreview,
CPrintPreviewState* pState);

Parameters
bPreview
Specifies whether or not to place the application in print-preview mode. Set to TRUE to place in print
preview, FALSE to cancel preview mode.
pState
A pointer to a CPrintPreviewState structure.
Remarks
The default implementation disables all standard toolbars and hides the main menu and the main client
window. This turns MDI frame windows into temporary SDI frame windows.
Override this member function to customize the hiding and showing of control bars and other frame
window parts during print preview. Call the base class implementation from within the overridden
version.

CFrameWnd::OnShowMenuBar
This function is called when the system is about to display the menu bar in the current MFC application.

virtual void OnShowMenuBar();

Remarks
This event handler enables your application to perform custom actions when the menu is about to be
displayed. You cannot prevent the menu from being displayed, but you can, for example, call other
methods to retrieve the menu style or state.
CFrameWnd::OnUpdateControlBarMenu
Called by the framework when the associated menu is updated.

afx_msg void OnUpdateControlBarMenu(CCmdUI* pCmdUI);

Parameters
pCmdUI
A pointer to a CCmdUI object representing the menu that generated the update command. The update
handler calls the Enable member function of the CCmdUI object through pCmdUI to update the user
interface.

CFrameWnd::RecalcLayout
Called by the framework when the standard control bars are toggled on or off or when the frame
window is resized.

virtual void RecalcLayout(BOOL bNotify = TRUE);

Parameters
bNotify
Determines whether the active in-place item for the frame window receives notification of the layout
change. If TRUE, the item is notified; otherwise FALSE.
Remarks
The default implementation of this member function calls the CWnd member function RepositionBars
to reposition all the control bars in the frame as well as in the main client window (usually a CView or
MDICLIENT).
Override this member function to control the appearance and behavior of control bars after the layout
of the frame window has changed. For example, call it when you turn control bars on or off or add
another control bar.

CFrameWnd::rectDefault
Pass this static CRect as a parameter when creating a window to allow Windows to choose the
window's initial size and position.

static AFX_DATA const CRect rectDefault;

CFrameWnd::SaveBarState
Call this function to store information about each control bar owned by the frame window.

void SaveBarState(LPCTSTR lpszProfileName) const;

Parameters
lpszProfileName
Name of a section in the initialization file or a key in the Windows registry where state information is
stored.
Remarks
This information can be read from the initialization file using LoadBarState. Information stored includes
visibility, horizontal/vertical orientation, docking state, and control bar position.

CFrameWnd::SetActivePreviewView
Designates the specified view to be the active view for Rich Preview.

void SetActivePreviewView(CView* pViewNew);

Parameters
pViewNew
A pointer to a view to be activated.
Remarks

CFrameWnd::SetActiveView
Call this member function to set the active view.

void SetActiveView(
CView* pViewNew,
BOOL bNotify = TRUE);

Parameters
pViewNew
Specifies a pointer to a CView object, or NULL for no active view.
bNotify
Specifies whether the view is to be notified of activation. If TRUE, OnActivateView is called for the new
view; if FALSE, it is not.
Remarks
The framework will call this function automatically as the user changes the focus to a view within the
frame window. You can explicitly call SetActiveView to change the focus to the specified view.

CFrameWnd::SetDockState
Call this member function to apply state information stored in a CDockState object to the frame
window's control bars.

void SetDockState(const CDockState& state);

Parameters
state
Apply the stored state to the frame window's control bars.
Remarks
To restore a previous state of the control bars, you can load the stored state with
CDockState::LoadState or Serialize , then use SetDockState to apply it to the frame window's control
bars. The previous state is stored in the CDockState object with GetDockState
CFrameWnd::SetMenuBarState
Sets the display state of the menu in the current MFC application to hidden or displayed.

virtual BOOL SetMenuBarState(DWORD nState);

Parameters
PA RA M ET ER DESC RIP T IO N

nState [in] Specifies whether to display or hide the menu. The


nState parameter can have the following values:

- AFX_MBS_VISIBLE (0x01) - Displays the menu if it is


hidden, but has no effect if it is visible.
- AFX_MBS_HIDDEN (0x02) - Hides the menu if it is
visible, but has no effect if it is hidden.

Return Value
TRUE if this method successfully changes the menu state; otherwise, FALSE.
Remarks
If a runtime error occurs, this method asserts in Debug mode and raises an exception derived from the
CException class.

CFrameWnd::SetMenuBarVisibility
Sets the default behavior of the menu in the current MFC application to be either hidden or visible.

virtual void SetMenuBarVisibility(DWORD nStyle);

Parameters
PA RA M ET ER DESC RIP T IO N

nStyle [in] Specifies whether the menu is by default hidden, or


is visible and has the focus. The nStyle parameter can
have the following values:

- AFX_MBV_KEEPVISIBLE (0x01) -
The menu is displayed at all times, and by default does
not have the focus.
- AFX_MBV_DISPLAYONFOCUS (0x02) -
The menu is hidden by default. If the menu is hidden,
press the ALT key to display the menu and give it the
focus. If the menu is displayed, press the ALT or ESC
key to hide menu.
- AFX_MBV_ DISPLAYONFOCUS (0x02) |
AFX_MBV_DISPLAYONF10 (0x04)
(bitwise combination (OR)) - The menu is hidden by
default. If the menu is hidden, press the F10 key to
display the menu and give it the focus. If the menu is
displayed, press the F10 key to toggle the focus on or
off the menu. The menu is displayed until you press the
ALT or ESC key to hide it.

Remarks
If the value of the nStyle parameter is not valid, this method asserts in Debug mode and raises
CInvalidArgException in Release mode. In case of other runtime errors, this method asserts in Debug
mode and raises an exception derived from the CException class.
This method affects the state of menus in applications written for Windows Vista and later.

CFrameWnd::SetMessageText
Call this function to place a string in the status-bar pane that has an ID of 0.

void SetMessageText(LPCTSTR lpszText);


void SetMessageText(UINT nID);

Parameters
lpszText
Points to the string to be placed on the status bar.
nID
String resource ID of the string to be placed on the status bar.
Remarks
This is typically the leftmost, and longest, pane of the status bar.

CFrameWnd::SetProgressBarPosition
Sets the current position for the Windows 7 progress bar displayed on the taskbar.

void SetProgressBarPosition(int nProgressPos);

Parameters
nProgressPos
Specifies the position to set. It must be within the range set by SetProgressBarRange .
Remarks

CFrameWnd::SetProgressBarRange
Sets the range for the Windows 7 progress bar displayed on the taskbar.

void SetProgressBarRange(
int nRangeMin,
int nRangeMax);

Parameters
nRangeMin
Minimal value.
nRangeMax
Maximal value.
Remarks

CFrameWnd::SetProgressBarState
Sets the type and state of the progress indicator displayed on a taskbar button.

void SetProgressBarState(TBPFLAG tbpFlags);

Parameters
tbpFlags
Flags that control the current state of the progress button. Specify only one of the following flags
because all states are mutually exclusive: TBPF_NOPROGRESS, TBPF_INDETERMINATE, TBPF_NORMAL,
TBPF_ERROR, TBPF_PAUSED.
Remarks

CFrameWnd::SetTaskbarOverlayIcon
Overloaded. Applies an overlay to a taskbar button to indicate application status or to notify the user.

BOOL SetTaskbarOverlayIcon(
UINT nIDResource,
LPCTSTR lpcszDescr);

BOOL SetTaskbarOverlayIcon(
HICON hIcon,
LPCTSTR lpcszDescr);

Parameters
nIDResource
Specifies the Resource ID of an icon to use as the overlay. See description for hIcon for details.
lpcszDescr
A pointer to a string that provides an alt text version of the information conveyed by the overlay, for
accessibility purposes.
hIcon
The handle of an icon to use as the overlay. This should be a small icon, measuring 16x16 pixels at 96
dots per inch (dpi). If an overlay icon is already applied to the taskbar button, that existing overlay is
replaced. This value can be NULL. How a NULL value is handled depends on whether the taskbar
button represents a single window or a group of windows. It is the responsibility of the calling
application to free hIcon when it is no longer needed.
Return Value
TRUE if successful; FALSE if OS version is less than Windows 7 or if an error occurs setting the icon.
Remarks

CFrameWnd::SetTitle
Sets the title of the window object.

void SetTitle(LPCTSTR lpszTitle);

Parameters
lpszTitle
A pointer to a character string containing the title of the window object.
CFrameWnd::ShowControlBar
Call this member function to show or hide the control bar.

void ShowControlBar(
CControlBar* pBar,
BOOL bShow,
BOOL bDelay);

Parameters
pBar
Pointer to the control bar to be shown or hidden.
bShow
If TRUE, specifies that the control bar is to be shown. If FALSE, specifies that the control bar is to be
hidden.
bDelay
If TRUE, delay showing the control bar. If FALSE, show the control bar immediately.

CFrameWnd::ShowOwnedWindows
Call this member function to show all windows that are descendants of the CFrameWnd object.

void ShowOwnedWindows(BOOL bShow);

Parameters
bShow
Specifies whether the owned windows are to be shown or hidden.

See also
CWnd Class
Hierarchy Chart
CWnd Class
CMDIFrameWnd Class
CMDIChildWnd Class
CView Class
CDocTemplate Class
CRuntimeClass Structure
CFrameWndEx Class
4/21/2020 • 31 minutes to read • Edit Online

Implements the functionality of a Windows single document interface (SDI) overlapped or popup frame window,
and provides members for managing the window. It extends the CFrameWnd class.

Syntax
class CFrameWndEx : public CFrameWnd

Members
Public Methods
NAME DESC RIP T IO N

CFrameWndEx::ActiveItemRecalcLayout Adjusts the layout of the OLE client item and the frame's
client area.

CFrameWndEx::AddDockSite This method is not used.

CFrameWndEx::AddPane Registers a control bar with the docking manager.

CFrameWndEx::AdjustDockingLayout Recalculates the layout of all panes that are docked to the
frame window.

CFrameWndEx::DelayUpdateFrameMenu Sets the frame menu and then updates it when command
processing is idle.

CFrameWndEx::DockPane Docks the specified pane to the frame window.

CFrameWndEx::DockPaneLeftOf Docks one pane to the left of another pane.

CFrameWndEx::EnableAutoHidePanes Enables the auto-hide mode for the panes when they are
docked to the specified sides of the main frame window.

CFrameWndEx::EnableDocking Enables the docking of the panes that belong to the frame
window.

CFrameWndEx::EnableFullScreenMainMenu Shows or hides the main menu in a full screen mode.

CFrameWndEx::EnableFullScreenMode Enables the full screen mode for the frame window.

CFrameWndEx::EnableLoadDockState Enables or disables the loading of the docking state.

CFrameWndEx::EnablePaneMenu Enables or disables the automatic handling of the pane menu.

CFrameWndEx::GetActivePopup Returns a pointer to the currently displayed pop-up menu.


NAME DESC RIP T IO N

CFrameWndEx::GetDefaultResId Returns the resource ID that you specified when the


framework loaded the frame window.

CFrameWndEx::GetDockingManager Retrieves the CDockingManager Class object for the frame


window.

CFrameWndEx::GetMenuBar Returns a pointer to the menu bar object attached to the


frame window.

CFrameWndEx::GetPane Returns a pointer to the pane that has the specified ID.

CFrameWndEx::GetRibbonBar Retrieves the ribbon bar control for the frame.

CFrameWndEx::GetTearOffBars Returns a list of pane objects that are in a tear-off state.

CFrameWndEx::GetToolbarButtonToolTipText Called by the framework when the application displays the


tooltip for a toolbar button.

CFrameWndEx::InsertPane Registers a pane with the docking manager.

CFrameWndEx::IsFullScreen Determines whether the frame window is in full screen mode.

CFrameWndEx::IsMenuBarAvailable Determines whether the pointer to the menu bar object is


valid.

CFrameWndEx::IsPointNearDockSite Indicates whether the point is located in an alignment zone.

CFrameWndEx::IsPrintPreview Indicates whether the frame window is in print preview mode.

CFrameWndEx::LoadFrame This method is called after construction to create the frame


window and load its resources.

CFrameWndEx::NegotiateBorderSpace Implements OLE client border negotiation.

CFrameWndEx::OnActivate The framework calls this method when user input is switched
to or away from the frame.

CFrameWndEx::OnActivateApp Called by the framework when the application is either


selected or deselected.

CFrameWndEx::OnChangeVisualManager Called by the framework when a change to the frame


requires a change to the visual manager.

CFrameWndEx::OnClose The framework calls this method to close the frame.

CFrameWndEx::OnCloseDockingPane Called by the framework when the user clicks the Close
button on a docking pane.

CFrameWndEx::OnCloseMiniFrame Called by the framework when the user clicks the Close
button on a floating mini frame window.
NAME DESC RIP T IO N

CFrameWndEx::OnClosePopupMenu Called by the framework when an active pop-up menu


processes a WM_DESTROY message.

CFrameWndEx::OnCmdMsg Dispatches command messages.

CFrameWndEx::OnContextHelp Called by the framework to display context related help.

CFrameWndEx::OnCreate Called by the framework after the frame is created.

CFrameWndEx::OnDestroy Called by the framework when the frame is destroyed.

CFrameWndEx::OnDrawMenuImage Called by the framework when the application draws the


image associated with a menu item.

CFrameWndEx::OnDrawMenuLogo Called by the framework when a CMFCPopupMenu object


processes a WM_PAINT message.

CFrameWndEx::OnDWMCompositionChanged Called by the framework when Desktop Window Manager


(DWM) composition has been enabled or disabled.

CFrameWndEx::OnExitSizeMove Called by the framework when the frame stops moving or


resizing.

CFrameWndEx::OnGetMinMaxInfo Called by the framework when the frame is resized to set


window dimension limits.

CFrameWndEx::OnIdleUpdateCmdUI Called by the framework to update the frame display when


command processing is idle.

CFrameWndEx::OnLButtonDown The framework calls this method when the user presses the
left mouse button.

CFrameWndEx::OnLButtonUp The framework calls this method when the user releases the
left mouse button.

CFrameWndEx::OnMenuButtonToolHitTest Called by the framework when a CMFCToolBarButton object


processes a WM_NCHITTEST message.

CFrameWndEx::OnMenuChar Called by the framework when a menu is displayed and the


user presses a key that does not correspond to a command.

CFrameWndEx::OnMouseMove The framework calls this method when the pointer moves.

CFrameWndEx::OnMoveMiniFrame Called by the framework when a pane window moves.

CFrameWndEx::OnNcActivate Called by the framework when the non-client area of the


frame must be redrawn to indicate a change in the active
state.

CFrameWndEx::OnNcCalcSize Called by the framework when the size and position of the
client area must be calculated.
NAME DESC RIP T IO N

CFrameWndEx::OnNcHitTest Called by the framework when the pointer moves or when a


mouse button is pressed or released.

CFrameWndEx::OnNcMouseMove Called by the framework when the pointer moves in a non-


client area.

CFrameWndEx::OnNcPaint Called by the framework when the non-client area must be


painted.

CFrameWndEx::OnPaneCheck Called by the framework to control the visibility of a pane.

CFrameWndEx::OnPostPreviewFrame Called by the framework when the user has changed the
print preview mode.

CFrameWndEx::OnPowerBroadcast Called by the framework when a power management event


occurs.

CFrameWndEx::OnSetMenu Called by the framework to replace the frame window menu.

CFrameWndEx::OnSetPreviewMode Called by the framework to set the print preview mode for
the frame.

CFrameWndEx::OnSetText Called by the framework to set the text of a window.

CFrameWndEx::OnShowCustomizePane Called by the framework when a quick customize pane is


enabled.

CFrameWndEx::OnShowPanes Called by the framework to show or hide panes.

CFrameWndEx::OnShowPopupMenu Called by the framework when a pop-up menu is enabled.

CFrameWndEx::OnSize The framework calls this method after the frame's size
changes.

CFrameWndEx::OnSizing The framework calls this method when the user resizes the
frame.

CFrameWndEx::OnSysColorChange Called by the framework when the system colors change.

CFrameWndEx::OnTearOffMenu Called by the framework when a menu that has a tear-off bar
is enabled.

CFrameWndEx::OnToolbarContextMenu Called by the framework to build a toolbar context menu.

CFrameWndEx::OnToolbarCreateNew The framework calls this method to create a new toolbar.

CFrameWndEx::OnToolbarDelete Called by the framework when a toolbar is deleted.

CFrameWndEx::OnUpdateFrameMenu Called by the framework to set the frame menu.

CFrameWndEx::OnUpdateFrameTitle The framework calls this method to update the title bar of the
frame window.
NAME DESC RIP T IO N

CFrameWndEx::OnUpdatePaneMenu Called by the framework to update the pane menu.

CFrameWndEx::OnWindowPosChanged Called by the framework when the frame size, position, or z-


order has changed because of a call to a window
management method.

CFrameWndEx::PaneFromPoint Returns the docking pane that contains the specified point.

CFrameWndEx::PreTranslateMessage Handles specific window messages before they are


dispatched.

CFrameWndEx::RecalcLayout Adjusts the layout of the frame and its child windows.

CFrameWndEx::RemovePaneFromDockManager Unregisters a pane and removes it from the internal list in the
docking manager.

CFrameWndEx::SetDockState Restores the docking layout to the docking state stored in


the registry.

CFrameWndEx::SetPrintPreviewFrame Sets the print preview frame window.

CFrameWndEx::SetupToolbarMenu Inserts user-defined commands into a toolbar menu.

CFrameWndEx::ShowFullScreen Switches the main frame between the full screen and the
regular modes.

CFrameWndEx::ShowPane Shows or hides the specified pane.

CFrameWndEx::UpdateCaption Called by the framework to update the window frame


caption.

CFrameWndEx::WinHelp Invokes either the WinHelp application or context related


help.

Example
The following example demonstrates how to inherit a class from the CFrameWndEx class. The example illustrates
the method signatures in the subclass, and how to override the OnShowPopupMenu method. This code snippet is
part of the Word Pad sample.

class CMainFrame : public CFrameWndEx


{
protected: // create from serialization only
CMainFrame();
DECLARE_DYNCREATE(CMainFrame)

// Attributes
public:
HICON m_hIconDoc;
HICON m_hIconText;
HICON m_hIconWrite;
HICON GetIcon(int nDocType);

// Operations
public:
void UpdateMRUFilesList()
{
m_wndTaskPane.UpdateMRUFilesList();
}

void OnChangeLook();

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual void ActivateFrame(int nCmdShow = -1);
virtual BOOL LoadFrame(UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd *pParentWnd = NULL,
CCreateContext *pContext = NULL);

protected:
virtual BOOL PreCreateWindow(CREATESTRUCT &cs);
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL

virtual BOOL OnShowPopupMenu(CMFCPopupMenu *pMenuPopup);


virtual BOOL OnTearOffMenu(CMFCPopupMenu *pMenuPopup, CPane *pBar);

protected:
void AdjustObjectSubmenu(CMFCPopupMenu *pMenuPopup);
void AdjustColorsMenu(CMFCPopupMenu *pMenuPopup, UINT uiId);

// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext &dc) const;
#endif

public:
CMFCMenuBar m_wndMenuBar;
CMFCToolBar m_wndToolBar;
CMFCStatusBar m_wndStatusBar;
CFormatBar m_wndFormatBar;
CRulerBar m_wndRulerBar;
CTaskPane m_wndTaskPane;

protected: // control bar embedded members


BOOL CreateMenuBar();
BOOL CreateToolBar();
BOOL CreateFormatBar();
BOOL CreateStatusBar();
BOOL CreateRulerBar();
BOOL CreateTaskPane();

// Generated message map functions


protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnSysColorChange();
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnMove(int x, int y);
afx_msg void OnHelpFinder();
afx_msg void OnDropFiles(HDROP hDropInfo);
afx_msg void OnFontChange();
afx_msg BOOL OnQueryNewPalette();
afx_msg void OnPaletteChanged(CWnd *pFocusWnd);
afx_msg void OnDevModeChange(LPTSTR lpDeviceName);
afx_msg void OnViewCustomize();
afx_msg void OnViewFullScreen();
//}}AFX_MSG
//}}AFX_MSG
afx_msg LRESULT OnBarState(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnOpenMsg(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnHelpCustomizeToolbars(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnStartCustomize(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnToolbarCreateNew(WPARAM, LPARAM);
afx_msg LRESULT OnGetDocumentColors(WPARAM, LPARAM);
afx_msg void OnDummy();
afx_msg void OnAskQuestion();
DECLARE_MESSAGE_MAP()
};

// CMainFrame is application-defined object of type CFrameWndEx


BOOL CMainFrame::OnShowPopupMenu(CMFCPopupMenu *pMenuPopup)
{
BOOL bRes = CFrameWndEx::OnShowPopupMenu(pMenuPopup);

if (pMenuPopup != NULL && !pMenuPopup->IsCustomizePane())


{
AdjustObjectSubmenu(pMenuPopup);
AdjustColorsMenu(pMenuPopup, ID_CHAR_COLOR);
}

return bRes;
}

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd
CFrameWndEx

Requirements
Header : afxframewndex.h

CFrameWndEx::ActiveItemRecalcLayout
Adjusts the layout of the OLE client item and the frame's client area.

void ActiveItemRecalcLayout();

Remarks

CFrameWndEx::AddPane
Registers a control bar with the docking manager.

BOOL AddPane(
CBasePane* pControlBar,
BOOL bTail=TRUE);

Parameters
pControlBar
[in] A control bar pane to register.
bTail
[in] TRUE if you want to add the control bar pane to the end of the list; FALSE otherwise.
Return Value
TRUE if the control bar was successfully registered; FALSE otherwise.

CFrameWndEx::AdjustDockingLayout
Recalculates the layout of all panes that are docked to the frame window.

virtual void AdjustDockingLayout(HDWP hdwp=NULL);

Parameters
hdwp
A handle to a structure that contains the positions of multiple windows. .
Remarks
The hdwp structure is initialized by the BeginDeferWindowPos method.

CFrameWndEx::DelayUpdateFrameMenu
Sets the frame menu and then updates it when command processing is idle.

virtual void DelayUpdateFrameMenu(HMENU hMenuAlt);

Parameters
hMenuAlt
[in] Handle to an alternative menu.
Remarks

CFrameWndEx::DockPane
Docks the specified pane to the frame window.

void DockPane(
CBasePane* pBar,
UINT nDockBarID=0,
LPCRECT lpRect=NULL);

Parameters
pBar
[in] A pointer to the control bar to be docked.
nDockBarID
[in] The ID of the side of the frame window to dock to.
lpRect
[in] A pointer to a constant Rect structure that specifies the window's screen position and size.
Remarks
The nDockBarID parameter can have one of the following values:
AFX_IDW_DOCKBAR_TOP
AFX_IDW_DOCKBAR_BOTTOM
AFX_IDW_DOCKBAR_LEFT
AFX_IDW_DOCKBAR_RIGHT

CFrameWndEx::DockPaneLeftOf
Docks the specified pane to the left of another pane.

BOOL DockPaneLeftOf(
CPane* pBar,
CPane* pLeftOf);

Parameters
pBar
[in] A pointer to the pane object to be docked.
pLeftOf
[in] A pointer to the pane to the left of which to dock the pane specified by pBar.
Return Value
TRUE if pBar is docked successfully. FALSE otherwise.
Remarks
The method takes the toolbar specified by the pBar parameter and docks it at the left side of the toolbar specified
by pLeftOf parameter.

CFrameWndEx::EnableAutoHidePanes
Enables auto-hide mode for the pane when it is docked to the specified side of the main frame window.

BOOL EnableAutoHidePanes(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the side of the main frame window to which to dock the pane.
Return Value
TRUE if a bar pane is successfully docked to the frame window side that is specified by dwDockStyle, FALSE
otherwise.
Remarks
dwDockStyle can have one of the following values:
CBRS_ALIGN_TOP: allows the control bar to be docked to the top of the client area of a frame window.
CBRS_ALIGN_BOTTOM: allows the control bar to be docked to the bottom of the client area of a frame
window.
CBRS_ALIGN_LEFT: allows the control bar to be docked to the left side of the client area of a frame window.
CBRS_ALIGN_RIGHT: allows the control bar to be docked to the right side of the client area of a frame
window.

CFrameWndEx::EnableDocking
Enables the docking of the panes of the frame window.

BOOL EnableDocking(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the side of the main frame window where the pane bar docks.
Return Value
TRUE if a bar pane can be successfully docked at the specified side. FALSE otherwise.
Remarks
The dwDockStyle parameter can have one of the following values:
CBRS_ALIGN_TOP
CBRS_ALIGN_BOTTOM
CBRS_ALIGN_LEFT
CBRS_ALIGN_RIGHT

CFrameWndEx::EnableFullScreenMainMenu
Shows or hides the main menu in a full screen mode.

void EnableFullScreenMainMenu(BOOL bEnableMenu);

Parameters
bEnableMenu
[in] TRUE to show the main menu in a full screen mode, FALSE otherwise.

CFrameWndEx::EnableFullScreenMode
Enables the full-screen mode for the frame window.

void EnableFullScreenMode(UINT uiFullScreenCmd);

Parameters
uiFullScreenCmd
[in] The ID of a command that enables and disables the full screen mode.
Remarks
In the full-screen mode, all docking control bars, toolbars and menu are hidden and the active view is resized to
occupy the full-screen.
When you enable the full-screen mode, you must specify an ID of the command that enables or disables the full-
screen mode. You can call EnableFullScreenMode from the main frame's OnCreate function. When a frame
window is being switched to a full-screen mode, the framework creates a floating toolbar with one button that
has the specified command ID.
If you want to keep the main menu on the screen, call CFrameWndEx::EnableFullScreenMainMenu.

CFrameWndEx::EnableLoadDockState
Enables or disables the loading of the docking state.

void EnableLoadDockState(BOOL bEnable=TRUE);

Parameters
bEnable
[in] TRUE to enable the loading of the docking state, FALSE to disable the loading of the docking state.

CFrameWndEx::EnablePaneMenu
Enables or disables the automatic handling of the pane menu.

void EnablePaneMenu(
BOOL bEnable,
UINT uiCustomizeCmd,
const CString& strCustomizeLabel,
UINT uiViewToolbarsMenuEntryID,
BOOL bContextMenuShowsToolbarsOnly=FALSE,
BOOL bViewMenuShowsToolbarsOnly=FALSE);

Parameters
bEnable
[in] TRUE to enable the automatic handling of the control bar pop-up menus; FALSE to disable the automatic
handling of the control bar pop-up menus.
uiCustomizeCmd
[in] The command ID of the Customize menu item.
strCustomizeLabel
[in] The label to be displayed for the Customize menu item
uiViewToolbarsMenuEntryID
[in] The ID of a toolbar menu item that opens the pop-up menu in the control bar.
bContextMenuShowsToolbarsOnly
[in] If TRUE, the control bar context menu displays the list of toolbars only. If FALSE, the menu displays the list of
the toolbars and the docking bars.
bViewMenuShowsToolbarsOnly
[in] If TRUE, the control bar menu displays the list of the toolbars only. If FALSE, the menu displays the list of the
toolbars and the docking bars.

CFrameWndEx::GetActivePopup
Returns a pointer to the currently displayed pop-up menu.

CMFCPopupMenu* GetActivePopup() const;


Return Value
A pointer to the currently displayed pop-up menu; otherwise NULL.

CFrameWndEx::GetDefaultResId
Returns the resource ID that you specified when the framework loaded the frame window.

UINT GetDefaultResId() const;

Return Value
The resource ID value that the user specified when the framework loaded the frame window. Zero if the frame
window does not have a menu bar.

CFrameWndEx::GetDockingManager
Retrieves the CDockingManager Class object for the frame window.

CDockingManager* GetDockingManager();

Return Value
A pointer to the CDockingManager Class.
Remarks
The frame window creates and uses a CDockingManager Class object to manage child window docking.

CFrameWndEx::GetMenuBar
Returns a pointer to the menu bar object attached to the frame window.

const CMFCMenuBar* GetMenuBar() const;

Return Value
A pointer to the menu bar object attached to the frame window.

CFrameWndEx::GetPane
Returns a pointer to the pane that has the specified ID.

CBasePane* GetPane(UINT nID);

Parameters
nID
[in] The control ID.
Return Value
A pointer to the pane that has the specified ID. NULL if no such pane exists.

CFrameWndEx::GetRibbonBar
Retrieves the ribbon bar control for the frame.
CMFCRibbonBar* GetRibbonBar();

Return Value
Pointer to the CMFCRibbonBar Class for the frame.
Remarks

CFrameWndEx::GetTearOffBars
Returns a list of pane objects that are in a tear-off state.

const CObList& GetTearOffBars() const;

Return Value
A reference to CObList object that contains a collection of pointers to the pane objects that are in a tear-off state.

CFrameWndEx::GetToolbarButtonToolTipText
Called by the framework when the application displays the tooltip for a toolbar button.

virtual BOOL GetToolbarButtonToolTipText(


CMFCToolBarButton* pButton,
CString& strTTText);

Parameters
pButton
[in] A pointer to a toolbar button.
strTTText
[in] The tooltip text to display for the button.
Return Value
TRUE if the tooltip has been displayed. FALSE otherwise.
Remarks
By default, this method does nothing. Override this method if you want to display the tooltip for the toolbar
button.

CFrameWndEx::InsertPane
Inserts a pane into a list of control bars and registers it with the docking manager.

BOOL InsertPane(
CBasePane* pControlBar,
CBasePane* pTarget,
BOOL bAfter=TRUE);

Parameters
pControlBar
A pointer to a control bar to be inserted into the list of control bars and registered with the docking manager.
pTarget
A pointer to a control bar before or after which to insert the pane.
bAfter
TRUE if you want to insert pControlBar after pTarget, FALSE otherwise.
Return Value
TRUE if the control bar was successfully inserted and registered, FALSE otherwise.
Remarks
You must register each control bar by using the CDockingManager Class to take a part in the docking layout.

CFrameWndEx::IsFullScreen
Determines whether the frame window is in full screen mode.

BOOL IsFullScreen() const;

Return Value
TRUE if the frame window is in full screen mode; otherwise FALSE.
Remarks
You can set the full screen mode by calling the CFrameWndEx::EnableFullScreenMode method.

CFrameWndEx::IsMenuBarAvailable
Determines whether the pointer to the menu bar object is valid.

BOOL IsMenuBarAvailable() const;

Return Value
TRUE if the frame window has a menu bar; otherwise FALSE.

CFrameWndEx::IsPointNearDockSite
Determines whether the point is located in an alignment zone.

BOOL IsPointNearDockSite(
CPoint point,
DWORD& dwBarAlignment,
BOOL& bOuterEdge) const;

Parameters
point
[in] The position of the point.
dwBarAlignment
[out] Where the point is aligned. See the table in the Remarks section for possible values.
bOuterEdge
[out] TRUE if the point is located close to the frame border; FALSE if the point is located in a client area.
Return Value
TRUE if the point is located in an alignment zone; otherwise, FALSE.
Remarks
The following table lists the possible values for the dwBarAlignment parameter.

CBRS_ALIGN_TOP Aligned to the top.

CBRS_ALIGN_RIGHT Aligned to the right.

CBRS_ALIGN_BOTTOM Aligned to the bottom.

CBRS_ALIGN_LEFT Aligned to the left.

CFrameWndEx::IsPrintPreview
Determines whether the frame window is in print preview mode.

BOOL IsPrintPreview();

Return Value
TRUE if the frame window is in print preview mode; otherwise, FALSE.
Remarks

CFrameWndEx::LoadFrame
This method is called after construction to create the frame window and load its resources.

virtual BOOL LoadFrame(


UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);

Parameters
nIDResource
[in] The resource ID that is used to load all frame resources.
dwDefaultStyle
[in] The default frame window style.
pParentWnd
[in] Pointer to the parent window of the frame.
pContext
[in] Pointer to a CCreateContext Structure class that is used by the framework during application creation.
Return Value
TRUE if the method was successful; otherwise, FALSE.
Remarks

CFrameWndEx::NegotiateBorderSpace
Implements OLE client border negotiation.
virtual BOOL NegotiateBorderSpace(
UINT nBorderCmd,
LPRECT lpRectBorder);

Parameters
nBorderCmd
[in] The border negotiation command. See the Remarks section for possible values.
lpRectBorder
[in, out] Dimensions of the border.
Return Value
TRUE if the layout must be recalculated; otherwise, FALSE.
Remarks
The following table lists the possible values for the nBorderCmd parameter.
borderGet
Get available OLE client space.
borderRequest
Request OLE client space.
borderSet
Set OLE client space.

CFrameWndEx::OnActivate
The framework calls this method when user input is switched to or away from the frame.

afx_msg void OnActivate(


UINT nState,
CWnd* pWndOther,
BOOL bMinimized);

Parameters
nState
[in] Whether the frame is active or inactive. See the table in the Remarks section for possible values.
pWndOther
[in] Pointer to another window that is switching user input with the current one.
bMinimized
[in] The minimized state of the frame. TRUE if the frame is minimized; otherwise, FALSE.
Remarks
The following table lists the possible values for the nState parameter.

WA_ACTIVE The frame is selected by a method other than a mouse click.

WA_CLICKACTIVE The frame is selected by a mouse click.

WA_INACTIVE The frame is not selected.


CFrameWndEx::OnActivateApp
Called by the framework when the application is either selected or deselected.

afx_msg void OnActivateApp(


BOOL bActive,
DWORD dwThreadID);

Parameters
bActive
[in] TRUE if the application is selected; FALSE if the application is not selected.
dwThreadID
[in] This parameter is not used.
Remarks

CFrameWndEx::OnChangeVisualManager
Called by the framework when a change to the frame requires a change to the visual manager.

afx_msg LRESULT OnChangeVisualManager(


WPARAM wParam,
LPARAM lParam);

Parameters
wParam
[in] This parameter is not used.
lParam
[in] This parameter is not used.
Return Value
Always returns 0.
Remarks

CFrameWndEx::OnClose
The framework calls this method to close the frame.

afx_msg void OnClose();

Remarks
If the frame is in print preview mode, it sends a Windows message to close the print preview; otherwise, if the
frame hosts an OLE client, the client is deactivated.

CFrameWndEx::OnCloseDockingPane
Called by the framework when the user clicks the Close button on a docking pane.

virtual BOOL OnCloseDockingPane(CDockablePane* pPane);


Return Value
TRUE if the docking bar can be closed. FALSE otherwise
Remarks
The default implement does nothing. Override this method if you want to handle the hiding of the docking bar.

CFrameWndEx::OnCloseMiniFrame
Called by the framework when the user clicks the Close button on a floating mini frame window.

virtual BOOL OnCloseMiniFrame(CPaneFrameWnd* pWnd);

Return Value
TRUE if a floating mini frame window can be closed. FALSE otherwise.
Remarks
The default implementation does nothing. Override this method if you want to process the hiding of a floating
mini frame window.

CFrameWndEx::OnClosePopupMenu
Called by the framework when an active pop-up menu processes a WM_DESTROY message.

virtual void OnClosePopupMenu(CMFCPopupMenu* pMenuPopup);

Parameters
pMenuPopup
A pointer to a pop-up menu.
Remarks
The framework sends a WM_DESTROY message when it is about to close the window. Override this method if
you want to handle notifications from CMFCPopupMenu objects that belong to the frame window when a
CMFCPopupMenu object is processing a WM_DESTROY message sent by the framework when the window is being
closed.

CFrameWndEx::OnCmdMsg
Dispatches command messages.

virtual BOOL OnCmdMsg(


UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);

Parameters
nID
[in] The command ID.
nCode
[in] Command message category.
pExtra
[in, out] Pointer to a command object.
pHandlerInfo
[in, out] Pointer to a command handler structure.
Return Value
TRUE if the command message was handled; otherwise, FALSE.
Remarks

CFrameWndEx::OnContextHelp
Called by the framework to display context-related help.

afx_msg void OnContextHelp();

Remarks

CFrameWndEx::OnCreate
Called by the framework after the frame is created.

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

Parameters
lpCreateStruct
[in] A pointer to the CREATESTRUCT Structure for the new frame.
Return Value
0 to continue with the frame creation; -1 to destroy the frame.
Remarks

CFrameWndEx::OnDestroy
Called by the framework when the frame is destroyed.

afx_msg void OnDestroy();

Remarks
The accelerator table and all windows are destroyed.

CFrameWndEx::OnDrawMenuImage
Called by the framework when the application draws the image associated with a menu item.

virtual BOOL OnDrawMenuImage(


CDC* pDC,
const CMFCToolBarMenuButton* pMenuButton,
const CRect& rectImage);

Parameters
pDC
[in] A pointer to a device context.
pMenuButton
[in] A pointer to a menu button whose image is being rendered.
rectImage
[in] A pointer to a Rect structure that specifies the screen position and size of the image.
Return Value
TRUE if the framework successfully renders the image; FALSE otherwise.
Remarks
Override this method if you want to customize the image rendering for the menu items that belong to the menu
bar owned by the CFrameWndEx derived object.

CFrameWndEx::OnDrawMenuLogo
Called by the framework when a CMFCPopupMenu object processes a WM_PAINT message.

virtual void OnDrawMenuLogo(


CDC* pDC,
CMFCPopupMenu* pMenu,
const CRect& rectLogo);

Parameters
pDC
[in] A pointer to a device context.
pMenu
[in] A pointer to the menu item.
rectLogo
[in] A reference to a constant CRect structure that specifies the screen position and size of the menu logo.
Remarks
Override this function if you want to display a logo on the pop-up menu that belongs to the menu bar owned by
the CFrameWndEx derived object.

CFrameWndEx::OnDWMCompositionChanged
Called by the framework when Desktop Window Manager (DWM) composition has been enabled or disabled.

afx_msg LRESULT OnDWMCompositionChanged(


WPARAM wp,
LPARAM lp);

Parameters
wp
[in] This parameter is not used.
lp
[in] This parameter is not used.
Return Value
Always returns 0.
Remarks

CFrameWndEx::OnExitSizeMove
Called by the framework when the frame stops moving or resizing.

LRESULT OnExitSizeMove(
WPARAM wp,
LPARAM lp);

Parameters
wp
[in] This parameter is not used.
lp
[in] This parameter is not used.
Return Value
Always returns 0.
Remarks

CFrameWndEx::OnGetMinMaxInfo
Called by the framework when the frame is resized to set window dimension limits.

afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);

Parameters
lpMMI
[in] Pointer to a MINMAXINFO structure.
Remarks

CFrameWndEx::OnIdleUpdateCmdUI
Called by the framework to update the frame display when command processing is idle.

afx_msg LRESULT OnIdleUpdateCmdUI(


WPARAM wParam = 0,
LPARAM lParam = 0);

Parameters
wParam
[in] This parameter is not used.
lParam
[in] This parameter is not used.
Return Value
Always returns 0.
Remarks
CFrameWndEx::OnLButtonDown
The framework calls this method when the user presses the left mouse button.

afx_msg void OnLButtonDown(


UINT nFlags,
CPoint point);

Parameters
nFlags
[in] Indicates whether the user pressed modifier keys. For possible values see the parameter wParam in
WM_LBUTTONDOWN Notification.
point
[in] Specifies the x and y coordinates of the pointer, relative to the upper-left corner of the window.
Remarks

CFrameWndEx::OnLButtonUp
The framework calls this method when the user releases the left mouse button.

afx_msg void OnLButtonUp(


UINT nFlags,
CPoint point);

Parameters
nFlags
[in] Indicates whether the user pressed modifier keys. For possible values see the parameter wParam in
WM_LBUTTONUP Notification.
point
[in] Specifies the x and y coordinates of the pointer, relative to the upper-left corner of the window.
Remarks

CFrameWndEx::OnMenuButtonToolHitTest
Called by the framework when a CMFCToolBarButton object processes a WM_NCHITTEST message.

virtual BOOL OnMenuButtonToolHitTest(


CMFCToolBarButton* pButton,
TOOLINFO* pTI);

Parameters
pButton
[in] A pointer to the tool bar button.
pTI
[out] A pointer to a tool information structure.
Return Value
TRUE if the application fills the pTI parameter. FALSE otherwise.
Remarks
Override this method if you want to provide a tooltip information about a specific menu item.

CFrameWndEx::OnMenuChar
Called by the framework when a menu is displayed and the user presses a key that does not correspond to a
command.

afx_msg LRESULT OnMenuChar(


UINT nChar,
UINT nFlags,
CMenu* pMenu);

Parameters
nChar
[in] Character code of the pressed key.
nFlags
[in] Contains the MF_POPUP flag if the menu displayed is a submenu; contains the MF_SYSMENU flag if the menu
displayed is a control menu.
pMenu
[in] Pointer to a menu.
Return Value
The high-order word must be one of the following values.

0 The framework should ignore the keystroke.

1 The framework should close the menu.

2 The framework should select one of the items displayed in


the menu. The low-order word contains the ID of the
command to select.

CFrameWndEx::OnMouseMove
The framework calls this method when the pointer moves.

afx_msg void OnMouseMove(


UINT nFlags,
CPoint point);

Parameters
nFlags
[in] Indicates whether a user pressed modifier keys. For possible values see the parameter wParam in
WM_MOUSEMOVE Notification.
point
[in] Specifies the x and y coordinates of the pointer relative to the upper-left corner of the window.
Remarks
CFrameWndEx::OnMoveMiniFrame
Called by the framework when a pane window moves.

virtual BOOL OnMoveMiniFrame(CWnd* pFrame);

Parameters
pFrame
[in] Pointer to the CPaneFrameWnd Class pane window.
Return Value
TRUE if the pane window was not docked; FALSE if the pane window was docked.
Remarks

CFrameWndEx::OnNcActivate
Called by the framework when the non-client area of the frame must be redrawn to indicate a change in the
active state.

afx_msg BOOL OnNcActivate(BOOL bActive);

Parameters
bActive
[in] TRUE to draw the frame active; FALSE to draw the frame inactive.
Return Value
Nonzero to continue with default processing; 0 to prevent the non-client area from being deactivated.
Remarks

CFrameWndEx::OnNcCalcSize
Called by the framework when the size and position of the client area must be calculated.

afx_msg void OnNcCalcSize(


BOOL bCalcValidRects,
NCCALCSIZE_PARAMS FAR* lpncsp);

Parameters
bCalcValidRects
[in] TRUE when the application must specify a valid client area; otherwise, FALSE.
lpncsp
[in] Pointer to a NCCALCSIZE_PARAMS structure that contains frame dimension changes.
Remarks

CFrameWndEx::OnNcHitTest
Called by the framework when the pointer moves or when a mouse button is pressed or released.

afx_msg LRESULT OnNcHitTest(CPoint point);


Parameters
point
[in] The location of the pointer in screen coordinates.
Return Value
A pointer hit enumerated value. For a list of possible values see WM_NCHITTEST Notification.
Remarks

CFrameWndEx::OnNcMouseMove
Called by the framework when the pointer moves in a non-client area.

afx_msg void OnNcMouseMove(


UINT nHitTest,
CPoint point);

Parameters
nHitTest
[in] A pointer hit enumerated value. For a list of possible values see WM_NCHITTEST Notification.
point
[in] The location of the pointer in screen coordinates.
Remarks

CFrameWndEx::OnNcPaint
Called by the framework when the non-client area must be painted.

afx_msg void OnNcPaint();

Remarks

CFrameWndEx::OnPaneCheck
Called by the framework to control the visibility of a pane.

afx_msg BOOL OnPaneCheck(UINT nID);

Parameters
nID
[in] Control ID of a pane.
Return Value
TRUE if the command was handled; FALSE to continue with command processing.
Remarks

CFrameWndEx::OnPostPreviewFrame
Called by the framework when the user changes the print preview mode.
afx_msg LRESULT OnPostPreviewFrame(
WPARAM wParam,
LPARAM lParam);

Parameters
wParam
[in] This parameter is not used.
lParam
[in] TRUE when the frame is in print preview mode; FALSE when print preview mode is off.
Return Value
Always returns 0.
Remarks

CFrameWndEx::OnPowerBroadcast
Called by the framework when a power management event occurs.

afx_msg LRESULT OnPowerBroadcast(


WPARAM wp,
LPARAM lp);

Parameters
wp
[in] The power management event. For a list of possible values see WM_POWERBROADCAST Message.
lp
[in] This parameter is not used.
Return Value
Result from calling the default window procedure.
Remarks

CFrameWndEx::OnSetMenu
Called by the framework to replace the frame window menu.

afx_msg LRESULT OnSetMenu(


WPARAM wp,
LPARAM lp);

BOOL OnSetMenu(HMENU hmenu);

Parameters
wp
[in] Handle to the new frame window menu.
lp
[in] Handle to the new window menu.
hmenu
[in] Handle to the new frame window menu.
Return Value
LRESULT is the result from calling the default window procedure.
BOOL is TRUE if the event was handled; otherwise, FALSE.
Remarks

CFrameWndEx::OnSetPreviewMode
Called by the framework to set the print preview mode for the frame.

virtual void OnSetPreviewMode(


BOOL bPreview,
CPrintPreviewState* pState);

Parameters
bPreview
[in] TRUE to enable print preview; FALSE to disable print preview.
pState
[in] Pointer to a CPrintPreviewState frame state structure.
Remarks

CFrameWndEx::OnSetText
Called by the framework to set the text of a window.

afx_msg LRESULT OnSetText(


WPARAM wParam,
LPARAM lParam);

Parameters
wParam
[in] This parameter is not used.
lParam
[in] Pointer to the text for the window.
Return Value
Return value from a call to DefWindowProc.
Remarks

CFrameWndEx::OnShowCustomizePane
Called by the framework when it displays a QuickCustomizePane .

virtual BOOL OnShowCustomizePane(


CMFCPopupMenu* pMenuPane,
UINT uiToolbarID);

Parameters
pMenuPane
[in] A pointer to the quick customize pane.
uiToolbarID
[in] The control ID of the toolbar to customize.
Return Value
This method always return TRUE.
Remarks
The quick customize menu is a pop-up menu that appears when you click the toolbar’s customize button

CFrameWndEx::OnShowPanes
Called by the framework to show or hide panes.

virtual BOOL OnShowPanes(BOOL bShow);

Parameters
bShow
[in] TRUE if the application shows the panes; FALSE otherwise.
Return Value
This method always return FALSE.
Remarks
The default implementation shows the panes if bShow is TRUE and the panes are hidden or when bShow is FALSE
and the panes are visible.
The default implementation hides the panes if bShow is TRUE and the panes are visible or when bShow is FALSE
and the panes are hidden.
Override this method in a derived class to execute custom code when the framework shows or hides panes.

CFrameWndEx::OnShowPopupMenu
Called by the framework when it displays a pop-up menu.

virtual BOOL OnShowPopupMenu(CMFCPopupMenu* pMenu);

Parameters
pMenu
[in] A pointer to a pop-up menu.
Return Value
TRUE if the pop-up menu is visible; otherwise FALSE.
Remarks
Override this method in a derived class to execute custom code when the framework displays a pop-up menu. For
example, override this method to change the background color of the commands in a pop-up menu.

CFrameWndEx::OnSize
Called by the framework after the frame's size changes.
afx_msg void OnSize(
UINT nType,
int cx,
int cy);

Parameters
nType
[in] The type of resizing. For possible values see the parameter wParam in WM_SIZE Notification.
cx
[in] New width of the frame in pixels.
cy
[in] New height of the frame in pixels.
Remarks

CFrameWndEx::OnSizing
Called by the framework when the user resizes the frame.

afx_msg void OnSizing(


UINT fwSide,
LPRECT pRect);

Parameters
fwSide
[in] The edge of the frame that is moved. See the parameter wParam in WM_SIZING Notification.
pRect
[in, out] Pointer to a CRect or RECT structure that contains the frame's coordinates.
Remarks

CFrameWndEx::OnSysColorChange
Called by the framework when the system colors change.

void OnSysColorChange();

Remarks

CFrameWndEx::OnTearOffMenu
Called by the framework when the application displays a menu that has a tear-off bar.

virtual BOOL OnTearOffMenu(


CMFCPopupMenu* pMenuPopup,
CPane* pBar);

Parameters
pMenuPopup
[in] A pointer to a pop-up menu.
pBar
[in] A pointer to a tear-off bar.
Return Value
TRUE if the pop-up menu with the tear-off bar is enabled; otherwise FALSE.
Remarks
Override this method in a derived class to execute custom code when the framework displays a control bar.
The default implementation does nothing and returns TRUE.

CFrameWndEx::OnToolbarContextMenu
Called by the framework to build a toolbar pop-up menu.

afx_msg LRESULT OnToolbarContextMenu(


WPARAM wp,
LPARAM lp);

Parameters
wp
[in] This parameter is not used.
lp
[in] This parameter is not used.
Return Value
Always returns 1.
Remarks

CFrameWndEx::OnToolbarCreateNew
The framework calls this method to create a new toolbar.

afx_msg LRESULT OnToolbarCreateNew(


WPARAM wp,
LPARAM lp);

Parameters
wp
[in] This parameter is not used.
lp
[in] Pointer to the text for the title bar of the toolbar.
Return Value
Pointer to the new toolbar; or NULL if a toolbar was not created.
Remarks

CFrameWndEx::OnToolbarDelete
Called by the framework when a toolbar is deleted.
afx_msg LRESULT OnToolbarDelete(
WPARAM /* unused */,
LPARAM lp);

Parameters
unused
[in] This parameter is not used.
lp
[in] Pointer to a toolbar.
Return Value
TRUE if the toolbar was deleted; otherwise, FALSE.
Remarks

CFrameWndEx::OnUpdateFrameMenu
Called by the framework to set the frame menu.

virtual void OnUpdateFrameMenu(HMENU hMenuAlt);

Parameters
hMenuAlt
[in] Handle to the alternative menu.
Remarks

CFrameWndEx::OnUpdateFrameTitle
The framework calls this method to update the title bar of the frame window.

virtual void OnUpdateFrameTitle(BOOL bAddToTitle);

Parameters
bAddToTitle
[in] TRUE to add the active document title to the frame window title bar; otherwise FALSE.
Remarks

CFrameWndEx::OnUpdatePaneMenu
Called by the framework to update the pane menu.

afx_msg void OnUpdatePaneMenu(CCmdUI* pCmdUI);

Parameters
pCmdUI
[in] Pointer to the pane user interface object.
Remarks
CFrameWndEx::OnWindowPosChanged
Called by the framework when the frame size, position, or z-order has changed because of a call to a window
management method.

afx_msg void OnWindowPosChanged(WINDOWPOS FAR* lpwndpos);

Parameters
lpwndpos
[in] Pointer to a WINDOWPOS structure that contains the new size and position.
Remarks

CFrameWndEx::PaneFromPoint
Searches each pane for the given point.

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
bool bExactBar,
CRuntimeClass* pRTCBarType) const;

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
DWORD& dwAlignment,
CRuntimeClass* pRTCBarType) const;

Parameters
point
[in] The screen coordinates of the point to check.
nSensitivity
[in] Expand the bounding rectangle of each control bar by this amount when searching for point.
bExactBar
[in] TRUE to ignore the nSensitivity parameter; otherwise, FALSE.
pRTCBarType
[in] If not NULL, the method searches only the control bars of the specified type.
dwAlignment
[out] If successful, this parameter contains the side of the control bar that is closest to the specified point.
Otherwise, this parameter is not initialized.
Return Value
A pointer to a control bar that contains the point; NULL if no control is found.
Remarks
This method searches all the control bars in your application for a point.
Use nSensitivity to increase the size of the search area. Use pRTCBarType to restrict the types of control bars that
the method searches.

CFrameWndEx::PreTranslateMessage
Handles specific window messages before they are dispatched.

virtual BOOL PreTranslateMessage(MSG* pMsg);

Parameters
pMsg
[in] A pointer to a MSG structure that contains the message to process.
Return Value
Non-zero if the message was handled and should not be dispatched; 0 if the message was not handled and
should be dispatched.
Remarks

CFrameWndEx::RecalcLayout
Adjusts the layout of the frame and its child windows.

virtual void RecalcLayout(BOOL bNotify = TRUE);

Parameters
bNotify
[in] Specifies whether to notify the OLE client item about the layout change.
Remarks
This method is called when the size of the frame window has changed or when control bars are displayed or
hidden.

CFrameWndEx::RemovePaneFromDockManager
Unregisters a pane and removes it from the docking manager.

void RemovePaneFromDockManager(
CBasePane* pControlBar,
BOOL bDestroy,
BOOL bAdjustLayout,
BOOL bAutoHide,
CBasePane* pBarReplacement);

Parameters
pControlBar
[in] A pointer to the control bar pane to remove.
bDestroy
[in] TRUE to destroy the control bar after removing it; FALSE otherwise.
bAdjustLayout
[in] TRUE to adjust the docking layout; FALSE otherwise.
bAutoHide
[in] TRUE if the control bar is in auto-hide mode; FALSE otherwise.
pBarReplacement
[in] A pointer to a pane that replaces the removed pane.
Remarks
Use this method to remove a control bar from the docking layout of the frame window.
The CDockingManager Class handles the layout of control bars. You must register each control bar with the
docking manager by using the CFrameWndEx::AddPane method or the CFrameWndEx::InsertPane method.

CFrameWndEx::SetDockState
Restores the docking layout to the docking state stored in the registry.

void SetDockState(const CDockState& state);

Parameters
state
The docking state. This parameter is ignored.

CFrameWndEx::SetPrintPreviewFrame
Sets the print preview frame window.

void SetPrintPreviewFrame(CFrameWnd* pWnd);

Parameters
pWnd
[in] Pointer to a print preview frame window.
Remarks

CFrameWndEx::SetupToolbarMenu
Inserts user-defined commands into a toolbar menu.

void SetupToolbarMenu(
CMenu& menu,
const UINT uiViewUserToolbarCmdFirst,
const UINT uiViewUserToolbarCmdLast);

Parameters
menu
[in] A CMenu object to be modified.
uiViewUserToolbarCmdFirst
[in] The first user-defined command.
uiViewUserToolbarCmdLast
[in] The last user-defined command.
Remarks
The framework stores user-defined commands in a list. Use uiViewUserToolbarCmdFirst and
uiViewUserToolbarCmdList to specify the indexes of the commands to insert.

CFrameWndEx::ShowFullScreen
Switches the main frame between full-screen mode and regular mode.

void ShowFullScreen();

CFrameWndEx::ShowPane
Shows or hides the specified pane.

void ShowPane(
CBasePane* pBar,
BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
pBar
[in] A pointer to the control bar to show or hide.
bShow
[in] If TRUE, the application shows the control bar. Otherwise, the application hides the control bar.
bDelay
[in] If TRUE, delay the adjustment of the docking layout until the framework calls
CFrameWndEx::AdjustDockingLayout. Otherwise, recalculate the docking layout immediately.
bActivate
[in] If TRUE, make the control bar active. Otherwise, display the control bar in an inactive state.

CFrameWndEx::UpdateCaption
Called by the framework to update the window frame caption.

void UpdateCaption();

Remarks

CFrameWndEx::WinHelp
Invokes either the WinHelp application or context related help.

virtual void WinHelp(


DWORD dwData,
UINT nCmd = HELP_CONTEXT);

Parameters
dwData
Data that depends on the nCmd parameter. For a list of possible values see WinHelp.
nCmd
The help command. For a list of possible values see WinHelp.
Remarks
See also
Hierarchy Chart
Classes
CFrameWnd
CFtpConnection Class
3/27/2020 • 14 minutes to read • Edit Online

Manages your FTP connection to an Internet server and allows direct manipulation of directories and files on
that server.

Syntax
class CFtpConnection : public CInternetConnection

Members
Public Constructors
NAME DESC RIP T IO N

CFtpConnection::CFtpConnection Constructs a CFtpConnection object.

Public Methods
NAME DESC RIP T IO N

CFtpConnection::Command Sends a command directly to an FTP server.

CFtpConnection::CreateDirectory Creates a directory on the server.

CFtpConnection::GetCurrentDirectory Gets the current directory for this connection.

CFtpConnection::GetCurrentDirectoryAsURL Gets the current directory for this connection as a URL.

CFtpConnection::GetFile Gets a file from the connected server

CFtpConnection::OpenFile Opens a file on the connected server.

CFtpConnection::PutFile Places a file on the server.

CFtpConnection::Remove Removes a file from the server.

CFtpConnection::RemoveDirectory Removes the specified directory from the server.

CFtpConnection::Rename Renames a file on the server.

CFtpConnection::SetCurrentDirectory Sets the current FTP directory.

Remarks
FTP is one of the three Internet services recognized by the MFC WinInet classes.
To communicate with an FTP Internet server, you must first create an instance of CInternetSession, and then
create a CFtpConnection object. You never create a CFtpConnection object directly; rather, call
CInternetSession::GetFtpConnection, which creates the CFtpConnection object and returns a pointer to it.
To learn more about how CFtpConnection works with the other MFC Internet classes, see the article Internet
Programming with WinInet. For more information about communicating with the other two supported services,
HTTP and gopher, see the classes CHttpConnection and CGopherConnection.

Example
See the example in the CFtpFileFind class overview.

Inheritance Hierarchy
CObject
CInternetConnection
CFtpConnection

Requirements
Header : afxinet.h

CFtpConnection::CFtpConnection
This member function is called to construct a CFtpConnection object.

CFtpConnection(
CInternetSession* pSession,
HINTERNET hConnected,
LPCTSTR pstrServer,
DWORD_PTR dwContext);

CFtpConnection(
CInternetSession* pSession,
LPCTSTR pstrServer,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
DWORD_PTR dwContext = 0,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
BOOL bPassive = FALSE);

Parameters
pSession
A pointer to the related CInternetSession object.
hConnected
The Windows handle of the current Internet session.
pstrServer
A pointer to a string containing the FTP server name.
dwContext
The context identifier for the operation. dwContext identifies the operation's status information returned by
CInternetSession::OnStatusCallback. The default is set to 1; however, you can explicitly assign a specific context
ID for the operation. The object and any work it does will be associated with that context ID.
pstrUserName
Pointer to a null-terminated string that specifies the name of the user to log in. If NULL, the default is
anonymous.
pstrPassword
A pointer to a null-terminated string that specifies the password to use to log in. If both pstrPassword and
pstrUserName are NULL, the default anonymous password is the user's email name. If pstrPassword is NULL (or
an empty string) but pstrUserName is not NULL, a blank password is used. The following table describes the
behavior for the four possible settings of pstrUserName and pstrPassword:

USERN A M E SEN T TO F T P PA SSW O RD SEN T TO F T P


P ST RUSERN A M E P ST RPA SSWO RD SERVER SERVER

NULL or " " NULL or " " "anonymous" User's email name

Non- NULL String NULL or " " pstrUserName ""

NULL Non- NULL String ERROR ERROR

Non- NULL String Non- NULL String pstrUserName pstrPassword

nPort
A number that identifies the TCP/IP port to use on the server.
bPassive
Specifies passive or active mode for this FTP session. If set to TRUE, it sets the Win32 API dwFlag to
INTERNET_FLAG_PASSIVE.
Remarks
You never create a CFtpConnection object directly. Instead, call CInternetSession::GetFtpConnection, which
creates the CFptConnection object.

CFtpConnection::Command
Sends a command directly to an FTP server.

CInternetFile* Command(
LPCTSTR pszCommand,
CmdResponseType eResponse = CmdRespNone,
DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY,
DWORD_PTR dwContext = 1);

Parameters
pszCommand
A pointer to a string containing the command to be sent.
eResponse
Specifies whether a response is expected from the FTP server. Can be one of the following values:
CmdRespNone No response is expected.
CmdRespRead A response is expected.
CmdRespWrite Not used.

The CmdResponseType is a member of CFtpConnection, defined in afxinet.h.


dwFlags
A value containing the flags that control this function. For a complete list, see FTPCommand.
dwContext
A pointer to a value containing an application-defined value used to identify the application context in callbacks.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function emulates the functionality of the FTPCommand function, as described in the Windows
SDK.
If an error occurs, MFC throws an exception of type CInternetException.

CFtpConnection::CreateDirectory
Call this member function to create a directory on the connected server.

BOOL CreateDirectory(LPCTSTR pstrDirName);

Parameters
pstrDirName
A pointer to a string containing the name of the directory to create.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Windows function GetLastError may be called to
determine the cause of the error.
Remarks
Use GetCurrentDirectory to determine the current working directory for this connection to the server. Do not
assume that the remote system has connected you to the root directory.
The pstrDirName parameter can be either a partially or a fully qualified filename relative to the current
directory. A backslash (\) or forward slash (/) can be used as the directory separator for either name.
CreateDirectory translates the directory name separators to the appropriate characters before they are used.

CFtpConnection::GetCurrentDirectory
Call this member function to get the name of the current directory.

BOOL GetCurrentDirectory(CString& strDirName) const;

BOOL GetCurrentDirectory(
LPTSTR pstrDirName,
LPDWORD lpdwLen) const;

Parameters
strDirName
A reference to a string that will receive the name of the directory.
pstrDirName
A pointer to a string that will receive the name of the directory.
lpdwLen
A pointer to a DWORD that contains the following information:
On entry The size of the buffer referenced by pstrDirName.

On return The number of characters stored to pstrDirName. If the


member function fails and ERROR_INSUFFICIENT_BUFFER is
returned, then lpdwLen contains the number of bytes that
the application must allocate in order to receive the string.

Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
To get the directory name as a URL instead, call GetCurrentDirectoryAsURL.
The parameters pstrDirName or strDirName can be either partially qualified filenames relative to the current
directory or fully qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either
name. GetCurrentDirectory translates the directory name separators to the appropriate characters before they
are used.

CFtpConnection::GetCurrentDirectoryAsURL
Call this member function to get the current directory's name as a URL.

BOOL GetCurrentDirectoryAsURL(CString& strDirName) const;

BOOL GetCurrentDirectoryAsURL(
LPTSTR pstrName,
LPDWORD lpdwLen) const;

Parameters
strDirName
A reference to a string that will receive the name of the directory.
pstrDirName
A pointer to a string that will receive the name of the directory.
lpdwLen
A pointer to a DWORD that contains the following information:

On entry The size of the buffer referenced by pstrDirName.

On return The number of characters stored to pstrDirName. If the


member function fails and ERROR_INSUFFICIENT_BUFFER is
returned, then lpdwLen contains the number of bytes that
the application must allocate in order to receive the string.

Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
GetCurrentDirectoryAsURL behaves the same as GetCurrentDirectory
The parameter strDirName can be either partially qualified filenames relative to the current directory or fully
qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either name.
GetCurrentDirectoryAsURL translates the directory name separators to the appropriate characters before they
are used.

CFtpConnection::GetFile
Call this member function to get a file from an FTP server and store it on the local machine.

BOOL GetFile(
LPCTSTR pstrRemoteFile,
LPCTSTR pstrLocalFile,
BOOL bFailIfExists = TRUE,
DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL,
DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY,
DWORD_PTR dwContext = 1);

Parameters
pstrRemoteFile
A pointer to a null-terminated string containing the name of a file to retrieve from the FTP server.
pstrLocalFile
A pointer to a null-terminated string containing the name of the file to create on the local system.
bFailIfExists
Indicates whether the file name may already be used by an existing file. If the local file name already exists, and
this parameter is TRUE, GetFile fails. Otherwise, GetFile will erase the existing copy of the file.
dwAttributes
Indicates the attributes of the file. This can be any combination of the following FILE_ATTRIBUTE_* flags.
FILE_ATTRIBUTE_ARCHIVE The file is an archive file. Applications use this attribute to mark files for
backup or removal.
FILE_ATTRIBUTE_COMPRESSED The file or directory is compressed. For a file, compression means that all
of the data in the file is compressed. For a directory, compression is the default for newly created files
and subdirectories.
FILE_ATTRIBUTE_DIRECTORY The file is a directory.
FILE_ATTRIBUTE_NORMAL The file has no other attributes set. This attribute is valid only if used alone. All
other file attributes override FILE_ATTRIBUTE_NORMAL:
FILE_ATTRIBUTE_HIDDEN The file is hidden. It is not to be included in an ordinary directory listing.
FILE_ATTRIBUTE_READONLY The file is read only. Applications can read the file but cannot write to it or
delete it.
FILE_ATTRIBUTE_SYSTEM The file is part of or is used exclusively by the operating system.
FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary storage. Applications should write to
the file only if absolutely necessary. Most of the file's data remains in memory without being flushed to
the media because the file will soon be deleted.
dwFlags
Specifies the conditions under which the transfer occurs. This parameter can be any of the dwFlags values
described in FtpGetFile in the Windows SDK.
dwContext
The context identifier for the file retrieval. See Remarks for more information about dwContext.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
GetFile is a high-level routine that handles all of the overhead associated with reading a file from an FTP
server and storing it locally. Applications that only retrieve file data, or that require close control over the file
transfer, should use OpenFile and CInternetFile::Read instead.
If dwFlags is FILE_TRANSFER_TYPE_ASCII, translation of file data also converts control and formatting characters
to Windows equivalents. The default transfer is binary mode, where the file is downloaded in the same format
as it is stored on the server.
Both pstrRemoteFile and pstrLocalFile can be either partially qualified filenames relative to the current directory
or fully qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either name.
GetFile translates the directory name separators to the appropriate characters before they are used.

Override the dwContext default to set the context identifier to a value of your choosing. The context identifier is
associated with this specific operation of the CFtpConnection object created by its CInternetSession object. The
value is returned to CInternetSession::OnStatusCallback to provide status on the operation with which it is
identified. See the article Internet First Steps: WinInet for more information about the context identifier.

CFtpConnection::OpenFile
Call this member function to open a file located on an FTP server for reading or writing.

CInternetFile* OpenFile(
LPCTSTR pstrFileName,
DWORD dwAccess = GENERIC_READ,
DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY,
DWORD_PTR dwContext = 1);

Parameters
pstrFileName
A pointer to a string containing the name of the file to be opened.
dwAccess
Determines how the file will be accessed. Can be either GENERIC_READ or GENERIC_WRITE, but not both.
dwFlags
Specifies the conditions under which subsequent transfers occur. This can be any of the following
FTP_TRANSFER_* constants:
FTP_TRANSFER_TYPE_ASCII The file transfers using FTP ASCII (Type A) transfer method. Converts control
and formatting information to local equivalents.
FTP_TRANSFER_TYPE_BINARY The file transfers data using FTP's Image (Type I) transfer method. The file
transfers data exactly as it exists, with no changes. This is the default transfer method.
dwContext
The context identifier for opening the file. See Remarks for more information about dwContext.
Return Value
A pointer to a CInternetFile object.
Remarks
OpenFile should be used in the following situations:
An application has data that needs to be sent and created as a file on the FTP server, but that data is not in
a local file. Once OpenFile opens a file, the application uses CInternetFile::Write to send the FTP file data
to the server.
An application must retrieve a file from the server and place it into application-controlled memory,
instead of writing it to disk. The application uses CInternetFile::Read after using OpenFile to open the file.
An application needs a fine level of control over a file transfer. For example, the application may want to
display a progress control indicate the progress of the file transfer status while downloading a file.
After calling OpenFile and until calling CInternetConnection::Close , the application can only call
CInternetFile::Read, CInternetFile::Write, CInternetConnection::Close , or CFtpFileFind::FindFile. Calls to other FTP
functions for the same FTP session will fail and set the error code to FTP_ETRANSFER_IN_PROGRESS.
The pstrFileName parameter can be either a partially qualified filename relative to the current directory or fully
qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either name. OpenFile
translates the directory name separators to the appropriate characters before using it.
Override the dwContext default to set the context identifier to a value of your choosing. The context identifier is
associated with this specific operation of the CFtpConnection object created by its CInternetSession object. The
value is returned to CInternetSession::OnStatusCallback to provide status on the operation with which it is
identified. See the article Internet First Steps: WinInet for more information about the context identifier.

CFtpConnection::PutFile
Call this member function to store a file on an FTP server.

BOOL PutFile(
LPCTSTR pstrLocalFile,
LPCTSTR pstrRemoteFile,
DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY,
DWORD_PTR dwContext = 1);

Parameters
pstrLocalFile
A pointer to a string containing the name of the file to send from the local system.
pstrRemoteFile
A pointer to a string containing the name of the file to create on the FTP server.
dwFlags
Specifies the conditions under which the transfer of the file occurs. Can be any of the FTP_TRANSFER_*
constants described in OpenFile.
dwContext
The context identifier for placing the file. See Remarks for more information about dwContext.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
PutFile is a high-level routine that handles all of the operations associated with storing a file on an FTP server.
Applications that only send data, or that require closer control over the file transfer, should use OpenFile and
CInternetFile::Write.
Override the dwContext default to set the context identifier to a value of your choosing. The context identifier is
associated with this specific operation of the CFtpConnection object created by its CInternetSession object. The
value is returned to CInternetSession::OnStatusCallback to provide status on the operation with which it is
identified. See the article Internet First Steps: WinInet for more information about the context identifier.

CFtpConnection::Remove
Call this member function to delete the specified file from the connected server.

BOOL Remove(LPCTSTR pstrFileName);

Parameters
pstrFileName
A pointer to a string containing the file name to remove.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
The pstrFileName parameter can be either a partially qualified filename relative to the current directory or fully
qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either name. The
Remove function translates the directory name separators to the appropriate characters before they are used.

CFtpConnection::RemoveDirectory
Call this member function to remove the specified directory from the connected server.

BOOL RemoveDirectory(LPCTSTR pstrDirName);

Parameters
pstrDirName
A pointer to a string containing the directory to be removed.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
Use GetCurrentDirectory to determine the server's current working directory. Do not assume that the remote
system has connected you to the root directory.
The pstrDirName parameter can be either a partially or fully qualified filename relative to the current directory.
A backslash (\) or forward slash (/) can be used as the directory separator for either name. RemoveDirectory
translates the directory name separators to the appropriate characters before they are used.

CFtpConnection::Rename
Call this member function to rename the specified file on the connected server.
BOOL Rename(
LPCTSTR pstrExisting,
LPCTSTR pstrNew);

Parameters
pstrExisting
A pointer to a string containing the current name of the file to be renamed.
pstrNew
A pointer to a string containing the file's new name.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
The pstrExisting and pstrNew parameters can be either a partially qualified filename relative to the current
directory or fully qualified. A backslash (\) or forward slash (/) can be used as the directory separator for either
name. Rename translates the directory name separators to the appropriate characters before they are used.

CFtpConnection::SetCurrentDirectory
Call this member function to change to a different directory on the FTP server.

BOOL SetCurrentDirectory(LPCTSTR pstrDirName);

Parameters
pstrDirName
A pointer to a string containing the name of the directory.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
The pstrDirName parameter can be either a partially or fully qualified filename relative to the current directory.
A backslash (\) or forward slash (/) can be used as the directory separator for either name. SetCurrentDirectory
translates the directory name separators to the appropriate characters before they are used.
Use GetCurrentDirectory to determine an FTP server's current working directory. Do not assume that the
remote system has connected you to the root directory.

See also
CInternetConnection Class
Hierarchy Chart
CInternetConnection Class
CInternetSession Class
CFtpFileFind Class
3/27/2020 • 4 minutes to read • Edit Online

Aids in Internet file searches of FTP servers.

Syntax
class CFtpFileFind : public CFileFind

Members
Public Constructors
NAME DESC RIP T IO N

CFtpFileFind::CFtpFileFind Constructs a CFtpFileFind object.

Public Methods
NAME DESC RIP T IO N

CFtpFileFind::FindFile Finds a file on a FTP server.

CFtpFileFind::FindNextFile Continues a file search from a previous call to FindFile.

CFtpFileFind::GetFileURL Gets the URL, including path, of the found file.

Remarks
CFtpFileFind includes member functions that begin a search, locate a file, and return the URL or other
descriptive information about the file.
Other MFC classes designed for Internet and local file searched include CGopherFileFind and CFileFind. Together
with CFtpFileFind , these classes provide a seamless mechanism for the client to find specific files, regardless of
the server protocol or file type (either a local machine or a remote server). Note that there is no MFC class for
searching on HTTP servers because HTTP does not support the direct file manipulation required for searches.
For more information about how to use CFtpFileFind and the other WinInet classes, see the article Internet
Programming with WinInet.

Example
The following code demonstrates how to enumerate all files in the current directory of the FTP server.
// create a session object to initialize WININET library
// Default parameters mean the access method in the registry
// (that is, set by the "Internet" icon in the Control Panel)
// will be used.

CInternetSession sess(_T("My FTP Session"));

CFtpConnection *pConnect = NULL;

try
{
// Request a connection to ftp.microsoft.com. Default
// parameters mean that we'll try with username = ANONYMOUS
// and password set to the machine name @ domain name
pConnect = sess.GetFtpConnection(_T("ftp.microsoft.com"));

// use a file find object to enumerate files


CFtpFileFind finder(pConnect);

// start looping
BOOL bWorking = finder.FindFile(_T("*"));

while (bWorking)
{
bWorking = finder.FindNextFile();
_tprintf_s(_T("%s\n"), (LPCTSTR)finder.GetFileURL());
}
}
catch (CInternetException *pEx)
{
TCHAR sz[1024];
pEx->GetErrorMessage(sz, 1024);
_tprintf_s(_T("ERROR! %s\n"), sz);
pEx->Delete();
}

// if the connection is open, close it


if (pConnect != NULL)
{
pConnect->Close();
delete pConnect;
}

Inheritance Hierarchy
CObject
CFileFind
CFtpFileFind

Requirements
Header : afxinet.h

CFtpFileFind::CFtpFileFind
This member function is called to construct a CFtpFileFind object.
explicit CFtpFileFind(
CFtpConnection* pConnection,
DWORD_PTR dwContext = 1);

Parameters
pConnection
A pointer to a CFtpConnection object. You can obtain an FTP connection by calling
CInternetSession::GetFtpConnection.
dwContext
The context identifier for the CFtpFileFind object. See Remarks for more information about this parameter.
Remarks
The default value for dwContext is sent by MFC to the CFtpFileFind object from the CInternetSession object
that created the CFtpFileFind object. You can override the default to set the context identifier to a value of your
choosing. The context identifier is returned to CInternetSession::OnStatusCallback to provide status on the
object with which it is identified. See the article Internet First Steps: WinInet for more information about the
context identifier.
Example
See the example in the class overview earlier in this topic.

CFtpFileFind::FindFile
Call this member function to find an FTP file.

virtual BOOL FindFile(


LPCTSTR pstrName = NULL,
DWORD dwFlags = INTERNET_FLAG_RELOAD);

Parameters
pstrName
A pointer to a string containing the name of the file to find. If NULL, the call will perform a wildcard search (*).
dwFlags
The flags describing how to handle this session. These flags can be combined with the bitwise OR operator (|)
and are as follows:
INTERNET_FLAG_RELOAD Get the data from the wire even if it is locally cached. This is the default flag.
INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateways.
INTERNET_FLAG_RAW_DATA Override the default to return the raw data ( WIN32_FIND_DATA structures
for FTP).
INTERNET_FLAG_SECURE Secures transactions on the wire with Secure Sockets Layer or PCT. This flag is
applicable to HTTP requests only.
INTERNET_FLAG_EXISTING_CONNECT If possible, reuse the existing connections to the server for new
FindFile requests instead of creating a new session for each request.

Return Value
Nonzero if successful; otherwise 0. To get extended error information, call the Win32 function GetLastError.
Remarks
After calling FindFile to retrieve the first FTP file, you can call FindNextFile to retrieve subsequent FTP files.
Example
See the earlier example in this topic.

CFtpFileFind::FindNextFile
Call this member function to continue a file search begun with a call to the FindFile member function.

virtual BOOL FindNextFile();

Return Value
Nonzero if there are more files; zero if the file found is the last one in the directory or if an error occurred. To get
extended error information, call the Win32 function GetLastError. If the file found is the last file in the directory,
or if no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.
Remarks
You must call this function at least once before calling any attribute function (see CFileFind::FindNextFile).
FindNextFile wraps the Win32 function FindNextFile.
Example
See the example earlier in this topic.

CFtpFileFind::GetFileURL
Call this member function to get the URL of the specified file.

CString GetFileURL() const;

Return Value
The file and path of the Universal Resource Locator (URL).
Remarks
GetFileURL is similar to the member function CFileFind::GetFilePath, except that it returns the URL in the form
ftp://moose/dir/file.txt .

See also
CFileFind Class
Hierarchy Chart
CGopherFileFind Class
CInternetFile Class
CGopherFile Class
CHttpFile Class
CGdiObject Class
3/27/2020 • 6 minutes to read • Edit Online

Provides a base class for various kinds of Windows graphics device interface (GDI) objects such as bitmaps,
regions, brushes, pens, palettes, and fonts.

Syntax
class CGdiObject : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CGdiObject::CGdiObject Constructs a CGdiObject object.

Public Methods
NAME DESC RIP T IO N

CGdiObject::Attach Attaches a Windows GDI object to a CGdiObject object.

CGdiObject::CreateStockObject Retrieves a handle to one of the Windows predefined stock


pens, brushes, or fonts.

CGdiObject::DeleteObject Deletes the Windows GDI object attached to the


CGdiObject object from memory by freeing all system
storage associated with the object.

CGdiObject::DeleteTempMap Deletes any temporary CGdiObject objects created by


FromHandle .

CGdiObject::Detach Detaches a Windows GDI object from a CGdiObject object


and returns a handle to the Windows GDI object.

CGdiObject::FromHandle Returns a pointer to a CGdiObject object given a handle to


a Windows GDI object.

CGdiObject::GetObject Fills a buffer with data that describes the Windows GDI
object attached to the CGdiObject object.

CGdiObject::GetObjectType Retrieves the type of the GDI object.

CGdiObject::GetSafeHandle Returns m_hObject unless this is NULL, in which case


NULL is returned.

CGdiObject::UnrealizeObject Resets the origin of a brush or resets a logical palette.


Public Operators
NAME DESC RIP T IO N

CGdiObject::operator != Determines if two GDI objects are logically not equal.

CGdiObject::operator == Determines if two GDI objects are logically equal.

CGdiObject::operator HGDIOBJ Retrieves a HANDLE to the attached Windows GDI object.

Public Data Members


NAME DESC RIP T IO N

CGdiObject::m_hObject A HANDLE containing the HBITMAP, HPALETTE, HRGN,


HBRUSH, HPEN, or HFONT attached to this object.

Remarks
You never create a CGdiObject directly. Rather, you create an object from one of its derived classes, such as
CPen or CBrush .

For more information on CGdiObject , see Graphic Objects.

Inheritance Hierarchy
CObject
CGdiObject

Requirements
Header : afxwin.h

CGdiObject::Attach
Attaches a Windows GDI object to a CGdiObject object.

BOOL Attach(HGDIOBJ hObject);

Parameters
hObject
A HANDLE to a Windows GDI object (for example, HPEN or HBRUSH).
Return Value
Nonzero if attachment is successful; otherwise 0.

CGdiObject::CGdiObject
Constructs a CGdiObject object.

CGdiObject();
Remarks
You never create a CGdiObject directly. Rather, you create an object from one of its derived classes, such as
CPen or Cbrush .

CGdiObject::CreateStockObject
Retrieves a handle to one of the predefined stock Windows GDI pens, brushes, or fonts, and attaches the GDI
object to the CGdiObject object.

BOOL CreateStockObject(int nIndex);

Parameters
nIndex
A constant specifying the type of stock object desired. See the parameter fnObject for GetStockObject in the
Windows SDK for a description of appropriate values.
Return Value
Nonzero if the function is successful; otherwise 0.
Remarks
Call this function with one of the derived classes that corresponds to the Windows GDI object type, such as
CPen for a stock pen.

CGdiObject::DeleteObject
Deletes the attached Windows GDI object from memory by freeing all system storage associated with the
Windows GDI object.

BOOL DeleteObject();

Return Value
Nonzero if the GDI object was successfully deleted; otherwise 0.
Remarks
The storage associated with the CGdiObject object is not affected by this call. An application should not call
DeleteObject on a CGdiObject object that is currently selected into a device context.

When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be
deleted independently.

CGdiObject::DeleteTempMap
Called automatically by the CWinApp idle-time handler, DeleteTempMap deletes any temporary CGdiObject
objects created by FromHandle .

static void PASCAL DeleteTempMap();

Remarks
DeleteTempMap detaches the Windows GDI object attached to a temporary CGdiObject object before deleting
the CGdiObject object.
Example
// DeleteTempMap() is a static member and so does not need to
// be called within the scope of an instantiated CGdiObject object.
CGdiObject::DeleteTempMap();

CGdiObject::Detach
Detaches a Windows GDI object from a CGdiObject object and returns a handle to the Windows GDI object.

HGDIOBJ Detach();

Return Value
A HANDLE to the Windows GDI object detached; otherwise NULL if no GDI object is attached.

CGdiObject::FromHandle
Returns a pointer to a CGdiObject object given a handle to a Windows GDI object.

static CGdiObject* PASCAL FromHandle(HGDIOBJ hObject);

Parameters
hObject
A HANDLE to a Windows GDI object.
Return Value
A pointer to a CGdiObject that may be temporary or permanent.
Remarks
If a CGdiObject object is not already attached to the Windows GDI object, a temporary CGdiObject object is
created and attached.
This temporary CGdiObject object is only valid until the next time the application has idle time in its event loop,
at which time all temporary graphic objects are deleted. Another way of saying this is that the temporary object
is only valid during the processing of one window message.

CGdiObject::GetObject
Fills a buffer with data that defines a specified object.

int GetObject(
int nCount,
LPVOID lpObject) const;

Parameters
nCount
Specifies the number of bytes to copy into the lpObject buffer.
lpObject
Points to a user-supplied buffer that is to receive the information.
Return Value
The number of bytes retrieved; otherwise 0 if an error occurs.
Remarks
The function retrieves a data structure whose type depends on the type of graphic object, as shown by the
following list:

O B JEC T B UF F ER T Y P E

CPen LOGPEN

CBrush LOGBRUSH

CFont LOGFONT

CBitmap BITMAP

CPalette WORD

CRgn Not supported

If the object is a CBitmap object, GetObject returns only the width, height, and color format information of the
bitmap. The actual bits can be retrieved by using CBitmap::GetBitmapBits.
If the object is a CPalette object, GetObject retrieves a WORD that specifies the number of entries in the
palette. The function does not retrieve the LOGPALETTE structure that defines the palette. An application can get
information on palette entries by calling CPalette::GetPaletteEntries.

CGdiObject::GetObjectType
Retrieves the type of the GDI object.

UINT GetObjectType() const;

Return Value
The type of the object, if successful; otherwise 0. The value can be one of the following:
OBJ_BITMAP Bitmap
OBJ_BRUSH Brush
OBJ_FONT Font
OBJ_PAL Palette
OBJ_PEN Pen
OBJ_EXTPEN Extended pen
OBJ_REGION Region
OBJ_DC Device context
OBJ_MEMDC Memory device context
OBJ_METAFILE Metafile
OBJ_METADC Metafile device context
OBJ_ENHMETAFILE Enhanced metafile
OBJ_ENHMETADC Enhanced-metafile device context

CGdiObject::GetSafeHandle
Returns m_hObject unless this is NULL, in which case NULL is returned.

HGDIOBJ GetSafeHandle() const;

Return Value
A HANDLE to the attached Windows GDI object; otherwise NULL if no object is attached.
Remarks
This is part of the general handle interface paradigm and is useful when NULL is a valid or special value for a
handle.
Example
See the example for CWnd::IsWindowEnabled.

CGdiObject::m_hObject
A HANDLE containing the HBITMAP, HRGN, HBRUSH, HPEN, HPALETTE, or HFONT attached to this object.

HGDIOBJ m_hObject;

CGdiObject::operator !=
Determines if two GDI objects are logically not equal.

BOOL operator!=(const CGdiObject& obj) const;

Parameters
obj
A pointer to an existing CGdiObject .
Remarks
Determines if a GDI object on the left side is not equal to a GDI object on the right side.

CGdiObject::operator ==
Determines if two GDI objects are logically equal.

BOOL operator==(const CGdiObject& obj) const;

Parameters
obj
A reference to an existing CGdiObject .
Remarks
Determines if a GDI object on the left side is equal to a GDI object on the right side.
CGdiObject::operator HGDIOBJ
Retrieves a HANDLE to the attached Windows GDI object; otherwise NULL if no object is attached.

operator HGDIOBJ() const;

CGdiObject::UnrealizeObject
Resets the origin of a brush or resets a logical palette.

BOOL UnrealizeObject();

Return Value
Nonzero if successful; otherwise 0.
Remarks
While UnrealizeObject is a member function of the CGdiObject class, it should be invoked only on CBrush or
CPalette objects.

For CBrush objects, UnrealizeObject directs the system to reset the origin of the given brush the next time it is
selected into a device context. If the object is a CPalette object, UnrealizeObject directs the system to realize
the palette as though it had not previously been realized. The next time the application calls the
CDC::RealizePalette function for the specified palette, the system completely remaps the logical palette to the
system palette.
The UnrealizeObject function should not be used with stock objects. The UnrealizeObject function must be
called whenever a new brush origin is set (by means of the CDC::SetBrushOrg function). The UnrealizeObject
function must not be called for the currently selected brush or currently selected palette of any display context.

See also
Hierarchy Chart
CBitmap Class
CBrush Class
CFont Class
CPalette Class
CPen Class
CRgn Class
CGlobalUtils Class
4/21/2020 • 2 minutes to read • Edit Online

For more detail see the source code located in the VC\atlmfc\src\mfc folder of your Visual Studio installation.

Syntax
class CGlobalUtils

Members
Public Methods
NAME DESC RIP T IO N

CGlobalUtils::AdjustRectToWorkArea

CGlobalUtils::CalcExpectedDockedRect

CGlobalUtils::CanBeAttached

CGlobalUtils::CanPaneBeInFloatingMultiPaneFrameWnd

CGlobalUtils::CheckAlignment

CGlobalUtils::CyFromString

CGlobalUtils::DecimalFromString

CGlobalUtils::FlipRect

CGlobalUtils::ForceAdjustLayout

CGlobalUtils::GetDockingManager

CGlobalUtils::GetOppositeAlignment

CGlobalUtils::GetPaneAndAlignFromPoint

CGlobalUtils::GetWndIcon

CGlobalUtils::SetNewParent

CGlobalUtils::StringFromCy

CGlobalUtils::StringFromDecimal
Remarks
Inheritance Hierarchy
CGlobalUtils

Requirements
Header : afxglobalutils.h

CGlobalUtils::AdjustRectToWorkArea
void AdjustRectToworkArea(
CRect& rect,
CRect* pRectDelta = NULL);

Parameters
[in, out] rect
[in] pRectDelta
Remarks

CGlobalUtils::CalcExpectedDockedRect
void CalcExpectedDockedRect(
CPaneContainerManager& barContainerManager,
CWnd* pWndTodock,
CPoint ptMouse,
CRect& rectResult,
BOOL& bDrawTab,
CDockablePane** ppTargetBar);

Parameters
[in] barContainerManager
[in] pWndTodock
[in] ptMouse
[out] rectResult
[out] bDrawTab
[out] ppTargetBar
Remarks

CGlobalUtils::CanBeAttached
BOOL CanBeAttached(CWnd* pWnd) const;

Parameters
[in] pWnd
Return Value
Remarks

CGlobalUtils::CanPaneBeInFloatingMultiPaneFrameWnd
BOOL CanPaneBeInFloatingMultiPaneFrameWnd(CWnd* pWnd) const;

Parameters
[in] pWnd
Return Value
Remarks

CGlobalUtils::CheckAlignment
BOOL CheckAlignment(
CPoint point,
CBasePane* pBar,
int nSensitivity,
const CDockingManager* pDockManager,
BOOL bOuterEdge,
DWORD& dwAlignment,
DWORD dwEnabledDockBars = CBRS_ALIGN_ANY,
LPCRECT lpRectBounds = NULL) const;

Parameters
[in] point
[in] pBar
[in] nSensitivity
[in] pDockManager
[in] bOuterEdge
[out] dwAlignment
[in] dwEnabledDockBars
[in] lpRectBounds
Return Value
Remarks

CGlobalUtils::CyFromString
BOOL CyFromString(
CY& cy,
LPCTSTR psz);

Parameters
[out] cy
[in] psz
Return Value
Remarks

CGlobalUtils::DecimalFromString
BOOL DecimalFromString(
DECIMAL& decimal,
LPCTSTR psz);

Parameters
[out] decimal
[in] psz
Return Value
Remarks

CGlobalUtils::FlipRect
void FlipRect(
CRect& rect,
int nDegrees);

Parameters
[in, out] rect
[in] nDegrees
Remarks

CGlobalUtils::ForceAdjustLayout
void ForceAdjustLayout(
CDockingManager* pDockManager,
BOOL bForce = FALSE,
BOOL bForceInvisible = FALSE);

Parameters
[in, out] pDockManager
[in] bForce
[in] bForceInvisible
Remarks

CGlobalUtils::GetDockingManager
CDockingManager* GetDockingManager(CWnd* pWnd);

Parameters
[in] pWnd
Return Value
Remarks
CGlobalUtils::GetOppositeAlignment
DWORD GetOppositeAlignment(DWORD dwAlign);

Parameters
[in] dwAlign
Return Value
Remarks

CGlobalUtils::GetPaneAndAlignFromPoint
BOOL GetPaneAndAlignFromPoint(
CPaneContainerManager& barContainerManager,
CPoint pt,
CDockablePane** ppTargetControlBar,
DWORD& dwAlignment,
BOOL& bTabArea,
BOOL& bCaption);

Parameters
[in] barContainerManager
[in] pt
[out] ppTargetControlBar
[out] dwAlignment
[out] bTabArea
[out] bCaption
Return Value
Remarks

CGlobalUtils::GetWndIcon
HICON GetWndIcon(CWnd* pWnd);

Parameters
[in] pWnd
Return Value
Remarks

CGlobalUtils::SetNewParent
void SetNewParent(
CObList& lstControlBars,
CWnd* pNewParent,
BOOL bCheckVisibility = TRUE);
Parameters
[in] lstControlBars
[in] pNewParent
[in] bCheckVisibility
Remarks

CGlobalUtils::StringFromCy
BOOL StringFromCy(
CString& str,
CY& cy);

Parameters
[out] str
[in] cy
Return Value
Remarks

CGlobalUtils::StringFromDecimal
BOOL StringFromDecimal(
CString& str,
DECIMAL& decimal);

Parameters
[out] str
[in] decimal
Return Value
Remarks

See also
Hierarchy Chart
Classes
CGopherConnection Class
3/27/2020 • 5 minutes to read • Edit Online

Manages your connection to a gopher Internet server.

NOTE
The classes CGopherConnection , CGopherFile , CGopherFileFind , CGopherLocator and their members have been
deprecated because they do not work on the Windows XP platform, but they will continue to work on earlier platforms.

Syntax
class CGopherConnection : public CInternetConnection

Members
Public Constructors
NAME DESC RIP T IO N

CGopherConnection::CGopherConnection Constructs a CGopherConnection object.

Public Methods
NAME DESC RIP T IO N

CGopherConnection::CreateLocator Creates a CGopherLocator object to find files on a gopher


server.

CGopherConnection::GetAttribute Retrieves attribute information about the gopher object.

CGopherConnection::OpenFile Opens a gopher file.

Remarks
The gopher service is one of three Internet services recognized by the MFC WinInet classes.
The class CGopherConnection contains a constructor and three additional member functions that manage the
gopher service: OpenFile, CreateLocator, and GetAttribute.
To communicate with a gopher Internet server, you must first create an instance of CInternetSession, and then
call CInternetSession::GetGopherConnection, which creates the CGopherConnection object and returns a pointer
to it. You never create a CGopherConnection object directly.
To learn more about how CGopherConnection works with the other MFC Internet classes, see the article Internet
Programming with WinInet. For more information about using the other two supported Internet services, FTP
and HTTP see the classes CHttpConnection and CFtpConnection.
Inheritance Hierarchy
CObject
CInternetConnection
CGopherConnection

Requirements
Header : afxinet.h

CGopherConnection::CGopherConnection
This member function is called to construct a CGopherConnection object.

CGopherConnection(
CInternetSession* pSession,
HINTERNET hConnected,
LPCTSTR pstrServer,
DWORD_PTR dwContext);

CGopherConnection(
CInternetSession* pSession,
LPCTSTR pstrServer,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
DWORD_PTR dwContext = 0,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER);

Parameters
pSession
A pointer to the related CInternetSession object.
hConnected
The Windows handle of the current Internet session.
pstrServer
A pointer to a string containing the FTP server name.
dwContext
The context identifier for the operation. dwContext identifies the operation's status information returned by
CInternetSession::OnStatusCallback. The default is set to 1; however, you can explicitly assign a specific context ID
for the operation. The object and any work it does will be associated with that context ID.
pstrUserName
Pointer to a null-terminated string that specifies the name of the user to log in. If NULL, the default is
anonymous.
pstrPassword
A pointer to a null-terminated string that specifies the password to use to log in. If both pstrPassword and
pstrUserName are NULL, the default anonymous password is the user's email name. If pstrPassword is NULL (or
an empty string) but pstrUserName is not NULL, a blank password is used. The following table describes the
behavior for the four possible settings of pstrUserName and pstrPassword:
USERN A M E SEN T TO F T P PA SSW O RD SEN T TO F T P
P ST RUSERN A M E P ST RPA SSWO RD SERVER SERVER

NULL or " " NULL or " " "anonymous" User's email name

Non- NULL String NULL or " " pstrUserName ""

NULL Non- NULL String ERROR ERROR

Non- NULL String Non- NULL String pstrUserName pstrPassword

nPort
A number that identifies the TCP/IP port to use on the server.
Remarks
You never create a CGopherConnection directly. Rather, call CInternetSession::GetGopherConnection, which
creates a CGopherConnection object and returns a pointer to it.

CGopherConnection::CreateLocator
Call this member function to create a gopher locator to find or identify a file on a gopher server.

CGopherLocator CreateLocator(
LPCTSTR pstrDisplayString,
LPCTSTR pstrSelectorString,
DWORD dwGopherType);

static CGopherLocator CreateLocator(LPCTSTR pstrLocator);

static CGopherLocator CreateLocator(


LPCTSTR pstrServerName,
LPCTSTR pstrDisplayString,
LPCTSTR pstrSelectorString,
DWORD dwGopherType,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER);

Parameters
pstrDisplayString
A pointer to a string containing the name of the gopher document or directory to be retrieved. If the
pstrDisplayString parameter is NULL, the default directory for the gopher server is returned.
pstrSelectorString
A pointer to the selector string to be sent to the gopher server in order to retrieve an item. pstrSelectorString can
be NULL.
dwGopherType
This specifies whether pstrSelectorString refers to a directory or document, and whether the request is gopher
or gopher+. See the attributes for the structure GOPHER_FIND_DATA in the Windows SDK.
pstrLocator
A pointer to a string identifying the file to open. Generally, this string is returned from a call to
CGopherFileFind::GetLocator.
pstrServerName
A pointer to a string containing the gopher server name.
nPort
The number identifying the Internet port for this connection.
Return Value
A CGopherLocator object.
Remarks
The static version of the member function requires you to specify a server, while the non-static version uses the
server name from the connection object.
In order to retrieve information from a gopher server, an application must first get a gopher locator. The
application must then treat the locator as an opaque token (that is, the application can use the locator but not
directly manipulate or compare it). Normally, the application uses the locator for calls to the
CGopherFileFind::FindFile member function to retrieve a specific piece of information.

CGopherConnection::GetAttribute
Call this member function to retrieve specific attribute information about an item from the gopher server.

BOOL GetAttribute(
CGopherLocator& refLocator CString strRequestedAttributes,
CString& strResult,);

Parameters
refLocator
A reference to a CGopherLocator object.
strRequestedAttributes
A space-delimited string specifying the names of the requested attributes.
strResult
A reference to a CString that receives the locator type.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.

CGopherConnection::OpenFile
Call this member function to open a file on a gopher server.

CGopherFile* OpenFile(
CGopherLocator& refLocator,
DWORD dwFlags = 0,
LPCTSTR pstrView = NULL,
DWORD_PTR dwContext = 1);

Parameters
refLocator
A reference to a CGopherLocator object.
dwFlags
Any combination of INTERNET_FLAG_* flags. See CInternetSession::OpenUrl for further information on
INTERNET_FLAG_* flags.
pstrView
A pointer to a file-view string. If several views of the file exist at the server, this parameter specifies which file
view to open. If pstrView is NULL, the default file view is used.
dwContext
The context ID for the file being opened. See Remarks for more information about dwContext.
Return Value
A pointer to the CGopherFile object to be opened.
Remarks
Override the dwContext default to set the context identifier to a value of your choosing. The context identifier is
associated with this specific operation of the CGopherConnection object created by its CInternetSession object.
The value is returned to CInternetSession::OnStatusCallback to provide status on the operation with which it is
identified. See the article Internet First Steps: WinInet for more information about the context identifier.

See also
CInternetConnection Class
Hierarchy Chart
CFtpConnection Class
CHttpConnection Class
CInternetConnection Class
CGopherLocator Class
CGopherFile Class
CInternetSession Class
CGopherFile Class
3/27/2020 • 2 minutes to read • Edit Online

Provides the functionality to find and read files on a gopher server.

NOTE
The classes CGopherConnection , CGopherFile , CGopherFileFind , CGopherLocator and their members have been
deprecated because they do not work on the Windows XP platform, but they will continue to work on earlier platforms.

Syntax
class CGopherFile : public CInternetFile

Members
Protected Constructors
NAME DESC RIP T IO N

CGopherFile::CGopherFile Constructs a CGopherFile object.

Remarks
The gopher service does not allow users to write data to a gopher file because this service functions mainly as
a menu-driven interface for finding information. The CGopherFile member functions Write , WriteString , and
Flush are not implemented for CGopherFile . Calling these functions on a CGopherFile object, returns a
CNotSupportedException.
To learn more about how CGopherFile works with the other MFC Internet classes, see the article Internet
Programming with WinInet.

Inheritance Hierarchy
CObject
CFile
CStdioFile
CInternetFile
CGopherFile

Requirements
Header : afxinet.h

CGopherFile::CGopherFile
This member function is called to construct a CGopherFile object.

CGopherFile(
HINTERNET hFile,
CGopherLocator& refLocator,
CGopherConnection* pConnection);

CGopherFile(
HINTERNET hFile,
HINTERNET hSession,
LPCTSTR pstrLocator,
DWORD dwLocLen,
DWORD_PTR dwContext);

Parameters
hFile
A handle to an HINTERNET file.
refLocator
A reference to a CGopherLocator object.
pConnection
A pointer to a CGopherConnection object.
hSession
A handle to the current Internet session.
pstrLocator
A pointer to a string used to locate the gopher server. See Gopher Sessions for more information about gopher
locators.
dwLocLen
A DWORD containing the number of bytes in pstrLocator.
dwContext
A pointer to the context identifier of the file being opened.
Remarks
You need a CGopherFile object to read from a file during a gopher Internet session.
You never create a CGopherFile object directly. Instead, call CGopherConnection::OpenFile to open a file on a
gopher server.

See also
CInternetFile Class
Hierarchy Chart
CInternetFile Class
CGopherLocator Class
CGopherFileFind Class
CGopherConnection Class
CGopherFileFind Class
3/27/2020 • 6 minutes to read • Edit Online

Aids in Internet file searches of gopher servers.

NOTE
The classes CGopherConnection , CGopherFile , CGopherFileFind , CGopherLocator and their members have been
deprecated because they do not work on the Windows XP platform, but they will continue to work on earlier platforms.

Syntax
class CGopherFileFind : public CFileFind

Members
Public Constructors
NAME DESC RIP T IO N

CGopherFileFind::CGopherFileFind Constructs a CGopherFileFind object.

Public Methods
NAME DESC RIP T IO N

CGopherFileFind::FindFile Finds a file on a gopher server.

CGopherFileFind::FindNextFile Continues a file search from a previous call to FindFile.

CGopherFileFind::GetCreationTime Gets the time the specified file was created.

CGopherFileFind::GetLastAccessTime Gets the time the specified file was last accessed.

CGopherFileFind::GetLastWriteTime Gets the time the specified file was last written to.

CGopherFileFind::GetLength Gets the length of the found file, in bytes.

CGopherFileFind::GetLocator Get a CGopherLocator object.

CGopherFileFind::GetScreenName Gets the name of a gopher screen.

CGopherFileFind::IsDots Tests for the current directory and parent directory markers
while iterating through files.

Remarks
CGopherFileFind includes member functions that begin a search, locate a file, and return a file's URL.
Other MFC classes designed for Internet and local file searched include CFtpFileFind and CFileFind. Together
with CGopherFileFind , these classes provide a seamless mechanism for the user to find specific files, regardless
of the server protocol, file type, or location (either a local machine or a remote server.) Note that there is no
MFC class for searching on HTTP servers because HTTP does not support the direct file manipulation required
by searches.

NOTE
CGopherFileFind does not support the following member functions of its base class CFileFind:

GetRoot
GetFileName
GetFilePath
GetFileTitle
GetFileURL
In addition, when used with CGopherFileFind , the CFileFind member function IsDots is always FALSE.
For more information about how to use CGopherFileFind and the other WinInet classes, see the article Internet
Programming with WinInet.

Inheritance Hierarchy
CObject
CFileFind
CGopherFileFind

Requirements
Header : afxinet.h

CGopherFileFind::CGopherFileFind
This member function is called to construct a CGopherFileFind object.

explicit CGopherFileFind(
CGopherConnection* pConnection,
DWORD_PTR dwContext = 1);

Parameters
pConnection
A pointer to a CGopherConnection object.
dwContext
The context identifier for the operation. See Remarks for more information about dwContext.
Remarks
The default value for dwContext is sent by MFC to the CGopherFileFind object from the CInternetSession object
that created the CGopherFileFind object. When you construct a CGopherFileFind object, you can override the
default to set the context identifier to a value of your choosing. The context identifier is returned to
CInternetSession::OnStatusCallback to provide status on the object with which it is identified. See the article
Internet First Steps: WinInet for more information about the context identifier.

CGopherFileFind::FindFile
Call this member function to find a gopher file.

virtual BOOL FindFile(


CGopherLocator& refLocator,
LPCTSTR pstrString,
DWORD dwFlags = INTERNET_FLAG_RELOAD);

virtual BOOL FindFile(


LPCTSTR pstrString,
DWORD dwFlags = INTERNET_FLAG_RELOAD);

Parameters
refLocator
A reference to a CGopherLocator object.
pstrString
A pointer to a string containing the file name.
dwFlags
The flags describing how to handle this session. The valid flags are:
INTERNET_FLAG_RELOAD Get the data from the remote server even if it is locally cached.
INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateways.
INTERNET_FLAG_SECURE Request secure transactions on the wire with Secure Sockets Layer or PCT. This
flag is applicable to HTTP requests only.
INTERNET_FLAG_USE_EXISTING If possible, reuse the existing connections to the server for new
FindFile requests, instead of creating a new session for each request.

Return Value
Nonzero if successful; otherwise 0. To get extended error information, call the Win32 function GetLastError.
Remarks
After calling FindFile to retrieve the first gopher object, you can call FindNextFile to retrieve subsequent
gopher files.

CGopherFileFind::FindNextFile
Call this member function to continue a file search begun with a call to CGopherFileFind::FindFile.

virtual BOOL FindNextFile();

Return Value
Nonzero if there are more files; zero if the file found is the last one in the directory or if an error occurred. To
get extended error information, call the Win32 function GetLastError. If the file found is the last file in the
directory, or if no matching files can be found, the GetLastError function returns ERROR_NO_MORE_FILES.

CGopherFileFind::GetCreationTime
Gets the creation time for the current file.

virtual BOOL GetCreationTime(FILETIME* pTimeStamp) const;


virtual BOOL GetCreationTime(CTime& refTime) const;

Parameters
pTimeStamp
A pointer to a FILETIME structure containing the time the file was created.
refTime
A reference to a CTime object.
Return Value
Nonzero if successful; 0 if unsuccessful. GetCreationTime returns 0 only if FindNextFile has never been called
on this CGopherFileFind object.
Remarks
You must call FindNextFile at least once before calling GetCreationTime .

NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operating
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

CGopherFileFind::GetLastAccessTime
Gets the time the specified file was last accessed.

virtual BOOL GetLastAccessTime(CTime& refTime) const;


virtual BOOL GetLastAccessTime(FILETIME* pTimeStamp) const;

Parameters
refTime
A reference to a CTime object.
pTimeStamp
A pointer to a FILETIME structure containing the time the file was last accessed.
Return Value
Nonzero if successful; 0 if unsuccessful. GetLastAccessTime returns 0 only if FindNextFile has never been called
on this CGopherFileFind object.
Remarks
You must call FindNextFile at least once before calling GetLastAccessTime .
NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operating
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

CGopherFileFind::GetLastWriteTime
Gets the last time the file was changed.

virtual BOOL GetLastWriteTime(FILETIME* pTimeStamp) const;


virtual BOOL GetLastWriteTime(CTime& refTime) const;

Parameters
pTimeStamp
A pointer to a FILETIME structure containing the time the file was last written to.
refTime
A reference to a CTime object.
Return Value
Nonzero if successful; 0 if unsuccessful. GetLastWriteTime returns 0 only if FindNextFile has never been called
on this CGopherFileFind object.
Remarks
You must call FindNextFile at least once before calling GetLastWriteTime .

NOTE
Not all file systems use the same semantics to implement the time stamp returned by this function. This function may
return the same value returned by other time stamp functions if the underlying file system or server does not support
keeping the time attribute. See the WIN32_FIND_DATA structure for information about time formats. On some operating
systems, the returned time is in the time zone local to the machine were the file is located. See the Win32
FileTimeToLocalFileTime API for more information.

CGopherFileFind::GetLength
Call this member function to get the length, in bytes, of the found file.

virtual ULONGLONG GetLength() const;

Return Value
The length, in bytes, of the found file.
Remarks
GetLength uses the Win32 structure WIN32_FIND_DATA to get the value of the file size in bytes.
NOTE
As of MFC 7.0, GetLength supports 64-bit integer types. Previously-existing code built with this newer version of the
library may result in truncation warnings.

Example
See the example for CFile::GetLength (the base class implementation).

CGopherFileFind::GetLocator
Call this member function to get the CGopherLocator object that FindFile uses to find the gopher file.

CGopherLocator GetLocator() const;

Return Value
A CGopherLocator object.

CGopherFileFind::GetScreenName
Call this member function to get the name of the gopher screen.

CString GetScreenName() const;

Return Value
The name of the gopher screen.

CGopherFileFind::IsDots
Tests for the current directory and parent directory markers while iterating through files.

virtual BOOL IsDots() const;

Return Value
Nonzero if the found file has the name "." or "..", which indicates that the found file is actually a directory.
Otherwise 0.
Remarks
You must call FindNextFile at least once before calling IsDots .

See also
CFileFind Class
Hierarchy Chart
CFtpFileFind Class
CFileFind Class
CInternetFile Class
CGopherFile Class
CHttpFile Class
CGopherLocator Class
3/27/2020 • 2 minutes to read • Edit Online

Gets a gopher "locator" from a gopher server, determines the locator's type, and makes the locator available to
CGopherFileFind.

NOTE
The classes CGopherConnection , CGopherFile , CGopherFileFind , CGopherLocator and their members have been
deprecated because they do not work on the Windows XP platform, but they will continue to work on earlier platforms.

Syntax
class CGopherLocator : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CGopherLocator::CGopherLocator Constructs a CGopherLocator object.

Public Methods
NAME DESC RIP T IO N

CGopherLocator::GetLocatorType Parses a gopher locator and determines its attributes.

Public Operators
NAME DESC RIP T IO N

CGopherLocator::operator LPCTSTR Directly accesses characters stored in a CGopherLocator


object as a C-style string.

Remarks
An application must get a gopher server's locator before it can retrieve information from that server. Once it
has the locator, it must treat the locator as an opaque token.
Each gopher locator has attributes that determine the type of file or server found. See GetLocatorType for a list
of types of gopher locators.
An application normally uses the locator for calls to CGopherFileFind::FindFile to retrieve a specific piece of
information.
To learn more about how CGopherLocator works with the other MFC Internet classes, see the article Internet
Programming with WinInet.
Inheritance Hierarchy
CObject
CGopherLocator

Requirements
Header : afxinet.h

CGopherLocator::CGopherLocator
This member function is called to create a CGopherLocator object.

CGopherLocator(const CGopherLocator& ref);

Parameters
ref
A reference to a constant CGopherLocator object.
Remarks
You never create a CGopherLocator object directly. Instead, call CGopherConnection::CreateLocator to create and
return a pointer to the CGopherLocator object.

CGopherLocator::GetLocatorType
Call this member function to get the locator type.

BOOL GetLocatorType(DWORD& dwRef) const;

Parameters
dwRef
A reference to a DWORD that will receive the locator type. See Remarks for a table of locator types.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
The possible types are as follows:

VA L UE M EA N IN G

GOPHER_TYPE_TEXT_FILE An ASCII text file.

GOPHER_TYPE_DIRECTORY A directory of additional Gopher items.

GOPHER_TYPE_CSO A CSO phone book server.

GOPHER_TYPE_ERROR Indicates an error condition.

GOPHER_TYPE_MAC_BINHEX A Macintosh file in BINHEX format.


VA L UE M EA N IN G

GOPHER_TYPE_DOS_ARCHIVE A DOS archive file.

GOPHER_TYPE_UNIX_UUENCODED A UUENCODED file.

GOPHER_TYPE_INDEX_SERVER An index server.

GOPHER_TYPE_TELNET A Telnet Server.

GOPHER_TYPE_BINARY A binary file.

GOPHER_TYPE_REDUNDANT A duplicated server. The information contained within is a


duplicate of the primary server. The primary server is the
last directory entry that did not have a
GOPHER_TYPE_REDUNDANT type.

GOPHER_TYPE_TN3270 A TN3270 server.

GOPHER_TYPE_GIF A GIF graphics file.

GOPHER_TYPE_IMAGE An image file.

GOPHER_TYPE_BITMAP A bitmap file.

GOPHER_TYPE_MOVIE A movie file.

GOPHER_TYPE_SOUND A sound file.

GOPHER_TYPE_HTML An HTML document.

GOPHER_TYPE_PDF A PDF file.

GOPHER_TYPE_CALENDAR A calendar file.

GOPHER_TYPE_INLINE An inline file.

GOPHER_TYPE_UNKNOWN The item type is unknown.

GOPHER_TYPE_ASK An Ask+ item.

GOPHER_TYPE_GOPHER_PLUS A Gopher+ item.

CGopherLocator::operator LPCTSTR
This useful casting operator provides an efficient method to access the null-terminated C string contained in a
CGopherLocator object.

operator LPCTSTR () const;

Return Value
A character pointer to the string's data.
Remarks
No characters are copied; only a pointer is returned.

See also
CObject Class
Hierarchy Chart
CGopherFileFind Class
CHeaderCtrl Class
4/21/2020 • 22 minutes to read • Edit Online

Provides the functionality of the Windows common header control.

Syntax
class CHeaderCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CHeaderCtrl::CHeaderCtrl Constructs a CHeaderCtrl object.

Public Methods
NAME DESC RIP T IO N

CHeaderCtrl::ClearAllFilters Clears all filters for a header control.

CHeaderCtrl::ClearFilter Clears the filter for a header control.

CHeaderCtrl::Create Creates a header control and attaches it to a CHeaderCtrl


object.

CHeaderCtrl::CreateDragImage Creates a transparent version of an item's image within a


header control.

CHeaderCtrl::CreateEx Creates a header control with the specified Windows


extended styles and attaches it to a CListCtrl object.

CHeaderCtrl::DeleteItem Deletes an item from a header control.

CHeaderCtrl::DrawItem Draws the specified item of a header control.

CHeaderCtrl::EditFilter Starts editing the specified filter of a header control.

CHeaderCtrl::GetBitmapMargin Retrieves the width of the margin of a bitmap in a header


control.

CHeaderCtrl::GetFocusedItem Gets the identifier of the item in the current header control
that has the focus.

CHeaderCtrl::GetImageList Retrieves the handle of an image list used for drawing


header items in a header control.
NAME DESC RIP T IO N

CHeaderCtrl::GetItem Retrieves information about an item in a header control.

CHeaderCtrl::GetItemCount Retrieves a count of the items in a header control.

CHeaderCtrl::GetItemDropDownRect Gets the bounding rectangle information for the specified


drop-down button in a header control.

CHeaderCtrl::GetItemRect Retrieves the bounding rectangle for a given item in a


header control.

CHeaderCtrl::GetOrderArray Retrieves the left-to-right order of items in a header control.

CHeaderCtrl::GetOverflowRect Gets the bounding rectangle of the overflow button for the
current header control.

CHeaderCtrl::HitTest Determines which header item, if any, is located at a


specified point.

CHeaderCtrl::InsertItem Inserts a new item into a header control.

CHeaderCtrl::Layout Retrieves the size and position of a header control within a


given rectangle.

CHeaderCtrl::OrderToIndex Retrieves the index value for an item based on its order in
the header control.

CHeaderCtrl::SetBitmapMargin Sets the width of the margin of a bitmap in a header control.

CHeaderCtrl::SetFilterChangeTimeout Sets the timeout interval between the time a change takes
place in the filter attributes and the posting of an
HDN_FILTERCHANGE notification.

CHeaderCtrl::SetFocusedItem Sets the focus to a specified header item in the current


header control.

CHeaderCtrl::SetHotDivider Changes the divider between header items to indicate a


manual drag and drop of a header item.

CHeaderCtrl::SetImageList Assigns an image list to a header control.

CHeaderCtrl::SetItem Sets the attributes of the specified item in a header control.

CHeaderCtrl::SetOrderArray Sets the left-to-right order of items in a header control.

Remarks
A header control is a window that is usually positioned above a set of columns of text or numbers. It contains a
title for each column, and it can be divided into parts. The user can drag the dividers that separate the parts to
set the width of each column. For an illustration of a header control, see Header Controls.
This control (and therefore the CHeaderCtrl class) is available only to programs that run under Windows 95/98
and Windows NT version 3.51 and later.
Functionality added for Windows 95/Internet Explorer 4.0 common controls includes the following:
Header item custom ordering.
Header item drag and drop, for reordering of header items. Use the HDS_DRAGDROP style when you
create the CHeaderCtrl object.
Header column text constantly viewable during column resizing. Use the HDS_FULLDRAG style when
you create a CHeaderCtrl object.
Header hot tracking, which highlights the header item when the pointer is hovering over it. Use the
HDS_HOTTRACK style when you create the CHeaderCtrl object.
Image list support. Header items can contain images stored in a CImageList object or text.

For more information about using CHeaderCtrl , see Controls and Using CHeaderCtrl.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CHeaderCtrl

Requirements
Header : afxcmn.h

CHeaderCtrl::CHeaderCtrl
Constructs a CHeaderCtrl object.

CHeaderCtrl();

Example

// Declare a local CHeaderCtrl object.


CHeaderCtrl myHeaderCtrl;

// Declare a dynamic CHeaderCtrl object.


CHeaderCtrl *pmyHeaderCtrl = new CHeaderCtrl;

CHeaderCtrl::ClearAllFilters
Clears all filters for a header control.

BOOL ClearAllFilters();

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method implements the behavior of the Win32 message HDM_CLEARFILTER with a column value of -1, as
described in the Windows SDK.
Example

m_myHeaderCtrl.ClearAllFilters();

CHeaderCtrl::ClearFilter
Clears the filter for a header control.

BOOL ClearFilter(int nColumn);

Parameters
nColumn
Column value indicating which filter to clear.
Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method implements the behavior of the Win32 message HDM_CLEARFILTER, as described in the Windows
SDK.
Example

int iFilt = m_myHeaderCtrl.ClearFilter(1);

CHeaderCtrl::Create
Creates a header control and attaches it to a CHeaderCtrl object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the header control's style. For a description of header control styles, see Header Control Styles in the
Windows SDK.
rect
Specifies the header control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the header control's parent window, usually a CDialog . It must not be NULL.
nID
Specifies the header control's ID.
Return Value
Nonzero if initialization was successful; otherwise zero.
Remarks
You construct a CHeaderCtrl object in two steps. First, call the constructor and then call Create , which creates
the header control and attaches it to the CHeaderCtrl object.
In addition to the header control styles, you can use the following common control styles to determine how the
header control positions and resizes itself (see Common Control Styles for more information):
CCS_BOTTOM Causes the control to position itself at the bottom of the parent window's client area and
sets the width to be the same as the parent window's width.
CCS_NODIVIDER Prevents a two-pixel highlight from being drawn at the top of the control.
CCS_NOMOVEY Causes the control to resize and move itself horizontally, but not vertically, in response
to a WM_SIZE message. If the CCS_NORESIZE style is used, this style does not apply. Header controls
have this style by default.
CCS_NOPARENTALIGN Prevents the control from automatically moving to the top or bottom of the
parent window. Instead, the control keeps its position within the parent window despite changes to the
size of the parent window. If the CCS_TOP or CCS_BOTTOM style is also used, the height is adjusted to
the default, but the position and width remain unchanged.
CCS_NORESIZE Prevents the control from using the default width and height when setting its initial size
or a new size. Instead, the control uses the width and height specified in the request for creation or
sizing.
CCS_TOP Causes the control to position itself at the top of the parent window's client area and sets the
width to be the same as the parent window's width.
You can also apply the following window styles to a header control (see Window Styles for more information):
WS_CHILD Creates a child window. Cannot be used with the WS_POPUP style.
WS_VISIBLE Creates a window that is initially visible.
WS_DISABLED Creates a window that is initially disabled.
WS_GROUP Specifies the first control of a group of controls in which the user can move from one
control to the next with the arrow keys. All controls defined with the WS_GROUP style after the first
control belong to the same group. The next control with the WS_GROUP style ends the style group and
starts the next group (that is, one group ends where the next begins).
WS_TABSTOP Specifies one of any number of controls through which the user can move by using the
TAB key. The TAB key moves the user to the next control specified by the WS_TABSTOP style.
If you want to use extended windows styles with your control, call CreateEx instead of Create .
Example

// pParentWnd is a pointer to the parent window.


m_myHeaderCtrl.Create(WS_CHILD | WS_VISIBLE | HDS_HORZ,
CRect(10, 10, 600, 50), pParentWnd, 1);

CHeaderCtrl::CreateEx
Creates a control (a child window) and associate it with the CHeaderCtrl object.
virtual BOOL CreateEx(
DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the
dwExStyle parameter for CreateWindowEx in the Windows SDK.
dwStyle
The header control's style. For a description of header control styles, see Header Control Styles in the Windows
SDK. See Create for a list of additional styles.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client
coordinates of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended style
preface WS_EX_ .

CHeaderCtrl::CreateDragImage
Creates a transparent version of an item's image within a header control.

CImageList* CreateDragImage(int nIndex);

Parameters
nIndex
The zero-based index of the item within the header control. The image assigned to this item is the basis for the
transparent image.
Return Value
A pointer to a CImageList object if successful; otherwise NULL. The returned list contains only one image.
Remarks
This member function implements the behavior of the Win32 message HDM_CREATEDRAGIMAGE, as described
in the Windows SDK. It is provided to support header item drag and drop.
The CImageList object to which the returned pointer points is a temporary object and is deleted in the next
idle-time processing.
CHeaderCtrl::DeleteItem
Deletes an item from a header control.

BOOL DeleteItem(int nPos);

Parameters
nPos
Specifies the zero-based index of the item to delete.
Return Value
Nonzero if successful; otherwise 0.
Example

int nCount = m_myHeaderCtrl.GetItemCount();

// Delete all of the items.


for (int i = 0; i < nCount; i++)
{
m_myHeaderCtrl.DeleteItem(0);
}

CHeaderCtrl::DrawItem
Called by the framework when a visual aspect of an owner-draw header control changes.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A pointer to a DRAWITEMSTRUCT structure describing the item to be painted.
Remarks
The itemAction member of the DRAWITEMSTRUCT structure defines the drawing action that is to be performed.
By default, this member function does nothing. Override this member function to implement drawing for an
owner-draw CHeaderCtrl object.
The application should restore all graphics device interface (GDI) objects selected for the display context
supplied in lpDrawItemStruct before this member function terminates.
Example
// NOTE: CMyHeaderCtrl is a class derived from CHeaderCtrl.
// The CMyHeaderCtrl object was created as follows:
//
// CMyHeaderCtrl m_myHeader;
// myHeader.Create(WS_CHILD | WS_VISIBLE | HDS_HORZ,
// CRect(10, 10, 600, 50), pParentWnd, 1);

// This example implements the DrawItem method for a


// CHeaderCtrl-derived class that draws every item as a
// 3D button using the text color red.
void CMyHeaderCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// This code only works with header controls.
ASSERT(lpDrawItemStruct->CtlType == ODT_HEADER);

HDITEM hdi;
const int c_cchBuffer = 256;
TCHAR lpBuffer[c_cchBuffer];

hdi.mask = HDI_TEXT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = c_cchBuffer;

GetItem(lpDrawItemStruct->itemID, &hdi);

// Draw the button frame.


::DrawFrameControl(lpDrawItemStruct->hDC,
&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH);

// Draw the items text using the text color red.


COLORREF crOldColor = ::SetTextColor(lpDrawItemStruct->hDC,
RGB(255, 0, 0));
::DrawText(lpDrawItemStruct->hDC, lpBuffer,
(int)_tcsnlen(lpBuffer, c_cchBuffer),
&lpDrawItemStruct->rcItem, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
::SetTextColor(lpDrawItemStruct->hDC, crOldColor);
}

CHeaderCtrl::EditFilter
Begins to edit the specified filter of a header control.

BOOL EditFilter(
int nColumn,
BOOL bDiscardChanges);

Parameters
nColumn
The column to edit.
bDiscardChanges
A value that specifies how to handle the user's editing changes if the user is in the process of editing the filter
when the HDM_EDITFILTER message is sent.
Specify TRUE to discard the changes made by the user, or FALSE to accept the changes made by the user.
Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method implements the behavior of the Win32 message HDM_EDITFILTER, as described in the Windows
SDK.
Example

int iFilter = m_myHeaderCtrl.EditFilter(1, TRUE);

CHeaderCtrl::GetBitmapMargin
Retrieves the width of the margin of a bitmap in a header control.

int GetBitmapMargin() const;

Return Value
The width of the bitmap margin in pixels.
Remarks
This member function implements the behavior of the Win32 message HDM_GETBITMAPMARGIN, as described
in the Windows SDK.
Example

int iMargin = m_myHeaderCtrl.GetBitmapMargin();

CHeaderCtrl::GetFocusedItem
Gets the index of the item that has the focus in the current header control.

int GetFocusedItem() const;

Return Value
The zero-based index of the header item that has the focus.
Remarks
This method sends the HDM_GETFOCUSEDITEM message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_headerCtrl , that is used to access the current header
control. This variable is used in the next example.

CHeaderCtrl m_headerCtrl;
CSplitButton m_splitButton;

Example
The following code example demonstrates the SetFocusedItem and GetFocusedItem methods. In an earlier
section of the code, we created a header control with five columns. However, you can drag a column separator
so that the column is not visible. The following example sets and then confirms the last column header as the
focus item.
void CNVC_MFC_CHeaderCtrl_s4Dlg::OnXSetfocuseditem()
{
if (controlCreated == FALSE)
{
MessageBox(_T("Header control has not been created yet."));
return;
}

// Check that we get the value we set.


int item = m_headerCtrl.GetItemCount() - 1;
m_headerCtrl.SetFocusedItem(item);
int itemGet = m_headerCtrl.GetFocusedItem();
CString str = _T("Set: focused item = %d\nGet: focused item = %d");
str.Format(str, item, itemGet);
MessageBox(str, _T("Set/GetFocused Item"));
}

CHeaderCtrl::GetImageList
Retrieves the handle of an image list used for drawing header items in a header control.

CImageList* GetImageList() const;

Return Value
A pointer to a CImageList object.
Remarks
This member function implements the behavior of the Win32 message HDM_GETIMAGELIST, as described in
the Windows SDK. The CImageList object to which the returned pointer points is a temporary object and is
deleted in the next idle-time processing.
Example

// The new image list of the header control.


m_HeaderImages.Create(16, 16, ILC_COLOR, 2, 2);
m_HeaderImages.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_HeaderImages.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_HeaderImages.Add(AfxGetApp()->LoadIcon(IDI_ICON3));

ASSERT(m_myHeaderCtrl.GetImageList() == NULL);

m_myHeaderCtrl.SetImageList(&m_HeaderImages);
ASSERT(m_myHeaderCtrl.GetImageList() == &m_HeaderImages);

CHeaderCtrl::GetItem
Retrieves information about a header control item.

BOOL GetItem(
int nPos,
HDITEM* pHeaderItem) const;

Parameters
nPos
Specifies the zero-based index of the item to retrieve.
pHeaderItem
Pointer to an HDITEM structure that receives the new item. This structure is used with the InsertItem and
SetItem member functions. Any flags set in the mask element ensure that values in the corresponding
elements are properly filled in upon return. If the mask element is set to zero, values in the other structure
elements are meaningless.
Return Value
Nonzero if successful; otherwise 0.
Example

LPCTSTR lpszmyString = _T("column 2");


LPCTSTR lpszmyString2 = _T("vertical 2");

// Find the item whose text matches lpszmyString, and


// replace it with lpszmyString2.
int i, nCount = m_myHeaderCtrl.GetItemCount();
HDITEM hdi;
enum
{
sizeOfBuffer = 256
};
TCHAR lpBuffer[sizeOfBuffer];
bool fFound = false;

hdi.mask = HDI_TEXT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = sizeOfBuffer;

for (i = 0; !fFound && (i < nCount); i++)


{
m_myHeaderCtrl.GetItem(i, &hdi);

if (_tcsncmp(hdi.pszText, lpszmyString, sizeOfBuffer) == 0)


{
_tcscpy_s(hdi.pszText, sizeOfBuffer, lpszmyString2);
m_myHeaderCtrl.SetItem(i, &hdi);
fFound = true;
}
}

CHeaderCtrl::GetItemCount
Retrieves a count of the items in a header control.

int GetItemCount() const;

Return Value
Number of header control items if successful; otherwise - 1.
Example
See the example for CHeaderCtrl::DeleteItem.

CHeaderCtrl::GetItemDropDownRect
Gets the bounding rectangle of the drop-down button for a header item in the current header control.
BOOL GetItemDropDownRect(
int iItem,
LPRECT lpRect) const;

Parameters
PA RA M ET ER DESC RIP T IO N

iItem [in] Zero-based index of a header item whose style is


HDF_SPLITBUTTON. For more information, see the fmt
member of the HDITEM structure.

lpRect [out] Pointer to a RECT structure to receive the bounding


rectangle information.

Return Value
TRUE if this function is successful; otherwise, FALSE.
Remarks
This method sends the HDM_GETITEMDROPDOWNRECT message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_headerCtrl , that is used to access the current header
control. This variable is used in the next example.

CHeaderCtrl m_headerCtrl;
CSplitButton m_splitButton;

Example
The following code example demonstrates the GetItemDropDownRect method. In an earlier section of the code,
we created a header control with five columns. The following code example draws a 3D rectangle around the
location on the first column that is reserved for the header drop-down button.

void CNVC_MFC_CHeaderCtrl_s4Dlg::OnXGetitemdropdownrect()
{
if (controlCreated == FALSE)
{
MessageBox(_T("Header control has not been created yet."));
return;
}

// Get the dropdown rect for the first column.


CRect rect;
BOOL bRetVal = m_headerCtrl.GetItemDropDownRect(0, &rect);
if (bRetVal == TRUE)
{
// Draw around the dropdown rect a rectangle that has red
// left and top sides, and blue right and bottom sides.
CDC *pDC = m_headerCtrl.GetDC();
pDC->Draw3dRect(rect, RGB(255, 0, 0), RGB(0, 0, 255));
}
}

CHeaderCtrl::GetItemRect
Retrieves the bounding rectangle for a given item in a header control.
BOOL GetItemRect(
int nIndex,
LPRECT lpRect) const;

Parameters
nIndex
The zero-based index of the header control item.
lpRect
A pointer to the address of a RECT structure that receives the bounding rectangle information.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This method implements the behavior of the Win32 message HDM_GETITEMRECT, as described in the
Windows SDK.

CHeaderCtrl::GetOrderArray
Retrieves the left-to-right order of items in a header control.

BOOL GetOrderArray(
LPINT piArray,
int iCount);

Parameters
piArray
A pointer to the address of a buffer that receives the index values of the items in the header control, in the order
in which they appear from left to right.
iCount
The number of header control items. Must be non-negative.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function implements the behavior of the Win32 message HDM_GETORDERARRAY, as described in
the Windows SDK. It is provided to support header item ordering.
Example
// Reverse the order of the items in the header control.
// (i.e. make the first item the last one, the last item
// the first one, and so on ...).
int nCount = m_myHeaderCtrl.GetItemCount();
LPINT pnOrder = (LPINT)malloc(nCount * sizeof(int));
ASSERT(pnOrder != NULL);
if (NULL != pnOrder)
{
m_myHeaderCtrl.GetOrderArray(pnOrder, nCount);

int i, j, nTemp;
for (i = 0, j = nCount - 1; i < j; i++, j--)
{
nTemp = pnOrder[i];
pnOrder[i] = pnOrder[j];
pnOrder[j] = nTemp;
}

m_myHeaderCtrl.SetOrderArray(nCount, pnOrder);
free(pnOrder);
}

CHeaderCtrl::GetOverflowRect
Gets the bounding rectangle of the overflow button of the current header control.

BOOL GetOverflowRect(LPRECT lpRect) const;

Parameters
PA RA M ET ER DESC RIP T IO N

lpRect [out] Pointer to a RECT structure that receives the bounding


rectangle information.

Return Value
TRUE if this function is successful; otherwise, FALSE.
Remarks
If the header control contains more items than can be simultaneously displayed, the control can display an
overflow button that scrolls to items that are not visible. The header control must have the HDS_OVERFLOW
and HDF_SPLITBUTTON styles to display the overflow button. The bounding rectangle encloses the overflow
button and exists only when the overflow button is displayed. For more information, see Header Control Styles.
This method sends the HDM_GETOVERFLOWRECT message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_headerCtrl , that is used to access the current header
control. This variable is used in the next example.

CHeaderCtrl m_headerCtrl;
CSplitButton m_splitButton;

Example
The following code example demonstrates the GetOverflowRect method. In an earlier section of the code, we
created a header control with five columns. However, you can drag a column separator so that the column is
not visible. If some columns are not visible, the header control draws an overflow button. The following code
example draws a 3D rectangle around the location of the overflow button.

void CNVC_MFC_CHeaderCtrl_s4Dlg::OnXGetoverflowrect()
{
if (controlCreated == FALSE)
{
MessageBox(_T("Header control has not been created yet."));
return;
}
CRect rect;
// Get the overflow rectangle.
BOOL bRetVal = m_headerCtrl.GetOverflowRect(&rect);
// Get the device context.
CDC *pDC = m_headerCtrl.GetDC();
// Draw around the overflow rect a rectangle that has red
// left and top sides, and green right and bottom sides.
pDC->Draw3dRect(rect, RGB(255, 0, 0), RGB(0, 255, 0));
}

CHeaderCtrl::HitTest
Determines which header item, if any, is located at a specified point.

int HitTest(LPHDHITTESTINFO* phdhti);

Parameters
PA RA M ET ER DESC RIP T IO N

phdhti [in, out] Pointer to a HDHITTESTINFO structure that specifies


the point to test and receives the results of the test.

Return Value
The zero-based index of the header item, if any, at the specified position; otherwise, -1.
Remarks
This method sends the HDM_HITTEST message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_headerCtrl , that is used to access the current header
control. This variable is used in the next example.

CHeaderCtrl m_headerCtrl;
CSplitButton m_splitButton;

Example
The following code example demonstrates the HitTest method. In an earlier section of this code example, we
created a header control with five columns. However, you can drag a column separator so that the column is
not visible. This example reports the index of the column if it is visible and -1 if the column is not visible.
void CNVC_MFC_CHeaderCtrl_s4Dlg::OnXHittest()
{
if (controlCreated == FALSE)
{
MessageBox(_T("Header control has not been created yet."));
return;
}
// Initialize HDHITTESTINFO structure.
HDHITTESTINFO hdHitIfo;
memset(&hdHitIfo, 0, sizeof(HDHITTESTINFO));

CString str;
CRect rect;
int iRetVal = -1;
for (int i = 0; i < m_headerCtrl.GetItemCount(); i++)
{
m_headerCtrl.GetItemRect(i, &rect);
hdHitIfo.pt = rect.CenterPoint();
// The hit test depends on whether the header item is visible.
iRetVal = m_headerCtrl.HitTest(&hdHitIfo);
str.AppendFormat(_T("Item = %d, Hit item = %d\n"), i, iRetVal);
}
MessageBox(str, _T("Hit test results"));
}

CHeaderCtrl::InsertItem
Inserts a new item into a header control at the specified index.

int InsertItem(
int nPos,
HDITEM* phdi);

Parameters
nPos
The zero-based index of the item to be inserted. If the value is zero, the item is inserted at the beginning of the
header control. If the value is greater than the maximum value, the item is inserted at the end of the header
control.
phdi
Pointer to an HDITEM structure that contains information about the item to be inserted.
Return Value
Index of the new item if successful; otherwise - 1.
Example
CString str;
HDITEM hdi;

hdi.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT | HDI_IMAGE;


hdi.cxy = 100; // Make all columns 100 pixels wide.
hdi.fmt = HDF_STRING | HDF_CENTER;

// Insert 6 columns in the header control.


for (int i = 0; i < 6; i++)
{
str.Format(TEXT("column %d"), i);
hdi.pszText = str.GetBuffer(0);
hdi.iImage = i % 3;

m_myHeaderCtrl.InsertItem(i, &hdi);
}

CHeaderCtrl::Layout
Retrieves the size and position of a header control within a given rectangle.

BOOL Layout(HDLAYOUT* pHeaderLayout);

Parameters
pHeaderLayout
Pointer to an HDLAYOUT structure, which contains information used to set the size and position of a header
control.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This function is used to determine the appropriate dimensions for a new header control that is to occupy the
given rectangle.
Example

HDLAYOUT hdl;
WINDOWPOS wpos;
RECT rc;

// Reposition the header control so that it is placed at


// the top of its parent window's client area.
m_myHeaderCtrl.GetParent()->GetClientRect(&rc);

hdl.prc = &rc;
hdl.pwpos = &wpos;
if (m_myHeaderCtrl.Layout(&hdl))
{
m_myHeaderCtrl.SetWindowPos(
CWnd::FromHandle(wpos.hwndInsertAfter),
wpos.x,
wpos.y,
wpos.cx,
wpos.cy,
wpos.flags | SWP_SHOWWINDOW);
}
CHeaderCtrl::OrderToIndex
Retrieves the index value for an item based on its order in the header control.

int OrderToIndex(int nOrder) const;

Parameters
nOrder
The zero-based order that the item appears in the header control, from left to right.
Return Value
The index of the item, based on its order in the header control. The index counts from left to right, beginning
with 0.
Remarks
This member function implements the behavior of the Win32 macro HDM_ORDERTOINDEX, as described in the
Windows SDK. It is provided to support header item ordering.

CHeaderCtrl::SetBitmapMargin
Sets the width of the margin of a bitmap in a header control.

int SetBitmapMargin(int nWidth);

Parameters
nWidth
Width, specified in pixels, of the margin that surrounds a bitmap within an existing header control.
Return Value
The width of the bitmap margin in pixels.
Remarks
This member function implements the behavior of the Win32 message HDM_SETBITMAPMARGIN, as described
in the Windows SDK.
Example

int iOldMargin = m_myHeaderCtrl.SetBitmapMargin(15);

CHeaderCtrl::SetFilterChangeTimeout
Sets the timeout interval between the time a change takes place in the filter attributes and the posting of an
HDN_FILTERCHANGE notification.

int SetFilterChangeTimeout(DWORD dwTimeOut);

Parameters
dwTimeOut
Timeout value, in milliseconds.
Return Value
The index of the filter control being modified.
Remarks
This member function implements the behavior of the Win32 message HDM_SETFILTERCHANGETIMEOUT, as
described in the Windows SDK.
Example

int iFltr = m_myHeaderCtrl.SetFilterChangeTimeout(15);

CHeaderCtrl::SetFocusedItem
Sets the focus to a specified header item in the current header control.

BOOL SetFocusedItem(int iItem);

Parameters
PA RA M ET ER DESC RIP T IO N

iItem [in] Zero-based index of a header item.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the HDM_SETFOCUSEDITEM message, which is described in the Windows SDK.
Example
The following code example defines the variable, m_headerCtrl , that is used to access the current header
control. This variable is used in the next example.

CHeaderCtrl m_headerCtrl;
CSplitButton m_splitButton;

Example
The following code example demonstrates the SetFocusedItem and GetFocusedItem methods. In an earlier
section of the code, we created a header control with five columns. However, you can drag a column separator
so that the column is not visible. The following example sets and then confirms the last column header as the
focus item.
void CNVC_MFC_CHeaderCtrl_s4Dlg::OnXSetfocuseditem()
{
if (controlCreated == FALSE)
{
MessageBox(_T("Header control has not been created yet."));
return;
}

// Check that we get the value we set.


int item = m_headerCtrl.GetItemCount() - 1;
m_headerCtrl.SetFocusedItem(item);
int itemGet = m_headerCtrl.GetFocusedItem();
CString str = _T("Set: focused item = %d\nGet: focused item = %d");
str.Format(str, item, itemGet);
MessageBox(str, _T("Set/GetFocused Item"));
}

CHeaderCtrl::SetHotDivider
Changes the divider between header items to indicate a manual drag and drop of a header item.

int SetHotDivider(CPoint pt);


int SetHotDivider(int nIndex);

Parameters
pt
The position of the pointer. The header control highlights the appropriate divider based on the pointer's
position.
nIndex
The index of the highlighted divider.
Return Value
The index of the highlighted divider.
Remarks
This member function implements the behavior of the Win32 message HDM_SETHOTDIVIDER, as described in
the Windows SDK. It is provided to support header item drag and drop.
Example

void CMyHeaderCtrl::OnMouseMove(UINT nFlags, CPoint point)


{
SetHotDivider(point);

CHeaderCtrl::OnMouseMove(nFlags, point);
}

CHeaderCtrl::SetImageList
Assigns an image list to a header control.

CImageList* SetImageList(CImageList* pImageList);

Parameters
pImageList
A pointer to a CImageList object containing the image list to be assigned to the header control.
Return Value
A pointer to the CImageList object previously assigned to the header control.
Remarks
This member function implements the behavior of the Win32 message HDM_SETIMAGELIST, as described in
the Windows SDK. The CImageList object to which the returned pointer points is a temporary object and is
deleted in the next idle-time processing.
Example
See the example for CHeaderCtrl::GetImageList.

CHeaderCtrl::SetItem
Sets the attributes of the specified item in a header control.

BOOL SetItem(
int nPos,
HDITEM* pHeaderItem);

Parameters
nPos
The zero-based index of the item to be manipulated.
pHeaderItem
Pointer to an HDITEM structure that contains information about the new item.
Return Value
Nonzero if successful; otherwise 0.
Example
See the example for CHeaderCtrl::GetItem.

CHeaderCtrl::SetOrderArray
Sets the left-to-right order of items in a header control.

BOOL SetOrderArray(
int iCount,
LPINT piArray);

Parameters
iCount
The number of header control items.
piArray
A pointer to the address of a buffer that receives the index values of the items in the header control, in the order
in which they appear from left to right.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function implements the behavior of the Win32 macro HDM_SETORDERARRAY, as described in
the Windows SDK. It is provided to support header item ordering.
Example
See the example for CHeaderCtrl::GetOrderArray.

See also
CWnd Class
Hierarchy Chart
CTabCtrl Class
CListCtrl Class
CImageList Class
CHotKeyCtrl Class
4/21/2020 • 6 minutes to read • Edit Online

Provides the functionality of the Windows common hot key control.

Syntax
class CHotKeyCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CHotKeyCtrl::CHotKeyCtrl Constructs a CHotKeyCtrl object.

Public Methods
NAME DESC RIP T IO N

CHotKeyCtrl::Create Creates a hot key control and attaches it to a CHotKeyCtrl


object.

CHotKeyCtrl::CreateEx Creates a hot key control with the specified Windows


extended styles and attaches it to a CHotKeyCtrl object.

CHotKeyCtrl::GetHotKey Retrieves the virtual key code and modifier flags of a hot key
from a hot key control.

CHotKeyCtrl::GetHotKeyName Retrieves the key name, in the local character set, assigned to
a hot key.

CHotKeyCtrl::GetKeyName Retrieves the key name, in the local character set, assigned to
the specified virtual key code.

CHotKeyCtrl::SetHotKey Sets the hot key combination for a hot key control.

CHotKeyCtrl::SetRules Defines the invalid combinations and the default modifier


combination for a hot key control.

Remarks
A "hot key control" is a window that enables the user to create a hot key. A "hot key" is a key combination that the
user can press to perform an action quickly. (For example, a user can create a hot key that activates a given
window and brings it to the top of the Z order.) The hot key control displays the user's choices and ensures that
the user selects a valid key combination.
This control (and therefore the CHotKeyCtrl class) is available only to programs running under Windows 95/98
and Windows NT version 3.51 and later.
When the user has chosen a key combination, the application can retrieve the specified key combination from the
control and use the WM_SETHOTKEY message to set up the hot key in the system. Whenever the user presses the
hot key thereafter, from any part of the system, the window specified in the WM_SETHOTKEY message receives a
WM_SYSCOMMAND message specifying SC_HOTKEY. This message activates the window that receives it. The hot
key remains valid until the application that called WM_SETHOTKEY exits.
This mechanism is different from the hot key support that depends on the WM_HOTKEY message and the
Windows RegisterHotKey and UnregisterHotKey functions.
For more information on using CHotKeyCtrl , see Controls and Using CHotKeyCtrl.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CHotKeyCtrl

Requirements
Header : afxcmn.h

CHotKeyCtrl::CHotKeyCtrl
Constructs a CHotKeyCtrl object.

CHotKeyCtrl();

CHotKeyCtrl::Create
Creates a hot key control and attaches it to a CHotKeyCtrl object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the hot key control's style. Apply any combination of control styles. See Common Control Styles in the
Windows SDK for more information.
rect
Specifies the hot key control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the hot key control's parent window, usually a CDialog. It must not be NULL.
nID
Specifies the hot key control's ID.
Return Value
Nonzero, if initialization was successful; otherwise 0.
Remarks
You construct a CHotKeyCtrl object in two steps. First, call the constructor and then call Create , which creates
the hot key control and attaches it to the CHotKeyCtrl object.
If you want to use extended windows styles with your control, call CreateEx instead of Create .

CHotKeyCtrl::CreateEx
Call this function to create a control (a child window) and associate it with the CHotKeyCtrl object.

virtual BOOL CreateEx(


DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the dwExStyle
parameter for CreateWindowEx in the Windows SDK.
dwStyle
Specifies the hot key control's style. Apply any combination of control styles. For more information, see Common
Control Styles in the Windows SDK.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client coordinates
of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended style
preface WS_EX_ .

CHotKeyCtrl::GetHotKey
Retrieves the virtual key code and modifier flags of a keyboard shortcut from a hot key control.

DWORD GetHotKey() const;

void GetHotKey(
WORD& wVirtualKeyCode,
WORD& wModifiers) const;
Parameters
wVirtualKeyCode
[out] Virtual key code of the keyboard shortcut. For a list of standard virtual key codes, see Winuser.h.
wModifiers
[out] A bitwise combination (OR) of flags that indicate the modifier keys in the keyboard shortcut.
The modifier flags are as follows:

FLAG C O RRESP O N DIN G K EY

HOTKEYF_ALT ALT key

HOTKEYF_CONTROL CTRL key

HOTKEYF_EXT Extended key

HOTKEYF_SHIFT SHIFT key

Return Value
In the first overloaded method, a DWORD that contains the virtual key code and modifier flags. The low-order
byte of the low-order word contains the virtual key code, the high-order byte of the low-order word contains the
modifier flags, and the high-order word is zero.
Remarks
The virtual key code and the modifier keys together define the keyboard shortcut.

CHotKeyCtrl::GetHotKeyName
Call this member function to get the localized name of the hot key.

CString GetHotKeyName() const;

Return Value
The localized name of the currently selected hot key. If there is no selected hot key, GetHotKeyName returns an
empty string.
Remarks
The name that this member function returns comes from the keyboard driver. You can install a non-localized
keyboard driver in a localized version of Windows, and vice versa.

CHotKeyCtrl::GetKeyName
Call this member function to get the localized name of the key assigned to a specified virtual key code.

static CString GetKeyName(


UINT vk,
BOOL fExtended);

Parameters
vk
The virtual key code.
fExtended
If the virtual key code is an extended key, TRUE; otherwise FALSE.
Return Value
The localized name of the key specified by the vk parameter. If the key has no mapped name, GetKeyName returns
an empty string.
Remarks
The key name that this function returns comes from the keyboard driver, so you can install a non-localized
keyboard driver in a localized version of Windows, and vice versa.
Example

CString str;
str = CHotKeyCtrl::GetKeyName(VK_CONTROL, FALSE);
// str is now "Ctrl", or the localized equivalent.

CHotKeyCtrl::SetHotKey
Sets the keyboard shortcut for a hot key control.

void SetHotKey(
WORD wVirtualKeyCode,
WORD wModifiers);

Parameters
wVirtualKeyCode
[in] Virtual key code of the keyboard shortcut. For a list of standard virtual key codes, see Winuser.h.
wModifiers
[in] A bitwise combination (OR) of flags that indicate the modifier keys in the keyboard shortcut.
The modifier flags are as follows:

FLAG C O RRESP O N DIN G K EY

HOTKEYF_ALT ALT key

HOTKEYF_CONTROL CTRL key

HOTKEYF_EXT Extended key

HOTKEYF_SHIFT SHIFT key

Remarks
The virtual key code and the modifier keys together define the keyboard shortcut.

CHotKeyCtrl::SetRules
Call this function to define the invalid combinations and the default modifier combination for a hot key control.
void SetRules(
WORD wInvalidComb,
WORD wModifiers);

Parameters
wInvalidComb
Array of flags that specifies invalid key combinations. It can be a combination of the following values:
HKCOMB_A ALT
HKCOMB_C CTRL
HKCOMB_CA CTRL+ALT
HKCOMB_NONE Unmodified keys
HKCOMB_S SHIFT
HKCOMB_SA SHIFT+ALT
HKCOMB_SC SHIFT+CTRL
HKCOMB_SCA SHIFT+CTRL+ALT
wModifiers
Array of flags that specifies the key combination to use when the user enters an invalid combination. For more
information on the modifier flags, see GetHotKey.
Remarks
When a user enters an invalid key combination, as defined by flags specified in wInvalidComb, the system uses
the OR operator to combine the keys entered by the user with the flags specified in wModifiers. The resulting key
combination is converted into a string and then displayed in the hot key control.

See also
CWnd Class
Hierarchy Chart
CHtmlEditCtrl Class
3/27/2020 • 2 minutes to read • Edit Online

Provides the functionality of the WebBrowser ActiveX control in an MFC window.

Syntax
class CHtmlEditCtrl: public CWnd,
public CHtmlEditCtrlBase<CHtmlEditCtrl>

Members
Public Constructors
NAME DESC RIP T IO N

CHtmlEditCtrl::CHtmlEditCtrl Constructs a CHtmlEditCtrl object.

Public Methods
NAME DESC RIP T IO N

CHtmlEditCtrl::Create Creates a WebBrowser ActiveX control and attaches it to the


CHtmlEditCtrl object. This function automatically puts the
WebBrowser ActiveX control into edit mode.

CHtmlEditCtrl::GetDHtmlDocument Retrieves the IHTMLDocument2 interface on the document


currently loaded in the contained WebBrowser control.

CHtmlEditCtrl::GetStartDocument Retrieves the URL to a default document to load in the


contained WebBrowser control.

Remarks
The hosted WebBrowser control is automatically put into edit mode after it is created.

Inheritance Hierarchy
CObject
CCmdTarget
CHtmlEditCtrlBase
CWnd
CHtmlEditCtrl

Requirements
Header : afxhtml.h
CHtmlEditCtrl::CHtmlEditCtrl
Constructs a CHtmlEditCtrl object.

CHtmlEditCtrl();

CHtmlEditCtrl::Create
Creates a WebBrowser ActiveX control and attaches it to the CHtmlEditCtrl object. The WebBrowser ActiveX
control automatically navigates to a default document and then is placed in edit mode by this function.

virtual BOOL Create(


LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
int nID,
CCreateContext* pContext = NULL);

Parameters
lpszWindowName
This parameter is unused.
dwStyle
This parameter is unused.
rect
Specifies the control's size and position.
pParentWnd
Specifies the control's parent window. It must not be NULL.
nID
Specifies the control's ID.
pContext
This parameter is unused.
Return Value
Returns TRUE on success, FALSE on failure.

CHtmlEditCtrl::GetDHtmlDocument
Retrieves the IHTMLDocument2 interface on the document currently loaded in the contained WebBrowser control

BOOL GetDHtmlDocument(IHTMLDocument2** ppDocument) const;

Parameters
ppDocument
The document interface.

CHtmlEditCtrl::GetStartDocument
Retrieves the URL to a default document to load in the contained WebBrowser control.
virtual LPCTSTR GetStartDocument();

See also
Hierarchy Chart
CHtmlEditCtrlBase Class
4/21/2020 • 32 minutes to read • Edit Online

Represents an HTML editing component.

Syntax
template <class T> class CHtmlEditCtrlBase

Members
Public Methods
NAME DESC RIP T IO N

CHtmlEditCtrlBase::AddToGlyphTable Adds an entry to the glyph table, which specifies images to


display for specific tags in design mode.

CHtmlEditCtrlBase::Bold Toggles the bold state of the selected text.

CHtmlEditCtrlBase::Button Overwrites a button control on the current selection.

CHtmlEditCtrlBase::CheckBox Overwrites a check box control on the current selection.

CHtmlEditCtrlBase::ClearSelection Clears the current selection.

CHtmlEditCtrlBase::Copy Copies the current selection to the clipboard.

CHtmlEditCtrlBase::Cut Copies the current selection to the clipboard and then deletes
it.

CHtmlEditCtrlBase::Delete Deletes the current selection.

CHtmlEditCtrlBase::DropDownBox Overwrites a drop-down selection control on the current


selection.

CHtmlEditCtrlBase::EmptyGlyphTable Removes all entries from the glyph table, which hides all
images displayed for tags in design mode.

CHtmlEditCtrlBase::ExecCommand Executes a command.

CHtmlEditCtrlBase::Font Opens a font dialog box to enable the user to change the text
color, font, and font size of the current selection.

CHtmlEditCtrlBase::GetAbsolutePosition Returns whether an element's position property is "absolute."

CHtmlEditCtrlBase::GetBackColor Retrieves the background color of the current selection.

CHtmlEditCtrlBase::GetBlockFormat Retrieves the current block format tag.


NAME DESC RIP T IO N

CHtmlEditCtrlBase::GetBlockFormatNames Retrieves the strings corresponding to the available block


format tags.

CHtmlEditCtrlBase::GetBookMark Retrieves the name of a bookmark anchor.

CHtmlEditCtrlBase::GetDocument Retrieves the document object.

CHtmlEditCtrlBase::GetDocumentHTML Retrieves the HTML of the current document.

CHtmlEditCtrlBase::GetDocumentTitle Retrieves the document's title.

CHtmlEditCtrlBase::GetEvent Retrieves an interface pointer to the event object that contains


information relevant to the most recent event.

CHtmlEditCtrlBase::GetEventSrcElement Retrieves the object that fired the event.

CHtmlEditCtrlBase::GetFontFace Retrieves the font name for the current selection.

CHtmlEditCtrlBase::GetFontSize Retrieves the font size for the current selection.

CHtmlEditCtrlBase::GetForeColor Retrieves the foreground (text) color of the current selection.

CHtmlEditCtrlBase::GetFrameZone Returns the security zone of the current page in the web
browser.

CHtmlEditCtrlBase::GetIsDirty Indicates whether the HTML document has changed.

CHtmlEditCtrlBase::GetShowAlignedSiteTags Returns whether a glyph is displayed for all elements that


have a styleFloat property.

CHtmlEditCtrlBase::GetShowAllTags Returns whether the WebBrowser displays glyphs to show the


location of all tags in a document.

CHtmlEditCtrlBase::GetShowAreaTags Retrieves whether the WebBrowser displays a glyph for area


tags.

CHtmlEditCtrlBase::GetShowBRTags Retrieves whether the WebBrowser displays a glyph for br


tags.

CHtmlEditCtrlBase::GetShowCommentTags Retrieves whether the WebBrowser displays a glyph for


comment tags.

CHtmlEditCtrlBase::GetShowMiscTags Retrieves whether the WebBrowser displays all the tags shown
in Microsoft Internet Explorer 4.0.

CHtmlEditCtrlBase::GetShowScriptTags Retrieves whether the WebBrowser displays a glyph for all the
script tags.

CHtmlEditCtrlBase::GetShowStyleTags Retrieves whether the WebBrowser displays a glyph for all the
style tags.
NAME DESC RIP T IO N

CHtmlEditCtrlBase::GetShowUnknownTags Retrieves whether the WebBrowser displays a glyph for all


unknown tags.

CHtmlEditCtrlBase::HorizontalLine Overwrites a horizontal line on the current selection.

CHtmlEditCtrlBase::HyperLink Inserts a hyperlink on the current selection.

CHtmlEditCtrlBase::IE50Paste Performs a paste operation compatible with Microsoft Internet


Explorer 5.

CHtmlEditCtrlBase::Iframe Overwrites an inline frame on the current selection.

CHtmlEditCtrlBase::Image Overwrites an image on the current selection.

CHtmlEditCtrlBase::Indent Increases the indent of the selected text by one indentation


increment.

CHtmlEditCtrlBase::InsFieldSet Overwrites a box on the current selection.

CHtmlEditCtrlBase::InsInputButton Overwrites a button control on the current selection.

CHtmlEditCtrlBase::InsInputHidden Inserts a hidden control on the current selection.

CHtmlEditCtrlBase::InsInputImage Overwrites an image control on the current selection.

CHtmlEditCtrlBase::InsInputPassword Overwrites a password control on the current selection.

CHtmlEditCtrlBase::InsInputReset Overwrites a reset control on the current selection.

CHtmlEditCtrlBase::InsInputSubmit Overwrites a submit control on the current selection.

CHtmlEditCtrlBase::InsInputUpload Overwrites a file upload control on the current selection.

CHtmlEditCtrlBase::Is1DElement Determines if an element is statically positioned.

CHtmlEditCtrlBase::Is2DElement Determines if an element is absolutely positioned.

CHtmlEditCtrlBase::Italic Toggles the current selection between italic and nonitalic.

CHtmlEditCtrlBase::JustifyCenter Centers the format block in which the current selection is


located.

CHtmlEditCtrlBase::JustifyLeft Left-justifies the format block in which the current selection is


located.

CHtmlEditCtrlBase::JustifyRight Right-justifies the format block in which the current selection


is located.

CHtmlEditCtrlBase::ListBox Overwrites a list box selection control on the current selection.

CHtmlEditCtrlBase::Marquee Overwrites an empty marquee on the current selection.


NAME DESC RIP T IO N

CHtmlEditCtrlBase::NewDocument Creates a new document.

CHtmlEditCtrlBase::OrderList Toggles the current selection between an ordered list and a


normal format block.

CHtmlEditCtrlBase::Outdent Decreases by one increment the indentation of the format


block in which the current selection is located.

CHtmlEditCtrlBase::Paragraph Overwrites a line break on the current selection.

CHtmlEditCtrlBase::Paste Overwrites the contents of the clipboard on the current


selection.

CHtmlEditCtrlBase::PrintDocument Prints the current document.

CHtmlEditCtrlBase::PrintPreview Opens the Print Preview window for the current document
using either the default print preview template or a custom
template.

CHtmlEditCtrlBase::QueryStatus Call this method to query the status of commands.

CHtmlEditCtrlBase::RadioButton Overwrites a radio control on the current selection.

CHtmlEditCtrlBase::RefreshDocument Refreshes the current document.

CHtmlEditCtrlBase::RemoveFormat Removes the formatting tags from the current selection.

CHtmlEditCtrlBase::SaveAs Saves the current Web page to a file.

CHtmlEditCtrlBase::SelectAll Selects the entire document.

CHtmlEditCtrlBase::Set2DPosition Allows absolutely positioned elements to be moved by


dragging.

CHtmlEditCtrlBase::SetAbsolutePosition Sets an element's position property to "absolute" or "static."

CHtmlEditCtrlBase::SetAtomicSelection Set atomic selection mode.

CHtmlEditCtrlBase::SetAutoURLDetectMode Turns automatic URL detection on and off.

CHtmlEditCtrlBase::SetBackColor Sets the background color of the current selection.

CHtmlEditCtrlBase::SetBlockFormat Sets the current block format tag.

CHtmlEditCtrlBase::SetBookMark Creates a bookmark anchor for the current selection or


insertion point.

CHtmlEditCtrlBase::SetCSSEditingLevel Selects which CSS level (CSS1 or CSS2) the editor will support,
if any.

CHtmlEditCtrlBase::SetDefaultComposeSettings Call this method to set the default compose settings.


NAME DESC RIP T IO N

CHtmlEditCtrlBase::SetDesignMode Set design mode.

CHtmlEditCtrlBase::SetDisableEditFocusUI Disables the hatched border and handles around an element


that has edit focus.

CHtmlEditCtrlBase::SetDocumentHTML Sets the HTML of the current document.

CHtmlEditCtrlBase::SetFontFace Sets the font for the current selection.

CHtmlEditCtrlBase::SetFontSize Sets the font size for the current selection.

CHtmlEditCtrlBase::SetForeColor Sets the foreground (text) color of the current selection.

CHtmlEditCtrlBase::SetIE5PasteMode Sets the paste operation to be compatible with Microsoft


Internet Explorer 5.

CHtmlEditCtrlBase::SetLiveResize Causes the WebBrowser to update an element's appearance


continuously during a resizing or moving operation.

CHtmlEditCtrlBase::SetMultiSelect Enables multiple selection.

CHtmlEditCtrlBase::SetOverrideCursor Commands the WebBrowser never to change the mouse


pointer.

CHtmlEditCtrlBase::SetOverwriteMode Toggles the text-entry mode between insert and overwrite.

CHtmlEditCtrlBase::SetRespectVisInDesign Hides invisible elements in design mode.

CHtmlEditCtrlBase::SetShowAlignedSiteTags Displays a glyph for all elements that have a styleFloat


property.

CHtmlEditCtrlBase::SetShowAllTags Displays glyphs to show the location of all tags in a document.

CHtmlEditCtrlBase::SetShowAreaTags Displays a glyph for all the area tags.

CHtmlEditCtrlBase::SetShowBRTags Displays a glyph for all the br tags.

CHtmlEditCtrlBase::SetShowCommentTags Displays a glyph for all the comment tags.

CHtmlEditCtrlBase::SetShowMiscTags Displays all the tags shown in Microsoft Internet Explorer 4.0.

CHtmlEditCtrlBase::SetShowScriptTags Displays a glyph for all the script tags.

CHtmlEditCtrlBase::SetShowStyleTags Displays a glyph for all the style tags.

CHtmlEditCtrlBase::SetShowUnknownTags Displays a glyph for all the unknown tags.

CHtmlEditCtrlBase::TextArea Overwrites a multiline text input control on the current


selection.

CHtmlEditCtrlBase::TextBox Overwrites a text control on the current selection.


NAME DESC RIP T IO N

CHtmlEditCtrlBase::UnBookmark Removes any bookmark from the current selection.

CHtmlEditCtrlBase::Underline Toggles the current selection between underlined and not


underlined.

CHtmlEditCtrlBase::Unlink Removes any hyperlink from the current selection.

CHtmlEditCtrlBase::UnorderList Toggles the current selection between an ordered list and a


normal format block.

Parameters
T
The name of the derived class.

Remarks
CHtmlEditCtrlBase provides member functions for the WebBrowser's HTML editing commands, such as Bold.
(Alternately, you can call ExecCommand to execute the IDM_BOLD command.)
CHtmlEditCtrlBaseis not intended to stand on its own. It is designed to be a base class for derived classes that
expose the HTML editing functionality of the WebBrowser (see CHtmlEditCtrl and CHtmlEditView).

Inheritance Hierarchy
CHtmlEditCtrlBase

Requirements
Header : afxhtml.h

CHtmlEditCtrlBase::AddToGlyphTable
Adds an entry to the glyph table, which specifies images to display for specific tags in design mode.

HRESULT AddToGlyphTable(
LPCTSTR szTag,
LPCTSTR szImgUrl,
unsigned short nTagType,
unsigned short nAlignment,
unsigned short nPosInfo,
unsigned short nDirection,
unsigned int nImgWidth,
unsigned int nImgHeight) const;

Parameters
szTag
The tag name (for example, "P" or "table").
szImgUrl
The image URL.
nTagType
Tag type: 0 means the image is for the opening tag only. 1 means the image is for the closing tag only. 2 means the
image is for both the opening and closing tags. Single tags such as br and comment must be added with the tag
type set to 0.
nAlignment
Alignment (rectangular elements only): This parameter indicates that the image is for an element with an
alignment attribute. Left = 0, center = 1, right = 2, and undefined = 3. Left, right, or center attributes must be
explicitly set on the element.
nPosInfo
Positioning information. Determines what cascading style sheets (CSS) positioning value the glyph applies to,
where static positioning = 0, absolute positioning = 1, relative positioning = 2, and all = 3. This field enables you to
specify one glyph for a tag when it is not positioned and another glyph to show an anchor point when the tag is
positioned.
nDirection
The direction. This parameter specifies the image for a tag based on the reading order of the current language. 0
specifies left to right, 1 specifies right to left, 2 specifies top to bottom, 3 specifies bottom to top, and 4 specifies all.
You normally set this field to 4.
nImgWidth
The image width in pixels.
nImgHeight
The image height in pixels.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information on the parameters, see "Glyph Table String Format" in Using Editing Glyphs.
This method sends the IDM_ADDTOGLYPHTABLE command ID to the WebBrowser control.

CHtmlEditCtrlBase::Bold
Toggles the bold state of the selected text.

HRESULT Bold() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BOLD command ID to the WebBrowser control.

CHtmlEditCtrlBase::Button
Overwrites a button control on the current selection.

HRESULT Button(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the button control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BUTTON command ID to the WebBrowser control.

CHtmlEditCtrlBase::CheckBox
Overwrites a check box control on the current selection.

HRESULT CheckBox(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the check box control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_CHECKBOX command ID to the WebBrowser control.

CHtmlEditCtrlBase::ClearSelection
Clears the current selection.

HRESULT ClearSelection() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_CLEARSELECTION command ID to the WebBrowser control.

CHtmlEditCtrlBase::Copy
Copies the current selection to the clipboard.

HRESULT Copy() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_COPY command ID to the WebBrowser control.

CHtmlEditCtrlBase::Cut
Copies the current selection to the clipboard and then deletes it.

HRESULT Cut() const;


Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_CUT command ID to the WebBrowser control.

CHtmlEditCtrlBase::Delete
Deletes the current selection.

HRESULT Delete() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_DELETE command ID to the WebBrowser control.

CHtmlEditCtrlBase::DropDownBox
Overwrites a drop-down selection control on the current selection.

HRESULT DropDownBox(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the drop-down selection control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_DROPDOWNBOX command ID to the WebBrowser control.

CHtmlEditCtrlBase::EmptyGlyphTable
Removes all entries from the glyph table, which hides all images displayed for tags in design mode.

HRESULT EmptyGlyphTable() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_EMPTYGLYPHTABLE command ID to the WebBrowser control.

CHtmlEditCtrlBase::ExecCommand
Executes a command.
HRESULT ExecCommand(
long cmdID,
long cmdExecOpt,
VARIANT* pInVar = NULL,
VARIANT* pOutVar = NULL) const;

HRESULT ExecCommand(
const GUID* pGuid,
long cmdID,
long cmdExecOpt,
VARIANT* pInVar = NULL,
VARIANT* pOutVar = NULL) const;

Parameters
cmdID
The command ID to be executed. For a list, see MSHTML Command Identifiers.
cmdExecOpt
Values taken from the OLECMDEXECOPT enumeration, which describe how the object should execute the
command.
pInVar
The input arguments.
pOutVar
The command output.
pGuid
The GUID of the command group.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method provides the functionality of IOleCommandTarget::Exec.

CHtmlEditCtrlBase::Font
Opens a font dialog box to enable the user to change the text color, font, and font size of the current selection.

HRESULT Font() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_FONT command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetAbsolutePosition
Returns whether an element's position property is "absolute."

HRESULT GetAbsolutePosition(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the element's position property is set to "absolute."
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_ABSOLUTE_POSITION Command ID.

CHtmlEditCtrlBase::GetBackColor
Retrieves the background color of the current selection.

HRESULT GetBackColor(int& nColor) const;

Parameters
nColor
The background color.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BACKCOLOR Command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetBlockFormat
Retrieves the current block format tag.

HRESULT GetBlockFormat(CString& strFormat) const;

Parameters
strFormat
The current block format tag.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BLOCKFMT command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetBlockFormatNames
Retrieves the strings corresponding to the available block format tags.

HRESULT GetBlockFormatNames(CStringArray& sa) const;

Parameters
sa
The available block format tags, as an array of strings.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_GETBLOCKFMTS command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetBookMark
Retrieves the name of a bookmark anchor.

HRESULT GetBookMark(CString& strAnchor) const;

Parameters
strAnchor
The name of a bookmark anchor.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_BOOKMARK Command ID.

CHtmlEditCtrlBase::GetDocument
Retrieves the document object.

HRESULT GetDocument(IHTMLDocument2** ppDoc) const;

Parameters
ppDoc
The document object.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::GetDocumentHTML
Retrieves the HTML of the current document.

HRESULT GetDocumentHTML(CString& szHTML) const;

Parameters
szHTML
The HTML.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::GetDocumentTitle
Retrieves the document's title.
HRESULT GetDocumentTitle(CString& szTitle) const;

Parameters
szTitle
The document's title.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::GetEvent
Retrieves an interface pointer to the event object that contains information relevant to the most recent event.

HRESULT GetEvent(IHTMLEventObj** ppEventObj) const;

Parameters
ppEventObj
The event object.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::GetEventSrcElement
Retrieves the object that fired the event.

HRESULT GetEventSrcElement(IHTMLElement** ppSrcElement) const;

Parameters
ppSrcElement
The element that fired the event.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::GetFontFace
Retrieves the font name for the current selection.

HRESULT GetFontFace(CString& strFace) const;

Parameters
strFace
The font name.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
If the current selection uses more than one font, strFace will be an empty string.
This method sends the IDM_FONTNAME command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetFontSize
Retrieves the font size for the current selection.

HRESULT GetFontSize(short& nSize) const;

Parameters
nSize
The font size.
Return Value
Returns the HTML font size (1-7). Returns 0 if the selection contains multiple font sizes.
Remarks
This method sends the IDM_FONTSIZE command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetForeColor
Retrieves the foreground (text) color of the current selection.

HRESULT GetForeColor(int& nColor);

Parameters
nColor
The foreground color.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_FORECOLOR Command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetFrameZone
Returns the security zone of the current page in the web browser.

HRESULT GetFrameZone(short& nZone) const;

Parameters
nZone
The security zone.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_GETFRAMEZONE command ID to the WebBrowser control.

CHtmlEditCtrlBase::GetIsDirty
Indicates whether the HTML document has changed.

HRESULT GetIsDirty() const;

Remarks
Indicates whether the document has changed. GetIsDirty returns an HRESULT from IPersistStorage::IsDirty.

CHtmlEditCtrlBase::GetShowAlignedSiteTags
Returns whether a glyph is displayed for all elements that have a styleFloat property.

HRESULT GetShowAlignedSiteTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if a glyph is displayed for all elements that have a styleFloat property; FALSE if no glyph is displayed.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWALIGNEDSITETAGS Command ID.

CHtmlEditCtrlBase::GetShowAllTags
Returns whether the WebBrowser displays glyphs to show the location of all tags in a document.

HRESULT GetShowAllTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays glyphs to show the location of all tags in a document; FALSE if it does not.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWALLTAGS Command ID.

CHtmlEditCtrlBase::GetShowAreaTags
Retrieves whether the WebBrowser displays a glyph for area tags.

HRESULT GetShowAreaTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for area tags, FALSE if it does not.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWAREATAGS Command ID.

CHtmlEditCtrlBase::GetShowBRTags
Retrieves whether the WebBrowser displays a glyph for br tags.

HRESULT GetShowBRTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for br tags, FALSE if it doesn't.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWWBRTAGS Command ID.

CHtmlEditCtrlBase::GetShowCommentTags
Retrieves whether the WebBrowser displays a glyph for comment tags.

HRESULT GetShowCommentTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for comment tags, FALSE if it doesn't.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWCOMMENTTAGS Command ID.

CHtmlEditCtrlBase::GetShowMiscTags
Retrieves whether the WebBrowser displays all the tags shown in Microsoft Internet Explorer 4.0.

HRESULT GetShowMiscTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays all the tags shown in Microsoft Internet Explorer 4.0, FALSE if it does not.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWMISCTAGS Command ID.
CHtmlEditCtrlBase::GetShowScriptTags
Retrieves whether the WebBrowser displays a glyph for all the script tags.

HRESULT GetShowScriptTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for all the script tags, FALSE if it does not.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWSCRIPTTAGS Command ID.

CHtmlEditCtrlBase::GetShowStyleTags
Retrieves whether the WebBrowser displays a glyph for all the style tags.

HRESULT GetShowStyleTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for all the style tags, FALSE if it does not
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWSTYLETAGS Command ID.

CHtmlEditCtrlBase::GetShowUnknownTags
Retrieves whether the WebBrowser displays a glyph for all unknown tags.

HRESULT GetShowUnknownTags(bool& bCurValue) const;

Parameters
bCurValue
TRUE if the WebBrowser displays a glyph for all unknown tags, FALSE if it does not.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
For more information, see IDM_SHOWUNKNOWNTAGS Command ID.

CHtmlEditCtrlBase::HorizontalLine
Overwrites a horizontal line on the current selection.
HRESULT HorizontalLine(LPCTSTR szId = NULL) const;

Parameters
szID
The ID for the horizontal line.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_HORIZONTALLINE command ID to the WebBrowser control.

CHtmlEditCtrlBase::HyperLink
Inserts a hyperlink on the current selection.

HRESULT HyperLink(LPCTSTR szUrl = NULL) const;

Parameters
szUrl
The hyperlink URL.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_HYPERLINK command ID to the WebBrowser control.

CHtmlEditCtrlBase::IE50Paste
Performs a paste operation that's compatible with Internet Explorer 5.

HRESULT IE50Paste(LPCTSTR szData) const;

Parameters
szData
The string to paste.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_IE50_PASTE command ID to the WebBrowser control.

CHtmlEditCtrlBase::Iframe
Overwrites an inline frame on the current selection.

HRESULT Iframe(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the inline frame.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_IFRAME command ID to the WebBrowser control.

CHtmlEditCtrlBase::Image
Overwrites an image on the current selection.

HRESULT Image(LPCTSTR szUrl = NULL) const;

Parameters
szUrl
The path and file name of the image to be inserted.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_IMAGE command ID to the WebBrowser control.

CHtmlEditCtrlBase::Indent
Increases the indent of the selected text by one indentation increment.

HRESULT Indent() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INDENT command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsFieldSet
Overwrites a box on the current selection.

HRESULT InsFieldSet(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the box.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSFIELDSET command ID to the WebBrowser control.
CHtmlEditCtrlBase::InsInputButton
Overwrites a button control on the current selection.

HRESULT InsInputButton(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the button control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTBUTTON command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputHidden
Inserts a hidden control on the current selection.

HRESULT InsInputHidden(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the hidden control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTHIDDEN command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputImage
Overwrites an image control on the current selection.

HRESULT InsInputImage(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the image control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTIMAGE command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputPassword
Overwrites a password control on the current selection.
HRESULT InsInputPassword(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the password control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTPASSWORD command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputReset
Overwrites a reset control on the current selection.

HRESULT InsInputReset(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the reset control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTRESET command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputSubmit
Overwrites a submit control on the current selection.

HRESULT InsInputSubmit(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the submit control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTSUBMIT command ID to the WebBrowser control.

CHtmlEditCtrlBase::InsInputUpload
Overwrites a file upload control on the current selection.

HRESULT InsInputUpload(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the file upload control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_INSINPUTUPLOAD command ID to the WebBrowser control.

CHtmlEditCtrlBase::Is1DElement
Determines if an element is statically positioned.

HRESULT Is1DElement(bool& bValue) const;

Parameters
bValue
TRUE if the element is statically positioned, FALSE otherwise.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_1D_ELEMENT command ID to the WebBrowser control.

CHtmlEditCtrlBase::Is2DElement
Determines if an element is absolutely positioned.

HRESULT Is2DElement(bool& bValue) const;

Parameters
bValue
TRUE if the element is absolutely positioned, FALSE otherwise.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_2D_ELEMENT command ID to the WebBrowser control.

CHtmlEditCtrlBase::Italic
Toggles the current selection between italic and nonitalic.

HRESULT Italic() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_ITALIC command ID to the WebBrowser control.
CHtmlEditCtrlBase::JustifyCenter
Centers the format block in which the current selection is located.

HRESULT JustifyCenter() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_JUSTIFYCENTER command ID to the WebBrowser control.

CHtmlEditCtrlBase::JustifyLeft
Left-justifies the format block in which the current selection is located.

HRESULT JustifyLeft() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_JUSTIFYLEFT command ID to the WebBrowser control.

CHtmlEditCtrlBase::JustifyRight
Right-justifies the format block in which the current selection is located.

HRESULT JustifyRight() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_JUSTIFYRIGHT command ID to the WebBrowser control.

CHtmlEditCtrlBase::ListBox
Overwrites a list box selection control on the current selection.

HRESULT ListBox(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the list box control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_LISTBOX command ID to the WebBrowser control.
CHtmlEditCtrlBase::Marquee
Overwrites an empty marquee on the current selection.

HRESULT Marquee(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the marquee.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_MARQUEE command ID to the WebBrowser control.

CHtmlEditCtrlBase::NewDocument
Creates a new document.

HRESULT NewDocument() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::OrderList
Toggles the current selection between an ordered list and a normal format block.

HRESULT OrderList(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the ordered list.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_ORDERLIST command ID to the WebBrowser control.

CHtmlEditCtrlBase::Outdent
Decreases by one increment the indentation of the format block in which the current selection is located.

HRESULT Outdent() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_OUTDENT command ID to the WebBrowser control.

CHtmlEditCtrlBase::Paragraph
Overwrites a line break on the current selection.

HRESULT Paragraph(LPCTSTR szId = NULL) const;

Parameters
szId
The ID for the paragraph.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_PARAGRAPH command ID to the WebBrowser control.

CHtmlEditCtrlBase::Paste
Overwrites the contents of the clipboard on the current selection.

HRESULT Paste() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_PASTE command ID to the WebBrowser control.

CHtmlEditCtrlBase::PrintDocument
Prints the current document.

HRESULT PrintDocument() const;


HRESULT PrintDocument(LPCTSTR szPrintTemplate) const;
HRESULT PrintDocument(bool bShowPrintDialog) const;

Parameters
szPrintTemplate
Path to a print template; if none is specified, the default print template is used.
bShowPrintDialog
If TRUE, shows the Print dialog.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_PRINT command ID to the WebBrowser control.

CHtmlEditCtrlBase::PrintPreview
Opens the Print Preview window for the current document using either the default print preview template or a
custom template.

HRESULT PrintPreview() const;


HRESULT PrintPreview(LPCTSTR szPrintTemplate) const;

Parameters
szPrintTemplate
Path to a print template.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_PRINTPREVIEW command ID to the WebBrowser control.

CHtmlEditCtrlBase::QueryStatus
Call this method to query the status of commands.

long QueryStatus(long cmdID) const;

Parameters
cmdID
The command ID. Command identifiers are taken from the CGID_MSHTML command group. These commands are
defined in Mshtmcid.h. You can also find the list online at MSHTML Command Identifiers.
Return Value
Returns an OLECMDF indicating the status for cmdID, or 0 on failure.

CHtmlEditCtrlBase::RadioButton
Overwrites a radio control on the current selection.

HRESULT RadioButton(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the radio button.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_RADIOBUTTON command ID to the WebBrowser control.

CHtmlEditCtrlBase::RefreshDocument
Refreshes the current document.

HRESULT RefreshDocument() const;


Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_REFRESH Command ID to the WebBrowser control.

CHtmlEditCtrlBase::RemoveFormat
Removes the formatting tags from the current selection.

HRESULT RemoveFormat() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_REMOVEFORMAT command ID to the WebBrowser control.

CHtmlEditCtrlBase::SaveAs
Saves the current Web page to a file.

HRESULT SaveAs(LPCTSTR szPath = NULL) const;

Parameters
szPath
The path and file name to which to save the Web page.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SAVEAS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SelectAll
Selects the entire document.

HRESULT SelectAll() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SELECTALL command ID to the WebBrowser control.

CHtmlEditCtrlBase::Set2DPosition
Allows absolutely positioned elements to be moved by dragging.

HRESULT Set2DPosition(bool bNewValue) const;


Parameters
bNewValue
If TRUE, absolutely positioned elements can be moved by dragging.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_2D_POSITION command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetAbsolutePosition
Sets an element's position property to "absolute" or "static."

HRESULT SetAbsolutePosition(bool bNewValue) const;

Parameters
bNewValue
If TRUE, the element's position property is "absolute"; if FALSE, it is "static."
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_ABSOLUTE_POSITION command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetAtomicSelection
Set atomic selection mode.

HRESULT SetAtomicSelection(bool bNewValue) const;

Parameters
bNewValue
If TRUE, any element that has an ATOMICSELECTION attribute set to TRUE will be selectable only as a unit.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_ATOMICSELECTION command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetAutoURLDetectMode
Turns automatic URL detection on and off.

HRESULT SetAutoURLDetectMode(bool bNewValue) const;

Parameters
bNewValue
If TRUE, automatic URL detection is enabled.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_AUTOURLDETECT_MODE command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetBackColor
Sets the background color of the current selection.

HRESULT SetBackColor(int nColor) const;


HRESULT SetBackColor(LPCTSTR szColor) const;

Parameters
nColor
The color. See pvaIn in IDM_BACKCOLOR Command ID.
szColor
The color. See pvaIn in IDM_BACKCOLOR Command ID.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BACKCOLOR_ command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetBlockFormat
Sets the current block format tag.

HRESULT SetBlockFormat(LPCTSTR szFormat) const;

Parameters
szFormat
The format tag.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BLOCKFMT_command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetBookMark
Creates a bookmark anchor for the current selection or insertion point.

HRESULT SetBookMark(LPCTSTR szAnchorName) const;

Parameters
szAnchorName
The anchor name.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_BOOKMARK command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetCSSEditingLevel
Selects which CSS level (CSS1 or CSS2) the editor will support, if any.

HRESULT SetCSSEditingLevel(short nLevel) const;

Parameters
nLevel
The CSS level. Pass 0 if you do not want CSS support.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_CSSEDITING_LEVEL command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetDefaultComposeSettings
Call this method to set the default compose settings.

HRESULT SetDefaultComposeSettings(
LPCSTR szFontName = NULL,
unsigned short nFontSize = 3,
COLORREF crFontColor = 0xFF000000,
COLORREF crFontBgColor = 0xFF000000,
bool bBold = false,
bool bItalic = false,
bool bUnderline = false) const;

Parameters
szFontName
The font name.
nFontSize
The font size.
crFontColor
The font color.
crFontBgColor
The font background color.
bBold
Pass TRUE for bold text.
bItalic
Pass TRUE for italic text.
bUnderline
Pass TRUE for underlined text.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_COMPOSESETTINGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetDesignMode
Set design mode.

BOOL SetDesignMode(BOOL bMode) const;

Parameters
bMode
If TRUE, turns design mode on.
Return Value
Returns TRUE on success, FALSE on failure.

CHtmlEditCtrlBase::SetDisableEditFocusUI
Disables the hatched border and handles around an element that has edit focus.

HRESULT SetDisableEditFocusUI(bool bNewValue) const;

Parameters
bNewValue
If TRUE, disables the hatched border and handles around a site selectable element when the element has "edit
focus" in design mode; that is, when the text or contents of the element can be edited.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_DISABLE_EDITFOCUS_UI command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetDocumentHTML
Sets the HTML of the current document.

HRESULT SetDocumentHTML(LPCTSTR szHTML) const;

Parameters
szHTML
The HTML.
Return Value
Returns S_OK on success, or an error HRESULT on failure.

CHtmlEditCtrlBase::SetFontFace
Sets the font for the current selection.
HRESULT SetFontFace(LPCTSTR szFace) const;

Parameters
szFace
The font name.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_FONTNAME Command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetFontSize
Sets the font size for the current selection.

HRESULT SetFontSize(unsigned short size) const;

Parameters
size
The HTML font size (1-7). A value of 0 sets the font size to 1.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_FONTSIZE command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetForeColor
Sets the foreground (text) color of the current selection.

HRESULT SetForeColor(LPCTSTR szColor) const;


HRESULT SetForeColor(int nColor) const;

Parameters
szColor
The color.
nColor
The color.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_FORECOLOR command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetIE5PasteMode
Sets the paste operation to be compatible with Microsoft Internet Explorer 5.
HRESULT SetIE5PasteMode(bool bNewValue) const;

Parameters
bNewValue
If TRUE, all paste operations are compatible with Internet Explorer 5; if FALSE, paste operations are compatible with
Internet Explorer 5.5.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_IE50_PASTE_MODE command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetLiveResize
Causes the WebBrowser to update an element's appearance continuously during a resizing or moving operation,
rather than updating only at the completion of the move or resize.

HRESULT SetLiveResize(bool bNewValue) const;

Parameters
bNewValue
If TRUE, causes the WebBrowser to update an element's appearance continuously during a resizing or moving
operation; if FALSE, it updates only at the completion of the move or resize.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_LIVERESIZE command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetMultiSelect
Enables multiple selection.

HRESULT SetMultiSelect(bool bNewValue) const;

Parameters
bNewValue
If TRUE, allows for the selection of more than one site-selectable element at a time when the user holds down the
SHIFT or CTRL keys.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_MULTIPLESELECTION command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetOverrideCursor
Commands the WebBrowser never to change the mouse pointer.
HRESULT SetOverrideCursor(bool bNewValue) const;

Parameters
bNewValue
If TRUE, the WebBrowser will not change the mouse pointer.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_OVERRIDE_CURSOR command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetOverwriteMode
Toggles the text-entry mode between insert and overwrite.

HRESULT SetOverwriteMode(bool bMode) const;

Parameters
bMode
If TRUE, text-entry mode is overwrite; if FALSE, text-entry mode is insert.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_OVERWRITE command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetRespectVisInDesign
Hides invisible elements in design mode.

HRESULT SetRespectVisInDesign(bool bNewValue) const;

Parameters
bNewValue
If TRUE, any elements that have a visibility set to "hidden" or display property set to "none" will not be shown in
both design mode and browse mode; if FALSE, those elements will be displayed only in browse mode.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_RESPECTVISIBILITY_INDESIGN command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowAlignedSiteTags
Displays a glyph for all elements that have a styleFloat property.

HRESULT SetShowAlignedSiteTags(bool bNewValue) const;


Parameters
bNewValue
If TRUE, displays a glyph for all elements that have a styleFloat property.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWALIGNEDSITETAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowAllTags
Displays glyphs to show the location of all tags in a document.

HRESULT SetShowAllTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays glyphs to show the location of all tags in a document.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWALLTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowAreaTags
Displays a glyph for all the area tags.

HRESULT SetShowAreaTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the area tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWAREATAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowBRTags
Displays a glyph for all the br tags.

HRESULT SetShowBRTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the br tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWWBRTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowCommentTags
Displays a glyph for all the comment tags.

HRESULT SetShowCommentTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the comment tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWCOMMENTTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowMiscTags
Displays all the tags shown in Microsoft Internet Explorer 4.0.

HRESULT SetShowMiscTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays all the tags shown in Microsoft Internet Explorer 4.0.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWMISCTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowScriptTags
Displays a glyph for all the script tags.

HRESULT SetShowScriptTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the script tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWSCRIPTTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowStyleTags
Displays a glyph for all the style tags.

HRESULT SetShowStyleTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the style tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWSTYLETAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::SetShowUnknownTags
Displays a glyph for all the unknown tags.

HRESULT SetShowUnknownTags(bool bNewValue) const;

Parameters
bNewValue
If TRUE, displays a glyph for all the unknown tags.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_SHOWUNKNOWNTAGS command ID to the WebBrowser control.

CHtmlEditCtrlBase::TextArea
Overwrites a multiline text input control on the current selection.

HRESULT TextArea(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the multiline text input control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_TEXTAREA command ID to the WebBrowser control.

CHtmlEditCtrlBase::TextBox
Overwrites a text control on the current selection.

HRESULT TextBox(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the text control.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_TEXTBOX command ID to the WebBrowser control.

CHtmlEditCtrlBase::UnBookmark
Removes any bookmark from the current selection.

HRESULT UnBookmark() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_UNBOOKMARK command ID to the WebBrowser control.

CHtmlEditCtrlBase::Underline
Toggles the current selection between underlined and not underlined.

HRESULT Underline() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_UNDERLINE command ID to the WebBrowser control.

CHtmlEditCtrlBase::Unlink
Removes any hyperlink from the current selection.

HRESULT Unlink() const;

Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_UNLINK command ID to the WebBrowser control.

CHtmlEditCtrlBase::UnorderList
Toggles the current selection between an ordered list and a normal format block.

HRESULT UnorderList(LPCTSTR szId = NULL) const;

Parameters
szId
The ID of the unordered list.
Return Value
Returns S_OK on success, or an error HRESULT on failure.
Remarks
This method sends the IDM_UNORDERLIST command ID to the WebBrowser control.

See also
Hierarchy Chart
HTMLEdit Sample
CHtmlEditDoc Class
3/27/2020 • 2 minutes to read • Edit Online

With CHtmlEditView, provides the functionality of the WebBrowser editing platform within the context of the MFC
document-view architecture.

Syntax
class AFX_NOVTABLE CHtmlEditDoc : public CDocument

Members
Public Constructors
NAME DESC RIP T IO N

CHtmlEditDoc::CHtmlEditDoc Constructs a CHtmlEditDoc object.

Public Methods
NAME DESC RIP T IO N

CHtmlEditDoc::GetView Retrieves the CHtmlEditView object attached to this


document.

CHtmlEditDoc::IsModified Returns whether the associated view's WebBrowser control


contains a document that has been modified by the user.

CHtmlEditDoc::OpenURL Opens a URL.

Inheritance Hierarchy
CObject
CCmdTarget
CDocument
CHtmlEditDoc

Requirements
Header : afxhtml.h

CHtmlEditDoc::CHtmlEditDoc
Constructs a CHtmlEditDoc object.

CHtmlEditDoc();
CHtmlEditDoc::GetView
Retrieves the CHtmlEditView object attached to this document.

virtual CHtmlEditView* GetView() const;

Return Value
Returns a pointer to the document's CHtmlEditView object.

CHtmlEditDoc::IsModified
Returns whether the associated view's WebBrowser control contains a document that has been modified by the
user.

virtual BOOL IsModified();

CHtmlEditDoc::OpenURL
Opens a URL.

virtual BOOL OpenURL(LPCTSTR lpszURL);

Parameters
lpszURL
The URL to open.
Return Value
Returns TRUE on success, FALSE on failure.

See also
HTMLEdit Sample
Hierarchy Chart
CHtmlEditView Class
4/21/2020 • 2 minutes to read • Edit Online

Provides the functionality of the WebBrowser editing platform within the context of MFC's document/view
architecture.

Syntax
class CHtmlEditView : public CHtmlView, public CHtmlEditCtrlBase<CHtmlEditView>

Members
Public Constructors
NAME DESC RIP T IO N

CHtmlEditView::CHtmlEditView Constructs a CHtmlEditView object.

Public Methods
NAME DESC RIP T IO N

CHtmlEditView::Create Creates a new window object.

CHtmlEditView::GetDHtmlDocument Returns the IHTMLDocument2 interface on the current


document.

CHtmlEditView::GetStartDocument Retrieves the name of the default document for this view.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CScrollView
CFormView
CHtmlEditCtrlBase
CHtmlView
CHtmlEditView

Requirements
Header : afxhtml.h
CHtmlEditView::CHtmlEditView
Constructs a CHtmlEditView object.

CHtmlEditView();

CHtmlEditView::Create
Creates a new window object.

virtual BOOL Create(


LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID,
CCreateContext* pContext = NULL);

Parameters
lpszClassName
Points to a null-terminated character string that names the Windows class. The class name can be any name
registered with the AfxRegisterWndClass global function or the RegisterClass Windows function. If NULL, uses
the predefined default CFrameWnd attributes.
lpszWindowName
Points to a null-terminated character string that represents the window name.
dwStyle
Specifies the window style attributes. By default, the WS_VISIBLE and WS_CHILD Windows styles are set.
rect
A reference to a RECT structure specifying the size and position of the window. The rectDefault value allows
Windows to specify the size and position of the new window.
pParentWnd
A pointer to the parent window of the control.
nID
The ID number of the view. By default, set to AFX_IDW_PANE_FIRST.
pContext
A pointer to a CCreateContext. NULL by default.
Remarks
This method will also call the contained WebBrowser's Navigate method to load a default document (see
CHtmlEditView::GetStartDocument).

CHtmlEditView::GetDHtmlDocument
Returns the IHTMLDocument2 interface on the current document.

BOOL GetDHtmlDocument(IHTMLDocument2** ppDocument) const;

Parameters
ppDocument
The IHTMLDocument2 interface.

CHtmlEditView::GetStartDocument
Retrieves the name of the default document for this view.

virtual LPCTSTR GetStartDocument();

See also
HTMLEdit Sample
Hierarchy Chart
CHtmlView Class
4/21/2020 • 40 minutes to read • Edit Online

Provides the functionality of the WebBrowser control within the context of MFC's document/view architecture.

Syntax
class CHtmlView : public CFormView

Members
Public Methods
NAME DESC RIP T IO N

CHtmlView::Create Creates the WebBrowser control.

CHtmlView::CreateControlSite Overridable used to create a control site instance to host a


control on the form.

CHtmlView::ExecFormsCommand Executes the specified command using the


IOleCommandTarget::Exec method.

CHtmlView::ExecWB Executes a command.

CHtmlView::GetAddressBar Determines if the Internet Explorer object's address bar is


visible. (WebBrowser control ignores; Internet Explorer only.)

CHtmlView::GetApplication Retrieves an application object representing the application


that contains the current instance of the Internet Explorer
application.

CHtmlView::GetBusy Retrieves a value indicating whether a download or other


activity is still in progress.

CHtmlView::GetContainer Retrieves the container of the WebBrowser control.

CHtmlView::GetFullName Retrieves the full name, including the path, of the resource
displayed in the web browser. (WebBrowser control ignores;
Internet Explorer only.)

CHtmlView::GetFullScreen Indicates whether the WebBrowser control is operating in full-


screen mode or in normal window mode.

CHtmlView::GetHeight Retrieves the height of the Internet Explorer main window.

CHtmlView::GetHtmlDocument Retrieves the active HTML document.

CHtmlView::GetLeft Retrieves the screen coordinate of the left edge of the


Internet Explorer main window.
NAME DESC RIP T IO N

CHtmlView::GetLocationName Retrieves the name of the resource that WebBrowser is


currently displaying

CHtmlView::GetLocationURL Retrieves the URL of the resource that WebBrowser is


currently displaying.

CHtmlView::GetMenuBar Retrieves a value that determines whether the menu bar is


visible.

CHtmlView::GetOffline Retrieves a value that determines whether the control is


offline.

CHtmlView::GetParentBrowser Retrieves a pointer to the IDispatch interface. For more


information, see Implementing the IDispatch Interface.

CHtmlView::GetProperty Retrieves the current value of a property associated with the


given object.

CHtmlView::GetReadyState Retrieves the ready state of the web browser object.

CHtmlView::GetRegisterAsBrowser Indicates whether the WebBrowser control is registered as a


top-level browser for target name resolution.

CHtmlView::GetRegisterAsDropTarget Indicates whether the WebBrowser control is registered as a


drop target for navigation.

CHtmlView::GetSilent Indicates whether any dialog boxes can be shown.

CHtmlView::GetSource The HTML source code of the web page.

CHtmlView::GetStatusBar Indicates whether the Internet Explorer's status bar is visible.


(WebBrowser control ignores; Internet Explorer only.)

CHtmlView::GetTheaterMode Indicates whether the WebBrowser control is in theater mode.

CHtmlView::GetToolBar Retrieves a value that determines whether the toolbar is


visible.

CHtmlView::GetTop Retrieves the screen coordinate of the top edge of the


Internet Explorer main window.

CHtmlView::GetTopLevelContainer Retrieves a value indicating whether the current object is the


top-level container of the WebBrowser control.

CHtmlView::GetType Retrieves the type name of the document object.

CHtmlView::GetVisible Retrieves a value indicating whether the object is visible or


hidden.

CHtmlView::GetWidth Retrieves the width of the Internet Explorer main window.

CHtmlView::GoBack Navigates to the previous item in the history list.


NAME DESC RIP T IO N

CHtmlView::GoForward Navigates to the next item in the history list.

CHtmlView::GoHome Navigates to the current home or start page.

CHtmlView::GoSearch Navigates to the current search page.

CHtmlView::LoadFromResource Loads a resource in the WebBrowser control.

CHtmlView::Navigate Navigates to the resource identified by a URL.

CHtmlView::Navigate2 Navigates to the resource identified by a URL, or to the file


identified by a full path.

CHtmlView::OnBeforeNavigate2 Called before a navigation occurs in the given WebBrowser


(on either a window or frameset element).

CHtmlView::OnCommandStateChange Called to notify an application that the enabled state of a web


browser command has changed.

CHtmlView::OnDocumentComplete Called to notify an application that a document has reached


the READYSTATE_COMPLETE state.

CHtmlView::OnDocWindowActivate Called from the Internet Explorer or MSHTML implementation


of IOleInPlaceActiveObject::OnDocWindowActivate, which
notifies the active in-place object when the container's
document window is activated or deactivated.

CHtmlView::OnDownloadBegin Called to notify an application that a navigation operation is


beginning.

CHtmlView::OnDownloadComplete Called when a navigation operation finished, was halted, or


failed.

CHtmlView::OnEnableModeless Called to enable or disable modeless dialog boxes when the


container creates or destroys a modal dialog box.

CHtmlView::OnFilterDataObject Called on the host by Internet Explorer or MSHTML to allow


the host to replace Internet Explorer or MSHTML's data
object.

CHtmlView::OnFrameWindowActivate Called from


IOleInPlaceActiveObject::OnFrameWindowActivate to notify
the object when the container's top-level frame window is
activated or deactivated.

CHtmlView::OnFullScreen Called when the FullScreen property has changed.

CHtmlView::OnGetDropTarget Called by Internet Explorer or MSHTML when it is being used


as a drop target to allow the host to supply an alternative
IDropTarget.

CHtmlView::OnGetExternal Called by Internet Explorer or MSHTML to obtain the host's


IDispatch interface.
NAME DESC RIP T IO N

CHtmlView::OnGetHostInfo Retrieves the UI capabilities of the Internet Explorer or


MSHTML host.

CHtmlView::OnGetOptionKeyPath Returns the registry key under which Internet Explorer or


MSHTML stores user preferences.

CHtmlView::OnHideUI Called when Internet Explorer or MSHTML removes its menus


and toolbars.

CHtmlView::OnMenuBar Called when the MenuBar property has changed.

CHtmlView::OnNavigateComplete2 Called after a navigation to a hyperlink completes (on either a


window or frameset element).

CHtmlView::OnNavigateError Called by the framework if navigation to a hyperlink fails.

CHtmlView::OnNewWindow2 Called when a new window is to be created for displaying a


resource.

CHtmlView::OnProgressChange Called to notify an application that the progress of a


download operation has been updated.

CHtmlView::OnPropertyChange Called to notify an application that the PutProperty method


has changed the value of a property.

CHtmlView::OnQuit Called to notify an application that the Internet Explorer


application is ready to quit. (Applies to Internet Explorer only)

CHtmlView::OnResizeBorder Called from the Internet Explorer or MSHTML implementation


of IOleInPlaceActiveObject::ResizeBorder, which alerts the
object that it needs to resize its border space.

CHtmlView::OnShowContextMenu Called from Internet Explorer or MSHTML when it is about to


show its context menu.

CHtmlView::OnShowUI Called before Internet Explorer or MSHTML displays its menus


and toolbars.

CHtmlView::OnStatusBar Called when the StatusBar property has changed.

CHtmlView::OnStatusTextChange Called to notify an application that the text of the status bar
associated with the WebBrowser control has changed.

CHtmlView::OnTheaterMode Called when the TheaterMode property has changed.

CHtmlView::OnTitleChange Called to notify an application if the title of a document in the


WebBrowser control becomes available or changes.

CHtmlView::OnToolBar Called when the ToolBar property has changed.


NAME DESC RIP T IO N

CHtmlView::OnTranslateAccelerator Called by Internet Explorer or MSHTML when


IOleInPlaceActiveObject::TranslateAccelerator or
IOleControlSite::TranslateAccelerator is called to process menu
accelerator-key messages from the container's message
queue.

CHtmlView::OnTranslateUrl Called by Internet Explorer or MSHTML to allow the host an


opportunity to modify the URL to be loaded.

CHtmlView::OnUpdateUI Notifies the host that the command state has changed.

CHtmlView::OnVisible Called when the window for the WebBrowser control should
be shown/hidden.

CHtmlView::PutProperty Sets the value of a property associated with the given object.

CHtmlView::QueryFormsCommand Queries for the status of one or more commands generated


by user interface events.

CHtmlView::QueryStatusWB Queries the status of a command being processed by the


WebBrowser control.

CHtmlView::Refresh Reloads the current file.

CHtmlView::Refresh2 Reloads the current file and optionally prevents the


pragma:nocache header from being sent.

CHtmlView::SetAddressBar Shows or hides the Internet Explorer object's address bar.


(WebBrowser control ignores; Internet Explorer only.)

CHtmlView::SetFullScreen Sets a value to determine whether the control is operating in


full-screen mode or in normal window mode. (WebBrowser
control ignores; Internet Explorer only.)

CHtmlView::SetHeight Sets the height of the Internet Explorer main window.

CHtmlView::SetLeft Sets the horizontal position of the Internet Explorer main


window.

CHtmlView::SetMenuBar Sets a value to determine whether the control's menu bar is


visible. (WebBrowser control ignores; Internet Explorer only.)

CHtmlView::SetOffline Sets a value to determine whether the control is offline.

CHtmlView::SetRegisterAsBrowser Sets a value indicating whether the WebBrowser control is


registered as a top-level browser for target name resolution.

CHtmlView::SetRegisterAsDropTarget Sets a value indicating whether the WebBrowser control is


registered as a drop target for navigation.

CHtmlView::SetSilent Sets a value to determine whether the control will display


dialog boxes.
NAME DESC RIP T IO N

CHtmlView::SetStatusBar Sets a value to determine whether the Internet Explorer's


status bar is visible. (WebBrowser control ignores; Internet
Explorer only.)

CHtmlView::SetTheaterMode Sets a value indicating whether the WebBrowser control is in


theater mode.

CHtmlView::SetToolBar Sets a value to determine whether the control's toolbar is


visible. (WebBrowser control ignores; Internet Explorer only.)

CHtmlView::SetTop Sets the vertical position of the Internet Explorer main


window.

CHtmlView::SetVisible Sets a value indicating whether the object is visible or hidden.

CHtmlView::SetWidth Sets the width of the Internet Explorer main window.

CHtmlView::Stop Stops opening a file.

Remarks
The WebBrowser control is a window in which the user can browse sites on the World Wide Web, as well as
folders in the local file system and on a network. The WebBrowser control supports hyperlinking, Uniform
Resource Locator (URL) navigation, and maintains a history list.

Using the CHtmlView Class in an MFC Application


In the standard MFC framework application (either SDI or MDI based), the view object is commonly derived from a
specialized set of classes. These classes, all derived from CView , provide specialized functionality beyond that
provided by CView .
Basing the application's view class on CHtmlView provides the view with the WebBrowser control. This effectively
makes the application a web browser. The preferred method of creating a web browser-style application is to use
the MFC Application Wizard, and specify CHtmlView as the view class. For more information on implementing and
using the WebBrowser control within MFC applications, see Creating a Web Browser-Style Application.

NOTE
The WebBrowser ActiveX control (and therefore CHtmlView ) is available only to programs running under Windows NT
versions 4.0 or later, in which Internet Explorer 4.0 or later has been installed.

CHtmlView is designed for applications that access the Web (and/or HTML documents). The following CHtmlView
member functions apply to the Internet Explorer application only. These functions will succeed on the WebBrowser
control, but they will have no visible effect.
GetAddressBar
GetFullName
GetStatusBar
SetAddressBar
SetFullScreen
SetMenuBar
SetStatusBar
SetToolBar

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CScrollView
CFormView
CHtmlView

Requirements
Header : afxhtml.h

CHtmlView::Create
Call this member function to create a WebBrowser control or container for the Internet Explorer executable.

virtual BOOL Create(


LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID,
CCreateContext* pContext = NULL);

Parameters
lpszClassName
Points to a null-terminated character string that names the Windows class. The class name can be any name
registered with the AfxRegisterWndClass global function or the RegisterClass Windows function. If NULL, uses
the predefined default CFrameWnd attributes.
lpszWindowName
Points to a null-terminated character string that represents the window name.
dwStyle
Specifies the window style attributes. By default, the WS_VISIBLE and WS_CHILD Windows styles are set.
rect
A reference to a RECT structure specifying the size and position of the window. The rectDefault value allows
Windows to specify the size and position of the new window.
pParentWnd
A pointer to the parent window of the control.
nID
The ID number of the view. By default, set to AFX_IDW_PANE_FIRST.
pContext
A pointer to a CCreateContext. NULL by default.

CHtmlView::CreateControlSite
Overridable used to create a control site instance to host a control on the form.

virtual BOOL CreateControlSite(


COleControlContainer* pContainer,
COleControlSite** ppSite,
UINT nID,
REFCLSID clsid);

Parameters
pContainer
A pointer to a COleControlContainer object containing the control.
ppSite
A pointer to a pointer to a COleControlSite object, providing the site for the control.
nID
The identifier of the control to be hosted.
clsid
The CLSID of the control to be hosted
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
You can override this member function to return an instance of your own control site class.

CHtmlView::ExecFormsCommand
Executes the specified command using the IOleCommandTarget::Exec method.

HRESULT ExecFormsCommand(
DWORD dwCommandID,
VARIANT* pVarIn,
VARIANT* pVarOut);

Parameters
dwCommandID
The command to be executed. This command must belong to the CMDSETID3_Forms3 group.
pVarIn
Pointer to a VARIANT structure containing input arguments. Can be NULL.
pVarOut
Pointer to a VARIANT structure to receive command output. Can be NULL.
Return Value
A standard HRESULT value. For a complete listing of possible values, see IOleCommandTarget::Exec in the
Windows SDK.
Remarks
ExecFormsCommand implements the behavior of the IOleCommandTarget::Exec method.

CHtmlView::ExecWB
Call this member function to execute a command in the WebBrowser or Internet Explorer.

void ExecWB(
OLECMDID cmdID,
OLECMDEXECOPT cmdexecopt,
VARIANT* pvaIn,
VARIANT* pvaOut);

Parameters
cmdID
The command to execute.
cmdexecopt
The options set for executing the command.
pvaIn
A variant used for specifying command input arguments.
pvaOut
A variant used for specifying command output arguments.
Remarks
See IWebBrowser2::ExecWB in the Windows SDK.

CHtmlView::GetAddressBar
Call this member function to retrieve Internet Explorer's address bar.

BOOL GetAddressBar() const;

Return Value
Nonzero if the address bar is visible; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::GetApplication
Call this member function to retrieve the automation object supported by the application that contains the
WebBrowser control.

LPDISPATCH GetApplication() const;

Return Value
A pointer to the IDispatch interface of the active document object. For more information, see Implementing the
IDispatch Interface.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetBusy
Call this member function to determine whether the WebBrowser control is engaged in a navigation or
downloading operation.

BOOL GetBusy() const;

Return Value
Nonzero if the web browser is busy; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetContainer
Call this member function to retrieve an object that evaluates to the container of the web browser.

LPDISPATCH GetContainer() const;

Return Value
A pointer to the IDispatch interface of the active document object.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetFullName
Call this member function to retrieve the full path of the file that Internet Explorer is currently displaying.

CString GetFullName() const;

Return Value
A CString object containing the path and name of the currently displayed file. If no path and filename exist,
GetFullName returns an empty CString .

Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::GetFullScreen
Call this member function to determine whether the WebBrowser control is operating in full-screen mode or in
normal window mode.

BOOL GetFullScreen() const;


Return Value
Nonzero if the WebBrowser is operating in full-screen mode; otherwise zero.
Remarks
In full-screen mode, the Internet Explorer main window is maximized and the status bar, toolbar, menu bar, and
title bar are hidden.
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetHeight
Call this member function to retrieve the height, in pixels, of the WebBrowser control's frame window.

long GetHeight() const;

Return Value
The control's frame window height, in pixels.

CHtmlView::GetHtmlDocument
Call this member function to retrieve the HTML document for the active document.

LPDISPATCH GetHtmlDocument() const;

Return Value
A pointer to the IDispatch interface of the active document object.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetLeft
Call this member function to retrieve the distance between the internal left edge of the WebBrowser control and
the left edge of its container.

long GetLeft() const;

Return Value
The left-edge distance, in pixels.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetLocationName
Call this member function to get the name of the resource being displayed in the WebBrowser.

CString GetLocationName() const;

Return Value
A CString object containing the name of the resource currently displayed in the WebBrowser.
Remarks
If the resource is an HTML page on the World Wide Web, the name is the title of that page. If the resource is a
folder or file on the network or local computer, the name is the UNC or full path of the folder or file.
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetLocationURL
Call this member function to retrieve the URL of the resource that the WebBrowser control is currently displaying.

CString GetLocationURL() const;

Return Value
A CString object containing the URL of the resource currently displayed in the WebBrowser.
Remarks
If the resource is a folder or file on the network or local computer, the name is the UNC or full path of the folder or
file.
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetMenuBar
Call this member function to determine whether the menu bar is visible.

BOOL GetMenuBar() const;

Return Value
Nonzero if the menu bar is visible; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetOffline
Call this member function to determine whether the web browser is operating offline.

BOOL GetOffline() const;

Return Value
Nonzero if the web browser is currently offline; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetParentBrowser
Call this member function to retrieve a pointer to the parent object of the WebBrowser control.

LPDISPATCH GetParentBrowser() const;

Return Value
A pointer to the IDispatch interface of the object that is the parent of the WebBrowser control.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetProperty
Call this member function to get the value of the property currently associated with the control.

BOOL GetProperty(
LPCTSTR lpszProperty,
CString& strValue);

COleVariant GetProperty(LPCTSTR lpszProperty);

Parameters
lpszProperty
A pointer to a string containing the property to retrieve.
strValue
A reference to a CString object that receives the current value of the property.
Return Value
In the first version, nonzero if completed successfully; otherwise zero. In the second version, a COleVariant object.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetReadyState
Call this member function to retrieve the ready state of the WebBrowser object.

READYSTATE GetReadyState() const;

Return Value
A READYSTATE value, as described in the Windows SDK.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetRegisterAsBrowser
Call this member function to determine whether the WebBrowser object is registered as a top-level browser for
target name resolution.

BOOL GetRegisterAsBrowser() const;

Return Value
Nonzero if the browser is registered as a top-level browser; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.
CHtmlView::GetRegisterAsDropTarget
Call this member function to determine whether the WebBrowser control is registered as a drop target for
navigation.

BOOL GetRegisterAsDropTarget() const;

Return Value
Nonzero if the browser is registered as a drop target; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetSilent
Call this member function to determine whether any dialog boxes can be shown in the WebBrowser control.

BOOL GetSilent() const;

Return Value
Nonzero if dialog boxes cannot be displayed from the WebBrowser control; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetSource
Call this member function to retrieve the HTML source code for the web page.

BOOL GetSource(CString& strRef);

Return Value
Nonzero if successful; otherwise zero.
Parameters
refString
A CString that will hold the source code.
Remarks
This function is equivalent to the "View Source" command in Internet Explorer, except that the source code is
returned in a CString .

CHtmlView::GetStatusBar
Call this member function to determine whether the WebBrowser control displays a status bar.

BOOL GetStatusBar() const;

Return Value
Nonzero if the status bar can be displayed; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::GetTheaterMode
Call this member function to determine whether the web browser is in theater mode.

BOOL GetTheaterMode() const;

Return Value
Nonzero if the web browser is in theater mode; otherwise zero.
Remarks
When the web browser is in theater mode, the browser main window fills the entire screen, a toolbar with a
minimal set of navigational tools appears, and the status bar appears in the upper right-hand corner of the screen.
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetToolBar
Call this member function to determine whether the toolbar is visible.

int GetToolBar() const;

Return Value
A value indicating whether the toolbar is visible. Nonzero if toolbar is visible; otherwise zero.

CHtmlView::GetTop
Call this member function to retrieve the screen coordinate of the top edge of the WebBrowser control's main
window.

long GetTop() const;

Return Value
Address of a variable that receives the screen coordinate of the main window's top edge.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetTopLevelContainer
Call this member function to determine whether Internet Explorer is the top-level container of the WebBrowser
control.

BOOL GetTopLevelContainer() const;

Return Value
Nonzero the container is the top-level container; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetType
Call this member function to retrieve the type name of the contained active document.

CString GetType() const;

Return Value
A CString object containing the type name of the contained active document.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetVisible
Call this member function to determine if the contained object is visible.

BOOL GetVisible() const;

Return Value
Nonzero if the object is visible; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GetWidth
Retrieves the width of the Internet Explorer main window.

long GetWidth() const;

Return Value
The current width of the window, in pixels.

CHtmlView::GoBack
Navigates backward one item in the history list.

void GoBack();

Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GoForward
Navigates forward one item in the history list.

void GoForward();
CHtmlView::GoHome
Navigates to the current home or start page specified in the Internet Explorer Internet Options dialog box or the
Internet Properties dialog box, accessed from the Control Panel.

void GoHome();

Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::GoSearch
Navigates to the current search page, as specified in the Internet Explorer Internet Options dialog box or the
Internet Properties dialog box, accessed from the Control Panel.

void GoSearch();

Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::LoadFromResource
Call this member function to load the specified resource into the WebBrowser control.

BOOL LoadFromResource(LPCTSTR lpszResource);


BOOL LoadFromResource(UINT nRes);

Parameters
lpszResource
A pointer to a string containing the name of the resource to load.
nRes
The ID of the buffer containing the name of the resource to load.
Return Value
Nonzero if successful; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::Navigate
Call this member function to navigate to the resource identified by a URL.

void Navigate(
LPCTSTR URL,
DWORD dwFlags = 0,
LPCTSTR lpszTargetFrameName = NULL,
LPCTSTR lpszHeaders = NULL,
LPVOID lpvPostData = NULL,
DWORD dwPostDataLen = 0);

Parameters
URL
A caller-allocated string that contains the URL to navigate to, or the full path of the file to display.
dwFlags
The flags of a variable that specifies whether to add the resource to the history list, whether to read to or write
from the cache, and whether to display the resource in a new window. The variable can be a combination of the
values defined by the BrowserNavConstants enumeration.
lpszTargetFrameName
A pointer to a string that contains the name of the frame in which to display the resource.
lpszHeaders
A pointer to a value that specifies the HTTP headers to send to the server. These headers are added to the default
Internet Explorer headers. The headers can specify such things as the action required of the server, the type of data
being passed to the server, or a status code. This parameter is ignored if URL is not an HTTP URL.
lpvPostData
A pointer to the data to send with the HTTP POST transaction. For example, the POST transaction is used to send
data gathered by an HTML form. If this parameter does not specify any post data, Navigate issues an HTTP GET
transaction. This parameter is ignored if URL is not an HTTP URL.
dwPostDataLen
Data to send with the HTTP POST transaction. For example, the POST transaction is used to send data gathered by
an HTML form. If this parameter does not specify any post data, Navigate issues an HTTP GET transaction. This
parameter is ignored if URL is not an HTTP URL.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::Navigate2
Call this member function to navigate to the resource identified by a URL, or to the file identified by a full path.

void Navigate2(
LPITEMIDLIST pIDL,
DWORD dwFlags = 0,
LPCTSTR lpszTargetFrameName = NULL);

void Navigate2(
LPCTSTR lpszURL,
DWORD dwFlags = 0,
LPCTSTR lpszTargetFrameName = NULL,
LPCTSTR lpszHeaders = NULL,
LPVOID lpvPostData = NULL,
DWORD dwPostDataLen = 0);

void Navigate2(
LPCTSTR lpszURL,
DWORD dwFlags,
CByteArray& baPostedData,
LPCTSTR lpszTargetFrameName = NULL,
LPCTSTR lpszHeader = NULL);

Parameters
pIDL
A pointer to an ITEMIDLIST structure.
dwFlags
The flags of a variable that specifies whether to add the resource to the history list, whether to read to or write
from the cache, and whether to display the resource in a new window. The variable can be a combination of the
values defined by the BrowserNavConstants enumeration.
lpszTargetFrameName
A pointer to a string that contains the name of the frame in which to display the resource.
lpszURL
A pointer to a string containing the URL.
lpvPostData
Data to send with the HTTP POST transaction. For example, the POST transaction is used to send data gathered by
an HTML form. If this parameter does not specify any post data, Navigate2 issues an HTTP GET transaction. This
parameter is ignored if URL is not an HTTP or HTTPS URL.
dwPostDataLen
Length in bytes of the data pointed to by the lpvPostData parameter.
lpszHeaders
A pointer to a value that specifies the HTTP or HTTPS headers to send to the server. These headers are added to
the default Internet Explorer headers. The headers can specify such things as the action required of the server, the
type of data being passed to the server, or a status code. This parameter is ignored if URL is not an HTTP or HTTPS
URL.
baPostedData
A reference to a CByteArray object.
Remarks
This member function extends the Navigate member function by supporting browsing on special folders, such as
Desktop and My Computer, that are represented by the parameter pIDL.
Applies to Internet Explorer and WebBrowser.
Example

void CMyHtmlView::OnGoToMicrosoft()
{
Navigate2(_T("http://home.microsoft.com"));
}

CHtmlView::OnBeforeNavigate2
This member function is called by the framework to cause an event to fire before a navigation occurs in the web
browser.

virtual void OnBeforeNavigate2(


LPCTSTR lpszURL,
DWORD nFlags,
LPCTSTR lpszTargetFrameName,
CByteArray& baPostedData,
LPCTSTR lpszHeaders,
BOOL* pbCancel);

Parameters
lpszURL
Pointer to a string containing the URL to navigate to.
nFlags
Reserved for future use.
lpszTargetFrameName
A string that contains the name of the frame in which to display the resource, or NULL if no named frame is
targeted for the resource.
baPostedData
A reference to a CByteArray object containing the data to send to the server if the HTTP POST transaction is being
used.
lpszHeaders
A pointer to a string containing additional HTTP headers to send to the server (HTTP URLs only). The headers can
specify such things as the action required of the server, the type of data being passed to the server, or a status
code.
pbCancel
A pointer to a cancel flag. An application can set this parameter to nonzero to cancel the navigation operation, or
to zero to allow it to proceed.

CHtmlView::OnCommandStateChange
This member function is called by the framework to notify an application that the enabled state of a web browser
command has changed.

virtual void OnCommandStateChange(


long nCommand,
BOOL bEnable);

Parameters
nCommand
Identifier of the command whose enabled state has changed.
bEnable
Enabled state. This parameter is nonzero if the command is enabled, or zero if it is disabled.

CHtmlView::OnDocumentComplete
This member function is called by the framework to notify an application that a document has reached the
READYSTATE_COMPLETE state.

virtual void OnDocumentComplete(LPCTSTR lpszURL);

Parameters
lpszURL
A pointer to a string that evaluates to the URL, UNC file name, or a PIDL (a pointer to an item identifier list) that
was navigated to.
Remarks
Not every frame will fire this event, but each frame that fires an OnDownloadBegin event will fire a corresponding
OnDocumentComplete event.

The URL indicated by lpszURL can be different from the URL that the browser was told to navigate to, because this
URL is the canonicalized and qualified URL. For example, if an application specifies a URL of "www.microsoft.com"
in a call to Navigate or Navigate2, the URL passed by OnNavigateComplete2 will be "<https://www.microsoft.com/>"
. Also, if the server has redirected the browser to a different URL, the redirected URL will be reflected here.

CHtmlView::OnDocWindowActivate
Called from the Internet Explorer or MSHTML implementation of IOleInPlaceActiveObject::OnDocWindowActivate ,
which notifies the active in-place object when the container's document window is activated or deactivated.

virtual HRESULT OnDocWindowActivate(BOOL fActivate);

Parameters
fActivate
Indicates the state of the document window. If this value is nonzero, the window is being activated. If this value is
zero, the window is being deactivated.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnDocWindowActivate to react to the OnDocWindowActivate notification from the Microsoft Web Browser
control. See IDocHostUIHandler::OnDocWindowActivate in the Windows SDK for more information.

CHtmlView::OnDownloadBegin
This member function is called by the framework to begin downloading a document.

virtual void OnDownloadBegin();

Remarks
This event is fired shortly after the OnBeforeNavigate2 event, unless the navigation is canceled. Any animation or
"busy" indication that the container needs to display should be connected to this event.

CHtmlView::OnDownloadComplete
This member function is called by the framework to indicate that a navigation operation finished, was halted, or
failed.

virtual void OnDownloadComplete();

CHtmlView::OnEnableModeless
Called when Internet Explorer or MSHTML displays modal UI.

virtual HRESULT OnEnableModeless(BOOL fEnable);

Parameters
fEnable
Indicates if the host's modeless dialog boxes are enabled or disabled. If this value is nonzero, modeless dialog
boxes are enabled. If this value is zero, modeless dialog boxes are disabled.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Enables or disables modeless dialog boxes when the container creates or destroys a modal dialog box. Override
OnEnableModeless to react to the EnableModeless notification from the Microsoft Web Browser control. See
IDocHostUIHandler::EnableModeless in the Windows SDK for more information.

CHtmlView::OnFilterDataObject
Called on the host by Internet Explorer or MSHTML to allow the host to replace Internet Explorer or MSHTML's
data object.

virtual HRESULT OnFilterDataObject(


LPDATAOBJECT pDataObject,
LPDATAOBJECT* ppDataObject);

Parameters
pDataObject
Address of the IDataObject interface supplied by Internet Explorer or MSHTML.
ppDataObject
Address that receives the IDataObject interface pointer supplied by the host. The contents of this parameter
should always be initialized to NULL, even if the method fails.
Return Value
S_OK if the data object is replaced, S_FALSE if the data object is not replaced, or an OLE-defined error code if an
error occurs.
Remarks
Override OnFilterDataObject to react to the FilterDataObject notification from the Microsoft Web Browser
control. See IDocHostUIHandler::FilterDataObject in the Windows SDK for more information.

CHtmlView::OnFrameWindowActivate
Called from IOleInPlaceActiveObject::OnFrameWindowActivate to notify the object when the container's top-level
frame window is activated or deactivated.

virtual HRESULT OnFrameWindowActivate(BOOL fActivate);

Parameters
fActivate
Indicates the state of the container's top-level frame window. If this value is nonzero, the window is being
activated. If this value is zero, the window is being deactivated.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnFrameWindowActivate to react to the OnFrameWindowActivate notification from the Microsoft Web
Browser control. See IDocHostUIHandler::OnFrameWindowActivate in the Windows SDK for more information.

CHtmlView::OnFullScreen
This member function is called by the framework when the FullScreen property has changed.

virtual void OnFullScreen(BOOL bFullScreen);

Parameters
bFullScreen
Nonzero if Internet Explorer is in full screen mode; zero otherwise.

CHtmlView::OnGetDropTarget
Called by Internet Explorer or MSHTML when it is being used as a drop target to allow the host to supply an
alternative IDropTarget .

virtual HRESULT OnGetDropTarget(


LPDROPTARGET pDropTarget,
LPDROPTARGET* ppDropTarget);

Parameters
pDropTarget
IDropTarget Internet Explorer or MSHTML proposes to use.
ppDropTarget
Address of the IDropTarget that receives the IDropTarget interface pointer the host wants to provide.
Return Value
See IDocHostUIHandler::GetDropTarget in the Windows SDK for a list of return codes.
Remarks
Override OnGetDropTarget to react to the GetDropTarget notification from the Microsoft Web Browser control. See
IDocHostUIHandler::GetDropTarget in the Windows SDK for more information.

CHtmlView::OnGetExternal
Called by Internet Explorer or MSHTML to obtain the host's IDispatch interface.

virtual HRESULT OnGetExternal(LPDISPATCH* lppDispatch);

Parameters
lppDispatch
A pointer to the address that receives the IDispatch interface pointer of the host application. If the host exposes
an Automation interface, it can provide a reference to Internet Explorer or MSHTML through this parameter. The
contents of this parameter should always be initialized to NULL, even if the method fails.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnGetExternal to react to the GetExternal notification from the Microsoft Web Browser control. See
IDocHostUIHandler::GetExternal in the Windows SDK for more information.

CHtmlView::OnGetHostInfo
Retrieves the UI capabilities of the Internet Explorer or MSHTML host.

virtual HRESULT OnGetHostInfo(DOCHOSTUIINFO* pInfo);

Parameters
pInfo
Address of a DOCHOSTUIINFO structure that receives the host's UI capabilities.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnGetHostInfo to react to the GetHostInfo notification from the Microsoft Web Browser control. See
IDocHostUIHandler::GetHostInfo in the Windows SDK for more information.

CHtmlView::OnGetOptionKeyPath
Call this member function to get the registry key under which Internet Explorer or MSHTML stores user
preferences.

virtual HRESULT OnGetOptionKeyPath(


LPOLESTR* pchKey,
DWORD dwReserved);

Parameters
pchKey
Address of an LPOLESTR that receives the registry subkey string where the host stores its default options. This
subkey will be under the HKEY_CURRENT_USER key. Allocate this memory using CoTaskMemAlloc. The calling
application is responsible for freeing this memory using CoTaskMemFree. This parameter should always be
initialized to NULL, even if the method fails.
dwReserved
Reserved for future use. Not currently used.
Return Value
S_OK if successful, or S_FALSE otherwise. If S_FALSE, Internet Explorer or MSHTML will default to its own user
options.
Remarks
Override OnGetOptionKeyPath to react to the GetOptionKeyPath notification from the Microsoft Web Browser
control. See IDocHostUIHandler::GetOptionKeyPath in the Windows SDK for more information.

CHtmlView::OnHideUI
This member function is called by the framework when Internet Explorer or MSHTML removes its menus and
toolbars.

virtual HRESULT OnHideUI();

Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnHideUI to react to the HideUI notification from the Microsoft Web Browser control. See
IDocHostUIHandler::HideUI in the Windows SDK for more information.

CHtmlView::OnMenuBar
This member function is called by the framework when the MenuBar property has changed.

virtual void OnMenuBar(BOOL bMenuBar);

Parameters
bMenuBar
Nonzero if the Internet Explorer menu bar is visible; zero otherwise.

CHtmlView::OnNavigateComplete2
This member function is called by the framework after a navigation to a hyperlink completes (on either a window
or frameset element).

virtual void OnNavigateComplete2(LPCTSTR strURL);

Parameters
strURL
A string expression that evaluates to the URL, UNC file name, or PIDL (a pointer to an item identifier list) that was
navigated to.
Remarks
The URL parameter can be a PIDL in the case of a shell name space entity for which there is no URL
representation.
Note that the URL contained in strURL can be different from the URL that the browser was told to navigate to,
because this URL is the canonicalized and qualified URL. For example, if an application specifies a URL of
"www.microsoft.com" in a call to Navigate or Navigate2, the URL passed by OnNavigateComplete2 will be
"<https://www.microsoft.com/>" . Also, if the server has redirected the browser to a different URL, the redirected
URL will be reflected here.

CHtmlView::OnNavigateError
Called by the framework if navigation to a hyperlink fails.

virtual void OnNavigateError(


LPCTSTR lpszURL,
LPCTSTR lpszFrame,
DWORD dwError,
BOOL* pbCancel);

Parameters
lpszURL
The URL for which navigation failed.
lpszFrame
The name of the frame in which the resource is to be displayed, or NULL if no named frame was targeted for the
resource.
dwError
An error status code, if available. For a list of the possible HRESULT and HTTP status codes, see NavigateError
Event Status Codes..
pbCancel
Specifies whether to cancel the navigation to an error page or any further autosearch. If TRUE (the default),
continue with navigation to an error page or autosearch; if FALSE, cancel navigation to an error page or
autosearch.
Remarks
Override this method to provide custom navigation error handling.
For more information, see DWebBrowserEvents2::NavigateError

CHtmlView::OnNewWindow2
This member function is called by the framework when a new window is to be created for displaying a resource.

virtual void OnNewWindow2(


LPDISPATCH* ppDisp,
BOOL* Cancel);

Parameters
ppDisp
A pointer to an interface pointer that, optionally, receives the IDispatch interface pointer of a new WebBrowser or
Internet Explorer object.
Cancel
A pointer to a cancel flag. An application can set this parameter to nonzero to cancel the navigation operation, or
to zero to allow it to proceed.
Remarks
This event precedes the creation of a new window from within the WebBrowser.

CHtmlView::OnProgressChange
This member function is called by the framework to notify an application that the progress of a download
operation has been updated.

virtual void OnProgressChange(


long nProgress,
long nProgressMax);

Parameters
nProgress
Amount of total progress to show, or -1 when progress is complete.
nProgressMax
Maximum progress value.
Remarks
The container can use the information provided by this event to display the number of bytes downloaded so far or
to update a progress indicator.
CHtmlView::OnPropertyChange
This member function is called by the framework to notify an application that PutProperty has changed the value
of a property.

virtual void OnPropertyChange(LPCTSTR lpszProperty);

Parameters
lpszProperty
A pointer to a string containing the name of the property.

CHtmlView::OnQuit
This member function is called by the framework to notify an application that the Internet Explorer application is
ready to quit.

virtual void OnQuit();

CHtmlView::OnResizeBorder
Called from the Internet Explorer or MSHTML implementation of IOleInPlaceActiveObject::ResizeBorder, which
alerts the object that it needs to resize its border space.

virtual HRESULT OnResizeBorder(


LPCRECT prcBorder,
LPOLEINPLACEUIWINDOW pUIWindow,
BOOL fFrameWindow);

Parameters
prcBorder
New outer rectangle for border space.
pUIWindow
A pointer to the interface for the frame or document window object whose border has changed.
fFrameWindow
TRUE if the frame window is calling IOleInPlaceActiveObject::ResizeBorder, otherwise FALSE.
Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
Override OnResizeBorder to react to the ResizeBorder notification from the Microsoft Web Browser control. See
IDocHostUIHandler::ResizeBorder in the Windows SDK for more information.

CHtmlView::OnShowContextMenu
Called from Internet Explorer or MSHTML when it is about to show its context menu.
virtual HRESULT OnShowContextMenu(
DWORD dwID,
LPPOINT ppt,
LPUNKNOWN pcmdtReserved,
LPDISPATCH pdispReserved);

Parameters
dwID
Identifier of the context menu to be displayed. See IDocHostUIHandler::ShowContextMenu in the Windows SDK for a
list of values.
ppt
Screen coordinates for the menu.
pcmdtReserved
IOleCommandTarget interface used to query command status and execute commands on this object.
pdispReserved
IDispatch interface of the object at the screen coordinates. This allows a host to differentiate particular objects to
provide more specific context.
Return Value
See IDocHostUIHandler::ShowContextMenu in the Windows SDK for a list of values.
Remarks
Override OnShowContextMenu to react to the ShowContextMenu notification from the Microsoft Web Browser control.
See IDocHostUIHandler::ShowContextMenu in the Windows SDK for more information.

CHtmlView::OnShowUI
Called before Internet Explorer or MSHTML displays its menus and toolbars.

virtual HRESULT OnShowUI(


DWORD dwID,
LPOLEINPLACEACTIVEOBJECT pActiveObject,
LPOLECOMMANDTARGET pCommandTarget,
LPOLEINPLACEFRAME pFrame,
LPOLEINPLACEUIWINDOW pDoc);

Parameters
dwID
Reserved for future use.
pActiveObject
IOleInPlaceActiveObject interface of the currently active object.
pCommandTarget
IOleCommandTarget interface of the object.
pFrame
IOleInPlaceFrame interface of the object. This is needed for menus and toolbars.
pDoc
IOleInPlaceUIWindow interface for the object. This is needed for toolbars.
Return Value
See IDocHostUIHandler::ShowUI in the Windows SDK for a list of values.
Remarks
Override OnShowUI to react to the ShowUI notification from the Microsoft Web Browser control. See
IDocHostUIHandler::ShowUI in the Windows SDK for more information.

CHtmlView::OnStatusBar
This member function is called by the framework when the StatusBar property has changed.

virtual void OnStatusBar(BOOL bStatusBar);

Parameters
bStatusBar
Nonzero if Internet Explorer's status bar is visible or zero otherwise.

CHtmlView::OnStatusTextChange
This member function is called by the framework to notify an application that the text of the status bar associated
with the WebBrowser control has changed.

virtual void OnStatusTextChange(LPCTSTR lpszText);

Parameters
lpszText
A string that contains the new status bar text.

CHtmlView::OnTheaterMode
This member function is called by the framework when the TheaterMode property has changed.

virtual void OnTheaterMode(BOOL bTheaterMode);

Parameters
bTheaterMode
Nonzero if Internet Explorer is in theater mode; zero otherwise.

CHtmlView::OnTitleChange
This member function is called by the framework to notify an application if the title of a document in the
WebBrowser control becomes available or changes.

virtual void OnTitleChange(LPCTSTR lpszText);

Parameters
lpszText
The new document title.
Remarks
For HTML, the title might change; while HTML is still downloading, the URL of the document is set as the title. After
the real title (if there is one) is parsed from the HTML, the title is changed to reflect the actual title.

CHtmlView::OnToolBar
This member function is called by the framework when the ToolBar property has changed.

virtual void OnToolBar(BOOL bToolBar);

Parameters
bToolBar
Nonzero if Internet Explorer's toolbar is visible or zero otherwise.

CHtmlView::OnTranslateAccelerator
Called by Internet Explorer or MSHTML when IOleInPlaceActiveObject::TranslateAccelerator or
IOleControlSite::TranslateAccelerator is called to process menu accelerator-key messages from the container's
message queue.

virtual HRESULT OnTranslateAccelerator(


LPMSG lpMsg,
const GUID* pguidCmdGroup,
DWORD nCmdID);

Parameters
lpMsg
Points to the message that might need to be translated.
pguidCmdGroup
Command group identifier.
nCmdID
Command identifier.
Return Value
S_OK if successful, or S_FALSE otherwise.
Remarks
Override OnTranslateAccelerator to react to the TranslateAccelerator notification from the Microsoft Web
Browser control. See IDocHostUIHandler::TranslateAccelerator in the Windows SDK for more information.

CHtmlView::OnTranslateUrl
Called by Internet Explorer or MSHTML to allow the host an opportunity to modify the URL to be loaded.

virtual HRESULT OnTranslateUrl(


DWORD dwTranslate,
OLECHAR* pchURLIn,
OLECHAR** ppchURLOut);

Parameters
dwTranslate
Reserved for future use.
pchURLIn
Address of a string supplied by Internet Explorer or MSHTML that represents the URL to be translated.
ppchURLOut
Address of a string pointer that receives the address of the translated URL. The host allocates the buffer using the
task memory allocator. The contents of this parameter should always be initialized to NULL, even if the URL is not
translated or the method fails.
Return Value
S_OK if the URL was translated, S_FALSE if the URL was not translated, or an OLE-defined error code if an error
occurred.
Remarks
Override OnTranslateUrl to react to the TranslateUrl notification from the Microsoft Web Browser control. See
IDocHostUIHandler::TranslateUrl in the Windows SDK for more information.

CHtmlView::OnUpdateUI
Notifies the host that the command state has changed.

virtual HRESULT OnUpdateUI();

Return Value
S_OK if successful, or an OLE-defined error code otherwise.
Remarks
The host should update the state of toolbar buttons. This method is called regardless of the return value from
ShowUI . Override OnUpdateUI to react to the UpdateUI notification from the Microsoft Web Browser control.

CHtmlView::OnVisible
This member function is called by the framework when the window for the WebBrowser should be shown or
hidden.

virtual void OnVisible(BOOL bVisible);

Parameters
bVisible
Nonzero if the object is visible or zero otherwise.
Remarks
This allows the object control host window to behave the same way the Internet Explorer window would behave.

CHtmlView::PutProperty
Call this member function to set the property associated with a given object.
void PutProperty(
LPCTSTR lpszProperty,
const VARIANT& vtValue);

void PutProperty(
LPCTSTR lpszPropertyName,
double dValue);

void PutProperty(
LPCTSTR lpszPropertyName,
long lValue);

void PutProperty(
LPCTSTR lpszPropertyName,
LPCTSTR lpszValue);

void PutProperty(
LPCTSTR lpszPropertyName,
short nValue);

Parameters
lpszProperty
A string containing the property to set.
vtValue
The new value of the property indicated by lpszProperty.
lpszPropertyName
A pointer to a string containing the name of the property to set.
dValue
The new value of the property.
lValue
The new value of the property.
lpszValue
A pointer to a string containing the new value of the property.
nValue
The new value of the property.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::QueryFormsCommand
Queries for the status of one or more commands generated by user interface events.

HRESULT QueryFormsCommand(
DWORD dwCommandID,
BOOL* pbSupported,
BOOL* pbEnabled,
BOOL* pbChecked);

Parameters
dwCommandID
The identifier of the command being queried for.
pbSupported
A pointer to a BOOL specifying if the command (identified by dwCommandID) is supported. If TRUE, the
command is supported; otherwise FALSE.
pbEnabled
A pointer to a BOOL specifying if the command (identified by dwCommandID) is enabled. If TRUE, the command is
supported; otherwise FALSE.
pbChecked
A pointer to a BOOL specifying if the command (identified by dwCommandID) is checked. If TRUE, the command is
supported; otherwise FALSE.
Return Value
A standard HRESULT value. For a complete listing of possible values, see IOleCommandTarget::QueryStatus in the
Windows SDK.
Remarks
QueryFormsCommand implements the behavior of the IOleCommandTarget::QueryStatus method.

CHtmlView::QueryStatusWB
Call this member function to query a command status.

OLECMDF QueryStatusWB(OLECMDID cmdID) const;

Parameters
cmdID
The OLECMDID value of the command for which the caller needs status information.
Return Value
The address of the OLECMDF value that receives the status of the command.
Remarks
QueryStatusWB implements the behavior of the IOleCommandTarget::QueryStatus method.
Applies to Internet Explorer and WebBrowser.

CHtmlView::Refresh
Reloads the URL or file that the web browser is currently displaying.

void Refresh();

Remarks
Refresh contains no parameters for setting the refresh level.
Applies to Internet Explorer and WebBrowser.

CHtmlView::Refresh2
Reloads the file that Internet Explorer is currently displaying.

void Refresh2(int nLevel);


Parameters
nLevel
The address of the variable specifying the refresh level. The possible variables are defined in RefreshConstants, in
the Windows SDK.
Remarks
Unlike Refresh, Refresh2 contains a parameter that specifies the refresh level.
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetAddressBar
Call this member function to show or hide the Internet Explorer object's address bar.

void SetAddressBar(BOOL bNewValue);

Parameters
bNewValue
Nonzero to show address bar; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::SetFullScreen
Call this member function to set Internet Explorer to either full-screen or normal window mode.

void SetFullScreen(BOOL bNewValue);

Parameters
bNewValue
Nonzero for full-screen mode; otherwise zero.
Remarks
In full-screen mode, the Internet Explorer main window is maximized and the status bar, toolbar, menu bar, and
title bar are hidden.
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::SetHeight
Call this member function to set the height of the Internet Explorer main window.

void SetHeight(long nNewValue);

Parameters
nNewValue
The height, in pixels, of the main window.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetLeft
Sets the horizontal position of the Internet Explorer main window.

void SetLeft(long nNewValue);

Parameters
nNewValue
The screen coordinate of the left edge of the main window.

CHtmlView::SetMenuBar
Call this member function to show or hide the Internet Explorer menu bar.

void SetMenuBar(BOOL bNewValue);

Parameters
bNewValue
Nonzero to show menu bar; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::SetOffline
Call this member function to set a value indicating whether the WebBrowser control is currently operating in
offline mode.

void SetOffline(BOOL bNewValue);

Parameters
bNewValue
Nonzero to read from the local cache; otherwise zero.
Remarks
In offline mode, the browser reads HTML pages from the local cache rather than from the source document.
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetRegisterAsBrowser
Call this member function to set a value indicating whether the WebBrowser control is registered as a top-level
browser for target name resolution.

void SetRegisterAsBrowser(BOOL bNewValue);

Parameters
bNewValue
Determines whether Internet Explorer is registered as a top-level browser. If nonzero, the web browser is
registered as a top-level browser; if zero, it is not a top-level browser. The default value is zero.
Remarks
A top-level browser is the browser set in the registry as the default browser.
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetRegisterAsDropTarget
Call this member function to set a value indicating whether the WebBrowser control is registered as a drop target
for navigation.

void SetRegisterAsDropTarget(BOOL bNewValue);

Parameters
bNewValue
Determines if the WebBrowser control is registered as a drop target for navigation. If nonzero, the object is
registered as a drop target; if zero, it is not a drop target.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetSilent
Call this member function to set a value indicating whether any dialog boxes can be shown.

void SetSilent(BOOL bNewValue);

Parameters
bNewValue
If nonzero, dialog boxes will not be displayed; if zero, dialog boxes will be displayed. The default value is zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetStatusBar
Call this member function to display the status bar.

void SetStatusBar(BOOL bNewValue);

Parameters
bNewValue
Nonzero if the status bar is visible; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::SetTheaterMode
Call this member function to set a value indicating whether the WebBrowser control is in theater mode.

void SetTheaterMode(BOOL bNewValue);

Parameters
bNewValue
Nonzero to set the WebBrowser control to theater mode; otherwise zero. The default value is zero.
Remarks
When the web browser is in theater mode, the browser main window fills the entire screen, a toolbar with a
minimal set of navigational tools appears, and the status bar appears in the upper right-hand corner of the screen.
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetToolBar
Call this member function to show or hide the Internet Explorer toolbar.

void SetToolBar(int nNewValue);

Parameters
nNewValue
Indicates whether to display the toolbar. Nonzero if the toolbar is to be displayed; otherwise zero.
Remarks
Applies to Internet Explorer. If you use this call with a WebBrowser control, it will return no error, but it will ignore
this call.

CHtmlView::SetTop
Call this member function to set the distance between the internal top edge of the WebBrowser control and the
top edge of its container

void SetTop(long nNewValue);

Parameters
nNewValue
The screen coordinate of the top edge of the main window.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetVisible
Call this member function to set the visibility state of the WebBrowser control.

void SetVisible(BOOL bNewValue);

Parameters
bNewValue
Nonzero if the control is visible; otherwise zero.
Remarks
Applies to Internet Explorer and WebBrowser.

CHtmlView::SetWidth
Sets the width of the Internet Explorer main window.

void SetWidth(long nNewValue);

Parameters
nNewValue
The width, in pixels, of the Internet Explorer main window.

CHtmlView::Stop
Call this member function to cancel any pending navigation or download operation and stop any dynamic page
elements, such as background sounds and animations.

void Stop();

Remarks
Applies to Internet Explorer and WebBrowser.

See also
MFC Sample MFCIE
CFormView Class
Hierarchy Chart
IWebBrowser2
CHttpConnection Class
3/27/2020 • 4 minutes to read • Edit Online

Manages your connection to an HTTP server.

Syntax
class CHttpConnection : public CInternetConnection

Members
Public Constructors
NAME DESC RIP T IO N

CHttpConnection::CHttpConnection Creates a CHttpConnection object.

Public Methods
NAME DESC RIP T IO N

CHttpConnection::OpenRequest Opens an HTTP request.

Remarks
HTTP is one of three Internet server protocols implemented by the MFC WinInet classes.
The class CHttpConnection contains a constructor and one member function, OpenRequest, that manages
connections to a server with an HTTP protocol.
To communicate with an HTTP server, you must first create an instance of CInternetSession, and then create a
CHttpConnection object. You never create a CHttpConnection object directly; rather, call
CInternetSession::GetHttpConnection, which creates the CHttpConnection object and returns a pointer to it.
To learn more about how CHttpConnection works with the other MFC Internet classes, see the article Internet
Programming with WinInet. For more information about connecting to servers using the other two supported
Internet protocols, gopher and FTP, see the classes CGopherConnection and CFtpConnection.

Inheritance Hierarchy
CObject
CInternetConnection
CHttpConnection

Requirements
Header : afxinet.h
CHttpConnection::CHttpConnection
This member function is called to construct a CHttpConnection object.

CHttpConnection(
CInternetSession* pSession,
HINTERNET hConnected,
LPCTSTR pstrServer,
DWORD_PTR dwContext);

CHttpConnection(
CInternetSession* pSession,
LPCTSTR pstrServer,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
DWORD_PTR dwContext = 1);

CHttpConnection(
CInternetSession* pSession,
LPCTSTR pstrServer,
DWORD dwFlags,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
DWORD_PTR dwContext = 1);

Parameters
pSession
A pointer to a CInternetSession object.
hConnected
A handle to an Internet connection.
pstrServer
A pointer to a string containing the server name.
dwContext
The context identifier for the CInternetConnection object. For more information about dwContext, see the
Remarks section.
nPort
The number that identifies the Internet port for this connection.
pstrUserName
Pointer to a null-terminated string that specifies the name of the user to sign in. If NULL, the default is
anonymous.
pstrPassword
A pointer to a null-terminated string that specifies the password to use to sign in. If both pstrPassword and
pstrUserName are NULL, the default anonymous password is the user's email name. If pstrPassword is NULL or
an empty string, but pstrUserName is not NULL, a blank password is used. The following table describes the
behavior for the four possible settings of pstrUserName and pstrPassword:

USERN A M E SEN T TO F T P PA SSW O RD SEN T TO F T P


P ST RUSERN A M E P ST RPA SSWO RD SERVER SERVER

NULL or " " NULL or " " "anonymous" User's email name
USERN A M E SEN T TO F T P PA SSW O RD SEN T TO F T P
P ST RUSERN A M E P ST RPA SSWO RD SERVER SERVER

Non-NULL String NULL or " " pstrUserName ""

NULL Non-NULL String ERROR ERROR

Non-NULL String Non-NULL String pstrUserName pstrPassword

dwFlags
Any combination of the INTERNET_FLAG_* flags. See the table in the Remarks section of
CHttpConnection::OpenRequest for a description of dwFlags values.
Remarks
You never create a CHttpConnection directly. Rather, you create an object by calling
CInternetSession::GetHttpConnection.

CHttpConnection::OpenRequest
Call this member function to open an HTTP connection.

CHttpFile* OpenRequest(
LPCTSTR pstrVerb,
LPCTSTR pstrObjectName,
LPCTSTR pstrReferer = NULL,
DWORD_PTR dwContext = 1,
LPCTSTR* ppstrAcceptTypes = NULL,
LPCTSTR pstrVersion = NULL,
DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);

CHttpFile* OpenRequest(
int nVerb,
LPCTSTR pstrObjectName,
LPCTSTR pstrReferer = NULL,
DWORD_PTR dwContext = 1,
LPCTSTR* ppstrAcceptTypes = NULL,
LPCTSTR pstrVersion = NULL,
DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT);

Parameters
pstrVerb
A pointer to a string containing the verb to use in the request. If NULL, "GET" is used.
pstrObjectName
A pointer to a string containing the target object of the specified verb. This string is generally a filename, an
executable module, or a search specifier.
pstrReferer
A pointer to a string that specifies the address (URL) of the document from which the URL in the request
(pstrObjectName) was obtained. If NULL, no HTTP header is specified.
dwContext
The context identifier for the OpenRequest operation. For more information about dwContext, see the Remarks
section.
ppstrAcceptTypes
A pointer to a null-terminated array of LPCTSTR pointers to strings indicating content types accepted by the
client. If ppstrAcceptTypes is NULL, the servers interpret that the client only accepts documents of type "text/*"
(that is, only text documents and not pictures or other binary files). The content type is equivalent to the CGI
variable CONTENT_TYPE, which identifies the type of data for queries that have attached information, such as
HTTP POST and PUT.
pstrVersion
A pointer to a string defining the HTTP version. If NULL, "HTTP/1.0" is used.
dwFlags
Any combination of the INTERNET_ FLAG_* flags. See the Remarks section for a description of possible dwFlags
values.
nVerb
A number associated with the HTTP request type. Can be one of the following:

H T T P REQ UEST T Y P E N VERB VA L UE

HTTP_VERB_POST 0

HTTP_VERB_GET 1

HTTP_VERB_HEAD 2

HTTP_VERB_PUT 3

HTTP_VERB_LINK 4

HTTP_VERB_DELETE 5

HTTP_VERB_UNLINK 6

Return Value
A pointer to the CHttpFile object requested.
Remarks
dwFlags can be one of the following:

IN T ERN ET F L A G DESC RIP T IO N

INTERNET_FLAG_RELOAD Forces a download of the requested file, object, or directory


listing from the origin server, not from the cache.

INTERNET_FLAG_DONT_CACHE Doesn't add the returned entity to the cache.

INTERNET_FLAG_MAKE_PERSISTENT Adds the returned entity to the cache as a persistent entity.


It means that standard cache cleanup, consistency checking,
or garbage collection cannot remove this item from the
cache.

INTERNET_FLAG_SECURE Uses secure transaction semantics. It translates to using


SSL/PCT and is only meaningful in HTTP requests

INTERNET_FLAG_NO_AUTO_REDIRECT Used only with HTTP, specifies that redirections shouldn't be


handled automatically in CHttpFile::SendRequest.
Override the dwContext default to set the context identifier to a value of your choosing. The context identifier is
associated with this specific operation of the CHttpConnection object created by its CInternetSession object. The
value is returned to CInternetSession::OnStatusCallback to provide status on the operation with which it's
identified. See the article Internet First Steps: WinInet for more information about the context identifier.
Exceptions may be thrown with this function.

See also
CInternetConnection Class
Hierarchy Chart
CInternetConnection Class
CHttpFile Class
CHttpFile Class
3/27/2020 • 11 minutes to read • Edit Online

Provides the functionality to request and read files on an HTTP server.

Syntax
class CHttpFile : public CInternetFile

Members
Protected Constructors
NAME DESC RIP T IO N

CHttpFile::CHttpFile Creates a CHttpFile object.

Public Methods
NAME DESC RIP T IO N

CHttpFile::AddRequestHeaders Adds headers to the request sent to an HTTP server.

CHttpFile::EndRequest Ends a request sent to an HTTP server with the


SendRequestEx member function.

CHttpFile::GetFileURL Gets the URL for the specified file.

CHttpFile::GetObject Gets the target object of the verb in a request to an HTTP


server.

CHttpFile::GetVerb Gets the verb that was used in a request to an HTTP server.

CHttpFile::QueryInfo Returns the response or request headers from the HTTP


server.

CHttpFile::QueryInfoStatusCode Retrieves the status code associated with an HTTP request


and places it in the supplied dwStatusCode parameter.

CHttpFile::SendRequest Sends a request to an HTTP server.

CHttpFile::SendRequestEx Sends a request to an HTTP server using the Write or


WriteString methods of CInternetFile .

Remarks
If your Internet session reads data from an HTTP server, you must create an instance of CHttpFile .
To learn more about how CHttpFile works with the other MFC Internet classes, see the article Internet
Programming with WinInet.

Inheritance Hierarchy
CObject
CFile
CStdioFile
CInternetFile
CHttpFile

Requirements
Header : afxinet.h

CHttpFile::AddRequestHeaders
Call this member function to add one or more HTTP request headers to the HTTP request handle.

BOOL AddRequestHeaders(
LPCTSTR pstrHeaders,
DWORD dwFlags = HTTP_ADDREQ_FLAG_ADD_IF_NEW,
int dwHeadersLen = -1);

BOOL AddRequestHeaders(
CString& str,
DWORD dwFlags = HTTP_ADDREQ_FLAG_ADD_IF_NEW);

Parameters
pstrHeaders
A pointer to a string containing the header or headers to append to the request. Each header must be
terminated by a CR/LF pair.
dwFlags
Modifies the semantics of the new headers. Can be one of the following:
HTTP_ADDREQ_FLAG_COALESCE Merges headers of the same name, using the flag to add the first
header found to the subsequent header. For example, "Accept: text/*" followed by "Accept: audio/*"
results in the formation of the single header "Accept: text/*, audio/*". It is up to the calling application to
ensure a cohesive scheme with respect to data received by requests sent with coalesced or separate
headers.
HTTP_ADDREQ_FLAG_REPLACE Performs a remove and add to replace the current header. The header
name will be used to remove the current header, and the full value will be used to add the new header. If
the header-value is empty and the header is found, it is removed. If not empty, the header-value is
replaced.
HTTP_ADDREQ_FLAG_ADD_IF_NEW Only adds the header if it does not already exist. If one exists, an
error is returned.
HTTP_ADDREQ_FLAG_ADD Used with REPLACE. Adds the header if it doesn't exist.
dwHeadersLen
The length, in characters, of pstrHeaders. If this is -1L, then pstrHeaders is assumed to be zero-terminated and
the length is computed.
str
A reference to a CString object containing the request header or headers to be added.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
AddRequestHeaders appends additional, free-format headers to the HTTP request handle. It is intended for use
by sophisticated clients who need detailed control over the exact request sent to the HTTP server.

NOTE
The application can pass multiple headers in pstrHeaders or str for an AddRequestHeaders call using
HTTP_ADDREQ_FLAG_ADD or HTTP_ADDREQ_FLAG_ADD_IF_NEW. If the application tries to remove or replace a header
using HTTP_ADDREQ_FLAG_REMOVE or HTTP_ADDREQ_FLAG_REPLACE, only one header can be supplied in
lpszHeaders.

CHttpFile::CHttpFile
This member function is called to construct a CHttpFile object.

CHttpFile(
HINTERNET hFile,
HINTERNET hSession,
LPCTSTR pstrObject,
LPCTSTR pstrServer,
LPCTSTR pstrVerb,
DWORD_PTR dwContext);

CHttpFile(
HINTERNET hFile,
LPCTSTR pstrVerb,
LPCTSTR pstrObject,
CHttpConnection* pConnection);

Parameters
hFile
A handle to an Internet file.
hSession
A handle to an Internet session.
pstrObject
A pointer to a string containing the CHttpFile object.
pstrServer
A pointer to a string containing the name of the server.
pstrVerb
A pointer to a string containing the method to be used when sending the request. Can be POST, HEAD, or GET.
dwContext
The context identifier for the CHttpFile object. See Remarks for more information about this parameter.
pConnection
A pointer to a CHttpConnection object.
Remarks
You never construct a CHttpFile object directly; rather call CInternetSession::OpenURL or
CHttpConnection::OpenRequest instead.
The default value for dwContext is sent by MFC to the CHttpFile object from the CInternetSession object that
created the CHttpFile object. When you call CInternetSession::OpenURL or CHttpConnection to construct a
CHttpFile object, you can override the default to set the context identifier to a value of your choosing. The
context identifier is returned to CInternetSession::OnStatusCallback to provide status on the object with which it
is identified. See the article Internet First Steps: WinInet for more information about the context identifier.

CHttpFile::EndRequest
Call this member function to end a request sent to an HTTP server with the SendRequestEx member function.

BOOL EndRequest(
DWORD dwFlags = 0,
LPINTERNET_BUFFERS lpBuffIn = NULL,
DWORD_PTR dwContext = 1);

Parameters
dwFlags
Flags describing the operation. For a list of the appropriate flags, see HttpEndRequest in the Windows SDK.
lpBuffIn
Pointer to an initialized INTERNET_BUFFERS that describes the input buffer used for the operation.
dwContext
The context identifier for the CHttpFile operation. See Remarks for more information about this parameter.
Return Value
Nonzero if successful; otherwise 0. If the call fails, determine the cause of the failure by examining the thrown
CInternetException object.
Remarks
The default value for dwContext is sent by MFC to the CHttpFile object from the CInternetSession object that
created the CHttpFile object. When you call CInternetSession::OpenURL or CHttpConnection to construct a
CHttpFile object, you can override the default to set the context identifier to a value of your choosing. The
context identifier is returned to CInternetSession::OnStatusCallback to provide status on the object with which it
is identified. See article Internet First Steps: WinInet for more information about the context identifier.

CHttpFile::GetFileURL
Call this member function to get the name of the HTTP file as a URL.

virtual CString GetFileURL() const;

Return Value
A CString object containing a URL referencing the resource associated with this file.
Remarks
Use this member function only after a successful call to SendRequest or on a CHttpFile object successfully
created by OpenURL.

CHttpFile::GetObject
CHttpFile::GetObject
Call this member function to get the name of the object associated with this CHttpFile .

CString GetObject() const;

Return Value
A CString object containing the name of the object.
Remarks
Use this member function only after a successful call to SendRequest or on a CHttpFile object successfully
created by OpenURL.

CHttpFile::GetVerb
Call this member function to get the HTTP verb (or method) associated with this CHttpFile .

CString GetVerb() const;

Return Value
A CString object containing the name of the HTTP verb (or method).
Remarks
Use this member function only after a successful call to SendRequest or on a CHttpFile object successfully
created by OpenURL.

CHttpFile::QueryInfo
Call this member function to return response or request headers from an HTTP request.

BOOL QueryInfo(
DWORD dwInfoLevel,
LPVOID lpvBuffer,
LPDWORD lpdwBufferLength,
LPDWORD lpdwIndex = NULL) const;

BOOL QueryInfo(
DWORD dwInfoLevel,
CString& str,
LPDWORD dwIndex = NULL) const;

BOOL QueryInfo(
DWORD dwInfoLevel,
SYSTEMTIME* pSysTime,
LPDWORD dwIndex = NULL) const;

Parameters
dwInfoLevel
A combination of the attribute to query and the following flags that specify the type of information requested:
HTTP_QUERY_CUSTOM Finds the header name and returns this value in lpvBuffer on output.
HTTP_QUERY_CUSTOM throws an assertion if the header isn't found.
HTTP_QUERY_FLAG_REQUEST_HEADERS Typically, the application queries the response headers, but an
application can also query request headers by using this flag.
HTTP_QUERY_FLAG_SYSTEMTIME For those headers whose value is a date/time string, such as "Last-
Modified-Time," this flag returns the header value as a standard Win32 SYSTEMTIME structure that does
not require the application to parse the data. If you use this flag, you may want to use the SYSTEMTIME
override of the function.
HTTP_QUERY_FLAG_NUMBER For those headers whose value is a number, such as the status code, this
flag returns the data as a 32-bit number.
See the Remarks section for a list of the possible values.
lpvBuffer
A pointer to the buffer that receives the information.
lpdwBufferLength
On entry, this points to a value containing the length of the data buffer, in number of characters or bytes. See
the Remarks section for more detailed information about this parameter.
lpdwIndex
A pointer to a zero-based header index. Can be NULL. Use this flag to enumerate multiple headers with the
same name. On input, lpdwIndex indicates the index of the specified header to return. On output, lpdwIndex
indicates the index of the next header. If the next index cannot be found, ERROR_HTTP_HEADER_NOT_FOUND is
returned.
str
A reference to the CString object receiving the returned information.
dwIndex
An index value. See lpdwIndex.
pSysTime
A pointer to a Win32 SYSTEMTIME structure.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
Use this member function only after a successful call to SendRequest or on a CHttpFile object successfully
created by OpenURL.
You can retrieve the following types of data from QueryInfo :
strings (default)
SYSTEMTIME (for "Data:" "Expires:" etc, headers)
DWORD (for STATUS_CODE, CONTENT_LENGTH, etc.)
When a string is written to the buffer, and the member function succeeds, lpdwBufferLength contains the
length of the string in characters minus 1 for the terminating NULL character.
The possible dwInfoLevel values include:
HTTP_QUERY_MIME_VERSION
HTTP_QUERY_CONTENT_TYPE
HTTP_QUERY_CONTENT_TRANSFER_ENCODING
HTTP_QUERY_CONTENT_ID
HTTP_QUERY_CONTENT_DESCRIPTION
HTTP_QUERY_CONTENT_LENGTH
HTTP_QUERY_ALLOWED_METHODS
HTTP_QUERY_PUBLIC_METHODS
HTTP_QUERY_DATE
HTTP_QUERY_EXPIRES
HTTP_QUERY_LAST_MODIFIED
HTTP_QUERY_MESSAGE_ID
HTTP_QUERY_URI
HTTP_QUERY_DERIVED_FROM
HTTP_QUERY_LANGUAGE
HTTP_QUERY_COST
HTTP_QUERY_WWW_LINK
HTTP_QUERY_PRAGMA
HTTP_QUERY_VERSION
HTTP_QUERY_STATUS_CODE
HTTP_QUERY_STATUS_TEXT
HTTP_QUERY_RAW_HEADERS
HTTP_QUERY_RAW_HEADERS_CRLF

CHttpFile::QueryInfoStatusCode
Call this member function to get the status code associated with an HTTP request and place it in the supplied
dwStatusCode parameter.

BOOL QueryInfoStatusCode(DWORD& dwStatusCode) const;

Parameters
dwStatusCode
A reference to a status code. Status codes indicate the success or failure of the requested event. See Remarks
for a selection of status code descriptions.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to determine
the cause of the error.
Remarks
Use this member function only after a successful call to SendRequest or on a CHttpFile object successfully
created by OpenURL.
HTTP status codes fall into groups indicating the success or failure of the request. The following tables outline
the status code groups and the most common HTTP status codes.
GRO UP M EA N IN G

200-299 Success

300-399 Information

400-499 Request error

500-599 Server error

Common HTTP Status Codes:

STAT US C O DE M EA N IN G

200 URL located, transmission follows

400 Unintelligible request

404 Requested URL not found

405 Server does not support requested method

500 Unknown server error

503 Server capacity reached

CHttpFile::SendRequest
Call this member function to send a request to an HTTP server.

BOOL SendRequest(
LPCTSTR pstrHeaders = NULL,
DWORD dwHeadersLen = 0,
LPVOID lpOptional = NULL,
DWORD dwOptionalLen = 0);

BOOL SendRequest(
CString& strHeaders,
LPVOID lpOptional = NULL,
DWORD dwOptionalLen = 0);

Parameters
pstrHeaders
A pointer to a string containing the name of the headers to send.
dwHeadersLen
The length of the headers identified by pstrHeaders.
lpOptional
Any optional data to send immediately after the request headers. This is generally used for POST and PUT
operations. This can be NULL if there is no optional data to send.
dwOptionalLen
The length of lpOptional.
strHeaders
A string containing the name of the headers for the request being sent.
Return Value
Nonzero if successful; otherwise 0. If the call fails, determine the cause of the failure by examining the thrown
CInternetException object.

CHttpFile::SendRequestEx
Call this member function to send a request to an HTTP server.

BOOL SendRequestEx(
DWORD dwTotalLen,
DWORD dwFlags = HSR_INITIATE,
DWORD_PTR dwContext = 1);

BOOL SendRequestEx(
LPINTERNET_BUFFERS lpBuffIn,
LPINTERNET_BUFFERS lpBuffOut,
DWORD dwFlags = HSR_INITIATE,
DWORD_PTR dwContext = 1);

Parameters
dwTotalLen
Number of bytes to be sent in the request.
dwFlags
Flags describing the operation. For a list of appropriate flags, see HttpSendRequestEx in the Windows SDK.
dwContext
The context identifier for the CHttpFile operation. See Remarks for more information about this parameter.
lpBuffIn
Pointer to an initialized INTERNET_BUFFERS that describes the input buffer used for the operation.
lpBuffOut
Pointer to an initialized INTERNET_BUFFERS that describes the output buffer used for the operation.
Return Value
Nonzero if successful. If the call fails, determine the cause of the failure by examining the thrown
CInternetException object.
Remarks
This function allows your application to send data using the Write and WriteString methods of CInternetFile .
You must know the length of the data to send before calling either override of this function. The first override
allows you to specify the length of data you'd like to send. The second override accepts pointers to
INTERNET_BUFFERS structures, which can be used to describe the buffer in great detail.
After content is written to the file, call EndRequest to end the operation.
The default value for dwContext is sent by MFC to the CHttpFile object from the CInternetSession object that
created the CHttpFile object. When you call CInternetSession::OpenURL or CHttpConnection to construct a
CHttpFile object, you can override the default to set the context identifier to a value of your choosing. The
context identifier is returned to CInternetSession::OnStatusCallback to provide status on the object with which it
is identified. See the article Internet First Steps: WinInet for more information about the context identifier.
Example
This code fragment sends the content of a string to a DLL named MFCISAPI.DLL on the LOCALHOST server.
While this example uses only one call to WriteString , using multiple calls to send data in blocks is acceptable.

CString strData = _T("Some very long data to be POSTed here!");


pServer = session.GetHttpConnection(_T("localhost"));
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,
_T("/MFCISAPI/MFCISAPI.dll?"));
pFile->SendRequestEx(strData.GetLength());

pFile->WriteString(strData);
pFile->EndRequest();

See also
CInternetFile Class
Hierarchy Chart
CInternetFile Class
CGopherFile Class
CHttpConnection Class
CHwndRenderTarget Class
4/21/2020 • 2 minutes to read • Edit Online

A wrapper for ID2D1HwndRenderTarget.

Syntax
class CHwndRenderTarget : public CRenderTarget;

Members
Public Constructors
NAME DESC RIP T IO N

CHwndRenderTarget::CHwndRenderTarget Constructs a CHwndRenderTarget object from HWND.

Public Methods
NAME DESC RIP T IO N

CHwndRenderTarget::Attach Attaches existing render target interface to the object

CHwndRenderTarget::CheckWindowState Indicates whether the HWND associated with this render


target is occluded.

CHwndRenderTarget::Create Creates a render target associated with the window

CHwndRenderTarget::Detach Detaches render target interface from the object

CHwndRenderTarget::GetHwnd Returns the HWND associated with this render target.

CHwndRenderTarget::GetHwndRenderTarget Returns ID2D1HwndRenderTarget interface.

CHwndRenderTarget::ReCreate Re-creates a render target associated with the window

CHwndRenderTarget::Resize Changes the size of the render target to the specified pixel size

Public Operators
NAME DESC RIP T IO N

CHwndRenderTarget::operator ID2D1HwndRenderTarget* Returns ID2D1HwndRenderTarget interface.

Protected Data Members


NAME DESC RIP T IO N

CHwndRenderTarget::m_pHwndRenderTarget A pointer to an ID2D1HwndRenderTarget object.


Inheritance Hierarchy
CObject
CRenderTarget
CHwndRenderTarget

Requirements
Header : afxrendertarget.h

CHwndRenderTarget::Attach
Attaches existing render target interface to the object

void Attach(ID2D1HwndRenderTarget* pTarget);

Parameters
pTarget
Existing render target interface. Cannot be NULL

CHwndRenderTarget::CheckWindowState
Indicates whether the HWND associated with this render target is occluded.

D2D1_WINDOW_STATE CheckWindowState() const;

Return Value
A value that indicates whether the HWND associated with this render target is occluded.

CHwndRenderTarget::CHwndRenderTarget
Constructs a CHwndRenderTarget object from HWND.

CHwndRenderTarget(HWND hwnd = NULL);

Parameters
hwnd
The HWND associated with this render target

CHwndRenderTarget::Create
Creates a render target associated with the window

BOOL Create(HWND hWnd);

Parameters
hWnd
The HWND associated with this render target
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE

CHwndRenderTarget::Detach
Detaches render target interface from the object

ID2D1HwndRenderTarget* Detach();

Return Value
Pointer to detached render target interface.

CHwndRenderTarget::GetHwnd
Returns the HWND associated with this render target.

HWND GetHwnd() const;

Return Value
The HWND associated with this render target.

CHwndRenderTarget::GetHwndRenderTarget
Returns ID2D1HwndRenderTarget interface.

ID2D1HwndRenderTarget* GetHwndRenderTarget();

Return Value
Pointer to an ID2D1HwndRenderTarget interface or NULL if object is not initialized yet.

CHwndRenderTarget::m_pHwndRenderTarget
A pointer to an ID2D1HwndRenderTarget object.

ID2D1HwndRenderTarget* m_pHwndRenderTarget;

CHwndRenderTarget::operator ID2D1HwndRenderTarget*
Returns ID2D1HwndRenderTarget interface.

operator ID2D1HwndRenderTarget*();

Return Value
Pointer to an ID2D1HwndRenderTarget interface or NULL if object is not initialized yet.

CHwndRenderTarget::ReCreate
Re-creates a render target associated with the window
BOOL ReCreate(HWND hWnd);

Parameters
hWnd
The HWND associated with this render target
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

CHwndRenderTarget::Resize
Changes the size of the render target to the specified pixel size

BOOL Resize(const CD2DSizeU& size);

Parameters
size
The new size of the render target in device pixels
Return Value
If the method succeeds, it returns TRUE. Otherwise, it returns FALSE.

See also
Classes
CImageList Class
4/21/2020 • 23 minutes to read • Edit Online

Provides the functionality of the Windows common image list control.

Syntax
class CImageList : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CImageList::CImageList Constructs a CImageList object.

Public Methods
NAME DESC RIP T IO N

CImageList::Add Adds an image or images to an image list.

CImageList::Attach Attaches an image list to a CImageList object.

CImageList::BeginDrag Begins dragging an image.

CImageList::Copy Copies an image within a CImageList object.

CImageList::Create Initializes an image list and attaches it to a CImageList


object.

CImageList::DeleteImageList Deletes an image list.

CImageList::DeleteTempMap Called by the CWinApp idle-time handler to delete any


temporary CImageList object created by
FromHandle .

CImageList::Detach Detaches an image list object from a CImageList


object and returns a handle to an image list.

CImageList::DragEnter Locks updates during a drag operation and displays the


drag image at a specified position.

CImageList::DragLeave Unlocks the window and hides the drag image so that
the window can be updated.

CImageList::DragMove Moves the image that is being dragged during a drag-


and-drop operation.
NAME DESC RIP T IO N

CImageList::DragShowNolock Shows or hides the drag image during a drag operation,


without locking the window.

CImageList::Draw Draws the image that is being dragged during a drag-


and-drop operation.

CImageList::DrawEx Draws an image list item in the specified device context.


The function uses the specified drawing style and blends
the image with the specified color.

CImageList::DrawIndirect Draws an image from an image list.

CImageList::EndDrag Ends a drag operation.

CImageList::ExtractIcon Creates an icon based on an image and mask in an


image list.

CImageList::FromHandle Returns a pointer to a CImageList object when given a


handle to an image list. If a CImageList object is not
attached to the handle, a temporary CImageList
object is created and attached.

CImageList::FromHandlePermanent Returns a pointer to a CImageList object when given a


handle to an image list. If a CImageList object is not
attached to the handle, NULL is returned.

CImageList::GetBkColor Retrieves the current background color for an image list.

CImageList::GetDragImage Gets the temporary image list that is used for dragging.

CImageList::GetImageCount Retrieves the number of images in an image list.

CImageList::GetImageInfo Retrieves information about an image.

CImageList::GetSafeHandle Retrieves m_hImageList .

CImageList::Read Reads an image list from an archive.

CImageList::Remove Removes an image from an image list.

CImageList::Replace Replaces an image in an image list with a new image.

CImageList::SetBkColor Sets the background color for an image list.

CImageList::SetDragCursorImage Creates a new drag image.

CImageList::SetImageCount Resets the count of images in an image list.

CImageList::SetOverlayImage Adds the zero-based index of an image to the list of


images to be used as overlay masks.

CImageList::Write Writes an image list to an archive.


Public Operators
NAME DESC RIP T IO N

CImageList::operator HIMAGELIST Returns the HIMAGELIST attached to the CImageList .

Public Data Members


NAME DESC RIP T IO N

CImageList::m_hImageList A handle containing the image list attached to this


object.

Remarks
An "image list" is a collection of same-sized images, each of which can be referred to by its zero-based
index. Image lists are used to efficiently manage large sets of icons or bitmaps. All images in an image
list are contained in a single, wide bitmap in screen device format. An image list may also include a
monochrome bitmap that contains masks used to draw images transparently (icon style). The Microsoft
Win32 application programming interface (API) provides image list functions that enable you to draw
images, create and destroy image lists, add and remove images, replace images, merge images, and
drag images.
This control (and therefore the CImageList class) is available only to programs running under Windows
95/98 and Windows NT version 3.51 and later.
For more information on using CImageList , see Controls and Using CImageList.

Inheritance Hierarchy
CObject
CImageList

Requirements
Header : afxcmn.h

CImageList::Add
Call this function to add one or more images or an icon to an image list.

int Add(
CBitmap* pbmImage,
CBitmap* pbmMask);

int Add(
CBitmap* pbmImage,
COLORREF crMask);

int Add(HICON hIcon);

Parameters
pbmImage
Pointer to the bitmap containing the image or images. The number of images is inferred from the width
of the bitmap.
pbmMask
Pointer to the bitmap containing the mask. If no mask is used with the image list, this parameter is
ignored.
crMask
Color used to generate the mask. Each pixel of this color in the given bitmap is changed to black and the
corresponding bit in the mask is set to one.
hIcon
Handle of the icon that contains the bitmap and mask for the new image.
Return Value
Zero-based index of the first new image if successful; otherwise - 1.
Remarks
You are responsible for releasing the icon handle when you are done with it.
Example

// Add my icons.
m_myImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_myImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));

// Add my bitmap, make all black pixels transparent.


CBitmap bm;
bm.LoadBitmap(IDB_BITMAP1);
m_myImageList.Add(&bm, RGB(0, 0, 0));

CImageList::Attach
Call this function to attach an image list to a CImageList object.

BOOL Attach(HIMAGELIST hImageList);

Parameters
hImageList
A handle to an image list object.
Return Value
Nonzero if the attachment was successful; otherwise 0.
Example

void AddQuestion(HIMAGELIST hmyImageList)


{
CImageList imgList;

// Attach the image list handle to the CImageList object.


imgList.Attach(hmyImageList);

// Add a new icon to the image list.


imgList.Add(AfxGetApp()->LoadStandardIcon(IDI_QUESTION));

// Detach the handle from the CImageList object.


imgList.Detach();
}
CImageList::BeginDrag
Call this function to begin dragging an image.

BOOL BeginDrag(
int nImage,
CPoint ptHotSpot);

Parameters
nImage
Zero-based index of the image to drag.
ptHotSpot
Coordinates of the starting drag position (typically, the cursor position). The coordinates are relative to
the upper left corner of the image.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This function creates a temporary image list that is used for dragging. The image combines the specified
image and its mask with the current cursor. In response to subsequent WM_MOUSEMOVE messages,
you can move the drag image by using the DragMove member function. To end the drag operation, you
can use the EndDrag member function.
Example

void CImageListDlg::OnLButtonDown(UINT nFlags, CPoint point)


{
// Initialize the drag image (usually called from WM_LBUTTONDOWN).
m_myImageList.BeginDrag(0, CPoint(0, 0));
m_myImageList.DragEnter(this, point);

CDialog::OnLButtonDown(nFlags, point);
}

CImageList::CImageList
Constructs a CImageList object.

CImageList();

CImageList::Copy
This member function implements the behavior of the Win32 function ImageList_Copy, as described in
the Windows SDK.
BOOL Copy(
int iDst,
int iSrc,
UINT uFlags = ILCF_MOVE);

BOOL Copy(
int iDst,
CImageList* pSrc,
int iSrc,
UINT uFlags = ILCF_MOVE);

Parameters
iDst
The zero-based index of the image to be used as the destination of the copy operation.
iSrc
The zero-based index of the image to be used as the source of the copy operation.
uFlags
The bit flag value that specifies the type of copy operation to be made. This parameter can be one of the
following values:

VA L UE M EA N IN G

ILCF_MOVE The source image is copied to the destination image's


index. This operation results in multiple instances of a
given image. ILCF_MOVE is the default.

ILCF_SWAP The source and destination images exchange positions


within the image list.

pSrc
A pointer to a CImageList object that is the target of the copy operation.
Return Value
Nonzero if successful; otherwise zero.
Example

CImageList myImageList2;
myImageList2.Create(32, 32, ILC_COLOR8, 0, 4);

// Copy the first image from myImageList2 and make it


// the first image of m_myImageList.
m_myImageList.Copy(0, &myImageList2, 0, ILCF_MOVE);

// Recopy the image to make it also the last image in m_myImageList.


m_myImageList.Copy(m_myImageList.GetImageCount() - 1, (int)0,
(UINT)ILCF_MOVE);

CImageList::Create
Initializes an image list and attaches it to a CImageList object.
BOOL Create(
int cx,
int cy,
UINT nFlags,
int nInitial,
int nGrow);

BOOL Create(
UINT nBitmapID,
int cx,
int nGrow,
COLORREF crMask);

BOOL Create(
LPCTSTR lpszBitmapID,
int cx,
int nGrow,
COLORREF crMask);

BOOL Create(
CImageList& imagelist1,
int nImage1,
CImageList& imagelist2,
int nImage2,
int dx,
int dy);

BOOL Create(CImageList* pImageList);

Parameters
cx
Dimensions of each image, in pixels.
cy
Dimensions of each image, in pixels.
nFlags
Specifies the type of image list to create. This parameter can be a combination of the following values,
but it can include only one of the ILC_COLOR values.

VA L UE M EA N IN G

ILC_COLOR Use the default behavior if none of the other


ILC_COLOR* flags is specified. Typically, the default is
ILC_COLOR4; but for older display drivers, the default is
ILC_COLORDDB.

ILC_COLOR4 Use a 4-bit (16 color) device-independent bitmap (DIB)


section as the bitmap for the image list.

ILC_COLOR8 Use an 8-bit DIB section. The colors used for the color
table are the same colors as the halftone palette.

ILC_COLOR16 Use a 16-bit (32/64k color) DIB section.

ILC_COLOR24 Use a 24-bit DIB section.

ILC_COLOR32 Use a 32-bit DIB section.


VA L UE M EA N IN G

ILC_COLORDDB Use a device-dependent bitmap.

ILC_MASK Uses a mask. The image list contains two bitmaps, one
of which is a monochrome bitmap used as a mask. If
this value is not included, the image list contains only
one bitmap. See Drawing Images from an Image List for
additional information on masked images.

nInitial
Number of images that the image list initially contains.
nGrow
Number of images by which the image list can grow when the system needs to resize the list to make
room for new images. This parameter represents the number of new images the resized image list can
contain.
nBitmapID
Resource IDs of the bitmap to be associated with the image list.
crMask
Color used to generate a mask. Each pixel of this color in the specified bitmap is changed to black, and
the corresponding bit in the mask is set to one.
lpszBitmapID
A string containing the resource IDs of the images.
imagelist1
A reference to a CImageList object.
nImage1
Index of the first existing image.
imagelist2
A reference to a CImageList object.
nImage2
Index of the second existing image.
dx
Offset of the x-axis of the second image in relationship to the first image, in pixels.
dy
Offset of the y-axis of the second image in relationship to the first image, in pixels.
pImageList
A pointer to a CImageList object.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You construct a CImageList in two steps. First, call the constructor and then call Create , which creates
the image list and attaches it to the CImageList object.
Example
m_myImageList.Create(32, 32, ILC_COLOR8, 0, 4);

CImageList::DeleteImageList
Call this function to delete an image list.

BOOL DeleteImageList();

Return Value
Nonzero if successful; otherwise 0.
Example

// Delete the image list and verify.


myImageList2.DeleteImageList();
ASSERT(myImageList2.GetSafeHandle() == NULL);

CImageList::DeleteTempMap
Called automatically by the CWinApp idle-time handler, DeleteTempMap deletes any temporary
CImageList objects created by FromHandle, but does not destroy any handles ( hImageList )
temporarily associated with the ImageList objects.

static void PASCAL DeleteTempMap();

Example

// Note that this is a static member so an instantiated CImageList


// object is unnecessary.
CImageList::DeleteTempMap();

CImageList::Detach
Call this function to detach an image list object from a CImageList object.

HIMAGELIST Detach();

Return Value
A handle to an image list object.
Remarks
This function returns a handle to the image list object.
Example
See the example for CImageList::Attach.

CImageList::DragEnter
During a drag operation, locks updates to the window specified by pWndLock and displays the drag
image at the position specified by point.
static BOOL PASCAL DragEnter(
CWnd* pWndLock,
CPoint point);

Parameters
pWndLock
Pointer to the window that owns the drag image.
point
Position at which to display the drag image. Coordinates are relative to the upper left corner of the
window (not the client area).
Return Value
Nonzero if successful; otherwise 0.
Remarks
The coordinates are relative to the window's upper left corner, so you must compensate for the widths of
window elements, such as the border, title bar, and menu bar, when specifying the coordinates.
If pWndLock is NULL, this function draws the image in the display context associated with the desktop
window, and coordinates are relative to the upper left corner of the screen.
This function locks all other updates to the given window during the drag operation. If you need to do
any drawing during a drag operation, such as highlighting the target of a drag-and-drop operation, you
can temporarily hide the dragged image by using the CImageList::DragLeave function.
Example
See the example for CImageList::BeginDrag.

CImageList::DragLeave
Unlocks the window specified by pWndLock and hides the drag image, allowing the window to be
updated.

static BOOL PASCAL DragLeave(CWnd* pWndLock);

Parameters
pWndLock
Pointer to the window that owns the drag image.
Return Value
Nonzero if successful; otherwise 0.
Example
See the example for CImageList::EndDrag.

CImageList::DragMove
Call this function to move the image that is being dragged during a drag-and-drop operation.

static BOOL PASCAL DragMove(CPoint pt);

Parameters
pt
New drag position.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This function is typically called in response to a WM_MOUSEMOVE message. To begin a drag operation,
use the BeginDrag member function.
Example

void CImageListDlg::OnMouseMove(UINT nFlags, CPoint point)


{
m_myImageList.DragMove(point);

CDialog::OnMouseMove(nFlags, point);
}

CImageList::DragShowNolock
Shows or hides the drag image during a drag operation, without locking the window.

static BOOL PASCAL DragShowNolock(BOOL bShow);

Parameters
bShow
Specifies whether the drag image is to be shown.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The CImageList::DragEnter function locks all updates to the window during a drag operation. This
function, however, does not lock the window.

CImageList::Draw
Call this function to draw the image that is being dragged during a drag-and-drop operation.

BOOL Draw(
CDC* pDC,
int nImage,
POINT pt,
UINT nStyle);

Parameters
pDC
Pointer to the destination device context.
nImage
Zero-based index of the image to draw.
pt
Location at which to draw within the specified device context.
nStyle
Flag specifying the drawing style. It can be one or more of these values:

VA L UE M EA N IN G

ILD_BLEND25, ILD_FOCUS Draws the image, blending 25 percent with the system
highlight color. This value has no effect if the image list
does not contain a mask.

ILD_BLEND50, ILD_SELECTED, ILD_BLEND Draws the image, blending 50 percent with the system
highlight color. This value has no effect if the image list
does not contain a mask.

ILD_MASK Draws the mask.

ILD_NORMAL Draws the image using the background color for the
image list. If the background color is the CLR_NONE
value, the image is drawn transparently using the mask.

ILD_TRANSPARENT Draws the image transparently using the mask,


regardless of the background color.

Return Value
Nonzero if successful; otherwise 0.
Example
See the example for CImageList::SetOverlayImage.

CImageList::DrawEx
Draws an image list item in the specified device context.

BOOL DrawEx(
CDC* pDC,
int nImage,
POINT pt,
SIZE sz,
COLORREF clrBk,
COLORREF clrFg,
UINT nStyle);

Parameters
pDC
Pointer to the destination device context.
nImage
Zero-based index of the image to draw.
pt
Location at which to draw within the specified device context.
sz
Size of the portion of the image to draw relative to the upper-left corner of the image. See dx and dy in
ImageList_DrawEx in the Windows SDK.
clrBk
Background color of the image. See rgbBk in ImageList_DrawEx in the Windows SDK.
clrFg
Foreground color of the image. See rgbFg in ImageList_DrawEx in the Windows SDK.
nStyle
Flag specifying the drawing style. See fStyle in ImageList_DrawEx in the Windows SDK.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The function uses the specified drawing style and blends the image with the specified color.
Example

m_myImageList.DrawEx(&dc, 0, CPoint(0, 0), CSize(16, 16), CLR_DEFAULT,


CLR_DEFAULT, ILD_IMAGE);

CImageList::DrawIndirect
Call this member function to draw an image from an image list.

BOOL DrawIndirect(IMAGELISTDRAWPARAMS* pimldp);

BOOL DrawIndirect(
CDC* pDC,
int nImage,
POINT pt,
SIZE sz,
POINT ptOrigin,
UINT fStyle = ILD_NORMAL,
DWORD dwRop = SRCCOPY,
COLORREF rgbBack = CLR_DEFAULT,
COLORREF rgbFore = CLR_DEFAULT,
DWORD fState = ILS_NORMAL,
DWORD Frame = 0,
COLORREF crEffect = CLR_DEFAULT);

Parameters
pimldp
A pointer to an IMAGELISTDRAWPARAMS structure that contains information about the draw operation.
pDC
A pointer to the destination device context. You must delete this CDC object when you are done with it.
nImage
The zero-based index of the image to be drawn.
pt
A POINT structure containing the x- and y- coordinates where the image will be drawn.
sz
A SIZE structure indicating the size of the image to be drawn.
ptOrigin
A POINT structure containing the x- and y-coordinates specifying the upper left corner of the drawing
operation with respect to the image itself. Pixels of the image that are to the left of the x-coordinate and
above the y-coordinate are not drawn.
fStyle
Flag specifying the drawing style and, optionally, the overlay image. See the Remarks section for
information on the overlay image. The MFC default implementation, ILD_NORMAL, draws the image
using the background color for the image list. If the background color is the CLR_NONE value, the image
is drawn transparently using a mask.
Other possible styles are described under the fStyle member of the IMAGELISTDRAWPARAMS structure.
dwRop
Value specifying a raster-operation code. These codes define how the color data for the source rectangle
will be combined with the color data for the destination rectangle to achieve the final color. MFC's
default implementation, SRCCOPY, copies the source rectangle directly to the destination rectangle. This
parameter is ignored if the fStyle parameter does not include the ILD_ROP flag.
Other possible values are described under the dwRop member of the IMAGELISTDRAWPARAMS
structure.
rgbBack
The image background color, by default CLR_DEFAULT. This parameter can be an application-defined
RGB value or one of the following values:

VA L UE M EA N IN G

CLR_DEFAULT Default background color. The image is drawn using the


image list background color.

CLR_NONE No background color. The image is drawn transparently.

rgbFore
Image foreground color, by default CLR_DEFAULT. This parameter can be an application-defined RGB
value or one of the following values:

VA L UE M EA N IN G

CLR_DEFAULT Default foreground color. The image is drawn using the


system highlight color as the foreground color.

CLR_NONE No blend color. The image is blended with the color of


the destination device context.

This parameter is used only if fStyle includes the ILD_BLEND25 or ILD_BLEND50 flag.
fState
Flag specifying the drawing state. This member can contain one or more image list state flags.
Frame
Affects the behavior of saturate and alpha-blending effects.
When used with ILS_SATURATE, this member holds the value that is added to each color component of
the RGB triplet for each pixel in the icon.
When used with ILS_APLHA, this member holds the value for the alpha channel. This value can be from
0 to 255, with 0 being completely transparent, and 255 being completely opaque.
crEffect
A COLORREF value used for glow and shadow effects.
Return Value
TRUE if the image is successfully drawn; otherwise FALSE.
Remarks
Use the first version if you want to fill the Win32 structure yourself. Use the second version if you want
to take advantage of one or more of MFC's default arguments, or avoid managing the structure.
An overlay image is an image that is drawn on top of the primary image, specified in this member
function by the nImage parameter. Draw an overlay mask by using the Draw member function with the
one-based index of the overlay mask specified by using the INDEXTOOVERLAYMASK macro.
Example

int i, dx, cx, cy, nCount = m_myImageList.GetImageCount();

::ImageList_GetIconSize(m_myImageList, &cx, &cy);

// Draw the images of the image list on the DC.


for (dx = 0, i = 0; i < nCount; i++)
{
m_myImageList.DrawIndirect(&dc, i, CPoint(dx, 0),
CSize(cx, cy), CPoint(0, 0));
dx += cx;
}

CImageList::EndDrag
Call this function to end a drag operation.

static void PASCAL EndDrag();

Remarks
To begin a drag operation, use the BeginDrag member function.
Example

void CImageListDlg::OnLButtonUp(UINT nFlags, CPoint point)


{
// Terminate the drag image (usually called from WM_LBUTTONUP).
m_myImageList.DragLeave(this);
m_myImageList.EndDrag();

CDialog::OnLButtonUp(nFlags, point);
}

CImageList::ExtractIcon
Call this function to create an icon based on an image and its related mask in an image list.

HICON ExtractIcon(int nImage);

Parameters
nImage
Zero-based index of the image.
Return Value
Handle of the icon if successful; otherwise NULL.
Remarks
This method relies on the behavior of the ImageList_ExtractIcon macro to create the icon. Refer to the
ImageList_ExtractIcon macro for more information on icon creation and cleanup.
Example

int i, dx, cx, cy, nCount = m_myImageList.GetImageCount();


HICON hIcon;

::ImageList_GetIconSize(m_myImageList, &cx, &cy);

// Draw the images of the image list on the DC.


for (dx = 0, i = 0; i < nCount; i++)
{
hIcon = m_myImageList.ExtractIcon(i);

dc.DrawIcon(dx, 0, hIcon);
dx += cx;
}

CImageList::FromHandle
Returns a pointer to a CImageList object when given a handle to an image list.

static CImageList* PASCAL FromHandle(HIMAGELIST hImageList);

Parameters
hImageList
Specifies the image list.
Return Value
A pointer to a CImageList object if successful; otherwise NULL.
Remarks
If a CImageList is not already attached to the handle, a temporary CImageList object is created and
attached. This temporary CImageList object is valid only until the next time the application has idle time
in its event loop, at which time all temporary objects are deleted.
Example

CImageList *ConvertHandle(HIMAGELIST hmyImageList)


{
// Convert the HIMAGELIST to a CImageList*.
ASSERT(hmyImageList != NULL);
CImageList *pmyImageList = CImageList::FromHandle(hmyImageList);
ASSERT(pmyImageList != NULL);

return pmyImageList;
}

CImageList::FromHandlePermanent
Returns a pointer to a CImageList object when given a handle to an image list.
static CImageList* PASCAL FromHandlePermanent(HIMAGELIST hImageList);

Parameters
hImageList
Specifies the image list.
Return Value
A pointer to a CImageList object if successful; otherwise NULL.
Remarks
If a CImageList object is not attached to the handle, NULL is returned.
Example

CImageList *ConvertHandlePermanent(HIMAGELIST hmyImageList)


{
// Convert the HIMAGELIST to a CImageList*.
ASSERT(hmyImageList != NULL);
CImageList *pmyImageList = CImageList::FromHandlePermanent(hmyImageList);
ASSERT(pmyImageList != NULL);

return pmyImageList;
}

CImageList::GetBkColor
Call this function to retrieve the current background color for an image list.

COLORREF GetBkColor() const;

Return Value
The RGB color value of the CImageList object background color.
Example
See the example for CImageList::SetBkColor.

CImageList::GetDragImage
Gets the temporary image list that is used for dragging.

static CImageList* PASCAL GetDragImage(


LPPOINT lpPoint,
LPPOINT lpPointHotSpot);

Parameters
lpPoint
Address of a POINT structure that receives the current drag position.
lpPointHotSpot
Address of a POINT structure that receives the offset of the drag image relative to the drag position.
Return Value
If successful, a pointer to the temporary image list that is used for dragging; otherwise, NULL.
CImageList::GetImageCount
Call this function to retrieve the number of images in an image list.

int GetImageCount() const;

Return Value
The number of images.
Example
See the example for CImageList::ExtractIcon.

CImageList::GetImageInfo
Call this function to retrieve information about an image.

BOOL GetImageInfo(
int nImage,
IMAGEINFO* pImageInfo) const;

Parameters
nImage
Zero-based index of the image.
pImageInfo
Pointer to an IMAGEINFO structure that receives information about the image. The information in this
structure can be used to directly manipulate the bitmaps for the image.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The IMAGEINFO structure contains information about an image in an image list.

CImageList::GetSafeHandle
Call this function to retrieve the m_hImageList data member.

HIMAGELIST GetSafeHandle() const;

Return Value
A handle to the attached image list; otherwise NULL if no object is attached.
Example

// Get the safe handle to the image list.


HIMAGELIST hImageList = m_myImageList.GetSafeHandle();

CImageList::m_hImageList
A handle of the image list attached to this object.
HIMAGELIST m_hImageList;

Remarks
The m_hImageList data member is a public variable of type HIMAGELIST.
Example

// Get the safe handle to the image list.


HIMAGELIST hImageList = m_myImageList.m_hImageList;

CImageList::operator HIMAGELIST
Use this operator to get the attached handle of the CImageList object.

operator HIMAGELIST() const;

Return Value
If successful, a handle to the image list represented by the CImageList object; otherwise NULL.
Remarks
This operator is a casting operator, which supports direct use of an HIMAGELIST object.
Example

// Get the safe handle to the image list.


HIMAGELIST hImageList = m_myImageList;

CImageList::Read
Call this function to read an image list from an archive.

BOOL Read(CArchive* pArchive);

Parameters
pArchive
A pointer to a CArchive object from which the image list is to be read.
Return Value
Nonzero if successful; otherwise 0.
Example

// Open the archive to load the image list from.


CFile myFile(_T("myfile.data"), CFile::modeRead);
CArchive ar(&myFile, CArchive::load);
CImageList myImgList;

// Load the image list from the archive.


myImgList.Read(&ar);

CImageList::Remove
Call this function to remove an image from an image list object.
BOOL Remove(int nImage);

Parameters
nImage
Zero-based index of the image to remove.
Return Value
Nonzero if successful; otherwise 0.
Remarks
All items following nImage now move down one position. For example, if an image list contains two
items, deleting the first item will cause the remaining item to now be in the first position. nImage=0 for
the item in the first position.
Example

// Remove every other image from the image list.


for (int i = 0; i < m_myImageList.GetImageCount(); i++)
{
m_myImageList.Remove(i);
}

CImageList::Replace
Call this function to replace an image in an image list with a new image.

BOOL Replace(
int nImage,
CBitmap* pbmImage,
CBitmap* pbmMask);

int Replace(
int nImage,
HICON hIcon);

Parameters
nImage
Zero-based index of the image to replace.
pbmImage
A pointer to the bitmap containing the image.
pbmMask
A pointer to the bitmap containing the mask. If no mask is used with the image list, this parameter is
ignored.
hIcon
A handle to the icon that contains the bitmap and mask for the new image.
Return Value
The version returning BOOL returns nonzero if successful; otherwise 0.
The version returning int returns the zero-based index of the image if successful; otherwise - 1.
Remarks
Call this member function after calling SetImageCount to assign the new, valid images to the
placeholder image index numbers.
Example
See the example for CImageList::SetImageCount.

CImageList::SetBkColor
Call this function to set the background color for an image list.

COLORREF SetBkColor(COLORREF cr);

Parameters
cr
Background color to set. It can be CLR_NONE. In that case, images are drawn transparently using the
mask.
Return Value
The previous background color if successful; otherwise CLR_NONE.
Example

// Set the background color to white.


m_myImageList.SetBkColor(RGB(255, 255, 255));
ASSERT(m_myImageList.GetBkColor() == RGB(255, 255, 255));

CImageList::SetDragCursorImage
Creates a new drag image by combining the given image (typically a mouse cursor image) with the
current drag image.

BOOL SetDragCursorImage(
int nDrag,
CPoint ptHotSpot);

Parameters
nDrag
Index of the new image to be combined with the drag image.
ptHotSpot
Position of the hot spot within the new image.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Because the dragging functions use the new image during a drag operation, you should use the
Windows ShowCursor function to hide the actual mouse cursor after calling
CImageList::SetDragCursorImage . Otherwise, the system may appear to have two mouse cursors for the
duration of the drag operation.

CImageList::SetImageCount
Call this member function to reset the number of images in a CImageList object.

BOOL SetImageCount(UINT uNewCount);

Parameters
uNewCount
The value specifying the new total number of images in the image list.
Return Value
Nonzero if successful; otherwise zero.
Remarks
If you call this member function to increase the number of images in the image list, then call Replace for
each additional image to assign the new indexes to valid images. If you fail to assign the indexes to valid
images, draw operations that create the new images will be unpredictable.
If you decrease the size of an image list by using this function, the truncated images are freed.
Example

// Set the image count of the image list to be 10 with


// all images being the system question mark icon.
m_myImageList.SetImageCount(10);
HICON hIcon = AfxGetApp()->LoadStandardIcon(IDI_QUESTION);

for (int i = 0; i < 10; i++)


{
m_myImageList.Replace(i, hIcon);
}

CImageList::SetOverlayImage
Call this function to add the zero-based index of an image to the list of images to be used as overlay
masks.

BOOL SetOverlayImage(
int nImage,
int nOverlay);

Parameters
nImage
Zero-based index of the image to use as an overlay mask.
nOverlay
One-based index of the overlay mask.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Up to four indices can be added to the list.
An overlay mask is an image drawn transparently over another image. Draw an overlay mask over an
image by using the CImageList::Draw member function with the one-based index of the overlay mask
specified by using the INDEXTOOVERLAYMASK macro.
Example

// Add a new image to the image list.


int nIndex = m_myImageList.Add(AfxGetApp()->LoadStandardIcon(IDI_QUESTION));

if (nIndex != -1)
{
// Make the new image an overlay image.
m_myImageList.SetOverlayImage(nIndex, 1);

// Draw the first image in the image list with an overlay image.
m_myImageList.Draw(&dc, 0, CPoint(0, 0), INDEXTOOVERLAYMASK(1));
}

CImageList::Write
Call this function to write an image list object to an archive.

BOOL Write(CArchive* pArchive);

Parameters
pArchive
A pointer to a CArchive object in which the image list is to be stored.
Return Value
Nonzero if successful; otherwise 0.
Example

// Open the archive to store the image list in.


CFile myFile(_T("myfile.data"), CFile::modeCreate | CFile::modeWrite);
CArchive ar(&myFile, CArchive::store);

// Store the image list in the archive.


m_myImageList.Write(&ar);

See also
CObject Class
Hierarchy Chart
CListCtrl Class
CTabCtrl Class
CInstantaneousTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates an instantaneous transition.

Syntax
class CInstantaneousTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CInstantaneousTransition::CInstantaneousTransition Constructs a transition object and initializes its final value.

Public Methods
NAME DESC RIP T IO N

CInstantaneousTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CInstantaneousTransition::m_dblFinalValue The value of the animation variable at the end of the


transition.

Remarks
During an instantaneous transition, the value of the animation variable changes instantly from its current value to a
specified final value. The duration of this transition is always zero. Because all transitions are cleared automatically,
it's recommended to allocated them using operator new. The encapsulated IUIAnimationTransition COM object is
created by CAnimationController::AnimateGroup, until then it's NULL. Changing member variables after creation of
this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CInstantaneousTransition

Requirements
Header : afxanimationcontroller.h
CInstantaneousTransition::CInstantaneousTransition
Constructs a transition object and initializes its final value.

CInstantaneousTransition(DOUBLE dblFinalValue);

Parameters
dblFinalValue
The value of the animation variable at the end of the transition.

CInstantaneousTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CInstantaneousTransition::m_dblFinalValue
The value of the animation variable at the end of the transition.

DOUBLE m_dblFinalValue;

See also
Classes
CInternetConnection Class
3/27/2020 • 2 minutes to read • Edit Online

Manages your connection to an Internet server.

Syntax
class CInternetConnection : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CInternetConnection::CInternetConnection Constructs a CInternetConnection object.

Public Methods
NAME DESC RIP T IO N

CInternetConnection::GetContext Gets the context ID for this connection object.

CInternetConnection::GetServerName Gets the name of the server associated with the connection.

CInternetConnection::GetSession Gets a pointer to the CInternetSession object associated


with the connection.

Public Operators
NAME DESC RIP T IO N

CInternetConnection::operator HINTERNET A handle to an Internet session.

Remarks
It is the base class for MFC classes CFtpConnection, CHttpConnection, and CGopherConnection. Each of these
classes provides additional functionality for communicating with the respective FTP, HTTP, or gopher server.
To communicate directly with an Internet server, you must have a CInternetSession object and a
CInternetConnection object.

To learn more about how the WinInet classes work, see the article Internet Programming with WinInet.

Inheritance Hierarchy
CObject
CInternetConnection
Requirements
Header : afxinet.h

CInternetConnection::CInternetConnection
This member function is called when a CInternetConnection object is created.

CInternetConnection(
CInternetSession* pSession,
LPCTSTR pstrServer,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
DWORD_PTR dwContext = 1);

Parameters
pSession
A pointer to a CInternetSession object.
pstrServer
A pointer to a string containing the server name.
nPort
The number that identifies the Internet port for this connection.
dwContext
The context identifier for the CInternetConnection object. See Remarks for more information about
dwContext.
Remarks
You never call CInternetConnection yourself; instead, call the CInternetSession member function for the type of
connection you want to establish:
CInternetSession::GetFtpConnection
CInternetSession::GetHttpConnection
CInternetSession::GetGopherConnection
The default value for dwContext is sent by MFC to the CInternetConnection -derived object from the
CInternetSession object that created the InternetConnection -derived object. The default is set to 1; however,
you can explicitly assign a specific context identifier in the CInternetSession constructor for the connection. The
object and any work it does will be associated with that context ID. The context identifier is returned to
CInternetSession::OnStatusCallback to provide status on the object with which it is identified. See the article
Internet First Steps: WinInet for more information about the context identifier.

CInternetConnection::GetContext
Call this member function to get the context ID for this session.

DWORD_PTR GetContext() const;

Return Value
The application-assigned context ID.
Remarks
The context ID is originally specified in CInternetSession and propagates to CInternetConnection - and
CInternetFile-derived classes, unless specified differently in the call to a function that opens the connection. The
context ID is associated with any operation of the given object and identifies the operation's status information
returned by CInternetSession::OnStatusCallback.
For more information about how GetContext works with other WinInet classes to give the user status
information, see the article Internet First Steps: WinInet for more information about the context identifier.

CInternetConnection::GetServerName
Call this member function to get the name of the server associated with this Internet connection.

CString GetServerName() const;

Return Value
The name of the server this connection object is working with.

CInternetConnection::GetSession
Call this member function to get a pointer to the CInternetSession object that's associated with this
connection.

CInternetSession* GetSession() const;

Return Value
A pointer to a CInternetSession object associated with this Internet connection object.

CInternetConnection::operator HINTERNET
Use this operator to get the API-level handle for the current Internet session.

operator HINTERNET() const;

See also
CObject Class
Hierarchy Chart
CInternetException Class
3/27/2020 • 2 minutes to read • Edit Online

Represents an exception condition related to an Internet operation.

Syntax
class CInternetException : public CException

Members
Public Constructors
NAME DESC RIP T IO N

CInternetException::CInternetException Constructs a CInternetException object.

Public Data Members


NAME DESC RIP T IO N

CInternetException::m_dwContext The context value associated with the operation that caused
the exception.

CInternetException::m_dwError The error that caused the exception.

Remarks
The CInternetException class includes two public data members: one holds the error code associated with the
exception, and the other holds the context identifier of the Internet application associated with the error.
For more information about context identifiers for Internet applications, see the article Internet Programming
with WinInet.

Inheritance Hierarchy
CObject
CException
CInternetException

Requirements
Header : afxinet.h

CInternetException::CInternetException
This member function is called when a CInternetException object is created.
CInternetException(DWORD dwError);

Parameters
dwError
The error that caused the exception.
Remarks
To throw a CInternetException, call the MFC global function AfxThrowInternetException.

CInternetException::m_dwContext
The context value associated with the related Internet operation.

DWORD_PTR m_dwContext;

Remarks
The context identifier is originally specified in CInternetSession and passed by MFC to CInternetConnection-
and CInternetFile-derived classes. You can override this default and assign any dwContext parameter a value of
your choosing. dwContext is associated with any operation of the given object. dwContext identifies the
operation's status information returned by CInternetSession::OnStatusCallback.

CInternetException::m_dwError
The error that caused the exception.

DWORD m_dwError;

Remarks
This error value may be a system error code, found in WINERROR.H, or an error value from WININET.H.
For a list of Win32 error codes, see Error Codes. For a list of Internet-specific error messages, see . Both topics
are in the Windows SDK.

See also
CException Class
Hierarchy Chart
CException Class
CInternetFile Class
3/27/2020 • 8 minutes to read • Edit Online

Allows access to files on remote systems that use Internet protocols.

Syntax
class CInternetFile : public CStdioFile

Members
Protected Constructors
NAME DESC RIP T IO N

CInternetFile::CInternetFile Constructs a CInternetFile object.

Public Methods
NAME DESC RIP T IO N

CInternetFile::Abort Closes the file, ignoring all warnings and errors.

CInternetFile::Close Closes a CInternetFile and frees its resources.

CInternetFile::Flush Flushes the contents of the write buffer and makes sure the
data in memory is written to the target machine.

CInternetFile::GetLength Returns the size of the file.

CInternetFile::Read Reads the number of specified bytes.

CInternetFile::ReadString Reads a stream of characters.

CInternetFile::Seek Repositions the pointer in an open file.

CInternetFile::SetReadBufferSize Sets the size of the buffer where data will be read.

CInternetFile::SetWriteBufferSize Sets the size of the buffer where data will be written.

CInternetFile::Write Writes the number of specified bytes.

CInternetFile::WriteString Writes a null-terminated string to a file.

Public Operators
NAME DESC RIP T IO N

CInternetFile::operator HINTERNET A casting operator for an Internet handle.

Protected Data Members


NAME DESC RIP T IO N

CInternetFile::m_hFile A handle to a file.

Remarks
Provides a base class for the CHttpFile and CGopherFile file classes. You never create a CInternetFile object
directly. Instead, create an object of one of its derived classes by calling CGopherConnection::OpenFile or
CHttpConnection::OpenRequest. You also can create a CInternetFile object by calling
CFtpConnection::OpenFile.
The CInternetFile member functions Open , LockRange , UnlockRange , and Duplicate are not implemented
for CInternetFile . If you call these functions on a CInternetFile object, you will get a
CNotSupportedException.
To learn more about how CInternetFile works with the other MFC Internet classes, see the article Internet
Programming with WinInet.

Inheritance Hierarchy
CObject
CFile
CStdioFile
CInternetFile

Requirements
Header : afxinet.h

CInternetFile::Abort
Closes the file associated with this object and makes the file unavailable for reading or writing.

virtual void Abort();

Remarks
If you have not closed the file before destroying the object, the destructor closes it for you.
When handling exceptions, Abort differs from Close in two important ways. First, the Abort function does
not throw an exception on failures because it ignores failures. Second, Abort does not ASSERT if the file has
not been opened or was closed previously.

CInternetFile::CInternetFile
This member function is called when a CInternetFile object is created.
CInternetFile(
HINTERNET hFile,
LPCTSTR pstrFileName,
CInternetConnection* pConnection,
BOOL bReadMode);

CInternetFile(
HINTERNET hFile,
HINTERNET hSession,
LPCTSTR pstrFileName,
LPCTSTR pstrServer,
DWORD_PTR dwContext,
BOOL bReadMode);

Parameters
hFile
A handle to an Internet file.
pstrFileName
A pointer to a string containing the file name.
pConnection
A pointer to a CInternetConnection object.
bReadMode
Indicates whether the file is read-only.
hSession
A handle to an Internet session.
pstrServer
A pointer to a string containing the name of the server.
dwContext
The context identifier for the CInternetFile object. See WinInet Basics for more information about the
context identifier.
Remarks
You never create a CInternetFile object directly. Instead, create an object of one of its derived classes by
calling CGopherConnection::OpenFile or CHttpConnection::OpenRequest. You also can create a CInternetFile
object by calling CFtpConnection::OpenFile.

CInternetFile::Close
Closes a CInternetFile and frees any of its resources.

virtual void Close();

Remarks
If the file was opened for writing, there is an implicit call to Flush to assure that all buffered data is written to
the host. You should call Close when you are finished using a file.

CInternetFile::Flush
Call this member function to flush the contents of the write buffer.
virtual void Flush();

Remarks
Use Flush to assure that all data in memory has actually been written to the target machine and to assure
your transaction with the host machine has been completed. Flush is only effective on CInternetFile
objects opened for writing.

CInternetFile::GetLength
Returns the size of the file.

virtual ULONGLONG GetLength() const;

CInternetFile::m_hFile
A handle to the file associated with this object.

HINTERNET m_hFile;

CInternetFile::operator HINTERNET
Use this operator to get the Windows handle for the current Internet session.

operator HINTERNET() const;

CInternetFile::Read
Call this member function to read into the given memory, starting at lpvBuf, the specified number of bytes,
nCount.

virtual UINT Read(


void* lpBuf,
UINT nCount);

Parameters
lpBuf
A pointer to a memory address to which file data is read.
nCount
The number of bytes to be written.
Return Value
The number of bytes transferred to the buffer. The return value may be less than nCount if the end of file was
reached.
Remarks
The function returns the number of bytes actually read — a number that may be less than nCount if the file
ends. If an error occurs while reading the file, the function throws a CInternetException object that describes
the error. Note that reading past the end of the file is not considered an error and no exception will be thrown.
To ensure all data is retrieved, an application must continue to call the CInternetFile::Read method until the
method returns zero.

CInternetFile::ReadString
Call this member function to read a stream of characters until it finds a newline character.

virtual BOOL ReadString(CString& rString);

virtual LPTSTR ReadString(


LPTSTR pstr,
UINT nMax);

Parameters
pstr
A pointer to a string which will receive the line being read.
nMax
The maximum number of characters to be read.
rString
A reference to the CString object that receives the read line.
Return Value
A pointer to the buffer containing plain data retrieved from the CInternetFile object. Regardless of the data
type of the buffer passed to this method, it does not perform any manipulations on the data (for example,
conversion to Unicode), so you must map the returned data to the structure you expect, as if the void * type
were returned.
NULL if end-of-file was reached without reading any data; or, if boolean, FALSE if end-of-file was reached
without reading any data.
Remarks
The function places the resulting line into the memory referenced by the pstr parameter. It stops reading
characters when it reaches the maximum number of characters, specified by nMax. The buffer always receives
a terminating null character.
If you call ReadString without first calling SetReadBufferSize, you will get a buffer of 4096 bytes.

CInternetFile::Seek
Call this member function to reposition the pointer in a previously opened file.

virtual ULONGLONG Seek(


LONGLONG lOffset,
UINT nFrom);

Parameters
lOffset
Offset in bytes to move the read/write pointer in the file.
nFrom
Relative reference for the offset. Must be one of the following values:
CFile::begin Move the file pointer lOff bytes forward from the beginning of the file.
CFile::current Move the file pointer lOff bytes from the current position in the file.
CFile::end Move the file pointer lOff bytes from the end of the file. lOff must be negative to seek into
the existing file; positive values will seek past the end of the file.
Return Value
The new byte offset from the beginning of the file if the requested position is legal; otherwise, the value is
undefined and a CInternetException object is thrown.
Remarks
The Seek function permits random access to a file's contents by moving the pointer a specified amount,
absolutely or relatively. No data is actually read during the seek.
At this time, a call to this member function is only supported for data associated with CHttpFile objects. It is
not supported for FTP or gopher requests. If you call Seek for one of these unsupported services, it will pass
back you to the Win32 error code ERROR_INTERNET_INVALID_OPERATION.
When a file is opened, the file pointer is at offset 0, the beginning of the file.

NOTE
Using Seek may cause an implicit call to Flush.

Example
See the example for the base class implementation ( CFile::Seek).

CInternetFile::SetReadBufferSize
Call this member function to set the size of the temporary read buffer used by a CInternetFile -derived
object.

BOOL SetReadBufferSize(UINT nReadSize);

Parameters
nReadSize
The desired buffer size in bytes.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to
determine the cause of the error.
Remarks
The underlying WinInet APIs do not perform buffering, so choose a buffer size that allows your application to
read data efficiently, regardless of the amount of data to be read. If each call to Read normally involves a large
aount of data (for example, four or more kilobytes), you should not need a buffer. However, if you call Read to
get small chunks of data, or if you use ReadString to read individual lines at a time, then a read buffer
improves application performance.
By default, a CInternetFile object does not provide any buffering for reading. If you call this member
function, you must be sure that the file has been opened for read access.
You can increase the buffer size at any time, but shrinking the buffer will have no effect. If you call ReadString
without first calling SetReadBufferSize , you will get a buffer of 4096 bytes.
CInternetFile::SetWriteBufferSize
Call this member function to set the size of the temporary write buffer used by a CInternetFile -derived
object.

BOOL SetWriteBufferSize(UINT nWriteSize);

Parameters
nWriteSize
The size of the buffer in bytes.
Return Value
Nonzero if successful; otherwise 0. If the call fails, the Win32 function GetLastError may be called to
determine the cause of the error.
Remarks
The underlying WinInet APIs don't perform buffering, so choose a buffer size that allows your application to
write data efficiently regardless of the amount of data to be written. If each call to Write normally involves a
large amount of data (for example, four or more kilobytes at a time), you should not need a buffer. However, if
you call Write to write small chunks of data, a write buffer improves your application's performance.
By default, a CInternetFile object does not provide any buffering for writing. If you call this member
function, you must be sure that the file has been opened for write access. You can change the size of the write
buffer at any time, but doing so causes an implicit call to Flush.

CInternetFile::Write
Call this member function to write into the given memory, lpvBuf, the specified number of bytes, nCount.

virtual void Write(


const void* lpBuf,
UINT nCount);

Parameters
lpBuf
A pointer to the first byte to be written.
nCount
Specifies the number of bytes to be written.
Remarks
If any error occurs while writing the data, the function throws a CInternetException object describing the error.

CInternetFile::WriteString
This function writes a null-terminated string to the associated file.

virtual void WriteString(LPCTSTR pstr);

Parameters
pstr
A pointer to a string containing the contents to be written.
Remarks
If any error occurs while writing the data, the function throws a CInternetException object describing the error.

See also
CStdioFile Class
Hierarchy Chart
CInternetConnection Class
CInternetSession Class
4/2/2020 • 16 minutes to read • Edit Online

Creates and initializes a single or several simultaneous Internet sessions and, if necessary, describes
your connection to a proxy server.

Syntax
class CInternetSession : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CInternetSession::CInternetSession Constructs a CInternetSession object.

Public Methods
NAME DESC RIP T IO N

CInternetSession::Close Closes the Internet connection when the Internet


session is terminated.

CInternetSession::EnableStatusCallback Establishes a status callback routine.

CInternetSession::GetContext Closes the Internet connection when the Internet


session is terminated.

CInternetSession::GetCookie Returns cookies for the specified URL and all its parent
URLs.

CInternetSession::GetCookieLength Retrieves the variable specifying the length of the


cookie stored in the buffer.

CInternetSession::GetFtpConnection Opens an FTP session with a server. Logs on the user.

CInternetSession::GetGopherConnection Opens a gopher server for an application that is trying


to open a connection.

CInternetSession::GetHttpConnection Opens an HTTP server for an application that is trying


to open a connection.

CInternetSession::OnStatusCallback Updates the status of an operation when status


callback is enabled.

CInternetSession::OpenURL Parses and opens a URL.


NAME DESC RIP T IO N

CInternetSession::SetCookie Sets a cookie for the specified URL.

CInternetSession::SetOption Sets options for the Internet session.

Public Operators
NAME DESC RIP T IO N

CInternetSession::operator HINTERNET A handle to the current Internet session.

Remarks
If your Internet connection must be maintained for the duration of an application, you can create a
CInternetSession member of the class CWinApp.

Once you have established an Internet session, you can call OpenURL. CInternetSession then parses
the URL for you by calling the global function AfxParseURL. Regardless of its protocol type,
CInternetSession interprets the URL and manages it for you. It can handle requests for local files
identified with the URL resource "file://". OpenURL will return a pointer to a CStdioFile object if the
name you pass it is a local file.
If you open a URL on an Internet server using OpenURL , you can read information from the site. If you
want to perform service-specific (for example, HTTP, FTP, or gopher) actions on files located on a
server, you must establish the appropriate connection with that server. To open a particular kind of
connection directly to a particular service, use one of the following member functions:
GetGopherConnection to open a connection to a gopher service.
GetHttpConnection to open a connection to an HTTP service.
GetFtpConnection to open a connection to an FTP service.
SetOption allows you to set the query options of your session, such as time-out values, number of
retries, and so on.
CInternetSession member functions SetCookie, GetCookie, and GetCookieLength provide the means
to manage a Win32 cookie database, through which servers and scripts maintain state information
about the client workstation.
For more information about basic Internet programming tasks, see the article Internet First Steps:
WinInet. For general information about using the MFC WinInet classes, see the article Internet
Programming with WinInet.

NOTE
CInternetSession will throw an AfxThrowNotSupportedException for unsupported service types. Only the
following service types are currently supported: FTP, HTTP, gopher, and file.

Inheritance Hierarchy
CObject
CInternetSession
Requirements
Header : afxinet.h

CInternetSession::CInternetSession
This member function is called when a CInternetSession object is created.

CInternetSession(
LPCTSTR pstrAgent = NULL,
DWORD_PTR dwContext = 1,
DWORD dwAccessType = PRE_CONFIG_INTERNET_ACCESS,
LPCTSTR pstrProxyName = NULL,
LPCTSTR pstrProxyBypass = NULL,
DWORD dwFlags = 0);

Parameters
pstrAgent
A pointer to a string that identifies the name of the application or entity calling the Internet functions
(for example, "Microsoft Internet Browser"). If pstrAgent is NULL (the default), the framework calls the
global function AfxGetAppName, which returns a null-terminated string containing an application's
name. Some protocols use this string to identify your application to the server.
dwContext
The context identifier for the operation. dwContext identifies the operation's status information
returned by CInternetSession::OnStatusCallback. The default is set to 1; however, you can explicitly
assign a specific context ID for the operation. The object and any work it does will be associated with
that context ID.
dwAccessType
The type of access required. The following are valid values, exactly one of which may be supplied:
INTERNET_OPEN_TYPE_PRECONFIG Connect using preconfigured settings in the registry. This
access type is set as the default. To connect through a TIS proxy, set dwAccessType to this value;
you then set the registry appropriately.
INTERNET_OPEN_TYPE_DIRECT Connect directly to Internet.
INTERNET_OPEN_TYPE_PROXY Connect through a CERN proxy.
For information on connecting with different types of proxies, see Steps in a Typical FTP Client
Application.
pstrProxyName
The name of the preferred CERN proxy if dwAccessType is set as INTERNET_OPEN_TYPE_PROXY. The
default is NULL.
pstrProxyBypass
A pointer to a string containing an optional list of server addresses. These addresses may be bypassed
when using proxy access. If a NULL value is supplied, the bypass list will be read from the registry.
This parameter is meaningful only if dwAccessType is set to INTERNET_OPEN_TYPE_PROXY.
dwFlags
Indicates various caching options. The default is set to 0. The possible values include:
INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateway servers.
INTERNET_FLAG_OFFLINE Download operations are satisfied through the persistent cache
only. If the item does not exist in the cache, an appropriate error code is returned. This flag may
be combined with the bitwise OR ( | ) operator.
Remarks
CInternetSession is the first Internet function called by an application. It initializes internal data
structures and prepares for future calls from the application.
If no Internet connection can be opened, CInternetSession throws an AfxThrowInternetException.
Example
See the example for CFtpFileFind.

CInternetSession::Close
Call this member function when your application has finished using the CInternetSession object.

virtual void Close();

Example
See the example for CFtpFileFind.

CInternetSession::EnableStatusCallback
Call this member function to enable status callback.

BOOL EnableStatusCallback(BOOL bEnable = TRUE);

Parameters
bEnable
Specifies whether callback is enabled or disabled. The default is TRUE.
Return Value
Nonzero if successful; otherwise 0. If the call fails, determine the cause of the failure by examining the
thrown CInternetException object.
Remarks
When handling status callback, you can provide status about the progress of the operation (such as
resolving name, connecting to server, and so on) in the status bar of the application. Displaying
operation status is especially desirable during a long-term operation.
Because callbacks occur during the request's processing, the application should spend as little time as
possible in the callback to prevent degradation of data throughput to the network. For example,
putting up a dialog box in a callback may be such a lengthy operation that the server terminates the
request.
The status callback cannot be removed as long as any callbacks are pending.
To handle any operations asynchronously, you must either create your own thread or use the WinInet
functions without MFC.

CInternetSession::GetContext
Call this member function to get the context value for a particular application session.
DWORD_PTR GetContext() const;

Return Value
The application-defined context Identifier.
Remarks
OnStatusCallback uses the context ID returned by GetContext to report the status of a particular
application. For example, when a user activates an Internet request that involves returning status
information, the status callback uses the context ID to report status on that particular request. If the
user activates two separate Internet requests that both involve returning status information,
OnStatusCallback uses the context identifiers to return status about their corresponding requests.
Consequently, the context identifier is used for all status callback operations, and it is associated with
the session until the session is ended.
For more information about asynchronous operations, see the article Internet First Steps: WinInet.

CInternetSession::GetCookie
This member function implements the behavior of the Win32 function InternetGetCookie, as
described in the Windows SDK.

static BOOL GetCookie(


LPCTSTR pstrUrl,
LPCTSTR pstrCookieName,
LPTSTR pstrCookieData,
DWORD dwBufLen);

static BOOL GetCookie(


LPCTSTR pstrUrl,
LPCTSTR pstrCookieName,
CString& strCookieData);

Parameters
pstrUrl
A pointer to a string containing the URL.
pstrCookieName
A pointer to a string containing the name of the cookie to get for the specified URL.
pstrCookieData
In the first overload, a pointer to a string containing the address of the buffer that receives the cookie
data. This value can be NULL. In the second overload, a reference to a CString object to receive the
cookie data.
dwBufLen
The variable specifying the size of the pstrCookieData buffer. If the function succeeds, the buffer
receives the amount of data copied to the pstrCookieData buffer. If pstrCookieData is NULL, this
parameter receives a value that specifies the size of the buffer necessary to copy all the cookie data.
Return Value
Returns TRUE if successful, or FALSE otherwise. If the call fails, call the Win32 function GetLastError to
determine the cause of the error. The following error values apply:
ERROR_NO_MORE_ITEMS There is no cookie for the specified URL and all its parents.
ERROR_INSUFFICIENT_BUFFER The value passed in dwBufLen is insufficient to copy all the
cookie data. The value returned in dwBufLen is the size of the buffer necessary to get all the
data.
Remarks
In the second overload, MFC retrieves the cookie data into the supplied CString object.

CInternetSession::GetCookieLength
Call this member function to get the length of the cookie stored in the buffer.

static DWORD GetCookieLength(


LPCTSTR pstrUrl,
LPCTSTR pstrCookieName);

Parameters
pstrUrl
A pointer to a string containing the URL
pstrCookieName
A pointer to a string containing the name of the cookie.
Return Value
A DWORD value indicating the length of the cookie, stored in the buffer. Zero if no cookie with the
name indicated by pstrCookieName exists.
Remarks
This value is used by GetCookie.

CInternetSession::GetFtpConnection
Call this member function to establish an FTP connection and get a pointer to a CFtpConnection
object.

CFtpConnection* GetFtpConnection(
LPCTSTR pstrServer,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
BOOL bPassive = FALSE);

Parameters
pstrServer
A pointer to a string containing the FTP server name.
pstrUserName
Pointer to a null-terminated string that specifies the name of the user to log in. If NULL, the default is
anonymous.
pstrPassword
A pointer to a null-terminated string that specifies the password to use to log in. If both pstrPassword
and pstrUserName are NULL, the default anonymous password is the user's email name. If
pstrPassword is NULL (or an empty string) but pstrUserName is not NULL, a blank password is used.
The following table describes the behavior for the four possible settings of pstrUserName and
pstrPassword:
USERN A M E SEN T TO F T P PA SSW O RD SEN T TO F T P
P ST RUSERN A M E P ST RPA SSWO RD SERVER SERVER

NULL or " " NULL or " " "anonymous" User's email name

Non-NULL String NULL or " " pstrUserName ""

NULL Non-NULL String ERROR ERROR

Non-NULL String Non-NULL String pstrUserName pstrPassword

nPort
A number that identifies the TCP/IP port to use on the server.
bPassive
Specifies passive or active mode for this FTP session. If set to TRUE, it sets the Win32 API dwFlag to
INTERNET_FLAG_PASSIVE.
Return Value
A pointer to a CFtpConnection object. If the call fails, determine the cause of the failure by examining
the thrown CInternetException object.
Remarks
GetFtpConnection connects to an FTP server, and creates and returns a pointer to a CFTPConnection
object. It does not perform any specific operation on the server. If you intend to read or write to files,
for example, you must perform those operations as separate steps. See the classes CFtpConnection
and CFtpFileFind for information about searching for files, opening files, and reading or writing to
files. See the article Internet Programming with WinInet for steps in performing common FTP
connection tasks.
Example
See the example for CFtpFileFind.

CInternetSession::GetGopherConnection
Call this member function to establish a new gopher connection and get a pointer to a
CGopherConnection object.

CGopherConnection* GetGopherConnection(
LPCTSTR pstrServer,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER);

Parameters
pstrServer
A pointer to a string containing the gopher server name.
pstrUserName
A pointer to a string containing the user name.
pstrPassword
A pointer to a string containing the access password.
nPort
A number that identifies the TCP/IP port to use on the server.
Return Value
A pointer to a CGopherConnection object. If the call fails, determine the cause of the failure by
examining the thrown CInternetException object.
Remarks
GetGopherConnection connects to a gopher server, and creates and returns a pointer to a
CGopherConnection object. It does not perform any specific operation on the server. If you intend to
read or write data, for example, you must perform those operations as separate steps. See the classes
CGopherConnection, CGopherFile, and CGopherFileFind for information about searching for files,
opening files, and reading or writing to files. For information about browsing an FTP site, see the
member function OpenURL. See the article Internet Programming with WinInet for steps in
performing common gopher connection tasks.

CInternetSession::GetHttpConnection
Call this member function to establish an HTTP connection and get a pointer to a CHttpConnection
object.

CHttpConnection* GetHttpConnection(
LPCTSTR pstrServer,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL);

CHttpConnection* GetHttpConnection(
LPCTSTR pstrServer,
DWORD dwFlags,
INTERNET_PORT nPort = INTERNET_INVALID_PORT_NUMBER,
LPCTSTR pstrUserName = NULL,
LPCTSTR pstrPassword = NULL);

Parameters
pstrServer
A pointer to a string containing the HTTP server name.
nPort
A number that identifies the TCP/IP port to use on the server.
pstrUserName
A pointer to a string containing the user name.
pstrPassword
A pointer to a string containing the access password.
dwflags
Any combination of the INTERNET_FLAG_* flags. See the table in the Remarks section of
CHttpConnection::OpenRequest for a description of dwFlags values.
Return Value
A pointer to a CHttpConnection object. If the call fails, determine the cause of the failure by examining
the thrown CInternetException object.
Remarks
GetHttpConnection connects to an HTTP server, and creates and returns a pointer to a
CHttpConnection object. It does not perform any specific operation on the server. If you intend to
query an HTTP header, for example, you must perform this operation as a separate step. See the
classes CHttpConnection and CHttpFile for information about operations you can perform by using a
connection to an HTTP server. For information about browsing an HTTP site, see the member function
OpenURL. See the article Internet Programming with WinInet for steps in performing common HTTP
connection tasks.

CInternetSession::OnStatusCallback
This member function is called by the framework to update the status when status callback is enabled
and an operation is pending.

virtual void OnStatusCallback(


DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength);

Parameters
dwContext
The context value supplied by the application.
dwInternetStatus
A status code which indicates why the callback is being made. See Remarks for a table of possible
values.
lpvStatusInformation
A pointer to a buffer containing information pertinent to this callback.
dwStatusInformationLength
The size of lpvStatusInformation.
Remarks
You must first call EnableStatusCallback to take advantage of status callback.
The dwInternetStatus parameter indicates the operation being performed and determines what the
contents of lpvStatusInformation will be. dwStatusInformationLength indicates the length of the data
included in lpvStatusInformation. The following status values for dwInternetStatus are defined as
follows:

VA L UE M EA N IN G

INTERNET_STATUS_RESOLVING_NAME Looking up the IP address of the name contained in


lpvStatusInformation.

INTERNET_STATUS_NAME_RESOLVED Successfully found the IP address of the name


contained in lpvStatusInformation.

INTERNET_STATUS_CONNECTING_TO_SERVER Connecting to the socket address (SOCKADDR)


pointed to by lpvStatusInformation.

INTERNET_STATUS_CONNECTED_TO_SERVER Successfully connected to the socket address


(SOCKADDR) pointed to by lpvStatusInformation.

INTERNET_STATUS_SENDING_REQUEST Sending the information request to the server. The


lpvStatusInformation parameter is NULL.
VA L UE M EA N IN G

INTERNET_STATUS_ REQUEST_SENT Successfully sent the information request to the server.


The lpvStatusInformation parameter is NULL.

INTERNET_STATUS_RECEIVING_RESPONSE Waiting for the server to respond to a request. The


lpvStatusInformation parameter is NULL.

INTERNET_STATUS_RESPONSE_RECEIVED Successfully received a response from the server. The


lpvStatusInformation parameter is NULL.

INTERNET_STATUS_CLOSING_CONNECTION Closing the connection to the server. The


lpvStatusInformation parameter is NULL.

INTERNET_STATUS_CONNECTION_CLOSED Successfully closed the connection to the server. The


lpvStatusInformation parameter is NULL.

INTERNET_STATUS_HANDLE_CREATED Used by the Win32 API function InternetConnect to


indicate that it has created the new handle. This lets
the application call the Win32 function
InternetCloseHandle from another thread if the
connect is taking too long. See the Windows SDKfor
more information about these functions.

INTERNET_STATUS_HANDLE_CLOSING Successfully terminated this handle value.

Override this member function to require some action before a status callback routine is performed.

NOTE
Status callbacks need thread-state protection. If you are using MFC in a shared library, add the following line
to the beginning of your override:

AFX_MANAGE_STATE(AfxGetAppModuleState());

For more information about asynchronous operations, see the article Internet First Steps: WinInet.

CInternetSession::OpenURL
Call this member function to send the specified request to the HTTP server and allow the client to
specify additional RFC822, MIME, or HTTP headers to send along with the request.

CStdioFile* OpenURL(
LPCTSTR pstrURL,
DWORD_PTR dwContext = 1,
DWORD dwFlags = INTERNET_FLAG_TRANSFER_ASCII,
LPCTSTR pstrHeaders = NULL,
DWORD dwHeadersLength = 0);

Parameters
pstrURL
A pointer to the name of the URL to begin reading. Only URLs beginning with file:, ftp:, gopher:, or
http: are supported. Asserts if pstrURL is NULL.
dwContext
An application-defined value passed with the returned handle in callback.
dwFlags
The flags describing how to handle this connection. See Remarks for more information about the
valid flags. The valid flags are:
INTERNET_FLAG_TRANSFER_ASCII The default. Transfer the file as ASCII text.
INTERNET_FLAG_TRANSFER_BINARY Transfer the file as a binary file.
INTERNET_FLAG_RELOAD Get the data from the wire even if it is locally cached.
INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateways.
INTERNET_FLAG_SECURE This flag is applicable to HTTP requests only. It requests secure
transactions on the wire with Secure Sockets Layer or PCT.
INTERNET_OPEN_FLAG_USE_EXISTING_CONNECT If possible, reuse the existing connections to
the server for new requests generated by OpenUrl instead of creating a new session for each
connection request.
INTERNET_FLAG_PASSIVE Used for an FTP site. Uses passive FTP semantics. Used with
CInternetConnection of OpenURL .
pstrHeaders
A pointer to a string containing the headers to be sent to the HTTP server.
dwHeadersLength
The length, in characters, of the additional headers. If this is -1L and pstrHeaders is non-NULL, then
pstrHeaders is assumed to be zero terminated and the length is calculated.
Return Value
Returns a file handle for FTP, GOPHER, HTTP, and FILE-type Internet services only. Returns NULL if
parsing was unsuccessful.
The pointer that OpenURL returns depends on pstrURL's type of service. The table below illustrates the
possible pointers OpenURL can return.

URL T Y P E RET URN S

file:// CStdioFile*

http:// CHttpFile*

gopher:// CGopherFile*

ftp:// CInternetFile*

Remarks
The parameter dwFlags must include either INTERNET_FLAG_TRANSFER_ASCII or
INTERNET_FLAG_TRANSFER_BINARY, but not both. The remaining flags can be combined with the
bitwise OR operator ( | ).
OpenURL , which wraps the Win32 function InternetOpenURL , allows only downloading, retrieving, and
reading the data from an Internet server. OpenURL allows no file manipulation on a remote location,
so it requires no CInternetConnection object.
To use connection-specific (that is, protocol-specific) functions, such as writing to a file, you must open
a session, then open a particular kind of connection, then use that connection to open a file in the
desired mode. See CInternetConnection for more information about connection-specific functions.

CInternetSession::operator HINTERNET
Use this operator to get the Windows handle for the current Internet session.

operator HINTERNET() const;

CInternetSession::SetCookie
Sets a cookie for the specified URL.

static BOOL SetCookie(


LPCTSTR pstrUrl,
LPCTSTR pstrCookieName,
LPCTSTR pstrCookieData);

Parameters
pstrUrl
A pointer to a null-terminated string that specifies the URL for which the cookie should be set.
pstrCookieName
A pointer to a string containing the name of the cookie.
pstrCookieData
A pointer to a string containing the actual string data to associate with the URL.
Return Value
Returns TRUE if successful, or FALSE otherwise. To get the specific error code, call GetLastError.

Remarks
This member function implements the behavior of the Win32 message InternetSetCookie, as
described in the Windows SDK.

CInternetSession::SetOption
Call this member function to set options for the Internet session.

BOOL SetOption(
DWORD dwOption,
LPVOID lpBuffer,
DWORD dwBufferLength,
DWORD dwFlags = 0);

BOOL SetOption(
DWORD dwOption,
DWORD dwValue,
DWORD dwFlags = 0);

Parameters
dwOption
The Internet option to set. See Option Flags in the Windows SDKfor a list of the possible options.
lpBuffer
A buffer that contains the option setting.
dwBufferLength
The length of lpBuffer or the size of dwValue.
dwValue
A DWORD that contains the option setting.
dwFlags
Indicates various caching options. The default is set to 0. The possible values include:
INTERNET_FLAG_DONT_CACHE Do not cache the data, either locally or in any gateway servers.
INTERNET_FLAG_OFFLINE Download operations are satisfied through the persistent cache
only. If the item does not exist in the cache, an appropriate error code is returned. This flag may
be combined with the bitwise OR ( | ) operator.
Return Value
If the operation was successful, a value of TRUE is returned. If an error occurred, a value of FALSE is
returned. If the call fails, the Win32 function GetLastError may be called to determine the cause of the
error.

See also
CObject Class
Hierarchy Chart
CInternetConnection Class
CHttpConnection Class
CFtpConnection Class
CGopherConnection Class
CInterpolatorBase Class
4/21/2020 • 3 minutes to read • Edit Online

Implements a callback, which is called by the Animation API when it has to calculate a new value of an animation
variable.

Syntax
class CInterpolatorBase : public CUIAnimationInterpolatorBase<CInterpolatorBase>;

Members
Public Constructors
NAME DESC RIP T IO N

CInterpolatorBase::CInterpolatorBase Constructs the CInterpolatorBase object.

Public Methods
NAME DESC RIP T IO N

CInterpolatorBase::CreateInstance Creates an instance of CInterpolatorBase and stores a


pointer to custom interpolator, which will be handling events.

CInterpolatorBase::GetDependencies Gets the interpolator's dependencies. (Overrides


CUIAnimationInterpolatorBase::GetDependencies .)

CInterpolatorBase::GetDuration Gets the interpolator's duration. (Overrides


CUIAnimationInterpolatorBase::GetDuration .)

CInterpolatorBase::GetFinalValue Gets the final value to which the interpolator leads. (Overrides
CUIAnimationInterpolatorBase::GetFinalValue .)

CInterpolatorBase::InterpolateValue Interpolates the value at a given offset (Overrides


CUIAnimationInterpolatorBase::InterpolateValue .)

CInterpolatorBase::InterpolateVelocity Interpolates the velocity at a given offset (Overrides


CUIAnimationInterpolatorBase::InterpolateVelocity .)

CInterpolatorBase::SetCustomInterpolator Stores a pointer to custom interpolator, which will be handling


events.

CInterpolatorBase::SetDuration Sets the interpolator's duration (Overrides


CUIAnimationInterpolatorBase::SetDuration .)

CInterpolatorBase::SetInitialValueAndVelocity Sets the interpolator's initial value and velocity. (Overrides


CUIAnimationInterpolatorBase::SetInitialValueAndVelocity
.)
Remarks
This handler is created and passed to IUIAnimationTransitionFactory::CreateTransition when a CCustomTransition
object is being created as a part of animation initialization process (started by CAnimationController::AnimateGroup
). Usually you don't need to use this class directly, it just routs all events to a CCustomInterpolator -derived class,
whose pointer is passed to constructor of CCustomTransition .

Inheritance Hierarchy
CUIAnimationCallbackBase

CUIAnimationInterpolatorBase

CInterpolatorBase

Requirements
Header : afxanimationcontroller.h

CInterpolatorBase::CInterpolatorBase
Constructs the CInterpolatorBase object.

CInterpolatorBase();

CInterpolatorBase::CreateInstance
Creates an instance of CInterpolatorBase and stores a pointer to custom interpolator, which will be handling events.

static COM_DECLSPEC_NOTHROW HRESULT CreateInstance(


CCustomInterpolator* pInterpolator,
IUIAnimationInterpolator** ppHandler);

Parameters
pInterpolator
A pointer to custom interpolator.
ppHandler
Output. Contains a pointer to instance of CInterpolatorBase when the function returns.
Return Value

CInterpolatorBase::GetDependencies
Gets the interpolator's dependencies.

IFACEMETHOD(GetDependencies)(
__out UI_ANIMATION_DEPENDENCIES* initialValueDependencies,
__out UI_ANIMATION_DEPENDENCIES* initialVelocityDependencies,
__out UI_ANIMATION_DEPENDENCIES* durationDependencies);

Parameters
initialValueDependencies
Output. Aspects of the interpolator that depend on the initial value passed to SetInitialValueAndVelocity.
initialVelocityDependencies
Output. Aspects of the interpolator that depend on the initial velocity passed to SetInitialValueAndVelocity.
durationDependencies
Output. Aspects of the interpolator that depend on the duration passed to SetDuration.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the GetDependencies method.

CInterpolatorBase::GetDuration
Gets the interpolator's duration.

IFACEMETHOD(GetDuration)(__out UI_ANIMATION_SECONDS* duration);

Parameters
duration
Output. The duration of the transition, in seconds.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the GetDuration method.

CInterpolatorBase::GetFinalValue
Gets the final value to which the interpolator leads.

IFACEMETHOD(GetFinalValue)(__out DOUBLE* value);

Parameters
value
Output. The final value of a variable at the end of the transition.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the GetFinalValue method.

CInterpolatorBase::InterpolateValue
Interpolates the value at a given offset

IFACEMETHOD(InterpolateValue)(
__in UI_ANIMATION_SECONDS offset,
__out DOUBLE* value);

Parameters
offset
The offset from the start of the transition. The offset is always greater than or equal to zero and less than the
duration of the transition. This method is not called if the duration of the transition is zero.
value
Output. The interpolated value.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the InterpolateValue method.

CInterpolatorBase::InterpolateVelocity
Interpolates the velocity at a given offset

IFACEMETHOD(InterpolateVelocity)(
__in UI_ANIMATION_SECONDS offset,
__out DOUBLE* velocity);

Parameters
offset
The offset from the start of the transition. The offset is always greater than or equal to zero and less than or equal
to the duration of the transition. This method is not called if the duration of the transition is zero.
velocity
Output. The velocity of the variable at the offset.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the InterpolateVelocity method.

CInterpolatorBase::SetCustomInterpolator
Stores a pointer to custom interpolator, which will be handling events.

void SetCustomInterpolator(CCustomInterpolator* pInterpolator);

Parameters
pInterpolator
A pointer to custom interpolator.

CInterpolatorBase::SetDuration
Sets the interpolator's duration

IFACEMETHOD(SetDuration)(__in UI_ANIMATION_SECONDS duration);

Parameters
duration
The duration of the transition.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the SetDuration method.

CInterpolatorBase::SetInitialValueAndVelocity
Sets the interpolator's initial value and velocity.
IFACEMETHOD(SetInitialValueAndVelocity)(
__in DOUBLE initialValue,
__in DOUBLE initialVelocity);

Parameters
initialValue
The value of the variable at the start of the transition.
initialVelocity
The velocity of the variable at the start of the transition.
Return Value
If the method succeeds, it returns S_OK. It returns E_FAIL if CCustomInterpolator is not set, or custom
implementation returns FALSE from the SetInitialValueAndVelocity method.

See also
Classes
CInvalidArgException Class
3/27/2020 • 2 minutes to read • Edit Online

This class represents an invalid argument exception condition.

Syntax
class CInvalidArgException : public CSimpleException

Members
Public Constructors
NAME DESC RIP T IO N

CInvalidArgException::CInvalidArgException The constructor.

Remarks
A CInvalidArgException object represents an invalid argument exception condition.
For more information on Exception Handling, see the CException Class topic and Exception Handling (MFC).

Inheritance Hierarchy
CObject
CException
CSimpleException
CInvalidArgException

Requirements
Header : afx.h

CInvalidArgException::CInvalidArgException
The constructor.

CInvalidArgException();

Remarks
Do not use this constructor directly; call the global function AfxThrowInvalidArgException .

See also
Hierarchy Chart
CSimpleException Class
CIPAddressCtrl Class
4/21/2020 • 5 minutes to read • Edit Online

Provides the functionality of the Windows common IP Address control.

Syntax
class CIPAddressCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CIPAddressCtrl::CIPAddressCtrl Constructs a CIPAddressCtrl object.

Public Methods
NAME DESC RIP T IO N

CIPAddressCtrl::ClearAddress Clears the contents of the IP Address Control.

CIPAddressCtrl::Create Creates an IP Address Control and attaches it to a


CIPAddressCtrl object.

CIPAddressCtrl::CreateEx Creates an IP Address control with the specified Windows


extended styles and attaches it to a CIPAddressCtrl object.

CIPAddressCtrl::GetAddress Retrieves the address values for all four fields in the IP Address
Control.

CIPAddressCtrl::IsBlank Determines if all fields in the IP Address Control are empty.

CIPAddressCtrl::SetAddress Sets the address values for all four fields in the IP Address
Control.

CIPAddressCtrl::SetFieldFocus Sets the keyboard focus to the specified field in the IP Address
Control.

CIPAddressCtrl::SetFieldRange Sets the range in the specified field in the IP Address Control.

Remarks
An IP Address control, a control similar to an edit control, allows you to enter and manipulate a numerical address
in Internet Protocol (IP) format.
This control (and therefore the CIPAddressCtrl class) is available only to programs running under Microsoft
Internet Explorer 4.0 and later. They will also be available under future versions of Windows and Windows NT.
For more general information about the IP Address Control, see IP Address Controls in the Windows SDK.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CIPAddressCtrl

Requirements
Header : afxcmn.h

CIPAddressCtrl::CIPAddressCtrl
Creates a CIPAddressCtrl object.

CIPAddressCtrl();

CIPAddressCtrl::ClearAddress
Clears the contents of the IP Address Control.

void ClearAddress();

Remarks
This member function implements the behavior of the Win32 message IPM_CLEARADDRESS, as described in the
Windows SDK.

CIPAddressCtrl::Create
Creates an IP Address Control and attaches it to a CIPAddressCtrl object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
The IP Address control's style. Apply a combination of window styles. You must include the WS_CHILD style
because the control must be a child window. See CreateWindow in the Windows SDK for a list of windows styles.
rect
A reference to the IP Address Control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
A pointer to the IP Address Control's parent window. It must not be NULL.
nID
The IP Address Control's ID.
Return Value
Nonzero if initialization was successful; otherwise 0.
Remarks
You construct a CIPAddressCtrl object in two steps.
1. Call the constructor, which creates the CIPAddressCtrl object.
2. Call Create , which creates the IP Address Control.
If you want to use extended windows styles with your control, call CreateEx instead of Create .

CIPAddressCtrl::CreateEx
Call this function to create a control (a child window) and associate it with the CIPAddressCtrl object.

virtual BOOL CreateEx(


DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the dwExStyle
parameter for CreateWindowEx in the Windows SDK.
dwStyle
The IP Address control's style. Apply a combination of window styles. You must include the WS_CHILD style
because the control must be a child window. See CreateWindow in the Windows SDK for a list of windows styles.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client coordinates
of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended style
preface WS_EX_ .

CIPAddressCtrl::GetAddress
Retrieves the address values for all four fields in the IP Address Control.
int GetAddress(
BYTE& nField0,
BYTE& nField1,
BYTE& nField2,
BYTE& nField3);

int GetAddress(DWORD& dwAddress);

Parameters
nField0
A reference to the field 0 value from a packed IP address.
nField1
A reference to the field 1 value from a packed IP address.
nField2
A reference to the field 2 value from a packed IP address.
nField3
A reference to the field 3 value from a packed IP address.
dwAddress
A reference to the address of a DWORD value that receives the IP address. See Remarks for a table that shows
how dwAddress is filled.
Return Value
The number of non-blank fields in the IP Address Control.
Remarks
This member function implements the behavior of the Win32 message IPM_GETADDRESS, as described in the
Windows SDK. In the first prototype above, the numbers in fields 0 through 3 of the control, read left to right
respectively, populate the four parameters. In the second prototype above, dwAddress is populated as follows.

F IEL D B IT S C O N TA IN IN G T H E F IEL D VA L UE

0 24 through 31

1 16 through 23

2 8 through 15

3 0 through 7

CIPAddressCtrl::IsBlank
Determines if all fields in the IP Address Control are empty.

BOOL IsBlank() const;

Return Value
Nonzero if all of the IP Address Control fields are empty; otherwise 0.
Remarks
This member function implements the behavior of the Win32 message IPM_ISBLANK, as described in the Windows
SDK.

CIPAddressCtrl::SetAddress
Sets the address values for all four fields in the IP Address Control.

void SetAddress(
BYTE nField0,
BYTE nField1,
BYTE nField2,
BYTE nField3);

void SetAddress(DWORD dwAddress);

Parameters
nField0
The field 0 value from a packed IP address.
nField1
The field 1 value from a packed IP address.
nField2
The field 2 value from a packed IP address.
nField3
The field 3 value from a packed IP address.
dwAddress
A DWORD value that contains the new IP address. See Remarks for a table that shows how the DWORD value is
filled.
Remarks
This member function implements the behavior of the Win32 message IPM_SETADDRESS, as described in the
Windows SDK. In the first prototype above, the numbers in fields 0 through 3 of the control, read left to right
respectively, populate the four parameters. In the second prototype above, dwAddress is populated as follows.

F IEL D B IT S C O N TA IN IN G T H E F IEL D VA L UE

0 24 through 31

1 16 through 23

2 8 through 15

3 0 through 7

CIPAddressCtrl::SetFieldFocus
Sets the keyboard focus to the specified field in the IP Address Control.

void SetFieldFocus(WORD nField);

Parameters
nField
Zero-based field index to which the focus should be set. If this value is greater than the number of fields, focus is
set to the first blank field. If all fields are non-blank, focus is set to the first field.
Remarks
This member function implements the behavior of the Win32 message IPM_SETFOCUS, as described in the
Windows SDK.

CIPAddressCtrl::SetFieldRange
Sets the range in the specified field in the IP Address Control.

void SetFieldRange(
int nField,
BYTE nLower,
BYTE nUpper);

Parameters
nField
Zero-based field index to which the range will be applied.
nLower
A reference to an integer receiving the lower limit of the specified field in this IP Address Control.
nUpper
A reference to an integer receiving the upper limit of the specified field in this IP Address Control.
Remarks
This member function implements the behavior of the Win32 message IPM_SETRANGE, as described in the
Windows SDK. Use the two parameters, nLower and nUpper, to indicate the lower and upper limits of the field,
instead of the wRange parameter used with the Win32 message.

See also
CWnd Class
Hierarchy Chart
CJumpList Class
4/21/2020 • 5 minutes to read • Edit Online

A CJumpList is the list of shortcuts revealed when you right-click on an icon in the task bar.

Syntax
class CJumpList;

Members
Public Constructors
NAME DESC RIP T IO N

CJumpList::CJumpList Constructs a CJumpList object.

CJumpList::~CJumpList Destroys a CJumpList object.

NAME DESC RIP T IO N

CJumpList::AbortList Aborts a list-building transaction without committing.

CJumpList::AddDestination Overloaded. Adds destination to the list.

CJumpList::AddKnownCategory Appends a Known Category to the list.

CJumpList::AddTask Overloaded. Adds items to the canonical Tasks category.

CJumpList::AddTasks Adds items to the canonical Tasks category.

CJumpList::AddTaskSeparator Adds a separator between tasks.

CJumpList::ClearAll Removes all tasks and destinations that have been added to
the current instance of CJumpList so far.

CJumpList::ClearAllDestinations Removes all destinations that have been added to the current
instance of CJumpList so far.

CJumpList::CommitList Ends a list-building transaction and commits the reported list


to the associated store (the registry in this case.)

CJumpList::GetDestinationList Retrieves an interface pointer to destination list.

CJumpList::GetMaxSlots Retrieves the maximum number of items, including category


headers that can display in the calling application's destination
menu.
NAME DESC RIP T IO N

CJumpList::GetRemovedItems Returns array of items that represent removed destinations.

CJumpList::InitializeList Begins a list-building transaction.

CJumpList::SetAppID Sets the Application User Model ID for the list that will be
built.

Inheritance Hierarchy
CJumpList

Requirements
Header : afxadv.h

CJumpList::~CJumpList
Destroys a CJumpList object.

~CJumpList();

CJumpList::AbortList
Aborts a list-building transaction without committing.

void AbortList();

Remarks
Calling this method has the same effect as destroying CJumpList without calling CommitList .

CJumpList::AddDestination
Adds destination to the list.

BOOL AddDestination(
LPCTSTR lpcszCategoryName,
LPCTSTR strDestinationPath);

BOOL AddDestination(
LPCTSTR strCategoryName,
IShellItem* pShellItem);

BOOL AddDestination(
LPCTSTR strCategoryName,
IShellLink* pShellLink);

Parameters
lpcszCategoryName
Specifies a category name. If the specified category does not exist, it will be created.
strDestinationPath
Specifies a path to destination file.
strCategoryName
Specifies a category name. If the specified category does not exist, it will be created.
pShellItem
Specifies a Shell Item representing the destination being added.
pShellLink
Specifies a Shell Link representing the destination being added.
Return Value
Remarks
The instance of CJumpList internally accumulates added destinations and then commits them in CommitList .

CJumpList::AddKnownCategory
Appends a Known Category to the list.

BOOL AddKnownCategory(KNOWNDESTCATEGORY category);

Parameters
category
Specifies a known category type. Can be either KDC_RECENT, or KDC_KNOWN.
Return Value
Remarks
Known Categories are the Frequent and Recent categories that we will automatically calculate for every application
that utilizes SHAddToRecentDocs (or indirectly uses it as the shell will call it on the application's behalf in some
scenarios).

CJumpList::AddTask
Adds items to the canonical Tasks category.

BOOL AddTask(
LPCTSTR strTargetExecutablePath,
LPCTSTR strCommandLineArgs,
LPCTSTR strTitle,
LPCTSTR strIconLocation,
int iIconIndex);

BOOL AddTask(IShellLink* pShellLink);

Parameters
strTargetExecutablePath
Specifies the target task path.
strCommandLineArgs
Specifies command-line arguments of the executable specified by strTargetExecutablePath.
strTitle
Task name that will be displayed in the Destination List.
strIconLocation
Location of icon that will be displayed in the Destination List along with the title.
iIconIndex
Icon index.
pShellLink
Shell Link that represents a task to be added.
Return Value
Remarks
The instance of CJumpList accumulates specified tasks and adds them to the Destination List during CommitList .
Task items will appear in a category at the bottom of the application's destination menu. This category takes
precedence over all other categories when it is filled in the UI.

CJumpList::AddTasks
Adds items to the canonical Tasks category.

BOOL AddTasks(IObjectArray* pObjectCollection);

Parameters
pObjectCollection
A collection of tasks to be added.
Return Value
Remarks
The instance of CJumpList accumulates specified tasks and adds them to the Destination List during CommitList .
Task items will appear in a category at the bottom of the application's destination menu. This category takes
precedence over all other categories when it is filled in the UI.

CJumpList::AddTaskSeparator
Adds a separator between tasks.

BOOL AddTaskSeparator();

Return Value
Nonzero if it is successful, 0 if it is not.

CJumpList::CJumpList
Constructs a CJumpList object.

CJumpList(BOOL bAutoCommit = TRUE);

Parameters
bAutoCommit
If this parameter is FALSE the list is not automatically committed in destructor.

CJumpList::ClearAll
Removes all tasks and destinations that have been added to the current instance of CJumpList so far.

void ClearAll();

Remarks
This method clears and releases all data and internal interfaces.

CJumpList::ClearAllDestinations
Removes all destinations that have been added to the current instance of CJumpList so far.

void ClearAllDestinations();

Remarks
Call this function if you need to remove all destinations that have been added so far in the current session of
destination list building and add other destinations again. If the internal ICustomDestinationList has been
initialized, it's left alive.

CJumpList::CommitList
Ends a list-building transaction and commits the reported list to the associated store (the registry in this case).

BOOL CommitList();

Return Value
Remarks
The commit is atomic. An error will be returned if the commit fails. When CommitList is called, the current list of
removed items will be cleaned up. Calling this method resets the object so that it does not have an active list-
building transaction. To update the list, BeginList needs to be called again.

CJumpList::GetDestinationList
Retrieves an interface pointer to destination list.

ICustomDestinationList* GetDestinationList();

Return Value
Remarks
If the jump list has not been initialized, or has been committed or aborted, the returned value will be NULL.

CJumpList::GetMaxSlots
Retrieves the maximum number of items, including category headers that can display in the calling application's
destination menu.

UINT GetMaxSlots() const;

Return Value
Remarks
Applications may only report a number of items and category headers combined up to this value. If calls to
AppendCategory , AppendKnownCategory , or AddUserTasks exceed this number, they will return failure.

CJumpList::GetRemovedItems
Returns array of items that represent removed destinations.

IObjectArray* GetRemovedItems();

Return Value
Remarks
The removed destinations are retrieved during initialization of jump list. When generating a new destination list,
applications are expected to first process the removed destinations list, clearing their tracking data for any item
returned by the removed list enumerator. If an application attempts to provide an item that was just removed in the
transaction that the current call to BeginList started, the method call that re-added that item will fail, to ensure
that applications are respecting the removed list.

CJumpList::InitializeList
Begins a list-building transaction.

BOOL InitializeList();

Return Value
Remarks
You don't need to call this method explicitly unless you wish to retrieve a pointer to ICustomDestinationList using
GetDestinationList , the number of available slots using GetMaxSlots , or list of removed items using
GetRemovedItems .

CJumpList::SetAppID
Sets the Application User Model ID for the list that will be built.

void SetAppID(LPCTSTR strAppID);

Parameters
strAppID
A string that specifies the Application User Model ID.

See also
Classes
CKeyboardManager Class
4/21/2020 • 6 minutes to read • Edit Online

Manages shortcut key tables for the main frame window and child frame windows.

Syntax
class CKeyboardManager : public CObject

Members
Public Constructors

Name Description

CKeyboardManager::CKeyboardManager Constructs a CKeyboardManager object.

Public Methods

Name Description

CKeyboardManager::CleanUp Clears the shortcut key tables.

CKeyboardManager::FindDefaultAccelerator Retrieves the default shortcut key for the specified command
and window.

CKeyboardManager::IsKeyHandled Determines whether a key is handled by the accelerator


table.

CKeyboardManager::IsKeyPrintable Indicates whether a character is printable.

CKeyboardManager::IsShowAllAccelerators Indicates whether menus show all shortcut keys for a


command or only the default shortcut key.

CKeyboardManager::LoadState Loads the shortcut key tables from the Windows registry.

CKeyboardManager::ResetAll Reloads the shortcut key tables from the application


resource.

CKeyboardManager::SaveState Saves the shortcut key tables to the Windows registry.

CKeyboardManager::ShowAllAccelerators Specifies whether the framework displays all the shortcut


keys for all commands, or a single shortcut key for each
command. This method does not affect commands that have
only one associated shortcut key.

CKeyboardManager::TranslateCharToUpper Converts a character to its upper register.


CKeyboardManager::UpdateAccelTable Updates a shortcut key table with a new shortcut key table.

Remarks
The members of this class enable you to save and load shortcut key tables to the Windows registry, use a
template to update the short cut key tables, and find the default shortcut key for a command in a frame window.
In addition, the CKeyboardManager object lets you control how shortcut keys are displayed to the user.
You should not create a CKeyboardManager object manually. It will be created automatically by the framework of
your application. However, you should call CWinAppEx::InitKeyboardManager during the initialization process of
your application. To get a pointer to the keyboard manager for your application, call
CWinAppEx::GetKeyboardManager.

Example
The following example demonstrates how to retrieve a pointer to a CKeyboardManager object from a CWinAppEx
class, and how to show all the shortcut keys associated with menu commands. This code snippet is part of the
Custom Pages sample.

// The GetKeyboardManager method is inherited from the CWinAppEx class.


CKeyboardManager *cKeyboardManager = GetKeyboardManager();
cKeyboardManager->ShowAllAccelerators();

Inheritance Hierarchy
CObject
CKeyboardManager

Requirements
Header : afxkeyboardmanager.h

CKeyboardManager::CKeyboardManager
Constructs a CKeyboardManager object.

CKeyboardManager();

Remarks
In most cases, you do not have to create a CKeyboardManager directly. By default, the framework creates one for
you. To get a pointer to the CKeyboardManager , call CWinAppEx::GetKeyboardManager. If you do create one
manually, you must initialize it with the method CWinAppEx::InitKeyboardManager.

CKeyboardManager::CleanUp
Frees the CKeyboardManager resources and clears all shortcut key mappings.

static void CleanUp();


Remarks
For more information about shortcut keys, see Keyboard and Mouse Customization.
You do not have to call this function when your application exits because the framework calls it automatically
during application exit.

CKeyboardManager::FindDefaultAccelerator
Retrieves the default shortcut key for the specified command and window.

static BOOL FindDefaultAccelerator(


UINT uiCmd,
CString& str,
CFrameWnd* pWndFrame,
BOOL bIsDefaultFrame);

Parameters
uiCmd
[in] The command ID.
str
[out] A reference to a CString object.
pWndFrame
[in] A pointer to a frame window.
bIsDefaultFrame
[in] Specifies whether the frame window is the default frame window.
Return Value
Nonzero if the shortcut is found; otherwise 0.
Remarks
This method looks up the command specified by uiCmd and retrieves the default shortcut key. Then the method
takes the string associated with this shortcut key and writes the value to the str parameter.

CKeyboardManager::IsKeyHandled
Determines whether the specified key is handled by the CKeyboardManager Class.

static BOOL __stdcall IsKeyHandled(


WORD nKey,
BYTE fVirt,
CFrameWnd* pWndFrame,
BOOL bIsDefaultFrame);

Parameters

Parameter Description

nKey [in] The key to check.

fVirt [in] Specifies the behavior of the shortcut key. For a list of
possible values, see ACCEL Structure.
pWndFrame [in] A frame window. This method determines whether a
shortcut key is handled in this frame.

bIsDefaultFrame [in] A Boolean parameter that indicates whether pWndFrame


is the default frame window.

Return Value
TRUE if the shortcut key is handled. FALSE if the key is not handled or if pWndFrame is NULL.
Remarks
The input parameters must match the entry in the accelerator table both for nKey and fVirt to determine
whether a shortcut key is handled in pWndFrame.

CKeyboardManager::IsKeyPrintable
Indicates whether a character is printable.

static BOOL __stdcall IsKeyPrintable(const UINT nChar);

Parameters

Parameter Description

nChar [in] The character that this method checks.

Return Value
Nonzero if the character is printable, zero if it is not.
Remarks
This method fails if a call to GetKeyboardState fails.

CKeyboardManager::IsShowAllAccelerators
Indicates whether menus show all the shortcut keys associated with menu commands or only the default
shortcut keys.

static BOOL IsShowAllAccelerators();

Return Value
Nonzero if the application lists all the shortcut keys for menu commands; 0 if the application displays only
default shortcut keys.
Remarks
The application lists the shortcut keys for menu commands in the menu bar. Use the function
CKeyboardManager::ShowAllAccelerators to control whether the application lists all the shortcut keys or just the
default shortcut keys.

CKeyboardManager::LoadState
Loads the shortcut key tables from the Windows registry.
BOOL LoadState(
LPCTSTR lpszProfileName = NULL,
CFrameWnd* pDefaultFrame = NULL);

Parameters
lpszProfileName
[in] The registry path where CKeyboardManager data is saved.
pDefaultFrame
[in] A pointer to a frame window to use as the default window.
Return Value
Nonzero if the state was loaded successfully or 0 otherwise.
Remarks
If the lpszProfileName parameter is NULL, this method checks the default registry location for CKeyboardManager
data. The default registry location is specified by the CWinAppEx Class. The data must be previously written with
the method CKeyboardManager::SaveState.
If you do not specify a default window, the main frame window of your application will be used.

CKeyboardManager::ResetAll
Reloads the shortcut key tables from the application resource.

void ResetAll();

Remarks
This function clears the shortcuts stored in the CKeyboardManager instance. It will then reload the state of the
keyboard manager from the application resource.

CKeyboardManager::SaveState
Saves the shortcut key tables to the Windows registry.

BOOL SaveState(
LPCTSTR lpszProfileName = NULL,
CFrameWnd* pDefaultFrame = NULL);

Parameters
lpszProfileName
[in] The registry path for saving the CKeyboardManager state.
pDefaultFrame
[in] A pointer to a frame window that becomes the default window.
Return Value
Nonzero if the keyboard manager state was saved successfully, or 0 otherwise.
Remarks
If the lpszProfileName parameter is NULL, this method will write the CKeyboardManager state to the default
location specified by the CWinAppEx Class. If you specify a location, you can load the data later using the method
CKeyboardManager::LoadState.
If you do not specify a default window, the main frame window will be used as the default window.

CKeyboardManager::ShowAllAccelerators
Shows all the shortcut keys associated with menu commands.

static void ShowAllAccelerators(


BOOL bShowAll = TRUE,
LPCTSTR lpszDelimiter = _afxDefaultAcceleratorDelimiter);

Parameters
bShowAll
[in] If TRUE, all the shortcut keys will be displayed. If FALSE, only the first shortcut key will be displayed.
lpszDelimiter
[in] A string to insert between shortcut keys. This delimiter has no effect if only one shortcut key is displayed.
Remarks
By default, if a command has more than one shortcut key associated with it, only the first shortcut key will be
shown. This function enables you to list all the shortcut keys associated with all commands.
The shortcut keys will be listed next to the command in the menu bar. If all the shortcut keys are displayed, the
string provided by lpszDelimiter will separate individual shortcut keys.

CKeyboardManager::TranslateCharToUpper
Converts a character to its upper register.

static UINT TranslateCharToUpper(const UINT nChar);

Parameters
nChar
[in] The character to convert.
Return Value
The character that is the upper register of the input parameter.

CKeyboardManager::UpdateAccelTable
Updates a shortcut key table with a new shortcut key table.

BOOL UpdateAccelTable(
CMultiDocTemplate* pTemplate,
LPACCEL lpAccel,
int nSize,
CFrameWnd* pDefaultFrame = NULL);

BOOL UpdateAccelTable(
CMultiDocTemplate* pTemplate,
HACCEL hAccelNew,
CFrameWnd* pDefaultFrame = NULL);

Parameters
pTemplate
[in] A pointer to a document template.
lpAccel
[in] A pointer to the new shortcut key.
nSize
[in] The size of the new shortcut table.
pDefaultFrame
[in] A pointer to the default frame window.
hAccelNew
[in] A handle to the new shortcut table.
Return Value
Nonzero if the method is successful; otherwise 0.
Remarks
Use this function to replace the existing shortcut table with new shortcut keys for several frame window objects.
The function receives a document template as a parameter to obtain access to all frame window objects
connected to the given document template.

See also
Hierarchy Chart
Classes
CWinAppEx Class
CWinAppEx::InitKeyboardManager
Keyboard and Mouse Customization
CKeyFrame Class
3/27/2020 • 3 minutes to read • Edit Online

Represents an animation keyframe.

Syntax
class CKeyFrame : public CBaseKeyFrame;

Members
Public Constructors
NAME DESC RIP T IO N

CKeyFrame::CKeyFrame Overloaded. Constructs a keyframe that depends on other


keyframe.

Public Methods
NAME DESC RIP T IO N

CKeyFrame::AddToStoryboard Adds a keyframe to a storyboard. (Overrides


CBaseKeyFrame::AddToStoryboard.)

CKeyFrame::AddToStoryboardAfterTransition Adds a keyframe to storyboard after transition.

CKeyFrame::AddToStoryboardAtOffset Adds a keyframe to storyboard at offset.

CKeyFrame::GetExistingKeyframe Returns a pointer to a keyframe this keyframe depends on.

CKeyFrame::GetOffset Returns an offset from other keyframe.

CKeyFrame::GetTransition Returns a pointer to a transition this keyframe depends on.

Protected Data Members


NAME DESC RIP T IO N

CKeyFrame::m_offset Specifies offset of this keyframe from a keyframe stored in


m_pExistingKeyFrame.

CKeyFrame::m_pExistingKeyFrame Stores a pointer to an existing keframe. This keyframe is added


to storyboard with m_offset to the existing keyframe.

CKeyFrame::m_pTransition Stores a pointer to transtion that begins at this keyframe.

Remarks
This class implements an animation keyframe. A keyframe represents a moment in time within a storyboard and
can be used to specify the start and end times of transitions. A keyframe may be based on other keyframe and
have an offset (in seconds) from it, or may be based on a transition and represent a moment in time when this
transition ends.

Inheritance Hierarchy
CObject
CBaseKeyFrame
CKeyFrame

Requirements
Header : afxanimationcontroller.h

CKeyFrame::AddToStoryboard
Adds a keyframe to a storyboard.

virtual BOOL AddToStoryboard(


IUIAnimationStoryboard* pStoryboard,
BOOL bDeepAdd);

Parameters
pStoryboard
A pointer to a storyboard.
bDeepAdd
Specifies whether to add keyframe or transition recursively.
Return Value
TRUE, if keyframe was added successfully.
Remarks
This method adds a keyframe to storyboard. If it depends on other keyframe or transition and bDeepAdd is TRUE,
this method tries to add them recursively.

CKeyFrame::AddToStoryboardAfterTransition
Adds a keyframe to storyboard after transition.

BOOL AddToStoryboardAfterTransition(
IUIAnimationStoryboard* pStoryboard,
BOOL bDeepAdd);

Parameters
pStoryboard
A pointer to a storyboard.
bDeepAdd
Specifies whether to add a transition recursively.
Return Value
TRUE, if keyframe was added successfully.
Remarks
This function is called by the framework to add a keyframe to storyboard after transition.

CKeyFrame::AddToStoryboardAtOffset
Adds a keyframe to storyboard at offset.

virtual BOOL AddToStoryboardAtOffset(


IUIAnimationStoryboard* pStoryboard,
BOOL bDeepAdd);

Parameters
pStoryboard
A pointer to a storyboard.
bDeepAdd
Specifies whether to add a keyframe this keyframe depend on recursively.
Return Value
TRUE, if keyframe was added successfully.
Remarks
This function is called by the framework to add a keyframe to storyboard at offset.

CKeyFrame::CKeyFrame
Constructs a keyframe that depends on a transition.

CKeyFrame(CBaseTransition* pTransition);

CKeyFrame(
CBaseKeyFrame* pKeyframe,
UI_ANIMATION_SECONDS offset = 0.0);

Parameters
pTransition
A pointer to a transition.
pKeyframe
A pointer to keyframe.
offset
Offset, in seconds, from keyframe specified by pKeyframe.
Remarks
The constructed keyframe will represent a moment in time within a storyboard when the specified transition ends.

CKeyFrame::GetExistingKeyframe
Returns a pointer to a keyframe this keyframe depends on.

CBaseKeyFrame* GetExistingKeyframe();
Return Value
A valid pointer to keyframe, or NULL if this keyframe does not depend on other keyframe.
Remarks
This is an accessor to a keyframe this keyframe depends on.

CKeyFrame::GetOffset
Returns an offset from other keyframe.

UI_ANIMATION_SECONDS GetOffset();

Return Value
An offset in seconds from other keyframe.
Remarks
This method should be called to determine an offset in seconds from other keyframe.

CKeyFrame::GetTransition
Returns a pointer to a transition this keyframe depends on.

CBaseTransition* GetTransition();

Return Value
A valid pointer to transition, or NULL if this keyframe does not depend on transition.
Remarks
This is an accessor to a transition this keyframe depends on.

CKeyFrame::m_offset
Specifies offset of this keyframe from a keyframe stored in m_pExistingKeyFrame.

UI_ANIMATION_SECONDS m_offset;

CKeyFrame::m_pExistingKeyFrame
Stores a pointer to an existing keframe. This keyframe is added to storyboard with m_offset to the existing
keyframe.

CBaseKeyFrame* m_pExistingKeyFrame;

CKeyFrame::m_pTransition
Stores a pointer to transtion that begins at this keyframe.

CBaseTransition* m_pTransition;
See also
Classes
CLinearTransition Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates a linear transition.

Syntax
class CLinearTransition : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CLinearTransition::CLinearTransition Constructs a linear transition object and initializes it with


duration and final value.

Public Methods
NAME DESC RIP T IO N

CLinearTransition::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CLinearTransition::m_dblFinalValue The value of the animation variable at the end of the


transition.

CLinearTransition::m_duration The duration of the transition.

Remarks
During a linear transition, the value of the animation variable transitions linearly from its initial value to a specified
final value. Because all transitions are cleared automatically, it's recommended to allocated them using operator
new. The encapsulated IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup,
until then it's NULL. Changing member variables after creation of this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CLinearTransition
Requirements
Header : afxanimationcontroller.h

CLinearTransition::CLinearTransition
Constructs a linear transition object and initializes it with duration and final value.

CLinearTransition(
UI_ANIMATION_SECONDS duration,
DOUBLE dblFinalValue);

Parameters
duration
The duration of the transition.
dblFinalValue
The value of the animation variable at the end of the transition.

CLinearTransition::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CLinearTransition::m_dblFinalValue
The value of the animation variable at the end of the transition.

DOUBLE m_dblFinalValue;

CLinearTransition::m_duration
The duration of the transition.

UI_ANIMATION_SECONDS m_duration;

See also
Classes
CLinearTransitionFromSpeed Class
3/27/2020 • 2 minutes to read • Edit Online

Encapsulates a linear-speed transition.

Syntax
class CLinearTransitionFromSpeed : public CBaseTransition;

Members
Public Constructors
NAME DESC RIP T IO N

CLinearTransitionFromSpeed::CLinearTransitionFromSpeed Constructs a linear-speed transition object and initializes it


with speed and final value.

Public Methods
NAME DESC RIP T IO N

CLinearTransitionFromSpeed::Create Calls the transition library to create encapsulated transition


COM object. (Overrides CBaseTransition::Create.)

Public Data Members


NAME DESC RIP T IO N

CLinearTransitionFromSpeed::m_dblFinalValue The value of the animation variable at the end of the


transition.

CLinearTransitionFromSpeed::m_dblSpeed The absolute value of the variable's velocity.

Remarks
During a linear-speed transition, the value of the animation variable changes at a specified rate. The duration of the
transition is determined by the difference between the initial value and the specified final value. Because all
transitions are cleared automatically, it's recommended to allocated them using operator new. The encapsulated
IUIAnimationTransition COM object is created by CAnimationController::AnimateGroup, until then it's NULL.
Changing member variables after creation of this COM object has no effect.

Inheritance Hierarchy
CObject
CBaseTransition
CLinearTransitionFromSpeed
Requirements
Header : afxanimationcontroller.h

CLinearTransitionFromSpeed::CLinearTransitionFromSpeed
Constructs a linear-speed transition object and initializes it with speed and final value.

CLinearTransitionFromSpeed(
DOUBLE dblSpeed,
DOUBLE dblFinalValue);

Parameters
dblSpeed
The absolute value of the variable's velocity.
dblFinalValue
The value of the animation variable at the end of the transition.

CLinearTransitionFromSpeed::Create
Calls the transition library to create encapsulated transition COM object.

virtual BOOL Create(


IUIAnimationTransitionLibrary* pLibrary,
IUIAnimationTransitionFactory* \*not used*\);

Parameters
pLibrary
A pointer to an IUIAnimationTransitionLibrary interface, which defines a library of standard transitions.
Return Value
TRUE if transition is created successfully; otherwise FALSE.

CLinearTransitionFromSpeed::m_dblFinalValue
The value of the animation variable at the end of the transition.

DOUBLE m_dblFinalValue;

CLinearTransitionFromSpeed::m_dblSpeed
The absolute value of the variable's velocity.

DOUBLE m_dblSpeed;

See also
Classes
CLinkCtrl Class
3/27/2020 • 9 minutes to read • Edit Online

Provides the functionality of the Windows common SysLink control.

Syntax
class CLinkCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CLinkCtrl::CLinkCtrl Constructs a CLinkCtrl object.

Public Methods
NAME DESC RIP T IO N

CLinkCtrl::Create Creates a link control and attaches it to a CLinkCtrl object.

CLinkCtrl::CreateEx Creates a link control with extended styles and attaches it to a


CLinkCtrl object.

CLinkCtrl::GetIdealHeight Retrieves the ideal height of the link control.

CLinkCtrl::GetIdealSize Calculates the preferred height of the link text for the current
link control, depending on the specified width of the link.

CLinkCtrl::GetItem Retrieves the states and attributes of a link control item.

CLinkCtrl::GetItemID Retrieves the ID of a link control item.

CLinkCtrl::GetItemState Retrieves the state of the link control item.

CLinkCtrl::GetItemUrl Retrieves the URL represented by the link control item.

CLinkCtrl::HitTest Determines whether the user clicked the specified link.

CLinkCtrl::SetItem Sets the states and attributes of a link control item.

CLinkCtrl::SetItemID Sets the ID of a link control item.

CLinkCtrl::SetItemState Sets the state of the link control item.

CLinkCtrl::SetItemUrl Sets the URL represented by the link control item.


Remarks
A "link control" provides a convenient way to embed hypertext links in a window. The actual control is a window
that renders marked-up text and launches appropriate applications when the user clicks an embedded link.
Multiple links are supported within one control and can be accessed by a zero-based index.
This control (and therefore the CLinkCtrl class) is available only to programs running under Windows XP and
later.
For more information, see SysLink Control in the Windows SDK.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CLinkCtrl

Requirements
Header : afxcmn.h

CLinkCtrl::CLinkCtrl
Constructs a CLinkCtrl object.

CLinkCtrl();

CLinkCtrl::Create
Creates a link control and attaches it to a CLinkCtrl object.

virtual BOOL Create(


LPCTSTR lpszLinkMarkup,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

virtual BOOL Create(DWORD dwStyle,


const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
lpszLinkMarkup
Pointer to a zero-terminated string that contains the marked up text to display. For more information, see the
section "Markup and Link Access" in the topic Overview of SysLink Controls.
dwStyle
Specifies the link control's style. Apply any combination of control styles. See Common Control Styles in the
Windows SDK for more information.

rect
Specifies the link control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the link control's parent window. It must not be NULL.
nID
Specifies the link control's ID.
Return Value
TRUE if initialization was successful; otherwise FALSE.
Remarks
You construct a CLinkCtrl object in two steps. First, call the constructor and then call Create , which creates the
link control and attaches it to the CLinkCtrl object. If you want to use extended windows styles with your control,
call CLinkCtrl::CreateEx instead of Create .
The second form of the Create method is deprecated. Use the first form that specifies the lpszLinkMarkup
parameter.
Example
The following code example defines two variables, named m_Link1 and m_Link2 , that are used to access two link
controls.

afx_msg void OnNMClickSyslink1(NMHDR *pNMHDR, LRESULT *pResult);


afx_msg void OnNMClickSyslink2(NMHDR *pNMHDR, LRESULT *pResult);
// Link variable associated with resource editor CLinkCtrl control.
CLinkCtrl m_Link1;
// Link variable associated with programmatic CLinkCtrl control.
CLinkCtrl m_Link2;

Example
The following code example creates one link control based on the location of another link control. The resource
loader creates the first link control when your application starts. When your application enters the OnInitDialog
method, you create the second link control relative to the position of the first link control. Then you resize the
second link control to fit the text that it displays.
CRect rect1, rect2;
int height = 0;
SIZE sz = {0};
PTCHAR url =
_T("Link 2) ")
_T("<A HREF=\"https://visualstudio.microsoft.com\">")
_T("Microsoft VC++ Home")
_T("</A>");
m_Link1.GetWindowRect(&rect1);
m_Link2.Create(url,
(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER),
CRect(
rect1.left, rect1.bottom + rect1.Height(),
rect1.right, rect1.bottom + (2 * rect1.Height())),
this,
IDC_SYSLINK2);
m_Link2.GetClientRect(&rect2);
// The return value of GetIdealSize() is the same as sz.cy
height = m_Link2.GetIdealSize(
rect2.Width(), &sz);
if ((sz.cx != 0) && (sz.cy != 0))
{
int rc = m_Link2.SetWindowPos(
this,
0, 0, sz.cx, sz.cy,
(SWP_NOMOVE | SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOACTIVATE));
}

CLinkCtrl::CreateEx
Creates a link control with extended styles and attaches it to a CLinkCtrl object.

virtual BOOL CreateEx(


LPCTSTR lpszLinkMarkup,
DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

virtual BOOL CreateEx(DWORD dwExStyle,


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
lpszLinkMarkup
Pointer to a zero-terminated string that contains the marked up text to display. For more information, see the
section "Markup and Link Access" in the topic Overview of SysLink Controls.
dwExStyle
Specifies the extended style of the link control. For a list of extended Windows styles, see the dwExStyle parameter
for CreateWindowEx in the Windows SDK.
dwStyle
Specifies the link control's style. Apply any combination of control styles. For more information, see Common
Control Styles in the Windows SDK.
rect
Specifies the link control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the link control's parent window. It must not be NULL.
nID
Specifies the link control's ID.
Return Value
TRUE if initialization was successful; otherwise FALSE.
Remarks
Use CreateEx instead of Create to apply extended Windows style constants.
The second form of the CreateEx method is deprecated. Use the first form that specifies the lpszLinkMarkup
parameter.

CLinkCtrl::GetIdealHeight
Retrieves the ideal height of the link control.

int GetIdealHeight() const;

Return Value
The ideal height of the control, in pixels.
Remarks
This member function implements the behavior of the Win32 message LM_GETIDEALHEIGHT, as described in the
Windows SDK.

CLinkCtrl::GetIdealSize
Calculates the preferred height of the link text for the current link control, depending on the specified width of the
link.

int GetIdealSize(
int cxMaxWidth,
SIZE* pSize) const;

Parameters
PA RA M ET ER DESC RIP T IO N

cxMaxWidth [in] The maximum width of the link, in pixels.

[out] * pSize A pointer to a Windows SIZE structure. When this method


returns, the cy member of the SIZE structure contains the
ideal link text height for the link text width that is specified by
cxMaxWidth. The cx member of the structure contains the link
text width that is actually needed.

Return Value
The preferred height of the link text, in pixels. The return value is the same as the value of the cy member of the
SIZE structure.
Remarks
For an example of the GetIdealSize method, see the example in CLinkCtrl::Create.
This method sends the LM_GETIDEALSIZE message, which is described in the Windows SDK.

CLinkCtrl::GetItem
Retrieves the states and attributes of a link control item.

BOOL GetItem(PLITEM pItem) const;

Parameters
pItem
A pointer to a LITEM structure to receive item information.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function implements the behavior of the Win32 message LM_GETITEM, as described in the Windows
SDK.

CLinkCtrl::GetItemID
Retrieves the ID of a link control item.

BOOL GetItemID(
int iLink,
CString& strID) const;

BOOL GetItemID(
int iLink,
LPWSTR szID,
UINT cchID) const;

Parameters
iLink
The index of a link control item.
strID
A CStringT object containing the ID of the specified item.
szID
A null-terminated string containing the ID of the specified item.
cchID
The size in characters of the szID buffer.
Return Value
Returns TRUE on success, FALSE on failure.

NOTE
This function also returns FALSE if the buffer of szID or strID is smaller than MAX_LINKID_TEXT.
Remarks
Retrieves the ID of a specific link control item. For more information, see the Win32 message LM_GETITEM in the
Windows SDK.

CLinkCtrl::GetItemState
Retrieves the state of the link control item.

BOOL GetItemState(
int iLink,
UINT* pnState,
UINT stateMask = LIS_FOCUSED | LIS_ENABLED | LIS_VISITED) const;

Parameters
iLink
The index of a link control item.
pnState
The value of the specified state item.
stateMask
Combination of flags describing which state item to get. For a list of values, see the description of the state
member in the LITEM structure. Allowable items are identical to those allowed in state .
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
Retrieves the value of the specified state item of a specific link control item. For more information, see the Win32
message LM_GETITEM in the Windows SDK.

CLinkCtrl::GetItemUrl
Retrieves the URL represented by the link control item.

BOOL GetItemUrl(
int iLink,
CString& strUrl) const;

BOOL GetItemUrl(
int iLink,
LPWSTR szUrl,
UINT cchUrl) const;

Parameters
iLink
The index of a link control item.
strUrl
A CStringT object containing the URL represented by the specified item
szUrl
A null-terminated string containing the URL represented by the specified item
cchUrl
The size in characters of the szURL buffer.
Return Value
Returns TRUE on success, FALSE on failure.

NOTE
This function also returns FALSE if the buffer of szUrl or strUrl is smaller than MAX_LINKID_TEXT.

Remarks
Retrieves the URL represented by the specified link control item. For more information, see the Win32 message
LM_GETITEM in the Windows SDK.

CLinkCtrl::HitTest
Determines if the user clicked the specified link.

BOOL HitTest(PLHITTESTINFO phti) const;

Parameters
phti
Pointer to a LHITTESTINFO structure containing any information about the link the user clicked.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function implements the behavior of the Win32 message LM_HITTEST, as described in the Windows
SDK.

CLinkCtrl::SetItem
Sets the states and attributes of a link control item.

BOOL SetItem(PLITEM pItem);

Parameters
pItem
A pointer to a LITEM structure containing the information to set.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function implements the behavior of the Win32 message LM_SETITEM, as described in the Windows
SDK.

CLinkCtrl::SetItemID
Retrieves the ID of a link control item.
BOOL SetItemID(
int iLink,
LPCWSTR szID);

Parameters
iLink
The index of a link control item.
szID
A null-terminated string containing the ID of the specified item.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
Sets the ID of a specific link control item. For more information, see the Win32 message LM_SETITEM in the
Windows SDK.

CLinkCtrl::SetItemState
Retrieves the state of the link control item.

BOOL SetItemState(
int iLink,
UINT state,
UINT stateMask = LIS_FOCUSED | LIS_ENABLED | LIS_VISITED);

Parameters
iLink
The index of a link control item.
pnState
The value of the specified state item being set.
stateMask
Combination of flags describing the state item being set. For a list of values, see the description of the state
member in the LITEM structure. Allowable items are identical to those allowed in state .
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
Sets the value of the specified state item of a specific link control item. For more information, see the Win32
message LM_SETITEM in the Windows SDK.

CLinkCtrl::SetItemUrl
Sets the URL represented by the link control item.

BOOL SetItemUrl(
int iLink,
LPCWSTR szUrl);

Parameters
iLink
The index of a link control item.
szUrl
A null-terminated string containing the URL represented by the specified item
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
Sets the URL represented by the specified link control item. For more information, see the Win32 message
LM_SETITEM in the Windows SDK.

See also
Hierarchy Chart
CWnd Class
CList Class
4/21/2020 • 16 minutes to read • Edit Online

Supports ordered lists of nonunique objects accessible sequentially or by value.

Syntax
template<class TYPE, class ARG_TYPE = const TYPE&>
class CList : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CList::CList Constructs an empty ordered list.

Public Methods
NAME DESC RIP T IO N

CList::AddHead Adds an element (or all the elements in another list) to the
head of the list (makes a new head).

CList::AddTail Adds an element (or all the elements in another list) to the
tail of the list (makes a new tail).

CList::Find Gets the position of an element specified by pointer value.

CList::FindIndex Gets the position of an element specified by a zero-based


index.

CList::GetAt Gets the element at a given position.

CList::GetCount Returns the number of elements in this list.

CList::GetHead Returns the head element of the list (cannot be empty).

CList::GetHeadPosition Returns the position of the head element of the list.

CList::GetNext Gets the next element for iterating.

CList::GetPrev Gets the previous element for iterating.

CList::GetSize Returns the number of elements in this list.

CList::GetTail Returns the tail element of the list (cannot be empty).


NAME DESC RIP T IO N

CList::GetTailPosition Returns the position of the tail element of the list.

CList::InsertAfter Inserts a new element after a given position.

CList::InsertBefore Inserts a new element before a given position.

CList::IsEmpty Tests for the empty list condition (no elements).

CList::RemoveAll Removes all the elements from this list.

CList::RemoveAt Removes an element from this list, specified by position.

CList::RemoveHead Removes the element from the head of the list.

CList::RemoveTail Removes the element from the tail of the list.

CList::SetAt Sets the element at a given position.

Parameters
TYPE
Type of object stored in the list.
ARG_TYPE
Type used to reference objects stored in the list. Can be a reference.

Remarks
CList lists behave like doubly-linked lists.
A variable of type POSITION is a key for the list. You can use a POSITION variable as an iterator to traverse a list
sequentially and as a bookmark to hold a place. A position is not the same as an index, however.
Element insertion is very fast at the list head, at the tail, and at a known POSITION. A sequential search is
necessary to look up an element by value or index. This search can be slow if the list is long.
If you need a dump of individual elements in the list, you must set the depth of the dump context to 1 or greater.
Certain member functions of this class call global helper functions that must be customized for most uses of the
CList class. See Collection Class Helpers in the "Macros and Globals" section.

For more information on using CList , see the article Collections.

Example
// CList is a template class that takes two template arguments.
// The first argument is type stored internally by the list, the
// second argument is the type used in the arguments for the
// CList methods.

// This code defines a list of ints.


CList<int, int> myIntList;

// This code defines a list of CStrings


CList<CString, CString &> myStringList;

// This code defines a list of MYTYPEs,


// NOTE: MYTYPE could be any struct, class or type definition
CList<MYTYPE, MYTYPE &> myTypeList;

Inheritance Hierarchy
CObject
CList

Requirements
Header : afxtempl.h

CList::AddHead
Adds a new element or list of elements to the head of this list.

POSITION AddHead(ARG_TYPE newElement);


void AddHead(CList* pNewList);

Parameters
ARG_TYPE
Template parameter specifying the type of the list element (can be a reference).
newElement
The new element.
pNewList
A pointer to another CList list. The elements in pNewList will be added to this list.
Return Value
The first version returns the POSITION value of the newly inserted element.
Remarks
The list can be empty before the operation.
Example
// Declarations of the variables used in the example
CList<CString, CString &> myList;
CList<CString, CString &> myList2;

// There are two versions of CList::AddHead: one adds a single


// element to the front of the list, the second adds another list
// to the front.

// This adds the string "ABC" to the front of myList.


// myList is a list of CStrings (ie defined as CList<CString,CString&>).
myList.AddHead(CString(_T("ABC")));

// This adds the elements of myList2 to the front of myList.


myList.AddHead(&myList2);

CList::AddTail
Adds a new element or list of elements to the tail of this list.

POSITION AddTail(ARG_TYPE newElement);


void AddTail(CList* pNewList);

Parameters
ARG_TYPE
Template parameter specifying the type of the list element (can be a reference).
newElement
The element to be added to this list.
pNewList
A pointer to another CList list. The elements in pNewList will be added to this list.
Return Value
The first version returns the POSITION value of the newly inserted element.
Remarks
The list can be empty before the operation.
Example
// Define myList and myList2.
CList<CString, CString &> myList;
CList<CString, CString &> myList2;

// Add elements to the end of myList and myList2.


myList.AddTail(CString(_T("A")));
myList.AddTail(CString(_T("B")));
myList2.AddTail(CString(_T("C")));
myList2.AddTail(CString(_T("D")));

// There are two versions of CList::AddTail: one adds a single


// element to the end of the list, the second adds another list
// to the end.

// This adds the string "ABC" to the end of myList.


// myList is a list of CStrings (ie defined as CList<CString,CString&>).
myList.AddTail(CString(_T("ABC")));
ASSERT(CString(_T("ABC")) == myList.GetTail());

// This adds the elements of myList2 to the end of myList.


myList.AddTail(&myList2);

CList::CList
Constructs an empty ordered list.

CList(INT_PTR nBlockSize = 10);

Parameters
nBlockSize
The memory-allocation granularity for extending the list.
Remarks
As the list grows, memory is allocated in units of nBlockSize entries.
Example

// This code defines myList as a list of strings


// such that memory gets allocated in chunks of
// 16 strings.
CList<CString, CString &> myList(16);

// This code defines myList2 as a list of ints


// such that memory gets allocated in chunks of
// 128 ints.
CList<int, int> myList2(128);

CList::Find
Searches the list sequentially to find the first element matching the specified searchValue.

POSITION Find(
ARG_TYPE searchValue,
POSITION startAfter = NULL) const;

Parameters
ARG_TYPE
Template parameter specifying the type of the list element (can be a reference).
searchValue
The value to be found in the list.
startAfter
The start position for the search. If no value is specified, the search begins with the head element.
Return Value
A POSITION value that can be used for iteration or object pointer retrieval; NULL if the object is not found.
Example

// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


myList.AddHead(CString(_T("XYZ")));
myList.AddHead(CString(_T("ABC")));
myList.AddHead(CString(_T("123")));

// Find a specific element.


POSITION pos = myList.Find(CString(_T("XYZ")));
ASSERT(CString(_T("XYZ")) == myList.GetAt(pos));

CList::FindIndex
Uses the value of nIndex as an index into the list.

POSITION FindIndex(INT_PTR nIndex) const;

Parameters
nIndex
The zero-based index of the list element to be found.
Return Value
A POSITION value that can be used for iteration or object pointer retrieval; NULL if nIndex is negative or too large.
Remarks
It starts a sequential scan from the head of the list, stopping on the nth element.
Example

// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


myList.AddTail(CString(_T("XYZ")));
myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Verify the first element (index 0).


ASSERT(CString(_T("XYZ")) == myList.GetAt(myList.FindIndex(0)));

// Verify the third element (index 2).


ASSERT(CString(_T("123")) == myList.GetAt(myList.FindIndex(2)));
CList::GetAt
Gets the list element at a given position.

TYPE& GetAt(POSITION position);


const TYPE& GetAt(POSITION position) const;

Parameters
TYPE
Template parameter specifying the type of object in the list.
position
The position in the list of the element to get.
Return Value
See the return value description for GetHead .
Remarks
GetAt returns the element (or a reference to the element) associated with a given position. It is not the same as
an index, and you cannot operate on a POSITION value yourself. A variable of type POSITION is a key for the list.
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.
Example
See the example for CList::GetHeadPosition.

CList::GetCount
Gets the number of elements in this list.

INT_PTR GetCount() const;

Return Value
An integer value containing the element count.
Remarks
Calling this method will generate the same result as the CList::GetSize method.
Example
See the example for CList::RemoveHead.

CList::GetHead
Gets the head element (or a reference to the head element) of this list.

const TYPE& GetHead() const;

TYPE& GetHead();

Parameters
TYPE
Template parameter specifying the type of object in the list.
Return Value
If the list is const , GetHead returns a copy of the element at the head of the list. This allows the function to be
used only on the right side of an assignment statement and protects the list from modification.
If the list is not const , GetHead returns a reference to the element at the head of the list. This allows the function
to be used on either side of an assignment statement and thus allows the list entries to be modified.
Remarks
You must ensure that the list is not empty before calling GetHead . If the list is empty, then the Debug version of
the Microsoft Foundation Class Library asserts. Use IsEmpty to verify that the list contains elements.
Example

// Define myList.
CList<CString, CString &> myList;

// Add an element to the front of the list.


myList.AddHead(CString(_T("ABC")));

// Verify the element was added to the front of the list.


ASSERT(CString(_T("ABC")) == myList.GetHead());

CList::GetHeadPosition
Gets the position of the head element of this list.

POSITION GetHeadPosition() const;

Return Value
A POSITION value that can be used for iteration or object pointer retrieval; NULL if the list is empty.
Example

// Define myList.
CList<CString, CString &> myList;

// Add an element to the front of the list.


myList.AddHead(CString(_T("ABC")));

// Verify the element at the head position


// is the one added.
POSITION pos = myList.GetHeadPosition();
ASSERT(CString(_T("ABC")) == myList.GetAt(pos));

CList::GetNext
Gets the list element identified by rPosition, then sets rPosition to the POSITION value of the next entry in the list.

TYPE& GetNext(POSITION& rPosition);


const TYPE& GetNext(POSITION& rPosition) const;

Parameters
TYPE
Template parameter specifying the type of the elements in the list.
rPosition
A reference to a POSITION value returned by a previous GetNext , GetHeadPosition, or other member function
call.
Return Value
If the list is const , GetNext returns a copy of an element of the list. This allows the function to be used only on the
right side of an assignment statement and protects the list from modification.
If the list is not const , GetNext returns a reference to an element of the list. This allows the function to be used on
either side of an assignment statement and thus allows the list entries to be modified.
Remarks
You can use GetNext in a forward iteration loop if you establish the initial position with a call to GetHeadPosition
or Find .
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.
If the retrieved element is the last in the list, then the new value of rPosition is set to NULL.
Example

// Define myList.
// Define myList.
CList<CString, CString &> myList;

// Add two elements to the list.


myList.AddHead(CString(_T("ABC")));
myList.AddHead(CString(_T("123")));

// Dump the list elements to the debug window.


POSITION pos = myList.GetHeadPosition();
for (int i = 0; i < myList.GetCount(); i++)
{
TRACE(_T("%s\r\n"), (LPCTSTR)myList.GetNext(pos));
}

CList::GetPrev
Gets the list element identified by rPosition , then sets rPosition to the POSITION value of the previous entry in
the list.

TYPE& GetPrev(POSITION& rPosition);


const TYPE& GetPrev(POSITION& rPosition) const;

Parameters
TYPE
Template parameter specifying the type of the elements in the list.
rPosition
A reference to a POSITION value returned by a previous GetPrev or other member function call.
Return Value
If the list is const , GetPrev returns a copy of the element at the head of the list. This allows the function to be
used only on the right side of an assignment statement and protects the list from modification.
If the list is not const , GetPrev returns a reference to an element of the list. This allows the function to be used on
either side of an assignment statement and thus allows the list entries to be modified.
Remarks
You can use GetPrev in a reverse iteration loop if you establish the initial position with a call to GetTailPosition
or Find .
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.
If the retrieved element is the first in the list, then the new value of rPosition is set to NULL.
Example

// Define myList.
CList<CString,CString&> myList;

// Add two elements to the list.


myList.AddHead(CString(_T("ABC")));
myList.AddHead(CString(_T("123")));

// Dump the list elements to the debug window,


// in reverse order.
POSITION pos = myList.GetTailPosition();
for (int i = 0; i < myList.GetCount(); i++)
{
TRACE(_T("%s\r\n"), (LPCTSTR)myList.GetPrev(pos));
}

CList::GetSize
Returns the number of list elements.

INT_PTR GetSize() const;

Return Value
The number of items in the list.
Remarks
Call this method to retrieve the number of elements in the list. Calling this method will generate the same result
as the CList::GetCount method.
Example

// Define myList.
CList<CString, CString &> myList;

// Add two elements to the list.


myList.AddHead(CString(_T("ABC")));
myList.AddHead(CString(_T("123")));

// Remove the head element and verify the list.


// NOTE: once the head is removed, the number of
// elements in the list will be one.
CString strHead = myList.RemoveHead();
ASSERT((CString(_T("123")) == strHead) && (myList.GetSize() == 1) &&
(CString(_T("ABC")) == myList.GetHead()));

CList::GetTail
Gets the CObject pointer that represents the tail element of this list.

TYPE& GetTail();
const TYPE& GetTail() const;

Parameters
TYPE
Template parameter specifying the type of elements in the list.
Return Value
See the return value description for GetHead.
Remarks
You must ensure that the list is not empty before calling GetTail . If the list is empty, then the Debug version of
the Microsoft Foundation Class Library asserts. Use IsEmpty to verify that the list contains elements.
Example

// Define myList.
CList<CString, CString &> myList;

// Add an element to the end of the list.


myList.AddTail(CString(_T("ABC")));

// Verify the element was added to the end of the list.


ASSERT(CString(_T("ABC")) == myList.GetTail());

CList::GetTailPosition
Gets the position of the tail element of this list; NULL if the list is empty.

POSITION GetTailPosition() const;

Return Value
A POSITION value that can be used for iteration or object pointer retrieval; NULL if the list is empty.
Example

// Define myList.
CList<CString,CString&> myList;

// Add an element to the end of the list.


myList.AddTail(CString(_T("ABC")));

// Verify the element at the end position


// is the one added.
POSITION pos = myList.GetTailPosition();
ASSERT(CString(_T("ABC")) == myList.GetAt(pos));

CList::InsertAfter
Adds an element to this list after the element at the specified position.

POSITION InsertAfter(POSITION position, ARG_TYPE newElement);


Parameters
position
A POSITION value returned by a previous GetNext , GetPrev , or Find member function call.
ARG_TYPE
Template parameter specifying the type of the list element.
newElement
The element to be added to this list.
Return Value
A POSITION value that can be used for iteration or list element retrieval.
Example

// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


POSITION pos = myList.AddHead(CString(_T("XYZ")));
pos = myList.InsertAfter(pos, CString(_T("ABC")));
pos = myList.InsertAfter(pos, CString(_T("123")));

// Verify the tail element is what's expected.


ASSERT(CString(_T("123")) == myList.GetTail());

CList::InsertBefore
Adds an element to this list before the element at the specified position.

POSITION InsertBefore(POSITION position, ARG_TYPE newElement);

Parameters
position
A POSITION value returned by a previous GetNext , GetPrev , or Find member function call.
ARG_TYPE
Template parameter specifying the type of the list element (can be a reference).
newElement
The element to be added to this list.
Return Value
A POSITION value that can be used for iteration or list element retrieval.
Remarks
If position is NULL, the element is inserted at the head of the list.
Example
// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


POSITION pos = myList.AddHead(CString(_T("XYZ")));
pos = myList.InsertBefore(pos, CString(_T("ABC")));
pos = myList.InsertBefore(pos, CString(_T("123")));

// Verify the head element is what's expected.


ASSERT(CString(_T("123")) == myList.GetHead());

CList::IsEmpty
Indicates whether this list contains no elements.

BOOL IsEmpty() const;

Return Value
Nonzero if this list is empty; otherwise 0.
Example

// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


myList.AddTail(CString(_T("XYZ")));
myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Remove the head element until the list is empty.


CString str;
while (!myList.IsEmpty())
{
str = myList.RemoveHead();
TRACE(_T("%s\r\n"), (LPCTSTR)str);
}

CList::RemoveAll
Removes all the elements from this list and frees the associated memory.

void RemoveAll();

Remarks
No error is generated if the list is already empty.
Example
// Define myList.
CList<CString, CString&> myList;

// Add three elements to the list.


myList.AddTail(CString(_T("XYZ")));
myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Remove all of the elements in the list.


myList.RemoveAll();

// Verify the list is empty.


ASSERT(myList.IsEmpty());

CList::RemoveAt
Removes the specified element from this list.

void RemoveAt(POSITION position);

Parameters
position
The position of the element to be removed from the list.
Remarks
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.
Example

// Define myList.
CList<CString, CString&> myList;

// Add three elements to the list.


myList.AddTail(CString(_T("XYZ")));
myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Remove CString("ABC") from the list.


myList.RemoveAt(myList.FindIndex(1));

// Verify CString("ABC") is not in the list.


ASSERT(myList.Find(CString(_T("ABC"))) == NULL);

CList::RemoveHead
Removes the element from the head of the list and returns a pointer to it.

TYPE RemoveHead();

Parameters
TYPE
Template parameter specifying the type of elements in the list.
Return Value
The element previously at the head of the list.
Remarks
You must ensure that the list is not empty before calling RemoveHead . If the list is empty, then the Debug version of
the Microsoft Foundation Class Library asserts. Use IsEmpty to verify that the list contains elements.
Example

// Define myList.
CList<CString, CString&> myList;

// Add two elements to the list.


myList.AddHead(CString(_T("ABC")));
myList.AddHead(CString(_T("123")));

// Remove the head element and verify the list.


// NOTE: once the head is removed, the number of
// elements in the list will be one.
CString strHead = myList.RemoveHead();
ASSERT((CString(_T("123")) == strHead) && (myList.GetCount() == 1) &&
(CString(_T("ABC")) == myList.GetHead()));

CList::RemoveTail
Removes the element from the tail of the list and returns a pointer to it.

TYPE RemoveTail();

Parameters
TYPE
Template parameter specifying the type of elements in the list.
Return Value
The element that was at the tail of the list.
Remarks
You must ensure that the list is not empty before calling RemoveTail . If the list is empty, then the Debug version of
the Microsoft Foundation Class Library asserts. Use IsEmpty to verify that the list contains elements.
Example

// Define myList.
CList<CString, CString &> myList;

// Add two elements to the list.


myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Remove the tail element and verify the list.


// NOTE: once the tail is removed, the number of
// elements in the list will be one.
CString strTail = myList.RemoveTail();
ASSERT((CString(_T("123")) == strTail) && (myList.GetCount() == 1) &&
(CString(_T("ABC")) == myList.GetTail()));

CList::SetAt
A variable of type POSITION is a key for the list.
void SetAt(POSITION pos, ARG_TYPE newElement);

Parameters
pos
The POSITION of the element to be set.
ARG_TYPE
Template parameter specifying the type of the list element (can be a reference).
newElement
The element to be added to the list.
Remarks
It is not the same as an index, and you cannot operate on a POSITION value yourself. SetAt writes the element to
the specified position in the list.
You must ensure that your POSITION value represents a valid position in the list. If it is invalid, then the Debug
version of the Microsoft Foundation Class Library asserts.
Example

// Define myList.
CList<CString, CString &> myList;

// Add three elements to the list.


myList.AddTail(CString(_T("XYZ")));
myList.AddTail(CString(_T("ABC")));
myList.AddTail(CString(_T("123")));

// Replace CString("ABC") with CString("CBA")


POSITION pos = myList.Find(CString(_T("ABC")));
myList.SetAt(pos, CString(_T("CBA")));

// Verify CString("ABC") is not in the list.


ASSERT(myList.Find(CString(_T("ABC"))) == NULL);

See also
MFC Sample COLLECT
CObject Class
Hierarchy Chart
CMap Class
CArray Class
CListBox Class
4/21/2020 • 40 minutes to read • Edit Online

Provides the functionality of a Windows list box.

Syntax
class CListBox : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CListBox::CListBox Constructs a CListBox object.

Public Methods
NAME DESC RIP T IO N

CListBox::AddString Adds a string to a list box.

CListBox::CharToItem Override to provide custom WM_CHAR handling for owner-


draw list boxes which don't have strings.

CListBox::CompareItem Called by the framework to determine the position of a new


item in a sorted owner-draw list box.

CListBox::Create Creates the Windows list box and attaches it to the


CListBox object.

CListBox::DeleteItem Called by the framework when the user deletes an item


from an owner-draw list box.

CListBox::DeleteString Deletes a string from a list box.

CListBox::Dir Adds filenames, drives, or both from the current directory


to a list box.

CListBox::DrawItem Called by the framework when a visual aspect of an owner-


draw list box changes.

CListBox::FindString Searches for a string in a list box.

CListBox::FindStringExact Finds the first list-box string that matches a specified string.

CListBox::GetAnchorIndex Retrieves the zero-based index of the current anchor item in


a list box.
NAME DESC RIP T IO N

CListBox::GetCaretIndex Determines the index of the item that has the focus
rectangle in a multiple-selection list box.

CListBox::GetCount Returns the number of strings in a list box.

CListBox::GetCurSel Returns the zero-based index of the currently selected string


in a list box.

CListBox::GetHorizontalExtent Returns the width in pixels that a list box can be scrolled
horizontally.

CListBox::GetItemData Returns a value associated with the list-box item.

CListBox::GetItemDataPtr Returns a pointer to a list-box item.

CListBox::GetItemHeight Determines the height of items in a list box.

CListBox::GetItemRect Returns the bounding rectangle of the list-box item as it is


currently displayed.

CListBox::GetListBoxInfo Retrieves the number of items per column.

CListBox::GetLocale Retrieves the locale identifier for a list box.

CListBox::GetSel Returns the selection state of a list-box item.

CListBox::GetSelCount Returns the number of strings currently selected in a


multiple-selection list box.

CListBox::GetSelItems Returns the indices of the strings currently selected in a list


box.

CListBox::GetText Copies a list-box item into a buffer.

CListBox::GetTextLen Returns the length in bytes of a list-box item.

CListBox::GetTopIndex Returns the index of the first visible string in a list box.

CListBox::InitStorage Preallocates blocks of memory for list box items and strings.

CListBox::InsertString Inserts a string at a specific location in a list box.

CListBox::ItemFromPoint Returns the index of the list-box item nearest a point.

CListBox::MeasureItem Called by the framework when an owner-draw list box is


created to determine list-box dimensions.

CListBox::ResetContent Clears all the entries from a list box.

CListBox::SelectString Searches for and selects a string in a single-selection list


box.
NAME DESC RIP T IO N

CListBox::SelItemRange Selects or deselects a range of strings in a multiple-selection


list box.

CListBox::SetAnchorIndex Sets the anchor in a multiple-selection list box to begin an


extended selection.

CListBox::SetCaretIndex Sets the focus rectangle to the item at the specified index in
a multiple-selection list box.

CListBox::SetColumnWidth Sets the column width of a multicolumn list box.

CListBox::SetCurSel Selects a list-box string.

CListBox::SetHorizontalExtent Sets the width in pixels that a list box can be scrolled
horizontally.

CListBox::SetItemData Sets a value associated with the list-box item.

CListBox::SetItemDataPtr Sets a pointer to the list-box item.

CListBox::SetItemHeight Sets the height of items in a list box.

CListBox::SetLocale Sets the locale identifier for a list box.

CListBox::SetSel Selects or deselects a list-box item in a multiple-selection list


box.

CListBox::SetTabStops Sets the tab-stop positions in a list box.

CListBox::SetTopIndex Sets the zero-based index of the first visible string in a list
box.

CListBox::VKeyToItem Override to provide custom WM_KEYDOWN handling for


list boxes with the LBS_WANTKEYBOARDINPUT style set.

Remarks
A list box displays a list of items, such as filenames, that the user can view and select.
In a single-selection list box, the user can select only one item. In a multiple-selection list box, a range of items
can be selected. When the user selects an item, it is highlighted and the list box sends a notification message to
the parent window.
You can create a list box either from a dialog template or directly in your code. To create it directly, construct the
CListBox object, then call the Create member function to create the Windows list-box control and attach it to
the CListBox object. To use a list box in a dialog template, declare a list-box variable in your dialog box class,
then use DDX_Control in your dialog box class's DoDataExchange function to connect the member variable to
the control. (this is done for you automatically when you add a control variable to your dialog box class.)
Construction can be a one-step process in a class derived from CListBox . Write a constructor for the derived
class and call Create from within the constructor.
If you want to handle Windows notification messages sent by a list box to its parent (usually a class derived
from CDialog), add a message-map entry and message-handler member function to the parent class for each
message.
Each message-map entry takes the following form:
ON_Notification( id, memberFxn )

where id specifies the child window ID of the list-box control sending the notification and memberFxn is the
name of the parent member function you have written to handle the notification.
The parent's function prototype is as follows:
afx_msg void memberFxn( );

Following is a list of potential message-map entries and a description of the cases in which they would be sent
to the parent:
ON_LBN_DBLCLK The user double-clicks a string in a list box. Only a list box that has the LBS_NOTIFY
style will send this notification message.
ON_LBN_ERRSPACE The list box cannot allocate enough memory to meet the request.
ON_LBN_KILLFOCUS The list box is losing the input focus.
ON_LBN_SELCANCEL The current list-box selection is canceled. This message is only sent when a list box
has the LBS_NOTIFY style.
ON_LBN_SELCHANGE The selection in the list box has changed. This notification is not sent if the
selection is changed by the CListBox::SetCurSel member function. This notification applies only to a list
box that has the LBS_NOTIFY style. The LBN_SELCHANGE notification message is sent for a multiple-
selection list box whenever the user presses an arrow key, even if the selection does not change.
ON_LBN_SETFOCUS The list box is receiving the input focus.
ON_WM_CHARTOITEM An owner-draw list box that has no strings receives a WM_CHAR message.
ON_WM_VKEYTOITEM A list box with the LBS_WANTKEYBOARDINPUT style receives a WM_KEYDOWN
message.
If you create a CListBox object within a dialog box (through a dialog resource), the CListBox object is
automatically destroyed when the user closes the dialog box.
If you create a CListBox object within a window, you may need to destroy the CListBox object. If you create
the CListBox object on the stack, it is destroyed automatically. If you create the CListBox object on the heap
by using the new function, you must call delete on the object to destroy it when the user closes the parent
window.
If you allocate any memory in the CListBox object, override the CListBox destructor to dispose of the
allocation.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CListBox
Requirements
Header : afxwin.h

CListBox::AddString
Adds a string to a list box.

int AddString(LPCTSTR lpszItem);

Parameters
lpszItem
Points to the null-terminated string that is to be added.
Return Value
The zero-based index to the string in the list box. The return value is LB_ERR if an error occurs; the return value
is LB_ERRSPACE if insufficient space is available to store the new string.
Remarks
If the list box was not created with the LBS_SORT style, the string is added to the end of the list. Otherwise, the
string is inserted into the list, and the list is sorted. If the list box was created with the LBS_SORT style but not
the LBS_HASSTRINGS style, the framework sorts the list by one or more calls to the CompareItem member
function.
Use InsertString to insert a string into a specific location within the list box.
Example

// Add 10 items to the list box.


CString str;
for (int i = 0; i < 10; i++)
{
str.Format(_T("item string %d"), i);
m_myListBox.AddString(str);
}

CListBox::CharToItem
Called by the framework when the list box's parent window receives a WM_CHARTOITEM message from the list
box.

virtual int CharToItem(


UINT nKey,
UINT nIndex);

Parameters
nKey
The ANSI code of the character the user typed.
nIndex
The current position of the list-box caret.
Return Value
Returns - 1 or - 2 for no further action or a nonnegative number to specify an index of a list-box item on which
to perform the default action for the keystroke. The default implementation returns - 1.
Remarks
The WM_CHARTOITEM message is sent by the list box when it receives a WM_CHAR message, but only if the
list box meets all of these criteria:
Is an owner-draw list box.
Does not have the LBS_HASSTRINGS style set.
Has at least one item.
You should never call this function yourself. Override this function to provide your own custom handling of
keyboard messages.
In your override, you must return a value to tell the framework what action you performed. A return value of -
1 or - 2 indicates that you handled all aspects of selecting the item and requires no further action by the list
box. Before returning - 1 or - 2, you could set the selection or move the caret or both. To set the selection, use
SetCurSel or SetSel. To move the caret, use SetCaretIndex.
A return value of 0 or greater specifies the index of an item in the list box and indicates that the list box should
perform the default action for the keystroke on the given item.
Example

// CMyODListBox is my owner-drawn list box derived from CListBox. This


// example moves the caret down one item on a numeric key and up one item
// on an alphabetic key. The list box control was created with the
// following code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
int CMyODListBox::CharToItem(UINT nChar, UINT nIndex)
{
// On a numeric key, move the caret up one item.
if (isdigit(nChar) && (nIndex > 0))
{
SetCaretIndex(nIndex - 1);
}
// On an alphabetic key, move the caret down one item.
else if (isalpha(nChar) && (nIndex < (UINT)GetCount()))
{
SetCaretIndex(nIndex + 1);
}

// Do not perform any default processing.


return -1;
}

CListBox::CListBox
Constructs a CListBox object.

CListBox();

Remarks
You construct a CListBox object in two steps. First, call the constructor ClistBox and then call Create , which
initializes the Windows list box and attaches it to the CListBox .
Example

// Declare a local CListBox object.


CListBox myListBox;

// Declare a dynamic CListBox object.


CListBox *pmyListBox = new CListBox;

CListBox::CompareItem
Called by the framework to determine the relative position of a new item in a sorted owner-draw list box.

virtual int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);

Parameters
lpCompareItemStruct
A long pointer to a COMPAREITEMSTRUCT structure.
Return Value
Indicates the relative position of the two items described in the COMPAREITEMSTRUCT structure. It may be any
of the following values:

VA L UE M EA N IN G

-1 Item 1 sorts before item 2.

0 Item 1 and item 2 sort the same.

1 Item 1 sorts after item 2.

See CWnd::OnCompareItem for a description of the COMPAREITEMSTRUCT structure.


Remarks
By default, this member function does nothing. If you create an owner-draw list box with the LBS_SORT style,
you must override this member function to assist the framework in sorting new items added to the list box.
Example
// CMyODListBox is my owner-drawn list box derived from CListBox. This
// example compares two items using _tcscmp to sort items in reverse
// alphabetical order. The list box control was created with the
// following code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
int CMyODListBox::CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct)
{
ASSERT(lpCompareItemStruct->CtlType == ODT_LISTBOX);
LPCTSTR lpszText1 = (LPCTSTR)lpCompareItemStruct->itemData1;
ASSERT(lpszText1 != NULL);
LPCTSTR lpszText2 = (LPCTSTR)lpCompareItemStruct->itemData2;
ASSERT(lpszText2 != NULL);

return _tcscmp(lpszText2, lpszText1);


}

CListBox::Create
Creates the Windows list box and attaches it to the CListBox object.

virtual BOOL Create(


DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the style of the list box. Apply any combination of list-box styles to the box.
rect
Specifies the list-box size and position. Can be either a CRect object or a RECT structure.
pParentWnd
Specifies the list box's parent window (usually a CDialog object). It must not be NULL.
nID
Specifies the list box's control ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
You construct a CListBox object in two steps. First, call the constructor and then call Create , which initializes
the Windows list box and attaches it to the CListBox object.
When Create executes, Windows sends the WM_NCCREATE, WM_CREATE, WM_NCCALCSIZE, and
WM_GETMINMAXINFO messages to the list-box control.
These messages are handled by default by the OnNcCreate, OnCreate, OnNcCalcSize, and OnGetMinMaxInfo
member functions in the CWnd base class. To extend the default message handling, derive a class from
CListBox , add a message map to the new class, and override the preceding message-handler member
functions. Override OnCreate , for example, to perform needed initialization for a new class.
Apply the following window styles to a list-box control.
WS_CHILD Always
WS_VISIBLE Usually
WS_DISABLED Rarely
WS_VSCROLL To add a vertical scroll bar
WS_HSCROLL To add a horizontal scroll bar
WS_GROUP To group controls
WS_TABSTOP To allow tabbing to this control
Example

// pParentWnd is a pointer to the parent window.


m_myListBox.Create(WS_CHILD | WS_VISIBLE | LBS_STANDARD | WS_HSCROLL,
CRect(10, 10, 200, 200), pParentWnd, IDC_MYLISTBOX);

CListBox::DeleteItem
Called by the framework when the user deletes an item from an owner-draw CListBox object or destroys the
list box.

virtual void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);

Parameters
lpDeleteItemStruct
A long pointer to a Windows DELETEITEMSTRUCT structure that contains information about the deleted item.
Remarks
The default implementation of this function does nothing. Override this function to redraw an owner-draw list
box as needed.
See CWnd::OnDeleteItem for a description of the DELETEITEMSTRUCT structure.
Example

// CMyODListBox is my owner-drawn list box derived from CListBox. This


// example simply frees the item's text. The list box control was created
// with the following code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
void CMyODListBox::DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct)
{
ASSERT(lpDeleteItemStruct->CtlType == ODT_LISTBOX);
LPVOID lpszText = (LPVOID)lpDeleteItemStruct->itemData;
ASSERT(lpszText != NULL);

free(lpszText);

CListBox::DeleteItem(lpDeleteItemStruct);
}
CListBox::DeleteString
Deletes the item in position nIndex from the list box.

int DeleteString(UINT nIndex);

Parameters
nIndex
Specifies the zero-based index of the string to be deleted.
Return Value
A count of the strings remaining in the list. The return value is LB_ERR if nIndex specifies an index greater than
the number of items in the list.
Remarks
All items following nIndex now move down one position. For example, if a list box contains two items, deleting
the first item will cause the remaining item to now be in the first position. nIndex=0 for the item in the first
position.
Example

// Delete every other item from the list box.


for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.DeleteString(i);
}

CListBox::Dir
Adds a list of filenames, drives, or both to a list box.

int Dir(
UINT attr,
LPCTSTR lpszWildCard);

Parameters
attr
Can be any combination of the enum values described in CFile::GetStatu s, or any combination of the
following values:

VA L UE M EA N IN G

0x0000 File can be read from or written to.

0x0001 File can be read from but not written to.

0x0002 File is hidden and does not appear in a directory listing.

0x0004 File is a system file.

0x0010 The name specified by lpszWildCard specifies a directory.


VA L UE M EA N IN G

0x0020 File has been archived.

0x4000 Include all drives that match the name specified by


lpszWildCard.

0x8000 Exclusive flag. If the exclusive flag is set, only files of the
specified type are listed. Otherwise, files of the specified
type are listed in addition to "normal" files.

lpszWildCard
Points to a file-specification string. The string can contain wildcards (for example, *.*).
Return Value
The zero-based index of the last filename added to the list. The return value is LB_ERR if an error occurs; the
return value is LB_ERRSPACE if insufficient space is available to store the new strings.
Example

// Add all the files and directories in the windows directory.


TCHAR lpszWinPath[MAX_PATH], lpszOldPath[MAX_PATH];
::GetWindowsDirectory(lpszWinPath, MAX_PATH);

::GetCurrentDirectory(MAX_PATH, lpszOldPath);
::SetCurrentDirectory(lpszWinPath);

m_myListBox.ResetContent();
m_myListBox.Dir(DDL_READWRITE | DDL_DIRECTORY, _T("*.*"));

::SetCurrentDirectory(lpszOldPath);

CListBox::DrawItem
Called by the framework when a visual aspect of an owner-draw list box changes.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A long pointer to a DRAWITEMSTRUCT structure that contains information about the type of drawing required.
Remarks
The itemAction and itemState members of the DRAWITEMSTRUCT structure define the drawing action that is to
be performed.
By default, this member function does nothing. Override this member function to implement drawing for an
owner-draw CListBox object. The application should restore all graphics device interface (GDI) objects selected
for the display context supplied in lpDrawItemStruct before this member function terminates.
See CWnd::OnDrawItem for a description of the DRAWITEMSTRUCT structure.
Example
// CMyODListBox is my owner-drawn list box derived from CListBox. This
// example draws an item's text centered vertically and horizontally. The
// list box control was created with the following code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
void CMyODListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct->CtlType == ODT_LISTBOX);
LPCTSTR lpszText = (LPCTSTR)lpDrawItemStruct->itemData;
ASSERT(lpszText != NULL);
CDC dc;

dc.Attach(lpDrawItemStruct->hDC);

// Save these value to restore them when done drawing.


COLORREF crOldTextColor = dc.GetTextColor();
COLORREF crOldBkColor = dc.GetBkColor();

// If this item is selected, set the background color


// and the text color to appropriate values. Also, erase
// rect by filling it with the background color.
if ((lpDrawItemStruct->itemAction | ODA_SELECT) &&
(lpDrawItemStruct->itemState & ODS_SELECTED))
{
dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
dc.FillSolidRect(&lpDrawItemStruct->rcItem,
::GetSysColor(COLOR_HIGHLIGHT));
}
else
{
dc.FillSolidRect(&lpDrawItemStruct->rcItem, crOldBkColor);
}

// If this item has the focus, draw a red frame around the
// item's rect.
if ((lpDrawItemStruct->itemAction | ODA_FOCUS) &&
(lpDrawItemStruct->itemState & ODS_FOCUS))
{
CBrush br(RGB(255, 0, 0));
dc.FrameRect(&lpDrawItemStruct->rcItem, &br);
}

// Draw the text.


dc.DrawText(
lpszText,
(int)_tcslen(lpszText),
&lpDrawItemStruct->rcItem,
DT_CENTER | DT_SINGLELINE | DT_VCENTER);

// Reset the background color and the text color back to their
// original values.
dc.SetTextColor(crOldTextColor);
dc.SetBkColor(crOldBkColor);

dc.Detach();
}

CListBox::FindString
Finds the first string in a list box that contains the specified prefix without changing the list-box selection.
int FindString(
int nStartAfter,
LPCTSTR lpszItem) const;

Parameters
nStartAfter
Contains the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nStartAfter. If
nStartAfter is -1, the entire list box is searched from the beginning.
lpszItem
Points to the null-terminated string that contains the prefix to search for. The search is case independent, so this
string may contain any combination of uppercase and lowercase letters.
Return Value
The zero-based index of the matching item, or LB_ERR if the search was unsuccessful.
Remarks
Use the SelectString member function to both find and select a string.
Example

// The string to match.


LPCTSTR lpszmyString = _T("item");

// Delete all items that begin with the specified string.


int nIndex = 0;
while ((nIndex = m_myListBox.FindString(nIndex, lpszmyString)) != LB_ERR)
{
m_myListBox.DeleteString(nIndex);
}

CListBox::FindStringExact
Finds the first list-box string that matches the string specified in lpszFind.

int FindStringExact(
int nIndexStart,
LPCTSTR lpszFind) const;

Parameters
nIndexStart
Specifies the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nIndexStart. If
nIndexStart is -1, the entire list box is searched from the beginning.
lpszFind
Points to the null-terminated string to search for. This string can contain a complete filename, including the
extension. The search is not case sensitive, so the string can contain any combination of uppercase and
lowercase letters.
Return Value
The index of the matching item, or LB_ERR if the search was unsuccessful.
Remarks
If the list box was created with an owner-draw style but without the LBS_HASSTRINGS style, the
FindStringExact member function attempts to match the doubleword value against the value of lpszFind.

Example

// The string to match.


LPCTSTR lpszmyString = _T("item string 3");

// Delete all items that exactly match the specified string.


int nIndex = 0;
while ((nIndex = m_myListBox.FindStringExact(nIndex, lpszmyString)) != LB_ERR)
{
m_myListBox.DeleteString(nIndex);
}

CListBox::GetAnchorIndex
Retrieves the zero-based index of the current anchor item in the list box.

int GetAnchorIndex() const;

Return Value
The index of the current anchor item, if successful; otherwise LB_ERR.
Remarks
In a multiple-selection list box, the anchor item is the first or last item in a block of contiguous selected items.
Example
See the example for CListBox::SetAnchorIndex.

CListBox::GetCaretIndex
Determines the index of the item that has the focus rectangle in a multiple-selection list box.

int GetCaretIndex() const;

Return Value
The zero-based index of the item that has the focus rectangle in a list box. If the list box is a single-selection list
box, the return value is the index of the item that is selected, if any.
Remarks
The item may or may not be selected.
Example
See the example for CListBox::SetCaretIndex.

CListBox::GetCount
Retrieves the number of items in a list box.

int GetCount() const;

Return Value
The number of items in the list box, or LB_ERR if an error occurs.
Remarks
The returned count is one greater than the index value of the last item (the index is zero-based).
Example

// Add 10 items to the list box.


CString str;
for (int i = 0; i < 10; i++)
{
str.Format(_T("item %d"), i);
m_myListBox.AddString(str);
}

// Verify that 10 items were added to the list box.


ASSERT(m_myListBox.GetCount() == 10);

CListBox::GetCurSel
Retrieves the zero-based index of the currently selected item, if any, in a single-selection list box.

int GetCurSel() const;

Return Value
The zero-based index of the currently selected item if it is a single-selection list box. It is LB_ERR if no item is
currently selected.
In a multiple-selection list box, the index of the item that has the focus.
Remarks
Do not call GetCurSel for a multiple-selection list box. Use CListBox::GetSelItems instead.
Example

// Select the next item of the currently selected one.


int nIndex = m_myListBox.GetCurSel();
int nCount = m_myListBox.GetCount();
if ((nIndex != LB_ERR) && (nCount > 1))
{
if (++nIndex < nCount)
m_myListBox.SetCurSel(nIndex);
else
m_myListBox.SetCurSel(0);
}

CListBox::GetHorizontalExtent
Retrieves from the list box the width in pixels by which it can be scrolled horizontally.

int GetHorizontalExtent() const;

Return Value
The scrollable width of the list box, in pixels.
Remarks
This is applicable only if the list box has a horizontal scroll bar.
Example

// Find the longest string in the list box.


CString str;
CSize sz;
int dx = 0;
CDC *pDC = m_myListBox.GetDC();
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.GetText(i, str);
sz = pDC->GetTextExtent(str);

if (sz.cx > dx)


dx = sz.cx;
}
m_myListBox.ReleaseDC(pDC);

// Set the horizontal extent only if the current extent is not large enough.
if (m_myListBox.GetHorizontalExtent() < dx)
{
m_myListBox.SetHorizontalExtent(dx);
ASSERT(m_myListBox.GetHorizontalExtent() == dx);
}

CListBox::GetItemData
Retrieves the application-supplied doubleword value associated with the specified list-box item.

DWORD_PTR GetItemData(int nIndex) const;

Parameters
nIndex
Specifies the zero-based index of the item in the list box.
Return Value
The value associated with the item, or LB_ERR if an error occurs.
Remarks
The doubleword value was the dwItemData parameter of a SetItemData call.
Example

// If any item's data is equal to zero then reset it to -1.


for (int i = 0; i < m_myListBox.GetCount(); i++)
{
if (m_myListBox.GetItemData(i) == 0)
{
m_myListBox.SetItemData(i, (DWORD)-1);
}
}

CListBox::GetItemDataPtr
Retrieves the application-supplied 32-bit value associated with the specified list-box item as a pointer (void * ).
void* GetItemDataPtr(int nIndex) const;

Parameters
nIndex
Specifies the zero-based index of the item in the list box.
Return Value
Retrieves a pointer, or -1 if an error occurs.
Example

LPVOID lpmyPtr = pParentWnd;

// Check all the items in the list box; if an item's


// data pointer is equal to my pointer then reset it to NULL.
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
if (m_myListBox.GetItemDataPtr(i) == lpmyPtr)
{
m_myListBox.SetItemDataPtr(i, NULL);
}
}

CListBox::GetItemHeight
Determines the height of items in a list box.

int GetItemHeight(int nIndex) const;

Parameters
nIndex
Specifies the zero-based index of the item in the list box. This parameter is used only if the list box has the
LBS_OWNERDRAWVARIABLE style; otherwise, it should be set to 0.
Return Value
The height, in pixels, of the items in the list box. If the list box has the LBS_OWNERDRAWVARIABLE style, the
return value is the height of the item specified by nIndex. If an error occurs, the return value is LB_ERR.
Example

// Set the height of every item so the item


// is completely visible.
CString str;
CSize sz;
CDC *pDC = m_myListBox.GetDC();
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.GetText(i, str);
sz = pDC->GetTextExtent(str);

// Only want to set the item height if the current height


// is not big enough.
if (m_myListBox.GetItemHeight(i) < sz.cy)
m_myListBox.SetItemHeight(i, sz.cy);
}
m_myListBox.ReleaseDC(pDC);
CListBox::GetItemRect
Retrieves the dimensions of the rectangle that bounds a list-box item as it is currently displayed in the list-box
window.

int GetItemRect(
int nIndex,
LPRECT lpRect) const;

Parameters
nIndex
Specifies the zero-based index of the item.
lpRect
Specifies a long pointer to a RECT structure that receives the list-box client coordinates of the item.
Return Value
LB_ERR if an error occurs.
Example

// Dump all of the items bounds.


CString str;
RECT r;
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.GetItemRect(i, &r);

str.Format(_T("item %d: left = %d, top = %d, right = %d, ")


_T("bottom = %d\r\n"),
i,
r.left,
r.top,
r.right,
r.bottom);
AFXDUMP(str);
}

CListBox::GetListBoxInfo
Retrieves the number of items per column.

DWORD GetListBoxInfo() const;

Return Value
Number of items per column of the CListBox object.
Remarks
This member function emulates the functionality of the LB_GETLISTBOXINFO message, as described in the
Windows SDK.

CListBox::GetLocale
Retrieves the locale used by the list box.
LCID GetLocale() const;

Return Value
The locale identifier (LCID) value for the strings in the list box.
Remarks
The locale is used, for example, to determine the sort order of the strings in a sorted list box.
Example
See the example for CListBox::SetLocale.

CListBox::GetSel
Retrieves the selection state of an item.

int GetSel(int nIndex) const;

Parameters
nIndex
Specifies the zero-based index of the item.
Return Value
A positive number if the specified item is selected; otherwise, it is 0. The return value is LB_ERR if an error
occurs.
Remarks
This member function works with both single- and multiple-selection list boxes.
To retrieve the index of the currently-selected list box item, use CListBox::GetCurSel.
Example

// Dump all of the items select state.


CString str;
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
str.Format(_T("item %d: select state is %s\r\n"),
i,
m_myListBox.GetSel(i) > 0 ? _T("true") : _T("false"));
AFXDUMP(str);
}

CListBox::GetSelCount
Retrieves the total number of selected items in a multiple-selection list box.

int GetSelCount() const;

Return Value
The count of selected items in a list box. If the list box is a single-selection list box, the return value is LB_ERR.
Example
See the example for CListBox::GetSelItems.
CListBox::GetSelItems
Fills a buffer with an array of integers that specifies the item numbers of selected items in a multiple-selection
list box.

int GetSelItems(
int nMaxItems,
LPINT rgIndex) const;

Parameters
nMaxItems
Specifies the maximum number of selected items whose item numbers are to be placed in the buffer.
rgIndex
Specifies a pointer to a buffer large enough for the number of integers specified by nMaxItems.
Return Value
The actual number of items placed in the buffer. If the list box is a single-selection list box, the return value is
LB_ERR .

Example

// Get the indexes of all the selected items.


int nCount = m_myODListBox.GetSelCount();
CArray<int, int> aryListBoxSel;

aryListBoxSel.SetSize(nCount);
m_myODListBox.GetSelItems(nCount, aryListBoxSel.GetData());

// Dump the selection array.


AFXDUMP(aryListBoxSel);

CListBox::GetText
Gets a string from a list box.

int GetText(
int nIndex,
LPTSTR lpszBuffer) const;

void GetText(
int nIndex,
CString& rString) const;

Parameters
nIndex
Specifies the zero-based index of the string to be retrieved.
lpszBuffer
Points to the buffer that receives the string. The buffer must have sufficient space for the string and a
terminating null character. The size of the string can be determined ahead of time by calling the GetTextLen
member function.
rString
A reference to a CString object.
Return Value
The length (in bytes) of the string, excluding the terminating null character. If nIndex does not specify a valid
index, the return value is LB_ERR.
Remarks
The second form of this member function fills a CString object with the string text.
Example

// Dump all of the items in the list box.


CString str, str2;
int n;
for (int i = 0; i < m_myListBox.GetCount(); i++)
{
n = m_myListBox.GetTextLen(i);
m_myListBox.GetText(i, str.GetBuffer(n));
str.ReleaseBuffer();

str2.Format(_T("item %d: %s\r\n"), i, str.GetBuffer(0));


AFXDUMP(str2);
}

CListBox::GetTextLen
Gets the length of a string in a list-box item.

int GetTextLen(int nIndex) const;

Parameters
nIndex
Specifies the zero-based index of the string.
Return Value
The length of the string in characters, excluding the terminating null character. If nIndex does not specify a valid
index, the return value is LB_ERR.
Example
See the example for CListBox::GetText.

CListBox::GetTopIndex
Retrieves the zero-based index of the first visible item in a list box.

int GetTopIndex() const;

Return Value
The zero-based index of the first visible item in a list box if successful, LB_ERR otherwise.
Remarks
Initially, item 0 is at the top of the list box, but if the list box is scrolled, another item may be at the top.
Example
// Want an item in the bottom half to be the first visible item.
int n = m_myListBox.GetCount() / 2;
if (m_myListBox.GetTopIndex() < n)
{
m_myListBox.SetTopIndex(n);
ASSERT(m_myListBox.GetTopIndex() == n);
}

CListBox::InitStorage
Allocates memory for storing list-box items.

int InitStorage(
int nItems,
UINT nBytes);

Parameters
nItems
Specifies the number of items to add.
nBytes
Specifies the amount of memory, in bytes, to allocate for item strings.
Return Value
If successful, the maximum number of items that the list box can store before a memory reallocation is needed,
otherwise LB_ERRSPACE, meaning not enough memory is available.
Remarks
Call this function before adding a large number of items to a CListBox .
This function helps speed up the initialization of list boxes that have a large number of items (more than 100).
It preallocates the specified amount of memory so that subsequent AddString, InsertString, and Dir functions
take the shortest possible time. You can use estimates for the parameters. If you overestimate, some extra
memory is allocated; if you underestimate, the normal allocation is used for items that exceed the preallocated
amount.
Windows 95/98 only: The nItems parameter is limited to 16-bit values. This means list boxes cannot contain
more than 32,767 items. Although the number of items is restricted, the total size of the items in a list box is
limited only by available memory.
Example

// Initialize the storage of the list box to be 256 strings with


// about 10 characters per string, performance improvement.
int n = m_myListBox.InitStorage(256, 16 * sizeof(TCHAR));
ASSERT(n != LB_ERRSPACE);

// Add 256 items to the list box.


CString str;
for (int i = 0; i < 256; i++)
{
str.Format(_T("item string %d"), i);
m_myListBox.AddString(str);
}

CListBox::InsertString
Inserts a string into the list box.

int InsertString(
int nIndex,
LPCTSTR lpszItem);

Parameters
nIndex
Specifies the zero-based index of the position to insert the string. If this parameter is -1, the string is added to
the end of the list.
lpszItem
Points to the null-terminated string that is to be inserted.
Return Value
The zero-based index of the position at which the string was inserted. The return value is LB_ERR if an error
occurs; the return value is LB_ERRSPACE if insufficient space is available to store the new string.
Remarks
Unlike the AddString member function, InsertString does not cause a list with the LBS_SORT style to be
sorted.
Example

// Insert items in between existing items.


CString str;
int n = m_myListBox.GetCount();
for (int i = 0; i < n; i++)
{
str.Format(_T("item string %c"), (char)('A' + i));
m_myListBox.InsertString(2 * i, str);
}

CListBox::ItemFromPoint
Determines the list-box item nearest the point specified in pt.

UINT ItemFromPoint(
CPoint pt,
BOOL& bOutside) const;

Parameters
pt
Point for which to find the nearest item, specified relative to the upper-left corner of the client area of the list
box.
bOutside
Reference to a BOOL variable which will be set to TRUE if pt is outside the client area of the list box, FALSE if pt
is inside the client area of the list box.
Return Value
The index of the nearest item to the point specified in pt.
Remarks
You could use this function to determine which list-box item the mouse cursor moves over.
Example
See the example for CListBox::SetAnchorIndex.

CListBox::MeasureItem
Called by the framework when a list box with an owner-draw style is created.

virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

Parameters
lpMeasureItemStruct
A long pointer to a MEASUREITEMSTRUCT structure.
Remarks
By default, this member function does nothing. Override this member function and fill in the
MEASUREITEMSTRUCT structure to inform Windows of the list-box dimensions. If the list box is created with the
LBS_OWNERDRAWVARIABLE style, the framework calls this member function for each item in the list box.
Otherwise, this member is called only once.
For further information about using the LBS_OWNERDRAWFIXED style in an owner-draw list box created with
the SubclassDlgItem member function of CWnd , see the discussion in Technical Note 14.
See CWnd::OnMeasureItem for a description of the MEASUREITEMSTRUCT structure.
Example

// CMyODListBox is my owner-drawn list box derived from CListBox. This


// example measures an item and sets the height of the item to twice the
// vertical extent of its text. The list box control was created with the
// following code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
void CMyODListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
ASSERT(lpMeasureItemStruct->CtlType == ODT_LISTBOX);
LPCTSTR lpszText = (LPCTSTR)lpMeasureItemStruct->itemData;
ASSERT(lpszText != NULL);
CSize sz;
CDC *pDC = GetDC();

sz = pDC->GetTextExtent(lpszText);

ReleaseDC(pDC);

lpMeasureItemStruct->itemHeight = 2 * sz.cy;
}

CListBox::ResetContent
Removes all items from a list box.

void ResetContent();

Example
// Delete all the items from the list box.
m_myListBox.ResetContent();
ASSERT(m_myListBox.GetCount() == 0);

CListBox::SelectString
Searches for a list-box item that matches the specified string, and if a matching item is found, it selects the item.

int SelectString(
int nStartAfter,
LPCTSTR lpszItem);

Parameters
nStartAfter
Contains the zero-based index of the item before the first item to be searched. When the search reaches the
bottom of the list box, it continues from the top of the list box back to the item specified by nStartAfter. If
nStartAfter is -1, the entire list box is searched from the beginning.
lpszItem
Points to the null-terminated string that contains the prefix to search for. The search is case independent, so this
string may contain any combination of uppercase and lowercase letters.
Return Value
The index of the selected item if the search was successful. If the search was unsuccessful, the return value is
LB_ERR and the current selection is not changed.
Remarks
The list box is scrolled, if necessary, to bring the selected item into view.
This member function cannot be used with a list box that has the LBS_MULTIPLESEL style.
An item is selected only if its initial characters (from the starting point) match the characters in the string
specified by lpszItem.
Use the FindString member function to find a string without selecting the item.
Example

// The string to match.


LPCTSTR lpszmyString = _T("item 5");

// Select the item that begins with the specified string.


int nIndex = m_myListBox.SelectString(0, lpszmyString);
ASSERT(nIndex != LB_ERR);

CListBox::SelItemRange
Selects multiple consecutive items in a multiple-selection list box.

int SelItemRange(
BOOL bSelect,
int nFirstItem,
int nLastItem);

Parameters
bSelect
Specifies how to set the selection. If bSelect is TRUE, the string is selected and highlighted; if FALSE, the
highlight is removed and the string is no longer selected.
nFirstItem
Specifies the zero-based index of the first item to set.
nLastItem
Specifies the zero-based index of the last item to set.
Return Value
LB_ERR if an error occurs.
Remarks
Use this member function only with multiple-selection list boxes. If you need to select only one item in a
multiple-selection list box — that is, if nFirstItem is equal to nLastItem — call the SetSel member function
instead.
Example

// Select half of the items.


m_myODListBox.SelItemRange(TRUE, 0, m_myODListBox.GetCount() / 2);

CListBox::SetAnchorIndex
Sets the anchor in a multiple-selection list box to begin an extended selection.

void SetAnchorIndex(int nIndex);

Parameters
nIndex
Specifies the zero-based index of the list-box item that will be the anchor.
Remarks
In a multiple-selection list box, the anchor item is the first or last item in a block of contiguous selected items.
Example

void CMyODListBox::OnLButtonDown(UINT nFlags, CPoint point)


{
BOOL bOutside = TRUE;
UINT uItem = ItemFromPoint(point, bOutside);

if (!bOutside)
{
// Set the anchor to be the middle item.
SetAnchorIndex(uItem);
ASSERT((UINT)GetAnchorIndex() == uItem);
}

CListBox::OnLButtonDown(nFlags, point);
}

CListBox::SetCaretIndex
Sets the focus rectangle to the item at the specified index in a multiple-selection list box.
int SetCaretIndex(
int nIndex,
BOOL bScroll = TRUE);

Parameters
nIndex
Specifies the zero-based index of the item to receive the focus rectangle in the list box.
bScroll
If this value is 0, the item is scrolled until it is fully visible. If this value is not 0, the item is scrolled until it is at
least partially visible.
Return Value
LB_ERR if an error occurs.
Remarks
If the item is not visible, it is scrolled into view.
Example

// Set the caret to be the middle item.


m_myListBox.SetCaretIndex(m_myListBox.GetCount() / 2);
ASSERT(m_myListBox.GetCaretIndex() == m_myListBox.GetCount() / 2);

CListBox::SetColumnWidth
Sets the width in pixels of all columns in a multicolumn list box (created with the LBS_MULTICOLUMN style).

void SetColumnWidth(int cxWidth);

Parameters
cxWidth
Specifies the width in pixels of all columns.
Example

// Find the pixel width of the largest item.


CString str;
CSize sz;
int dx = 0;
CDC* pDC = myListBox.GetDC();
for (int i = 0; i < myListBox.GetCount(); i++)
{
myListBox.GetText(i, str);
sz = pDC->GetTextExtent(str);

if (sz.cx > dx)


dx = sz.cx;
}
myListBox.ReleaseDC(pDC);

// Set the column width of the first column to be one and 1/3 units
// of the largest string.
myListBox.SetColumnWidth(dx * 4 / 3);
CListBox::SetCurSel
Selects a string and scrolls it into view, if necessary.

int SetCurSel(int nSelect);

Parameters
nSelect
Specifies the zero-based index of the string to be selected. If nSelect is -1, the list box is set to have no selection.
Return Value
LB_ERR if an error occurs.
Remarks
When the new string is selected, the list box removes the highlight from the previously selected string.
Use this member function only with single-selection list boxes.
To set or remove a selection in a multiple-selection list box, use CListBox::SetSel.
Example

// Select the last item in the list box.


int nCount = m_myListBox.GetCount();
if (nCount > 0)
m_myListBox.SetCurSel(nCount - 1);

CListBox::SetHorizontalExtent
Sets the width, in pixels, by which a list box can be scrolled horizontally.

void SetHorizontalExtent(int cxExtent);

Parameters
cxExtent
Specifies the number of pixels by which the list box can be scrolled horizontally.
Remarks
If the size of the list box is smaller than this value, the horizontal scroll bar will horizontally scroll items in the
list box. If the list box is as large or larger than this value, the horizontal scroll bar is hidden.
To respond to a call to SetHorizontalExtent , the list box must have been defined with the WS_HSCROLL style.
This member function is not useful for multicolumn list boxes. For multicolumn list boxes, call the
SetColumnWidth member function.

Example
// Find the longest string in the list box.
CString str;
CSize sz;
int dx = 0;
TEXTMETRIC tm;
CDC *pDC = m_myListBox.GetDC();
CFont *pFont = m_myListBox.GetFont();

// Select the listbox font, save the old font


CFont *pOldFont = pDC->SelectObject(pFont);
// Get the text metrics for avg char width
pDC->GetTextMetrics(&tm);

for (int i = 0; i < m_myListBox.GetCount(); i++)


{
m_myListBox.GetText(i, str);
sz = pDC->GetTextExtent(str);

// Add the avg width to prevent clipping


sz.cx += tm.tmAveCharWidth;

if (sz.cx > dx)


dx = sz.cx;
}
// Select the old font back into the DC
pDC->SelectObject(pOldFont);
m_myListBox.ReleaseDC(pDC);

// Set the horizontal extent so every character of all strings


// can be scrolled to.
m_myListBox.SetHorizontalExtent(dx);

CListBox::SetItemData
Sets a value associated with the specified item in a list box.

int SetItemData(
int nIndex,
DWORD_PTR dwItemData);

Parameters
nIndex
Specifies the zero-based index of the item.
dwItemData
Specifies the value to be associated with the item.
Return Value
LB_ERR if an error occurs.
Example

// Set the data of each item to be equal to its index.


for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.SetItemData(i, i);
}

CListBox::SetItemDataPtr
Sets the 32-bit value associated with the specified item in a list box to be the specified pointer ( void * ).

int SetItemDataPtr(
int nIndex,
void* pData);

Parameters
nIndex
Specifies the zero-based index of the item.
pData
Specifies the pointer to be associated with the item.
Return Value
LB_ERR if an error occurs.
Remarks
This pointer remains valid for the life of the list box, even though the item's relative position within the list box
might change as items are added or removed. Hence, the item's index within the box can change, but the
pointer remains reliable.
Example

// Set the data pointer of each item to be NULL.


for (int i = 0; i < m_myListBox.GetCount(); i++)
{
m_myListBox.SetItemDataPtr(i, NULL);
}

CListBox::SetItemHeight
Sets the height of items in a list box.

int SetItemHeight(
int nIndex,
UINT cyItemHeight);

Parameters
nIndex
Specifies the zero-based index of the item in the list box. This parameter is used only if the list box has the
LBS_OWNERDRAWVARIABLE style; otherwise, it should be set to 0.
cyItemHeight
Specifies the height, in pixels, of the item.
Return Value
LB_ERR if the index or height is invalid.
Remarks
If the list box has the LBS_OWNERDRAWVARIABLE style, this function sets the height of the item specified by
nIndex. Otherwise, this function sets the height of all items in the list box.
Example
// Set the height of every item to be the
// vertical size of the item's text extent.
CString str;
CSize sz;
CDC *pDC = myListBox.GetDC();
for (int i = 0; i < myListBox.GetCount(); i++)
{
myListBox.GetText(i, str);
sz = pDC->GetTextExtent(str);

myListBox.SetItemHeight(i, sz.cy);
}
myListBox.ReleaseDC(pDC);

CListBox::SetLocale
Sets the locale identifier for this list box.

LCID SetLocale(LCID nNewLocale);

Parameters
nNewLocale
The new locale identifier (LCID) value to set for the list box.
Return Value
The previous locale identifier (LCID) value for this list box.
Remarks
If SetLocale is not called, the default locale is obtained from the system. This system default locale can be
modified by using Control Panel's Regional (or International) application.
Example

// My LCID to use.
LCID mylcid = MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN),
SORT_DEFAULT);

// Force the list box to use my locale.


m_myListBox.SetLocale(mylcid);
ASSERT(m_myListBox.GetLocale() == mylcid);

CListBox::SetSel
Selects a string in a multiple-selection list box.

int SetSel(
int nIndex,
BOOL bSelect = TRUE);

Parameters
nIndex
Contains the zero-based index of the string to be set. If -1, the selection is added to or removed from all strings,
depending on the value of bSelect.
bSelect
Specifies how to set the selection. If bSelect is TRUE, the string is selected and highlighted; if FALSE, the
highlight is removed and the string is no longer selected. The specified string is selected and highlighted by
default.
Return Value
LB_ERR if an error occurs.
Remarks
Use this member function only with multiple-selection list boxes.
To select an item from a single-selection list box, use CListBox::SetCurSel.
Example

// Select all of the items with an even index and


// deselect all others.
for (int i = 0; i < m_myODListBox.GetCount(); i++)
{
m_myODListBox.SetSel(i, ((i % 2) == 0));
}

CListBox::SetTabStops
Sets the tab-stop positions in a list box.

void SetTabStops();
BOOL SetTabStops(const int& cxEachStop);

BOOL SetTabStops(
int nTabStops,
LPINT rgTabStops);

Parameters
cxEachStop
Tab stops are set at every cxEachStop dialog units. See rgTabStops for a description of a dialog unit.
nTabStops
Specifies the number of tab stops to have in the list box.
rgTabStops
Points to the first member of an array of integers containing the tab-stop positions in dialog units. A dialog unit
is a horizontal or vertical distance. One horizontal dialog unit is equal to one-fourth of the current dialog base
width unit, and one vertical dialog unit is equal to one-eighth of the current dialog base height unit. The dialog
base units are computed based on the height and width of the current system font. The GetDialogBaseUnits
Windows function returns the current dialog base units in pixels. The tab stops must be sorted in increasing
order; back tabs are not allowed.
Return Value
Nonzero if all the tabs were set; otherwise 0.
Remarks
To set tab stops to the default size of 2 dialog units, call the parameterless version of this member function. To
set tab stops to a size other than 2, call the version with the cxEachStop argument.
To set tab stops to an array of sizes, use the version with the rgTabStops and nTabStops arguments. A tab stop
will be set for each value in rgTabStops, up to the number specified by nTabStops.
To respond to a call to the SetTabStops member function, the list box must have been created with the
LBS_USETABSTOPS style.
Example

// Find the pixel width of the largest first substring.


CString str;
CSize sz;
int nIndex, dx = 0;
CDC *pDC = myListBox.GetDC();
for (int i = 0; i < myListBox.GetCount(); i++)
{
myListBox.GetText(i, str);

if ((nIndex = str.Find('\t')) != -1)


str = str.Right(nIndex);

sz = pDC->GetTextExtent(str);

if (sz.cx > dx)


dx = sz.cx;
}
myListBox.ReleaseDC(pDC);

// Set tab stops at every one and 1/3 units


// of the largest string.
// NOTE: Convert pixels to dialog units.
myListBox.SetTabStops((dx * 4 / 3 * 4) / LOWORD(::GetDialogBaseUnits()));

CListBox::SetTopIndex
Ensures that a particular list-box item is visible.

int SetTopIndex(int nIndex);

Parameters
nIndex
Specifies the zero-based index of the list-box item.
Return Value
Zero if successful, or LB_ERR if an error occurs.
Remarks
The system scrolls the list box until either the item specified by nIndex appears at the top of the list box or the
maximum scroll range has been reached.
Example

// Set the first visible item in the list box to be the middle item
m_myListBox.SetTopIndex(m_myListBox.GetCount() / 2);

CListBox::VKeyToItem
Called by the framework when the list box's parent window receives a WM_VKEYTOITEM message from the list
box.
virtual int VKeyToItem(
UINT nKey,
UINT nIndex);

Parameters
nKey
The virtual key code of the key the user pressed. For a list of standard virtual key codes, see Winuser.h
nIndex
The current position of the list-box caret.
Return Value
Returns - 2 for no further action, - 1 for default action, or a nonnegative number to specify an index of a list box
item on which to perform the default action for the keystroke.
Remarks
The WM_VKEYTOITEM message is sent by the list box when it receives a WM_KEYDOWN message, but only if
the list box meets both of the following:
Has the LBS_WANTKEYBOARDINPUT style set.
Has at least one item.
You should never call this function yourself. Override this function to provide your own custom handling of
keyboard messages.
You must return a value to tell the framework what action your override performed. A return value of - 2
indicates that the application handled all aspects of selecting the item and requires no further action by the list
box. Before returning - 2, you could set the selection or move the caret or both. To set the selection, use
SetCurSel or SetSel. To move the caret, use SetCaretIndex.
A return value of - 1 indicates that the list box should perform the default action in response to the
keystroke.The default implementation returns - 1.
A return value of 0 or greater specifies the index of an item in the list box and indicates that the list box should
perform the default action for the keystroke on the given item.
Example
// CMyODListBox is my owner-drawn list box derived from CListBox. This
// example moves the caret down one item on the down key and up one item
// on the up key. The list box control was created with the following
// code:
// m_myODListBox.Create(
// WS_CHILD|WS_VISIBLE|WS_BORDER|WS_HSCROLL|WS_VSCROLL|
// LBS_SORT|LBS_MULTIPLESEL|LBS_OWNERDRAWVARIABLE|LBS_WANTKEYBOARDINPUT,
// CRect(10,250,200,450), pParentWnd, IDC_MYODLISTBOX);
//
int CMyODListBox::VKeyToItem(UINT nKey, UINT nIndex)
{
// On key up, move the caret up one item.
if ((nKey == VK_UP) && (nIndex > 0))
{
SetCaretIndex(nIndex - 1);
}
// On key down, move the caret down one item.
else if ((nKey == VK_DOWN) && (nIndex < (UINT)GetCount()))
{
SetCaretIndex(nIndex + 1);
}

// Do not perform any default processing.


return -2;
}

See also
MFC Sample CTRLTEST
CWnd Class
Hierarchy Chart
CWnd Class
CButton Class
CComboBox Class
CEdit Class
CScrollBar Class
CStatic Class
CListCtrl Class
4/21/2020 • 77 minutes to read • Edit Online

Encapsulates the functionality of a "list view control," which displays a collection of items each consisting of
an icon (from an image list) and a label.

Syntax
class CListCtrl : public CWnd

Members
Public Constructors
NAME DESC RIP T IO N

CListCtrl::CListCtrl Constructs a CListCtrl object.

Public Methods
NAME DESC RIP T IO N

CListCtrl::ApproximateViewRect Determines the width and height required to display the


items of a list view control.

CListCtrl::Arrange Aligns items on a grid.

CListCtrl::CancelEditLabel Cancels item text editing operation.

CListCtrl::Create Creates a list control and attaches it to a CListCtrl


object.

CListCtrl::CreateDragImage Creates a drag image list for a specified item.

CListCtrl::CreateEx Creates a list control with the specified Windows extended


styles and attaches it to a CListCtrl object.

CListCtrl::DeleteAllItems Deletes all items from the control.

CListCtrl::DeleteColumn Deletes a column from the list view control.

CListCtrl::DeleteItem Deletes an item from the control.

CListCtrl::DrawItem Called when a visual aspect of an owner-draw control


changes.

CListCtrl::EditLabel Begins in-place editing of an item's text.


NAME DESC RIP T IO N

CListCtrl::EnableGroupView Enables or disables whether the items in a list view control


display as a group.

CListCtrl::EnsureVisible Ensures that an item is visible.

CListCtrl::FindItem Searches for a list view item having specified


characteristics.

CListCtrl::GetBkColor Retrieves the background color of a list view control.

CListCtrl::GetBkImage Retrieves the current background image of a list view


control.

CListCtrl::GetCallbackMask Retrieves the callback mask for a list view control.

CListCtrl::GetCheck Retrieves the current display status of the state image


associated with an item.

CListCtrl::GetColumn Retrieves the attributes of a control's column.

CListCtrl::GetColumnOrderArray Retrieves the column order (left to right) of a list view


control.

CListCtrl::GetColumnWidth Retrieves the width of a column in report view or list view.

CListCtrl::GetCountPerPage Calculates the number of items that can fit vertically in a


list view control.

CListCtrl::GetEditControl Retrieves the handle of the edit control used to edit an


item's text.

CListCtrl::GetEmptyText Retrieves the string to display if the current list-view


control is empty.

CListCtrl::GetExtendedStyle Retrieves the current extended styles of a list view control.

CListCtrl::GetFirstSelectedItemPosition Retrieves the position of the first selected list view item in
a list view control.

CListCtrl::GetFocusedGroup Retrieves the group that has the keyboard focus in the
current list-view control.

CListCtrl::GetGroupCount Retrieves the number of groups in the current list-view


control.

CListCtrl::GetGroupInfo Gets the information for a specified group of the list view
control.

CListCtrl::GetGroupInfoByIndex Retrieves information about a specified group in the


current list-view control.

CListCtrl::GetGroupMetrics Retrieves the metrics of a group.


NAME DESC RIP T IO N

CListCtrl::GetGroupRect Retrieves the bounding rectangle for a specified group in


the current list-view control.

CListCtrl::GetGroupState Retrieves the state for a specified group in the current list-
view control.

CListCtrl::GetHeaderCtrl Retrieves the header control of a list view control.

CListCtrl::GetHotCursor Retrieves the cursor used when hot tracking is enabled for
a list view control.

CListCtrl::GetHotItem Retrieves the list view item currently under the cursor.

CListCtrl::GetHoverTime Retrieves the current hover time of a list view control.

CListCtrl::GetImageList Retrieves the handle of an image list used for drawing list
view items.

CListCtrl::GetInsertMark Retrieves the current position of the insertion mark.

CListCtrl::GetInsertMarkColor Retrieves the current color of the insertion mark.

CListCtrl::GetInsertMarkRect Retrieves the rectangle that bounds the insertion point.

CListCtrl::GetItem Retrieves a list view item's attributes.

CListCtrl::GetItemCount Retrieves the number of items in a list view control.

CListCtrl::GetItemData Retrieves the application-specific value associated with an


item.

CListCtrl::GetItemIndexRect Retrieves the bounding rectangle for all or part of a


subitem in the current list-view control.

CListCtrl::GetItemPosition Retrieves the position of a list view item.

CListCtrl::GetItemRect Retrieves the bounding rectangle for an item.

CListCtrl::GetItemSpacing Calculates the spacing between items in the current list-


view control.

CListCtrl::GetItemState Retrieves the state of a list view item.

CListCtrl::GetItemText Retrieves the text of a list view item or subitem.

CListCtrl::GetNextItem Searches for a list view item with specified properties and
with specified relationship to a given item.

CListCtrl::GetNextItemIndex Retrieves the index of the item in the current list-view


control that has a specified set of properties.
NAME DESC RIP T IO N

CListCtrl::GetNextSelectedItem Retrieves the index of a list view item position, and the
position of the next selected list view item for iterating.

CListCtrl::GetNumberOfWorkAreas Retrieves the current number of working areas for a list


view control.

CListCtrl::GetOrigin Retrieves the current view origin for a list view control.

CListCtrl::GetOutlineColor Retrieves the color of the border of a list view control.

CListCtrl::GetSelectedColumn Retrieves the index of the currently selected column in the


list control.

CListCtrl::GetSelectedCount Retrieves the number of selected items in the list view


control.

CListCtrl::GetSelectionMark Retrieves the selection mark of a list view control.

CListCtrl::GetStringWidth Determines the minimum column width necessary to


display all of a given string.

CListCtrl::GetSubItemRect Retrieves the bounding rectangle of an item in a list view


control.

CListCtrl::GetTextBkColor Retrieves the text background color of a list view control.

CListCtrl::GetTextColor Retrieves the text color of a list view control.

CListCtrl::GetTileInfo Retrieves information about a tile in a list view control.

CListCtrl::GetTileViewInfo Retrieves information about a list view control in tile view.

CListCtrl::GetToolTips Retrieves the tooltip control that the list view control uses
to display tooltips.

CListCtrl::GetTopIndex Retrieves the index of the topmost visible item.

CListCtrl::GetView Gets the view of the list view control.

CListCtrl::GetViewRect Retrieves the bounding rectangle of all items in the list


view control.

CListCtrl::GetWorkAreas Retrieves the current working areas of a list view control.

CListCtrl::HasGroup Determines if the list view control has the specified group.

CListCtrl::HitTest Determines which list view item is at a specified position.

CListCtrl::InsertColumn Inserts a new column in a list view control.

CListCtrl::InsertGroup Inserts a group into the list view control.


NAME DESC RIP T IO N

CListCtrl::InsertGroupSorted Inserts the specified group into an ordered list of groups.

CListCtrl::InsertItem Inserts a new item in a list view control.

CListCtrl::InsertMarkHitTest Retrieves the insertion point closest to a specified point.

CListCtrl::IsGroupViewEnabled Determines whether group view is enabled for a list view


control.

CListCtrl::IsItemVisible Indicates whether a specified item in the current list-view


control is visible.

CListCtrl::MapIDToIndex Maps the unique ID of an item in the current list-view


control to an index.

CListCtrl::MapIndexToID Maps the index of an item in the current list-view control


to a unique ID.

CListCtrl::MoveGroup Moves the specified group.

CListCtrl::MoveItemToGroup Moves the specified group to the specified zero based


index of the list view control.

CListCtrl::RedrawItems Forces a list view control to repaint a range of items.

CListCtrl::RemoveAllGroups Removes all groups from a list view control.

CListCtrl::RemoveGroup Removes the specified group from the list view control.

CListCtrl::Scroll Scrolls the content of a list view control.

CListCtrl::SetBkColor Sets the background color of the list view control.

CListCtrl::SetBkImage Sets the current background image of a list view control.

CListCtrl::SetCallbackMask Sets the callback mask for a list view control.

CListCtrl::SetCheck Sets the current display status of the state image


associated with an item.

CListCtrl::SetColumn Sets the attributes of a list view column.

CListCtrl::SetColumnOrderArray Sets the column order (left to right) of a list view control.

CListCtrl::SetColumnWidth Changes the width of a column in report view or list view.

CListCtrl::SetExtendedStyle Sets the current extended styles of a list view control.

CListCtrl::SetGroupInfo Sets the information for the specified group of a list view
control.
NAME DESC RIP T IO N

CListCtrl::SetGroupMetrics Sets the group metrics of a list view control.

CListCtrl::SetHotCursor Sets the cursor used when hot tracking is enabled for a
list view control.

CListCtrl::SetHotItem Sets the current hot item of a list view control.

CListCtrl::SetHoverTime Sets the current hover time of a list view control.

CListCtrl::SetIconSpacing Sets the spacing between icons in a list view control.

CListCtrl::SetImageList Assigns an image list to a list view control.

CListCtrl::SetInfoTip Sets the tooltip text.

CListCtrl::SetInsertMark Sets the insertion point to the defined position.

CListCtrl::SetInsertMarkColor Sets the color of the insertion point.

CListCtrl::SetItem Sets some or all of a list view item's attributes.

CListCtrl::SetItemCount Prepares a list view control for adding a large number of


items.

CListCtrl::SetItemCountEx Sets the item count for a virtual list view control.

CListCtrl::SetItemData Sets the item's application-specific value.

CListCtrl::SetItemIndexState Sets the state of an item in the current list-view control.

CListCtrl::SetItemPosition Moves an item to a specified position in a list view control.

CListCtrl::SetItemState Changes the state of an item in a list view control.

CListCtrl::SetItemText Changes the text of a list view item or subitem.

CListCtrl::SetOutlineColor Sets the color of the border of a list view control.

CListCtrl::SetSelectedColumn Sets the selected column of the list view control.

CListCtrl::SetSelectionMark Sets the selection mark of a list view control.

CListCtrl::SetTextBkColor Sets the background color of text in a list view control.

CListCtrl::SetTextColor Sets the text color of a list view control.

CListCtrl::SetTileInfo Sets the information for a tile of the list view control.

CListCtrl::SetTileViewInfo Sets information that a list view control uses in tile view.
NAME DESC RIP T IO N

CListCtrl::SetToolTips Sets the tooltip control that the list view control will use
to display tooltips.

CListCtrl::SetView Sets the view of the list view control.

CListCtrl::SetWorkAreas Sets the area where icons can be displayed in a list view
control.

CListCtrl::SortGroups Sorts the groups of a list view control with a user-defined


function.

CListCtrl::SortItems Sorts list view items using an application-defined


comparison function.

CListCtrl::SortItemsEx Sorts list view items using an application-defined


comparison function.

CListCtrl::SubItemHitTest Determines which list view item, if any, is at a given


position.

CListCtrl::Update Forces the control to repaint a specified item.

Remarks
In addition to an icon and label, each item can have information displayed in columns to the right of the
icon and label. This control (and therefore the CListCtrl class) is available only to programs running under
Windows 95/98 and Windows NT version 3.51 and later.
The following is a brief overview of the CListCtrl class. For a detailed, conceptual discussion, see Using
CListCtrl and Controls.

Views
List view controls can display their contents in four different ways, called "views."
Icon view
Each item appears as a full-sized icon (32 x 32 pixels) with a label below it. The user can drag the
items to any location in the list view window.
Small icon view
Each item appears as a small icon (16 x 16 pixels) with the label to the right of it. The user can drag
the items to any location in the list view window.
List view
Each item appears as a small icon with a label to the right of it. Items are arranged in columns and
cannot be dragged to any location in the list view window.
Report view
Each item appears on its own line, with additional information arranged in columns to the right. The
leftmost column contains the small icon and label, and subsequent columns contain subitems as
specified by the application. An embedded header control (class CHeaderCtrl) implements these
columns. For more information on the header control and columns in a report view, see Using
CListCtrl: Adding Columns to the Control (Report View).
The style of the control's current list view determines the current view. For more information on these styles
and their usage, see Using CListCtrl: Changing List Control Styles.

Extended Styles
In addition to the standard list styles, class CListCtrl supports a large set of extended styles, providing
enriched functionality. Some examples of this functionality include:
Hover selection
When enabled, allows automatic selection of an item when the cursor remains over the item for a
certain period of time.
Virtual list views
When enabled, allows the control to support up to DWORD items. This is possible by placing the
overhead of managing item data on the application. Except for the item selection and focus
information, all item information must be managed by the application. For more information, see
Using CListCtrl: Virtual List Controls.
One- and two- click activation
When enabled, allows hot tracking (automatic highlighting of the item text) and one- or two- click
activation of the highlighted item.
Drag and drop column ordering
When enabled, allows drag-and-drop reordering of columns in a list view control. Only available in
report view.
For information on using these new extended styles, see Using CListCtrl: Changing List Control Styles.

Items and Subitems


Each item in a list view control consists of an icon (from an image list), a label, a current state, and an
application-defined value (referred to as "item data"). One or more subitems can also be associated with
each item. A "subitem" is a string that, in report view, can be displayed in a column to the right of an item's
icon and label. All items in a list view control must have the same number of subitems.
Class CListCtrl provides several functions for inserting, deleting, finding, and modifying these items. For
more information, see CListCtrl::GetItem, CListCtrl::InsertItem, and CListCtrl::FindItem, Adding Items to the
Control, and Scrolling, Arranging, Sorting, and Finding in list controls.
By default, the list view control is responsible for storing an item's icon and text attributes. However, in
addition to these item types, class CListCtrl supports "callback items." A "callback item" is a list view item
for which the application — rather than the control — stores the text, icon, or both. A callback mask is used
to specify which item attributes (text and/or icon) are supplied by the application. If an application uses
callback items, it must be able to supply the text and/or icon attributes on demand. Callback items are
helpful when your application already maintains some of this information. For more information, see Using
CListCtrl: Callback Items and the Callback Mask.

Image Lists
The icons, header item images, and application- defined states for list view items are contained in several
image lists (implemented by class CImageList), which you create and assign to the list view control. Each list
view control can have up to four different types of image lists:
Large icon
Used in the icon view for full-sized icons.
Small icon
Used in the small icon, list, and report views for smaller versions of the icons used in the icon view.
Application-defined state
Contains state images, which are displayed next to an item's icon to indicate an application-defined
state.
Header item
Used in the report view for small images that appear in each header control item.
By default, a list view control destroys the image lists assigned to it when it is destroyed; however, the
developer can customize this behavior by destroying each image list when it is no longer used, as
determined by the application. For more information, see Using CListCtrl: List Items and Image Lists.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CListCtrl

Requirements
Header : afxcmn.h

CListCtrl::ApproximateViewRect
Determines the width and height required to display the items of a list view control.

CSize ApproximateViewRect(
CSize sz = CSize(-1, -1),
int iCount = -1) const;

Parameters
sz
The proposed dimensions of the control, in pixels. If dimensions are not specified, the framework uses the
current width or height values of the control.
iCount
Number of items to be displayed in the control. If this parameter is -1, the framework uses the total number
of items currently in the control.
Return Value
A CSize object that contains the approximate width and height needed to display the items, in pixels.
Remarks
This member function implements the behavior of the Win32 macro, ListView_ApproximateViewRect, as
described in the Windows SDK.

CListCtrl::Arrange
Repositions items in an icon view so that they align on a grid.

BOOL Arrange(UINT nCode);

Parameters
nCode
Specifies the alignment style for the items. It can be one of the following values:
LVA_ALIGNLEFT Aligns items along the left edge of the window.
LVA_ALIGNTOP Aligns items along the top edge of the window.
LVA_DEFAULT Aligns items according to the list view's current alignment styles (the default value).
LVA_SNAPTOGRID Snaps all icons to the nearest grid position.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The nCode parameter specifies the alignment style.
Example

// Align all of the list view control items along the top
// of the window (the list view control must be in icon or
// small icon mode).
m_myListCtrl.Arrange(LVA_ALIGNTOP);

CListCtrl::CancelEditLabel
Cancels item text editing operation.

void CancelEditLabel();

Remarks
This member function emulates the functionality of the LVM_CANCELEDITLABEL message, as described in
the Windows SDK.

CListCtrl::CListCtrl
Constructs a CListCtrl object.

CListCtrl();

CListCtrl::Create
Creates a list control and attaches it to a CListCtrl object.
virtual BOOL Create(
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwStyle
Specifies the list control's style. Apply any combination of list control styles to the control. See List view
window styles in the Windows SDK for a complete list of these styles. Set extended styles specific to a
control using SetExtendedStyle.
rect
Specifies the list control's size and position. It can be either a CRect object or a RECT structure.
pParentWnd
Specifies the list control's parent window, usually a CDialog . It must not be NULL.
nID
Specifies the list control's ID.
Return Value
Nonzero if successful; otherwise zero.
Remarks
You construct a CListCtrl in two steps. First, call the constructor and then call Create , which creates the
list view control and attaches it to the CListCtrl object.
To apply extended Windows styles to the list control object, call CreateEx instead of Create .
Example

m_myListCtrl.Create(
WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS,
CRect(10,10,400,200), pParentWnd, IDD_MYLISTCTRL);

CListCtrl::CreateEx
Creates a control (a child window) and associates it with the CListCtrl object.

virtual BOOL CreateEx(


DWORD dwExStyle,
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID);

Parameters
dwExStyle
Specifies the extended style of the control being created. For a list of extended Windows styles, see the
dwExStyle parameter for CreateWindowEx in the Windows SDK.
dwStyle
Specifies the list control's style. Apply any combination of list control styles to the control. For a complete
list of these styles, see List view window styles in the Windows SDK.
rect
A reference to a RECT structure describing the size and position of the window to be created, in client
coordinates of pParentWnd.
pParentWnd
A pointer to the window that is the control's parent.
nID
The control's child-window ID.
Return Value
Nonzero if successful; otherwise 0.
Remarks
Use CreateEx instead of Create to apply extended Windows styles, specified by the Windows extended
style preface WS_EX_ .
CreateEx creates the control with the extended Windows styles specified by dwExStyle. To set extended
styles specific to a control, call SetExtendedStyle. For example, use CreateEx to set such styles as
WS_EX_CONTEXTHELP, but use SetExtendedStyle to set such styles as LVS_EX_FULLROWSELECT. For more
information, see the styles described in the article Extended List View Styles in the Windows SDK.

CListCtrl::CreateDragImage
Creates a drag image list for the item specified by nItem.

CImageList* CreateDragImage(
int nItem,
LPPOINT lpPoint);

Parameters
nItem
Index of the item whose drag image list is to be created.
lpPoint
Address of a POINT structure that receives the initial location of the upper-left corner of the image, in view
coordinates.
Return Value
A pointer to the drag image list if successful; otherwise NULL.
Remarks
The CImageList object is permanent, and you must delete it when finished. For example:

CImageList* pImageList = m_myListCtrl.CreateDragImage(nItem, &point);

// do something

delete pImageList;

CListCtrl::DeleteAllItems
Deletes all items from the list view control.
BOOL DeleteAllItems();

Return Value
Nonzero if successful; otherwise zero.
Example

// Delete all of the items from the list view control.


m_myListCtrl.DeleteAllItems();
ASSERT(m_myListCtrl.GetItemCount() == 0);

CListCtrl::DeleteColumn
Deletes a column from the list view control.

BOOL DeleteColumn(int nCol);

Parameters
nCol
Index of the column to be deleted.
Return Value
Nonzero if successful; otherwise zero.
Example

int nColumnCount = m_myListCtrl.GetHeaderCtrl()->GetItemCount();

// Delete all of the columns.


for (int i=0; i < nColumnCount; i++)
{
m_myListCtrl.DeleteColumn(0);
}

CListCtrl::DeleteItem
Deletes an item from a list view control.

BOOL DeleteItem(int nItem);

Parameters
nItem
Specifies the index of the item to be deleted.
Return Value
Nonzero if successful; otherwise zero.
Example
int nCount = m_myListCtrl.GetItemCount();

// Delete all of the items from the list view control.


for (int i=0; i < nCount; i++)
{
m_myListCtrl.DeleteItem(0);
}

CListCtrl::DrawItem
Called by the framework when a visual aspect of an owner-draw list view control changes.

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

Parameters
lpDrawItemStruct
A long pointer to a DRAWITEMSTRUCT structure that contains information about the type of drawing required.
Remarks
The itemAction member of the DRAWITEMSTRUCT structure defines the drawing action that is to be
performed.
By default, this member function does nothing. Override this member function to implement drawing for
an owner-draw CListCtrl object.
The application should restore all graphics device interface (GDI) objects selected for the display context
supplied in lpDrawItemStruct before this member function terminates.

CListCtrl::EditLabel
Begins in-place editing of an item's text.

CEdit* EditLabel(int nItem);

Parameters
nItem
Index of the list view item that is to be edited.
Return Value
If successful, a pointer to the CEdit object that is used to edit the item text; otherwise NULL.
Remarks
A list view control that has the LVS_EDITLABELS window style enables a user to edit item labels in place. The
user begins editing by clicking the label of an item that has the focus.
Use this function to begin in-place editing of the specified list view item's text.
Example
// Make sure the focus is set to the list view control.
m_myListCtrl.SetFocus();

// Show the edit control on the label of the first


// item in the list view control.
CEdit* pmyEdit = m_myListCtrl.EditLabel(1);
ASSERT(pmyEdit != NULL);

CListCtrl::EnableGroupView
Enables or disables whether the items in a list view control display as a group.

LRESULT EnableGroupView(BOOL fEnable);

Parameters
fEnable
Indicates whether to enable a listview control to group displayed items. TRUE to enable grouping; FALSE to
disable it.
Return Value
Returns one of the following values:
0 The ability to display list view items as a group is already enabled or disabled.
1 The state of the control was successfully changed.
-1 The operation failed.
Remarks
This member function emulates the functionality of the LVM_ENABLEGROUPVIEW message, as described in
the Windows SDK.

CListCtrl::EnsureVisible
Ensures that a list view item is at least partially visible.

BOOL EnsureVisible(
int nItem,
BOOL bPartialOK);

Parameters
nItem
Index of the list view item that is to be visible.
bPartialOK
Specifies whether partial visibility is acceptable.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The list view control is scrolled if necessary. If the bPartialOK parameter is nonzero, no scrolling occurs if
the item is partially visible.
Example
// Ensure that the last item is visible.
int nCount = m_myListCtrl.GetItemCount();
if (nCount > 0)
m_myListCtrl.EnsureVisible(nCount-1, FALSE);

CListCtrl::FindItem
Searches for a list view item having specified characteristics.

int FindItem(
LVFINDINFO* pFindInfo,
int nStart = -1) const;

Parameters
pFindInfo
A pointer to an LVFINDINFO structure containing information about the item to be searched for.
nStart
Index of the item to begin the search with, or -1 to start from the beginning. The item at nStart is excluded
from the search if nStart is not equal to -1.
Return Value
The index of the item if successful or -1 otherwise.
Remarks
The pFindInfo parameter points to an LVFINDINFO structure, which contains information used to search for
a list view item.
Example

LVFINDINFO info;
int nIndex;

info.flags = LVFI_PARTIAL|LVFI_STRING;
info.psz = _T("item");

// Delete all of the items that begin with the string.


while ((nIndex = m_myListCtrl.FindItem(&info)) != -1)
{
m_myListCtrl.DeleteItem(nIndex);
}

CListCtrl::GetBkColor
Retrieves the background color of a list view control.

COLORREF GetBkColor() const;

Return Value
A 32-bit value used to specify an RGB color.
Example
See the example for CListCtrl::SetBkColor.
CListCtrl::GetBkImage
Retrieves the current background image of a list view control.

BOOL GetBkImage(LVBKIMAGE* plvbkImage) const;

Parameters
plvbkImage
A pointer to an LVBKIMAGE structure containing the current background image of the list view.
Return Value
Returns nonzero if successful, or zero otherwise.
Remarks
This method implements the behavior of the Win32 macro, ListView_GetBkImage, as described in the
Windows SDK.
Example

LVBKIMAGE bki;

// If no background image is set for the list view control use


// the Microsoft homepage image as the background image.
if (m_myListCtrl.GetBkImage(&bki) && (bki.ulFlags == LVBKIF_SOURCE_NONE))
{
m_myListCtrl.SetBkImage(
_T("https://www.microsoft.com/library/images/gifs/homepage/microsoft.gif"),
TRUE);
}

CListCtrl::GetCallbackMask
Retrieves the callback mask for a list view control.

UINT GetCallbackMask() const;

Return Value
The list view control's callback mask.
Remarks
A "callback item" is a list view item for which the application — rather than the control — stores the text,
icon, or both. Although a list view control can store these attributes for you, you may want to use callback
items if your application already maintains some of this information. The callback mask specifies which
item state bits are maintained by the application, and it applies to the whole control rather than to a specific
item. The callback mask is zero by default, meaning that the control tracks all item states. If an application
uses callback items or specifies a nonzero callback mask, it must be able to supply list view item attributes
on demand.
Example
See the example for CListCtrl::SetCallbackMask.

CListCtrl::GetCheck
Retrieves the current display status of the state image that is associated with an item.
BOOL GetCheck(int nItem) const;

Parameters
nItem
The zero-based index of a list control item.
Return Value
Nonzero if the item is selected, otherwise 0.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetCheckState, as described
in the Windows SDK.
Example
See the example for CListCtrl::SetCheck.

CListCtrl::GetColumn
Retrieves the attributes of a list view control's column.

BOOL GetColumn(
int nCol,
LVCOLUMN* pColumn) const;

Parameters
nCol
Index of the column whose attributes are to be retrieved.
pColumn
Address of an LVCOLUMN structure that specifies the information to retrieve and receives information
about the column. The mask member specifies which column attributes to retrieve. If the mask member
specifies the LVCF_TEXT value, the pszText member must contain the address of the buffer that receives
the item text and the cchTextMax member must specify the size of the buffer.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The LVCOLUMN structure contains information about a column in report view.
Example

LVCOLUMN col;

col.mask = LVCF_WIDTH;

// Double the column width of the first column.


if (m_myListCtrl.GetColumn(0, &col))
{
col.cx *= 2;
m_myListCtrl.SetColumn(0, &col);
}

CListCtrl::GetColumnOrderArray
Retrieves the column order (left to right) of a list view control.

BOOL GetColumnOrderArray(
LPINT piArray,
int iCount = -1);

Parameters
piArray
A pointer to a buffer that will contain the index values of the columns in the list view control. The buffer
must be large enough to contain the total number of columns in the list view control.
iCount
Number of columns in the list view control. If this parameter is -1, the number of columns is automatically
retrieved by the framework.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetColumnOrderArray, as
described in the Windows SDK.
Example

// Reverse the order of the columns in the list view control


// (i.e. make the first column the last, the last column
// the first, and so on...).
CHeaderCtrl* pHeaderCtrl = m_myListCtrl.GetHeaderCtrl();

if (pHeaderCtrl != NULL)
{
int nColumnCount = pHeaderCtrl->GetItemCount();
LPINT pnOrder = (LPINT) malloc(nColumnCount*sizeof(int));
ASSERT(pnOrder != NULL);
m_myListCtrl.GetColumnOrderArray(pnOrder, nColumnCount);

int i, j, nTemp;
for (i = 0, j = nColumnCount-1; i < j; i++, j--)
{
nTemp = pnOrder[i];
pnOrder[i] = pnOrder[j];
pnOrder[j] = nTemp;
}

m_myListCtrl.SetColumnOrderArray(nColumnCount, pnOrder);
free(pnOrder);
}

CListCtrl::GetColumnWidth
Retrieves the width of a column in report view or list view.

int GetColumnWidth(int nCol) const;

Parameters
nCol
Specifies the index of the column whose width is to be retrieved.
Return Value
The width, in pixels, of the column specified by nCol.
Example

// Increase the column width of the second column by 20.


int nWidth = m_myListCtrl.GetColumnWidth(1);
m_myListCtrl.SetColumnWidth(1, 20 + nWidth);

CListCtrl::GetCountPerPage
Calculates the number of items that can fit vertically in the visible area of a list view control when in list
view or report view.

int GetCountPerPage() const;

Return Value
The number of items that can fit vertically in the visible area of a list view control when in list view or report
view.
Example
See the example for CListCtrl::GetTopIndex.

CListCtrl::GetEditControl
Retrieves the handle of the edit control used to edit a list view item's text.

CEdit* GetEditControl() const;

Return Value
If successful, a pointer to the CEdit object that is used to edit the item text; otherwise NULL.
Example

// The string replacing the text in the edit control.


LPCTSTR lpszmyString = _T("custom label!");

// If possible, replace the text in the label edit control.


CEdit* pEdit = m_myListCtrl.GetEditControl();

if (pEdit != NULL)
{
pEdit->SetWindowText(lpszmyString);
}

CListCtrl::GetEmptyText
Retrieves the string to display if the current list-view control is empty.

CString GetEmptyText() const;

Return Value
A CString that contains the text to display if the control is empty.
Remarks
This method sends the LVM_GETEMPTYTEXT message, which is described in the Windows SDK.

CListCtrl::GetExtendedStyle
Retrieves the current extended styles of a list view control.

DWORD GetExtendedStyle();

Return Value
A combination of the extended styles currently in use by the list view control. For a descriptive list of these
extended styles, see the Extended List View Styles article in the Windows SDK.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetExtendedListViewStyle, as
described in the Windows SDK.
Example
See the example for CListCtrl::SetExtendedStyle.

CListCtrl::GetFirstSelectedItemPosition
Gets the position of the first selected item in the list view control.

POSITION GetFirstSelectedItemPosition() const;

Return Value
A POSITION value that can be used for iteration or object pointer retrieval; NULL if no items are selected.
Example
The following code sample demonstrates the usage of this function.

POSITION pos = m_myListCtrl.GetFirstSelectedItemPosition();


if (pos == NULL)
{
TRACE(_T("No items were selected!\n"));
}
else
{
while (pos)
{
int nItem = m_myListCtrl.GetNextSelectedItem(pos);
TRACE(_T("Item %d was selected!\n"), nItem);
// you could do your own processing on nItem here
}
}

CListCtrl::GetFocusedGroup
Retrieves the group that has the keyboard focus in the current list-view control.

int GetFocusedGroup() const;


Return Value
The index of the group whose state is LVGS_FOCUSED, if there is such a group; otherwise, -1.
Remarks
This method sends the LVM_GETFOCUSEDGROUP message, which is described in the Windows SDK. For
more information, see the LVGS_FOCUSED value of the state member of the LVGROUP structure.

CListCtrl::GetGroupCount
Retrieves the number of groups in the current list-view control.

int GetGroupCount()const;

Return Value
The number of groups in the list-view control.
Remarks
This method sends the LVM_GETGROUPCOUNT message, which is described in the Windows SDK -->.

CListCtrl::GetGroupInfo
Gets the information for a specified group of the list view control.

int GetGroupInfo(
int iGroupId,
PLVGROUP pgrp) const;

Parameters
iGroupId
The identifier of the group whose information is to be retrieved.
pgrp
A pointer to the LVGROUP containing information on the group specified.
Return Value
Returns the ID of the group if successful, or -1 otherwise.
Remarks
This member function emulates the functionality of the LVM_GETGROUPINFO message, as described in the
Windows SDK.

CListCtrl::GetGroupInfoByIndex
Retrieves information about a specified group in the current list-view control.

BOOL GetGroupInfoByIndex(
int iIndex,
PLVGROUP pGroup) const;

Parameters
PA RA M ET ER DESC RIP T IO N

iIndex [in] Zero-based index of a group.

pGroup [out] Pointer to an LVGROUP structure that receives


information about the group specified by the iIndex
parameter.

The caller is responsible for initializing the members of the


LVGROUP structure. Set the cbSize member to the size
of the structure, and the flags of the mask member to
specify the information to retrieve.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the LVM_GETGROUPINFOBYINDEX message, which is described in the Windows SDK --
>.
Example
The following code example defines a variable, m_listCtrl , that is used to access the current list-view
control. This variable is used in the next example.

public:
// Variable used to access the list control.
CListCtrl m_listCtrl;

Example
The following code example demonstrates the GetGroupInfoByIndex method. In an earlier section of this
code example, we created a list-view control that displays two columns titled "ClientID" and "Grade" in a
report view. The following code example retrieves information about the group whose index is 0, if such a
group exists.
// GetGroupInfoByIndex
const int GROUP_HEADER_BUFFER_SIZE = 40;

// Initialize the structure


LVGROUP gInfo = {0};
gInfo.cbSize = sizeof(LVGROUP);
wchar_t wstrHeadGet[GROUP_HEADER_BUFFER_SIZE] = {0};
gInfo.cchHeader = GROUP_HEADER_BUFFER_SIZE;
gInfo.pszHeader = wstrHeadGet;
gInfo.mask = (LVGF_ALIGN | LVGF_STATE | LVGF_HEADER | LVGF_GROUPID);
gInfo.state = LVGS_NORMAL;
gInfo.uAlign = LVGA_HEADER_LEFT;

BOOL bRet = m_listCtrl.GetGroupInfoByIndex( 0, &gInfo );


if (bRet == TRUE) {
CString strHeader = CString( gInfo.pszHeader );
CString str;
str.Format(_T("Header: '%s'"), strHeader);
AfxMessageBox(str, MB_ICONINFORMATION);
}
else
{
AfxMessageBox(_T("No group information was retrieved."));
}

CListCtrl::GetGroupMetrics
Retrieves the metrics of a group.

void GetGroupMetrics(PLVGROUPMETRICS pGroupMetrics) const;

Parameters
pGroupMetrics
A pointer to a LVGROUPMETRICS containing the group metrics information.
Remarks
This member function emulates the functionality of the LVM_GETGROUPMETRICS message, as described in
the Windows SDK.

CListCtrl::GetGroupRect
Retrieves the bounding rectangle for a specified group in the current list-view control.

BOOL GetGroupRect(
int iGroupId,
LPRECT lpRect,
int iCoords = LVGGR_GROUP) const;

Parameters
PA RA M ET ER DESC RIP T IO N

iGroupId [in] Specifies a group.

lpRect [in, out] Pointer to a RECT structure. If this method is


successful, the structure receives the rectangle
coordinates of the group that is specified by iGroupId.
PA RA M ET ER DESC RIP T IO N

iCoords [in] Specifies the rectangle coordinates to retrieve. Use


one of these values:

- LVGGR_GROUP - (Default) Coordinates of the entire


expanded group.
- LVGGR_HEADER - Coordinates of only the header
(collapsed group).
- LVGGR_SUBSETLINK - Coordinates of only the subset
link (markup subset).

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
The caller is responsible for allocating the RECT structure pointed to by the pRect parameter.
This method sends the LVM_GETGROUPRECT message, which is described in the Windows SDK.
Example
The following code example defines a variable, m_listCtrl , that is used to access the current list-view
control. This variable is used in the next example.

public:
// Variable used to access the list control.
CListCtrl m_listCtrl;

Example
The following code example demonstrates the GetGroupRect method. In an earlier section of this code
example, we created a list-view control that displays two columns titled "ClientID" and "Grade" in a report
view. The following code example draws a 3D rectangle around the group whose index is 0, if such a group
exists.

// GetGroupRect

// Get the graphics rectangle that surrounds group 0.


CRect rect;
BOOL bRet = m_listCtrl.GetGroupRect( 0, &rect, LVGGR_GROUP);
// Draw a blue rectangle around group 0.
if (bRet == TRUE) {
m_listCtrl.GetDC()->Draw3dRect( &rect, RGB(0, 0, 255), RGB(0, 0, 255));
}
else {
AfxMessageBox(_T("No group information was retrieved."), MB_ICONINFORMATION);
}

CListCtrl::GetGroupState
Retrieves the state for a specified group in the current list-view control.

UINT GetGroupState(
int iGroupId,
DWORD dwMask) const;

Parameters
PA RA M ET ER DESC RIP T IO N

iGroupId [in] Zero-based index of a group.

dwMask [in] Mask that specifies the state value to retrieve for the
specified group. For more information, see the mask
member of the LVGROUP structure.

Return Value
The requested state for the specified group, or 0 if the group cannot be found.
Remarks
The return value is the result of a bitwise AND operation on the dwMask parameter and the value of the
state member of an LVGROUP structure that represents the current list-view control.

This method sends the LVM_GETGROUPSTATE message, which is described in the Windows SDK. For more
information, see the ListView_GetGroupState macro.

CListCtrl::GetHeaderCtrl
Retrieves the header control of a list view control.

CHeaderCtrl* GetHeaderCtrl();

Return Value
A pointer to the header control, used by the list view control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetHeader, as described in
the Windows SDK.
Example
See the example for CListCtrl::GetColumnOrderArray.

CListCtrl::GetHotCursor
Retrieves the cursor used when hot tracking is enabled for a list view control.

HCURSOR GetHotCursor();

Return Value
The handle to the current hot cursor resource being used by the list view control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetHotCursor, as described
in the Windows SDK. The hot cursor, only visible when hover selection is enabled, appears when the cursor
passes over any list view item. Hover selection is enabled by setting the LVS_EX_TRACKSELECT extended
style.
Example
// Set the hot cursor to be the system app starting cursor.
HCURSOR hCursor = ::LoadCursor(NULL, IDC_APPSTARTING);
m_myListCtrl.SetHotCursor(hCursor);
ASSERT(m_myListCtrl.GetHotCursor() == hCursor);

CListCtrl::GetHotItem
Retrieves the list view item currently under the cursor.

int GetHotItem();

Return Value
The index of the current hot item of the list view control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetHotItem, as described in
the Windows SDK. The hot item is defined as the currently selected item when hot tracking (and hover
selection) is enabled.
If hot tracking is enabled, when a user pauses over a list view item, the item label is automatically
highlighted without the use of a mouse button.
Example

// Set the hot item to the first item only if no other item is
// highlighted.
if (m_myListCtrl.GetHotItem() == -1)
m_myListCtrl.SetHotItem(0);

CListCtrl::GetHoverTime
Retrieves the current hover time of a list view control.

DWORD GetHoverTime() const;

Return Value
Returns the delay, in milliseconds, which the mouse cursor must hover over an item before it is selected. If
the return value is -1, then the hover time is the default hover time.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetHoverTime, as described
in the Windows SDK.
Example

// If the hover time is the default set to 1 sec.


DWORD dwTime = m_myListCtrl.GetHoverTime();
if (dwTime == -1)
m_myListCtrl.SetHoverTime(1000);

CListCtrl::GetImageList
Retrieves the handle of an image list used for drawing list view items.

CImageList* GetImageList(int nImageList) const;

Parameters
nImageList
Value specifying which image list to retrieve. It can be one of these values:
LVSIL_NORMAL Image list with large icons.
LVSIL_SMALL Image list with small icons.
LVSIL_STATE Image list with state images.
Return Value
A pointer to the image list used for drawing list view items.
Example

ASSERT(m_myListCtrl.GetImageList(LVSIL_NORMAL) == NULL);
m_myListCtrl.SetImageList(&m_lcImageList, LVSIL_NORMAL);
ASSERT(m_myListCtrl.GetImageList(LVSIL_NORMAL) == &m_lcImageList);

CListCtrl::GetInsertMark
Retrieves the current position of the insertion mark.

BOOL GetInsertMark(LPLVINSERTMARK plvim) const;

Parameters
plvim
A pointer to an LVINSERTMARK structure containing the information for the insert mark.
Return Value
Returns TRUE if successful, or FALSE otherwise. FALSE is returned if the size in the cbSize member of the
LVINSERTMARK structure does not equal the actual size of the structure.

Remarks
This member function emulates the functionality of the LVM_GETINSERTMARK message, as described in the
Windows SDK.

CListCtrl::GetInsertMarkColor
Retrieves the current color of the insertion mark.

COLORREF GetInsertMarkColor() const;

Return Value
Returns a COLORREF structure that contains the color of the insertion point.
Remarks
This member function emulates the functionality of the LVM_GETINSERTMARKCOLOR message, as
described in the Windows SDK.
CListCtrl::GetInsertMarkRect
Retrieves the rectangle that bounds the insertion point.

int GetInsertMarkRect(LPRECT pRect) const;

Parameters
pRect
Pointer to a RECT structure that contains the coordinates of a rectangle that bounds the insertion point.
Return Value
Returns one of the following values:
0 No insertion point found.
1 Insertion point found.
Remarks
This member function emulates the functionality of the LVM_GETINSERTMARKRECT message, as described
in the Windows SDK.

CListCtrl::GetItem
Retrieves some or all of a list view item's attributes.

BOOL GetItem(LVITEM* pItem) const;

Parameters
pItem
Pointer to an LVITEM structure that receives the item's attributes.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The LVITEM structure specifies or receives the attributes of a list view item.

CListCtrl::GetItemCount
Retrieves the number of items in a list view control.

int GetItemCount() const;

Return Value
The number of items in the list view control.
Example
See the example for CListCtrl::DeleteItem.

CListCtrl::GetItemData
Retrieves the 32-bit application-specific value associated with the item specified by nItem .
DWORD_PTR GetItemData(int nItem) const;

Parameters
nItem
Index of the list item whose data is to be retrieved.
Return Value
A 32-bit application-specific value associated with the specified item.
Remarks
This value is the lParam member of the LVITEM structure, as described in the Windows SDK
Example

// If any item's data is equal to zero then reset it to -1.


for (int i=0; i < m_myListCtrl.GetItemCount(); i++)
{
if (m_myListCtrl.GetItemData(i) == 0)
{
m_myListCtrl.SetItemData(i, (DWORD) -1);
}
}

CListCtrl::GetItemIndexRect
Retrieves the bounding rectangle for all or part of a subitem in the current list-view control.

BOOL GetItemIndexRect(
PLVITEMINDEX pItemIndex,
int iColumn,
int rectType,
LPRECT pRect) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pItemIndex [in] Pointer to an LVITEMINDEX structure for the parent


item of the subitem.

The caller is responsible for allocating and setting the


members of the LVITEMINDEX structure. This parameter
cannot be NULL.

iColumn [in] Zero-based index of a column in the control.


PA RA M ET ER DESC RIP T IO N

rectType [in] Portion of the list-view subitem for which the


bounding rectangle is retrieved. Specify one of the
following values:

LVIR_BOUNDS - Returns the bounding rectangle of the


entire subitem, including the icon and label.

LVIR_ICON - Returns the bounding rectangle of the icon


or small icon of the subitem.

LVIR_LABEL - Returns the bounding rectangle of the


subitem text.

pRect [out] Pointer to a RECT structure that receives information


about the bounding rectangle of the subitem.

The caller is responsible for allocating the RECT structure.


This parameter cannot be NULL.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the LVM_GETITEMINDEXRECT message, which is described in the Windows SDK. For
more information, see ListView_GetItemIndexRect Macro.
Example
The following code example defines a variable, m_listCtrl , that is used to access the current list-view
control. This variable is used in the next example.

public:
// Variable used to access the list control.
CListCtrl m_listCtrl;

Example
The following code example demonstrates the GetGroupRect method. Prior to entering this code example
we created a list-view control that displays two columns titled "ClientID" and "Grade" in a report view. The
following code example draws a 3D rectangle around the second subitem in both columns.

// GetItemIndexRect
// Get the rectangle that bounds the second item in the first group.
LVITEMINDEX lvItemIndex;
lvItemIndex.iGroup = 0;
lvItemIndex.iItem = 1;
CRect rect;
BOOL bRet = m_listCtrl.GetItemIndexRect(
&lvItemIndex, 0, LVIR_BOUNDS, &rect);

// Draw a red rectangle around the item.


m_listCtrl.GetDC()->Draw3dRect( &rect, RGB(255, 0, 0), RGB(255, 0, 0) );

CListCtrl::GetItemPosition
Retrieves the position of a list view item.
BOOL GetItemPosition(
int nItem,
LPPOINT lpPoint) const;

Parameters
nItem
The index of the item whose position is to be retrieved.
lpPoint
Address of a POINT structure that receives the position of the item's upper-left corner, in view coordinates.
Return Value
Nonzero if successful; otherwise zero.
Example

POINT pt;

// Move all items in the list control 100 pixels to the right.
UINT i, nCount = m_myListCtrl.GetItemCount();

for (i=0; i < nCount; i++)


{
m_myListCtrl.GetItemPosition(i, &pt);
pt.x += 100;
m_myListCtrl.SetItemPosition(i, pt);
}

CListCtrl::GetItemRect
Retrieves the bounding rectangle for all or part of an item in the current view.

BOOL GetItemRect(
int nItem,
LPRECT lpRect,
UINT nCode) const;

Parameters
nItem
The index of the item whose position is to be retrieved.
lpRect
Address of a RECT structure that receives the bounding rectangle.
nCode
Portion of the list view item for which to retrieve the bounding rectangle. It can be one of these values:
LVIR_BOUNDS Returns the bounding rectangle of the entire item, including the icon and label.
LVIR_ICON Returns the bounding rectangle of the icon or small icon.
LVIR_LABEL Returns the bounding rectangle of the item text.
Return Value
Nonzero if successful; otherwise zero.
Example
// OnClick is the handler for the NM_CLICK notification
void CListCtrlDlg::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
UNREFERENCED_PARAMETER(pResult);
LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pNMHDR;

// Get the current mouse location and convert it to client


// coordinates.
CPoint pos( ::GetMessagePos() );
ScreenToClient(&pos);

// Get indexes of the first and last visible items in


// the listview control.
int index = m_myListCtrl.GetTopIndex();
int last_visible_index = index + m_myListCtrl.GetCountPerPage();
if (last_visible_index > m_myListCtrl.GetItemCount())
last_visible_index = m_myListCtrl.GetItemCount();

// Loop until number visible items has been reached.


while (index <= last_visible_index)
{
// Get the bounding rectangle of an item. If the mouse
// location is within the bounding rectangle of the item,
// you know you have found the item that was being clicked.
CRect r;
m_myListCtrl.GetItemRect(index, &r, LVIR_BOUNDS);
if (r.PtInRect(pia->ptAction))
{
UINT flag = LVIS_SELECTED | LVIS_FOCUSED;
m_myListCtrl.SetItemState(index, flag, flag);
break;
}

// Get the next item in listview control.


index++;
}
}

CListCtrl::GetItemSpacing
Calculates the spacing between items in the current list-view control.

BOOL GetItemSpacing(
BOOL fSmall,
int* pnHorzSpacing,
int* pnVertSpacing) const;

Parameters
PA RA M ET ER DESC RIP T IO N

fSmall [in] View for which to retrieve the item spacing. Specify
TRUE for small icon view, or FALSE for icon view.

pnHorzSpacing [out] Contains the horizontal spacing between items.

pnVertSpacing [out] Contains the vertical spacing between items.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method sends the LVM_GETITEMSPACING message, which is described in the Windows SDK.

CListCtrl::GetItemState
Retrieves the state of a list view item.

UINT GetItemState(
int nItem,
UINT nMask) const;

Parameters
nItem
The index of the item whose state is to be retrieved.
nMask
Mask specifying which of the item's state flags to return.
Return Value
The state flags for the specified list view item.
Remarks
An item's state is specified by the state member of the LVITEM structure, as described in the Windows
SDK. When you specify or change an item's state, the stateMask member specifies which state bits you
want to change.
Example
See the example for CListCtrl::GetTopIndex.

CListCtrl::GetItemText
Retrieves the text of a list view item or subitem.

int GetItemText(
int nItem,
int nSubItem,
LPTSTR lpszText,
int nLen) const;

CString GetItemText(
int nItem,
int nSubItem) const;

Parameters
nItem
The index of the item whose text is to be retrieved.
nSubItem
Specifies the subitem whose text is to be retrieved.
lpszText
Pointer to a string that is to receive the item text.
nLen
Length of the buffer pointed to by lpszText.
Return Value
The version returning int returns the length of the retrieved string.
The version returning a CString returns the item text.
Remarks
If nSubItem is zero, this function retrieves the item label; if nSubItem is nonzero, it retrieves the text of the
subitem. For more information on the subitem argument, see the discussion of the LVITEM structure in the
Windows SDK.

CListCtrl::GetNextItem
Searches for a list view item that has the specified properties and that bears the specified relationship to a
given item.

int GetNextItem(
int nItem,
int nFlags) const;

Parameters
nItem
Index of the item to begin the searching with, or -1 to find the first item that matches the specified flags. The
specified item itself is excluded from the search.
nFlags
Geometric relation of the requested item to the specified item, and the state of the requested item. The
geometric relation can be one of these values:
LVNI_ABOVE Searches for an item that is above the specified item.
LVNI_ALL Searches for a subsequent item by index (the default value).
LVNI_BELOW Searches for an item that is below the specified item.
LVNI_TOLEFT Searches for an item to the left of the specified item.
LVNI_TORIGHT Searches for an item to the right of the specified item.
The state can be zero, or it can be one or more of these values:
LVNI_DROPHILITED The item has the LVIS_DROPHILITED state flag set.
LVNI_FOCUSED The item has the LVIS_FOCUSED state flag set.
LVNI_SELECTED The item has the LVIS_SELECTED state flag set.
If an item does not have all of the specified state flags set, the search continues with the next item.
Return Value
The index of the next item if successful, or -1 otherwise.

CListCtrl::GetNextItemIndex
Retrieves the index of the item in the current list-view control that has a specified set of properties.
BOOL GetNextItemIndex(
PLVITEMINDEX pItemIndex,
int nFlags) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pItemIndex [in, out] Pointer to the LVITEMINDEX structure that


describes the item where the search begins, or -1 to find
the first item that matches the flags in the nFlags
parameter.

If this method is successful, the LVITEMINDEX structure


describes the item found by the search.

nFlags [in] A bitwise combination (OR) of flags that specify how


to perform the search.

The search can depend on the index, state, or appearance


of the target item, or the target item's physical position
relative to the item specified by the pItemIndex parameter.
For more information, see the flags parameter in the
LVM_GETNEXTITEMINDEX message.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
The caller is responsible for allocating and setting the members of the LVITEMINDEX structure pointed to by
the pItemIndex parameter.
This method sends the LVM_GETNEXTITEMINDEX message, which is described in the Windows SDK.

CListCtrl::GetNextSelectedItem
Gets the index of the list item identified by pos, then sets pos to the POSITION value.

int GetNextSelectedItem(POSITION& pos) const;

Parameters
pos
A reference to a POSITION value returned by a previous call to GetNextSelectedItem or
GetFirstSelectedItemPosition . The value is updated to the next position by this call.

Return Value
The index of the list item identified by pos.
Remarks
You can use GetNextSelectedItem in a forward iteration loop if you establish the initial position with a call to
GetFirstSelectedItemPosition .
You must ensure that your POSITION value is valid. If it is invalid, then the Debug version of the Microsoft
Foundation Class Library asserts.
Example
The following code sample demonstrates the usage of this function.

POSITION pos = m_myListCtrl.GetFirstSelectedItemPosition();


if (pos == NULL)
{
TRACE(_T("No items were selected!\n"));
}
else
{
while (pos)
{
int nItem = m_myListCtrl.GetNextSelectedItem(pos);
TRACE(_T("Item %d was selected!\n"), nItem);
// you could do your own processing on nItem here
}
}

CListCtrl::GetNumberOfWorkAreas
Retrieves the current number of working areas for a list view control.

UINT GetNumberOfWorkAreas() const;

Return Value
Not used at this time.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetNumberOfWorkAreas, as
described in the Windows SDK.
Example

UINT i, uCount = m_myListCtrl.GetNumberOfWorkAreas();


LPRECT lpRects = (LPRECT) malloc(uCount*sizeof(RECT));

if (lpRects != NULL)
{
// Dump all of the work area dimensions.
m_myListCtrl.GetWorkAreas(uCount, lpRects);

for (i=0; i < uCount; i++)


{
TRACE(_T("Work area %d; left = %d, top = %d, right = %d, ")
_T("bottom = %d\r\n"),
i, lpRects[i].left, lpRects[i].top, lpRects[i].right,
lpRects[i].bottom);
}

free(lpRects);
}
else
{
TRACE(_T("Couldn't allocate enough memory!"));
}

CListCtrl::GetOutlineColor
Retrieves the color of the border of a list view control.
COLORREF GetOutlineColor() const;

Return Value
Returns a COLORREF structure containing the outline color.
Remarks
This member function emulates the functionality of the LVM_GETOUTLINECOLOR message, as described in
the Windows SDK.

CListCtrl::GetOrigin
Retrieves the current view origin for a list view control.

BOOL GetOrigin(LPPOINT lpPoint) const;

Parameters
lpPoint
Address of a POINT structure that receives the view origin.
Return Value
Nonzero if successful; otherwise zero. However, if the control is in report view, the return value is always
zero.

CListCtrl::GetSelectedColumn
Retrieves the index of the currently selected column in the list control.

UINT GetSelectedColumn() const;

Return Value
The index of the selected column.
Remarks
This member function emulates the functionality of the LVM_GETSELECTEDCOLUMN message, as described
in the Windows SDK.

CListCtrl::GetSelectedCount
Retrieves the number of selected items in the list view control.

UINT GetSelectedCount() const;

Return Value
The number of selected items in the list view control.
Example
UINT i, uSelectedCount = m_myListCtrl.GetSelectedCount();
int nItem = -1;

// Update all of the selected items.


if (uSelectedCount > 0)
{
for (i=0; i < uSelectedCount; i++)
{
nItem = m_myListCtrl.GetNextItem(nItem, LVNI_SELECTED);
ASSERT(nItem != -1);
m_myListCtrl.Update(nItem);
}
}

CListCtrl::GetSelectionMark
Retrieves the selection mark of a list view control.

int GetSelectionMark();

Return Value
The zero-based selection mark, or -1 if there is no selection mark.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetSelectionMark, as
described in the Windows SDK.
Example

// Set the selection mark to the first item only if no other item is
// selected.
if (m_myListCtrl.GetSelectionMark() == -1)
m_myListCtrl.SetSelectionMark(0);

CListCtrl::GetStringWidth
Determines the minimum column width necessary to display all of a given string.

int GetStringWidth(LPCTSTR lpsz) const;

Parameters
lpsz
Address of a null-terminated string whose width is to be determined.
Return Value
The width, in pixels, of the string pointed to by lpsz.
Remarks
The returned width takes into account the control's current font and column margins, but not the width of a
small icon.
Example
CString strColumn;
int nWidth;

// Insert six columns in the list view control. Make the width of
// the column be the width of the column header plus 50%.
for (int i = 0; i < 6; i++)
{
strColumn.Format(_T("column %d"), i);
nWidth = 3*m_myListCtrl.GetStringWidth(strColumn)/2;
m_myListCtrl.InsertColumn(i, strColumn, LVCFMT_LEFT, nWidth);
}

CListCtrl::GetSubItemRect
Retrieves the bounding rectangle of an item in a list view control.

BOOL GetSubItemRect(
int iItem,
int iSubItem,
int nArea,
CRect& ref);

Parameters
iItem
Index of the subitem's parent item.
iSubItem
The one-based index of the subitem.
nArea
Determines the portion of the bounding rectangle (of the list view subitem) to be retrieved. The portion
(icon, label, or both) of the bounding rectangle is specified by applying the bitwise OR operator to one or
more of the following values:
LVIR_BOUNDS Returns the bounding rectangle of the entire item, including the icon and label.
LVIR_ICON Returns the bounding rectangle of the icon or small icon.
LVIR_LABEL Returns the bounding rectangle of the entire item, including the icon and label. This is
identical to LVIR_BOUNDS.
ref
Reference to a CRect object that contains the coordinates of the subitem's bounding rectangle.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetSubItemRect, as
described in the Windows SDK.

CListCtrl::GetTextBkColor
Retrieves the text background color of a list view control.

COLORREF GetTextBkColor() const;


Return Value
A 32-bit value used to specify an RGB color.
Example
See the example for CListCtrl::SetTextBkColor.

CListCtrl::GetTextColor
Retrieves the text color of a list view control.

COLORREF GetTextColor() const;

Return Value
A 32-bit value used to specify an RGB color.
Example
See the example for CListCtrl::SetTextColor.

CListCtrl::GetTileInfo
Retrieves information about a tile in a list view control.

BOOL GetTileInfo(PLVTILEINFO plvti) const;

Parameters
plvti
A pointer to an LVTILEINFO structure that receives the tile information.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the LVM_GETTILEINFO message, as described in the
Windows SDK.

CListCtrl::GetTileViewInfo
Retrieves information about a list view control in tile view.

BOOL GetTileViewInfo(PLVTILEVIEWINFO ptvi) const;

Parameters
ptvi
A pointer to an LVTILEVIEWINFO structure that receives the retrieved information.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the LVM_GETTILEVIEWINFO message, as described in
the Windows SDK.
CListCtrl::GetToolTips
Retrieves the tooltip control that the list view control uses to display tooltips.

CToolTipCtrl* GetToolTips() const;

Return Value
A pointer to a CToolTipCtrl object to be used by the list control. If the Create member function uses the style
LVS_NOTOOLTIPS, no tooltips are used, and NULL is returned.
Remarks
This member function implements the behavior of the Win32 message LVM_GETTOOLTIPS, as described in
the Windows SDK. The MFC implementation of GetToolTips returns a CToolTipCtrl object, which is used
by the list control, rather than a handle to a tooltip control.
Example

CToolTipCtrl* pTip = m_myListCtrl.GetToolTips();


if (NULL != pTip)
{
pTip->UpdateTipText(_T("I'm a list view!"), &m_myListCtrl,
IDD_MYLISTCTRL);
}

CListCtrl::GetTopIndex
Retrieves the index of the topmost visible item when in list view or report view.

int GetTopIndex() const;

Return Value
The index of the topmost visible item.
Example

// Make sure the focus is set to the list view control.


m_myListCtrl.SetFocus();

// Select all of the items that are completely visible.


int n = m_myListCtrl.GetTopIndex();
int nLast = n + m_myListCtrl.GetCountPerPage();

for (; n < nLast; n++)


{
m_myListCtrl.SetItemState(n, LVIS_SELECTED, LVIS_SELECTED);
ASSERT(m_myListCtrl.GetItemState(n, LVIS_SELECTED) == LVIS_SELECTED);
}

CListCtrl::GetView
Gets the view of the list view control.

DWORD GetView() const;


Return Value
The current view of the list view control.
Remarks
This member function emulates the functionality of the LVM_GETVIEW message, as described in the
Windows SDK.

CListCtrl::GetViewRect
Retrieves the bounding rectangle of all items in the list view control.

BOOL GetViewRect(LPRECT lpRect) const;

Parameters
lpRect
Address of a RECT structure.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The list view must be in icon view or small icon view.

CListCtrl::GetWorkAreas
Retrieves the current working areas of a list view control.

void GetWorkAreas(
int nWorkAreas,
LPRECT pRect) const;

Parameters
nWorkAreas
The number of RECT structures contained in the pRect array.
pRect
A pointer to an array of RECT structures (or CRect objects) that receive the working areas of the list view
control. Values in these structures are in client coordinates.
Remarks
This member function implements the behavior of the Win32 macro, ListView_GetWorkAreas, as described
in the Windows SDK.
Example
See the example for CListCtrl::GetNumberOfWorkAreas.

CListCtrl::HasGroup
Determines if the list view control has the specified group.

BOOL HasGroup(int iGroupId) const;

Parameters
iGroupId
The identifier of the group being requested.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the LVM_HASGROUP message, as described in the
Windows SDK.

CListCtrl::HitTest
Determines which list view item, if any, is at a specified position.

int HitTest(LVHITTESTINFO* pHitTestInfo) const;

int HitTest(
CPoint pt,
UINT* pFlags = NULL) const;

Parameters
pHitTestInfo
Address of an LVHITTESTINFO structure that contains the position to hit test and that receives information
about the results of the hit test.
pt
Point to be tested.
pFlags
Pointer to an integer that receives information about the results of the test. See the explanation of the
flags member of the LVHITTESTINFO structure in the Windows SDK.

Return Value
The index of the item at the position specified by pHitTestInfo, if any, or -1 otherwise.
Remarks
You can use the LVHT_ABOVE, LVHT_BELOW, LVHT_TOLEFT, and LVHT_TORIGHT values of the structure's
flag member to determine whether to scroll the contents of a list view control. Two of these flags can be
combined, for example, if the position is above and to the left of the client area.
You can test for the LVHT_ONITEM value of the structure's flag member to determine whether a given
position is over a list view item. This value is a bitwise-OR operation on the LVHT_ONITEMICON,
LVHT_ONITEMLABEL, and LVHT_ONITEMSTATEICON values of the structure's flag member.
Example
void CListCtrlDlg::OnRClick(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pNMHDR;
CPoint point(pia->ptAction);

// Select the item the user clicked on.


UINT uFlags;
int nItem = m_myListCtrl.HitTest(point, &uFlags);

if (uFlags & LVHT_ONITEMLABEL)


{
m_myListCtrl.SetItem(nItem, 0, LVIF_STATE, NULL, 0, LVIS_SELECTED,
LVIS_SELECTED, 0);
}

*pResult = 0;
}

CListCtrl::InsertColumn
Inserts a new column in a list view control.

int InsertColumn(
int nCol,
const LVCOLUMN* pColumn);

int InsertColumn(
int nCol,
LPCTSTR lpszColumnHeading,
int nFormat = LVCFMT_LEFT,
int nWidth = -1,
int nSubItem = -1);

Parameters
nCol
The index of the new column.
pColumn
Address of an LVCOLUMN structure that contains the attributes of the new column.
lpszColumnHeading
Address of a string containing the column's heading.
nFormat
Integer specifying the alignment of the column. It can be one of these values: LVCFMT_LEFT,
LVCFMT_RIGHT, or LVCFMT_CENTER.
nWidth
Width of the column, in pixels. If this parameter is -1, the column width is not set.
nSubItem
Index of the subitem associated with the column. If this parameter is -1, no subitem is associated with the
column.
Return Value
The index of the new column if successful or -1 otherwise.
Remarks
The leftmost column in a list view control must be left-aligned.
The LVCOLUMN structure contains the attributes of a column in report view. It is also used to receive
information about a column. This structure is described in the Windows SDK.

CListCtrl::InsertGroup
Inserts a group into the list view control.

LRESULT InsertGroup(
int index,
PLVGROUP pgrp);

Parameters
index
The index of the item where the group is to be inserted.
pgrp
A pointer to an LVGROUP structure containing the group to be added.
Return Value
Returns the index of the item that the group was added to, or -1 if the operation failed.
Remarks
This member function emulates the functionality of the LVM_INSERTGROUP message, as described in the
Windows SDK.

CListCtrl::InsertGroupSorted
Inserts the specified group into an ordered list of groups.

LRESULT InsertGroupSorted(PLVINSERTGROUPSORTED pStructInsert);

Parameters
pStructInsert
A pointer to an LVINSERTGROUPSORTED structure that contains the group to insert.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the LVM_INSERTGROUPSORTED message, as described
in the Windows SDK.

CListCtrl::InsertItem
Inserts an item into the list view control.
int InsertItem(const LVITEM* pItem);

int InsertItem(
int nItem,
LPCTSTR lpszItem);

int InsertItem(
int nItem,
LPCTSTR lpszItem,
int nImage);

int InsertItem(
UINT nMask,
int nItem,
LPCTSTR lpszItem,
UINT nState,
UINT nStateMask,
int nImage,
LPARAM lParam);

Parameters
pItem
Pointer to an LVITEM structure that specifies the item's attributes, as described in the Windows SDK.
nItem
Index of the item to be inserted.
lpszItem
Address of a string containing the item's label, or LPSTR_TEXTCALLBACK if the item is a callback item. For
information on callback items, see CListCtrl::GetCallbackMask.
nImage
Index of the item's image, or I_IMAGECALLBACK if the item is a callback item. For information on callback
items, see CListCtrl::GetCallbackMask.
nMask
The nMask parameter specifies which item attributes passed as parameters are valid. It can be one or more
of the mask values described in LVITEM Structure in the Windows SDK. The valid values can be combined
with the bitwise OR operator.
nState
Indicates the item's state, state image, and overlay image. For more information, see the Windows SDK
topics LVITEM Structure and List-View Item States for a list of valid flags.
nStateMask
Indicates which bits of the state member will be retrieved or modified. For more information, see LVITEM
Structure in the Windows SDK.
lParam
A 32-bit application-specific value associated with the item. If this parameter is specified, you must set the
nMask attribute LVIF_PARAM.
Return Value
The index of the new item if successful or -1 otherwise.
Remarks
Calling this method may cause the LVM_INSERTITEM message to be sent to your control window. The
associated message handler for the control may fail to set the item text under certain conditions (such as
using window styles such as LVS_OWNERDRAW). For more information on these conditions, see
LVM_INSERTITEM in the Windows SDK.
Example

CString strText;
int nColumnCount = m_myListCtrl.GetHeaderCtrl()->GetItemCount();

// Insert 10 items in the list view control.


for (int i = 0; i < 10; i++)
{
strText.Format(TEXT("item %d"), i);

// Insert the item, select every other item.


m_myListCtrl.InsertItem(LVIF_TEXT | LVIF_STATE, i, strText,
(i % 2) == 0 ? LVIS_SELECTED : 0, LVIS_SELECTED, 0, 0);

// Initialize the text of the subitems.


for (int j = 1; j < nColumnCount; j++)
{
strText.Format(TEXT("sub-item %d %d"), i, j);
m_myListCtrl.SetItemText(i, j, strText);
}
}

CListCtrl::InsertMarkHitTest
Retrieves the insertion point closest to a specified point.

int InsertMarkHitTest(
LPPOINT pPoint,
LPLVINSERTMARK plvim) const;

Parameters
pPoint
A pointer to a POINT structure that contains the hit test coordinates, relative to the client area of the list
control.
plvim
A pointer to an LVINSERTMARK structure that specifies the insertion point closest to the coordinates
defined by the point parameter.
Return Value
The insertion point closest to the specified point.
Remarks
This member function emulates the functionality of the LVM_INSERTMARKHITTEST message, as described
in the Windows SDK.

CListCtrl::IsGroupViewEnabled
Determines whether group view is enabled for a list view control.

BOOL IsGroupViewEnabled() const;

Return Value
Returns TRUE if group view is enabled, or FALSE otherwise.
Remarks
This member function emulates the functionality of the LVM_ISGROUPVIEWENABLED message, as
described in the Windows SDK.

CListCtrl::IsItemVisible
Indicates whether a specified item in the current list-view control is visible.

BOOL IsItemVisible(int index) const;

Parameters
PA RA M ET ER DESC RIP T IO N

index [in] Zero-based index of an item in the current list-view


control.

Return Value
TRUE if the specified item is visible; otherwise, FALSE.
Remarks
This method sends the LVM_ISITEMVISIBLE message, which is described in the Windows SDK.

CListCtrl::MapIDToIndex
Maps the unique ID of an item in the current list-view control to an index.

UINT MapIDToIndex(UINT id) const;

Parameters
PA RA M ET ER DESC RIP T IO N

id [in] The unique ID of an item.

Return Value
The current index for the specified ID.
Remarks
A list-view control internally tracks items by index. This can present problems because indexes can change
during the control's lifetime. The list-view control can tag an item with an ID when the item is created and
you can use this ID to guarantee uniqueness during the lifetime of the list-view control.
Note that in a multithreaded environment the index is guaranteed only on the thread that hosts the list-
view control, not on background threads.
This method sends the LVM_MAPIDTOINDEX message, which is described in the Windows SDK.

CListCtrl::MapIndexToID
Maps the index of an item in the current list-view control to a unique ID.
UINT MapIndexToID(UINT index) const;

Parameters
PA RA M ET ER DESC RIP T IO N

index [in] The zero-based index of an item.

Return Value
A unique ID for the specified item.
Remarks
A list-view control internally tracks items by index. This can present problems because indexes can change
during the control's lifetime. The list-view control can tag an item with an ID when the item is created. You
can use this ID to access a specific item for the lifetime of the list-view control.
Note that in a multithreaded environment the index is guaranteed only on the thread that hosts the list-
view control, not on background threads.
This method sends the LVM_MAPINDEXTOID message, which is described in the Windows SDK.
Example
The following code example defines a variable, m_listCtrl , that is used to access the current list-view
control. This variable is used in the next example.

public:
// Variable used to access the list control.
CListCtrl m_listCtrl;

Example
The following code example demonstrates the MapIndexToID method. In an earlier section of this code
example, we created a list-view control that displays two columns titled "ClientID" and "Grade" in a report
view. The following example maps the index of each list-view item to an identification number, and then
retrieves the index for each identification number. Finally, the example reports whether the original indexes
were retrieved.
// MapIndexToID
int iCount = m_listCtrl.GetItemCount();
UINT nId = 0;
UINT nIndex = 0;
for (int iIndexOriginal = 0; iIndexOriginal < iCount; iIndexOriginal++)
{
// Map index to ID.
nId = m_listCtrl.MapIndexToID((UINT)iIndexOriginal);

// Map ID to index.
nIndex = m_listCtrl.MapIDToIndex(nId);

if (nIndex != (UINT)(iIndexOriginal))
{
CString str;
str.Format(_T("Mapped index (%d) is not equal to original index (%d)"),
nIndex, (UINT)(iIndexOriginal));
AfxMessageBox(str);
return;
}
}
AfxMessageBox(_T("The mapped indexes and original indexes are equal."),
MB_ICONINFORMATION);

CListCtrl::MoveGroup
Moves the specified group to the specified zero based index of the list view control.

LRESULT MoveGroup(
int iGroupId,
int toIndex);

Parameters
iGroupId
The identifier of the group to be moved.
toIndex
The zero-based index where the group is to be moved.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the LVM_MOVEGROUP message, as described in the
Windows SDK.

CListCtrl::MoveItemToGroup
Moves the specified item into the specified group.

void MoveItemToGroup(
int idItemFrom,
int idGroupTo);

Parameters
idItemFrom
[in] The index of the item to be moved.
idGroupTo
[in] The identifier of the group the item will be moved to.
Remarks

NOTE
This method currently is not implemented.

This method emulates the functionality of the LVM_MOVEITEMTOGROUP message, as described in the
Windows SDK.

CListCtrl::RedrawItems
Forces a list view control to repaint a range of items.

BOOL RedrawItems(
int nFirst,
int nLast);

Parameters
nFirst
Index of the first item to be repainted.
nLast
Index of the last item to be repainted.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The specified items are not actually repainted until the list view window receives a WM_PAINT message. To
repaint immediately, call the Windows UpdateWindow function after using this function.

CListCtrl::RemoveAllGroups
Removes all groups from a list view control.

void RemoveAllGroups();

Remarks
This member function emulates the functionality of the LVM_REMOVEALLGROUPS message, as described
in the Windows SDK.

CListCtrl::RemoveGroup
Removes the specified group from the list view control.

LRESULT RemoveGroup(int iGroupId);

Parameters
iGroupId
The identifier of the group to be removed.
Return Value
Returns the index of the group if successful, or -1 otherwise.
Remarks
This member function emulates the functionality of the LVM_REMOVEGROUP message, as described in the
Windows SDK.

CListCtrl::Scroll
Scrolls the content of a list view control.

BOOL Scroll(CSize size);

Parameters
size
A CSize object specifying the amount of horizontal and vertical scrolling, in pixels. The y member of size
is divided by the height, in pixels, of the list view control's line, and the control is scrolled by the resulting
number of lines.
Return Value
Nonzero if successful; otherwise zero.

CListCtrl::SetBkColor
Sets the background color of the list view control.

BOOL SetBkColor(COLORREF cr);

Parameters
cr
Background color to set, or the CLR_NONE value for no background color. List view controls with
background colors redraw themselves significantly faster than those without background colors. For
information, see COLORREF in the Windows SDK.
Return Value
Nonzero if successful; otherwise zero.
Example

// Use the 3D button face color for the background.


COLORREF crBkColor = ::GetSysColor(COLOR_3DFACE);
m_myListCtrl.SetBkColor(crBkColor);
ASSERT(m_myListCtrl.GetBkColor() == crBkColor);

CListCtrl::SetBkImage
Sets the background image of a list view control.
BOOL SetBkImage(LVBKIMAGE* plvbkImage);

BOOL SetBkImage(
HBITMAP hBitmap,
BOOL fTile = TRUE,
int xOffsetPercent = 0,
int yOffsetPercent = 0);

BOOL SetBkImage(
LPTSTR pszUrl,
BOOL fTile = TRUE,
int xOffsetPercent = 0,
int yOffsetPercent = 0);

Parameters
plvbkImage
Address of an LVBKIMAGE structure, containing the new background image information.
hBitmap
Handle to a bitmap.
pszUrl
A NULL-terminated string that contains the URL of the background image.
fTile
Nonzero if the image is to be tiled in the background of the list view control; otherwise 0.
xOffsetPercent
The offset, in pixels, of the image's left edge, from origin of the list view control.
yOffsetPercent
The offset, in pixels, of the image's top edge, from origin of the list view control.
Return Value
Returns nonzero if successful, or zero otherwise.
Remarks

NOTE
Because CListCtrl::SetBkImage makes use of OLE COM functionality, the OLE libraries must be initialized before
using SetBkImage . It is best to initialize the COM libraries when the application is initialized and uninitialize the
libraries when the application terminates. This is automatically done in MFC applications that make use of ActiveX
technology, OLE Automation, OLE Linking/Embedding, or ODBC/DAO operations.

Example
See the example for CListCtrl::GetBkImage.

CListCtrl::SetCallbackMask
Sets the callback mask for a list view control.

BOOL SetCallbackMask(UINT nMask);

Parameters
nMask
New value of the callback mask.
Return Value
Nonzero if successful; otherwise zero.
Example

// Set the callback mask so that only the selected and focused states
// are stored for each item.
m_myListCtrl.SetCallbackMask(LVIS_SELECTED|LVIS_FOCUSED);
ASSERT(m_myListCtrl.GetCallbackMask() ==
(LVIS_SELECTED|LVIS_FOCUSED));

CListCtrl::SetCheck
Determines if the state image of a list control item is visible.

BOOL SetCheck(
int nItem,
BOOL fCheck = TRUE);

Parameters
nItem
The zero-based index of a list control item.
fCheck
Specifies whether the state image of the item should be visible or not. By default, fCheck is TRUE and the
state image is visible. If fCheck is FALSE, it is not visible.
Return Value
Nonzero if the item is checked, otherwise 0.
Example

int nCount = m_myListCtrl.GetItemCount();


BOOL fCheck = FALSE;

// Set the check state of every other item to TRUE and


// all others to FALSE.
for (int i = 0; i < nCount; i++)
{
m_myListCtrl.SetCheck(i, fCheck);
ASSERT((m_myListCtrl.GetCheck(i) && fCheck) ||
(!m_myListCtrl.GetCheck(i) && !fCheck));
fCheck = !fCheck;
}

CListCtrl::SetColumn
Sets the attributes of a list view column.

BOOL SetColumn(
int nCol,
const LVCOLUMN* pColumn);

Parameters
nCol
Index of the column whose attributes are to be set.
pColumn
Address of an LVCOLUMN structure that contains the new column attributes, as described in the Windows
SDK. The structure's mask member specifies which column attributes to set. If the mask member specifies
the LVCF_TEXT value, the structure's pszText member is the address of a null-terminated string and the
structure's cchTextMax member is ignored.
Return Value
Nonzero if successful; otherwise zero.
Example
See the example for CListCtrl::GetColumn.

CListCtrl::SetColumnOrderArray
Sets the column order (left to right) of a list view control.

BOOL SetColumnOrderArray(
int iCount,
LPINT piArray);

Parameters
piArray
A pointer to a buffer containing the index values of the columns in the list view control (from left to right).
The buffer must be large enough to contain the total number of columns in the list view control.
iCount
Number of columns in the list view control.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetColumnOrderArray, as
described in the Windows SDK.
Example
See the example for CListCtrl::GetColumnOrderArray.

CListCtrl::SetColumnWidth
Changes the width of a column in report view or list view.

BOOL SetColumnWidth(
int nCol,
int cx);

Parameters
nCol
Index of the column for which the width is to be set. In list view, this parameter must be 0.
cx
The new width of the column. Can be either LVSCW_AUTOSIZE or LVSCW_AUTOSIZE_USEHEADER, as
described in LVM_SETCOLUMNWIDTH in the Windows SDK.
Return Value
Nonzero if successful; otherwise zero.

CListCtrl::SetExtendedStyle
Sets the current extended styles of a list view control.

DWORD SetExtendedStyle(DWORD dwNewStyle);

Parameters
dwNewStyle
A combination of extended styles to be used by the list view control. For a descriptive list of these styles, see
the Extended List View Styles topic in the Windows SDK.
Return Value
A combination of the previous extended styles used by the list view control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetExtendedListViewStyle, as
described in the Windows SDK.
Example

// Allow the header controls item to be movable by the user.


m_myListCtrl.SetExtendedStyle
(m_myListCtrl.GetExtendedStyle()|LVS_EX_HEADERDRAGDROP);

CListCtrl::SetGroupInfo
Sets the information that describes the specified group of the current list-view control.

int SetGroupInfo(
int iGroupId,
PLVGROUP pgrp);

Parameters
iGroupId
The identifier of the group whose information is set.
pgrp
Pointer to an LVGROUP structure that contains the information to set. The caller is responsible for allocating
this structure and setting its members.
Return Value
The ID of the group if the method is successful; otherwise, -1.
Remarks
This method sends the LVM_SETGROUPINFO message, which is described in the Windows SDK.

CListCtrl::SetGroupMetrics
Sets the group metrics of a list view control.

void SetGroupMetrics(PLVGROUPMETRICS pGroupMetrics);

Parameters
pGroupMetrics
A pointer to an LVGROUPMETRICS structure containing the group metrics information to be set.
Remarks
This member function emulates the functionality of the LVM_SETGROUPMETRICS message, as described in
the Windows SDK.

CListCtrl::SetHotCursor
Sets the cursor used when hot tracking is enabled for a list view control.

HCURSOR SetHotCursor(HCURSOR hc);

Parameters
hc
A handle to a cursor resource, used to represent the hot cursor.
Return Value
The handle to the previous hot cursor resource being used by the list view control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetHotCursor, as described
in the Windows SDK.
The hot cursor, only visible when hover selection is enabled, appears as the cursor passes over any list view
item. Hover selection is enabled by setting the LVS_EX_TRACKSELECT extended style.
Example
See the example for CListCtrl::GetHotCursor.

CListCtrl::SetHotItem
Sets the current hot item of a list view control.

int SetHotItem(int iIndex);

Parameters
iIndex
Zero-based index of the item to be set as the hot item.
Return Value
The zero-based index of the previously hot item.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetHotItem, as described in
the Windows SDK.
Example
See the example for CListCtrl::GetHotItem.

CListCtrl::SetHoverTime
Sets the current hover time of a list view control.

DWORD SetHoverTime(DWORD dwHoverTime = (DWORD)-1);

Parameters
dwHoverTime
The new delay, in milliseconds, which the mouse cursor must hover over an item before it is selected. If the
default value is passed, the time is set to the default hover time.
Return Value
The previous hover time, in milliseconds.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetHoverTime, as described
in the Windows SDK.
Example
See the example for CListCtrl::GetHoverTime.

CListCtrl::SetIconSpacing
Sets the spacing between icons in a list view control.

CSize SetIconSpacing(
int cx,
int cy);

CSize SetIconSpacing(CSize size);

Parameters
cx
The distance (in pixels) between icons on the x-axis.
cy
The distance (in pixels) between icons on the y-axis.
size
A CSize object specifying the distance (in pixels) between icons on the x- and y-axes.
Return Value
A CSize object containing the previous values for icon spacing.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetIconSpacing, as described
in the Windows SDK.
Example

// Leave lots of space between icons.


m_myListCtrl.SetIconSpacing(CSize(100, 100));
CListCtrl::SetImageList
Assigns an image list to a list view control.

CImageList* SetImageList(
CImageList* pImageList,
int nImageListType);

Parameters
pImageList
Pointer to the image list to assign.
nImageListType
Type of image list. It can be one of these values:
LVSIL_NORMAL Image list with large icons.
LVSIL_SMALL Image list with small icons.
LVSIL_STATE Image list with state images.
Return Value
A pointer to the previous image list.
Example
See the example for CListCtrl::GetImageList.

CListCtrl::SetInfoTip
Sets the tooltip text.

BOOL SetInfoTip(PLVSETINFOTIP plvInfoTip);

Parameters
plvInfoTip
A pointer to an LVFSETINFOTIP structure containing the information to be set.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the LVM_SETINFOTIP message, as described in the
Windows SDK.

CListCtrl::SetInsertMark
Sets the insertion point to the defined position.

BOOL SetInsertMark(LPLVINSERTMARK plvim);

Parameters
plvim
A pointer to an LVINSERTMARK structure specifying where to set the insertion point.
Return Value
Returns TRUE if successful, or FALSE otherwise. FALSE is returned if the size in the cbSize member of the
LVINSERTMARK structure does not equal the actual size of the structure, or when an insertion point does not
apply in the current view.
Remarks
This member function emulates the functionality of the LVM_SETINSERTMARK message, as described in the
Windows SDK.

CListCtrl::SetInsertMarkColor
Sets the color of the insertion point.

COLORREF SetInsertMarkColor(COLORREF color);

Parameters
color
A COLORREF structure specifying the color to set the insertion point.
Return Value
Returns a COLORREF structure containing the previous color.
Remarks
This member function emulates the functionality of the LVM_SETINSERTMARKCOLOR message, as
described in the Windows SDK.

CListCtrl::SetItem
Sets some or all of a list view item's attributes.

BOOL SetItem(const LVITEM* pItem);

BOOL SetItem(
int nItem,
int nSubItem,
UINT nMask,
LPCTSTR lpszItem,
int nImage,
UINT nState,
UINT nStateMask,
LPARAM lParam);

BOOL SetItem(
int nItem,
int nSubItem,
UINT nMask,
LPCTSTR lpszItem,
int nImage,
UINT nState,
UINT nStateMask,
LPARAM lParam,
int nIndent);

Parameters
pItem
Address of an LVITEM structure that contains the new item attributes, as described in the Windows SDK. The
structure's iItem and iSubItem members identify the item or subitem, and the structure's mask member
specifies which attributes to set. For more information on the mask member, see the Remarks .
nItem
Index of the item whose attributes are to be set.
nSubItem
Index of the subitem whose attributes are to be set.
nMask
Specifies which attributes are to be set (see the Remarks).
lpszItem
Address of a null-terminated string specifying the item's label.
nImage
Index of the item's image within the image list.
nState
Specifies values for states to be changed (see the Remarks).
nStateMask
Specifies which states are to be changed (see the Remarks).
lParam
A 32-bit application-specific value to be associated with the item.
nIndent
Width, in pixels, of the indentation. If nIndent is less than the system-defined minimum width, the new
width is set to the system-defined minimum
Return Value
Nonzero if successful; otherwise zero.
Remarks
The iItem and iSubItem members of the LVITEM structure and the nItem and nSubItem parameters
identify the item and subitem whose attributes are to be set.
The mask member of the LVITEM structure and the nMask parameter specify which item attributes are to
be set:
LVIF_TEXT The pszText member or the lpszItem parameter is the address of a null-terminated
string; the cchTextMax member is ignored.
LVIF_STATE The stateMask member or nStateMask parameter specifies which item states to change
and the state member or nState parameter contains the values for those states.
Example
See the example for CListCtrl::HitTest.

CListCtrl::SetItemCount
Prepares a list view control for adding a large number of items.

void SetItemCount(int nItems);

Parameters
nItems
Number of items that the control will ultimately contain.
Remarks
To set the item count for a virtual list view control, see CListCtrl::SetItemCountEx.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetItemCount, as described
in the Windows SDK.
Example

CString str;

// Add 1024 items to the list view control.


m_myListCtrl.SetItemCount(1024);

for (int i = 0; i < 1024; i++)


{
str.Format(TEXT("item %d"), i);
m_myListCtrl.InsertItem(i, str);
}

CListCtrl::SetItemCountEx
Sets the item count for a virtual list view control.

BOOL SetItemCountEx(
int iCount,
DWORD dwFlags = LVSICF_NOINVALIDATEALL);

Parameters
iCount
Number of items that the control will ultimately contain.
dwFlags
Specifies the behavior of the list view control after resetting the item count. This value can be a combination
of the following:
LVSICF_NOINVALIDATEALL The list view control will not repaint unless affected items are currently in
view. This is the default value.
LVSICF_NOSCROLL The list view control will not change the scroll position when the item count
changes.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetItemCountEx, as
described in the Windows SDKand should only be called for virtual list views.
Example
CString str;

// Add 1024 items to the list view control.

// Force my virtual list view control to allocate


// enough memory for my 1024 items.
m_myVirtualListCtrl.SetItemCountEx(1024, LVSICF_NOSCROLL|
LVSICF_NOINVALIDATEALL);

for (int i = 0; i < 1024; i++)


{
str.Format(TEXT("item %d"), i);
m_myVirtualListCtrl.InsertItem(i, str);
}

CListCtrl::SetItemData
Sets the 32-bit application-specific value associated with the item specified by nItem.

BOOL SetItemData(int nItem, DWORD_PTR dwData);

Parameters
nItem
Index of the list item whose data is to be set.
dwData
A 32-bit value to be associated with the item.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This value is the lParam member of the LVITEM structure, as described in the Windows SDK.
Example

// Set the data of each item to be equal to its index.


for (int i = 0; i < m_myListCtrl.GetItemCount(); i++)
{
m_myListCtrl.SetItemData(i, i);
}

CListCtrl::SetItemIndexState
Sets the state of an item in the current list-view control.

BOOL SetItemIndexState(
PLVITEMINDEX pItemIndex,
DWORD dwState,
DWORD dwMask) const;

Parameters
PA RA M ET ER DESC RIP T IO N

pItemIndex [in] Pointer to an LVITEMINDEX structure that describes


an item. The caller is responsible for allocating this
structure and setting its members.

dwState [in] The state to set the item, which is a bitwise


combination of list view item states. Specify zero to reset,
or one to set, a state.

dwMask [in] A mask of the valid bits of the state specified by the
dwState parameter. Specify a bitwise combination (OR) of
list view item states.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
For more information about the dwState parameter, see List View Item States.
For more information about the dwMask parameter, see the stateMask member of the LVITEM structure.
This method sends the LVM_SETITEMINDEXSTATE message, which is described in the Windows SDK.

CListCtrl::SetItemPosition
Moves an item to a specified position in a list view control.

BOOL SetItemPosition(
int nItem,
POINT pt);

Parameters
nItem
Index of the item whose position is to be set.
pt
A POINT structure specifying the new position, in view coordinates, of the item's upper-left corner.
Return Value
Nonzero if successful; otherwise zero.
Remarks
The control must be in icon or small icon view.
If the list view control has the LVS_AUTOARRANGE style, the list view is arranged after the position of the
item is set.
Example
See the example for CListCtrl::GetItemPosition.

CListCtrl::SetItemState
Changes the state of an item in a list view control.
BOOL SetItemState(
int nItem,
LVITEM* pItem);

BOOL SetItemState(
int nItem,
UINT nState,
UINT nMask);

Parameters
nItem
Index of the item whose state is to be set.
pItem
Address of an LVITEM structure, as described in the Windows SDK. The structure's stateMask member
specifies which state bits to change, and the structure's state member contains the new values for those
bits. The other members are ignored.
nState
New values for the state bits. For a list of possible values, see CListCtrl::GetNextItem and the LVITEM state
member.
nMask
Mask specifying which state bits to change. This value corresponds to the stateMask member of the LVITEM
structure.
Return Value
Nonzero if successful; otherwise zero.
Remarks
An item's "state" is a value that specifies the item's availability, indicates user actions, or otherwise reflects
the item's status. A list view control changes some state bits, such as when the user selects an item. An
application might change other state bits to disable or hide the item, or to specify an overlay image or state
image.
Example
See the example for CListCtrl::GetTopIndex.

CListCtrl::SetItemText
Changes the text of a list view item or subitem.

BOOL SetItemText(
int nItem,
int nSubItem,
LPCTSTR lpszText);

Parameters
nItem
Index of the item whose text is to be set.
nSubItem
Index of the subitem, or zero to set the item label.
lpszText
Pointer to a string that contains the new item text.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This method is not intended for use with controls containing the LVS_OWNERDATA window style (in fact,
this will cause an assertion in Debug builds). For more information about this list control style, see List-View
Controls Overview.
Example
See the example for CListCtrl::InsertItem.

CListCtrl::SetOutlineColor
Sets the color of the border of a list-view control if the LVS_EX_BORDERSELECT extended window style is
set.

COLORREF SetOutlineColor(COLORREF color);

Parameters
color
The new COLORREF structure containing the outline color.
Return Value
The previous COLORREF structure containing the outline color
Remarks
This member function emulates the functionality of the LVM_SETOUTLINECOLOR message, as described in
the Windows SDK.

CListCtrl::SetSelectedColumn
Sets the selected column of the list view control.

LRESULT SetSelectedColumn(int iCol);

Parameters
iCol
The index of the column to be selected.
Return Value
The return value is not used.
Remarks
This member function emulates the functionality of the LVM_SETSELECTEDCOLUMN message, as described
in the Windows SDK.

CListCtrl::SetSelectionMark
Sets the selection mark of a list view control.

int SetSelectionMark(int iIndex);


Parameters
iIndex
The zero-based index of the first item in a multiple selection.
Return Value
The previous selection mark, or -1 if there was no selection mark.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetSelectionMark, as
described in the Windows SDK.
Example
See the example for CListCtrl::GetSelectionMark.

CListCtrl::SetTextBkColor
Sets the background color of text in a list view control.

BOOL SetTextBkColor(COLORREF cr);

Parameters
cr
A COLORREF specifying the new text background color. For information, see COLORREF in the Windows
SDK.
Return Value
Nonzero if successful; otherwise zero.
Example

// Use the 3D button face color for the background.


COLORREF crBkColor = ::GetSysColor(COLOR_3DFACE);
m_myListCtrl.SetTextBkColor(crBkColor);
ASSERT(m_myListCtrl.GetTextBkColor() == crBkColor);

CListCtrl::SetTextColor
Sets the text color of a list view control.

BOOL SetTextColor(COLORREF cr);

Parameters
cr
A COLORREF specifying the new text color. For information, see COLORREF in the Windows SDK.
Return Value
Nonzero if successful; otherwise zero.
Example
// Use the window text color for
// the item text of the list view control.
COLORREF crTextColor = ::GetSysColor(COLOR_WINDOWTEXT);
m_myListCtrl.SetTextColor(crTextColor);
ASSERT(m_myListCtrl.GetTextColor() == crTextColor);

CListCtrl::SetTileInfo
Sets the information for a tile of the list view control.

BOOL SetTileInfo(PLVTILEINFO pTileInfo);

Parameters
pTileInfo
A pointer to an LVTILEINFO structure containing the information to be set.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the LVM_SETTILEINFO message, as described in the
Windows SDK.

CListCtrl::SetTileViewInfo
Sets information that a list view control uses in tile view.

BOOL SetTileViewInfo(PLVTILEVIEWINFO ptvi);

Parameters
ptvi
A pointer to an LVTILEVIEWINFO structure containing the information to set.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the LVM_SETTILEVIEWINFO message, as described in
the Windows SDK.

CListCtrl::SetToolTips
Sets the tooltip control that the list view control will use to display tooltips.

CToolTipCtrl* SetToolTips(CToolTipCtrl* pWndTip);

Parameters
pWndTip
A pointer to a CToolTipCtrl object that the list control will use.
Return Value
A pointer to a CToolTipCtrl object containing the tooltip previously used by the control, or NULL if no
tooltips were used previously.
Remarks
This member function implements the behavior of the Win32 message LVM_SETTOOLTIPS, as described in
the Windows SDK.
To not use tooltips, indicate the LVS_NOTOOLTIPS style when you create the CListCtrl object.

CListCtrl::SetView
Sets the view of the list view control.

DWORD SetView(int iView);

Parameters
iView
The view to be selected.
Return Value
Returns 1 if successful, or -1 otherwise. For example, -1 is returned if the view is invalid.
Remarks
This member function emulates the functionality of the LVM_SETVIEW message, as described in the
Windows SDK.

CListCtrl::SetWorkAreas
Sets the area where icons can be displayed in a list view control.

void SetWorkAreas(
int nWorkAreas,
LPRECT lpRect);

Parameters
nWorkAreas
The number of RECT structures (or CRect objects) in the array pointed to by lpRect.
lpRect
The address of an array of RECT structures (or CRect objects) that specify the new work areas of the list
view control. These areas must be specified in client coordinates. If this parameter is NULL, the working
area will be set to the client area of the control.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SetWorkAreas, as described
in the Windows SDK.
Example

// Remove all working areas.


m_myListCtrl.SetWorkAreas(0, NULL);

CListCtrl::SortGroups
Uses an application-defined comparison function to sort groups by ID within a list view control.

BOOL SortGroups(
PFNLVGROUPCOMPARE _pfnGroupCompare,
LPVOID _plv);

Parameters
_pfnGroupCompare
A pointer to the group comparison function.
_plv
A void pointer.
Return Value
Returns TRUE on success, FALSE on failure.
Remarks
This member function emulates the functionality of the LVM_SORTGROUPS message, as described in the
Windows SDK.

CListCtrl::SortItems
Sorts list view items by using an application-defined comparison function.

BOOL SortItems(
PFNLVCOMPARE pfnCompare,
DWORD_PTR dwData);

Parameters
pfnCompare
[in] Address of the application-defined comparison function.
The sort operation calls the comparison function each time the relative order of two list items needs to be
determined. The comparison function must be either a static member of a class or a stand-alone function
that is not a member of any class.
dwData
[in] Application-defined value that is passed to the comparison function.
Return Value
TRUE if the method successful; otherwise FALSE.
Remarks
This method changes the index of each item to reflect the new sequence.
The comparison function, pfnCompare, has the following form:

int CALLBACK CompareFunc(LPARAM lParam1,


LPARAM lParam2,
LPARAM lParamSort);

The comparison function must return a negative value if the first item should precede the second, a positive
value if the first item should follow the second, or zero if the two items are equal.
The lParam1 parameter is the 32-bit value associated with the first item that is compared, and the lParam2
parameter is the value associated with the second item. These are the values that were specified in the
lParam member of the items' LVITEM structure when they were inserted into the list. The lParamSort
parameter is the same as the dwData value.
This method sends the LVM_SORTITEMS message, which is described in the Windows SDK.
Example
The following is a simple comparison function that results in items being sorted by their lParam values.

// Sort items by associated lParam


int CALLBACK CListCtrlDlg::MyCompareProc(LPARAM lParam1, LPARAM lParam2,
LPARAM lParamSort)
{
UNREFERENCED_PARAMETER(lParamSort);
return (int)(lParam1 - lParam2);
}

// Sort the items by passing in the comparison function.


void CListCtrlDlg::Sort()
{
m_myListCtrl.SortItems(&CListCtrlDlg::MyCompareProc, 0);
}

CListCtrl::SortItemsEx
Sorts the items of the current list-view control by using an application-defined comparison function.

BOOL SortItemsEx(
PFNLVCOMPARE pfnCompare,
DWORD_PTR dwData);

Parameters
PA RA M ET ER DESC RIP T IO N

pfnCompare [in] Address of the application-defined comparison


function.

The sort operation calls the comparison function each


time the relative order of two list items needs to be
determined. The comparison function must be either a
static member of a class or a stand-alone function that is
not a member of any class.

dwData [in] Application-defined value passed to the comparison


function.

Return Value
TRUE if this method is successful; otherwise, FALSE.
Remarks
This method changes the index of each item to reflect the new sequence.
The comparison function, pfnCompare, has the following form:
int CALLBACK CompareFunc(LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort);

This message is like LVM_SORTITEMS, except for the type of information passed to the comparison
function. In LVM_SORTITEMS, lParam1 and lParam2 are the values of the items to compare. In
LVM_SORTITEMSEX, lParam1 is the current index of the first item to compare and lParam2 is the current
index of the second item. You can send an LVM_GETITEMTEXT message to retrieve more information about
an item.
The comparison function must return a negative value if the first item should precede the second, a positive
value if the first item should follow the second, or zero if the two items are equal.

NOTE
During the sorting process, the list-view contents are unstable. If the callback function sends any messages to the
list-view control other than LVM_GETITEM, the results are unpredictable.

This method sends the LVM_SORTITEMSEX message, which is described in the Windows SDK.
Example
The following code example defines a variable, m_listCtrl , that is used to access the current list-view
control. This variable is used in the next example.

public:
// Variable used to access the list control.
CListCtrl m_listCtrl;

Example
The following code example demonstrates the SortItemEx method. In an earlier section of this code
example, we created a list-view control that displays two columns titled "ClientID" and "Grade" in a report
view. The following code example sorts the table by using the values in the "Grade" column.
// The ListCompareFunc() method is a global function used by SortItemEx().
int CALLBACK ListCompareFunc(
LPARAM lParam1,
LPARAM lParam2,
LPARAM lParamSort)
{
CListCtrl* pListCtrl = (CListCtrl*) lParamSort;
CString strItem1 = pListCtrl->GetItemText(static_cast<int>(lParam1), 1);
CString strItem2 = pListCtrl->GetItemText(static_cast<int>(lParam2), 1)
int x1 = _tstoi(strItem1.GetBuffer());
int x2 = _tstoi(strItem2.GetBuffer());
int result = 0;
if ((x1 - x2) < 0)
result = -1;
else if ((x1 - x2) == 0)
result = 0;
else
result = 1;

return result;
}

void CCListCtrl_s2Dlg::OnBnClickedButton1()
{
// SortItemsEx
m_listCtrl.SortItemsEx( ListCompareFunc, (LPARAM)&m_listCtrl );
}

CListCtrl::SubItemHitTest
Determines which list view item, if any, is at a given position.

int SubItemHitTest(LPLVHITTESTINFO pInfo);

Parameters
pInfo
A pointer to the LVHITTESTINFO structure.
Return Value
The one-based index of the item, or subitem, being tested (if any), or -1 otherwise.
Remarks
This member function implements the behavior of the Win32 macro, ListView_SubItemHitTest, as described
in the Windows SDK.
Example
void CListCtrlDlg::OnDblClk(NMHDR* pNMHDR, LRESULT* pResult)
{
UNREFERENCED_PARAMETER(pResult);
LPNMITEMACTIVATE pia = (LPNMITEMACTIVATE)pNMHDR;
LVHITTESTINFO lvhti;

// Clear the subitem text the user clicked on.


lvhti.pt = pia->ptAction;
m_myListCtrl.SubItemHitTest(&lvhti);

if (lvhti.flags & LVHT_ONITEMLABEL)


{
m_myListCtrl.SetItemText(lvhti.iItem, lvhti.iSubItem, NULL);
}
}

CListCtrl::Update
Forces the list view control to repaint the item specified by nItem.

BOOL Update(int nItem);

Parameters
nItem
Index of the item to be updated.
Return Value
Nonzero if successful; otherwise zero.
Remarks
This function also arranges the list view control if it has the LVS_AUTOARRANGE style.
Example
See the example for CListCtrl::GetSelectedCount.

See also
MFC Sample ROWLIST
CWnd Class
Hierarchy Chart
CImageList Class
CListView Class
4/21/2020 • 2 minutes to read • Edit Online

Simplifies use of the list control and of CListCtrl, the class that encapsulates list-control functionality, with
MFC's document-view architecture.

Syntax
class CListView : public CCtrlView

Members
Public Constructors
NAME DESC RIP T IO N

CListView::CListView Constructs a CListView object.

Public Methods
NAME DESC RIP T IO N

CListView::GetListCtrl Returns the list control associated with the view.

Protected Methods
NAME DESC RIP T IO N

CListView::RemoveImageList Removes the specified image list from the list view.

Remarks
For more information on this architecture, see the overview for the CView class and the cross-references cited
there.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CView
CCtrlView
CListView

Requirements
Header : afxcview.h

CListView::CListView
Constructs a CListView object.

CListView();

CListView::GetListCtrl
Call this member function to get a reference to the list control associated with the view.

CListCtrl& GetListCtrl() const;

Return Value
A reference to the list control associated with the view.
Example

void CMyListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();

// this code only works for a report-mode list view


ASSERT(GetStyle() & LVS_REPORT);

CListCtrl& listCtrl = GetListCtrl();

// Insert a column. This override is the most convenient.


listCtrl.InsertColumn(0, _T("Player Name"), LVCFMT_LEFT);

// The other InsertColumn() override requires an initialized


// LVCOLUMN structure.
LVCOLUMN col;
col.mask = LVCF_FMT | LVCF_TEXT;
col.pszText = _T("Jersey Number");
col.fmt = LVCFMT_LEFT;
listCtrl.InsertColumn(1, &col);

// Set reasonable widths for our columns


listCtrl.SetColumnWidth(0, LVSCW_AUTOSIZE_USEHEADER);
listCtrl.SetColumnWidth(1, LVSCW_AUTOSIZE_USEHEADER);
}

CListView::RemoveImageList
Removes the specified image list from the list view.

void RemoveImageList(int nImageList);

Parameters
nImageList
The zero-based index of the image to remove.

See also
MFC Sample ROWLIST
CCtrlView Class
Hierarchy Chart
CCtrlView Class
CLongBinary Class
3/27/2020 • 2 minutes to read • Edit Online

Simplifies working with very large binary data objects (often called BLOBs, or "binary large objects") in a
database.

Syntax
class CLongBinary : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CLongBinary::CLongBinary Constructs a CLongBinary object.

Public Data Members


NAME DESC RIP T IO N

CLongBinary::m_dwDataLength Contains the actual size in bytes of the data object whose
handle is stored in m_hData .

CLongBinary::m_hData Contains a Windows HGLOBAL handle to the actual image


object.

Remarks
For example, a record field in a SQL table might contain a bitmap representing a picture. A CLongBinary object
stores such an object and keeps track of its size.

NOTE
In general, it is better practice now to use CByteArray in conjunction with the DFX_Binary function. You can still use
CLongBinary , but in general CByteArray provides more functionality under Win32, since there is no longer the size
limitation encountered with 16-bit CByteArray . This advice applies to programming with Data Access Objects (DAO) as
well as Open Database Connectivity (ODBC).

To use a CLongBinary object, declare a field data member of type CLongBinary in your recordset class. This
member will be an embedded member of the recordset class and will be constructed when the recordset is
constructed. After the CLongBinary object is constructed, the record field exchange (RFX) mechanism loads the
data object from a field in the current record on the data source and stores it back to the record when the record
is updated. RFX queries the data source for the size of the binary large object, allocates storage for it (via the
CLongBinary object's m_hData data member), and stores an HGLOBAL handle to the data in m_hData . RFX also
stores the actual size of the data object in the m_dwDataLength data member. Work with the data in the object
through m_hData , using the same techniques you would normally use to manipulate the data stored in a
Windows HGLOBAL handle.
When you destroy your recordset, the embedded CLongBinary object is also destroyed, and its destructor
deallocates the HGLOBAL data handle.
For more information about large objects and the use of CLongBinary , see the articles Recordset (ODBC) and
Recordset: Working with Large Data Items (ODBC).

Inheritance Hierarchy
CObject
CLongBinary

Requirements
Header : afxdb_.h

CLongBinary::CLongBinary
Constructs a CLongBinary object.

CLongBinary();

CLongBinary::m_dwDataLength
Stores the actual size in bytes of the data stored in the HGLOBAL handle in m_hData .

SQLULEN m_dwDataLength;

Remarks
This size may be smaller than the size of the memory block allocated for the data. Call the Win32 GLobalSize
function to get the allocated size.

CLongBinary::m_hData
Stores a Windows HGLOBAL handle to the actual binary large object data.

HGLOBAL m_hData;

See also
CObject Class
Hierarchy Chart
CRecordset Class
CMap Class
4/21/2020 • 10 minutes to read • Edit Online

A dictionary collection class that maps unique keys to values.

Syntax
template<class KEY, class ARG_KEY, class VALUE, class ARG_VALUE>class CMap : public CObject

Parameters
KEY
Class of the object used as the key to the map.
ARG_KEY
Data type used for KEY arguments; usually a reference to KEY.
VALUE
Class of the object stored in the map.
ARG_VALUE
Data type used for VALUE arguments; usually a reference to VALUE.

Members
Public Structures
NAME DESC RIP T IO N

CMap::CPair A nested structure containing a key value and the value of


the associated object.

Public Constructors
NAME DESC RIP T IO N

CMap::CMap Constructs a collection that maps keys to values.

Public Methods
NAME DESC RIP T IO N

CMap::GetCount Returns the number of elements in this map.

CMap::GetHashTableSize Returns the number of elements in the hash table.

CMap::GetNextAssoc Gets the next element for iterating.

CMap::GetSize Returns the number of elements in this map.

CMap::GetStartPosition Returns the position of the first element.


NAME DESC RIP T IO N

CMap::InitHashTable Initializes the hash table and specifies its size.

CMap::IsEmpty Tests for the empty-map condition (no elements).

CMap::Lookup Looks up the value mapped to a given key.

CMap::PGetFirstAssoc Returns a pointer to the first element.

CMap::PGetNextAssoc Gets a pointer to the next element for iterating.

CMap::PLookup Returns a pointer to a key whose value matches the specified


value.

CMap::RemoveAll Removes all the elements from this map.

CMap::RemoveKey Removes an element specified by a key.

CMap::SetAt Inserts an element into the map; replaces an existing element


if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMap::operator [ ] Inserts an element into the map — operator substitution for


SetAt .

Remarks
Once you have inserted a key-value pair (element) into the map, you can efficiently retrieve or delete the pair
using the key to access it. You can also iterate over all the elements in the map.
A variable of type POSITION is used for alternate access to entries. You can use a POSITION to "remember" an
entry and to iterate through the map. You might think that this iteration is sequential by key value; it is not. The
sequence of retrieved elements is indeterminate.
Certain member functions of this class call global helper functions that must be customized for most uses of the
CMap class. See Collection Class Helpers in the Macros and Globals section of the MFC Reference .

CMap overrides CObject::Serialize to support serialization and dumping of its elements. If a map is stored to an
archive using Serialize , each map element is serialized in turn. The default implementation of the
SerializeElements helper function does a bitwise write. For information about serialization of pointer collection
items derived from CObject or other user defined types, see How to: Make a Type-Safe Collection.
If you need a diagnostic dump of the individual elements in the map (the keys and values), you must set the depth
of the dump context to 1 or greater.
When a CMap object is deleted, or when its elements are removed, the keys and values both are removed.
Map class derivation is similar to list derivation. See the article Collections for an illustration of the derivation of a
special-purpose list class.

Inheritance Hierarchy
CObject
CMap

Requirements
Header : afxtempl.h

CMap::CMap
Constructs an empty map.

CMap(INT_PTR nBlockSize = 10);

Parameters
nBlockSize
Specifies the memory-allocation granularity for extending the map.
Remarks
As the map grows, memory is allocated in units of nBlockSize entries.
Example

// declares a map of ints to points


CMap<int, int, CPoint, CPoint> myMap(16);

CMap::CPair
Contains a key value and the value of the associated object.
Remarks
This is a nested structure within class CMap.
The structure is composed of two fields:
key The actual value of the key type.
value The value of the associated object.

It is used to store the return values from CMap::PLookup, CMap::PGetFirstAssoc, and CMap::PGetNextAssoc.
Example
For an example of usage, see the example for CMap::PLookup.

CMap::GetCount
Retrieves the number of elements in the map.

INT_PTR GetCount() const;

Return Value
The number of elements.
Example
See the example for CMap::Lookup.

CMap::GetHashTableSize
Determines the number of elements in the hash table for the map.

UINT GetHashTableSize() const;

Return Value
The number of elements in the hash table.
Example

CMap<int, int, CPoint, CPoint> myMap;

UINT uTableSize = myMap.GetHashTableSize();

CMap::GetNextAssoc
Retrieves the map element at rNextPosition , then updates rNextPosition to refer to the next element in the map.

void GetNextAssoc(
POSITION& rNextPosition,
KEY& rKey,
VALUE& rValue) const;

Parameters
rNextPosition
Specifies a reference to a POSITION value returned by a previous GetNextAssoc or GetStartPosition call.
KEY
Template parameter specifying the type of the map's key.
rKey
Specifies the returned key of the retrieved element.
VALUE
Template parameter specifying the type of the map's value.
rValue
Specifies the returned value of the retrieved element.
Remarks
This function is most useful for iterating through all the elements in the map. Note that the position sequence is
not necessarily the same as the key value sequence.
If the retrieved element is the last in the map, then the new value of rNextPosition is set to NULL.
Example
See the example for CMap::SetAt.

CMap::GetSize
Returns the number of map elements.
INT_PTR GetSize() const;

Return Value
The number of items in the map.
Remarks
Call this method to retrieve the number of elements in the map.
Example

CMap<int, int, CPoint, CPoint> myMap;

myMap.InitHashTable(257);

// Add 200 elements to the map.


for (int i = 0; i < 200; i++)
{
myMap[i] = CPoint(i, i);
}

// Remove the elements with even key values.


CPoint pt;
for (int i = 0; myMap.Lookup(i, pt); i += 2)
{
myMap.RemoveKey(i);
}

ASSERT(myMap.GetSize() == 100);
TRACE(_T("myMap with %d elements:\n"), myMap.GetCount());
POSITION pos = myMap.GetStartPosition();
int iKey;
CPoint ptVal;
while (pos != NULL)
{
myMap.GetNextAssoc(pos, iKey, ptVal);
TRACE(_T("\t[%d] = (%d,%d)\n"), iKey, ptVal.x, ptVal.y);
}

CMap::GetStartPosition
Starts a map iteration by returning a POSITION value that can be passed to a GetNextAssoc call.

POSITION GetStartPosition() const;

Return Value
A POSITION value that indicates a starting position for iterating the map; or NULL if the map is empty.
Remarks
The iteration sequence is not predictable; therefore, the "first element in the map" has no special significance.
Example
See the example for CMap::SetAt.

CMap::InitHashTable
Initializes the hash table.
void InitHashTable(UINT hashSize, BOOL bAllocNow = TRUE);

Parameters
hashSize
Number of entries in the hash table.
bAllocNow
If TRUE, allocates the hash table upon initialization; otherwise the table is allocated when needed.
Remarks
For best performance, the hash table size should be a prime number. To minimize collisions, the size should be
roughly 20 percent larger than the largest anticipated data set.
Example
See the example for CMap::Lookup.

CMap::IsEmpty
Determines whether the map is empty.

BOOL IsEmpty() const;

Return Value
Nonzero if this map contains no elements; otherwise 0.
Example
See the example for CMap::RemoveAll.

CMap::Lookup
Looks up the value mapped to a given key.

BOOL Lookup(ARG_KEY key, VALUE& rValue) const;

Parameters
ARG_KEY
Template parameter specifying the type of the key value.
key
Specifies the key that identifies the element to be looked up.
VALUE
Specifies the type of the value to be looked up.
rValue
Receives the looked-up value.
Return Value
Nonzero if the element was found; otherwise 0.
Remarks
Lookup uses a hashing algorithm to quickly find the map element with a key that exactly matches the given key.
Example

CMap<int, int, CPoint, CPoint> myMap;

myMap.InitHashTable(257);

// Add 200 elements to the map.


for (int i = 0; i < 200; i++)
{
myMap[i] = CPoint(i, i);
}

// Remove the elements with even key values.


CPoint pt;
for (int i = 0; myMap.Lookup(i, pt); i += 2)
{
myMap.RemoveKey(i);
}

ASSERT(myMap.GetSize() == 100);
TRACE(_T("myMap with %d elements:\n"), myMap.GetCount());
POSITION pos = myMap.GetStartPosition();
int iKey;
CPoint ptVal;
while (pos != NULL)
{
myMap.GetNextAssoc(pos, iKey, ptVal);
TRACE(_T("\t[%d] = (%d,%d)\n"), iKey, ptVal.x, ptVal.y);
}

CMap::operator [ ]
A convenient substitute for the SetAt member function.

VALUE& operator[](arg_key key);

Parameters
VALUE
Template parameter specifying the type of the map value.
ARG_KEY
Template parameter specifying the type of the key value.
key
The key used to retrieve the value from the map.
Remarks
Thus it can be used only on the left side of an assignment statement (an l-value). If there is no map element with
the specified key, then a new element is created.
There is no "right side" (r-value) equivalent to this operator because there is a possibility that a key may not be
found in the map. Use the Lookup member function for element retrieval.
Example
See the example for CMap::Lookup.

CMap::PGetFirstAssoc
Returns the first entry of the map object.
const CPair* PGetFirstAssoc() const;
CPair* PGetFirstAssoc();

Return Value
A pointer to the first entry in the map; see CMap::CPair. If the map contains no entries, the value is NULL.
Remarks
Call this function to return a pointer the first element in the map object.
Example

typedef CMap<int, int, CPoint, CPoint> CMyMap;


CMyMap myMap;

myMap.InitHashTable(257);

// Add 10 elements to the map.


for (int i = 0; i <= 10; i++)
myMap.SetAt(i, CPoint(i, i));

// Print the element value with even key values.


int nKey = 0;
CPoint pt;
CMyMap::CPair *pCurVal;

pCurVal = myMap.PGetFirstAssoc();
while (pCurVal != NULL)
{
if ((nKey % 2) == 0)
{
_tprintf_s(_T("Current key value at %d: %d,%d\n"),
pCurVal->key, pCurVal->value.x, pCurVal->value.y);
}
pCurVal = myMap.PGetNextAssoc(pCurVal);
nKey++;
}

CMap::PGetNextAssoc
Retrieves the map element pointed to by pAssocRec.

const CPair *PGetNextAssoc(const CPair* pAssocRet) const;

CPair *PGetNextAssoc(const CPair* pAssocRet);

Parameters
pAssocRet
Points to a map entry returned by a previous PGetNextAssoc or CMap::PGetFirstAssoc call.
Return Value
A pointer to the next entry in the map; see CMap::CPair. If the element is the last in the map, the value is NULL.
Remarks
Call this method to iterate through all the elements in the map. Retrieve the first element with a call to
PGetFirstAssoc and then iterate through the map with successive calls to PGetNextAssoc .

Example
See the example for CMap::PGetFirstAssoc.

CMap::PLookup
Finds the value mapped to a given key.

const CPair* PLookup(ARG_KEY key) const;


CPair* PLookup(ARG_KEY key);

Parameters
key
Key for the element to be searched for.
Return Value
A pointer to a key structure; see CMap::CPair. If no match is found, CMap::PLookup returns NULL.
Remarks
Call this method to search for a map element with a key that exactly matches the given key.
Example

typedef CMap<int, int, CPoint, CPoint> CMyMap;


CMyMap myMap;

myMap.InitHashTable(257);

// Add 10 elements to the map.


for (int i = 0; i <= 10; i++)
myMap[i] = CPoint(i, i);

// Print the element values with even key values.


CMyMap::CPair *pCurVal;

for (int i = 0; i <= myMap.GetCount(); i += 2)


{
pCurVal = myMap.PLookup(i);
_tprintf_s(_T("Current key value at %d: %d,%d\n"),
pCurVal->key, pCurVal->value.x, pCurVal->value.y);
}

CMap::RemoveAll
Removes all the values from this map by calling the global helper function DestructElements .

void RemoveAll();

Remarks
The function works correctly if the map is already empty.
Example
CMap<int, int, CPoint, CPoint> myMap;

// Add 10 elements to the map.


for (int i = 0; i < 10; i++)
myMap.SetAt(i, CPoint(i, i));

myMap.RemoveAll();

ASSERT(myMap.IsEmpty());

CMap::RemoveKey
Looks up the map entry corresponding to the supplied key; then, if the key is found, removes the entry.

BOOL RemoveKey(ARG_KEY key);

Parameters
ARG_KEY
Template parameter specifying the type of the key.
key
Key for the element to be removed.
Return Value
Nonzero if the entry was found and successfully removed; otherwise 0.
Remarks
The DestructElements helper function is used to remove the entry.
Example
See the example for CMap::SetAt.

CMap::SetAt
The primary means to insert an element in a map.

void SetAt(ARG_KEY key, ARG_VALUE newValue);

Parameters
ARG_KEY
Template parameter specifying the type of the key parameter.
key
Specifies the key of the new element.
ARG_VALUE
Template parameter specifying the type of the newValue parameter.
newValue
Specifies the value of the new element.
Remarks
First, the key is looked up. If the key is found, then the corresponding value is changed; otherwise a new key-value
pair is created.
Example

CMap<int, int, CPoint, CPoint> myMap;

// Add 10 elements to the map.


for (int i = 0; i < 10; i++)
myMap.SetAt(i, CPoint(i, i));

// Remove the elements with even key values.


POSITION pos = myMap.GetStartPosition();
int nKey;
CPoint pt;
while (pos != NULL)
{
myMap.GetNextAssoc(pos, nKey, pt);

if ((nKey % 2) == 0)
myMap.RemoveKey(nKey);
}

// Print the element values.


pos = myMap.GetStartPosition();
while (pos != NULL)
{
myMap.GetNextAssoc(pos, nKey, pt);
_tprintf_s(_T("Current key value at %d: %d,%d\n"),
nKey, pt.x, pt.y);
}

See also
MFC Sample COLLECT
CObject Class
Hierarchy Chart
CMapPtrToPtr Class
3/16/2020 • 2 minutes to read • Edit Online

Supports maps of void pointers keyed by void pointers.

Syntax
class CMapPtrToPtr : public CObject

Members
The member functions of CMapPtrToPtr are similar to the member functions of class CMapStringToOb. Because
of this similarity, you can use the CMapStringToOb reference documentation for member function specifics.
Wherever you see a CObject pointer as a function parameter or return value, substitute a pointer to void .
Wherever you see a CString or a const pointer to char as a function parameter or return value, substitute a
pointer to void .
BOOL CMapPtrToPtr::Lookup( void* <key>, void*& <rValue> ) const;

for example, translates to


BOOL CMapStringToOb::Lookup( const char* <key>, CObject*& <rValue> ) const;

Public Constructors
NAME DESC RIP T IO N

CMapPtrToPtr::CMapPtrToPtr Constructor.

Public Methods
NAME DESC RIP T IO N

CMapPtrToPtr::GetCount Returns the number of elements in this map.

CMapPtrToPtr::GetHashTableSize Determines the current number of elements in the hash


table.

CMapPtrToPtr::GetNextAssoc Gets the next element for iterating.

CMapPtrToPtr::GetSize Returns the number of elements in this map.

CMapPtrToPtr::GetStartPosition Returns the position of the first element.

CMapPtrToPtr::HashKey Calculates the hash value of a specified key.

CMapPtrToPtr::InitHashTable Initializes the hash table.

CMapPtrToPtr::IsEmpty Tests for the empty-map condition (no elements).


NAME DESC RIP T IO N

CMapPtrToPtr::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapPtrToPtr::LookupKey Returns a reference to the key associated with the specified


key value.

CMapPtrToPtr::RemoveAll Removes all the elements from this map.

CMapPtrToPtr::RemoveKey Removes an element specified by a key.

CMapPtrToPtr::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapPtrToPtr::operator [ ] Inserts an element into the map — operator substitution for


SetAt .

Remarks
CMapPtrToPtr incorporates the IMPLEMENT_DYNAMIC macro to support run-time type access and dumping to
a CDumpContext object. If you need a dump of individual map elements (pointer values), you must set the depth
of the dump context to 1 or greater.
Pointer-to-pointer maps may not be serialized.
When a CMapPtrToPtr object is deleted, or when its elements are removed, only the pointers are removed, not
the entities they reference.
For more information on CMapPtrToPtr , see the article Collections.

Inheritance Hierarchy
CObject
CMapPtrToPtr

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CMapPtrToWord Class
3/16/2020 • 2 minutes to read • Edit Online

Supports maps of 16-bit words keyed by void pointers.

Syntax
class CMapPtrToWord : public CObject

Members
The member functions of CMapPtrToWord are similar to the member functions of class CMapStringToOb. Because
of this similarity, you can use the CMapStringToOb reference documentation for member function specifics.
Wherever you see a CObject pointer as a function parameter or return value, substitute WORD. Wherever you
see a CString or a const pointer to char as a function parameter or return value, substitute a pointer to void .
BOOL CMapPtrToWord::Lookup( const void* <key>, WORD& <rValue> ) const;

for example, translates to


BOOL CMapStringToOb::Lookup( const char* <key>, CObject*& <rValue> ) const;

Public Constructors
NAME DESC RIP T IO N

CMapPtrToWord::CMapPtrToWord Constructor.

Public Methods
NAME DESC RIP T IO N

CMapPtrToWord::GetCount Returns the number of elements in this map.

CMapPtrToWord::GetHashTableSize Determines the current number of elements in the hash


table.

CMapPtrToWord::GetNextAssoc Gets the next element for iterating.

CMapPtrToWord::GetSize Returns the number of elements in this map.

CMapPtrToWord::GetStartPosition Returns the position of the first element.

CMapPtrToWord::HashKey Calculates the hash value of a specified key.

CMapPtrToWord::InitHashTable Initializes the hash table.

CMapPtrToWord::IsEmpty Tests for the empty-map condition (no elements).


NAME DESC RIP T IO N

CMapPtrToWord::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapPtrToWord::LookupKey Returns a reference to the key associated with the specified


key value.

CMapPtrToWord::RemoveAll Removes all the elements from this map.

CMapPtrToWord::RemoveKey Removes an element specified by a key.

CMapPtrToWord::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapPtrToWord::operator [ ] Inserts an element into the map — operator substitution for


SetAt .

Remarks
CMapWordToPtr incorporates the IMPLEMENT_DYNAMIC macro to support run-time type access and dumping to
a CDumpContext object. If you need a dump of individual map elements, you must set the depth of the dump
context to 1 or greater.
Pointer-to-word maps may not be serialized.
When a CMapPtrToWord object is deleted, or when its elements are removed, the pointers and the words are
removed. The entities referenced by the key pointers are not removed.
For more information on CMapPtrToWord , see the article Collections.

Inheritance Hierarchy
CObject
CMapPtrToWord

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CMapStringToOb Class
4/21/2020 • 13 minutes to read • Edit Online

A dictionary collection class that maps unique CString objects to CObject pointers.

Syntax
class CMapStringToOb : public CObject

Members
Public Constructors
NAME DESC RIP T IO N

CMapStringToOb::CMapStringToOb Constructor.

Public Methods
NAME DESC RIP T IO N

CMapStringToOb::GetCount Returns the number of elements in this map.

CMapStringToOb::GetHashTableSize Determines the current number of elements in the hash table.

CMapStringToOb::GetNextAssoc Gets the next element for iterating.

CMapStringToOb::GetSize Returns the number of elements in this map.

CMapStringToOb::GetStartPosition Returns the position of the first element.

CMapStringToOb::HashKey Calculates the hash value of a specified key.

CMapStringToOb::InitHashTable Initializes the hash table.

CMapStringToOb::IsEmpty Tests for the empty-map condition (no elements).

CMapStringToOb::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapStringToOb::LookupKey Returns a reference to the key associated with the specified


key value.

CMapStringToOb::RemoveAll Removes all the elements from this map.

CMapStringToOb::RemoveKey Removes an element specified by a key.


NAME DESC RIP T IO N

CMapStringToOb::SetAt Inserts an element into the map; replaces an existing element


if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapStringToOb::operator [ ] Inserts an element into the map — operator substitution for


SetAt .

Remarks
Once you have inserted a CString - CObject* pair (element) into the map, you can efficiently retrieve or delete
the pair using a string or a CString value as a key. You can also iterate over all the elements in the map.
A variable of type POSITION is used for alternate entry access in all map variations. You can use a POSITION to
"remember" an entry and to iterate through the map. You might think that this iteration is sequential by key value;
it is not. The sequence of retrieved elements is indeterminate.
CMapStringToOb incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its elements.
Each element is serialized in turn if a map is stored to an archive, either with the overloaded insertion ( << )
operator or with the Serialize member function.
If you need a diagnostic dump of the individual elements in the map (the CString value and the CObject
contents), you must set the depth of the dump context to 1 or greater.
When a CMapStringToOb object is deleted, or when its elements are removed, the CString objects and the
CObject pointers are removed. The objects referenced by the CObject pointers are not destroyed.
Map class derivation is similar to list derivation. See the article Collections for an illustration of the derivation of a
special-purpose list class.

Inheritance Hierarchy
CObject
CMapStringToOb

Requirements
Header : afxcoll.h

CMapStringToOb::CMapStringToOb
Constructs an empty CString -to- CObject* map.

CMapStringToOb(INT_PTR nBlockSize = 10);

Parameters
nBlockSize
Specifies the memory-allocation granularity for extending the map.
Remarks
As the map grows, memory is allocated in units of nBlockSize entries.
The following table shows other member functions that are similar to CMapStringToOb:: CMapStringToOb .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr CMapPtrToPtr( INT_PTR nBlockSize = 10 );

CMapPtrToWord CMapPtrToWord( INT_PTR nBlockSize = 10 );

CMapStringToPtr CMapStringToPtr( INT_PTR nBlockSize = 10 );

CMapStringToString CMapStringToString( INT_PTR nBlockSize = 10 );

CMapWordToOb CMapWordToOb( INT_PTR nBlockSize = 10 );

CMapWordToPtr MapWordToPtr( INT_PTR nBlockSize = 10 );

Example

CMapStringToOb map(20); // Map on the stack with blocksize of 20

CMapStringToOb *pm = new CMapStringToOb; // Map on the heap


// with default blocksize

See CObList::CObList for a listing of the CAge class used in all collection examples.

CMapStringToOb::GetCount
Determines how many elements are in the map.

INT_PTR GetCount() const;

Return Value
The number of elements in this map.
Remarks
The following table shows other member functions that are similar to CMapStringToOb::GetCount .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr INT_PTR GetCount( ) const;

CMapPtrToWord INT_PTR GetCount( ) const;

CMapStringToPtr INT_PTR GetCount( ) const;

CMapStringToString INT_PTR GetCount( ) const;

CMapWordToOb INT_PTR GetCount( ) const;

CMapWordToPtr INT_PTR GetCount( ) const;


Example
See CObList::CObList for a listing of the CAge class used in all collection examples.

CMapStringToOb map;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Homer"), new CAge(36));
ASSERT(map.GetCount() == 2);

CMapStringToOb::GetHashTableSize
Determines the current number of elements in the hash table.

UINT GetHashTableSize() const;

Return Value
Returns the number of elements in the hash table.
Remarks
The following table shows other member functions that are similar to CMapStringToOb::GetHashTableSize .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr UINT GetHashTableSize( ) const;

CMapPtrToWord UINT GetHashTableSize( ) const;

CMapStringToPtr UINT GetHashTableSize( ) const;

CMapStringToString UINT GetHashTableSize( ) const;

CMapWordToOb UINT GetHashTableSize( ) const;

CMapWordToPtr UINT GetHashTableSize( ) const;

CMapStringToOb::GetNextAssoc
Retrieves the map element at rNextPosition, then updates rNextPosition to refer to the next element in the map.

void GetNextAssoc(
POSITION& rNextPosition,
CString& rKey,
CObject*& rValue) const;

Parameters
rNextPosition
Specifies a reference to a POSITION value returned by a previous GetNextAssoc or GetStartPosition call.
rKey
Specifies the returned key of the retrieved element (a string).
rValue
Specifies the returned value of the retrieved element (a CObject pointer). See Remarks for more about this
parameter.
Remarks
This function is most useful for iterating through all the elements in the map. Note that the position sequence is
not necessarily the same as the key value sequence.
If the retrieved element is the last in the map, then the new value of rNextPosition is set to NULL.
For the rValue parameter, be sure to cast your object type to CObject*& , which is what the compiler requires, as
shown in the following example:

CObject *ob;
map.GetNextAssoc(pos, key, (CObject *&)ob);

This is not true of GetNextAssoc for maps based on templates.


The following table shows other member functions that are similar to CMapStringToOb::GetNextAssoc .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr void GetNextAssoc( POSITION& rNextPosition , void*&


rKey , void*& rValue ) const;

CMapPtrToWord void GetNextAssoc( POSITION& rNextPosition , void*&


rKey , WORD& rValue ) const;

CMapStringToPtr void GetNextAssoc( POSITION& rNextPosition ,


CString& rKey , void*& rValue ) const;

CMapStringToString void GetNextAssoc( POSITION& rNextPosition ,


CString& rKey , CString& rValue ) const;

CMapWordToOb void GetNextAssoc( POSITION& rNextPosition ,


WORD& rKey , CObject*& rValue ) const;

CMapWordToPtr void GetNextAssoc( POSITION& rNextPosition ,


WORD& rKey , void*& rValue ) const;

Example
See CObList::CObList for a listing of the CAge class used in all collection examples.
CMapStringToOb map;
POSITION pos;
CString key;
CAge *pa;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Lisa"), new CAge(11));
map.SetAt(_T("Homer"), new CAge(36));
map.SetAt(_T("Marge"), new CAge(35));
// Iterate through the entire map, dumping both name and age.
for (pos = map.GetStartPosition(); pos != NULL;)
{
map.GetNextAssoc(pos, key, (CObject *&)pa);
#ifdef _DEBUG
afxDump << key << _T(" : ") << pa << _T("\n");
#endif
}

The results from this program are as follows:

Lisa : a CAge at $4724 11


Marge : a CAge at $47A8 35
Homer : a CAge at $4766 36
Bart : a CAge at $45D4 13

CMapStringToOb::GetSize
Returns the number of map elements.

INT_PTR GetSize() const;

Return Value
The number of items in the map.
Remarks
Call this method to retrieve the number of elements in the map.
The following table shows other member functions that are similar to CMapStringToOb::GetSize .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr INT_PTR GetSize( ) const;

CMapPtrToWord INT_PTR GetSize( ) const;

CMapStringToPtr INT_PTR GetSize( ) const;

CMapStringToString INT_PTR GetSize( ) const;

CMapWordToOb INT_PTR GetSize( ) const;

CMapWordToPtr INT_PTR GetSize( ) const;

Example
CMapStringToOb map;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Homer"), new CAge(36));
ASSERT(map.GetSize() == 2);

CMapStringToOb::GetStartPosition
Starts a map iteration by returning a POSITION value that can be passed to a GetNextAssoc call.

POSITION GetStartPosition() const;

Return Value
A POSITION value that indicates a starting position for iterating the map; or NULL if the map is empty.
Remarks
The iteration sequence is not predictable; therefore, the "first element in the map" has no special significance.
The following table shows other member functions that are similar to CMapStringToOb::GetStartPosition .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr POSITION GetStar tPosition( ) const;

CMapPtrToWord POSITION GetStar tPosition( ) const;

CMapStringToPtr POSITION GetStar tPosition( ) const;

CMapStringToString POSITION GetStar tPosition( ) const;

CMapWordToOb POSITION GetStar tPosition( ) const;

CMapWordToPtr POSITION GetStar tPosition( ) const;

Example
See the example for CMapStringToOb::GetNextAssoc.

CMapStringToOb::HashKey
Calculates the hash value of a specified key.

UINT HashKey(LPCTSTR key) const;

Parameters
key
The key whose hash value is to be calculated.
Return Value
The Key's hash value
Remarks
The following table shows other member functions that are similar to CMapStringToOb::HashKey .
C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr UINT HashKey( void * key ) const;

CMapPtrToWord UINT HashKey( void * key ) const;

CMapStringToString UINT HashKey( LPCTSTR key ) const;

CMapStringToPtr UINT HashKey( LPCTSTR key ) const;

CMapWordToOb UINT HashKey( WORD key ) const;

CMapWordToPtr UINT HashKey( WORD key ) const;

CMapStringToOb::InitHashTable
Initializes the hash table.

void InitHashTable(
UINT hashSize,
BOOL bAllocNow = TRUE);

Parameters
hashSize
Number of entries in the hash table.
bAllocNow
If TRUE, allocates the hash table upon initialization; otherwise the table is allocated when needed.
Remarks
For best performance, the hash table size should be a prime number. To minimize collisions, the size should be
roughly 20 percent larger than the largest anticipated data set.
The following table shows other member functions that are similar to CMapStringToOb::InitHashTable .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );

CMapPtrToWord void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );

CMapStringToString void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );

CMapStringToPtr void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );

CMapWordToOb void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );
C L A SS M EM B ER F UN C T IO N

CMapWordToPtr void InitHashTable( UINT hashSize , BOOL


bAllocNow = TRUE );

CMapStringToOb::IsEmpty
Determines whether the map is empty.

BOOL IsEmpty() const;

Return Value
Nonzero if this map contains no elements; otherwise 0.
Example
See the example for RemoveAll.
Remarks
The following table shows other member functions that are similar to CMapStringToOb:: IsEmpty .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr BOOL IsEmpty( ) const;

CMapPtrToWord BOOL IsEmpty( ) const;

CMapStringToPtr BOOL IsEmpty( ) const;

CMapStringToString BOOL IsEmpty( ) const;

CMapWordToOb BOOL IsEmpty( ) const;

CMapWordToPtr BOOL IsEmpty( ) const;

CMapStringToOb::Lookup
Returns a CObject pointer based on a CString value.

BOOL Lookup(
LPCTSTR key,
CObject*& rValue) const;

Parameters
key
Specifies the string key that identifies the element to be looked up.
rValue
Specifies the returned value from the looked-up element.
Return Value
Nonzero if the element was found; otherwise 0.
Remarks
Lookup uses a hashing algorithm to quickly find the map element with a key that matches exactly ( CString
value).
The following table shows other member functions that are similar to CMapStringToOb::LookUp .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr BOOL Lookup( void * key , void*& rValue ) const;

CMapPtrToWord BOOL Lookup( void * key , WORD& rValue ) const;

CMapStringToPtr BOOL Lookup( LPCTSTR key , void*& rValue )


const;

CMapStringToString BOOL Lookup( LPCTSTR key , CString& rValue )


const;

CMapWordToOb BOOL Lookup( WORD key , CObject*& rValue )


const;

CMapWordToPtr BOOL Lookup( WORD key , void*& rValue ) const;

Example
See CObList::CObList for a listing of the CAge class used in all collection examples.

CMapStringToOb map;
CAge *pa;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Lisa"), new CAge(11));
map.SetAt(_T("Homer"), new CAge(36));
map.SetAt(_T("Marge"), new CAge(35));
ASSERT(map.Lookup(_T("Lisa"), (CObject *&)pa)); // Is "Lisa" in the map?
ASSERT(*pa == CAge(11)); // Is she 11?

CMapStringToOb::LookupKey
Returns a reference to the key associated with the specified key value.

BOOL LookupKey(
LPCTSTR key,
LPCTSTR& rKey) const;

Parameters
key
Specifies the string key that identifies the element to be looked up.
rKey
The reference to the associated key.
Return Value
Nonzero if the key was found; otherwise 0.
Remarks
Using a reference to a key is unsafe if used after the associated element was removed from the map or after the
map was destroyed.
The following table shows other member functions that are similar to CMapStringToOb:: LookupKey .

C L A SS M EM B ER F UN C T IO N

CMapStringToPtr BOOL LookupKey( LPCTSTR key , LPCTSTR& rKey )


const;

CMapStringToString BOOL LookupKey( LPCTSTR key , LPCTSTR& rKey )


const;

CMapStringToOb::operator [ ]
A convenient substitute for the SetAt member function.

CObject*& operator[ ](lpctstr key);

Return Value
A reference to a pointer to a CObject object; or NULL if the map is empty or key is out of range.
Remarks
Thus it can be used only on the left side of an assignment statement (an l-value). If there is no map element with
the specified key, then a new element is created.
There is no "right side" (r-value) equivalent to this operator because there is a possibility that a key may not be
found in the map. Use the Lookup member function for element retrieval.
The following table shows other member functions that are similar to CMapStringToOb::operator [] .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr void*& operator[](void * key );

CMapPtrToWord WORD& operator[](void * key );

CMapStringToPtr void*& operator[](lpctstr key );

CMapStringToString CString& operator[](lpctstr key );

CMapWordToOb CObject*& operator[](word key );

CMapWordToPtr void*& operator[](word key );

Example
See CObList::CObList for a listing of the CAge class used in all collection examples.
CMapStringToOb map;

map[_T("Bart")] = new CAge(13);


map[_T("Lisa")] = new CAge(11);
#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << _T("Operator [] example: ") << &map << _T("\n");
#endif

The results from this program are as follows:

Operator [] example: A CMapStringToOb with 2 elements


[Lisa] = a CAge at $4A02 11
[Bart] = a CAge at $497E 13

CMapStringToOb::RemoveAll
Removes all the elements from this map and destroys the CString key objects.

void RemoveAll();

Remarks
The CObject objects referenced by each key are not destroyed. The RemoveAll function can cause memory leaks
if you do not ensure that the referenced CObject objects are destroyed.
The function works correctly if the map is already empty.
The following table shows other member functions that are similar to CMapStringToOb::RemoveAll .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr void RemoveAll( );

CMapPtrToWord void RemoveAll( );

CMapStringToPtr void RemoveAll( );

CMapStringToString void RemoveAll( );

CMapWordToOb void RemoveAll( );

CMapWordToPtr void RemoveAll( );

Example
See CObList::CObList for a listing of the CAge class used in all collection examples.
{
CMapStringToOb map;

CAge age1(13); // Two objects on the stack


CAge age2(36);
map.SetAt(_T("Bart"), &age1);
map.SetAt(_T("Homer"), &age2);
ASSERT(map.GetCount() == 2);
map.RemoveAll(); // CObject pointers removed; objects not removed.
ASSERT(map.GetCount() == 0);
ASSERT(map.IsEmpty());
} // The two CAge objects are deleted when they go out of scope.

CMapStringToOb::RemoveKey
Looks up the map entry corresponding to the supplied key; then, if the key is found, removes the entry.

BOOL RemoveKey(LPCTSTR key);

Parameters
key
Specifies the string used for map lookup.
Return Value
Nonzero if the entry was found and successfully removed; otherwise 0.
Remarks
This can cause memory leaks if the CObject object is not deleted elsewhere.
The following table shows other member functions that are similar to CMapStringToOb::RemoveKey .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr BOOL RemoveKey( void * key );

CMapPtrToWord BOOL RemoveKey( void * key );

CMapStringToPtr BOOL RemoveKey( LPCTSTR key );

CMapStringToString BOOL RemoveKey( LPCTSTR key );

CMapWordToOb BOOL RemoveKey( WORD key );

CMapWordToPtr BOOL RemoveKey( WORD key );

Example
See CObList::CObList for a listing of the CAge class used in all collection examples.
CMapStringToOb map;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Lisa"), new CAge(11));
map.SetAt(_T("Homer"), new CAge(36));
map.SetAt(_T("Marge"), new CAge(35));
map.RemoveKey(_T("Lisa")); // Memory leak: CAge object not
// deleted.
#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << _T("RemoveKey example: ") << &map << _T("\n");
#endif

The results from this program are as follows:

RemoveKey example: A CMapStringToOb with 3 elements


[Marge] = a CAge at $49A0 35
[Homer] = a CAge at $495E 36
[Bart] = a CAge at $4634 13

CMapStringToOb::SetAt
The primary means to insert an element in a map.

void SetAt(
LPCTSTR key,
CObject* newValue);

Parameters
key
Specifies the string that is the key of the new element.
newValue
Specifies the CObject pointer that is the value of the new element.
Remarks
First, the key is looked up. If the key is found, then the corresponding value is changed; otherwise a new key-value
element is created.
The following table shows other member functions that are similar to CMapStringToOb::SetAt .

C L A SS M EM B ER F UN C T IO N

CMapPtrToPtr void SetAt( void * key , void * newValue );

CMapPtrToWord void SetAt( void * key , WORD newValue );

CMapStringToPtr void SetAt( LPCTSTR key , void * newValue );

CMapStringToString void SetAt( LPCTSTR key , LPCTSTR newValue );

CMapWordToOb void SetAt( WORD key , CObject * newValue );

CMapWordToPtr void SetAt( WORD key , void * newValue );


Example
See CObList::CObList for a listing of the CAge class used in all collection examples.

CMapStringToOb map;
CAge *pa;

map.SetAt(_T("Bart"), new CAge(13));


map.SetAt(_T("Lisa"), new CAge(11)); // Map contains 2
// elements.
#ifdef _DEBUG
afxDump.SetDepth(1);
afxDump << _T("before Lisa's birthday: ") << &map << _T("\n");
#endif
if (map.Lookup(_T("Lisa"), (CObject *&)pa))
{ // CAge 12 pointer replaces CAge 11 pointer.
map.SetAt(_T("Lisa"), new CAge(12));
delete pa; // Must delete CAge 11 to avoid memory leak.
}
#ifdef _DEBUG
afxDump << _T("after Lisa's birthday: ") << &map << _T("\n");
#endif

The results from this program are as follows:

before Lisa's birthday: A CMapStringToOb with 2 elements


[Lisa] = a CAge at $493C 11
[Bart] = a CAge at $4654 13
after Lisa's birthday: A CMapStringToOb with 2 elements
[Lisa] = a CAge at $49C0 12
[Bart] = a CAge at $4654 13

See also
CObject Class
Hierarchy Chart
CMapPtrToPtr Class
CMapPtrToWord Class
CMapStringToPtr Class
CMapStringToString Class
CMapWordToOb Class
CMapWordToPtr Class
CMapStringToPtr Class
3/16/2020 • 2 minutes to read • Edit Online

Supports maps of void pointers keyed by CString objects.

Syntax
class CMapStringToPtr : public CObject

Members
The member functions of CMapStringToPtr are similar to the member functions of class CMapStringToOb.
Because of this similarity, you can use the CMapStringToOb reference documentation for member function
specifics. Wherever you see a CObject pointer as a function parameter or return value, substitute a pointer to
void .
BOOL CMapStringToPtr::Lookup( LPCTSTR <key>, void*& <rValue> ) const;

for example, translates to


BOOL CMapStringToOb::Lookup( const char* <key>, CObject*& <rValue> ) const;

Public Constructors
NAME DESC RIP T IO N

CMapStringToPtr::CMapStringToPtr Constructor.

Public Methods
NAME DESC RIP T IO N

CMapStringToPtr::GetCount Returns the number of elements in this map.

CMapStringToPtr::GetHashTableSize Determines the current number of elements in the hash


table.

CMapStringToPtr::GetNextAssoc Gets the next element for iterating.

CMapStringToPtr::GetSize Returns the number of elements in this map.

CMapStringToPtr::GetStartPosition Returns the position of the first element.

CMapStringToPtr::HashKey Calculates the hash value of a specified key.

CMapStringToPtr::InitHashTable Initializes the hash table.

CMapStringToPtr::IsEmpty Tests for the empty-map condition (no elements).


NAME DESC RIP T IO N

CMapStringToPtr::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapStringToPtr::LookupKey Returns a reference to the key associated with the specified


key value.

CMapStringToPtr::RemoveAll Removes all the elements from this map.

CMapStringToPtr::RemoveKey Removes an element specified by a key.

CMapStringToPtr::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapStringToPtr::operator [ ] Inserts an element into the map — operator substitution


for SetAt .

Remarks
CMapStringToPtr incorporates the IMPLEMENT_DYNAMIC macro to support run-time type access and
dumping to a CDumpContext object. If you need a dump of individual map elements, you must set the depth of
the dump context to 1 or greater.
String-to-pointer maps may not be serialized.
When a CMapStringToPtr object is deleted, or when its elements are removed, the CString key objects and
the words are removed.

Inheritance Hierarchy
CObject
CMapStringToPtr

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CMapStringToString Class
3/27/2020 • 4 minutes to read • Edit Online

Supports maps of CString objects keyed by CString objects.

Syntax
class CMapStringToString : public CObject

Members
The member functions of CMapStringToString are similar to the member functions of class CMapStringToOb.
Because of this similarity, you can use the CMapStringToOb reference documentation for member function
specifics. Wherever you see a CObject pointer as a return value or "output" function parameter, substitute a
pointer to char . Wherever you see a CObject pointer as an "input" function parameter, substitute a pointer to
char .
BOOL CMapStringToString::Lookup(LPCTSTR<key>, CString&<rValue>) const;

for example, translates to


BOOL CMapStringToOb::Lookup(const char*<key>, CObject*&<rValue>) const;

Public Structures
NAME DESC RIP T IO N

CMapStringToString::CPair A nested structure containing a key value and the value of


the associated string object.

Public Constructors
NAME DESC RIP T IO N

CMapStringToString::CMapStringToString Constructor.

Public Methods
NAME DESC RIP T IO N

CMapStringToString::GetCount Returns the number of elements in this map.

CMapStringToString::GetHashTableSize Determines the current number of elements in the hash


table.

CMapStringToString::GetNextAssoc Gets the next element for iterating.

CMapStringToString::GetSize Returns the number of elements in this map.

CMapStringToString::GetStartPosition Returns the position of the first element.


NAME DESC RIP T IO N

CMapStringToString::HashKey Calculates the hash value of a specified key.

CMapStringToString::InitHashTable Initializes the hash table.

CMapStringToString::IsEmpty Tests for the empty-map condition (no elements).

CMapStringToString::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapStringToString::LookupKey Returns a reference to the key associated with the specified


key value.

CMapStringToString::PGetFirstAssoc Gets a pointer to the first CString in the map.

CMapStringToString::PGetNextAssoc Gets a pointer to the next CString for iterating.

CMapStringToString::PLookup Returns a pointer to a CString whose value matches the


specified value.

CMapStringToString::RemoveAll Removes all the elements from this map.

CMapStringToString::RemoveKey Removes an element specified by a key.

CMapStringToString::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapStringToString::operator [ ] Inserts an element into the map — operator substitution


for SetAt .

Remarks
CMapStringToString incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its
elements. Each element is serialized in turn if a map is stored to an archive, either with the overloaded
insertion ( << ) operator or with the Serialize member function.
If you need a dump of individual CString - CString elements, you must set the depth of the dump context to
1 or greater.
When a CMapStringToString object is deleted, or when its elements are removed, the CString objects are
removed as appropriate.
For more information on CMapStringToString , see the article Collections.

Inheritance Hierarchy
CObject
CMapStringToString
Requirements
Header : afxcoll.h

CMapStringToString::CPair
Contains a key value and the value of the associated string object.
Remarks
This is a nested structure within class CMapStringToString.
The structure is composed of two fields:
key The actual value of the key type.
value The value of the associated object.
It is used to store the return values from CMapStringToString::PLookup, CMapStringToString::PGetFirstAssoc,
and CMapStringToString::PGetNextAssoc.
Example
For an example of usage, see the example for CMapStringToString::PLookup.

CMapStringToString::PGetFirstAssoc
Returns the first entry of the map object.

const CPair* PGetFirstAssoc() const;

CPair* PGetFirstAssoc();

Return Value
A pointer to the first entry in the map; see CMapStringToString::CPair. If the map is empty, the value is NULL.
Remarks
Call this function to return a pointer the first element in the map object.
Example

CMapStringToString myMap;
CString myStr[4] = {_T("One"), _T("Two"), _T("Three"), _T("Four")};
CMapStringToString::CPair *pCurVal;

myMap.InitHashTable(257);

// Add 4 elements to the map.


myMap.SetAt(myStr[0], _T("Odd"));
myMap.SetAt(myStr[1], _T("Even"));
myMap.SetAt(myStr[2], _T("Odd"));
myMap.SetAt(myStr[3], _T("Even"));

pCurVal = myMap.PGetFirstAssoc();
while (pCurVal != NULL)
{
_tprintf_s(_T("Current key value at %s: %s\n"),
pCurVal->key, pCurVal->value);
pCurVal = myMap.PGetNextAssoc(pCurVal);
}
CMapStringToString::PGetNextAssoc
Retrieves the map element pointed to by pAssocRec.

const CPair *PGetNextAssoc(const CPair* pAssoc) const;

CPair *PGetNextAssoc(const CPair* pAssoc);

Parameters
pAssoc
Points to a map entry returned by a previous PGetNextAssoc or PGetFirstAssoc call.
Return Value
A pointer to the next entry in the map; see CMapStringToString::CPair. If the element is the last in the map, the
value is NULL.
Remarks
Call this method to iterate through all the elements in the map. Retrieve the first element with a call to
PGetFirstAssoc and then iterate through the map with successive calls to PGetNextAssoc .

Example
See the example for CMapStringToString::PGetFirstAssoc.

CMapStringToString::PLookup
Looks up the value mapped to a given key.

const CPair* PLookup(LPCTSTR key) const;

CPair* PLookup(LPCTSTR key);

Parameters
key
A pointer to the key for the element to be searched for.
Return Value
A pointer to the specified key.
Remarks
Call this method to search for a map element with a key that exactly matches the given key.
Example
CMapStringToString myMap;
CString myStr[4] = {_T("One"), _T("Two"), _T("Three"), _T("Four")};

myMap.InitHashTable(257);

// Add 4 elements to the map.


myMap.SetAt(myStr[0], _T("Odd"));
myMap.SetAt(myStr[1], _T("Even"));
myMap.SetAt(myStr[2], _T("Odd"));
myMap.SetAt(myStr[3], _T("Even"));

// Print the element values with odd key values.


CMapStringToString::CPair *pCurVal;

for (int i = 0; i < 4; i += 2)


{
pCurVal = myMap.PLookup(myStr[i]);
_tprintf_s(_T("Current key value at %s: %s\n"),
pCurVal->key, pCurVal->value);
}

See also
MFC Sample COLLECT
CObject Class
Hierarchy Chart
CMapWordToOb Class
3/17/2020 • 2 minutes to read • Edit Online

Supports maps of CObject pointers keyed by 16-bit words.

Syntax
class CMapWordToOb : public CObject

Members
The member functions of CMapWordToOb are similar to the member functions of class CMapStringToOb. Because
of this similarity, you can use the CMapStringToOb reference documentation for member function specifics.
Wherever you see a CString or a const pointer to char as a function parameter or return value, substitute
WORD.
BOOL CMapWordToOb::Lookup( WORD <key>, CObject*& <rValue> ) const;

for example, translates to


BOOL CMapStringToOb::Lookup( const char* <key>, CObject*& <rValue> ) const;

Public Constructors
NAME DESC RIP T IO N

CMapWordToOb::CMapWordToOb Constructor.

Public Methods
NAME DESC RIP T IO N

CMapWordToOb::GetCount Returns the number of elements in this map.

CMapWordToOb::GetHashTableSize Determines the current number of elements in the hash


table.

CMapWordToOb::GetNextAssoc Gets the next element for iterating.

CMapWordToOb::GetSize Returns the number of elements in this map.

CMapWordToOb::GetStartPosition Returns the position of the first element.

CMapWordToOb::HashKey Calculates the hash value of a specified key.

CMapWordToOb::InitHashTable Initializes the hash table.

CMapWordToOb::IsEmpty Tests for the empty-map condition (no elements).


NAME DESC RIP T IO N

CMapWordToOb::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapWordToOb::LookupKey Returns a reference to the key associated with the specified


key value.

CMapWordToOb::RemoveAll Removes all the elements from this map.

CMapWordToOb::RemoveKey Removes an element specified by a key.

CMapWordToOb::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapWordToOb::operator [ ] Inserts an element into the map — operator substitution


for SetAt .

Remarks
CMapWordToOb incorporates the IMPLEMENT_SERIAL macro to support serialization and dumping of its
elements. Each element is serialized in turn if a map is stored to an archive, either with the overloaded
insertion ( << ) operator or with the Serialize member function.
If you need a dump of individual WORD- CObject elements, you must set the depth of the dump context to 1
or greater.
When a CMapWordToOb object is deleted, or when its elements are removed, the CObject pointers are removed.
The objects referenced by the CObject pointers are not destroyed.
For more information on CMapWordToOb , see the article Collections.

Inheritance Hierarchy
CObject
CMapWordToOb

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CMapWordToPtr Class
3/16/2020 • 2 minutes to read • Edit Online

Supports maps of void pointers keyed by 16-bit words.

Syntax
class CMapWordToPtr : public CObject

Members
The member functions of CMapWordToPtr are similar to the member functions of class CMapStringToOb.
Because of this similarity, you can use the CMapStringToOb reference documentation for member function
specifics. Wherever you see a CObject pointer as a function parameter or return value, substitute a pointer to
void . Wherever you see a CString or a const pointer to char as a function parameter or return value,
substitute WORD.
BOOL CMapWordToPtr::Lookup( WORD <key>, void*& <rValue> ) const;

for example, translates to


BOOL CMapStringToOb::Lookup( const char* <key>, CObject*& <rValue> ) const;

Public Constructors
NAME DESC RIP T IO N

CMapWordToPtr::CMapWordToPtr Constructor.

Public Methods
NAME DESC RIP T IO N

CMapWordToPtr::GetCount Returns the number of elements in this map.

CMapWordToPtr::GetHashTableSize Determines the current number of elements in the hash


table.

CMapWordToPtr::GetNextAssoc Gets the next element for iterating.

CMapWordToPtr::GetSize Returns the number of elements in this map.

CMapWordToPtr::GetStartPosition Returns the position of the first element.

CMapWordToPtr::HashKey Calculates the hash value of a specified key.

CMapWordToPtr::InitHashTable Initializes the hash table.

CMapWordToPtr::IsEmpty Tests for the empty-map condition (no elements).


NAME DESC RIP T IO N

CMapWordToPtr::Lookup Looks up a void pointer based on the void pointer key. The
pointer value, not the entity it points to, is used for the key
comparison.

CMapWordToPtr::LookupKey Returns a reference to the key associated with the specified


key value.

CMapWordToPtr::RemoveAll Removes all the elements from this map.

CMapWordToPtr::RemoveKey Removes an element specified by a key.

CMapWordToPtr::SetAt Inserts an element into the map; replaces an existing


element if a matching key is found.

Public Operators
NAME DESC RIP T IO N

CMapWordToPtr::operator [ ] Inserts an element into the map — operator substitution


for SetAt .

Remarks
CMapWordToPtr incorporates the IMPLEMENT_DYNAMIC macro to support run-time type access and dumping
to a CDumpContext object. If you need a dump of individual map elements, you must set the depth of the dump
context to 1 or greater.
Word-to-pointer maps may not be serialized.
When a CMapWordToPtr object is deleted, or when its elements are removed, the words and the pointers are
removed. The entities referenced by the pointers are not removed.
For more information on CMapWordToPtr , see the article Collections.

Inheritance Hierarchy
CObject
CMapWordToPtr

Requirements
Header : afxcoll.h

See also
CObject Class
Hierarchy Chart
CMDIChildWnd Class
4/21/2020 • 7 minutes to read • Edit Online

Provides the functionality of a Windows multiple document interface (MDI) child window, along with
members for managing the window.

Syntax
class CMDIChildWnd : public CFrameWnd

Members
Public Constructors
NAME DESC RIP T IO N

CMDIChildWnd::CMDIChildWnd Constructs a CMDIChildWnd object.

Public Methods
NAME DESC RIP T IO N

CMDIChildWnd::Create Creates the Windows MDI child window associated with


the CMDIChildWnd object.

CMDIChildWnd::GetMDIFrame Returns the parent MDI frame of the MDI client window.

CMDIChildWnd::MDIActivate Activates this MDI child window.

CMDIChildWnd::MDIDestroy Destroys this MDI child window.

CMDIChildWnd::MDIMaximize Maximizes this MDI child window.

CMDIChildWnd::MDIRestore Restores this MDI child window from maximized or


minimized size.

CMDIChildWnd::SetHandles Sets the handles for menu and accelerator resources.

Remarks
An MDI child window looks much like a typical frame window, except that the MDI child window appears
inside an MDI frame window rather than on the desktop. An MDI child window does not have a menu bar of
its own, but instead shares the menu of the MDI frame window. The framework automatically changes the
MDI frame menu to represent the currently active MDI child window.
To create a useful MDI child window for your application, derive a class from CMDIChildWnd . Add member
variables to the derived class to store data specific to your application. Implement message-handler member
functions and a message map in the derived class to specify what happens when messages are directed to
the window.
There are three ways to construct an MDI child window:
Directly construct it using Create .
Directly construct it using LoadFrame .
Indirectly construct it through a document template.
Before you call Create or LoadFrame , you must construct the frame-window object on the heap using the
C++ new operator. Before calling Create you can also register a window class with the AfxRegisterWndClass
global function to set the icon and class styles for the frame.
Use the Create member function to pass the frame's creation parameters as immediate arguments.
LoadFrame requires fewer arguments than Create , and instead retrieves most of its default values from
resources, including the frame's caption, icon, accelerator table, and menu. To be accessible by LoadFrame , all
these resources must have the same resource ID (for example, IDR_MAINFRAME).
When a CMDIChildWnd object contains views and documents, they are created indirectly by the framework
instead of directly by the programmer. The CDocTemplate object orchestrates the creation of the frame, the
creation of the containing views, and the connection of the views to the appropriate document. The
parameters of the CDocTemplate constructor specify the CRuntimeClass of the three classes involved
(document, frame, and view). A CRuntimeClass object is used by the framework to dynamically create new
frames when specified by the user (for example, by using the File New command or the MDI Window New
command).
A frame-window class derived from CMDIChildWnd must be declared with DECLARE_DYNCREATE in order for
the above RUNTIME_CLASS mechanism to work correctly.
The CMDIChildWnd class inherits much of its default implementation from CFrameWnd . For a detailed list of
these features, please refer to the CFrameWnd class description. The CMDIChildWnd class has the following
additional features:
In conjunction with the CMultiDocTemplate class, multiple CMDIChildWnd objects from the same
document template share the same menu, saving Windows system resources.
The currently active MDI child window menu entirely replaces the MDI frame window's menu, and the
caption of the currently active MDI child window is added to the MDI frame window's caption. For
further examples of MDI child window functions that are implemented in conjunction with an MDI
frame window, see the CMDIFrameWnd class description.

Do not use the C++ delete operator to destroy a frame window. Use CWnd::DestroyWindow instead. The
CFrameWnd implementation of PostNcDestroy will delete the C++ object when the window is destroyed.
When the user closes the frame window, the default OnClose handler will call DestroyWindow .
For more information on CMDIChildWnd , see Frame Windows.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd
CMDIChildWnd
Requirements
Header : afxwin.h

CMDIChildWnd::CMDIChildWnd
Call to construct a CMDIChildWnd object.

CMDIChildWnd();

Remarks
Call Create to create the visible window.
Example
See the example for CMDIChildWnd::Create.

CMDIChildWnd::Create
Call this member function to create a Windows MDI child window and attach it to the CMDIChildWnd object.

virtual BOOL Create(


LPCTSTR lpszClassName,
LPCTSTR lpszWindowName,
DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
const RECT& rect = rectDefault,
CMDIFrameWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);

Parameters
lpszClassName
Points to a null-terminated character string that names the Windows class (a WNDCLASS structure). The class
name can be any name registered with the AfxRegisterWndClass global function. Should be NULL for a
standard CMDIChildWnd .
lpszWindowName
Points to a null-terminated character string that represents the window name. Used as text for the title bar.
dwStyle
Specifies the window style attributes. The WS_CHILD style is required.
rect
Contains the size and position of the window. The rectDefault value allows Windows to specify the size and
position of the new CMDIChildWnd .
pParentWnd
Specifies the window's parent. If NULL, the main application window is used.
pContext
Specifies a CCreateContext structure. This parameter can be NULL.
Return Value
Nonzero if successful; otherwise 0.
Remarks
The currently active MDI child frame window can determine the caption of the parent frame window. This
feature is disabled by turning off the FWS_ADDTOTITLE style bit of the child frame window.
The framework calls this member function in response to a user command to create a child window, and the
framework uses the pContext parameter to properly connect the child window to the application. When you
call Create , pContext can be NULL.
Example
Example 1:

// CMainFrame::OnFileNewCMdiChildWnd() is a menu command handler for the


// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It shows the creation of a standard Windows MDI child window using
// the registered CMDIChildWnd class.
void CMainFrame::OnFileNewMdiChildWnd()
{
CMDIChildWnd *pMDIChildWnd = new CMDIChildWnd;
VERIFY(pMDIChildWnd->Create(
NULL, // standard CMDIChildWnd class
_T("My MDIChildWnd"), // caption of MDI child window
WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW, // window styles
rectDefault, // default rectangle size
this)); // parent window; can be NULL

// the default PostNcDestroy handler will delete this object when destroyed
}

Example
Example 2:

// CMainFrame::OnHello() is a menu command handler for the CMainFrame


// class, which in turn is a CMDIFrameWnd-derived class.
// It shows the creation of a Windows MDI child window using a custom
// window class. The custom window class is registered in
// CHelloWnd::Create(). CHelloWnd is a CMDIChildWnd-derived class.
void CMainFrame::OnHello()
{
CHelloWnd *pHelloWnd = new CHelloWnd;
if (!pHelloWnd->Create(_T("Hello"),
WS_CHILD | WS_VISIBLE | WS_OVERLAPPEDWINDOW,
rectDefault, this))
return;

// the default PostNcDestroy handler will delete this object when destroyed
}
BOOL CHelloWnd::Create(
LPCTSTR szTitle,
LONG style /* = 0 */,
const RECT &rect /* = rectDefault */,
CMDIFrameWnd *parent /* = NULL */)
{
// Setup the shared menu
SetHandles(::LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_HELLO)),
NULL);

// Register a custom WndClass and create a window.


// This must be done because CHelloWnd has a custom icon.
LPCTSTR lpszHelloClass =
AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),
LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_HELLO)));

return CMDIChildWnd::Create(lpszHelloClass, szTitle, style, rect, parent);


}

CMDIChildWnd::GetMDIFrame
Call this function to return the MDI parent frame.

CMDIFrameWnd* GetMDIFrame();

Return Value
A pointer to the MDI parent frame window.
Remarks
The frame returned is two parents removed from the CMDIChildWnd and is the parent of the window of type
MDICLIENT that manages the CMDIChildWnd object. Call the GetParent member function to return the
CMDIChildWnd object's immediate MDICLIENT parent as a temporary CWnd pointer.

Example
See the example for CMDIFrameWnd::MDISetMenu.

CMDIChildWnd::MDIActivate
Call this member function to activate an MDI child window independently of the MDI frame window.

void MDIActivate();

Remarks
When the frame becomes active, the child window that was last activated will be activated as well.
Example
See the example for CMDIFrameWnd::GetWindowMenuPopup.

CMDIChildWnd::MDIDestroy
Call this member function to destroy an MDI child window.
void MDIDestroy();

Remarks
The member function removes the title of the child window from the frame window and deactivates the child
window.
Example

// CMainFrame::OnCloseWindow() is a menu command handler for


// CMainFrame class, which in turn is a CMDIFrameWnd-derived
// class. It closes and destroys the current active MDI child window.
void CMainFrame::OnCloseWindow()
{
CMDIChildWnd *child = MDIGetActive();
if (child)
child->MDIDestroy();
}

CMDIChildWnd::MDIMaximize
Call this member function to maximize an MDI child window.

void MDIMaximize();

Remarks
When a child window is maximized, Windows resizes it to make its client area fill the client area of the frame
window. Windows places the child window's Control menu in the frame's menu bar so that the user can
restore or close the child window and adds the title of the child window to the frame-window title.
Example

// CMainFrame::OnMaximizeWindow() is a menu command handler for


// CMainFrame class, which in turn is a CMDIFrameWnd-derived
// class. It maximizes the current active MDI child window.
void CMainFrame::OnMaximizeWindow()
{
BOOL maximized;
CMDIChildWnd *child = MDIGetActive(&maximized);
if (child && (!maximized))
child->MDIMaximize(); // or MDIMaximize(child);
}

CMDIChildWnd::MDIRestore
Call this member function to restore an MDI child window from maximized or minimized size.

void MDIRestore();

Example
// CMainFrame::OnRestoreWindow() is a menu command handler for
// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It restores the current active MDI child window from maximized
// or minimized size.
void CMainFrame::OnRestoreWindow()
{
BOOL maximized;
CMDIChildWnd *child = MDIGetActive(&maximized);
if (child && (maximized || child->IsIconic()))
child->MDIRestore(); // or MDIRestore(child);
}

CMDIChildWnd::SetHandles
Sets the handles for menu and accelerator resources.

void SetHandles(
HMENU hMenu,
HACCEL hAccel);

Parameters
hMenu
The handle of a menu resource.
hAccel
The handle of an accelerator resource.
Remarks
Call this function to set the menu and accelerator resources used by the MDI child window object.

See also
MFC Sample MDI
MFC Sample MDIDOCVW
MFC Sample SNAPVW
CFrameWnd Class
Hierarchy Chart
CWnd Class
CMDIFrameWnd Class
CMDIChildWndEx Class
4/21/2020 • 19 minutes to read • Edit Online

The CMDIChildWndEx class provides the functionality of a Windows multiple document interface (MDI) child
window. It extends the functionality of CMDIChildWnd Class. The framework requires this class when an MDI
application uses certain MFC classes.
For more detail see the source code located in the VC\atlmfc\src\mfc folder of your Visual Studio installation.

Syntax
class CMDIChildWndEx : public CMDIChildWnd

Members
Public Methods
NAME DESC RIP T IO N

CMDIChildWndEx::ActivateTopLevelFrame Called internally by the framework to activate top level frame


when the application should be activated from a taskbar tab.

CMDIChildWndEx::AddDockSite This method is not used or implemented.

CMDIChildWndEx::AddPane Adds a pane.

CMDIChildWndEx::AddTabbedPane Adds a tabbed pane.

CMDIChildWndEx::AdjustDockingLayout Adjusts the docking layout.

CMDIChildWndEx::CanShowOnMDITabs

CMDIChildWndEx::CanShowOnTaskBarTabs Tells the framework whether this MDI child can be displayed
on Windows 7 taskbar tabs.

CMDIChildWndEx::CanShowOnWindowsList Returns TRUE if the MDI child window name can be displayed
in the CMFCWindowsManagerDialog Class dialog box.
Otherwise returns FALSE.

CMDIChildWndEx::CreateObject Called by the framework to create a dynamic instance of this


class type.

CMDIChildWndEx::DockPane Docks a pane.

CMDIChildWndEx::DockPaneLeftOf Docks one pane to the left of another pane.

CMDIChildWndEx::EnableAutoHidePanes Enables auto-hide mode for panes when they are docked at
the specified sides of the window.
NAME DESC RIP T IO N

CMDIChildWndEx::EnableDocking Enables docking of the child window to the main frame.

CMDIChildWndEx::EnableTaskbarThumbnailClipRect Enables or disables automatic selection of a portion of a


window's client area to display as that window's thumbnail in
the taskbar.

CMDIChildWndEx::GetDockingManager

CMDIChildWndEx::GetDocumentName Returns the name of the document that is displayed in the


MDI child window.

CMDIChildWndEx::GetFrameIcon Called by the framework to retrieve the MDI child window


icon.

CMDIChildWndEx::GetFrameText Called by the framework to retrieve the text for the MDI child
window.

CMDIChildWndEx::GetPane Finds a pane by the specified control ID.

CMDIChildWndEx::GetRelatedTabGroup

CMDIChildWndEx::GetTabbedPane Returns a pointer to an embedded docking pane that was


converted to a tabbed document.

CMDIChildWndEx::GetTabProxyWnd Returns tab proxy window actually registered with Windows 7


taskbar tabs.

CMDIChildWndEx::GetTaskbarPreviewWnd Called by the framework when it needs to obtain a child


window (usually a view or splitter window) to be displayed on
Windows 7 taskbar tab thumbnail.

CMDIChildWndEx::GetTaskbarThumbnailClipRect Called by the framework when it needs to select a portion of


a window's client area to display as that window's thumbnail
in the taskbar.

CMDIChildWndEx::GetThisClass Called by the framework to obtain a pointer to the


CRuntimeClass object that is associated with this class type.

CMDIChildWndEx::GetToolbarButtonToolTipText Called by the framework to retrieve a tooltip for a toolbar


button.

CMDIChildWndEx::InsertPane Registers the specified pane with the docking manager.

CMDIChildWndEx::InvalidateIconicBitmaps Invalidates iconic bitmap representation of MDI child.

CMDIChildWndEx::IsPointNearDockSite Determines whether a specified point is near the dock site.

CMDIChildWndEx::IsReadOnly Returns TRUE if the document that is displayed in the child


window is read-only. Otherwise returns FALSE.

CMDIChildWndEx::IsRegisteredWithTaskbarTabs Returns TRUE if MDI child was successfully registered with


Windows 7 taskbar tabs.
NAME DESC RIP T IO N

CMDIChildWndEx::IsTabbedPane Returns TRUE if the MDI child window contains a docking


pane. Otherwise returns FALSE.

CMDIChildWndEx::IsTaskbarTabsSupportEnabled Tells whether the MDI child can appear on Windows 7 taskbar
tabs.

CMDIChildWndEx::IsTaskbarThumbnailClipRectEnabled Tells whether automatic selection of a portion of a window's


client area to display as that window's thumbnail in the
taskbar is enabled or disabled.

CMDIChildWndEx::m_dwDefaultTaskbarTabPropertyFlags A combination of flags, which is passed by the framework to


the SetTaskbarTabProperties method, when a tab (MDI child)
is being registered with Windows 7 taskbar tabs. The default
combination is STPF_USEAPPTHUMBNAILWHENACTIVE |
STPF_USEAPPPEEKWHENACTIVE.

CMDIChildWndEx::OnGetIconicLivePreviewBitmap Called by the framework when it needs to obtain a bitmap for


live preview of MDI child.

CMDIChildWndEx::OnGetIconicThumbnail Called by the framework when it needs to obtain a bitmap for


iconic thumbnail of MDI child.

CMDIChildWndEx::OnMoveMiniFrame Called by the framework to move a mini-frame window.

CMDIChildWndEx::OnPressTaskbarThmbnailCloseButton Called by the framework when the user presses close button
on Taskbar tab thumbnail..

CMDIChildWndEx::OnSetPreviewMode Called by the framework to enter or exit print preview mode.

CMDIChildWndEx::OnTaskbarTabThumbnailActivate Called by the framework when the Taskbar tab thumbnail


should process WM_ACTIVATE message.

CMDIChildWndEx::OnTaskbarTabThumbnailMouseActivate Called by the framework when the Taskbar tab thumbnail


should process WM_MOUSEACTIVATE message.

CMDIChildWndEx::OnTaskbarTabThumbnailStretch Called by the framework when it needs to stretch a bitmap for


Windows 7 taskbar tab thumbnail preview of MDI child.

CMDIChildWndEx::OnUpdateFrameTitle Called by the framework to update the frame title. (Overrides


CMDIChildWnd::OnUpdateFrameTitle .)

CMDIChildWndEx::PaneFromPoint Returns the pane that contains the given point.

CMDIChildWndEx::PreTranslateMessage Used by class CWinApp to translate window messages before


they are dispatched to the TranslateMessage and
DispatchMessage Windows functions. (Overrides
CWnd::PreTranslateMessage.)

CMDIChildWndEx::RecalcLayout Recalculates the layout of the window.

CMDIChildWndEx::RegisterTaskbarTab Registers MDI child with Windows 7 taskbar tabs.

CMDIChildWndEx::RemovePaneFromDockManager Removes a pane from the docking manager.


NAME DESC RIP T IO N

CMDIChildWndEx::SetRelatedTabGroup

CMDIChildWndEx::SetTaskbarTabActive Activates corresponding Windows 7 taskbar tab.

CMDIChildWndEx::SetTaskbarTabOrder Inserts MDI child before specified window on Windows 7


taskbar tabs.

CMDIChildWndEx::SetTaskbarTabProperties Sets properties for a Windows 7 taskbar tab.

CMDIChildWndEx::SetTaskbarThumbnailClipRect Called internally by the framework to set clipping rectangle to


select a portion of a window's client area to display as that
window's thumbnail in the taskbar.

CMDIChildWndEx::ShowPane

CMDIChildWndEx::UnregisterTaskbarTab Removes MDI child from Windows 7 taskbar tabs.

CMDIChildWndEx::UpdateTaskbarTabIcon Updates Windows 7 taskbar tab icon.

Remarks
To take advantage of extended docking features in MDI applications, derive the MDI child window class of your
application from CMDIChildWndEx instead of CMDIChildWnd.

Example
The following example derives a class from CMDIChildWndEx . This code snippet comes from the VisualStudioDemo
Sample: MFC Visual Studio Application.

class CChildFrame : public CMDIChildWndEx


{
DECLARE_DYNCREATE(CChildFrame)
public:
CChildFrame();

// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT &cs);
virtual void ActivateFrame(int nCmdShow = -1);

virtual BOOL IsReadOnly();


virtual LPCTSTR GetDocumentName(CObject **pObj);

// Implementation
public:
virtual ~CChildFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext &dc) const;
#endif

protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

DECLARE_MESSAGE_MAP()
};
Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd
CMDIChildWnd
CMDIChildWndEx

Requirements
Header : afxMDIChildWndEx.h

CMDIChildWndEx::AddPane
Adds a pane.

BOOL AddPane(
CBasePane* pControlBar,
BOOL bTail = TRUE);

Parameters
pControlBar
[in] A pointer to the pane.
bTail
[in] TRUE to add the pane to the end of the list of panes for the docking manager; otherwise, FALSE.
Return Value
TRUE if the pane was successfully registered with the docking manager; otherwise, FALSE.

CMDIChildWndEx::AddTabbedPane
Adds a tabbed pane.

void AddTabbedPane(CDockablePane* pControlBar);

Parameters
pControlBar
[in] A pointer to the pane.

CMDIChildWndEx::AdjustDockingLayout
Adjusts the docking layout.

virtual void AdjustDockingLayout(HDWP hdwp = NULL);

Parameters
hdwp
[in] Handle to a deferred window position structure.

CMDIChildWndEx::CanShowOnMDITabs
virtual BOOL CanShowOnMDITabs();

Return Value
Remarks

CMDIChildWndEx::CanShowOnWindowsList
Specifies whether the MDI child window name can be displayed in the CMFCWindowsManagerDialog Class dialog
box.

virtual BOOL CanShowOnWindowsList();

Return Value
TRUE if the window can be displayed in the Windows dialog box; otherwise, FALSE.
Remarks
Override this method in a derived class and return FALSE if the window should not be displayed in the Windows
dialog box. This function is called from CMFCWindowsManagerDialog .

CMDIChildWndEx::DockPane
Docks a pane.

void DockPane(
CBasePane* pBar,
UINT nDockBarID = 0,
LPCRECT lpRect = NULL);

Parameters
pBar
[in] A pointer to the pane.
nDockBarID
[in] The ID of the pane.
lpRect
[in] A pointer to a rectangle.
Remarks
The lpRect parameter is not used.

CMDIChildWndEx::DockPaneLeftOf
Docks one pane to the left of another pane.

BOOL DockPaneLeftOf(
CPane* pBar,
CPane* pLeftOf);
Parameters
pBar
A pointer to the pane that is to be docked.
pLeftOf
A pointer to the pane that serves as the point of reference.
Return Value
TRUE on success, FALSE on failure.
Remarks
This method takes the pane specified by pBar and docks it at the left side of the pane specified by pLeftOf.
Call this method when you want to dock several panes in predefined order.

CMDIChildWndEx::EnableAutoHidePanes
Enables auto-hide mode for panes when they are docked at the specified sides of the window.

BOOL EnableAutoHidePanes(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the sides of the main frame window that is enabled. Use one or more of the following flags.
CBRS_ALIGN_LEFT
CBRS_ALIGN_RIGHT
CBRS_ALIGN_TOP
CBRS_ALIGN_BOTTOM
Return Value
TRUE if the method succeeds; otherwise FALSE.

CMDIChildWndEx::EnableDocking
Enables docking of the child window to the main frame.

BOOL EnableDocking(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the docking alignment to enable.
Return Value
TRUE if the method succeeds; otherwise FALSE.
Remarks
Call this method to enable docking alignment to the main frame. You can pass a combination of CBRS_ALIGN_
flags (for more information, see CControlBar::EnableDocking).

CMDIChildWndEx::GetDockingManager
CDockingManager* GetDockingManager();

Return Value
Remarks

CMDIChildWndEx::GetDocumentName
Returns the name of the document that is displayed in the MDI child window.

virtual LPCTSTR GetDocumentName(CObject** pObj);

Return Value
A pointer to a string that contains the name of a document.
Remarks
A document is what the MDI child window displays. Generally, the window displays data that is loaded from or
saved to a file. Therefore, the name of the document is the name of the file. The default implementation of
GetDocumentName returns a string obtained from CDocument::GetPathName .

If the window displays a document that is not loaded from a file, override this method in a derived class and return
a unique document identifier.
GetDocumentName is called by the framework when it saves the state of all opened documents. The returned string
is written to the registry.
When the framework is restoring state later, the document name is read from the registry and passed to
CMDIFrameWndEx::CreateDocumentWindow. Override this method in a CMDIFrameWndEx-derived class and
create or open a document that has this name and read in the file that has this name. If the document is not based
on a file, create the document based on the document identifier itself. You should do the preceding actions only if
you intend to save and restore documents.
Example
The following example demonstrates the use of the GetDocumentName method. This code snippet comes from the
VisualStudioDemo Sample: MFC Visual Studio Application.

LPCTSTR CChildFrame::GetDocumentName(CObject **pObj)


{
if (DYNAMIC_DOWNCAST(CStartView, GetActiveView()) != NULL)
{
return g_strStartViewName;
}
return CMDIChildWndEx::GetDocumentName(pObj);
}

CMDIChildWndEx::GetFrameIcon
Called by the framework to retrieve the icon of the MDI child window.

virtual HICON GetFrameIcon() const;

Return Value
A handle to the window icon.
Remarks
This method is called by the framework to determine what icon to display on the MDI tab that contains the MDI
child frame window.
By default this method returns the window icon. Override GetFrameIcon in a CMDIChildWndEx -derived class to
customize this behavior.

CMDIChildWndEx::GetFrameText
Called by the framework to retrieve the text for the MDI child window.

virtual CString GetFrameText() const;

Return Value
A string that contains the frame window text.
Remarks
This method is called by the framework to determine what text to display on the MDI tab that contains the MDI
child frame window.
By default this method returns the window text. Override GetFrameText in a CMDIChildWndEx -derived class to
customize this behavior.

CMDIChildWndEx::GetPane
Finds a pane by the specified control ID.

CBasePane* GetPane(UINT nID);

Parameters
nID
[in] The control ID of the pane to find.
Return Value
A pointer to the pane if found, otherwise NULL.

CMDIChildWndEx::GetRelatedTabGroup
CMFCTabCtrl* GetRelatedTabGroup();

Return Value
Remarks

CMDIChildWndEx::GetTabbedPane
Returns a pointer to a docking pane that is part of a group of MDI tabbed documents.

CDockablePane* GetTabbedPane() const;

Return Value
A pointer to a docking pane that is part of a group of MDI tabbed documents.
CMDIChildWndEx::GetToolbarButtonToolTipText
Called by the framework to retrieve a tooltip for a toolbar button.

virtual BOOL GetToolbarButtonToolTipText(


CMFCToolBarButton*,
CString&);

Return Value
TRUE if the tooltip has been displayed. The default implementation returns FALSE.
Remarks
Override this method if you want to display custom tool tips for toolbar buttons.

CMDIChildWndEx::InsertPane
Registers the specified pane with the docking manager.

BOOL InsertPane(
CBasePane* pControlBar,
CBasePane* pTarget,
BOOL bAfter = TRUE);

Parameters
pControlBar
[in] A pointer to the pane to insert.
pTarget
[in] A pointer to the adjacent pane.
bAfter
[in] If TRUE, pControlBar is inserted after pTarget. If FALSE, pControlBar is inserted before pTarget.
Return Value
TRUE if the method succeeds, FALSE otherwise.

CMDIChildWndEx::IsPointNearDockSite
Determines whether a specified point is near the dock site.

BOOL IsPointNearDockSite(
CPoint point,
DWORD& dwBarAlignment,
BOOL& bOuterEdge) const;

Parameters
point
[in] The specified point.
dwBarAlignment
[in] Specifies which edge the point is near. Possible values are CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT,
CBRS_ALIGN_TOP, and CBRS_ALIGN_BOTTOM
bOuterEdge
[in] TRUE if the point is near the outer border of the dock site; FALSE otherwise.
Return Value
TRUE if the point is near the dock site; otherwise FALSE.
Remarks
The point is near the dock site when it is within the sensitivity set in the docking manager. The default sensitivity is
15 pixels.

CMDIChildWndEx::IsReadOnly
Specifies whether the document that is displayed in the child window is read-only.

virtual BOOL IsReadOnly();

Return Value
TRUE if the document is read-only; otherwise FALSE.
Remarks
This function is used to prevent saving of read-only documents.
Example
The following example demonstrates overriding the IsReadOnly method. This code snippet comes from the
VisualStudioDemo Sample: MFC Visual Studio Application.

BOOL CChildFrame::IsReadOnly()
{
return DYNAMIC_DOWNCAST(CStartView, GetActiveView()) != NULL;
}

CMDIChildWndEx::IsTabbedPane
Specifies whether the MDI child window contains a docking pane.

BOOL IsTabbedPane() const;

Return Value
TRUE if the MDI child window contains a docking pane that was converted to a tabbed document; otherwise
FALSE.

CMDIChildWndEx::OnMoveMiniFrame
Called by the framework to move a mini-frame window.

virtual BOOL OnMoveMiniFrame(CWnd* pFrame);

Parameters
pFrame
[in] A pointer to a mini-frame window.
Return Value
TRUE if the method succeeds, otherwise FALSE.
CMDIChildWndEx::OnSetPreviewMode
Called by the framework to enter or exit print preview mode.

virtual void OnSetPreviewMode(


BOOL bPreview,
CPrintPreviewState* pState);

Parameters
bPreview
[in] If TRUE, enter print preview mode. If FALSE, exit print preview mode.
pState
[in] A pointer to the print preview state structure.

CMDIChildWndEx::OnUpdateFrameTitle
Called by the framework to update the frame title.

virtual void OnUpdateFrameTitle(BOOL bAddToTitle);

Parameters
bAddToTitle
[in] If TRUE, add the document name to the title.

CMDIChildWndEx::PaneFromPoint
Returns the pane that contains the given point.

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
bool bExactBar,
CRuntimeClass* pRTCBarType) const;

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
DWORD& dwAlignment,
CRuntimeClass* pRTCBarType) const;

Parameters
point
[in] Specifies the point, in screen coordinates, to check.
nSensitivity
[in] Increase the search area by this amount. A pane satisfies the search criteria if the given point falls in the
increased area.
bExactBar
[in] TRUE to ignore the nSensitivity parameter; otherwise, FALSE.
pRTCBarType
[in] If not NULL, the method searches only panes of the specified type.
dwAlignment
[in] If a pane is found at the specified point, this parameter contains the side of the pane that was closest to the
specified point. For more information, see the Remarks section.
Return Value
A pointer to the CBasePane -derived object that contains the given point, or NULL if no pane was found.
Remarks
Call this method to determine whether a pane contains the specified point according to the specified conditions
such as runtime class and visibility.
When the function returns and a pane was found, dwAlignment contains the alignment of the specified point. For
example, if the point was closest to the top of the pane, dwAlignment is set to CBRS_ALIGN_TOP.

CMDIChildWndEx::RecalcLayout
Recalculates the layout of the window.

virtual void RecalcLayout(BOOL bNotify = TRUE);

Parameters
bNotify
[in] If TRUE, the active in-place item for the window receives notification of the layout change.

CMDIChildWndEx::RemovePaneFromDockManager
Removes a pane from the docking manager.

void RemovePaneFromDockManager(
CBasePane* pControlBar,
BOOL bDestroy,
BOOL bAdjustLayout,
BOOL bAutoHide,
CBasePane* pBarReplacement);

Parameters
pControlBar
[in] A pointer to the pane to remove.
bDestroy
[in] If TRUE, the removed pane is destroyed.
bAdjustLayout
[in] If TRUE, adjust the docking layout immediately.
bAutoHide
[in] If TRUE, the docking layout is related to the list of autohide bars. If FALSE, the docking layout is related to the
list of regular panes.
pBarReplacement
[in] A pointer to a pane that replaces the removed pane.

CMDIChildWndEx::SetRelatedTabGroup
void SetRelatedTabGroup(CMFCTabCtrl* p);

Parameters
[in] p
Remarks

CMDIChildWndEx::ShowPane
void ShowPane(
CBasePane* pBar,
BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
[in] pBar
[in] bShow
[in] bDelay
[in] bActivate
Remarks

CMDIChildWndEx::UpdateTaskbarTabIcon
Updates the Windows 7 taskbar tab icon.

virtual void UpdateTaskbarTabIcon(HICON hIcon);

Parameters
hIcon
A handle to an icon to display on the Windows 7 taskbar tab.
Remarks

CMDIChildWndEx::UnregisterTaskbarTab
Removes the MDI child from Windows 7 taskbar tabs.

void UnregisterTaskbarTab(BOOL bCheckRegisteredMDIChildCount = TRUE);

Parameters
bCheckRegisteredMDIChildCount
Specifies whether this function needs to check the number of MDI children registered with MDI tabs. If this
number is 0, then this function removes the clipping rectangle from the application's taskbar thumbnail.
Remarks

CMDIChildWndEx::SetTaskbarThumbnailClipRect
Called by the framework to set the clipping rectangle to select a portion of a window's client area to display as that
window's thumbnail in the taskbar.

virtual BOOL SetTaskbarThumbnailClipRect(CRect rect);

Parameters
rect
Specifies the new clipping rectangle. If the rectangle is empty or null, the clipping is removed.
Return Value
TRUE if successful; otherwise FALSE.
Remarks

CMDIChildWndEx::SetTaskbarTabProperties
Sets properties for a Windows 7 taskbar tab.

void SetTaskbarTabProperties(DWORD dwFlags);

Parameters
dwFlags
A combination of STPFLAG values. For more information, see ITaskbarList4::SetTabProperties.
Remarks

CMDIChildWndEx::SetTaskbarTabOrder
Inserts the MDI child before the specified window on Windows 7 taskbar tabs.

void SetTaskbarTabOrder(CMDIChildWndEx* pWndBefore = NULL);

Parameters
pWndBefore
A pointer to the MDI child window whose thumbnail is inserted to the left. This window must already be registered
through RegisterTaskbarTab . If this value is NULL, the new thumbnail is added to the end of the list.
Remarks

CMDIChildWndEx::SetTaskbarTabActive
Activates the corresponding Windows 7 taskbar tab.

void SetTaskbarTabActive();

Remarks

CMDIChildWndEx::RegisterTaskbarTab
Registers the MDI child with Windows 7 taskbar tabs.

virtual void RegisterTaskbarTab(CMDIChildWndEx* pWndBefore = NULL);


Parameters
pWndBefore
A pointer to the MDI child window whose thumbnail is inserted to the left. This window must already be registered
through RegisterTaskbarTab . If this value is NULL, the new thumbnail is added to the end of the list.
Remarks

CMDIChildWndEx::OnTaskbarTabThumbnailStretch
Called by the framework when it needs to stretch a bitmap for a Windows 7 taskbar tab thumbnail preview of the
MDI child.

virtual BOOL OnTaskbarTabThumbnailStretch(


HBITMAP hBmpDst,
const CRect& rectDst,
HBITMAP hBmpSrc,
const CRect& rectSrc);

Parameters
hBmpDst
A handle to a destination bitmap.
rectDst
Specifies the destination rectangle.
hBmpSrc
A handle to a source bitmap.
rectSrc
Specifies the source rectangle.
Remarks
Requirement : afxmdichildwndex.h

CMDIChildWndEx::OnTaskbarTabThumbnailMouseActivate
Called by the framework when the Taskbar tab thumbnail should process the WM_MOUSEACTIVATE message.

virtual int OnTaskbarTabThumbnailMouseActivate(


CWnd* pDesktopWnd,
UINT nHitTest,
UINT message);

Parameters
pDesktopWnd
Specifies a pointer to the top-level parent window of the window being activated. The pointer may be temporary
and should not be stored.
nHitTest
Specifies the hit-test area code. A hit test is a test that determines the location of the cursor.
message
Specifies the mouse message number.
Remarks
The default implementation activates the related MDI child frame.
CMDIChildWndEx::OnTaskbarTabThumbnailActivate
Called by the framework when the Taskbar tab thumbnail should process the WM_ACTIVATE message.

virtual void OnTaskbarTabThumbnailActivate(


UINT nState,
CWnd* pWndOther,
BOOL bMinimized);

Parameters
nState
Specifies whether the CWnd is being activated or deactivated.
pWndOther
Pointer to the CWnd being activated or deactivated. The pointer can be NULL, and it may be temporary.
bMinimized
Specifies the minimized state of the CWnd being activated or deactivated. A value of TRUE indicates the window is
minimized.
Remarks
The default implementation activates the related MDI child frame.

CMDIChildWndEx::OnPressTaskbarThmbnailCloseButton
Called by the framework when the user presses the close button on the Taskbar tab thumbnail.

virtual void OnPressTaskbarThmbnailCloseButton();

Remarks

CMDIChildWndEx::OnGetIconicThumbnail
Called by the framework when it needs to obtain a bitmap for the iconic thumbnail of the MDI child.

virtual HBITMAP OnGetIconicThumbnail(


int nWidth,
int nHeight);

Parameters
nWidth
Specifies the width of the required bitmap.
nHeight
Specifies the height of the required bitmap.
Remarks

CMDIChildWndEx::OnGetIconicLivePreviewBitmap
Called by the framework when it needs to obtain a bitmap for live preview of the MDI child.
virtual HBITMAP OnGetIconicLivePreviewBitmap(
BOOL bIsMDIChildActive,
CPoint& ptLocation);

Parameters
bIsMDIChildActive
This parameter is TRUE if the bitmap is requested for the MDI child, which is currently active and the main window
is not minimized. The default processing in this case takes a snapshot of the main window.
ptLocation
Specifies the location of the bitmap in the main (top level) window client coordinates. This point should be
provided by the callee.
Return Value
If processed, returns a handle to a valid 32bpp bitmap, otherwise NULL.
Remarks
Override this method in a derived class and return a valid 32bpp bitmap for live preview of MDI child. This method
is called only when the MDI child is displayed on Windows 7 taskbar tabs. If you return NULL, MFC calls the
default handlers and obtains bitmaps using PrintClient or PrintWindow .

CMDIChildWndEx::m_dwDefaultTaskbarTabPropertyFlags
A combination of flags, which is passed by the framework to the SetTaskbarTabProperties method, when a tab
(MDI child) is being registered with Windows 7 taskbar tabs.

AFX_IMPORT_DATA static DWORD m_dwDefaultTaskbarTabPropertyFlags;

Remarks
The default combination is STPF_USEAPPTHUMBNAILWHENACTIVE | STPF_USEAPPPEEKWHENACTIVE.

CMDIChildWndEx::IsTaskbarThumbnailClipRectEnabled
Tells whether automatic selection of a portion of a window's client area to display as that window's thumbnail in
the taskbar is enabled or disabled.

BOOL IsTaskbarThumbnailClipRectEnabled() const;

Return Value
Returns TRUE if automatic selection of a portion of a window's client area to display is enabled; otherwise FALSE.
Remarks

CMDIChildWndEx::IsTaskbarTabsSupportEnabled
Tells whether the MDI child can appear on Windows 7 taskbar tabs.

BOOL IsTaskbarTabsSupportEnabled();

Return Value
TRUE if the MDI child can appear on Windows 7 taskbar tabs; FALSE if the MDI child can not appear on Windows 7
taskbar tabs.
Remarks

CMDIChildWndEx::IsRegisteredWithTaskbarTabs
Returns TRUE if the MDI child was successfully registered with Windows 7 taskbar tabs.

BOOL IsRegisteredWithTaskbarTabs();

Return Value
TRUE if the MDI child is registered with Windows 7 taskbar tabs; otherwise FALSE.
Remarks

CMDIChildWndEx::InvalidateIconicBitmaps
Invalidates an iconic bitmap representation of a MDI child.

BOOL InvalidateIconicBitmaps();

Return Value
Returns FALSE if Windows 7 taskbar support is disabled or the MDI child is not registered with Windows 7 taskbar
tabs; otherwise returns TRUE.
Remarks
Should be called when the live content or size of a MDI child has changed.

CMDIChildWndEx::GetTaskbarThumbnailClipRect
Called by the framework when it needs to select a portion of a window's client area to display as that window's
thumbnail in the taskbar.

virtual CRect GetTaskbarThumbnailClipRect() const;

Return Value
A rectangle in windows coordinates. This rectangle is mapped to the client area of the top level frame. The
rectangle should be empty to clear the clipping rectangle.
Remarks

CMDIChildWndEx::GetTaskbarPreviewWnd
Called by the framework when it needs to obtain a child window (usually a view or splitter window) to be
displayed on a Windows 7 taskbar tab thumbnail.

virtual CWnd* GetTaskbarPreviewWnd();

Return Value
Should return a valid pointer to a CWnd object, whose preview should be displayed on a Windows 7 taskbar tab
related to this MDI child. The default implementation returns a child window of this MDI child with
AFX_IDW_PANE_FIRST control ID (which is usually a CView -derived class).
Remarks

CMDIChildWndEx::GetTabProxyWnd
Returns the tab proxy window registered with Windows 7 taskbar tabs.

CMDITabProxyWnd* GetTabProxyWnd();

Return Value
A pointer to a CMDITabProxyWnd object, which is registered with Windows 7 taskbar tabs.
Remarks

CMDIChildWndEx::EnableTaskbarThumbnailClipRect
Enables or disables automatic selection of a portion of a window's client area to display as that window's
thumbnail in the taskbar.

void EnableTaskbarThumbnailClipRect(BOOL bEnable = TRUE);

Parameters
bEnable
Specifies whether to enable (TRUE), or disable (FALSE) automatic selection of a portion of a window's client area to
display.
Remarks

CMDIChildWndEx::CanShowOnTaskBarTabs
Tells the framework whether this MDI child can be displayed on Windows 7 taskbar tabs.

virtual BOOL CanShowOnTaskBarTabs();

Return Value
TRUE if the content of the MDI child can be displayed on Windows 7 taskbar thumbnails.
Remarks
Override this method in a derived class and return FALSE to disable the appearance of this MDI child on Windows
7 taskbar tabs.

CMDIChildWndEx::ActivateTopLevelFrame
Called by the framework to activate the top level frame when the application is activated from a taskbar tab.

virtual void ActivateTopLevelFrame();

Remarks

See also
Hierarchy Chart
Classes
CMDIChildWnd Class
CMFCWindowsManagerDialog Class
CMDIFrameWndEx Class
CMDIFrameWnd Class
4/21/2020 • 12 minutes to read • Edit Online

Provides the functionality of a Windows multiple document interface (MDI) frame window, along with
members for managing the window.

Syntax
class CMDIFrameWnd : public CFrameWnd

Members
Public Constructors
NAME DESC RIP T IO N

CMDIFrameWnd::CMDIFrameWnd Constructs a CMDIFrameWnd .

Public Methods
NAME DESC RIP T IO N

CMDIFrameWnd::CreateClient Creates a Windows MDICLIENT window for this


CMDIFrameWnd . Called by the OnCreate member function
of CWnd .

CMDIFrameWnd::CreateNewChild Creates a new child window.

CMDIFrameWnd::GetWindowMenuPopup Returns the Window pop-up menu.

CMDIFrameWnd::MDIActivate Activates a different MDI child window.

CMDIFrameWnd::MDICascade Arranges all child windows in a cascaded format.

CMDIFrameWnd::MDIGetActive Retrieves the currently active MDI child window, along with
a flag indicating whether or not the child is maximized.

CMDIFrameWnd::MDIIconArrange Arranges all minimized document child windows.

CMDIFrameWnd::MDIMaximize Maximizes an MDI child window.

CMDIFrameWnd::MDINext Activates the child window immediately behind the currently


active child window and places the currently active child
window behind all other child windows.

CMDIFrameWnd::MDIPrev Activates the previous child window and places the currently
active child window immediately behind it.
NAME DESC RIP T IO N

CMDIFrameWnd::MDIRestore Restores an MDI child window from maximized or minimized


size.

CMDIFrameWnd::MDISetMenu Replaces the menu of an MDI frame window, the Window


pop-up menu, or both.

CMDIFrameWnd::MDITile Arranges all child windows in a tiled format.

Remarks
To create a useful MDI frame window for your application, derive a class from CMDIFrameWnd . Add member
variables to the derived class to store data specific to your application. Implement message-handler member
functions and a message map in the derived class to specify what happens when messages are directed to the
window.
You can construct an MDI frame window by calling the Create or LoadFrame member function of CFrameWnd .
Before you call Create or LoadFrame , you must construct the frame window object on the heap using the C++
new operator. Before calling Create you can also register a window class with the AfxRegisterWndClass global
function to set the icon and class styles for the frame.
Use the Create member function to pass the frame's creation parameters as immediate arguments.
LoadFrame requires fewer arguments than Create , and instead retrieves most of its default values from
resources, including the frame's caption, icon, accelerator table, and menu. To be accessed by LoadFrame , all
these resources must have the same resource ID (for example, IDR_MAINFRAME).
Though MDIFrameWnd is derived from CFrameWnd , a frame window class derived from CMDIFrameWnd need not
be declared with DECLARE_DYNCREATE .
The CMDIFrameWnd class inherits much of its default implementation from CFrameWnd . For a detailed list of these
features, refer to the CFrameWnd class description. The CMDIFrameWnd class has the following additional
features:
An MDI frame window manages the MDICLIENT window, repositioning it in conjunction with control
bars. The MDI client window is the direct parent of MDI child frame windows. The WS_HSCROLL and
WS_VSCROLL window styles specified on a CMDIFrameWnd apply to the MDI client window rather than
the main frame window so the user can scroll the MDI client area (as in the Windows Program Manager,
for example).
An MDI frame window owns a default menu that is used as the menu bar when there is no active MDI
child window. When there is an active MDI child, the MDI frame window's menu bar is automatically
replaced by the MDI child window menu.
An MDI frame window works in conjunction with the current MDI child window, if there is one. For
instance, command messages are delegated to the currently active MDI child before the MDI frame
window.
An MDI frame window has default handlers for the following standard Window menu commands:
ID_WINDOW_TILE_VERT
ID_WINDOW_TILE_HORZ
ID_WINDOW_CASCADE
ID_WINDOW_ARRANGE
An MDI frame window also has an implementation of ID_WINDOW_NEW, which creates a new frame
and view on the current document. An application can override these default command
implementations to customize MDI window handling.
Do not use the C++ delete operator to destroy a frame window. Use CWnd::DestroyWindow instead. The
CFrameWnd implementation of PostNcDestroy will delete the C++ object when the window is destroyed. When
the user closes the frame window, the default OnClose handler will call DestroyWindow .
For more information on CMDIFrameWnd , see Frame Windows.

Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd
CMDIFrameWnd

Requirements
Header : afxwin.h

CMDIFrameWnd::CMDIFrameWnd
Constructs a CMDIFrameWnd object.

CMDIFrameWnd();

Remarks
Call the Create or LoadFrame member function to create the visible MDI frame window.
Example

// Create main MDI Frame window. CMainFrame is a CMDIFrameWnd-derived


// class. The default CFrameWnd::PostNcDestroy() handler will delete this
// object when destroyed.
CMainFrame *pMainFrame = new CMainFrame;

CMDIFrameWnd::CreateClient
Creates the MDI client window that manages the CMDIChildWnd objects.

virtual BOOL CreateClient(


LPCREATESTRUCT lpCreateStruct,
CMenu* pWindowMenu);

Parameters
lpCreateStruct
A long pointer to a CREATESTRUCT structure.
pWindowMenu
A pointer to the Window pop-up menu.
Return Value
Nonzero if successful; otherwise 0.
Remarks
This member function should be called if you override the OnCreate member function directly.
Example

// The code below is from winmdi.cpp. It shows how to


// call CMDIFrameWnd::CreateClient(). CMainFrame is a
// CMDIFrameWnd-derived class.
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext * /*pContext*/)
{
CMenu *pMenu = NULL;
if (m_hMenuDefault == NULL)
{
// default implementation for MFC V1 backward compatibility
pMenu = GetMenu();
ASSERT(pMenu != NULL);
// This is attempting to guess which sub-menu is the Window menu.
// The Windows user interface guidelines say that the right-most
// menu on the menu bar should be Help and Window should be one
// to the left of that.
int iMenu = pMenu->GetMenuItemCount() - 2;

// If this assertion fails, your menu bar does not follow the guidelines
// so you will have to override this function and call CreateClient
// appropriately or use the MFC V2 MDI functionality.
ASSERT(iMenu >= 0);
pMenu = pMenu->GetSubMenu(iMenu);
ASSERT(pMenu != NULL);
}

return CreateClient(lpcs, pMenu);


}

CMDIFrameWnd::CreateNewChild
Creates a new child window.

CMDIChildWnd* CreateNewChild(
CRuntimeClass* pClass,
UINT nResource,
HMENU hMenu = NULL,
HACCEL hAccel = NULL);

Parameters
pClass
The run-time class of the child window to be created.
nResource
The ID of shared resources associated with the child window.
hMenu
The child window's menu.
hAccel
The child window's accelerator.
Remarks
Use this function to create child windows of an MDI frame window.
Example

// CMainFrame is a CMDIFrameWnd-derived class,


// OnNewDraw is a menu command handler,
// CDrawFrame is a CMDIChildWnd-derived class.
void CMainFrame::OnNewDraw()
{
CreateNewChild(RUNTIME_CLASS(CDrawFrame), IDR_DRAW, m_hDrawMenu,
m_hDrawAccel);
}

CMDIFrameWnd::GetWindowMenuPopup
Call this member function to obtain a handle to the current pop-up menu named "Window" (the pop-up menu
with menu items for MDI window management).

virtual HMENU GetWindowMenuPopup(HMENU hMenuBar);

Parameters
hMenuBar
The current menu bar.
Return Value
The Window pop-up menu if one exists; otherwise NULL.
Remarks
The default implementation looks for a pop-up menu containing standard Window menu commands such as
ID_WINDOW_NEW and ID_WINDOW_TILE_HORZ.
Override this member function if you have a Window menu that does not use the standard menu command
IDs.
Example
// CMainFrame::OnActivateFirstMDIChild() is a menu command handler for
// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It looks for the caption of the first created MDI child window from
// the Window popup menu, and then activate the child window.
void CMainFrame::OnActivateFirstMDIChild()
{
// Get handle to the Window pop-up menu.
CMenu *menubar = GetMenu();
CMenu *wmenu = CMenu::FromHandle(GetWindowMenuPopup(menubar->GetSafeHmenu()));
if (wmenu == NULL)
return;

// Get the caption of the first created MDI child window.


CString caption;
if (!wmenu->GetMenuString(AFX_IDM_FIRST_MDICHILD, caption, MF_BYCOMMAND))
return;

// Get the actual name of the first created MDI child window by
// getting rid of the number and space, e.g. "&1 MDI 1".
int pos = caption.FindOneOf(_T(" "));
if (pos == -1)
return;

caption = caption.Right(caption.GetLength() - (pos + 1));

// Get the CWnd* of the first created MDI child window by comparing
// the caption of each MDI child window in the MDI application.
// Activate the first created MDI child window if found.
CMDIChildWnd *child = MDIGetActive();
do
{
CString str;
child->GetWindowText(str);
if (str == caption)
{
child->MDIActivate(); // or MDIActivate(child);
break;
}

child = (CMDIChildWnd*)child->GetWindow(GW_HWNDNEXT);
} while (child);
}

CMDIFrameWnd::MDIActivate
Activates a different MDI child window.

void MDIActivate(CWnd* pWndActivate);

Parameters
pWndActivate
Points to the MDI child window to be activated.
Remarks
This member function sends the WM_MDIACTIVATE message to both the child window being activated and the
child window being deactivated.
This is the same message that is sent if the user changes the focus to an MDI child window by using the mouse
or keyboard.
NOTE
An MDI child window is activated independently of the MDI frame window. When the frame becomes active, the child
window that was last activated is sent a WM_NCACTIVATE message to draw an active window frame and caption bar,
but it does not receive another WM_MDIACTIVATE message.

Example
See the example for CMDIFrameWnd::GetWindowMenuPopup.

CMDIFrameWnd::MDICascade
Arranges all the MDI child windows in a cascade format.

void MDICascade();
void MDICascade(int nType);

Parameters
nType
Specifies a cascade flag. Only the following flag can be specified: MDITILE_SKIPDISABLED, which prevents
disabled MDI child windows from being cascaded.
Remarks
The first version of MDICascade , with no parameters, cascades all MDI child windows, including disabled ones.
The second version optionally does not cascade disabled MDI child windows if you specify
MDITILE_SKIPDISABLED for the nType parameter.
Example

// CMainFrame::OnWindowCommand() is a menu command handler for


// CMainFrame class, which is a CMDIFrameWnd-derived
// class. It handles menu commands for the Windows pop-up menu.
// Its entries in the message map are of the following form:
// ON_COMMAND_EX(ID_WINDOW_ARRANGE, &CMainFrame::OnWindowCommand)
BOOL CMainFrame::OnWindowCommand(UINT nID)
{
switch (nID)
{
case ID_WINDOW_ARRANGE: // For Window\Arrange Icons menu item, arrange
MDIIconArrange(); // all minimized document child windows.
break;

case ID_WINDOW_CASCADE: // For Window\Cascade menu item, arrange


MDICascade(); // all the MDI child windows in a cascade format.
break;

case ID_WINDOW_TILE_HORZ: // For Window\Tile Horizontal menu item,


MDITile(MDITILE_HORIZONTAL); // tile MDI child windows so that
break; // one window appears above another.

case ID_WINDOW_TILE_VERT: // For Window\Tile Vertical menu item,


MDITile(MDITILE_VERTICAL); // tile MDI child windows so that
break; // one window appears beside another.
}

return TRUE;
}
CMDIFrameWnd::MDIGetActive
Retrieves the current active MDI child window, along with a flag indicating whether the child window is
maximized.

CMDIChildWnd* MDIGetActive(BOOL* pbMaximized = NULL) const;

Parameters
pbMaximized
A pointer to a BOOL return value. Set to TRUE on return if the window is maximized; otherwise FALSE.
Return Value
A pointer to the active MDI child window.
Example
See the example for CMDIChildWnd::MDIMaximize.

CMDIFrameWnd::MDIIconArrange
Arranges all minimized document child windows.

void MDIIconArrange();

Remarks
It does not affect child windows that are not minimized.
Example
See the example for CMDIFrameWnd::MDICascade.

CMDIFrameWnd::MDIMaximize
Maximizes the specified MDI child window.

void MDIMaximize(CWnd* pWnd);

Parameters
pWnd
Points to the window to maximize.
Remarks
When a child window is maximized, Windows resizes it to make its client area fill the client window. Windows
places the child window's Control menu in the frame's menu bar so the user can restore or close the child
window. It also adds the title of the child window to the frame-window title.
If another MDI child window is activated when the currently active MDI child window is maximized, Windows
restores the currently active child and maximizes the newly activated child window.
Example
See the example for CMDIChildWnd::MDIMaximize.

CMDIFrameWnd::MDINext
Activates the child window immediately behind the currently active child window and places the currently
active child window behind all other child windows.

void MDINext();

Remarks
If the currently active MDI child window is maximized, the member function restores the currently active child
and maximizes the newly activated child.
Example

// CMainFrame::OnActivateNextWindow() is a menu command handler for


// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It activates the child window immediately behind the currently
// active child window and places the currently active child window
// behind all other child windows.
void CMainFrame::OnActivateNextWindow()
{
MDINext();
}

CMDIFrameWnd::MDIPrev
Activates the previous child window and places the currently active child window immediately behind it.

void MDIPrev();

Remarks
If the currently active MDI child window is maximized, the member function restores the currently active child
and maximizes the newly activated child.

CMDIFrameWnd::MDIRestore
Restores an MDI child window from maximized or minimized size.

void MDIRestore(CWnd* pWnd);

Parameters
pWnd
Points to the window to restore.
Example
See the example for CMDIChildWnd::MDIRestore.

CMDIFrameWnd::MDISetMenu
Replaces the menu of an MDI frame window, the Window pop-up menu, or both.

CMenu* MDISetMenu(
CMenu* pFrameMenu,
CMenu* pWindowMenu);
Parameters
pFrameMenu
Specifies the menu of the new frame-window menu. If NULL, the menu is not changed.
pWindowMenu
Specifies the menu of the new Window pop-up menu. If NULL, the menu is not changed.
Return Value
A pointer to the frame-window menu replaced by this message. The pointer may be temporary and should not
be stored for later use.
Remarks
After calling MDISetMenu , an application must call the DrawMenuBar member function of CWnd to update the
menu bar.
If this call replaces the Window pop-up menu, MDI child-window menu items are removed from the previous
Window menu and added to the new Window pop-up menu.
If an MDI child window is maximized and this call replaces the MDI frame-window menu, the Control menu
and restore controls are removed from the previous frame-window menu and added to the new menu.
Do not call this member function if you use the framework to manage your MDI child windows.
Example

// CMdiView::OnReplaceMenu() is a menu command handler for CMdiView


// class, which in turn is a CView-derived class. It loads a new
// menu resource and replaces the main application window's menu
// bar with this new menu.
void CMdiView::OnReplaceMenu()
{
// Load a new menu resource named IDR_SHORT_MENU. m_hDefaultMenu is
// a member variable of CMdiDoc class (a CDocument-derived class).
// Its type is HMENU.
CMdiDoc *pdoc = (CMdiDoc*)GetDocument();
pdoc->m_hDefaultMenu =
::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_SHORT_MENU));
if (pdoc->m_hDefaultMenu == NULL)
return;

// Get the parent window of this view window. The parent window is
// a CMDIChildWnd-derived class. We can then obtain the MDI parent
// frame window using the CMDIChildWnd*. Then, replace the current
// menu bar with the new loaded menu resource.
CMDIFrameWnd *frame = ((CMDIChildWnd*)GetParent())->GetMDIFrame();
frame->MDISetMenu(CMenu::FromHandle(pdoc->m_hDefaultMenu), NULL);
frame->DrawMenuBar();
}
// GetDefaultMenu() is an undocumented virtual function for
// CDocument class. It allows the document to determine which
// menu to display. m_hDefaultMenu is of type HMENU. Its value
// is initialized to NULL either in the constructor or
// CDocument::OnNewDocument(). And the menu resource is destroyed
// in the destructor to avoid having too many menus loaded at once.
HMENU CMdiDoc::GetDefaultMenu()
{
if (m_hDefaultMenu)
return m_hDefaultMenu;

return COleServerDoc::GetDefaultMenu();
}

// Initialize member variable(s) in the constructor. CMdiDoc is


// a CDocument-derived class.
CMdiDoc::CMdiDoc()
{
// Use OLE compound files
EnableCompoundFile();

m_hDefaultMenu = NULL; // initialize to NULL


}

// Destroy menu resource in CMdiDoc's destructor. CMdiDoc is


// a CDocument-derived class.
CMdiDoc::~CMdiDoc()
{
if (m_hDefaultMenu)
::DestroyMenu(m_hDefaultMenu);
}

CMDIFrameWnd::MDITile
Arranges all child windows in a tiled format.

void MDITile();
void MDITile(int nType);

Parameters
nType
Specifies a tiling flag. This parameter can be any one of the following flags:
MDITILE_HORIZONTAL Tiles MDI child windows so that one window appears above another.
MDITILE_SKIPDISABLED Prevents disabled MDI child windows from being tiled.
MDITILE_VERTICAL Tiles MDI child windows so that one window appears beside another.
Remarks
The first version of MDITile , without parameters, tiles the windows vertically under Windows versions 3.1 and
later. The second version tiles windows vertically or horizontally, depending on the value of the nType
parameter.
Example
See the example for CMDIFrameWnd::MDICascade.

See also
MFC Sample MDI
MFC Sample MDIDOCVW
MFC Sample SNAPVW
CFrameWnd Class
Hierarchy Chart
CWnd Class
CMDIChildWnd Class
CMDIFrameWndEx Class
4/21/2020 • 37 minutes to read • Edit Online

Extends the functionality of CMDIFrameWnd, a Windows Multiple Document Interface (MDI) frame window.

Syntax
class CMDIFrameWndEx : public CMDIFrameWnd

Members
Public Methods
NAME DESC RIP T IO N

CMDIFrameWndEx::ActiveItemRecalcLayout Recalculates the layout of the active item.

CMDIFrameWndEx::AddDockSite This method is not used.

CMDIFrameWndEx::AddPane Registers a pane with the docking manager.

CMDIFrameWndEx::AdjustClientArea Reduces the client area to allow for a border.

CMDIFrameWndEx::AdjustDockingLayout Recalculates the layout of all docked panes.

CMDIFrameWndEx::AreMDITabs Determines whether the MDI Tabs feature or the MDI


Tabbed Groups feature is enabled.

CMDIFrameWndEx::CanCovertControlBarToMDIChild Called by the framework to determine whether the frame


window can convert docking panes to tabbed documents.

CMDIFrameWndEx::ControlBarToTabbedDocument Converts the specified docking pane to a tabbed document.

CMDIFrameWndEx::CreateDocumentWindow Creates a child document window.

CMDIFrameWndEx::CreateNewWindow Called by the framework to create a new window.

CMDIFrameWndEx::CreateObject Used by the framework to create a dynamic instance of this


class type.

CMDIFrameWndEx::DockPane Docks the specified pane to the frame window.

CMDIFrameWndEx::DockPaneLeftOf Docks one pane to the left of another pane.

CMDIFrameWndEx::EnableAutoHidePanes Enables auto-hide mode for panes when they are docked at
specified sides of the main frame window.

CMDIFrameWndEx::EnableDocking Enables docking of the panes that belong to the MDI frame
window.
NAME DESC RIP T IO N

CMDIFrameWndEx::EnableFullScreenMainMenu Shows or hides the main menu in full-screen mode.

CMDIFrameWndEx::EnableFullScreenMode Enables full-screen mode for the frame window.

CMDIFrameWndEx::EnableLoadDockState Enables or disables the loading of the docking state.

CMDIFrameWndEx::EnableMDITabbedGroups Enables or disables the MDI Tabbed Groups feature.

CMDIFrameWndEx::EnableMDITabs Enables or disables the MDI Tabs feature. When enabled, the
frame window displays a tab for each MDI child window.

CMDIFrameWndEx::EnableMDITabsLastActiveActivation Specifies whether the last active tab should be activated


when the user closes the current tab.

CMDIFrameWndEx::EnablePaneMenu Enables or disables automatic creation and management of


the pop-up pane menu, which displays a list of application
panes. .

CMDIFrameWndEx::EnableWindowsDialog Inserts a menu item whose command ID calls a


CMFCWindowsManagerDialog dialog box.

CMDIFrameWndEx::GetActivePopup Returns a pointer to the currently displayed popup menu.

CMDIFrameWndEx::GetPane Returns a pointer to the pane that has the specified control
ID.

CMDIFrameWndEx::GetDefaultResId Returns the ID of shared resources of the MDI frame


window.

CMDIFrameWndEx::GetMDITabGroups Returns a list of MDI tabbed windows.

CMDIFrameWndEx::GetMDITabs Returns a reference to the underlined tabbed window.

CMDIFrameWndEx::GetMDITabsContextMenuAllowedItems Returns a combination of flags that determines what context


menu items are valid when the MDI Tabbed Groups feature
is enabled.

CMDIFrameWndEx::GetMenuBar Returns a pointer to a menu bar object attached to the


frame window.

CMDIFrameWndEx::GetRibbonBar Retrieves the ribbon bar control for the frame.

CMDIFrameWndEx::GetTearOffBars Returns a list of CPane-derived objects that are in a tear-off


state.

CMDIFrameWndEx::GetThisClass Called by the framework to obtain a pointer to the


CRuntimeClass object that is associated with this class type.

CMDIFrameWndEx::GetToolbarButtonToolTipText Called by the framework when the application displays the


tooltip for a toolbar button.

CMDIFrameWndEx::InsertPane Registers the specified pane with the docking manager.


NAME DESC RIP T IO N

CMDIFrameWndEx::IsFullScreen Determines whether the frame window is in full-screen


mode.

CMDIFrameWndEx::IsMDITabbedGroup Determines whether the MDI Tabbed Groups feature is


enabled.

CMDIFrameWndEx::IsMemberOfMDITabGroup Determines whether the specified tabbed window is in the


list of windows that are in MDI Tabbed Groups.

CMDIFrameWndEx::IsMenuBarAvailable Determines whether the frame window has a menu bar.

CMDIFrameWndEx::IsPointNearDockSite Determines whether a specified point is near the dock site.

CMDIFrameWndEx::IsPrintPreview Determines whether the frame window is in print-preview


mode.

CMDIFrameWndEx::LoadFrame Creates a frame window from resource information.


(Overrides CMDIFrameWnd::LoadFrame .)

CMDIFrameWndEx::LoadMDIState Loads the specified layout of MDI Tabbed Groups and the list
of previously opened documents.

CMDIFrameWndEx::MDITabMoveToNextGroup Moves the active tab from the currently active tabbed
window to the next or previous tabbed group.

CMDIFrameWndEx::MDITabNewGroup Creates a new tabbed group that has a single window.

CMDIFrameWndEx::NegotiateBorderSpace Negotiates border space in a frame window during OLE in-


place activation.

CMDIFrameWndEx::OnCloseDockingPane Called by the framework when the user clicks the Close
button on a dockable pane.

CMDIFrameWndEx::OnCloseMiniFrame Called by the framework when the user clicks the Close
button on a floating mini frame window.

CMDIFrameWndEx::OnClosePopupMenu Called by the framework when an active pop-up menu


processes a WM_DESTROY message.

CMDIFrameWndEx::OnCmdMsg Called by the framework to route and dispatch command


messages and to update command user-interface objects.

CMDIFrameWndEx::OnDrawMenuImage Called by the framework when the image associated with a


menu item is drawn.

CMDIFrameWndEx::OnDrawMenuLogo Called by the framework when a CMFCPopupMenuprocesses


a WM_PAINT message.

CMDIFrameWndEx::OnEraseMDIClientBackground Called by the framework when the MDI frame window


processes a WM_ERASEBKGND message.

CMDIFrameWndEx::OnMenuButtonToolHitTest Called by the framework when a CMFCToolBarButtonobject


processes a WM_NCHITTEST message.
NAME DESC RIP T IO N

CMDIFrameWndEx::OnMoveMiniFrame Called by the framework to move a mini-frame window.

CMDIFrameWndEx::OnSetPreviewMode Sets the application's main frame window print-preview


mode. (Overrides CFrameWnd::OnSetPreviewMode.)

CMDIFrameWndEx::OnShowCustomizePane Called by the framework when a Quick Customize pane is


activated.

CMDIFrameWndEx::OnShowMDITabContextMenu Called by the framework when a context menu should be


displayed on one of the tabs. (Valid for MDI Tabbed Groups
only.)

CMDIFrameWndEx::OnShowPanes Called by the framework to show or hide panes.

CMDIFrameWndEx::OnShowPopupMenu Called by the framework when a pop-up menu is activated.

CMDIFrameWndEx::OnSizeMDIClient Called by the framework when the size of the client MDI
window is changing.

CMDIFrameWndEx::OnTearOffMenu Called by the framework when a menu that has a tear-off


bar is activated.

CMDIFrameWndEx::OnUpdateFrameMenu Called by the framework to update the frame menu.


(Overrides CMDIFrameWnd::OnUpdateFrameMenu .)

CMDIFrameWndEx::PaneFromPoint Returns the docking pane that contains the specified point.

CMDIFrameWndEx::PreTranslateMessage Used by class CWinApp to translate window messages


before they are dispatched to the TranslateMessage and
DispatchMessage Windows functions. (Overrides
CMDIFrameWnd::PreTranslateMessage .)

CMDIFrameWndEx::RecalcLayout Called by the framework to recalculate the layout of the


frame window. (Overrides CFrameWnd::RecalcLayout.)

CMDIFrameWndEx::RemovePaneFromDockManager Unregisters a pane and removes it from the docking


manager.

CMDIFrameWndEx::SaveMDIState Saves the current layout of MDI Tabbed Groups and the list
of previously opened documents.

CMDIFrameWndEx::SetPrintPreviewFrame Sets the print preview frame window.

CMDIFrameWndEx::SetupToolbarMenu Modifies a toolbar object by searching for dummy items and


replacing them with the specified user-defined items.

CMDIFrameWndEx::ShowFullScreen Switches the main frame from regular mode to full-screen


mode.

CMDIFrameWndEx::ShowPane Shows or hides the specified pane.

CMDIFrameWndEx::ShowWindowsDialog Creates a CMFCWindowsManagerDialog box and opens it.


NAME DESC RIP T IO N

CMDIFrameWndEx::TabbedDocumentToControlBar Converts the specified tabbed document to a docking pane.

CMDIFrameWndEx::UpdateCaption Called by the framework to update the window frame


caption.

CMDIFrameWndEx::UpdateMDITabbedBarsIcons Sets the icon for each MDI tabbed pane.

CMDIFrameWndEx::WinHelp Called by the framework to initiate the WinHelp application


or context help. (Overrides CWnd::WinHelp.)

Data Members
NAME DESC RIP T IO N

CMDIFrameWndEx::m_bCanCovertControlBarToMDIChild Determines whether docking panes can be converted to


MDI child windows.

CMDIFrameWndEx::m_bDisableSetRedraw Enables or disables redraw optimization for MDI child


windows.

Remarks
To take advantage of extended customization features in your MDI application, derive the MDI frame window
class of the application from CMDIFrameWndEx instead of CMDIFrameWnd .

Example
The following example derives a class from CMDIFrameWndEx . This code snippet comes from the DrawClient
Sample: MFC Ribbon-Based OLE Object Drawing Application.

class CMainFrame : public CMDIFrameWndEx


{
DECLARE_DYNAMIC(CMainFrame)
public:
struct XStyle
{
COLORREF clrFill;
COLORREF clrLine;
};

public:
CMainFrame();

// Attributes
public:
CMFCRibbonBar *GetRibbonBar() { return &m_wndRibbonBar; }

// Operations
public:
void UpdateUI(CDrawView *pCurrView);
void UpdateContextTab(CDrawView *pCurrView);
void UpdateContextTabFromObject(CDrawObjList &list);

COLORREF GetColorFromColorButton(int nButtonID);


int GetWeightFromLineWeight(int nButtonID);
BOOL GetStyleFromStyles(XStyle &style);

void SetRibbonContextCategory(UINT uiCategoryID);


void SetRibbonContextCategory(UINT uiCategoryID);
void ActivateRibbonContextCategory(UINT uiCategoryID);

// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext &dc) const;
#endif

protected:
// control bar embedded members
CMFCRibbonStatusBar m_wndStatusBar;
CMFCRibbonBar m_wndRibbonBar;

CMFCRibbonApplicationButton m_MainButton;

// panel images
CMFCToolBarImages m_PanelImages;

// Document colors for demo:


CList<COLORREF, COLORREF> m_lstMainColors;
CList<COLORREF, COLORREF> m_lstAdditionalColors;
CList<COLORREF, COLORREF> m_lstStandardColors;

// Generated message map functions


protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnAppLook(UINT id);
afx_msg void OnUpdateAppLook(CCmdUI *pCmdUI);
afx_msg void OnWindowManager();
afx_msg void OnMdiMoveToNextGroup();
afx_msg void OnMdiMoveToPrevGroup();
afx_msg void OnMdiNewHorzTabGroup();
afx_msg void OnMdiNewVertGroup();
afx_msg void OnMdiCancel();
afx_msg LRESULT OnRibbonCustomize(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnHighlightRibbonListItem(WPARAM wp, LPARAM lp);
afx_msg void OnToolsOptions();
afx_msg void OnDummy();
afx_msg void OnSysColorChange();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()

virtual BOOL OnShowMDITabContextMenu(CPoint point, DWORD dwAllowedItems, BOOL bDrop);


virtual BOOL OnShowPopupMenu(CMFCPopupMenu *pMenuPopup);

void ShowOptions(int nPage);


void CreateDocumentColors();

private:
BOOL CreateRibbonBar();
BOOL CreateStatusBar();

void InitMainButton();
void InitHomeCategory();
void InitViewCategory();
void InitTabButtons();

void AddContextTab_Format();

void AdjustObjectSubmenu(CMFCPopupMenu *pMenuPopup);


void UpdateStatusBarCountPane(int nID, CString strText, int nCount);

UINT m_nAppLook;
};
Inheritance Hierarchy
CObject
CCmdTarget
CWnd
CFrameWnd
CMDIFrameWnd
CMDIFrameWndEx

Requirements
Header : afxMDIFrameWndEx.h

CMDIFrameWndEx::ActiveItemRecalcLayout
Recalculates the layout of the active item.

void ActiveItemRecalcLayout();

CMDIFrameWndEx::AddPane
Registers a pane with the docking manager.

BOOL AddPane(
CBasePane* pControlBar,
BOOL bTail=TRUE);

Parameters
pControlBar
[in] Pointer to the pane to register.
bTail
[in] Specifies whether to add this pane to the end of the list.
Return Value
Returns a non-zero value if the pane is registered successfully. Returns 0 if the pane is already registered with
the docking manager.
Remarks
Each pane must be registered with the CDockingManager Class before it can take a part in the docking layout.
Use this method to notify the docking manager that you want to dock a specific pane. Once that pane is
registered, the docking manager aligns it based on its alignment setting and position in the list of panes
maintained by the docking manager.

CMDIFrameWndEx::AdjustClientArea
Reduces the client area to allow for a border.
virtual void AdjustClientArea();

CMDIFrameWndEx::AdjustDockingLayout
Recalculates the layout of all docked panes.

virtual void AdjustDockingLayout(HDWP hdwp=NULL);

Parameters
hdwp
[in] Identifies the multiple-window-position structure. You can obtain this value by calling BeginDeferWindowPos .
Remarks
Call this member function to recalculate the layout of all panes docked to the frame window.

CMDIFrameWndEx::AreMDITabs
Determines whether the MDI tabs feature or the MDI tabbed groups feature is enabled.

BOOL AreMDITabs(int* pnMDITabsType=NULL) const;

Parameters
pnMDITabsType
[out] A pointer to an integer variable that indicates which features are enabled:
0: All features are disabled.
1: MDI tabs is enabled.
2: MDI tabbed groups is enabled.
Return Value
Returns TRUE if MDI tabs or MDI tabbed groups is enabled.
Returns FALSE if none of the above features is enabled.
Remarks
Use this function to determine whether MDI tabs or MDI tabbed groups is enabled for the frame window. Use
CMDIFrameWndEx::EnableMDITabs to enable or disable the MDI tabs feature.
Use CMDIFrameWndEx::EnableMDITabbedGroups to enable or disable the MDI tabbed groups feature.

CMDIFrameWndEx::CanCovertControlBarToMDIChild
Called by the framework to determine whether the frame window can convert docking panes to tabbed
documents

virtual BOOL CanCovertControlBarToMDIChild();

Return Value
Returns TRUE if the frame window can convert docking panes to tabbed documents; otherwise returns FALSE.
Remarks
Override this method in a derived class and return TRUE to enable the conversion of docking panes to tabbed
documents. Alternatively, you can set CMDIFrameWndEx::m_bCanCovertControlBarToMDIChild to TRUE.

CMDIFrameWndEx::ControlBarToTabbedDocument
Converts the specified docking pane to a tabbed document.

virtual CMDIChildWndEx* ControlBarToTabbedDocument(CDockablePane* pBar);

Parameters
pBar
A pointer to the docking pane to convert.
Return Value
Returns a pointer to the new MDI child window that contains the docking pane.
Remarks
This method converts a docking pane to a tabbed document. When you call this method, the framework creates
a CMDIChildWndEx Class object, removes the docking pane from the docking manager, and adds the docking
pane to the new MDI child window. The MDI child window resizes the docking pane to cover the entire client
area

CMDIFrameWndEx::CreateDocumentWindow
Creates a child document window.

virtual CMDIChildWndEx* CreateDocumentWindow(


LPCTSTR lpcszDocName,
CObject* pObj);

Parameters
lpcszDocName
[in] A text string that contains a document identifier. Typically, it is the full path of a document file.
pObj
[in] A pointer to a user-defined object. For example, a developer can create an application-specific data structure
describing the document and telling how the document should be initialized at startup.
Return Value
A pointer to CMDIChildWndEx .
Remarks
The framework calls this method when it loads the list of documents previously saved in the registry.
Override this method in order to create documents when they are being loaded from the registry.
Example
The following example shows how CreateDocumentWindow is used in the VisualStudioDemo Sample: MFC Visual
Studio Application.
In this example, g_strStartViewName could be the name of a "virtual document" (for example, "Start Page") that is
not actually loaded from a disk file. Therefore we need special processing to handle that case.
CMainFrame::CMainFrame()
{
CMFCPopupMenu::SetForceShadow(TRUE);
m_bCanConvertControlBarToMDIChild = TRUE;
}

CMDIFrameWndEx::CreateNewWindow
Called by the framework to create a new window.

virtual CMDIChildWndEx* CreateNewWindow(


LPCTSTR lpcszDocName,
CObject* pObj);

Parameters
lpcszDocName
[in] The document name.
pObj
[in] Reserved for future use.
Return Value
A pointer to the new window.

CMDIFrameWndEx::DockPane
Docks the specified pane to the frame window.

void DockPane(
CBasePane* pBar,
UINT nDockBarID=0,
LPCRECT lpRect=NULL);

Parameters
pBar
[in] Pointer to the pane to dock.
nDockBarID
[in] Specifies which sides of the frame window to dock to.
lpRect
[in] Not used.
Remarks
This method docks the specified the pane to one of the sides of the frame window that was specified when
CBasePane::EnableDocking and CMDIFrameWndEx::EnableDocking were called.
Example
The following example demonstrates the use of the DockPane method. This code snippet comes from the
VisualStudioDemo Sample: MFC Visual Studio Application.
DockPane(&m_wndMenuBar);
DockPane(&m_wndToolBar);
DockPane(&m_wndPropertiesBar);

DockPane(&m_wndToolbarBuild);

CMDIFrameWndEx::DockPaneLeftOf
Docks one pane to the left of another pane.

BOOL DockPaneLeftOf(
CPane* pBar,
CPane* pLeftOf);

Parameters
pBar
[in] A pointer to the docking pane.
pLeftOf
[in] A pointer to the pane that serves as the dock site. .
Return Value
Returns TRUE if the operation is successful. Otherwise returns FALSE.
Remarks
Call this method to dock several pane objects in a predefined order. This method docks the pane specified by
pBar to the left of the pane specified by pLeftOf.
Example
The following example shows how the DockPaneLeftOf method is used in the VisualStudioDemo Sample: MFC
Visual Studio Application.

DockPane(&m_wndToolbarBuild);
DockPaneLeftOf(&m_wndToolbarEdit, &m_wndToolbarBuild);

CMDIFrameWndEx::EnableAutoHidePanes
Enables auto-hide mode for panes when they are docked at the specified sides of the main frame window.

BOOL EnableAutoHidePanes(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the sides of the main frame window that will be enabled. Use one or more of the following flags.
CBRS_ALIGN_LEFT
CBRS_ALIGN_RIGHT
CBRS_ALIGN_TOP
CBRS_ALIGN_BOTTOM
Return Value
Call this function to enable auto-hide mode for panes when they are docked at the specified sides of the main
frame window.
Example
The following example shows how the EnableAutoHidePanes method is used in the VisualStudioDemo Sample:
MFC Visual Studio Application.

EnableAutoHidePanes(CBRS_ALIGN_ANY);

Remarks

CMDIFrameWndEx::EnableDocking
Enables docking of the panes that belong to the MDI frame window.

BOOL EnableDocking(DWORD dwDockStyle);

Parameters
dwDockStyle
[in] Specifies the docking style that you want to apply.
Return Value
Remarks
Call this function to enable docking of panes that belong to the CMDIFrameWndEx object.
Example
The following example shows how the EnableDocking method is used in the VisualStudioDemo Sample: MFC
Visual Studio Application.

EnableDocking(CBRS_ALIGN_ANY);

CMDIFrameWndEx::EnableFullScreenMainMenu
Shows or hides the main menu in full-screen mode.

void EnableFullScreenMainMenu(BOOL bEnableMenu);

Parameters
bEnableMenu
[in] TRUE to show the main menu in full-screen mode, or FALSE to hide it.
Remarks

CMDIFrameWndEx::EnableFullScreenMode
Enables full-screen mode for the frame window.

void EnableFullScreenMode(UINT uiFullScreenCmd);

Parameters
uiFullScreenCmd
[in] The ID of a command that enables or disables full-screen mode.
Remarks
In full-screen mode, all docking control bars, toolbars and menus are hidden and the active view is resized to
occupy the full-screen.When you enable full-screen mode, you must specify an ID of the command that enables
or disables it. You can call EnableFullScreenMode from the main frame's OnCreate function. When a frame
window is being switched to full-screen mode, the framework creates a floating toolbar with one button that has
the specified command ID.If you want to keep the main menu on the screen, call
CMDIFrameWndEx::EnableFullScreenMainMenu.

CMDIFrameWndEx::EnableLoadDockState
Enables or disables the loading of the docking state.

void EnableLoadDockState(BOOL bEnable = TRUE);

Parameters
bEnable
[in] TRUE to enable the loading of the docking state, FALSE to disable the loading of the docking state.
Remarks

CMDIFrameWndEx::EnableMDITabbedGroups
Enables or disables the MDI tabbed groups feature for the frame window.

void EnableMDITabbedGroups(
BOOL bEnable,
const CMDITabInfo& params);

Parameters
bEnable
[in] If TRUE, the MDI tabbed groups feature is enabled; if FALSE, the MDI tabbed groups feature is disabled.
params
[in] Specifies parameters that the framework applies to child windows that are created in the MDI client area.
Remarks
Use this method to enable or disable the MDI tabbed groups feature. This feature enables MDI applications to
display child windows as tabbed windows that are aligned vertically or horizontally within the MDI client area.
Groups of tabbed windows are separated by splitters. The user can resize tabbed groups by using a splitter.
The user can:
Drag individual tabs between groups.
Drag individual tabs to the edge of the window to create new groups.
Move tabs or create new groups by using a shortcut menu.
Your application can save the current layout of tabbed windows and the list of currently opened
documents.
If you call this method with bEnable set to FALSE, params is ignored.
Even if MDI tabbed groups is already enabled, you can call this method again to modify the settings for child
windows. Call the method with bEnable set to TRUE and modify the members of the CMDITabInfo object that are
specified by the params parameter.
For more information about how to use MDI tabbed groups, see MDI Tabbed Groups.
Example
The following example shows how EnableMDITabbedGroups is used in the VisualStudioDemo Sample: MFC Visual
Studio Application.

CMDITabInfo mdiTabParams;
mdiTabParams.m_bTabCustomTooltips = TRUE;

if (bMDITabsVS2005Look)
{
mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_VS2005;
mdiTabParams.m_bDocumentMenu = TRUE;
}
else if (bOneNoteTabs)
{
mdiTabParams.m_style = CMFCTabCtrl::STYLE_3D_ONENOTE;
mdiTabParams.m_bAutoColor = bMDITabColors;
}

if (bActiveTabCloseButton)
{
mdiTabParams.m_bTabCloseButton = FALSE;
mdiTabParams.m_bActiveTabCloseButton = TRUE;
}

EnableMDITabbedGroups(TRUE, mdiTabParams);

CMDIFrameWndEx::EnableMDITabs
Enables or disables the MDI Tabs feature for the MDI frame window. When enabled, the frame window displays a
tab for each MDI child window.

void EnableMDITabs(
BOOL bEnable=TRUE,
BOOL bIcons=TRUE,
CMFCTabCtrl::Location tabLocation=CMFCTabCtrl::LOCATION_BOTTOM,
BOOL bTabCloseButton=FALSE,
CMFCTabCtrl::Style style=CMFCTabCtrl::STYLE_3D_SCROLLED,
BOOL bTabCustomTooltips=FALSE,
BOOL bActiveTabCloseButton=FALSE);

Parameters
bEnable
Specifies whether tabs are enabled.
bIcons
Specifies whether icons should be displayed on the tabs.
tabLocation
Specifies the location of the tab labels.
bTabCloseButton
Specifies whether to display tab close buttons.
style
Specifies the style of tabs. Use STYLE_3D_SCROLLED for regular tabs or STYLE_3D_ONENOTE for Microsoft
OneNote tabs.
bTabCustomTooltips
Specifies whether custom tooltips are enabled.
bActiveTabCloseButton
If TRUE, a Close button will be displayed on the active tab instead of on the right corner of the tab area.
Remarks
Call this method to enable or disable the MDI tabs feature for the MDI frame window. When enabled, all child
windows are displayed as tabs.
The tab labels can be located at the top or bottom of the frame, depending on the setting of the parameter
tabLocation. You may specify either CMFCTabCtrl::LOCATION_BOTTOM (the default setting) or
CMFCTabCtrl::LOCATION_TOP .

If bTabCustomTooltips is TRUE, an AFX_WM_ON_GET_TAB_TOOLTIP message will be sent to the main frame


window. Your code can handle this message and provide the framework with custom tooltips for MDI tabs.
Example
The following example shows how EnableMDITabs is used in the MDITabsDemo Sample: MFC Tabbed MDI
Application.
void CMainFrame::UpdateMDITabs(BOOL bResetMDIChild)
{
CMDITabInfo params;
HWND hwndActive = NULL;

switch (theApp.m_Options.m_nMDITabsType)
{
case CMDITabOptions::None:
{
BOOL bCascadeMDIChild = FALSE;

if (IsMDITabbedGroup())
{
EnableMDITabbedGroups(FALSE, params);
bCascadeMDIChild = TRUE;
}
else if (AreMDITabs())
{
EnableMDITabs(FALSE);
bCascadeMDIChild = TRUE;
}

if (bCascadeMDIChild)
{
// CMDIClientAreaWnd m_wndClientArea
hwndActive = (HWND)m_wndClientArea.SendMessage(WM_MDIGETACTIVE);
m_wndClientArea.PostMessage(WM_MDICASCADE);
m_wndClientArea.UpdateTabs(false);
m_wndClientArea.SetActiveTab(hwndActive);
::BringWindowToTop(hwndActive);
}
}
break;

case CMDITabOptions::MDITabsStandard:
hwndActive = (HWND)m_wndClientArea.SendMessage(WM_MDIGETACTIVE);
m_wndClientArea.PostMessage(WM_MDIMAXIMIZE, LPARAM(hwndActive), 0L);
::BringWindowToTop(hwndActive);

EnableMDITabs(TRUE, theApp.m_Options.m_bMDITabsIcons, theApp.m_Options.m_bTabsOnTop ?


CMFCTabCtrl::LOCATION_TOP : CMFCTabCtrl::LOCATION_BOTTOM, theApp.m_Options.m_nTabsStyle);

GetMDITabs().EnableAutoColor(theApp.m_Options.m_bTabsAutoColor);
GetMDITabs().EnableTabDocumentsMenu(theApp.m_Options.m_bMDITabsDocMenu);
GetMDITabs().EnableTabSwap(theApp.m_Options.m_bDragMDITabs);
GetMDITabs().SetTabBorderSize(theApp.m_Options.m_nMDITabsBorderSize);
GetMDITabs().SetFlatFrame(theApp.m_Options.m_bFlatFrame);
GetMDITabs().EnableCustomToolTips(theApp.m_Options.m_bCustomTooltips);
GetMDITabs().EnableCustomToolTips(theApp.m_Options.m_bCustomTooltips);
GetMDITabs().EnableActiveTabCloseButton(theApp.m_Options.m_bActiveTabCloseButton);
break;

CMDIFrameWndEx::EnableMDITabsLastActiveActivation
Specifies whether the last active tab should be opened when the user closes the current tab.

void EnableMDITabsLastActiveActivation(BOOL bLastActiveTab=TRUE);

Parameters
bLastActiveTab
[in] If TRUE, enable activation of the last active tab. If FALSE, disable activation of the last active tab.
Remarks
There are two ways to open a tab when the active tab is closed:
Activate the next tab.
Activate the previously active tab.
The default implementation uses the first way.
Use EnableMDITabsLastActiveActivation to enable the second way of tab activation. It emulates the way Windows
opens MDI child windows.

CMDIFrameWndEx::EnablePaneMenu
Enables or disables automatic creation and management of the pop-up pane menu, which displays a list of
application panes.

void EnablePaneMenu(
BOOL bEnable,
UINT uiCustomizeCmd,
const CString& strCustomizeLabel,
UINT uiViewToolbarsMenuEntryID,
BOOL bContextMenuShowsToolbarsOnly=FALSE,
BOOL bViewMenuShowsToolbarsOnly=FALSE);

Parameters
bEnable
[in] If TRUE, automatic handling of the pane menu is enabled; if FALSE, automatic handling is disabled.
uiCustomizeCmd
[in] Command ID of the Customize menu item. This menu item is usually added to the end of the list of panes.
strCustomizeLabel
[in] The text to be displayed for the Customize menu item (for localization).
uiViewToolbarsMenuEntryID
[in] Specifies the ID of a toolbar menu item that opens the pane menu. Usually this is the Toolbars submenu of
the View menu.
bContextMenuShowsToolbarsOnly
[in] If TRUE, the pane menu displays only a list of toolbars. If FALSE, the menu displays a list of toolbars and
docking bars.
bViewMenuShowsToolbarsOnly
[in] If TRUE, the pane menu displays only a list of toolbars. If FALSE, the menu displays a list of toolbars and
docking bars.
Remarks
The pop-up pane menu displays the list of the application's panes and lets the user show or hide individual
panes.
Example
The following example shows how EnablePaneMenu is used in the VisualStudioDemo Sample: MFC Visual Studio
Application.

// Enable pane context menu(list of bars + customize command):


EnablePaneMenu(TRUE, ID_VIEW_CUSTOMIZE, _T("Customize..."), ID_VIEW_TOOLBARS, FALSE, TRUE);
CMDIFrameWndEx::EnableWindowsDialog
Inserts a menu item whose command ID calls a CMFCWindowsManagerDialog dialog box.

void EnableWindowsDialog(
UINT uiMenuId,
LPCTSTR lpszMenuText,
BOOL bShowAllways=FALSE,
BOOL bShowHelpButton=FALSE);

void EnableWindowsDialog(
UINT uiMenuId,
UINT uiMenuTextResId,
BOOL bShowAllways=FALSE,
BOOL bShowHelpButton=FALSE);

Parameters
uiMenuId
[in] Specifies the resource ID of a menu.
lpszMenuText
[in] Specifies the item's text.
bShowHelpButton
[in] Specifies whether to display a Help button on the windows management dialog box.
uiMenuTextResId
[in] The string resource identifier that contains the item's text string.
Remarks
Use this method to insert a menu item whose command calls a MDI child window management dialog box (
CMFCWindowsManagerDialog Class). The new item is inserted into the menu specified by uiMenuId. Call
EnableWindowsDialog when you process the WM_CREATE message.

Example
The following example shows how EnableWindowsDialog is used in the VisualStudioDemo Sample: MFC Visual
Studio Application.

// Enable windows manager:


EnableWindowsDialog(ID_WINDOW_MANAGER, _T("Windows..."), TRUE);

CMDIFrameWndEx::GetActivePopup
Returns a pointer to the currently displayed popup menu.

CMFCPopupMenu* GetActivePopup() const;

Return Value
A pointer to the active popup menu; NULL if no popup menu is active.
Remarks
Use this function to obtain a pointer to the CMFCPopupMenu Class object that is currently displayed.

CMDIFrameWndEx::GetDefaultResId
Returns the ID of shared resources of the MDI frame window.

UINT GetDefaultResId() const;

Return Value
A resource ID value. 0 if the frame window has no menu bar.
Remarks
This method returns the resource ID that was specified when the MDI frame window was loaded by
CFrameWnd::LoadFrame.

CMDIFrameWndEx::GetMDITabGroups
Returns a list of MDI tabbed windows.

const CObList& GetMDITabGroups() const;

Return Value
A reference to a CObList Class object that contains a list of tabbed windows. Do not store or modify the list.
Remarks
Use this method to access the list of tabbed windows. It can be helpful if you want to change or query some
parameters of individual tabbed windows.

CMDIFrameWndEx::GetMDITabs
Returns a reference to the underlined tabbed window.

CMFCTabCtrl& GetMDITabs();

Return Value
A reference to the underlined tabbed window.

CMDIFrameWndEx::GetMDITabsContextMenuAllowedItems
Returns a combination of flags that determines what operations are valid when the MDI Tabbed Groups feature
is enabled.

DWORD GetMDITabsContextMenuAllowedItems();

Return Value
A bitwise-OR combination of the following flags:
BCGP_MDI_CREATE_VERT_GROUP - can create a vertical tab group.
BCGP_MDI_CREATE_HORZ_GROUP - can create a horizontal tab group.
BCGP_MDI_CAN_MOVE_PREV - can move a tab to the previous tab group.
BCGP_MDI_CAN_MOVE_NEXT - can move a tab to the next tab group.
Remarks
When the MDI Tabbed Groups feature is enabled, you must know what operations are allowed on the tabs of a
particular window. This method analyzes the current layout of tabbed windows and returns a combination of
flags that can be used to build, for example, a shortcut menu.
You can create a new vertical tab group when all tabbed windows are aligned vertically, or when there is only
one tabbed window.
You can create a new horizontal tab group when all tabbed windows are aligned horizontally, or when there is
only one tabbed window.
You can move a tab to the previous group only if there is more than one tab in a tabbed window.
You can move a tab to the next group only if there is more than one tab in a tabbed window.

CMDIFrameWndEx::GetMenuBar
Returns a pointer to a menu bar object attached to the frame window.

const CMFCMenuBar* GetMenuBar() const;

Return Value
A pointer to a menu bar object.

CMDIFrameWndEx::GetPane
Returns a pointer to the pane that has the specified control ID.

CBasePane* GetPane(UINT nID);

Parameters
nID
[in] The control ID.
Return Value
A pointer to the pane that has the specified control ID, if it exists. Otherwise, NULL.

CMDIFrameWndEx::GetRibbonBar
Retrieves the ribbon bar control for the frame.

CMFCRibbonBar* GetRibbonBar();

Return Value
Pointer to the CMFCRibbonBar Class for the frame.
Remarks

CMDIFrameWndEx::GetTearOffBars
Returns a list of tear-off menus.

const CObList& GetTearOffBars() const;


Return Value
A reference to a CObList Class object that contains a collection of pointers to CPane -derived objects that are in a
tear-off state.
Remarks
CMDIFrameWndEx maintains a collection of tear-off menus. Use this method to retrieve a reference to this list.

CMDIFrameWndEx::GetToolbarButtonToolTipText
Called by the framework when the application displays the tooltip for a toolbar button.

virtual BOOL GetToolbarButtonToolTipText(


CMFCToolBarButton* pButton,
CString& strTTText);

Parameters
pButton
[in] A pointer to a toolbar button.
strTTText
[in] The tooltip text to display for the button.
Return Value
TRUE if the tooltip has been displayed. FALSE otherwise.
Remarks

CMDIFrameWndEx::InsertPane
Registers the specified pane with the docking manager.

BOOL InsertPane(
CBasePane* pControlBar,
CBasePane* pTarget,
BOOL bAfter=TRUE);

Parameters
pControlBar
[in] A pointer to the pane to be inserted.
pTarget
[in] A pointer to the pane before or after which to insert the pane.
bAfter
[in] If TRUE, pControlBar is inserted after pTarget. If FALSE, pControlBar is inserted before pTarget.
Return Value
TRUE if the method successfully registers the pane, FALSE if the pane was already registered with the docking
manager.
Remarks
Use this method to tell the docking manager about a pane specified by pControlBar. The docking manager will
align this pane according to the pane's alignment and position in the docking manager's internal list.
CMDIFrameWndEx::IsFullScreen
Determines whether the frame window is in full-screen mode.

BOOL IsFullScreen() const;

Return Value
TRUE if the frame window is in full screen mode; otherwise FALSE.
Remarks
You can set the full screen mode by calling the CMDIFrameWndEx::EnableFullScreenMode method.

CMDIFrameWndEx::IsMDITabbedGroup
Specifies whether the MDI Tabbed Groups feature is enabled.

BOOL IsMDITabbedGroup() const;

Return Value
TRUE if the MDI Tabbed Groups feature is enabled; otherwise FALSE.
Remarks
To determine whether regular MDI tabs or the MDI Tabbed Groups feature is enabled, use
CMDIFrameWndEx::AreMDITabs.

CMDIFrameWndEx::IsMemberOfMDITabGroup
Determines whether the specified tabbed window is in the list of windows that are in MDI Tabbed Groups.

BOOL IsMemberOfMDITabGroup(CWnd* pWnd);

Parameters
pWnd
[in] A pointer to tabbed window.
Return Value
TRUE if the specified tabbed window is in the list of tabbed windows that form MDI Tabbed Groups. Otherwise
FALSE.

CMDIFrameWndEx::IsMenuBarAvailable
Determines whether the frame window has a menu bar.

BOOL IsMenuBarAvailable() const;

Return Value
TRUE if the pointer to the menu bar object is not NULL; otherwise FALSE.

CMDIFrameWndEx::IsPointNearDockSite
Determines whether a specified point is near the dock site.
BOOL IsPointNearDockSite(
CPoint point,
DWORD& dwBarAlignment,
BOOL& bOuterEdge) const;

Parameters
point
[in] The specified point in screen coordinates.
dwBarAlignment
[in] Specifies which edge the point is near. Possible values are CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT,
CBRS_ALIGN_TOP, and CBRS_ALIGN_BOTTOM
bOuterEdge
[in] TRUE if the point is near the outer border of the dock site; FALSE otherwise.
Return Value
TRUE if the point is near the dock site; otherwise FALSE.
Remarks
The point is near the dock site when it is within the sensitivity set in the docking manager. The default sensitivity
is 15 pixels.

CMDIFrameWndEx::IsPrintPreview
Determines whether the frame window is in print-preview mode.

BOOL IsPrintPreview();

Return Value
TRUE if the frame window is in print-preview mode; otherwise, FALSE.
Remarks

CMDIFrameWndEx::LoadFrame
Creates a frame window from resource information.

virtual BOOL LoadFrame(


UINT nIDResource,
DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
CWnd* pParentWnd = NULL,
CCreateContext* pContext = NULL);

Parameters
nIDResource
[in] The ID of a shared resource associated with the frame window.
dwDefaultStyle
[in] The style of the frame window.
pParentWnd
[in] A pointer to the frame's parent.
pContext
[in] A pointer to a CCreateContext Structure. This parameter can be NULL.
Return Value
TRUE if the method succeeds, otherwise FALSE.

CMDIFrameWndEx::LoadMDIState
Loads the specified layout of MDI Tabbed Groups and the list of previously opened documents.

virtual BOOL LoadMDIState(LPCTSTR lpszProfileName);

Parameters
lpszProfileName
[in] Specifies the profile name.
Return Value
TRUE if the load succeeded; FALSE if the load failed or there is no data to load.
Remarks
To load or save the state of MDI tabs and groups and the list of opened documents, do the following:
Call CMDIFrameWndEx::SaveMDIState when the main frame is being closed
Call CMDIFrameWndEx::LoadMDIState when the main frame is being created. The recommended place for
this call is before the main frame is displayed for the first time. Add CWinAppEx::EnableLoadWindowPlacement
(FALSE); before pMainFrame->LoadFrame (IDR_MAINFRAME);. Add CBCGPWorkspace::ReloadWindowPlacement
(pMainFrame); after the call to LoadMDIState to display the main frame at the position that was stored in
the registry.
Override GetDocumentName in the CMDIChildWndEx - derived class if your application displays documents
that are not stored as files. The returned string will be saved in the registry as the document identifier. The
base implementation of CMDIChildWndEx::GetDocumentName returns a value obtained from
CDocument::GetPathName.
Override CMDIFrameWndEx::CreateDocumentWindow to correctly create documents when they are
being loaded from the registry. The first parameter is the string that GetDocumentName returned.
Example
The following example shows how LoadMDIState is used in the VisualStudioDemo Sample: MFC Visual Studio
Application.
// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);

if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
{
if (!pMainFrame->LoadMDIState(GetRegSectionPath()))
{
m_pStartDocTemplate->OpenDocumentFile(NULL);
}
}
else
{
// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
{
return FALSE;
}
}

CMDIFrameWndEx::MDITabMoveToNextGroup
Moves the active tab from the currently active tabbed window to the next or previous tabbed group.

void MDITabMoveToNextGroup(BOOL bNext=TRUE);

Parameters
bNext
[in] If TRUE, move the tab to the next tabbed group. If FALSE, move it to the previous tabbed group.

CMDIFrameWndEx::MDITabNewGroup
Creates a new tabbed group that has a single window.

void MDITabNewGroup(BOOL bVert=TRUE);

Parameters
bVert
[in] Specifies the new group alignment. If TRUE, the new group is aligned vertically. If FALSE, the new group is
aligned horizontally.
Remarks
Use this function to create a new tabbed window (new tabbed group) and add the first tab to it.
Example
The following example shows how MDITabNewGroup is used in the VisualStudioDemo Sample: MFC Visual Studio
Application.

void CMainFrame::OnMdiNewHorzTabGroup()
{
MDITabNewGroup(FALSE);
}

CMDIFrameWndEx::m_bCanCovertControlBarToMDIChild
Specifies whether docking panes can be converted to MDI child windows.

BOOL m_bCanCovertControlBarToMDIChild;

Remarks
Indicates whether docking control bars can be converted to MDI child windows. If this flag is TRUE, the
framework handles the conversion automatically when the user selects the Tabbed Document command. The
flag is protected and you must explicitly enable this option either by setting m_bCanCovertControlBarToMDIChild in
a constructor of a CMDIFrameWndEx -derived class, or by overriding CanConvertControlBarToMDIChild .
The default value is FALSE .
Example
The following example shows how m_bCanCovertControlBarToMDIChild is used in the VisualStudioDemo Sample:
MFC Visual Studio Application.

CMainFrame::CMainFrame()
{
CMFCPopupMenu::SetForceShadow(TRUE);
m_bCanConvertControlBarToMDIChild = TRUE;
}

CMDIFrameWndEx::m_bDisableSetRedraw
Enables or disables redraw optimization for MDI child windows.

AFX_IMPORT_DATA static BOOL m_bDisableSetRedraw;

Remarks
The default value is TRUE.
Set this flag to FALSE if you want to optimize redrawing of MDI children. In this case the framework will call
SetRedraw (FALSE) for the main frame when the application is changing the active tab.

This flag can cause unwanted effects (such as background applications that become visible). Therefore we
recommend that you change the default only if you experience noticeable flickering during MDI tab activation.

CMDIFrameWndEx::NegotiateBorderSpace
Negotiates border space in a frame window during OLE in-place activation.

virtual BOOL NegotiateBorderSpace(


UINT nBorderCmd,
LPRECT lpRectBorder);

Parameters
nBorderCmd
[in] Contains one of the following values from the enum CFrameWnd::BorderCmd :
borderGet =1
borderRequest =2
borderSet =3
lpRectBorder
[in, out] Pointer to a RECT Structure or a CRect Class object that specifies the coordinates of the border.
Return Value
Nonzero if the method was successful; otherwise 0.
Remarks
This method is an implementation of OLE border space negotiation.

CMDIFrameWndEx::OnCloseDockingPane
Called by the framework when the user clicks the Close button on a dockable pane.

virtual BOOL OnCloseDockingPane(CDockablePane* pWnd);

Parameters
pWnd
[in] Pointer to the pane being closed.
Return Value
TRUE if the docking pane can be closed. Otherwise, FALSE.
Remarks
Override this method to handle hiding of docking panes. Return FALSE if you want to prevent a docking pane
from being hidden.
The default implementation does nothing and returns TRUE.

CMDIFrameWndEx::OnCloseMiniFrame
Called by the framework when the user clicks the Close button on a floating mini-frame window.

virtual BOOL OnCloseMiniFrame(CPaneFrameWnd*);

Parameters
pWnd
[in] Pointer to the mini-frame window being closed.
Return Value
TRUE if the floating mini-frame window can be closed. Otherwise, FALSE.
Remarks
Override this method to handle hiding of floating mini-frame windows. Return FALSE if you want to prevent a
floating mini-frame window from being hidden.
The default implementation does nothing and returns TRUE.

CMDIFrameWndEx::OnClosePopupMenu
Called by the framework when an active pop-up menu processes a WM_DESTROY message.
virtual void OnClosePopupMenu(CMFCPopupMenu* pMenuPopup);

Parameters
pMenuPopup
[in] Pointer to a pop-up menu.
Remarks
Override this method if you want to process notifications from CMFCPopupMenu Class objects that belong to
the MDI frame window when those objects process WM_DESTROY messages.

CMDIFrameWndEx::OnCmdMsg
Called by the framework to route and dispatch command messages and to update command user-interface
objects.

virtual BOOL OnCmdMsg(


UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);

Parameters
nID
[in] The command ID.
nCode
[in] Identifies the command notification code. See CCmdTarget::OnCmdMsg for more information about values
for nCode.
pExtra
[in] Used according to the value of nCode. See CCmdTarget::OnCmdMsg for more information about pExtra.
pHandlerInfo
[in, out] Typically, this parameter should be NULL.If not NULL, OnCmdMsg fills in the pTarget and pmf members
of the pHandlerInfo structure instead of dispatching the command.
Return Value
Nonzero if the message is handled; otherwise 0.

CMDIFrameWndEx::OnDrawMenuImage
Called by the framework when the image associated with a menu item is drawn.

virtual BOOL OnDrawMenuImage(


CDC* pDC,
const CMFCToolBarMenuButton* pMenuButton,
const CRect& rectImage);

Parameters
pDC
[in] Pointer to a device context.
pMenuButton
[in] Pointer to the menu button.
rectImage
[in] Bounding rectangle of the image.
Return Value
TRUE if the method draws the image. The default implementation returns FALSE.
Remarks
Override this method if you want to customize image rendering for the menu items that belong to the menu bar
owned by the CMDIFrameWndEx -derived object. The default implementation does nothing.

CMDIFrameWndEx::OnDrawMenuLogo
Called by the framework when a CMFCPopupMenuprocesses a WM_PAINT message.

virtual void OnDrawMenuLogo(


CDC*,
CMFCPopupMenu*,
const CRect&);

Remarks
Override this function to display a logo on the pop-up menu that belongs to the menu bar owned by the
CMDIFrameWndEx -derived object. The default implementation does nothing.

CMDIFrameWndEx::OnEraseMDIClientBackground
Called by the framework when the MDI frame window processes a WM_ERASEBKGND message.

virtual BOOL OnEraseMDIClientBackground(CDC*);

Return Value
TRUE if the application processes the message and erases the background.
Remarks
Override this member function if you want to process the WM_ERASEBKGND message in a CMDIFrameWndEx -
derived class.

CMDIFrameWndEx::OnMenuButtonToolHitTest
Called by the framework when a CMFCToolBarButtonobject processes a WM_NCHITTEST message.

virtual BOOL OnMenuButtonToolHitTest(


CMFCToolBarButton* pButton,
TOOLINFO* pTI);

Parameters
pButton
[in] The toolbar button.
pTI
[out] Pointer to a TOOLINFO structure.
Return Value
TRUE if the application fills the pTI parameter. The default implementation returns FALSE.
Remarks
Override this method if you want to provide information about specific menu items to a tooltip. The default
implementation does nothing.

CMDIFrameWndEx::OnMoveMiniFrame
Called by the framework to move a mini-frame window.

virtual BOOL OnMoveMiniFrame(CWnd* pFrame);

Parameters
pFrame
[in] A pointer to a mini-frame window.
Return Value
TRUE if the method succeeds, otherwise FALSE.

CMDIFrameWndEx::OnSetPreviewMode
Sets the application's main frame window print-preview mode.

virtual void OnSetPreviewMode(


BOOL bPreview,
CPrintPreviewState* pState);

Parameters
bPreview
[in] If TRUE, sets print-preview mode. If FALSE, cancels preview mode.
pState
[in] A pointer to a CPrintPreviewState structure.
Remarks
This method overrides CFrameWnd::OnSetPreviewMode.

CMDIFrameWndEx::OnShowCustomizePane
Called by the framework when a Quick Customize pane is activated.

virtual BOOL OnShowCustomizePane(


CMFCPopupMenu* pMenuPane,
UINT uiToolbarID);

Parameters
pMenuPane
[in] A pointer to the Quick Customize pane.
uiToolbarID
[in] Control ID of the toolbar to customize.
Return Value
This method always returns TRUE.
Remarks
The Quick Customize pane is a menu that opens when the user clicks Customize on a toolbar.
Override this method in a derived class to make changes in the Quick Customize pane.

CMDIFrameWndEx::OnShowMDITabContextMenu
Called by the framework before a shortcut menu is displayed on one of the tabs. Valid for MDI Tabbed Groups
only.

virtual BOOL OnShowMDITabContextMenu(


CPoint point,
DWORD dwAllowedItems,
BOOL bTabDrop);

Parameters
point
[in] The location of the menu in screen coordinates.
dwAllowedItems
[in] A bitwise-OR combination of flags that indicates what actions are allowed for the current tab:
BCGP_MDI_CREATE_VERT_GROUP - can create a vertical tab group.
BCGP_MDI_CREATE_HORZ_GROUP - can create a horizontal tab group.
BCGP_MDI_CAN_MOVE_PREV - can move a tab to the previous tab group.
BCGP_MDI_CAN_MOVE_NEXT - can move a tab to the next tab group.
BCGP_MDI_CAN_BE_DOCKED - switch a tabbed document to docked state (relevant for tabbed
documents only).
bTabDrop
[in] TRUE to display the menu as a result of dragging the tab onto another tabbed group. FALSE to display the
menu as a shortcut menu on the currently active tab.
Return Value
Override this method in a CBCGPMDIFrameWnd-derived class.
Remarks
If you do not process OnShowMDITabContextMenu , the shortcut menu will not be displayed. This function is
generated by the MFC Application Wizard when you enable the MDI Tabbed Groups feature.
Example
The following example shows how OnShowMDITabContextMenu is used in the VisualStudioDemo Sample: MFC
Visual Studio Application.
BOOL CMainFrame::OnShowMDITabContextMenu(CPoint point, DWORD dwAllowedItems, BOOL bDrop)
{
CMenu menu;
VERIFY(menu.LoadMenu(bDrop ? IDR_POPUP_DROP_MDITABS : IDR_POPUP_MDITABS));

CMenu* pPopup = menu.GetSubMenu(0);


ASSERT(pPopup != NULL);

if ((dwAllowedItems & AFX_MDI_CREATE_HORZ_GROUP) == 0)


{
pPopup->DeleteMenu(ID_MDI_NEW_HORZ_TAB_GROUP, MF_BYCOMMAND);
}

if ((dwAllowedItems & AFX_MDI_CREATE_VERT_GROUP) == 0)


{
pPopup->DeleteMenu(ID_MDI_NEW_VERT_GROUP, MF_BYCOMMAND);
}

if ((dwAllowedItems & AFX_MDI_CAN_MOVE_NEXT) == 0)


{
pPopup->DeleteMenu(ID_MDI_MOVE_TO_NEXT_GROUP, MF_BYCOMMAND);
}

if ((dwAllowedItems & AFX_MDI_CAN_MOVE_PREV) == 0)


{
pPopup->DeleteMenu(ID_MDI_MOVE_TO_PREV_GROUP, MF_BYCOMMAND);
}

if ((dwAllowedItems & AFX_MDI_CAN_BE_DOCKED) == 0)


{
pPopup->DeleteMenu(ID_MDI_TABBED_DOCUMENT, MF_BYCOMMAND);
}

CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu;


pPopupMenu->SetAutoDestroy(FALSE);
pPopupMenu->Create(this, point.x, point.y, pPopup->GetSafeHmenu());

return TRUE;
}

CMDIFrameWndEx::OnShowPanes
Called by the framework to show or hide panes.

virtual BOOL OnShowPanes(BOOL bShow);

Parameters
bShow
[in] TRUE to show panes, FALSE to hide panes.
Return Value
TRUE if the state of the panes changes as a result of calling this method, FALSE if the panes are already in the
state specified by bShow . For example, if the panes are hidden and bShow is FALSE, the return value is FALSE.
Remarks
The default implementation removes the toolbar from the top-level frame window.
If CDockingManager::m_bHideDockingBarsInContainerMode is TRUE (the default), all docking panes will be
hidden.
CMDIFrameWndEx::OnShowPopupMenu
Called by the framework when it opens a pop-up menu.

virtual BOOL OnShowPopupMenu(CMFCPopupMenu*);

Return Value
TRUE if the pop-up menu is to be displayed. Otherwise, FALSE. The default implementation returns TRUE.
Remarks
Override this method if you want to implement special processing upon pop-up menu activation. For example, if
you want to change regular menu items to color menu buttons, set up tear-off bars, and so on.
The default implementation does nothing.

CMDIFrameWndEx::OnSizeMDIClient
Called by the framework when the size of the client MDI window is changing.

virtual void OnSizeMDIClient(


const CRect& rectOld,
const CRect& rectNew);

Parameters
rectOld
[in] The current size of the MDI client window.
rectNew
[in] The new size of the MDI client window.
Remarks

CMDIFrameWndEx::OnTearOffMenu
Called by the framework when a menu that has a tear-off bar is activated.

virtual BOOL OnTearOffMenu(


CMFCPopupMenu* pMenuPopup,
CPane* pBar);

Parameters
pMenuPopup
[in] A pointer to the pop-up menu.
pBar
[in] A pointer to the tear-off bar.
Return Value
TRUE to allow the pop-up menu with the tear-off bar to be made activate; otherwise FALSE. The default is TRUE.
Remarks
Override this function when you want to implement a special setup for the tear-off bar. The default
implementation does nothing.
CMDIFrameWndEx::OnUpdateFrameMenu
Called by the framework to update the frame menu.

virtual void OnUpdateFrameMenu(HMENU hMenuAlt);

Parameters
hMenuAlt
[in] A handle to a menu.

CMDIFrameWndEx::PaneFromPoint
Returns the docking pane that contains the specified point.

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
bool bExactBar,
CRuntimeClass* pRTCBarType) const;

CBasePane* PaneFromPoint(
CPoint point,
int nSensitivity,
DWORD& dwAlignment,
CRuntimeClass* pRTCBarType) const;

Parameters
point
[in] The point (in screen coordinates).
nSensitivity
[in] The window rectangle of each checked pane is enlarged in all directions by this value.
bExactBar
[in] If TRUE, the nSensitivity parameter is ignored.
pRTCBarType
[in] If non- NULL, the method iterates over only the panes of the specified type.
dwAlignment
[out] If a pane is found, this parameter will specify which side of the pane is closest to the specified point.
Return Value
A pointer to a docking pane, or NULL if no control contains the point specified by point.
Remarks
The call is redirected to the CDockingManager Class. See CDockingManager::ControlBarFromPoint for more
information.

CMDIFrameWndEx::RecalcLayout
Called by the framework to recalculate the layout of the frame window.

virtual void RecalcLayout(BOOL bNotify = TRUE);


Parameters
bNotify
[in] Determines whether the active in-place item for the frame window receives notification of the layout change.
If TRUE, the item is notified; otherwise FALSE.
Remarks
This method overrides CFrameWnd::RecalcLayout.

CMDIFrameWndEx::RemovePaneFromDockManager
Unregisters a pane and removes it from the docking manager.

void RemovePaneFromDockManager(
CBasePane* pControlBar,
BOOL bDestroy,
BOOL bAdjustLayout,
BOOL bAutoHide,
CBasePane* pBarReplacement);

Parameters
pControlBar
[in] A pointer to a pane to be removed.
bDestroy
[in] TRUE to destroy the removed pane. FALSE to not destroy it.
bAdjustLayout
[in] TRUE to adjust the docking layout immediately. If FALSE, the adjustment will occur only when a redraw event
occurs for other reasons (the user resizes the window, drags the main frame, etc.).
bAutoHide
[in] TRUE to remove the pane from the list of autohide panes. FALSE to remove the pane from the list of regular
panes.
pBarReplacement
[in] A pointer to a pane that replaces the removed pane.
Remarks
You must register each pane with the docking manager to take part in the docking layout. Use
CMDIFrameWndEx::AddPane or CMDIFrameWndEx::InsertPane to register panes.
Use this method when a pane is no longer a part of the docking layout of the frame window.

CMDIFrameWndEx::SaveMDIState
Saves the current layout of MDI Tabbed Groups and the list of previously opened documents.

virtual BOOL SaveMDIState(LPCTSTR lpszProfileName);

Parameters
lpszProfileName
[in] Specifies the profile name.
Return Value
TRUE if the save succeeded; FALSE if the save failed.
Remarks
To load or save the state of MDI tabs and groups and the list of opened documents, do the following:
Call SaveMDIState when the main frame is being closed
Call CMDIFrameWndEx::LoadMDIState when the main frame is being created. The recommended location
for this call is before the main frame is displayed for the first time.
Call CWinAppEx::EnableLoadWindowPlacement(FALSE); before pMainFrame->LoadFrame (IDR_MAINFRAME);

Call CWinAppEx::ReloadWindowPlacement(pMainFrame) after LoadMDIState to display the main frame at the


position that was stored in the registry.
Override GetDocumentName in the CMDIChildWndEx - derived class if your application displays documents
that are not stored as files. The returned string will be saved in the registry as a document identifier. For
more information, see CMDIChildWndEx::GetDocumentName.
Override CMDIFrameWndEx::CreateDocumentWindow to correctly create documents when they are
loaded from the registry. The parameter to CreateDocumentWindow is the string that GetDocumentName
returned earlier.
Example
The following example shows how SaveMDIState is used in the VisualStudioDemo Sample: MFC Visual Studio
Application.

void CMainFrame::OnClose()
{
SaveMDIState(theApp.GetRegSectionPath());
CMDIFrameWndEx::OnClose();
}

CMDIFrameWndEx::SetPrintPreviewFrame
Sets the print preview frame window.

void SetPrintPreviewFrame(CFrameWnd* pWnd);

Parameters
pWnd
[in] Pointer to a print preview frame window.
Remarks

CMDIFrameWndEx::SetupToolbarMenu
Modifies a toolbar object by replacing dummy items with user-defined items.

void SetupToolbarMenu(
CMenu& menu,
const UINT uiViewUserToolbarCmdFirst,
const UINT uiViewUserToolbarCmdLast);

Parameters
menu
[in] A reference to a CMenu Class object to be modified.
uiViewUserToolbarCmdFirst
[in] Specifies the first user-defined command.
uiViewUserToolbarCmdLast
[in] Specifies the last user-defined command.

CMDIFrameWndEx::ShowFullScreen
Switches the main frame from regular mode to full-screen mode.

void ShowFullScreen();

Remarks

CMDIFrameWndEx::ShowPane
Shows or hides the specified pane.

void ShowPane(
CBasePane* pBar,
BOOL bShow,
BOOL bDelay,
BOOL bActivate);

Parameters
pBar
[in] Pointer to the pane to be shown or hidden.
bShow
[in] TRUE to show the pane. FALSE to hide the pane.
bDelay
[in] TRUE to delay the recalculation of the docking layout. FALSE to recalculate the docking layout immediately.
bActivate
[in] TRUE to show the pane should as active. FALSE to show the pane as inactive.
Remarks
Call this method to show or hide the pane. Do not use ShowWindow for docking panes.
Example
The following example shows how ShowPane is used in the VisualStudioDemo Sample: MFC Visual Studio
Application.

void COutputList1::OnViewOutput()
{
CBasePane* pParentBar = DYNAMIC_DOWNCAST(CBasePane, GetOwner());
CFrameWndEx* pMainFrame = DYNAMIC_DOWNCAST(CFrameWndEx, GetTopLevelFrame());

if (pMainFrame != NULL && pParentBar != NULL)


{
pMainFrame->SetFocus();
pMainFrame->ShowPane(pParentBar, FALSE, FALSE, FALSE);
}
}
CMDIFrameWndEx::ShowWindowsDialog
Creates a CMFCWindowsManagerDialog box and opens it.

void ShowWindowsDialog();

Example
The following example shows how ShowWindowsDialog is used in the VisualStudioDemo Sample: MFC Visual
Studio Application.

void CMainFrame::OnWindowManager()
{
ShowWindowsDialog();
}

CMDIFrameWndEx::TabbedDocumentToControlBar
Converts the specified tabbed document to a docking pane.

virtual BOOL Tabbe

Das könnte Ihnen auch gefallen