299 lines
5.8 KiB
C
299 lines
5.8 KiB
C
/*++
|
|
|
|
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; i<Spaces; i++) {
|
|
Gauge->Buffer[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);
|
|
}
|
|
}
|
|
}
|