The Wayback Machine - https://web.archive.org/web/20111102122618/http://www.codeguru.com/cpp/controls/buttonctrl/advancedbuttons/article.php/c8211/CCustomBitmapButtonmdashMFC-Button-Control.htm

    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();
         }
      

    Downloads

  • CustomBitmapButtonDemo.zip
  • CustomBitmapButtonDemo_exe.zip

  • IT Offers