MFC 4.0: The Story Can Be Told

New version adds control views and OLE container/control support

Sal Coco

November 1, 1995

One of the most significant products available for Windows-based software development is the Microsoft Foundation Class Library (MFC) version 4.0. MFC 4.0 fully supports 32-bit programming for Microsoft Windows 95. Your MFC applications will run on Windows 95, Windows NT 3.51, or Win32s 1.3. Applications developed with MFC 4.0 will automatically have the visual look and feel appropriate for any of these operating systems.

Using Visual C++ 4.0 and MFC 4.0 simplifies the task of meeting the Windows 95 logo requirements. Of course, it is virtually impossible for a development tool to automatically satisfy all of the logo requirements, since a lot depends on what your application is doing. However, using Visual C++ 4.0 and MFC 4.0 allows you to satisfy some of the requirements automatically, including the stipulation for providing a Win32 executable in a portable executable (PE) format, Windows NT compatibility, and long file name support.

New Win32 common control classes

Windows 95 common controls are now available in Windows NT 3.51 and Win32s 1.3. MFC 4.0 offers new common control classes that encapsulate the following controls: rich text edit, slider, list, tree, spin button, header, progress, hot key, tool tip, tab, animate, tool bar, status bar, image list, drag list box, and check list box. The new common control classes are as easy to use as familiar standard control classes such as CEdit.

MFC 4.0 has a new view control base class, CCtrlView, that allows you to create a view from one of the new common control classes with little effort. Although previously it was technically possible to attach a control class to a CView object, CCtrlView hammers out all the details of making your own control view. CCtrlView can also be used with third-party controls and with controls you design yourself.

MFC 4.0 exploits the new CCtrlView class by introducing several new common control view classes: CListView, CTreeView, and CRichEditView.

Use a common control class when you need a plain child window control; for example, in a dialog box or form view. Plain common control classes are especially useful in the same window with other child control windows, as in a typical dialog box.

Use a common control view when you want the control to behave as a view window, such as in document/view architecture. A control view will occupy the entire client area of a single splitter window pane or frame window, and will automatically resize itself when the parent window is resized. In addition, command messages from menus, accelerator keys, and toolbars will be routed to the view automatically. Of course, the user of these control views can override most of the default functionality and customize the behavior as needed.

A simple example

To illustrate the power of these common control classes and control views, let's use them to build a simple application that allows a user to preview animation files. To make this application user-friendly, let's add a splitter window with two vertical panes: one that displays a list of animation file names (organized into several categories), and one that plays the animation.

The application will behave similarly to the Windows 95 Explorer. A tree view is used in the left pane and an animation view is used in the right pane of the vertical splitter window. The user will select an animation file by drilling down into the tree view user interface and finding its file name. Once the animation file is selected, the application will play it in the right pane of the splitter window.

One approach to implementing this simple application is to have AppWizard generate the code for a basic application, using the CView class. After the application is built, we can edit the code and add a splitter window using the CSplitterWnd class. After creating the individual panes of the splitter window, we just need to add the appropriate view classes. Since the tree view is already implemented, we can use CTreeView. At this time, MFC does not contain an animation view class, so we have to create one ourselves using the CCtrlView base class. A brief example of the code needed to declare a CAnimateView class is shown below. This code is by no means complete; its purpose is to illustrate the basic idea of creating your own view control object.

Here's the CAnimateView header file:

// CAnimateView header file

 

class CAnimateView : public CCtrlView

{

DECLARE_DYNCREATE(CAnimateView)

 

public:

// CAnimateView constructor

CAnimateView();

// CAnimateView destructor

~CAnimateView();

 

// Returns a reference to the animation

// control.

CAnimateCtrl& GetAnimateCtrl() const;

 

// Perform control initialization.

virtual BOOL PreCreateWindow(CREATESTRUCT&

cs);

 

// Open the animation file.

void OnInitialUpdate();

 

//{{AFX_MSG(CAnimateView)

//}}AFX_MSG

 

DECLARE_MESSAGE_MAP()

};

As you can see, creating a custom control view class based on the CCtrlView class is an easy and straightforward task.

// CAnimateView source file

 

IMPLEMENT_DYNCREATE(CAnimateView, CCtrlView)

 

BEGIN_MESSAGE_MAP(CAnimateView, CCtrlView)

//{{AFX_MSG_MAP(CAnimateView)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

// CAnimateView constructor.

// This is where CCtrlView uses the control

// class name "SysAnimate32" to create the

// view object.

CAnimateView::CAnimateView() : CCtrlView("SysAnimate32", AFX_WS_DEFAULT_VIEW)

{ }

 

// Destructor.

CAnimateView::~CAnimateView()

{ }

 

