458 lines
9.8 KiB
C
458 lines
9.8 KiB
C
/*++
|
||
|
||
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);
|
||
}
|
||
|
||
|