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

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

Most Popular Programming Stories

More for Developers

RSS Feeds