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);