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 FormBorderStyle border_style;
56 internal bool allow_drop;
58 internal bool visible;
59 internal bool zero_sized;
60 internal Rectangle invalid;
61 internal bool expose_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 internal ArrayList marshal_free_list;
68 #endregion // Local Variables
70 #region Constructors and destructors
77 menu_handle = IntPtr.Zero;
78 border_style = FormBorderStyle.None;
79 client_window = IntPtr.Zero;
80 whole_window = IntPtr.Zero;
83 invalid = Rectangle.Empty;
84 expose_pending = false;
85 nc_expose_pending = false;
86 client_rectangle = Rectangle.Empty;
87 marshal_free_list = new ArrayList(2);
90 public void Dispose() {
91 windows[client_window] = null;
92 windows[whole_window] = null;
93 for (int i = 0; i < marshal_free_list.Count; i++) {
94 Marshal.FreeHGlobal((IntPtr)marshal_free_list[i]);
96 marshal_free_list.Clear();
100 #region Static Methods
101 public void SetObjectWindow(Hwnd obj, IntPtr window) {
102 windows[window] = obj;
105 public static Hwnd ObjectFromWindow(IntPtr window) {
106 return (Hwnd)windows[window];
109 public static Hwnd ObjectFromHandle(IntPtr handle) {
110 //return (Hwnd)(((GCHandle)handle).Target);
111 return (Hwnd)windows[handle];
114 public static IntPtr HandleFromObject(Hwnd obj) {
118 public static Hwnd GetObjectFromWindow(IntPtr window) {
119 return (Hwnd)windows[window];
122 public static IntPtr GetHandleFromWindow(IntPtr window) {
125 hwnd = (Hwnd)windows[window];
133 public static Rectangle GetWindowRectangle(FormBorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, Rectangle client_rect) {
136 rect = new Rectangle(client_rect.Location, client_rect.Size);
138 if (menu_handle != IntPtr.Zero) {
139 MenuAPI.MENU menu = MenuAPI.GetMenuFromID (menu_handle);
141 int menu_height = menu.Height;
142 rect.Y -= menu_height;
143 rect.Height += menu_height;
145 Console.WriteLine("Hwnd.GetWindowRectangle: No MENU for menu_handle = {0}", menu_handle);
148 switch(border_style) {
149 case FormBorderStyle.Fixed3D: {
157 case FormBorderStyle.FixedSingle: {
166 if (title_style == TitleStyle.Normal) {
167 rect.Y -= caption_height;
168 rect.Height += caption_height;
169 } else if (title_style == TitleStyle.Tool) {
170 rect.Y -= tool_caption_height;
171 rect.Height += tool_caption_height;
177 public static Rectangle GetClientRectangle(FormBorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, int width, int height) {
180 rect = new Rectangle(0, 0, width, height);
182 if (menu_handle != IntPtr.Zero) {
183 MenuAPI.MENU menu = MenuAPI.GetMenuFromID (menu_handle);
185 int menu_height = menu.Height;
186 rect.Y += menu_height;
187 rect.Height -= menu_height;
189 Console.WriteLine("Hwnd.GetClientRectangle: No MENU for menu_handle = {0}", menu_handle);
192 if (border_style == FormBorderStyle.Fixed3D) {
197 } else if (border_style == FormBorderStyle.FixedSingle) {
204 if (title_style == TitleStyle.Normal) {
205 rect.Y += caption_height;
206 rect.Height -= caption_height;
207 } else if (title_style == TitleStyle.Normal) {
208 rect.Y += tool_caption_height;
209 rect.Height -= tool_caption_height;
214 #endregion // Static Methods
216 #region Instance Properties
217 public FormBorderStyle BorderStyle {
223 border_style = value;
227 public Graphics ClientDC {
237 public Rectangle ClientRect {
239 if (client_rectangle == Rectangle.Empty) {
240 return DefaultClientRect;
242 return client_rectangle;
246 client_rectangle = value;
250 public IntPtr ClientWindow {
252 return client_window;
256 client_window = value;
259 if (windows[client_window] == null) {
260 windows[client_window] = this;
265 public Rectangle DefaultClientRect {
269 rect = new Rectangle(0, 0, width, height);
271 if (border_style == FormBorderStyle.Fixed3D) {
276 } else if (border_style == FormBorderStyle.FixedSingle) {
283 if (this.title_style == TitleStyle.Normal) {
284 rect.Y += caption_height;
285 rect.Height -= caption_height;
286 } else if (this.title_style == TitleStyle.Normal) {
287 rect.Y += tool_caption_height;
288 rect.Height -= tool_caption_height;
295 public bool ExposePending {
297 return expose_pending;
301 expose_pending = value;
305 public IntPtr Handle {
307 if (handle == IntPtr.Zero) {
308 throw new ArgumentNullException("Handle", "Handle is not yet assigned, need a ClientWindow");
324 public IntPtr MenuHandle {
334 public Point MenuOrigin {
338 pt = new Point(0, 0);
340 if (border_style == FormBorderStyle.Fixed3D) {
343 } else if (border_style == FormBorderStyle.FixedSingle) {
348 if (this.title_style == TitleStyle.Normal) {
349 pt.Y += caption_height;
350 } else if (this.title_style == TitleStyle.Normal) {
351 pt.Y += tool_caption_height;
357 public Rectangle Invalid {
367 public bool NCExposePending {
369 return nc_expose_pending;
373 nc_expose_pending = value;
387 public TitleStyle TitleStyle {
397 public object UserData {
407 public IntPtr WholeWindow {
413 whole_window = value;
415 if (windows[whole_window] == null) {
416 windows[whole_window] = this;
431 public bool Visible {
460 #endregion // Instance properties
463 public void AddInvalidArea(int x, int y, int width, int height) {
464 if (invalid == Rectangle.Empty) {
465 invalid = new Rectangle (x, y, width, height);
470 right = Math.Max (invalid.Right, x + width);
471 bottom = Math.Max (invalid.Bottom, y + height);
472 invalid.X = Math.Min (invalid.X, x);
473 invalid.Y = Math.Min (invalid.Y, y);
475 invalid.Width = right - invalid.X;
476 invalid.Height = bottom - invalid.Y;
479 public void AddInvalidArea(Rectangle rect) {
480 if (invalid == Rectangle.Empty) {
484 invalid = Rectangle.Union (invalid, rect);
487 public void ClearInvalidArea() {
488 invalid = Rectangle.Empty;
489 expose_pending = false;
491 #endregion // Methods