|
由于MFC的按钮样式过于古老,不做美化的话开发出来的软件跟Windows98上的软件一样,所以有必要对MFC的CButton类进行扩展生绘。
先说下思路,要改CButton的外观的话只要对DrawItem虚函数进行重写就可以了。通过itemState可以判断出按钮的状态,比如焦点、禁用、默认等等,鼠标进入和移出需要自己响应MouseMove消息。
具体实现代码:
MyButton.h:
#pragma once
#include "afxwin.h"
class CMyButton : public CButton
{
//DECLARE_DYNAMIC(CMyButton)
private:
bool _isCustom;
COLORREF upBorderColor,downBorderColor,focusBorderColor,hoverBorderColor,diableBorderColor; //定义弹起、铵下、焦点、鼠标进入、禁用的边框颜色
COLORREF disableBgColor;//定义禁用的背景颜色
int hoverBgColorR0,hoverBgColorG0,hoverBgColorB0,hoverBgColorR1,hoverBgColorG1,hoverBgColorB1;//分别定义鼠标进入的上边RGB和下边RGB颜色(实现渐变)
int upBgColorR0,upBgColorG0,upBgColorB0,upBgColorR1,upBgColorG1,upBgColorB1;
int downBgColorR0,downBgColorG0,downBgColorB0,downBgColorR1,downBgColorG1,downBgColorB1;//同上,鼠标铵下颜色
public:
CMyButton();
virtual ~CMyButton();
void SetDownColor(COLORREF color); //设置Button Down的背景颜色
void SetUpColor(COLORREF color);//设置弹起颜色
void SetFont(CFont* font);//设置字体
void SetFontColor(COLORREF color);//设置字体颜色
CWnd* cWndParent;
BOOL Attach(int nID, CWnd* pParent);//根据资源ID创建自定义按钮
protected:
//必需重载的函数
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);//重案绘制函数
public:
WNDPROC OldWndProc;
CtoolTipCtrl m_Mytip;
BOOL m_bTracking;
LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
//三种颜色分别为文字,Button Down的背景颜色,Button Up的背景颜色
COLORREF m_TextColor, m_DownColor, m_UpColor,m_TempColor;
protected:
// Generated message map functions
//{{AFX_MSG(CMyButton)
//}}AFX_MSG
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);//鼠标离开事件
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);//鼠标进入事件
DECLARE_MESSAGE_MAP()
};
MyButton.cpp:
#include "StdAfx.h"
#include "MyButton.h"
BEGIN_MESSAGE_MAP(CMyButton, CButton)
//{{AFX_MSG_MAP(CMyButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)//鼠标离开
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)//鼠标悬挂
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CMyButton::CMyButton(void)
{
m_TempColor=m_TextColor=m_DownColor = m_UpColor = RGB(0,0,0);
m_Mytip.Create(this);
m_bTracking=false;
_isCustom=false;
upBorderColor=RGB(172,172,172);
upBgColorR0=upBgColorG0=upBgColorB0=240;
upBgColorR1=upBgColorG1=upBgColorB1=229;
hoverBorderColor=RGB(126,180,234);
hoverBgColorR0=236;
hoverBgColorG0=244;
hoverBgColorB0=252;
hoverBgColorR1=220;
hoverBgColorG1=236;
hoverBgColorB1=252;
downBorderColor=RGB(86,157,229);
downBgColorR0=218;
downBgColorG0=232;
downBgColorB0=252;
downBgColorR1=196;
downBgColorG1=224;
downBgColorB1=252;
focusBorderColor=RGB(51,153,255);
diableBorderColor=RGB(217,217,217);
disableBgColor=RGB(239,239,239);
}
CMyButton::~CMyButton(void){
}
BOOL CMyButton::Attach(int nID, CWnd* pParent){
cWndParent=pParent->GetDlgItem(nID);
cWndParent->ModifyStyle(0,BS_OWNERDRAW,0);
if (!SubclassDlgItem(nID, pParent))
return FALSE;
return TRUE;
}
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);
const int bufSize = 512;
TCHAR buffer[bufSize];
GetWindowText(buffer, bufSize);//获取按钮上的文字
int size=strlen(buffer); //得到文字长度
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT); //设置背景透明
if (lpDrawItemStruct->itemState &ODS_SELECTED){ //当按下按钮时的处理
CRect rect;
GetClientRect(&rect);//获取按钮区域
for(int i=0;ihDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);//绘制文字
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);//设置背景透明
CBrush brush1(downBorderColor);//边框颜色
dc.SetTextColor(RGB(0,0,0));//设置文字颜色
dc.FrameRect(&(lpDrawItemStruct->rcItem),&brush1);//
}
else if(lpDrawItemStruct->itemState &ODS_FOCUS||lpDrawItemStruct->itemState &ODS_CHECKED){//获得焦点处理,同上
CRect rect;
GetClientRect(&rect);
for(int i=0;ihDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);
DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
CBrush brush1(focusBorderColor);//边框颜色
dc.SetTextColor(RGB(0,0,0));//设置文字颜色
dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//
}
else if(lpDrawItemStruct->itemState &ODS_DISABLED){//禁用处理,同上
CBrush brush(disableBgColor);//背景颜色
dc.FillRect(&(lpDrawItemStruct->rcItem),&brush);
dc.SetTextColor(RGB(131,131,131));//设置文字颜色
DrawText(lpDrawItemStruct->hDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);
DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
CBrush brush1(diableBorderColor);//边框颜色
dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//
}
else{//当按钮不操作或者弹起处理
CRect rect;
GetClientRect(&rect);
for(int i=0;ihDC,buffer,size,&lpDrawItemStruct->rcItem,DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_TABSTOP);
SetBkMode(lpDrawItemStruct->hDC,TRANSPARENT);
CBrush brush1(upBorderColor);//边框颜色
dc.SetTextColor(RGB(0,0,0));//设置文字颜色
dc.FrameRect(&lpDrawItemStruct->rcItem,&brush1);//
}
dc.Detach();
}
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 10;
m_bTracking = _TrackMouseEvent(&tme);
}
}
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam){
m_bTracking=false;
if(!_isCustom){
upBorderColor=RGB(172,172,172);;
upBgColorR0=upBgColorG0=upBgColorB0=240;
upBgColorR1=upBgColorG1=upBgColorB1=229;
}
else{
m_UpColor=m_TempColor;
//m_TextColor=RGB(255,255,0);
}
Invalidate(); //重绘按钮
return 0;
}
LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam){
if(!_isCustom){
upBorderColor=hoverBorderColor;
// upBgColor=hoverBgColor;
upBgColorR0=hoverBgColorR0;
upBgColorG0=hoverBgColorG0;
upBgColorB0=hoverBgColorB0;
upBgColorR1=hoverBgColorR1;
upBgColorG1=hoverBgColorG1;
upBgColorB1=hoverBgColorB1;
}
else{
//m_TextColor=RGB(255,0,255);
m_UpColor=m_DownColor;
}
Invalidate(); //重绘按钮
return 0;
}
使用:
在窗体的头文件中添加引用:
#include "MyButton.h"
并创建CmyButton对象:
CMyButton myBtnSubmit;
在窗体的OnInitDialog()事件中添加如下代码
myBtnSubmit.Attach(btnSubmit,this);
最终效果图:
|
|