* ImageList.cs: When the image stream is set pull all the images
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Hwnd.cs
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:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
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.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    (pbartok@novell.com)
24 //
25 //
26
27 // NOT COMPLETE
28
29 using System;
30 using System.Collections;
31 using System.Drawing;
32 using System.Runtime.InteropServices;
33
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)
37
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
45
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;
53                 internal int            x;
54                 internal int            y;
55                 internal int            width;
56                 internal int            height;
57                 internal Hwnd           parent;
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
68
69                 #region Constructors and destructors
70                 public Hwnd() {
71                         x = 0;
72                         y = 0;
73                         width = 0;
74                         height = 0;
75                         visible = false;
76                         menu_handle = IntPtr.Zero;
77                         border_style = BorderStyle.None;
78                         client_window = IntPtr.Zero;
79                         whole_window = IntPtr.Zero;
80                         handle = IntPtr.Zero;
81                         parent = null;
82                         invalid = Rectangle.Empty;
83                         expose_pending = false;
84                         nc_expose_pending = false;
85                         edge_style = Border3DStyle.Raised;
86                         client_rectangle = Rectangle.Empty;
87                         erase_pending = true;
88                 }
89
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());
94                 }
95                 #endregion
96
97                 #region Static Methods
98                 public void SetObjectWindow(Hwnd obj, IntPtr window) {
99                         windows[window] = obj;
100                 }
101
102                 public static Hwnd ObjectFromWindow(IntPtr window) {
103                         return (Hwnd)windows[window];
104                 }
105
106                 public static Hwnd ObjectFromHandle(IntPtr handle) {
107                         //return (Hwnd)(((GCHandle)handle).Target);
108                         return (Hwnd)windows[handle];
109                 }
110
111                 public static IntPtr HandleFromObject(Hwnd obj) {
112                         return obj.handle;
113                 }
114
115                 public static Hwnd GetObjectFromWindow(IntPtr window) {
116                         return (Hwnd)windows[window];
117                 }
118
119                 public static IntPtr GetHandleFromWindow(IntPtr window) {
120                         Hwnd    hwnd;
121
122                         hwnd = (Hwnd)windows[window];
123                         if (hwnd != null) {
124                                 return hwnd.handle;
125                         } else {
126                                 return IntPtr.Zero;
127                         }
128                 }
129
130                 public static Rectangle GetWindowRectangle(BorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, Rectangle client_rect) {
131                         Rectangle       rect;
132
133                         rect = new Rectangle(client_rect.Location, client_rect.Size);
134
135                         if (menu_handle != IntPtr.Zero) {
136                                 rect.Y -= menu_height;
137                                 rect.Height += menu_height;
138                         }
139
140                         if (border_style == BorderStyle.Fixed3D) {
141                                 rect.X -= 2;
142                                 rect.Y -= 2;
143                                 rect.Width += 4;
144                                 rect.Height += 4;
145                         } else if (border_style == BorderStyle.FixedSingle) {
146                                 rect.X -= 1;
147                                 rect.Y -= 1;
148                                 rect.Width += 2;
149                                 rect.Height += 2;
150                         }
151
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;
158                         }
159
160                         return rect;
161                 }
162
163                 public static Rectangle GetClientRectangle(BorderStyle border_style, IntPtr menu_handle, TitleStyle title_style, int width, int height) {
164                         Rectangle rect;
165
166                         rect = new Rectangle(0, 0, width, height);
167
168                         if (menu_handle != IntPtr.Zero) {
169                                 rect.Y += menu_height;
170                                 rect.Height -= menu_height;
171                         }
172
173                         if (border_style == BorderStyle.Fixed3D) {
174                                 rect.X += 2;
175                                 rect.Y += 2;
176                                 rect.Width -= 4;
177                                 rect.Height -= 4;
178                         } else if (border_style == BorderStyle.FixedSingle) {
179                                 rect.X += 1;
180                                 rect.Y += 1;
181                                 rect.Width -= 2;
182                                 rect.Height -= 2;
183                         }
184
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;
191                         }
192
193                         return rect;
194                 }
195                 #endregion      // Static Methods
196
197                 #region Instance Properties
198                 public BorderStyle BorderStyle {
199                         get {
200                                 return border_style;
201                         }
202
203                         set {
204                                 border_style = value;
205                         }
206                 }
207
208                 public Graphics ClientDC {
209                         get {
210                                 return client_dc;
211                         }
212
213                         set {
214                                 client_dc = value;
215                         }
216                 }
217
218                 public Rectangle ClientRect {
219                         get {
220                                 if (client_rectangle == Rectangle.Empty) {
221                                         return DefaultClientRect;
222                                 }
223                                 return client_rectangle;
224                         }
225
226                         set {
227                                 client_rectangle = value;
228                         }
229                 }
230
231                 public IntPtr ClientWindow {
232                         get {
233                                 return client_window;
234                         }
235
236                         set {
237                                 client_window = value;
238                                 handle = value;
239
240                                 if (windows[client_window] == null) {
241                                         windows[client_window] = this;
242                                 }
243                         }
244                 }
245
246                 public Rectangle DefaultClientRect {
247                         get {
248                                 Rectangle rect;
249
250                                 rect = new Rectangle(0, 0, width, height);
251
252                                 if (border_style == BorderStyle.Fixed3D) {
253                                         rect.X += 2;
254                                         rect.Y += 2;
255                                         rect.Width -= 4;
256                                         rect.Height -= 4;
257                                 } else if (border_style == BorderStyle.FixedSingle) {
258                                         rect.X += 1;
259                                         rect.Y += 1;
260                                         rect.Width -= 2;
261                                         rect.Height -= 2;
262                                 }
263
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;
270                                 }
271
272                                 return rect;
273                         }
274                 }
275
276                 public Border3DStyle EdgeStyle {
277                         get {
278                                 return edge_style;
279                         }
280
281                         set {
282                                 edge_style = value;
283                         }
284                 }
285
286                 public bool ErasePending {
287                         get {
288                                 return erase_pending;
289                         }
290
291                         set {
292                                 erase_pending = value;
293                         }
294                 }
295
296                 public bool ExposePending {
297                         get {
298                                 return expose_pending;
299                         }
300
301                         set {
302                                 expose_pending = value;
303                         }
304                 }
305
306                 public IntPtr Handle {
307                         get {
308                                 if (handle == IntPtr.Zero) {
309                                         throw new ArgumentNullException("Handle", "Handle is not yet assigned, need a ClientWindow");
310                                 }
311                                 return handle;
312                         }
313                 }
314
315                 public int Height {
316                         get {
317                                 return height;
318                         }
319
320                         set {
321                                 height = value;
322                         }
323                 }
324
325                 public IntPtr MenuHandle {
326                         get {
327                                 return menu_handle;
328                         }
329
330                         set {
331                                 menu_handle = value;
332                         }
333                 }
334
335                 public Point MenuOrigin {
336                         get {
337                                 Point   pt;
338
339                                 pt = new Point(0, 0);
340
341                                 if (border_style == BorderStyle.Fixed3D) {
342                                         pt.X += 2;
343                                         pt.Y += 2;
344                                 } else if (border_style == BorderStyle.FixedSingle) {
345                                         pt.X += 1;
346                                         pt.Y += 1;
347                                 }
348
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;
353                                 }
354
355                                 return pt;
356                         }
357                 }
358                 public Rectangle Invalid {
359                         get {
360                                 return invalid;
361                         }
362
363                         set {
364                                 invalid = value;
365                         }
366                 }
367
368                 public bool NCExposePending {
369                         get {
370                                 return nc_expose_pending;
371                         }
372
373                         set {
374                                 nc_expose_pending = value;
375                         }
376                 }
377
378                 public Hwnd Parent {
379                         get {
380                                 return parent;
381                         }
382
383                         set {
384                                 parent = value;
385                         }
386                 }
387
388                 public TitleStyle TitleStyle {
389                         get {
390                                 return title_style;
391                         }
392
393                         set {
394                                 title_style = value;
395                         }
396                 }
397
398                 public object UserData {
399                         get {
400                                 return user_data;
401                         }
402
403                         set {
404                                 user_data = value;
405                         }
406                 }
407
408                 public IntPtr WholeWindow {
409                         get {
410                                 return whole_window;
411                         }
412
413                         set {
414                                 whole_window = value;
415
416                                 if (windows[whole_window] == null) {
417                                         windows[whole_window] = this;
418                                 }
419                         }
420                 }
421
422                 public int Width {
423                         get {
424                                 return width;
425                         }
426
427                         set {
428                                 width = value;
429                         }
430                 }
431
432                 public bool Visible {
433                         get {
434                                 return visible;
435                         }
436
437                         set {
438                                 visible = value;
439                         }
440                 }
441
442                 public int X {
443                         get {
444                                 return x;
445                         }
446
447                         set {
448                                 x = value;
449                         }
450                 }
451
452                 public int Y {
453                         get {
454                                 return y;
455                         }
456
457                         set {
458                                 y = value;
459                         }
460                 }
461                 #endregion      // Instance properties
462
463                 #region Methods
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);
467                                 return;
468                         }
469                         invalid = Rectangle.Union (invalid, new Rectangle (x, y, width, height));
470                 }
471
472                 public void AddInvalidArea(Rectangle rect) {
473                         if (invalid == Rectangle.Empty) {
474                                 invalid = rect;
475                                 return;
476                         }
477                         invalid = Rectangle.Union (invalid, rect);
478                 }
479
480                 public void ClearInvalidArea() {
481                         invalid = Rectangle.Empty;
482                         expose_pending = false;
483                 }
484                 #endregion      // Methods
485         }
486 }