WTL 自绘Button类,支持按钮三种形态,正常模式,hover模式,鼠标按下模式,支持png图片。使用方法很简单:

MyButton* pButton = new MyButton;
   pButton->SetBtnBmp(strBtnNormal,strBtnHover,strBtnDown);
   pButton->Create(m_hWnd,rt,NULL,WS_CHILD|WS_VISIBLE);
   pButton->SetBtnID(nID);//该ID是用来处理WM_COMMAND 命令的,即单机左键命令

  1. #pragma once
  2.  
  3. #pragma comment(lib, "gdiplus.lib")
  4. static ULONG_PTR s_gdiplusToken2=0;
  5.  
  6. enum
  7. {
  8. btn_state_normal = 0,
  9. btn_state_over = 1,
  10. btn_state_down = 2
  11. };
  12.  
  13. class MyButton:public CWindowImpl<MyButton>
  14. {
  15. public:
  16. MyButton()
  17. {
  18. GdiplusStartupInput gdiplusStartupInput;
  19. GdiplusStartup(&s_gdiplusToken2, &gdiplusStartupInput, NULL);
  20. m_nState = btn_state_normal;
  21. m_bBtnDown = false;
  22.  
  23. }
  24. ~MyButton()
  25. {
  26. GdiplusShutdown(s_gdiplusToken2);
  27. }
  28. protected:
  29. BEGIN_MSG_MAP(MyButton)
  30. MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  31. MESSAGE_HANDLER(WM_PAINT,OnPaint)
  32. MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)
  33. MESSAGE_HANDLER(WM_MOUSELEAVE,OnMouseLeave)
  34. MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown)
  35. MESSAGE_HANDLER(WM_LBUTTONUP,OnLButtonUp)
  36. MESSAGE_HANDLER(WM_CREATE,OnCreate)
  37. MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBkgnd)
  38. END_MSG_MAP()
  39.  
  40. LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  41. {
  42. CRect winRect;
  43. GetWindowRect(winRect);
  44. SetWindowPos(HWND_TOPMOST,winRect,SWP_SHOWWINDOW);
  45.  
  46. return TRUE;
  47. }
  48. LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  49. {
  50.  
  51. return TRUE;
  52. }
  53. HBITMAP GetBitmapFromFile( LPCWSTR pFile )
  54. {
  55. std::auto_ptr<Bitmap> pBmp(new Bitmap(pFile));
  56. if(!pBmp.get())
  57. return NULL;
  58. HBITMAP hBmp = NULL;
  59. Color backColor = Color(255,0,0,0);
  60. if(Ok!=pBmp->GetHBITMAP(backColor,&hBmp))
  61. return NULL;
  62. return hBmp;
  63. }
  64. void SetBtnBmp(CString strBtnNormal,CString strBtnHover,CString strBtnDown)
  65. {
  66. m_btmNormal.Attach(GetBitmapFromFile(strBtnNormal));
  67. m_btmOver.Attach(GetBitmapFromFile(strBtnHover));
  68. m_btmDown.Attach(GetBitmapFromFile(strBtnDown));
  69. }
  70. BOOL DrawBmp( HDC hdc, CRect rect, HBITMAP hBitmap )
  71. {
  72. BITMAP bm;
  73. GetObject(hBitmap,sizeof(bm),(VOID*)&bm);
  74. INT nWidth = bm.bmWidth;
  75. INT nHeight = bm.bmHeight;
  76. CDC memdc;
  77. memdc.CreateCompatibleDC(hdc);
  78. CBitmap bitmap;
  79. bitmap.CreateCompatibleBitmap(hdc,nWidth,nHeight);
  80. memdc.SelectBitmap(hBitmap);
  81.  
  82. BLENDFUNCTION bf = {AC_SRC_OVER,0,255,1};
  83. return ::AlphaBlend(hdc,rect.left,rect.top,nWidth,nHeight,memdc,0,0,nWidth,nHeight,bf);
  84.  
  85. //::StretchBlt(hdc,rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top,
  86. // comDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY );
  87. }
  88. LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  89. {
  90. CPaintDC dc(m_hWnd);
  91. CRect rect;
  92. GetClientRect(&rect);
  93. switch(m_nState)
  94. {
  95. case btn_state_over:
  96. DrawBmp(dc,rect,m_btmOver);
  97. break;
  98. case btn_state_down:
  99. DrawBmp(dc,rect,m_btmDown);
  100. break;
  101. default://case = btn_state_normal
  102. DrawBmp(dc,rect,m_btmNormal);
  103. break;
  104.  
  105. }
  106. dc.SetBkMode(TRANSPARENT);
  107. dc.SetTextColor(RGB(240,250,240));
  108. dc.DrawText(m_strText,m_strText.GetLength(),&rect,DT_CENTER);
  109. return TRUE;
  110. }
  111. LRESULT OnMouseMove(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  112. {
  113. if(!m_bBtnDown)
  114. {
  115. m_nState = btn_state_over;
  116. InvalidateRect(NULL);
  117. TRACKMOUSEEVENT t_MouseEvent;
  118. t_MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
  119. t_MouseEvent.dwFlags = TME_LEAVE|TME_HOVER;
  120. t_MouseEvent.hwndTrack = m_hWnd;
  121. t_MouseEvent.dwHoverTime = 30;
  122. ::_TrackMouseEvent(&t_MouseEvent);
  123.  
  124. }
  125.  
  126. return TRUE;
  127. }
  128. LRESULT OnMouseLeave(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  129. {
  130. m_nState = btn_state_normal;
  131. m_bBtnDown = false;
  132. InvalidateRect(NULL);
  133. return TRUE;
  134. }
  135. LRESULT OnLButtonUp(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  136. {
  137. m_nState = btn_state_normal;
  138. m_bBtnDown = false;
  139. InvalidateRect(NULL);
  140. ::PostMessage(GetParent(),WM_COMMAND,m_nBtnID,NULL);
  141. return TRUE;
  142. }
  143. LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  144. {
  145. m_bBtnDown = true;
  146. m_nState = btn_state_down;
  147. InvalidateRect(NULL);
  148. return TRUE;
  149. }
  150. LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
  151. {
  152.  
  153. return TRUE;
  154. }
  155. void SetBtnText(CString strText)
  156. {
  157. m_strText = strText;
  158.  
  159. }
  160. void SetBtnID(int nID)
  161. {
  162. m_nBtnID = nID;
  163. }
  164. private:
  165. CBitmap m_btmNormal;
  166. CBitmap m_btmOver;
  167. CBitmap m_btmDown;
  168. int m_nState;
  169. bool m_bBtnDown;
  170. CString m_strText;
  171.  
  172. INT m_nBtnID;
  173.  
  174. };

WTL 自定义 Button类-自绘的更多相关文章

  1. IOS开发之自定义Button(集成三种回调模式)

    前面在做东西的时候都用到了storyboard,在今天的代码中就纯手写代码自己用封装个Button.这个Button继承于UIView类,在封装的时候用上啦OC中的三种回调模式:目标动作回调,委托回调 ...

  2. iOS_Swift初识之使用三种回调方式自定义Button

    最近在学习Swift ,发现青玉伏案大神早期用OC写的一篇博客--IOS开发之自定义Button(集成三种回调模式)  很适合用来熟悉Swift的回调方式,于是我就用Swift翻版了一下,具体实现原理 ...

  3. WPF 自定义Button控件及样式

    这次通过最近做的小例子说明一下自定义Button控件和样式. 实现的效果为:

  4. android 自定义Button,抛弃写shape文件

      标签: android 控件  自定义 2017年05月27日 17:52:13 611人阅读 评论(0) 收藏 举报 分类: 自定义View(2) 作者同类文章 X 版权声明:本文为博主原创文章 ...

  5. Android面试基础(一)IOC(DI)框架(ViewUtils)讲解_反射和自定义注解类

    1. Android中的IOC(DI)框架 1.1 ViewUtils简介(xUtils中的四大部分之一) IOC: Inverse of Controller 控制反转. DI: Dependenc ...

  6. C#自定义Button按钮控件

    C#自定义Button按钮控件 在实际项目开发中经常可以遇到.net自带控件并不一定可以满足需要,因此需要自定义开发一些新的控件,自定义控件的办法也有多种,可以自己绘制线条颜色图形等进行重绘,也可以采 ...

  7. Android 自定义View之自绘控件

    首先要提前声明一下,我对于自定义View的理解并不是很深,最近啃了几天guolin博主写的关于自定义View的博客,讲的非常棒,只不过涉及到源码和底层的一些东西,我自己就懵逼了,目前只是会了关于自定义 ...

  8. 【Android开发日记】之入门篇(十四)——Button控件+自定义Button控件

        好久不见,又是一个新的学期开始了,为什么我感觉好惆怅啊!这一周也发生了不少事情,节假日放了三天的假(好久没有这么悠闲过了),实习公司那边被组长半强制性的要求去解决一个后台登陆的问题,结果就是把 ...

  9. c#winform自定义窗体,重绘标题栏,自定义控件学习

    c#winform自定义窗体,重绘标题栏 虽然现在都在说winform窗体太丑了,但是我也能尽量让桌面应用程序漂亮那么一点点话不多说,先上图 重绘标题栏先将原生窗体设置成无边框,FormBoderSt ...

随机推荐

  1. 蓝牙RSSI计算距离

    利用CoreLocation.framework很容易扫描获得周边蓝牙设备,苹果开源代码AirLocate有具体实现,下载地址: https://developer.apple.com/library ...

  2. Qt浅谈之三十九圆形进度条(已经有50篇了)

    http://blog.csdn.net/taiyang1987912/article/category/2314763

  3. C#面向对象基础类与方法

    C#是纯粹的面向对象编程语言,它真正体现了“一切皆为对象”的精神. 在C#中,即使是最基本的数据类型,如int,double,bool类型,都属于System.Object(Object为所有类型的基 ...

  4. Visual Studio 2015 Update 1 成功安装后运行 “出现未能正确加载[XXXX]包,此问题可能是由配置更改或安装另一个扩展导致的。” 可能的解决方法

    作死装Visual Studio 2015 update 1.安装过程中虽然波澜不惊,但是安装之后运行回报未能正确安装[XXXX]包.找了半天,在stackoverflow中找到了相关的问题,在问题描 ...

  5. 【HDOJ】2853 Assignment

    最小费用最大流可解最优解.至于dif如何解,可以把w扩大100倍,如果mission编号和排列P相等则对w+1,然后建立网络流.对结果取模100可以得到没有改变mission的company数目,用c ...

  6. HIbernate java.lang.AbstractMethodError: com.microsoft.jdbc.base.BaseDatabaseMetaData.supportsGetGeneratedKeys()Z

    [HIbernate]java.lang.AbstractMethodError: com.microsoft.jdbc.base.BaseDatabaseMetaData.supportsGetGe ...

  7. POJ -- 1151

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16222   Accepted: 6172 Descrip ...

  8. 选择服务器OS标准

    稳定性.可靠性.兼容性.高效率.可持续,五大标准; recommend always using the stable version for production environments http ...

  9. 5 weekend01、02、03、04、05、06、07的分布式集群的HA测试 + hdfs--动态增加节点和副本数量管理 + HA的java api访问要点

    weekend01.02.03.04.05.06.07的分布式集群的HA测试 1)  weekend01.02的hdfs的HA测试 2)  weekend03.04的yarn的HA测试 1)  wee ...

  10. CentOS搭建GIT服务器【二】-HTTP源码访问及smart http协议

    搭建完git之后,我们希望可以在线看见源码,以及使用http协议上传下载源码. 安装gitweb.httpd: yum install gitweb yum install httpd gitweb默 ...