1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Peter Bartok (pbartok@novell.com)
30 using System.Collections;
32 using System.Runtime.InteropServices;
34 // NOTE: Possible optimization:
35 // Several properties calculate dimensions on the fly; instead; they can
36 // be stored in a field and only be recalculated when a style is changed (DefaultClientRect, for example)
38 namespace System.Windows.Forms {
39 internal class Hwnd : IDisposable {
40 #region Local Variables
41 private static Hashtable windows = new Hashtable(100, 0.5f);
42 private const int menu_height = 14; // FIXME - Read this value from somewhere
43 private const int caption_height = 0; // FIXME - Read this value from somewhere
44 private const int tool_caption_height = 0; // FIXME - Read this value from somewhere
46 private IntPtr handle;
47 internal IntPtr client_window;
48 internal IntPtr whole_window;
49 internal IntPtr menu_handle;
50 internal TitleStyle title_style;
51 internal BorderStyle border_style;
52 internal Border3DStyle edge_style;
58 internal bool visible;
59 internal Rectangle invalid;
60 internal bool expose_pending;
61 internal bool erase_pending;
62 internal bool nc_expose_pending;
63 internal bool configure_pending;
64 internal Graphics client_dc;
65 internal object user_data;
66 internal Rectangle client_rectangle;
67 #endregion // Local Variables
69 #region Constructors and destructors
76 menu_handle = IntPtr.Zero;
77 border_style = BorderStyle.None;
78 client_window = IntPtr.Zero;
79 whole_window = IntPtr.Zero;
82 invalid = Rectangle.Empty;
83 expose_pending = false;
84 nc_expose_pending = false;
85 edge_style = Border3DStyle.Raised;
86 client_rectangle = Rectangle.Empty;
90 public void Dispose() {
91 windows[client_window] = null;
92 windows[whole_window] = null;
93 Console.WriteLine("Disposing window {0:X} (whole: {1:X})", client_window.ToInt32(), whole_window.ToInt32());
97 #region Static Methods
98 public void SetObjectWindow(Hwnd obj, IntPtr window) {
99 windows[window] = obj;
102 public static Hwnd ObjectFromWindow(IntPtr window) {
103 return (Hwnd)windows[window];
106 public static Hwnd ObjectFromHandle(IntPtr handle) {
107 //return (Hwnd)(((GCHandle)handle).Target);
108 return (Hwnd)windows[handle];
111 public static IntPtr HandleFromObject(Hwnd obj) {
115 public static Hwnd GetObjectFromWindow(IntPtr window) {
116 return (Hwnd)windows[window];
119 public static IntPtr GetHandleFromWindow(IntPtr window) {
122 hwnd = (Hwnd)windows[window];
130 public static Rectangle GetWindowRectangle(BorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, Rectangle client_rect) {
133 rect = new Rectangle(client_rect.Location, client_rect.Size);
135 if (menu_handle != IntPtr.Zero) {
136 rect.Y -= menu_height;
137 rect.Height += menu_height;
140 if (border_style == BorderStyle.Fixed3D) {
145 } else if (border_style == BorderStyle.FixedSingle) {
152 if (title_style == TitleStyle.Normal) {
153 rect.Y -= caption_height;
154 rect.Height += caption_height;
155 } else if (title_style == TitleStyle.Tool) {
156 rect.Y -= tool_caption_height;
157 rect.Height += tool_caption_height;
163 public static Rectangle GetClientRectangle(BorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, int width, int height) {
166 rect = new Rectangle(0, 0, width, height);
168 if (menu_handle != IntPtr.Zero) {
169 rect.Y += menu_height;
170 rect.Height -= menu_height;
173 if (border_style == BorderStyle.Fixed3D) {
178 } else if (border_style == BorderStyle.FixedSingle) {
185 if (title_style == TitleStyle.Normal) {
186 rect.Y += caption_height;
187 rect.Height -= caption_height;
188 } else if (title_style == TitleStyle.Normal) {
189 rect.Y += tool_caption_height;
190 rect.Height -= tool_caption_height;
195 #endregion // Static Methods
197 #region Instance Properties
198 public BorderStyle BorderStyle {
204 border_style = value;
208 public Graphics ClientDC {
218 public Rectangle ClientRect {
220 if (client_rectangle == Rectangle.Empty) {
221 return DefaultClientRect;
223 return client_rectangle;
227 client_rectangle = value;
231 public IntPtr ClientWindow {
233 return client_window;
237 client_window = value;
240 if (windows[client_window] == null) {
241 windows[client_window] = this;
246 public Rectangle DefaultClientRect {
250 rect = new Rectangle(0, 0, width, height);
252 if (border_style == BorderStyle.Fixed3D) {
257 } else if (border_style == BorderStyle.FixedSingle) {
264 if (this.title_style == TitleStyle.Normal) {
265 rect.Y += caption_height;
266 rect.Height -= caption_height;
267 } else if (this.title_style == TitleStyle.Normal) {
268 rect.Y += tool_caption_height;
269 rect.Height -= tool_caption_height;
276 public Border3DStyle EdgeStyle {
286 public bool ErasePending {
288 return erase_pending;
292 erase_pending = value;
296 public bool ExposePending {
298 return expose_pending;
302 expose_pending = value;
306 public IntPtr Handle {
308 if (handle == IntPtr.Zero) {
309 throw new ArgumentNullException("Handle", "Handle is not yet assigned, need a ClientWindow");
325 public IntPtr MenuHandle {
335 public Point MenuOrigin {
339 pt = new Point(0, 0);
341 if (border_style == BorderStyle.Fixed3D) {
344 } else if (border_style == BorderStyle.FixedSingle) {
349 if (this.title_style == TitleStyle.Normal) {
350 pt.Y += caption_height;
351 } else if (this.title_style == TitleStyle.Normal) {
352 pt.Y += tool_caption_height;
358 public Rectangle Invalid {
368 public bool NCExposePending {
370 return nc_expose_pending;
374 nc_expose_pending = value;
388 public TitleStyle TitleStyle {
398 public object UserData {
408 public IntPtr WholeWindow {
414 whole_window = value;
416 if (windows[whole_window] == null) {
417 windows[whole_window] = this;
432 public bool Visible {
461 #endregion // Instance properties
464 public void AddInvalidArea(int x, int y, int width, int height) {
465 if (invalid == Rectangle.Empty) {
466 invalid = new Rectangle (x, y, width, height);
469 invalid = Rectangle.Union (invalid, new Rectangle (x, y, width, height));
472 public void AddInvalidArea(Rectangle rect) {
473 if (invalid == Rectangle.Empty) {
477 invalid = Rectangle.Union (invalid, rect);
480 public void ClearInvalidArea() {
481 invalid = Rectangle.Empty;
482 expose_pending = false;
484 #endregion // Methods