Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / MFC
Article

CCustomBitmapButton - MFC Bitmap Button

Rate me:
Please Sign up or sign in to vote.
4.69/5 (25 votes)
17 Sep 20046 min read 313.8K   9.7K   98   53
An owner-draw bitmap button and a frame for the caption bar, in one class.

Sample Image - CustomBitmapButtonDemo.jpg

Introduction

CCustomBitmapButton is an 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 a 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
  • Flicker-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 dialog class header where class CCustomBitmapButton 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.

    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"));
        }
  6. 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, 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));
        }
        ....
  7. 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();
        }

CCustomBitmapButton class members

Construction/Destruction

CCustomBitmapButtonConstructs a CCustomBitmapButton object.
CreateCreates a bitmap button and attaches it to an instance of a CCustomBitmapButton object.
CreateCaptionFrameCreates a caption frame.
DestroyCaptionFrameDestroys a caption frame.

Attributes

GetCaptionButtonPtrRetrieves the pointer to the caption button.
SetTooltipTextChanges the tooltip text of a button.
GetBkStyleRetrieves information about the button control background style.
SetBkStyleChanges the background style of a button.
GetGlyphBitmapRetrieves the handle of the glyph bitmap previously set with SetGlyphBitmap.
SetGlyphBitmapSpecifies a glyph bitmap to be displayed on the button.
EnableWindowEnables or disables the button.

Operations

AddCaptionButtonInserts a new button in a caption bar.

CCustomBitmapButton::CCustomBitmapButton

CCustomBitmapButton( );

Remarks

Call this function to construct a CCustomBitmapButton object.

CCustomBitmapButton::Create

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

Return Value

TRUE if initialization of the object was successful, otherwise FALSE.

Parameters

  • dwStyle - Specifies the button style.
  • rect - Specifies the button size and position. It can be either a CRect object or a RECT structure.
  • pParentWnd - Specifies the button parent window.
  • nID - Specifies the button ID.

Remarks

Creates a bitmap button and attaches it to an instance of a CCustomBitmapButton object.

CCustomBitmapButton::CreateCaptionFrame

int CreateCaptionFrame( CWnd* pCaptionWnd, int nIDIcon );

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

  • pCaptionWnd - Specifies the caption bar owner window.
  • nIDIcon - Specifies the caption icon resource ID.

Remarks

Creates a caption frame.

CCustomBitmapButton::DestroyCaptionFrame

int DestroyCaptionFrame();

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Remarks

Destroys a caption frame.

CCustomBitmapButton::GetCaptionButtonPtr

CCustomBitmapButton* GetCaptionButtonPtr( int nButtonID ) const;

Return Value

Pointer to the CCustomBitmapButton object if successful, otherwise NULL.

Parameters

  • nButtonID - The ID of the caption button.

Remarks

Call this function to retrieve the pointer to the caption button.

CCustomBitmapButton::SetTooltipText

int SetTooltipText( CString sText );

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

  • sText - Pointer to a string object that contains the new tooltip text.

Remarks

This function changes the tooltip text of a button.

CCustomBitmapButton::GetBkStyle

int GetBkStyle();

Return Value

Returns the button background style for this CCustomBitmapButton object.

Remarks

Call this function to retrieve information about the button control background style.

CCustomBitmapButton::SetBkStyle

int SetBkStyle( int nBkStyle );

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

nBkStyle - Specifies the button background style.

Supported background styles:

  • CBNBKGNDSTYLE_CAPTION - frame buttons
  • CBNBKGNDSTYLE_CLOSE
  • CBNBKGNDSTYLE_MDI
  • CBNBKGNDSTYLE_COMBO - combobox dropdown button
  • CBNBKGNDSTYLE_SPINUP - spin buttons
  • CBNBKGNDSTYLE_SPINDN
  • CBNBKGNDSTYLE_SPINUPHOR
  • CBNBKGNDSTYLE_SPINDNHOR
  • CBNBKGNDSTYLE_SCROLLUP - scrollbar buttons
  • CBNBKGNDSTYLE_SCROLLDOWN
  • CBNBKGNDSTYLE_SCROLLLEFT
  • CBNBKGNDSTYLE_SCROLLRIGHT

