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

298 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. spgauge.c
  5. Abstract:
  6. Code implementing a gas gauge for file copies for text mode NT setup.
  7. Author:
  8. Ted Miller (tedm) 14-April-1992
  9. Revision History:
  10. --*/
  11. #include "spprecmp.h"
  12. #pragma hdrstop
  13. PWSTR PctFmtStr = L"%u%% ";
  14. VOID
  15. pSpDrawVariableParts(
  16. IN PGAS_GAUGE Gauge
  17. );
  18. PVOID
  19. SpCreateAndDisplayGauge(
  20. IN ULONG ItemCount,
  21. IN ULONG GaugeWidth, OPTIONAL
  22. IN ULONG Y,
  23. IN PWCHAR Caption,
  24. IN PWCHAR ProgressFmtStr, OPTIONAL
  25. IN ULONG Flags, OPTIONAL
  26. IN UCHAR Attribute OPTIONAL
  27. )
  28. {
  29. PGAS_GAUGE Gauge;
  30. ULONG X;
  31. //
  32. // Allocate a gauge structure.
  33. //
  34. Gauge = SpMemAlloc(sizeof(GAS_GAUGE));
  35. if(!Gauge) {
  36. return(NULL);
  37. }
  38. Gauge->Buffer = SpMemAlloc(VideoVars.ScreenWidth*sizeof(WCHAR));
  39. if(!Gauge->Buffer) {
  40. SpMemFree(Gauge);
  41. return(NULL);
  42. }
  43. Gauge->Caption = SpMemAlloc((wcslen(Caption)+1)*sizeof(WCHAR));
  44. if(!Gauge->Caption) {
  45. SpMemFree(Gauge->Buffer);
  46. SpMemFree(Gauge);
  47. return(NULL);
  48. }
  49. wcscpy(Gauge->Caption,Caption);
  50. if (ProgressFmtStr) {
  51. Gauge->ProgressFmtStr = SpMemAlloc((wcslen(ProgressFmtStr)+1)*sizeof(WCHAR));
  52. if(!Gauge->ProgressFmtStr) {
  53. SpMemFree(Gauge->Buffer);
  54. SpMemFree(Gauge->Caption);
  55. SpMemFree(Gauge);
  56. return(NULL);
  57. }
  58. wcscpy(Gauge->ProgressFmtStr,ProgressFmtStr);
  59. Gauge->ProgressFmtWidth = SplangGetColumnCount(ProgressFmtStr);
  60. } else {
  61. Gauge->ProgressFmtStr = PctFmtStr;
  62. Gauge->ProgressFmtWidth = 3;
  63. }
  64. Gauge->Flags = Flags;
  65. if (Attribute) {
  66. Gauge->Attribute = Attribute;
  67. } else {
  68. Gauge->Attribute = GAUGE_ATTRIBUTE;
  69. }
  70. //
  71. // If the caller did not specify a width, calculate one.
  72. // Originally, a gauge was 66 chars wide on an 80 character vga screen.
  73. // To preserve that ratio, make the width 66/80ths of the screen.
  74. //
  75. if(!GaugeWidth) {
  76. GaugeWidth = VideoVars.ScreenWidth * 66 / 80;
  77. if(GaugeWidth & 1) {
  78. GaugeWidth++; // make sure it's even.
  79. }
  80. }
  81. //
  82. // Center the gauge horizontally.
  83. //
  84. X = (VideoVars.ScreenWidth - GaugeWidth) / 2;
  85. Gauge->GaugeX = X;
  86. Gauge->GaugeY = Y;
  87. Gauge->GaugeW = GaugeWidth;
  88. //
  89. // Calculate the size of the thermometer box.
  90. // The box is always offset by 6 characters from the gauge itself.
  91. //
  92. Gauge->ThermX = X+6;
  93. Gauge->ThermY = Y+3;
  94. Gauge->ThermW = GaugeWidth-12;
  95. //
  96. // Save away additional info about the gauge.
  97. //
  98. Gauge->ItemCount = max (ItemCount, 1); // ensure no divide-by-zero bug checks
  99. Gauge->ItemsElapsed = 0;
  100. Gauge->CurrentPercentage = 0;
  101. SpDrawGauge(Gauge);
  102. return(Gauge);
  103. }
  104. VOID
  105. SpDestroyGauge(
  106. IN PVOID GaugeHandle
  107. )
  108. {
  109. PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle;
  110. if (Gauge == NULL)
  111. return;
  112. if (Gauge->ProgressFmtStr != PctFmtStr) {
  113. SpMemFree(Gauge->ProgressFmtStr);
  114. }
  115. SpMemFree(Gauge->Caption);
  116. SpMemFree(Gauge->Buffer);
  117. SpMemFree(Gauge);
  118. }
  119. VOID
  120. SpDrawGauge(
  121. IN PVOID GaugeHandle
  122. )
  123. {
  124. PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle;
  125. //
  126. // Draw the outer box.
  127. //
  128. SpDrawFrame(
  129. Gauge->GaugeX,
  130. Gauge->GaugeW,
  131. Gauge->GaugeY,
  132. GAUGE_HEIGHT,
  133. DEFAULT_ATTRIBUTE,
  134. TRUE
  135. );
  136. //
  137. // Draw the thermometer box.
  138. //
  139. SpDrawFrame(
  140. Gauge->ThermX,
  141. Gauge->ThermW,
  142. Gauge->ThermY,
  143. 3,
  144. DEFAULT_ATTRIBUTE,
  145. FALSE
  146. );
  147. //
  148. // Percent complete, etc.
  149. //
  150. pSpDrawVariableParts(Gauge);
  151. //
  152. // Caption text
  153. //
  154. SpvidDisplayString(Gauge->Caption,DEFAULT_ATTRIBUTE,Gauge->GaugeX+2,Gauge->GaugeY+1);
  155. }
  156. VOID
  157. SpTickGauge(
  158. IN PVOID GaugeHandle
  159. )
  160. {
  161. PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle;
  162. ULONG NewPercentage;
  163. if(Gauge->ItemsElapsed < Gauge->ItemCount) {
  164. Gauge->ItemsElapsed++;
  165. NewPercentage = 100 * Gauge->ItemsElapsed / Gauge->ItemCount;
  166. if(NewPercentage != Gauge->CurrentPercentage) {
  167. Gauge->CurrentPercentage = NewPercentage;
  168. pSpDrawVariableParts(Gauge);
  169. }
  170. }
  171. }
  172. VOID
  173. pSpDrawVariableParts(
  174. IN PGAS_GAUGE Gauge
  175. )
  176. {
  177. ULONG Spaces;
  178. ULONG i;
  179. WCHAR Percent[128];
  180. //
  181. // Figure out how many spaces this is.
  182. //
  183. Spaces = Gauge->ItemsElapsed * (Gauge->ThermW-2) / Gauge->ItemCount;
  184. for(i=0; i<Spaces; i++) {
  185. Gauge->Buffer[i] = L' ';
  186. }
  187. Gauge->Buffer[Spaces] = 0;
  188. SpvidDisplayString(Gauge->Buffer,Gauge->Attribute,Gauge->ThermX+1,Gauge->ThermY+1);
  189. //
  190. // Now put the percentage text up.
  191. //
  192. switch (Gauge->Flags) {
  193. case GF_PERCENTAGE:
  194. swprintf( Percent, Gauge->ProgressFmtStr, Gauge->CurrentPercentage );
  195. break;
  196. case GF_ITEMS_REMAINING:
  197. swprintf( Percent, Gauge->ProgressFmtStr, Gauge->ItemCount - Gauge->ItemsElapsed );
  198. break;
  199. case GF_ITEMS_USED:
  200. swprintf( Percent, Gauge->ProgressFmtStr, Gauge->ItemsElapsed );
  201. break;
  202. }
  203. SpvidDisplayString(
  204. Percent,
  205. DEFAULT_ATTRIBUTE,
  206. Gauge->GaugeX + ((Gauge->GaugeW-Gauge->ProgressFmtWidth)/2),
  207. Gauge->GaugeY+2
  208. );
  209. }
  210. VOID
  211. SpFillGauge(
  212. IN PVOID GaugeHandle,
  213. IN ULONG Amount
  214. )
  215. {
  216. PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle;
  217. ULONG NewPercentage;
  218. if(Amount <= Gauge->ItemCount) {
  219. Gauge->ItemsElapsed = Amount;
  220. NewPercentage = 100 * Gauge->ItemsElapsed / Gauge->ItemCount;
  221. if(NewPercentage != Gauge->CurrentPercentage) {
  222. Gauge->CurrentPercentage = NewPercentage;
  223. pSpDrawVariableParts(Gauge);
  224. }
  225. }
  226. }