最近工作在学MFC,就写点博客记录一下
算是新手上路,勿喷
用的是VS2010
做的是一个圆形按钮 按下和弹起会不同颜色
.h文件
#pragma once
#include "afxwin.h"
class CCustomDrawBtn :
public CButton
{
CDC* pDC;
CPen* pOldPen;
CFont* pOldFont;
DECLARE_DYNAMIC(CCustomDrawBtn)
public:
CCustomDrawBtn();
virtual ~CCustomDrawBtn();
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void PreSubclassWindow();
void SetColorStyle(COLORREF bkColor, COLORREF hoverColor, COLORREF textColor, COLORREF borderColor, int fontSize, int radis);
void SetFontSize(int fontsize);
void SetTextColor(COLORREF color);
// afx_msg void OnTimer(UINT nIDEvent);
protected:
DECLARE_MESSAGE_MAP()
void Draw(LPDRAWITEMSTRUCT lpDrSt, CDC* pDC, CRect rect, int roundRadis, COLORREF bkColor, CString strText);
void Redraw(LPDRAWITEMSTRUCT lpDrSt);
public:
//绘制区域
CRect m_rcDrawClient;
//默认背景颜色
COLORREF m_bkColor;
//鼠标移动上去的颜色
COLORREF m_hoverColor;
//文字颜色
COLORREF m_textColor;
//边框颜色
COLORREF m_borderColor;
//背景颜色
COLORREF m_drawBkColor;
//字体大小
int m_fontSize;
//圆角幅度>0,=0 无圆角
int m_radis;
//累计
int count;
//是否已经画了高亮色
BOOL m_bPaintedHighLight;
//文本
CString m_btnText;
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
int m_flag;
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
};
.cpp文件
#include "StdAfx.h"
#include "CustomDrawBtn.h"
#include "SKinColors.h"
#include "resource.h"
IMPLEMENT_DYNAMIC(CCustomDrawBtn, CButton)
CCustomDrawBtn::CCustomDrawBtn()
: m_flag(0)
{
m_bkColor = RGB(51, 126, 251);//默认是蓝色风格背景
m_hoverColor = RGB(17, 94, 188);//默认高亮色
m_textColor = RGB(255, 255, 255);//默认文字颜色
m_radis = 100;//圆角幅度
m_fontSize = 14;//字体
m_bPaintedHighLight = FALSE;
m_btnText = "";
m_drawBkColor = m_bkColor;
m_borderColor = m_bkColor;
m_flag = FALSE;
count = 1;
}
CCustomDrawBtn::~CCustomDrawBtn(){}
BEGIN_MESSAGE_MAP(CCustomDrawBtn, CButton)
ON_WM_ERASEBKGND()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
//设置颜色
void CCustomDrawBtn::SetColorStyle(COLORREF bkColor, COLORREF hoverColor,
COLORREF textColor, COLORREF borderColor, int fontSize, int radis){
m_bkColor = bkColor;
m_hoverColor = hoverColor;
m_radis = radis;
m_textColor = textColor;
m_fontSize = fontSize;
m_drawBkColor = m_bkColor;
m_borderColor = borderColor;
Invalidate();
}
//设置文字大小
void CCustomDrawBtn::SetFontSize(int fontsize){
m_fontSize = fontsize;
}
//设置文字颜色
void CCustomDrawBtn::SetTextColor(COLORREF color){
m_textColor = color;
}
//画 调用↓
void CCustomDrawBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
Redraw(lpDrawItemStruct);
}
//画 调用↓
void CCustomDrawBtn::Redraw(LPDRAWITEMSTRUCT lpDrSt){
//获取窗口客户区
GetClientRect(&m_rcDrawClient);
//获取句柄
pDC = GetDC();
if (pDC){
//获取窗口的标题条文本
GetWindowText(m_btnText);
//调用自己封装的重写方法
Draw(lpDrSt, pDC, m_rcDrawClient, m_radis, m_drawBkColor, m_btnText);
//释放
ReleaseDC(pDC);
}
}
//画
void CCustomDrawBtn::Draw(LPDRAWITEMSTRUCT lpDrSt, CDC* pDC, CRect rect, int roundRadis,
COLORREF bkColor, CString strText){
if (pDC){
CRect rect, rectFocus;
GetClientRect(&rect);
rectFocus.CopyRect(&rect);
//朝它的中心移动边以缩小
rectFocus.DeflateRect(4, 4, 4, 4);
//获取文字颜色
COLORREF textColor = m_textColor;
//获取边框颜色
COLORREF borderColor = m_borderColor;
//BOOL bRet = pDC->Rectangle(&rectFocus);
CBrush framebrush = borderColor;
if (lpDrSt->itemState & ODS_DISABLED){
bkColor = SKinColors::lightgray;
textColor = SKinColors::dark_gray;
borderColor = SKinColors::dark_gray;
}
CPen pen(PS_SOLID, 1, borderColor);
pOldPen = pDC->SelectObject(&pen);
CFont font;
font.CreateFont(m_fontSize, 0, 0, 0, 700, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, _T("宋体"));
pOldFont = pDC->SelectObject(&font);
CBrush brushtemp;
brushtemp.CreateSolidBrush(RGB(192,124,104));
pDC->SelectObject(&brushtemp);
pDC->RoundRect(0, 0, rect.right , rect.bottom , roundRadis + 10, roundRadis + 10);
pDC->SelectObject(pOldPen);
CBrush brush;
brush.CreateSolidBrush(bkColor);
pDC->SelectObject(&brush);
pDC->RoundRect(10, 10, rect.right-10, rect.bottom-10, roundRadis, roundRadis);
pDC->SelectObject(pOldPen);
//绘制按钮文本 定义一个CRect用于绘制文本
CRect textRect;
//拷贝矩形区域
textRect.CopyRect(&m_rcDrawClient);
//获得字符串尺寸
CString btnCaption = m_btnText;
CSize sz = pDC->GetTextExtent(btnCaption);
//调整文本位置 居中
textRect.top += (textRect.Height() - sz.cy) / 2;
//设置文本背景透明
pDC->SetBkMode(TRANSPARENT);
//设置文本颜色
pDC->SetTextColor(textColor);
//绘制文本内容
pDC->DrawText(btnCaption, &textRect, DT_RIGHT | DT_CENTER | DT_BOTTOM);
//焦点下的外观绘制
if (lpDrSt->itemState & ODS_FOCUS){
int iPrevBkMode = pDC->GetBkMode();
pDC->SetBkMode(TRANSPARENT);
CPen pen(PS_DOT, 0, m_hoverColor);
CPen *pPrevPen = pDC->SelectObject(&pen);
CGdiObject *pPrevBrush = pDC->SelectStockObject(NULL_BRUSH);
pDC->SetBkMode(iPrevBkMode);
pDC->SelectObject(pPrevPen);
pDC->SelectObject(pPrevBrush);
}
pDC->SelectObject(pOldFont);
font.DeleteObject();
pen.DeleteObject();
}
}
//改为所有者绘制
void CCustomDrawBtn::PreSubclassWindow(){
ModifyStyle(0, BS_OWNERDRAW); // make the button owner drawn
CButton::PreSubclassWindow();
}
//背景擦除
BOOL CCustomDrawBtn::OnEraseBkgnd(CDC* pDC){
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
//return CButton::OnEraseBkgnd(pDC);
}
//按键按下
void CCustomDrawBtn::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rcWindow;
GetWindowRect(&rcWindow);
CPoint ptCursor;//鼠标光标位置
GetCursorPos(&ptCursor);
if (!m_bPaintedHighLight) {
count = count % 10 + 1;
m_drawBkColor = m_hoverColor;//变换背景色
InvalidateRect(NULL);
//m_bPaintedHighLight = true;
}
Invalidate(FALSE);
CButton::OnLButtonDown(nFlags, point);
}
void CCustomDrawBtn::OnLButtonUp(UINT nFlags, CPoint point){
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rcWindow;
GetWindowRect(&rcWindow);
CPoint ptCursor;//鼠标光标位置
GetCursorPos(&ptCursor);
if (m_bPaintedHighLight) {
m_drawBkColor = m_bkColor;
InvalidateRect(NULL);
//m_bPaintedHighLight = false;
}
Invalidate(FALSE);
CButton::OnLButtonUp(nFlags, point);
}
调用 在Dlg.h文件中申明一个重绘按钮变量CCustomDrawBtn CCustomDrawBtnTest;
再在Dlg.cpp文件中创建
//按钮重绘
CCustomDrawBtnTest.Create(_T("测试"), WS_VISIBLE | WS_EX_COMPOSITED, CRect(900, 600, 1000, 700), this, IDC_MYBUTTON);
函数细节可以在微软的网站上找api MFC类 | Microsoft learn
想增加其他效果也可以通过类向导里增加映射来实现