]> cygwin.com Git - cygwin-apps/setup.git/blob - window.cc
2002-02-19 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / window.cc
1 /*
2 * Copyright (c) 2001, Gary R. Van Sickle.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
13 *
14 */
15
16 // This is the implementation of the Window class. It serves both as a window class
17 // in its own right and as a base class for other window-like classes (e.g. PropertyPage,
18 // PropSheet).
19
20 #include <windows.h>
21 #include "window.h"
22
23 ATOM Window::WindowClassAtom = 0;
24 HINSTANCE Window::AppInstance = NULL;
25
26 // FIXME: I know, this is brutal. Mutexing should at least make window creation threadsafe,
27 // but if somebody has any ideas as to how to get rid of it entirely, please tell me / do so.
28 struct REFLECTION_INFO
29 {
30 Window *
31 This;
32 bool
33 FirstCall;
34 };
35 REFLECTION_INFO ReflectionInfo;
36
37 Window::Window ()
38 {
39 WindowHandle = NULL;
40 Parent = NULL;
41 FontCounter = 0;
42 }
43
44 Window::~Window ()
45 {
46 // Delete any fonts we created.
47 int i;
48 for (i = 0; i < FontCounter; i++)
49 {
50 DeleteObject (Fonts[i]);
51 }
52 FontCounter = 0;
53
54 // FIXME: Maybe do some reference counting and do this Unregister
55 // when there are no more of us left. Not real critical unless
56 // we're in a DLL which we're not right now.
57 //UnregisterClass(WindowClassAtom, InstanceHandle);
58 }
59
60 LRESULT CALLBACK
61 Window::FirstWindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
62 LPARAM lParam)
63 {
64 // Get our this pointer
65 REFLECTION_INFO *rip = &ReflectionInfo;
66
67 if (rip->FirstCall)
68 {
69 rip->FirstCall = false;
70
71 // Set the Window handle so the real WindowProc has one to work with.
72 rip->This->WindowHandle = hwnd;
73
74 // Set a backreference to this class instance in the HWND.
75 // FIXME: Should really be SetWindowLongPtr(), but it appears to
76 // not be defined yet.
77 SetWindowLong (hwnd, GWL_USERDATA, (LONG) rip->This);
78
79 // Set a new WindowProc now that we have the peliminaries done.
80 // Like subclassing, only not.
81 SetWindowLong (hwnd, GWL_WNDPROC, (LONG) & Window::WindowProcReflector);
82 }
83
84 return rip->This->WindowProc (uMsg, wParam, lParam);
85 }
86
87 LRESULT CALLBACK
88 Window::WindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
89 LPARAM lParam)
90 {
91 Window *This;
92
93 // Get our this pointer
94 // FIXME: Should really be GetWindowLongPtr(), but it appears to
95 // not be defined yet.
96 This = (Window *) GetWindowLong (hwnd, GWL_USERDATA);
97
98 return This->WindowProc (uMsg, wParam, lParam);
99 }
100
101 bool Window::Create (Window * parent, DWORD Style)
102 {
103 // First register the window class, if we haven't already
104 if (RegisterWindowClass () == false)
105 {
106 // Registration failed
107 return false;
108 }
109
110 // Set up the reflection info, so that the Windows window can find us.
111 ReflectionInfo.This = this;
112 ReflectionInfo.FirstCall = true;
113
114 Parent = parent;
115
116 // Create the window instance
117 WindowHandle = CreateWindow ("MainWindowClass", //MAKEINTATOM(WindowClassAtom), // window class atom (name)
118 "Hello", // no title-bar string yet
119 // Style bits
120 Style,
121 // Default positions and size
122 CW_USEDEFAULT,
123 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
124 // Parent Window
125 parent ==
126 NULL ? (HWND) NULL : parent->GetHWND (),
127 // use class menu
128 (HMENU) NULL,
129 // The application instance
130 GetInstance (), (LPVOID) NULL);
131
132 if (WindowHandle == NULL)
133 {
134 // Failed
135 return false;
136 }
137
138 return true;
139 }
140
141 bool Window::RegisterWindowClass ()
142 {
143 if (WindowClassAtom == 0)
144 {
145 // We're not registered yet
146 WNDCLASSEX
147 wc;
148
149 wc.cbSize = sizeof (wc);
150 // Some sensible style defaults
151 wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
152 // Our default window procedure. This replaces itself
153 // on the first call with the simpler Window::WindowProcReflector().
154 wc.lpfnWndProc = Window::FirstWindowProcReflector;
155 // No class bytes
156 wc.cbClsExtra = 0;
157 // One pointer to REFLECTION_INFO in the extra window instance bytes
158 wc.cbWndExtra = 4;
159 // The app instance
160 wc.hInstance = GetInstance ();
161 // Use a bunch of system defaults for the GUI elements
162 wc.hIcon = NULL;
163 wc.hIconSm = NULL;
164 wc.hCursor = NULL;
165 wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
166 // No menu
167 wc.lpszMenuName = NULL;
168 // We'll get a little crazy here with the class name
169 wc.lpszClassName = "MainWindowClass";
170
171 // All set, try to register
172 WindowClassAtom = RegisterClassEx (&wc);
173
174 if (WindowClassAtom == 0)
175 {
176 // Failed
177 return false;
178 }
179 }
180
181 // We're registered, or already were before the call,
182 // return success in either case.
183 return true;
184 }
185
186 void
187 Window::Show (int State)
188 {
189 ::ShowWindow (WindowHandle, State);
190 }
191
192 void
193 Window::CenterWindow ()
194 {
195 RECT WindowRect, ParentRect;
196 int WindowWidth, WindowHeight;
197 POINT p;
198
199 // Get the window rectangle
200 GetWindowRect (GetHWND (), &WindowRect);
201
202 if (GetParent () == NULL)
203 {
204 // Center on desktop window
205 GetWindowRect (GetDesktopWindow (), &ParentRect);
206 }
207 else
208 {
209 // Center on client area of parent
210 GetClientRect (GetParent ()->GetHWND (), &ParentRect);
211 }
212
213 WindowWidth = WindowRect.right - WindowRect.left;
214 WindowHeight = WindowRect.bottom - WindowRect.top;
215
216 // Find center of area we're centering on
217 p.x = (ParentRect.right - ParentRect.left) / 2;
218 p.y = (ParentRect.bottom - ParentRect.top) / 2;
219
220 // Convert that to screen coords
221 if (GetParent () == NULL)
222 {
223 ClientToScreen (GetDesktopWindow (), &p);
224 }
225 else
226 {
227 ClientToScreen (GetParent ()->GetHWND (), &p);
228 }
229
230 // Calculate new top left corner for window
231 p.x -= WindowWidth / 2;
232 p.y -= WindowHeight / 2;
233
234 // And finally move the window
235 MoveWindow (GetHWND (), p.x, p.y, WindowWidth, WindowHeight, TRUE);
236 }
237
238 LRESULT Window::WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
239 {
240 switch (uMsg)
241 {
242 default:
243 return DefWindowProc (WindowHandle, uMsg, wParam, lParam);
244 }
245
246 return 0;
247 }
248
249 bool Window::MessageLoop ()
250 {
251 MSG
252 msg;
253
254 while (GetMessage (&msg, NULL, 0, 0) != 0
255 && GetMessage (&msg, (HWND) NULL, 0, 0) != -1)
256 {
257 if (!IsWindow (WindowHandle) || !IsDialogMessage (WindowHandle, &msg))
258 {
259 TranslateMessage (&msg);
260 DispatchMessage (&msg);
261 }
262 }
263
264 return true;
265 }
266
267 void
268 Window::PostMessage (UINT uMsg, WPARAM wParam, LPARAM lParam)
269 {
270 ::PostMessage (GetHWND (), uMsg, wParam, lParam);
271 }
272
273 UINT Window::IsButtonChecked (int nIDButton) const
274 {
275 return::IsDlgButtonChecked (GetHWND (), nIDButton);
276 }
277
278 bool
279 Window::SetDlgItemFont (int id, const TCHAR * fontname, int Pointsize,
280 int Weight, bool Italic, bool Underline,
281 bool Strikeout)
282 {
283 HWND ctrl;
284 ctrl = GetDlgItem (id);
285 if (ctrl == NULL)
286 {
287 // Couldn't get that ID
288 return false;
289 }
290
291 // We need the DC for the point size calculation.
292 HDC hdc = GetDC (ctrl);
293
294 // Create the font. We have to keep it around until the dialog item
295 // goes away - basically until we're destroyed.
296 HFONT hfnt;
297 hfnt =
298 CreateFont (-MulDiv (Pointsize, GetDeviceCaps (hdc, LOGPIXELSY), 72), 0,
299 0, 0, Weight, Italic ? TRUE : FALSE,
300 Underline ? TRUE : FALSE, Strikeout ? TRUE : FALSE,
301 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
302 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname);
303 if (hfnt == NULL)
304 {
305 // Font creation failed
306 return false;
307 }
308
309 // Set the new fint, and redraw any text which was already in the item.
310 SendMessage (ctrl, WM_SETFONT, (WPARAM) hfnt, TRUE);
311
312 // Save it for later.
313 Fonts[FontCounter] = hfnt;
314 FontCounter++;
315
316 return true;
317 }
This page took 0.048467 seconds and 5 git commands to generate.