]> cygwin.com Git - cygwin-apps/setup.git/blame - window.cc
2003-06-22 Max Bowsher <maxb@ukf.net>
[cygwin-apps/setup.git] / window.cc
CommitLineData
df62e023 1/*
0a539fe4 2 * Copyright (c) 2001, 2002, 2003 Gary R. Van Sickle.
df62e023
RC
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"
58db1046 22#include "String++.h"
0a539fe4 23#include "RECTWrapper.h"
df62e023
RC
24
25ATOM Window::WindowClassAtom = 0;
26HINSTANCE Window::AppInstance = NULL;
27
df62e023
RC
28Window::Window ()
29{
30 WindowHandle = NULL;
31 Parent = NULL;
b7301c43 32 FontCounter = 0;
df62e023
RC
33}
34
35Window::~Window ()
36{
b7301c43
RC
37 // Delete any fonts we created.
38 int i;
39 for (i = 0; i < FontCounter; i++)
40 {
41 DeleteObject (Fonts[i]);
42 }
43 FontCounter = 0;
44
df62e023
RC
45 // FIXME: Maybe do some reference counting and do this Unregister
46 // when there are no more of us left. Not real critical unless
47 // we're in a DLL which we're not right now.
48 //UnregisterClass(WindowClassAtom, InstanceHandle);
49}
50
51LRESULT CALLBACK
52Window::FirstWindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
53 LPARAM lParam)
54{
63c82708 55 Window *wnd = NULL;
df62e023 56
63c82708 57 if(uMsg == WM_NCCREATE)
df62e023 58 {
63c82708
RC
59 // This is the first message a window gets (so MSDN says anyway).
60 // Take this opportunity to "link" the HWND to the 'this' ptr, steering
61 // messages to the class instance's WindowProc().
62 wnd = reinterpret_cast<Window *>(((LPCREATESTRUCT)lParam)->lpCreateParams);
df62e023
RC
63
64 // Set a backreference to this class instance in the HWND.
0a539fe4 65 SetWindowLongPtr (hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(wnd));
df62e023
RC
66
67 // Set a new WindowProc now that we have the peliminaries done.
63c82708
RC
68 // We could instead simply do the contents of Window::WindowProcReflector
69 // in the 'else' clause below, but this way we eliminate an unnecessary 'if/else' on
70 // every message. Yeah, it's probably not worth the trouble.
71 SetWindowLongPtr (hwnd, GWL_WNDPROC, (LONG_PTR) & Window::WindowProcReflector);
72 }
73 else
74 {
75 // Should never get here.
76 abort();
df62e023
RC
77 }
78
63c82708 79 return wnd->WindowProc (uMsg, wParam, lParam);
df62e023
RC
80}
81
82LRESULT CALLBACK
83Window::WindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
84 LPARAM lParam)
85{
86 Window *This;
87
88 // Get our this pointer
0a539fe4 89 This = reinterpret_cast<Window *>(GetWindowLongPtr (hwnd, GWL_USERDATA));
df62e023
RC
90
91 return This->WindowProc (uMsg, wParam, lParam);
92}
93
94bool Window::Create (Window * parent, DWORD Style)
95{
96 // First register the window class, if we haven't already
97 if (RegisterWindowClass () == false)
98 {
99 // Registration failed
100 return false;
101 }
102
0a539fe4 103 // Save our parent, we'll probably need it eventually.
df62e023
RC
104 Parent = parent;
105
106 // Create the window instance
63c82708
RC
107 WindowHandle = CreateWindowEx (
108 // Extended Style
109 0,
110 "MainWindowClass", //MAKEINTATOM(WindowClassAtom), // window class atom (name)
df62e023
RC
111 "Hello", // no title-bar string yet
112 // Style bits
113 Style,
114 // Default positions and size
115 CW_USEDEFAULT,
116 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
117 // Parent Window
118 parent ==
119 NULL ? (HWND) NULL : parent->GetHWND (),
120 // use class menu
121 (HMENU) NULL,
122 // The application instance
63c82708
RC
123 GetInstance (),
124 // The this ptr, which we'll use to set up the WindowProc reflection.
125 (LPVOID) this);
df62e023
RC
126
127 if (WindowHandle == NULL)
128 {
129 // Failed
130 return false;
131 }
132
133 return true;
134}
135
136bool Window::RegisterWindowClass ()
137{
138 if (WindowClassAtom == 0)
139 {
140 // We're not registered yet
141 WNDCLASSEX
142 wc;
143
144 wc.cbSize = sizeof (wc);
145 // Some sensible style defaults
146 wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
147 // Our default window procedure. This replaces itself
148 // on the first call with the simpler Window::WindowProcReflector().
149 wc.lpfnWndProc = Window::FirstWindowProcReflector;
150 // No class bytes
151 wc.cbClsExtra = 0;
152 // One pointer to REFLECTION_INFO in the extra window instance bytes
153 wc.cbWndExtra = 4;
154 // The app instance
155 wc.hInstance = GetInstance ();
156 // Use a bunch of system defaults for the GUI elements
157 wc.hIcon = NULL;
158 wc.hIconSm = NULL;
159 wc.hCursor = NULL;
160 wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
161 // No menu
162 wc.lpszMenuName = NULL;
163 // We'll get a little crazy here with the class name
164 wc.lpszClassName = "MainWindowClass";
165
166 // All set, try to register
167 WindowClassAtom = RegisterClassEx (&wc);
168
169 if (WindowClassAtom == 0)
170 {
171 // Failed
172 return false;
173 }
174 }
175
176 // We're registered, or already were before the call,
177 // return success in either case.
178 return true;
179}
180
181void
182Window::Show (int State)
183{
184 ::ShowWindow (WindowHandle, State);
185}
186
63c82708
RC
187RECT
188Window::GetWindowRect() const
189{
190 RECT retval;
191 ::GetWindowRect(WindowHandle, &retval);
192 return retval;
193}
194
195RECT
196Window::GetClientRect() const
197{
198 RECT retval;
199 ::GetClientRect(WindowHandle, &retval);
200 return retval;
201}
202
203bool
204Window::MoveWindow(long x, long y, long w, long h, bool Repaint)
205{
206 return ::MoveWindow (WindowHandle, x, y, w, h, Repaint);
207}
208
0a539fe4
MB
209bool
210Window::MoveWindow(const RECTWrapper &r, bool Repaint)
211{
212 return ::MoveWindow (WindowHandle, r.left, r.top, r.width(), r.height(), Repaint);
213}
214
df62e023
RC
215void
216Window::CenterWindow ()
217{
218 RECT WindowRect, ParentRect;
219 int WindowWidth, WindowHeight;
220 POINT p;
221
222 // Get the window rectangle
63c82708 223 WindowRect = GetWindowRect ();
df62e023
RC
224
225 if (GetParent () == NULL)
226 {
227 // Center on desktop window
63c82708 228 ::GetWindowRect (GetDesktopWindow (), &ParentRect);
df62e023
RC
229 }
230 else
231 {
232 // Center on client area of parent
63c82708 233 ::GetClientRect (GetParent ()->GetHWND (), &ParentRect);
df62e023
RC
234 }
235
236 WindowWidth = WindowRect.right - WindowRect.left;
237 WindowHeight = WindowRect.bottom - WindowRect.top;
238
239 // Find center of area we're centering on
240 p.x = (ParentRect.right - ParentRect.left) / 2;
241 p.y = (ParentRect.bottom - ParentRect.top) / 2;
242
243 // Convert that to screen coords
244 if (GetParent () == NULL)
245 {
246 ClientToScreen (GetDesktopWindow (), &p);
247 }
248 else
249 {
250 ClientToScreen (GetParent ()->GetHWND (), &p);
251 }
252
253 // Calculate new top left corner for window
254 p.x -= WindowWidth / 2;
255 p.y -= WindowHeight / 2;
256
257 // And finally move the window
63c82708 258 MoveWindow (p.x, p.y, WindowWidth, WindowHeight);
df62e023
RC
259}
260
261LRESULT Window::WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
262{
263 switch (uMsg)
264 {
265 default:
266 return DefWindowProc (WindowHandle, uMsg, wParam, lParam);
267 }
268
269 return 0;
270}
271
272bool Window::MessageLoop ()
273{
274 MSG
275 msg;
276
277 while (GetMessage (&msg, NULL, 0, 0) != 0
278 && GetMessage (&msg, (HWND) NULL, 0, 0) != -1)
279 {
280 if (!IsWindow (WindowHandle) || !IsDialogMessage (WindowHandle, &msg))
281 {
282 TranslateMessage (&msg);
283 DispatchMessage (&msg);
284 }
285 }
286
287 return true;
288}
289
290void
291Window::PostMessage (UINT uMsg, WPARAM wParam, LPARAM lParam)
292{
293 ::PostMessage (GetHWND (), uMsg, wParam, lParam);
294}
b7301c43
RC
295
296UINT Window::IsButtonChecked (int nIDButton) const
297{
0a539fe4 298 return ::IsDlgButtonChecked (GetHWND (), nIDButton);
b7301c43
RC
299}
300
301bool
302 Window::SetDlgItemFont (int id, const TCHAR * fontname, int Pointsize,
303 int Weight, bool Italic, bool Underline,
304 bool Strikeout)
305{
306 HWND ctrl;
63c82708 307
b7301c43
RC
308 ctrl = GetDlgItem (id);
309 if (ctrl == NULL)
310 {
311 // Couldn't get that ID
312 return false;
313 }
314
315 // We need the DC for the point size calculation.
316 HDC hdc = GetDC (ctrl);
317
318 // Create the font. We have to keep it around until the dialog item
319 // goes away - basically until we're destroyed.
320 HFONT hfnt;
321 hfnt =
322 CreateFont (-MulDiv (Pointsize, GetDeviceCaps (hdc, LOGPIXELSY), 72), 0,
323 0, 0, Weight, Italic ? TRUE : FALSE,
324 Underline ? TRUE : FALSE, Strikeout ? TRUE : FALSE,
325 ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
326 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, fontname);
327 if (hfnt == NULL)
328 {
329 // Font creation failed
330 return false;
331 }
332
0a539fe4 333 // Set the new font, and redraw any text which was already in the item.
b7301c43
RC
334 SendMessage (ctrl, WM_SETFONT, (WPARAM) hfnt, TRUE);
335
336 // Save it for later.
337 Fonts[FontCounter] = hfnt;
338 FontCounter++;
339
340 return true;
341}
58db1046
RC
342
343void
344Window::SetWindowText (const String & s)
345{
346 ::SetWindowText (WindowHandle, s.cstr_oneuse ());
347}
63c82708
RC
348
349RECT
350Window::ScreenToClient(const RECT &r) const
351{
352 POINT tl;
353 POINT br;
354
355 tl.y = r.top;
356 tl.x = r.left;
357 ::ScreenToClient(GetHWND(), &tl);
358 br.y = r.bottom;
359 br.x = r.right;
360 ::ScreenToClient(GetHWND(), &br);
361
362 RECT ret;
363
364 ret.top = tl.y;
365 ret.left = tl.x;
366 ret.bottom = br.y;
367 ret.right = br.x;
368
369 return ret;
370}
371
This page took 0.070493 seconds and 5 git commands to generate.