PageRenderTime 118ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/Samples/Chap05/Bezier/Bezier.d

http://github.com/AndrejMitrovic/DWinProgramming
D | 206 lines | 158 code | 43 blank | 5 comment | 5 complexity | c45d093af96bedd7934c1de4646f40ed MD5 | raw file
  1. /+
  2. + Copyright (c) Charles Petzold, 1998.
  3. + Ported to the D Programming Language by Andrej Mitrovic, 2011.
  4. +/
  5. module Bezier;
  6. import core.runtime;
  7. import std.string;
  8. import std.utf;
  9. auto toUTF16z(S)(S s)
  10. {
  11. return toUTFz!(const(wchar)*)(s);
  12. }
  13. pragma(lib, "gdi32.lib");
  14. pragma(lib, "winmm.lib");
  15. import core.sys.windows.mmsystem;
  16. import core.sys.windows.windef;
  17. import core.sys.windows.winuser;
  18. import core.sys.windows.wingdi;
  19. extern(Windows)
  20. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  21. {
  22. int result;
  23. try
  24. {
  25. Runtime.initialize();
  26. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  27. Runtime.terminate();
  28. }
  29. catch(Throwable o)
  30. {
  31. MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
  32. result = 0;
  33. }
  34. return result;
  35. }
  36. int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  37. {
  38. string appName = "Bezier";
  39. HWND hwnd;
  40. MSG msg;
  41. WNDCLASS wndclass;
  42. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  43. wndclass.lpfnWndProc = &WndProc;
  44. wndclass.cbClsExtra = 0;
  45. wndclass.cbWndExtra = 0;
  46. wndclass.hInstance = hInstance;
  47. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  48. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  49. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  50. wndclass.lpszMenuName = NULL;
  51. wndclass.lpszClassName = appName.toUTF16z;
  52. if(!RegisterClass(&wndclass))
  53. {
  54. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  55. return 0;
  56. }
  57. hwnd = CreateWindow(appName.toUTF16z, // window class name
  58. "Bezier Splines", // window caption
  59. WS_OVERLAPPEDWINDOW, // window style
  60. CW_USEDEFAULT, // initial x position
  61. CW_USEDEFAULT, // initial y position
  62. CW_USEDEFAULT, // initial x size
  63. CW_USEDEFAULT, // initial y size
  64. NULL, // parent window handle
  65. NULL, // window menu handle
  66. hInstance, // program instance handle
  67. NULL); // creation parameters
  68. ShowWindow(hwnd, iCmdShow);
  69. UpdateWindow(hwnd);
  70. while(GetMessage(&msg, NULL, 0, 0))
  71. {
  72. TranslateMessage(&msg);
  73. DispatchMessage(&msg);
  74. }
  75. return msg.wParam;
  76. }
  77. extern(Windows)
  78. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
  79. {
  80. scope (failure) assert(0);
  81. static int cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth;
  82. HDC hdc;
  83. int i, x, y, iVertPos, iHorzPos, iPaintStart, iPaintEnd;
  84. PAINTSTRUCT ps;
  85. SCROLLINFO si;
  86. TEXTMETRIC tm;
  87. static POINT[4] apt;
  88. switch(message)
  89. {
  90. case WM_CREATE:
  91. {
  92. hdc = GetDC(hwnd);
  93. scope(exit) ReleaseDC(hwnd, hdc);
  94. GetTextMetrics(hdc, &tm);
  95. cxChar = tm.tmAveCharWidth;
  96. cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
  97. cyChar = tm.tmHeight + tm.tmExternalLeading;
  98. // Save the width of the three columns
  99. iMaxWidth = 40 * cxChar + 22 * cxCaps;
  100. return 0;
  101. }
  102. case WM_SIZE:
  103. {
  104. cxClient = LOWORD(lParam);
  105. cyClient = HIWORD(lParam);
  106. apt[0].x = cxClient / 4;
  107. apt[0].y = cyClient / 2;
  108. apt[1].x = cxClient / 2;
  109. apt[1].y = cyClient / 4;
  110. apt[2].x = cxClient / 2;
  111. apt[2].y = 3 * cyClient / 4;
  112. apt[3].x = 3 * cxClient / 4;
  113. apt[3].y = cyClient / 2;
  114. return 0;
  115. }
  116. case WM_LBUTTONDOWN:
  117. case WM_RBUTTONDOWN:
  118. case WM_MOUSEMOVE:
  119. {
  120. if (wParam & MK_LBUTTON || wParam & MK_RBUTTON)
  121. {
  122. hdc = GetDC(hwnd);
  123. scope(exit)
  124. ReleaseDC(hwnd, hdc);
  125. SelectObject(hdc, GetStockObject(WHITE_PEN));
  126. DrawBezier(hdc, apt);
  127. if (wParam & MK_LBUTTON)
  128. {
  129. apt[1].x = LOWORD(lParam);
  130. apt[1].y = HIWORD(lParam);
  131. }
  132. if (wParam & MK_RBUTTON)
  133. {
  134. apt[2].x = LOWORD(lParam);
  135. apt[2].y = HIWORD(lParam);
  136. }
  137. SelectObject(hdc, GetStockObject(BLACK_PEN));
  138. DrawBezier(hdc, apt);
  139. }
  140. return 0;
  141. }
  142. case WM_PAINT:
  143. {
  144. hdc = BeginPaint(hwnd, &ps);
  145. scope(exit) EndPaint(hwnd, &ps);
  146. DrawBezier(hdc, apt);
  147. return 0;
  148. }
  149. case WM_DESTROY:
  150. PostQuitMessage(0);
  151. return 0;
  152. default:
  153. }
  154. return DefWindowProc(hwnd, message, wParam, lParam);
  155. }
  156. void DrawBezier(HDC hdc, POINT[4] apt)
  157. {
  158. PolyBezier(hdc, apt.ptr, apt.length);
  159. MoveToEx(hdc, apt[0].x, apt[0].y, NULL);
  160. LineTo(hdc, apt[1].x, apt[1].y);
  161. MoveToEx(hdc, apt[2].x, apt[2].y, NULL);
  162. LineTo(hdc, apt[3].x, apt[3].y);
  163. }