FooButton (英文叶挺好的)

Introduction

This article describes FooButton, a lightweight owner-drawn button class that's served me well for several years.  Although there are plenty of other excellent button classes at CodeProject, I thought I'd add this trusty friend to the pile in the hope that someone may find it equally useful.

Features

FooButton lets you use a vanilla CButton as a:
  • standard pushbutton
  • pushbutton button with a drop-down indicator
  • multi pushbutton (like IE's "Back" and "Next" buttons)
  • checkbutton
  • hyperlink
  • static text control that's responsive to mouse clicks
  • check box
  • radio button
Support is also provided for:
  • bitmaps (currently only 16-color)
  • left-justified, centered and multi-line captions
  • colored captions
  • gradient shaded button backgrounds
  • popup menus
  • hot tracking
  • optional focus rectangle and "default button" indicator
  • grouped checkbuttons

How to use FooButton

  1. First, associate a standard button control (eg: IDC_FOO_BUTTON) in your dialog with an instance of the object.

      /////
      // MyDialog.h
      #include "FooButton.h"
      ...
      FooButton m_fooButton;
      ///
      // MyDialog.cpp
      void CMyDialog::DoDataExchange(CDataExchange* pDX)
      {
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CMyDialog)
        DDX_Control(pDX, IDC_FOO_BUTTON, m_fooButton);
        //}}AFX_DATA_MAP
      }

  2. Then, initialize the instance in your dialog's OnInitDialog() method to suit your needs.  In this example, the button is set to display a bitmap and a drop-down indicator.

      // Initialize FooButton
      m_fooButton.setBitmapId (IDB_FOO_BUTTON);
      m_fooButton.setType (FooButton::Type::pushButtonDropDown);
    
         Drop-down pushbutton

API

 MethodPurpose
 getType(), setType()Gets and sets the button's type 
 getTextStyle(), setTextStyle()Gets and sets the button's text style 
 getTextColor(), setTextColor()Gets and sets the button's text color 
 getFocusStyle(), setFocusStyle()Gets and sets the button's focus style 
 getGradient(), setGradient()Gets and sets the button's gradient property 
 getBitmapId(), setBitmapId()Gets and sets the button's (optional) bitmap id 
 displayPopupMenu()Displays a popup menu below the button 
 isChecked(), check()Gets and sets a checkButton's checked state 
 isMultiClicked(), clearMultiClick()Gets and resets a multiPushButton's multi-clicked state 
 addToGroup(), removeFromGroup()Adds/removes a checkButton to/from a button group 
 reset()Frees storage used by all button groups 
 

Using FooButton as a check button

You can freely change any property of the button at run time.  This code snippet turns the button into a checkbutton and checks it.  Use check() and isChecked() to set and retrieve the button's checked state.

  // Make it a checkbutton and check it
  m_fooButton.setType (FooButton::Type::checkButton);
  m_fooButton.check (true);
  ASSERT (m_fooButton.isChecked());    // testing
     Unchecked   Checked

Gradient shading

Pushbuttons and checkbuttons can be set to display a gradient shaded background by calling setGradient().  This method has no effect if the button isn't a pushbutton or checkbutton.

  // Use a gradient shaded background
  m_fooButton.setGradient (true);
     Using a gradient shaded background

Button groups

You can make a bunch of checkButtons behave as mutually exclusive radio buttons by adding them to a button group.  A button group is just a named collection of buttons.  FooButton automatically handles group creation, membership and cleanup.

  // Make "size" checkbuttons mutually exclusive
  m_btnSmall.addToGroup (_T("foo"));
  m_btnMedium.addToGroup (_T("foo"));
  m_btnLarge.addToGroup (_T("foo"));
  m_btnXLarge.addToGroup (_T("foo"));
     A button group

Displaying a popup menu

To display a popup menu in response to a button click, call displayPopupMenu().  You can call this method for any type of FooButton.

  void CMyDialog::OnFooButton()
  {
    CMenu menu;
    menu.LoadMenu (IDR_POPUP_MENU);
    CMenu* pPopupMenu = menu.GetSubMenu (0);
    int nResult = m_fooButton.displayPopupMenu (pPopupMenu);
    if (0 != nResult)
       PostMessage (WM_COMMAND, nResult);
  }
     Normal   Pressed

Multi-pushbuttons

A multi-pushbutton behaves as two buttons in one, similar to IE's "Back" and "Next" buttons.  When the user clicks the button's drop-down region, FooButton sets its "multi-clicked" property to true.  You can query this property by calling isMultiClicked().  Regardless of whether the user clicked in the button's main or drop-down region, a standard notification is sent to the parent.  To clear the button's multi-click property, call clearMultiClick().

  void CMyDialog::OnFooButton() 
  {
    if (m_fooButton.isMultiClicked()) {
 
        // Display menu if drop-down region was clicked
        CMenu menu;
        menu.LoadMenu (IDR_POPUP_MENU);
        CMenu* pPopupMenu = menu.GetSubMenu (0);
        int nResult = m_fooButton.displayPopupMenu (pPopupMenu);
        if (0 != nResult)
           PostMessage (WM_COMMAND, nResult);
 
        // Remember to clear the button's multi-click property!
        m_fooButton.clearMultiClick();
 
    } else {
 
        // Otherwise do default action
        PostMessage (WM_COMMAND, IDC_DEFAULT_ACTION);
    }
  }
     Multi-pushbutton   Multi-pushbutton with drop-down pressed

Check boxes and radio buttons

You can make a FooButton appear as a standard check box or radio button by using the FooButton:Type::checkBox and FooButton:Type::radio types.  Of course, this is really only useful when you want to also display a bitmap or add menu support to the button.

  // Appear as check box and radio button
  m_fooButton1.setType (FooButton::Type::checkBox);
  m_fooButton2.setType (FooButton::Type::radio);
     Check box   Radio button with a popup menu

Hyperlink button

A hyperlink button is just a regular button that renders itself as a hyperlink.  You can navigate to a URL or perform any other action in the button's handler.

  // Appear as hyperlink
  m_fooButton.setType (FooButton::Type::hyperink);
     A button that looks like a hyperlink

Text color

You can change the color of the button's text at any time by calling setTextColor().  The text of hyperlink buttons is always rendered in C_HyperlinkColor and that of disabled buttons is always rendered in the standard etched format.

  // Draw caption in red
  m_fooButton.setTextColor (RGB (192, 0, 0));
     Custom caption text color

Focus rectangle

By default, a FooButton doesn't display a focus rectangle.  Call setFocusStyle() with FooButton::Focus::normalFocus to enable the button to display a focus rectangle.

  // Allow focus rectangle to be displayed
  m_fooButton.setFocusStyle (FooButton::Focus::normalFocus);
     Focus rectangle disabled   Focus rectangle enabled

Default button indicator

To enable a default FooButton to display its standard dark border, call setFocusStyle() with FooButton::Focus::defaultFocus.

  // Allow focus rectangle and default indicator to be displayed
  m_fooButton.setFocusStyle (FooButton::Focus::defaultFocus);
    Default button (unpressed)   Default button (pressed)

Rendering disabled bitmaps

Use the standard MFC EnableWindow() API to enable and disable the button.  FooButton uses its original bitmap to render a disabled version.

  m_fooButton.EnableWindow (TRUE);   // enable button
  m_fooButton.EnableWindow (FALSE);  // disable button
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值