自制button

来源:互联网 发布:语音域名 编辑:程序博客网 时间:2024/04/26 03:53

SkinButton.h

[cpp] view plain copy
  1. #ifndef SKINBUTTON_HEAD  
  2. #define SKINBUTTON_HEAD  
  3. #pragma once  
  4. //#include "stdafx.h"  
  5. #include <afxwin.h>  
  6. #include <afxext.h>  
  7. #include <GdiPlus.h>  
  8. #include <AtlImage.h>  
  9. #include "resource.h"  
  10. #pragma comment(lib,"gdiplus.lib")    
  11.   
  12. //命名空间  
  13. using namespace Gdiplus;  
  14.   
  15. //接口释放  
  16. #define SafeRelease(pObject) { if (pObject!=NULL) { pObject->Release(); pObject=NULL; } }  
  17. //删除指针  
  18. #define SafeDelete(pData) { try { delete pData; } catch (...) { ASSERT(FALSE); } pData=NULL; }   
  19. //关闭句柄  
  20. #define SafeCloseHandle(hHandle) { if (hHandle!=NULL) { CloseHandle(hHandle); hHandle=NULL; } }  
  21. //删除数组  
  22. #define SafeDeleteArray(pData) { try { delete [] pData; } catch (...) { ASSERT(FALSE); } pData=NULL; }   
  23.   
  24.   
  25.   
  26.   
  27. class CSkinButtonbmp :public CButton/*CWnd*/  
  28. {  
  29.     //状态变量  
  30. private:  
  31.     UINT                            m_uState;                           //当前按钮状态  
  32.     UINT                            m_uFlags;                           //当前鼠标状态  
  33.   
  34.   
  35.     //资源变量  
  36. private:  
  37.     SIZE                            m_szButton;                         //按钮大小  
  38.     HDC                             m_hButtonDC;                        //按钮图片DC  
  39.     HBITMAP                         m_hButtonBmp;                       //按钮图片BMP  
  40.   
  41.   
  42.   
  43. public:  
  44.     //构造函数  
  45.     CSkinButtonbmp();  
  46.     //析构函数  
  47.     virtual ~CSkinButtonbmp();  
  48.   
  49.     //功能函数  
  50. public:  
  51.     //创建按钮  
  52.     BOOL CreateButton(LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,CWnd*  pParentWnd,UINT uID);  
  53.     //创建按钮    
  54.     BOOL CreateButton(LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,HINSTANCE hInstance, UINT nIDResource,CWnd*  pParentWnd,UINT uID);  
  55.   
  56.     //加载位图  
  57.     BOOL SetButtonImage(LPCTSTR lpszFileName);  
  58.     //加载位图  
  59.     BOOL SetButtonImage(HINSTANCE hInstance, UINT nIDResource );  
  60.   
  61.   
  62.     //重载函数  
  63. protected:  
  64.     //创建消息  
  65.     afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);  
  66.     //绘画背景  
  67.     afx_msg BOOL OnEraseBkgnd(CDC *pDC);  
  68.     //绘画函数  
  69.     virtual VOID DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);  
  70.     ////鼠标按钮  
  71.     //afx_msg void OnLButtonDown(UINT, CPoint);  
  72.     ////鼠标抬起  
  73.     //afx_msg void OnLButtonUp(UINT ,CPoint);  
  74.     //鼠标移动  
  75.     afx_msg void OnMouseMove(UINT, CPoint);  
  76.     //鼠标离开  
  77.     afx_msg void OnMouseLeave();  
  78.   
  79.     DECLARE_MESSAGE_MAP()  
  80.   
  81. };  
  82.   
  83.   
  84. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  85. class CSkinButtonpng :public CButton  
  86. {  
  87.     //状态变量  
  88. private:  
  89.     UINT                    m_uState;                       //当前按钮状态  
  90.     UINT                    m_uFlags;                       //当前鼠标状态  
  91.   
  92.     //资源变量  
  93. private:  
  94.     SIZE                    m_szButton;                     //按钮大小  
  95.     HDC                     m_hButtonDC;                    //按钮图片DC  
  96.     HBITMAP                 m_hButtonBmp;                   //按钮图片BMP  
  97.   
  98.     //图片对象  
  99. private:  
  100.     Image*                  m_pButtonImage;                 //图片对象  
  101.   
  102.     //A变量  
  103. private:  
  104.     ULONG_PTR               token;                          //初始化GDI+  
  105.   
  106. public:  
  107.     //构造函数  
  108.     CSkinButtonpng();  
  109.     //析构函数  
  110.     virtual ~CSkinButtonpng();  
  111.   
  112.     //功能函数  
  113. public:  
  114.     //创建按钮  
  115.     BOOL CreateButton(LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,CWnd*  pParentWnd,UINT uID);  
  116.     //加载图片  
  117.     bool SetButtonImage(LPCTSTR pszFileName);  
  118.     //加载图片  
  119.     bool SetButtonImage(HINSTANCE hInstance, LPCTSTR pszResourceName);  
  120.   
  121.     //重载函数  
  122. protected:  
  123.     //创建消息  
  124.     afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);  
  125.     //绘画背景  
  126.     afx_msg BOOL OnEraseBkgnd(CDC *pDC);  
  127.     //绘画函数  
  128.     virtual VOID DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);  
  129.     ////鼠标按钮  
  130.     //afx_msg void OnLButtonDown(UINT, CPoint);  
  131.     ////鼠标抬起  
  132.     //afx_msg void OnLButtonUp(UINT ,CPoint);  
  133.     //鼠标移动  
  134.     afx_msg void OnMouseMove(UINT, CPoint);  
  135.     //鼠标离开  
  136.     afx_msg void OnMouseLeave();  
  137.   
  138.     DECLARE_MESSAGE_MAP()  
  139.   
  140. };  
  141.   
  142.   
  143. #endif  


