CCustomBitmapButton�MFC Button Control

Introduction

CCustomBitmapButton is MFC control derived from the CWnd class. The button has two parts: a background and a foreground. If the operating system is WinXP and XP Themes are enabled the background is a bitmap loaded from the current active theme resource file (I use similar technique to draw the scroll buttons in the CCustomTabCtrl control); otherwise, the “DrawFrameControl” function is used to draw the button background. The foreground is a user-defined monochrome bitmap (glyph) drawn transparently on the button background.

Supported features:

  • Standard or XP Themes view
  • 12 predefined background styles
  • User-defined foregrounds (bitmap glyphs)
  • Button states supported: “NORMAL”,”HOT”,”PRESSED”, and “DISABLED”
  • Buttons can be created in the caption bar area
  • Dialog, SDI and MDI support for the caption buttons
  • Ficker-free drawing
  • Built-in tooltips

Using the Code

To integrate the CCustomBitmapButton class into your application as a caption frame, please follow the steps below:

  1. Add ThemeUtil.h, ThemeUtil.cpp, CustomBitmapButton.h, CustomBitmapButton.cpp, Tmschema.h, and Schemadef.h to your project.
  2. Include CustomBitmapButton.h to the appropriate header file—usually the dialog class header where the CCustomBitmapButton class is used.
    //  CustomBitmapButtonDemoDlg.h : header file
       #include "CustomBitmapButton.h"
    
  3. Declare m_ctrlCaptionFrame object of type CCustomBitmapButton in your dialog header.
    //  CustomBitmapButtonDemoDlg.h : header file
       class CCustomBitmapButtonDemoDlg : CDialog
       {
          ......
       private:
          CCustomBitmapButton m_ctrlCaptionFrame;
       };
    
  4. Create the caption frame.

    In your dialog’s OnInitDialog, add the following code:

    //  CustomBitmapButtonDemoDlg.cpp : definition file
       m_ctrlCaptionFrame.CreateCaptionFrame(this,IDR_MAINFRAME);
    
  5. After creating the caption frame, add as many buttons as you need.
  6. To add caption buttons, call AddCaptionButton in your dialog’s OnInitDialog:

    //  CustomCaptionButtonDemoDlg.cpp : definition file
       m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,0,0),1,
          CBNBKGNDSTYLE_CLOSE, FALSE);
       m_ctrlCaptionFrame.AddCaptionButton(CRect(0,0,150,0),2,
          CBNBKGNDSTYLE_CAPTION, TRUE);
       CCustomBitmapButton* pBn1 =
          m_ctrlCaptionFrame.GetCaptionButtonPtr(1);
       if(pBn1)
       {
          CBitmap bmpGlyph1;
          bmpGlyph1.LoadBitmap(IDB_GLYPH1);
          pBn1->SetGlyphBitmap(bmpGlyph1);
          pBn1->SetTooltipText(_T("Double click to close the
                                   window, Right click to
                                   display the popup menu"));
       }
       CCustomBitmapButton* pBn2 =
          m_ctrlCaptionFrame.GetCaptionButtonPtr(2);
       if(pBn2)
       {
          CBitmap bmpGlyph2;
          bmpGlyph2.LoadBitmap(IDB_GLYPH2);
          pBn2->SetGlyphBitmap(bmpGlyph2);
          pBn2->SetTooltipText(_T("Articles by Andrzej
                                   Markowski"));
       }
    
  7. Process WM_NOTIFY messages from the caption buttons in your dialog class. As users click a button, the button sends notification messages (NM_CLICK, NM_RCLICK, NM_DBLCLK, and NM_RDBLCLK) to its parent window. Handle these messages if you want to do something in response.
    //  CustomBitmapButtonDemoDlg.cpp : definition file
       BEGIN_MESSAGE_MAP(CCustomBitmapButtonDemoDlg, CDialog)
       //{{AFX_MSG_MAP(CCustomBitmapButtonDemoDlg)
       ON_NOTIFY(NM_DBLCLK, 1, OnBnDblClickedCaptionbn1)
       ON_NOTIFY(NM_RCLICK, 1, OnBnRClickedCaptionbn1)
       ON_NOTIFY(NM_CLICK,  2, OnBnClickedCaptionbn2)
       //}}AFX_MSG_MAP
       END_MESSAGE_MAP()
       ....
       void CCustomBitmapButtonDemoDlg::
          OnBnDblClickedCaptionbn1(NMHDR * pNotifyStruct,
                                   LRESULT * result)
       {
          CPoint pt;
          ::GetCursorPos(&pt);
          PostMessage(WM_SYSCOMMAND,SC_CLOSE,MAKEWORD(pt.x,pt.y));
       }
       ....
    
  8. Don’t forget to destroy the caption frame; otherwise, you will have memory leaks.
    //  CustomBitmapButtonDemoDlg.cpp : definition file
    
       void CCustomBitmapButtonDemoDlg::OnDestroy()
       {
          m_ctrlCaptionFrame.DestroyCaptionFrame();
          CDialog::OnDestroy();
       }
    

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read