VC++实现切换按钮

VC++实现切换按钮

有时候要实现两个选项的切换,常规做法1是放两个Radio按钮控件,并设置这两个按钮为一组。2是放一个Check按钮控件。但感觉都不是那么理想和直观。有没有更好的实现方式呢?下面将给你介绍一种我自绘的控件,我把它命名为“切换控件”(SwitchButton)。实现的效果如下图实现,给你一个多的选择,以供参考。

下面是实现源码:

 
  1. /////////////////////////////// 说明文件/////////////////////////////////////////////

  2. //文件:SwitchBtn.h //

  3. //功能:切换按钮类,实现两个选项一个按钮实现,自绘实现。 //

  4. //作者:cbNotes(http://blog.csdn.net/cbnotes) //

  5. //版本:1.0.0 //

  6. //时间:2013-01-23 //

  7. //备注:该控件类免费开源,欢迎大家使用和改进。但请保持该说明文件的完整和原创性 //

  8. /////////////////////////////////////////////////////////////////////////////////////

  9.  
  10. #pragma once

  11.  
  12. // CSwitchBtn

  13.  
  14. class CSwitchBtn : public CWnd

  15. {

  16. DECLARE_DYNAMIC(CSwitchBtn)

  17.  
  18. public:

  19. CSwitchBtn();

  20. virtual ~CSwitchBtn();

  21. private:

  22. int m_nID; //控件ID

  23. CWnd *m_pParentWnd; //父窗口指针

  24. BOOL m_bAnimation; //是否动画标记

  25. BOOL m_bLeft; //是否选择左边标记

  26. CString m_szLeftText,m_szRightText;

  27. COLORREF m_clrNorText,m_clrHotText;//文字颜色

  28. COLORREF m_clrNorBG,m_clrHotBG; //背景颜色

  29. COLORREF m_clrNorBorder,m_clrHotBorder;//边框颜色

  30. int m_ngap;//间隔

  31.  
  32. protected:

  33. DECLARE_MESSAGE_MAP()

  34. public:

  35. //自绘按钮

  36. afx_msg void OnPaint();

  37. //按钮按钮释放消息处理,主要是发送消息

  38. afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

  39. afx_msg BOOL OnEraseBkgnd(CDC* pDC);

  40. //设置按钮上的文字

  41. void SetText(CString szLeft,CString szRight);

  42. // 选择哪个选项

  43. void SetSelect(bool bLeft);

  44. // 设置背景色

  45. void SetBKColor(COLORREF clrBackGround);

  46. // 设置滑块的颜色

  47. void SetSliderColor(COLORREF clrSider);

  48. // 设置文本的颜色

  49. void SetTextColor(COLORREF clrText);

  50. //设置选择文本的颜色

  51. void SetHotTextColor(COLORREF clrHotText);

  52. //设置外边框的颜色

  53. void SetBorderColor(COLORREF clrBorder);

  54. //设置滑块边框的颜色

  55. void SetSliderBorderColor(COLORREF clrSliderBorder);

  56. // 动态创建按钮

  57. bool CreateButton(CRect rt,CWnd *pParentWnd,int nID);

  58. // 初始化按钮

  59. void InitButton(CString szLeft,CString szRight,bool bLeft = true);

  60. };

  61.  
 
  1. /////////////////////////////// 说明文件/////////////////////////////////////////////

  2. //文件:SwitchBtn.cpp //

  3. //功能:切换按钮类,实现两个选项一个按钮实现,自绘实现。 //

  4. //作者:cbNotes(http://blog.csdn.net/cbnotes) //

  5. //版本:1.0.0 //

  6. //时间:2013-01-23 //

  7. //备注:该控件类免费开源,欢迎大家使用和改进。但请保持该说明文件的完整和原创性 //

  8. /////////////////////////////////////////////////////////////////////////////////////

  9.  
  10. #include "stdafx.h"

  11. #include "SwitchBtnTest.h"

  12. #include "SwitchBtn.h"

  13.  
  14.  
  15. // CSwitchBtn

  16.  
  17. IMPLEMENT_DYNAMIC(CSwitchBtn, CWnd)

  18.  
  19. CSwitchBtn::CSwitchBtn()

  20. {

  21. m_pParentWnd = NULL;

  22. m_bAnimation = FALSE;

  23. m_bLeft = TRUE;

  24. m_szLeftText = "左边";

  25. m_szRightText = "右边";

  26.  
  27. m_clrNorText = RGB(0,0,0);//文字颜色

  28. m_clrHotText = RGB(255,255,255);

  29. m_clrNorBG = RGB(200,200,200);//背景颜色

  30. m_clrHotBG = RGB(254,184,66);

  31. m_clrNorBorder = RGB(128,128,128);//边框颜色

  32. m_clrHotBorder = RGB(0,0,255);

  33. m_ngap =10;//间隔

  34. }

  35.  
  36. CSwitchBtn::~CSwitchBtn()

  37. {

  38. }

  39.  
  40.  
  41. BEGIN_MESSAGE_MAP(CSwitchBtn, CWnd)

  42. ON_WM_PAINT()

  43. ON_WM_LBUTTONUP()

  44. ON_WM_ERASEBKGND()

  45. END_MESSAGE_MAP()

  46.  
  47.  
  48.  
  49. // CSwitchBtn 消息处理程序

  50.  
  51.  
  52. // 初始化按钮

  53. void CSwitchBtn::InitButton(CString szLeft,CString szRight,bool bLeft)

  54. {

  55. m_szLeftText = szLeft;

  56. m_szRightText = szRight;

  57. m_bLeft = bLeft;

  58. }

  59.  
  60. // 动态创建按钮

  61. bool CSwitchBtn::CreateButton(CRect rt,CWnd *pParentWnd,int nID)

  62. {

  63. if (!pParentWnd)

  64. {

  65. return false;

  66. }

  67. m_pParentWnd = pParentWnd;

  68. m_nID = nID;//用于消息的标识

  69. return Create(NULL,NULL,WS_CHILD|WS_VISIBLE,rt,pParentWnd,nID);

  70. }

  71.  
  72. void CSwitchBtn::OnPaint()

  73. {

  74. CPaintDC dc(this); // device context for painting

  75. // TODO: 在此处添加消息处理程序代码

  76. // 不为绘图消息调用 CWnd::OnPaint()

  77. CRect winrt;

  78. GetClientRect(&winrt);

  79. CDC memDC;

  80. memDC.CreateCompatibleDC(&dc);

  81. CBitmap bmp;

  82. bmp.CreateCompatibleBitmap(&dc,winrt.Width(),winrt.Height());

  83. memDC.SelectObject(&bmp);

  84. memDC.FillSolidRect(winrt,RGB(240,240,240));//

  85. //背景

  86. CBrush norbgbrush,hotbgbrush;//

  87. norbgbrush.CreateSolidBrush(m_clrNorBG);

  88. hotbgbrush.CreateSolidBrush(m_clrHotBG);

  89. CBrush* pOldBrush = memDC.SelectObject(&norbgbrush);

  90. //边框

  91. CPen norborderpen,hotborderpen;

  92. norborderpen.CreatePen(PS_SOLID, 2, m_clrNorBorder);

  93. hotborderpen.CreatePen(PS_SOLID, 1, m_clrHotBorder);

  94. CPen* pOldPen = memDC.SelectObject(&norborderpen);

  95. CFont font;

  96. font.CreatePointFont(160,"宋体");

  97. memDC.SelectObject(&font);

  98. memDC.SetBkMode(TRANSPARENT);

  99. CRect leftrt,rightrt;

  100. leftrt = rightrt = winrt;

  101. leftrt.right=leftrt.left+winrt.Width()/2-m_ngap/2;

  102. leftrt.DeflateRect(3,3,2,2);

  103.  
  104. rightrt.left=rightrt.right-winrt.Width()/2+m_ngap/2;

  105. rightrt.DeflateRect(3,3,2,2);

  106. //

  107. CRect rt = winrt;

  108. rt.DeflateRect(2,2,0,0);

  109. if(!m_bAnimation)

  110. {

  111. //画背景

  112. memDC.RoundRect(&rt,CPoint(17,17));

  113. //焦点背景

  114. pOldBrush = memDC.SelectObject(&hotbgbrush);

  115. pOldPen = memDC.SelectObject(&hotborderpen);

  116. if (m_bLeft)

  117. {//

  118. memDC.RoundRect(&leftrt,CPoint(17,17));

  119. }

  120. else

  121. {

  122. memDC.RoundRect(&rightrt,CPoint(17,17));

  123. }

  124. //写文字

  125. if (m_bLeft)

  126. { //左边文字

  127. memDC.SetTextColor(m_clrHotText);

  128. memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  129. //右边文字

  130. memDC.SetTextColor(m_clrNorText);

  131. memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  132. }

  133. else

  134. {

  135. memDC.SetTextColor(m_clrNorText);

  136. memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  137.  
  138. memDC.SetTextColor(m_clrHotText);

  139. memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  140. }

  141. dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);

  142. }

  143. else

  144. {//动画切换

  145. CRect rr= winrt;

  146. rr.DeflateRect(2,2,0,0);

  147. if (m_bLeft)

  148. {//往左

  149. rt = rightrt;

  150. while(rt.left>winrt.left+3)

  151. {

  152. pOldBrush =memDC.SelectObject(&norbgbrush);

  153. pOldPen = memDC.SelectObject(&norborderpen);

  154. memDC.RoundRect(&rr,CPoint(17,17));

  155. rt.OffsetRect(CPoint(-5,0));

  156. pOldPen = memDC.SelectObject(&hotborderpen);

  157. pOldBrush = memDC.SelectObject(&hotbgbrush);

  158. memDC.RoundRect(&rt,CPoint(17,17));

  159. //写文字

  160. //左边文字

  161. memDC.SetTextColor(m_clrHotText);

  162. memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  163. //右边文字

  164. memDC.SetTextColor(m_clrNorText);

  165. memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  166. dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);

  167. Sleep(10);

  168. }

  169. }

  170. else

  171. {//往右

  172. rt = leftrt;

  173. while(rt.right<winrt.right-3)

  174. {

  175. pOldBrush =memDC.SelectObject(&norbgbrush);

  176. pOldPen = memDC.SelectObject(&norborderpen);

  177. memDC.RoundRect(&rr,CPoint(17,17));

  178. rt.OffsetRect(CPoint(5,0));

  179. pOldPen = memDC.SelectObject(&hotborderpen);

  180. pOldBrush = memDC.SelectObject(&hotbgbrush);

  181. memDC.RoundRect(&rt,CPoint(17,17));

  182. //写文字

  183. memDC.SetTextColor(m_clrNorText);

  184. memDC.DrawText(m_szLeftText,m_szLeftText.GetLength(),&leftrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  185.  
  186. memDC.SetTextColor(m_clrHotText);

  187. memDC.DrawText(m_szRightText,m_szRightText.GetLength(),&rightrt,DT_VCENTER|DT_CENTER|DT_SINGLELINE);

  188. dc.BitBlt(0,0,winrt.Width(),winrt.Height(),&memDC,0,0,SRCCOPY);

  189. Sleep(10);

  190. }

  191. }

  192. m_bAnimation = FALSE;

  193. }

  194. bmp.DeleteObject();

  195. norbgbrush.DeleteObject();

  196. hotbgbrush.DeleteObject();

  197. norborderpen.DeleteObject();

  198. hotborderpen.DeleteObject();

  199. font.DeleteObject();

  200. memDC.DeleteDC();

  201. }

  202.  
  203. void CSwitchBtn::OnLButtonUp(UINT nFlags, CPoint point)

  204. {

  205. // TODO: 在此添加消息处理程序代码和/或调用默认值

  206. CRect rt;

  207. GetClientRect(&rt);

  208. CRect leftrt,rightrt;

  209. leftrt = rightrt =rt;

  210. leftrt.right=leftrt.left+rt.Width()/2-m_ngap/2;

  211. leftrt.DeflateRect(2,2,2,2);

  212.  
  213. rightrt.left=rightrt.right-rt.Width()/2+m_ngap/2;

  214. rightrt.DeflateRect(2,2,2,2);

  215.  
  216. if (m_bLeft)

  217. {

  218. if (rightrt.PtInRect(point))

  219. {

  220. m_bLeft = FALSE;

  221. m_bAnimation = TRUE;

  222. m_pParentWnd->SendMessage(m_nID,1,0);

  223. Invalidate();

  224. }

  225. }

  226. else

  227. {

  228. if (leftrt.PtInRect(point))

  229. {

  230. m_bLeft = TRUE;

  231. m_bAnimation = TRUE;

  232. m_pParentWnd->SendMessage(m_nID,0,0);

  233. Invalidate();

  234. }

  235. }

  236. CWnd::OnLButtonUp(nFlags, point);

  237. }

  238.  
  239. BOOL CSwitchBtn::OnEraseBkgnd(CDC* pDC)

  240. {

  241. // TODO: 在此添加消息处理程序代码和/或调用默认值

  242. return FALSE;

  243. //return CWnd::OnEraseBkgnd(pDC);

  244. }

  245.  
  246. void CSwitchBtn::SetText(CString szLeft,CString szRight)

  247. {

  248. m_szLeftText = szLeft;

  249. m_szRightText = szRight;

  250. }

  251.  
  252. // 选择哪个选项

  253. void CSwitchBtn::SetSelect(bool bLeft)

  254. {

  255. m_bLeft = bLeft;

  256. }

  257.  
  258. // 设置背景色

  259. void CSwitchBtn::SetBKColor(COLORREF clrBackGround)

  260. {

  261. m_clrNorBG = clrBackGround;

  262. }

  263. // 设置滑块的颜色

  264. void CSwitchBtn::SetSliderColor(COLORREF clrSider)

  265. {

  266. m_clrHotBG = clrSider;

  267. }

  268.  
  269. // 设置文本的颜色

  270. void CSwitchBtn::SetTextColor(COLORREF clrText)

  271. {

  272. m_clrNorText = clrText;

  273. }

  274.  
  275. //设置选择文本的颜色

  276. void CSwitchBtn::SetHotTextColor(COLORREF clrHotText)

  277. {

  278. m_clrHotText = clrHotText;

  279. }

  280.  
  281. //设置外边框的颜色

  282. void CSwitchBtn::SetBorderColor(COLORREF clrBorder)

  283. {

  284. m_clrNorBorder = clrBorder;

  285. }

  286.  
  287. //设置滑块边框的颜色

  288. void CSwitchBtn::SetSliderBorderColor(COLORREF clrSliderBorder)

  289. {

  290. m_clrHotBorder = clrSliderBorder;

  291. }


测试代码如下:

 
  1. CSwitchBtn m_btn1;

  2. CSwitchBtn m_btn2;

  3. //按钮1

  4. m_btn1.CreateButton(CRect(20,10,200,50),this,WM_SWITCHBTN1);

  5. m_btn1.SetText("打开","关闭");

  6. //按钮2

  7. m_btn2.CreateButton(CRect(20,65,200,105),this,WM_SWITCHBTN2);

  8. m_btn2.InitButton("选项一","选项二",false);

  9. //设置颜色

  10. m_btn2.SetBKColor(RGB(111,222,20));

  11. m_btn2.SetSliderColor(RGB(250,0,0));

  12. m_btn2.SetBorderColor(RGB(0,250,250));

  13. m_btn2.SetSliderBorderColor(RGB(200,200,200));

  14. m_btn2.SetTextColor(RGB(100,100,100));

  15. m_btn2.SetHotTextColor(RGB(255,2550,0));

控件源码(包括测试源码)打包下载地址:http://download.csdn.net/detail/cbnotes/5022058

猜你喜欢

转载自blog.csdn.net/u011647007/article/details/81433358