PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/Samples/Chap08/DigiClock/DigiClock.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 260 lines | 200 code | 55 blank | 5 comment | 10 complexity | 86ee5e4881d21fcae0ab28d38d3669df MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module DigiClock;
  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. import core.sys.windows.winnls;
  23. enum ID_TIMER = 1;
  24. extern (Windows)
  25. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  26. {
  27. int result;
  28. try
  29. {
  30. Runtime.initialize();
  31. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  32. Runtime.terminate();
  33. }
  34. catch (Throwable o)
  35. {
  36. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  37. result = 0;
  38. }
  39. return result;
  40. }
  41. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  42. {
  43. string appName = "DigClock";
  44. HWND hwnd;
  45. MSG msg;
  46. WNDCLASS wndclass;
  47. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  48. wndclass.lpfnWndProc = &WndProc;
  49. wndclass.cbClsExtra = 0;
  50. wndclass.cbWndExtra = 0;
  51. wndclass.hInstance = hInstance;
  52. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  53. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  54. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  55. wndclass.lpszMenuName = NULL;
  56. wndclass.lpszClassName = appName.toUTF16z;
  57. if (!RegisterClass(&wndclass))
  58. {
  59. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  60. return 0;
  61. }
  62. hwnd = CreateWindow(appName.toUTF16z, // window class name
  63. "Digital Clock", // window caption
  64. WS_OVERLAPPEDWINDOW, // window style
  65. CW_USEDEFAULT, // initial x position
  66. CW_USEDEFAULT, // initial y position
  67. CW_USEDEFAULT, // initial x size
  68. CW_USEDEFAULT, // initial y size
  69. NULL, // parent window handle
  70. NULL, // window menu handle
  71. hInstance, // program instance handle
  72. NULL); // creation parameters
  73. ShowWindow(hwnd, iCmdShow);
  74. UpdateWindow(hwnd);
  75. while (GetMessage(&msg, NULL, 0, 0))
  76. {
  77. TranslateMessage(&msg);
  78. DispatchMessage(&msg);
  79. }
  80. return msg.wParam;
  81. }
  82. void DisplayDigit(HDC hdc, int iNumber)
  83. {
  84. static int[7][10] fSevenSegment =
  85. [
  86. [1, 1, 1, 0, 1, 1, 1,],
  87. [0, 0, 1, 0, 0, 1, 0,],
  88. [1, 0, 1, 1, 1, 0, 1,],
  89. [1, 0, 1, 1, 0, 1, 1,],
  90. [0, 1, 1, 1, 0, 1, 0,],
  91. [1, 1, 0, 1, 0, 1, 1,],
  92. [1, 1, 0, 1, 1, 1, 1,],
  93. [1, 0, 1, 0, 0, 1, 0,],
  94. [1, 1, 1, 1, 1, 1, 1,],
  95. [1, 1, 1, 1, 0, 1, 1 ]
  96. ];
  97. static POINT[6][7] ptSegment =
  98. [
  99. [POINT(7, 6), POINT(11, 2), POINT(31, 2), POINT(35, 6), POINT(31, 10), POINT(11, 10)],
  100. [POINT(6, 7), POINT(10, 11), POINT(10, 31), POINT(6, 35), POINT(2, 31), POINT(2, 11)],
  101. [POINT(36, 7), POINT(40, 11), POINT(40, 31), POINT(36, 35), POINT(32, 31), POINT(32, 11)],
  102. [POINT(7, 36), POINT(11, 32), POINT(31, 32), POINT(35, 36), POINT(31, 40), POINT(11, 40)],
  103. [POINT(6, 37), POINT(10, 41), POINT(10, 61), POINT(6, 65), POINT(2, 61), POINT(2, 41)],
  104. [POINT(36, 37), POINT(40, 41), POINT(40, 61), POINT(36, 65), POINT(32, 61), POINT(32, 41)],
  105. [POINT(7, 66), POINT(11, 62), POINT(31, 62), POINT(35, 66), POINT(31, 70), POINT(11, 70)],
  106. ];
  107. int iSeg;
  108. for(iSeg = 0; iSeg < 7; iSeg++)
  109. if(fSevenSegment [iNumber][iSeg])
  110. Polygon(hdc, ptSegment[iSeg].ptr, 6);
  111. }
  112. void DisplayTwoDigits(HDC hdc, int iNumber, BOOL fSuppress)
  113. {
  114. if(!fSuppress ||(iNumber / 10 != 0))
  115. DisplayDigit(hdc, iNumber / 10);
  116. OffsetWindowOrgEx(hdc, -42, 0, NULL);
  117. DisplayDigit(hdc, iNumber % 10);
  118. OffsetWindowOrgEx(hdc, -42, 0, NULL);
  119. }
  120. void DisplayColon(HDC hdc)
  121. {
  122. POINT[4][2] ptColon =
  123. [
  124. [
  125. POINT(2, 21),
  126. POINT(6, 17),
  127. POINT(10, 21),
  128. POINT(6, 25),
  129. ],
  130. [
  131. POINT(2, 51),
  132. POINT(6, 47),
  133. POINT(10, 51),
  134. POINT(6, 55)
  135. ]
  136. ];
  137. Polygon(hdc, ptColon[0].ptr, 4);
  138. Polygon(hdc, ptColon[1].ptr, 4);
  139. OffsetWindowOrgEx(hdc, -12, 0, NULL);
  140. }
  141. void DisplayTime(HDC hdc, BOOL f24Hour, BOOL fSuppress)
  142. {
  143. SYSTEMTIME st;
  144. GetLocalTime(&st);
  145. if(f24Hour)
  146. DisplayTwoDigits(hdc, st.wHour, fSuppress);
  147. else
  148. DisplayTwoDigits(hdc,(st.wHour %= 12) ? st.wHour : 12, fSuppress);
  149. DisplayColon(hdc);
  150. DisplayTwoDigits(hdc, st.wMinute, FALSE);
  151. DisplayColon(hdc);
  152. DisplayTwoDigits(hdc, st.wSecond, FALSE);
  153. }
  154. extern(Windows)
  155. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  156. {
  157. scope (failure) assert(0);
  158. static BOOL f24Hour, fSuppress;
  159. static HBRUSH hBrushRed;
  160. static int cxClient, cyClient;
  161. HDC hdc;
  162. PAINTSTRUCT ps;
  163. wchar[2] szBuffer;
  164. switch (message)
  165. {
  166. case WM_CREATE:
  167. hBrushRed = CreateSolidBrush(RGB(255, 0, 0));
  168. SetTimer(hwnd, ID_TIMER, 1000, NULL);
  169. goto case;
  170. // fall through
  171. case WM_SETTINGCHANGE:
  172. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITIME, szBuffer.ptr, 2);
  173. f24Hour = (szBuffer[0] == '1');
  174. GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_ITLZERO, szBuffer.ptr, 2);
  175. fSuppress = (szBuffer[0] == '0');
  176. InvalidateRect(hwnd, NULL, TRUE);
  177. return 0;
  178. case WM_SIZE:
  179. cxClient = LOWORD(lParam);
  180. cyClient = HIWORD(lParam);
  181. return 0;
  182. case WM_TIMER:
  183. InvalidateRect(hwnd, NULL, TRUE);
  184. return 0;
  185. case WM_PAINT:
  186. hdc = BeginPaint(hwnd, &ps);
  187. SetMapMode(hdc, MM_ISOTROPIC);
  188. SetWindowExtEx(hdc, 276, 72, NULL);
  189. SetViewportExtEx(hdc, cxClient, cyClient, NULL);
  190. SetWindowOrgEx(hdc, 138, 36, NULL);
  191. SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
  192. SelectObject(hdc, GetStockObject(NULL_PEN));
  193. SelectObject(hdc, hBrushRed);
  194. DisplayTime(hdc, f24Hour, fSuppress);
  195. EndPaint(hwnd, &ps);
  196. return 0;
  197. case WM_DESTROY:
  198. KillTimer(hwnd, ID_TIMER);
  199. DeleteObject(hBrushRed);
  200. PostQuitMessage(0);
  201. return 0;
  202. default:
  203. }
  204. return DefWindowProc(hwnd, message, wParam, lParam);
  205. }