Caption Bar Interface

Environment: VC6 SP4, W2K SP1 – Does not work on Win95 with DirectX because of Transparent Bitmap drawing.

    After having this base code for about a year and a half it has finally matured to the stage where I feel that it can be used in other people’s applications. The basis of the CCaptionButton class is to create a “button-like” interface toolbar in the caption area. My original idea was to create a uniform interface with the existing windows captions (Minimize,Maximize,Close), but I decided to go the more creative route and use bitmaps which would allow me to create a unique interface rather than the same old bland captions. With this CCaptionButton was born. It uses 2 bitmaps per caption plus 1 common mousedown bitmap. You can also pass in HICONs for the captions, but they are then just converted to HBITMAPs.

The features:

  • Bitmap Image Captions
  • Icon Image Captions
  • Tooltips
  • Dynamic Replace
  • Dynamic Add
  • Dynamic Deletion
  • Caption Press notification
  • Flexible Design

    As you look through the class you may notice that some
functions that you would expect to see are missing. This is for a simple reason.
I did not need to use them during the course of creating programs with this class.
They should be quite easy to add so post an addition in the comments below.

    The initialization may seem complex, but it is actually
fairly simple. You will probably spend most of your time creating the bitmaps. For
the first 3 captions I used a technique of combining bitmaps together to create a
uniform mouseover effect. This is not necessary, but saves lots of memory in the
.exe since you don’t have to store different mouseover bitmaps for every caption.


// declare as class variable or global
CCaptionButton cbExtra;

// subclass the window
cbExtra.Init(hWnd);
// set the number of regular captions (Minimize/Maximize/Close)
cbExtra.SetNumOfDefaultCaptions(3);
// set the images transparency color
COLORREF crTransparent = RGB(255,0,255);
cbExtra.SetTransparentColor(crTransparent);
// set the bitmap to be displayed
cbExtra.SetSelectionBitmap((HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_SELECTION),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR));

// create our mouseover bitmaps (you could load them directly,
// but this way saves memory)

HBITMAP hMouseOverBitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_MOUSEOVER),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR);
// caption AM Productions
HBITMAP hCaptionAMBitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP_AM),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR);
HBITMAP hCaptionAMBitmapHilite =
CCaptionButton::CombineBitmaps(hCaptionAMBitmap,
hMouseOverBitmap, crTransparent);
// caption 2
HBITMAP hCaption2Bitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP2),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR);
HBITMAP hCaption2BitmapHilite =
CCaptionButton::CombineBitmaps(hCaption2Bitmap,
hMouseOverBitmap,crTransparent);
// caption 3
HBITMAP hCaption3Bitmap = (HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP3),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR);
HBITMAP hCaption3BitmapHilite =
CCaptionButton::CombineBitmaps(hCaption3Bitmap,
hMouseOverBitmap,crTransparent);

// create caption with ID = 1, mouseover effect bitmap of
// hCaptionAMBitmapHilite, normal bitmap of hCaptionAMBitmap,
// and tooltip text of “AM Productions – Visit Now!”

cbExtra.New(1,hCaptionAMBitmapHilite,hCaptionAMBitmap,
“AM Productions – Visit Now!”);
cbExtra.New(2,hCaption2BitmapHilite,hCaption2Bitmap,”Caption 2″);
cbExtra.New(3,hCaption3BitmapHilite,hCaption3Bitmap,”Caption 3″);
// just load it directly from the bitmap resources
cbExtra.New(4,
(HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP5),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR),
(HBITMAP)LoadImage(hInstance,
MAKEINTRESOURCE(IDB_BITMAP6),
IMAGE_BITMAP,
0,
0,
LR_LOADMAP3DCOLORS|LR_DEFAULTCOLOR),
“Caption 4”);

    At this point you may be saying “That’s all great, but
how do I know if a caption has been pressed?” Well here is your answer. When a
caption is clicked a WM_CBLBUTTONCLICKED is generated and sent to the window with
the captions. The WPARAM of this message contains the ID of the caption which was
pressed, and the LPARAM contains a POINT structure of the screen coordinates of the
cursor when the caption was clicked (good for displaying menus).

    What is with all those “Dynamic” features? Well the
CCaptionButton class has the ability to add, replace, and delete captions at
runtime. To add a caption simply call the New() function, but as a fifth parameter
specify the zero based index of where you would like to insert the caption (from
right to left). It is not much harder to replace an existing caption.

   // replacing a caption
   cbExtra.Replace(nCurrentCaptionID,
                   nNewCaptionID,
                   hNewMouseoverBitmap,
                   hNewNormalBitmap,
                   pNewToolTipText);

    Deleting a caption may seem difficult, but I’m sure that
you will get used to it.

   // deleting a caption
   cbExtra.Delete(nCurrentCaptionID);

KNOWN ISSUES:

  • Adds significant overhead to a window’s message processing
  • Flickering during window resize

UPDATES:

  • Removed the SetCaptionType() and SetWindowType()
    functions and auto-detected that information in Init().
  • Now works with child windows.
  • Example shows the use with a child window
  • Example shows the use with a modeless dialog

    I know that there is a lot of room for improvement, so
feel free to post or email comments.

Downloads

Download demo project and source – 44.3 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read