Bitmapped Command Button

All buttons begin their incarnation as a member of class Cbutton, which is derived from the class CWnd. Although this class includes Radiobuttons and Checkboxes, This perticuler Discussion will focus only on the command buttons.

All dialog box control , including command buttons, have properties and styles. Button styles are recognized by their BS_Prefix. Some of the Button styles are

BS_PUSHBUTTON
BS_RADIOBUTTON
BS_AUTORADIOBUTTON
BS_3STATE
BS_AUTOSTATE
BS_CHECKBOX
BS_AUTOCHECKBOX
BS_DEFPUSHBUTTON
BS_GROUPBOX
BS_LEFTTEXT
BS_OWNERDRAW

In above all styles we mainly concentrate on BS_OWNERDRAW for creating a Bitmapped buttons.

Avery easy way to add a touch of elegance to command button is to draw them with bitmap instead of simple text descriptions. This is not only a simple procedure but there is little penalty to be paid in terms of resource consumption. The bitmaps are loaded when needed and discarded when closed.

Using a bitmap as a face of a command button can change the perception of the application. At the heart of this technique is the class CbitmapButton. Object of this class consists of up to 4 bitmaps, corresponding to each of the possible states of a button can possess.

1. Up
2. Down
3. Focused
4. Disabled

Only the bitmap for UP is required ; the rest at the discretion of the developer. For simple "OK" and "Cancel" buttons that immediately close a dialog box when clicked, this is all that is necessary. More complex dialog boxes require some or all of the other states. E.g. the application requires the user to make a selection from a combo or list box before an action completed , then application may show OK as disabled button until such selection is made, ofcourse the cancel button should always be available.

Whenever user create any bitmap for any button , pay close attention to the border of the image, because this is use to provide visual feedback to the user regarding the state of the button.

Implementing Bitmapped Buttons
New lets see how its done. There are six main step to follow in order to use a bitmapped button in a dialog box.
  1. Draw the necessary bitmaps
  2. Create the Dialog box template , positioning the buttons where desired.
  3. Declare a resource ID and button caption.
  4. Insert bitmap reference in to your .RC file
  5. Add a CBitmapButton member object to the dialogs class.
  6. Load the bitmaps in the dialogbox;s OnInitDialog() routine.

For this Discussion , App Studio is used as the drawing tool for the bitmap in order to make it easier to discuss the associated properties , resource ID, and so on. When drawing the bitmap of the buttons strive to keep them 16X16 pixels or 16X32 pixels. However they can be any size and all are treated as the same as bitmap for the Upstate. Depending upon how your dialogbox is laid out user may have to adjust the postion of the buttons in the dialog box after testing.

While in App studio assign the button a unique ID ( e.g. ID_CANCEL ,etc.) and the BS_OWNERDRAW style. User must also assign a caption to the button, even though it will be covered by the bitmap. This is very important because this caption is related to the name of the bitmap that become the face of the button. The framework looks for the letter U, D, F and X appended to the caption of the button which signify Up, Down, Focus and Disable respectively. Lets say user give the button the caption "CANCEL". In resource file (.RC), user must have a bitmap with the ID, "CANCELU" for upstate of button, a "CANCELD" for down state of button, "CANCELF" for focus state of button and "CANCELX" for disable state of button. Thus the .RC file might contain the following declaration for the Cancel button having four states:

CANCELUBITMAP DISCARDABLE "RES\\CANCELU.BMP"
CANCELDBITMAP DISCARDABLE "RES\\CANCELD.BMP"
CANCELFBITMAP DISCARDABLE "RES\\CANCELF.BMP"
CANCELXBITMAP DISCARDABLE "RES\\CANCELX.BMP"

If suppose the ID of button on the dialog box is IDCANCEL which is default ID for cancel then user just have to create one Bitmap in that case the .RC file contain only one string like this :

CANCELUBITMAP DISCARDABLE "RES\\CANCELU.BMP"

In the same way if button id is IDOK then .RC file can have one resource entry and this is:

OKUBITMAP DISCARDABLE "RES\\OKU.BMP"

Now lets see how we can do this ::

In your project Add one dialog box with two button as show in the first diagram for button "ok" give resource ID "IDOK" and for button "cancel" give resource ID "IDCANCEL" which are default resource ID for "ok" and "Cancel".

Insert bitmap for "OKU" and "CANCELU" of size 16X32 or whatever size you want. You can also have bitmap for "OKD", "OKF", "OKX", "CANCELD","CANCEF" and "CANCELX" that up to the developer and the requirement of the application.

Now derive a class CBitmapDlg from CDialog.

The modification to the file BitmapDlg.h are shown here in bold typeface :

class CBitmapDlg : public CDialog
{
// Construction
public:
 // standard constructor
 CBitmapDlg(CWnd* pParent = NULL);   

// Dialog Data
 //{{AFX_DATA(CBitmapDlg)
 enum { IDD = IDD_BITMAPDLG };
CBitmapButton m_Cancel; CBitmapButton m_Ok;
//}}AFX_DATA // Implementation }

The last thing to do is change the OnInitDialog() routine for CBitmapDlg. It will look like this:

BOOL CBitmapDlg::OnInitDialog()
{
 m_Ok.AutoLoad(IDOK, this);
 m_Cancel.AutoLoad(IDCANCEL, this);
 // Additional statement goes here
}

Thats all there is to it. When the dialog box is activated the buttons will have the bitmaps attached. Notice that developer do not have to explicitly load each bitmap for each of the four states of the button this is handled automatically by the framework routine AutoLoad(). If you want to know what exactly this AutoLoad() routine is doing mail me I will send you the completed internal concept.

Now user can use the member routine function to activate and deactivate the buttons like:

// it will show the bitmap "OKU" on "Ok" button
m_Ok.EnableWindow(TRUE); 	

// it will show the bitmap "OKX" on "Ok" button
m_OK.EnableWindow(FALSE); 	

in this way user can have a new look to the Dialog Box.

Downloads

Download source - 46 Kb