/*++ 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 #include #include #include #include "gauge.h" #include #include #include #include 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)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); }