windows-nt/Source/XPSP1/NT/sdktools/diskmon/gauge.c

458 lines
9.8 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
gauge.c
Abstract:
This module contains the code for the gauge window class used
with the diskmon utility.
Author:
Chuck Park (chuckp) 10-Feb-1994
Mike Glass (mglass)
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include "gauge.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
BOOL
IndicatorOverText(
DOUBLE radians
);
VOID
DrawDial(
HWND handle
);
VOID
DrawGaugeText(
HANDLE handle
);
HPEN ArcPen,
IndicatorPen,
CoverPen,
TickMarkPen;
INT cx, cy;
PGAUGEVALS head;
RECT LeftTick,
RightTick;
BOOL
RegisterGauge(
HINSTANCE hInstance
)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)GaugeWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 4;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GaugeClass";
return RegisterClass(&wc);
}
HWND
CreateGauge(
HWND parent,
HINSTANCE hInstance,
INT x,
INT y,
INT width,
INT height,
INT minVal,
INT maxVal
)
{
static INT winId = 0;
HWND handle;
PGAUGEVALS curvals;
handle = CreateWindow("GaugeClass",
NULL,
WS_CHILD | WS_VISIBLE,
x,y,
width,
height,
parent,
(HMENU)IntToPtr(winId++),
hInstance,
NULL
);
ShowWindow( handle, SW_SHOW) ;
//
//Allocate mem for GAUGEVALS (window specific info.)
//
if ((curvals = (PGAUGEVALS)malloc(sizeof(GAUGEVALS))) == NULL) {
MessageBox(NULL,"Couldn't allocate memory for window.","Error",
MB_ICONEXCLAMATION | MB_OK);
return NULL;
}
curvals->handle = handle;
curvals->minValue = minVal;
curvals->maxValue = maxVal;
curvals->curValue = 0;
curvals->next = NULL;
//
//Link into list.
//
if (head == NULL) {
head = curvals;
} else {
curvals->next = head;
head = curvals;
}
return handle;
}
LRESULT CALLBACK GaugeWndProc(
HWND hWnd,
UINT message,
WPARAM uParam,
LPARAM lParam
)
{
HDC DC;
switch (message) {
case WM_CREATE:
DC = GetDC(hWnd);
//
// Create Objects to be used in drawing the different parts
// of the gauge.
//
ArcPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXFRAME),RGB(255,0,0));
IndicatorPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXDLGFRAME),RGB(230,230,220));
CoverPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXDLGFRAME),RGB(0,0,0));
TickMarkPen = CreatePen(PS_SOLID,(2*GetSystemMetrics(SM_CXBORDER)),RGB(255,255,0));
cx = 70;
cy = 70;
LeftTick.top = (INT)(cy * 2 - ((1.5 * cy) * sin (.78) ) );
LeftTick.left = (INT)(cx * 1.5 - ((1.5 * cx) * cos (.78)));
LeftTick.bottom = (INT)(cy * 2 - ((1.4 * cy) * sin (.78) ) );
LeftTick.right = (INT)(cx * 1.5 - ((1.4 * cx) * cos (.78)));
RightTick.top = (INT)(cy * 2 - ((1.5 * cy) * sin (.78) ) );
RightTick.left = (INT)(cx * 1.5 + ((1.5 * cx) * cos (.78)));
RightTick.bottom = (INT)(cy * 2 - ((1.4 * cy) * sin (.78) ) );
RightTick.right = (INT)(cx * 1.5 + ((1.4 * cx) * cos (.78)));
ReleaseDC(hWnd,DC);
break;
case WM_PAINT:
DrawDial(hWnd);
break;
case WM_DESTROY:
DeleteObject (ArcPen);
DeleteObject (IndicatorPen);
DeleteObject (CoverPen);
DeleteObject (TickMarkPen);
break;
default:
return (DefWindowProc(hWnd, message, uParam, lParam));
}
return 0;
}
VOID
UpdateGauge(
HWND handle,
INT value
)
{
DOUBLE radians;
HDC DC;
INT x,y;
PGAUGEVALS current;
POINT pt,point;
RECT gaugeRect;
current = head;
while (current) {
if (current->handle == handle) {
break;
}
current = current->next;
}
current->curValue = value;
DC = GetDC (handle);
RealizePalette(DC);
//
// Get the original brush origins
//
GetBrushOrgEx(DC,&point);
//
// Get the extents of the child window.
//
GetWindowRect(handle,&gaugeRect);
//
// Set new brush origin
//
SetStretchBltMode(DC,HALFTONE);
SetBrushOrgEx(DC,gaugeRect.left,gaugeRect.top,&point);
//
//Draw line over old indicator line
//
MoveToEx (DC,current->base.x, current->base.y, &pt);
SelectObject(DC,CoverPen);
LineTo (DC,current->top.x,current->top.y);
SelectObject(DC,IndicatorPen);
MoveToEx (DC,current->base.x, current->base.y, &pt);
//
//calc value adjusting it if over or under max/min.
//
if (current->curValue > current->maxValue) {
current->curValue = current->maxValue;
} else if (current->curValue < current->minValue) {
current->curValue = current->minValue;
}
radians = (DOUBLE)(current->curValue * 3.14159) / (DOUBLE)(current->maxValue - current->minValue);
x = (INT)(cx * (1.5 - cos(radians)));
y = (INT)(cy * (1.9 - sin(radians)));
LineTo (DC,x,y);
current->top.x = x;
current->top.y = y;
ReleaseDC(handle,DC);
DrawGaugeText( handle);
}
VOID
DrawDial(
HWND handle
)
{
CHAR buffer[15];
DOUBLE radians;
HDC DC;
INT x,y;
POINT pt;
PAINTSTRUCT ps;
PGAUGEVALS gaugevals;
DC = BeginPaint(handle,&ps);
SetBkMode(DC,TRANSPARENT);
//
//Find correct info for this window.
//
gaugevals = head;
while (gaugevals) {
if (gaugevals->handle == handle) {
break;
}
gaugevals = gaugevals->next;
}
//
// Draw the Arc for the gauge
//
MoveToEx ( DC, 0, cy * 2, &pt);
SelectObject(DC,ArcPen);
AngleArc (DC,
(INT)(cx * 1.5),
(INT)(cy * 2),
(INT)(cy * 1.5),
(float)0.0,
(float)180.0
);
//
//Fill in arc with black.
//
SelectObject(DC,GetStockObject(BLACK_BRUSH));
ExtFloodFill (DC,5,cy*2 - 10,RGB(255,0,0),FLOODFILLBORDER);
//
// Draw the tick marks
//
SelectObject (DC, TickMarkPen);
MoveToEx (DC, (INT)(cx * 1.5),(INT)( cy * .5), &pt);
LineTo (DC, (INT)(cx * 1.5),(INT)(cy * .6));
MoveToEx (DC, LeftTick.right, LeftTick.bottom, &pt);
LineTo (DC, LeftTick.left, LeftTick.top);
MoveToEx (DC, RightTick.right, RightTick.bottom, &pt);
LineTo (DC, RightTick.left, RightTick.top);
MoveToEx (DC, 0, (INT)(cy * 1.9), &pt);
LineTo (DC, (INT)(cx * .1),(INT)(cy * 1.9));
MoveToEx (DC, (INT)(cx * 3), (INT)(cy * 1.9), &pt);
LineTo (DC, (INT)(cx * 2.9), (INT)(cy * 1.9));
//
// Max difference / curvalue = PI / radians
//
radians = (DOUBLE)(gaugevals->curValue * 3.14159) / (DOUBLE)(gaugevals->maxValue - gaugevals->minValue);
MoveToEx (DC,(INT)(cx * 1.5), (INT)(cy * 1.9), &pt);
SelectObject(DC,IndicatorPen);
//
//Save begin and end point in gaugevals.
//
gaugevals->base.x = (INT)(cx * 1.5);
gaugevals->base.y = (INT)(cx * 1.9);
//
//Draw dial indicator as thick line.
//
y = (INT)(cy * (1.9 - sin(radians)));
x = (INT)(cx * (1.5 - cos(radians)));
gaugevals->top.x = x;
gaugevals->top.y = y;
LineTo(DC,x ,y );
//
//Draw indicator value text.
//
SetTextColor(DC,RGB(230,230,200));
sprintf (buffer,"%Lu",gaugevals->minValue);
TextOut (DC,(INT)(cx / 10),(INT)(cy * 1.70),buffer,strlen(buffer));
sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) /4 );
TextOut (DC,(INT)(cx * .4),(INT)(cy * 1.1 ), buffer, strlen(buffer));
sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) / 2 );
TextOut (DC,(INT)(cx * 1.3), (INT)(cy * .6) ,buffer,strlen(buffer));
sprintf (buffer,"%Lu",((gaugevals->maxValue - gaugevals->minValue) / 4) * 3 );
TextOut (DC,(INT)(cx * (2 + (gaugevals->maxValue > 10000 ? .1 : .2))),(INT)(cy * 1.1), buffer, strlen(buffer));
sprintf(buffer,"%Lu",gaugevals->maxValue);
TextOut(DC,(int)(cx * (2 + (gaugevals->maxValue > 10000 ? .4 : .5 ))), (INT)(cy * 1.70),buffer,strlen(buffer));
EndPaint(handle,&ps);
}
VOID
DrawGaugeText(
HANDLE handle
)
{
HDC DC;
CHAR buffer[15];
PGAUGEVALS gaugevals;
//
//Find correct info for this window.
//
gaugevals = head;
while (gaugevals) {
if (gaugevals->handle == handle) {
break;
}
gaugevals = gaugevals->next;
}
DC = GetDC (handle);
SetBkMode(DC,TRANSPARENT);
SetTextColor(DC,RGB(230,230,200));
sprintf (buffer,"%Lu",gaugevals->minValue);
TextOut (DC,(INT)(cx / 10),(INT)(cy * 1.70),buffer,strlen(buffer));
sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) /4 );
TextOut (DC,(INT)(cx * .4),(INT)(cy * 1.1 ), buffer, strlen(buffer));
sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) / 2 );
TextOut (DC,(INT)(cx * 1.3), (INT)(cy * .6) ,buffer,strlen(buffer));
sprintf (buffer,"%Lu",((gaugevals->maxValue - gaugevals->minValue) / 4) * 3 );
TextOut (DC,(INT)(cx * (2 + (gaugevals->maxValue > 10000 ? .1 : .2))),(INT)(cy * 1.1), buffer, strlen(buffer));
sprintf(buffer,"%Lu",gaugevals->maxValue);
TextOut(DC,(int)(cx * (2 + (gaugevals->maxValue > 10000 ? .4 : .5 ))), (INT)(cy * 1.70),buffer,strlen(buffer));
ReleaseDC (handle,DC);
}