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

CA认证

开发平台:

Visual C++

  1. )
  2. {
  3. #ifdef dCSP_DIALOG_PROGRESS
  4.   CRect oRectPane;
  5.   // Init
  6.   // Process + Return
  7.   if(m_poWndProgress == NULL)
  8.   {
  9. #endif // dCSP_DIALOG_PROGRESS
  10. // A..... Return the current <m_nSize> value
  11.     return m_nSize;
  12. #ifdef dCSP_DIALOG_PROGRESS
  13.   }
  14.   else
  15.   {
  16. // B..... Return the CWnd based pane size
  17.     if(GetTargetRect(&oRectPane))
  18.     {
  19. #ifdef dCSP_VERTICAL_BAR
  20.       if(m_bVertical == false)
  21.       {
  22. #endif // dCSP_VERTICAL_BAR
  23.         return oRectPane.Width();
  24. #ifdef dCSP_VERTICAL_BAR
  25.       }
  26.       else
  27.       {
  28.         return oRectPane.Height();
  29.       }
  30. #endif // dCSP_VERTICAL_BAR
  31.     }
  32.     else
  33.     {
  34.       return 0;
  35.     }
  36.   }
  37. #endif // dCSP_DIALOG_PROGRESS
  38. }
  39. /*--- START FUNCTION HEADER --------------------------------------------------*/
  40. /* Name          : GetPos                                                     */
  41. /* Role          : Get <m_nRight> value                                       */
  42. /* Type          : public                                                     */
  43. /* Interface     : RETURN (direct value)                                      */
  44. /*                   int : Current <m_nRight> position                        */
  45. /*                 OUTPUT (pointer to value)                                  */
  46. /*                   None                                                     */
  47. /*                 INPUT  (pointer to value, direct/default value)            */
  48. /*                   i_bPercent : Return the position in percent              */
  49. /* Pre-condition : None                                                       */
  50. /* Constraints   : None                                                       */
  51. /* Behavior      : A - Return the current <m_nRight> position                 */
  52. /*                 B - Return the current <m_nRight position in percent       */
  53. /*----------------------------------------------------------------------------*/
  54. /* PROC SetStart                                                              */
  55. /*                                                                            */
  56. /* [IF normal mode]                                                           */
  57. /* : A..... Return the current <m_nRight> position                            */
  58. /* [ELSE]                                                                     */
  59. /* : B..... Return the current <m_nRight> position in percent                 */
  60. /* [ENDIF]                                                                    */
  61. /*----------------------------------------------------------------------------*/
  62. /* If return in percent, 90% gives 23040, divided by 256 (>> 8) returns 90 !  */
  63. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  64. int CSkinProgress::GetPos
  65. ( // Get <m_nRight> value
  66.   BOOL i_bPercent // = false
  67. )
  68. {
  69.   if(i_bPercent == false)
  70.   {
  71. // A..... Return the current <m_nRight> position
  72.     return m_nRight;
  73.   }
  74.   else
  75.   {
  76. // B..... Return the current <m_nRight> position in 8-bits fixed point percent value ('>> 8' to get the 'int' value)
  77.     return (int) ( // 100% *256 to keep a pseudo 8-bits fixed point value (0.00390625 - 1/256 - resolution)
  78.                      (
  79.                          (LONGLONG) // Turns the whole calculation in 64 bits
  80.                          (m_nRight - m_nLower)
  81.                        * 25600
  82.                      )
  83.                    / (m_nUpper - m_nLower)
  84.                  );
  85.   }
  86. }
  87. /*--- START FUNCTION HEADER --------------------------------------------------*/
  88. /* Name          : GetStep                                                    */
  89. /* Role          : Get <m_nStep> value                                        */
  90. /* Type          : public                                                     */
  91. /* Interface     : RETURN (direct value)                                      */
  92. /*                   int : Current <m_nStep> value                            */
  93. /*                 OUTPUT (pointer to value)                                  */
  94. /*                   None                                                     */
  95. /*                 INPUT  (pointer to value, direct/default value)            */
  96. /*                   None                                                     */
  97. /* Pre-condition : None                                                       */
  98. /* Constraints   : None                                                       */
  99. /* Behavior      : A - Return the current <m_nStep> value                     */
  100. /*----------------------------------------------------------------------------*/
  101. /* PROC SetStart                                                              */
  102. /*                                                                            */
  103. /* A..... Return the current <m_nStep> value                                  */
  104. /*----------------------------------------------------------------------------*/
  105. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  106. int CSkinProgress::GetStep
  107. ( // Get <m_nStep> value
  108. )
  109. {
  110. // A..... Return the current <m_nStep> value
  111.   return m_nStep;
  112. }
  113. /*--- START FUNCTION HEADER --------------------------------------------------*/
  114. /* Name          : GetLower                                                   */
  115. /* Role          : Get <m_nLower> value                                       */
  116. /* Type          : public                                                     */
  117. /* Interface     : RETURN (direct value)                                      */
  118. /*                   int : Current <m_nLower> value                           */
  119. /*                 OUTPUT (pointer to value)                                  */
  120. /*                   None                                                     */
  121. /*                 INPUT  (pointer to value, direct/default value)            */
  122. /*                   None                                                     */
  123. /* Pre-condition : None                                                       */
  124. /* Constraints   : None                                                       */
  125. /* Behavior      : A - Return the current <m_nLower> value                    */
  126. /*----------------------------------------------------------------------------*/
  127. /* PROC SetStart                                                              */
  128. /*                                                                            */
  129. /* A..... Return the current <m_nLower> value                                 */
  130. /*----------------------------------------------------------------------------*/
  131. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  132. int CSkinProgress::GetLower
  133. ( // Get <m_nLower> value
  134. )
  135. {
  136. // A..... Return the current <m_nLower> value
  137.   return m_nLower;
  138. }
  139. /*--- START FUNCTION HEADER --------------------------------------------------*/
  140. /* Name          : GetUpper                                                   */
  141. /* Role          : Get <m_nUpper> value                                       */
  142. /* Type          : public                                                     */
  143. /* Interface     : RETURN (direct value)                                      */
  144. /*                   int : Current <m_nUpper> value                           */
  145. /*                 OUTPUT (pointer to value)                                  */
  146. /*                   None                                                     */
  147. /*                 INPUT  (pointer to value, direct/default value)            */
  148. /*                   None                                                     */
  149. /* Pre-condition : None                                                       */
  150. /* Constraints   : None                                                       */
  151. /* Behavior      : A - Return the current <m_nUpper> value                    */
  152. /*----------------------------------------------------------------------------*/
  153. /* PROC SetStart                                                              */
  154. /*                                                                            */
  155. /* A..... Return the current <m_nUpper> value                                 */
  156. /*----------------------------------------------------------------------------*/
  157. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  158. int CSkinProgress::GetUpper
  159. ( // Get <m_nUpper> value
  160. )
  161. {
  162. // A..... Return the current <m_nUpper> value
  163.   return m_nUpper;
  164. }
  165. #ifdef dCSP_SLIDERBAR_METHOD
  166. /*--- START FUNCTION HEADER --------------------------------------------------*/
  167. /* Name          : SetStart                                                   */
  168. /* Role          : None                                                       */
  169. /* Type          : public                                                     */
  170. /* Interface     : RETURN (direct value)                                      */
  171. /*                   int : Previous <m_nLeft> position, 0 if error            */
  172. /*                 OUTPUT (pointer to value)                                  */
  173. /*                   None                                                     */
  174. /*                 INPUT  (pointer to value, direct/default value)            */
  175. /*                   i_nStart   : Select the new start position               */
  176. /*                   i_bDisplay : Display the changes                         */
  177. /* Pre-condition : None                                                       */
  178. /* Constraints   : None                                                       */
  179. /* Behavior      : A - Jump to a specified position                           */
  180. /*                 B - Display the changes                                    */
  181. /*                 C - Return the previous position                           */
  182. /*----------------------------------------------------------------------------*/
  183. /* PROC SetStart                                                              */
  184. /*                                                                            */
  185. /* A..... Jump to a specified <i_nStart> position                             */
  186. /* B..... Display the changes                                                 */
  187. /* C..... Return the previous <m_nLeft> position                              */
  188. /*----------------------------------------------------------------------------*/
  189. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  190. int CSkinProgress::SetStart
  191. ( // Set <m_nLeft> value
  192.   int  i_nStart   // Set a new start position
  193. #ifndef dCSP_TIMED_REDRAW
  194.  ,BOOL i_bDisplay // = true : Display the changes
  195. #endif // dCSP_TIMED_REDRAW
  196. )
  197. {
  198.   // Init
  199.   // Process + Return
  200.   if(IsWindow(GetSafeHwnd()))
  201.   {
  202.     ASSERT((-0x7FFFFFFF <= i_nStart) && (i_nStart <= 0x7FFFFFFF));
  203.     if(i_nStart > m_nUpper)
  204.     { // Avoid problems
  205.       i_nStart = m_nUpper;
  206.     }else{}
  207.     if(i_nStart < m_nLower)
  208.     { // Avoid problems
  209.       i_nStart = m_nLower;
  210.     }else{}
  211.     if(i_nStart > m_nRight)
  212.     { // Avoid problems
  213.       i_nStart = m_nRight;
  214.     }else{}
  215.     m_nPrevLeft = m_nLeft;
  216. // A..... Jump to a specified <i_nEnd> position
  217.     m_nLeft     = i_nStart;
  218. // B..... Display the changes
  219. #ifndef dCSP_TIMED_REDRAW
  220.     if(i_bDisplay != false)
  221.     {
  222.       RefreshPanes();
  223.     }else{}
  224. #endif // dCSP_TIMED_REDRAW
  225. // C..... Return the previous <m_nPrevLeft> position
  226.     return m_nPrevLeft;
  227.   }
  228.   else
  229.   {
  230.     return 0;
  231.   }
  232. }
  233. /*--- START FUNCTION HEADER --------------------------------------------------*/
  234. /* Name          : GetStart                                                   */
  235. /* Role          : Get <m_nLeft> value                                        */
  236. /* Type          : public                                                     */
  237. /* Interface     : RETURN (direct value)                                      */
  238. /*                   int : Current <m_nLeft> position                         */
  239. /*                 OUTPUT (pointer to value)                                  */
  240. /*                   None                                                     */
  241. /*                 INPUT  (pointer to value, direct/default value)            */
  242. /*                   i_bPercent : Return the position in percent              */
  243. /* Pre-condition : None                                                       */
  244. /* Constraints   : None                                                       */
  245. /* Behavior      : A - Return the current <m_nLeft> position                  */
  246. /*                 B - Return the current <m_nLeft> position in percent       */
  247. /*----------------------------------------------------------------------------*/
  248. /* PROC SetStart                                                              */
  249. /*                                                                            */
  250. /* [IF normal mode]                                                           */
  251. /* : A..... Return the current <m_nLeft> position                             */
  252. /* [ELSE]                                                                     */
  253. /* : B..... Return the current <m_nLeft> position in percent                  */
  254. /* [ENDIF]                                                                    */
  255. /*----------------------------------------------------------------------------*/
  256. /* If return in percent, 90% gives 23040, divided by 256 (>> 8) returns 90 !  */
  257. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  258. int CSkinProgress::GetStart
  259. ( // Get <m_nLeft> value
  260.   BOOL i_bPercent // = false
  261. )
  262. {
  263.   if(i_bPercent == false)
  264.   {
  265. // A..... Return the current <m_nLeft> position
  266.     return m_nLeft;
  267.   }
  268.   else
  269.   {
  270. // B..... Return the current <m_nLeft> position in 8-bits fixed point percent value ('>> 8' to get the 'int' value)
  271.     return (int) ( // 100% *256 to keep a pseudo 8-bits fixed point value (0.00390625 - 1/256 - resolution)
  272.                      (
  273.                          (LONGLONG) // Turns the whole calculation in 64 bits
  274.                          (m_nLeft - m_nLower)
  275.                        * 25600
  276.                      )
  277.                    / (m_nUpper - m_nLower)
  278.                  );
  279.   }
  280. }
  281. #endif // dCSP_SLIDERBAR_METHOD
  282. /*--- START FUNCTION HEADER --------------------------------------------------*/
  283. /* Name          : Reset                                                      */
  284. /* Role          :  // Restart the progress bar                               */
  285. /* Type          : public                                                     */
  286. /* Interface     : RETURN (direct value)                                      */
  287. /*                   None                                                     */
  288. /*                 OUTPUT (pointer to value)                                  */
  289. /*                   None                                                     */
  290. /*                 INPUT  (pointer to value, direct/default value)            */
  291. /*                   i_bDisplay : Display the changes                         */
  292. /* Pre-condition : None                                                       */
  293. /* Constraints   : None                                                       */
  294. /* Behavior      : A - Get the creation date and time of the progress bar     */
  295. /*                 B - Set the position of the bar to its beginning           */
  296. /*----------------------------------------------------------------------------*/
  297. /* PROC StepIt                                                                */
  298. /*                                                                            */
  299. /* A..... Get the creation date and time of the progress bar                  */
  300. /* B..... Set the position of the bar to its beginning                        */
  301. /*----------------------------------------------------------------------------*/
  302. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  303. void CSkinProgress::Reset
  304. ( // Restart the progress bar
  305. #ifndef dCSP_TIMED_REDRAW
  306.   BOOL i_bDisplay // = true : Display the changes
  307. #endif // dCSP_TIMED_REDRAW
  308. )
  309. {
  310.   FILETIME sStartTimeFile;
  311.   // Init
  312.   // Process
  313. // A..... Get the creation date and time of the progress bar
  314. //  GetSystemTime(&m_sStartTimeSystem);
  315.   GetLocalTime(&m_sStartTimeSystem);
  316.   SystemTimeToFileTime(&m_sStartTimeSystem, &sStartTimeFile);
  317.   m_nStartTimeLongLong = (
  318.                              (
  319.                                   (LONGLONG) // Turns the whole calculation in 64 bits
  320.                                   sStartTimeFile.dwHighDateTime
  321.                                << 32
  322.                              )
  323.                            | sStartTimeFile.dwLowDateTime
  324.                          );
  325. // B..... Set the position of the bar to its beginning
  326.   SetPos
  327.   (
  328.     m_nLower
  329. #ifndef dCSP_TIMED_REDRAW
  330.    ,i_bDisplay
  331. #endif // dCSP_TIMED_REDRAW
  332.   );
  333. }
  334. // *** TEXT INTERFACE ***
  335. /*--- START FUNCTION HEADER --------------------------------------------------*/
  336. /* Name          : SetText                                                    */
  337. /* Role          : Change the text                                            */
  338. /* Type          : public                                                     */
  339. /* Interface     : RETURN (direct value)                                      */
  340. /*                   BOOL = false : NEVER                                     */
  341. /*                          true  : ALWAYS                                    */
  342. /*                 OUTPUT (pointer to value)                                  */
  343. /*                   None                                                     */
  344. /*                 INPUT  (pointer to value, direct/default value)            */
  345. /*                   i_poStrMessage : New text to display                     */
  346. /*                   i_bDisplay    : Display the changes                      */
  347. /* Pre-condition : None                                                       */
  348. /* Constraints   : None                                                       */
  349. /* Behavior      : A - Set the new text                                       */
  350. /*                 B - Display the new text                                   */
  351. /*----------------------------------------------------------------------------*/
  352. /* PROC SetText                                                               */
  353. /*                                                                            */
  354. /* A..... Set the new text                                                    */
  355. /* B..... Display the changes                                                 */
  356. /*----------------------------------------------------------------------------*/
  357. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  358. BOOL CSkinProgress::SetText
  359. ( // Set the new text
  360.   LPCTSTR i_poStrMessage  // New text to display      
  361. #ifndef dCSP_TIMED_REDRAW
  362.  ,BOOL    i_bDisplay      // = true : Display the changes
  363. #endif // dCSP_TIMED_REDRAW
  364. )
  365.   // Init
  366. // A..... Set the new text
  367.   m_oStrMessage = i_poStrMessage;
  368.   // Process
  369. // B..... Display the changes
  370. #ifndef dCSP_TIMED_REDRAW
  371.   if(i_bDisplay != false)
  372.   {
  373.     RefreshPanes();
  374.   }else{}
  375. #endif // dCSP_TIMED_REDRAW
  376.   // Return
  377.   return true;
  378. }
  379. /*--- START FUNCTION HEADER --------------------------------------------------*/
  380. /* Name          : SetProgress                                                */
  381. /* Role          : Change the completion status text                          */
  382. /* Type          : public                                                     */
  383. /* Interface     : RETURN (direct value)                                      */
  384. /*                   BOOL = false : NEVER                                     */
  385. /*                          true  : ALWAYS                                    */
  386. /*                 OUTPUT (pointer to value)                                  */
  387. /*                   None                                                     */
  388. /*                 INPUT  (pointer to value, direct/default value)            */
  389. /*                   i_nProgress : Any <eProgressSkinText> entry value        */
  390. /*                   i_bDisplay  : Display the changes                        */
  391. /* Pre-condition : None                                                       */
  392. /* Constraints   : None                                                       */
  393. /* Behavior      : A - Set the new progress text                              */
  394. /*                 B - Display the new progress text                          */
  395. /*----------------------------------------------------------------------------*/
  396. /* PROC SetProgress                                                           */
  397. /*                                                                            */
  398. /* A..... Set the new progress text                                           */
  399. /* B..... Display the new progress text                                       */
  400. /*----------------------------------------------------------------------------*/
  401. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  402. BOOL CSkinProgress::SetProgress
  403. ( // Set <m_nProgressText> value
  404.   int  i_nProgress  // Set progress text
  405. #ifndef dCSP_TIMED_REDRAW
  406.  ,BOOL i_bDisplay   // = true : Display the changes
  407. #endif // dCSP_TIMED_REDRAW
  408. )
  409. {
  410.   // Init
  411. // A..... Set the new progress text
  412.   m_nProgressText = i_nProgress;
  413.   // Process
  414. // B..... Display the resized progress bar
  415. #ifndef dCSP_TIMED_REDRAW
  416.   if(i_bDisplay != false)
  417.   {
  418.     RefreshPanes();
  419.   }else{}
  420. #endif // dCSP_TIMED_REDRAW
  421.   // Return
  422.   return true;
  423. }
  424. /*--- START FUNCTION HEADER --------------------------------------------------*/
  425. /* Name          : GetProgress                                                */
  426. /* Role          : Get the completion status message currently used           */
  427. /* Type          : public                                                     */
  428. /* Interface     : RETURN (direct value)                                      */
  429. /*                   int : The current <m_nProgressText> value                */
  430. /*                 OUTPUT (pointer to value)                                  */
  431. /*                   None                                                     */
  432. /*                 INPUT  (pointer to value, direct/default value)            */
  433. /*                   None                                                     */
  434. /* Pre-condition : None                                                       */
  435. /* Constraints   : None                                                       */
  436. /* Behavior      : A - Return the current <m_nProgressText> value             */
  437. /*----------------------------------------------------------------------------*/
  438. /* PROC GetProgress                                                           */
  439. /*                                                                            */
  440. /* A..... Return the current <m_nProgressText> value                          */
  441. /*----------------------------------------------------------------------------*/
  442. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  443. int CSkinProgress::GetProgress
  444. ( // Get <m_nProgressText> value
  445. )
  446. {
  447.   // Init
  448.   // Process
  449.   // Return
  450. // A..... Return the current <m_nProgressText> value
  451.   return m_nProgressText;
  452. }
  453. // *** UPDATE PROCESS ***
  454. /*--- START FUNCTION HEADER --------------------------------------------------*/
  455. /* Name          : RefreshPanes                                               */
  456. /* Role          : None                                                       */
  457. /* Type          : public                                                     */
  458. /* Interface     : RETURN (direct value)                                      */
  459. /*                   BOOL = false : Error while trying to resize the text     */
  460. /*                          true  : Process completed without error           */
  461. /*                 OUTPUT (pointer to value)                                  */
  462. /*                   None                                                     */
  463. /*                 INPUT  (pointer to value, direct/default value)            */
  464. /*                   None                                                     */
  465. /* Pre-condition : None                                                       */
  466. /* Constraints   : None                                                       */
  467. /* Behavior      : A - Get the text pane pointer and dimension                */
  468. /*                 B - Progress pane size calculation                         */
  469. /*                 C - Get optional message length                            */
  470. /*                 D - Compact the text in the remaining space                */
  471. /*                 E - Create the complete information message                */
  472. /*                 F - Modify the progress bar size according of its size     */
  473. /*                 G - Refresh the progress bar                               */
  474. /*                 H - Display the complete information message               */
  475. /*----------------------------------------------------------------------------*/
  476. /* PROC RefreshPanes                                                          */
  477. /*                                                                            */
  478. /* A..... Get the text pane pointer and dimension                             */
  479. /* [IF it is in dialog mode, in a CWnd target pane]                           */
  480. /* : [IF there is a CWnd text pane]                                           */
  481. /* : : AA.... Dialog CWnd text anchor                                         */
  482. /* : [ENDIF]                                                                  */
  483. /* [ELSE]                                                                     */
  484. /* : [IF there is a status bar]                                               */
  485. /* : : AB.... Status bar pane 0                                               */
  486. /* : [ENDIF]                                                                  */
  487. /* [ENDIF]                                                                    */
  488. /* B..... Progress pane size calculation                                      */
  489. /* [IF the progress bar dimension is valid]                                   */
  490. /* : BA.... Set the size of the progress bar to the full width of its pane    */
  491. /* : [IF there is a text pane]                                                */
  492. /* : : BB.... Get text pane's DC                                              */
  493. /* : : [IF text in status bar]                                                */
  494. /* : : : BC.... Calculate the fixed size of the progress bar                  */
  495. /* : : : [IF progress in pane 0 and have a fixed size]                        */
  496. /* : : : : [IF size > 0]                                                      */
  497. /* : : : : : BCA... Calculate the remaining size for the text                 */
  498. /* : : : : [ELSE]                                                             */
  499. /* : : : : : BCB... Calculate the size of the text to use                     */
  500. /* : : : : [ENDIF]                                                            */
  501. /* : : : [ELSE]                                                               */
  502. /* : : : : BCC... Use whole width of pane 0 for the text                      */
  503. /* : : : [ENDIF]                                                              */
  504. /* : : [ELSE]                                                                 */
  505. /* : : : BD.... Use all the space of the CWnd text anchor                     */
  506. /* : : [ENDIF]                                                                */
  507. /* : : [IF text is visble]                                                    */
  508. /* : : : C..... Get optional message length                                   */
  509. /* : : : [IF there is a message to add]                                       */
  510. /* : : : : CA.... Get the length of the cSPT_PERCENT message                  */
  511. /* : : : : [IF the message is at least TIMED]                                 */
  512. /* : : : : : CB.... Get the length of the cSPT_TIMED message                  */
  513. /* : : : : [ENDIF]                                                            */
  514. /* : : : [ENDIF]                                                              */
  515. /* : : : CC.... Get the length of the text to display                         */
  516. /* : : : D..... Compact the text in the remaining space                       */
  517. /* : : : [IF there is no message]                                             */
  518. /* : : : : DA.... Compact the text according to just its length               */
  519. /* : : : [ELSE]                                                               */
  520. /* : : : : DB.... Compact the text minus the length of the cSPT_PERCENT       */
  521. /* : : : [ELSE]                                                               */
  522. /* : : : : DC.... Compact the text minus the length of the cSPT_TIMED         */
  523. /* : : : [ELSE]                                                               */
  524. /* : : : : DD.... Compact the text according to the remaining place           */
  525. /* : : : : [IF the message is at least TIMED]                                 */
  526. /* : : : : : DDA... Try to compact the text with cSPT_TIMED at first          */
  527. /* : : : : [ELSE]                                                             */
  528. /* : : : : : [IF the message is at least TIMED]                               */
  529. /* : : : : : : DDB... Reset the text                                          */
  530. /* : : : : : : DDC... Calculate the length of the three dots                  */
  531. /* : : : : : : DDD... Compact the text minus the three doted cSPT_PERCENT     */
  532. /* : : : : : : DDE... Indicate the message used is cRTP_PERCENT               */
  533. /* : : : : : [ELSE]                                                           */
  534. /* : : : : : : DDF... Indicate the message used is cSPT_TIMED                 */
  535. /* : : : : : [ENDIF]                                                          */
  536. /* : : : : [ENDIF]                                                            */
  537. /* : : : [ELSE]                                                               */
  538. /* : : : : DE.... Compact the text according to just its length               */
  539. /* : : : [ENDIF]                                                              */
  540. /* : : : [IF there is no message]                                             */
  541. /* : : : : DF.... Indicate the text is completely compacted,                  */
  542. /* : : : [ENDIF]                                                              */
  543. /* : : : [IF there is no message]                                             */
  544. /* : : : : DG.... Indicate that there is no text, but perhaps a message       */
  545. /* : : : [ENDIF]                                                              */
  546. /* : : : E..... Create the complete information message                       */
  547. /* : : : [IF there is no message]                                             */
  548. /* : : : : EA.... Add the cSPT_PERCENT message                                */
  549. /* : : : [ELSE]                                                               */
  550. /* : : : : EB.... Add the cSPT_TIMED message                                  */
  551. /* : : : [ELSE]                                                               */
  552. /* : : : : [IF the message is at least TIMED]                                 */
  553. /* : : : : : EC.... Add the cSPT_PERCENT message                              */
  554. /* : : : : [ELSE]                                                             */
  555. /* : : : : : ED.... Add the cSPT_TIMED message                                */
  556. /* : : : : [ENDIF]                                                            */
  557. /* : : : [ENDIF]                                                              */
  558. /* : : : EE.... Scrub the text to delete trailing characters                  */
  559. /* : : : F..... Modify the progress bar size according of its size            */
  560. /* : : : [IF there is no message]                                             */
  561. /* : : : : FA.... Get the length of the complete text plus its margin         */
  562. /* : : : [ENDIF]                                                              */
  563. /* : : : [IF there is no message]                                             */
  564. /* : : : : FB.... Get the maximum length of the text pane                     */
  565. /* : : : [ENDIF]                                                              */
  566. /* : : : FC.... Set the new progress bar rectangle                            */
  567. /* : : : FD.... Move the left side of the progress bar after the text         */
  568. /* : : : FE.... Move the right side of the text to the beginning of the bar   */
  569. /* : : [ENDIF]                                                                */
  570. /* : : FF.... Make sure the previous text is erased                           */
  571. /* : [ENDIF]                                                                  */
  572. /* : G..... Refresh the progress bar                                          */
  573. /* : [IF the progress bar is visible]                                         */
  574. /* : : [IF text is visble]                                                    */
  575. /* : : : GA.... Move the progress bar                                         */
  576. /* : : [ELSE]                                                                 */
  577. /* : : : [IF there is no message]                                             */
  578. /* : : : : GB.... Display the modified progress bar                           */
  579. /* : : : [ENDIF]                                                              */
  580. /* : : [ENDIF]                                                                */
  581. /* : [ENDIF]                                                                  */
  582. /* : H..... Display the complete information message                          */
  583. /* : [IF the progress bar is visible]                                         */
  584. /* : : [IF text is visble]                                                    */
  585. /* : : : [IF there is no message]                                             */
  586. /* : : : : HA.... Text in pane 0 of the status bar                            */
  587. /* : : : [ELSE]                                                               */
  588. /* : : : : HB.... Text in the CWnd text pane                                  */
  589. /* : : : [ENDIF]                                                              */
  590. /* : : [ENDIF]                                                                */
  591. /* : [ENDIF]                                                                  */
  592. /* [ENDIF]                                                                    */
  593. /*----------------------------------------------------------------------------*/
  594. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  595. #define cRTP_BLOCK   (           1 << 0)
  596. #define cRTP_NOTEXT  (cRTP_BLOCK   << 1)
  597. #define cRTP_PERCENT (cRTP_NOTEXT  << 1)
  598. #define cRTP_TIMED   (cRTP_PERCENT << 1)
  599. BOOL CSkinProgress::RefreshPanes
  600. ( // Resize the text pane and the progress bar
  601. {
  602.   CStatusBar* poStatusBar;
  603.   CWnd*       poTextCWnd;
  604.   CFont*      poFontOld;
  605.   CString     oStrMessage;    // Working buffer for m_oStrMessage
  606.   CString     oStrPercent;    // Percent of completion level
  607.   CString     oStrTimed;      // Timed completion level
  608.   int         nProgressText;  // Absolute value of <m_nProgressText>
  609.   int         nLenMessage;    // Len of m_oStrMessage in pixel
  610.   int         nLenPercent;    // Len of oStrPercent in pixel
  611.   int         nLenTimed;      // Len of oStrTimed in pixel
  612.   int         nLenMargin;     // Len of 2*' ' in pixel
  613.   int         nLenCompact;    // Number of character packed
  614.   int         nLenText;       // Allowed len of the text (used to wrap it)
  615.   int         nLenPane;       // 
  616.   int         nLenBlock;      // Flags for computation (text wrapping)
  617.   CRect       oRectText;      // Rect of pane 0 -> oRectPane at the end of the process if m_nPane == 0
  618.   CRect       oRectPane;      // Rect of pane m_nPane, can be also pane 0
  619.   // Init
  620.   poStatusBar   = NULL; // AVOID /W4 -> HA.... *STUPID COMPILER*
  621.   poTextCWnd    = NULL; // AVOID /W4 -> BA.... *STUPID COMPILER*
  622.   nLenPercent   = 0;    // AVOID /W4 -> DB.... *STUPID COMPILER*
  623.   nLenTimed     = 0;    // AVOID /W4 -> DDA... *STUPID COMPILER*
  624.   nLenText      = 0;    // AVOID /W4 -> DE.... *STUPID COMPILER*
  625.   nLenBlock     = 0;    // AVOID /W4 -> F..... *STUPID COMPILER*
  626.   if(m_nProgressText < 0)
  627.   {
  628.     nProgressText = 0 - m_nProgressText; // Make it positive
  629.   }
  630.   else
  631.   {
  632.     nProgressText = m_nProgressText;
  633.   }
  634.   // Process + Return
  635.   if(IsWindow(GetSafeHwnd()))
  636.   {
  637. // A..... Get the text pane pointer and dimension
  638. #ifdef dCSP_DIALOG_PROGRESS
  639.     if(m_poWndProgress != NULL)
  640.     {
  641. // AA.... Dialog CWnd text anchor
  642.       if(m_poWndMessage != NULL)
  643.       {
  644.         poTextCWnd = m_poWndMessage;
  645.         poTextCWnd->GetWindowRect(oRectText);
  646.       }else{}
  647.     }
  648.     else
  649.     {
  650. #endif // dCSP_DIALOG_PROGRESS
  651.       poStatusBar = GetStatusBar();
  652.       if(poStatusBar != NULL)
  653.       {
  654. // AB.... Status bar pane 0
  655.         poTextCWnd = poStatusBar;
  656.         poStatusBar->GetItemRect(0, oRectText);
  657.       }
  658.       else
  659.       {
  660.         return false;
  661.       }
  662. #ifdef dCSP_DIALOG_PROGRESS
  663.     }
  664. #endif // dCSP_DIALOG_PROGRESS
  665. // B..... Progress pane size calculation
  666.     if(GetTargetRect(&oRectPane))
  667.     {
  668. // BA.... Set the size of the progress bar to the full width of its current pane
  669.       nLenPane = oRectPane.Width();
  670.       if(poTextCWnd != NULL)
  671.       {
  672. // BB.... Get text pane's DC
  673.         CClientDC oDC(poTextCWnd);
  674.         poFontOld = oDC.SelectObject(poTextCWnd->GetFont());
  675. #ifdef dCSP_DIALOG_PROGRESS
  676.         if(m_poWndProgress == NULL)
  677.         {
  678. #endif // dCSP_DIALOG_PROGRESS
  679. // BC.... Calculate the fixed size of the progress bar
  680.           if(
  681.                  (m_nPane == 0)
  682.               && (m_nSize != 0)
  683.             )
  684.           { // If the text pane is shared with the progress bar, calculate how much space the text takes up
  685.             if(m_nSize > 0)
  686.             { // Force progress bar size
  687. // BCA... Calculate the remaining size for the text once removed the fixed size of the progress bar
  688.               nLenPane = oRectText.Width() - (m_nSize - 3); // Minus 3 to keep the same spacing with the others ways just below, to resize the text
  689.               nLenText = nLenPane; // Use the remaining space left by the resized progress bar
  690.             }
  691.             else
  692.             { // Resize the progress bar if the text is too long
  693. // BCB... Calculate the size of the text to use (here the whole width of pane 0)
  694.               nLenPane = oRectText.Width() + m_nSize; // *BEWARE* : m_nSize < 0 -> Get the optimal width of the progress bar before resizing it if necessary
  695.               nLenText = oRectText.Width() - 3; // Use the whole space of pane 0, minus 3 to avoid a complete pane 0 disclosure leading to a windows bug
  696.             }
  697.           }
  698.           else
  699.           { // Resize the text if it is too long (even in pane 0 if m_nSize == 0)
  700. // BCC... Use whole width of pane 0 for the text, and what remains for the progress bar
  701.             nLenPane = 0; // Full length for the progress bar, might be resized for pane 0
  702.             nLenText = oRectText.Width() - 3; // Use the whole space of pane 0, minus 3 to avoid a complete pane 0 disclosure leading to a windows bug
  703.           }
  704. #ifdef dCSP_DIALOG_PROGRESS
  705.         }
  706.         else
  707.         {
  708. // BD.... Use all the space of the CWnd text anchor
  709.           if(poTextCWnd != NULL)
  710.           { // Use the whole lenght of the CWnd text pane
  711.             nLenText = oRectText.Width();
  712.           }else{}
  713.         }
  714. #endif // dCSP_DIALOG_PROGRESS
  715.         if(poTextCWnd->IsWindowVisible())
  716.         { // Redraw the text window
  717. // C..... Get optional message length
  718.           if(nProgressText != cSPT_NONE)
  719.           { // Calculate progress text
  720. // CA.... Get the length of the cSPT_PERCENT message
  721.             oStrPercent.Format
  722.             (
  723.               "%d%%",
  724.               (int) // Result on 'int'
  725.               ( // From 0 to 100
  726.                   (
  727.                       (LONGLONG) // Turns the whole calculation in 64 bits
  728.                       (m_nRight - m_nLower)
  729.                     * 100
  730.                   )
  731.                 / (m_nUpper - m_nLower)
  732.               )
  733.             );
  734.             if(m_nProgressText > 0)
  735.             {
  736.               oStrPercent = "(" + oStrPercent + ")";
  737.             }else{}
  738.             oStrPercent = " " + oStrPercent;
  739.             nLenPercent = oDC.GetTextExtent(oStrPercent).cx; // Length of Percent
  740.             if(nProgressText >= cSPT_TIMED)
  741.             {
  742. // CB.... Get the length of the cSPT_TIMED message
  743.               GetTimed(&oStrTimed);
  744.               nLenTimed = oDC.GetTextExtent(oStrTimed).cx; // Length of Timed
  745.             }else{}
  746.           }else{}
  747. // CC.... Get the length of the text to display
  748.           oStrMessage = m_oStrMessage;
  749.           nLenMessage = oDC.GetTextExtent(oStrMessage).cx; // Length of Message
  750.           nLenMargin  = oDC.GetTextExtent(" ").cx << 1; // Text margin
  751. // D..... Compact the text in the remaining space
  752.           // Dompact the text
  753.           switch(nProgressText)
  754.           {
  755.             case cSPT_NONE :
  756. // DA.... Compact the text according to just its length
  757.               nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin);
  758.               break;
  759.             case cSPT_PERCENT :
  760. // DB.... Compact the text according to its length minus the length of the cSPT_PERCENT message
  761.               nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin + nLenPercent);
  762.               break;
  763.             case cSPT_TIMED :
  764. // DC.... Compact the text according to its length minus the length of the cSPT_TIMED message
  765.               nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin + nLenTimed);
  766.               break;
  767.             case cSPT_AUTOSIZE :
  768. // DD.... Compact the text according to the most usable remaining place between the text and the progress bar
  769. // DDA... Try to compact the text with the cSPT_TIMED message at first
  770.               nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin + nLenTimed);
  771.               if(
  772.                      (nLenCompact != 0)
  773.                   && (nLenCompact != oStrMessage.GetLength())
  774.                 )
  775.               { // If the message was compacted, try with Percent
  776. // DDB... Reset the text
  777.                 oStrMessage = m_oStrMessage; // Restore the message
  778. // DDC... Calculate the length of the three dots that will be displayed after the cSPT_PERCENT message
  779.                 // In case of Timed wrapping, use Percent instead, but add "..." to show that the Timed information was wrapped
  780.                 oStrPercent += "...";
  781.                 nLenPercent = oDC.GetTextExtent(oStrPercent).cx; // Length of Percent
  782. // DDD... Compact the text according to its length minus the length of the cSPT_PERCENT message and the added three dots
  783.                 // Dompact the Percent + "..." information
  784.                 nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin + nLenPercent);
  785. // DDE... Indicate the message used is cRTP_PERCENT
  786.                 nLenBlock |= cRTP_PERCENT;
  787.               }
  788.               else
  789.               { // There was enough place to add the Timed information
  790. // DDF... Indicate the message used is cSPT_TIMED
  791.                 nLenBlock |= cRTP_TIMED;
  792.               }
  793.               break;
  794.             default :
  795. // DE.... Compact the text according to just its length
  796.               nLenCompact = CompactText(&oStrMessage, &oDC, nLenText, nLenMargin);
  797.           }
  798. #ifdef dCSP_DIALOG_PROGRESS
  799.           if(m_poWndProgress == NULL)
  800.           {
  801. #endif // dCSP_DIALOG_PROGRESS
  802.             // Block the text wrapping if there is nothing more to wrap
  803.             if(
  804.                    (nLenCompact < 0)
  805.                 || (
  806.                         (oStrMessage.GetLength() <= 4)
  807.                      && (oStrMessage.Right(3) == "...")
  808.                    )
  809.               )
  810.             {
  811. // DF.... Indicate the text is completely compacted, 
  812.               nLenBlock |= cRTP_BLOCK;
  813.             }else{}
  814.             if(oStrMessage == "")
  815.             {
  816. // DG.... Indicate that there is no text, but there might be a message
  817.               nLenBlock |= cRTP_NOTEXT;
  818.             }else{}
  819. #ifdef dCSP_DIALOG_PROGRESS
  820.           }else{}
  821. #endif // dCSP_DIALOG_PROGRESS
  822. // E..... Create the complete information message with the user text and the completion report
  823.           // Add the information
  824.           switch(nProgressText)
  825.           {
  826.             case cSPT_NONE :
  827.               break;
  828.             case cSPT_PERCENT :
  829. // EA.... Add the cSPT_PERCENT message
  830.               oStrMessage += oStrPercent;
  831.               break;
  832.             case cSPT_TIMED :
  833. // EB.... Add the cSPT_TIMED message
  834.               oStrMessage += oStrTimed;
  835.               break;
  836.             case cSPT_AUTOSIZE :
  837.               if((nLenBlock & cRTP_PERCENT) != 0)
  838.               { // If the message was compacted, try with Percent
  839. // EC.... Add the cSPT_PERCENT message
  840.                 oStrMessage += oStrPercent;
  841.               }
  842.               else
  843.               { // There was enough place to add the Timed information
  844. // ED.... Add the cSPT_TIMED message
  845.                 oStrMessage += oStrTimed;
  846.               }
  847.               break;
  848.             default :
  849.               break;
  850.           }
  851. // EE.... Scrub the text to delete trailing characters
  852.           oStrMessage.TrimLeft();
  853. #ifdef dCSP_DIALOG_PROGRESS
  854.           if(m_poWndProgress == NULL)
  855.           {
  856. #endif // dCSP_DIALOG_PROGRESS
  857. // F..... Modify the progress bar size according of its size
  858.             if(m_nPane == 0)
  859.             { // If the text pane is shared with the progress bar, calculate how much space the text takes up to
  860.               nLenMessage = oDC.GetTextExtent(oStrMessage).cx; // Length of the compacted Message
  861.               if(
  862.                      (
  863.                           (
  864.                               (nLenMessage + nLenMargin) // Lenght of Message + Margin
  865.                             > (nLenPane)                 // Lenght of remaining space for text
  866.                           )
  867.                        && (
  868.                                (m_nSize <= 0) // Resize of the progress bar if the text is longer, also used for m_nSize == 0
  869.                             || (
  870.                                     (nLenMessage > 0)
  871.                                  && ((nLenBlock & cRTP_NOTEXT) != 0)
  872.                                )
  873.                           )
  874.                      )
  875.                   || ((nLenBlock & cRTP_BLOCK) != 0) // Avoid paning if the text is wrapped to the max (when only "...'+information remains)
  876.                 )
  877.               { // *IF* the packed text is larger than the space left by the resized progress bar *AND* the resizing of the progress bar is allowed *OR* the wrapping is blocked
  878. // FA.... Get the length of the complete text plus its margin
  879.                 nLenPane = nLenMessage;
  880.                 if(nLenMessage > 0)
  881.                 {
  882.                   nLenPane += nLenMargin;
  883.                 }else{}
  884.               }else{}
  885.               if(nLenPane > oRectText.Width())
  886.               { // Make sure the length will stay positive
  887. // FB.... Get the maximum length of the text pane
  888.                 nLenPane = oRectText.Width();
  889.               }else{}
  890.               if(nLenPane < 2)
  891.               {
  892.                 nLenPane = 2;
  893.               }else{}
  894. // FC.... Set the new progress bar rectangle
  895.               // This is the pane to display
  896.               oRectPane = oRectText;
  897. // FD.... Move the left side of the progress bar to the right of the text
  898.               // Move left edge of the progress bar to the right, to leave some place for the text
  899.               oRectPane.left = nLenPane;
  900. // FE.... Move the right side of the text to the beginning of the bar
  901.               oRectText.right = nLenPane;
  902.             }else{}
  903. #ifdef dCSP_DIALOG_PROGRESS
  904.           }else{}
  905. #endif // dCSP_DIALOG_PROGRESS
  906.         }else{}
  907. // FF.... Make sure the previous text is erased, so display at least a space character
  908.         if(oStrMessage == "")
  909.         {
  910.           oStrMessage = " "; // If no text, force the pane to be cleared
  911.         }else{}
  912.         // Release DC
  913.         oDC.SelectObject(poFontOld);
  914.       }else{}
  915.       if(IsWindowVisible())
  916.       {
  917. // G..... Refresh the progress bar
  918.         if(
  919.                (m_oRectPane != oRectPane)
  920.             && ( // Avoid pane disclosure, so that you can reopen the window and the pane won't stay closed
  921.                     (oRectPane.Width()  > 2)
  922.                  && (oRectPane.Height() > 2)
  923.                )
  924.           )
  925.         {
  926. // GA.... Move the progress bar
  927.           m_oRectPane = oRectPane; // The new progress rectangle
  928.           MoveWindow(&oRectPane);
  929.           Invalidate(); // Display the progress bar on its new position
  930.         }
  931.         else
  932.         {
  933.           if(UpdateProgress())
  934.           {
  935. // GB.... Display the modified progress bar
  936.             Invalidate(); // Display the changes
  937.           }else{}
  938.         }
  939.       }else{}
  940.       if(poTextCWnd != NULL)
  941.       {
  942.         if(m_oStrPrevMessage != oStrMessage)
  943.         { // If the new message has changed from the previous, set it
  944. // H..... Display the complete information message
  945. #ifdef dCSP_DIALOG_PROGRESS
  946.           if(m_poWndProgress == NULL)
  947.           {
  948. #endif // dCSP_DIALOG_PROGRESS
  949. // HA.... Text in pane 0 of the status bar
  950.             poStatusBar->SetPaneText(0, oStrMessage); // Force text in pane 0
  951.             m_oStrPrevMessage = oStrMessage;
  952. #ifdef dCSP_DIALOG_PROGRESS
  953.           }
  954.           else
  955.           {
  956.             if(m_poWndMessage != NULL)
  957.             {
  958. // HB.... Text in the CWnd text pane
  959.               m_poWndMessage->SetWindowText(oStrMessage);
  960.               m_oStrPrevMessage = oStrMessage;
  961.             }else{}
  962.           }
  963. #endif // dCSP_DIALOG_PROGRESS
  964.         }else{}
  965.       }else{}
  966.       return true;
  967.     }
  968.     else
  969.     {
  970.       return false;
  971.     }
  972.   }
  973.   else
  974.   {
  975.     return false;
  976.   }
  977. }
  978. // *** DATA PROCESS ***
  979. /*--- START FUNCTION HEADER --------------------------------------------------*/
  980. /* Name          : CompactText                                                */
  981. /* Role          : None                                                       */
  982. /* Type          : PROTECTED                                                  */
  983. /* Interface     : RETURN (direct value)                                      */
  984. /*                   int : > 0 = Number of character packed                   */
  985. /*                           0 = Nothing packed                               */
  986. /*                         < 0 = Pack blocked                                 */
  987. /*                 OUTPUT (pointer to value)                                  */
  988. /*                   io_poString  : Packed and three-doted text               */
  989. /*                 INPUT  (pointer to value, direct/default value)            */
  990. /*                   io_poString  : Text to compact                           */
  991. /*                   i_poDC       : Target DC                                 */
  992. /*                   i_nMaxWidth  : Width in pixel the text should fits in    */
  993. /*                   i_nAddWidth  : Additional width for some purposes        */
  994. /* Pre-condition : None                                                       */
  995. /* Constraints   : None                                                       */
  996. /* Behavior      : A - Get the current DC                                     */
  997. /*                 B - Remove any ending dots                                 */
  998. /*                 C - Verify there is something to do                        */
  999. /*                 D - Check if the text can be compacted                     */
  1000. /*                 E - Compact the string                                     */
  1001. /*                 F - Add the three dots at the end of the string            */
  1002. /*----------------------------------------------------------------------------*/
  1003. /* PROC CompactText                                                           */
  1004. /*                                                                            */
  1005. /* [IF a string is provided to process]                                       */
  1006. /* : [IF no DC specified]                                                     */
  1007. /* : : A..... Get the current DC                                              */
  1008. /* : [ENDIF]                                                                  */
  1009. /* : [IF there is ending dots]                                                */
  1010. /* : : B..... Remove any ending dots                                          */
  1011. /* : [ENDIF]                                                                  */
  1012. /* : C..... Verify there is something to do                                   */
  1013. /* : [IF something have to be done]                                           */
  1014. /* : : D..... Check if the text can be compacted                              */
  1015. /* : : [IF the text can be compacted]                                         */
  1016. /* : : : E..... Compact the string as long as it does'nt fit                  */
  1017. /* : : : D..... Add the three dots at the end of the string                   */
  1018. /* : : [ENDIF]                                                                */
  1019. /* : [ENDIF]                                                                  */
  1020. /* [ENDIF]                                                                    */
  1021. /*----------------------------------------------------------------------------*/
  1022. /* Quite easy and fun to use... No trailing blank characters !                */
  1023. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  1024. int CSkinProgress::CompactText
  1025. (
  1026.   CString* io_poString, 
  1027.   CDC*     i_poDC,
  1028.   int      i_nMaxWidth,
  1029.   int      i_nAddWidth
  1030. )
  1031. {
  1032.   int     nLenString;
  1033.   int     nLenDots;
  1034.   int     nCountChar;
  1035.   TCHAR   nFirstChar;
  1036.   
  1037.   // Init
  1038.   if(io_poString != NULL)
  1039.   {
  1040.     if(i_poDC == NULL)
  1041.     { // If no target device context provided, use the current one
  1042. // A..... Get the current DC
  1043.       CClientDC oDC(this);
  1044.       i_poDC = &oDC;
  1045.     }else{}
  1046.     nLenString = io_poString->GetLength();
  1047.     if(io_poString->Right(3) == "...")
  1048.     {
  1049. // B..... Remove any ending dots
  1050.       nLenString  -= 3;
  1051.       *io_poString = io_poString->Left(nLenString);
  1052.     }else{}
  1053.   // Process + Return
  1054. // C..... Verify there is something to do
  1055.     if(
  1056.            (nLenString == 0) // No text
  1057.         || ( // Enough space for the unmodified text and the margin
  1058.                 (i_poDC->GetTextExtent(*io_poString, nLenString).cx + i_nAddWidth)
  1059.              <= i_nMaxWidth
  1060.            )
  1061.       )
  1062.     {
  1063.       return 0;
  1064.     }
  1065.     else
  1066.     {
  1067. // D..... Check if the three doted first character is longer than the whole string (VERY few characters only)
  1068.       nFirstChar = io_poString->GetAt(0);
  1069.       nLenDots   = i_poDC->GetTextExtent(anThreeDots, sizeof(anThreeDots)).cx;
  1070.       if(
  1071.              i_poDC->GetTextExtent(*io_poString, nLenString).cx
  1072.           <= (i_poDC->GetTextExtent(&nFirstChar, sizeof(nFirstChar)).cx + nLenDots)
  1073.         )
  1074.       {
  1075.         return (0 - nLenString);
  1076.       }
  1077.       else
  1078.       {
  1079.         nCountChar = 0; 
  1080.         
  1081. // E..... Compact the string as long as it does'nt fit in the desired space
  1082.         while( // As long as something remains *AND* the stuff is bigger than the allowed space
  1083.                   (nLenString > 1) // Leading character must remain at least
  1084.                && (
  1085.                       (i_poDC->GetTextExtent(*io_poString, nLenString).cx + (nLenDots >> 1) + i_nAddWidth)
  1086.                     > i_nMaxWidth
  1087.                   )
  1088.              )
  1089.         {
  1090.           *io_poString = io_poString->Left(io_poString->GetLength() - 1); // BEWARE : Modify the original object
  1091.           io_poString->TrimRight();               // Kill spaces 
  1092.           nLenString  = io_poString->GetLength(); // Get the real length after trim
  1093.           nCountChar += 1;
  1094.         }
  1095. // F..... Add the three dots at the end of the string
  1096.         *io_poString += anThreeDots;
  1097.         return nCountChar;
  1098.       }
  1099.     }
  1100.   }
  1101.   else
  1102.   {
  1103.     return 0;
  1104.   }
  1105. }
  1106. /*--- START FUNCTION HEADER --------------------------------------------------*/
  1107. /* Name          : GetTimed                                                   */
  1108. /* Role          : Get a complete and accurate timed text message             */
  1109. /* Type          : PROTECTED                                                  */
  1110. /* Interface     : RETURN (direct value)                                      */
  1111. /*                   BOOL = false : NEVER                                     */
  1112. /*                          true  : ALWAYS                                    */
  1113. /*                 OUTPUT (pointer to value)                                  */
  1114. /*                   o_poTimed : Timed message                                */
  1115. /*                 INPUT  (pointer to value, direct/default value)            */
  1116. /*                   None                                                     */
  1117. /* Pre-condition : None                                                       */
  1118. /* Constraints   : None                                                       */
  1119. /* Behavior      : A - Get current date and time                              */
  1120. /*                 B - Add start date in timed message if necessary           */
  1121. /*                 C - Add start time int timed message                       */
  1122. /*                 D - Add the time elapsed from start                        */
  1123. /*                 E - Add the current progress completion status             */
  1124. /*                 F - Add the remaining progress completion                  */
  1125. /*                 G - Get the remaining time before end                      */
  1126. /*                 H - Display the expected date and time of the end          */
  1127. /*----------------------------------------------------------------------------*/
  1128. /* PROC GetTimed                                                              */
  1129. /*                                                                            */
  1130. /* A..... Get current date and time                                           */
  1131. /* B..... Add start date in timed message if necessary                        */
  1132. /* C..... Add start time int timed message                                    */
  1133. /* D..... Add the time elapsed from start                                     */
  1134. /* E..... Add the current progress completion status                          */
  1135. /* F..... Add the remaining progress completion                               */
  1136. /* G..... Get the remaining time before end                                   */
  1137. /* H..... Display the expected date and time of the end                       */
  1138. /*----------------------------------------------------------------------------*/
  1139. /* I will in the next update recode a bit this mess because if the progress   */
  1140. /* is not linear, the end time is far from being accurate. You might see that */
  1141. /* when grabing the bottom-right corner of the main window to resize it. It   */
  1142. /* block the progress, but the timer continue to elapse, so the end time      */
  1143. /* grows fast. Then, once you release the corner, the progress restart, but   */
  1144. /* then the time to finish is quite short so the remaining time decrease very */
  1145. /* fast, instead to readapt to show a 1:1 linear timer till the end.          */
  1146. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  1147. BOOL CSkinProgress::GetTimed
  1148. (
  1149.   CString* o_poTimed
  1150. )
  1151. {
  1152.   CString       oStrTempo;
  1153.   unsigned long nTempo;
  1154.   SYSTEMTIME    sCurrentTimeSystem;
  1155.   SYSTEMTIME    sTempoTimeSystem;
  1156.   FILETIME      sTempoTimeFile;
  1157.   LONGLONG      nTempoTimeLongLong;
  1158.   LONGLONG      nDeltaTimeLongLong;
  1159.   // Init
  1160. // A..... Get current date and time
  1161. //  GetSystemTime(&nCurrentTime);
  1162.   GetLocalTime(&sTempoTimeSystem);
  1163.   sCurrentTimeSystem = sTempoTimeSystem; // For the Date of End and Time of End
  1164.   SystemTimeToFileTime(&sTempoTimeSystem, &sTempoTimeFile);
  1165.   nTempoTimeLongLong = (
  1166.                            (
  1167.                                 (LONGLONG) // Turns the whole calculation in 64 bits
  1168.                                 sTempoTimeFile.dwHighDateTime
  1169.                              << 32
  1170.                            )
  1171.                          | sTempoTimeFile.dwLowDateTime
  1172.                        );
  1173.   // Process
  1174.   *o_poTimed = " ";
  1175.   if(m_nProgressText > 0)
  1176.   {
  1177.     *o_poTimed += "(";
  1178.   }else{}
  1179. // B..... Add start date in timed message if necessary
  1180.   if( // *IF* Date of Start is different from Current Date
  1181.          (sTempoTimeSystem.wDay   != m_sStartTimeSystem.wDay)   // Check what change first, days
  1182.       || (sTempoTimeSystem.wMonth != m_sStartTimeSystem.wMonth)
  1183.       || (sTempoTimeSystem.wYear  != m_sStartTimeSystem.wYear)
  1184.     )
  1185.   { // Date of Start
  1186.     oStrTempo.Format
  1187.     (
  1188.       "%04d/%02d/%02d/%02d ",
  1189.       m_sStartTimeSystem.wYear,
  1190.       m_sStartTimeSystem.wMonth,
  1191.       m_sStartTimeSystem.wDay,
  1192.       m_sStartTimeSystem.wDayOfWeek + 1
  1193.     );
  1194.     *o_poTimed += oStrTempo;
  1195.   }else{}
  1196. // C..... Add start time in timed message
  1197.   // Time of Start
  1198.   oStrTempo.Format
  1199.   (
  1200.     "%02d:%02d:%02d - ",
  1201.     m_sStartTimeSystem.wHour,
  1202.     m_sStartTimeSystem.wMinute,
  1203.     m_sStartTimeSystem.wSecond
  1204.   );
  1205.   *o_poTimed += oStrTempo;
  1206. // D..... Add the time elapsed from start
  1207.   // Calculate time from start
  1208.   nDeltaTimeLongLong            = nTempoTimeLongLong - m_nStartTimeLongLong;
  1209.   nTempoTimeLongLong            = nDeltaTimeLongLong; // Keep nDeltaTimeLongLong safe
  1210.   sTempoTimeFile.dwLowDateTime  = (DWORD) nTempoTimeLongLong;
  1211.   sTempoTimeFile.dwHighDateTime = (DWORD) ((LONGLONG) nTempoTimeLongLong >> 32);
  1212.   FileTimeToSystemTime(&sTempoTimeFile, &sTempoTimeSystem);
  1213.   sTempoTimeSystem.wYear       -= 1600; // Starts from 1601, so if 1601 you get year 1
  1214.   // Day from start
  1215.   if(
  1216.          (sTempoTimeSystem.wYear  != 1)
  1217.       || (sTempoTimeSystem.wMonth != 1)
  1218.       || (sTempoTimeSystem.wDay   != 1)
  1219.     )
  1220.   { // If not the same day, calculate the number of days elapsed from start
  1221.     nTempo = (unsigned long) (
  1222.                                  nTempoTimeLongLong // Already in 64 bits, so the calculation will be done in 64 bits
  1223.                                / (nDeltaTimeLongLong / 864000000000) // Number of days given in 100 nanosecond (0.1us)
  1224.                              );
  1225.     if(nTempo != 0)
  1226.     { // If there is some days elapsed
  1227.       oStrTempo.Format("%d:", nTempo);
  1228.       *o_poTimed += oStrTempo;
  1229.     }else{}
  1230.   }else{}
  1231.   // Time from start
  1232.   oStrTempo.Format
  1233.   (
  1234.     "%02d:%02d:%02d - ",
  1235.     sTempoTimeSystem.wHour,
  1236.     sTempoTimeSystem.wMinute,
  1237.     sTempoTimeSystem.wSecond
  1238.   );
  1239.   *o_poTimed += oStrTempo;
  1240. // E..... Add the current progress completion status
  1241.   // Elapsed percent
  1242. #ifndef dCSP_SLIDERBAR_METHOD
  1243.   nTempo = (int) ( // 100% *256 to keep a pseudo 8-bits fixed point value (0.00390625 - 1/256 - resolution)
  1244.                      (
  1245.                          (LONGLONG) // Turns the whole calculation in 64 bits
  1246.                          (m_nRight - m_nLower)
  1247.                        * 25600
  1248.                      )
  1249.                    / (m_nUpper - m_nLower)
  1250.                  );
  1251. #else
  1252.   nTempo = (int) ( // 100% *256 to keep a pseudo 8-bits fixed point value (0.00390625 - 1/256 - resolution)
  1253.                      (
  1254.                          (LONGLONG) // Turns the whole calculation in 64 bits
  1255.                          (m_nRight -  m_nLeft)
  1256.                        * 25600
  1257.                      )
  1258.                    / (m_nUpper - m_nLower)
  1259.                  );
  1260. #endif // dCSP_SLIDERBAR_METHOD
  1261.   oStrTempo.Format("%d%% / ", nTempo >> 8); // '>> 8' == '/ 256'
  1262.   *o_poTimed += oStrTempo;
  1263. // F..... Add the remaining progress completion
  1264.   // Remaining percent
  1265.   oStrTempo.Format("%d%% - ", 100 - (nTempo >> 8));
  1266.   *o_poTimed += oStrTempo;
  1267. // G..... Get the remaining time before end
  1268.   // Remaining time
  1269.   if(nTempo == 0)
  1270.   { // Avoid zero divide
  1271.     nTempoTimeLongLong = 0; // No more time to wait
  1272.   }
  1273.   else
  1274.   {
  1275.     nTempoTimeLongLong = ((nDeltaTimeLongLong * 25600) / nTempo) - nDeltaTimeLongLong; // The remaining time, 100% - Elasped (100% = Elapsed / Percent)
  1276.   }
  1277.   sTempoTimeFile.dwLowDateTime  = (DWORD) nTempoTimeLongLong;
  1278.   sTempoTimeFile.dwHighDateTime = (DWORD) ((LONGLONG) nTempoTimeLongLong >> 32);
  1279.   FileTimeToSystemTime(&sTempoTimeFile, &sTempoTimeSystem);
  1280.   sTempoTimeSystem.wYear       -= 1600;
  1281.   // Day to end
  1282.   if(
  1283.          (sTempoTimeSystem.wDay   != 1) // Check what change first, days
  1284.       || (sTempoTimeSystem.wMonth != 1)
  1285.       || (sTempoTimeSystem.wYear  != 1)
  1286.     )
  1287.   { // If not the same day, calculate the number of days elapsed from start
  1288.     nTempo = (unsigned long) (nDeltaTimeLongLong / 864000000000); // Number of days given in 100 nanosecond (0.1us)
  1289.     if(nTempo != 0)
  1290.     { // If there is some days elapsed
  1291.       oStrTempo.Format("%d:", nTempo);
  1292.       *o_poTimed += oStrTempo;
  1293.     }else{}
  1294.   }else{}
  1295.   // Time to end
  1296.   oStrTempo.Format("%02d:%02d:%02d - ", sTempoTimeSystem.wHour, sTempoTimeSystem.wMinute, sTempoTimeSystem.wSecond);
  1297.   *o_poTimed += oStrTempo;
  1298. // H..... Display the expected date and time of the end
  1299.   // Date of End
  1300.   if(nTempo == 0)
  1301.   { // Avoid zero divide
  1302.     nTempoTimeLongLong = m_nStartTimeLongLong + nDeltaTimeLongLong; // Current time, Delta = Tempo - Start, see above
  1303.   }
  1304.   else
  1305.   {
  1306.     nTempoTimeLongLong = m_nStartTimeLongLong + ((nDeltaTimeLongLong * 25600) / nTempo); // Start + 100% (100% = Elapsed / Percent)
  1307.   }
  1308.   sTempoTimeFile.dwLowDateTime  = (DWORD) nTempoTimeLongLong;
  1309.   sTempoTimeFile.dwHighDateTime = (DWORD) ((LONGLONG) nTempoTimeLongLong >> 32);
  1310.   FileTimeToSystemTime(&sTempoTimeFile, &sTempoTimeSystem);
  1311.   if(
  1312.          (sTempoTimeSystem.wYear  != sCurrentTimeSystem.wYear)
  1313.       && (sTempoTimeSystem.wMonth != sCurrentTimeSystem.wMonth)
  1314.       && (sTempoTimeSystem.wDay   != sCurrentTimeSystem.wDay)
  1315.     )
  1316.   {
  1317.     oStrTempo.Format
  1318.     (
  1319.       "%04d/%02d/%02d/%02d ",
  1320.       sTempoTimeSystem.wYear,
  1321.       sTempoTimeSystem.wMonth,
  1322.       sTempoTimeSystem.wDay,
  1323.       sTempoTimeSystem.wDayOfWeek + 1
  1324.     );
  1325.     *o_poTimed += oStrTempo;
  1326.   }else{}
  1327.   // Time of End
  1328.   oStrTempo.Format
  1329.   (
  1330.     "%02d:%02d:%02d",
  1331.     sTempoTimeSystem.wHour,
  1332.     sTempoTimeSystem.wMinute,
  1333.     sTempoTimeSystem.wSecond
  1334.   );
  1335.   *o_poTimed += oStrTempo;
  1336.   if(m_nProgressText > 0)
  1337.   {
  1338.     *o_poTimed += ")";
  1339.   }else{}
  1340.   // Return
  1341.   return true;
  1342. }
  1343. // *** UPDATE PROCESS ***
  1344. /*--- START FUNCTION HEADER --------------------------------------------------*/
  1345. /* Name          : UpdateProgress                                             */
  1346. /* Role          : None                                                       */
  1347. /* Type          : PROTECTED                                                  */
  1348. /* Interface     : RETURN (direct value)                                      */
  1349. /*                   BOOL = false : The progress bar has not changed          */
  1350. /*                          true  : The display needs to be updated           */
  1351. /*                 OUTPUT (pointer to value)                                  */
  1352. /*                   o_poRectPaint : Return the progress bar client rect      */
  1353. /*                 INPUT  (pointer to value, direct/default value)            */
  1354. /*                   None                                                     */
  1355. /* Pre-condition : None                                                       */
  1356. /* Constraints   : None                                                       */
  1357. /* Behavior      : A - Get the current progress bar dimension                 */
  1358. /*                 B - Set variables for calculation                          */
  1359. /*                 C - Calculate the elements' position in pixel              */
  1360. /*                 D - Reverse the left and right element position            */
  1361. /*                 E - On progress bar change, return the need to refresh it  */
  1362. /*----------------------------------------------------------------------------*/
  1363. /* PROC UpdateProgress                                                        */
  1364. /*                                                                            */
  1365. /* A..... Get the current progress bar dimension                              */
  1366. /* B..... Set variables for calculation                                       */
  1367. /* C..... Calculate the elements' position                                    */
  1368. /*   CA.... Get the position of the end of the progress bar                   */
  1369. /*   CB.... Get the length in pixel of the prgress bar                        */
  1370. /*   CC.... Get the position of the left end of the progress bar              */
  1371. /*   [IF the lenght of the progress bar exceed the end position]              */
  1372. /*   : CD... Reset the length of the progress bar to its maximum size         */
  1373. /*   [ENDIF]                                                                  */
  1374. /*   [IF the left element is located after the right element]                 */
  1375. /*   : CE... Set the start before the end                                     */
  1376. /*   [ENDIF]                                                                  */
  1377. /* [IF the display is reversed]                                               */
  1378. /* : D..... Reverse the left and right elements position                      */
  1379. /* [ENDIF]                                                                    */
  1380. /* E..... On progress bar change, return the need to refresh it               */
  1381. /*----------------------------------------------------------------------------*/
  1382. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  1383. BOOL CSkinProgress::UpdateProgress
  1384. ( // Update of the progress bar values
  1385.   CRect* o_poRectPaint // = NULL
  1386. {
  1387.   CRect    oRectPaint;
  1388. #ifdef dCSP_SLIDERBAR_METHOD
  1389.   int      nCurrentPos; // Pos of the current calculated position
  1390. #endif // dCSP_SLIDERBAR_METHOD
  1391.   int      nLenPos;
  1392.   int      nStepPos;
  1393.   // Init
  1394.   // Init
  1395. // A..... Get the current progress bar dimension
  1396.   GetClientRect(&oRectPaint); // the CStatic currently being repaint
  1397.   if(o_poRectPaint != NULL)
  1398.   {
  1399.     *o_poRectPaint = oRectPaint;
  1400.   }else{}
  1401. //  GetParent()->GetClientRect(&rcStatusBar); // For old test purpose, just stay here to recall me the syntax
  1402. //  GetParent()->ClientToScreen(&rcStatusBar);
  1403. //  ScreenToClient(&rcStatusBar);
  1404. // B...... Set variables for calculation
  1405. #ifdef dCSP_VERTICAL_BAR
  1406.   if(m_bVertical == false)
  1407.   { // Horizontal bar
  1408. #endif // dCSP_VERTICAL_BAR
  1409.     nLenPos  = oRectPaint.Width();
  1410.     nStepPos = m_nBmpWidth;
  1411. #ifdef dCSP_VERTICAL_BAR
  1412.   }
  1413.   else
  1414.   { // Vertical bar
  1415.     nLenPos  = oRectPaint.Height();
  1416.     nStepPos = m_nBmpHeight;
  1417.   }
  1418. #endif // dCSP_VERTICAL_BAR
  1419.   // Process
  1420.   // m_nEndAff ----------------------------------------------------,
  1421.   // m_nRightAff ----------------------------,                     |
  1422.   // m_nLeftAff ---------,                   | m_nBmpWidth --,-,   |
  1423.   //                     |<------ bar ------>|               | |   |
  1424.   // ProgressBar = [ : : :(:=:=:=:=:=:=:=:=:=:): : : : : : : : : : : ]
  1425.   //               | |                                           | |
  1426.   //               | '- 0% --------- m_nRightAff --------- 100% -+-'
  1427.   //               '- 0% --------- m_nLeftAff ------------ 100% -'
  1428. // C..... Calculate the elements' position in pixel
  1429. // CA.... Get the position of the end of the progress bar
  1430.   m_nEndAff   = nLenPos - nStepPos; // Position of the cSPB_RIGHT element
  1431. // CB.... Get the position of the right end of the progress bar
  1432.   m_nRightAff = (int) ( // Position of the cSPB_RIGHT element
  1433.                           (
  1434.                               (LONGLONG) // Turns the whole calculation in 64 bits
  1435.                               (m_nRight - m_nLower)
  1436.                             * (nLenPos  - (nStepPos << 1))
  1437.                           )
  1438.                         / (m_nUpper - m_nLower)
  1439.                       ) + nStepPos;
  1440. #ifdef dCSP_SLIDERBAR_METHOD
  1441. // CC.... Get the position of the left end of the progress bar
  1442.   m_nLeftAff  = (int) ( // Position of the cSPB_LEFT element
  1443.                           (
  1444.                               (LONGLONG) // Turns the whole calculation in 64 bits
  1445.                               (m_nLeft - m_nLower)
  1446.                             * (nLenPos - (nStepPos << 1)) 
  1447.                           )
  1448.                         / (m_nUpper - m_nLower)
  1449.                       );
  1450. #endif // dCSP_SLIDERBAR_METHOD
  1451.   if(m_nRightAff > m_nEndAff)
  1452.   { // Cannot be be bigger than the bar itselves
  1453. // CD.... Reset the length of the progress bar to its maximum size
  1454.     m_nRightAff = m_nEndAff;
  1455.   }else{}
  1456. #ifdef dCSP_SLIDERBAR_METHOD
  1457.   if(m_nLeftAff > (m_nRightAff - nStepPos))
  1458.   { // Cannot be be bigger than the bar itselves
  1459. // CE.... Set the start before the end
  1460.     m_nLeftAff = m_nRightAff - nStepPos;
  1461.   }else{}
  1462. #endif // dCSP_SLIDERBAR_METHOD
  1463. // D..... Reverse the left and right elements position
  1464. #ifdef dCSP_SLIDERBAR_METHOD
  1465.   if(m_bReverse != false)
  1466.   { // If reversing the display, just invert the positions in dCSP_SLIDERBAR_METHOD mode, TRICKY ISN'T IT !
  1467.     nCurrentPos = nLenPos - m_nRightAff - nStepPos; // Will become m_nLeftAff
  1468.     m_nRightAff = nLenPos - m_nLeftAff  - nStepPos; // m_nLeftAff  becomes m_nRightAff
  1469.     m_nLeftAff  = nCurrentPos;                      // m_nRightAff becomes m_nLeftAff
  1470.   }else{}
  1471. #endif // dCSP_SLIDERBAR_METHOD
  1472.   // Return
  1473. // E..... On progress bar change, return the need to refresh it
  1474.   if(
  1475.          (m_nPrevEndAff   != m_nEndAff)
  1476.       || (m_nPrevRightAff != m_nRightAff)
  1477. #ifdef dCSP_SLIDERBAR_METHOD
  1478.       || (m_nPrevLeftAff  != m_nLeftAff)
  1479. #endif // dCSP_SLIDERBAR_METHOD
  1480.     )
  1481.   {
  1482.     return true;
  1483.   }
  1484.   else
  1485.   {
  1486.     return false;
  1487.   }
  1488. }
  1489. // *** WINDOWS MAPPED PROCESSING ***
  1490. /*--- START FUNCTION HEADER --------------------------------------------------*/
  1491. /* Name          : OnEraseBkgnd                                               */
  1492. /* Role          : Erase the background (with a filled rect) before [OnPaint] */
  1493. /* Type          : PROTECTED                                                  */
  1494. /* Interface     : RETURN (direct value)                                      */
  1495. /*                   None                                                     */
  1496. /*                 OUTPUT (pointer to value)                                  */
  1497. /*                   None                                                     */
  1498. /*                 INPUT  (pointer to value, direct/default value)            */
  1499. /*                   i_poDC : current DC                                      */
  1500. /* Pre-condition : None                                                       */
  1501. /* Constraints   : None                                                       */
  1502. /* Behavior      : A - Erase the background                                   */
  1503. /*                 B - Resize and display the text                            */
  1504. /*----------------------------------------------------------------------------*/
  1505. /* PROC OnEraseBkgnd                                                          */
  1506. /*                                                                            */
  1507. /* A..... Erase the background                                                */
  1508. /* B..... Resize and display the text                                         */
  1509. /*----------------------------------------------------------------------------*/
  1510. /* This function is called prior to [OnSizing] because we cannot over-ride    */
  1511. /* the status bar [OnSizing] function from here. And we also cannot do it for */
  1512. /* the main window also, which is the parent window of the status bar. So, in */
  1513. /* order to resize the text in real-time while it is moved/resized, just call */
  1514. /* the [RefreshPanes] function when the status bar is asked to be erased.     */
  1515. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  1516. BOOL CSkinProgress::OnEraseBkgnd
  1517. (
  1518.   CDC* i_poDC
  1519. )
  1520. {
  1521.   BOOL bResult;
  1522.   // Init
  1523. // A..... Erase the background
  1524.   bResult = CStatic::OnEraseBkgnd(i_poDC);
  1525.   // Process
  1526. // B..... Resize and display the text
  1527.   RefreshPanes();
  1528.   // Return
  1529.   return bResult;
  1530. }
  1531. BEGIN_MESSAGE_MAP(CSkinProgress, CStatic)
  1532. //{{AFX_MSG_MAP(CSkinProgress)
  1533.   ON_WM_ERASEBKGND()
  1534. ON_WM_PAINT()
  1535. ON_WM_TIMER()
  1536. //}}AFX_MSG_MAP
  1537. END_MESSAGE_MAP()
  1538. /////////////////////////////////////////////////////////////////////////////
  1539. // CSkinProgress message handlers
  1540. /*--- START FUNCTION HEADER --------------------------------------------------*/
  1541. /* Name          : OnPaint                                                    */
  1542. /* Role          : Repaint the progress bar according to its new size         */
  1543. /* Type          : PROTECTED                                                  */
  1544. /* Interface     : RETURN (direct value)                                      */
  1545. /*                   None                                                     */
  1546. /*                 OUTPUT (pointer to value)                                  */
  1547. /*                   None                                                     */
  1548. /*                 INPUT  (pointer to value, direct/default value)            */
  1549. /*                   None                                                     */
  1550. /* Pre-condition : None                                                       */
  1551. /* Constraints   : None                                                       */
  1552. /* Behavior      : A - Update values, get dimension and check refresh         */
  1553. /*                 B - Set variables for calculation                          */
  1554. /*                 C - Draw the progress bar                                  */
  1555. /*                 D - Display the progress bar                               */
  1556. /*----------------------------------------------------------------------------*/
  1557. /* PROC OnPaint                                                               */
  1558. /*                                                                            */
  1559. /* A..... Update values, get dimension and check refresh                      */
  1560. /* [IF the progress bar needs to be refreshed]                                */
  1561. /* : B..... Set variables for calculation                                     */
  1562. /* : C..... Draw the progress bar                                             */
  1563. /* : [IF the progress bar size is different from the previous time]           */
  1564. /* : : CA.... Redraw the complete bar from scratch                            */
  1565. /* : : [IF the progress bar was existing]                                     */
  1566. /* : : : CAA... Delete the previous progress bar bitmap                       */
  1567. /* : : [ENDIF]                                                                */
  1568. /* : : CAB... Create the new progress bar bitmap with the new dimension       */
  1569. /* : [ENDIF]                                                                  */
  1570. /* : CB.... Select the DC on the progress bar bitmap                          */
  1571. /* : [IF the progress bar size is different from the previous time]           */
  1572. /* : : CC.... Start the complete redraw of the progress bar from the end      */
  1573. /* : :   CCA... Draw the background element                                   */
  1574. /* : :     CCAA.. Draw the background element at the most right position      */
  1575. /* : :     [UNTIL the right end of the progress bar is not reached]           */
  1576. /* : :     : CCAB.. Draw background element until the right end of the bar    */
  1577. /* : :     [NEXT]                                                             */
  1578. /* : :   CCB... Save the previous position of the end of the progress bar     */
  1579. /* : :   CCC... Draw the bar element                                          */
  1580. /* : :     CCCA.. Reset the drawing position on a base of an element's width  */
  1581. /* : :     [UNTIL the beginning is not reached]                               */
  1582. /* : :     : CCCB.. Draw the bar element until the left end of the bar        */
  1583. /* : :     [NEXT]                                                             */
  1584. /* : :   CCD... Draw the center element                                       */
  1585. /* : :   [IF not under the start element]                                     */
  1586. /* : :   : CCE... Draw the before-left element                                */
  1587. /* : :   [ENDIF]                                                              */
  1588. /* : :   [IF not under the end element]                                       */
  1589. /* : :   : CCF... Draw the after-right element                                */
  1590. /* : :   [ENDIF]                                                              */
  1591. /* : :   CCG... Draw the start element                                        */
  1592. /* : :   CCH... Draw the end element                                          */
  1593. /* : :   CCI... Draw the left element of the bar                              */
  1594. /* : :   CCJ... Draw the right element of the bar                             */
  1595. /* : [ELSE]                                                                   */
  1596. /* : : CD.... Modify the moved elements without redrawing everything          */
  1597. /* : :   CDA... Start to update the progress bar from the previous position   */
  1598. /* : :   [IF going backward (Oh my God, could it be possible ?)]              */
  1599. /* : :   : CDB... Going backward                                              */
  1600. /* : :   :   CDBA.. Draw background to replace the end of the progress bar    */
  1601. /* : :   :   CDBB.. Reset drawing position on a base of an element's width    */
  1602. /* : :   :   [UNTIL the right end of the progress bar is not reached]         */
  1603. /* : :   :   : CDBC.. Draw the background until the right end of the bar      */
  1604. /* : :   :   [NEXT]                                                           */
  1605. /* : :   [ELSE]                                                               */
  1606. /* : :   : CDC... Going forward                                               */
  1607. /* : :   :   CDCA.. Draw the bar element to replace the progress bar end      */
  1608. /* : :   :   CDCB.. Reset drawing position on a base of an element's width    */
  1609. /* : :   :   [UNTIL the right end of the progress bar is not reached]         */
  1610. /* : :   :   : CDCC.. Draw the progress bar until the right end of the bar    */
  1611. /* : :   :   [NEXT]                                                           */
  1612. /* : :   [ENDIF]                                                              */
  1613. /* : :   CDD... Draw the center element                                       */
  1614. /* : :   [IF moved AND not under the start element]                           */
  1615. /* : :   : CDE... Draw the before-left element                                */
  1616. /* : :   [ENDIF]                                                              */
  1617. /* : :   [IF moved AND not under the end element]                             */
  1618. /* : :   : CDF... Draw the after-right element                                */
  1619. /* : :   [ENDIF]                                                              */
  1620. /* : :   [IF modifed by BEFORE or LEFT or CENTER]                             */
  1621. /* : :   : CDG... Draw the start element                                      */
  1622. /* : :   [ENDIF]                                                              */
  1623. /* : :   [IF modifed by CENTER or RIGHT or AFTER]                             */
  1624. /* : :   : CDH... Draw the end element                                        */
  1625. /* : :   [ENDIF]                                                              */
  1626. /* : :   [IF LEFT moved OR RIGHT too close from LEFT]                         */
  1627. /* : :   : CDI... Draw the left element of the bar                            */
  1628. /* : :   [ENDIF]                                                              */
  1629. /* : :   [IF RIGHT moved OR LEFT too close from RIGHT]                        */
  1630. /* : :   : CDJ... Draw the right element of the bar                           */
  1631. /* : :   [ENDIF]                                                              */
  1632. /* : [ENDIF]                                                                  */
  1633. /* : D..... Display the progress bar                                          */
  1634. /* [ENDIF]                                                                    */
  1635. /*----------------------------------------------------------------------------*/
  1636. /* Specific details about the dCSP_SLIDERBAR_METHOD or the dCSP_VERTICAL_BAR  */
  1637. /* are not provided because beyon the scope of the class. The code is also    */
  1638. /* fully functionnal, but is not yet intented to be used. It will surely be   */
  1639. /* a near update. But right now, anyone who wants to understand how slider    */
  1640. /* bars and/or vertical bars works just have to understand first how the      */
  1641. /* progress bars works. Hope there is enough comments for this purpose ;p     */
  1642. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  1643. void CSkinProgress::OnPaint
  1644. ( // On redraw event
  1645. {
  1646. CPaintDC oDC(this);   // Device context for painting - Do not call CStatic::OnPaint() for painting messages
  1647.   CDC      oDcProgress; // CompatibleDC
  1648.   CBitmap* poOldBitmap; // oDC's previous bitmap
  1649.   CRect    oRectPaint;
  1650.   int      nCurrentPos; // Pos of the current calculated position
  1651.   int      nStepPos;
  1652. //  LPPAINTSTRUCT sPaintStruct;
  1653.   // Init
  1654.   // Process
  1655. // A..... Update the progress bar elements position and get the progress bar dimension
  1656.   UpdateProgress(&oRectPaint); // the CStatic currently being repaint
  1657. //  BeginPaint(sPaintStruct);
  1658. // B...... Set variables for calculation
  1659. #ifdef dCSP_VERTICAL_BAR
  1660.   if(m_bVertical == false)
  1661.   { // Horizontal bar
  1662. #endif // dCSP_VERTICAL_BAR
  1663.     nStepPos = m_nBmpWidth;
  1664. #ifdef dCSP_VERTICAL_BAR
  1665.   }
  1666.   else
  1667.   { // Vertical bar
  1668.     nStepPos = m_nBmpHeight;
  1669.   }
  1670. #endif // dCSP_VERTICAL_BAR
  1671. // C..... Draw the progress bar
  1672.   if( // If the SIZE (don't mind the position) of the ProgressBar has changed
  1673.          (oRectPaint.Width()  != m_oRectPaint.Width())
  1674.       || (oRectPaint.Height() != m_oRectPaint.Height())
  1675.     )
  1676.   { // If the progress bar size has changed
  1677. // CA.... Redraw the complete bar from scratch
  1678.     if(m_poProgressBmp != NULL)
  1679.     { // If the ProgressBitmap already exists, delete it and create a new one with the new dimension of the pane
  1680. // CAA... Delete the previous progress bar bitmap
  1681.       delete m_poProgressBmp;
  1682.     }else{}
  1683. // CAB... Create the new progress bar bitmap with the new dimension
  1684.     m_poProgressBmp = new CBitmap;
  1685.     m_poProgressBmp->CreateCompatibleBitmap(&oDC, oRectPaint.Width(), oRectPaint.Height()); // *ALWAYS* use '&oDC', *NEVER* '&oDcProgress' otherwise you'll get a monochrom image
  1686.   }else{}
  1687. // CB.... Select the DC on the progress bar bitmap
  1688.   oDcProgress.CreateCompatibleDC(&oDC);
  1689.   poOldBitmap = oDcProgress.SelectObject(m_poProgressBmp);
  1690.   if( // If the SIZE (don't mind the position) of the ProgressBar has changed
  1691.          (oRectPaint.Width()  != m_oRectPaint.Width())
  1692.       || (oRectPaint.Height() != m_oRectPaint.Height())
  1693.     )
  1694.   { // If the ProgressBar has changed, redraw it completly
  1695. // CC.... Start the complete redraw of the progress bar from the end
  1696.     // Background
  1697. // CCA... Draw the background element
  1698. // CCAA.. Draw the background element from the most right position
  1699.     nCurrentPos = m_nEndAff - (m_nEndAff % nStepPos);
  1700.     for(; nCurrentPos > m_nRightAff; nCurrentPos -= nStepPos)
  1701.     {
  1702. // CCAB.. Draw the background element until the right end of the bar
  1703. #ifdef dCSP_VERTICAL_BAR
  1704.       if(m_bVertical == false)
  1705.       { // Horizontal bar
  1706. #endif // dCSP_VERTICAL_BAR
  1707.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1708. #ifdef dCSP_VERTICAL_BAR
  1709.       }
  1710.       else
  1711.       { // Vertical bar
  1712.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(0, nCurrentPos), ILD_NORMAL);
  1713.       }
  1714. #endif // dCSP_VERTICAL_BAR
  1715.     }
  1716. // CCB... Save the previous position of the end of the progress bar
  1717.     // Position of the end of the bar
  1718.     m_nPrevRightAff = m_nRightAff;
  1719. // CCC... Draw the bar element
  1720.     // Bar
  1721. // CCCA.. Reset the drawing position on a base of the image list element's width
  1722.     nCurrentPos -= (nCurrentPos % nStepPos);
  1723. #ifndef dCSP_SLIDERBAR_METHOD
  1724.     for(; nCurrentPos >= nStepPos;   nCurrentPos -= nStepPos) // For m_nLeft-less progress bar routine
  1725. #else
  1726.     for(; nCurrentPos >= m_nLeftAff; nCurrentPos -= nStepPos)
  1727. #endif // dCSP_SLIDERBAR_METHOD
  1728.     {
  1729. // CCCB.. Draw the bar element until the left end of the bar
  1730. #ifdef dCSP_VERTICAL_BAR
  1731.       if(m_bVertical == false)
  1732.       { // Horizontal bar
  1733. #endif // dCSP_VERTICAL_BAR
  1734.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1735. #ifdef dCSP_VERTICAL_BAR
  1736.       }
  1737.       else
  1738.       { // Vertical bar
  1739.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(0, nCurrentPos), ILD_NORMAL);
  1740.       }
  1741. #endif // dCSP_VERTICAL_BAR
  1742.     }
  1743. #ifdef dCSP_SLIDERBAR_METHOD
  1744.     // Position of the beginning of the bar
  1745.     m_nPrevLeftAff = m_nLeftAff;
  1746.     // Background
  1747.     nCurrentPos -= (nCurrentPos % nStepPos);
  1748.     for(; nCurrentPos >= nStepPos; nCurrentPos -= nStepPos)
  1749.     {
  1750. #ifdef dCSP_VERTICAL_BAR
  1751.       if(m_bVertical == false)
  1752.       { // Horizontal bar
  1753. #endif // dCSP_VERTICAL_BAR
  1754.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1755. #ifdef dCSP_VERTICAL_BAR
  1756.       }
  1757.       else
  1758.       { // Vertical bar
  1759.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(0, nCurrentPos), ILD_NORMAL);
  1760.       }
  1761. #endif // dCSP_VERTICAL_BAR
  1762.     }
  1763. #endif // dCSP_SLIDERBAR_METHOD
  1764. // CCD... Draw the center element
  1765.     // Center
  1766. #ifdef dCSP_VERTICAL_BAR
  1767.     if(m_bVertical == false)
  1768.     { // Horizontal bar
  1769. #endif // dCSP_VERTICAL_BAR
  1770. #ifndef dCSP_SLIDERBAR_METHOD
  1771.       m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(m_nRightAff >> 1, 0), ILD_NORMAL);
  1772. #else
  1773.       m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint((m_nLeftAff + m_nRightAff) >> 1, 0), ILD_NORMAL);
  1774. #endif // dCSP_SLIDERBAR_METHOD
  1775. #ifdef dCSP_VERTICAL_BAR
  1776.     }
  1777.     else
  1778.     { // Vertical bar
  1779. #ifndef dCSP_SLIDERBAR_METHOD
  1780.       m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(0, m_nRightAff >> 1), ILD_NORMAL);
  1781. #else
  1782.       m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(0, (m_nLeftAff + m_nRightAff) >> 1), ILD_NORMAL);
  1783. #endif // dCSP_SLIDERBAR_METHOD
  1784.     }
  1785. #endif // dCSP_VERTICAL_BAR
  1786. // CCE... Draw the before-left element
  1787.     // Before
  1788. #ifdef dCSP_SLIDERBAR_METHOD
  1789.     if(m_nLeftAff > nStepPos)
  1790.     {
  1791. #ifdef dCSP_VERTICAL_BAR
  1792.       if(m_bVertical == false)
  1793.       { // Horizontal bar
  1794. #endif // dCSP_VERTICAL_BAR
  1795.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BEFORE, CPoint(m_nLeftAff - m_nBmpWidth, 0), ILD_NORMAL);
  1796. #ifdef dCSP_VERTICAL_BAR
  1797.       }
  1798.       else
  1799.       { // Vertical bar
  1800.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BEFORE, CPoint(0, m_nLeftAff - m_nBmpHeight), ILD_NORMAL);
  1801.       }
  1802. #endif // dCSP_VERTICAL_BAR
  1803.     }else{}
  1804. #endif // dCSP_SLIDERBAR_METHOD
  1805. // CCF... Draw the after-right element
  1806.     // After
  1807.     if(m_nRightAff < (m_nEndAff - nStepPos))
  1808.     {
  1809. #ifdef dCSP_VERTICAL_BAR
  1810.       if(m_bVertical == false)
  1811.       { // Horizontal bar
  1812. #endif // dCSP_VERTICAL_BAR
  1813.         m_oBarImgLst.Draw(&oDcProgress, cSPB_AFTER, CPoint(m_nRightAff + m_nBmpWidth, 0), ILD_NORMAL);
  1814. #ifdef dCSP_VERTICAL_BAR
  1815.       }
  1816.       else
  1817.       { // Vertical bar
  1818.         m_oBarImgLst.Draw(&oDcProgress, cSPB_AFTER, CPoint(0, m_nRightAff + m_nBmpHeight), ILD_NORMAL);
  1819.       }
  1820. #endif // dCSP_VERTICAL_BAR
  1821.     }else{}
  1822. // CCG... Draw the start element
  1823.     // Start
  1824. #ifdef dCSP_SLIDERBAR_METHOD
  1825.     m_oBarImgLst.Draw(&oDcProgress, cSPB_START, CPoint(0, 0), ILD_NORMAL);
  1826. #endif // dCSP_SLIDERBAR_METHOD
  1827. // CCH... Draw the end element
  1828.     // End
  1829. #ifdef dCSP_VERTICAL_BAR
  1830.     if(m_bVertical == false)
  1831.     { // Horizontal bar
  1832. #endif // dCSP_VERTICAL_BAR
  1833.       m_oBarImgLst.Draw(&oDcProgress, cSPB_END, CPoint(m_nEndAff, 0), ILD_NORMAL);
  1834. #ifdef dCSP_VERTICAL_BAR
  1835.     }
  1836.     else
  1837.     { // Vertical bar
  1838.       m_oBarImgLst.Draw(&oDcProgress, cSPB_END, CPoint(0, m_nEndAff), ILD_NORMAL);
  1839.     }
  1840. #endif // dCSP_VERTICAL_BAR
  1841. // CCI... Draw the left element of the bar
  1842.     // Left
  1843. #ifdef dCSP_VERTICAL_BAR
  1844.     if(m_bVertical == false)
  1845.     { // Horizontal bar
  1846. #endif // dCSP_VERTICAL_BAR
  1847. #ifndef dCSP_SLIDERBAR_METHOD
  1848.       m_oBarImgLst.Draw(&oDcProgress, cSPB_LEFT, CPoint(0, 0), ILD_NORMAL); // For m_nLeft-less progress bar routine
  1849. #else
  1850.       m_oBarImgLst.Draw(&oDcProgress, cSPB_LEFT, CPoint(m_nLeftAff, 0), ILD_NORMAL);
  1851. #endif // dCSP_SLIDERBAR_METHOD
  1852. #ifdef dCSP_VERTICAL_BAR
  1853.     }
  1854.     else
  1855.     { // Vertical bar
  1856. #ifndef dCSP_SLIDERBAR_METHOD
  1857.       m_oBarImgLst.Draw(&oDcProgress, cSPB_TOP, CPoint(0, 0), ILD_NORMAL); // For m_nLeft-less progress bar routine
  1858. #else
  1859.       m_oBarImgLst.Draw(&oDcProgress, cSPB_TOP, CPoint(0, m_nLeftAff), ILD_NORMAL);
  1860. #endif // dCSP_SLIDERBAR_METHOD
  1861.     }
  1862. #endif // dCSP_VERTICAL_BAR
  1863. // CCJ// Car... Draw the right element of the bar
  1864.     // Right
  1865. #ifdef dCSP_VERTICAL_BAR
  1866.     if(m_bVertical == false)
  1867.     { // Horizontal bar
  1868. #endif // dCSP_VERTICAL_BAR
  1869.       m_oBarImgLst.Draw(&oDcProgress, cSPB_RIGHT, CPoint(m_nRightAff, 0), ILD_NORMAL);
  1870. #ifdef dCSP_VERTICAL_BAR
  1871.     }
  1872.     else
  1873.     { // Vertical bar
  1874.       m_oBarImgLst.Draw(&oDcProgress, cSPB_BOTTOM, CPoint(0, m_nRightAff), ILD_NORMAL);
  1875.     }
  1876. #endif // dCSP_VERTICAL_BAR
  1877.     m_nPrevEndAff = m_nEndAff;
  1878.     m_oRectPaint  = oRectPaint;
  1879.   }
  1880.   else
  1881.   {
  1882. // CD.... Modify the moved elements without redrawing the complete progress bar
  1883.     if(m_nPrevRightAff != m_nRightAff)
  1884.     {
  1885. // CDA... Start to update the progress bar from the previous position
  1886.       nCurrentPos = m_nPrevRightAff;
  1887.       if(m_nRightAff < m_nPrevRightAff)
  1888.       { // If going backward, draw BACKGROUND and last with RIGHT
  1889. // CDB... Going backward
  1890. // CDBA.. Draw the background element to replace the end of the progress bar
  1891.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1892. // CDBB.. Reset the drawing position on a base of the image list element's width
  1893.         nCurrentPos -= (nCurrentPos % nStepPos);
  1894.         for(; nCurrentPos > m_nRightAff; nCurrentPos -= nStepPos)
  1895.         {
  1896. // CDBC.. Draw the background element until the right end of the bar
  1897. #ifdef dCSP_VERTICAL_BAR
  1898.           if(m_bVertical == false)
  1899.           { // Horizontal bar
  1900. #endif // dCSP_VERTICAL_BAR
  1901.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1902. #ifdef dCSP_VERTICAL_BAR
  1903.           }
  1904.           else
  1905.           { // Vertical bar
  1906.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(0, nCurrentPos), ILD_NORMAL);
  1907.           }
  1908. #endif // dCSP_VERTICAL_BAR
  1909.         }
  1910.       }
  1911.       else
  1912.       { // If going forward, draw BAR and last with RIGHT
  1913. // CDC... Going forward
  1914. // CDCA.. Draw the progress bar element to replace the end of the progress bar
  1915.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1916. // CDCB.. Reset the drawing position on a base of the image list element's width
  1917.         nCurrentPos += nStepPos;
  1918.         nCurrentPos -= (nCurrentPos % nStepPos);
  1919.         for(; nCurrentPos < m_nRightAff; nCurrentPos += nStepPos)
  1920.         {
  1921. // CDCC.. Draw the progress bar element until the right end of the bar
  1922. #ifdef dCSP_VERTICAL_BAR
  1923.           if(m_bVertical == false)
  1924.           { // Horizontal bar
  1925. #endif // dCSP_VERTICAL_BAR
  1926.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1927. #ifdef dCSP_VERTICAL_BAR
  1928.           }
  1929.           else
  1930.           { // Vertical bar
  1931.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(0, nCurrentPos), ILD_NORMAL);
  1932.           }
  1933. #endif // dCSP_VERTICAL_BAR
  1934.         }
  1935.       }
  1936.     }else{}
  1937. #ifdef dCSP_SLIDERBAR_METHOD
  1938.     if(m_nLeftAff!= m_nPrevLeftAff)
  1939.     {
  1940.       nCurrentPos = m_nPrevLeftAff;
  1941.       if(m_nLeftAff < m_nPrevLeftAff)
  1942.       { // If going backward, draw BAR and last with LEFT
  1943.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1944.         nCurrentPos -= (nCurrentPos % nStepPos);
  1945.         for(; nCurrentPos > m_nLeftAff; nCurrentPos -= nStepPos)
  1946.         {
  1947. #ifdef dCSP_VERTICAL_BAR
  1948.           if(m_bVertical == false)
  1949.           { // Horizontal bar
  1950. #endif // dCSP_VERTICAL_BAR
  1951.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1952. #ifdef dCSP_VERTICAL_BAR
  1953.           }
  1954.           else
  1955.           { // Vertical bar
  1956.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BAR, CPoint(0, nCurrentPos), ILD_NORMAL);
  1957.           }
  1958. #endif // dCSP_VERTICAL_BAR
  1959.         }
  1960.       }
  1961.       else
  1962.       { // If going forward, draw BACKGROUND and last with LEFT
  1963.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1964.         nCurrentPos += nStepPos;
  1965.         nCurrentPos -= (nCurrentPos % nStepPos);
  1966.         for(; nCurrentPos < m_nLeftAff; nCurrentPos += nStepPos)
  1967.         {
  1968. #ifdef dCSP_VERTICAL_BAR
  1969.           if(m_bVertical == false)
  1970.           { // Horizontal bar
  1971. #endif // dCSP_VERTICAL_BAR
  1972.           m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(nCurrentPos, 0), ILD_NORMAL);
  1973. #ifdef dCSP_VERTICAL_BAR
  1974.           }
  1975.           else
  1976.           { // Vertical bar
  1977.             m_oBarImgLst.Draw(&oDcProgress, cSPB_BACKGROUND, CPoint(0, nCurrentPos), ILD_NORMAL);
  1978.           }
  1979. #endif // dCSP_VERTICAL_BAR
  1980.         }
  1981.       }
  1982.     }else{}
  1983. #endif // dCSP_SLIDERBAR_METHOD
  1984. // CDD... Draw the center element
  1985.     if(
  1986.            (m_nPrevRightAff != m_nRightAff)
  1987. #ifdef dCSP_SLIDERBAR_METHOD
  1988.         || (m_nPrevLeftAff  != m_nLeftAff)
  1989. #endif // dCSP_SLIDERBAR_METHOD
  1990.       )
  1991.     {
  1992. #ifdef dCSP_VERTICAL_BAR
  1993.       if(m_bVertical == false)
  1994.       { // Horizontal bar
  1995. #endif // dCSP_VERTICAL_BAR
  1996. #ifndef dCSP_SLIDERBAR_METHOD
  1997.         m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(m_nRightAff >> 1, 0), ILD_NORMAL);
  1998. #else
  1999.         m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint((m_nLeftAff + m_nRightAff) >> 1, 0), ILD_NORMAL);
  2000. #endif // dCSP_SLIDERBAR_METHOD
  2001. #ifdef dCSP_VERTICAL_BAR
  2002.       }
  2003.       else
  2004.       { // Vertical bar
  2005. #ifndef dCSP_SLIDERBAR_METHOD
  2006.         m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(0, m_nRightAff >> 1), ILD_NORMAL);
  2007. #else
  2008.         m_oBarImgLst.Draw(&oDcProgress, cSPB_CENTER, CPoint(0, (m_nLeftAff + m_nRightAff) >> 1), ILD_NORMAL);
  2009. #endif // dCSP_SLIDERBAR_METHOD
  2010.       }
  2011. #endif // dCSP_VERTICAL_BAR
  2012.     }
  2013. // CDE... Draw the before-left element
  2014.     // Before
  2015. #ifdef dCSP_SLIDERBAR_METHOD
  2016.     if(m_nPrevLeftAff != m_nLeftAff)
  2017.     {
  2018.       if(m_nLeftAff > nStepPos)
  2019.       {
  2020. #ifdef dCSP_VERTICAL_BAR
  2021.         if(m_bVertical == false)
  2022.         { // Horizontal bar
  2023. #endif // dCSP_VERTICAL_BAR
  2024.           m_oBarImgLst.Draw(&oDcProgress, cSPB_BEFORE, CPoint(m_nLeftAff - nStepPos, 0), ILD_NORMAL);
  2025. #ifdef dCSP_VERTICAL_BAR
  2026.         }
  2027.         else
  2028.         { // Vertical bar
  2029.           m_oBarImgLst.Draw(&oDcProgress, cSPB_BEFORE, CPoint(0, m_nLeftAff - nStepPos), ILD_NORMAL);
  2030.         }
  2031. #endif // dCSP_VERTICAL_BAR
  2032.       }else{}
  2033.     }else{}
  2034. #endif // dCSP_SLIDERBAR_METHOD
  2035. // CDF... Draw the after-right element
  2036.     // After
  2037.     if(m_nRightAff != m_nPrevRightAff)
  2038.     {
  2039.       if(m_nRightAff < (m_nEndAff - nStepPos))
  2040.       {
  2041. #ifdef dCSP_VERTICAL_BAR
  2042.         if(m_bVertical == false)
  2043.         { // Horizontal bar
  2044. #endif // dCSP_VERTICAL_BAR
  2045.           m_oBarImgLst.Draw(&oDcProgress, cSPB_AFTER, CPoint(m_nRightAff + nStepPos, 0), ILD_NORMAL);
  2046. #ifdef dCSP_VERTICAL_BAR
  2047.         }
  2048.         else
  2049.         { // Vertical bar
  2050.           m_oBarImgLst.Draw(&oDcProgress, cSPB_AFTER, CPoint(0, m_nRightAff + nStepPos), ILD_NORMAL);
  2051.         }
  2052. #endif // dCSP_VERTICAL_BAR
  2053.       }else{}
  2054.     }else{}
  2055. // CDG... Draw the start element
  2056.     // Start
  2057. #ifdef dCSP_SLIDERBAR_METHOD
  2058.     if(m_nPrevLeftAff  != m_nLeftAff)
  2059. #else
  2060.     if(m_nPrevRightAff != m_nRightAff) // In non-<dCSP_SLIDERBAR_METHOD> mode, only the right end can move
  2061. #endif // dCSP_SLIDERBAR_METHOD
  2062.     {
  2063. #ifdef dCSP_SLIDERBAR_METHOD
  2064.       if(m_nLeftAff  < (nStepPos << 1))
  2065. #else
  2066.       if(m_nRightAff < (nStepPos << 1)) // In non-<dCSP_SLIDERBAR_METHOD> mode, only the right end can move
  2067. #endif // dCSP_SLIDERBAR_METHOD
  2068.       { // If the START element was over-written, refresh it
  2069.         m_oBarImgLst.Draw(&oDcProgress, cSPB_START, CPoint(0, 0), ILD_NORMAL);
  2070.       }else{}
  2071.     }else{}
  2072. // CDH... Draw the end element
  2073.     // End
  2074.     if(m_nPrevRightAff != m_nRightAff)
  2075.     {
  2076.       if(m_nRightAff > (m_nEndAff - (nStepPos << 1)))
  2077.       { // If the END element was over-written, refresh it
  2078. #ifdef dCSP_VERTICAL_BAR
  2079.         if(m_bVertical == false)
  2080.         { // Horizontal bar
  2081. #endif // dCSP_VERTICAL_BAR
  2082.           m_oBarImgLst.Draw(&oDcProgress, cSPB_END, CPoint(m_nEndAff, 0), ILD_NORMAL);
  2083. #ifdef dCSP_VERTICAL_BAR
  2084.         }
  2085.         else
  2086.         { // Vertical bar
  2087.           m_oBarImgLst.Draw(&oDcProgress, cSPB_END, CPoint(0, m_nEndAff), ILD_NORMAL);
  2088.         }
  2089. #endif // dCSP_VERTICAL_BAR
  2090.       }else{}
  2091.     }else{}
  2092. // CDI... Draw the left element of the bar
  2093. #ifdef dCSP_SLIDERBAR_METHOD
  2094.     if( // In case of slider display, the closeness of the RIGHT element from the LEFT can cause an over-write of the LEFT element with BAR and/or CENTER
  2095.            (m_nPrevLeftAff != m_nLeftAff)
  2096.         || (m_nRightAff < (m_nLeftAff + (nStepPos << 1)))
  2097.       )
  2098.     {
  2099.       // Position of the start of the bar
  2100.       m_nPrevLeftAff = m_nLeftAff;
  2101. #ifdef dCSP_VERTICAL_BAR
  2102.       if(m_bVertical == false)
  2103.       { // Horizontal bar
  2104. #endif // dCSP_VERTICAL_BAR
  2105.         // Left
  2106.         m_oBarImgLst.Draw(&oDcProgress, cSPB_LEFT, CPoint(m_nLeftAff, 0), ILD_NORMAL);
  2107. #ifdef dCSP_VERTICAL_BAR
  2108.       }
  2109.       else
  2110.       { // Vertical bar
  2111.         // Top
  2112.         m_oBarImgLst.Draw(&oDcProgress, cSPB_TOP, CPoint(0, m_nLeftAff), ILD_NORMAL);
  2113.       }
  2114. #endif // dCSP_VERTICAL_BAR
  2115.     }else{}
  2116. #else
  2117.     // As long as the RIGHT element is too close from the LEFT element, the CENTER element over-writes the LEFT element, thus we have to refresh the LEFT element
  2118.     if(m_nRightAff < (nStepPos << 1))
  2119.     {
  2120. #ifdef dCSP_VERTICAL_BAR
  2121.       if(m_bVertical == false)
  2122.       { // Horizontal bar
  2123. #endif // dCSP_VERTICAL_BAR
  2124.         // Left
  2125.         m_oBarImgLst.Draw(&oDcProgress, cSPB_LEFT, CPoint(0, 0), ILD_NORMAL);
  2126. #ifdef dCSP_VERTICAL_BAR
  2127.       }
  2128.       else
  2129.       { // Vertical bar
  2130.         // Top
  2131.         m_oBarImgLst.Draw(&oDcProgress, cSPB_TOP, CPoint(0, 0), ILD_NORMAL);
  2132.       }
  2133. #endif // dCSP_VERTICAL_BAR
  2134.     }else{}
  2135. #endif // dCSP_SLIDERBAR_METHOD
  2136. // CDJ... Draw the right element of the bar
  2137.     if( // In case of slider display, the closeness of the LEFT element from the RIGHT can cause an over-write of the RIGHT element with BAR and/or CENTER
  2138.            (m_nPrevRightAff != m_nRightAff)
  2139. #ifdef dCSP_SLIDERBAR_METHOD
  2140.         || (m_nLeftAff> (m_nRightAff - (nStepPos << 1)))
  2141. #endif // dCSP_SLIDERBAR_METHOD
  2142.       )
  2143.     {
  2144.       // Position of the end of the bar
  2145.       m_nPrevRightAff = m_nRightAff;
  2146. #ifdef dCSP_VERTICAL_BAR
  2147.       if(m_bVertical == false)
  2148.       { // Horizontal bar
  2149. #endif // dCSP_VERTICAL_BAR
  2150.         // Right
  2151.         m_oBarImgLst.Draw(&oDcProgress, cSPB_RIGHT, CPoint(m_nRightAff, 0), ILD_NORMAL);
  2152. #ifdef dCSP_VERTICAL_BAR
  2153.       }
  2154.       else
  2155.       { // Vertical bar
  2156.         // Cottom
  2157.         m_oBarImgLst.Draw(&oDcProgress, cSPB_BOTTOM, CPoint(0, m_nRightAff), ILD_NORMAL);
  2158.       }
  2159. #endif // dCSP_VERTICAL_BAR
  2160.     }else{}
  2161.     if(m_nPrevEndAff != m_nEndAff)
  2162.     {
  2163.       m_nPrevEndAff = m_nEndAff;
  2164.     }else{}
  2165.   }
  2166. // D..... Display the progress bar
  2167.   // Copy the progress bitmap each time the object have to be refreshed
  2168. #ifndef dCSP_DISPLAY_STRETCH
  2169.   oDC.BitBlt(0, 0, oRectPaint.Width(), oRectPaint.Height(), &oDcProgress, 0, 0, SRCCOPY);
  2170. #else
  2171.   CDC      oDcStretch;   // CompatibleDC
  2172.   CBitmap* poOldStretch; // oDC's previous bitmap
  2173.   BITMAP   sStretchBmp;
  2174.   oDcStretch.CreateCompatibleDC(&oDC);
  2175. poOldStretch = oDcStretch.SelectObject(m_poStretchBmp);
  2176.   m_poStretchBmp->GetBitmap(&sStretchBmp);
  2177.   oDC.BitBlt(0, 0, sStretchBmp.bmWidth, sStretchBmp.bmHeight, &oDcStretch, 0, 0, SRCCOPY);
  2178.   oDcStretch.SelectObject(poOldStretch);
  2179.   oDcStretch.DeleteDC();
  2180. #endif // dCSP_DISPLAY_STRETCH
  2181.   // Release the DC
  2182.   oDcProgress.SelectObject(poOldBitmap);
  2183.   oDcProgress.DeleteDC();
  2184. //  EndPaint(sPaintStruct);
  2185. }
  2186. /*--- START FUNCTION HEADER --------------------------------------------------*/
  2187. /* Name          : OnSizing                                                   */
  2188. /* Role          : Before things are resized                                  */
  2189. /* Type          : PROTECTED                                                  */
  2190. /* Interface     : RETURN (direct value)                                      */
  2191. /*                   None                                                     */
  2192. /*                 OUTPUT (pointer to value)                                  */
  2193. /*                   None                                                     */
  2194. /*                 INPUT  (pointer to value, direct/default value)            */
  2195. /*                   fwSide : Edge of window to be moved                      */
  2196. /*                   pRect  : New rectangle                                   */
  2197. /* Pre-condition : None                                                       */
  2198. /* Constraints   : None                                                       */
  2199. /* Behavior      : A - Resize the object                                      */
  2200. /*                 B - Resize the text                                        */
  2201. /*----------------------------------------------------------------------------*/
  2202. /* PROC OnSizing                                                              */
  2203. /*                                                                            */
  2204. /* A..... Resize the object                                                   */
  2205. /* B..... Resize the text                                                     */
  2206. /*----------------------------------------------------------------------------*/
  2207. /* In normal cases, this is NEVER called                                      */
  2208. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  2209. void CSkinProgress::OnSizing
  2210. (
  2211.   UINT   fwSide, // Edge of window to be moved
  2212.   LPRECT pRect   // New rectangle
  2213. )
  2214. {
  2215. // A..... Resize the object
  2216. CStatic::OnSizing(fwSide, pRect);
  2217.   // Process
  2218. // B..... Resize the text
  2219.   RefreshPanes(); // Recalculate text layout on sizing the window
  2220. }
  2221. /*--- START FUNCTION HEADER --------------------------------------------------*/
  2222. /* Name          : OnSize                                                     */
  2223. /* Role          : Once things were resized                                   */
  2224. /* Type          : PROTECTED                                                  */
  2225. /* Interface     : RETURN (direct value)                                      */
  2226. /*                   None                                                     */
  2227. /*                 OUTPUT (pointer to value)                                  */
  2228. /*                   None                                                     */
  2229. /*                 INPUT  (pointer to value, direct/default value)            */
  2230. /*                   nType : Type of resizing requested                       */
  2231. /*                   cx    : Width                                            */
  2232. /*                   cy    : Height                                           */
  2233. /* Pre-condition : None                                                       */
  2234. /* Constraints   : None                                                       */
  2235. /* Behavior      : A - Transmit the new dimensions                            */
  2236. /*----------------------------------------------------------------------------*/
  2237. /* PROC OnSize                                                                */
  2238. /*                                                                            */
  2239. /* A..... Transmit the new dimensions                                         */
  2240. /*----------------------------------------------------------------------------*/
  2241. /* Just over-ridden, ready to use for various purposes ;)                     */
  2242. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  2243. void CSkinProgress::OnSize
  2244. (
  2245.   UINT nType, // Type of resizing requested 
  2246.   int  cx,    // Width
  2247.   int  cy     // Height
  2248. )
  2249. {
  2250. // A..... Transmit the new dimensions
  2251. CStatic::OnSize(nType, cx, cy);
  2252. }
  2253. /*--- START FUNCTION HEADER --------------------------------------------------*/
  2254. /* Name          : OnTimer                                                    */
  2255. /* Role          : The object timer has elapsed                               */
  2256. /* Type          : PROTECTED                                                  */
  2257. /* Interface     : RETURN (direct value)                                      */
  2258. /*                   None                                                     */
  2259. /*                 OUTPUT (pointer to value)                                  */
  2260. /*                   None                                                     */
  2261. /*                 INPUT  (pointer to value, direct/default value)            */
  2262. /*                   nIDEvent : The Timer handle that elapsed                 */
  2263. /* Pre-condition : None                                                       */
  2264. /* Constraints   : None                                                       */
  2265. /* Behavior      : A - Refresh the text and the progress bar                  */
  2266. /*                 B - Transmit the Timer handle to the parent                */
  2267. /*----------------------------------------------------------------------------*/
  2268. /* PROC OnTimer                                                               */
  2269. /*                                                                            */
  2270. /* A..... Refresh the text and the progress bar                               */
  2271. /* B..... Transmit the Timer handle to the parent                             */
  2272. /*----------------------------------------------------------------------------*/
  2273. /* Just used to refresh the timed message when things are going too slow...   */
  2274. /* Also used when on time redrawing the progress bar, to limit to 50 refresh  */
  2275. /* per second...                                                              */
  2276. /*--- END FUNCTION HEADER ----------------------------------------------------*/
  2277. void CSkinProgress::OnTimer
  2278. ( // On a Timer event
  2279.   UINT nIDEvent
  2280. )
  2281. {
  2282.   if(nIDEvent == (UINT) this) // Use object's unique address as timer identifier
  2283.   {
  2284. // A..... Refresh the text and the progress bar
  2285.     RefreshPanes(); // Refresh the whole stuff, each 500 ms or 20 ms if in dCSP_TIMED_REDRAW mode
  2286.   }else{}
  2287. // B..... Transmit the Timer handle to the parent
  2288. CStatic::OnTimer(nIDEvent);
  2289. }