1 module winsamp;
2 
3 /+ Compile with:
4  +  dmd winsamp winsamp.def
5  + or:
6  +  dmd winsamp -L-Subsystem:Windows
7  +
8  + 64 bit version:
9  +  dmd -m64 winsamp -L-Subsystem:Windows user32.lib
10  +/
11 
12 pragma(lib, "gdi32.lib");
13 import core.runtime;
14 import core.sys.windows.windows;
15 import std.string;
16 
17 enum IDC_BTNCLICK     = 101;
18 enum IDC_BTNDONTCLICK = 102;
19 
20 extern(Windows)
21 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
22 {
23     int result;
24 
25     try
26     {
27         Runtime.initialize();
28         result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
29         Runtime.terminate();
30     }
31     catch (Throwable e)
32     {
33         MessageBoxA(null, e.toString().toStringz, "Error", MB_OK | MB_ICONEXCLAMATION);
34         result = 0;
35     }
36 
37     return result;
38 }
39 
40 int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
41 {
42     string caption = "The Hello Program";
43     string className = "DWndClass";
44     HWND hWnd, btnClick, btnDontClick;
45     MSG  msg;
46     WNDCLASS wndclass;
47 
48     wndclass.style         = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
49     wndclass.lpfnWndProc   = &WindowProc;
50     wndclass.cbClsExtra    = 0;
51     wndclass.cbWndExtra    = 0;
52     wndclass.hInstance     = hInstance;
53     wndclass.hIcon         = LoadIconA(null, IDI_APPLICATION);
54     wndclass.hCursor       = LoadCursorA(null, IDC_CROSS);
55     wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH);
56     wndclass.lpszMenuName  = null;
57     wndclass.lpszClassName = className.toStringz;
58 
59     if (!RegisterClassA(&wndclass))
60     {
61         MessageBoxA(null, "Couldn't register Window Class!", caption.toStringz, MB_ICONERROR);
62         return 0;
63     }
64 
65     hWnd = CreateWindowA(className.toStringz,  // window class name
66                          caption.toStringz,    // window caption
67                          WS_THICKFRAME   |
68                          WS_MAXIMIZEBOX  |
69                          WS_MINIMIZEBOX  |
70                          WS_SYSMENU      |
71                          WS_VISIBLE,           // window style
72                          CW_USEDEFAULT,        // initial x position
73                          CW_USEDEFAULT,        // initial y position
74                          600,                  // initial x size
75                          400,                  // initial y size
76                          HWND_DESKTOP,         // parent window handle
77                          null,                 // window menu handle
78                          hInstance,            // program instance handle
79                          null);                // creation parameters
80 
81     if (hWnd is null)
82     {
83         MessageBoxA(null, "Couldn't create window.", caption.toStringz, MB_ICONERROR);
84         return 0;
85     }
86 
87     btnClick = CreateWindowA("BUTTON", "Click Me", WS_CHILD | WS_VISIBLE,
88                              0, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNCLICK, hInstance, null);
89 
90     btnDontClick = CreateWindowA("BUTTON", "DON'T CLICK!", WS_CHILD | WS_VISIBLE,
91                                  110, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNDONTCLICK, hInstance, null);
92 
93     ShowWindow(hWnd, iCmdShow);
94     UpdateWindow(hWnd);
95 
96     while (GetMessageA(&msg, null, 0, 0))
97     {
98         TranslateMessage(&msg);
99         DispatchMessageA(&msg);
100     }
101 
102     return cast(int) msg.wParam;
103 }
104 
105 int* p;
106 extern(Windows)
107 LRESULT WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow
108 {
109     switch (message)
110     {
111         case WM_COMMAND:
112         {
113             switch (LOWORD(wParam))
114             {
115                 case IDC_BTNCLICK:
116                     if (HIWORD(wParam) == BN_CLICKED)
117                         MessageBoxA(hWnd, "Hello, world!", "Greeting",
118                                     MB_OK | MB_ICONINFORMATION);
119 
120                     break;
121 
122                 case IDC_BTNDONTCLICK:
123                     if (HIWORD(wParam) == BN_CLICKED)
124                     {
125                         MessageBoxA(hWnd, "You've been warned...", "Prepare to GP fault",
126                                     MB_OK | MB_ICONEXCLAMATION);
127                         *p = 1;
128                     }
129 
130                     break;
131 
132                 default:
133             }
134 
135             break;
136         }
137 
138         case WM_PAINT:
139         {
140             enum text = "D Does Windows";
141             PAINTSTRUCT ps;
142 
143             HDC  dc = BeginPaint(hWnd, &ps);
144             scope(exit) EndPaint(hWnd, &ps);
145             RECT r;
146             GetClientRect(hWnd, &r);
147             HFONT font = CreateFontA(80, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE,
148                                      FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
149                                      DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial");
150             HGDIOBJ old = SelectObject(dc, cast(HGDIOBJ) font);
151             SetTextAlign(dc, TA_CENTER | TA_BASELINE);
152             TextOutA(dc, r.right / 2, r.bottom / 2, text.toStringz, text.length);
153             DeleteObject(SelectObject(dc, old));
154 
155             break;
156         }
157 
158         case WM_DESTROY:
159             PostQuitMessage(0);
160             break;
161 
162         default:
163             break;
164     }
165 
166     return DefWindowProcA(hWnd, message, wParam, lParam);
167 }