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.

1548 lines
47 KiB

  1. // trialpha.cpp : Defines the entry point for the application.
  2. //
  3. #include "trialpha.h"
  4. #include "..\gpinit.inc"
  5. #define MAX_LOADSTRING 100
  6. // #define STANDALONE_DEBUG 1
  7. #ifdef STANDALONE_DEBUG
  8. // Global Variables:
  9. HINSTANCE hMainInstance = (HINSTANCE)NULL;
  10. HWND ghwndMain = (HWND)NULL;
  11. #else // !STANDALONE_DEBUG
  12. extern HINSTANCE hMainInstance;
  13. #endif // !STANDALONE_DEBUG
  14. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  15. TCHAR szWindowClass[MAX_LOADSTRING];// The title bar text
  16. UINT_PTR timerID = 0;
  17. int timercount = 0;
  18. BOOL suspend = FALSE;
  19. BOOL showconfig = FALSE;
  20. BOOL screensaver = FALSE;
  21. BOOL silent = FALSE;
  22. HWND hwndParent = (HWND)NULL;
  23. // Foward declarations of functions included in this code module:
  24. ATOM MyRegisterClass(HINSTANCE hInstance);
  25. BOOL InitInstance(HINSTANCE, int);
  26. #ifdef STANDALONE_DEBUG
  27. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  28. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  29. #else // !STANDALONE_DEBUG
  30. BOOL WINAPI RegisterDialogClasses(HANDLE hInst);
  31. LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  32. #endif // !STANDALONE_DEBUG
  33. INT_PTR CALLBACK ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
  34. //===========================================================================
  35. typedef enum
  36. {
  37. dtTriangles = 0,
  38. dtCurves = 1,
  39. dtEllipses = 2,
  40. dtRectangles = 3,
  41. dtText = 4
  42. }
  43. SHAPE;
  44. typedef struct
  45. {
  46. BYTE alpha; // Alpha value
  47. int count; // Number of simultaneous triangles
  48. int lifetime; // Number of displayed cycles
  49. int delay; // Number of cycles to delay before clearing
  50. BOOL leaveTrails;
  51. BOOL reflectVertical;
  52. BOOL reflectHorizontal;
  53. BOOL reflectDiagonal;
  54. BOOL clearScreen;
  55. BOOL oscillate;
  56. BOOL filled;
  57. int rotations;
  58. float theta; // Additional rotation applied per iteration
  59. SHAPE shape;
  60. WCHAR wchString[256];
  61. WCHAR wchFont[256];
  62. REAL textHeight;
  63. }
  64. LINESETTINGS;
  65. typedef struct
  66. {
  67. float x1;
  68. float y1;
  69. float x2;
  70. float y2;
  71. float x3;
  72. float y3;
  73. float dx1;
  74. float dy1;
  75. float dx2;
  76. float dy2;
  77. float dx3;
  78. float dy3;
  79. float r;
  80. float g;
  81. float b;
  82. float dr;
  83. float dg;
  84. float db;
  85. }
  86. LINEINFO;
  87. typedef struct
  88. {
  89. HDC hdc;
  90. HBITMAP hbmpOffscreen;
  91. HBITMAP hbmpOld;
  92. BITMAPINFO bmi;
  93. void *pvBits;
  94. }
  95. OFFSCREENINFO;
  96. //===========================================================================
  97. LINESETTINGS currentSettings =
  98. {
  99. 20, // Alpha value
  100. 1, // number of simultaneous shapes
  101. 1500, // number of displayed cycles
  102. 250, // number if cycles to pause
  103. TRUE, // leave trails
  104. FALSE, // reflect Vertical
  105. TRUE, // reflect Horizontal
  106. FALSE, // reflect Diagonal
  107. TRUE, // clear screen
  108. FALSE, // oscillate
  109. FALSE, // filled
  110. 3, // Count of rotations
  111. 0.0f, // theta
  112. dtTriangles, // shape
  113. L"Animated", // string for dtText
  114. L"Tahoma", // font for dtText
  115. 120.0f // text height for dtText
  116. };
  117. #define MAX_LINES 256
  118. LINESETTINGS dialogSettings;
  119. LINEINFO rgLineInfo[MAX_LINES];
  120. OFFSCREENINFO offscreenInfo = { 0 };
  121. //===========================================================================
  122. int GetIntValue(char *name, int value)
  123. {
  124. return GetPrivateProfileInt("Settings", name, value, "Trialpha.ini");
  125. }
  126. void SetIntValue(char *name, int value)
  127. {
  128. char szValue[80];
  129. wsprintf(szValue, "%d", value);
  130. WritePrivateProfileString("Settings", name, szValue, "Trialpha.ini");
  131. }
  132. void LoadState()
  133. {
  134. currentSettings.alpha = (BYTE)GetIntValue("Alpha", 20);
  135. currentSettings.count = GetIntValue("Count", 1);
  136. currentSettings.lifetime = GetIntValue("Lifetime", 1500);
  137. currentSettings.delay = GetIntValue("Delay", 250);
  138. currentSettings.leaveTrails = GetIntValue("LeaveTrails", 1);
  139. currentSettings.reflectVertical = GetIntValue("ReflectV", 0);
  140. currentSettings.reflectHorizontal = GetIntValue("ReflectH", 1);
  141. currentSettings.reflectDiagonal = GetIntValue("ReflectD", 0);
  142. currentSettings.clearScreen = GetIntValue("ClearScreen", 0);
  143. currentSettings.oscillate = GetIntValue("Oscillate", 0);
  144. currentSettings.filled = GetIntValue("Filled", 0);
  145. currentSettings.rotations = GetIntValue("Rotations", 3);
  146. currentSettings.theta = GetIntValue("Theta", 0) / 10.0f;
  147. currentSettings.shape = (SHAPE)GetIntValue("Shape", 0);
  148. }
  149. void SaveState()
  150. {
  151. SetIntValue("Alpha", currentSettings.alpha );
  152. SetIntValue("Count", currentSettings.count );
  153. SetIntValue("Lifetime", currentSettings.lifetime );
  154. SetIntValue("Delay", currentSettings.delay );
  155. SetIntValue("LeaveTrails", currentSettings.leaveTrails );
  156. SetIntValue("ReflectV", currentSettings.reflectVertical );
  157. SetIntValue("ReflectH", currentSettings.reflectHorizontal );
  158. SetIntValue("ReflectD", currentSettings.reflectDiagonal );
  159. SetIntValue("ClearScreen", currentSettings.clearScreen );
  160. SetIntValue("Oscillate", currentSettings.oscillate );
  161. SetIntValue("Filled", currentSettings.filled );
  162. SetIntValue("Rotations", currentSettings.rotations );
  163. SetIntValue("Theta", (int)(currentSettings.theta*10.0f));
  164. SetIntValue("Shape", (int)currentSettings.shape );
  165. }
  166. //===========================================================================
  167. void randomizelocations()
  168. {
  169. if (currentSettings.count > MAX_LINES)
  170. currentSettings.count = MAX_LINES;
  171. for(int i=0;i<currentSettings.count;i++)
  172. {
  173. rgLineInfo[i].x1 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  174. rgLineInfo[i].y1 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  175. rgLineInfo[i].x2 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  176. rgLineInfo[i].y2 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  177. rgLineInfo[i].x3 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  178. rgLineInfo[i].y3 = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  179. rgLineInfo[i].dx1 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  180. rgLineInfo[i].dy1 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  181. rgLineInfo[i].dx2 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  182. rgLineInfo[i].dy2 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  183. rgLineInfo[i].dx3 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  184. rgLineInfo[i].dy3 = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  185. if (rand() > (RAND_MAX/2))
  186. rgLineInfo[i].dx1 = -rgLineInfo[i].dx1;
  187. if (rand() > (RAND_MAX/2))
  188. rgLineInfo[i].dx2 = -rgLineInfo[i].dx2;
  189. if (rand() > (RAND_MAX/2))
  190. rgLineInfo[i].dx3 = -rgLineInfo[i].dx3;
  191. if (rand() > (RAND_MAX/2))
  192. rgLineInfo[i].dy1 = -rgLineInfo[i].dy1;
  193. if (rand() > (RAND_MAX/2))
  194. rgLineInfo[i].dy2 = -rgLineInfo[i].dy2;
  195. if (rand() > (RAND_MAX/2))
  196. rgLineInfo[i].dy3 = -rgLineInfo[i].dy3;
  197. rgLineInfo[i].dx1 /= 3.0f;
  198. rgLineInfo[i].dy1 /= 3.0f;
  199. rgLineInfo[i].dx2 /= 3.0f;
  200. rgLineInfo[i].dy2 /= 3.0f;
  201. rgLineInfo[i].dx3 /= 3.0f;
  202. rgLineInfo[i].dy3 /= 3.0f;
  203. }
  204. }
  205. void randomizecolors(int index)
  206. {
  207. if (currentSettings.count > MAX_LINES)
  208. currentSettings.count = MAX_LINES;
  209. for(int i=0;i<currentSettings.count;i++)
  210. {
  211. rgLineInfo[i].r = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  212. rgLineInfo[i].g = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  213. rgLineInfo[i].b = (rand() / REAL(RAND_MAX) * 80.0f) + 10.0f;
  214. rgLineInfo[i].dr = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  215. rgLineInfo[i].dg = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  216. rgLineInfo[i].db = (rand() / REAL(RAND_MAX) * 1.0f) + 0.5f;
  217. if (rand() > (RAND_MAX/2))
  218. rgLineInfo[i].dr = -rgLineInfo[i].dr;
  219. if (rand() > (RAND_MAX/2))
  220. rgLineInfo[i].dg = -rgLineInfo[i].dg;
  221. if (rand() > (RAND_MAX/2))
  222. rgLineInfo[i].db = -rgLineInfo[i].db;
  223. }
  224. }
  225. void FreeOffscreen()
  226. {
  227. if (offscreenInfo.hdc)
  228. {
  229. SelectObject(offscreenInfo.hdc, offscreenInfo.hbmpOld);
  230. DeleteObject(offscreenInfo.hbmpOffscreen);
  231. DeleteDC(offscreenInfo.hdc);
  232. offscreenInfo.hdc = (HDC)NULL;
  233. offscreenInfo.hbmpOffscreen = (HBITMAP)NULL;
  234. offscreenInfo.hbmpOld = (HBITMAP)NULL;
  235. offscreenInfo.bmi.bmiHeader.biWidth = 0;
  236. offscreenInfo.bmi.bmiHeader.biHeight = 0;
  237. }
  238. }
  239. void ClearOffscreen()
  240. {
  241. if (offscreenInfo.hdc)
  242. {
  243. PatBlt(
  244. offscreenInfo.hdc,
  245. 0,
  246. 0,
  247. offscreenInfo.bmi.bmiHeader.biWidth,
  248. offscreenInfo.bmi.bmiHeader.biHeight,
  249. BLACKNESS);
  250. }
  251. #ifdef STANDALONE_DEBUG
  252. InvalidateRect(ghwndMain, NULL, TRUE);
  253. #endif // STANDALONE_DEBUG
  254. }
  255. HDC GetOffscreen(HDC hDC, int width, int height)
  256. {
  257. HDC hdcResult = NULL;
  258. if (width > offscreenInfo.bmi.bmiHeader.biWidth ||
  259. height > offscreenInfo.bmi.bmiHeader.biHeight ||
  260. offscreenInfo.hdc == (HDC)NULL)
  261. {
  262. FreeOffscreen();
  263. offscreenInfo.bmi.bmiHeader.biSize = sizeof(offscreenInfo.bmi.bmiHeader);
  264. offscreenInfo.bmi.bmiHeader.biWidth = width;
  265. offscreenInfo.bmi.bmiHeader.biHeight = height;
  266. offscreenInfo.bmi.bmiHeader.biPlanes = 1;
  267. offscreenInfo.bmi.bmiHeader.biBitCount = 32;
  268. offscreenInfo.bmi.bmiHeader.biCompression = BI_RGB;
  269. offscreenInfo.bmi.bmiHeader.biSizeImage = 0;
  270. offscreenInfo.bmi.bmiHeader.biXPelsPerMeter = 10000;
  271. offscreenInfo.bmi.bmiHeader.biYPelsPerMeter = 10000;
  272. offscreenInfo.bmi.bmiHeader.biClrUsed = 0;
  273. offscreenInfo.bmi.bmiHeader.biClrImportant = 0;
  274. offscreenInfo.hbmpOffscreen = CreateDIBSection(
  275. hDC,
  276. &offscreenInfo.bmi,
  277. DIB_RGB_COLORS,
  278. &offscreenInfo.pvBits,
  279. NULL,
  280. 0);
  281. if (offscreenInfo.hbmpOffscreen)
  282. {
  283. offscreenInfo.hdc = CreateCompatibleDC(hDC);
  284. if (offscreenInfo.hdc)
  285. {
  286. offscreenInfo.hbmpOld = (HBITMAP)SelectObject(offscreenInfo.hdc, offscreenInfo.hbmpOffscreen);
  287. ClearOffscreen();
  288. }
  289. }
  290. }
  291. hdcResult = offscreenInfo.hdc;
  292. return hdcResult;
  293. }
  294. void DrawGraphics(HWND hWnd, HDC hDC, LPRECT lpRectDraw, LPRECT lpRectBounds)
  295. {
  296. RECT rectBounds;
  297. Graphics *gr = NULL;
  298. gr = new Graphics(hDC);
  299. gr->ResetTransform();
  300. gr->SetPageUnit(UnitPixel);
  301. gr->SetSmoothingMode(SmoothingModeHighQuality);
  302. gr->TranslateTransform(REAL(-0.5), REAL(-0.5));
  303. SolidBrush whiteBrush(Color(0xFF, 0xFF, 0xFF));
  304. SolidBrush blackBrush(Color(0x00, 0x00, 0x00));
  305. Pen blackPen(Color(0x00, 0x00, 0x00));
  306. Pen whitePen(Color(0xFF, 0xFF, 0xFF));
  307. FontFamily fontFamily(currentSettings.wchFont);
  308. StringFormat stringFormat(StringFormatFlagsDirectionRightToLeft);
  309. stringFormat.SetAlignment(StringAlignmentCenter);
  310. stringFormat.SetLineAlignment(StringAlignmentCenter);
  311. RectF rfDraw(REAL(lpRectDraw->left), REAL(lpRectDraw->top), REAL(lpRectDraw->right-lpRectDraw->left), REAL(lpRectDraw->bottom-lpRectDraw->top));
  312. RectF rect(-500.0f, -(currentSettings.textHeight/2.0f), 1000.0f, currentSettings.textHeight);
  313. GraphicsPath textPath;
  314. textPath.AddString(currentSettings.wchString, -1, &fontFamily, FontStyleRegular, currentSettings.textHeight, rect, &stringFormat);
  315. // This paints the background using GDI+...
  316. if (!currentSettings.leaveTrails)
  317. gr->FillRectangle(&blackBrush, rfDraw);
  318. REAL width = REAL(lpRectDraw->right - lpRectDraw->left) / REAL(100.0);
  319. REAL height = REAL(lpRectDraw->bottom - lpRectDraw->top) / REAL(100.0);
  320. if (currentSettings.count > MAX_LINES)
  321. currentSettings.count = MAX_LINES;
  322. for(int index=0;index<currentSettings.count;index++)
  323. {
  324. int i = index;
  325. BYTE r = (BYTE)(rgLineInfo[i].r * 255.0 / 100.0);
  326. BYTE g = (BYTE)(rgLineInfo[i].g * 255.0 / 100.0);
  327. BYTE b = (BYTE)(rgLineInfo[i].b * 255.0 / 100.0);
  328. SolidBrush brush(Color(currentSettings.leaveTrails ? currentSettings.alpha : 0xC0, r, g, b));
  329. Pen pen(Color(currentSettings.leaveTrails ? currentSettings.alpha : 0xC0, r, g, b), 0);
  330. BOOL fHitWall = FALSE;
  331. Rect bounds;
  332. GraphicsPath path;
  333. PointF rgPoints[4];
  334. float offsetx = 0.0f;
  335. float offsety = 0.0f;
  336. float scalex = (float)width;
  337. float scaley = (float)height;
  338. if (currentSettings.oscillate)
  339. {
  340. float ratiox = (((timercount+(index*5)) % 200) / 100.0f) - 1.0f;
  341. float ratioy = (((timercount+(index*9)) % 160) / 80.0f) - 1.0f;
  342. if (ratiox < 0.0)
  343. ratiox = -ratiox;
  344. if (ratioy < 0.0)
  345. ratioy = -ratioy;
  346. offsetx = (width * ratiox) * 50.0f;
  347. offsety = (height * ratioy) * 50.0f;
  348. scalex = (width * (1.0f - ratiox));
  349. scaley = (height * (1.0f - ratioy));
  350. }
  351. // Setup the array of points...
  352. rgPoints[0].X = offsetx + rgLineInfo[i].x1 * scalex;
  353. rgPoints[0].Y = offsety + rgLineInfo[i].y1 * scaley;
  354. rgPoints[1].X = offsetx + rgLineInfo[i].x2 * scalex;
  355. rgPoints[1].Y = offsety + rgLineInfo[i].y2 * scaley;
  356. rgPoints[2].X = offsetx + rgLineInfo[i].x3 * scalex;
  357. rgPoints[2].Y = offsety + rgLineInfo[i].y3 * scaley;
  358. rgPoints[3].X = offsetx + rgLineInfo[i].x1 * scalex;
  359. rgPoints[3].Y = offsety + rgLineInfo[i].y1 * scaley;
  360. path.Reset();
  361. switch(currentSettings.shape)
  362. {
  363. case dtCurves :
  364. {
  365. // Add 3 curve points...
  366. path.AddClosedCurve(rgPoints, 3);
  367. }
  368. break;
  369. case dtTriangles :
  370. {
  371. // Add 4 line points...
  372. path.AddLines(rgPoints, 4);
  373. }
  374. break;
  375. case dtEllipses :
  376. {
  377. // Draw an ellipse at x1, y1
  378. REAL x = rgPoints[0].X;
  379. REAL y = rgPoints[0].Y;
  380. REAL dx = rgLineInfo[i].x3 * width / 4.0f;
  381. REAL dy = rgLineInfo[i].y3 * height / 4.0f;
  382. REAL rotate = (timercount / 3.0f) + (rgLineInfo[i].x2 + rgLineInfo[i].y2) * 1.8f;
  383. rotate += (index * 360.0f) / currentSettings.count;
  384. RectF rect(x-dx/2.0f, y-dy/2.0f, dx, dy);
  385. path.AddEllipse(rect);
  386. Matrix matrix;
  387. matrix.Translate(x, y);
  388. matrix.Rotate(rotate);
  389. matrix.Translate(-x, -y);
  390. path.Transform(&matrix);
  391. }
  392. break;
  393. case dtRectangles :
  394. {
  395. // Draw a rectangle at x1, y1
  396. REAL x = rgPoints[0].X;
  397. REAL y = rgPoints[0].Y;
  398. REAL dx = rgLineInfo[i].x3 * width / 4.0f;
  399. REAL dy = rgLineInfo[i].y3 * height / 4.0f;
  400. REAL rotate = (timercount / 3.0f) + (rgLineInfo[i].x2 + rgLineInfo[i].y2) * 1.8f;
  401. rotate += (index * 360.0f) / currentSettings.count;
  402. RectF rect(x-dx/2.0f, y-dy/2.0f, dx, dy);
  403. path.AddRectangle(rect);
  404. Matrix matrix;
  405. matrix.Translate(x, y);
  406. matrix.Rotate(rotate);
  407. matrix.Translate(-x, -y);
  408. path.Transform(&matrix);
  409. }
  410. break;
  411. case dtText:
  412. {
  413. // Draw text in a rectangle bounded by x1, y1, x2, y2:
  414. REAL x = rgPoints[0].X;
  415. REAL y = rgPoints[0].Y;
  416. REAL scale = (rgLineInfo[i].x3+rgLineInfo[i].y3) / 200.0f;
  417. REAL rotate = (timercount / 3.0f) + (rgLineInfo[i].x2 + rgLineInfo[i].y2) * 1.8f;
  418. rotate += (index * 360.0f) / currentSettings.count;
  419. path.AddPath(&textPath, FALSE);
  420. Matrix matrix;
  421. matrix.Translate(x, y);
  422. matrix.Rotate(rotate);
  423. matrix.Scale(scale, scale);
  424. path.Transform(&matrix);
  425. }
  426. break;
  427. }
  428. for(int k=0;k<currentSettings.rotations;k++)
  429. {
  430. Matrix rotation;
  431. rotation.Translate(width * 50.0f, height * 50.0f);
  432. rotation.Rotate((currentSettings.theta * timercount) + (k * 360.0f) / currentSettings.rotations);
  433. rotation.Translate(width * -50.0f, height * -50.0f);
  434. path.Transform(&rotation);
  435. rotation.Invert();
  436. if (currentSettings.filled)
  437. gr->FillPath(&brush, &path);
  438. else
  439. gr->DrawPath(&pen, &path);
  440. path.GetBounds(&bounds);
  441. if ((k == 0) && (i == 0))
  442. {
  443. rectBounds.left = bounds.X;
  444. rectBounds.right = bounds.X + bounds.Width;
  445. rectBounds.top = bounds.Y;
  446. rectBounds.bottom = bounds.Y + bounds.Height;
  447. }
  448. else
  449. {
  450. rectBounds.left = min(bounds.X, rectBounds.left);
  451. rectBounds.top = min(bounds.Y, rectBounds.top);
  452. rectBounds.right = max(bounds.X + bounds.Width, rectBounds.right);
  453. rectBounds.bottom = max(bounds.Y + bounds.Height, rectBounds.bottom);
  454. }
  455. if (currentSettings.reflectVertical)
  456. {
  457. Matrix matrix;
  458. matrix.Translate(0.0f, height * 100.0f);
  459. matrix.Scale(1.0f, -1.0f);
  460. path.Transform(&matrix);
  461. if (currentSettings.filled)
  462. gr->FillPath(&brush, &path);
  463. else
  464. gr->DrawPath(&pen, &path);
  465. path.GetBounds(&bounds);
  466. rectBounds.left = min(bounds.X, rectBounds.left);
  467. rectBounds.top = min(bounds.Y, rectBounds.top);
  468. rectBounds.right = max(bounds.X + bounds.Width, rectBounds.right);
  469. rectBounds.bottom = max(bounds.Y + bounds.Height, rectBounds.bottom);
  470. matrix.Invert();
  471. path.Transform(&matrix);
  472. }
  473. if (currentSettings.reflectHorizontal)
  474. {
  475. Matrix matrix;
  476. matrix.Translate(width*100.0f, 0.0f);
  477. matrix.Scale(-1.0f, 1.0f);
  478. path.Transform(&matrix);
  479. if (currentSettings.filled)
  480. gr->FillPath(&brush, &path);
  481. else
  482. gr->DrawPath(&pen, &path);
  483. path.GetBounds(&bounds);
  484. rectBounds.left = min(bounds.X, rectBounds.left);
  485. rectBounds.top = min(bounds.Y, rectBounds.top);
  486. rectBounds.right = max(bounds.X + bounds.Width, rectBounds.right);
  487. rectBounds.bottom = max(bounds.Y + bounds.Height, rectBounds.bottom);
  488. matrix.Invert();
  489. path.Transform(&matrix);
  490. }
  491. if (currentSettings.reflectDiagonal)
  492. {
  493. Matrix matrix;
  494. matrix.Translate(width*100.0f, height*100.0f);
  495. matrix.Scale(-1.0f, -1.0f);
  496. path.Transform(&matrix);
  497. if (currentSettings.filled)
  498. gr->FillPath(&brush, &path);
  499. else
  500. gr->DrawPath(&pen, &path);
  501. path.GetBounds(&bounds);
  502. rectBounds.left = min(bounds.X, rectBounds.left);
  503. rectBounds.top = min(bounds.Y, rectBounds.top);
  504. rectBounds.right = max(bounds.X + bounds.Width, rectBounds.right);
  505. rectBounds.bottom = max(bounds.Y + bounds.Height, rectBounds.bottom);
  506. matrix.Invert();
  507. path.Transform(&matrix);
  508. }
  509. path.Transform(&rotation);
  510. }
  511. if (!suspend)
  512. {
  513. rgLineInfo[i].x1 += rgLineInfo[i].dx1;
  514. rgLineInfo[i].y1 += rgLineInfo[i].dy1;
  515. rgLineInfo[i].x2 += rgLineInfo[i].dx2;
  516. rgLineInfo[i].y2 += rgLineInfo[i].dy2;
  517. rgLineInfo[i].x3 += rgLineInfo[i].dx3;
  518. rgLineInfo[i].y3 += rgLineInfo[i].dy3;
  519. rgLineInfo[i].r += rgLineInfo[i].dr;
  520. rgLineInfo[i].g += rgLineInfo[i].dg;
  521. rgLineInfo[i].b += rgLineInfo[i].db;
  522. if (rgLineInfo[i].x1 < 5.0 || rgLineInfo[i].x1 > 95.0)
  523. {
  524. rgLineInfo[i].dx1 = -rgLineInfo[i].dx1;
  525. fHitWall = TRUE;
  526. }
  527. if (rgLineInfo[i].y1 < 5.0 || rgLineInfo[i].y1 > 95.0)
  528. {
  529. rgLineInfo[i].dy1 = -rgLineInfo[i].dy1;
  530. fHitWall = TRUE;
  531. }
  532. if (rgLineInfo[i].x2 < 5.0 || rgLineInfo[i].x2 > 95.0)
  533. {
  534. rgLineInfo[i].dx2 = -rgLineInfo[i].dx2;
  535. fHitWall = TRUE;
  536. }
  537. if (rgLineInfo[i].y2 < 5.0 || rgLineInfo[i].y2 > 95.0)
  538. {
  539. rgLineInfo[i].dy2 = -rgLineInfo[i].dy2;
  540. fHitWall = TRUE;
  541. }
  542. if (rgLineInfo[i].x3 < 5.0 || rgLineInfo[i].x3 > 95.0)
  543. {
  544. rgLineInfo[i].dx3 = -rgLineInfo[i].dx3;
  545. fHitWall = TRUE;
  546. }
  547. if (rgLineInfo[i].y3 < 5.0 || rgLineInfo[i].y3 > 95.0)
  548. {
  549. rgLineInfo[i].dy3 = -rgLineInfo[i].dy3;
  550. fHitWall = TRUE;
  551. }
  552. if (rgLineInfo[i].r < 5.0 || rgLineInfo[i].r > 95.0)
  553. rgLineInfo[i].dr = -rgLineInfo[i].dr;
  554. if (rgLineInfo[i].g < 5.0 || rgLineInfo[i].g > 95.0)
  555. rgLineInfo[i].dg = -rgLineInfo[i].dg;
  556. if (rgLineInfo[i].b < 5.0 || rgLineInfo[i].b > 95.0)
  557. rgLineInfo[i].db = -rgLineInfo[i].db;
  558. }
  559. }
  560. if (lpRectBounds)
  561. {
  562. *lpRectBounds = rectBounds;
  563. }
  564. delete gr;
  565. }
  566. LRESULT PaintWnd(HWND hWnd, HDC hDC)
  567. {
  568. HBRUSH hBrush, hBrushOld;
  569. HPEN hPen, hPenOld;
  570. RECT rectClient;
  571. RECT rectDraw;
  572. hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
  573. hPen = (HPEN)GetStockObject(BLACK_PEN);
  574. hBrushOld = (HBRUSH)SelectObject(hDC, hBrush);
  575. hPenOld = (HPEN)SelectObject(hDC, hPen);
  576. GetClientRect(hWnd, &rectClient);
  577. int width = rectClient.right - rectClient.left;
  578. int height = rectClient.bottom - rectClient.top;
  579. // Setup the drawing rectangle relative to the client (inset 5 pixels)
  580. rectDraw.left = 0;
  581. rectDraw.top = 0;
  582. rectDraw.right = (rectClient.right - rectClient.left);
  583. rectDraw.bottom = (rectClient.bottom - rectClient.top);
  584. // Now draw within this rectangle with GDI+ ...
  585. if (currentSettings.clearScreen)
  586. {
  587. // Render everything to an offscreen buffer instead of
  588. // directly to the display surface...
  589. HDC hdcOffscreen = NULL;
  590. int width, height;
  591. RECT rectOffscreen;
  592. width = rectDraw.right - rectDraw.left;
  593. height = rectDraw.bottom - rectDraw.top;
  594. rectOffscreen.left = 0;
  595. rectOffscreen.top = 0;
  596. rectOffscreen.right = width;
  597. rectOffscreen.bottom = height;
  598. hdcOffscreen = GetOffscreen(hDC, width, height);
  599. if (hdcOffscreen)
  600. {
  601. if (!currentSettings.leaveTrails)
  602. {
  603. PatBlt(hdcOffscreen, 0, 0, width, height, BLACKNESS);
  604. }
  605. DrawGraphics(hWnd, hdcOffscreen, &rectOffscreen, NULL);
  606. StretchBlt(
  607. hDC,
  608. rectDraw.left,
  609. rectDraw.top,
  610. width,
  611. height,
  612. hdcOffscreen,
  613. 0,
  614. 0,
  615. width,
  616. height,
  617. SRCCOPY);
  618. }
  619. ReleaseDC(hWnd, hDC);
  620. }
  621. SelectObject(hDC, hBrushOld);
  622. SelectObject(hDC, hPenOld);
  623. return 0;
  624. }
  625. static RECT rectLast = {0, 0, 0, 0};
  626. #ifdef STANDALONE_DEBUG
  627. int cmpi(char *s1, char *s2)
  628. {
  629. int result = 0;
  630. if (s1 && s2)
  631. {
  632. while((*s1 == *s2) && *s1)
  633. {
  634. s1++;
  635. s2++;
  636. }
  637. if (*s1 && *s2)
  638. result = *s1 - *s2;
  639. else
  640. result = *(s1-1) - *(s2-1);
  641. }
  642. return result;
  643. }
  644. void ParseCommandLine(LPSTR lpCmdLine)
  645. {
  646. if (!cmpi(lpCmdLine,"/s") ||
  647. !cmpi(lpCmdLine,"-s") ||
  648. !cmpi(lpCmdLine,"s"))
  649. {
  650. screensaver = TRUE;
  651. }
  652. if (!cmpi(lpCmdLine,"/c") ||
  653. !cmpi(lpCmdLine,"-c") ||
  654. !cmpi(lpCmdLine,"c"))
  655. {
  656. // Run config with current window as parent.
  657. showconfig = TRUE;
  658. screensaver = TRUE;
  659. }
  660. // In-Place preview
  661. if (!cmpi(lpCmdLine, "/p") ||
  662. !cmpi(lpCmdLine, "-p") ||
  663. !cmpi(lpCmdLine, "p"))
  664. {
  665. char *p = lpCmdLine;
  666. int handle = 0;
  667. while(*p)
  668. {
  669. switch(*p)
  670. {
  671. case '0' :
  672. case '1' :
  673. case '2' :
  674. case '3' :
  675. case '4' :
  676. case '5' :
  677. case '6' :
  678. case '7' :
  679. case '8' :
  680. case '9' :
  681. handle *= 10;
  682. handle += *p-'0';
  683. break;
  684. }
  685. p++;
  686. }
  687. screensaver = TRUE;
  688. silent = TRUE;
  689. hwndParent = (HWND)handle;
  690. }
  691. if (!cmpi(lpCmdLine,"/t") ||
  692. !cmpi(lpCmdLine,"-t") ||
  693. !cmpi(lpCmdLine,"t"))
  694. {
  695. screensaver = FALSE;
  696. }
  697. }
  698. int APIENTRY WinMain(
  699. HINSTANCE hInstance,
  700. HINSTANCE hPrevInstance,
  701. LPSTR lpCmdLine,
  702. int nCmdShow)
  703. {
  704. MSG msg;
  705. HACCEL hAccelTable;
  706. // Parse the command line...
  707. ParseCommandLine(lpCmdLine);
  708. if (!gGdiplusInitHelper.IsValid())
  709. return 0;
  710. srand(GetTickCount());
  711. randomizelocations();
  712. randomizecolors(-1);
  713. // Initialize global strings
  714. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  715. LoadString(hInstance, IDC_TRIALPHA, szWindowClass, MAX_LOADSTRING);
  716. MyRegisterClass(hInstance);
  717. // Perform application initialization:
  718. if (!InitInstance (hInstance, nCmdShow))
  719. {
  720. return FALSE;
  721. }
  722. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_TRIALPHA);
  723. // Main message loop:
  724. while (GetMessage(&msg, NULL, 0, 0))
  725. {
  726. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  727. {
  728. TranslateMessage(&msg);
  729. DispatchMessage(&msg);
  730. }
  731. }
  732. FreeOffscreen();
  733. return (int)msg.wParam;
  734. }
  735. //
  736. // FUNCTION: MyRegisterClass()
  737. //
  738. // PURPOSE: Registers the window class.
  739. //
  740. // COMMENTS:
  741. //
  742. // This function and its usage is only necessary if you want this code
  743. // to be compatible with Win32 systems prior to the 'RegisterClassEx'
  744. // function that was added to Windows 95. It is important to call this function
  745. // so that the application will get 'well formed' small icons associated
  746. // with it.
  747. //
  748. ATOM MyRegisterClass(HINSTANCE hInstance)
  749. {
  750. WNDCLASSEX wcex;
  751. wcex.cbSize = sizeof(WNDCLASSEX);
  752. wcex.style = CS_HREDRAW | CS_VREDRAW;
  753. wcex.lpfnWndProc = WndProc;
  754. wcex.cbClsExtra = 0;
  755. wcex.cbWndExtra = 0;
  756. wcex.hInstance = hInstance;
  757. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_TRIALPHA);
  758. if (screensaver)
  759. wcex.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_NULL));
  760. else
  761. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  762. wcex.hbrBackground = (HBRUSH)NULL;
  763. if (screensaver)
  764. wcex.lpszMenuName = (LPCSTR)NULL;
  765. else
  766. wcex.lpszMenuName = (LPCSTR)IDC_TRIALPHA;
  767. wcex.lpszClassName = szWindowClass;
  768. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  769. return RegisterClassEx(&wcex);
  770. }
  771. //
  772. // FUNCTION: InitInstance(HANDLE, int)
  773. //
  774. // PURPOSE: Saves instance handle and creates main window
  775. //
  776. // COMMENTS:
  777. //
  778. // In this function, we save the instance handle in a global variable and
  779. // create and display the main program window.
  780. //
  781. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  782. {
  783. RECT rectDesktop;
  784. RECT rectWnd;
  785. HWND hWndDesktop = GetDesktopWindow();
  786. hMainInstance = hInstance; // Store instance handle in our global variable
  787. if (screensaver)
  788. {
  789. if (silent)
  790. {
  791. GetWindowRect(hwndParent, &rectWnd);
  792. }
  793. else
  794. {
  795. rectWnd.left = 0;
  796. rectWnd.top = 0;
  797. rectWnd.right = GetSystemMetrics(SM_CXSCREEN);
  798. rectWnd.bottom = GetSystemMetrics(SM_CYSCREEN);
  799. }
  800. ghwndMain = CreateWindowEx(
  801. WS_EX_TOPMOST,
  802. szWindowClass,
  803. NULL,
  804. WS_POPUP,
  805. rectWnd.left, rectWnd.top,
  806. rectWnd.right - rectWnd.left, rectWnd.bottom - rectWnd.top,
  807. NULL,
  808. NULL,
  809. hInstance,
  810. NULL);
  811. }
  812. else
  813. {
  814. GetWindowRect(hWndDesktop, &rectDesktop);
  815. rectWnd = rectDesktop;
  816. rectWnd.top += 100;
  817. rectWnd.left += 100;
  818. rectWnd.right -= 100;
  819. rectWnd.bottom -= 100;
  820. ghwndMain = CreateWindow(
  821. szWindowClass,
  822. szTitle,
  823. WS_OVERLAPPEDWINDOW,
  824. rectWnd.left, rectWnd.top,
  825. rectWnd.right - rectWnd.left, rectWnd.bottom - rectWnd.top,
  826. NULL,
  827. NULL,
  828. hInstance,
  829. NULL);
  830. }
  831. if (!ghwndMain)
  832. {
  833. return FALSE;
  834. }
  835. if (!showconfig)
  836. {
  837. ShowWindow(ghwndMain, nCmdShow);
  838. UpdateWindow(ghwndMain);
  839. }
  840. timerID = SetTimer(ghwndMain, 1, 10, NULL);
  841. return TRUE;
  842. }
  843. //
  844. // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  845. //
  846. // PURPOSE: Processes messages for the main window.
  847. //
  848. // WM_COMMAND - process the application menu
  849. // WM_PAINT - Paint the main window
  850. // WM_DESTROY - post a quit message and return
  851. //
  852. //
  853. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  854. {
  855. LRESULT lresult = 0;
  856. switch (message)
  857. {
  858. case WM_WINDOWPOSCHANGED:
  859. {
  860. timercount = 0;
  861. ClearOffscreen();
  862. lresult = DefWindowProc(hWnd, message, wParam, lParam);
  863. }
  864. break;
  865. case WM_LBUTTONDOWN:
  866. {
  867. timercount = 0;
  868. currentSettings.leaveTrails = !currentSettings.leaveTrails;
  869. ClearOffscreen();
  870. }
  871. break;
  872. case WM_RBUTTONDOWN:
  873. {
  874. randomizecolors(-1);
  875. }
  876. break;
  877. case WM_TIMER:
  878. {
  879. if (!suspend)
  880. {
  881. if (timercount >= currentSettings.lifetime && currentSettings.leaveTrails)
  882. {
  883. if ((timercount - currentSettings.lifetime) > currentSettings.delay)
  884. {
  885. timercount = 0;
  886. InvalidateRect(hWnd, NULL, TRUE);
  887. randomizelocations();
  888. randomizecolors(-1);
  889. ClearOffscreen();
  890. }
  891. }
  892. else
  893. {
  894. // Render everything to an offscreen buffer instead of
  895. // directly to the display surface...
  896. HDC hdcOffscreen = NULL;
  897. int width, height;
  898. HDC hDC = GetDC(hWnd);
  899. RECT rectClient;
  900. RECT rectOffscreen;
  901. GetClientRect(hWnd, &rectClient);
  902. width = rectClient.right - rectClient.left;
  903. height = rectClient.bottom - rectClient.top;
  904. rectOffscreen.left = 0;
  905. rectOffscreen.top = 0;
  906. rectOffscreen.right = width;
  907. rectOffscreen.bottom = height;
  908. hdcOffscreen = GetOffscreen(hDC, width, height);
  909. if (hdcOffscreen)
  910. {
  911. RECT rectBounds;
  912. if (!currentSettings.leaveTrails)
  913. {
  914. PatBlt(hdcOffscreen, 0, 0, width, height, BLACKNESS);
  915. }
  916. DrawGraphics(hWnd, hdcOffscreen, &rectOffscreen, &rectBounds);
  917. RECT rectBlt = rectBounds;
  918. if (!currentSettings.leaveTrails)
  919. {
  920. rectBlt.left = min(rectBlt.left, rectLast.left);
  921. rectBlt.top = min(rectBlt.top, rectLast.top);
  922. rectBlt.right = max(rectBlt.right, rectLast.right);
  923. rectBlt.bottom = max(rectBlt.bottom, rectLast.bottom);
  924. }
  925. StretchBlt(
  926. hDC,
  927. rectClient.left + rectBlt.left,
  928. rectClient.top + rectBlt.top,
  929. rectBlt.right - rectBlt.left,
  930. rectBlt.bottom - rectBlt.top,
  931. hdcOffscreen,
  932. rectBlt.left,
  933. rectBlt.top,
  934. rectBlt.right - rectBlt.left,
  935. rectBlt.bottom - rectBlt.top,
  936. SRCCOPY);
  937. rectLast = rectBounds;
  938. }
  939. ReleaseDC(hWnd, hDC);
  940. }
  941. timercount++;
  942. }
  943. }
  944. break;
  945. case WM_COMMAND:
  946. {
  947. int wmId, wmEvent;
  948. wmId = LOWORD(wParam);
  949. wmEvent = HIWORD(wParam);
  950. // Parse the menu selections:
  951. switch (wmId)
  952. {
  953. case IDM_SETTINGS:
  954. {
  955. suspend = TRUE;
  956. if (DialogBox(hMainInstance, (LPCTSTR)DLG_SCRNSAVECONFIGURE, hWnd, ScreenSaverConfigureDialog) == IDOK)
  957. {
  958. timercount = 0;
  959. randomizelocations();
  960. randomizecolors(-1);
  961. ClearOffscreen();
  962. }
  963. InvalidateRect(hWnd, NULL, TRUE);
  964. suspend = FALSE;
  965. if (showconfig)
  966. PostQuitMessage(0);
  967. }
  968. break;
  969. case IDM_ABOUT:
  970. DialogBox(hMainInstance, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
  971. break;
  972. case IDM_EXIT:
  973. DestroyWindow(hWnd);
  974. break;
  975. default:
  976. lresult = DefWindowProc(hWnd, message, wParam, lParam);
  977. break;
  978. }
  979. }
  980. break;
  981. case WM_PAINT:
  982. {
  983. PAINTSTRUCT ps;
  984. HDC hdc;
  985. hdc = BeginPaint(hWnd, &ps);
  986. lresult = PaintWnd(hWnd, hdc);
  987. EndPaint(hWnd, &ps);
  988. return lresult;
  989. }
  990. break;
  991. case WM_DESTROY:
  992. {
  993. PostQuitMessage(0);
  994. }
  995. break;
  996. default:
  997. lresult = DefWindowProc(hWnd, message, wParam, lParam);
  998. }
  999. return lresult;
  1000. }
  1001. // Message handler for about box.
  1002. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1003. {
  1004. LRESULT lresult = 0;
  1005. switch (message)
  1006. {
  1007. case WM_INITDIALOG:
  1008. lresult = TRUE;
  1009. break;
  1010. case WM_COMMAND:
  1011. {
  1012. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  1013. {
  1014. EndDialog(hDlg, LOWORD(wParam));
  1015. lresult = TRUE;
  1016. }
  1017. }
  1018. break;
  1019. }
  1020. return lresult;
  1021. }
  1022. #else // !STANDALONE_DEBUG
  1023. BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
  1024. {
  1025. return TRUE;
  1026. }
  1027. LRESULT WINAPI ScreenSaverProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1028. {
  1029. LRESULT lresult = 0;
  1030. switch(message)
  1031. {
  1032. case WM_CREATE:
  1033. {
  1034. if (!gGdiplusInitHelper.IsValid())
  1035. return 0;
  1036. srand(GetTickCount());
  1037. LoadState();
  1038. randomizelocations();
  1039. randomizecolors(-1);
  1040. timerID = SetTimer(hwnd, 1, 10, NULL);
  1041. }
  1042. break;
  1043. case WM_TIMER:
  1044. {
  1045. if (!suspend)
  1046. {
  1047. if (timercount >= currentSettings.lifetime && currentSettings.leaveTrails)
  1048. {
  1049. if ((timercount - currentSettings.lifetime) > currentSettings.delay)
  1050. {
  1051. timercount = 0;
  1052. InvalidateRect(hwnd, NULL, TRUE);
  1053. randomizelocations();
  1054. randomizecolors(-1);
  1055. ClearOffscreen();
  1056. }
  1057. }
  1058. else
  1059. {
  1060. // Render everything to an offscreen buffer instead of
  1061. // directly to the display surface...
  1062. HDC hdcOffscreen = NULL;
  1063. int width, height;
  1064. HDC hDC = GetDC(hwnd);
  1065. RECT rectClient;
  1066. RECT rectOffscreen;
  1067. GetClientRect(hwnd, &rectClient);
  1068. width = rectClient.right - rectClient.left;
  1069. height = rectClient.bottom - rectClient.top;
  1070. rectOffscreen.left = 0;
  1071. rectOffscreen.top = 0;
  1072. rectOffscreen.right = width;
  1073. rectOffscreen.bottom = height;
  1074. hdcOffscreen = GetOffscreen(hDC, width, height);
  1075. if (hdcOffscreen)
  1076. {
  1077. RECT rectBounds;
  1078. if (!currentSettings.leaveTrails)
  1079. {
  1080. PatBlt(hdcOffscreen, 0, 0, width, height, BLACKNESS);
  1081. }
  1082. DrawGraphics(hwnd, hdcOffscreen, &rectOffscreen, &rectBounds);
  1083. RECT rectBlt = rectBounds;
  1084. if (!currentSettings.leaveTrails)
  1085. {
  1086. rectBlt.left = min(rectBlt.left, rectLast.left);
  1087. rectBlt.top = min(rectBlt.top, rectLast.top);
  1088. rectBlt.right = max(rectBlt.right, rectLast.right);
  1089. rectBlt.bottom = max(rectBlt.bottom, rectLast.bottom);
  1090. }
  1091. StretchBlt(
  1092. hDC,
  1093. rectClient.left + rectBlt.left,
  1094. rectClient.top + rectBlt.top,
  1095. rectBlt.right - rectBlt.left,
  1096. rectBlt.bottom - rectBlt.top,
  1097. hdcOffscreen,
  1098. rectBlt.left,
  1099. rectBlt.top,
  1100. rectBlt.right - rectBlt.left,
  1101. rectBlt.bottom - rectBlt.top,
  1102. SRCCOPY);
  1103. rectLast = rectBounds;
  1104. }
  1105. ReleaseDC(hwnd, hDC);
  1106. }
  1107. timercount++;
  1108. }
  1109. }
  1110. break;
  1111. case WM_PAINT:
  1112. {
  1113. PAINTSTRUCT ps;
  1114. HDC hdc;
  1115. hdc = BeginPaint(hwnd, &ps);
  1116. lresult = PaintWnd(hwnd, hdc);
  1117. EndPaint(hwnd, &ps);
  1118. return lresult;
  1119. }
  1120. break;
  1121. case WM_DESTROY:
  1122. KillTimer(hwnd, timerID);
  1123. FreeOffscreen();
  1124. break;
  1125. }
  1126. lresult = DefScreenSaverProc(hwnd, message, wParam, lParam);
  1127. return lresult;
  1128. }
  1129. #endif // !STANDALONE_DEBUG
  1130. // Message handler for settings dlg
  1131. INT_PTR CALLBACK ScreenSaverConfigureDialog (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1132. {
  1133. LRESULT lresult = 0;
  1134. switch (message)
  1135. {
  1136. case WM_INITDIALOG:
  1137. {
  1138. LoadState();
  1139. // Set the current values into the dialog controls...
  1140. dialogSettings = currentSettings;
  1141. SetDlgItemInt(hDlg, IDC_COUNT, dialogSettings.count, FALSE);
  1142. SetDlgItemInt(hDlg, IDC_ALPHA, dialogSettings.alpha, FALSE);
  1143. SetDlgItemInt(hDlg, IDC_LIFETIME, dialogSettings.lifetime, FALSE);
  1144. SetDlgItemInt(hDlg, IDC_DELAY, dialogSettings.delay, FALSE);
  1145. SetDlgItemInt(hDlg, IDC_ROTATIONS,dialogSettings.rotations, FALSE);
  1146. SetDlgItemInt(hDlg, IDC_THETA, (int)(dialogSettings.theta * 10), TRUE);
  1147. for(int i=dtTriangles;i<=dtText;i++)
  1148. {
  1149. char szShape[256];
  1150. LoadString(hMainInstance, IDS_SHAPE_BASE + i, szShape, sizeof(szShape));
  1151. SendMessage(GetDlgItem(hDlg, IDC_SHAPE), CB_ADDSTRING, 0, (LPARAM)szShape);
  1152. }
  1153. SendMessage(GetDlgItem(hDlg, IDC_SHAPE), CB_SETCURSEL, (WPARAM)dialogSettings.shape, 0);
  1154. SendMessage(GetDlgItem(hDlg, IDC_LEAVETRAILS), BM_SETCHECK, dialogSettings.leaveTrails ? BST_CHECKED : BST_UNCHECKED, 0);
  1155. SendMessage(GetDlgItem(hDlg, IDC_CLEARSCREEN), BM_SETCHECK, dialogSettings.clearScreen ? BST_CHECKED : BST_UNCHECKED, 0);
  1156. SendMessage(GetDlgItem(hDlg, IDC_REFLECTVERT), BM_SETCHECK, dialogSettings.reflectVertical ? BST_CHECKED : BST_UNCHECKED, 0);
  1157. SendMessage(GetDlgItem(hDlg, IDC_REFLECTHORZ), BM_SETCHECK, dialogSettings.reflectHorizontal ? BST_CHECKED : BST_UNCHECKED, 0);
  1158. SendMessage(GetDlgItem(hDlg, IDC_REFLECTDIAG), BM_SETCHECK, dialogSettings.reflectDiagonal ? BST_CHECKED : BST_UNCHECKED, 0);
  1159. SendMessage(GetDlgItem(hDlg, IDC_OSCILLATE), BM_SETCHECK, dialogSettings.oscillate ? BST_CHECKED : BST_UNCHECKED, 0);
  1160. SendMessage(GetDlgItem(hDlg, IDC_FILLED), BM_SETCHECK, dialogSettings.filled ? BST_CHECKED : BST_UNCHECKED, 0);
  1161. lresult = TRUE;
  1162. }
  1163. break;
  1164. case WM_COMMAND:
  1165. {
  1166. switch (LOWORD(wParam))
  1167. {
  1168. case IDC_COUNT :
  1169. dialogSettings.count = GetDlgItemInt(hDlg, IDC_COUNT, NULL, FALSE);
  1170. if (dialogSettings.count > MAX_LINES)
  1171. dialogSettings.count = MAX_LINES;
  1172. break;
  1173. case IDC_ALPHA :
  1174. dialogSettings.alpha = (BYTE)GetDlgItemInt(hDlg, IDC_ALPHA, NULL, FALSE);
  1175. break;
  1176. case IDC_LIFETIME:
  1177. dialogSettings.lifetime = GetDlgItemInt(hDlg, IDC_LIFETIME, NULL, FALSE);
  1178. if (dialogSettings.lifetime > 10000)
  1179. dialogSettings.lifetime = 10000;
  1180. break;
  1181. case IDC_DELAY :
  1182. dialogSettings.delay = GetDlgItemInt(hDlg, IDC_DELAY, NULL, FALSE);
  1183. if (dialogSettings.delay > 10000)
  1184. dialogSettings.delay = 10000;
  1185. break;
  1186. case IDC_ROTATIONS :
  1187. dialogSettings.rotations = GetDlgItemInt(hDlg, IDC_ROTATIONS, NULL, FALSE);
  1188. if (dialogSettings.rotations > 90)
  1189. dialogSettings.rotations = 90;
  1190. break;
  1191. case IDC_THETA :
  1192. dialogSettings.theta = GetDlgItemInt(hDlg, IDC_THETA, NULL, FALSE) / 10.0f;
  1193. while(dialogSettings.theta >= 360.0f)
  1194. dialogSettings.theta -= 360.0f;
  1195. while(dialogSettings.theta <= -360.0f)
  1196. dialogSettings.theta += 360.0f;
  1197. break;
  1198. case IDC_LEAVETRAILS :
  1199. dialogSettings.leaveTrails = SendMessage(GetDlgItem(hDlg, IDC_LEAVETRAILS), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1200. break;
  1201. case IDC_CLEARSCREEN :
  1202. dialogSettings.clearScreen = SendMessage(GetDlgItem(hDlg, IDC_CLEARSCREEN), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1203. break;
  1204. case IDC_REFLECTVERT :
  1205. dialogSettings.reflectVertical = SendMessage(GetDlgItem(hDlg, IDC_REFLECTVERT), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1206. break;
  1207. case IDC_REFLECTHORZ :
  1208. dialogSettings.reflectHorizontal = SendMessage(GetDlgItem(hDlg, IDC_REFLECTHORZ), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1209. break;
  1210. case IDC_REFLECTDIAG :
  1211. dialogSettings.reflectDiagonal = SendMessage(GetDlgItem(hDlg, IDC_REFLECTDIAG), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1212. break;
  1213. case IDC_OSCILLATE :
  1214. dialogSettings.oscillate = SendMessage(GetDlgItem(hDlg, IDC_OSCILLATE), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1215. break;
  1216. case IDC_FILLED :
  1217. dialogSettings.filled = SendMessage(GetDlgItem(hDlg, IDC_FILLED), BM_GETCHECK, 0, 0) == BST_CHECKED;
  1218. break;
  1219. case IDC_SHAPE:
  1220. dialogSettings.shape = (SHAPE)SendMessage(GetDlgItem(hDlg, IDC_SHAPE), CB_GETCURSEL, 0, 0);
  1221. break;
  1222. case IDOK:
  1223. {
  1224. // copy the dialog control values to our currentSettings:
  1225. currentSettings = dialogSettings;
  1226. SaveState();
  1227. }
  1228. // break; - fall through so the dialog closes!
  1229. case IDCANCEL:
  1230. {
  1231. EndDialog(hDlg, LOWORD(wParam));
  1232. lresult = TRUE;
  1233. }
  1234. break;
  1235. }
  1236. }
  1237. break;
  1238. }
  1239. return lresult;
  1240. }