Your browser doesn't support JavaScript mfc Archives - Windows Programming

Common Controls

In addition to standard controls windows offers and extended set of child controls know as common Controls. In order to use these common controls, an application must include the header file afxcmn.h. The development environment must also link to the library comctl32.lib but this library is usually included when developing under a Microsoft environment. Applications utilising common control must call the function InitCommonControls() to ensure that the appropriate components are loaded and initialised.

For further reading

https://docs.microsoft.com/en-us/cpp/mfc/controls-mfc?view=msvc-170

Mapping Modes

The mapping mode governs how Windows translates logical coordinates into device coordinates within the current device context. Logical coordinates represent the graphics and text application values and the device coordinates are the resulting pixel positions within a window. The mapping mode also determines the orientation of the X-axis and the Y-axis and whether the values of X and Y increase or decrease with respect to the origin. The default device context sets logical units the same as pixels with the X axis being right positive, the Y axis being positive down, and sets the coordinate origin to the upper left corner of the window. Windows defines eight mapping modes. These are listed below

Mapping Mode Logical Unit x-axis and y-axis
MM_TEXT Pixel Positive x is to the right; positive y is down
MM_LOMETRIC 0.1 mm Positive x is to the right; positive y is up.
MM_HIMETRIC 0.01 mm Positive x is to the right; positive y is up.
MM_LOENGLISH 0.01 in Positive x is to the right; positive y is up.
MM_HIENGLISH 0.001 in Positive x is to the right; positive y is up.
MM_TWIPS 1/1440 in Positive x is to the right; positive y is up.
MM_ISOTROPIC user-specified user-specified
MM_ANISOTROPIC user-specified user-specified

To select a different mapping mode, use the CDC member function SetMapMode()

virtual int SetMapMode( int nMapMode );

where
nMapMode specifies the new mapping mode. The Return Value is the previous mapping mode.

Programmable Mapping Modes

The MM_ISOTROPIC and MM_ANISOTROPIC mapping modes differ from the other mapping modes in that the unit of measurement used to transform logical coordinates to device coordinates is user-defined. The MM_ISOTROPIC and MM_ANISOTROPIC mapping modes differ from each other in that with the former, the range of the x-axis and y-axis must be the same, and with the latter, the range of the x-axis and y-axis can be different. Selecting either of these modes means the developer will need to set the Window dimensions.

To set the logical extents of the window associated with the device context using the SetWindowExt() member function. To map the corresponding device size, known as the viewpoint onto these logical coordinates use the SetViewportExt() member function.

SetWindowExt

Sets the x- and y-extents of the window associated with the device context.

virtual CSize SetWindowExt( int cx, int cy ); virtual CSize SetWindowExt( SIZE size );

Parameters
cx – Specifies the Window x-extent (in logical units).
cy – Specifies the Window y-extent (in logical units).
size – Specifies the Windows x- and y-extents (in logical units).

Returns the previous extents of the window as a CSize object. If an error occurs, the x- and y-coordinates of the returned CSize object are set to 0.

SetViewportExt

Sets the x- and y-extents of the viewport of the device context.

virtual CSize SetViewportExt( int cx, int cy ); virtual 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).

Returns the previous extent of the viewport as a CSize object. When an error occurs, the x- and y-coordinates of the returned CSize object are set to 0.

For example, if SetViewportExt is called with parameters 100,50 and SetWindowExt is called with parameters 100,100 this will mean that each logical unit in the X direction will equate to 1 device unit and each logical unit in the y direction will equate to 1/2 a unit in the device coordinate.

Moving the Origin

By default, a device context’s origin, regardless of the mapping mode is in the upper left corner of the display. The device context origin can be changed by the CDC member functions SetWindowOrg() and SetViewportOrg() . The former moves the windows origin, and the latter, the viewport origin. The prototype for these functions are

CPoint SetWindowOrg( int x, int y ); CPoint SetWindowOrg( POINT point );

