VC++实现切换按钮
有时候要实现两个选项的切换,常规做法1是放两个Radio按钮控件,并设置这两个按钮为一组。2是放一个Check按钮控件。但感觉都不是那么理想和直观。有没有更好的实现方式呢?下面将给你介绍一种我自绘的控件,我把它命名为“切换控件”(SwitchButton)。实现的效果如下图实现,给你一个多的选择,以供参考。
下面是实现源码:
-
/// 说明文件/
-
//文件:SwitchBtn.h //
-
//功能:切换按钮类,实现两个选项一个按钮实现,自绘实现。 //
-
//作者:cbNotes(http://blog.csdn.net/cbnotes) //
-
//版本:1.0.0 //
-
//时间:2013-01-23 //
-
//备注:该控件类免费开源,欢迎大家使用和改进。但请保持该说明文件的完整和原创性 //
-
/
-
#pragma once
-
// CSwitchBtn
-
class CSwitchBtn : public CWnd
-
{
-
DECLARE_DYNAMIC(CSwitchBtn)
-
public:
-
CSwitchBtn();
-
virtual ~CSwitchBtn();
-
private:
-
int m_nID; //控件ID
-
CWnd *m_pParentWnd; //父窗口指针
-
BOOL m_bAnimation; //是否动画标记
-
BOOL m_bLeft; //是否选择左边标记
-
CString m_szLeftText,m_szRightText;
-
COLORREF m_clrNorText,m_clrHotText;//文字颜色
-
COLORREF m_clrNorBG,m_clrHotBG; //背景颜色
-
COLORREF m_clrNorBorder,m_clrHotBorder;//边框颜色
-
int m_ngap;//间隔
-
protected:
-
DECLARE_MESSAGE_MAP()
-
public:
-
//自绘按钮
-
afx_msg void OnPaint();
-
//按钮按钮释放消息处理,主要是发送消息
-
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
-
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
-
//设置按钮上的文字
-
void SetText(CString szLeft,CString szRight);
-
// 选择哪个选项
-
void SetSelect(bool bLeft);
-
// 设置背景色
-
void SetBKColor(COLORREF clrBackGround);
-
// 设置滑块的颜色
-
void SetSliderColor(COLORREF clrSider);
-
// 设置文本的颜色
-
void SetTextColor(COLORREF clrText);
-
//设置选择文本的颜色
-
void SetHotTextColor(COLORREF clrHotText);
-
//设置外边框的颜色
-
void SetBorderColor(COLORREF clrBorder);
-
//设置滑块边框的颜色
-
void SetSliderBorderColor(COLORREF clrSliderBorder);
-
// 动态创建按钮
-
bool CreateButton(CRect rt,CWnd *pParentWnd,int nID);
-
// 初始化按钮
-
void InitButton(CString szLeft,CString szRight,bool bLeft = true);
-
};
-
/// 说明文件/
-
//文件:SwitchBtn.cpp //
-
//功能:切换按钮类,实现两个选项一个按钮实现,自绘实现。 //
-
//作者:cbNotes(http://blog.csdn.net/cbnotes) //
-
//版本:1.0.0 //
-
//时间:2013-01-23 //
-
//备注:该控件类免费开源,欢迎大家使用和改进。但请保持该说明文件的完整和原创性 //
-
/
-
#include "stdafx.h"
-
#include "SwitchBtnTest.h"
-
#include "SwitchBtn.h"
-
// CSwitchBtn
-
IMPLEMENT_DYNAMIC(CSwitchBtn, CWnd)
-
CSwitchBtn::CSwitchBtn()
-
{
-
m_pParentWnd = NULL;
-
m_bAnimation = FALSE;
-
m_bLeft = TRUE;
-
m_szLeftText = "左边";
-
m_szRightText = "右边";
-
m_clrNorText = RGB(0,0,0);//文字颜色
-
m_clrHotText = RGB(255,255,255);
-
m_clrNorBG = RGB(200,200,200);//背景颜色
-
m_clrHotBG = RGB(254,184,66);
-
m_clrNorBorder = RGB(128,128,128);//边框颜色
-
m_clrHotBorder = RGB(0,0,255);
-
m_ngap =10;//间隔
-
}
-
CSwitchBtn::~CSwitchBtn()
-
{
-
}
-
BEGIN_MESSAGE_MAP(CSwitchBtn, CWnd)
-
ON_WM_PAINT()
-
ON_WM_LBUTTONUP()
-
ON_WM_ERASEBKGND()
-
END_MESSAGE_MAP()
-
// CSwitchBtn 消息处理程序
-
// 初始化按钮
-
void CSwitchBtn::InitButton(CString szLeft,CString szRight,bool bLeft)
-
{
-
m_szLeftText = szLeft;
-
m_szRightText = szRight;
-
m_bLeft = bLeft;
-
}
-
// 动态创建按钮
-
bool CSwitchBtn::CreateButton(CRect rt,CWnd *pParentWnd,int nID)
-
{
-
if (!pParentWnd)
-
{
-
return false;
-
}
-
m_pParentWnd = pParentWnd;
-
m_nID = nID;//用于消息的标识
-
return Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rt,pParentWnd,nID);
-
}
-
void CSwitchBtn::OnPaint()
-
{
-
CPaintDC dc(this); // device context for painting
-
// TODO: 在此处添加消息处理程序代码
-
// 不为绘图消息调用 CWnd::OnPaint()
-
CRect winrt;
-
GetClientRect(&winrt);
-
CDC memDC;
-
memDC.CreateCompatibleDC(&dc);
-
CBitmap bmp;
-
bmp.CreateCompatibleBitmap(&dc,winrt.Width(),winrt.Height());
-
memDC.SelectObject(&bmp);
-
memDC.FillSolidRect(winrt,RGB(240,240,240));//
-
//背景
-
CBrush norbgbrush,hotbgbrush;//
-
norbgbrush.CreateSolidBrush(m_clrNorBG);
-
hotbgbrush.CreateSolidBrush(m_clrHotBG);
-
CBrush* pOldBrush = memDC.SelectObject(&norbgbrush);
-
//边框
-
CPen norborderpen,hotborderpen;
-
norborderpen.CreatePen(PS_SOLID, 2, m_clrNorBorder);
-
hotborderpen.CreatePen(PS_SOLID, 1, m_clrHotBorder);
-
CPen* pOldPen = memDC.SelectObject(&norborderpen);
-
CFont font;
-
font.CreatePointFont(160,"宋体");
-
memDC.SelectObject(&font);
-
memDC.SetBkMode(TRANSPARENT);
-
CRect leftrt,rightrt;
-
leftrt = rightrt = winrt;
-
leftrt.right=leftrt.left+winrt.Width()/2-m_ngap/2;
-
leftrt.DeflateRect(3,3,2,2);
-
rightrt.left=rightrt.right-winrt.Width()/2+m_ngap/2;
-
rightrt.DeflateRect(3,3,2,2);
-
//
-
CRect rt = winrt;
-
rt.DeflateRect(2,2,0,0);
-
if(!m_bAnimation)
-
{
-
//画背景
-
memDC.RoundRect(&rt,CPoint(17,17));
-
//焦点背景
-
pOldBrush = memDC.SelectObject(&hotbgbrush);
-
pOldPen = memDC.SelectObject(&hotborderpen);
-
if (m_bLeft)
-
{//
-
memDC.RoundRect(&leftrt,CPoint(17,17));
-
}
-
else
-
{
-
memDC.RoundRect(&rightrt,CPoint(17,17));
-
}
-
//写文字
-
if (m_bLeft)
-
{ //左边文字
-
memDC.SetTextColor(m_clrHotText);
-
memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
//右边文字
-
memDC.SetTextColor(m_clrNorText);
-
memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
}
-
else
-
{
-
memDC.SetTextColor(m_clrNorText);
-
memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
memDC.SetTextColor(m_clrHotText);
-
memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
}
-
dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);
-
}
-
else
-
{//动画切换
-
CRect rr= winrt;
-
rr.DeflateRect(2,2,0,0);
-
if (m_bLeft)
-
{//往左
-
rt = rightrt;
-
while(rt.left>winrt.left+3)
-
{
-
pOldBrush =memDC.SelectObject(&norbgbrush);
-
pOldPen = memDC.SelectObject(&norborderpen);
-
memDC.RoundRect(&rr,CPoint(17,17));
-
rt.OffsetRect(CPoint(-5,0));
-
pOldPen = memDC.SelectObject(&hotborderpen);
-
pOldBrush = memDC.SelectObject(&hotbgbrush);
-
memDC.RoundRect(&rt,CPoint(17,17));
-
//写文字
-
//左边文字
-
memDC.SetTextColor(m_clrHotText);
-
memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
//右边文字
-
memDC.SetTextColor(m_clrNorText);
-
memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);
-
Sleep(10);
-
}
-
}
-
else
-
{//往右
-
rt = leftrt;
-
while(rt.right<winrt.right-3)
-
{
-
pOldBrush =memDC.SelectObject(&norbgbrush);
-
pOldPen = memDC.SelectObject(&norborderpen);
-
memDC.RoundRect(&rr,CPoint(17,17));
-
rt.OffsetRect(CPoint(5,0));
-
pOldPen = memDC.SelectObject(&hotborderpen);
-
pOldBrush = memDC.SelectObject(&hotbgbrush);
-
memDC.RoundRect(&rt,CPoint(17,17));
-
//写文字
-
memDC.SetTextColor(m_clrNorText);
-
memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
memDC.SetTextColor(m_clrHotText);
-
memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
-
dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);
-
Sleep(10);
-
}
-
}
-
m_bAnimation = FALSE;
-
}
-
bmp.DeleteObject();
-
norbgbrush.DeleteObject();
-
hotbgbrush.DeleteObject();
-
norborderpen.DeleteObject();
-
hotborderpen.DeleteObject();
-
font.DeleteObject();
-
memDC.DeleteDC();
-
}
-
void CSwitchBtn::OnLButtonUp(UINT nFlags, CPoint point)
-
{
-
// TODO: 在此添加消息处理程序代码和/或调用默认值
-
CRect rt;
-
GetClientRect(&rt);
-
CRect leftrt,rightrt;
-
leftrt = rightrt =rt;
-
leftrt.right=leftrt.left+rt.Width()/2-m_ngap/2;
-
leftrt.DeflateRect(2,2,2,2);
-
rightrt.left=rightrt.right-rt.Width()/2+m_ngap/2;
-
rightrt.DeflateRect(2,2,2,2);
-
if (m_bLeft)
-
{
-
if (rightrt.PtInRect(point))
-
{
-
m_bLeft = FALSE;
-
m_bAnimation = TRUE;
-
m_pParentWnd->SendMessage(m_nID,1,0);
-
Invalidate();
-
}
-
}
-
else
-
{
-
if (leftrt.PtInRect(point))
-
{
-
m_bLeft = TRUE;
-
m_bAnimation = TRUE;
-
m_pParentWnd->SendMessage(m_nID,0,0);
-
Invalidate();
-
}
-
}
-
CWnd::OnLButtonUp(nFlags, point);
-
}
-
BOOL CSwitchBtn::OnEraseBkgnd(CDC* pDC)
-
{
-
// TODO: 在此添加消息处理程序代码和/或调用默认值
-
return FALSE;
-
//return CWnd::OnEraseBkgnd(pDC);
-
}
-
void CSwitchBtn::SetText(CString szLeft,CString szRight)
-
{
-
m_szLeftText = szLeft;
-
m_szRightText = szRight;
-
}
-
// 选择哪个选项
-
void CSwitchBtn::SetSelect(bool bLeft)
-
{
-
m_bLeft = bLeft;
-
}
-
// 设置背景色
-
void CSwitchBtn::SetBKColor(COLORREF clrBackGround)
-
{
-
m_clrNorBG = clrBackGround;
-
}
-
// 设置滑块的颜色
-
void CSwitchBtn::SetSliderColor(COLORREF clrSider)
-
{
-
m_clrHotBG = clrSider;
-
}
-
// 设置文本的颜色
-
void CSwitchBtn::SetTextColor(COLORREF clrText)
-
{
-
m_clrNorText = clrText;
-
}
-
//设置选择文本的颜色
-
void CSwitchBtn::SetHotTextColor(COLORREF clrHotText)
-
{
-
m_clrHotText = clrHotText;
-
}
-
//设置外边框的颜色
-
void CSwitchBtn::SetBorderColor(COLORREF clrBorder)
-
{
-
m_clrNorBorder = clrBorder;
-
}
-
//设置滑块边框的颜色
-
void CSwitchBtn::SetSliderBorderColor(COLORREF clrSliderBorder)
-
{
-
m_clrHotBorder = clrSliderBorder;
-
}
测试代码如下:
-
CSwitchBtn m_btn1;
-
CSwitchBtn m_btn2;
-
//按钮1
-
m_btn1.CreateButton(CRect(20,10,200,50),this,WM_SWITCHBTN1);
-
m_btn1.SetText("打开","关闭");
-
//按钮2
-
m_btn2.CreateButton(CRect(20,65,200,105),this,WM_SWITCHBTN2);
-
m_btn2.InitButton("选项一","选项二",false);
-
//设置颜色
-
m_btn2.SetBKColor(RGB(111,222,20));
-
m_btn2.SetSliderColor(RGB(250,0,0));
-
m_btn2.SetBorderColor(RGB(0,250,250));
-
m_btn2.SetSliderBorderColor(RGB(200,200,200));
-
m_btn2.SetTextColor(RGB(100,100,100));
-
m_btn2.SetHotTextColor(RGB(255,2550,0));
控件源码(包括测试源码)打包下载地址:http://download.csdn.net/detail/cbnotes/5022058