
Introduction
Most applications have a status bar of some description on their main window, and sometimes other windows. This class, derived from CStatusBar, provides several features missing from the standard class. The features it provides are as follows:
- Auto-fit of text
The panes can be set to resize as new text is set so that the text will always fit exactly.
- Command notifications to the parent window
Panes can send WM_COMMAND messages to the parent to allow actions to be invoked on clicking or double-clicking the pane.
- Tool-tips on panes
Although the standard status bar control provides tool-tip support, these are only displayed when the pane has an icon and no text, or if the text is too long to fit in the pane. The tool-tip support I have added allows tool tips to be displayed anytime the user hovers their mouse over a pane.
- Cursors for panes
You may specify the cursor to be displayed when hovering the mouse over a pane. The cursor could be used to give a visual hint of a command generated by a clicking on a pane.
How to use it
Using the CStatusBarACT class is very straightforward. Follow the steps below to add one to an existing project.
- After putting the source files (StatusBarACT.cpp and StatusBarACT.h) into the directory you wish to use them from, add the files to your Visual Studio project.
- Add
#include "StatusBarACT.h"
to the appropriate header file, depending on where you will be using CStatusBarACT. If you wish to use it in several places it makes sense to add it to your stdafx.h file.
- Anywhere where you are using a CStatusBar, it can be replaced with CStatusBarACT. The usual place to have a status bar defined is in mainfrm.h of AppWizard generated applications.
Once you have added to your project, you can start taking advantage of its features. There are a number of ways to set the status bar to behave the way you want it to. You can set the panes in the usual way using SetIndicators(), and then call SetPaneFlags() and/or SetPaneTooltip() and/or SetPaneCursor() for each pane you wish to set up, or you can replace the call to SetIndicators() with a call to SetPanes(), and pass in an array of SBACTPANEINFO structures. If you want most panes to be standard then it is simpler to set them the first way. If you want most of the panes to use the new features then it is best to use SetPanes().
Using SetPanes() allows you to add the panes, and set their tool-tips and flags with one function call. Let's assume that you have an AppWizard generated app, that has a member variable called m_wndStatusBar. You can replace the definition of
static UINT indicators[]
with something like the following:
static SBACTPANEINFO asbactpi[] =
{
{ ID_SEPARATOR, "This gives us our normal status information",
SBACTF_COMMAND | SBACTF_HANDCURSOR },
{ ID_INDICATOR_MOUSEPOS, "The current cursor position", SBACTF_AUTOFIT,
MAKEINTRESOURCE(IDC_MOUSE_CURSOR) },
{ ID_INDICATOR_CAPS, "Whether the Caps Lock is on. "
"Double-right-click or single-left-click to toggle",
SBACTF_COMMAND | SBACTF_HANDCURSOR | SBACTF_DOUBLECLICK |
SBACTF_SINGLECLICK | SBACTF_LEFTBUTTON | SBACTF_RIGHTBUTTON },
{ ID_INDICATOR_NUM, "Whether the Num Lock is on.
Double-left-click to toggle",
SBACTF_COMMAND | SBACTF_HANDCURSOR },
{ ID_INDICATOR_SCRL, "Whether the Scroll Lock is on. "
"Double-left-click to toggle, or right click for menu",
SBACTF_COMMAND | SBACTF_HANDCURSOR | SBACTF_DOUBLECLICK |
SBACTF_SINGLECLICK | SBACTF_LEFTBUTTON | SBACTF_RIGHTBUTTON },
};
Then replace
!m_wndStatusBar.SetPanes(indicators,
sizeof(indicators)/sizeof(UINT)))
with
!m_wndStatusBar.SetPanes(asbactpi,
sizeof(asbactpi)/sizeof(SBACTPANEINFO)))
Including SBACTF_AUTOFIT in the flags makes the pane resize when new text is set. The flag SBACTF_HANDCURSOR makes the cursor a hand cursor when the user moves the mouse over the pane. In order to get the status bar to send a WM_COMMAND message on mouse events, the flag SBACTF_COMMAND needs to be included. By default, this will cause a WM_COMMAND message to be sent when the user double-clicks with the left mouse button in the pane. This can be overridden to respond to any combination of double or single clicks, with the left, middle or right button, using the appropriate flags.
The status bar sends a WM_COMMAND message to the parent, with messages wParam set to the pane's ID, and the lParam set to the mouse message that caused the notification. This enables the application to respond to different clicks in different ways if required. See the demo app source code for an example of this.
Reference
Functions
The public functions in the class are as follows:
Enumerations
The flags for the panes are defined as follows:
SBACTF_NORMAL = 0x0000,
SBACTF_AUTOFIT = 0x0001, SBACTF_COMMAND = 0x0002, SBACTF_HANDCURSOR = 0x0004,
SBACTF_DOUBLECLICK = 0x0100, SBACTF_SINGLECLICK = 0x0200,
SBACTF_LEFTBUTTON = 0x1000, SBACTF_RIGHTBUTTON = 0x2000,
SBACTF_MIDDLEBUTTON = 0x4000,
SBACTF_STYLEFLAGMASK = 0x00FF, SBACTF_CLICKFLAGMASK = 0x0F00, SBACTF_BUTTONFLAGMASK = 0xF000,
Structures
The definition of the structure used to set pane information is as follows:
typedef struct SBACTPANEINFO
{
UINT nID; LPCTSTR lpszTip; DWORD dwFlags; LPCTSTR lpszCursor; }*LPSBACTPANEINFO;
History
- Version 3.1 - 24 Jun 2004
- Updated to support Unicode builds
- fixed bugs:
- using
ON_COMMAND macros causes assertion failure
- updating tip text re-adds the tool, and causes old one to overlap
- crash in
GetPaneCursorIndex() if no pane cursors set and also in
GetPaneFlagsIndex() if no pane flags set (reported by Tom Mason)
- Version 3 - 28 May 2003
- Can now specify a custom cursor for a pane
- Added ability to specify a hand cursor to use instead of the default (the default is only available on Windows 98/ME and Windows 2000/XP)
- Version 2 - 15 Apr 2003
- Extended control to allow pane tool-tips to be specified as part of the pane's text, separated by a new line ('\n') character.
- Added ability to show multi-line tool-tips by including carriage returns ('\r') and/or line breaks ('\n') in the tip text.
- Version 1 - 18 Feb 2003