CAtlBitmapButton - ATL/WTL Ownerdraw Superclassed Bitmap Button

Environment: VC++, ATL/WTL

Introduction

Recently, in one of my projects, I needed to build a simple user interface consisting of a series of bitmap buttons in a dialog. Something simple and probably easy to use. About the same time, I came across David Pizzolato's very nice article on skinned button at codeproject.com, that got me thinking. What came out of the whole endevour was CAtlBitmapButton - an ATL/WTL ownerdrawn superclassed bitmap button. The class is not really complete and represents work in progress. I'll be glad if any of you find this useful :-).

CAtlBitmapButton class is very friendly and you can learn to use it in no time. The hardest part might be drawing the bitmaps (if you are as artistically challenged as I am !).

Now let's get down to the basics. We'll be building an ATL/WTL Dialog-based application so I assume you are slightly familiar with ATL/WTL and ATL Windowing.

         

How to use

To build the client, fire up Visual C++ and create a new Win32 application . Next we shall rig up ATL support to the project. Since we'd like to have ATL Wizard support, just follow the instructions step-by-step. If you already know how to do this, you can skip this part. First, in project's stdafx.h file, replace:

 #include <windows.h>
with
#define RICHEDIT_VER 0x0100
#include <atlbase.h> 
extern CComModule _Module;
#include <atlcom.h>
#include <atlwin.h> #include <atlapp.h> #include <atlctrls.h>

Now add a new IDL file to the project that contains a blank library definition block like

library <Project Name>
{



};  

Now, in ClassView, right-click the IDL file you just added, and choose Settings. In the General tab of the project settings dialog, check the Exclude file from build option.

Next modify your projects .cpp file so that it looks like:

CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
   // TODO: Place code here.
   _Module.Init(0, hInstance);
   
   
   _Module.Term();
   return 0;
}

Having rigged up ATL/WTL support, goto Insert->New ATL Object. In the Miscellaneous category, choose Dialog and click on Next.Enter the short name as Dialog.

In the dialog resource, add 4 buttons(IDC_BUTTON1,IDC_BUTTON2,IDC_BUTTON3 and IDC_BUTTON4) and set the Ownerdraw properties of these buttons to true. You would also need to add a few bitmaps to the project such that each button has three state bitmaps (Selected, Down and Over).

Add the file, CAtlBitmapButton.h to the project. In ClassView, right click the dialog class and add four member variables of type CAtlBitmapButton to it like

 CAtlBitmapButton m_button1,m_button2,m_button3,m_button4;

In the dialog's OnInitDialog(), add the following code :

 m_button1.SubclassWindow(GetDlgItem(IDC_BUTTON1));
 m_button1.LoadStateBitmaps(IDB_LOADU, IDB_LOADD, IDB_LOAD);
 
 m_button2.SubclassWindow(GetDlgItem(IDC_BUTTON2));
 m_button2.LoadStateBitmaps(IDB_PLAYU, IDB_PLAYD, IDB_PLAY);

 m_button3.SubclassWindow(GetDlgItem(IDC_BUTTON3));
 m_button3.LoadStateBitmaps(IDB_SAVEU, IDB_SAVED, IDB_SAVE);
 
 m_button4.SubclassWindow(GetDlgItem(ID_BUTTON4));
 m_button4.LoadStateBitmaps(IDB_QUITU, IDB_QUITD, IDB_QUIT);

CAtlBitmapButton has a method LoadStateBitmaps() to load the state bitmaps. The last thing to do is to add the ATL macro REFLECT_NOTIFICATIONS() to the dialog's message map like:


  BEGIN_MSG_MAP(CDialog)
  MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
  COMMAND_ID_HANDLER(IDOK, OnOK)
  COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  COMMAND_ID_HANDLER(ID_QUIT, OnQuit)
  REFLECT_NOTIFICATIONS()
  END_MSG_MAP() 

Build the project and run it. Check that the buttons are displaying the correct state bitmap. To handle button-clicks. use ATL macro COMMAND_ID_HANDLER() in the messagemap as shown in above code for the OK and Cancel button. OnCancel looks like:

LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
    EndDialog(wID);
    return 0;
}

That's it. Yippee!
Have fun.

Acknowledgements: David Pizzolato.

Downloads

Download source - AtlBitmapButton Source - 48 Kb


Comments

  • Need Help

    Posted by Legacy on 03/20/2003 12:00am

    Originally posted by: Anthony Low

    Hello...

    What other ways to make the color constrast to suit the background of the website?

    Anthony Low

    Reply
  • How to creat the button more attractive?

    Posted by Legacy on 02/05/2003 12:00am

    Originally posted by: Anthony Low

    Hi,
    The GUI of the buttons are dull and unattractive. Anyone here has any idea to crea the button more attractive and userfiendly ?

    Reply
  • WTL CBitmapButton exists in WTL 7.0

    Posted by Legacy on 05/29/2002 12:00am

    Originally posted by: Sergey

    This class is already implemented by Microsoft in atlctrlx.h

    Reply
  • How to dynamically create the button in application

    Posted by Legacy on 05/18/2002 12:00am

    Originally posted by: Limou

    for example, if I will use this CAtlBitmapButton in a dialog-based application, how can I use the create function.

    Reply
  • bitmapbutton

    Posted by Legacy on 10/22/2001 12:00am

    Originally posted by: manish

    please tell me how can add bitmapbutton in my button if i load bitmapbutton it has not acttive
    manish

    Reply
  • help me !

    Posted by Legacy on 07/10/2001 12:00am

    Originally posted by: Trith Tohue

    Dear all!
    I need a helping , I can't write codes for change buton which is dynamic's bitmaps in my button is not moving.

    Reply
  • Compile Error

    Posted by Legacy on 07/03/2001 12:00am

    Originally posted by: Bench

    I try to compile the sample with VC 6.0(sp4) and failed. The error is:
    fatal error C1083: Cannot open include file: 'atlapp.h': No such file or directory
    What should I do?
    Thanks

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • With JRebel, developers get to see their code changes immediately, fine-tune their code with incremental changes, debug, explore and deploy their code with ease (both locally and remotely), and ultimately spend more time coding instead of waiting for the dreaded application redeploy to finish. Every time a developer tests a code change it takes minutes to build and deploy the application. JRebel keeps the app server running at all times, so testing is instantaneous and interactive.

  • The exponential growth of data, along with virtualization, is bringing a disruptive level of complexity to your IT infrastructure. Having multiple point solutions for data protection is not the answer, as it adds to the chaos and impedes on your ability to deliver consistent SLAs. Read this white paper to learn how a more holistic view of the infrastructure can help you to unify the data protection schemas by properly evaluating your business needs in order to gain a thorough understanding of the applications …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds