MFC + CxImage 实现自绘半透明按钮

btn.h

[cpp] view plain copy

  1. #pragma once
  2. // CBtn
  3. #include "ximage/ximage.h"
  4. class CBtn : public CButton
  5. {
  6. DECLARE_DYNAMIC(CBtn)
  7. private:
  8. CxImage * m_pImgNormal;
  9. CxImage * m_pImgOver;
  10. CxImage * m_pImgDown;
  11. CxImage * m_pImgFocus;
  12. CxImage * m_pImgDisable;
  13. BOOL m_bTracking;
  14. BOOL m_bMouseOver;
  15. BOOL m_bLBtnDown;
  16. public:
  17. CBtn(UINT imgID_LbtnDown,UINT imgID_Over,UINT imgID_Normal,UINT imgID_Disabled=0,UINT imgID_Focus=0);
  18. virtual ~CBtn();
  19. protected:
  20. DECLARE_MESSAGE_MAP()
  21. public:
  22. virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
  23. afx_msg void OnDestroy();
  24. afx_msg BOOL OnEraseBkgnd(CDC* pDC);
  25. afx_msg void OnMouseMove(UINT nFlags, CPoint point);
  26. afx_msg void OnMouseLeave();
  27. afx_msg void OnMouseHover(UINT nFlags, CPoint point);
  28. protected:
  29. virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
  30. public:
  31. void PaintParent();
  32. virtual BOOL Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID);
  33. afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
  34. afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
  35. afx_msg void OnBnDoubleclicked();
  36. afx_msg void OnKillFocus(CWnd* pNewWnd);
  37. };

btn.cpp

[cpp] view plain copy

  1. // Btn.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "Btn.h"
  5. // CBtn
  6. IMPLEMENT_DYNAMIC(CBtn, CButton)
  7. CBtn::CBtn(UINT imgID_LbtnDown,UINT imgID_Over,UINT imgID_Normal,UINT imgID_Disabled,UINT imgID_Focus):
  8. m_pImgNormal(NULL)
  9. , m_pImgOver(NULL)
  10. , m_pImgDown(NULL)
  11. , m_pImgFocus(NULL)
  12. , m_pImgDisable(NULL)
  13. , m_bTracking(FALSE)
  14. , m_bMouseOver(FALSE)
  15. , m_bLBtnDown(FALSE)
  16. {
  17. if(imgID_Normal > 0)
  18. {
  19. if(!m_pImgNormal)
  20. m_pImgNormal = new CxImage(CXIMAGE_FORMAT_PNG);
  21. m_pImgNormal ->LoadResource(FindResource(NULL,MAKEINTRESOURCE(imgID_Normal),L"PNG"),CXIMAGE_FORMAT_PNG);
  22. }
  23. if(imgID_Focus > 0)
  24. {
  25. if(!m_pImgFocus)
  26. m_pImgFocus = new CxImage(CXIMAGE_FORMAT_PNG);
  27. m_pImgFocus ->LoadResource(FindResource(NULL,MAKEINTRESOURCE(imgID_Focus),L"PNG"),CXIMAGE_FORMAT_PNG);
  28. }
  29. if( imgID_LbtnDown>0 )
  30. {
  31. if(!m_pImgDown)
  32. m_pImgDown = new CxImage(CXIMAGE_FORMAT_PNG);
  33. m_pImgDown ->LoadResource(FindResource(NULL,MAKEINTRESOURCE(imgID_LbtnDown),L"PNG"),CXIMAGE_FORMAT_PNG);
  34. }
  35. if( imgID_Disabled > 0 )
  36. {
  37. if(!m_pImgDisable)
  38. m_pImgDisable = new CxImage(CXIMAGE_FORMAT_PNG);
  39. m_pImgDisable ->LoadResource(FindResource(NULL,MAKEINTRESOURCE(imgID_Disabled),L"PNG"),CXIMAGE_FORMAT_PNG);
  40. }
  41. if( imgID_Over > 0)
  42. {
  43. if(!m_pImgOver)
  44. m_pImgOver = new CxImage(CXIMAGE_FORMAT_PNG);
  45. m_pImgOver ->LoadResource(FindResource(NULL,MAKEINTRESOURCE(imgID_Over),L"PNG"),CXIMAGE_FORMAT_PNG);
  46. }
  47. }
  48. CBtn::~CBtn()
  49. {
  50. }
  51. BEGIN_MESSAGE_MAP(CBtn, CWnd)
  52. ON_WM_DESTROY()
  53. ON_WM_ERASEBKGND()
  54. ON_WM_MOUSEMOVE()
  55. ON_WM_MOUSELEAVE()
  56. ON_WM_MOUSEHOVER()
  57. ON_WM_LBUTTONDOWN()
  58. ON_WM_LBUTTONUP()
  59. ON_CONTROL_REFLECT(BN_DOUBLECLICKED, &CBtn::OnBnDoubleclicked)
  60. ON_WM_KILLFOCUS()
  61. END_MESSAGE_MAP()
  62. // CBtn 消息处理程序
  63. void CBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  64. {
  65. CDC ButtonDC;
  66. CRect rc;
  67. ButtonDC.Attach(lpDrawItemStruct->hDC); //得到用于绘制按钮的DC
  68. rc=lpDrawItemStruct->rcItem; //获取按钮所占的矩形大小
  69. UINT state = lpDrawItemStruct->itemState; //获取按钮目前所处的状态,根据不同的状态绘制不同的按钮
  70. if(state&ODS_DISABLED && m_pImgDisable)
  71. {
  72. m_pImgDisable ->Draw(ButtonDC.GetSafeHdc(),rc);
  73. }
  74. else
  75. {
  76. if( m_bLBtnDown && m_pImgDown)
  77. {
  78. m_pImgDown ->Draw(ButtonDC.GetSafeHdc(),rc);
  79. }
  80. else if(m_bMouseOver && m_pImgOver)
  81. {
  82. m_pImgOver ->Draw(ButtonDC.GetSafeHdc(),rc);
  83. }
  84. else if(state&ODS_FOCUS && m_pImgFocus)
  85. {
  86. m_pImgFocus ->Draw(ButtonDC.GetSafeHdc(),rc);
  87. }
  88. else if(m_pImgNormal)
  89. {
  90. m_pImgNormal ->Draw(ButtonDC.GetSafeHdc(),rc);
  91. }
  92. }
  93. }
  94. void CBtn::OnDestroy()
  95. {
  96. CButton::OnDestroy();
  97. // TODO: 在此处添加消息处理程序代码
  98. if(m_pImgNormal)
  99. {
  100. m_pImgNormal ->Destroy();
  101. delete m_pImgNormal;
  102. m_pImgNormal = NULL;
  103. }
  104. if(m_pImgOver)
  105. {
  106. m_pImgOver ->Destroy();
  107. delete m_pImgOver;
  108. m_pImgOver = NULL;
  109. }
  110. if(m_pImgDown)
  111. {
  112. m_pImgDown ->Destroy();
  113. delete m_pImgDown;
  114. m_pImgDown = NULL;
  115. }
  116. if(m_pImgFocus)
  117. {
  118. m_pImgFocus ->Destroy();
  119. delete m_pImgFocus;
  120. m_pImgFocus = NULL;
  121. }
  122. if(m_pImgDisable)
  123. {
  124. m_pImgDisable ->Destroy();
  125. delete m_pImgDisable;
  126. m_pImgDisable = NULL;
  127. }
  128. }
  129. BOOL CBtn::OnEraseBkgnd(CDC* pDC)
  130. {
  131. // TODO: 在此添加消息处理程序代码和/或调用默认值
  132. return TRUE;
  133. //return CButton::OnEraseBkgnd(pDC);
  134. }
  135. BOOL CBtn::PreCreateWindow(CREATESTRUCT& cs)
  136. {
  137. // TODO: 在此添加专用代码和/或调用基类
  138. cs.style |= BS_OWNERDRAW;
  139. return CButton::PreCreateWindow(cs);
  140. }
  141. void CBtn::OnMouseMove(UINT nFlags, CPoint point)
  142. {
  143. // TODO: 在此添加消息处理程序代码和/或调用默认值
  144. m_bMouseOver = TRUE;
  145. if (!m_bTracking)
  146. {
  147. TRACKMOUSEEVENT   tme;
  148. tme.cbSize      =   sizeof(TRACKMOUSEEVENT);
  149. tme.dwFlags     =   TME_LEAVE|TME_HOVER; //
  150. tme.hwndTrack   =   GetSafeHwnd();
  151. tme.dwHoverTime =   8;
  152. _TrackMouseEvent(&tme);
  153. m_bTracking = TRUE;
  154. }
  155. CButton::OnMouseMove(nFlags, point);
  156. ::SetCursor(AfxGetApp() ->LoadCursor(IDC_CURSOR_HAND));
  157. }
  158. void CBtn::OnMouseLeave()
  159. {
  160. // TODO: 在此添加消息处理程序代码和/或调用默认值
  161. m_bMouseOver    =   FALSE;
  162. m_bTracking     =   FALSE;
  163. m_bLBtnDown     =   FALSE;
  164. PaintParent();
  165. CButton::OnMouseLeave();
  166. }
  167. void CBtn::OnMouseHover(UINT nFlags, CPoint point)
  168. {
  169. m_bMouseOver = TRUE;
  170. PaintParent();
  171. ::SetCursor(AfxGetApp() ->LoadCursor(IDC_CURSOR_HAND));
  172. }
  173. void CBtn::PaintParent()
  174. {
  175. CRect   rect;
  176. GetWindowRect(&rect);
  177. GetParent()-> ScreenToClient(&rect);
  178. GetParent()-> InvalidateRect(&rect);
  179. }
  180. BOOL CBtn::Create(LPCTSTR lpszCaption, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
  181. {
  182. BOOL OK=CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID);
  183. ModifyStyleEx(0, WS_EX_TRANSPARENT);// WS_EX_LAYERED||WS_EX_TRANSPARENT
  184. return OK;
  185. }
  186. void CBtn::OnLButtonDown(UINT nFlags, CPoint point)
  187. {
  188. m_bLBtnDown = TRUE;
  189. PaintParent();
  190. CButton::OnLButtonDown(nFlags, point);
  191. ::SetCursor(AfxGetApp() ->LoadCursor(IDC_CURSOR_HAND));
  192. }
  193. void CBtn::OnLButtonUp(UINT nFlags, CPoint point)
  194. {
  195. m_bLBtnDown = FALSE;
  196. PaintParent();
  197. CButton::OnLButtonUp(nFlags, point);
  198. ::SetCursor(AfxGetApp() ->LoadCursor(IDC_CURSOR_HAND));
  199. }
  200. void CBtn::OnBnDoubleclicked()
  201. {
  202. // TODO: 在此添加控件通知处理程序代码
  203. ::SetCursor(AfxGetApp() ->LoadCursor(IDC_CURSOR_HAND));
  204. }
  205. void CBtn::OnKillFocus(CWnd* pNewWnd)
  206. {
  207. CButton::OnKillFocus(pNewWnd);
  208. // TODO: 在此处添加消息处理程序代码
  209. PaintParent();
  210. }

调用

[cpp] view plain copy

  1. ///头文件中添加
  2. ...
  3. #include "Btn.h"
  4. ...
  5. enum {emTestBtnId1=8099,emTestBtnId2,emTestBtnId3};
  6. CBtn m_btnTest1,m_btnTest2,m_btnTest3;//test
  7. ///在构造函数初始化列表中初始化变量(IDB_PNG_BTN_TEST_*为Png图片资源ID)
  8. , m_btnTest1(IDB_PNG_BTN_TEST_DOWN,
  9. IDB_PNG_BTN_TEST_MOUSEOVER,
  10. IDB_PNG_BTN_TEST_NORMAL,
  11. IDB_PNG_BTN_TEST_DISABLE,
  12. IDB_PNG_BTN_TEST_FOCUS)
  13. , m_btnTest2(IDB_PNG_BTN_TEST_DOWN,
  14. IDB_PNG_BTN_TEST_MOUSEOVER,
  15. IDB_PNG_BTN_TEST_NORMAL,
  16. IDB_PNG_BTN_TEST_DISABLE/*,IDB_PNG_BTN_TEST_FOCUS*/)
  17. , m_btnTest3(IDB_PNG_BTN_TEST_DOWN,
  18. IDB_PNG_BTN_TEST_MOUSEOVER,
  19. IDB_PNG_BTN_TEST_NORMAL,
  20. IDB_PNG_BTN_TEST_DISABLE/*,IDB_PNG_BTN_TEST_FOCUS*/)
  21. ////在OnInitDialog()函数中创建按钮
  22. //test
  23. m_btnTest1.Create(_T("test"),WS_VISIBLE | WS_CHILD/* |WS_DISABLED*/,CRect(10,10,58,58),this,emTestBtnId1);
  24. m_btnTest2.Create(_T("test"),WS_VISIBLE | WS_CHILD/* |WS_DISABLED*/,CRect(10,60,58,108),this,emTestBtnId2);
  25. m_btnTest3.Create(_T("test"),WS_VISIBLE | WS_CHILD |WS_DISABLED,CRect(10,110,58,158),this,emTestBtnId2);

效果图

时间: 2024-10-09 23:12:13

MFC + CxImage 实现自绘半透明按钮的相关文章

MFC控件编程:旋转按钮、进度条和滑块控件

旋转按钮(微调按钮) : 对应的控件类是CSpinButtonCtrl 进度条:对应的控件类是CProgressCtrl 滑块:对应的控件类是CSliderCtrl 对这三个控件的操作都是同过与之相关联的控件类完成的,并且这三个控件有极大的相似性,故这里放到一起 先认识下: Spin:            Progress:             Slider: 常用函数: SetRange()/GetRange(); // 设置.获取控件表示的范围 /* 设置控件的增量(步长) */ CS

【MFC】MFC中窗口重绘

MFC中窗口重绘 摘自:http://blog.csdn.net/shuilan0066/article/details/5859057 在刷新窗口时经常要调用重绘函数 MFC提供了三个函数用于窗口重绘 InvalidateRect(&Rect) Invalidate() UpdateWindow() 当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和 WM_NCPAINT(通知非客户区有变化)WM_NVPAINT系统会自己搞定WM_PAINT消息对应的函数是

MFC控件重绘

MFC的一系列重绘控件: 如图所示: 示例下载地址:http://download.csdn.net/detail/qq_23992597/9510696

用C++实现半透明按钮控件(PNG,GDI+)

使用MFC实现上面的按钮半透明效果能看到父窗口中的内容,上面是效果图(一个是带背景图片的.另一个是不带的). 控件继承自CWnd类(彩色的部分是窗口的背景图片.按钮是PNG图片,第二个图标是鼠标指向时的效果). 图标的绘制使用GDI+绘制PNG图片,在此不多说了(处理WM_PAINT消息): 1 void PNGButton::OnPaint() 2 { 3 CPaintDC dc(this); 4 Graphics g(dc.m_hDC); 5 if(DrawBorder){ 6 g.Draw

MFC中窗口重绘

搬家于CSDN 2015-05-14 MFC提供了三个函数用于窗口重绘 InvalidateRect(&Rect) Invalidate() UpdateWindow() 当需要更新或者重绘窗口时,一般系统会发出两个消息WM_PAINT(通知客户区有变化)和 WM_NCPAINT    (通知非客户区有变化) WM_NVPAINT    系统会自己搞定 WM_PAINT         消息系统默认对应的函数是OnPaint(),但‍一般在重绘时都在OnDraw,因为在ONPAIN中调用了OND

如何在MFC界面开发中响应Button按钮的Down和Up事件

通过尝试有两种方案可以解决这个问题,第一种方案是通过PreTranslateMessage函数在调度消息之前对消息类型进行筛选,第二种方案是重载CButton类,在重载后的类CForTestButton中新增ON_WM_LBUTTONDOWN消息以及ON_WM_LBUTTONUP消息. 第一种方案 实现原理也挺简单,在消息调度函数PreTranslateMessage函数中拦截Button按钮的句柄,之后在对应大括号内调用相关功能块即可.核心源码如下: …… …… BOOL CTestButto

(转载)VS2010/MFC编程入门之二十二(常用控件:按钮控件Button、Radio Button和Check Box)

因为私人问题,鸡啄米暂停更新了几天,首先向关注鸡啄米动态的朋友说一声抱歉. 言归正传,鸡啄米上一节中讲了编辑框的用法,本节继续讲解常用控件--按钮控件的使用. 按钮控件简介 按钮控件包括命令按钮(Button).单选按钮(Radio Button)和复选框(Check Box)等.命令按钮就是我们前面多次提到的狭义的按钮控件,用来响应用户的鼠标单击操作,进行相应的处理,它可以显示文本也可以嵌入位图.单选按钮使用时,一般是多个组成一组,组中每个单选按钮的选中状态具有互斥关系,即同组的单选按钮只能有

MFC自绘控件学习总结

前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或者有更好的方法,请不吝赐教.我的机器环境是:Windows7旗舰版 Service Pack 1,Visual studio 20051).重绘某个控件时,强烈推荐使用子类化方法,比如想自绘Button控件, 首先添加自己的类CMYButton 继承自 CButton ,声明一个CMYButton

MFC按钮控件

CButton按钮分为4种基本类型:下压按钮.复选.单选和自绘按钮. 按钮会向父窗口发送控件通知消息: 1,BN_CLICKED(Button News):单击消息 2,BN_DOUBLECLICKED:双击消息 3,BN_SETFOCUS:获得用户焦点 4,BN_KILLFOCUS:失去用户焦点 MFC中的CButton封装了按钮的基本操作,其中create函数如下: BOOL Create(LPCTSTR lpszCaption,DWORD dwStyle,const CRECT& rect