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

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. MYSQ提高L查询效率的策略总结

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值推断,否则将导致引擎放弃使用索 ...

  2. 【BZOJ1132】【POI2008】Tro 计算几何 叉积求面积

    链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...

  3. 使用gson(一)

    1.数组和json的转换 package com.test.gson; import com.google.gson.Gson; public class ArrayToJson { public s ...

  4. Selenium Grid跨浏览器-兼容性测试

    Selenium Grid跨浏览器-兼容性测试 这里有两台机子,打算这样演示: 一台机子启动一个作为主点节的hub 和 一个作为次节点的hub(系统windows 浏览器为ie) ip为:192.16 ...

  5. Java I/O流-PipedInputStream、PipedOutputStream

    一.整体代码图 PipedStreamDemo.java import java.io.*; class PipedStreamDemo { public static void main(Strin ...

  6. C#中ref参数及out参数对比

    ref 关键字和out关键字均会导致参数通过引用来传递(相同点1).这是两者的共同点. 通过引用传递参数,会使方法中对参数所做的任何修改都将反映在该变量中. 两者还有一个共同点,那就是:若要使用 re ...

  7. C++如何屏蔽双击运行程序功能?

    问题描述: 我们开发过程中可能会经常遇到,需要屏蔽EXE的双击运行功能,只能通过宿主程序(Service或EXE)来启动.比如腾讯的迷你弹窗,就只能通过主程序来启动,而不能直接通过双击来运行. 实现原 ...

  8. premake在Ubuntu和GCC环境下创建简单的C++工程

    由于premake基于lua脚本,为了方便编辑lua脚本,我在emacs24中利用package system安装了lua-mode. 然后创建config.lua文件,填入下面这段,主要来自:htt ...

  9. php的var关键字

    public和var的作用差不多 因为 var定义的变量如果没有加protected 或 private则默认为public php4 中一般是用 varphp5 中就一般是用 public了 现在基 ...

  10. JAVA学习笔记 -- 数据结构

    一.数据结构的接口 在Java中全部类的鼻祖是Object类,可是全部有关数据结构处理的鼻祖就是Collection和Iterator接口,也就是集合与遍历. 1.Collection接口 Colle ...