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


Comments

  • fine

    Posted by Legacy on 06/29/2001 12:00am

    Originally posted by: Raghu Rama sarma

    It is superb
    

    Reply
  • Use with OnUpdateCmdUI

    Posted by Legacy on 04/30/2001 12:00am

    Originally posted by: Gabriel Murillo

    Soemthing that would be wonderful is the capability to update the state of the button using OnUpdateCmdUI or something like that. This way the button could dynamically be enabled and disabled instead of deleting and adding.

    Thanks

    Gabriel

    Reply
  • Using with MFC Child Windows?

    Posted by Legacy on 04/26/2001 12:00am

    Originally posted by: Gabriel Murillo

    Can this be used with Child Windows? I can make it work with my Main App Window, but How can I make it work with a child window?

    Thanks

    Gabriel

    Reply
  • How to...?

    Posted by Legacy on 04/19/2001 12:00am

    Originally posted by: Vivek

    Hi,
    I want to add a button on a toolbar window(next to close button) when it is on the fly. Any help how to do that?

    Thanks,
    Vivek

    Reply
  • Caption Bar Interface

    Posted by Legacy on 04/18/2001 12:00am

    Originally posted by: Scott Stringham

    Perhaps a CImageList would be better suited for this class. It would make the init code much simpler. This would allow it to work in Win95 as well.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • Live Event Date: September 10, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild". This loop of continuous delivery and continuous feedback is …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds