2 * windows.c: Windows front end for my puzzle collection.
17 HBITMAP bitmap
, prevbm
;
25 void fatal(char *fmt
, ...)
31 vsprintf(buf
, fmt
, ap
);
34 MessageBox(NULL
, buf
, "Fatal error", MB_ICONEXCLAMATION
| MB_OK
);
39 void frontend_default_colour(frontend
*fe
, float *output
)
41 DWORD c
= GetSysColor(COLOR_MENU
); /* ick */
43 output
[0] = (float)(GetRValue(c
) / 255.0);
44 output
[1] = (float)(GetGValue(c
) / 255.0);
45 output
[2] = (float)(GetBValue(c
) / 255.0);
48 void draw_rect(frontend
*fe
, int x
, int y
, int w
, int h
, int colour
)
50 HBRUSH oldbrush
= SelectObject(fe
->hdc_bm
, fe
->brushes
[colour
]);
51 HPEN oldpen
= SelectObject(fe
->hdc_bm
, fe
->pens
[colour
]);
52 Rectangle(fe
->hdc_bm
, x
, y
, x
+w
, y
+h
);
53 SelectObject(fe
->hdc_bm
, oldbrush
);
54 SelectObject(fe
->hdc_bm
, oldpen
);
57 void draw_line(frontend
*fe
, int x1
, int y1
, int x2
, int y2
, int colour
)
59 HPEN oldpen
= SelectObject(fe
->hdc_bm
, fe
->pens
[colour
]);
60 MoveToEx(fe
->hdc_bm
, x1
, y1
, NULL
);
61 LineTo(fe
->hdc_bm
, x2
, y2
);
62 SetPixel(fe
->hdc_bm
, x2
, y2
, fe
->colours
[colour
]);
63 SelectObject(fe
->hdc_bm
, oldpen
);
66 void draw_polygon(frontend
*fe
, int *coords
, int npoints
,
69 POINT
*pts
= snewn(npoints
+1, POINT
);
72 for (i
= 0; i
<= npoints
; i
++) {
73 int j
= (i
< npoints ? i
: 0);
74 pts
[i
].x
= coords
[j
*2];
75 pts
[i
].y
= coords
[j
*2+1];
79 HBRUSH oldbrush
= SelectObject(fe
->hdc_bm
, fe
->brushes
[colour
]);
80 HPEN oldpen
= SelectObject(fe
->hdc_bm
, fe
->pens
[colour
]);
81 Polygon(fe
->hdc_bm
, pts
, npoints
);
82 SelectObject(fe
->hdc_bm
, oldbrush
);
83 SelectObject(fe
->hdc_bm
, oldpen
);
85 HPEN oldpen
= SelectObject(fe
->hdc_bm
, fe
->pens
[colour
]);
86 Polyline(fe
->hdc_bm
, pts
, npoints
+1);
87 SelectObject(fe
->hdc_bm
, oldpen
);
93 void start_draw(frontend
*fe
)
96 hdc_win
= GetDC(fe
->hwnd
);
97 fe
->hdc_bm
= CreateCompatibleDC(hdc_win
);
98 fe
->prevbm
= SelectObject(fe
->hdc_bm
, fe
->bitmap
);
99 ReleaseDC(fe
->hwnd
, hdc_win
);
102 void draw_update(frontend
*fe
, int x
, int y
, int w
, int h
)
111 InvalidateRect(fe
->hwnd
, &r
, FALSE
);
114 void end_draw(frontend
*fe
)
116 SelectObject(fe
->hdc_bm
, fe
->prevbm
);
117 DeleteDC(fe
->hdc_bm
);
120 void deactivate_timer(frontend
*fe
)
122 KillTimer(fe
->hwnd
, fe
->timer
);
126 void activate_timer(frontend
*fe
)
128 fe
->timer
= SetTimer(fe
->hwnd
, fe
->timer
, 20, NULL
);
131 static frontend
*new_window(HINSTANCE inst
)
139 fe
->me
= midend_new(fe
);
140 midend_new_game(fe
->me
, NULL
);
141 midend_size(fe
->me
, &x
, &y
);
149 colours
= midend_colours(fe
->me
, &ncolours
);
151 fe
->colours
= snewn(ncolours
, COLORREF
);
152 fe
->brushes
= snewn(ncolours
, HBRUSH
);
153 fe
->pens
= snewn(ncolours
, HPEN
);
155 for (i
= 0; i
< ncolours
; i
++) {
156 fe
->colours
[i
] = RGB(255 * colours
[i
*3+0],
157 255 * colours
[i
*3+1],
158 255 * colours
[i
*3+2]);
159 fe
->brushes
[i
] = CreateSolidBrush(fe
->colours
[i
]);
161 MessageBox(fe
->hwnd
, "ooh", "eck", MB_OK
);
162 fe
->pens
[i
] = CreatePen(PS_SOLID
, 1, fe
->colours
[i
]);
169 AdjustWindowRectEx(&r
, WS_OVERLAPPEDWINDOW
&~
170 (WS_THICKFRAME
| WS_MAXIMIZEBOX
| WS_OVERLAPPED
),
173 fe
->hwnd
= CreateWindowEx(0, "puzzle", "puzzle",
174 WS_OVERLAPPEDWINDOW
&~
175 (WS_THICKFRAME
| WS_MAXIMIZEBOX
),
176 CW_USEDEFAULT
, CW_USEDEFAULT
,
177 r
.right
- r
.left
, r
.bottom
- r
.top
,
178 NULL
, NULL
, inst
, NULL
);
180 hdc
= GetDC(fe
->hwnd
);
181 fe
->bitmap
= CreateCompatibleBitmap(hdc
, x
, y
);
182 ReleaseDC(fe
->hwnd
, hdc
);
184 SetWindowLong(fe
->hwnd
, GWL_USERDATA
, (LONG
)fe
);
186 ShowWindow(fe
->hwnd
, SW_NORMAL
);
187 SetForegroundWindow(fe
->hwnd
);
189 midend_redraw(fe
->me
);
194 static LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
,
195 WPARAM wParam
, LPARAM lParam
)
197 frontend
*fe
= (frontend
*)GetWindowLong(hwnd
, GWL_USERDATA
);
212 hdc
= BeginPaint(hwnd
, &p
);
213 hdc2
= CreateCompatibleDC(hdc
);
214 prevbm
= SelectObject(hdc2
, fe
->bitmap
);
216 p
.rcPaint
.left
, p
.rcPaint
.top
,
217 p
.rcPaint
.right
- p
.rcPaint
.left
,
218 p
.rcPaint
.bottom
- p
.rcPaint
.top
,
220 p
.rcPaint
.left
, p
.rcPaint
.top
,
222 SelectObject(hdc2
, prevbm
);
232 case VK_LEFT
: key
= CURSOR_LEFT
; break;
233 case VK_RIGHT
: key
= CURSOR_RIGHT
; break;
234 case VK_UP
: key
= CURSOR_UP
; break;
235 case VK_DOWN
: key
= CURSOR_DOWN
; break;
239 if (!midend_process_key(fe
->me
, -1, -1, key
))
247 if (!midend_process_key(fe
->me
, LOWORD(lParam
), HIWORD(lParam
),
248 (message
== WM_LBUTTONDOWN ? LEFT_BUTTON
:
249 message
== WM_RBUTTONDOWN ? RIGHT_BUTTON
:
255 if (!midend_process_key(fe
->me
, -1, -1, (unsigned char)wParam
))
260 midend_timer(fe
->me
, (float)0.02);
264 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
267 int WINAPI
WinMain(HINSTANCE inst
, HINSTANCE prev
, LPSTR cmdline
, int show
)
277 wndclass
.lpfnWndProc
= WndProc
;
278 wndclass
.cbClsExtra
= 0;
279 wndclass
.cbWndExtra
= 0;
280 wndclass
.hInstance
= inst
;
281 wndclass
.hIcon
= LoadIcon(inst
, IDI_APPLICATION
);
282 wndclass
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
283 wndclass
.hbrBackground
= NULL
;
284 wndclass
.lpszMenuName
= NULL
;
285 wndclass
.lpszClassName
= "puzzle";
287 RegisterClass(&wndclass
);
292 while (GetMessage(&msg
, NULL
, 0, 0)) {
293 TranslateMessage(&msg
);
294 DispatchMessage(&msg
);