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);
<P>Sets a pane's tool-tip text by the pane's index. <CODE>lpszText
is a text string to use for the tip. nTipID
is a resource string ID from which to load the string
BOOL SetPaneTooltip(UINT nID, LPCTSTR lpszText = NULL);
- <codebool code="" ntipid);<="" uint="" nid,="" setpanetooltip(uint="">
<P>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
is TRUE
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. If bTryDefault
is FALSE
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,
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
Originally from an electronics background, I moved into software in 1996, partly as a result of being made redundant, and partly because I was very much enjoying the small amount of coding (in-at-the-deep-end-C) that I had been doing!
I swiftly moved from C to C++, and learned MFC, and then went on to real-time C on Unix. After this I moved to the company for which I currently work, which specialises in Configuration Management software, and currently program mainly in C/C++, for Windows. I have been gradually moving their legacy C code over to use C++ (with STL, MFC, ATL, and WTL). I have pulled in other technologies (Java, C#, VB, COM, SOAP) where appropriate, especially when integrating with third-party products.
In addition to that, I have overseen the technical side of the company website (ASP, VBScript, JavaScript, HTML, CSS), and have also worked closely with colleagues working on other products (Web-based, C#, ASP.NET, SQL, etc).
For developing, I mainly use Visual Studio 2010, along with an in-house-designed editor based on Andrei Stcherbatchenko's
syntax parsing classes, and various (mostly freeware) tools. For website design, I use Dreaweaver CS3.
When not developing software, I enjoy listening to and playing music, playing electric and acoustic guitars and mandolin.