Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

629 lines
14 KiB

  1. // ProgressBar.cpp : implementation file
  2. /////////////////////////////////////////////////////////////////////////////
  3. #include "stdafx.h"
  4. #include "ProgressBar.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. IMPLEMENT_DYNCREATE(CProgressBar, CProgressCtrl)
  11. BEGIN_MESSAGE_MAP(CProgressBar, CProgressCtrl)
  12. //{{AFX_MSG_MAP(CProgressBar)
  13. ON_WM_ERASEBKGND()
  14. //}}AFX_MSG_MAP
  15. END_MESSAGE_MAP()
  16. /**************************************************************************\
  17. * CProgressBar::CProgressBar()
  18. *
  19. * Constructor for the progress control
  20. *
  21. *
  22. * Arguments:
  23. *
  24. * none
  25. *
  26. * Return Value:
  27. *
  28. * none
  29. *
  30. * History:
  31. *
  32. * 2/14/1999 Original Version
  33. *
  34. \**************************************************************************/
  35. CProgressBar::CProgressBar()
  36. {
  37. m_Rect.SetRect(0,0,0,0);
  38. }
  39. /**************************************************************************\
  40. * CProgressBar::
  41. *
  42. * Constructor for the Progress control
  43. *
  44. *
  45. * Arguments:
  46. *
  47. * strMessage - Status message to display
  48. * nSize - Max range of Progress control
  49. * MaxValue - Max range of Progress control
  50. * bSmooth - Smooth/Normal mode of progress display
  51. * nPane - which pane to display the progress control
  52. *
  53. * Return Value:
  54. *
  55. * none
  56. *
  57. * History:
  58. *
  59. * 2/14/1999 Original Version
  60. *
  61. \**************************************************************************/
  62. CProgressBar::CProgressBar(LPCTSTR strMessage, int nSize /*=100*/,
  63. int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/,
  64. int nPane/*=0*/)
  65. {
  66. Create(strMessage, nSize, MaxValue, bSmooth, nPane);
  67. }
  68. /**************************************************************************\
  69. * CProgressBar::~CProgressBar()
  70. *
  71. * Destruction
  72. *
  73. *
  74. * Arguments:
  75. *
  76. * none
  77. *
  78. * Return Value:
  79. *
  80. * none
  81. *
  82. * History:
  83. *
  84. * 2/14/1999 Original Version
  85. *
  86. \**************************************************************************/
  87. CProgressBar::~CProgressBar()
  88. {
  89. Clear();
  90. }
  91. /**************************************************************************\
  92. * CProgressBar::GetStatusBar()
  93. *
  94. * Returns the Status bar
  95. *
  96. *
  97. * Arguments:
  98. *
  99. * none
  100. *
  101. * Return Value:
  102. *
  103. * CStatusBar* - Status bar to be returned
  104. *
  105. * History:
  106. *
  107. * 2/14/1999 Original Version
  108. *
  109. \**************************************************************************/
  110. CStatusBar* CProgressBar::GetStatusBar()
  111. {
  112. CWnd *pMainWnd = AfxGetMainWnd();
  113. if (!pMainWnd)
  114. return NULL;
  115. // If main window is a frame window, use normal methods...
  116. if (pMainWnd->IsKindOf(RUNTIME_CLASS(CFrameWnd)))
  117. {
  118. CWnd* pMessageBar = ((CFrameWnd*)pMainWnd)->GetMessageBar();
  119. return DYNAMIC_DOWNCAST(CStatusBar, pMessageBar);
  120. }
  121. // otherwise traverse children to try and find the status bar...
  122. else
  123. return DYNAMIC_DOWNCAST(CStatusBar,
  124. pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR));
  125. }
  126. /**************************************************************************\
  127. * CProgressBar::Create()
  128. *
  129. * Creates a new progress control
  130. * Create the CProgressCtrl as a child of the status bar positioned
  131. * over the first pane, extending "nSize" percentage across pane.
  132. * Sets the range to be 0 to MaxValue, with a step of 1.
  133. *
  134. *
  135. * Arguments:
  136. *
  137. * strMessage - Status message to display
  138. * nSize - Max range of Progress control
  139. * MaxValue - Max range of Progress control
  140. * bSmooth - Smooth/Normal mode of progress display
  141. * nPane - which pane to display the progress control
  142. *
  143. * Return Value:
  144. *
  145. * none
  146. *
  147. * History:
  148. *
  149. * 2/14/1999 Original Version
  150. *
  151. \**************************************************************************/
  152. BOOL CProgressBar::Create(LPCTSTR strMessage, int nSize /*=100*/,
  153. int MaxValue /*=100*/, BOOL bSmooth /*=FALSE*/, int nPane/*=0*/)
  154. {
  155. BOOL bSuccess = FALSE;
  156. CStatusBar *pStatusBar = GetStatusBar();
  157. if (!pStatusBar)
  158. return FALSE;
  159. DWORD dwStyle = WS_CHILD|WS_VISIBLE;
  160. #ifdef PBS_SMOOTH
  161. if (bSmooth)
  162. dwStyle |= PBS_SMOOTH;
  163. #endif
  164. // Get CRect coordinates for requested status bar pane
  165. CRect PaneRect;
  166. pStatusBar->GetItemRect(nPane, &PaneRect);
  167. // Create the progress bar
  168. bSuccess = CProgressCtrl::Create(dwStyle, PaneRect, pStatusBar, 1);
  169. ASSERT(bSuccess);
  170. if (!bSuccess)
  171. return FALSE;
  172. // Set range and step
  173. SetRange(0, MaxValue);
  174. SetStep(1);
  175. m_strMessage = strMessage;
  176. m_nSize = nSize;
  177. m_nPane = nPane;
  178. m_strPrevText = pStatusBar->GetPaneText(m_nPane);
  179. // Resize the control to its desired width
  180. Resize();
  181. return TRUE;
  182. }
  183. /**************************************************************************\
  184. * CProgressBar::Clear()
  185. *
  186. * Destroy the progress control
  187. *
  188. *
  189. * Arguments:
  190. *
  191. * none
  192. *
  193. * Return Value:
  194. *
  195. * none
  196. *
  197. * History:
  198. *
  199. * 2/14/1999 Original Version
  200. *
  201. \**************************************************************************/
  202. void CProgressBar::Clear()
  203. {
  204. if (!IsWindow(GetSafeHwnd()))
  205. return;
  206. // Hide the window. This is necessary so that a cleared
  207. // window is not redrawn if "Resize" is called
  208. ModifyStyle(WS_VISIBLE, 0);
  209. CString str;
  210. if (m_nPane == 0)
  211. str.LoadString(AFX_IDS_IDLEMESSAGE); // Get the IDLE_MESSAGE
  212. else
  213. str = m_strPrevText; // Restore previous text
  214. // Place the IDLE_MESSAGE in the status bar
  215. CStatusBar *pStatusBar = GetStatusBar();
  216. if (pStatusBar)
  217. {
  218. pStatusBar->SetPaneText(m_nPane, str);
  219. pStatusBar->UpdateWindow();
  220. }
  221. }
  222. /**************************************************************************\
  223. * CProgressBar::SetText()
  224. *
  225. * Set the display text for the progress control
  226. *
  227. *
  228. * Arguments:
  229. *
  230. * none
  231. *
  232. * Return Value:
  233. *
  234. * none
  235. *
  236. * History:
  237. *
  238. * 2/14/1999 Original Version
  239. *
  240. \**************************************************************************/
  241. BOOL CProgressBar::SetText(LPCTSTR strMessage)
  242. {
  243. m_strMessage = strMessage;
  244. SetPaneText(m_nPane,m_strMessage);
  245. return Resize();
  246. }
  247. /**************************************************************************\
  248. * CProgressBar::SetSize()
  249. *
  250. * Set the size for the progress control
  251. *
  252. *
  253. * Arguments:
  254. *
  255. * nSize - New size for the progress control
  256. *
  257. * Return Value:
  258. *
  259. * none
  260. *
  261. * History:
  262. *
  263. * 2/14/1999 Original Version
  264. *
  265. \**************************************************************************/
  266. BOOL CProgressBar::SetSize(int nSize)
  267. {
  268. m_nSize = nSize;
  269. return Resize();
  270. }
  271. /**************************************************************************\
  272. * CProgressBar::SetBarColour()
  273. *
  274. * Sets the color for the progress control
  275. *
  276. *
  277. * Arguments:
  278. *
  279. * clrBar - Color for progress control
  280. *
  281. * Return Value:
  282. *
  283. * COLORREF last color of progress control
  284. *
  285. * History:
  286. *
  287. * 2/14/1999 Original Version
  288. *
  289. \**************************************************************************/
  290. COLORREF CProgressBar::SetBarColour(COLORREF clrBar)
  291. {
  292. #ifdef PBM_SETBKCOLOR
  293. if (!IsWindow(GetSafeHwnd()))
  294. return CLR_DEFAULT;
  295. return (COLORREF )SendMessage(PBM_SETBARCOLOR, 0, (LPARAM) clrBar);
  296. #else
  297. UNUSED(clrBar);
  298. return CLR_DEFAULT;
  299. #endif
  300. }
  301. /**************************************************************************\
  302. * CProgressBar::SetBkColour()
  303. *
  304. * Sets the background color for the progress control
  305. *
  306. *
  307. * Arguments:
  308. *
  309. * none
  310. *
  311. * Return Value:
  312. *
  313. * COLORREF last color of progress control background
  314. *
  315. * History:
  316. *
  317. * 2/14/1999 Original Version
  318. *
  319. \**************************************************************************/
  320. COLORREF CProgressBar::SetBkColour(COLORREF clrBk)
  321. {
  322. #ifdef PBM_SETBKCOLOR
  323. if (!IsWindow(GetSafeHwnd()))
  324. return CLR_DEFAULT;
  325. return (COLORREF) SendMessage(PBM_SETBKCOLOR, 0, (LPARAM) clrBk);
  326. #else
  327. UNUSED(clrBk);
  328. return CLR_DEFAULT;
  329. #endif
  330. }
  331. /**************************************************************************\
  332. * CProgressBar::SetRange()
  333. *
  334. * Set the range limits for the progress control
  335. *
  336. *
  337. * Arguments:
  338. *
  339. * nLower - Lower limit
  340. * nUpper - Upper limit
  341. * nStep - Step value
  342. *
  343. * Return Value:
  344. *
  345. * status
  346. *
  347. * History:
  348. *
  349. * 2/14/1999 Original Version
  350. *
  351. \**************************************************************************/
  352. BOOL CProgressBar::SetRange(int nLower, int nUpper, int nStep /* = 1 */)
  353. {
  354. if (!IsWindow(GetSafeHwnd()))
  355. return FALSE;
  356. // To take advantage of the Extended Range Values we use the PBM_SETRANGE32
  357. // message intead of calling CProgressCtrl::SetRange directly. If this is
  358. // being compiled under something less than VC 5.0, the necessary defines
  359. // may not be available.
  360. #ifdef PBM_SETRANGE32
  361. ASSERT(-0x7FFFFFFF <= nLower && nLower <= 0x7FFFFFFF);
  362. ASSERT(-0x7FFFFFFF <= nUpper && nUpper <= 0x7FFFFFFF);
  363. SendMessage(PBM_SETRANGE32, (WPARAM) nLower, (LPARAM) nUpper);
  364. #else
  365. ASSERT(0 <= nLower && nLower <= 65535);
  366. ASSERT(0 <= nUpper && nUpper <= 65535);
  367. CProgressCtrl::SetRange(nLower, nUpper);
  368. #endif
  369. CProgressCtrl::SetStep(nStep);
  370. return TRUE;
  371. }
  372. /**************************************************************************\
  373. * CProgressBar::SetPos()
  374. *
  375. * Sets the current position for the progress control
  376. *
  377. *
  378. * Arguments:
  379. *
  380. * nPos - new Postion to be set
  381. *
  382. * Return Value:
  383. *
  384. * status
  385. *
  386. * History:
  387. *
  388. * 2/14/1999 Original Version
  389. *
  390. \**************************************************************************/
  391. int CProgressBar::SetPos(int nPos)
  392. {
  393. if (!IsWindow(GetSafeHwnd()))
  394. return 0;
  395. #ifdef PBM_SETRANGE32
  396. ASSERT(-0x7FFFFFFF <= nPos && nPos <= 0x7FFFFFFF);
  397. #else
  398. ASSERT(0 <= nPos && nPos <= 65535);
  399. #endif
  400. ModifyStyle(0,WS_VISIBLE);
  401. return CProgressCtrl::SetPos(nPos);
  402. }
  403. /**************************************************************************\
  404. * CProgressBar::OffestPos()
  405. *
  406. * Set the progress control's offset
  407. *
  408. *
  409. * Arguments:
  410. *
  411. * nPos - Position offset
  412. *
  413. * Return Value:
  414. *
  415. * status
  416. *
  417. * History:
  418. *
  419. * 2/14/1999 Original Version
  420. *
  421. \**************************************************************************/
  422. int CProgressBar::OffsetPos(int nPos)
  423. {
  424. if (!IsWindow(GetSafeHwnd()))
  425. return 0;
  426. ModifyStyle(0,WS_VISIBLE);
  427. return CProgressCtrl::OffsetPos(nPos);
  428. }
  429. /**************************************************************************\
  430. * CProgressBar::SetStep()
  431. *
  432. * Set progress control's step value
  433. *
  434. *
  435. * Arguments:
  436. *
  437. * nStep - Step value to be set
  438. *
  439. * Return Value:
  440. *
  441. * none
  442. *
  443. * History:
  444. *
  445. * 2/14/1999 Original Version
  446. *
  447. \**************************************************************************/
  448. int CProgressBar::SetStep(int nStep)
  449. {
  450. if (!IsWindow(GetSafeHwnd()))
  451. return 0;
  452. ModifyStyle(0,WS_VISIBLE);
  453. return CProgressCtrl::SetStep(nStep);
  454. }
  455. /**************************************************************************\
  456. * CProgressBar::StepIt()
  457. *
  458. * Step the progress control standard step value
  459. *
  460. *
  461. * Arguments:
  462. *
  463. * none
  464. *
  465. * Return Value:
  466. *
  467. * none
  468. *
  469. * History:
  470. *
  471. * 2/14/1999 Original Version
  472. *
  473. \**************************************************************************/
  474. int CProgressBar::StepIt()
  475. {
  476. if (!IsWindow(GetSafeHwnd()))
  477. return 0;
  478. ModifyStyle(0,WS_VISIBLE);
  479. return CProgressCtrl::StepIt();
  480. }
  481. /**************************************************************************\
  482. * CProgressBar::Resize()
  483. *
  484. * Resize the progress control to fit
  485. *
  486. *
  487. * Arguments:
  488. *
  489. * none
  490. *
  491. * Return Value:
  492. *
  493. * status
  494. *
  495. * History:
  496. *
  497. * 2/14/1999 Original Version
  498. *
  499. \**************************************************************************/
  500. BOOL CProgressBar::Resize()
  501. {
  502. if (!IsWindow(GetSafeHwnd()))
  503. return FALSE;
  504. CStatusBar *pStatusBar = GetStatusBar();
  505. if (!pStatusBar)
  506. return FALSE;
  507. // Redraw the window text
  508. if (IsWindowVisible())
  509. {
  510. pStatusBar->SetPaneText(m_nPane, m_strMessage);
  511. pStatusBar->UpdateWindow();
  512. }
  513. // Calculate how much space the text takes up
  514. CClientDC dc(pStatusBar);
  515. CFont *pOldFont = dc.SelectObject(pStatusBar->GetFont());
  516. CSize size = dc.GetTextExtent(m_strMessage); // Length of text
  517. int margin = dc.GetTextExtent(_T(" ")).cx * 2; // Text margin
  518. dc.SelectObject(pOldFont);
  519. // Now calculate the rectangle in which we will draw the progress bar
  520. CRect rc;
  521. pStatusBar->GetItemRect(m_nPane, rc);
  522. // Position left of progress bar after text and right of progress bar
  523. // to requested percentage of status bar pane
  524. if (!m_strMessage.IsEmpty())
  525. rc.left += (size.cx + 2*margin);
  526. rc.right -= (rc.right - rc.left) * (100 - m_nSize) / 100;
  527. if (rc.right < rc.left) rc.right = rc.left;
  528. // Leave a litle vertical margin (10%) between the top and bottom of the bar
  529. int Height = rc.bottom - rc.top;
  530. rc.bottom -= Height/10;
  531. rc.top += Height/10;
  532. // If the window size has changed, resize the window
  533. if (rc != m_Rect)
  534. {
  535. MoveWindow(&rc);
  536. m_Rect = rc;
  537. }
  538. return TRUE;
  539. }
  540. /**************************************************************************\
  541. * CProgressBar::OnEraseBkgnd()
  542. *
  543. * Resize, progress control
  544. *
  545. *
  546. * Arguments:
  547. *
  548. * none
  549. *
  550. * Return Value:
  551. *
  552. * status
  553. *
  554. * History:
  555. *
  556. * 2/14/1999 Original Version
  557. *
  558. \**************************************************************************/
  559. BOOL CProgressBar::OnEraseBkgnd(CDC* pDC)
  560. {
  561. Resize();
  562. return CProgressCtrl::OnEraseBkgnd(pDC);
  563. }
  564. /**************************************************************************\
  565. * CProgressBar::SetPaneText()
  566. *
  567. * Set the text for the Pane (Status text for progress control)
  568. *
  569. *
  570. * Arguments:
  571. *
  572. * nPane - pane number
  573. * strText - Text to add to the status pane
  574. *
  575. * Return Value:
  576. *
  577. * status
  578. *
  579. * History:
  580. *
  581. * 2/14/1999 Original Version
  582. *
  583. \**************************************************************************/
  584. BOOL CProgressBar::SetPaneText(int nPane, LPCTSTR strText)
  585. {
  586. CStatusBar* pStatusBar = GetStatusBar();
  587. if(pStatusBar != NULL)
  588. {
  589. pStatusBar->SetPaneText(nPane,strText);
  590. pStatusBar->UpdateWindow();
  591. }
  592. return TRUE;
  593. }