CCustomBitmapButton�MFC Button Control

CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

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