And

virtual CPoint SetViewportOrg( int x, int y ); virtual CPoint SetViewportOrg( POINT point );

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

Returns the previous origin or viewport of the window as a CPoint object

Example

The following short program draws 5 squares under different mapping to illustrate the different display characteristics of each

Download Code

MFC Data Handling

MFC Collections classes

The MFC library provides a rich series of collection classes aimed at providing an easy and safe way to manage dynamic data. The MFC library collection classes are divided into two categories: template-based and non-template classes.

The template classes

CArray – Supports arrays that can dynamically reduce and grow as necessary.
For further detailed reading – https://docs.microsoft.com/en-us/cpp/mfc/reference/carray-class?view=vs-2019

CList – supports ordered lists of nonunique objects accessible sequentially or by value.
https://docs.microsoft.com/en-us/cpp/mfc/reference/clist-class?view=vs-2019

CMap – is a dictionary collection class that maps unique keys to values
https://docs.microsoft.com/en-us/cpp/mfc/reference/cobject-class?view=vs-2019

CtypedPtrArray – Provides a type-safe “wrapper” for objects of class CPtrArray or CObArray.
https://docs.microsoft.com/en-us/cpp/mfc/reference/ctypedptrarray-class?view=vs-2019

CTypedPtrList – Provides a type-safe “wrapper” for objects of class CPtrList
https://docs.microsoft.com/en-us/cpp/mfc/reference/ctypedptrlist-class?view=vs-2019

CTypedPtrMap – Provides a type-safe “wrapper” for objects of the pointer-map classes CMapPtrToPtr, CMapPtrToWord, CMapWordToPtr, and CMapStringToPtr.
https://docs.microsoft.com/en-us/cpp/mfc/reference/ctypedptrmap-class?view=vs-2019

The non-template classes

CObArray – Supports arrays of CObject pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cobarray-class?view=vs-2019

CByteArray – Supports dynamic arrays of bytes.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cbytearray-class?view=vs-2019

CDWordArray – Supports arrays of 32-bit doublewords.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cdwordarray-class?view=vs-2019

CPtrArray – Supports arrays of void pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cptrarray-class?view=vs-2019

CStringArray – Supports arrays of CString objects.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cstringarray-class?view=vs-2019

CWordArray – Supports arrays of 16-bit words
https://docs.microsoft.com/en-us/cpp/mfc/reference/cwordarray-class?view=vs-2019

CUIntArray – Supports arrays of unsigned integers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cuintarray-class?view=vs-2019

CObList – Supports ordered lists of nonunique CObject pointers accessible sequentially or by pointer value.
https://docs.microsoft.com/en-us/cpp/mfc/reference/coblist-class?view=vs-2019

CPtrList – Supports lists of void pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cptrlist-class?view=vs-2019

CStringList – Supports lists of CString objects.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cstringlist-class?view=vs-2019

CmapPtrToWord – Supports maps of 16-bit words keyed by void pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapptrtoword-class?view=vs-2019

CMapPtrToPtr – Supports maps of void pointers keyed by void pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapptrtoptr-class?view=vs-2019

CMapStringToOb – A dictionary collection class that maps unique CString objects to CObject pointers.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapstringtoob-class?view=vs-2019

CMapStringToPtr – Supports maps of void pointers keyed by CString objects.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapstringtoptr-class?view=vs-2019

CMapStringToString – Supports maps of CString objects keyed by CString objects.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapstringtostring-class?view=vs-2019

CMapWordToOb – Supports maps of CObject pointers keyed by 16-bit words
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapwordtoob-class?view=vs-2019

CMapWordToPtr – Supports maps of void pointers keyed by 16-bit words.
https://docs.microsoft.com/en-us/cpp/mfc/reference/cmapwordtoptr-class?view=vs-2019

Simple Data Type Classes

