Common Controls

From the beginning, COMCTL32 has been less a library of functions than of window classes. Indeed, these window classes are what give COMCTL32 its name, because their typical use is not for the sort of windows that users are aware of as windows, but as controls in other windows to help with common user-interface tasks. The I/O performed through these controls can be quite sophisticated and is clearly best done in a standard way by all Windows applications. So standard are these common controls that it would be a very rare Windows program of any substance that does not use them, even if the program makes no other formal use of the Windows Shell.

The common controls were sufficiently important to the look and feel of better-quality Windows programs that they became an important tool for leveraging the Windows monopoly to favour Internet Explorer. Several new controls and many expansions of the existing controls’ feature sets first became available to third-party Windows programs not as natural progress from users installing the latest Windows version but by their installing Internet Explorer.

In the ancient history of 16-bit Windows, controls were a built-in feature of the windowing system. Not only were their class names pre-defined but the controls even had their own window messages in the reserved range below WM_USER. Other child windows might do similar work to the built-in controls, and be called custom controls, but were to some extent discouraged. See for instance The Windows Interface: An Application Design Guide from the Windows 3.1 SDK:

Applications may also contain custom controls, but widespread use of such controls defeats the benefits of consistency. Before deciding to use custom controls, application designers should carefully consider whether existing controls can be used instead.

Of course, a system manufacturer who can write this will want to be sure that the existing controls really do suffice for the generality of what application designers might imagine for their user interfaces. Once programmers are writing custom controls in any quantity, it becomes in everybody’s interests for the system manufacturer to provide additional controls with enough versatility to meet the need, not necessarily as more built-in controls but at least as standard extensions for common use. A library of such controls from Microsoft first saw the light of a retail release as COMMCTRL.DLL in Windows for Workgroups 3.11 late in 1993. With hindsight, the following from the SDK at the time is somewhere between quaint and curious:

Warning   Use of common controls is not recommended. Microsoft provides no guarantee that the common controls and the programming interface described in this chapter will be supported in future versions of Windows.

Only a few months later, Microsoft Systems Journal (February 1994) carried an article titled Seventeen Techniques for Preparing Your 16-bit Applications for Chicago which left no room for doubt that the new common controls were not just sure to stay in Windows but were essential to the commercial future of all Windows programmers.

Thus did Windows come to have some built-in controls implemented in USER32.DLL and the so-called common controls in COMCTL32.DLL. Microsoft’s warning from 1993 is a reminder that the interfaces and even some controls did change in some details. The very earliest of the common controls each have their own exported function for creating an instance of that control. Though these mostly persist in the 32-bit implementations, the interface settled to each control having a well-known class name, defined symbolically in the SDK header file COMMCTRL.H. One function, InitCommonControlsEx, is exported so that programs can direct COMCTL32 to register the window classes for the controls they want. The controls can thereafter be created, over and over, by calling the standard API functions CreateWindow or CreateWindowEx.

The following table lists the common controls and shows which COMCTL32 versions support them. The controls are listed in alphabetical order of their window classes. The symbolic name for use in program code is shown, if COMMCTRL.H defines one. The third column gives the heading under which Microsoft documents the control in the section Individual Control Information. Where no common name is given, it may be that Microsoft documents the control elsewhere or that the control is in some sense internal. More notes follow the table.

Class Name Symbolic Name Common Name Applicable Versions
Button WC_BUTTON Button Controls 6.00 and higher
ComboBox WC_COMBOBOX ComboBox Controls 6.00 and higher
ComboBoxEx32 WC_COMBOBOXEX ComboBoxEx Controls 4.00 (NT) and higher
ComboLBox     6.00 and higher
DropDown     6.10 and higher
Edit WC_EDIT Edit Controls 6.00 and higher
ImageDrag     6.10 and higher
ListBox WC_LISTBOX List Box Controls 6.00 and higher
msctls_hotkey32 HOTKEY_CLASS Hot Key Controls 3.50 and higher
msctls_progress32 PROGRESS_CLASS Progress Bar Controls 3.50 and higher
msctls_statusbar32 STATUSCLASSNAME Status Bars 3.50 and higher
msctls_trackbar32 TRACKBAR_CLASS Trackbar Controls 3.50 and higher
msctls_updown32 UPDOWN_CLASS Up-Down Controls 3.50 and higher
NativeFontCtl WC_NATIVEFONTCTL   4.71 and higher
ReaderModeCtl     6.00 and higher
ReBarWindow32 REBARCLASSNAME Rebar Controls 4.70 and higher
ScrollBar WC_SCROLLBAR Scroll Bars 6.00 and higher
Static WC_STATIC Static Controls 6.00 and higher
SysAnimate32 ANIMATE_CLASS Animation Controls 3.50 and higher
SysDateTimePick32 DATETIMEPICK_CLASS Date and Time Picker Controls 4.00 (NT) and higher
SysHeader32 WC_HEADER Header Controls 3.50 and higher
SysIPAddress32 WC_IPADDRESS IP Address Controls 4.71 and higher
SysLink WC_LINK SysLink Controls 6.00 and higher
SysListView32 WC_LISTVIEW List-View Controls 3.50 and higher
SysMonthCal32 MONTHCAL_CLASS Month Calendar Controls 4.00 (NT) and higher
SysPager WC_PAGESCROLLER Pager Controls 4.71 and higher
SysTabControl32 WC_TABCONTROL Tab Controls 3.50 and higher
SysTreeView32 WC_TREEVIEW Tree-View Controls 3.50 and higher
ToolbarWindow32 TOOLBARCLASSNAME Toolbar Controls 3.50 and higher
tooltips_class32 TOOLTIPS_CLASS ToolTip Controls 3.50 and higher

Note that in version 6.00 and higher, COMCTL32 re-implements some of the built-in controls. The implementations in USER32 remain. Both implementations use the same class names. Whether a given control is implemented through COMCTL32 or USER32 depends on the current activation context when the control is created. The affected controls are:

The ComboLBox control is obscure. Microsoft documents it as being “available only for use by the system” (yet MSHTML knows of it, admittedly to subclass an existing control, not to create one). The ComboLBox control is essentially a ListBox, with the same window procedure but different class styles, intended to exist only as a child of a ComboBox.

Redirection of window classes according to the current activation context is supported by USER32 in Windows XP and higher. Part of the feature is that any module, such as COMCTL32.DLL, that implements window classes can declare its support through an assembly manifest. If a window cannot be created because the requested class is not yet registered, but the class is supported by the module associated with the current activation context, then USER32 can call that module to get the class registered, and then retry the window creation. The module must export a function named RegisterClassNameW. COMCTL32 does this in versions 5.82 and 6.0 from Windows XP SP2, but not Windows XP SP3, and higher, with the effect that InitCommonControlsEx becomes unnecessary.

Version 6.10 takes this one step further. The ImageDrag control, new for version 6.10, is outside the machinery of InitCommonControlsEx. Its class name can only be registered through RegisterClassNameW. However, the only use known at present is internal, for COMCTL32 to enhance image lists.