按钮自绘,将按钮区域分成三部分,左边、右边、中间都由贴图绘制,可用于手动进度条按钮,或者左右选择项按钮

cpp代码部分:

  1. // LRSkinButton.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "CRedrawButtonDemo.h"
  5. #include "LRSkinButton.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CLRSkinButton
  13. CLRSkinButton::CLRSkinButton()
  14. {
  15. m_nWidth = 17;
  16. m_nHeight = 16;
  17. m_bDrawBorder = TRUE;
  18. }
  19. CLRSkinButton::~CLRSkinButton()
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CLRSkinButton, CButton)
  23. //{{AFX_MSG_MAP(CLRSkinButton)
  24. // NOTE - the ClassWizard will add and remove mapping macros here.
  25. //}}AFX_MSG_MAP
  26. ON_WM_CAPTURECHANGED()
  27. ON_WM_MOUSEMOVE()
  28. ON_WM_SETCURSOR()
  29. ON_WM_KILLFOCUS()
  30. END_MESSAGE_MAP()
  31. void CLRSkinButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
  32. {
  33. //  TRACE("DrawItem\n");
  34. // TODO:  添加您的代码以绘制指定项
  35. CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
  36. HDC hDC = pDC->GetSafeHdc();
  37. // 按钮客户区域
  38. CRect rectItem(lpDrawItemStruct->rcItem);
  39. m_nHeight = rectItem.Height();
  40. m_nWidth = 26;
  41. CRect rectCenter(rectItem.left+m_nWidth, rectItem.top, rectItem.right-m_nWidth, rectItem.bottom);
  42. CRect rectLeft(rectItem.left, rectItem.top, rectItem.left+m_nWidth, rectItem.top+m_nHeight);
  43. CRect rectRight(rectItem.right-m_nWidth,rectItem.top,rectItem.right,rectItem.bottom);
  44. static int nClrWidth = rectCenter.Width()/10;
  45. CRect rectColor(rectCenter.left, rectCenter.top, rectCenter.left, rectCenter.bottom);
  46. rectCenter.DeflateRect(0,1,0,1);
  47. //  pDC->SetBkMode(TRANSPARENT);
  48. HPEN hOldPen;
  49. UINT action, state;
  50. action = lpDrawItemStruct->itemAction;
  51. state  = lpDrawItemStruct->itemState;
  52. BOOL bIsPressed, bIsFocus, bIsDisabled;
  53. bIsPressed = state & ODS_SELECTED;
  54. bIsDisabled = state & ODS_DISABLED;
  55. bIsFocus = (state & ODS_FOCUS) == ODS_FOCUS; // ::GetFocus() == m_hWnd;
  56. ::SetBkColor(hDC, RGB(22, 33, 55));
  57. // Draw pressed button
  58. if (bIsPressed)
  59. {// 按钮按下状态
  60. /*
  61. HPEN penBtnHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT)); // Bianco
  62. HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));   // Grigio scuro
  63. // draw darkline of left-top conner
  64. hOldPen = (HPEN)SelectObject(hDC,penBtnShadow);
  65. MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
  66. LineTo(hDC,rectItem.left, rectItem.top);
  67. LineTo(hDC,rectItem.right, rectItem.top);
  68. // draw hilight line of right-bottom conner
  69. SelectObject(hDC,penBtnHiLight);
  70. MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
  71. LineTo(hDC,rectItem.right-1, rectItem.bottom-1);
  72. LineTo(hDC,rectItem.right-1, rectItem.top-1);
  73. //release resource
  74. SelectObject(hDC,hOldPen);
  75. DeleteObject(penBtnShadow);
  76. DeleteObject(penBtnHiLight);
  77. */
  78. // 判断点击的是左区域还是右区域
  79. POINT pos;
  80. GetCursorPos( &pos );
  81. ScreenToClient(&pos);
  82. if (PtInRect( &rectLeft, pos))
  83. {// 左键
  84. TRACE(_T("Clicked Left...\n"));
  85. nClrWidth -= 5;
  86. if (nClrWidth <=0)
  87. {
  88. nClrWidth = 0;
  89. }
  90. }
  91. if (PtInRect( &rectRight, pos))
  92. {// 右键
  93. TRACE(_T("Clicked Right...\n"));
  94. nClrWidth += 5;
  95. if (nClrWidth >= rectCenter.Width())
  96. {
  97. nClrWidth = rectCenter.Width();
  98. }
  99. }
  100. }
  101. else // ...else draw non pressed button
  102. {
  103. if(!m_bIsFlat || (m_bIsFlat && m_MouseOnButton))
  104. {// 鼠标移动到按钮上面时的状态
  105. /*
  106. HPEN pen3DLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT));       // Light gray
  107. HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));   // Dark gray
  108. // White line
  109. hOldPen = (HPEN)SelectObject(hDC,pen3DLight);
  110. MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
  111. LineTo(hDC,rectItem.left, rectItem.top);
  112. LineTo(hDC,rectItem.right, rectItem.top);
  113. // Dark gray line
  114. SelectObject(hDC,penBtnShadow);
  115. MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
  116. LineTo(hDC,rectItem.right-1, rectItem.bottom-1);
  117. LineTo(hDC,rectItem.right-1, rectItem.top-1);
  118. //
  119. SelectObject(hDC,hOldPen);
  120. DeleteObject(pen3DLight);
  121. DeleteObject(penBtnShadow);
  122. */
  123. }
  124. else{// FLAT 属性
  125. if(m_bDrawBorder)
  126. { // 失去焦点的时候绘制按钮边框
  127. HPEN penBorder = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
  128. hOldPen = (HPEN)SelectObject(hDC,penBorder);
  129. SelectObject(hDC,GetStockObject(NULL_BRUSH));
  130. // 绘制按钮边框
  131. Rectangle(hDC,rectItem.left, rectItem.top, rectItem.right, rectItem.bottom);
  132. SelectObject(hDC, hOldPen);
  133. DeleteObject(penBorder);
  134. }
  135. }
  136. }
  137. //  if (lpDrawItemStruct->itemData != NULL)
  138. //  {
  139. // 画图标
  140. CRect rect(rectCenter);
  141. //  rect.DeflateRect(0,5,0,0); // 改变矩形范围
  142. CDC dcMem;
  143. dcMem.CreateCompatibleDC(pDC);
  144. // 背景图
  145. CBitmap bmp;
  146. BITMAP bitmap;
  147. bmp.LoadBitmap(m_nBmpBK);
  148. bmp.GetBitmap( &bitmap );
  149. CBitmap* pOldBmp = dcMem.SelectObject(&bmp);
  150. pDC->StretchBlt(rectCenter.left, rectCenter.top, rectCenter.Width(), rectCenter.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
  151. bmp.DeleteObject();
  152. // 左按钮图
  153. bmp.LoadBitmap( m_nBmpLeft );
  154. dcMem.SelectObject( &bmp );
  155. bmp.GetBitmap( &bitmap );
  156. //  pDC->BitBlt(rectLeft.left,rectLeft.top,rectLeft.Width(),rectLeft.Height(),&dcMem,0,0,SRCCOPY);
  157. pDC->StretchBlt(rectLeft.left, rectLeft.top, rectLeft.Width(), rectLeft.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
  158. bmp.DeleteObject();
  159. // 右按钮图
  160. bmp.LoadBitmap( m_nBmpRight );
  161. bmp.GetBitmap( &bitmap );
  162. dcMem.SelectObject( &bmp );
  163. //  pDC->BitBlt(rectRight.left,rectRight.top,rectRight.Width(),rectRight.Height(),&dcMem,0,0,SRCCOPY);
  164. pDC->StretchBlt(rectRight.left, rectRight.top, rectRight.Width(), rectRight.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
  165. bmp.DeleteObject();
  166. dcMem.SelectObject(pOldBmp);
  167. // 绘制颜色进度条
  168. bmp.LoadBitmap(IDB_BMP_BTNLEFT);
  169. //  CBrush brush(&bmp);   //RGB(255, 255, 0)
  170. CBrush brush(RGB(255, 255, 0));   //
  171. rectColor.right = rectColor.left+nClrWidth;
  172. pDC->FillRect(rectColor, &brush);
  173. //      CBrush *pOldBrush = (CBrush*)pDC->SelectObject(&brush);
  174. //      pDC->Rectangle(&rectColor);
  175. //      pDC->SelectObject(pOldBrush);
  176. bmp.DeleteObject();
  177. // 绘制文字
  178. rect = rectCenter;
  179. //  rect.DeflateRect(0,5,0,0);  // 调整矩形大小
  180. rect.InflateRect(0,1,0,1);
  181. pDC->SetTextColor(RGB(0,0,0));
  182. //      rect.OffsetRect(2,1); // 平行移动矩形位置
  183. //  char zsCaption[64] = {0};
  184. CString str;
  185. GetWindowText( str );
  186. COLORREF clr = GetSysColor( COLOR_3DHILIGHT);
  187. clr = RGB(55, 155, 55);
  188. if (bIsPressed)
  189. {
  190. clr = RGB(155, 55, 55);
  191. }
  192. else if (bIsFocus /*|| m_MouseOnButton*/)
  193. {
  194. clr = RGB(55, 55, 155);
  195. HPEN penBorder = CreatePen(PS_SOLID, 1, RGB(255,0,255));
  196. hOldPen = (HPEN)SelectObject(hDC,penBorder);
  197. SelectObject(hDC,GetStockObject(NULL_BRUSH));
  198. // 绘制按钮边框
  199. Rectangle(hDC,rect.left, rect.top, rect.right, rect.bottom);
  200. SelectObject(hDC, hOldPen);
  201. DeleteObject(penBorder);
  202. }
  203. pDC->SetBkColor(clr);
  204. pDC->SetTextColor( RGB(255, 0, 0) );
  205. pDC->DrawText(str, str.GetLength(),rect, DT_CENTER | DT_VCENTER| DT_SINGLELINE);
  206. //  }
  207. }
  208. void CLRSkinButton::SetBtnBmps( UINT uBmpBK, UINT uBmpLeft, UINT uBmpRight )
  209. {
  210. m_nBmpBK = uBmpBK;
  211. m_nBmpLeft = uBmpLeft;
  212. m_nBmpRight = uBmpRight;
  213. }
  214. void CLRSkinButton::PreSubclassWindow()
  215. {
  216. UINT nBS = GetButtonStyle();
  217. if(nBS & BS_DEFPUSHBUTTON)
  218. m_bDefaultBtn = TRUE;
  219. else
  220. m_bDefaultBtn = FALSE;
  221. SetButtonStyle(nBS | BS_OWNERDRAW);
  222. CButton::PreSubclassWindow();
  223. }
  224. /////////////////////////////////////////////////////////////////////////////
  225. // CLRSkinButton message handlers
  226. void CLRSkinButton::OnCaptureChanged(CWnd *pWnd)
  227. {
  228. if(m_MouseOnButton == TRUE)
  229. {
  230. ReleaseCapture();
  231. Invalidate();
  232. }
  233. CButton::OnCaptureChanged(pWnd);
  234. }
  235. void CLRSkinButton::OnMouseMove(UINT nFlags, CPoint point)
  236. {
  237. CButton::OnMouseMove(nFlags, point);
  238. HWND hParent; // Finestra che contiene il bottone
  239. // If the mouse enter the button with the left button pressed then do nothing
  240. if (nFlags & MK_LBUTTON && !m_MouseOnButton)
  241. return;
  242. // If our button is not flat then do nothing
  243. if (m_bIsFlat)
  244. {
  245. hParent = ::GetParent(m_hWnd);
  246. if ((::GetCapture() != m_hWnd) &&   (hParent != NULL))
  247. {
  248. m_MouseOnButton = TRUE;
  249. SetCapture();
  250. Invalidate();
  251. }
  252. else
  253. {
  254. RECT rc;
  255. GetClientRect(&rc);
  256. if (!PtInRect(&rc,point))
  257. {
  258. // Redraw only if mouse goes out
  259. if (m_MouseOnButton == TRUE)
  260. {
  261. m_MouseOnButton = FALSE;
  262. Invalidate();
  263. }
  264. // If user is NOT pressing left button then release capture!
  265. if (!(nFlags & MK_LBUTTON))
  266. ReleaseCapture();
  267. }
  268. }
  269. }
  270. }
  271. BOOL CLRSkinButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  272. {
  273. if (m_hBtnCursor != NULL)
  274. {
  275. ::SetCursor(m_hBtnCursor);
  276. return TRUE;
  277. }
  278. return CButton::OnSetCursor(pWnd, nHitTest, message);
  279. }
  280. void CLRSkinButton::OnKillFocus(CWnd* pNewWnd)
  281. {
  282. CButton::OnKillFocus(pNewWnd);
  283. if(!m_bIsFlat)
  284. {
  285. m_MouseOnButton = FALSE;
  286. Invalidate();
  287. }
  288. }

vc 按钮自绘的更多相关文章

  1. VC++ WIN32 sdk实现按钮自绘详解.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  2. VC++ WIN32 sdk实现按钮自绘详解 之二(关键是BS_OWNERDRAW和WM_DRAWITEM)

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  3. VC++ WIN32 sdk实现按钮自绘详解 之二.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  4. VC按钮控件实现指示灯效果

    VC为按钮控件添加图片的方法有很多种: 直接调用SetBitmap:  CButton pButton->SetBitmap(hBitmap); 使用CButtonST控件: 使用CDC: 使用 ...

  5. Windows开发进阶之VC++中如何实现对话框的界面重绘

    技术:Windows 系统+Visual studio 2008   概述 应用程序界面是用户与应用程序之间的交互的桥梁和媒介,用户界面是应用程序中最重要的组成部分,也是最为直观的视觉体现.对用户而言 ...

  6. Windows 开发之VC++垃圾清理程序软件

    概述 本程序软件的主要实现垃圾文件清理的功能,即对指定的文件格式的临时文件或垃圾文件进行遍历.扫描.显示.删除清理等功能.在程序界面设计方面,对默认对话框重新自定义绘制,主要包括标题栏的重绘.对话框边 ...

  7. win32进阶之路:给锁屏软件增加一个超链接按钮

    前言: windows下一切皆窗口,我们看到的超链接也是窗口,效果图如下: 鼠标放在赵大哥博客园主页和关于软件两个按钮上,按钮上的字体会从绿色变成红色,同时鼠标指针变为手型,点下鼠标左键就会调用默认浏 ...

  8. MFC/VC++ UI界面美化技术

    1.     工具: 1.1设备环境类: Windows下的绘图操作说到底就是DC操作.DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它. ...

  9. 用Delphi制作仿每行带按钮的列表

    Delphi做程序开发在使用到列表控件时,一般是列表放文本内容,在列表以外放操作按钮,选中列表某项再点按钮进行操作.现在Web开发做列表的样式总是列表的每行都有操作按钮,如微博的列表风格: Web开发 ...

随机推荐

  1. 基于visual Studio2013解决C语言竞赛题之0603打印素数

     题目

  2. kingso_module - Taocode

    kingso_module - Taocode 模块介绍 Merger 功能介绍 Merger的功能: 合并多台Searcher机器的部分查询结果,得到最终的完整查询结果 向Detail集群请求最终展 ...

  3. python模块介绍- multi-mechanize 性能测试工具

    python模块介绍- multi-mechanize 性能测试工具 2013-09-13 磁针石 #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 3739 ...

  4. Android PopupWindow显示位置和显示大小

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3l1YW41MTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  5. 【转】centOS上安装redis+phpredis2.2.4扩展

    原文链接:http://www.cnblogs.com/xsi640/p/3756130.html 我原来的安装方式:http://www.cnblogs.com/wuling129/p/464738 ...

  6. CentOS 漏洞修补

    以前没注意 今后得实时更新系统漏洞和补丁了! 1.Bash软件安全漏洞检测及解决方案 http://netsecurity.51cto.com/art/201409/452322.htm

  7. Swift中的ViewController

    ViewController是iOS应用程序中重要的部分,是应用程序数据和视图之间的重要桥梁,ViewController管理应用中的众多视图.iOS的SDK中提供很多原生ViewController ...

  8. DP HDIJ1421 搬宿舍

    Problem Description 搬寝室是很累的,xhd深有体会.时间追述2006年7月9号,那天xhd迫于无奈要从27号楼搬到3号楼,因为10号要封楼了.看着寝室里的n件物品,xhd开始发呆, ...

  9. new Handler().postDelayed() 延迟intent跳转

    原文地址http://blog.csdn.net/x605940745/article/details/19401549 new Handler().postDelayed(new Runnable( ...

  10. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...