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