BMPButton.cpp
上传用户:xiaoke98
上传日期:2014-06-29
资源大小:5718k
文件大小:9k
源码类别:

家庭/个人应用

开发平台:

Visual C++

  1. // BMPButton.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "BMPButton.h"
  5. #include "tools.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CBMPButton
  13. CBMPButton::CBMPButton()
  14. {
  15. m_pBuffer = NULL;
  16. m_iBufferLen = 0;
  17. m_hBitmap = NULL;
  18. m_color = RGB(233, 247, 229);
  19. m_iLeftTopOffset = 0;
  20. m_iRightBottomOffset = 0;
  21. }
  22. CBMPButton::~CBMPButton()
  23. {
  24. if(m_pBuffer)
  25. {
  26. delete[] m_pBuffer;
  27. }
  28. }
  29. BEGIN_MESSAGE_MAP(CBMPButton, CButton)
  30. //{{AFX_MSG_MAP(CBMPButton)
  31. // NOTE - the ClassWizard will add and remove mapping macros here.
  32. //}}AFX_MSG_MAP
  33. ON_WM_ERASEBKGND() 
  34. ON_WM_PAINT()
  35. ON_WM_MOUSEMOVE()
  36. ON_MESSAGE(WM_MOUSELEAVE,OnMouseOut)
  37. END_MESSAGE_MAP()
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CBMPButton message handlers
  40. BOOL CBMPButton::OnEraseBkgnd( CDC* pDC)
  41. {
  42. RECT rcClient;
  43. this->GetClientRect(&rcClient);
  44. HBRUSH hOldBrush;
  45. HBRUSH hBrush = ::CreateSolidBrush(m_color);
  46. hOldBrush = (HBRUSH)pDC->SelectObject(hBrush);
  47. pDC->Rectangle(&rcClient);
  48. pDC->SelectObject(hOldBrush);
  49. ::DeleteObject(hBrush);
  50. return TRUE;
  51. }
  52. //-------------------------------------------------------------------------------
  53. void CBMPButton::OnPaint()
  54. {
  55. CButton::OnPaint();
  56. }
  57. //-------------------------------------------------------------------------------
  58. void CBMPButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) 
  59. {
  60. CDC *pDC =CDC::FromHandle(lpDIS->hDC);
  61. CRect rtControl(lpDIS->rcItem);
  62. CPen pen,*old_pen;
  63. CBrush brush,*old_brush;
  64. CString  strText;
  65. HFONT hOldFont = (HFONT)pDC->SelectObject ((HFONT)::GetStockObject (DEFAULT_GUI_FONT));
  66. UINT state =lpDIS->itemState;
  67. if(state & ODS_FOCUS)
  68. {
  69. rtControl.DeflateRect(1,1); //拥有焦点矩形变小
  70. }
  71. COLORREF crBorder =::GetSysColor(COLOR_HIGHLIGHT);
  72. pen.CreatePen(PS_SOLID, 1, crBorder);
  73. if( state & ODS_SELECTED)
  74. {
  75. //按钮按下时
  76. brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+50,-50));
  77. pDC->SetTextColor(RGB(240,240,240));
  78. }
  79. else
  80. {
  81. //鼠标在区域内
  82. brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+90,-66));
  83. pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
  84. }
  85. if(state &ODS_DISABLED)
  86. pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));//灰色字:禁用状态
  87. else if(state & ODS_SELECTED)
  88. pDC->SetTextColor(RGB(240,240,240)); //白色字:PUSH状态
  89. else if(MouseOver())
  90. pDC->SetTextColor(0); //黑色字:热感应状态
  91. else
  92. pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); //黑色字:普通状态
  93. old_brush=pDC->SelectObject(&brush);
  94. old_pen  =pDC->SelectObject(&pen);
  95. pDC->Rectangle(rtControl);
  96. pDC->SetBkMode(TRANSPARENT);
  97. GetWindowText(strText);
  98. pDC->DrawText(strText,rtControl,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
  99. if(state & ODS_FOCUS)
  100. {
  101. rtControl.DeflateRect(3,3);
  102. pDC->DrawFocusRect(rtControl);
  103. }
  104. pDC->SelectObject(old_pen);
  105. pDC->SelectObject(old_brush);
  106. pDC->SelectObject(hOldFont);
  107. Display();
  108. }
  109. //-------------------------------------------------------------------------------
  110. void CBMPButton::PreSubclassWindow( )
  111. {
  112. ModifyStyle(0,BS_OWNERDRAW);
  113. CButton::PreSubclassWindow();
  114. }
  115. //-------------------------------------------------------------------------------
  116. BOOL    CBMPButton::OpenBmpFile(void)
  117. {
  118. static char BASED_CODE szFilter[] = "BMP Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";
  119. CFileDialog dlg(TRUE,"BMP",NULL,  OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
  120. if(dlg.DoModal() == IDOK)
  121. {
  122. CString strFilePath = dlg.GetPathName();
  123. return(setBmpFile(strFilePath));
  124. }
  125. return FALSE;
  126. }
  127. //-------------------------------------------------------------------------------
  128. void    CBMPButton::getData(char* pBuffer, int& iDataLen)
  129. {
  130. if(pBuffer)
  131. {
  132. memcpy(pBuffer, m_pBuffer, m_iBufferLen);
  133. }
  134. iDataLen = m_iBufferLen;
  135. }
  136. //-------------------------------------------------------------------------------
  137. CString CBMPButton::getImagePath(void)
  138. {
  139. return m_strImagePath;
  140. }
  141. //-------------------------------------------------------------------------------
  142. void CBMPButton::setOffset(int iLeftTop, int iRightBottom)
  143. {
  144. m_iLeftTopOffset = iLeftTop;
  145. m_iRightBottomOffset = iRightBottom;
  146. }
  147. //-------------------------------------------------------------------------------
  148. void CBMPButton::setColor(COLORREF color)
  149. {
  150. m_color = color;
  151. }
  152. //-------------------------------------------------------------------------------
  153. BOOL CBMPButton::setBmpFile(CString& strFileName)
  154. {
  155. CFile file;
  156. if( !file.Open( strFileName, CFile::modeRead) )
  157. return FALSE;
  158. int iFileLen = file.GetLength();
  159. char* pData = new char[iFileLen];
  160. if(file.ReadHuge(pData,iFileLen) != iFileLen)
  161. return FALSE;
  162. m_strImagePath = strFileName;
  163. BOOL bResult =  setBmpData(pData, iFileLen);
  164. delete[] pData;
  165. return bResult;
  166. }
  167. //-----------------------------------------------------------------------------
  168. BOOL CBMPButton::setBmpData(char* pData, int iDataLen)
  169. {
  170. m_bFirst = true;
  171. if(iDataLen <= 0)
  172. {
  173. return FALSE;
  174. }
  175. if(m_iBufferLen < iDataLen)
  176. {
  177. delete[] m_pBuffer;
  178. m_pBuffer = new char[iDataLen];
  179. m_iBufferLen = iDataLen;
  180. }
  181. if(!m_pBuffer)
  182. {
  183. return FALSE;
  184. }
  185. memcpy(m_pBuffer, pData, iDataLen);
  186. if(BufferToHBITMAP() == NULL)
  187. {
  188. return FALSE;
  189. }
  190. Display();
  191. return TRUE;
  192. }
  193. //-----------------------------------------------------------------------------
  194. void    CBMPButton::Display(void)
  195. {
  196. if(NULL == m_hBitmap)
  197. {
  198. return;
  199. }
  200. CDC* pDC = this->GetDC();
  201. HBITMAP OldBitmap;
  202. CDC MemDC;
  203. MemDC.CreateCompatibleDC(pDC);
  204. OldBitmap=(HBITMAP)MemDC.SelectObject(m_hBitmap);
  205. RECT rcBmpButton;
  206. GetWindowRect(&rcBmpButton);
  207. CWnd* pParentWnd = this->GetParent();
  208. if(m_bFirst)
  209. {
  210. RECT rcParentWnd;
  211. pParentWnd->GetWindowRect(&rcParentWnd);
  212. RECT rcNewPos;
  213. rcNewPos.top = rcBmpButton.top - rcParentWnd.top;
  214. rcNewPos.left = rcBmpButton.left - rcParentWnd.left;
  215. rcNewPos.right = rcNewPos.left + m_iWidth+ m_iLeftTopOffset + m_iRightBottomOffset;
  216. rcNewPos.bottom = rcNewPos.top + m_iHeight + m_iLeftTopOffset + m_iRightBottomOffset;
  217. this->MoveWindow(&rcNewPos);
  218. m_bFirst = false;
  219. }
  220. pDC->BitBlt(m_iLeftTopOffset,m_iLeftTopOffset,m_iWidth,m_iHeight,&MemDC,0,0,SRCCOPY);
  221. MemDC.SelectObject(OldBitmap);
  222. }
  223. //-----------------------------------------------------------------------------
  224. HBITMAP CBMPButton::BufferToHBITMAP()
  225. {
  226. if(m_hBitmap)
  227. {
  228. ::DeleteObject(m_hBitmap);
  229. m_hBitmap = NULL;
  230. }
  231. LPSTR hDIB;
  232. LPSTR lpBuffer = m_pBuffer;
  233. LPVOID lpDIBBits;
  234. BITMAPFILEHEADER bmfHeader;
  235. DWORD bmfHeaderLen;
  236. bmfHeaderLen = sizeof(bmfHeader);
  237. strncpy((LPSTR)&bmfHeader,(LPSTR)lpBuffer,bmfHeaderLen);
  238. if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) return NULL;
  239. hDIB = lpBuffer + bmfHeaderLen;
  240. BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
  241. BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
  242. m_iWidth = bmInfo.bmiHeader.biWidth;
  243. m_iHeight = bmInfo.bmiHeader.biHeight;
  244. int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 << bmiHeader.biBitCount; 
  245. if( bmInfo.bmiHeader.biBitCount > 8 )
  246. lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + 
  247. ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
  248. else
  249. lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
  250. CDC* pDC = this->GetDC();
  251. m_hBitmap = CreateDIBitmap(pDC->m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
  252. return m_hBitmap;
  253. }
  254. //-----------------------------------------------------------------------------------------
  255. //返回鼠标是否在按钮区域内
  256. BOOL CBMPButton::MouseOver()
  257. {
  258. return m_bOver;
  259. }
  260. //-----------------------------------------------------------------------------------------
  261. void CBMPButton::OnMouseOut ()
  262. {
  263. //鼠标已离开按钮区域
  264.     m_bOver =FALSE;
  265. //重绘按钮
  266. InvalidateRect(NULL,FALSE);
  267. }
  268. //-----------------------------------------------------------------------------------------
  269. void CBMPButton::OnMouseMove(UINT nFlags, CPoint point)
  270. {
  271. /*if(m_bOver ==FALSE)
  272. {
  273. //鼠标在按钮之上
  274. m_bOver =TRUE;
  275. //按钮重绘
  276. InvalidateRect(NULL,FALSE);
  277. //跟踪鼠标
  278. //当鼠标离开按钮区域会收到WM_MOUSELEAVE,该消息直接调用OnMouseOut()
  279. TRACKMOUSEEVENT tme;
  280. tme.cbSize =sizeof(TRACKMOUSEEVENT);
  281. tme.dwFlags =TME_LEAVE;
  282. tme.dwHoverTime=0;
  283. tme.hwndTrack =m_hWnd;
  284. ::TrackMouseEvent(&tme);
  285. }*/
  286. CButton::OnMouseMove(nFlags, point);
  287. }
  288. //-----------------------------------------------------------------------------------------
  289. void    CBMPButton::ClearBmp(void)
  290. {
  291. if(m_hBitmap)
  292. {
  293. ::DeleteObject(m_hBitmap);
  294. m_hBitmap = NULL;
  295. }
  296. }