/*++ Copyright (c) 1992 Microsoft Corporation Module Name: spgauge.c Abstract: Code implementing a gas gauge for file copies for text mode NT setup. Author: Ted Miller (tedm) 14-April-1992 Revision History: --*/ #include "spprecmp.h" #pragma hdrstop PWSTR PctFmtStr = L"%u%% "; VOID pSpDrawVariableParts( IN PGAS_GAUGE Gauge ); PVOID SpCreateAndDisplayGauge( IN ULONG ItemCount, IN ULONG GaugeWidth, OPTIONAL IN ULONG Y, IN PWCHAR Caption, IN PWCHAR ProgressFmtStr, OPTIONAL IN ULONG Flags, OPTIONAL IN UCHAR Attribute OPTIONAL ) { PGAS_GAUGE Gauge; ULONG X; // // Allocate a gauge structure. // Gauge = SpMemAlloc(sizeof(GAS_GAUGE)); if(!Gauge) { return(NULL); } Gauge->Buffer = SpMemAlloc(VideoVars.ScreenWidth*sizeof(WCHAR)); if(!Gauge->Buffer) { SpMemFree(Gauge); return(NULL); } Gauge->Caption = SpMemAlloc((wcslen(Caption)+1)*sizeof(WCHAR)); if(!Gauge->Caption) { SpMemFree(Gauge->Buffer); SpMemFree(Gauge); return(NULL); } wcscpy(Gauge->Caption,Caption); if (ProgressFmtStr) { Gauge->ProgressFmtStr = SpMemAlloc((wcslen(ProgressFmtStr)+1)*sizeof(WCHAR)); if(!Gauge->ProgressFmtStr) { SpMemFree(Gauge->Buffer); SpMemFree(Gauge->Caption); SpMemFree(Gauge); return(NULL); } wcscpy(Gauge->ProgressFmtStr,ProgressFmtStr); Gauge->ProgressFmtWidth = SplangGetColumnCount(ProgressFmtStr); } else { Gauge->ProgressFmtStr = PctFmtStr; Gauge->ProgressFmtWidth = 3; } Gauge->Flags = Flags; if (Attribute) { Gauge->Attribute = Attribute; } else { Gauge->Attribute = GAUGE_ATTRIBUTE; } // // If the caller did not specify a width, calculate one. // Originally, a gauge was 66 chars wide on an 80 character vga screen. // To preserve that ratio, make the width 66/80ths of the screen. // if(!GaugeWidth) { GaugeWidth = VideoVars.ScreenWidth * 66 / 80; if(GaugeWidth & 1) { GaugeWidth++; // make sure it's even. } } // // Center the gauge horizontally. // X = (VideoVars.ScreenWidth - GaugeWidth) / 2; Gauge->GaugeX = X; Gauge->GaugeY = Y; Gauge->GaugeW = GaugeWidth; // // Calculate the size of the thermometer box. // The box is always offset by 6 characters from the gauge itself. // Gauge->ThermX = X+6; Gauge->ThermY = Y+3; Gauge->ThermW = GaugeWidth-12; // // Save away additional info about the gauge. // Gauge->ItemCount = max (ItemCount, 1); // ensure no divide-by-zero bug checks Gauge->ItemsElapsed = 0; Gauge->CurrentPercentage = 0; SpDrawGauge(Gauge); return(Gauge); } VOID SpDestroyGauge( IN PVOID GaugeHandle ) { PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle; if (Gauge == NULL) return; if (Gauge->ProgressFmtStr != PctFmtStr) { SpMemFree(Gauge->ProgressFmtStr); } SpMemFree(Gauge->Caption); SpMemFree(Gauge->Buffer); SpMemFree(Gauge); } VOID SpDrawGauge( IN PVOID GaugeHandle ) { PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle; // // Draw the outer box. // SpDrawFrame( Gauge->GaugeX, Gauge->GaugeW, Gauge->GaugeY, GAUGE_HEIGHT, DEFAULT_ATTRIBUTE, TRUE ); // // Draw the thermometer box. // SpDrawFrame( Gauge->ThermX, Gauge->ThermW, Gauge->ThermY, 3, DEFAULT_ATTRIBUTE, FALSE ); // // Percent complete, etc. // pSpDrawVariableParts(Gauge); // // Caption text // SpvidDisplayString(Gauge->Caption,DEFAULT_ATTRIBUTE,Gauge->GaugeX+2,Gauge->GaugeY+1); } VOID SpTickGauge( IN PVOID GaugeHandle ) { PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle; ULONG NewPercentage; if(Gauge->ItemsElapsed < Gauge->ItemCount) { Gauge->ItemsElapsed++; NewPercentage = 100 * Gauge->ItemsElapsed / Gauge->ItemCount; if(NewPercentage != Gauge->CurrentPercentage) { Gauge->CurrentPercentage = NewPercentage; pSpDrawVariableParts(Gauge); } } } VOID pSpDrawVariableParts( IN PGAS_GAUGE Gauge ) { ULONG Spaces; ULONG i; WCHAR Percent[128]; // // Figure out how many spaces this is. // Spaces = Gauge->ItemsElapsed * (Gauge->ThermW-2) / Gauge->ItemCount; for(i=0; iBuffer[i] = L' '; } Gauge->Buffer[Spaces] = 0; SpvidDisplayString(Gauge->Buffer,Gauge->Attribute,Gauge->ThermX+1,Gauge->ThermY+1); // // Now put the percentage text up. // switch (Gauge->Flags) { case GF_PERCENTAGE: swprintf( Percent, Gauge->ProgressFmtStr, Gauge->CurrentPercentage ); break; case GF_ITEMS_REMAINING: swprintf( Percent, Gauge->ProgressFmtStr, Gauge->ItemCount - Gauge->ItemsElapsed ); break; case GF_ITEMS_USED: swprintf( Percent, Gauge->ProgressFmtStr, Gauge->ItemsElapsed ); break; } SpvidDisplayString( Percent, DEFAULT_ATTRIBUTE, Gauge->GaugeX + ((Gauge->GaugeW-Gauge->ProgressFmtWidth)/2), Gauge->GaugeY+2 ); } VOID SpFillGauge( IN PVOID GaugeHandle, IN ULONG Amount ) { PGAS_GAUGE Gauge = (PGAS_GAUGE)GaugeHandle; ULONG NewPercentage; if(Amount <= Gauge->ItemCount) { Gauge->ItemsElapsed = Amount; NewPercentage = 100 * Gauge->ItemsElapsed / Gauge->ItemCount; if(NewPercentage != Gauge->CurrentPercentage) { Gauge->CurrentPercentage = NewPercentage; pSpDrawVariableParts(Gauge); } } }