CTRLBARS Sample: Illustrates Custom Control Bars
The CTRLBARS sample illustrates a wide variety of customization options for control bars:
- Multiple control bars in a frame window, selective hiding and showing of control bars, and dynamic rearrangement of controls along the border of the frame window. The control bars are allocated space in the frame window according to their Z-order, which initially is the order in which they are created (see CMainFrame::OnCreate). CTRLBARS changes the Z-order of the dialog bar with the CWnd::SetWindowPos function. It hides or shows a control bar using CWnd::ShowWindow. Whenever CTRLBARS changes the Z-order or hides or shows a control bar, it calls CFrameWnd::RecalcLayout afterward so that the window real estate is reallocated to the remaining visible control bars.
- Custom toolbars, dynamic rearrangement of buttons on the toolbar, and adding controls (such as a combo box) to a toolbar. CTRLBARS demonstrates two ways of customizing a toolbar. The first toolbar, the Tool Bar, changes the arrangement of buttons between short (5 buttons) and long (10 buttons). CTRLBARS calls CToolBar::SetButtonInfo for each button to map it to a tile position on the toolbar's bitmap and to a command identification. The second toolbar, the Style Bar, illustrates replacing a toolbar button (or separator) with a control — a combo box in this example. CMainFrame::CreateStyleBar creates a 100-pixel-wide toolbar separator. It then creates the combo box (IDW_COMBO) as a child of the toolbar, and sets the position of the combo box to take the space it just allocated for the separator.
- Custom status bar, custom indicators, and sending text to the message line. For status bars, the framework automatically updates a CAP LOCK, NUM LOCK, or SCROLL LOCK indicator if you specify, for example, ID_INDICATOR_CAPS as one of the identifications passed in the indicators[ ] array to CStatusBar::SetIndicators. CTRLBARS illustrates extending the standard status bar indicators with the overstrike (OVR) state, which the user toggles with the INSERT key. This requires a message handler for the ID_TOGGLE_INSERT command (mapped to the VK_INSERT key), and a resource string (ID_INDICATOR_OVR) for the text "OVR" to be displayed when the Overstrike mode is on. The resource identification ID_INDICATOR_OVR is a predefined MFC constant.
- Dialog bar, which is a control bar whose layout is defined by a dialog resource template. As with any control bar, notifications from controls in the dialog bar are routed to the owner of the dialog bar, namely the main frame window. For example, CMainFrame::OnSelChangePalette is the handler for the CBN_SELCHANGE notification from the combo box control in a dialog bar. CMainFrame also has handlers for two of the three Hide/Show check boxes (Styles and Palette). No handler needs to be written for the third check box, Hide/Show Toolbar, since the framework provides the standard handler for ID_VIEW_TOOLBAR.
- Floating tool palette, which behaves like a toolbar but displays a two-dimensional array of tool buttons and floats as a modeless window above the owner frame window. The floating tool palette is implemented in a reusable class, CPaletteBar, derived from CToolBar. The derivation from CToolBar provides CPaletteBar with toolbar button behavior. The palette-specific behavior implemented in CPaletteBar includes:
- Floating (WS_POPUP) window style.
- Two-dimensional arrangement of the tool buttons into rows and columns: creation, painting, and button hit-testing.
- Thin (no text) title bar.
- Movable palette using a tracking rectangle.
- CTRLBARS also illustrates using ON_COMMAND_EX and ON_UPDATE_COMMAND_UI_RANGE. Many of the control bar customization options illustrated by CTRLBARS are discussed in Technical Note 31.
Building and Running the Sample
To build and run the CTRLBARS sample
- Open the solution Ctrlbars.sln.
- On the Build menu, click Build.
- On the Debug menu, click Start Without Debugging.
When you first run CTRLBARS, all the various controls are visible.
- A toolbar with 5 buttons lies immediately below the menu bar. The first button (thick up-arrow) toggles the toolbar arrangement between "Short" (5 buttons) and "Long" (10 buttons). The buttons are always inactive except this first Short/Long button and the Help button, which opens the About box.
- A second toolbar lies immediately below the first toolbar. This toolbar, called the Style Bar, is where you specify one of the following text alignment styles — Left, Centered, Right, or Justified. Selecting one of the styles has no effect other than to change the state of the Style Bar.
- A status bar lies at the bottom of the window.
- A floating palette, with a 3-by-4 array of tool buttons, lies on top of the window.
- A dialog bar lies on the left border of the window. It is a dialog bar because the layout of this control bar is defined in a dialog template resource (IDD_VIEW_SELECT).
The View menu lets you hide or show any of the first four of the controls bars. The dialog bar is always visible. The hide/show state of the Tools, Styles, and Palette control bars is immediately reflected in the Hide/Show check boxes in the dialog bar. You can also hide or show one of the other control bars by toggling its check box.
With the Dlg Bar Top command on the View menu, you can rearrange the control bars so that the dialog bar is at the top of the Z-order of the control bars. When the dialog bar is at the top, it extends along the entire left border of the window except for the menu and title bars. The left ends of the two toolbars touch the dialog bar. When the dialog bar is returned to its original Z-order position (after all of the other control bars), the top of the dialog bar touches the lower edge of the second toolbar bar, and the bottom of the dialog bar touches the upper edge of the status bar. This reflects the basic algorithm that control bars are allocated window real estate on a first-come, first-serve basis.
The Style menu lets you select one of the four text alignment styles — Left, Centered, Right, or Justified. Any selection you make is immediately reflected in the Style Bar's combo box and in the corresponding button. Similarly, you can make a selection either by choosing one of the styles in the Style Bar combo box or by pressing one of the four buttons. The new selection is immediately reflected in the states of the other controls and in the Style menu.
The Palette menu lets you change the tool arrangement of the palette from 3-by-4 to 2-by-6.
When you select a tool from the Palette, the status bar message line shows "You have selected the <type> tool," in which <type> indicates which of the 12 tools you selected. This selection is reflected in the combo box in the dialog bar. You can also select a tool using this combo box.
The status bar, in addition to showing the most recently selected tool, also shows the status of three keys — INS, CAPS LOCK, and NUM LOCK.
This sample demonstrates the following keywords:
AfxFormatString1; AfxGetApp; AfxIsValidAddress; AfxRegisterWndClass; AfxThrowResourceException; BitBlt; CBrush::CreateSolidBrush; CCmdUI::ContinueRouting; CCmdUI::Enable; CCmdUI::SetCheck; CCmdUI::SetText; CComboBox::AddString; CComboBox::Create; CComboBox::GetCurSel; CComboBox::GetLBText; CComboBox::SetCurSel; CControlBar::GetBarStyle; CControlBar::SetBarStyle; CDC::Attach; CDC::Detach; CDC::PatBlt; CDC::RectVisible; CDialogBar::Create; CDumpContext::GetDepth; CFont::CreateFontIndirect; CFrameWnd::LoadFrame; CFrameWnd::RecalcLayout; CFrameWnd::SetMessageText; CGdiObject::Attach; CObject::AssertValid; CObject::Dump; CRect::Height; CRect::InflateRect; CRect::SetRectEmpty; CRect::Width; CStatusBar::Create; CStatusBar::GetPaneInfo; CStatusBar::SetIndicators; CStatusBar::SetPaneInfo; CString::LoadString; CToolBar::CToolBar; CToolBar::CommandToIndex; CToolBar::Create; CToolBar::GetButtonInfo; CToolBar::GetItemID; CToolBar::GetItemRect; CToolBar::LoadBitmap; CToolBar::SetButtonInfo; CToolBar::SetButtons; CToolBar::SetHeight; CToolBar::SetSizes; CWinApp::InitInstance; CWinApp::OnIdle; CWnd::ClientToScreen; CWnd::CreateEx; CWnd::GetCapture; CWnd::GetClientRect; CWnd::GetDC; CWnd::GetDlgItem; CWnd::GetOwner; CWnd::GetParentFrame; CWnd::GetSafeHwnd; CWnd::GetStyle; CWnd::GetWindowRect; CWnd::Invalidate; CWnd::InvalidateRect; CWnd::OnCancelMode; CWnd::OnCreate; CWnd::OnLButtonDown; CWnd::OnLButtonUp; CWnd::OnMouseActivate; CWnd::OnMouseMove; CWnd::OnSysColorChange; CWnd::PreCreateWindow; CWnd::ReleaseDC; CWnd::SendMessage; CWnd::SetCapture; CWnd::SetFont; CWnd::SetWindowPos; CWnd::ShowWindow; CWnd::UpdateDialogControls; CWnd::UpdateWindow; CreateBitmap; CreateCompatibleBitmap; CreateCompatibleDC; CreateDIBitmap; CreatePatternBrush; CreatePen; CreateSolidBrush; DeleteDC; DeleteObject; FillRect; FindResource; FrameRect; FreeResource; GetActiveWindow; GetBValue; GetCapture; GetDC; GetDeviceCaps; GetGValue; GetNextWindow; GetObjectType; GetParent; GetRValue; GetStockObject; GetSysColor; GetSystemMetrics; GetVersion; GetWindow; HIBYTE; InvertRect; LOBYTE; LoadCursor; LoadIcon; LoadResource; LockResource; MAKEINTRESOURCE; OffsetRect; PatBlt; RGB; ReleaseCapture; ReleaseDC; SelectObject; SendMessage; SetActiveWindow; SetBkColor; SetCapture; SetROP2; SetRect; SetTextColor; StretchDIBits; UpdateWindow; free; lstrcpy; malloc; memcpy; memset
Note Some samples, such as this one, have not been modified to reflect the changes in the Visual C++ wizards, libraries, and compiler, but still demonstrate how to complete your desired task.