// Code used to return the reference of the CAnimateCtrl.

CAnimateCtrl& CAnimateView::GetAnimateCtrl() const

{ return *(CAnimateCtrl*)this; }

 

// Called by the framework before the creation

// of the window attached to this CWnd object.

BOOL

CAnimateView::PreCreateWindow(CREATESTRUCT& cs)

{

static BOOL bInit = FALSE;

 

// Initialize the common controls once.

if ( bInit == FALSE )

{

// The InitCommonControls function ensures

// that the common control DLL is loaded.

InitCommonControls();

bInit = TRUE;

}

return CCtrlView::PreCreateWindow(cs);

}

 

// Write your initialization code here.

void CAnimateView::OnInitialUpdate(void)

{

CCtrlView::OnInitialUpdate();

// Open an animation AVI file for the animation control.

GetAnimateCtrl().Open("c:\\myavi.avi");

 

}

Now that we have the animation control view object and the tree view object, we can use these two views when we create the panes for the splitter window. And presto, we have an application.

New common dialogs

MFC 4.0 also introduces two common dialog classes—CPageSetupDialog and COlePropertiesDialog—that encapsulate the common dialog boxes in Windows. These provide easy-to-use implementations of complicated dialog boxes. MFC 4.0 also adds new functionality to the CFileDialog class.

The services provided by the Windows common OLE Page Setup dialog box are now encapsulated by the CPageSetupDialog class, which also provides support for setting and modifying print margins. The CPageSetupDialog class is derived from CCommonDialog and replaces the Print Setup dialog box. The Windows common OLE Object Properties dialog box is now encapsulated by the COlePropertiesDialog class. This dialog box provides a way to display and modify the properties of an OLE document item in a manner consistent with the Windows standards.

The old CFileDialog class also has new member functions for customizing the File Open dialog box, allowing you to add your own controls.

OLE container and control support

The introduction of the OLE Control Development Kit (CDK) provided the tools necessary to develop OLE Controls. Today the CDK has disappeared, and all of its components and classes have been integrated into MFC 4.0, which now offers OLE Control container and OLE Control implementation support. AppWizard now allows developers to add OLE Control support to their applications automatically, without writing code. (See companion story "MFC 4.0 Helps You Contain Your OLE Controls" in this issue of Developer Network News).

The new OLE Control container makes it easy to add OLE Controls to any window, similar to adding a standard Windows control. A developer who uses an OLE Control container does not need to know all the tedious implementation details of an OLE container application, only that the OLE Control container support is based on the CWnd class. An OLE Control becomes a unique kind of child window, inheriting new OLE functionality from the CWnd class, including a new method, CWnd::CreateControl. This method allows the dynamic creation of an OLE Control instead of an ordinary window.

AppWizard has become smarter with the introduction of a visual approach to adding OLE Control support. Use AppWizard to turn on the support for OLE Controls. OLE Control support is provided for dialog box-based or window-based applications. AppWizard will generate the code necessary to set up and prepare the OLE Control container. Your AppWizard-generated application is now ready to use OLE Controls.

New Data Access Object classes

The Data Access Object (DAO) classes allow you to set up and use workspaces, and to create and manipulate tables, queries, and indexes for tables using the SQL Data Definition Language (DDL). DAOs allow direct access to the Jet database engine, which is also used in the Microsoft Access and Microsoft Visual Basic 4.0 development environments. Overall data access performance improves when using the DAO classes with the Jet database engine. The Jet database engine is used when manipulating Microsoft Access databases.

The DAO classes allow you to connect to open database connectivity (ODBC) data sources. This allows you to connect to tables stored on SQL Server, Oracle, or other databases.

Multithreaded synchronization classes

MFC 4.0 includes several multithreaded classes, which provide synchronization methods to ensure the integrity of a resource and to gain access to the protected resource. These synchronization classes have been organized into two categories: synchronization object classes and synchronization access object classes.

The synchronization object classes control access to a resource and ensure its integrity. Classes in this category are CSyncObject and its derived classes CEvent, CSemaphore, CMutex, and CCriticalSection.

The synchronization access object classes allow the application to gain access to resources controlled by the synchronization object classes. These methods are CSingleLock and CMultiLock. Use CSingleLock when your application accesses a single controlled resource; use CMultiLock when your application accesses multiple controlled resources.

How to get MFC 4.0

MFC 4.0 can be purchased with Visual C++ 4.0. Visual C++ subscriptions, which provide three releases per year, are now available in the United States, Canada, and Europe. Elsewhere, contact your local Microsoft subsidiary. MFC 4.0 is also available from licensed software vendors.

Sal Coco is a strategic account engineer in the Premier Developer Support division of Microsoft Product Support Services.