SkinButton.cpp

[cpp] view plain copy
  1. #include "SkinButton.h"  
  2.   
  3.   
  4. #define                         STATE_COUNT                     5                   //按钮状态数量  
  5.   
  6. //按钮状态  
  7. enum  
  8. {  
  9.     STATE_NONE = 0, //当前鼠标不再按键上(常态)  
  10.     STATE_DOWN,     //当前鼠标在按键上按下  
  11.     STATE_MOVE,     //当前鼠标在按键上  
  12.     STATE_MOVEEx,   //当前鼠标在按键上  
  13.     STATE_DISABLE,  //当前按键禁用  
  14. };  
  15.   
  16.   
  17. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  18.   
  19. BEGIN_MESSAGE_MAP(CSkinButtonbmp, CWnd)  
  20.     ON_WM_CREATE()  
  21.     ON_WM_ERASEBKGND()  
  22.     //ON_WM_LBUTTONDOWN()  
  23.     //ON_WM_LBUTTONUP()  
  24.     ON_WM_MOUSEMOVE()  
  25.     ON_WM_MOUSELEAVE()  
  26. END_MESSAGE_MAP()  
  27.   
  28.   
  29. //构造函数  
  30. CSkinButtonbmp::CSkinButtonbmp()  
  31. {  
  32.     //状态变量  
  33.     m_uState=0;  
  34.     m_uFlags=0;  
  35.   
  36.     //资源变量  
  37.     ZeroMemory(&m_szButton,sizeof(m_szButton));  
  38.     m_hButtonDC=NULL;  
  39.     m_hButtonBmp=NULL;  
  40.   
  41. }  
  42.   
  43. //析构函数  
  44. CSkinButtonbmp::~CSkinButtonbmp()  
  45. {  
  46.     if(m_hButtonDC){::DeleteDC(m_hButtonDC);m_hButtonDC=NULL;}  
  47.     if(m_hButtonBmp){::DeleteObject(m_hButtonBmp);m_hButtonBmp=NULL;}  
  48. }  
  49.   
  50. //创建按钮  
  51. BOOL CSkinButtonbmp::CreateButton(LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,CWnd*  pParentWnd,UINT uID)  
  52. {  
  53.     //创建按钮  
  54.     return Create(lpszCaption, dwStyle, CRect(x, y, x+1, y+1), pParentWnd, uID);  
  55. }  
  56.   
  57. //创建按钮  
  58. BOOL CSkinButtonbmp::CreateButton( LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,HINSTANCE hInstance, UINT nIDResource,CWnd* pParentWnd,UINT uID )  
  59. {  
  60.   
  61.     //加载图片  
  62.     m_hButtonBmp = (HBITMAP)::LoadImage(hInstance, MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);  
  63.     ASSERT(m_hButtonBmp);if (m_hButtonBmp==NULL)return false;  
  64.   
  65.     //创建按钮  
  66.     return Create(lpszCaption, dwStyle, CRect(x, y, x+1, y+1), pParentWnd, uID);  
  67. }  
  68.   
  69. //加载位图  
  70. BOOL CSkinButtonbmp::SetButtonImage( LPCTSTR lpszFileName )  
  71. {  
  72.   
  73.     //设置按钮  
  74.     SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);  
  75.   
  76.     //加载图片  
  77.     m_hButtonBmp = (HBITMAP)::LoadImage(NULL, lpszFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);  
  78.   
  79.     ASSERT(m_hButtonBmp);if (m_hButtonBmp==NULL)return false;  
  80.   
  81.     ASSERT(m_hWnd);if (m_hWnd==NULL)return false;  
  82.     HDC hDC =::GetDC(m_hWnd);  
  83.     m_hButtonDC = CreateCompatibleDC(hDC);  
  84.     ::SelectObject(m_hButtonDC,m_hButtonBmp);  
  85.     ::ReleaseDC(m_hWnd,hDC);  
  86.   
  87.     //获取图片大小  
  88.     BITMAP bm;  
  89.     ::GetObject(m_hButtonBmp, sizeof(bm), &bm);  
  90.     m_szButton.cx = bm.bmWidth/STATE_COUNT;  
  91.     m_szButton.cy = bm.bmHeight;  
  92.   
  93.     //不移动X,Y坐标,不改变Z序,不重绘,仅改变窗口大小  
  94.     SetWindowPos(NULL, 0, 0, m_szButton.cx, m_szButton.cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);  
  95.   
  96.     return TRUE;  
  97. }  
  98.   
  99. //加载位图  
  100. BOOL CSkinButtonbmp::SetButtonImage( HINSTANCE hInstance, UINT nIDResource )  
  101. {  
  102.     //设置按钮  
  103.     SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);  
  104.   
  105.     //加载图片  
  106.     m_hButtonBmp = (HBITMAP)::LoadImage(hInstance, MAKEINTRESOURCE(nIDResource), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);  
  107.     ASSERT(m_hButtonBmp);if (m_hButtonBmp==NULL)return false;  
  108.   
  109.     ASSERT(m_hWnd);if (m_hWnd==NULL)return false;  
  110.     HDC hDC =::GetDC(m_hWnd);  
  111.     m_hButtonDC = CreateCompatibleDC(hDC);  
  112.     ::SelectObject(m_hButtonDC,m_hButtonBmp);  
  113.     ::ReleaseDC(m_hWnd,hDC);  
  114.   
  115.     //获取图片大小  
  116.     BITMAP bm;  
  117.     ::GetObject(m_hButtonBmp, sizeof(bm), &bm);  
  118.     m_szButton.cx = bm.bmWidth/STATE_COUNT;  
  119.     m_szButton.cy = bm.bmHeight;  
  120.   
  121.     //不移动X,Y坐标,不改变Z序,不重绘,仅改变窗口大小  
  122.     SetWindowPos(NULL, 0, 0, m_szButton.cx, m_szButton.cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);  
  123.   
  124.     return TRUE;  
  125. }  
  126.   
  127. //绘画背景  
  128. BOOL CSkinButtonbmp::OnEraseBkgnd( CDC *pDC )  
  129. {  
  130.     return TRUE;  
  131. }  
  132.   
  133. //创建消息  
  134. int CSkinButtonbmp::OnCreate( LPCREATESTRUCT lpCreateStruct )  
  135. {  
  136.     if (__super::OnCreate(lpCreateStruct) == -1)return -1;  
  137.   
  138.     return 0;  
  139. }  
  140.   
  141. //绘画函数  
  142. VOID CSkinButtonbmp::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )  
  143. {  
  144.     //变量定义  
  145.     HDC hDC=lpDrawItemStruct->hDC;  
  146.     CDC * pDC=CDC::FromHandle(lpDrawItemStruct->hDC);  
  147.     ASSERT(pDC);if (pDC==NULL)return ;  
  148.   
  149.     //按钮状态  
  150.     bool bDisable=((lpDrawItemStruct->itemState&ODS_DISABLED)!=0);  
  151.     bool bButtonDown=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0);  
  152.     if (bDisable)m_uState=STATE_DISABLE;  
  153.     if (bButtonDown)m_uState=STATE_DOWN;  
  154.   
  155.     ::BitBlt(pDC->m_hDC,0,0,m_szButton.cx,m_szButton.cy,m_hButtonDC,m_uState * m_szButton.cx,0,SRCCOPY);  
  156. }  
  157.   
  158. ////鼠标按钮  
  159. //void CSkinButtonbmp::OnLButtonDown( UINT, CPoint )  
  160. //{  
  161. //  m_uState = STATE_DOWN;  
  162. //  Invalidate();  
  163. //  return;  
  164. //}  
  165. //  
  166. ////鼠标抬起  
  167. //void CSkinButtonbmp::OnLButtonUp( UINT ,CPoint )  
  168. //{  
  169. //  m_uState = STATE_NONE;  
  170. //  Invalidate();  
  171. //  return;  
  172. //}  
  173.   
  174. //鼠标移动  
  175. void CSkinButtonbmp::OnMouseMove( UINT, CPoint )  
  176. {  
  177.     m_uState = STATE_MOVE;  
  178.     Invalidate();  
  179.   
  180.     TRACKMOUSEEVENT te = {sizeof(TRACKMOUSEEVENT) ,TME_LEAVE ,m_hWnd, 1};  
  181.     ::_TrackMouseEvent(&te);  
  182. }  
  183.   
  184. //鼠标离开  
  185. void CSkinButtonbmp::OnMouseLeave()  
  186. {  
  187.     m_uState = STATE_NONE;  
  188.     Invalidate();  
  189. }  
  190.   
  191.   
  192.   
  193.   
  194.   
  195.   
  196.   
  197.   
  198.   
  199. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  200. BEGIN_MESSAGE_MAP(CSkinButtonpng, CWnd)  
  201.     ON_WM_CREATE()  
  202.     ON_WM_ERASEBKGND()  
  203.     //ON_WM_LBUTTONDOWN()  
  204.     //ON_WM_LBUTTONUP()  
  205.     ON_WM_MOUSEMOVE()  
  206.     ON_WM_MOUSELEAVE()  
  207. END_MESSAGE_MAP()  
  208.   
  209.   
  210. //构造函数  
  211. CSkinButtonpng::CSkinButtonpng()  
  212. {  
  213.     //状态变量  
  214.     m_uState=0;  
  215.     m_uFlags=0;  
  216.   
  217.     //资源变量  
  218.     ZeroMemory(&m_szButton,sizeof(m_szButton));  
  219.     m_hButtonDC=NULL;  
  220.     m_hButtonBmp=NULL;  
  221.   
  222.     //图片对象  
  223.     m_pButtonImage=NULL;  
  224.   
  225.     //GDI+初始化  
  226.     GdiplusStartupInput m_GdiplusStartupInput;  
  227.     ULONG_PTR m_GdiplusToken;  
  228.     token=GdiplusStartup(&m_GdiplusToken, &m_GdiplusStartupInput, NULL);  
  229.   
  230. }  
  231.   
  232. //析构函数  
  233. CSkinButtonpng::~CSkinButtonpng()  
  234. {  
  235.     if(m_hButtonDC){::DeleteDC(m_hButtonDC);m_hButtonDC=NULL;}  
  236.     if(m_hButtonBmp){::DeleteObject(m_hButtonBmp);m_hButtonBmp=NULL;}  
  237.   
  238.     //清除使用  
  239.     GdiplusShutdown(token);   
  240. }  
  241.   
  242. //创建按钮  
  243. BOOL CSkinButtonpng::CreateButton(LPCTSTR lpszCaption,DWORD dwStyle,int x, int y,CWnd*  pParentWnd,UINT uID)  
  244. {  
  245.     return Create(lpszCaption, dwStyle, CRect(x, y, x+1, y+1), pParentWnd, uID);  
  246. }  
  247.   
  248. //加载图片  
  249. bool CSkinButtonpng::SetButtonImage( LPCTSTR pszFileName )  
  250. {  
  251.     //设置按钮  
  252.     SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);  
  253.   
  254.     //根据传入的图片地址,加载图片  
  255.     CT2CW strFileName(pszFileName);    
  256.     m_pButtonImage = Image::FromFile((LPCWSTR)strFileName);  
  257.     ASSERT(m_pButtonImage);if (m_pButtonImage==NULL)return FALSE;  
  258.   
  259.   
  260.     //获取图片大小  
  261.     m_szButton.cx = m_pButtonImage->GetWidth()/STATE_COUNT;  
  262.     m_szButton.cy = m_pButtonImage->GetHeight();  
  263.   
  264.     //不移动X,Y坐标,不改变Z序,不重绘,仅改变窗口大小  
  265.     SetWindowPos(NULL, 0, 0, m_szButton.cx,m_szButton.cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);  
  266.   
  267.     return TRUE;  
  268. }  
  269.   
  270. //加载图片  
  271. bool CSkinButtonpng::SetButtonImage( HINSTANCE hInstance, LPCTSTR pszResourceName )  
  272. {  
  273.     //设置按钮  
  274.     SetButtonStyle(GetButtonStyle()|BS_OWNERDRAW);  
  275.   
  276.     //加载判断  
  277.     ASSERT(m_pButtonImage==NULL);  
  278.     if (m_pButtonImage!=NULL) return false;  
  279.   
  280.     //查找资源  
  281.     HRSRC hResource=FindResource(hInstance,pszResourceName,TEXT("PNG"));  
  282.     if (hResource==NULL) return false;  
  283.   
  284.     //读取资源  
  285.     DWORD dwImageSize=SizeofResource(hInstance,hResource);  
  286.     LPVOID pImageBuffer=LoadResource(hInstance,hResource);  
  287.   
  288.     //创建数据  
  289.     IStream * pIStream=NULL;  
  290.     if (CreateStreamOnHGlobal(NULL,TRUE,&pIStream)!=S_OK)  
  291.     {  
  292.         ASSERT(FALSE);  
  293.         return false;  
  294.     }  
  295.   
  296.     //写入数据  
  297.     pIStream->Write(pImageBuffer,dwImageSize,NULL);  
  298.   
  299.     //创建位图  
  300.     m_pButtonImage=Image::FromStream(pIStream);  
  301.   
  302.     //释放资源  
  303.     SafeRelease(pIStream);  
  304.   
  305.     //错误判断  
  306.     if ((m_pButtonImage==NULL)||(m_pButtonImage->GetLastStatus()!=Ok))  
  307.     {  
  308.         ASSERT(FALSE);  
  309.         return false;  
  310.     }  
  311.   
  312.     //获取图片大小  
  313.     m_szButton.cx = m_pButtonImage->GetWidth()/STATE_COUNT;  
  314.     m_szButton.cy = m_pButtonImage->GetHeight();  
  315.   
  316.     //不移动X,Y坐标,不改变Z序,不重绘,仅改变窗口大小  
  317.     SetWindowPos(NULL, 0, 0, m_szButton.cx,m_szButton.cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW);  
  318.   
  319.     return TRUE;  
  320. }  
  321.   
  322.   
  323. //创建消息  
  324. int CSkinButtonpng::OnCreate( LPCREATESTRUCT lpCreateStruct )  
  325. {  
  326.     if (__super::OnCreate(lpCreateStruct) == -1)return -1;  
  327.   
  328.     return 0;  
  329.   
  330. }  
  331.   
  332. //绘画背景  
  333. BOOL CSkinButtonpng::OnEraseBkgnd( CDC *pDC )  
  334. {  
  335.     return TRUE;  
  336. }  
  337.   
  338. //绘画函数  
  339. VOID CSkinButtonpng::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )  
  340. {  
  341.     //变量定义  
  342.     Graphics graphics(lpDrawItemStruct->hDC);  
  343.   
  344.   
  345.     //按钮状态  
  346.     bool bDisable=((lpDrawItemStruct->itemState&ODS_DISABLED)!=0);  
  347.     bool bButtonDown=((lpDrawItemStruct->itemState&ODS_SELECTED)!=0);  
  348.     if (bDisable)m_uState=STATE_DISABLE;  
  349.     if (bButtonDown)m_uState=STATE_DOWN;  
  350.   
  351.       
  352.     //绘画按钮  
  353.     graphics.DrawImage(m_pButtonImage  
  354.         , Gdiplus::Rect(0, 0, m_szButton.cx,m_szButton.cy)  
  355.         , m_uState * m_szButton.cx  
  356.         , 0  
  357.         , m_szButton.cx  
  358.         , m_szButton.cy  
  359.         , Gdiplus::UnitPixel  
  360.         , NULL  
  361.         , NULL  
  362.         , NULL);  
  363.   
  364. }  
  365.   
  366. ////鼠标按钮  
  367. //void CSkinButtonpng::OnLButtonDown( UINT, CPoint )  
  368. //{  
  369. //  m_uState = STATE_DOWN;  
  370. //  Invalidate();  
  371. //  return;  
  372. //}  
  373. //  
  374. ////鼠标抬起  
  375. //void CSkinButtonpng::OnLButtonUp( UINT ,CPoint )  
  376. //{  
  377. //  m_uState = STATE_NONE;  
  378. //  Invalidate();  
  379. //  return;  
  380. //}  
  381.   
  382. //鼠标移动  
  383. void CSkinButtonpng::OnMouseMove( UINT, CPoint )  
  384. {  
  385.     m_uState = STATE_MOVE;  
  386.     Invalidate();  
  387.   
  388.     TRACKMOUSEEVENT te = {sizeof(TRACKMOUSEEVENT) ,TME_LEAVE ,m_hWnd, 1};  
  389.     ::_TrackMouseEvent(&te);  
  390. }  
  391.   
  392. //鼠标离开  
  393. void CSkinButtonpng::OnMouseLeave()  
  394. {  
  395.     m_uState = STATE_NONE;  
  396.     Invalidate();  
  397. }  
  398.   
  399.   
  400.   
  401. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  


0 0