Objective Toolkit : Chapter 30 Introduction to Objective Toolkit for ATL : Desktop Application Toolbar Class and Object Wizard
Desktop Application Toolbar Class and Object Wizard
To enable developers to create desktop toolbars similar to the Windows taskbar, OTL provides the COtlAppBarImpl class. Unlike IE Deskband objects, application toolbars are based on callbacks and windows messaging, not COM interfaces. OTL AppBars also support taskbar features like Autohide, Always on Top, and Incremental Sizing. The AppBar also has a mirror mode, which forces the Appbar settings to follow the Windows taskbar settings. An application toolbar, or appbar, runs as an executable, or a DLL loaded in the process you define. All you need is a window, and COtlAppBarImpl as a base class. COtlAppBarImpl is a CMessageMap derivative that listens for sizing and mouse messages sent to your window. It also implements a callback handler that is registered with the Windows application bar support mechanism.
OTL provides an Object Wizard to generate a simple dialog-based application bar that you can customize. The wizard generates an ATL CAxDialogImpl-derived class that also inherits from COtlAppBarImpl. The message map for the dialog chains to COtlAppBarImpl via the CHAIN_OTL_APPBAR() macro at the beginning of the message map. A context menu is provided to access common AppBar features.
Creating an AppBar
You can create a wizard generated AppBar the same way you create a normal dialog box. The WM_INITDIALOG handler needs to call the InitAppbar() and Dock() functions of COtlAppBarImpl. You can also build Appbars using the ATL CWindow classes instead of dialog classes. In that case, handle WM_CREATE to do the initialization.
Docking and Layout
By default, you can drag the AppBar to any edge of the desktop. If you want to prevent docking to a particular edge, override PrepareToDock(uEdge) and return FALSE for that edge. The AppBar supports the real time dragging. Whenever the AppBar is sized or moved, OnLayoutBar() is called. The AppBar Object Wizard generates code that overrides OnLayoutBar() in your COtlAppBarImpl-derived class. Reposition any child window and make any UI adjustment for docking orientation (vertical/horizontal) in OnLayoutBar(). Floating AppBars are not supported.
Appbar Tab Window Control
OTL also has a tab control class that is specifically designed for creating rows and columns of owner-draw buttons with tooltips, like the windows taskbar. The ZappBar sample shows the COtlAppBarTabs class used with COtlAppBarImpl to create a desktop navigation bar.
COtlAppBarTabs is designed to be used as a child control inside of an Application Desktop Toolbar (AppBar), similar to the Windows Taskbar. This class subclasses the Win32 common tab control. The control has the following enhancements:
Owner-draw buttons (tabs) with images.
Elided text on buttons when sizing is below minimum.
Automatic tooltips based on button text.
Dynamic change of tooltip hit rectangles when resizing.
Creation
After construction, you can initialize this control with a call to Create(), or SubclassWindow(). If subclassing, use the following styles in the dialog editor:
 
TCS_FORCELABELLEFT | TCS_HOTTRACK | TCS_BUTTONS | TCS_MULTILINE |
TCS_FIXEDWIDTH | TCS_FOCUSONBUTTONDOWN | TCS_OWNERDRAWFIXED | TCS_TOOLTIPS
NOTE >> If you want the flat button style, use ModifyStyle to add TCS_FLATBUTTONS after creation. This style is only supported in common controls version 4.71 and higher.
Message Reflection
The parent window must reflect messages back to COtlAppBarTabs by adding the ATL macro REFLECT_NOTIFICATIONS() to its message map or no tab drawing can occur.
Image List
If you need images to load an image list, call SetImageList() and then populate the tab control using the AddTab() method.
Selection Notification
Handle the TCN_SELCHANGING notification to perform some action when a button is clicked. In the handler, you can retrieve the button that was clicked with GetFocusItem(). Returning TRUE from this handler allows the button to return to the up position. Returning FALSE causes the button to remain pressed until another selection is made.