PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/Samples/Chap20/BigJob1/BigJob1.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 212 lines | 167 code | 40 blank | 5 comment | 9 complexity | a90bee21928d964b70f2a67d2a427e89 MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module BigJob1;
  6. import core.memory;
  7. import core.runtime;
  8. import core.thread;
  9. import std.concurrency;
  10. import std.conv;
  11. import std.math;
  12. import std.range;
  13. import std.string;
  14. import std.utf;
  15. auto toUTF16z(S)(S s)
  16. {
  17. return toUTFz!(const(wchar)*)(s);
  18. }
  19. pragma(lib, "gdi32.lib");
  20. pragma(lib, "comdlg32.lib");
  21. pragma(lib, "winmm.lib");
  22. import core.sys.windows.windef;
  23. import core.sys.windows.winuser;
  24. import core.sys.windows.wingdi;
  25. import core.sys.windows.winbase;
  26. import core.sys.windows.commdlg;
  27. import core.sys.windows.mmsystem;
  28. alias win32.winuser.MessageBox MessageBox;
  29. string appName = "BigJob1";
  30. string description = "Multithreading 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. enum REP = 10_000_000;
  92. enum STATUS_READY = 0;
  93. enum STATUS_WORKING = 1;
  94. enum STATUS_DONE = 2;
  95. enum WM_CALC_DONE = (WM_USER + 0);
  96. enum WM_CALC_ABORTED = (WM_USER + 1);
  97. struct PARAMS
  98. {
  99. HWND hwnd;
  100. BOOL bContinue;
  101. }
  102. // used to be volatile
  103. __gshared PARAMS params;
  104. void ThreadFunc()
  105. {
  106. double A = 1.0;
  107. INT i;
  108. LONG lTime;
  109. lTime = GetCurrentTime();
  110. for (i = 0; i < REP && params.bContinue; i++)
  111. A = tan(atan(exp(log(sqrt(A * A))))) + 1.0;
  112. if (i == REP)
  113. {
  114. lTime = GetCurrentTime() - lTime;
  115. SendMessage(params.hwnd, WM_CALC_DONE, 0, lTime);
  116. }
  117. else
  118. SendMessage(params.hwnd, WM_CALC_ABORTED, 0, 0);
  119. }
  120. extern (Windows)
  121. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  122. {
  123. scope (failure) assert(0);
  124. static INT iStatus;
  125. static LONG lTime;
  126. static string[] szMessage = ["Ready (left mouse button begins)",
  127. "Working (right mouse button ends)",
  128. "%s repetitions in %s msec"];
  129. HDC hdc;
  130. PAINTSTRUCT ps;
  131. RECT rect;
  132. string szBuffer;
  133. switch (message)
  134. {
  135. case WM_LBUTTONDOWN:
  136. if (iStatus == STATUS_WORKING)
  137. {
  138. MessageBeep(0);
  139. return 0;
  140. }
  141. iStatus = STATUS_WORKING;
  142. params.hwnd = hwnd;
  143. params.bContinue = TRUE;
  144. spawn(&ThreadFunc);
  145. InvalidateRect(hwnd, NULL, TRUE);
  146. return 0;
  147. case WM_RBUTTONDOWN:
  148. params.bContinue = FALSE;
  149. return 0;
  150. case WM_CALC_DONE:
  151. lTime = lParam;
  152. iStatus = STATUS_DONE;
  153. InvalidateRect(hwnd, NULL, TRUE);
  154. return 0;
  155. case WM_CALC_ABORTED:
  156. iStatus = STATUS_READY;
  157. InvalidateRect(hwnd, NULL, TRUE);
  158. return 0;
  159. case WM_PAINT:
  160. hdc = BeginPaint(hwnd, &ps);
  161. GetClientRect(hwnd, &rect);
  162. szBuffer = format(szMessage[iStatus], REP, lTime);
  163. DrawText(hdc, szBuffer.toUTF16z, -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
  164. EndPaint(hwnd, &ps);
  165. return 0;
  166. case WM_DESTROY:
  167. PostQuitMessage(0);
  168. return 0;
  169. default:
  170. }
  171. return DefWindowProc(hwnd, message, wParam, lParam);
  172. }