Introducing Visual C++ 6.0

Mike Blaszczak

On July 1st, Microsoft released Visual C++ 6.0 to manufacturing. The product contains several innovative features aimed at improving developer productivity and streamlining the software design lifecycle. Further, the product continues to be the first to deliver high-performance access to new strategic systems features from Microsoft. Mike, who heads the MFC team, introduces you to the newest release. What's new in Visual C++ 6.0? A lot. You'll see new IDE features, a faster compiler that produces faster code, a faster linker, MFC support for new SDK features (including new controls you might recognize from other Microsoft products,) new AppWizard options, easier ATL, and a brand new Test Container for your controls.

New Features in the IDE

Two of the most exciting features added to Visual C++ 6.0 are Edit and Continue and Automatic Statement Completion. While you won't see these features represented on any menus, their power and facility will undoubtedly help you spend more time actually writing code and less time working with your tools.

Most developers do their work in an iterative fashion. They edit, build, and debug over and over again until their code is just right. Of course, some developers spend longer on a given step than others, but the repetition of the process is inescapable. The Visual C++ IDE, by seamlessly incorporating tools to perform each of those three steps, goes a long way toward making the iterations less tedious than it would otherwise be.

But some parts of the process are still difficult. Debugging, for example, often requires you to run the application and then work with the application for some time in order to reproduce a bug. (Perhaps you need to open a specific file, fill out a sequence of dialogs, or in some other way follow many steps to get to the place where the bug occurs.) If you realize that one tiny change will significantly improve the undesirable behavior, you must stop the application, make the change, and completely rebuild the application. Worse yet, you then have to go through all the steps again to confirm that you have fixed the problem.

Visual C++ 6.0 includes Edit and Continue, which allows you to make changes to code while your application is stopped at a breakpoint in the debugger. If your build settings allow for edit and continue, the environment will automatically prompt you to allow a quick build to take place. In such a build, the system will build only the changed files and reload the code so that the execution state isn't destroyed but the new code is brought into memory, ready to execute. You don't have to do a full build, and you don't have to worry about getting the application ready to debug - just do it!

While there are some situations where Edit and Continue can't reload code and allow it to continue executing (for example, if you make a change to a function which requires a destructor call), you'll find that it saves you an immense amount of time in your debugging sessions.

Visual C++ users are also treated to online fly-by help for structure and class members. This is the first half of a feature called Automatic Statement Completion: the editor will provide a list of members in a class just after you type enough code to indicate which class or structure you're going to use. For example, imagine that you're typing this code:

	CString str;
	str.	// cursor here


Figure 1. Choose your member variable or function from a list presented as you type

Just as you type the dot operator, the editor will quickly provide a dropdown list box (see Figure 1) which allows you to choose any member of the CString class by selecting its name! If you don't want to pick a member, you can just keep typing - the list box doesn't intercept keystrokes.

The other half of Automatic Statement Completion is parameter help. As you paw through the list, the editor will examine the definition of the class or structure for appropriate comments and show you the comment as a brief description for the member you're about to select.