MFC supplies a number of classes to encapsulate various data types widely used as parameters to the member functions of Windows classes. These are

CStringT – Holds character strings.
CTime – Holds absolute time and date values.
COleDateTime – Wrapper for the OLE automation type DATE.
CTimeSpan – Holds relative time and date values.
COleDateTimeSpan – Holds relative 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.
COleVariant – Wrapper for the OLE automation type VARIANT
COleCurrency – Wrapper for the OLE automation type CURRENCY

For further detailed reading
https://docs.microsoft.com/en-us/cpp/mfc/simple-data-type-classes?view=vs-2019

File input and output

MFC encapsulates the windows API file handling functions in the CFile class. It includes member functions for opening and closing files, reading and writing file data, deleting and renaming files, and retrieving file information. For a full description of the Cfile class and associated member function go to the following.

For further reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/cfile-class?view=vs-2019

Timers

Timers are used to schedule a periodic event and execute some program code. The CWnd member function SetTimer() initiates a timer to fire at specified intervals and CWnd member function KillTimer() stops the timer. A timer notifies an application that a time interval has elapsed in one of two ways:

By sending a WM_TIMER message to a specified window
By calling an application-defined callback function

The prototype for the CWndSetTimer is

UINT SetTimer( UINT nIDEvent, UINT nElapse, lpfnTimer);

where
nIDEvent – Specifies a timer identifier. Must not be zero
nNElapse – Specifies the time-out value, in milliseconds.
lpfnTimer – Specifies the address of the application-supplied TimerProc callback function that processes the WM_TIMER messages. If this parameter is NULL, the WM_TIMER messages are placed in the application’s message queue and handled by the CWnd object.

Returns the timer identifier if the function is successful.

As an example

SetTimer (1, 700, NULL);

Assigns a timer ID of 1, and sends WM_TIMER message to the window whose SetTimer function was called every 700 milliseconds. The final NULL parameter configures the timer to send WM_TIMER messages rather than call a callback function

Responding to WM_TIMER Messages

MFC’s ON_WM_TIMER message-map macro responds to WM_TIMER messages by a call to the member function OnTimer. OnTimer is prototyped as follows:

afx_msg void OnTimer (UINT nTimerID)

where nTimerID is the ID of the timer that generated the message.

Setting a Timer to respond to a callback function

To set a timer that uses a callback, the 3rd parameter of the SetTimer function must be set to the name of the callback function as follows

SetTimer (ID_TIMER, 500, TimerCallBackProc)

The callback procedure is prototyped as follows:

void CALLBACK TimerCallBackProc (HWND hWnd, UINT nMsg, UINT nTimerID, DWORD dwTime)

where
hWnd contains the window handle,
nMsg contains the message ID WM_TIMER,
nTimerID holds the timer ID,
dwTime specifies the number of milliseconds that have elapsed since Windows was started.

Stopping a Timer

To stop a timer call the CWnd member function KillTimer, which stops a timer and stops the WM_TIMER messages or timer callbacks. The following statement releases the timer with ID is 1:

KillTimer (1);

Example

The following program illustrates a simple timer app by flashing a “hello world” message in the top left-hand corner of the window

Download Code

Multi Document Interface

Multiple-document interface applications enable the user to work with more than one document simultaneously. Each document is displayed within a separate child window within the client area. An MDI child window looks much like a typical frame window, except that the MDI child window appears inside an MDI frame window and does not have a dedicated menu bar, but instead shares the menu of the MDI frame window. The framework automatically changes the MDI frame menu to represent the active MDI child window.

In addition to the 3 classes found in an SDI application, an MDI application must derive a class from CMDIChildWnd which provides the functionality for the Windows multiple document interface (MDI) child window. To make a document different from its parent, the application will also require additional resources to those associated with the main window.

A Multiple Document Interface (MDI) application uses the CMultiDocTemplate class derived from CdocTemplate.