Remarks

Changes the background style of a button.

CCustomBitmapButton::GetGlyphBitmap

HBITMAP GetGlyphBitmap();

Return Value

A handle to a bitmap. NULL if no bitmap is previously specified.

Remarks

Call this member function to get the handle of a glyph bitmap that is associated with a button.

CCustomBitmapButton::SetGlyphBitmap

int SetGlyphBitmap( HBITMAP hBmpGlyph );

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

  • hBmpGlyph - The handle of a bitmap.

Remarks

Call this member function to associate a new glyph bitmap with the button.

CCustomBitmapButton::EnableWindow

int EnableWindow( BOOL bEnable = TRUE);

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

  • bEnable - Specifies whether the given window is to be enabled or disabled. If this parameter is TRUE, the window will be enabled. If this parameter is FALSE, the window will be disabled.

Remarks

Call this function to enable or disable a button control.

CCustomBitmapButton::AddCaptionButton

int AddCaptionButton( LPCRECT lpRect, UINT nID, int nBkStyle, BOOL fUserDefWidth );

Return Value

CBNERRR_NOERROR if successful, otherwise CBNERRR_ERRORCODE.

Parameters

  • lpRect - Specifies the button width if fUserDefWidth is true, otherwise ignored.
  • nID - Specifies the button ID.
  • nBkStyle - Specifies the button background style.
  • fUserDefWidth - If TRUE - user defined button width.

Remarks

Call this function to insert a new button in an existing caption bar.

Notification Messages

The following notification codes are supported by the button control:

  • NM_CLICK - User clicked left mouse button in the control.
  • NM_RCLICK - User clicked right mouse button in the control.
  • NM_DBLCLK - User double clicked left mouse button in the control.
  • NM_RDBLCLK - User double clicked right mouse button in the control.

Error Codes

The following errors can be returned by the button control functions:

  • CBNERRR_NOERROR - Operation successful.
  • CBNERR_OUTOFMEMORY - Function call failed because there was not enough memory available.
  • CBNERR_INCORRECTPARAMETER - Function call failed because an incorrect function parameter was specified.
  • CBNERR_INCORRECTBUTTONSTYLE - Function call failed because an incorrect button style was specified.
  • CBNERR_INCORRECTFRAMESTYLE - Function call failed because the WS_CAPTION style was not specified.
  • CBNERR_INCORRECTFUNCCALL - Incorrect function call (for example: ob.SetTooltipText(...) where ob is an instance of the caption frame object).
  • CBNERR_CREATEBUTTONFAILED - Function call failed because creation of the button control failed.
  • CBNERR_CREATETOOLTIPCTRLFAILED - Function call failed because creation of the tooltip control failed.
  • CBNERR_COPYIMAGEFAILED - Function call failed because copying of the glyph image failed.
  • CBNERR_SETWINDOWLONGFAILED - Call to the function SetWindowLong failed.
  • CBNERR_FRAMEALREADYCREATED - Function call failed because the caption frame was already created.
  • CBNERR_FRAMENOTCREATED - Function call failed because the caption frame was not created.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionColor bitmaps Pin
