ProgressCtrlST.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:9k
源码类别:

CA认证

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "ProgressCtrlST.h"
  3. #ifdef _DEBUG
  4. #define new DEBUG_NEW
  5. #undef THIS_FILE
  6. static char THIS_FILE[] = __FILE__;
  7. #endif
  8. CProgressCtrlST::CProgressCtrlST()
  9. {
  10. // Default range of the control
  11. m_nLower = 0;
  12. m_nUpper = 100;
  13. CalcRange();
  14. // Default position
  15. m_nPos = 0;
  16. // Default step
  17. m_nStep = 10;
  18. FreeResources(FALSE);
  19. }
  20. CProgressCtrlST::~CProgressCtrlST()
  21. {
  22. FreeResources();
  23. }
  24. BEGIN_MESSAGE_MAP(CProgressCtrlST, CProgressCtrl)
  25. //{{AFX_MSG_MAP(CProgressCtrlST)
  26. ON_WM_PAINT()
  27. //}}AFX_MSG_MAP
  28. END_MESSAGE_MAP()
  29. void CProgressCtrlST::FreeResources(BOOL bCheckForNULL)
  30. {
  31. if (bCheckForNULL == TRUE)
  32. {
  33. // Destroy bitmap
  34. if (m_hBitmap) ::DeleteObject(m_hBitmap);
  35. } // if
  36. m_hBitmap = NULL;
  37. m_dwWidth = 0;
  38. m_dwHeight = 0;
  39. } // End of FreeResources
  40. void CProgressCtrlST::OnPaint() 
  41. {
  42. // If there is no bitmap loaded
  43. if (m_hBitmap == NULL) 
  44. {
  45. CProgressCtrl::OnPaint();
  46. return;
  47. } // if
  48. CRect rcCtrl;
  49. DWORD dwStyle = 0;
  50. BOOL bVertical = FALSE;
  51. float f = 0;
  52. int nPercentage = 0;
  53. HDC hdcMem = NULL;
  54. HDC hdcTemp = NULL;
  55. HBITMAP hOldBitmap = NULL;
  56. HBITMAP hbmpTemp = NULL;
  57. HBITMAP hOldTempBitmap = NULL;
  58. CPaintDC dc(this);
  59. GetClientRect(rcCtrl);
  60. dwStyle = GetStyle();
  61. bVertical = (dwStyle & PBS_VERTICAL) == PBS_VERTICAL;
  62. // Has border ?
  63. if ((dwStyle & WS_BORDER) == WS_BORDER)
  64. {
  65. CBrush brBtnShadow(RGB(0, 0, 0));
  66. dc.FrameRect(rcCtrl, &brBtnShadow);
  67. rcCtrl.DeflateRect(1, 1);
  68. } // if
  69. rcCtrl.DeflateRect(1, 1);
  70. hdcMem = ::CreateCompatibleDC(dc.m_hDC);
  71. // Select bitmap
  72. hOldBitmap = (HBITMAP)::SelectObject(hdcMem, m_hBitmap);
  73. // Create temporary DC & bitmap
  74. hdcTemp = ::CreateCompatibleDC(dc.m_hDC);
  75. hbmpTemp = ::CreateCompatibleBitmap(hdcMem, rcCtrl.Width(), rcCtrl.Height());
  76. hOldTempBitmap = (HBITMAP)::SelectObject(hdcTemp, hbmpTemp);
  77. // Calculate control's percentage to draw
  78. nPercentage = (int)((100.0/m_nRange)*(abs(m_nLower)+m_nPos));
  79. // Adjust rectangle to draw on screen
  80. if (bVertical)
  81. {
  82. f = ((float)(rcCtrl.Height())/100)*nPercentage;
  83. if ((rcCtrl.bottom - (int)f) < rcCtrl.top)
  84. rcCtrl.top += 1;
  85. else
  86. rcCtrl.top = rcCtrl.bottom - (int)f;
  87. } // if
  88. else
  89. {
  90. f = ((float)(rcCtrl.Width())/100)*nPercentage;
  91. if ((rcCtrl.left + (int)f) > rcCtrl.right)
  92. rcCtrl.right -= 1;
  93. else
  94. rcCtrl.right = rcCtrl.left + (int)f;
  95. } // else
  96. // Tile the bitmap into the temporary rectangle
  97. TileBitmap(hdcTemp, hdcMem, rcCtrl);
  98. // Copy from temporary DC to screen (only the percentage rectangle)
  99. if (rcCtrl.IsRectEmpty() == FALSE)
  100. ::BitBlt(dc.m_hDC, rcCtrl.left, rcCtrl.top, rcCtrl.Width(), rcCtrl.Height(), hdcTemp, 0, 0, SRCCOPY);
  101. CRect rcFullCtrl;
  102. GetClientRect(rcFullCtrl);
  103. OnDrawText(&dc, nPercentage, rcFullCtrl, rcCtrl, bVertical);
  104. // Restore old selected bitmaps
  105. ::SelectObject(hdcTemp, hOldTempBitmap);
  106. ::SelectObject(hdcMem, hOldBitmap);
  107. ::DeleteObject( hbmpTemp );
  108.     ::DeleteDC( hdcTemp );
  109. ::DeleteDC( hdcMem );
  110. } // End of OnPaint
  111. void CProgressCtrlST::TileBitmap(HDC hdcDest, HDC hdcSrc, CRect rect)
  112. {
  113. int nHLoop = 0;
  114. int nVLoop = 0;
  115. int nHTiles = 0;
  116. int nVTiles = 0;
  117. // Calculate number of horizontal tiles
  118. nHTiles = (rect.Width() / m_dwWidth);
  119. if (rect.Width() % m_dwWidth != 0) nHTiles++;
  120. // Calculate number of vertical tiles
  121. nVTiles = (rect.Height() / m_dwHeight);
  122. if (rect.Height() % m_dwHeight != 0) nVTiles++;
  123. // Tile bitmap horizontally
  124. for (nHLoop = 0; nHLoop < nHTiles; nHLoop++)
  125. {
  126. // Tile bitmap vertically
  127. for (nVLoop = 0; nVLoop < nVTiles; nVLoop++)
  128. {
  129. ::BitBlt(hdcDest, (nHLoop * m_dwWidth), (nVLoop * m_dwHeight), m_dwWidth, m_dwHeight, hdcSrc, 0, 0, SRCCOPY);
  130. } // for
  131. } // for
  132. } // End of TileBitmap
  133. void CProgressCtrlST::CalcRange()
  134. {
  135. m_nRange = abs(m_nUpper - m_nLower);
  136. // Avoid divide by zero
  137. if (m_nRange == 0) m_nRange = 1;
  138. } // End of CalcRange
  139. // This function sets the bitmap to use to draw the progress bar.
  140. //
  141. // Parameters:
  142. // [IN] nBitmap
  143. // Resource ID of the bitmap to use as background.
  144. // Pass NULL to remove any previous bitmap.
  145. // [IN] bRepaint
  146. // If TRUE the control will be repainted.
  147. //
  148. // Return value:
  149. // PROGRESSST_OK
  150. // Function executed successfully.
  151. // PROGRESSST_INVALIDRESOURCE
  152. // The resource specified cannot be found or loaded.
  153. //
  154. DWORD CProgressCtrlST::SetBitmap(int nBitmap, BOOL bRepaint)
  155. {
  156. HBITMAP hBitmap = NULL;
  157. HINSTANCE hInstResource = NULL;
  158. // Find correct resource handle
  159. hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBitmap), RT_BITMAP);
  160. // Load bitmap
  161. hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBitmap), IMAGE_BITMAP, 0, 0, 0);
  162. return SetBitmap(hBitmap, bRepaint);
  163. } // End of SetBitmap
  164. // This function sets the bitmap to use to draw the progress bar.
  165. //
  166. // Parameters:
  167. // [IN] hBitmap
  168. // Handle to the bitmap to use as background.
  169. // Pass NULL to remove any previous bitmap.
  170. // [IN] bRepaint
  171. // If TRUE the control will be repainted.
  172. //
  173. // Return value:
  174. // PROGRESSCTRLST_OK
  175. // Function executed successfully.
  176. // PROGRESSCTRLST_INVALIDRESOURCE
  177. // The resource specified cannot be found or loaded.
  178. //
  179. DWORD CProgressCtrlST::SetBitmap(HBITMAP hBitmap, BOOL bRepaint)
  180. {
  181. int nRetValue;
  182. BITMAP csBitmapSize;
  183. // Free any loaded resource
  184. FreeResources();
  185. if (hBitmap)
  186. {
  187. m_hBitmap = hBitmap;
  188. // Get bitmap size
  189. nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &csBitmapSize);
  190. if (nRetValue == 0)
  191. {
  192. FreeResources();
  193. return PROGRESSCTRLST_INVALIDRESOURCE;
  194. } // if
  195. m_dwWidth = (DWORD)csBitmapSize.bmWidth;
  196. m_dwHeight = (DWORD)csBitmapSize.bmHeight;
  197. } // if
  198. if (bRepaint) Invalidate();
  199. return PROGRESSCTRLST_OK;
  200. } // End of SetBitmap
  201. // This function sets the upper and lower limits of the progress bar control's range
  202. // and redraws the bar to reflect the new ranges.
  203. //
  204. // Parameters:
  205. // [IN] nLower
  206. // Specifies the lower limit of the range (default is zero).
  207. // [IN] nUpper
  208. // Specifies the upper limit of the range (default is 100).
  209. //
  210. void CProgressCtrlST::SetRange(int nLower, int nUpper)
  211. {
  212. m_nLower = nLower;
  213. m_nUpper = nUpper;
  214. CalcRange();
  215. CProgressCtrl::SetRange32(nLower, nUpper);
  216. } // End of SetRange
  217. // This function specifies the step increment for a progress bar control.
  218. // The step increment is the amount by which a call to StepIt increases
  219. // the progress bar's current position.
  220. //
  221. // Parameters:
  222. // [IN] nStep
  223. // New step increment.
  224. //
  225. // Return value:
  226. // The previous step increment.
  227. //
  228. int CProgressCtrlST::SetStep(int nStep)
  229. {
  230. m_nStep = nStep;
  231. return CProgressCtrl::SetStep(nStep);
  232. } // End Of SetStep
  233. // This function sets the progress bar control's current position as specified by nPos
  234. // and redraws the bar to reflect the new position.
  235. // The position of the progress bar control is not the physical location on the screen,
  236. // but rather is between the upper and lower range indicated in SetRange.
  237. //
  238. // Parameters:
  239. // [IN] nPos
  240. // New position of the progress bar control.
  241. //
  242. // Return value:
  243. // The previous position of the progress bar control.
  244. //
  245. int CProgressCtrlST::SetPos(int nPos)
  246. {
  247. // Bound checking
  248. if (nPos < m_nLower) nPos = m_nLower;
  249. if (nPos > m_nUpper) nPos = m_nUpper;
  250. m_nPos = nPos;
  251. return CProgressCtrl::SetPos(nPos);
  252. } // End of SetPos
  253. // This function advances the current position for a progress bar control by the step increment
  254. // and redraws the bar to reflect the new position.
  255. // The step increment is set by the SetStep method.
  256. //
  257. // Return value:
  258. // The previous position of the progress bar control.
  259. //
  260. int CProgressCtrlST::StepIt()
  261. {
  262. m_nPos += m_nStep;
  263. // Bound checking
  264. if (m_nPos > m_nUpper) m_nPos = m_nLower + (m_nPos - m_nUpper);
  265. return CProgressCtrl::StepIt();
  266. } // End of StepIt
  267. // This function is called each time the progress bar is redrawn.
  268. // It is a virtual function to let derived classes do custom drawing.
  269. // The default implementation does nothing.
  270. //
  271. // Parameters:
  272. // [IN] pDC
  273. // Pointer to the device context.
  274. // [IN] nPercentage
  275. // Current percentage of the progress bar.
  276. // [IN] rcCtrl
  277. // A CRect object that indicates the dimensions of the entire control.
  278. // [IN] rcProgress
  279. // A CRect object that indicates the dimensions of the currently displayed bar.
  280. // [IN] bVertical
  281. // TRUE if the progress is vertical, otherwise FALSE.
  282. //
  283. void CProgressCtrlST::OnDrawText(CDC* pDC, int nPercentage, CRect rcCtrl, CRect rcProgress, BOOL bVertical)
  284. {
  285. /*
  286. CString sText;
  287. CFont Font;
  288. CFont* pOldFont = NULL;
  289. LOGFONT csLogFont;
  290. // Get log-font used by parent window
  291. GetParent()->GetFont()->GetLogFont(&csLogFont);
  292. // Make it bold
  293. csLogFont.lfWeight = FW_BOLD;
  294. // Vertical progress bar ?
  295. if (bVertical)
  296. {
  297. csLogFont.lfEscapement =  900;
  298. csLogFont.lfOrientation = 900;
  299. } // if
  300. // Create font
  301. Font.CreateFontIndirect(&csLogFont);
  302. sText.Format(_T("%d%%"), nPercentage);
  303. pOldFont = pDC->SelectObject(&Font);
  304. pDC->SetBkMode(TRANSPARENT);
  305. pDC->DrawText(sText, -1, rcProgress, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  306. if (pOldFont) pDC->SelectObject(pOldFont);
  307. Font.DeleteObject();
  308. */
  309. } // End of OnDrawText