PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/Chap20/Multi1/Multi1.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 369 lines | 274 code | 76 blank | 19 comment | 20 complexity | a1c915b7140c4f875f70ffd3be3bf67f MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module Multi1;
  6. import core.memory;
  7. import core.runtime;
  8. import core.thread;
  9. import std.algorithm : max, min;
  10. import std.conv;
  11. import std.math;
  12. import std.random;
  13. import std.range;
  14. import std.string;
  15. import std.utf : count, toUTFz;
  16. auto toUTF16z(S)(S s)
  17. {
  18. return toUTFz!(const(wchar)*)(s);
  19. }
  20. pragma(lib, "gdi32.lib");
  21. pragma(lib, "comdlg32.lib");
  22. pragma(lib, "winmm.lib");
  23. import core.sys.windows.windef;
  24. import core.sys.windows.winuser;
  25. import core.sys.windows.wingdi;
  26. import core.sys.windows.winbase;
  27. import core.sys.windows.commdlg;
  28. import core.sys.windows.mmsystem;
  29. string appName = "Multi1";
  30. string description = "Multitasking Demo";
  31. HINSTANCE hinst;
  32. extern (Windows)
  33. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  34. {
  35. int result;
  36. try
  37. {
  38. Runtime.initialize();
  39. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  40. Runtime.terminate();
  41. }
  42. catch (Throwable o)
  43. {
  44. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  45. result = 0;
  46. }
  47. return result;
  48. }
  49. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  50. {
  51. hinst = hInstance;
  52. HACCEL hAccel;
  53. HWND hwnd;
  54. MSG msg;
  55. WNDCLASS wndclass;
  56. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  57. wndclass.lpfnWndProc = &WndProc;
  58. wndclass.cbClsExtra = 0;
  59. wndclass.cbWndExtra = 0;
  60. wndclass.hInstance = hInstance;
  61. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  62. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  63. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  64. wndclass.lpszMenuName = appName.toUTF16z;
  65. wndclass.lpszClassName = appName.toUTF16z;
  66. if (!RegisterClass(&wndclass))
  67. {
  68. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  69. return 0;
  70. }
  71. hwnd = CreateWindow(appName.toUTF16z, // window class name
  72. description.toUTF16z, // window caption
  73. WS_OVERLAPPEDWINDOW, // window style
  74. CW_USEDEFAULT, // initial x position
  75. CW_USEDEFAULT, // initial y position
  76. CW_USEDEFAULT, // initial x size
  77. CW_USEDEFAULT, // initial y size
  78. NULL, // parent window handle
  79. NULL, // window menu handle
  80. hInstance, // program instance handle
  81. NULL); // creation parameters
  82. ShowWindow(hwnd, iCmdShow);
  83. UpdateWindow(hwnd);
  84. while (GetMessage(&msg, NULL, 0, 0))
  85. {
  86. TranslateMessage(&msg);
  87. DispatchMessage(&msg);
  88. }
  89. return msg.wParam;
  90. }
  91. int cyChar;
  92. int CheckBottom(HWND hwnd, int cyClient, int iLine)
  93. {
  94. if (iLine * cyChar + cyChar > cyClient)
  95. {
  96. InvalidateRect(hwnd, NULL, TRUE);
  97. UpdateWindow(hwnd);
  98. iLine = 0;
  99. }
  100. return iLine;
  101. }
  102. // ------------------------------------------------
  103. // Window 1: Display increasing sequence of numbers
  104. // ------------------------------------------------
  105. extern (Windows)
  106. LRESULT WndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  107. {
  108. static int iNum, iLine, cyClient;
  109. HDC hdc;
  110. string szBuffer;
  111. switch (message)
  112. {
  113. case WM_SIZE:
  114. cyClient = HIWORD(lParam);
  115. return 0;
  116. case WM_TIMER:
  117. if (iNum < 0)
  118. iNum = 0;
  119. iLine = CheckBottom(hwnd, cyClient, iLine);
  120. hdc = GetDC(hwnd);
  121. szBuffer = format("%s", iNum++);
  122. TextOut(hdc, 0, iLine * cyChar, szBuffer.toUTF16z, szBuffer.count);
  123. ReleaseDC(hwnd, hdc);
  124. iLine++;
  125. return 0;
  126. default:
  127. }
  128. return DefWindowProc(hwnd, message, wParam, lParam);
  129. }
  130. // ------------------------------------------------------
  131. // Window 2: Display increasing sequence of prime numbers
  132. // ------------------------------------------------------
  133. extern (Windows)
  134. LRESULT WndProc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  135. {
  136. static int iNum = 1, iLine, cyClient;
  137. HDC hdc;
  138. int i, iSqrt;
  139. string szBuffer;
  140. switch (message)
  141. {
  142. case WM_SIZE:
  143. cyClient = HIWORD(lParam);
  144. return 0;
  145. case WM_TIMER:
  146. do
  147. {
  148. if (++iNum < 0)
  149. iNum = 0;
  150. iSqrt = cast(int)sqrt(cast(float)iNum);
  151. for (i = 2; i <= iSqrt; i++)
  152. if (iNum % i == 0)
  153. break;
  154. }
  155. while (i <= iSqrt);
  156. iLine = CheckBottom(hwnd, cyClient, iLine);
  157. hdc = GetDC(hwnd);
  158. szBuffer = format("%s", iNum);
  159. TextOut(hdc, 0, iLine * cyChar, szBuffer.toUTF16z, szBuffer.count);
  160. ReleaseDC(hwnd, hdc);
  161. iLine++;
  162. return 0;
  163. default:
  164. }
  165. return DefWindowProc(hwnd, message, wParam, lParam);
  166. }
  167. // ----------------------------------------------------------
  168. // Window 3: Display increasing sequence of Fibonacci numbers
  169. // ----------------------------------------------------------
  170. extern (Windows)
  171. LRESULT WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  172. {
  173. static int iNum = 0, iNext = 1, iLine, cyClient;
  174. HDC hdc;
  175. int iTemp;
  176. string szBuffer;
  177. switch (message)
  178. {
  179. case WM_SIZE:
  180. cyClient = HIWORD(lParam);
  181. return 0;
  182. case WM_TIMER:
  183. if (iNum < 0)
  184. {
  185. iNum = 0;
  186. iNext = 1;
  187. }
  188. iLine = CheckBottom(hwnd, cyClient, iLine);
  189. hdc = GetDC(hwnd);
  190. szBuffer = format("%s", iNum);
  191. TextOut(hdc, 0, iLine * cyChar, szBuffer.toUTF16z, szBuffer.count);
  192. ReleaseDC(hwnd, hdc);
  193. iTemp = iNum;
  194. iNum = iNext;
  195. iNext += iTemp;
  196. iLine++;
  197. return 0;
  198. default:
  199. }
  200. return DefWindowProc(hwnd, message, wParam, lParam);
  201. }
  202. // -----------------------------------------
  203. // Window 4: Display circles of random radii
  204. // -----------------------------------------
  205. extern (Windows)
  206. LRESULT WndProc4(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  207. {
  208. static int cxClient, cyClient;
  209. HDC hdc;
  210. int iDiameter;
  211. switch (message)
  212. {
  213. case WM_SIZE:
  214. cxClient = LOWORD(lParam);
  215. cyClient = HIWORD(lParam);
  216. return 0;
  217. case WM_TIMER:
  218. InvalidateRect(hwnd, NULL, TRUE);
  219. UpdateWindow(hwnd);
  220. iDiameter = uniform(0, (max(1, min(cxClient, cyClient))));
  221. hdc = GetDC(hwnd);
  222. Ellipse(hdc, (cxClient - iDiameter) / 2,
  223. (cyClient - iDiameter) / 2,
  224. (cxClient + iDiameter) / 2,
  225. (cyClient + iDiameter) / 2);
  226. ReleaseDC(hwnd, hdc);
  227. return 0;
  228. default:
  229. }
  230. return DefWindowProc(hwnd, message, wParam, lParam);
  231. }
  232. // -----------------------------------
  233. // Main window to create child windows
  234. // -----------------------------------
  235. extern (Windows)
  236. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  237. {
  238. scope (failure) assert(0);
  239. static HWND hwndChild[4];
  240. static string[] szChildClass = ["Child1", "Child2", "Child3", "Child4"];
  241. static WNDPROC[] ChildProc = [&WndProc1, &WndProc2, &WndProc3, &WndProc4];
  242. HINSTANCE hInstance;
  243. int i, cxClient, cyClient;
  244. WNDCLASS wndclass;
  245. switch (message)
  246. {
  247. case WM_CREATE:
  248. hInstance = cast(HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE);
  249. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  250. wndclass.cbClsExtra = 0;
  251. wndclass.cbWndExtra = 0;
  252. wndclass.hInstance = hInstance;
  253. wndclass.hIcon = NULL;
  254. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  255. wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH);
  256. wndclass.lpszMenuName = NULL;
  257. for (i = 0; i < 4; i++)
  258. {
  259. wndclass.lpfnWndProc = ChildProc[i];
  260. wndclass.lpszClassName = szChildClass[i].toUTF16z;
  261. RegisterClass(&wndclass);
  262. hwndChild[i] = CreateWindow(szChildClass[i].toUTF16z, NULL,
  263. WS_CHILDWINDOW | WS_BORDER | WS_VISIBLE,
  264. 0, 0, 0, 0,
  265. hwnd, cast(HMENU)i, hInstance, NULL);
  266. }
  267. cyChar = HIWORD(GetDialogBaseUnits());
  268. SetTimer(hwnd, 1, 10, NULL);
  269. return 0;
  270. case WM_SIZE:
  271. cxClient = LOWORD(lParam);
  272. cyClient = HIWORD(lParam);
  273. for (i = 0; i < 4; i++)
  274. MoveWindow(hwndChild[i], (i % 2) * cxClient / 2,
  275. (i > 1) * cyClient / 2,
  276. cxClient / 2, cyClient / 2, TRUE);
  277. return 0;
  278. case WM_TIMER:
  279. for (i = 0; i < 4; i++)
  280. SendMessage(hwndChild[i], WM_TIMER, wParam, lParam);
  281. return 0;
  282. case WM_CHAR:
  283. if (wParam == '\x1B')
  284. DestroyWindow(hwnd);
  285. return 0;
  286. case WM_DESTROY:
  287. KillTimer(hwnd, 1);
  288. PostQuitMessage(0);
  289. return 0;
  290. default:
  291. }
  292. return DefWindowProc(hwnd, message, wParam, lParam);
  293. }