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

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. HDU--杭电--1501--Zipper--深搜、DP都好

    Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. CentOS 如何安装git server + Gitolite 【配置不成功需要再测试2015-8-20】

    安装git 关于安装git  可以参考 http://gitolite.com/gitolite/install.html 里面有官方的介绍 1. Git 的工作需要调用 curl,zlib,open ...

  3. Android 关于网址,电话号码,邮箱的正则表达式-最权威

    需求:判断网址是否合法 今天在写一个项目的时候,需要能够识别网址的功能,首先想到的是正则表达式 但是网址的类型多种多样,网络上各种表达式也一搜一大把,很难知道哪一位大神写的靠谱 发现:TextView ...

  4. 通过jQuery的attr修改onclick

    var js = "alert('B:' + this.id); return false;"; // creates a function from the "js&q ...

  5. Haxe UI框架StablexUI的使用备忘与心得(序)

    最近在手上的项目开发中,从原来的使用Sprite全手写UI,开始逐步使用StablexUI,感觉还是相当不错的,强大.高效.轻量.灵活,非常适应我当前的实际需求. 不过作为小种语言的一个小众第三方开源 ...

  6. 获取CPU序列号

    public string GetCPUSerialNo() { string cpuSerialNo = string.Empty; ManagementClass managementClass ...

  7. 【linux kernel】 中断处理-中断下半部

    欢迎转载,转载时需保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...

  8. Java集合框架Collection

    转自:http://www.cdtarena.com/javapx/201306/8891.html [plain] view plaincopyprint?01.在 Java2中,有一套设计优良的接 ...

  9. WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿

    原文:[原创]WCF技术剖析之三:如何进行基于非HTTP的IIS服务寄宿 在上面一篇文章中,我们对不同版本的IIS,以及ASP.NET得的实现机制进行了详细而深入的分析.在介绍IIS7.0的时候,我们 ...

  10. LoadRunner监控数据库服务器

    使用LoadRunner的数据库服务器资源监控器,可以在场景或会话步骤运行期间监控DB2.Oracle.SQL Server或Sybase数据库的资源使用率.在场景或会话步骤运行期间,使用这些监控器可 ...