標頭檔:CMyButton.h 如下:
#pragma once
#include "afxwin.h"
class CMyButton : public CButton
{
//DECLARE_DYNAMIC(CMyButton)
public:
CMyButton();
virtual ~CMyButton();
//設定Button Down的背景顏色
void SetDownColor(COLORREF color);
//設定Button Up的背景顏色
void SetUpColor(COLORREF color);
BOOL Attach(const UINT nID, CWnd* pParent);
protected:
//必需重載的函數
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
//三種顏色分別為文字,Button Down的背景顏色,Button Up的背景顏色
COLORREF m_TextColor, m_DownColor, m_UpColor;
};
源檔案:CMyButton.cpp
#include "StdAfx.h"
#include "CMyButton.h"
CMyButton::CMyButton(void)
{
m_DownColor = m_UpColor = RGB(0,0,0);
}
CMyButton::~CMyButton(void)
{
}
//CMyButton是CButton衍生類別,具有CButton的全部成員函數,
//但在建立時需要使用BS_OWNERDRAW風格。
//如果按鈕不是動態產生,使用Attach函數使CMyButton代替原來按鈕的視窗過程。
BOOL CMyButton::Attach(const UINT nID, CWnd* pParent)
{
//GetDlgItem(nID)->ModifyStyle(0,BS_OWNERDRAW,0);
if (!SubclassDlgItem(nID, pParent))
return FALSE;
return TRUE;
}
void CMyButton::SetDownColor(COLORREF color)
{
m_DownColor = color;
}
void CMyButton::SetUpColor(COLORREF color)
{
m_UpColor = color;
}
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
CDC dc;
dc.Attach(lpDrawItemStruct->hDC);//得到繪製的裝置環境CDC
VERIFY(lpDrawItemStruct->CtlType==ODT_BUTTON);
// 得當Button上文字,這裡的步驟是:1,先得到在資源裡編輯的按鈕的文字,
//然後將此文字重新繪製到按鈕上,
//同時將此文字的背景色設為透明,這樣,按鈕上僅會顯示文字
const int bufSize = 512;
TCHAR buffer[bufSize];
GetWindowText(buffer, bufSize);
int size=strlen(buffer); //得到長度
DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP); //繪製文字
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT); //透明
if (lpDrawItemStruct->itemState &ODS_SelectED) //當按下按鈕時的處理
{//
//重繪整個控制
CBrush brush(m_DownColor);
dc.FillRect(&(lpDrawItemStruct->rcItem),&brush);//
//因為這裡進行了重繪,所以文字也要重繪
DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
}
else //當按鈕不操作或者彈起時
{
CBrush brush(m_UpColor);
dc.FillRect(&(lpDrawItemStruct->rcItem),&brush);//
//同上,進行重繪文字
DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
}
if ((lpDrawItemStruct->itemState &ODS_SelectED)&&(lpDrawItemStruct->itemAction &(ODA_Select| ODA_DRAWENTIRE)))
{ //選中了本控制項,高亮邊框
COLORREF fc=RGB(255-GetRValue(m_UpColor),255-GetGValue(m_UpColor), 255- GetBValue(m_UpColor));//
CBrush brush(fc);//
dc.FrameRect(&(lpDrawItemStruct->rcItem),&brush);//
}
if (!(lpDrawItemStruct->itemState & ODS_SelectED) &&(lpDrawItemStruct->itemAction & ODA_Select))
{
//控制的選中狀態結束,去掉邊框
CBrush brush(m_UpColor);
dc.FrameRect(&lpDrawItemStruct->rcItem,&brush);//
}
dc.Detach();//
}
調用CMyButton類的方式:
在對話方塊類標頭檔中#include "CMyButton.h",再在對話方塊類中找到函數OnInitDialog()如果找不到可以在對話方塊事件屬性中重載出來,
其中m_cbBtn變數的聲明為:
CMyButton m_cbBtn;//這句可以放在類的其他地方,只要合法就行
//將按鈕修改為BS_OWNERDRAW風格,其他風格無效
GetDlgItem(IDC_BUTTON1)->ModifyStyle(0,BS_OWNERDRAW,0);
//繫結控制項IDC_BUTTON1與類CMyButton,響應重載函數DrawItem()
m_cbBtn.Attach(IDC_BUTTON1,this);
//設定Button Down的背景色
m_cbBtn.SetDownColor(RGB(255,0,0));
//設定Button Up的背景色
m_cbBtn.SetUpColor(RGB(0,0,255));
PS:如果串連代碼時在m_cbBtn.Attach(IDC_BUTTON1,this);這句產生中斷,可能的原因是IDC_BUTTON1控制項已經綁定了一次訊息,這裡再次綁定當然不成功啦,
改正方法為:將映射函數DoDataExchange()中
//DDX_Control(pDX, IDC_BUTTON1, m_cbBtn);//這句注釋掉就可以了。