Leaked source code of windows server 2003
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.

425 lines
10 KiB

  1. /* File: \WACKER\TDLL\VU_METER.C (Created: 10-JAN-1994)
  2. * Created from:
  3. * File: C:\HA5G\ha5g\stxtproc.c (Created: 27-SEP-1991)
  4. *
  5. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  6. * All rights reserved
  7. *
  8. * $Revision: 9 $
  9. * $Date: 4/16/02 2:41p $
  10. */
  11. #include <windows.h>
  12. #pragma hdrstop
  13. #define WE_DRAW_EDGE 1
  14. #include "stdtyp.h"
  15. #include "mc.h"
  16. #include <tdll\assert.h>
  17. #include <term\xfer_dlg.h>
  18. #include "vu_meter.h"
  19. #include "vu_meter.hh"
  20. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  21. * FUNCTION:
  22. * RegisterVuMeterClass
  23. *
  24. * DESCRIPTION:
  25. * Registers the VU Meter window class. (No kidding!)
  26. *
  27. * PARAMETERS:
  28. * Hinstance -- the instance handle
  29. *
  30. * RETURNS:
  31. * Whatever RegisterClass returns.
  32. */
  33. BOOL RegisterVuMeterClass(HANDLE hInstance)
  34. {
  35. BOOL bRetVal = TRUE;
  36. WNDCLASSEX wndclass;
  37. memset(&wndclass, 0, sizeof(WNDCLASSEX));
  38. wndclass.cbSize = sizeof(WNDCLASSEX);
  39. if (GetClassInfoEx(hInstance, VU_METER_CLASS, &wndclass) == FALSE)
  40. {
  41. if (bRetVal)
  42. {
  43. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  44. wndclass.lpfnWndProc = VuMeterWndProc;
  45. wndclass.cbClsExtra = 0;
  46. wndclass.cbWndExtra = sizeof(VOID FAR *);
  47. wndclass.hIcon = NULL;
  48. wndclass.hInstance = hInstance;
  49. wndclass.hCursor = NULL;
  50. wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  51. wndclass.lpszMenuName = NULL;
  52. wndclass.lpszClassName = VU_METER_CLASS;
  53. wndclass.hIconSm = NULL;
  54. bRetVal = RegisterClassEx(&wndclass);
  55. }
  56. }
  57. return bRetVal;
  58. }
  59. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  60. * FUNCTION:
  61. * VuMeterWndProc
  62. *
  63. * DESCRIPTION:
  64. * Window procedure for implementing our own internal VU Meter.
  65. *
  66. * ARGUEMENTS:
  67. * The standard window proc stuff.
  68. *
  69. * RETURNS:
  70. *
  71. */
  72. LRESULT CALLBACK VuMeterWndProc(HWND hWnd,
  73. UINT wMsg,
  74. WPARAM wPar,
  75. LPARAM lPar)
  76. {
  77. LPVM psV;
  78. switch (wMsg)
  79. {
  80. case WM_CREATE:
  81. psV = (LPVM)malloc(sizeof(VUMETER));
  82. SetWindowLongPtr(hWnd, 0, (LONG_PTR)psV);
  83. if (psV)
  84. {
  85. psV->ulCheck = VUMETER_VALID;
  86. #if FALSE
  87. /* Old colors */
  88. psV->cBackGround = 0x00000000;
  89. psV->cFillColor = 0x0000FF00;
  90. psV->cRefillColor = 0x00800080;
  91. psV->cMarkColor = 0x0000FFFF;
  92. psV->cUpperEdge = 0x00808080;
  93. psV->cLowerEdge = 0x00FFFFFF;
  94. #endif
  95. psV->cBackGround = GetSysColor(COLOR_3DFACE);
  96. psV->cFillColor = GetSysColor(COLOR_3DDKSHADOW);
  97. psV->cRefillColor = 0x00800080; /* Unused */
  98. psV->cMarkColor = GetSysColor(COLOR_3DSHADOW);
  99. psV->cUpperEdge = GetSysColor(COLOR_3DSHADOW);
  100. psV->cLowerEdge = GetSysColor(COLOR_3DHILIGHT);
  101. psV->ulMaxRange = 0;
  102. psV->ulHiValue = 0;
  103. psV->ulCurValue = 0;
  104. psV->usDepth = STXT_DEF_DEPTH;
  105. }
  106. break;
  107. case WM_DESTROY:
  108. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  109. if (VUMETER_OK(psV))
  110. {
  111. free(psV);
  112. psV = NULL;
  113. }
  114. SetWindowLongPtr(hWnd, 0, (LONG_PTR)0L);
  115. break;
  116. case WM_GETDLGCODE:
  117. /* Static controls don't want any of these */
  118. return DLGC_STATIC;
  119. case WM_PAINT:
  120. {
  121. int nEnd;
  122. int nIndex;
  123. int nFill;
  124. int nReFill;
  125. #if defined(WE_DRAW_EDGE)
  126. int nHeight;
  127. int nWidth;
  128. #endif
  129. int nStep;
  130. RECT rcC;
  131. RECT rcE;
  132. RECT rcD;
  133. PAINTSTRUCT ps;
  134. HBRUSH hBrush;
  135. BeginPaint(hWnd, &ps);
  136. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  137. if (VUMETER_OK(psV))
  138. {
  139. /*
  140. * We erase/fill in the invalid region
  141. */
  142. hBrush = CreateSolidBrush(psV->cBackGround);
  143. FillRect(ps.hdc, &ps.rcPaint, hBrush);
  144. DeleteObject(hBrush);
  145. #if defined(WE_DRAW_EDGE)
  146. /*
  147. * We redraw the edging completely, every time
  148. */
  149. nHeight = (int)GetSystemMetrics(SM_CYBORDER) * (int)psV->usDepth;
  150. nWidth = (int)GetSystemMetrics(SM_CXBORDER) * (int)psV->usDepth;
  151. GetClientRect(hWnd, &rcC);
  152. /* Draw the top edge */
  153. hBrush = CreateSolidBrush(psV->cUpperEdge);
  154. for (nIndex = 0; nIndex < nHeight; nIndex += 1)
  155. {
  156. rcE = rcC;
  157. rcE.top = nIndex;
  158. rcE.bottom = nIndex + 1;
  159. rcE.right -= nIndex;
  160. FillRect(ps.hdc, &rcE, hBrush);
  161. }
  162. /* Draw the left edge */
  163. for (nIndex = 0; nIndex < nWidth; nIndex += 1)
  164. {
  165. rcE = rcC;
  166. rcE.left = nIndex;
  167. rcE.right = nIndex + 1;
  168. rcE.bottom -= nIndex;
  169. FillRect(ps.hdc, &rcE, hBrush);
  170. }
  171. DeleteObject(hBrush);
  172. /* Draw the bottom edge */
  173. hBrush = CreateSolidBrush(psV->cLowerEdge);
  174. for (nIndex = 0; nIndex < nHeight; nIndex += 1)
  175. {
  176. rcE = rcC;
  177. rcE.top = rcE.bottom - nIndex - 1;
  178. rcE.bottom = rcE.bottom - nIndex;
  179. rcE.left += nIndex + 1;
  180. FillRect(ps.hdc, &rcE, hBrush);
  181. }
  182. /* Draw the right edge */
  183. for (nIndex = 0; nIndex < nWidth; nIndex += 1)
  184. {
  185. rcE = rcC;
  186. rcE.left = rcE.right - nIndex - 1;
  187. rcE.right = rcE.right - nIndex;
  188. rcE.top += nIndex + 1;
  189. FillRect(ps.hdc, &rcE, hBrush);
  190. }
  191. DeleteObject(hBrush);
  192. #else
  193. DrawEdge(ps.hdc, &ps.rcPaint,
  194. EDGE_SUNKEN,
  195. BF_SOFT | BF_RECT);
  196. #endif
  197. /*
  198. * Try and fill in the progress. This is done by building
  199. * a loop the would rewrite all of the lighted 'pixels' that
  200. * would normally be light. This is then modified by checking
  201. * the intersection of the lighted region and the invalid area.
  202. * If they interset, do the write, otherwise skip it.
  203. */
  204. if ((psV->ulMaxRange > 0) &&
  205. (psV->ulCurValue > 0) &&
  206. (psV->ulHiValue > 0))
  207. {
  208. HBRUSH hbFill;
  209. HBRUSH hbRefill;
  210. /* These lines must match those in the WM_VU_SETCURVALUE */
  211. GetClientRect(hWnd, &rcC);
  212. InflateRect(&rcC,
  213. -((INT)psV->usDepth),
  214. -((INT)psV->usDepth));
  215. nEnd = rcC.right - rcC.left;
  216. nFill = (int)(((ULONG)nEnd * psV->ulCurValue) /
  217. psV->ulMaxRange);
  218. nReFill = (int)(((ULONG)nEnd * psV->ulHiValue) /
  219. psV->ulMaxRange);
  220. /* Build simulated LEDs */
  221. hbFill = CreateSolidBrush(psV->cFillColor);
  222. hbRefill = CreateSolidBrush(psV->cMarkColor);
  223. rcE = rcC;
  224. rcE.right = rcE.left + ((rcE.bottom - rcE.top) / 2);
  225. InflateRect(&rcE,
  226. (int)(rcE.left - rcE.right) / 3,
  227. (int)(rcE.top - rcE.bottom) / 3);
  228. nStep = rcE.right - rcE.left;
  229. nStep *= 2;
  230. /*
  231. * TODO: figure out how to set the beginning and end of
  232. * this loop to eliminate dead cycles
  233. */
  234. for (nIndex = 0; nIndex < nEnd; nIndex += nStep)
  235. {
  236. if (IntersectRect(&rcD, &rcE, &ps.rcPaint) != 0)
  237. {
  238. hBrush = hbFill;
  239. if (nIndex > nFill)
  240. {
  241. hBrush = hbRefill;
  242. }
  243. if (nIndex > nReFill)
  244. {
  245. hBrush = NULL;
  246. }
  247. if (hBrush != NULL)
  248. {
  249. FillRect(ps.hdc, &rcE, hBrush);
  250. }
  251. }
  252. OffsetRect(&rcE, nStep, 0);
  253. }
  254. DeleteObject(hbFill);
  255. DeleteObject(hbRefill);
  256. hBrush = NULL;
  257. }
  258. }
  259. EndPaint(hWnd, &ps);
  260. }
  261. break;
  262. case WM_VU_SETMAXRANGE:
  263. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  264. if (VUMETER_OK(psV))
  265. {
  266. psV->ulMaxRange = (ULONG)lPar;
  267. psV->ulHiValue = 0;
  268. psV->ulCurValue = 0;
  269. InvalidateRect(hWnd, NULL, FALSE);
  270. DbgOutStr("VUmeter max range %ld\r\n", lPar, 0, 0, 0, 0);
  271. }
  272. break;
  273. case WM_VU_SETHIGHVALUE:
  274. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  275. if (VUMETER_OK(psV))
  276. {
  277. if ((ULONG)lPar > psV->ulMaxRange)
  278. psV->ulHiValue = psV->ulMaxRange;
  279. else
  280. psV->ulHiValue = (ULONG)lPar;
  281. if (psV->ulCurValue > psV->ulHiValue)
  282. psV->ulCurValue = psV->ulHiValue;
  283. InvalidateRect(hWnd, NULL, FALSE);
  284. DbgOutStr("VUmeter high value %ld\r\n", lPar, 0, 0, 0, 0);
  285. }
  286. break;
  287. case WM_VU_SETCURVALUE:
  288. /*
  289. * There are two separate tasks to be performed here.
  290. * 1. Make sure the values are correctly updated.
  291. * 2. Invalidate the correct region.
  292. */
  293. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  294. if (VUMETER_OK(psV))
  295. {
  296. ULONG ulOldValue;
  297. ULONG ulLeft;
  298. ULONG ulRight;
  299. RECT rc;
  300. INT base;
  301. if (psV->ulMaxRange == 0)
  302. break;
  303. ulOldValue = psV->ulCurValue;
  304. if ((ULONG)lPar > psV->ulMaxRange)
  305. psV->ulCurValue = psV->ulMaxRange;
  306. else
  307. psV->ulCurValue = (ULONG)lPar;
  308. if (psV->ulCurValue > psV->ulHiValue)
  309. psV->ulHiValue = psV->ulCurValue;
  310. ulLeft = ulOldValue; /* Get the low end */
  311. if (psV->ulCurValue < ulLeft)
  312. ulLeft = psV->ulCurValue;
  313. ulRight = ulOldValue; /* Get the high end */
  314. if (psV->ulCurValue > ulRight)
  315. ulRight = psV->ulCurValue;
  316. /*
  317. * Check for early exit
  318. */
  319. if ((psV->ulCurValue == 0) && (psV->ulHiValue == 0))
  320. break;
  321. /* These lines must match those in WM_PAINT */
  322. GetClientRect(hWnd, &rc);
  323. InflateRect(&rc, -((INT)psV->usDepth), -((INT)psV->usDepth));
  324. base = rc.right - rc.left;
  325. ulLeft = ((ULONG)base * ulLeft) / psV->ulMaxRange;
  326. ulRight = ((ULONG)base * ulRight) / psV->ulMaxRange;
  327. base = rc.left;
  328. rc.left = base + (INT)ulLeft;
  329. #if !defined(MIRRORS)
  330. rc.right = base + (INT)ulRight;
  331. #endif
  332. InvalidateRect(hWnd, &rc, FALSE);
  333. DbgOutStr("VUmeter current value %ld\r\n", lPar, 0, 0, 0, 0);
  334. }
  335. break;
  336. case WM_VU_SET_DEPTH:
  337. psV = (LPVM)GetWindowLongPtr(hWnd, 0);
  338. if (VUMETER_OK(psV))
  339. {
  340. if (wPar < 7)
  341. {
  342. psV->usDepth = (USHORT)wPar;
  343. InvalidateRect(hWnd, NULL, FALSE);
  344. }
  345. }
  346. break;
  347. default:
  348. break;
  349. }
  350. return DefWindowProc(hWnd, wMsg, wPar, (LPARAM)lPar);
  351. }
  352. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  353. * FUNCTION:
  354. * UnregisterVuMeterClass
  355. *
  356. * DESCRIPTION:
  357. * Registers the VU Meter window class. (No kidding!)
  358. *
  359. * PARAMETERS:
  360. * Hinstance -- the instance handle
  361. *
  362. * RETURNS:
  363. * Whatever RegisterClass returns.
  364. */
  365. BOOL UnregisterVuMeterClass(HANDLE hInstance)
  366. {
  367. return UnregisterClass(VU_METER_CLASS, hInstance);
  368. }