/win32_test.d

http://github.com/AndrejMitrovic/cairoDSamples · D · 237 lines · 186 code · 46 blank · 5 comment · 7 complexity · 7b024527135e0fda6bfa083a1cd402e3 MD5 · raw file

  1. module win32_test;
  2. /+
  3. + This tutorial is derived from: http://cairographics.org/cookbook/win32quickstart/
  4. + Translated to D2 by Andrej Mitrovic, 2011.
  5. +/
  6. import core.runtime;
  7. import std.utf;
  8. pragma(lib, "gdi32.lib");
  9. import win32.windef;
  10. import win32.winuser;
  11. import win32.wingdi;
  12. string appName = "CairoWindow";
  13. string description = "A simple win32 window with Cairo drawing";
  14. HINSTANCE hinst;
  15. import cairo.cairo;
  16. import cairo.win32;
  17. alias cairo.cairo.RGB RGB; // conflicts with win32.wingdi.RGB
  18. extern (Windows)
  19. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
  20. {
  21. int result;
  22. void exceptionHandler(Throwable e) { throw e; }
  23. try
  24. {
  25. Runtime.initialize(&exceptionHandler);
  26. result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
  27. Runtime.terminate(&exceptionHandler);
  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. hinst = hInstance;
  39. HACCEL hAccel;
  40. HWND hwnd;
  41. MSG msg;
  42. WNDCLASS wndclass;
  43. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  44. wndclass.lpfnWndProc = &WndProc;
  45. wndclass.cbClsExtra = 0;
  46. wndclass.cbWndExtra = 0;
  47. wndclass.hInstance = hInstance;
  48. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  49. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  50. wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
  51. wndclass.lpszMenuName = appName.toUTF16z;
  52. wndclass.lpszClassName = appName.toUTF16z;
  53. if (!RegisterClass(&wndclass))
  54. {
  55. MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
  56. return 0;
  57. }
  58. hwnd = CreateWindow(appName.toUTF16z, // window class name
  59. description.toUTF16z, // window caption
  60. WS_OVERLAPPEDWINDOW, // window style
  61. CW_USEDEFAULT, // initial x position
  62. CW_USEDEFAULT, // initial y position
  63. CW_USEDEFAULT, // initial x size
  64. CW_USEDEFAULT, // initial y size
  65. NULL, // parent window handle
  66. NULL, // window menu handle
  67. hInstance, // program instance handle
  68. NULL); // creation parameters
  69. ShowWindow(hwnd, iCmdShow);
  70. UpdateWindow(hwnd);
  71. while (GetMessage(&msg, NULL, 0, 0))
  72. {
  73. TranslateMessage(&msg);
  74. DispatchMessage(&msg);
  75. }
  76. return msg.wParam;
  77. }
  78. void roundedRectangle(Context ctx, int x, int y, int w, int h, int radius_x = 5, int radius_y = 5)
  79. {
  80. enum ARC_TO_BEZIER = 0.55228475;
  81. if (radius_x > w - radius_x)
  82. radius_x = w / 2;
  83. if (radius_y > h - radius_y)
  84. radius_y = h / 2;
  85. // approximate (quite close) the arc using a bezier curve
  86. auto c1 = ARC_TO_BEZIER * radius_x;
  87. auto c2 = ARC_TO_BEZIER * radius_y;
  88. ctx.newPath();
  89. ctx.moveTo(x + radius_x, y);
  90. ctx.relLineTo(w - 2 * radius_x, 0.0);
  91. ctx.relCurveTo(c1, 0.0, radius_x, c2, radius_x, radius_y);
  92. ctx.relLineTo(0, h - 2 * radius_y);
  93. ctx.relCurveTo(0.0, c2, c1 - radius_x, radius_y, -radius_x, radius_y);
  94. ctx.relLineTo(-w + 2 * radius_x, 0);
  95. ctx.relCurveTo(-c1, 0, -radius_x, -c2, -radius_x, -radius_y);
  96. ctx.relLineTo(0, -h + 2 * radius_y);
  97. ctx.relCurveTo(0.0, -c2, radius_x - c1, -radius_y, radius_x, -radius_y);
  98. ctx.closePath();
  99. }
  100. extern (Windows)
  101. LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  102. {
  103. switch (message)
  104. {
  105. case WM_CREATE:
  106. {
  107. window = new Window(hwnd);
  108. return 0;
  109. }
  110. default:
  111. }
  112. if (window)
  113. return window.process(hwnd, message, wParam, lParam);
  114. else
  115. return DefWindowProc(hwnd, message, wParam, lParam);
  116. }
  117. Window window;
  118. class Window
  119. {
  120. int x, y;
  121. HWND hwnd;
  122. HDC hdc;
  123. PAINTSTRUCT ps;
  124. RECT rc;
  125. HDC _buffer;
  126. HBITMAP hBitmap;
  127. HBITMAP hOldBitmap;
  128. this(HWND hwnd)
  129. {
  130. this.hwnd = hwnd;
  131. }
  132. LRESULT process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  133. {
  134. switch (message)
  135. {
  136. case WM_DESTROY:
  137. return OnDestroy(hwnd, message, wParam, lParam);
  138. case WM_PAINT:
  139. return OnPaint(hwnd, message, wParam, lParam);
  140. case WM_ERASEBKGND:
  141. return 0;
  142. default:
  143. }
  144. return DefWindowProc(hwnd, message, wParam, lParam);
  145. }
  146. auto OnPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  147. {
  148. hdc = BeginPaint(hwnd, &ps);
  149. GetClientRect(hwnd, &rc);
  150. auto left = rc.left;
  151. auto top = rc.top;
  152. auto right = rc.right;
  153. auto bottom = rc.bottom;
  154. auto width = right - left;
  155. auto height = bottom - top;
  156. x = left;
  157. y = top;
  158. _buffer = CreateCompatibleDC(hdc);
  159. hBitmap = CreateCompatibleBitmap(hdc, width, height);
  160. hOldBitmap = SelectObject(_buffer, hBitmap);
  161. auto surf = new Win32Surface(_buffer);
  162. auto ctx = Context(surf);
  163. ctx.setSourceRGB(1, 1, 1);
  164. ctx.paint();
  165. roundedRectangle(ctx, 50, 50, 250, 250, 10, 10);
  166. auto clr = RGB(0.9411764705882353, 0.996078431372549, 0.9137254901960784);
  167. ctx.setSourceRGB(clr);
  168. ctx.fillPreserve();
  169. clr = RGB(0.7019607843137254, 1.0, 0.5529411764705883);
  170. ctx.setSourceRGB(clr);
  171. ctx.stroke();
  172. ctx.setSourceRGB(0, 0, 0);
  173. ctx.selectFontFace("Arial", FontSlant.CAIRO_FONT_SLANT_NORMAL, FontWeight.CAIRO_FONT_WEIGHT_NORMAL);
  174. ctx.setFontSize(10.0);
  175. auto txt = "Cairo is the greatest thing!";
  176. ctx.moveTo(5.0, 10.0);
  177. ctx.showText(txt);
  178. surf.finish();
  179. BitBlt(hdc, 0, 0, width, height, _buffer, x, y, SRCCOPY);
  180. SelectObject(_buffer, hOldBitmap);
  181. DeleteObject(hBitmap);
  182. DeleteDC(_buffer);
  183. EndPaint(hwnd, &ps);
  184. return 0;
  185. }
  186. auto OnDestroy(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  187. {
  188. PostQuitMessage(0);
  189. return 0;
  190. }
  191. }