普通按钮:
#pragma once
#include"stdafx.h"
class MyButton : public CButton
{
private:
bool is_pressed; //鼠标是否按下
int type;//按钮形状
COLORREF m_bkColor;//背景色
COLORREF m_roundColor;//边框色
COLORREF m_textColor; //文字色
public:
virtual void PreSubclassWindow(); //修改自绘属性
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); //绘制 圆形按钮
void SetAttribute(int,COLORREF, COLORREF, COLORREF);
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //鼠标按下
afx_msg void OnLButtonUp(UINT nFlags, CPoint point); //鼠标松开
afx_msg BOOL OnEraseBkgnd(CDC* pDC); //不擦除背景
};
//实现文件
// MyButton
void MyButton::SetAttribute(int t=0,COLORREF bk=RGB(255,128,0),COLORREF rd=RGB(0,255,0),COLORREF txt=RGB(255,255,255))
{
type = t;
m_bkColor = bk;
m_roundColor= rd;
m_textColor=txt;
}
void MyButton::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW);
is_pressed = false;
CButton::PreSubclassWindow();
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
CRect rc = lp->rcItem;
CDC dc;
dc.Attach(lp->hDC);
dc.SetBkMode(TRANSPARENT);
CBrush br;
if (is_pressed)
{
//按下去的颜色设为一样,都是灰色
CPen pen(PS_SOLID, 2, RGB(200, 200, 255));//边框颜色
br.CreateSolidBrush(RGB(180, 180,180)); //按钮背景色
dc.SelectObject(&br);
dc.SelectObject(&pen);
switch (type)
{
case 0:
dc.Rectangle(0, 0, rc.Width(), rc.Height());
dc.Rectangle(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
break;
case 1:
dc.Ellipse(0, 0, rc.Width(), rc.Height());
dc.Ellipse(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
break;
case 2:
dc.RoundRect(0, 0, rc.Width(), rc.Height(), 20, 20);
dc.RoundRect(1, 1, rc.Width() - 1, rc.Height() - 1, 20, 20);//画边框
break;
default:
break;
}
}
else
{
CPen pen(PS_SOLID,2, m_roundColor);
dc.SelectObject(&pen);
br.CreateSolidBrush(m_bkColor); //按钮背景色
dc.SelectObject(&br);
switch (type)
{
case 0:
dc.Rectangle(0, 0, rc.Width(), rc.Height());
dc.Rectangle(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
break;
case 1:
dc.Ellipse(0, 0, rc.Width(), rc.Height());
dc.Ellipse(1, 1, rc.Width() - 1, rc.Height() - 1);//画边框
break;
case 2:
dc.RoundRect(0, 0, rc.Width(), rc.Height(), 30,30);
dc.RoundRect(1, 1, rc.Width() - 1, rc.Height() - 1, 30, 30);//画边框
break;
default:
break;
}
}
CString str;
GetWindowText(str);
dc.SetTextColor(m_textColor);
dc.DrawText(str, CRect(0, 0, rc.right, rc.bottom), DT_CENTER | DT_VCENTER | DT_SINGLELINE);
dc.DeleteDC();
}
BEGIN_MESSAGE_MAP(MyButton, CButton)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void MyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
is_pressed = true;
CButton::OnLButtonDown(nFlags, point);
}
void MyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
is_pressed = false;
CButton::OnLButtonUp(nFlags, point);
}
BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
return TRUE; //不擦除背景
}
开关按钮:
#pragma once
#include"stdafx.h"
class MyButton : public CButton
{
private:
int is_open; // 是否打开
int type;//按钮形状
COLORREF m_bkColor;//背景色
COLORREF m_roundColor;//边框色
COLORREF m_textColor; //文字色
public:
virtual void PreSubclassWindow(); //修改自绘属性
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); //绘制 圆形按钮
void SetAttribute(int,COLORREF, COLORREF, COLORREF);
public:
DECLARE_MESSAGE_MAP()
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //鼠标按下
afx_msg BOOL OnEraseBkgnd(CDC* pDC); //不擦除背景
};
//实现文件
// MyButton
void MyButton::SetAttribute(int t=0,COLORREF bk=RGB(255,128,0),COLORREF rd=RGB(0,255,0),COLORREF txt=RGB(255,255,255))
{
type = t;
m_bkColor = bk;
m_roundColor= rd;
m_textColor=txt;
}
void MyButton::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW);
is_open = -1;
CButton::PreSubclassWindow();
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
CRect rc = lp->rcItem;
CDC dc;
dc.Attach(lp->hDC);
dc.SetBkMode(TRANSPARENT);
dc.SelectObject(GetStockObject(NULL_PEN));
CBrush close, open,round; //分别代表关闭 打开 还有圆的颜色
close.CreateSolidBrush(RGB(192, 192, 192));
open.CreateSolidBrush(RGB(0, 220, 0));
round.CreateSolidBrush(RGB(120, 120, 120));
POINT pt = { 15,15};
if (is_open == -1)
{
dc.SelectObject(close);
dc.RoundRect(rc,pt);
dc.SelectObject(round);
dc.Ellipse(rc.left+2, rc.top+2, rc.bottom - rc.top-2, rc.bottom-2);
}
else
{
dc.SelectObject(open);
dc.RoundRect(rc, pt);
dc.SelectObject(GetStockObject(WHITE_BRUSH));
dc.Ellipse(rc.right-(rc.bottom - rc.top)+2, rc.top+2, rc.right-2, rc.bottom-2);
}
dc.DeleteDC();
}
BEGIN_MESSAGE_MAP(MyButton, CButton)
ON_WM_LBUTTONDOWN()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void MyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
is_open = -is_open;
CButton::OnLButtonDown(nFlags, point);
}
BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
return TRUE; //不擦除背景
}
最小化以及关闭按钮:
#pragma once
#include"stdafx.h"
class MyButton : public CButton
{
public:
MyButton(int t) :type(t) {}
virtual void PreSubclassWindow(); //修改自绘属性
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/); //绘制 圆形按钮
public:
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEraseBkgnd(CDC* pDC); //不擦除背景
afx_msg void OnTimer(UINT_PTR nIDEvent);
void DrawAlphaRect(CRect);
private:
BOOL bInBtn;//鼠标是否在按钮的区域内
int type; //按钮的类型 0为最小化,1为关闭
};
//实现文件
void MyButton::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW);
SetTimer(1, 200, NULL);
bInBtn = FALSE;
CButton::PreSubclassWindow();
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lp)
{
CRect rc = lp->rcItem;
CDC dc;
dc.Attach(lp->hDC);
dc.SetBkMode(TRANSPARENT);
dc.SelectObject(GetStockObject(NULL_PEN));
CPen pen;
pen.CreatePen(PS_SOLID, 2, RGB(160,160,160));
dc.SelectObject(pen);
if (type == 0)
{
dc.MoveTo(rc.left + 6, (rc.bottom - rc.top) / 3 * 2);
dc.LineTo(rc.right - 6, (rc.bottom - rc.top) / 3 * 2);
}
else if (type == 1)
{
dc.MoveTo(rc.left + 6, rc.top + 6);
dc.LineTo(rc.right - 6, rc.bottom - 6);
dc.MoveTo(rc.left + 6, rc.bottom - 6);
dc.LineTo(rc.right - 6, rc.top + 6);
}
pen.DeleteObject();
dc.DeleteDC();
}
BEGIN_MESSAGE_MAP(MyButton, CButton)
ON_WM_ERASEBKGND()
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
return FALSE; //不擦除背景
}
void MyButton::DrawAlphaRect(CRect rect)
{
CDC *dc = GetDC();
CDC cdc;
cdc.CreateCompatibleDC(dc);
CBitmap bitmap, *pOldBitmap;
bitmap.CreateCompatibleBitmap(dc, rect.right, rect.bottom);
CRect src(rect);
src.OffsetRect(CSize(-rect.left, -rect.top));
pOldBitmap = cdc.SelectObject(&bitmap);
cdc.FillSolidRect(src, RGB(0, 85, 255)); //透明色
if (::AlphaBlend == 0)
{
dc->BitBlt(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, &cdc, src.left, src.top, SRCINVERT);
} else {
BLENDFUNCTION bf;
memset(&bf, 0, sizeof(bf));
bf.SourceConstantAlpha = 0x3f; //透明程度//值越大越不透明
bf.BlendOp = AC_SRC_OVER;
::AlphaBlend(dc->GetSafeHdc(), rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
cdc.GetSafeHdc(), src.left, src.top, src.right - src.left, src.bottom - src.top, bf);
}
cdc.SelectObject(pOldBitmap);
}
void MyButton::OnTimer(UINT_PTR nIDEvent)
{
CRect rc;
GetClientRect(&rc);
CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);
CDC *dc = GetDC();
dc->SelectObject(GetStockObject(NULL_PEN));
if (rc.PtInRect(pt)) //如果鼠标悬浮在按钮上,则画出一个矩形
{
if (bInBtn)
{
CRect r = { rc.left + 1,rc.top + 1,rc.right - 1,rc.bottom - 1 };//由于画透明矩形时有1像素的边框,所以画的区域为按钮的区域-1
DrawAlphaRect(r);
bInBtn = FALSE;
}
}
else
{
bInBtn = TRUE;
CBrush brush;
brush.CreateSolidBrush(RGB(240, 240, 240));//屏幕默认RGB
dc->SelectObject(brush);
dc->Rectangle(rc);
CPen pen;
pen.CreatePen(PS_SOLID, 2, RGB(160, 160, 160));
dc->SelectObject(pen);
if (type == 0)
{
dc->MoveTo(rc.left+6, (rc.bottom - rc.top) / 3*2);
dc->LineTo(rc.right-6, (rc.bottom - rc.top) /3*2);
}
else if (type == 1)
{
dc->MoveTo(rc.left + 6, rc.top + 6);
dc->LineTo(rc.right - 6, rc.bottom - 6);
dc->MoveTo(rc.left + 6, rc.bottom - 6);
dc->LineTo(rc.right - 6, rc.top + 6);
}
pen.DeleteObject();
}
ReleaseDC(dc);
CButton::OnTimer(nIDEvent);
}