StatusBarACT






4.85/5 (22 votes)
StatusBar with auto-fit, command notifications, tooltips and cursors
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:
CStatusBarACT();
Standard empty constructor
BOOL SetPanes(LPSBACTPANEINFO lpsbactpi, UINT nPaneInfoCount);
Called to add panes to the status bar
BOOL SetPane(LPSBACTPANEINFO lpsbactpi);
Called to modify a pane
BOOL SetPaneTooltipIndex(int nIndex, LPCTSTR lpszText = NULL);
BOOL SetPaneTooltipIndex(int nIndex, UINT nTipID);
is a text string to use for the tip.Sets a pane's tool-tip text by the pane's index. <CODE>lpszText
nTipID
is a resource string ID from which to load the stringBOOL SetPaneTooltip(UINT nID, LPCTSTR lpszText = NULL);
Sets a pane's tool-tip text by the pane's ID. <CODE>lpszText is a text string to use for the tip.
nTipID
is a resource string ID from which to load the string.BOOL SetPaneFlagsIndex(int nIndex, DWORD dwFlags = SBACTF_NORMAL);
Sets the flags for a pane by the pane's index
BOOL SetPaneFlags(UINT nID, DWORD dwFlags = SBACTF_NORMAL);
Sets the flags for a pane by the pane's ID
DWORD GetPaneFlagsIndex(int nIndex);
Gets the flags for a pane by the pane's index
DWORD GetPaneFlags(UINT nID);
Gets the flags for a pane by the pane's ID
BOOL SetPaneCursorIndex(int nIndex, HCURSOR hCursor);
BOOL SetPaneCursorIndex(int nIndex, UINT nCursorID);
BOOL SetPaneCursorIndex(int nIndex, LPCTSTR lpszCursor);
Sets a pane's cursor to the specified cursor, by the pane's index.
BOOL SetPaneCursor(UINT nID, HCURSOR hCursor);
BOOL SetPaneCursor(UINT nID, UINT nCursorID);
BOOL SetPaneCursor(UINT nID, LPCTSTR lpszCursor);
Sets a pane's cursor to the specified cursor, by the pane's ID.
HCURSOR GetPaneCursorIndex(int nIndex);
Retrieves the cursor handle for a specified pane by the pane's index
HCURSOR GetPaneCursor(UINT nID);
Retrieves the cursor handle for a specified pane by the pane's ID
void SetHandCursor(HCURSOR hCursor, BOOL bTryDefault = TRUE);
BOOL SetHandCursor(LPCTSTR lpszCursorID, BOOL bTryDefault = TRUE);
BOOL SetHandCursor(UINT nCursorID, BOOL bTryDefault = TRUE);
Sets a cursor to use for the hand cursor. If
bTryDefault
isTRUE
then the built-in hand cursor is attempted to be loaded first. If this is not available, and an alternative has been specified then this is used. IfbTryDefault
isFALSE
then the specified cursor is used for the hand cursor regardless of whether the built-in cursor is available. The built-in hand cursor is only available in Windows 98/ME or Window 2000/XP.void AutoFitPane(int nIndex);
Re-sizes the specified pane to exactly fit its text
Enumerations
The flags for the panes are defined as follows:
SBACTF_NORMAL = 0x0000, SBACTF_AUTOFIT = 0x0001, // autosize as the text changes SBACTF_COMMAND = 0x0002, // send a WM_COMMAND message // to the parent frame SBACTF_HANDCURSOR = 0x0004, // show a hand cursor when the // mouse is over the pane // which clicks will send commands (only valid if SBACTF_COMMAND specified) SBACTF_DOUBLECLICK = 0x0100, // default if none specified SBACTF_SINGLECLICK = 0x0200, // which buttons will send commands (only valid if SBACTF_COMMAND specified) SBACTF_LEFTBUTTON = 0x1000, // default if none specified SBACTF_RIGHTBUTTON = 0x2000, SBACTF_MIDDLEBUTTON = 0x4000, SBACTF_STYLEFLAGMASK = 0x00FF, // mask for 'style' flags SBACTF_CLICKFLAGMASK = 0x0F00, // mask for click flags SBACTF_BUTTONFLAGMASK = 0xF000, // mask for button flags
Structures
The definition of the structure used to set pane information is as follows:
typedef struct SBACTPANEINFO { UINT nID; // pane command ID LPCTSTR lpszTip; // text for pane tooltip DWORD dwFlags; // pane flags (see above) LPCTSTR lpszCursor; // custom cursor, if specified }*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 inGetPaneFlagsIndex()
if no pane flags set (reported by Tom Mason)
- using
- 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
- First version