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