BitmapStatic.cpp
上传用户:maryhy001
上传日期:2007-05-02
资源大小:2317k
文件大小:7k
源码类别:

网格计算

开发平台:

Visual C++

  1. // BitmapStatic.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "BitmapStatic.h"
  5. #define TIMER_ID 100
  6. //It loads a "hand" cursor from the winhlp32.exe module.
  7. HCURSOR WINAPI GetSysHandCursor(void)
  8. {
  9. CString strWndDir;
  10. GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
  11. strWndDir.ReleaseBuffer();
  12. strWndDir += _T("\winhlp32.exe");
  13. HMODULE hModule = LoadLibrary(strWndDir);
  14. if(hModule)
  15. {
  16. HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
  17. if (hHandCursor)
  18. {
  19. FreeLibrary(hModule);
  20. return CopyCursor(hHandCursor);
  21. }
  22. }
  23. FreeLibrary(hModule);
  24. return NULL;
  25. }
  26. // CBitmapStatic
  27. CBitmapStatic::CBitmapStatic()
  28. {
  29. this->m_hHandCursor   = NULL;
  30. this->m_bHoverControl = FALSE;
  31. this->m_hBitmapHandle = NULL;
  32. this->m_strCaption.Empty();
  33. }
  34. CBitmapStatic::~CBitmapStatic()
  35. {
  36. this->DeAttachObject();
  37. }
  38. BEGIN_MESSAGE_MAP(CBitmapStatic, CStatic)
  39. //{{AFX_MSG_MAP(CBitmapStatic)
  40. ON_WM_TIMER()
  41. ON_WM_PAINT()
  42. ON_WM_MOUSEMOVE()
  43. ON_WM_SETCURSOR()
  44. ON_WM_ERASEBKGND()
  45. ON_CONTROL_REFLECT(STN_CLICKED, OnClicked)
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. // CBitmapStatic message handlers
  49. //free bitmap object.
  50. void CBitmapStatic::DeAttachObject(void)
  51. {
  52. if(NULL != this->m_hBitmapHandle)
  53. {
  54. ::DeleteObject(this->m_hBitmapHandle);
  55. this->m_hBitmapHandle = NULL;
  56. }
  57. }
  58. void CBitmapStatic::AdjustWindowRect(void)
  59. {
  60. if(NULL == this->m_hBitmapHandle || !GetSafeHwnd()) return ;
  61. CBitmap *pBitmap = CBitmap::FromHandle(this->m_hBitmapHandle);
  62. if(NULL != pBitmap)
  63. {
  64. BITMAP bmpinfo;
  65. pBitmap->GetBitmap(&bmpinfo);
  66. CRect rcclt;
  67. CSize sizetxt, sizeds;
  68. CDC *pdc = this->GetDC();
  69. sizeds.cx = 2;
  70. sizeds.cy = 2;
  71. this->GetClientRect(&rcclt);
  72. if(!this->m_strCaption.IsEmpty())
  73. {
  74. sizeds.cx = 2;
  75. sizeds.cy = 4;
  76. sizetxt = pdc->GetTextExtent(this->m_strCaption);
  77. sizeds.cy = (sizeds.cy + 2) * (2*sizetxt.cx / rcclt.Width() + 2);
  78. }
  79. this->GetWindowRect(&rcclt);
  80. CWnd *parwnd = this->GetParent();
  81. if(NULL != parwnd)
  82. {
  83. parwnd->ScreenToClient(&rcclt);
  84. }
  85. this->SetWindowPos(NULL, rcclt.left, rcclt.top, 
  86. bmpinfo.bmWidth + sizeds.cx, 
  87. bmpinfo.bmHeight + sizeds.cy, 
  88. SWP_SHOWWINDOW);
  89. }
  90. }
  91. BOOL CBitmapStatic::SetBitmap(UINT uResourceId)
  92. {
  93. this->DeAttachObject();
  94. this->m_hBitmapHandle = ::LoadBitmap(::AfxGetResourceHandle(), 
  95. MAKEINTRESOURCE(uResourceId));
  96. this->AdjustWindowRect();
  97. this->Invalidate();
  98. return (NULL != this->m_hBitmapHandle);
  99. }
  100. BOOL CBitmapStatic::SetBitmap(HBITMAP hBitmapHandle)
  101. {
  102. this->DeAttachObject();
  103. this->m_hBitmapHandle = hBitmapHandle;
  104. this->AdjustWindowRect();
  105. this->Invalidate();
  106. return (NULL != this->m_hBitmapHandle);
  107. }
  108. BOOL CBitmapStatic::SetBitmap(CBitmap &pBitmapObj)
  109. {
  110. this->DeAttachObject();
  111. this->m_hBitmapHandle = (HBITMAP)pBitmapObj.GetSafeHandle();
  112. this->AdjustWindowRect();
  113. this->Invalidate();
  114. return (NULL != this->m_hBitmapHandle);
  115. }
  116. void CBitmapStatic::SetCaption(const CString &strCaption)
  117. {
  118. this->m_strCaption.Empty();
  119. this->m_strCaption = strCaption;
  120. this->AdjustWindowRect();
  121. this->Invalidate();
  122. }
  123. BOOL CBitmapStatic::OnEraseBkgnd(CDC* pDC) 
  124. {
  125. CRect rc;
  126. CBrush brushbrd;
  127. this->GetClientRect(&rc);
  128. if(this->m_bHoverControl)
  129. {
  130. brushbrd.CreateSolidBrush(RGB(0, 0, 160));
  131. pDC->FillSolidRect(&rc, RGB(213, 227, 255));
  132. pDC->FrameRect(&rc, &brushbrd);
  133. brushbrd.DeleteObject();
  134. }
  135. else
  136. {
  137. pDC->FillSolidRect(rc, ::GetSysColor(COLOR_3DFACE));
  138. }
  139. return TRUE;
  140. }
  141. void CBitmapStatic::OnMouseMove(UINT nFlags, CPoint point) 
  142. {
  143. if(!this->m_bHoverControl)
  144. {
  145. this->m_bHoverControl = TRUE;
  146. this->Invalidate();
  147. this->SetTimer(TIMER_ID, 100, NULL);
  148. }
  149. CStatic::OnMouseMove(nFlags, point);
  150. }
  151. void CBitmapStatic::OnTimer(UINT nIDEvent) 
  152. {
  153. CRect rc;
  154. CPoint pt;
  155. ::GetCursorPos(&pt);
  156. this->GetClientRect(&rc);
  157. this->ClientToScreen(&rc);
  158. if(!rc.PtInRect(pt))
  159. {
  160. this->m_bHoverControl = FALSE;
  161. this->KillTimer(TIMER_ID);
  162. this->Invalidate();
  163. }
  164. CStatic::OnTimer(nIDEvent);
  165. }
  166. void CBitmapStatic::OnPaint() 
  167. {
  168. //device context for painting.
  169. CPaintDC dc(this);
  170. if(!m_hBitmapHandle) return ;
  171. CDC memdc;
  172. BITMAP bmpinfo;
  173. CRect rcclt;
  174. this->GetClientRect(&rcclt);
  175. memdc.CreateCompatibleDC(&dc);
  176. //get the bitmap information -- width / height.
  177. CBitmap *pbmp = CBitmap::FromHandle(m_hBitmapHandle);
  178. ASSERT(NULL != pbmp);
  179. pbmp->GetBitmap(&bmpinfo);
  180. //draw specialed bitmap.
  181. memdc.SelectObject(m_hBitmapHandle);
  182. memdc.SetBkMode(TRANSPARENT);
  183. memdc.SelectObject((HFONT)::GetStockObject(SYSTEM_FONT));
  184. dc.BitBlt(rcclt.left + 1, rcclt.top + 1,
  185. min(rcclt.Width() - 2, bmpinfo.bmWidth), 
  186. min(rcclt.Height()- 2, bmpinfo.bmHeight),
  187. &memdc, 0, 0, SRCCOPY);
  188. //draw static caption text.
  189. if(!m_strCaption.IsEmpty())
  190. {
  191. dc.SetBkMode(TRANSPARENT);
  192. COLORREF crcolor;
  193. CRect  rctxt;
  194. CSize  sizetxt = dc.GetTextExtent(m_strCaption);
  195. this->GetClientRect(&rcclt); rctxt = rcclt;
  196. HFONT hfont = (HFONT)dc.SelectObject(::GetStockObject(SYSTEM_FONT));
  197. //make text out rect.
  198. rctxt.left = (rcclt.Width() - sizetxt.cx) / 2 + sizetxt.cx / 8;
  199. rctxt.top = rcclt.bottom - (rcclt.Height()- sizetxt.cy) / 4;
  200. rctxt.right = rcclt.left + min(rcclt.left + sizetxt.cx, rcclt.right);
  201. rctxt.bottom= rctxt.top  + min(rcclt.top + sizetxt.cy, rcclt.bottom);
  202. //if the mouse is in window client rect then
  203. //change the text color and inflate textout rect.
  204. if(this->m_bHoverControl)
  205. {
  206. crcolor = dc.SetTextColor(RGB(255, 0, 0));
  207. rctxt.InflateRect(2, 1);
  208. }
  209. else
  210. {
  211. //use default font color -- black.
  212. crcolor = dc.SetTextColor(RGB(0, 0, 0));
  213. }
  214. dc.DrawText(m_strCaption, &rctxt, DT_CENTER | DT_VCENTER | DT_WORDBREAK);
  215. //restore the device context.
  216. dc.SetTextColor(crcolor);
  217. dc.SelectObject(hfont);
  218. }
  219. //delete GDI object.
  220. pbmp->Detach();
  221. memdc.DeleteDC();
  222. }
  223. void CBitmapStatic::PreSubclassWindow() 
  224. {
  225. //we want to get mouse clicks via STN_CLICKED.
  226. DWORD dwStyle = this->GetStyle();
  227. ::SetWindowLong(this->GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
  228. this->m_hHandCursor = GetSysHandCursor();
  229. CStatic::PreSubclassWindow();
  230. }
  231. void CBitmapStatic::OnClicked()
  232. {
  233. CWnd *parWnd = this->GetParent();
  234. ASSERT(NULL != parWnd);
  235. parWnd->SendMessage(UWM_STATICCLICKED, (WPARAM)GetSafeHwnd(), 0);
  236. }
  237. BOOL CBitmapStatic::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
  238. {
  239. if(this->m_bHoverControl && this->m_hHandCursor)
  240. {
  241. ::SetCursor(this->m_hHandCursor);
  242. return TRUE;
  243. }
  244. return FALSE;
  245. }