参考资料
1.MFC重载CButton类,实现改变按钮背景色、字体样式更改、鼠标滑动按钮变色功能
添加一个可以变色的按钮
// CCustomButton.h
#pragma once
#include <afxwin.h>
class CCustomButton :
public CButton
{
DECLARE_DYNAMIC(CCustomButton)
public:
CCustomButton();
virtual ~CCustomButton();
void SetButtonBgColor(COLORREF color);
void SetButtonTextColor(COLORREF color);
int SwitchDlgMouseMoveState;
private:
COLORREF m_bgColor;
COLORREF m_textColor;
COLORREF m_DownColor;
BOOL m_bPressed;
protected:
DECLARE_MESSAGE_MAP()
BOOL m_bTracking; //在鼠标按下没有释放时该值为true
afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
};
// CCustomButton.cpp
#include "pch.h"
#include "CCustomButton.h"
IMPLEMENT_DYNAMIC(CCustomButton, CButton)
CCustomButton::CCustomButton()
{
// 背景色
m_bgColor = RGB(39, 58, 91);
// 字体颜色
m_textColor = RGB(255, 255, 255);
m_bPressed = FALSE;
SwitchDlgMouseMoveState = 0;
}
CCustomButton::~CCustomButton()
{
}
BEGIN_MESSAGE_MAP(CCustomButton, CButton)
ON_WM_DRAWITEM()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
END_MESSAGE_MAP()
// COwerButton 消息处理程序
void CCustomButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CString btnCaption = L"";
//设置标题
CFont font;
CWnd* pItemCWnd = FromHandle(lpDrawItemStruct->hwndItem);
pItemCWnd->GetWindowText(btnCaption);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect drawRect;
CBrush pBrush;
CRect rect = lpDrawItemStruct->rcItem;//空间选择
//获得绘图DC
//得到原Button的矩形大小
drawRect.CopyRect(&(lpDrawItemStruct->rcItem));
//绘制控件框架
pDC->DrawFrameControl(&drawRect, DFC_BUTTON, lpDrawItemStruct->CtlType);
if (ODS_SELECTED & lpDrawItemStruct->itemState)
{
font.CreateFontW(0, 0, 0, 0, 400, NULL, NULL, NULL, DEFAULT_CHARSET, 0, 0, 0, 0, L"黑体");
pDC->SelectObject(&font);
// 鼠标按住不动时候的颜色
pBrush.CreateSolidBrush(RGB(100, 149, 237));
}
else if (SwitchDlgMouseMoveState == 1)
{
font.CreateFontW(0, 0, 0, 0, 400, NULL, NULL, NULL, DEFAULT_CHARSET, 0, 0, 0, 0, L"黑体");
pDC->SelectObject(&font);
// 鼠标放到button上时候的颜色,即hover
pBrush.CreateSolidBrush(RGB(30, 144, 255));
}
else
{
font.CreateFontW(0, 0, 0, 0, 400, NULL, NULL, NULL, DEFAULT_CHARSET, 0, 0, 0, 0, L"黑体");
pDC->SelectObject(&font);
// 对button无任何操作时候的颜色
pBrush.CreateSolidBrush(RGB(39, 58, 91));
}
//画矩形
pDC->FillRect(drawRect, &pBrush);
//定义一个CRect用于绘制文本
CRect textRect;
//拷贝矩形区域
textRect.CopyRect(&drawRect);
//获得字符串尺寸
CSize sz = pDC->GetTextExtent(btnCaption);
//调整文本位置 居中
textRect.top += (textRect.Height() - sz.cy) / 2;
//设置文本背景透明
pDC->SetBkMode(TRANSPARENT);
//设置文本颜色
pDC->SetTextColor(RGB(255, 255, 255));
//绘制文本内容
pDC->DrawText(btnCaption, &textRect, DT_RIGHT | DT_CENTER | DT_BOTTOM);
}
//设置按钮背景的颜色
void CCustomButton::SetButtonBgColor(COLORREF color)
{
m_bgColor = color;
}
//设置按钮字体的颜色
void CCustomButton::SetButtonTextColor(COLORREF color)
{
m_textColor = color;
}
void CCustomButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
SwitchDlgMouseMoveState = 1;
// 重画按钮
Invalidate(TRUE);
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
LRESULT CCustomButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
SwitchDlgMouseMoveState = 0;
m_bTracking = FALSE;
InvalidateRect(NULL, FALSE);
return 0;
}
先将上面两个文件添加到项目目录中。
1.添加按钮时,将控件属性中的 所有者描述 改为True
2.添加变量时,将变量类型改为CCostomButton
,也就是上面两个添加进来的文件名
3.在对话框文件(以Dlg.h结尾的文件)中引入 #include "CCustomButton.h"
如果不更改做更改文件ID等操作,应该不会出现bug,即使出现也不难改。
将已有按钮变为可变色按钮
1.将CCustomButton.h
和CCustomButton.cpp
添加到项目中。并在xxxDlg.h
文件中引入#include "CCustomButton.h"
。
2.将“所有者描述”改为true
3.添加变量
对于没有添加变量的按钮,将变量类型改为 CCustomButton
,也就是之前添加进来的文件的名称。名称自定义。
对于已经添加完成变量的按钮,在xxxDlg.h
文件的末尾找到变量的定义,将前面的变量声明改为CCustomButton
。
4.完成,按钮具体的颜色变化可以在CCustomButton.cpp
文件中修改,注释中已标明。