If the MDI application uses more than one type of document then a separate template must be supplied for each document. This will require a separate template for each type of document using a CDocMultiDocTemplate constructor for each.

Working with Multiple-Document Types

By default, an SDI or an MDI application, created with the AppWizard will be configured with only a single document class. Additional document class types can however be added by making a second call to AddDocTemplate() in the application class InitInstance() member function as outlined below –

CMultiDocTemplate* pDocTemplate; PDocTemplate = new CMultiDocTemplate(IDR_SAMPLE1, RUNTIME_CLASS(CSample1Doc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CSample1View)); AddDocTemplate(pDocTemplate); pDocTemplate = new CMultiDocTemplate( IDR_SAMPL2, RUNTIME_CLASS(CSample2Doc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(CSample2View)); AddDocTemplate(pDocTemplate);

The type of document to create can then be selected via the main menu.

Example

The application below allows the user to create a multi-document interface based on the CeditView view class

Download Code

Document View Architecture

The MFC Document View Architecture is a framework designed to separate the storage and maintenance of data from the display of data. This is achieved by encapsulating the data within a document class and the presentation specifics within a view class. The advantage of decoupling the view from the application data is of most use in larger applications when there are multiple views and multiple types of data objects to incorporate into an application.

MFC supports two types of document/view applications: single-document and multiple-document interface (SDI) applications.

Single Document interface

The expression Single Document Interface or SDI refers to a document that presents only one view to the user. This means the application is limited to displaying one document at a time. Notepad is an example of an SDI application. Notepad cannot open multiple text files without starting up another application instance. A simple single document/view application will contain four key class components-

The CDocumet class provides the basic functionality for an application’s document object. This functionality includes the ability to create load, save and update documents. This process of writing or reading data to a storage medium is known as serialization. The serialization objects supplied with MFC provide a standard and consistent interface, relieving the user from the need to perform file operations manually.

The CView Class encapsulates the document’s visual presentation rendering an image of the document on the screen or printer and handling user interaction through the view window. MFC provides several variations on the view class and the capabilities of a view class will depend on the MFC view class from which it derives. Further information about these view classes can be found at the following
https://docs.microsoft.com/en-us/cpp/mfc/derived-view-classes-available-in-mfc?view=vs-2019

The CMainFrame class encapsulates the frame window. MFC places the application view window into the client area of the frame window. In an SDI application, the view window is a child of the main frame window.

The CWinApp class is the base class from which every MFC programmer derives a Windows application object. This application object provides member functions for initialising and running the application.

Dynamic creation

In a document view application the view, frames and document objects are created dynamically using the following macros

DECLARE_DYNCREATE (class name) – found in the class declaration and allows dynamic creation of the class
IMPLEMENT_DYNCREATE(class-name, parent name) – found inside the class declaration. The class name is the name of the class being enabled and the parent class is the name of the MFC base class

Once the documents view and frame class have been created they can be used as parameters in a runtime class structure which is used as a parameter to create the document template using the class CsingleDocTemplate. The prototype of this class is –

CSingleDocTemplate( UINT nIDResource, CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass );

Where
nIDResource – Specifies the ID of the resources used with the document type.
pDocClass – Points to the CRuntimeClass object of the document class.
fFrameClass – Points to the CRuntimeClass object of the frame window class. This class can be a CFrameWnd-derived class, or the CFrameWnd itself.
pViewClass – Points to the CRuntimeClass object of the view class. This class is a CView-derived class you define to display your documents.

The newly created template can be added to the list of available document templates available to the application by calling the AddDocTemplate member function.

The CCommandLineInfo class encapsulates command line information when an application starts
And the ParseCommandLine parses the command line information.

Saving and loading documents

In a document view program the Serialize member function, defined in the CObject class, is responsible for loading or saving an object’s current state. The Serialize function contains a CArchive argument that is used to read and write the object data. The IsStoring or IsLoading member functions indicate whether Serialize is storing (writing data) or loading (reading data). An application either inserts or retrieves an application object’s data using the insertion operator (<<) or extracts data with the extraction operator (>>).

Example

In the following example, an SDI application is created which places a sequence of markers at the position of the mouse click. Selecting the relevant display option will change the display marker from x to asterisk and vice versa while the various file/save, file/load and /file/recent demonstrate how to save and load data using the serialize function

Download Code

Toolbars

MFC offers two classes to provide the functionality of the Windows toolbar: CToolbar and CtoolBarCtrl. The CToolBar encapsulates much of its functionality of the standard toolbar control whereas CToolBarCtrl offers a more substantive programming interface.

To create a toolbar the developer can either

1. Instantiate an object of the CToolbar class and then call the CreateEx() member function followed by the member function LoadToolBar() to load the toolbar resource.

2. Instantiate an object of the CtoolBarCtrl class and define a TBBUTTON structure to provide details about the individual buttons. The CtoolBarCtrl class also requires a bitmap resource containing images for the faces of the toolbar buttons.

Toolbar buttons are assigned command IDs and clicking a toolbar button sends a WM_COMMAND message to the parent windows where the button ID is linked to the relevant command handler.

In addition to buttons, Windows toolbars can contain combo boxes, checkboxes, and other non-push-button controls. MFC provides functions for hiding and displaying toolbars, saving and restoring toolbar states, and much more.

For a full description of the CToolBar Class and associated member functions
https://docs.microsoft.com/en-us/cpp/mfc/reference/ctoolbar-class?view=msvc-160#createex

For a full description of the CToolBarCtrl Class and associated member functions
https://docs.microsoft.com/en-us/cpp/mfc/reference/ctoolbarctrl-class?view=msvc-160

The following short program creates a simple program with two buttons. Clicking either button will produce a message box.

Example


Download Code

Working with Bitmaps

Windows supports two types of bitmap: device-independent (DIB) and device-dependent (DDB). A device-independent bitmap is an external format, which allows bitmaps to be moved from one device to another. Device-dependent bitmaps are designed and optimised for use with a specific device (device-dependent) and hence are unsuitable for use in an environment for which they were not created. A typical example would be a bitmap created for video memory which is specialised for displaying screen output.

CBitmap Class

The CBitmap class encapsulates a GDI bitmap and provides member functions to manipulate the bitmap. A GDI is a device-dependent bitmap compatible with the specified device context. Although there is an MFC class for GDI bitmaps, there is no MFC class for DIBs.

To use a bitmap first, create a bitmap object and then load the bitmap into the object using the CBitMap member function LoadBitmap(). The prototype for the function is

BOOL LoadBitmap(LPCTSTR lpszResourceName); BOOL LoadBitmap(UINT nIDResource);

Where
lpszResourceName – contains the name of the bitmap resource.
nIDResource – Specifies the resource ID number of the bitmap resource.
Return – Nonzero if successful; otherwise 0.

Displaying a bitmap

To display a bitmap, firstly two device contexts must be declared: one will hold the current device context while the other will create a second copy device context that will be used to store the bitmap until it is ready to be drawn in the window. This copy device context is created using the CDC member function CreateCompatiableDC(). A newly created or existing bitmap can then be selected into the copy device context using the SelectObject() member function and finally copied to the screen using the device context member function BitBlt(). The sequence of events is summarised as follows.

CClientDC DC(this) //creates device context CDC memDC//creates copy device context memDC.SelectObject(&bmp)//load bitmap into member device context DC.BitBlt(x,y,sz,sy,&memDC,0,0,SRCCOPY);//copys the memory device context, size sx and sy to the screen location specified in x and y.

Repainting the screen using Bitmaps

GDI Bitmaps can create a virtual window and store a copy of the screen contents. This is a useful way to repaint the screen quickly and easily. Output is not written directly to the screen but to the virtual windows. Each time a repaint request is received, the contents of the virtual windows are then copied back to the main screen. To implement this approach a memory device context compatible with the current device context is created and all screen output is directed to it. Each time a repaint request is received, the contents of the virtual windows are then copied back to the main screen.

Example

The following example creates a simple graphic drawing program, which draws a line to the mouse click position from the previous cursor position. All screen output is directed to the virtual device context stored in memory and then copied to the screen when a repaint message is sent. The screen can then be redisplayed without keeping a record of each point

Download Code

Common Dialog Box

Common dialogs are a set of predefined, standard dialogs that can be used in an application to carry out common tasks such as file selection, font selection, or colour selection. All the common dialog classes are derived from a common base class, CCommonDialog.

The behaviour and appearance of a common dialogue by set or altered by changing the parameters supplied to the dialog’s constructor or by setting various flags. All the common dialogs require the inclusion of the commdlg.h header file.

MFC CCommonDialog Classes are shown in the following table.

ClassPurpose
CColorDialogAllows the user to select or create a color
CFileDialogAllows the user to open or save a file
CFindReplaceDialogAllows the user to substitute one string for another
CFontDialogAllows the user to select a font from a list of available fonts
COleDialogUseful for inserting OLE objects
CPageSetupDialogAllows the user to set page measurement parameters
CPrintDialogAllows the user to set up the printer and print a document
CPrintDialogExPrinting and Print Preview for Windows 2000

For further detailed reading
https://docs.microsoft.com/en-us/cpp/mfc/reference/ccommondialog-class?view=vs-2019

Example

The following short program illustrates the use of the CColourDialog by changing the background colour of the windows to match that selected from the colour dialog box

Download Code

Dialog Windows

A dialog box is a temporary popup window an application uses to prompt the user for additional information input. A dialog box will usually contain one or more controls (child windows) with which the user can enter text, choose options, or control the direction of the application.

MFC encapsulates dialog box menus and all associated actions in the CDialog class. Dialogs are classified into modal and modeless depending on their behaviour. Modal dialog boxes prevent the user from accessing any other part of an application window until the dialog box is closed. In contrast, Modeless dialog boxes allow the user to access the application window without closing the dialog.

For simple dialogs, the CDialog class can be instantiated directly however to implement the full functionality of a dialog box it is necessary to derive a user-defined class from CDialog. This user-defined dialog class will need to have its own message map and handlers to respond to events within the dialog box since dialog box messages are not sent to the main window. A dialog box will usually be defined in a program resource file and incorporated into the application program.

A dialog box is closed when it receives an ID_CANCEL or an IDOK message. These messages are handled by the CDialog member functions OnCancel and OnOK. It is possible to override both handlers and write custom termination procedures.

Creating a Modal dialog box

To create a modal dialog box, the CDialog class constructor is initialised with details of the dialog resource identifier and the parent window. The prototype for the constructor function is

BOOL Cdialog objectname( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL ); BOOL Cdialog objectname( UINT nIDTemplate, CWnd* pParentWnd = NULL );

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

returns nonzero if dialog-box creation and initialisation were successful and 0 if it fails.

Creating a modeless dialogue box

To create a modeless dialog box instantiate a CDialog class object using the default constructor without any parameters. The dialog box is then activated by a call to the CDilog member function create(). Modal dialog classes are usually instantiated on the stack so the dialog object won’t be destroyed prematurely when the calling procedure goes out of scope.


The code section below demonstrates a modeless and modal dialog box.

Download Code

Dialog-Based Applications

A dialog-based application is where the main window is a dialog box. This method simplifies the application build process by making controls easier to place onto the main window. An example of a dialogue-based application is the Windows calculator. Windows functionality will be defined in the Cdialog class in a dialog-based application. A class must therefore be derived from the Cdialog base class and instantiated. The object reference is then stored in the MFC member variable m_pMainWnd member and the window created by a call to the member function doModal.

Download Code