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);
|
|||
|
}
|
|||
|
|
|||
|
|