If you finished the above example by selecting the FindOneOf() member, for example, the editor would insert the function name and the open parenthesis into your source - and then show a tool tip window with the names of all the parameters in the function call. As you start typing, the tool tip will embolden the current parameter name so that you know which parameter you're about to enter. The tool tip supports function overloading by showing the appropriate overload based on the type you've entered (if it's discernable), or by allowing you to scroll through the similar function overrides.

Automatic Statement Completion eases your reliance on the help subsystem by putting the information you most frequently need in front of you instead of forcing a trip to the online help. Best of all: it works for your own classes, as well as the types supplied in all the headers with the product! If you derive your own classes, or start from scratch, Automatic Statement Completion is there to help.

Automatic Statement Completion is a part of a wave of new features in Visual C++ all aimed at bringing Microsoft IntelliSense to the language tools. You're probably familiar with IntelliSense - it's the technology that helps you work with Microsoft Office applications by having them react to the work you're doing as you do it, without your worrying about the right command to invoke or button to press. The IntelliSense features in Visual C++ expand to several areas, including some existing features, like the fly-by DataTips that you're used to seeing in the debugger. The new features include TypeTips: the Visual C++ source editor will show you the type of a variable in a pop-up window if you park the cursor near the variable name.

The debugger also has some new features - perhaps the most pleasant is the Module List window. By using the Module... command in the Debug menu, you can pop up a dialog that looks like Figure 2. It enumerates the modules in the process you're debugging. The name of the module is shown, along with the logical address within your process. But best of all, the dialog also shows the full path name for the module you're viewing - which is a handy way to see what you've loaded and where it came from!


Figure 2. The module list shows all the modules you have loaded

The Compiler

The compiler shipped with Visual C++ 6.0 again continues to improve support for the ANSI conformance in the language implementation. The compiler now supports member templates, and has improved its overall template support significantly. Also, the compiler has tightened-up support for handling exceptions thrown during the allocation of an object - when a constructor for an object created with operator new throws an exception, an appropriate override of operator delete will be called.

The back-end of the compiler also features new optimizations that can improve code performance by five to twenty percent - with only a recompilation! The new optimizations are centered on better inlining. The compiler also provides a new keyword, __assume, which allows you to provide more information to the optimizer so it can make assumptions about how your code really works - and therefore generate a better translation. You can also use the new __forceinline keyword to make a function inline - always, no matter what the compiler might otherwise decide.

To support the theme of developer productivity, the compiler features a new command-line option: /GZ. This switch has the compiler generate more aggressive error checking at runtime. Such error checking will bring to light some bugs that were only readily evident in release-mode builds in debug builds, as well. For example, a bad cast of a function pointer using one calling convention to another calling convention always causes a runtime fault in a module built with /GZ, while modules built with /Od (normally used for debug builds) silently let the code work.

The use of the /GZ switch also causes local variables within a function to be initialized to a constant value - which can often make detecting the use of an uninitialized variable easier. /GZ isn't appropriate for release builds because it does emit less efficient code in order to afford the tests for problems. But the compiler detects most of the same problems in release builds anyway because the optimizer causes the compiler to do far more aggressive analysis of variables and their usage. For example, a release build detects an uninitialized variable by attempting to optimize its storage and accessibility characteristics - while a /GZ build notices an uninitialized variable at runtime because it's been flood-filled with a value that is guaranteed to point at memory not owned by the running process.

While /GZ focuses on trapping runtime errors earlier, the compiler also has several new warnings. Finally, developer productivity is also aided by improvements in compiler throughput - you'll find that your builds may take as much as thirty percent less time to complete.

The Linker

Nobody says much about the linker, but some significant improvements in link time have been made. Specifically, the file format for import libraries has been enhanced so that they're now much smaller. The import library for the release build of MFC, for example, is now only about half as large as it was in Visual C++ 5.0! Since the linker doesn't do as much I/O, and doesn't have to do extra work to manage the file format, build speed has been improved.

The linker now also features the /DELAYLOAD option. This option tells the linker that the module being linked is dependent on a particular DLL, but that the DLL shouldn't be loaded and initialized until it is actually needed. You can specify the /DELAYLOAD option more than once--you might use the /DELAYLOAD option on all of the DLLs that your module references, for example, but doesn't use until the user explicitly asks for them. If you load COMMMGR.DLL, for example, but only reference the code in the library when the user makes a connection, specifying /DELAYLOAD for that library will defer the initialization of the library until the time your application actually crosses into the code. Delay Load Imports, when carefully applied to your application, can defer the growth of your application's working set and significantly improve its start-up time.

New MFC Features

MFC 6.0 is shipped in the Visual C++ 6.0 box. The most important feature MFC adds in this release is compatibility with the newest Internet SDK and Platform SDK releases from Microsoft, so your MFC applications are ensured continued compatibility with the technologies emerging in Microsoft's newest operating systems, platforms, and extensions.

Many of the improvements in MFC 6.0 are evident in the AppWizard. When you run the MFC AppWizard in Visual C++ 6.0, you'll almost immediately notice that a few new project types have been added. On the first step in creating an MDI or SDI application, you'll notice that you can create applications that use the MDI or SDI user interface style but don't provide document/view support! (See Figure 3.) By removing document/view support from your application in AppWizard, you can reduce the runtime size of your program and ease porting to MFC from SDK-based applications.


Figure 3. Document/view support is now optional

Later in the AppWizard, you'll note that there's an option to create an Active Document Container application. (See Figure 4.) This support complements code added to the previous version of MFC to allow creation of Active Document Servers. An Active Document Container can hold an instance of other servers, such as the Office applications, Microsoft Internet Explorer, or third party tools like Adobe Acrobat, right within your application. The seamless containment afforded by the Active Document specification gives your applications the ability to contain servers with content that spans more than one page instead of occupying only a rectangle within a larger document space.


Figure 4. Your applications can contain Active Documents

MFC has been modified to support all of the newest common controls available in the system. The new controls include the IP Address control, which allows your users to enter dotted-quad IP Addresses (of the form 207.46.130.14) without performing any subclassing or validation. Support for ComboBoxEx-style controls have been added, allowing your application to provide a control with the user interface of a combo box but the advanced owner-draw painting normally only found in a list view control. The CDateTimeCtrl class provides a control similar to an edit box that displays or accepts date/time information. The control can optionally be linked to a CMonthCalCtrl, which provides a pop-up window showing dates organized like the pages of a calendar. The user can see, at a glance, the state of individual days on the control, or can use the control to select a particular date with a single click. The date-time controls feature new DDX_, DDV_, and RFX_ functions that allow your applications to use the controls in your DoDataExchange() implementation. ClassWizard knows about these new functions and data types, and is capable of adding data exchange code for the new controls automatically for you. Of course, the resource editor has also been enhanced so that you can place these controls on a dialog box whether you're using MFC or not. (See Figure 5.)


Figure 5. A number of new controls, with full MFC support, have been added

Several of the existing common control classes have been enhanced to support new features found in updated versions of the COMCTL32.DLL library, upgraded by installing Windows 98 or Internet Explorer 4.0 or later. The tree view control, list view control, slider control, and status bar control are all upgraded to support new styles, modes, and display features. The controls all feature hover highlighting, for example, as well as support for background bitmaps that can give the control a special texture or more artistic look-and-feel. All of the new capabilities you've read about in the magazines are finally supported by MFC itself!

To support HTML and Dynamic HTML, MFC has added the CHtmlView view type. This view allows your application to very easily host HTML - and work both on- and off-line with HTML-based content.

MFC's new features also extend to several gentle enhancements to even the most basic classes. Frequently requested find and replace functions have been added to CString, and new conversion calls have been added to the date and time classes, for example.

Developers who more adeptly use MFC know that the framework is useful for some console applications as well as classic GUI applications. To make initiating such projects easier, the AppWizard now features a Console Application wizard that supports both MFC and non-MFC applications.

Overall, MFC's undergone some substantial tuning to help reduce the size of the DLL and lower the amount of MFC code linked to your application if you choose to use the static libraries. Despite all of the new features the team has added, the DLL occupies under one megabyte. Simple console applications which statically link to MFC to use CString can shrink more than 35 percent while a release-mode build of WordPad will be more than five percent smaller than it was in Visual C++ 5.0!

New Active Template Library (ATL) Features

ATL version 3.0, provided in the Visual C++ 6.0 box, benefits from an impressive amount of growth that vastly expands the breadth of the library. While the library is still largely aimed at the development of COM objects, the number of object types readily supported by ATL have been impressively bolstered. Further, many issues surrounding the use of ATL within an MFC project have been resolved - making it easy to add efficient COM support to your existing applications. The link errors and obscure warnings when using the collection classes are now a thing of the past!

ATL also now features the ATL Composite Control, which can be used to create an ActiveX control that is based on other controls - even if the contained controls are ActiveX controls! The Composite Control relieves the developer interested in producing an integrated control from worrying about input focus issues, tabbing problems, and handling the esoteric details of keystroke processing while providing a framework for the development of impressive and rich controls. You can add the Composite Control to your existing application by using the ATL Object Wizard. The Wizard provides several customization features - including optional support for standard ambient properties for the contained controls. The resulting dialog resource is used to draw the contents of the composite control. Creating the composite control object instantiates the dialog and all of its contents as an ActiveX control.

The ATL Object Wizard now features support for generating the registration code appropriate for the object's participation in Microsoft Transaction Server packages. Once registered as part of an MTS package, the object will work on the server within the same process boundary, and can participate in trusted relationships with different objects in the same package.

Microsoft's OLE DB initiative brings a common database API to all languages. While OLE DB is highly performant and very flexible, it's not so easy to utilize. ATL now supports the generation of OLE DB consumers, which attach to OLE-DB data sources to query and enumerate data. Further, ATL also supports the creation of OLE DB providers, which allow for the creation of such data sources. Such a project can allow you to collect data to from disparate sources to be exposed as one single source, or publish data in a standard format to any tool that can consume OLE DB data. ATL's support for OLE DB exposes the technology in a very convenient and approachable way while inducing nearly no performance degradation.

The Microsoft Management Console support allows you to produce a snap-in that can be contained by the Microsoft Management Console. When hosted in the Management Console, your component can be used by anyone to manage a running service, a custom application, or a system component.

In the very near future, both the Microsoft Management Console and OLE DB will play pivotal roles in the development of system-level components. You've probably already noticed the user interface face lift in the newest versions of administrators' tools for Microsoft Internet Information Server and SQL Server: these tools use the Microsoft Management Console technology. Similarly, OLE DB is at the heart of Microsoft's Active Directory Services technology, available in the Windows NT Option Pack. These initiatives are only the tip of the iceberg!

Along the lines of server-side programming, the new Cluster Resource Type Wizard allows you to implement a Microsoft Cluster Server (MSCS) resource type, which allows your applications to be closely managed and monitored by MSCS. The project produced by the Wizard gives you a COM object that acts as an in-process server that provides a UI to manage the new resources - that object actually talks to the managing component, which is normally a Microsoft Management Console application. The project also includes a DLL to be loaded by the MSCS resource monitor on the cluster node where the application is run. It's that DLL that actually performs the monitoring functions.

Like MFC 6.0, ATL 3.0 has the capability to contain HTML-based user interface elements by using the Object Wizard to add the HTML control to your existing project. The ATL wizards have also been enhanced to make setting up connection points much easier, and by providing options to make adding message and event handlers a trivial effort.

The ATL Object Wizard has been further expanded to support "Lite" versions of normal OLE Controls, the Composite Control, and the HTML control. The lite versions of the controls supply only the interfaces necessary to get the control hosted in Internet Explorer - while that hurts the flexibility of the control, for web-based development it can make the already tiny ATL control implementations even smaller!

Other Tools

Perhaps one of the less-pronounced but absolutely shining improvements in the product involves one of the most under-designed and over-utilized tools that Microsoft has ever produced: The ActiveX Control Test Container. The container has been completely rewritten, but before I describe it's new features let me say this: complete source code is now included!

The new Test Container really is a complete rewrite, and that rewrite cleaned up lots of problems and offered support for lots of nifty features. First, the user interface (See Figure 6) is coherent, sane, and convenient. There are no sharp edges to snag and tear your testing efforts. Then, there's the brilliant support for serialization - you can watch your control serialize to or from any target, step by step. Painting tests within the control have also been made more robust - you can explicitly select the way your control will be required to paint, and you can have the container force the control to render itself very slowly in order to watch the blow-by-blow action.


Figure 6. The Test Container has an all-new interface.

Last, but not least, Test Container now is an Active Script container! Something of a development environment within a development environment, you can really use the tool to put together automated tests by writing script code to drive the automation interfaces exposed by your control. When you get the new product, don't let your boss catch you playing the "follow-me" game included as a sample script.

If you're a database developer, you'll notice a new Extended Stored Procedure Wizard that helps you write XSP dynamic-link libraries for SQL Server. If you're not using SQL Server, you'll find that the improved support for Oracle database tools throughout the product relieves some of your frustration.

Introducing Visual C++ 6.0

Visual C++ 6.0 represents hundreds of person-years of work, and I think the improvements are very obvious. Upgrading to Visual C++ will reward you with a more complete and comprehensive development environment with the most innovative developer productivity features Microsoft offers. Best of all, it will position you and your staff to support the newest operating system features that Microsoft has made available.

Mike Blaszczak is a development lead for the MFC team and sets the technical direction of the libraries while still participating in their implementation. Mike, a Microsoft employee for more than six years, enjoys long-distance motorcycling, ice hockey, and writing. He has written for several magazines, and the third edition of his book about Windows programming with MFC was published in 1997 by WROX Press. mikeblas@nwlink.com