Click here to Skip to main content
15,881,715 members
Articles / Desktop Programming / MFC
Article

StatusBarACT

Rate me:
Please Sign up or sign in to vote.
4.85/5 (24 votes)
27 Jun 2004CPOL6 min read 117.4K   2.9K   48   14
StatusBar with auto-fit, command notifications, tooltips and cursors

StatusBarACT Demo

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.

  1. 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.
  2. 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.
  3. 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, // 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 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
    • First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
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.

Comments and Discussions

 
GeneralDoes not work Pin
Chizzidy23-Feb-10 7:38
Chizzidy23-Feb-10 7:38 
Questiondc.SetBkColor? Pin
blamond28-Apr-08 14:11
blamond28-Apr-08 14:11 
GeneralNice work Paul Pin
Michael Pearce17-Aug-05 18:50
Michael Pearce17-Aug-05 18:50 
GeneralThanks for the guidance Pin
Ron Hinthorn21-Dec-04 0:27
Ron Hinthorn21-Dec-04 0:27 
GeneralSo cool Pin
Martin S.22-Jul-04 15:42
Martin S.22-Jul-04 15:42 
GeneralCrash in GetPaneCursorIndex Pin
Tom Mason9-Feb-04 4:28
Tom Mason9-Feb-04 4:28 
GeneralHand-Cursor Pin
reiser27-May-03 20:36
reiser27-May-03 20:36 
GeneralRe: Hand-Cursor Pin
Paul Vickery27-May-03 22:34
professionalPaul Vickery27-May-03 22:34 
GeneralRe: Hand-Cursor Pin
Paul Vickery28-May-03 2:09
professionalPaul Vickery28-May-03 2:09 
GeneralRe: Hand-Cursor Pin
reiser28-May-03 3:55
reiser28-May-03 3:55 
GeneralDynamic Tooltips Pin
reiser25-Feb-03 22:23
reiser25-Feb-03 22:23 
GeneralRe: Dynamic Tooltips Pin
reiser18-Mar-03 21:39
reiser18-Mar-03 21:39 
GeneralRe: Dynamic Tooltips Pin
Paul Vickery14-Apr-03 23:33
professionalPaul Vickery14-Apr-03 23:33 
GeneralIt crashes ! Pin
Joerg Hoffmann24-Feb-03 20:16
Joerg Hoffmann24-Feb-03 20:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.