Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

457 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. gauge.c
  5. Abstract:
  6. This module contains the code for the gauge window class used
  7. with the diskmon utility.
  8. Author:
  9. Chuck Park (chuckp) 10-Feb-1994
  10. Mike Glass (mglass)
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #include "gauge.h"
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <math.h>
  22. BOOL
  23. IndicatorOverText(
  24. DOUBLE radians
  25. );
  26. VOID
  27. DrawDial(
  28. HWND handle
  29. );
  30. VOID
  31. DrawGaugeText(
  32. HANDLE handle
  33. );
  34. HPEN ArcPen,
  35. IndicatorPen,
  36. CoverPen,
  37. TickMarkPen;
  38. INT cx, cy;
  39. PGAUGEVALS head;
  40. RECT LeftTick,
  41. RightTick;
  42. BOOL
  43. RegisterGauge(
  44. HINSTANCE hInstance
  45. )
  46. {
  47. WNDCLASS wc;
  48. wc.style = CS_HREDRAW | CS_VREDRAW;
  49. wc.lpfnWndProc = (WNDPROC)GaugeWndProc;
  50. wc.cbClsExtra = 0;
  51. wc.cbWndExtra = 4;
  52. wc.hInstance = hInstance;
  53. wc.hIcon = NULL;
  54. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  55. wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
  56. wc.lpszMenuName = NULL;
  57. wc.lpszClassName = "GaugeClass";
  58. return RegisterClass(&wc);
  59. }
  60. HWND
  61. CreateGauge(
  62. HWND parent,
  63. HINSTANCE hInstance,
  64. INT x,
  65. INT y,
  66. INT width,
  67. INT height,
  68. INT minVal,
  69. INT maxVal
  70. )
  71. {
  72. static INT winId = 0;
  73. HWND handle;
  74. PGAUGEVALS curvals;
  75. handle = CreateWindow("GaugeClass",
  76. NULL,
  77. WS_CHILD | WS_VISIBLE,
  78. x,y,
  79. width,
  80. height,
  81. parent,
  82. (HMENU)IntToPtr(winId++),
  83. hInstance,
  84. NULL
  85. );
  86. ShowWindow( handle, SW_SHOW) ;
  87. //
  88. //Allocate mem for GAUGEVALS (window specific info.)
  89. //
  90. if ((curvals = (PGAUGEVALS)malloc(sizeof(GAUGEVALS))) == NULL) {
  91. MessageBox(NULL,"Couldn't allocate memory for window.","Error",
  92. MB_ICONEXCLAMATION | MB_OK);
  93. return NULL;
  94. }
  95. curvals->handle = handle;
  96. curvals->minValue = minVal;
  97. curvals->maxValue = maxVal;
  98. curvals->curValue = 0;
  99. curvals->next = NULL;
  100. //
  101. //Link into list.
  102. //
  103. if (head == NULL) {
  104. head = curvals;
  105. } else {
  106. curvals->next = head;
  107. head = curvals;
  108. }
  109. return handle;
  110. }
  111. LRESULT CALLBACK GaugeWndProc(
  112. HWND hWnd,
  113. UINT message,
  114. WPARAM uParam,
  115. LPARAM lParam
  116. )
  117. {
  118. HDC DC;
  119. switch (message) {
  120. case WM_CREATE:
  121. DC = GetDC(hWnd);
  122. //
  123. // Create Objects to be used in drawing the different parts
  124. // of the gauge.
  125. //
  126. ArcPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXFRAME),RGB(255,0,0));
  127. IndicatorPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXDLGFRAME),RGB(230,230,220));
  128. CoverPen = CreatePen(PS_SOLID,GetSystemMetrics(SM_CXDLGFRAME),RGB(0,0,0));
  129. TickMarkPen = CreatePen(PS_SOLID,(2*GetSystemMetrics(SM_CXBORDER)),RGB(255,255,0));
  130. cx = 70;
  131. cy = 70;
  132. LeftTick.top = (INT)(cy * 2 - ((1.5 * cy) * sin (.78) ) );
  133. LeftTick.left = (INT)(cx * 1.5 - ((1.5 * cx) * cos (.78)));
  134. LeftTick.bottom = (INT)(cy * 2 - ((1.4 * cy) * sin (.78) ) );
  135. LeftTick.right = (INT)(cx * 1.5 - ((1.4 * cx) * cos (.78)));
  136. RightTick.top = (INT)(cy * 2 - ((1.5 * cy) * sin (.78) ) );
  137. RightTick.left = (INT)(cx * 1.5 + ((1.5 * cx) * cos (.78)));
  138. RightTick.bottom = (INT)(cy * 2 - ((1.4 * cy) * sin (.78) ) );
  139. RightTick.right = (INT)(cx * 1.5 + ((1.4 * cx) * cos (.78)));
  140. ReleaseDC(hWnd,DC);
  141. break;
  142. case WM_PAINT:
  143. DrawDial(hWnd);
  144. break;
  145. case WM_DESTROY:
  146. DeleteObject (ArcPen);
  147. DeleteObject (IndicatorPen);
  148. DeleteObject (CoverPen);
  149. DeleteObject (TickMarkPen);
  150. break;
  151. default:
  152. return (DefWindowProc(hWnd, message, uParam, lParam));
  153. }
  154. return 0;
  155. }
  156. VOID
  157. UpdateGauge(
  158. HWND handle,
  159. INT value
  160. )
  161. {
  162. DOUBLE radians;
  163. HDC DC;
  164. INT x,y;
  165. PGAUGEVALS current;
  166. POINT pt,point;
  167. RECT gaugeRect;
  168. current = head;
  169. while (current) {
  170. if (current->handle == handle) {
  171. break;
  172. }
  173. current = current->next;
  174. }
  175. current->curValue = value;
  176. DC = GetDC (handle);
  177. RealizePalette(DC);
  178. //
  179. // Get the original brush origins
  180. //
  181. GetBrushOrgEx(DC,&point);
  182. //
  183. // Get the extents of the child window.
  184. //
  185. GetWindowRect(handle,&gaugeRect);
  186. //
  187. // Set new brush origin
  188. //
  189. SetStretchBltMode(DC,HALFTONE);
  190. SetBrushOrgEx(DC,gaugeRect.left,gaugeRect.top,&point);
  191. //
  192. //Draw line over old indicator line
  193. //
  194. MoveToEx (DC,current->base.x, current->base.y, &pt);
  195. SelectObject(DC,CoverPen);
  196. LineTo (DC,current->top.x,current->top.y);
  197. SelectObject(DC,IndicatorPen);
  198. MoveToEx (DC,current->base.x, current->base.y, &pt);
  199. //
  200. //calc value adjusting it if over or under max/min.
  201. //
  202. if (current->curValue > current->maxValue) {
  203. current->curValue = current->maxValue;
  204. } else if (current->curValue < current->minValue) {
  205. current->curValue = current->minValue;
  206. }
  207. radians = (DOUBLE)(current->curValue * 3.14159) / (DOUBLE)(current->maxValue - current->minValue);
  208. x = (INT)(cx * (1.5 - cos(radians)));
  209. y = (INT)(cy * (1.9 - sin(radians)));
  210. LineTo (DC,x,y);
  211. current->top.x = x;
  212. current->top.y = y;
  213. ReleaseDC(handle,DC);
  214. DrawGaugeText( handle);
  215. }
  216. VOID
  217. DrawDial(
  218. HWND handle
  219. )
  220. {
  221. CHAR buffer[15];
  222. DOUBLE radians;
  223. HDC DC;
  224. INT x,y;
  225. POINT pt;
  226. PAINTSTRUCT ps;
  227. PGAUGEVALS gaugevals;
  228. DC = BeginPaint(handle,&ps);
  229. SetBkMode(DC,TRANSPARENT);
  230. //
  231. //Find correct info for this window.
  232. //
  233. gaugevals = head;
  234. while (gaugevals) {
  235. if (gaugevals->handle == handle) {
  236. break;
  237. }
  238. gaugevals = gaugevals->next;
  239. }
  240. //
  241. // Draw the Arc for the gauge
  242. //
  243. MoveToEx ( DC, 0, cy * 2, &pt);
  244. SelectObject(DC,ArcPen);
  245. AngleArc (DC,
  246. (INT)(cx * 1.5),
  247. (INT)(cy * 2),
  248. (INT)(cy * 1.5),
  249. (float)0.0,
  250. (float)180.0
  251. );
  252. //
  253. //Fill in arc with black.
  254. //
  255. SelectObject(DC,GetStockObject(BLACK_BRUSH));
  256. ExtFloodFill (DC,5,cy*2 - 10,RGB(255,0,0),FLOODFILLBORDER);
  257. //
  258. // Draw the tick marks
  259. //
  260. SelectObject (DC, TickMarkPen);
  261. MoveToEx (DC, (INT)(cx * 1.5),(INT)( cy * .5), &pt);
  262. LineTo (DC, (INT)(cx * 1.5),(INT)(cy * .6));
  263. MoveToEx (DC, LeftTick.right, LeftTick.bottom, &pt);
  264. LineTo (DC, LeftTick.left, LeftTick.top);
  265. MoveToEx (DC, RightTick.right, RightTick.bottom, &pt);
  266. LineTo (DC, RightTick.left, RightTick.top);
  267. MoveToEx (DC, 0, (INT)(cy * 1.9), &pt);
  268. LineTo (DC, (INT)(cx * .1),(INT)(cy * 1.9));
  269. MoveToEx (DC, (INT)(cx * 3), (INT)(cy * 1.9), &pt);
  270. LineTo (DC, (INT)(cx * 2.9), (INT)(cy * 1.9));
  271. //
  272. // Max difference / curvalue = PI / radians
  273. //
  274. radians = (DOUBLE)(gaugevals->curValue * 3.14159) / (DOUBLE)(gaugevals->maxValue - gaugevals->minValue);
  275. MoveToEx (DC,(INT)(cx * 1.5), (INT)(cy * 1.9), &pt);
  276. SelectObject(DC,IndicatorPen);
  277. //
  278. //Save begin and end point in gaugevals.
  279. //
  280. gaugevals->base.x = (INT)(cx * 1.5);
  281. gaugevals->base.y = (INT)(cx * 1.9);
  282. //
  283. //Draw dial indicator as thick line.
  284. //
  285. y = (INT)(cy * (1.9 - sin(radians)));
  286. x = (INT)(cx * (1.5 - cos(radians)));
  287. gaugevals->top.x = x;
  288. gaugevals->top.y = y;
  289. LineTo(DC,x ,y );
  290. //
  291. //Draw indicator value text.
  292. //
  293. SetTextColor(DC,RGB(230,230,200));
  294. sprintf (buffer,"%Lu",gaugevals->minValue);
  295. TextOut (DC,(INT)(cx / 10),(INT)(cy * 1.70),buffer,strlen(buffer));
  296. sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) /4 );
  297. TextOut (DC,(INT)(cx * .4),(INT)(cy * 1.1 ), buffer, strlen(buffer));
  298. sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) / 2 );
  299. TextOut (DC,(INT)(cx * 1.3), (INT)(cy * .6) ,buffer,strlen(buffer));
  300. sprintf (buffer,"%Lu",((gaugevals->maxValue - gaugevals->minValue) / 4) * 3 );
  301. TextOut (DC,(INT)(cx * (2 + (gaugevals->maxValue > 10000 ? .1 : .2))),(INT)(cy * 1.1), buffer, strlen(buffer));
  302. sprintf(buffer,"%Lu",gaugevals->maxValue);
  303. TextOut(DC,(int)(cx * (2 + (gaugevals->maxValue > 10000 ? .4 : .5 ))), (INT)(cy * 1.70),buffer,strlen(buffer));
  304. EndPaint(handle,&ps);
  305. }
  306. VOID
  307. DrawGaugeText(
  308. HANDLE handle
  309. )
  310. {
  311. HDC DC;
  312. CHAR buffer[15];
  313. PGAUGEVALS gaugevals;
  314. //
  315. //Find correct info for this window.
  316. //
  317. gaugevals = head;
  318. while (gaugevals) {
  319. if (gaugevals->handle == handle) {
  320. break;
  321. }
  322. gaugevals = gaugevals->next;
  323. }
  324. DC = GetDC (handle);
  325. SetBkMode(DC,TRANSPARENT);
  326. SetTextColor(DC,RGB(230,230,200));
  327. sprintf (buffer,"%Lu",gaugevals->minValue);
  328. TextOut (DC,(INT)(cx / 10),(INT)(cy * 1.70),buffer,strlen(buffer));
  329. sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) /4 );
  330. TextOut (DC,(INT)(cx * .4),(INT)(cy * 1.1 ), buffer, strlen(buffer));
  331. sprintf (buffer,"%Lu",(gaugevals->maxValue - gaugevals->minValue) / 2 );
  332. TextOut (DC,(INT)(cx * 1.3), (INT)(cy * .6) ,buffer,strlen(buffer));
  333. sprintf (buffer,"%Lu",((gaugevals->maxValue - gaugevals->minValue) / 4) * 3 );
  334. TextOut (DC,(INT)(cx * (2 + (gaugevals->maxValue > 10000 ? .1 : .2))),(INT)(cy * 1.1), buffer, strlen(buffer));
  335. sprintf(buffer,"%Lu",gaugevals->maxValue);
  336. TextOut(DC,(int)(cx * (2 + (gaugevals->maxValue > 10000 ? .4 : .5 ))), (INT)(cy * 1.70),buffer,strlen(buffer));
  337. ReleaseDC (handle,DC);
  338. }
  339. 
  340.