Click here to Skip to main content
15,879,348 members
Articles / Desktop Programming / WTL
Article

WTL - Button Menu

Rate me:
Please Sign up or sign in to vote.
3.50/5 (2 votes)
13 Aug 2000 111.7K   2.2K   28   11
Use WTL to create simple button that implements drop-down menu

Sample Image - ButtonMenu.gif

DevStudio's Tools|Customize menu displays a dialog box that contains a button control with an arrow on it. When pressed, the button will display a drop-down menu. I needed this feature in my ATL applications, but didn't want the overhead of MFC or the headache of Win32. So I borrowed from Norm Almond's excellent example of Cool Push Menu Button and ported it to WTL, simplifying it's functionality along the way. I'm not implying anything was wrong with what Norm developed...the control just did more than I needed it to. I will eventually port his entire control to WTL, when time allows.

Caveats

CButtonMenu is derived from CButtonMenuImpl. To draw the arrow on the button, CButtonMenuImpl needs to have the BS_OWNERDRAW style set. However, this will send the WM_DRAWITEM msg to the parent of the CButtonMenuImpl, and not the CButtonMenuImpl itself. By subclassing the parent HWND, the CButtonMenuImpl can hijack the msg and handle it alone. To do this, the CButtonMenuImpl has a private member CContainedWindow variable that subclasses the parent. Then, using the ALT_MSG_MAP() macro, we can catch the msg:

C++
class CButtonMenuImpl : ...
{
CContainedWindow m_Parent;
public:
    CButtonMenuImpl():
      m_Parent(this,1){}

    {other code}
protected:
    typedef CWindowImpl<T, TBase, TWinTraits> baseClass;
    BEGIN_MSG_MAP(CButtonMenuImpl)
        other msgs
    ALT_MSG_MAP(1)
        MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
    END_MSG_MAP()
        {other code}

};
Finally, to make simple use of this control, CButtonMenu provides an operator overload:
C++
class CButtonMenu : public CButtonMenuImpl<CButtonMenu>
{
public:
    DECLARE_WND_SUPERCLASS(_T("WTL_CButtonMenu"), GetWndClassName())
//ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
    CButtonMenu& operator=(HWND hWnd)
    {
        if ( m_hWnd )
            DestroyWindow();
        if ( ::IsWindow(hWnd) )
            SubclassWindow(hWnd);
        return *this;
    }
};
Here's an example of how to initialize a CButtonMenu with a button already on a dialog:
C++
// Member variable of dialog
CButtonMenu btnMenu;

// Somewhere in WM_INITDIALOG handler
btnMenu = GetDlgItem(IDC_BTN_ABOUT);
btnMenu.AddMenuItem(IDC_MNU_ONE,"Windows");
btnMenu.AddMenuItem(IDC_MNU_TWO,"Template");
btnMenu.AddMenuItem(IDC_MNU_THREE,"",MF_SEPARATOR);
btnMenu.AddMenuItem(IDC_MNU_FOUR,"Library");
When the user selects a menu item, a msg will be sent to the dialog.

Deficiencies

  • Doesn't provide a Create method that will initialize the control properly (yet)
  • Doesn't respond to the BS_DEFPUSHBUTTON flag

    History

    August 14, 2000 - Fixed the OnDraw method to use the DRAWITEMSTRUCT's HWND instead of the Button's HWND when calling GetWindowText(). This fixed a bug that resulted in two different CButtonMenu's on the same dialog always painting the same caption.
  • 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
    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

     
    GeneralNo Button title appearing on Win98 Pin
    d.khan5-Jun-03 23:36
    d.khan5-Jun-03 23:36 
    GeneralRe: No Button title appearing on Win98 Pin
    RCube-14-Nov-03 15:56
    RCube-14-Nov-03 15:56 
    Generaltext bug Pin
    ljhhome14-Jan-03 19:47
    ljhhome14-Jan-03 19:47 
    GeneralRe: text bug Pin
    RCube-16-Nov-03 12:02
    RCube-16-Nov-03 12:02 
    GeneralMenu off by one pixel Pin
    13-Dec-01 9:38
    suss13-Dec-01 9:38 
    GeneralCaption Pin
    11-Jul-01 1:47
    suss11-Jul-01 1:47 
    Generaldebug assertion failed. Pin
    28-Mar-01 5:54
    suss28-Mar-01 5:54 
    GeneralRe: debug assertion failed. Pin
    28-Mar-01 7:05
    suss28-Mar-01 7:05 
    GeneralMissing atlutils.h Pin
    shilp1-Nov-00 7:53
    shilp1-Nov-00 7:53 
    GeneralRe: Missing atlutils.h Pin
    SAWilde30-Nov-00 6:06
    SAWilde30-Nov-00 6:06 
    Generalcan't compile Pin
    khoon2-Oct-00 22:26
    khoon2-Oct-00 22:26 

    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.