PageRenderTime 18ms CodeModel.GetById 2ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/win32_test.d

http://github.com/AndrejMitrovic/cairoDSamples
D | 237 lines | 186 code | 46 blank | 5 comment | 7 complexity | 7b024527135e0fda6bfa083a1cd402e3 MD5 | raw file
  1module win32_test;
  2
  3/+
  4 + This tutorial is derived from: http://cairographics.org/cookbook/win32quickstart/
  5 + Translated to D2 by Andrej Mitrovic, 2011.
  6 +/
  7
  8import core.runtime;
  9import std.utf;
 10
 11pragma(lib, "gdi32.lib");
 12import win32.windef;
 13import win32.winuser;
 14import win32.wingdi;
 15
 16string appName     = "CairoWindow";
 17string description = "A simple win32 window with Cairo drawing";
 18HINSTANCE hinst;
 19
 20import cairo.cairo;
 21import cairo.win32;
 22
 23alias cairo.cairo.RGB RGB;  // conflicts with win32.wingdi.RGB
 24
 25extern (Windows)
 26int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
 27{
 28    int result;
 29    void exceptionHandler(Throwable e) { throw e; }
 30
 31    try
 32    {
 33        Runtime.initialize(&exceptionHandler);
 34        result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
 35        Runtime.terminate(&exceptionHandler);
 36    }
 37    catch (Throwable o)
 38    {
 39        MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
 40        result = 0;
 41    }
 42
 43    return result;
 44}
 45
 46int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
 47{
 48    hinst = hInstance;
 49    HACCEL hAccel;
 50    HWND hwnd;
 51    MSG  msg;
 52    WNDCLASS wndclass;
 53
 54    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
 55    wndclass.lpfnWndProc   = &WndProc;
 56    wndclass.cbClsExtra    = 0;
 57    wndclass.cbWndExtra    = 0;
 58    wndclass.hInstance     = hInstance;
 59    wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
 60    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
 61    wndclass.hbrBackground = cast(HBRUSH) GetStockObject(WHITE_BRUSH);
 62    wndclass.lpszMenuName  = appName.toUTF16z;
 63    wndclass.lpszClassName = appName.toUTF16z;
 64
 65    if (!RegisterClass(&wndclass))
 66    {
 67        MessageBox(NULL, "This program requires Windows NT!", appName.toUTF16z, MB_ICONERROR);
 68        return 0;
 69    }
 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
 83    ShowWindow(hwnd, iCmdShow);
 84    UpdateWindow(hwnd);
 85
 86    while (GetMessage(&msg, NULL, 0, 0))
 87    {
 88        TranslateMessage(&msg);
 89        DispatchMessage(&msg);
 90    }
 91
 92    return msg.wParam;
 93}
 94
 95void roundedRectangle(Context ctx, int x, int y, int w, int h, int radius_x = 5, int radius_y = 5)
 96{
 97    enum ARC_TO_BEZIER = 0.55228475;
 98
 99    if (radius_x > w - radius_x)
100        radius_x = w / 2;
101
102    if (radius_y > h - radius_y)
103        radius_y = h / 2;
104
105    // approximate (quite close) the arc using a bezier curve
106    auto c1 = ARC_TO_BEZIER * radius_x;
107    auto c2 = ARC_TO_BEZIER * radius_y;
108
109    ctx.newPath();
110    ctx.moveTo(x + radius_x, y);
111    ctx.relLineTo(w - 2 * radius_x, 0.0);
112    ctx.relCurveTo(c1, 0.0, radius_x, c2, radius_x, radius_y);
113    ctx.relLineTo(0, h - 2 * radius_y);
114    ctx.relCurveTo(0.0, c2, c1 - radius_x, radius_y, -radius_x, radius_y);
115    ctx.relLineTo(-w + 2 * radius_x, 0);
116    ctx.relCurveTo(-c1, 0, -radius_x, -c2, -radius_x, -radius_y);
117    ctx.relLineTo(0, -h + 2 * radius_y);
118    ctx.relCurveTo(0.0, -c2, radius_x - c1, -radius_y, radius_x, -radius_y);
119    ctx.closePath();
120}
121
122extern (Windows)
123LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
124{
125    switch (message)
126    {
127        case WM_CREATE:
128        {
129            window = new Window(hwnd);
130            return 0;
131        }
132        
133        default:
134    }
135    
136    if (window)
137        return window.process(hwnd, message, wParam, lParam);
138    else
139        return DefWindowProc(hwnd, message, wParam, lParam);
140}
141
142Window window;
143
144class Window
145{
146    int  x, y;
147    HWND hwnd;
148    HDC hdc;
149    PAINTSTRUCT ps;
150    RECT rc;
151    HDC _buffer;
152    HBITMAP hBitmap;
153    HBITMAP hOldBitmap;
154
155    this(HWND hwnd)
156    {
157        this.hwnd = hwnd;
158    }
159
160    LRESULT process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
161    {
162        switch (message)
163        {
164            case WM_DESTROY:
165                return OnDestroy(hwnd, message, wParam, lParam);
166
167            case WM_PAINT:
168                return OnPaint(hwnd, message, wParam, lParam);
169
170            case WM_ERASEBKGND:
171                return 0;
172
173            default:
174        }
175        
176        return DefWindowProc(hwnd, message, wParam, lParam);    
177    }
178    
179    auto OnPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
180    {
181        hdc = BeginPaint(hwnd, &ps);
182        GetClientRect(hwnd, &rc);
183        
184        auto left = rc.left;
185        auto top = rc.top;
186        auto right = rc.right;
187        auto bottom = rc.bottom;
188
189        auto width  = right - left;
190        auto height = bottom - top;
191        x = left;
192        y = top;
193
194        _buffer    = CreateCompatibleDC(hdc);
195        hBitmap    = CreateCompatibleBitmap(hdc, width, height);
196        hOldBitmap = SelectObject(_buffer, hBitmap);
197
198        auto surf = new Win32Surface(_buffer);
199        auto ctx = Context(surf);
200        
201        ctx.setSourceRGB(1, 1, 1);
202        ctx.paint();
203
204        roundedRectangle(ctx, 50, 50, 250, 250, 10, 10);
205        
206        auto clr = RGB(0.9411764705882353, 0.996078431372549, 0.9137254901960784);
207        ctx.setSourceRGB(clr);
208        ctx.fillPreserve();
209        
210        clr = RGB(0.7019607843137254, 1.0, 0.5529411764705883);
211        ctx.setSourceRGB(clr);
212        ctx.stroke();
213
214        ctx.setSourceRGB(0, 0, 0);
215        ctx.selectFontFace("Arial", FontSlant.CAIRO_FONT_SLANT_NORMAL, FontWeight.CAIRO_FONT_WEIGHT_NORMAL);
216        ctx.setFontSize(10.0);
217        auto txt = "Cairo is the greatest thing!";
218        ctx.moveTo(5.0, 10.0);
219        ctx.showText(txt);
220        
221        surf.finish();
222        BitBlt(hdc, 0, 0, width, height, _buffer, x, y, SRCCOPY);
223
224        SelectObject(_buffer, hOldBitmap);
225        DeleteObject(hBitmap);
226        DeleteDC(_buffer);
227
228        EndPaint(hwnd, &ps);
229        return 0;
230    }
231
232    auto OnDestroy(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
233    {
234        PostQuitMessage(0);
235        return 0;
236    }
237}