PageRenderTime 44ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap08/Clock/Clock.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 243 lines | 184 code | 55 blank | 4 comment | 8 complexity | 9bda46a66db351123cbfa8f93ad7ac61 MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module Clock;
  6. import core.runtime;
  7. import core.thread;
  8. import std.conv;
  9. import std.math;
  10. import std.range;
  11. import std.string;
  12. import std.utf;
  13. auto toUTF16z(S)(S s)
  14. {
  15. return toUTFz!(const(wchar)*)(s);
  16. }
  17. pragma(lib, "gdi32.lib");
  18. import core.sys.windows.windef;
  19. import core.sys.windows.winuser;
  20. import core.sys.windows.wingdi;
  21. import core.sys.windows.winbase;
  22. enum ID_TIMER = 1;
  23. extern (Windows)
  24. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  25. {
  26. int result;
  27. try
  28. {
  29. Runtime.initialize();
  30. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  31. Runtime.terminate();
  32. }
  33. catch (Throwable o)
  34. {
  35. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  36. result = 0;
  37. }
  38. return result;
  39. }
  40. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  41. {
  42. string appName = "Clock";
  43. HWND hwnd;
  44. MSG msg;
  45. WNDCLASS wndclass;
  46. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  47. wndclass.lpfnWndProc = &WndProc;
  48. wndclass.cbClsExtra = 0;
  49. wndclass.cbWndExtra = 0;
  50. wndclass.hInstance = hInstance;
  51. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  52. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  53. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  54. wndclass.lpszMenuName = NULL;
  55. wndclass.lpszClassName = appName.toUTF16z;
  56. if (!RegisterClass(&wndclass))
  57. {
  58. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  59. return 0;
  60. }
  61. hwnd = CreateWindow(appName.toUTF16z, // window class name
  62. "Analog Clock", // window caption
  63. WS_OVERLAPPEDWINDOW, // window style
  64. CW_USEDEFAULT, // initial x position
  65. CW_USEDEFAULT, // initial y position
  66. CW_USEDEFAULT, // initial x size
  67. CW_USEDEFAULT, // initial y size
  68. NULL, // parent window handle
  69. NULL, // window menu handle
  70. hInstance, // program instance handle
  71. NULL); // creation parameters
  72. ShowWindow(hwnd, iCmdShow);
  73. UpdateWindow(hwnd);
  74. while (GetMessage(&msg, NULL, 0, 0))
  75. {
  76. TranslateMessage(&msg);
  77. DispatchMessage(&msg);
  78. }
  79. return msg.wParam;
  80. }
  81. void SetIsotropic(HDC hdc, int cxClient, int cyClient)
  82. {
  83. SetMapMode(hdc, MM_ISOTROPIC);
  84. SetWindowExtEx(hdc, 1000, 1000, NULL);
  85. SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, NULL);
  86. SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
  87. }
  88. void RotatePoint(POINT[] pt, int iNum, int iAngle)
  89. {
  90. int i;
  91. POINT ptTemp;
  92. for (i = 0; i < iNum; i++)
  93. {
  94. ptTemp.x = cast(int)(pt[i].x * cos(PI * 2 * iAngle / 360) +
  95. pt[i].y * sin(PI * 2 * iAngle / 360));
  96. ptTemp.y = cast(int)(pt[i].y * cos(PI * 2 * iAngle / 360) -
  97. pt[i].x * sin(PI * 2 * iAngle / 360));
  98. pt[i] = ptTemp;
  99. }
  100. }
  101. void DrawClock(HDC hdc)
  102. {
  103. int iAngle;
  104. POINT pt[3];
  105. for (iAngle = 0; iAngle < 360; iAngle += 6)
  106. {
  107. pt[0].x = 0;
  108. pt[0].y = 900;
  109. RotatePoint(pt, 1, iAngle);
  110. pt[2].x = pt[2].y = iAngle % 5 ? 33 : 100;
  111. pt[0].x -= pt[2].x / 2;
  112. pt[0].y -= pt[2].y / 2;
  113. pt[1].x = pt[0].x + pt[2].x;
  114. pt[1].y = pt[0].y + pt[2].y;
  115. SelectObject(hdc, GetStockObject(BLACK_BRUSH));
  116. Ellipse(hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
  117. }
  118. }
  119. void DrawHands(HDC hdc, SYSTEMTIME* pst, BOOL fChange)
  120. {
  121. static POINT[5][3] pt =
  122. [
  123. [POINT(0, -150), POINT(100, 0), POINT(0, 600), POINT(-100, 0), POINT(0, -150)],
  124. [POINT(0, -200), POINT( 50, 0), POINT(0, 800), POINT( -50, 0), POINT(0, -200)],
  125. [POINT(0, 0), POINT( 0, 0), POINT(0, 0), POINT( 0, 0), POINT(0, 800)]
  126. ];
  127. int i;
  128. int[3] iAngle;
  129. POINT[5][3] ptTemp;
  130. iAngle[0] = (pst.wHour * 30) % 360 + pst.wMinute / 2;
  131. iAngle[1] = pst.wMinute * 6;
  132. iAngle[2] = pst.wSecond * 6;
  133. ptTemp[] = pt[];
  134. for (i = fChange ? 0 : 2; i < 3; i++)
  135. {
  136. RotatePoint(ptTemp[i], 5, iAngle[i]);
  137. Polyline(hdc, ptTemp[i].ptr, 5);
  138. }
  139. }
  140. extern (Windows)
  141. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  142. {
  143. scope (failure) assert(0);
  144. static int cxClient, cyClient;
  145. static SYSTEMTIME stPrevious;
  146. BOOL fChange;
  147. HDC hdc;
  148. PAINTSTRUCT ps;
  149. SYSTEMTIME st;
  150. switch (message)
  151. {
  152. case WM_CREATE:
  153. SetTimer(hwnd, ID_TIMER, 1000, NULL);
  154. GetLocalTime(&st);
  155. stPrevious = st;
  156. return 0;
  157. case WM_SIZE:
  158. cxClient = LOWORD(lParam);
  159. cyClient = HIWORD(lParam);
  160. return 0;
  161. case WM_TIMER:
  162. GetLocalTime(&st);
  163. fChange = st.wHour != stPrevious.wHour ||
  164. st.wMinute != stPrevious.wMinute;
  165. hdc = GetDC(hwnd);
  166. SetIsotropic(hdc, cxClient, cyClient);
  167. SelectObject(hdc, GetStockObject(WHITE_PEN));
  168. DrawHands(hdc, &stPrevious, fChange);
  169. SelectObject(hdc, GetStockObject(BLACK_PEN));
  170. DrawHands(hdc, &st, TRUE);
  171. ReleaseDC(hwnd, hdc);
  172. stPrevious = st;
  173. return 0;
  174. case WM_PAINT:
  175. hdc = BeginPaint(hwnd, &ps);
  176. SetIsotropic(hdc, cxClient, cyClient);
  177. DrawClock(hdc);
  178. DrawHands(hdc, &stPrevious, TRUE);
  179. EndPaint(hwnd, &ps);
  180. return 0;
  181. case WM_DESTROY:
  182. KillTimer(hwnd, ID_TIMER);
  183. PostQuitMessage(0);
  184. return 0;
  185. default:
  186. }
  187. return DefWindowProc(hwnd, message, wParam, lParam);
  188. }