Objective Toolkit : Chapter 12 Framework‑Tailored Shortcut Bars : Using the Shortcut Bar
Using the Shortcut Bar
We provide a windowed shortcut bar and a non-windowed shortcut bar; this section discusses using each version separately.
Using the Windowed Shortcut Bar
1. Depending on your application's framework, include either the ot_atlshortcutbar.h or ot_mfcshortcutbar.h header to your project.
2. To the parent class add a member of type SECATLShortcutBarWnd or SECMFCShortcutBarWnd, depending on which framework you use.
3. Handle the WM_CREATE message in the parent class. Within this handler, create the shortcut bar and set its initial styles.
 
// m_hWnd is the window handle of the parent.
m_wndSCBar.Create(m_hWnd, rcBar);
m_wndSCBar.SetBarStyle(m_wndSCBar.GetBarStyle() | SEC_TABBAR_CNTXTMENU);
4. Use the SECATLShortcutBarWnd::AddBarWnd() or SECATLShortcutBarWnd::AddBarVisual() methods to add either regular window-based clients or MVC visual component/viewport clients to the shortcut bar.
 
// m_pViewport is an instance of an MVC MvcViewport_T class
m_wndSCBar.AddBarVisual(&m_pViewport, _T("Canvas Viewport"));
 
// m_wndTree is a standard C++ wrapper(CWnd/CWindow) for
// a HWND
m_wndSCBar.AddBarWnd(m_wndTree.m_hWnd, _T("Tree"));
5. Finally, invoke ActivateBar() to set the initially active bar.
 
m_wndSCBar.ActivateBar(0);
Using the Non-Windowed Shortcut Bar
When using the non-windowed version of the control, the shortcut bar is merely a visual entity that uses the device context provided by the host window to render itself. All client windows will be created as children of the hosting parent. When using the shortcut bar in this metaphor, it is up to the parent window to suitably expose a window handle in a manner that the shortcut bar understands. This is achieved through the SFL IVisualWindow interface that the shortcut bar expects the host window to implement.
1. Implement IVisualWindow in the parent class that will host the shortcut bar.
2. To the parent class add a data member of type SECATLShortcutBarHosted or SECMFCShortcutBarHosted.
3. When using ATL, plug this object into the ATL message chain using the CHAIN_MSG_MAP_MEMBER() macro.
 
BEGIN_MSG_MAP(CScribbleFrame)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
CHAIN_MSG_MAP_MEMBER(m_wndSCBar)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
4. When using MFC, override the CWnd::OnWndMsg() and CWnd::OnCmdMsg() functions in the host class and call the equivalent methods in the shortcut bar.
5. In the WM_CREATE handler, call the SECATLShortcutBarHosted::Create() method and pass in a pointer to the parent class implementing IVisualWindow.
 
m_wndSCBar.Create((IVisualWindow*)this, rcBar);
6. Provide a handler for the WM_SIZE message and set the shortcut bar's viewport size using the SECATLShortcutBarHosted::SetSize() function.
 
m_wndSCBar.SetSize(250, 750);
NOTE >> When using the windowed version of the shortcut bar, all client windows must be created as children of the shortcut bar. However, while using the non-windowed version of the control, child windows share a common parent with the shortcut bar.
Setting visual aspects of the shortcut bar
Various visual aspects of the shortcut bar such as the bar label font, background brush, back-color, bar icon, text color, text alignment etc., can be set using the appropriately titled methods that the class implements. Some of these are shown below.
 
// Sets a hashed background brush for the bar. The second
// param is the bar index.
m_wndSCBar.SetBarBrush(m_hHashBrush, 0);
 
// Sets the text color used for the bar labels
m_wndSCBar.SetBarTextColor(RGB(0,0,255), 0);
 
// Sets the bar label font to m_hfBar. Specifying -1 sets the
// particular aspect for all the bars.
m_wndSCBar.SetBarFont(m_hfBar, -1);
 
// Displays, alongside the label, the IDI_ICON1 icon on bar 1.
m_wndSCBar.SetBarIcon(1, IDI_ICON1);
 
// Center aligns the bar text. The other options available are
// SEC_TABBAR_LBLALIGNLEFT & SEC_TABBAR_LBLALIGNRIGHT
m_wndSCBar.SetLabelAlignment(SEC_TABBAR_LBLALIGNCENTER);
Adding a context menu to the shortcut bar
When the SEC_TABBAR_CNTXTMENU style is set, right-clicking anywhere on the bar portion causes the shortcut bar to generate a WM_TABBAR_CNTXTMENU notification message. Providing a handler for this message within the shortcut bar's notification target allows customization of the context menu.
The following excerpt demonstrates the usage.
 
// ATL Message map entry
MESSAGE_HANDLER(WM_TABBAR_CNTXTMENU, OnBarContextMenu)
 
LRESULT OnBarContextMenu(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
// The lParam holds a pointer to the popup menu created by the
// ShortcutBar. We can either directly modify this menu or, if
// a menu resource is available, reinitialize this menu pointer
// with a new menu. In this case, we will destroy the current
// menu, create a new one based on our menu resource and reassign
// lParam to refer to the new menu handle. This menu will be
// destroyed later on by the Shortcut Bar.
 
if((int)wParam != -1)
m_nCurrentHit = wParam;
HMENU* phMenu = (HMENU*)lParam;
DestroyMenu(*phMenu);
*phMenu = GetSubMenu(LoadMenu(_Module.GetModuleInstance(),
MAKEINTRESOURCE(IDR_SHORTCUTBAR)), 0);
return TRUE;
}