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.

882 lines
31 KiB

  1. /* MYSTIFY.C
  2. **
  3. ** Copyright (C) Microsoft, 1991, All Rights Reserved.
  4. **
  5. ** Screensaver Control Panel Applet. This type creates one or two polygons
  6. ** which bounce around the screen.
  7. **
  8. ** History:
  9. ** 6/17/91 stevecat ported to NT Windows
  10. ** 2/10/92 stevecat snapped to latest ported to NT Windows
  11. */
  12. #define OEMRESOURCE
  13. #include <windows.h>
  14. #include <commctrl.h>
  15. #include <scrnsave.h>
  16. #include "mystify.dlg"
  17. #include "strings.h"
  18. #include "uniconv.h"
  19. // void SetFields (HWND, WORD);
  20. DWORD AdjustColor (DWORD dwSrc, DWORD dwDest, int nInc, int nCnt);
  21. LONG AppOwnerDraw (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
  22. WORD AtoI (LPTSTR lpszConvert);
  23. BOOL DrawBitmap (HDC hdc, int x, int y, HBITMAP hbm, DWORD rop);
  24. VOID DrawPolygon (HDC hDC, HPEN hPen, WORD wPolygon, WORD wLine);
  25. VOID FillR (HDC hdc, LPRECT prc, DWORD rgb);
  26. VOID FrameR (HDC hdc, LPRECT prc, DWORD rgb, int iFrame);
  27. DWORD GenerateColor (VOID);
  28. WORD GenerateVelocity (VOID);
  29. VOID GetFields (VOID);
  30. DWORD GetProfileRgb (LPTSTR szApp, LPTSTR szItem, DWORD rgb);
  31. VOID PatB (HDC hdc, int x, int y, int dx, int dy, DWORD rgb);
  32. WORD rand (VOID);
  33. VOID ShadeWindows (HWND hDlg, WORD wPoly, WORD wPolygon);
  34. VOID srand (DWORD dwSeed);
  35. #define RAND(x) ((rand () % (x))+1)
  36. #define ZRAND(x) (rand () % (x))
  37. #define rgbBlack RGB (0,0,0)
  38. #define rgbWhite RGB (255,255,255)
  39. #define rgbGrey RGB (128,128,128)
  40. #define rgbMenu GetSysColor (COLOR_MENU)
  41. #define rgbMenuText GetSysColor (COLOR_MENUTEXT)
  42. #define BUFFER_SIZE 20
  43. #define BUFFER2_SIZE 20
  44. #define NUMBER_POLYGONS 2
  45. #define MAXXVEL 12
  46. #define MAXYVEL 12
  47. #define MAXLINES 15
  48. #define NUMLINES 8
  49. TCHAR szClearName[] = TEXT("Clear Screen"); // ClearScreen .INI key
  50. DWORD dwRand = 1L; // current Random seed
  51. TCHAR szBuffer[BUFFER_SIZE]; // temp buffer
  52. TCHAR szBuffer2[BUFFER2_SIZE]; // temp buffer
  53. BOOL fOn[NUMBER_POLYGONS]; // flag for Active status of polygon
  54. BOOL fWalk[NUMBER_POLYGONS]; // color usage for each polygon
  55. WORD wLines[NUMBER_POLYGONS]; // number of lines for each polygon
  56. WORD wNumDisplay[2];
  57. WORD wFreeEntry[NUMBER_POLYGONS]; // colors for each polygon
  58. DWORD dwStartColor[NUMBER_POLYGONS];
  59. DWORD dwEndColor[NUMBER_POLYGONS];
  60. DWORD dwCurrentColor[NUMBER_POLYGONS];
  61. DWORD dwDestColor[NUMBER_POLYGONS];
  62. DWORD dwSrcColor[NUMBER_POLYGONS];
  63. WORD wIncColor[NUMBER_POLYGONS];
  64. WORD wCurInc[NUMBER_POLYGONS];
  65. TCHAR cblogpalPal[(MAXLINES*NUMBER_POLYGONS+1)
  66. *sizeof (PALETTEENTRY)+sizeof (LOGPALETTE)];
  67. POINT ptBox[MAXLINES*NUMBER_POLYGONS][4]; // array for points used in polygons
  68. LPLOGPALETTE lplogpalPal;
  69. LPPALETTEENTRY lppePal;
  70. HPALETTE hPalette;
  71. BOOL fClearScreen; // Global flag for ClearScreen state
  72. //
  73. // Help IDs
  74. //
  75. DWORD aMystDlgHelpIds[] = {
  76. ((DWORD) -1),((DWORD) -1),
  77. ID_SHAPE_LABEL, IDH_DISPLAY_SCREENSAVER_MYSTIFY_SHAPE,
  78. ID_SHAPE, IDH_DISPLAY_SCREENSAVER_MYSTIFY_SHAPE,
  79. ID_ACTIVE, IDH_DISPLAY_SCREENSAVER_MYSTIFY_ACTIVE,
  80. ID_LINES_LABEL, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
  81. ID_LINES, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
  82. ID_LINESARROW, IDH_DISPLAY_SCREENSAVER_MYSTIFY_LINES,
  83. ID_COLORGROUP, ((DWORD) -1),
  84. ID_2COLORS, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
  85. ID_COLOR1, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
  86. ID_COLOR2, IDH_DISPLAY_SCREENSAVER_MYSTIFY_TWO_COLORS,
  87. ID_RANDOMCOLORS, IDH_DISPLAY_SCREENSAVER_MYSTIFY_RANDOM_COLORS,
  88. ID_CLEARSCREEN, IDH_DISPLAY_SCREENSAVER_MYSTIFY_CLEAR_SCREEN,
  89. 0,0
  90. };
  91. LRESULT ScreenSaverProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  92. {
  93. static POINT ptChange[MAXLINES*NUMBER_POLYGONS][4];
  94. static UINT_PTR wTimer;
  95. WORD wLoop1;
  96. WORD wLoop2;
  97. WORD wMainLoop;
  98. static WORD wScreenX;
  99. static WORD wScreenY;
  100. HPEN hPen;
  101. static HPEN hErasePen;
  102. HDC hDC;
  103. HPALETTE hOldPal;
  104. switch (message)
  105. {
  106. // Things to do while setting up the window...
  107. case WM_CREATE:
  108. GetFields ();
  109. wTimer = SetTimer (hWnd, 1, 10, NULL);
  110. // Make sure we use the entire virtual desktop size for multiple
  111. // displays
  112. wScreenX = (WORD) ((LPCREATESTRUCT)lParam)->cx;
  113. wScreenY = (WORD) ((LPCREATESTRUCT)lParam)->cy;
  114. srand (GetCurrentTime ());
  115. for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
  116. {
  117. if (fOn[wMainLoop])
  118. {
  119. for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
  120. {
  121. ptBox[wMainLoop*MAXLINES][wLoop1].x = RAND (wScreenX) - 1;
  122. ptBox[wMainLoop*MAXLINES][wLoop1].y = RAND (wScreenY) - 1;
  123. if ((ptChange[wMainLoop*MAXLINES][wLoop1].x =
  124. RAND (MAXXVEL * 2)) > MAXXVEL)
  125. ptChange[wMainLoop*MAXLINES][wLoop1].x =
  126. -(ptChange[wMainLoop*MAXLINES][wLoop1].x
  127. -MAXXVEL);
  128. if ((ptChange[wMainLoop*MAXLINES][wLoop1].y =
  129. RAND (MAXYVEL * 2)) > MAXYVEL)
  130. ptChange[wMainLoop*MAXLINES][wLoop1].y =
  131. -(ptChange[wMainLoop*MAXLINES][wLoop1].y
  132. -MAXYVEL);
  133. }
  134. wNumDisplay[wMainLoop] = 1;
  135. wFreeEntry[wMainLoop] = 0;
  136. wCurInc[wMainLoop] = 0;
  137. wIncColor[wMainLoop] = 0;
  138. if (fWalk[wMainLoop])
  139. dwDestColor[wMainLoop] = GenerateColor ();
  140. else
  141. dwDestColor[wMainLoop] = dwStartColor[wMainLoop];
  142. }
  143. }
  144. lppePal = (LPPALETTEENTRY)(cblogpalPal + 4);
  145. lplogpalPal = (LPLOGPALETTE)cblogpalPal;
  146. lplogpalPal->palVersion = 0x300;
  147. lplogpalPal->palNumEntries = MAXLINES * NUMBER_POLYGONS + 1;
  148. for (wLoop1 = 0; wLoop1 <= MAXLINES * NUMBER_POLYGONS; wLoop1++)
  149. {
  150. lplogpalPal->palPalEntry[wLoop1].peRed = 0;
  151. lplogpalPal->palPalEntry[wLoop1].peGreen = 0;
  152. lplogpalPal->palPalEntry[wLoop1].peBlue = 0;
  153. lplogpalPal->palPalEntry[wLoop1].peFlags = PC_RESERVED;
  154. }
  155. hErasePen = CreatePen (PS_SOLID, 1,
  156. PALETTEINDEX (MAXLINES * NUMBER_POLYGONS));
  157. hPalette = CreatePalette (lplogpalPal);
  158. break;
  159. case WM_SIZE:
  160. wScreenX = LOWORD(lParam);
  161. wScreenY = HIWORD(lParam);
  162. break;
  163. case WM_ERASEBKGND:
  164. if (fClearScreen)
  165. break;
  166. return 0l;
  167. case WM_TIMER:
  168. // Get the display context...
  169. hDC = GetDC (hWnd);
  170. if (hDC != NULL)
  171. {
  172. // Now that we have changed the palette, make sure that it
  173. // gets updated by first unrealizing, and then realizing...
  174. hOldPal = SelectPalette (hDC, hPalette, 0);
  175. RealizePalette (hDC);
  176. for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
  177. {
  178. // Check to see if the current loop is on...
  179. if (fOn[wMainLoop])
  180. {
  181. // If our current count is the same as the final count,
  182. // generate a new count...
  183. if (wCurInc[wMainLoop] == wIncColor[wMainLoop])
  184. {
  185. // Set the count to zero...
  186. wCurInc[wMainLoop] = 0;
  187. // Set an new variant...
  188. wIncColor[wMainLoop] = GenerateVelocity ();
  189. // Set up the cycling colors...
  190. dwSrcColor[wMainLoop] = dwDestColor[wMainLoop];
  191. if (fWalk[wMainLoop])
  192. dwDestColor[wMainLoop] = GenerateColor ();
  193. else if (dwSrcColor[wMainLoop] == dwEndColor[wMainLoop])
  194. dwDestColor[wMainLoop] = dwStartColor[wMainLoop];
  195. else
  196. dwDestColor[wMainLoop] = dwEndColor[wMainLoop];
  197. }
  198. else
  199. wCurInc[wMainLoop]++;
  200. // Now adjust the color between the starting and the
  201. // ending values...
  202. dwCurrentColor[wMainLoop] = AdjustColor (dwSrcColor
  203. [wMainLoop], dwDestColor[wMainLoop], wIncColor
  204. [wMainLoop], wCurInc[wMainLoop]);
  205. wLoop2 = wFreeEntry[wMainLoop] + wMainLoop * MAXLINES;
  206. lplogpalPal->palPalEntry[wLoop2].peRed =
  207. GetRValue (dwCurrentColor[wMainLoop]);
  208. lplogpalPal->palPalEntry[wLoop2].peGreen =
  209. GetGValue (dwCurrentColor[wMainLoop]);
  210. lplogpalPal->palPalEntry[wLoop2].peBlue =
  211. GetBValue (dwCurrentColor[wMainLoop]);
  212. lplogpalPal->palPalEntry[wLoop2].peFlags = PC_RESERVED;
  213. // Adjust the palette...
  214. AnimatePalette (hPalette, wLoop2, 1,
  215. &lplogpalPal->palPalEntry[wLoop2]);
  216. }
  217. }
  218. // Now cycle through again...
  219. for (wMainLoop = 0; wMainLoop < NUMBER_POLYGONS; wMainLoop++)
  220. {
  221. if (fOn[wMainLoop])
  222. {
  223. /* If we are currently displaying all of the lines, then
  224. delete the last line... */
  225. if (wNumDisplay[wMainLoop] == wLines[wMainLoop])
  226. /* Erase the last line... */
  227. DrawPolygon (hDC, hErasePen, wMainLoop,
  228. (WORD) (wNumDisplay[wMainLoop] - 1));
  229. /* Starting with the last entry, make it equal to the
  230. entry before it... until we reach the first
  231. entry... */
  232. for (wLoop1 = (wNumDisplay[wMainLoop] - 1); wLoop1; wLoop1--)
  233. {
  234. /* Copy the points in the polygon over... */
  235. for (wLoop2 = 0; wLoop2 < 4; wLoop2++)
  236. {
  237. ptBox[wLoop1+wMainLoop*MAXLINES][wLoop2].x =
  238. ptBox[wLoop1-1+wMainLoop*MAXLINES][wLoop2].x;
  239. ptBox[wLoop1+wMainLoop*MAXLINES][wLoop2].y =
  240. ptBox[wLoop1-1+wMainLoop*MAXLINES][wLoop2].y;
  241. ptChange[wLoop1+wMainLoop*MAXLINES][wLoop2].x =
  242. ptChange[wLoop1-1+wMainLoop*MAXLINES]
  243. [wLoop2].x;
  244. ptChange[wLoop1+wMainLoop*MAXLINES][wLoop2].y =
  245. ptChange[wLoop1-1+wMainLoop*MAXLINES]
  246. [wLoop2].y;
  247. }
  248. }
  249. /* Seeing as we now have entry 0 the same as entry 1,
  250. generate a new entry 0... */
  251. for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
  252. {
  253. ptBox[wMainLoop*MAXLINES][wLoop1].x +=
  254. ptChange[wMainLoop*MAXLINES][wLoop1].x;
  255. ptBox[wMainLoop*MAXLINES][wLoop1].y +=
  256. ptChange[wMainLoop*MAXLINES][wLoop1].y;
  257. if (ptBox[wMainLoop*MAXLINES][wLoop1].x >=
  258. (int)wScreenX)
  259. {
  260. ptBox[wMainLoop*MAXLINES][wLoop1].x =
  261. ptBox[wMainLoop*MAXLINES][wLoop1].x
  262. -2 * (ptBox[wMainLoop*MAXLINES][wLoop1].x
  263. -wScreenX + 1);
  264. ptChange[wMainLoop*MAXLINES][wLoop1].x =
  265. -RAND (MAXXVEL);
  266. }
  267. if ((int)ptBox[wMainLoop*MAXLINES][wLoop1].x < 0)
  268. {
  269. ptBox[wMainLoop*MAXLINES][wLoop1].x =
  270. -ptBox[wMainLoop*MAXLINES][wLoop1].x;
  271. ptChange[wMainLoop*MAXLINES][wLoop1].x =
  272. RAND (MAXXVEL);
  273. }
  274. if (ptBox[wMainLoop*MAXLINES][wLoop1].y >=
  275. (int)wScreenY)
  276. {
  277. ptBox[wMainLoop*MAXLINES][wLoop1].y =
  278. ptBox[wMainLoop*MAXLINES][wLoop1].y - 2 *
  279. (ptBox[wMainLoop*MAXLINES][wLoop1].y
  280. -wScreenY + 1);
  281. ptChange[wMainLoop*MAXLINES][wLoop1].y =
  282. -RAND (MAXYVEL);
  283. }
  284. if ((int)ptBox[wMainLoop*MAXLINES][wLoop1].y < 0)
  285. {
  286. ptBox[wMainLoop*MAXLINES][wLoop1].y =
  287. -ptBox[wMainLoop*MAXLINES][wLoop1].y;
  288. ptChange[wMainLoop*MAXLINES][wLoop1].y =
  289. RAND (MAXYVEL);
  290. }
  291. }
  292. /* Now redraw the new line... */
  293. wLoop2 = wFreeEntry[wMainLoop] + wMainLoop * MAXLINES;
  294. hPen = CreatePen (PS_SOLID, 1, PALETTEINDEX (wLoop2));
  295. DrawPolygon (hDC, hPen, wMainLoop, 0);
  296. if (hPen)
  297. DeleteObject (hPen);
  298. /* Now, as we are finished with the entry in the
  299. palette, increment it such that the next time
  300. around, it points at the next position... */
  301. if ((++wFreeEntry[wMainLoop]) == wLines[wMainLoop])
  302. wFreeEntry[wMainLoop] = 0;
  303. /* Now, if we are not at the maximum number of lines,
  304. then increment towards there... */
  305. if (wNumDisplay[wMainLoop] < wLines[wMainLoop])
  306. wNumDisplay[wMainLoop]++;
  307. }
  308. }
  309. /* Reselect the old palette... */
  310. if (hOldPal)
  311. SelectPalette (hDC, hOldPal, FALSE);
  312. /* Release the display context... */
  313. ReleaseDC (hWnd, hDC);
  314. }
  315. break;
  316. case WM_DESTROY:
  317. if (wTimer)
  318. KillTimer (hWnd, 1);
  319. if (hPalette)
  320. DeleteObject (hPalette);
  321. if (hErasePen)
  322. DeleteObject (hErasePen);
  323. break;
  324. }
  325. return (DefScreenSaverProc (hWnd, message, wParam, lParam));
  326. }
  327. VOID srand (DWORD dwSeed)
  328. {
  329. dwRand = dwSeed;
  330. }
  331. WORD rand (VOID)
  332. {
  333. dwRand = dwRand * 214013L + 2531011L;
  334. return (WORD)((dwRand >> 16) & 0xffff);
  335. }
  336. BOOL RegisterDialogClasses (HANDLE hInst)
  337. {
  338. /* Register the custom controls.. */
  339. InitCommonControls();
  340. return TRUE;
  341. }
  342. //***************************************************************************
  343. BOOL ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  344. {
  345. WORD nPal;
  346. DWORD dwTemp = 0;
  347. HPALETTE hPal;
  348. WORD wLoop, wTemp;
  349. BOOL fError;
  350. BYTE byR, byG, byB;
  351. RECT rDlgBox;
  352. TCHAR szTemp[80];
  353. static HWND hIDOK;
  354. static WORD wPolygon;
  355. switch (message)
  356. {
  357. case WM_INITDIALOG:
  358. GetFields (); // Read fields from CONTROL.INI
  359. GetWindowRect (hDlg, (LPRECT) & rDlgBox);
  360. hIDOK = GetDlgItem (hDlg, IDOK);
  361. // Set the global clear state...
  362. CheckDlgButton (hDlg, ID_CLEARSCREEN, fClearScreen);
  363. // Fill the boxes...
  364. for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
  365. {
  366. TCHAR szBuffer[20];
  367. WORD wTemp;
  368. LoadString (hMainInstance, idsPolygon, szTemp, CharSizeOf(szTemp));
  369. wsprintf (szBuffer, szTemp, wLoop + 1);
  370. wTemp = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE, CB_ADDSTRING, 0,
  371. (LPARAM)szBuffer);
  372. SendDlgItemMessage (hDlg, ID_SHAPE, CB_SETITEMDATA, wTemp, wLoop);
  373. }
  374. hPal = GetStockObject (DEFAULT_PALETTE);
  375. GetObject (hPal, sizeof (WORD), (LPTSTR) &nPal);
  376. for (wTemp = 0; wTemp < nPal; wTemp++)
  377. {
  378. SendDlgItemMessage (hDlg, ID_COLOR1, CB_ADDSTRING, 0, (LPARAM)(LPSTR)"a");
  379. SendDlgItemMessage (hDlg, ID_COLOR2, CB_ADDSTRING, 0, (LPARAM)(LPSTR)"a");
  380. }
  381. // Start at the first polygon and let'r rip...
  382. SendDlgItemMessage (hDlg, ID_LINES, EM_LIMITTEXT, 2, 0l);
  383. SendDlgItemMessage( hDlg, ID_LINESARROW, UDM_SETRANGE, 0, MAKELONG(MAXLINES, 1));
  384. SendDlgItemMessage (hDlg, ID_SHAPE, CB_SETCURSEL, (wPolygon = 0), 0l);
  385. SendMessage (hDlg, WM_COMMAND, MAKELONG (ID_SHAPE, CBN_SELCHANGE), 0);
  386. return TRUE;
  387. case WM_COMMAND:
  388. switch (LOWORD(wParam))
  389. {
  390. // If we switch polygons, then update all of the info...
  391. case ID_SHAPE:
  392. if (HIWORD (wParam) == CBN_SELCHANGE)
  393. {
  394. WORD wTemp;
  395. wTemp = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE,
  396. CB_GETCURSEL, 0, 0l);
  397. wPolygon = (WORD)SendDlgItemMessage (hDlg, ID_SHAPE,
  398. CB_GETITEMDATA, wTemp, 0l);
  399. CheckDlgButton (hDlg, ID_ACTIVE, fOn[wPolygon]);
  400. SetDlgItemInt (hDlg, ID_LINES, wLines[wPolygon], FALSE);
  401. hPal = GetStockObject (DEFAULT_PALETTE);
  402. GetObject (hPal, sizeof (WORD), (LPTSTR) &nPal);
  403. if (SendDlgItemMessage (hDlg, ID_COLOR1, CB_SETCURSEL,
  404. GetNearestPaletteIndex (hPal, dwStartColor[wPolygon]),
  405. 0l) == CB_ERR)
  406. SendDlgItemMessage (hDlg, ID_COLOR1, CB_SETCURSEL, 0, 0l);
  407. if (SendDlgItemMessage (hDlg, ID_COLOR2, CB_SETCURSEL,
  408. GetNearestPaletteIndex (hPal, dwEndColor[wPolygon]),
  409. 0l) == CB_ERR)
  410. SendDlgItemMessage (hDlg, ID_COLOR2, CB_SETCURSEL, 0, 0l);
  411. // Set the walk state...
  412. CheckRadioButton (hDlg, ID_2COLORS, ID_RANDOMCOLORS, ID_2COLORS +
  413. fWalk[wPolygon]);
  414. // Enable/disbale windows...
  415. ShadeWindows (hDlg, wPolygon, wPolygon);
  416. }
  417. break;
  418. // Toggle the actiavtion state...
  419. case ID_ACTIVE:
  420. fOn[wPolygon] ^= 1;
  421. CheckDlgButton (hDlg, LOWORD(wParam), fOn[wPolygon]);
  422. ShadeWindows (hDlg, wPolygon, wPolygon);
  423. break;
  424. case ID_CLEARSCREEN:
  425. fClearScreen ^= 1;
  426. CheckDlgButton (hDlg, LOWORD(wParam), fClearScreen);
  427. break;
  428. case ID_COLOR1:
  429. case ID_COLOR2:
  430. if (HIWORD(wParam) == CBN_SELCHANGE)
  431. {
  432. wTemp = (WORD)SendDlgItemMessage (hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0l);
  433. hPal = GetStockObject (DEFAULT_PALETTE);
  434. GetPaletteEntries (hPal, wTemp, 1, (LPPALETTEENTRY)(LPDWORD) & dwTemp);
  435. if ( LOWORD(wParam) == ID_COLOR1 )
  436. dwStartColor[wPolygon] = dwTemp & 0xffffffL;
  437. else
  438. dwEndColor[wPolygon] = dwTemp & 0xffffffL;
  439. }
  440. break;
  441. // Toggle the walk state...
  442. case ID_2COLORS:
  443. case ID_RANDOMCOLORS:
  444. fWalk[wPolygon] = LOWORD(wParam) - ID_2COLORS;
  445. CheckRadioButton (hDlg, ID_2COLORS, ID_RANDOMCOLORS, LOWORD(wParam));
  446. EnableWindow (GetDlgItem (hDlg, ID_COLOR1), !fWalk[wPolygon]);
  447. InvalidateRect (GetDlgItem (hDlg, ID_COLOR1), NULL, TRUE);
  448. EnableWindow (GetDlgItem (hDlg, ID_COLOR2), !fWalk[wPolygon]);
  449. InvalidateRect (GetDlgItem (hDlg, ID_COLOR2), NULL, TRUE);
  450. break;
  451. // Check to see if the edit texts have lost their focus. If so
  452. // update...
  453. case ID_LINES:
  454. if (HIWORD(wParam) == EN_UPDATE)
  455. {
  456. wLoop = (WORD) GetDlgItemInt (hDlg, LOWORD(wParam), &fError, FALSE);
  457. fError = fError && (wLoop >= 1 && wLoop <= MAXLINES);
  458. EnableWindow (GetDlgItem (hDlg, ID_LINESARROW), fError);
  459. EnableWindow (GetDlgItem (hDlg, IDOK), fError);
  460. if (fError)
  461. wLines[wPolygon] = wLoop;
  462. }
  463. break;
  464. // Save the current parameters...
  465. case IDOK:
  466. wLines[wPolygon] = (WORD) GetDlgItemInt (hDlg, ID_LINES, &fError, FALSE);
  467. // Write the activation state of clearing the screen...
  468. wsprintf (szBuffer, TEXT("%d"), fClearScreen);
  469. WritePrivateProfileString (szAppName, szClearName, szBuffer, szIniFile);
  470. /* Write the updated versions of everything here... */
  471. for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
  472. {
  473. /* Set the activation state... */
  474. wsprintf (szBuffer, TEXT("Active%d"), wLoop + 1);
  475. wsprintf (szBuffer2, TEXT("%d"), fOn[wLoop]);
  476. WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
  477. /* Set the walk state... */
  478. wsprintf (szBuffer, TEXT("WalkRandom%d"), wLoop + 1);
  479. wsprintf (szBuffer2, TEXT("%d"), fWalk[wLoop]);
  480. WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
  481. /* Get the number of lines for the current polygon... */
  482. wsprintf (szBuffer, TEXT("Lines%d"), wLoop + 1);
  483. wsprintf (szBuffer2, TEXT("%d"), wLines[wLoop]);
  484. WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
  485. /* Set the start color... */
  486. wsprintf (szBuffer, TEXT("StartColor%d"), wLoop + 1);
  487. byR = GetRValue (dwStartColor[wLoop]);
  488. byG = GetGValue (dwStartColor[wLoop]);
  489. byB = GetBValue (dwStartColor[wLoop]);
  490. wsprintf (szBuffer2, TEXT("%d %d %d"), byR, byG, byB);
  491. WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
  492. /* Set the end color... */
  493. wsprintf (szBuffer, TEXT("EndColor%d"), wLoop + 1);
  494. byR = GetRValue (dwEndColor[wLoop]);
  495. byG = GetGValue (dwEndColor[wLoop]);
  496. byB = GetBValue (dwEndColor[wLoop]);
  497. wsprintf (szBuffer2, TEXT("%d %d %d"), byR, byG, byB);
  498. WritePrivateProfileString (szAppName, szBuffer, szBuffer2, szIniFile);
  499. }
  500. /* Bail out... */
  501. case IDCANCEL:
  502. EndDialog (hDlg, LOWORD(wParam) == IDOK);
  503. return TRUE;
  504. }
  505. break;
  506. case WM_DRAWITEM:
  507. return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
  508. case WM_MEASUREITEM:
  509. return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
  510. case WM_DELETEITEM:
  511. return (BOOL)AppOwnerDraw (hDlg, message, wParam, lParam);
  512. case WM_HELP: // F1
  513. WinHelp(
  514. (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  515. szHelpFile,
  516. HELP_WM_HELP,
  517. (ULONG_PTR) (LPSTR) aMystDlgHelpIds
  518. );
  519. break;
  520. case WM_CONTEXTMENU: // right mouse click
  521. WinHelp(
  522. (HWND) wParam,
  523. szHelpFile,
  524. HELP_CONTEXTMENU,
  525. (ULONG_PTR) (LPSTR) aMystDlgHelpIds
  526. );
  527. break;
  528. default:
  529. break;
  530. }
  531. return FALSE;
  532. }
  533. VOID GetFields (VOID)
  534. {
  535. WORD wLoop;
  536. //Load Global Strings from stringtable
  537. LoadString (hMainInstance, idsName, szName, CharSizeOf(szName));
  538. LoadString (hMainInstance, idsAppName, szAppName, CharSizeOf(szAppName));
  539. //Load Common Strings from stringtable...
  540. LoadString (hMainInstance, idsIniFile, szIniFile, CharSizeOf(szIniFile));
  541. LoadString (hMainInstance, idsScreenSaver, szScreenSaver, CharSizeOf(szScreenSaver));
  542. LoadString (hMainInstance, idsHelpFile, szHelpFile, CharSizeOf(szHelpFile));
  543. LoadString (hMainInstance, idsNoHelpMemory, szNoHelpMemory, CharSizeOf(szNoHelpMemory));
  544. /* Do we clear the screen when we start... */
  545. if ((fClearScreen = GetPrivateProfileInt (szAppName, szClearName, 1, szIniFile)) != 0)
  546. fClearScreen = 1;
  547. /* Loop through and get all of the field information... */
  548. for (wLoop = 0; wLoop < NUMBER_POLYGONS; wLoop++)
  549. {
  550. /* Get the activation state... */
  551. wsprintf (szBuffer, TEXT("Active%d"), wLoop + 1);
  552. if ((fOn[wLoop] = GetPrivateProfileInt (szAppName, szBuffer, 1, szIniFile)) != 0)
  553. fOn[wLoop] = 1;
  554. /* Get the walk state... */
  555. wsprintf (szBuffer, TEXT("WalkRandom%d"), wLoop + 1);
  556. if ((fWalk[wLoop] = GetPrivateProfileInt (szAppName, szBuffer, 1, szIniFile)) != 0)
  557. fWalk[wLoop] = 1;
  558. /* Get the number of lines for the current polygon... */
  559. wsprintf (szBuffer, TEXT("Lines%d"), wLoop + 1);
  560. wLines[wLoop] = (WORD) GetPrivateProfileInt (szAppName, szBuffer, 5, szIniFile);
  561. if ((int)wLines[wLoop] < 1)
  562. wLines[wLoop] = 1;
  563. if (wLines[wLoop] > MAXLINES)
  564. wLines[wLoop] = MAXLINES;
  565. /* Get the starting and ending colors (stored in DWORD format)... */
  566. wsprintf (szBuffer, TEXT("StartColor%d"), wLoop + 1);
  567. dwStartColor[wLoop] = GetProfileRgb (szAppName, szBuffer, RGB (0, 0, 0));
  568. wsprintf (szBuffer, TEXT("EndColor%d"), wLoop + 1);
  569. dwEndColor[wLoop] = GetProfileRgb (szAppName, szBuffer, RGB (255, 255, 255));
  570. }
  571. return;
  572. }
  573. VOID DrawPolygon (HDC hDC, HPEN hPen, WORD wPolygon, WORD wLine)
  574. {
  575. HANDLE hOldPen;
  576. WORD wLoop1;
  577. hOldPen = SelectObject (hDC, hPen);
  578. MoveToEx (hDC, ptBox[wPolygon*MAXLINES+wLine][0].x,
  579. ptBox[wPolygon*MAXLINES+wLine][0].y, NULL);
  580. for (wLoop1 = 0; wLoop1 < 4; wLoop1++)
  581. LineTo (hDC, ptBox[wPolygon*MAXLINES+wLine][(wLoop1+1)%4].x,
  582. ptBox[wPolygon*MAXLINES+wLine][(wLoop1+1)%4].y);
  583. if (hOldPen)
  584. SelectObject (hDC, hOldPen);
  585. return;
  586. }
  587. /* Adjust each of the rgb components according to the four input variables...*/
  588. DWORD AdjustColor (DWORD dwSrc, DWORD dwDest, int nInc, int nCnt)
  589. {
  590. DWORD dwTemp;
  591. WORD wLoop;
  592. int nSrc, nDst, nTmp;
  593. int n1, n2, n3, n4, n5;
  594. /* Nullify the end value... */
  595. dwTemp = 0;
  596. /* Cycle through and compute the difference on each byte... */
  597. for (wLoop = 0; wLoop < 3; wLoop++)
  598. {
  599. nSrc = (int)((dwSrc >> (wLoop * 8)) % 256);
  600. nDst = (int)((dwDest >> (wLoop * 8)) % 256);
  601. n1 = nDst - nSrc;
  602. n2 = n1 * 10;
  603. n3 = n2 / nInc;
  604. n4 = n3 * nCnt;
  605. n5 = n4 / 10;
  606. nTmp = nSrc + n5;
  607. dwTemp += ((DWORD)nTmp) << (wLoop * 8);
  608. }
  609. return dwTemp;
  610. }
  611. /* Compute a random color that is within the accepted norms... */
  612. DWORD GenerateColor (VOID)
  613. {
  614. return (((DWORD)ZRAND (256)) + (((DWORD)ZRAND (256)) << 8) +
  615. (((DWORD)ZRAND (256)) << 16));
  616. }
  617. /* Compute a random velocity that is within the accepted norms... */
  618. WORD GenerateVelocity (VOID)
  619. {
  620. return 255;
  621. return (RAND (30) + 20);
  622. }
  623. LONG AppOwnerDraw (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  624. {
  625. RECT rc;
  626. DWORD rgbBg;
  627. static HBITMAP hbmCheck = NULL;
  628. LPMEASUREITEMSTRUCT lpMIS = ((LPMEASUREITEMSTRUCT)lParam);
  629. LPDRAWITEMSTRUCT lpDIS = ((LPDRAWITEMSTRUCT)lParam);
  630. switch (msg)
  631. {
  632. case WM_MEASUREITEM:
  633. lpMIS->itemHeight = 15;
  634. return TRUE;
  635. case WM_DRAWITEM:
  636. rc = lpDIS->rcItem;
  637. rgbBg = PALETTEINDEX (lpDIS->itemID);
  638. if (lpDIS->itemState & ODS_SELECTED)
  639. {
  640. FrameR (lpDIS->hDC, &rc, rgbBlack, 2);
  641. InflateRect (&rc, -1, -1);
  642. FrameR (lpDIS->hDC, &rc, rgbWhite, 2);
  643. InflateRect (&rc, -1, -1);
  644. }
  645. if (lpDIS->itemState & ODS_DISABLED)
  646. FillR (lpDIS->hDC, &rc, rgbGrey);
  647. else
  648. FillR (lpDIS->hDC, &rc, rgbBg);
  649. return TRUE;
  650. case WM_DELETEITEM:
  651. return TRUE;
  652. }
  653. return TRUE;
  654. }
  655. VOID PatB (HDC hdc, int x, int y, int dx, int dy, DWORD rgb)
  656. {
  657. RECT rc;
  658. SetBkColor (hdc, rgb);
  659. rc.left = x;
  660. rc.top = y;
  661. rc.right = x + dx;
  662. rc.bottom = y + dy;
  663. ExtTextOut (hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  664. }
  665. VOID FillR (HDC hdc, LPRECT prc, DWORD rgb)
  666. {
  667. SetBkColor (hdc, rgb);
  668. ExtTextOut (hdc, 0, 0, ETO_OPAQUE, prc, NULL, 0, NULL);
  669. }
  670. VOID FrameR (HDC hdc, LPRECT prc, DWORD rgb, int iFrame)
  671. {
  672. // RECT rc;
  673. int dx, dy;
  674. dx = prc->right - prc->left;
  675. dy = prc->bottom - prc->top - 2 * iFrame;
  676. PatB (hdc, prc->left, prc->top, dx, iFrame, rgb);
  677. PatB (hdc, prc->left, prc->bottom - iFrame, dx, iFrame, rgb);
  678. PatB (hdc, prc->left, prc->top + iFrame, iFrame, dy, rgb);
  679. PatB (hdc, prc->right - iFrame, prc->top + iFrame, iFrame, dy, rgb);
  680. }
  681. BOOL DrawBitmap (HDC hdc, int x, int y, HBITMAP hbm, DWORD rop)
  682. {
  683. HDC hdcBits;
  684. BITMAP bm;
  685. // HPALETTE hpalT;
  686. HBITMAP oldbm;
  687. BOOL f;
  688. if (!hdc || !hbm)
  689. return FALSE;
  690. hdcBits = CreateCompatibleDC (hdc);
  691. GetObject (hbm, sizeof (BITMAP), (LPTSTR) & bm);
  692. oldbm = SelectObject (hdcBits, hbm);
  693. f = BitBlt (hdc, x, y, bm.bmWidth, bm.bmHeight, hdcBits, 0, 0, rop);
  694. if (oldbm)
  695. SelectObject (hdcBits, oldbm);
  696. DeleteDC (hdcBits);
  697. return f;
  698. }
  699. DWORD GetProfileRgb (LPTSTR szApp, LPTSTR szItem, DWORD rgb)
  700. {
  701. TCHAR buf[80];
  702. LPTSTR pch;
  703. WORD r, g, b;
  704. GetPrivateProfileString (szApp, szItem, TEXT(""), buf, CharSizeOf(buf), szIniFile);
  705. if (*buf)
  706. {
  707. pch = buf;
  708. r = AtoI (pch);
  709. while (*pch && *pch != TEXT(' '))
  710. pch++;
  711. while (*pch && *pch == TEXT(' '))
  712. pch++;
  713. g = AtoI (pch);
  714. while (*pch && *pch != TEXT(' '))
  715. pch++;
  716. while (*pch && *pch == TEXT(' '))
  717. pch++;
  718. b = AtoI (pch);
  719. return RGB (r, g, b);
  720. }
  721. else
  722. return rgb;
  723. }
  724. WORD AtoI (LPTSTR lpszConvert)
  725. {
  726. WORD wReturn = 0;
  727. while (*lpszConvert >= TEXT('0') && *lpszConvert <= TEXT('9'))
  728. {
  729. wReturn = wReturn * 10 + (WORD)(*lpszConvert - TEXT('0'));
  730. lpszConvert++;
  731. }
  732. return wReturn;
  733. }
  734. VOID ShadeWindows (HWND hDlg, WORD wPoly, WORD wPolygon)
  735. {
  736. EnableWindow (GetDlgItem (hDlg, ID_COLORGROUP), fOn[wPolygon]);
  737. EnableWindow (GetDlgItem (hDlg, ID_2COLORS), fOn[wPolygon]);
  738. EnableWindow (GetDlgItem (hDlg, ID_RANDOMCOLORS), fOn[wPolygon]);
  739. EnableWindow (GetDlgItem (hDlg, ID_LINES), fOn[wPolygon]);
  740. EnableWindow (GetDlgItem (hDlg, ID_LINESARROW), fOn[wPolygon]);
  741. EnableWindow (GetDlgItem (hDlg, ID_COLOR1), !fWalk[wPolygon] && fOn[wPolygon]);
  742. InvalidateRect (GetDlgItem (hDlg, ID_COLOR1), NULL, TRUE);
  743. EnableWindow (GetDlgItem (hDlg, ID_COLOR2), !fWalk[wPolygon] && fOn[wPolygon]);
  744. InvalidateRect (GetDlgItem (hDlg, ID_COLOR2), NULL, TRUE);
  745. }