Ed The C21-Jun-19 6:56
Ed The C21-Jun-19 6:56 
BugProvided demo exe totally fails on Windows 10. The project itself also fails to compile. Pin
dc_200027-Apr-17 18:05
dc_200027-Apr-17 18:05 
QuestionRedefinition errors Pin
masteryoda2114-Aug-15 12:52
masteryoda2114-Aug-15 12:52 
AnswerRe: Redefinition errors Pin
dc_200027-Apr-17 17:54
dc_200027-Apr-17 17:54 
BugOn Win7 when you press 'Enter' or 'Esc', the demo project will terminate. Pin
kissLife15-Dec-13 16:53
kissLife15-Dec-13 16:53 
GeneralProblem: WM_ACTIVATE always returns 0 Pin
are_all_nicks_taken_or_what9-Mar-09 23:34
are_all_nicks_taken_or_what9-Mar-09 23:34 
QuestionProblem under Vista x64 Pin
Bojan Hrnkas15-Dec-08 5:10
Bojan Hrnkas15-Dec-08 5:10 
GeneralBuggy! Pin
are_all_nicks_taken_or_what21-May-08 3:47
are_all_nicks_taken_or_what21-May-08 3:47 
GeneralYay Pin
greertr19-Nov-06 10:40
greertr19-Nov-06 10:40 
QuestionVista Caption Buttons? Pin
lfrequency9-Nov-06 18:23
lfrequency9-Nov-06 18:23 
AnswerRe: Vista Caption Buttons? Pin
jung-kreidler19-Jul-07 23:05
jung-kreidler19-Jul-07 23:05 
GeneralRe: Vista Caption Buttons? Pin
jung-kreidler19-Jul-07 23:41
jung-kreidler19-Jul-07 23:41 
GeneralRe: Vista Caption Buttons? Pin
jung-kreidler26-Jul-07 4:38
jung-kreidler26-Jul-07 4:38 
GeneralRe: Vista Caption Buttons? Pin
Bojan Hrnkas17-Jun-08 4:28
Bojan Hrnkas17-Jun-08 4:28 
GeneralRe: Vista Caption Buttons? Pin
jung-kreidler17-Jun-08 4:37
jung-kreidler17-Jun-08 4:37 
GeneralRe: Vista Caption Buttons? Pin
Bojan Hrnkas18-Jun-08 1:44
Bojan Hrnkas18-Jun-08 1:44 
QuestionRe: Vista Caption Buttons? Pin
Bojan Hrnkas18-Jun-08 3:00
Bojan Hrnkas18-Jun-08 3:00 
AnswerRe: Vista Caption Buttons? Pin
Bojan Hrnkas18-Jun-08 3:06
Bojan Hrnkas18-Jun-08 3:06 
GeneralRe: Vista Caption Buttons? Pin
Bojan Hrnkas19-Jun-08 3:04
Bojan Hrnkas19-Jun-08 3:04 
GeneralBug found! Pin
Eugene Podkopaev21-Jun-06 1:33
Eugene Podkopaev21-Jun-06 1:33 
This bug applies to switching from Windown XP theme to classic theme and back and can be repeated in these steps:
1. Turn on Windows XP theme (I tried in Blue)
2. Start your CustomBitmapButtonDemo app
3. Switch to Windows Classic theme. Look, close button in CustomBitmapButtonDemo app changed its size and gets smaller.
4. Switch back to Windows XP theme. Look at close button again, its size don't get back to square but rectangular, its vertical side is more than horizontal.

Please help me to solve this issue.

BTW, in Olive theme, bitmaps are not just monochrome, they appears with shadows on reliefs. How this can be implemented in CCustomBitmapButton class?

Thank you in advance.
Good luck!
GeneralRe: Bug found! Pin
Eugene Podkopaev22-Jun-06 1:09
Eugene Podkopaev22-Jun-06 1:09 
QuestionLicense? Pin
Geert van Horrik19-Apr-06 3:45
Geert van Horrik19-Apr-06 3:45 
AnswerRe: License? Pin
Andrzej Markowski21-Apr-06 18:39
Andrzej Markowski21-Apr-06 18:39 
QuestionWTL CCustomBitmapButton? Pin
skankwilson9-Nov-05 9:35
skankwilson9-Nov-05 9:35 
AnswerRe: WTL CCustomBitmapButton? Pin
lyshsd1-Apr-06 1:24
lyshsd1-Apr-06 1:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.