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
欢迎大家多多批评指正,有任何意见和改进请留言,谢谢。
===========================================
转载请标明出处,谢谢。http://blog.csdn.net/cbNotes
===========================================