* X11Keyboard.cs: Detect and use the num lock mask.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Control.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) 2004 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok            pbartok@novell.com
24 //
25 // Based on work by:
26 //      Aleksey Ryabchuk        ryabchuk@yahoo.com
27 //      Alexandre Pigolkine     pigolkine@gmx.de
28 //      Dennis Hayes            dennish@raytek.com
29 //      Jaak Simm               jaaksimm@firm.ee
30 //      John Sohn               jsohn@columbus.rr.com
31 //
32 // $Revision: 1.76 $
33 // $Modtime: $
34 // $Log: Control.cs,v $
35 // Revision 1.76  2004/11/05 19:16:48  jackson
36 // Do not call CreateHandle if the handle is already created
37 //
38 // Revision 1.75  2004/10/22 17:49:35  jackson
39 // oops
40 //
41 // Revision 1.74  2004/10/22 17:41:28  jackson
42 // Check to see if the window should have its background repainted by X when drawing.
43 //
44 // Revision 1.73  2004/10/20 03:52:06  pbartok
45 // - Removed unneeded locals
46 // - Added code to all size and location properties to understand and
47 //   deal with the parent container of Form
48 //
49 // Revision 1.71  2004/10/18 06:27:39  ravindra
50 // Default value of visible property must be true.
51 //
52 // Revision 1.70  2004/10/18 04:16:29  pbartok
53 // - Fixed/implemented flat list of controls
54 //
55 // Revision 1.69  2004/10/13 02:57:36  pbartok
56 // - Fix from John BouAntoun: Raise ForeColorChanged event when text color is
57 //   changed
58 //
59 // Revision 1.68  2004/10/06 09:59:05  jordi
60 // removes warnings from compilation
61 //
62 // Revision 1.67  2004/10/05 03:18:16  jackson
63 // When resizing the buffers should be invalidated. This should be handled in Control not in derived classes.
64 //
65 // Revision 1.66  2004/10/02 19:02:56  pbartok
66 // - Added private method to get the Control object from the window handle
67 // - Implemented ContextMenu property
68 // - Implemented PointToScreen
69 // - Implemented PreProcessMessage
70 // - Implemented IsInputChar
71 // - Implemented IsInputKey
72 // - Implemented ProcessCmdKey
73 // - Completed ProcessKeyEventArgs
74 // - Fixed message loop to call the proper chain of functions on key events
75 // - Implemented ProcessDialogChar
76 // - Implemented ProcessDialogKey
77 // - Implemented ProcessKeyMessage
78 // - Implemented ProcessKeyPreview
79 // - Added RaiseDragEvent stub (MS internal method)
80 // - Added RaiseKeyEvent stub (MS internal method)
81 // - Added RaiseMouseEvent stub (MS Internal method)
82 // - Added RaisePaintEvent stub (MS Internal method)
83 // - Added ResetMouseEventArgs stub (MS Internal method)
84 // - Implemented RtlTranslateAlignment
85 // - Implemented RtlTranslateContent
86 // - Implemented RtlTranslateHorizontal
87 // - Implemented RtlTranslateLeftRight
88 // - Added generation of KeyPress event
89 //
90 // Revision 1.65  2004/09/22 18:01:28  jackson
91 // Text is never null
92 //
93 // Revision 1.64  2004/09/16 23:44:19  pbartok
94 // - Added SendToBack and BringToFront methods
95 //
96 // Revision 1.63  2004/09/11 03:50:00  pbartok
97 // - Added DoDragDrop() [incomplete]
98 // - Properly implemented 'Visible' handling
99 // - Added SetVisibleCore()
100 // - Implemented FindChildAtPoint()
101 // - Implemented GetContainerControl()
102 // - Implemented Hide()
103 //
104 // Revision 1.62  2004/09/11 01:28:11  pbartok
105 // - Moved methods into their appropriate #regions
106 // - Reordered methods within regions alphabetically
107 //
108 // Revision 1.61  2004/09/11 00:56:33  pbartok
109 // - Moved some internal functions into the internal region
110 // - Implemented FontHeight
111 // - Implemented RenderRightToLeft
112 // - Implemented ResizeRedraw
113 // - Implemented ShowFocusCues
114 // - Implemented ShowKeyboardCues
115 // - Implemented FromChildHandle
116 // - Implemented FromHandle
117 // - Implemented IsMnemonic
118 // - Implemented ReflectMessage
119 // - All public and protected Static Methods are now complete
120 //
121 // Revision 1.60  2004/09/10 22:54:52  pbartok
122 // - Implemented remaining missing public instance properties
123 // - Alphabetized some out of order properties
124 //
125 // Revision 1.59  2004/09/06 12:55:07  jordi
126 // Caches ClientRectangle rectangle value
127 //
128 // Revision 1.58  2004/09/02 22:24:50  pbartok
129 // - Added sanity check to creation of double buffer bitmap
130 //
131 // Revision 1.57  2004/09/02 20:26:21  pbartok
132 // - Added missing Control.ControlAccessibleObject class
133 // - Started to implement Select()ion mechanisms, still very incomplete
134 //
135 // Revision 1.56  2004/09/01 13:19:19  jordi
136 // Init string variables with an empty object
137 //
138 // Revision 1.55  2004/09/01 10:20:57  jordi
139 // fires OnFontChanged event
140 //
141 // Revision 1.54  2004/09/01 01:41:31  pbartok
142 // - Added firing of BackColorChanged event
143 // - Added TopLevelControl property
144 // - Fixed handling of WM_ERASEBKGRND message
145 //
146 // Revision 1.53  2004/08/27 20:17:25  pbartok
147 // - Removed unneeded stack vars
148 // - First attempt to fix sizing issues when layout is suspended
149 //
150 // Revision 1.52  2004/08/25 19:20:47  pbartok
151 // - Control now properly passes the ambient background color to child
152 //   controls
153 //
154 // Revision 1.51  2004/08/25 18:32:15  pbartok
155 // - Fixed generation of MouseUp message
156 //
157 // Revision 1.50  2004/08/24 18:24:25  jordi
158 // fire OnEnabledChanged event
159 //
160 // Revision 1.49  2004/08/23 21:22:53  pbartok
161 // - Added InitLayout() method
162 // - Added code to properly perform layout when Anchor or Dock property is
163 //   changed
164 // - Changed 'interpretation' of ResumeLayout. MS seems to have a LAMESPEC,
165 //   tried to do it in a way that makes sense
166 //
167 // Revision 1.48  2004/08/23 19:55:08  pbartok
168 // - Properly fixed Jordi's last fix
169 // - Now uses Cursor's Position property instead of calling XplatUI directly
170 //
171 // Revision 1.47  2004/08/23 19:16:23  jordi
172 // avoids null exception
173 //
174 // Revision 1.46  2004/08/22 21:10:30  pbartok
175 // - Removed OverlappedWindow style from Control, instead it's default
176 //   now is child
177 // - Made form windows OverlappedWindow by default
178 //
179 // Revision 1.45  2004/08/21 22:19:30  pbartok
180 // - Signature fixes
181 //
182 // Revision 1.44  2004/08/21 20:53:13  pbartok
183 // - Updated to match new GrabWindow signature
184 //
185 // Revision 1.43  2004/08/21 19:32:15  pbartok
186 // - Implemented Created property
187 //
188 // Revision 1.42  2004/08/21 19:28:22  pbartok
189 // - Implemented ContainsFocus
190 //
191 // Revision 1.41  2004/08/21 19:26:24  pbartok
192 // - Implemented CausesValidation
193 //
194 // Revision 1.40  2004/08/21 19:21:50  pbartok
195 // - Implemented CanFocus
196 // - Implemented CanSelect
197 // - Implemented Capture
198 //
199 // Revision 1.39  2004/08/21 16:54:11  jackson
200 // Implement EndInvoke
201 //
202 // Revision 1.38  2004/08/20 23:38:54  ravindra
203 // Made RightToLeft property virtual and removed a Console.WriteLine.
204 //
205 // Revision 1.37  2004/08/20 20:09:24  pbartok
206 // - Added call to set window background color
207 //
208 // Revision 1.36  2004/08/20 19:18:30  jackson
209 // Implement Begininvoke
210 //
211 // Revision 1.35  2004/08/20 01:17:24  pbartok
212 // - Added handling of WM_MOUSEHOVER
213 // - Worked around 'bug' in Win32 WM_MOUSE_ENTER/WM_MOUSE_LEAVE driver code
214 //
215 // Revision 1.34  2004/08/19 23:09:22  pbartok
216 // - Added Right property
217 // - Added RightToLeft property
218 //
219 // Revision 1.33  2004/08/19 22:25:31  jordi
220 // theme enhancaments
221 //
222 // Revision 1.32  2004/08/17 21:25:12  pbartok
223 // - Drawing improvement; don't call UpdateBounds if we are not visible (or
224 //   have been minimized)
225 //
226 // Revision 1.31  2004/08/17 20:25:28  pbartok
227 // - Fixed broken handling of default window sizes
228 //
229 // Revision 1.30  2004/08/16 21:47:11  pbartok
230 // - Added handling of WM_MOUSE_ENTER & WM_MOUSE_LEAVE to
231 //   support OnMouseEnter/Leave()
232 // - Added WS_CLIPSIBLINGS and WS_CLIPCHILDREN window styles to improve
233 //   exposure handling
234 //
235 // Revision 1.29  2004/08/13 22:15:46  pbartok
236 // - Fixed Anchor default
237 //
238 // Revision 1.28  2004/08/13 21:43:39  pbartok
239 // - Changed GetCursorPos signature
240 //
241 // Revision 1.27  2004/08/13 19:00:15  jordi
242 // implements PointToClient (ScreenToClient)
243 //
244 // Revision 1.26  2004/08/13 18:52:07  pbartok
245 // - Added Dispose() and destructor
246 // - Fixed resizing and bounds calculation
247 // - Fixed Layout
248 // - Added memory savings for invisible windows
249 //
250 // Revision 1.25  2004/08/12 19:31:19  pbartok
251 // - Fixed Anchoring bugs
252 //
253 // Revision 1.24  2004/08/12 16:10:42  jackson
254 // Add missing properties
255 //
256 // Revision 1.23  2004/08/11 22:20:59  pbartok
257 // - Signature fixes
258 //
259 // Revision 1.22  2004/08/11 19:19:44  pbartok
260 // - We had SetWindowPos and MoveWindow to set window positions and size,
261 //   removed MoveWindow. We have GetWindowPos, so it made sense to keep
262 //   SetWindowPos as matching counterpart
263 // - Added some X11 sanity checking
264 //
265 // Revision 1.21  2004/08/11 18:59:45  pbartok
266 // - Major cleanup of my SetBounds/SetBoundsCore/UpdateBounds mess
267 //   (It seems that SetBounds is just a front for SetBoundsCore and
268 //    SetBoundsCore updates the underlying window system and UpdateBounds is
269 //    responsible for updating the variables associated with the Control and
270 //    sending the events)
271 // - Major cleanup of Size handling; we now have two sizes, client_size and
272 //   bounds. Bounds defines the window with decorations, client_size without
273 //   them.
274 //
275 // Revision 1.20  2004/08/11 15:13:32  pbartok
276 // - Now properly reparents windows
277 //
278 // Revision 1.19  2004/08/11 14:37:11  pbartok
279 // - Duh!
280 //
281 // Revision 1.18  2004/08/11 13:47:22  pbartok
282 // - Rewrote the collection stuff. Might not be as fast now, not keeping
283 //   the number of children around and accessible directly, but it's more
284 //   straightforward
285 //
286 // Revision 1.17  2004/08/10 18:32:10  jordi
287 // throw ontextchange event
288 //
289 // Revision 1.16  2004/08/10 17:43:04  pbartok
290 // - Added more to the still unfinished Dock/Anchor layout code
291 //
292 // Revision 1.15  2004/08/10 15:08:05  jackson
293 // Control will now handle the buffering code, so each control does not have to implement this.
294 //
295 // Revision 1.14  2004/08/09 22:11:25  pbartok
296 // - Added incomplete dock layout code
297 // - Added support for mouse wheel
298 //
299 // Revision 1.13  2004/08/09 17:25:56  jackson
300 // Use new color names
301 //
302 // Revision 1.12  2004/08/09 15:54:51  jackson
303 // Get default properties from the theme.
304 //
305 // Revision 1.11  2004/08/06 21:30:56  pbartok
306 // - Fixed recursive loop when resizing
307 // - Improved/fixed redrawing on expose messages
308 //
309 // Revision 1.10  2004/08/06 15:53:39  jordi
310 // X11 keyboard navigation
311 //
312 // Revision 1.9  2004/08/04 21:14:26  pbartok
313 // - Fixed Invalidation bug (calculated wrong client area)
314 // - Added ClientSize setter
315 //
316 // Revision 1.8  2004/08/04 20:11:24  pbartok
317 // - Added Invalidate handling
318 //
319 // Revision 1.7  2004/07/27 10:38:17  jordi
320 // changes to be able to run winforms samples
321 //
322 // Revision 1.6  2004/07/19 19:09:42  jordi
323 // label control re-written: added missing functionlity, events, and properties
324 //
325 // Revision 1.5  2004/07/19 16:49:23  jordi
326 // fixes SetBounds logic
327 //
328 // Revision 1.4  2004/07/19 07:29:35  jordi
329 // Call RefreshWindow only if the window has created
330 //
331 // Revision 1.3  2004/07/15 17:03:35  jordi
332 // added basic mouse handeling events
333 //
334 // Revision 1.2  2004/07/13 15:31:45  jordi
335 // commit: new properties and fixes form size problems
336 //
337 // Revision 1.1  2004/07/09 05:21:25  pbartok
338 // - Initial check-in
339 //
340 //
341
342 // NOT COMPLETE 
343
344 using System;
345 using System.Drawing;
346 using System.ComponentModel;
347 using System.Collections;
348 using System.Diagnostics;
349 using System.Threading;
350 using System.Runtime.InteropServices;
351
352 namespace System.Windows.Forms
353 {
354         public class Control : Component, ISynchronizeInvoke, IWin32Window
355         {
356                 #region Local Variables
357
358                 // Basic
359                 internal Rectangle              bounds;                 // bounding rectangle for control (client area + decorations)
360                 internal object                 creator_thread;         // thread that created the control
361                 internal ControlNativeWindow    window;                 // object for native window handle
362                 internal string                 name;                   // for object naming
363
364                 // State
365                 internal bool                   has_focus;              // true if control has focus
366                 internal bool                   is_visible;             // true if control is visible
367                 internal bool                   is_entered;             // is the mouse inside the control?
368                 internal bool                   is_enabled;             // true if control is enabled (usable/not grayed out)
369                 internal bool                   is_selected;            // true if control is selected
370                 internal bool                   is_accessible;          // true if the control is visible to accessibility applications
371                 internal bool                   is_captured;            // tracks if the control has captured the mouse
372                 internal bool                   is_recreating;          // tracks if the handle for the control is being recreated
373                 internal bool                   causes_validation;      // tracks if validation is executed on changes
374                 internal int                    tab_index;              // position in tab order of siblings
375                 internal bool                   tab_stop = true;        // is the control a tab stop?
376                 internal bool                   is_disposed;            // has the window already been disposed?
377                 internal Size                   client_size;            // size of the client area (window excluding decorations)
378                 internal Rectangle              client_rect;            // rectangle with the client area (window excluding decorations)
379                 internal ControlStyles          control_style;          // rather win32-specific, style bits for control
380                 internal ImeMode                ime_mode = ImeMode.Inherit;
381                 internal bool                   layout_pending;         // true if our parent needs to re-layout us
382                 internal object                 control_tag;            // object that contains data about our control
383                 internal int                    mouse_clicks;           // Counter for mouse clicks
384
385
386                 // Visuals
387                 internal Color                  foreground_color;       // foreground color for control
388                 internal Color                  background_color;       // background color for control
389                 internal Image                  background_image;       // background image for control
390                 internal Font                   font;                   // font for control
391                 internal string                 text;                   // window/title text for control
392
393                 // Layout
394                 internal AnchorStyles           anchor_style;           // anchoring requirements for our control
395                 internal DockStyle              dock_style;             // docking requirements for our control (supercedes anchoring)
396                 internal SizeF                  size_ratio;             // size ratio of our control to it's parent; required for anchoring
397                 internal Size                   prev_size;              // previous size of the control; required for anchoring
398
399                 // to be categorized...
400                 static internal ArrayList       controls = new ArrayList();             // All of the applications controls, in a flat list
401                 internal ControlCollection      child_controls;         // our children
402                 internal Control                parent;                 // our parent control
403                 internal AccessibleObject       accessibility_object;   // object that contains accessibility information about our control
404                 internal BindingContext         binding_context;        // TODO
405                 internal RightToLeft            right_to_left;          // drawing direction for control
406                 internal int                    layout_suspended;
407                 internal bool                   double_buffering;
408                 internal ContextMenu            context_menu;           // Context menu associated with the control
409
410                 private Graphics                dc_mem;                 // Graphics context for double buffering
411                 private Bitmap                  bmp_mem;                // Bitmap for double buffering control
412
413                 #endregion      // Local Variables
414
415                 #region Private Classes
416                 // This helper class allows us to dispatch messages to Control.WndProc
417                 internal class ControlNativeWindow : NativeWindow {
418                         private Control control;
419
420                         public ControlNativeWindow(Control control) : base() {
421                                 this.control=control;
422                         }
423
424                         static internal Control ControlFromHandle(IntPtr hWnd) {
425                                 ControlNativeWindow     window;
426
427                                 window = (ControlNativeWindow)window_collection[hWnd];
428
429                                 return window.control;
430                         }
431
432                         protected override void WndProc(ref Message m) {
433                                 control.WndProc(ref m);
434                         }
435                 }
436                 #endregion
437                 
438                 #region Public Classes
439                 public class ControlAccessibleObject : AccessibleObject {                       
440                         #region ControlAccessibleObject Local Variables
441                         private Control owner;
442                         #endregion      // ControlAccessibleObject Local Variables
443
444                         #region ControlAccessibleObject Constructors
445                         public ControlAccessibleObject(Control ownerControl) {
446                                 this.owner = ownerControl;
447                         }
448                         #endregion      // ControlAccessibleObject Constructors
449
450                         #region ControlAccessibleObject Public Instance Properties
451                         public override string DefaultAction {
452                                 get {
453                                         return base.DefaultAction;
454                                 }
455                         }
456
457                         public override string Description {
458                                 get {
459                                         return base.Description;
460                                 }
461                         }
462
463                         public IntPtr Handle {
464                                 get {
465                                         return owner.Handle;
466                                 }
467
468                                 set {
469                                         // We don't want to let them set it
470                                 }
471                         }
472
473                         public override string Help {
474                                 get {
475                                         return base.Help;
476                                 }
477                         }
478
479                         public override string KeyboardShortcut {
480                                 get {
481                                         return base.KeyboardShortcut;
482                                 }
483                         }
484
485                         public override string Name {
486                                 get {
487                                         return base.Name;
488                                 }
489
490                                 set {
491                                         base.Name = value;
492                                 }
493                         }
494
495                         public Control Owner {
496                                 get {
497                                         return owner;
498                                 }
499                         }
500
501                         public override AccessibleRole Role {
502                                 get {
503                                         return base.Role;
504                                 }
505                         }
506                         #endregion      // ControlAccessibleObject Public Instance Properties
507
508                         #region ControlAccessibleObject Public Instance Methods
509                         public override int GetHelpTopic(out string FileName) {
510                                 return base.GetHelpTopic (out FileName);
511                         }
512
513                         #endregion      // ControlAccessibleObject Public Instance Methods
514                 }
515
516                 public class ControlCollection : IList, ICollection, ICloneable, IEnumerable {
517                         #region ControlCollection Local Variables
518                         internal ArrayList      list;
519                         internal Control        owner;
520                         #endregion      // ControlCollection Local Variables
521
522                         #region ControlCollection Public Constructor
523                         public ControlCollection(Control owner) {
524                                 this.owner=owner;
525                                 this.list=new ArrayList();
526                         }
527                         #endregion
528
529                         #region ControlCollection Public Instance Properties
530                         public int Count {
531                                 get {
532                                         return list.Count;
533                                 }
534                         }
535
536                         public bool IsReadOnly {
537                                 get {
538                                         return list.IsReadOnly;
539                                 }
540                         }
541
542                         public virtual Control this[int index] {
543                                 get {
544                                         if (index < 0 || index >= list.Count) {
545                                                 throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
546                                         }
547                                         return (Control)list[index];
548                                 }
549                         }
550                         #endregion // ControlCollection Public Instance Properties
551                         
552                         #region ControlCollection Private Instance Methods
553                         public virtual void Add (Control value)
554                         {
555                                 
556                                 for (int i = 0; i < list.Count; i++) {
557                                         if (list [i] == value) {
558                                                 // Do we need to do anything here?
559                                                 return;
560                                         }
561                                 }
562                                 list.Add (value);
563                                 value.Parent = owner;
564                         }
565                         
566                         public virtual void AddRange (Control[] controls)
567                         {
568                                 if (controls == null)
569                                         throw new ArgumentNullException ("controls");
570
571                                 owner.SuspendLayout ();
572
573                                 try {
574                                         for (int i = 0; i < controls.Length; i++) 
575                                                 Add (controls[i]);
576                                 } finally {
577                                         owner.ResumeLayout ();
578                                 }
579                         }
580
581                         public virtual void Clear ()
582                         {
583                                 owner.SuspendLayout();
584                                 list.Clear();
585                                 owner.ResumeLayout();
586                         }
587
588                         public virtual bool Contains (Control value)
589                         {
590                                 return list.Contains (value);
591                         }
592
593                         public void CopyTo (Array array, int index)
594                         {
595                                 list.CopyTo(array, index);
596                         }
597
598                         public override bool Equals(object other) {
599                                 if (other is ControlCollection && (((ControlCollection)other).owner==this.owner)) {
600                                         return(true);
601                                 } else {
602                                         return(false);
603                                 }
604                         }
605
606                         public int GetChildIndex(Control child) {
607                                 return GetChildIndex(child, false);
608                         }
609
610                         public int GetChildIndex(Control child, bool throwException) {
611                                 int index;
612
613                                 index=list.IndexOf(child);
614
615                                 if (index==-1 && throwException) {
616                                         throw new ArgumentException("Not a child control", "child");
617                                 }
618                                 return index;
619                         }
620
621                         public IEnumerator GetEnumerator() {
622                                 return list.GetEnumerator();
623                         }
624
625                         public override int GetHashCode() {
626                                 return base.GetHashCode();
627                         }
628
629                         public int IndexOf(Control control) {
630                                 return list.IndexOf(control);
631                         }
632
633                         public virtual void Remove(Control value) {
634                                 list.Remove(value);
635                         }
636
637                         public void RemoveAt(int index) {
638                                 if (index<0 || index>=list.Count) {
639                                         throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
640                                 }
641
642                                 list.RemoveAt(index);
643                         }
644
645                         public void SetChildIndex(Control child, int newIndex) {
646                                 int     old_index;
647
648                                 old_index=list.IndexOf(child);
649                                 if (old_index==-1) {
650                                         throw new ArgumentException("Not a child control", "child");
651                                 }
652
653                                 if (old_index==newIndex) {
654                                         return;
655                                 }
656
657                                 RemoveAt(old_index);
658
659                                 if (newIndex>list.Count) {
660                                         list.Add(child);
661                                 } else {
662                                         list.Insert(newIndex, child);
663                                 }
664                         }
665                         #endregion // ControlCollection Private Instance Methods
666
667                         #region ControlCollection Interface Properties
668                         object IList.this[int index] {
669                                 get {
670                                         if (index<0 || index>=list.Count) {
671                                                 throw new ArgumentOutOfRangeException("index", index, "ControlCollection does not have that many controls");
672                                         }
673                                         return this[index];
674                                 }
675
676                                 set {
677                                         if (!(value is Control)) {
678                                                 throw new ArgumentException("Object of type Control required", "value");
679                                         }
680
681                                         list[index]=(Control)value;
682                                 }
683                         }
684
685                         bool IList.IsFixedSize {
686                                 get {
687                                         return false;
688                                 }
689                         }
690
691                         bool IList.IsReadOnly {
692                                 get {
693                                         return list.IsReadOnly;
694                                 }
695                         }
696
697                         bool ICollection.IsSynchronized {
698                                 get {
699                                         return list.IsSynchronized;
700                                 }
701                         }
702
703                         object ICollection.SyncRoot {
704                                 get {
705                                         return list.SyncRoot;
706                                 }
707                         }
708                         #endregion // ControlCollection Interface Properties
709
710                         #region ControlCollection Interface Methods
711                         int IList.Add(object value) {
712                                 if (value == null) {
713                                         throw new ArgumentNullException("value", "Cannot add null controls");
714                                 }
715
716                                 if (!(value is Control)) {
717                                         throw new ArgumentException("Object of type Control required", "value");
718                                 }
719
720                                 return list.Add(value);
721                         }
722
723                         bool IList.Contains(object value) {
724                                 if (!(value is Control)) {
725                                         throw new ArgumentException("Object of type Control required", "value");
726                                 }
727
728                                 return this.Contains((Control) value);
729                         }
730
731                         int IList.IndexOf(object value) {
732                                 if (!(value is Control)) {
733                                         throw new ArgumentException("Object of type Control  required", "value");
734                                 }
735
736                                 return this.IndexOf((Control) value);
737                         }
738
739                         void IList.Insert(int index, object value) {
740                                 if (!(value is Control)) {
741                                         throw new ArgumentException("Object of type Control required", "value");
742                                 }
743                                 list.Insert(index, value);
744                         }
745
746                         void IList.Remove(object value) {
747                                 if (!(value is Control)) {
748                                         throw new ArgumentException("Object of type Control required", "value");
749                                 }
750                                 list.Remove(value);
751                         }
752
753                         void ICollection.CopyTo(Array array, int index) {
754                                 if (list.Count>0) {
755                                         list.CopyTo(array, index);
756                                 }
757                         }
758
759                         Object ICloneable.Clone() {
760                                 ControlCollection clone = new ControlCollection(this.owner);
761                                 clone.list=(ArrayList)list.Clone();             // FIXME: Do we need this?
762                                 return clone;
763                         }
764                         #endregion // ControlCollection Interface Methods
765                 }
766                 #endregion      // ControlCollection Class
767                 
768                 #region Public Constructors
769                 public Control() {                      
770                         creator_thread = Thread.CurrentThread;
771
772                         child_controls = CreateControlsInstance();
773                         client_size = new Size(DefaultSize.Width, DefaultSize.Height);
774                         client_rect = new Rectangle(0, 0, DefaultSize.Width, DefaultSize.Height);
775                         XplatUI.CalculateWindowRect(IntPtr.Zero, ref client_rect, CreateParams.Style, false, out bounds);
776                         if ((CreateParams.Style & (int)WindowStyles.WS_CHILD) == 0) {
777                                 bounds.X=-1;
778                                 bounds.Y=-1;
779                         }
780                         prev_size = Size.Empty;
781                         anchor_style = AnchorStyles.Top | AnchorStyles.Left;
782
783                         is_visible = true;
784                         is_captured = false;
785                         is_disposed = false;
786                         is_enabled = true;
787                         is_entered = false;
788                         layout_pending = false;
789                         causes_validation = true;
790                         has_focus = false;
791                         layout_suspended = 0;           
792                         double_buffering = true;
793                         mouse_clicks = 1;
794
795                         parent = null;
796                         background_image = null;
797                         text = string.Empty;
798                         name = string.Empty;                    
799                 }
800
801                 public Control(Control parent, string text) : this() {
802                         Text=text;
803                         Parent=parent;
804                 }
805
806                 public Control(Control parent, string text, int left, int top, int width, int height) : this() {
807                         Parent=parent;
808                         bounds.X=left;
809                         bounds.Y=top;
810                         bounds.Width=width;
811                         bounds.Height=height;
812                         SetBoundsCore(left, top, width, height, BoundsSpecified.All);
813                         Text=text;
814                 }
815
816                 public Control(string text) : this() {
817                         Text=text;
818                 }
819
820                 public Control(string text, int left, int top, int width, int height) : this() {
821                         bounds.X=left;
822                         bounds.Y=top;
823                         bounds.Width=width;
824                         bounds.Height=height;
825                         SetBoundsCore(left, top, width, height, BoundsSpecified.All);
826                         Text=text;
827                 }
828
829                 protected override void Dispose(bool disposing) {
830                         is_disposed = true;
831                         if (dc_mem!=null) {
832                                 dc_mem.Dispose();
833                                 dc_mem=null;
834                         }
835
836                         if (bmp_mem!=null) {
837                                 bmp_mem.Dispose();
838                                 bmp_mem=null;
839                         }
840
841                         DestroyHandle();
842                         controls.Remove(this);
843                 }
844                 #endregion      // Public Constructors
845
846                 #region Internal Properties
847                 #endregion      // Internal Properties
848
849                 #region Private & Internal Methods
850                 internal static IAsyncResult BeginInvokeInternal (Delegate method, object [] args) {
851                         AsyncMethodResult result = new AsyncMethodResult ();
852                         AsyncMethodData data = new AsyncMethodData ();
853
854                         data.Method = method;
855                         data.Args = args;
856                         data.Result = new WeakReference (result);
857
858                         XplatUI.SendAsyncMethod (data);
859                         return result;
860                 }
861
862                 internal Graphics DeviceContext {
863                         get { 
864                                 if (dc_mem==null) {
865                                         CreateBuffers(this.Width, this.Height);
866                                 }
867                                 return dc_mem;
868                         }
869                 }
870
871                 internal Bitmap ImageBuffer {
872                         get {
873                                 if (bmp_mem==null) {
874                                         CreateBuffers(this.Width, this.Height);
875                                 }
876                                 return bmp_mem;
877                         }
878                 }
879
880                 internal void CreateBuffers (int width, int height) {
881                         if (double_buffering == false)
882                                 return;
883
884                         if (dc_mem != null)
885                                 dc_mem.Dispose ();
886                         if (bmp_mem != null)
887                                 bmp_mem.Dispose ();
888
889                         if (width < 1) {
890                                 width = 1;
891                         }
892
893                         if (height < 1) {
894                                 height = 1;
895                         }
896
897                         bmp_mem = new Bitmap (width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
898                         dc_mem = Graphics.FromImage (bmp_mem);
899                 }
900
901                 internal void InvalidateBuffers ()
902                 {
903                         if (double_buffering == false)
904                                 return;
905
906                         if (dc_mem != null)
907                                 dc_mem.Dispose ();
908                         if (bmp_mem != null)
909                                 bmp_mem.Dispose ();
910
911                         dc_mem = null;
912                         bmp_mem = null;
913                 }
914
915                 internal static void SetChildColor(Control parent) {
916                         Control child;
917
918                         for (int i=0; i < parent.child_controls.Count; i++) {
919                                 child=parent.child_controls[i];
920                                 if (child.IsHandleCreated) {
921                                         XplatUI.SetWindowBackground(child.window.Handle, child.BackColor);
922                                 }
923                                 if (child.child_controls.Count>0) {
924                                         SetChildColor(child);
925                                 }
926                         }
927                                 
928                 }
929
930                 private bool Select(Control control) {
931                         Control parent;
932
933                         if (control == null) {
934                                 return false;
935                         }
936
937                         parent = control.parent;
938
939                         if (((control.control_style & ControlStyles.Selectable) !=0)  && (parent != null)) {
940                                 while (parent != null) {
941                                         if (!parent.is_visible || !parent.is_enabled) {
942                                                 return false;
943                                         }
944                                 }
945                         }
946
947                         control.is_selected = true;
948
949                         return true;
950                 }
951
952
953                 private Control FindTabStop(Control control, bool forward) {
954                         if (control == null) {
955                                 return null;
956                         }
957
958                         return null;
959                 }
960
961
962                 internal virtual void DoDefaultAction() {
963                         // Only here to be overriden by our actual controls; this is needed by the accessibility class
964                 }
965
966                 internal static int LowOrder (int param) {
967                         return (param & 0xffff);
968                 }
969
970                 internal static int HighOrder (int param) {
971                         return (param >> 16);
972                 }
973                 
974                 internal static MouseButtons FromParamToMouseButtons (int param) {              
975                         MouseButtons buttons = MouseButtons.None;
976                                         
977                         if ((param & (int) MsgButtons.MK_LBUTTON) != 0)
978                                 buttons |= MouseButtons.Left;
979                         
980                         if ((param & (int) MsgButtons.MK_MBUTTON) != 0)
981                                 buttons |= MouseButtons.Middle;
982                                 
983                         if ((param & (int) MsgButtons.MK_RBUTTON) != 0)
984                                 buttons |= MouseButtons.Right;          
985                                 
986                         return buttons;
987
988                 }
989                 #endregion      // Private & Internal Methods
990
991                 #region Public Static Properties
992                 public static Color DefaultBackColor {
993                         get {
994                                 return ThemeEngine.Current.DefaultControlBackColor;
995                         }
996                 }
997
998                 public static Font DefaultFont {
999                         get {
1000                                 return ThemeEngine.Current.DefaultFont;
1001                         }
1002                 }
1003
1004                 public static Color DefaultForeColor {
1005                         get {
1006                                 return ThemeEngine.Current.DefaultControlForeColor;
1007                         }
1008                 }
1009
1010                 public static Keys ModifierKeys {
1011                         get {
1012                                 return XplatUI.State.ModifierKeys;
1013                         }
1014                 }
1015
1016                 public static MouseButtons MouseButtons {
1017                         get {
1018                                 return XplatUI.State.MouseButtons;
1019                         }
1020                 }
1021
1022                 public static Point MousePosition {
1023                         get {
1024                                 return Cursor.Position;
1025                         }
1026                 }
1027                 #endregion      // Public Static Properties
1028
1029                 #region Public Instance Properties
1030                 public AccessibleObject AccessibilityObject {
1031                         get {
1032                                 if (accessibility_object==null) {
1033                                         accessibility_object=CreateAccessibilityInstance();
1034                                 }
1035                                 return accessibility_object;
1036                         }
1037                 }
1038
1039                 public string AccessibleDefaultActionDescription {
1040                         get {
1041                                 return AccessibilityObject.default_action;
1042                         }
1043
1044                         set {
1045                                 AccessibilityObject.default_action=value;
1046                         }
1047                 }
1048
1049                 public string AccessibleDescription {
1050                         get {
1051                                 return AccessibilityObject.description;
1052                         }
1053
1054                         set {
1055                                 AccessibilityObject.description=value;
1056                         }
1057                 }
1058
1059                 public string AccessibleName {
1060                         get {
1061                                 return AccessibilityObject.Name;
1062                         }
1063
1064                         set {
1065                                 AccessibilityObject.Name=value;
1066                         }
1067                 }
1068
1069                 public AccessibleRole AccessibleRole {
1070                         get {
1071                                 return AccessibilityObject.role;
1072                         }
1073
1074                         set {
1075                                 AccessibilityObject.role=value;
1076                         }
1077                 }
1078
1079                 public virtual bool AllowDrop {
1080                         get {
1081                                 return XplatUI.State.DropTarget;
1082                         }
1083
1084                         set {
1085                                 XplatUI.State.DropTarget=value;
1086                         }
1087                 }
1088
1089                 public virtual AnchorStyles Anchor {
1090                         get {
1091                                 return anchor_style;
1092                         }
1093
1094                         set {
1095                                 anchor_style=value;
1096
1097                                 if (parent != null) {
1098                                         parent.PerformLayout(this, "Parent");
1099                                 }
1100                         }
1101                 }
1102
1103                 public virtual Color BackColor {
1104                         get {
1105                                 if (background_color.IsEmpty) {
1106                                         if (parent!=null) {
1107                                                 return parent.BackColor;
1108                                         }
1109                                         return DefaultBackColor;
1110                                 }
1111                                 return background_color;
1112                         }
1113
1114                         set {
1115                                 background_color=value;
1116                                 if (this.IsHandleCreated) {
1117                                         XplatUI.SetWindowBackground(this.window.Handle, value);
1118                                 }
1119                                 SetChildColor(this);
1120                                 OnBackColorChanged(EventArgs.Empty);
1121                                 Refresh();
1122                         }
1123                 }
1124
1125                 public virtual Image BackgroundImage {
1126                         get {
1127                                 return background_image;
1128                         }
1129
1130                         set {
1131                                 if (background_image!=value) {
1132                                         background_image=value;
1133                                         OnBackgroundImageChanged(EventArgs.Empty);
1134                                 }
1135                         }
1136                 }
1137
1138                 public virtual BindingContext BindingContext {
1139                         get {
1140                                 throw new NotImplementedException();
1141                         }
1142
1143                         set {
1144                                 throw new NotImplementedException();
1145                         }
1146                 }
1147
1148                 public int Bottom {
1149                         get {
1150                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1151                                         return ((Form)this).form_parent_window.Bottom;
1152                                 }
1153
1154                                 return bounds.Y+bounds.Height;
1155                         }
1156                 }
1157
1158                 public Rectangle Bounds {
1159                         get {
1160                                 return this.bounds;
1161                         }
1162
1163                         set {
1164                                 SetBoundsCore(value.Left, value.Top, value.Width, value.Height, BoundsSpecified.All);
1165                         }
1166                 }
1167
1168                 public bool CanFocus {
1169                         get {
1170                                 if (is_visible && is_enabled && GetStyle(ControlStyles.Selectable)) {
1171                                         return true;
1172                                 }
1173                                 return false;
1174                         }
1175                 }
1176
1177                 public bool CanSelect {
1178                         get {
1179                                 Control parent;
1180
1181                                 if (!GetStyle(ControlStyles.Selectable) || this.parent == null) {
1182                                         return false;
1183                                 }
1184
1185                                 parent = this.parent;
1186                                 while (parent != null) {
1187                                         if (!parent.is_visible || !parent.is_enabled) {
1188                                                 return false;
1189                                         }
1190
1191                                         parent = parent.parent;
1192                                 }
1193                                 return true;
1194                         }
1195                 }
1196
1197                 public bool Capture {
1198                         get {
1199                                 return this.is_captured;
1200                         }
1201
1202                         set {
1203                                 if (this.IsHandleCreated) {
1204                                         if (value && !is_captured) {
1205                                                 is_captured = true;
1206                                                 XplatUI.GrabWindow(this.window.Handle, IntPtr.Zero);
1207                                         } else if (!value && is_captured) {
1208                                                 XplatUI.ReleaseWindow(this.window.Handle);
1209                                                 is_captured = false;
1210                                         }
1211                                 }
1212                         }
1213                 }
1214
1215                 public bool CausesValidation {
1216                         get {
1217                                 return this.causes_validation;
1218                         }
1219
1220                         set {
1221                                 if (this.causes_validation != value) {
1222                                         causes_validation = value;
1223                                         OnCausesValidationChanged(EventArgs.Empty);
1224                                 }
1225                         }
1226                 }
1227
1228                 public Rectangle ClientRectangle {
1229                         get {
1230                                 client_rect.Width = client_size.Width;
1231                                 client_rect.Height = client_size.Height;
1232                                 return client_rect;
1233                         }
1234                 }
1235
1236                 public Size ClientSize {
1237                         get {
1238 #if notneeded
1239                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1240                                         return ((Form)this).form_parent_window.ClientSize;
1241                                 }
1242 #endif
1243
1244                                 return client_size;
1245                         }
1246
1247                         set {
1248                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1249                                         ((Form)this).form_parent_window.ClientSize = value;
1250                                         return;
1251                                 }
1252
1253                                 this.SetClientSizeCore(value.Width, value.Height);
1254                         }
1255                 }
1256
1257                 public String CompanyName {
1258                         get {
1259                                 return "Mono Project, Novell, Inc.";
1260                         }
1261                 }
1262
1263                 public bool ContainsFocus {
1264                         get {
1265                                 if (this.Focused) {
1266                                         return true;
1267                                 }
1268
1269                                 for (int i=0; i < child_controls.Count; i++) {
1270                                         if (child_controls[i].Focused) {
1271                                                 return true;
1272                                         }
1273                                 }
1274                                 return false;
1275                         }
1276                 }
1277                 public virtual ContextMenu ContextMenu {
1278                         get {
1279                                 return context_menu;
1280                         }
1281
1282                         set {
1283                                 if (context_menu != value) {
1284                                         context_menu = value;
1285                                         OnContextMenuChanged(EventArgs.Empty);
1286                                 }
1287                         }
1288                 }
1289
1290                 public ControlCollection Controls {
1291                         get {
1292                                 return this.child_controls;
1293                         }
1294                 }
1295
1296                 public bool Created {
1297                         get {
1298                                 if (!this.is_disposed && (this.window.Handle != IntPtr.Zero)) {
1299                                         return true;
1300                                 }
1301                                 return false;
1302                         }
1303                 }
1304
1305 #if notdef
1306                 public virtual Cursor Cursor {
1307                         get {
1308                                 throw new NotImplementedException();
1309                         }
1310
1311                         set {
1312                                 throw new NotImplementedException();
1313                         }
1314                 }
1315
1316                 public ControlBidingsCollection DataBindings {
1317                         get {
1318                                 throw new NotImplementedException();
1319                         }
1320                 }
1321 #endif
1322                 public virtual Rectangle DisplayRectangle {
1323                         get {
1324                                 return ClientRectangle;
1325                         }
1326                 }
1327
1328                 public bool Disposing {
1329                         get {
1330                                 return is_disposed;
1331                         }
1332                 }
1333
1334                 public virtual DockStyle Dock {
1335                         get {
1336                                 return dock_style;
1337                         }
1338
1339                         set {
1340                                 if (dock_style == value) {
1341                                         return;
1342                                 }
1343
1344                                 dock_style = value;
1345
1346                                 if (parent != null) {
1347                                         parent.PerformLayout(this, "Parent");
1348                                 }
1349
1350                                 OnDockChanged(EventArgs.Empty);
1351                         }
1352                 }
1353
1354                 public bool Enabled {
1355                         get {
1356                                 return is_enabled;
1357                         }
1358
1359                         set {
1360                                 if (is_enabled == value) {
1361                                         return;
1362                                 }
1363
1364                                 is_enabled = value;
1365                                 Refresh();
1366                                 OnEnabledChanged (EventArgs.Empty);                             
1367                         }
1368                 }
1369
1370                 public virtual bool Focused {
1371                         get {
1372                                 return this.has_focus;
1373                         }
1374                 }
1375
1376                 public virtual Font Font {
1377                         get {
1378                                 if (font != null) {
1379                                         return font;
1380                                 }
1381
1382                                 if (Parent != null && Parent.Font != null) {
1383                                         return Parent.Font;
1384                                 }
1385
1386                                 return DefaultFont;
1387                         }
1388
1389                         set {
1390                                 if (font == value) {
1391                                         return;
1392                                 }
1393
1394                                 font = value;   
1395                                 Refresh();
1396                                 OnFontChanged (EventArgs.Empty);                                
1397                         }
1398                 }
1399
1400                 public virtual Color ForeColor {
1401                         get {
1402                                 if (foreground_color.IsEmpty) {
1403                                         if (parent!=null) {
1404                                                 return parent.ForeColor;
1405                                         }
1406                                         return DefaultForeColor;
1407                                 }
1408                                 return foreground_color;
1409                         }
1410
1411                         set {
1412                                 if (foreground_color != value) {
1413                                         foreground_color=value;
1414                                         Refresh();
1415                                         OnForeColorChanged(EventArgs.Empty);
1416                                 }
1417                         }
1418                 }
1419
1420                 public IntPtr Handle {                                                  // IWin32Window
1421                         get {
1422                                 if (!IsHandleCreated) {
1423                                         CreateHandle();
1424                                 }
1425                                 return window.Handle;
1426                         }
1427                 }
1428
1429                 public bool HasChildren {
1430                         get {
1431                                 if (this.child_controls.Count>0) {
1432                                         return true;
1433                                 }
1434                                 return false;
1435                         }
1436                 }
1437
1438                 public int Height {
1439                         get {
1440                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1441                                         return ((Form)this).form_parent_window.Height;
1442                                 }
1443                                 return this.bounds.Height;
1444                         }
1445
1446                         set {
1447                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1448                                         ((Form)this).form_parent_window.Height = value;
1449                                         return;
1450                                 }
1451
1452                                 SetBoundsCore(bounds.X, bounds.Y, bounds.Width, value, BoundsSpecified.Height);
1453                         }
1454                 }
1455
1456                 public ImeMode ImeMode {
1457                         get {
1458                                 return ime_mode;
1459                         }
1460
1461                         set {
1462                                 ime_mode = value;
1463                         }
1464                 }
1465
1466                 public bool InvokeRequired {                                            // ISynchronizeInvoke
1467                         get {
1468                                 if (creator_thread!=Thread.CurrentThread) {
1469                                         return true;
1470                                 }
1471                                 return false;
1472                         }
1473                 }
1474
1475                 public bool IsAccessible {
1476                         get {
1477                                 return is_accessible;
1478                         }
1479
1480                         set {
1481                                 is_accessible = value;
1482                         }
1483                 }
1484
1485                 public bool IsDisposed {
1486                         get {
1487                                 return this.is_disposed;
1488                         }
1489                 }
1490
1491                 public bool IsHandleCreated {
1492                         get {
1493                                 if ((window!=null) && (window.Handle!=IntPtr.Zero)) {
1494                                         return true;
1495                                 }
1496
1497                                 return false;
1498                         }
1499                 }
1500
1501                 public int Left {
1502                         get {
1503                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1504                                         return ((Form)this).form_parent_window.Left;
1505                                 }
1506
1507                                 return this.bounds.X;
1508                         }
1509
1510                         set {
1511                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1512                                         ((Form)this).form_parent_window.Left = value;
1513                                         return;
1514                                 }
1515
1516                                 SetBoundsCore(value, bounds.Y, bounds.Width, bounds.Height, BoundsSpecified.X);
1517                         }
1518                 }
1519
1520                 public Point Location {
1521                         get {
1522                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1523                                         return ((Form)this).form_parent_window.Location;
1524                                 }
1525                                 return new Point(bounds.X, bounds.Y);
1526                         }
1527
1528                         set {
1529                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1530                                         ((Form)this).form_parent_window.Location = value;
1531                                         return;
1532                                 }
1533
1534                                 SetBoundsCore(value.X, value.Y, bounds.Width, bounds.Height, BoundsSpecified.Location);
1535                         }
1536                 }
1537
1538                 public string Name {
1539                         get {
1540                                 return this.name;
1541                         }
1542
1543                         set {
1544                                 this.name=value;
1545                         }
1546                 }
1547
1548                 public Control Parent {
1549                         get {
1550                                 return this.parent;
1551                         }
1552
1553                         set {
1554                                 if (value == this) {
1555                                         throw new ArgumentException("A circular control reference has been made. A control cannot be owned or parented to itself.");
1556                                 }
1557
1558                                 if (parent!=value) {
1559                                         if (parent!=null) {
1560                                                 parent.Controls.Remove(this);
1561                                         }
1562
1563                                         parent=value;
1564
1565                                         if (!parent.Controls.Contains(this)) {
1566                                                 parent.Controls.Add(this);
1567                                         }
1568
1569                                         XplatUI.SetParent(Handle, value.Handle);
1570
1571                                         InitLayout();
1572                                 }
1573                         }
1574                 }
1575
1576                 public string ProductName {
1577                         get {
1578                                 return "Novell Mono .NET Framework";
1579                         }
1580                 }
1581
1582                 public string ProductVersion {
1583                         get {
1584                                 return "1.1.4322.573";
1585                         }
1586                 }
1587
1588                 public bool RecreatingHandle {
1589                         get {
1590                                 return is_recreating;
1591                         }
1592                 }
1593
1594                 public Region Region {
1595                         get {
1596                                 return new Region(this.bounds);
1597                         }
1598
1599                         set {
1600                                 Graphics        g;
1601                                 RectangleF      r;
1602
1603                                 g = this.CreateGraphics();
1604                                 r = value.GetBounds(g);
1605
1606                                 SetBounds((int)r.X, (int)r.Y, (int)r.Width, (int)r.Height);
1607
1608                                 g.Dispose();
1609                         }
1610                 }
1611
1612                 public int Right {
1613                         get {
1614                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1615                                         return ((Form)this).form_parent_window.Right;
1616                                 }
1617
1618                                 return this.bounds.X+this.bounds.Width;
1619                         }
1620                 }
1621
1622                 public virtual RightToLeft RightToLeft {
1623                         get {
1624                                 return right_to_left;
1625                         }
1626
1627                         set {
1628                                 if (value != right_to_left) {
1629                                         right_to_left = value;
1630                                         OnRightToLeftChanged(EventArgs.Empty);
1631                                 }
1632                         }
1633                 }
1634
1635                 public override ISite Site {
1636                         get {
1637                                 return base.Site;
1638                         }
1639
1640                         set {
1641                                 base.Site = value;
1642                         }
1643                 }
1644
1645                 public Size Size {
1646                         get {
1647                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1648                                         return ((Form)this).form_parent_window.Size;
1649                                 }
1650                                 return new Size(Width, Height);
1651                         }
1652
1653                         set {
1654                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1655                                         ((Form)this).form_parent_window.Size = value;
1656                                         return;
1657                                 }
1658                                 SetBoundsCore(bounds.X, bounds.Y, value.Width, value.Height, BoundsSpecified.Size);
1659                         }
1660                 }
1661
1662                 public int TabIndex {
1663                         get {
1664                                 return tab_index;
1665                         }
1666
1667                         set {
1668                                 tab_index = value;
1669                         }
1670                 }
1671
1672                 public bool TabStop {
1673                         get {
1674                                 return tab_stop;
1675                         }
1676
1677                         set {
1678                                 tab_stop = value;
1679                         }
1680                 }
1681
1682                 public object Tag {
1683                         get {
1684                                 return control_tag;
1685                         }
1686
1687                         set {
1688                                 control_tag = value;
1689                         }
1690                 }
1691
1692                 public virtual string Text {
1693                         get {
1694                                 return this.text;
1695                         }
1696
1697                         set {
1698                                 if (value == null) {
1699                                         value = String.Empty;
1700                                 }
1701
1702                                 if (text!=value) {
1703                                         text=value;
1704                                         XplatUI.Text(Handle, text);
1705                                         // FIXME: Do we need a Refresh() here?
1706                                         OnTextChanged (EventArgs.Empty);
1707                                 }
1708                         }
1709                 }
1710
1711                 public int Top {
1712                         get {
1713                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1714                                         return ((Form)this).form_parent_window.Top;
1715                                 }
1716                                 return this.bounds.Y;
1717                         }
1718
1719                         set {
1720                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1721                                         ((Form)this).form_parent_window.Top = value;
1722                                         return;
1723                                 }
1724
1725                                 SetBoundsCore(bounds.X, value, bounds.Width, bounds.Height, BoundsSpecified.Y);
1726                         }
1727                 }
1728
1729                 public Control TopLevelControl {
1730                         get {
1731                                 Control p = this;
1732
1733                                 while (p.parent != null) {
1734                                         p = p.parent;
1735                                 }
1736
1737                                 return p;
1738                         }
1739                 }
1740
1741                 public bool Visible {
1742                         get {
1743                                 if (!is_visible) {
1744                                         return false;
1745                                 }
1746
1747                                 if (parent != null) {
1748                                         return parent.Visible;
1749                                 }
1750
1751                                 return true;
1752                         }
1753
1754                         set {
1755                                 SetVisibleCore(value);
1756                         }
1757                 }
1758
1759                 public int Width {
1760                         get {
1761                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1762                                         return ((Form)this).form_parent_window.Width;
1763                                 }
1764                                 return this.bounds.Width;
1765                         }
1766
1767                         set {
1768                                 if ((this is Form) && (((Form)this).form_parent_window != null)) {
1769                                         ((Form)this).form_parent_window.Width = value;
1770                                         return;
1771                                 }
1772
1773                                 SetBoundsCore(bounds.X, bounds.Y, value, bounds.Height, BoundsSpecified.Width);
1774                         }
1775                 }
1776
1777                 public IWindowTarget WindowTarget {
1778                         get {
1779                                 return null;
1780                         }
1781
1782                         set {
1783                                 ;
1784                         }
1785                 }
1786                 #endregion      // Public Instance Properties
1787
1788                 #region Protected Instance Properties
1789                 protected virtual CreateParams CreateParams {
1790                         get {
1791                                 CreateParams create_params = new CreateParams();
1792
1793                                 create_params.Caption = Text;
1794                                 create_params.X = Left;
1795                                 create_params.Y = Top;
1796                                 create_params.Width = Width;
1797                                 create_params.Height = Height;
1798
1799                                 create_params.ClassName = XplatUI.DefaultClassName;
1800                                 create_params.ClassStyle = 0;
1801                                 create_params.ExStyle = 0;
1802                                 create_params.Param = 0;
1803
1804                                 if (parent!=null) {
1805                                         create_params.Parent = parent.Handle;
1806                                 }
1807
1808                                 create_params.Style = (int)WindowStyles.WS_CHILD | (int)WindowStyles.WS_CLIPCHILDREN | (int)WindowStyles.WS_CLIPSIBLINGS;
1809
1810                                 if (Visible) {
1811                                         create_params.Style |= (int)WindowStyles.WS_VISIBLE;
1812                                 }
1813
1814                                 return create_params;
1815                         }
1816                 }
1817
1818                 protected virtual ImeMode DefaultImeMode {
1819                         get {
1820                                 return ImeMode.Inherit;
1821                         }
1822                 }
1823
1824                 protected virtual Size DefaultSize {
1825                         get {
1826                                 return new Size(100, 23);
1827                         }
1828                 }
1829
1830                 protected int FontHeight {
1831                         get {
1832                                 return Font.Height;
1833                         }
1834
1835                         set {
1836                                 ;; // Nothing to do
1837                         }
1838                 }
1839
1840                 protected bool RenderRightToLeft {
1841                         get {
1842                                 return (this.right_to_left == RightToLeft.Yes);
1843                         }
1844
1845                         set {
1846                                 ;; // Nothing to do?
1847                         }
1848                 }
1849
1850                 protected bool ResizeRedraw {
1851                         get {
1852                                 return GetStyle(ControlStyles.ResizeRedraw);
1853                         }
1854
1855                         set {
1856                                 SetStyle(ControlStyles.ResizeRedraw, value);
1857                         }
1858                 }
1859
1860                 protected virtual bool ShowFocusCues {
1861                         get {
1862                                 return true;
1863                         }
1864                 }
1865
1866                 protected bool ShowKeyboardCues {
1867                         get {
1868                                 return true;
1869                         }
1870                 }
1871                 #endregion      // Protected Instance Properties
1872
1873                 #region Public Static Methods
1874                 public static Control FromChildHandle(IntPtr handle) {
1875                         IEnumerator control = Control.controls.GetEnumerator();
1876
1877                         while (control.MoveNext()) {
1878                                 if (((Control)control.Current).window.Handle == handle) {
1879                                         // Found it
1880                                         if (((Control)control.Current).Parent != null) {
1881                                                 return ((Control)control.Current).Parent;
1882                                         }
1883                                 }
1884                         }
1885                         return null;
1886                 }
1887
1888                 public static Control FromHandle(IntPtr handle) {
1889                         IEnumerator control = Control.controls.GetEnumerator();
1890
1891                         while (control.MoveNext()) {
1892                                 if (((Control)control.Current).window.Handle == handle) {
1893                                         // Found it
1894                                         return ((Control)control.Current);
1895                                 }
1896                         }
1897                         return null;
1898                 }
1899
1900                 public static bool IsMnemonic(char charCode, string text) {
1901                         int amp;                        
1902
1903                         amp = text.IndexOf('&');
1904
1905                         if (amp != -1) {
1906                                 if (amp + 1 < text.Length) {
1907                                         if (text[amp + 1] != '&') {
1908                                                 if (Char.ToUpper(charCode) == Char.ToUpper(text.ToCharArray(amp + 1, 1)[0])) {
1909                                                         return true;
1910                                                 }       
1911                                         }
1912                                 }
1913                         }
1914                         return false;
1915                 }
1916                 #endregion
1917
1918                 #region Protected Static Methods
1919                 protected static bool ReflectMessage(IntPtr hWnd, ref Message m) {
1920                         Control c;
1921
1922                         c = Control.FromHandle(hWnd);
1923
1924                         if (c != null) {
1925                                 c.WndProc(ref m);
1926                                 return true;
1927                         }
1928                         return false;
1929                 }
1930                 #endregion
1931
1932                 #region Public Instance Methods
1933                 public IAsyncResult BeginInvoke(Delegate method) {
1934                         return BeginInvokeInternal(method, null);
1935                 }
1936
1937                 public IAsyncResult BeginInvoke (Delegate method, object[] args) {
1938                         return BeginInvokeInternal (method, args);
1939                 }
1940
1941                 public void BringToFront() {
1942                         if ((parent != null) && (parent.child_controls[0]!=this)) {
1943                                 if (parent.child_controls.Contains(this)) {
1944                                         parent.child_controls.SetChildIndex(this, 0);
1945                                 }
1946                         }
1947
1948                         XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, true, false);
1949
1950                         if (parent != null) {
1951                                 parent.Refresh();
1952                         }
1953                 }
1954
1955                 public bool Contains(Control ctl) {
1956                         Control current;
1957
1958                         current=ctl;
1959                         while (current!=null) {
1960                                 if (current==ctl) {
1961                                         return true;
1962                                 }
1963                                 current=current.parent;
1964                         }
1965                         return false;
1966                 }
1967
1968                 public void CreateControl() {
1969
1970                         if (!IsHandleCreated)
1971                                 CreateHandle();
1972
1973                         for (int i=0; i<child_controls.Count; i++) {
1974                                 child_controls[i].CreateControl();
1975                         }
1976                         OnCreateControl();
1977                 }
1978
1979                 public Graphics CreateGraphics() {
1980                         return Graphics.FromHwnd(this.window.Handle);
1981                 }
1982
1983                 [MonoTODO("Come up with cross platform drag-drop driver interface")]
1984                 public DragDropEffects DoDragDrop(object data, DragDropEffects allowedEffects) {
1985                         return DragDropEffects.None;
1986                 }
1987
1988                 public object EndInvoke (IAsyncResult async_result) {
1989                         AsyncMethodResult result = (AsyncMethodResult) async_result;
1990                         return result.EndInvoke ();
1991                 }
1992
1993
1994                 public Control GetChildAtPoint(Point pt) {
1995                         // Microsoft's version of this function doesn't seem to work, so I can't check
1996                         // if we only consider children or also grandchildren, etc.
1997                         // I'm gonna say 'children only'
1998                         for (int i=0; i<child_controls.Count; i++) {
1999                                 if (child_controls[i].Bounds.Contains(pt)) {
2000                                         return child_controls[i];
2001                                 }
2002                         }
2003                         return null;
2004                 }
2005
2006                 public IContainerControl GetContainerControl() {
2007                         Control current = this;
2008
2009                         while (current!=null) {
2010                                 if ((current.control_style & ControlStyles.ContainerControl)!=0) {
2011                                         return (IContainerControl)current;
2012                                 }
2013                                 current = current.parent;
2014                         }
2015                         return null;
2016                 }
2017
2018                 public void Hide() {
2019                         this.Visible = false;
2020                 }
2021
2022                 public void Invalidate() {
2023                         Invalidate(ClientRectangle, false);
2024                 }
2025
2026                 public void Invalidate(bool invalidateChildren) {
2027                         Invalidate(ClientRectangle, invalidateChildren);
2028                 }
2029
2030                 public void Invalidate(System.Drawing.Rectangle rc) {
2031                         Invalidate(rc, false);
2032                 }
2033
2034                 public void Invalidate(System.Drawing.Rectangle rc, bool invalidateChildren) {
2035                         if (!IsHandleCreated || !Visible) {
2036                                 return;
2037                         }
2038
2039                         XplatUI.Invalidate(Handle, rc, !GetStyle (ControlStyles.AllPaintingInWmPaint));
2040
2041                         if (invalidateChildren) {
2042                                 for (int i=0; i<child_controls.Count; i++) child_controls[i].Invalidate();
2043                         }
2044                 }
2045
2046                 public void Invalidate(System.Drawing.Region region) {
2047                         Invalidate(region, false);
2048                 }
2049
2050                 [MonoTODO("Figure out if GetRegionScans is usable")]
2051                 public void Invalidate(System.Drawing.Region region, bool invalidateChildren) {
2052                         throw new NotImplementedException();
2053
2054                         // FIXME - should use the GetRegionScans function of the region to invalidate each area
2055                         //if (invalidateChildren) {
2056                         //      for (int i=0; i<child_controls.Count; i++) child_controls[i].Invalidate();
2057                         //}
2058                 }
2059
2060                 public object Invoke (Delegate method) {
2061                         return Invoke(method, null);
2062                 }
2063
2064                 public object Invoke (Delegate method, object[] args) {
2065                         IAsyncResult result = BeginInvoke (method, args);
2066                         return EndInvoke(result);
2067                 }
2068
2069                 public void PerformLayout() {
2070                         PerformLayout(null, null);
2071                 }
2072
2073                 public void PerformLayout(Control affectedControl, string affectedProperty) {
2074                         LayoutEventArgs levent = new LayoutEventArgs(affectedControl, affectedProperty);
2075
2076                         if (layout_suspended>0) {
2077                                 layout_pending = true;
2078                                 return;
2079                         }
2080
2081                         layout_pending = false;
2082
2083                         // Prevent us from getting messed up
2084                         layout_suspended++;
2085
2086                         // Perform all Dock and Anchor calculations
2087                         try {
2088                                 Control         child;
2089                                 AnchorStyles    anchor;
2090                                 Rectangle       space;
2091                                 int             diff_width;
2092                                 int             diff_height;
2093
2094                                 space=this.DisplayRectangle;
2095                                 if (prev_size != Size.Empty) {
2096                                         diff_width = space.Width - prev_size.Width;
2097                                         diff_height = space.Height - prev_size.Height;
2098                                 } else {
2099                                         diff_width = 0;
2100                                         diff_height = 0;
2101                                 }
2102
2103                                 // Deal with docking
2104                                 for (int i=0; i < child_controls.Count; i++) {
2105                                         child=child_controls[i];
2106                                         switch (child.Dock) {
2107                                         case DockStyle.None: {
2108                                                 // Do nothing
2109                                                 break;
2110                                         }
2111
2112                                         case DockStyle.Left: {
2113                                                 child.SetBounds(space.Left, space.Y, child.Width, space.Height);
2114                                                 space.X+=child.Width;
2115                                                 space.Width-=child.Width;
2116                                                 break;
2117                                         }
2118
2119                                         case DockStyle.Top: {
2120                                                 child.SetBounds(space.Left, space.Y, space.Width, child.Height);
2121                                                 space.Y+=child.Height;
2122                                                 space.Height-=child.Height;
2123                                                 break;
2124                                         }
2125                                 
2126                                         case DockStyle.Right: {
2127                                                 child.SetBounds(space.Right-child.Width, space.Y, child.Width, space.Height);
2128                                                 space.Width-=child.Width;
2129                                                 break;
2130                                         }
2131
2132                                         case DockStyle.Bottom: {
2133                                                 child.SetBounds(space.Left, space.Bottom-child.Height, space.Width, child.Height);
2134                                                 space.Height-=child.Height;
2135                                                 break;
2136                                         }
2137
2138                                         case DockStyle.Fill: {
2139                                                 child.SetBounds(space.Left, space.Top, space.Width, space.Height);
2140                                                 space.Width=0;
2141                                                 space.Height=0;
2142                                                 break;
2143                                         }
2144                                         }
2145                                 }
2146
2147                                 space=this.DisplayRectangle;
2148
2149                                 // Deal with anchoring
2150                                 for (int i=0; i < child_controls.Count; i++) {
2151                                         int left;
2152                                         int top;
2153                                         int width;
2154                                         int height;
2155
2156                                         child=child_controls[i];
2157                                         anchor=child.Anchor;
2158
2159                                         left=child.Left;
2160                                         top=child.Top;
2161                                         width=child.Width;
2162                                         height=child.Height;
2163
2164                                         // If the control is docked we don't need to do anything
2165                                         if (child.Dock != DockStyle.None) {
2166                                                 continue;
2167                                         }
2168
2169                                         if ((anchor & AnchorStyles.Left) !=0 ) {
2170                                                 if ((anchor & AnchorStyles.Right) != 0) {
2171                                                         // Anchoring to left and right
2172                                                         width=width+diff_width;
2173                                                 } else {
2174                                                         ; // nothing to do
2175                                                 }
2176                                         } else if ((anchor & AnchorStyles.Right) != 0) {
2177                                                 left+=diff_width;
2178                                         } else {
2179                                                 left+=diff_width/2;
2180                                         }
2181
2182                                         if ((anchor & AnchorStyles.Top) !=0 ) {
2183                                                 if ((anchor & AnchorStyles.Bottom) != 0) {
2184                                                         height+=diff_height;
2185                                                 } else {
2186                                                         ; // nothing to do
2187                                                 }
2188                                         } else if ((anchor & AnchorStyles.Bottom) != 0) {
2189                                                 top+=diff_height;
2190                                         } else {
2191                                                 top+=diff_height/2;
2192                                         }
2193
2194                                         // Sanity
2195                                         if (width < 0) {
2196                                                 width=0;
2197                                         }
2198
2199                                         if (height < 0) {
2200                                                 height=0;
2201                                         }
2202
2203                                         child.SetBounds(left, top, width, height);
2204                                 }
2205
2206                                 // Let everyone know
2207                                 OnLayout(levent);
2208                         }
2209
2210                                 // Need to make sure we decremend layout_suspended
2211                         finally {
2212                                 layout_suspended--;
2213                         }
2214                 }
2215
2216                 public Point PointToClient (Point p) {
2217                         int x = p.X;
2218                         int y = p.Y;
2219
2220                         XplatUI.ScreenToClient (Handle, ref x, ref y);
2221
2222                         return new Point (x, y);
2223                 }
2224
2225                 public Point PointToScreen(Point p) {
2226                         int x = p.X;
2227                         int y = p.Y;
2228
2229                         XplatUI.ClientToScreen(Handle, ref x, ref y);
2230
2231                         return new Point(x, y);
2232                 }
2233
2234                 public virtual bool PreProcessMessage(ref Message msg) {
2235                         Keys key_data;
2236
2237                         if (msg.Msg == (int)Msg.WM_KEYDOWN) {
2238                                 key_data = (Keys)msg.WParam.ToInt32();
2239                                 if (!ProcessCmdKey(ref msg, key_data)) {
2240                                         if (IsInputKey(key_data)) {
2241                                                 return false;
2242                                         }
2243
2244                                         return ProcessDialogKey(key_data);
2245                                 }
2246
2247                                 return true;
2248                         } else if (msg.Msg == (int)Msg.WM_CHAR) {
2249                                 if (IsInputChar((char)msg.WParam)) {
2250                                         return false;
2251                                 }
2252
2253                                 return ProcessDialogChar((char)msg.WParam);
2254                         }
2255
2256                         return false;
2257                 }
2258
2259                 public virtual void Refresh() {                 
2260                         if (IsHandleCreated == true) {
2261                                 XplatUI.RefreshWindow(window.Handle);
2262                         }
2263                 }
2264
2265                 public void ResumeLayout() {
2266                         ResumeLayout (true);
2267                 }
2268
2269                 public void ResumeLayout(bool performLayout) {
2270                         layout_suspended--;
2271                         
2272                         if (layout_suspended > 0) {
2273                                 return;
2274                         }
2275
2276                         if (performLayout || layout_pending) {
2277                                 PerformLayout();
2278                         }
2279                 }
2280
2281                 public void Select() {
2282                         Select(false, false);
2283                 }
2284
2285                 [MonoTODO("Finish")]
2286                 public bool SelectNextControl(Control ctl, bool forward, bool tabStopOnly, bool nested, bool wrap) {
2287                         return false;
2288                 }
2289
2290                 public void SendToBack() {
2291                         if ((parent != null) && (parent.child_controls[parent.child_controls.Count-1]!=this)) {
2292                                 if (parent.child_controls.Contains(this)) {
2293                                         parent.child_controls.SetChildIndex(this, parent.child_controls.Count);
2294                                 }
2295                         }
2296
2297                         XplatUI.SetZOrder(this.window.Handle, IntPtr.Zero, false, true);
2298                         if (parent != null) {
2299                                 parent.Refresh();
2300                         }
2301                 }
2302
2303                 public void SetBounds(int x, int y, int width, int height) {
2304                         SetBoundsCore(x, y, width, height, BoundsSpecified.All);
2305                 }
2306
2307                 public void SetBounds(int x, int y, int width, int height, BoundsSpecified specified) {
2308                         SetBoundsCore(x, y, width, height, specified);
2309                 }
2310
2311                 public void Show() {
2312                         if (!IsHandleCreated) {
2313                                 this.CreateHandle();
2314                         }
2315
2316                         this.Visible=true;                      
2317                 }
2318
2319                 public void SuspendLayout() {
2320                         layout_suspended++;
2321                 }
2322
2323                 #endregion      // Public Instance Methods
2324
2325                 #region Protected Instance Methods
2326                 protected virtual AccessibleObject CreateAccessibilityInstance() {
2327                         return new AccessibleObject(this);
2328                 }
2329
2330                 protected virtual ControlCollection CreateControlsInstance() {
2331                         return new ControlCollection(this);
2332                 }
2333
2334                 protected virtual void CreateHandle() {
2335                         if (IsDisposed) {
2336                                 throw new ObjectDisposedException(Name);
2337                         }
2338
2339                         if (IsHandleCreated) {
2340                                 return;
2341                         }
2342
2343                         if (window==null) {
2344                                 window = new ControlNativeWindow(this);
2345                                 window.CreateHandle(CreateParams);
2346                         }
2347
2348                         if (window.Handle!=IntPtr.Zero) {
2349                                 if (!controls.Contains(window.Handle)) {
2350                                         controls.Add(this);
2351                                 }
2352
2353                                 creator_thread = Thread.CurrentThread;
2354
2355                                 XplatUI.SetWindowBackground(window.Handle, this.BackColor);
2356
2357                                 OnHandleCreated(EventArgs.Empty);
2358                         }
2359                 }
2360
2361                 protected virtual void DefWndProc(ref Message m) {
2362                         window.DefWndProc(ref m);
2363                 }
2364
2365                 protected virtual void DestroyHandle() {
2366                         if (IsHandleCreated) {
2367                                 if (Handle != IntPtr.Zero) {
2368                                         controls.Remove(Handle);
2369                                 }
2370
2371                                 if (window != null) {
2372                                         window.DestroyHandle();
2373                                 }
2374                         }
2375                 }
2376
2377                 protected bool GetStyle(ControlStyles flag) {
2378                         return (control_style & flag) != 0;
2379                 }
2380
2381                 protected virtual void InitLayout() {
2382                         if (parent != null) {
2383                                 parent.PerformLayout(this, "parent");
2384                         }
2385                 }
2386
2387                 protected virtual bool IsInputChar (char charCode) {
2388                         if (parent != null) {
2389                                 return parent.IsInputChar(charCode);
2390                         }
2391
2392                         return true;
2393                 }
2394
2395                 protected virtual bool IsInputKey (Keys keyData) {
2396                         // Doc says this one calls IsInputChar; not sure what to do with that
2397                         return false;
2398                 }
2399
2400                 protected virtual bool ProcessCmdKey(ref Message msg, Keys keyData) {
2401                         if ((context_menu != null) && context_menu.ProcessCmdKey(ref msg, keyData)) {
2402                                 return true;
2403                         }
2404
2405                         if (parent != null) {
2406                                 return parent.ProcessCmdKey(ref msg, keyData);
2407                         }
2408
2409                         return false;
2410                 }
2411
2412                 protected virtual bool ProcessDialogChar(char charCode) {
2413                         if (parent != null) {
2414                                 return parent.ProcessDialogChar (charCode);
2415                         }
2416
2417                         return false;
2418                 }
2419
2420                 protected virtual bool ProcessDialogKey (Keys keyData) {
2421                         if (parent != null) {
2422                                 return parent.ProcessDialogKey (keyData);
2423                         }
2424
2425                         return false;
2426                 }
2427
2428                 protected virtual bool ProcessKeyEventArgs (ref Message msg)
2429                 {
2430                         KeyEventArgs            key_event;
2431
2432                         PreProcessMessage(ref msg);
2433
2434                         switch (msg.Msg) {
2435                                 case (int)Msg.WM_KEYDOWN: {
2436                                         key_event = new KeyEventArgs ((Keys)msg.WParam.ToInt32 ());
2437                                         OnKeyDown (key_event);
2438                                         return key_event.Handled;
2439                                 }
2440                                 case (int)Msg.WM_KEYUP: {
2441                                         key_event = new KeyEventArgs ((Keys)msg.WParam.ToInt32 ());
2442                                         OnKeyUp (key_event);
2443                                         return key_event.Handled;
2444                                 }
2445
2446                                 case (int)Msg.WM_CHAR: {
2447                                         KeyPressEventArgs       key_press_event;
2448
2449                                         key_press_event = new KeyPressEventArgs((char)msg.WParam);
2450                                         OnKeyPress(key_press_event);
2451                                         return key_press_event.Handled;
2452                                 }
2453
2454                                 default: {
2455                                         break;
2456                                 }
2457                         }
2458
2459                         return false;
2460                 }
2461
2462                 protected internal virtual bool ProcessKeyMessage(ref Message msg) {
2463                         if (parent != null) {
2464                                 if (parent.ProcessKeyPreview(ref msg)) {
2465                                         return true;
2466                                 }
2467                         }
2468
2469                         return ProcessKeyEventArgs(ref msg);
2470                 }
2471
2472                 protected virtual bool ProcessKeyPreview(ref Message msg) {
2473                         if (parent != null) {
2474                                 return parent.ProcessKeyPreview(ref msg);
2475                         }
2476
2477                         return false;
2478                 }
2479
2480                 protected virtual bool ProcessMnemonic(char charCode) {
2481                         // override me
2482                         return false;
2483                 }
2484
2485                 protected void RaiseDragEvent(object key, DragEventArgs e) {
2486                         // MS Internal
2487                 }
2488
2489                 protected void RaiseKeyEvent(object key, KeyEventArgs e) {
2490                         // MS Internal
2491                 }
2492
2493                 protected void RaiseMouseEvent(object key, MouseEventArgs e) {
2494                         // MS Internal
2495                 }
2496
2497                 protected void RaisePaintEvent(object key, PaintEventArgs e) {
2498                         // MS Internal
2499                 }
2500
2501                 protected void RecreateHandle() {
2502                         IEnumerator child = child_controls.GetEnumerator();
2503
2504                         is_recreating=true;
2505
2506                         if (IsHandleCreated) {
2507                                 DestroyHandle();
2508                                 CreateHandle();
2509
2510                                 // FIXME ZOrder?
2511
2512                                 while (child.MoveNext()) {
2513                                         ((Control)child.Current).RecreateHandle();
2514                                 }
2515                         } else {
2516                                 CreateHandle();
2517                         }
2518
2519                         is_recreating = false;
2520                 }
2521
2522                 protected void ResetMouseEventArgs() {
2523                         // MS Internal
2524                 }
2525
2526                 protected ContentAlignment RtlTranslateAlignment(ContentAlignment align) {
2527                         if (right_to_left == RightToLeft.No) {
2528                                 return align;
2529                         }
2530
2531                         switch (align) {
2532                                 case ContentAlignment.TopLeft: {
2533                                         return ContentAlignment.TopRight;
2534                                 }
2535
2536                                 case ContentAlignment.TopRight: {
2537                                         return ContentAlignment.TopLeft;
2538                                 }
2539
2540                                 case ContentAlignment.MiddleLeft: {
2541                                         return ContentAlignment.MiddleRight;
2542                                 }
2543
2544                                 case ContentAlignment.MiddleRight: {
2545                                         return ContentAlignment.MiddleLeft;
2546                                 }
2547
2548                                 case ContentAlignment.BottomLeft: {
2549                                         return ContentAlignment.BottomRight;
2550                                 }
2551
2552                                 case ContentAlignment.BottomRight: {
2553                                         return ContentAlignment.BottomLeft;
2554                                 }
2555
2556                                 default: {
2557                                         // if it's center it doesn't change
2558                                         return align;
2559                                 }
2560                         }
2561                 }
2562
2563                 protected HorizontalAlignment RtlTranslateAlignment(HorizontalAlignment align) {
2564                         if ((right_to_left == RightToLeft.No) || (align == HorizontalAlignment.Center)) {
2565                                 return align;
2566                         }
2567
2568                         if (align == HorizontalAlignment.Left) {
2569                                 return HorizontalAlignment.Right;
2570                         }
2571
2572                         // align must be HorizontalAlignment.Right
2573                         return HorizontalAlignment.Left;
2574                 }
2575
2576                 protected LeftRightAlignment RtlTranslateAlignment(LeftRightAlignment align) {
2577                         if (right_to_left == RightToLeft.No) {
2578                                 return align;
2579                         }
2580
2581                         if (align == LeftRightAlignment.Left) {
2582                                 return LeftRightAlignment.Right;
2583                         }
2584
2585                         // align must be LeftRightAlignment.Right;
2586                         return LeftRightAlignment.Left;
2587                 }
2588
2589                 protected ContentAlignment RtlTranslateContent(ContentAlignment align) {
2590                         return RtlTranslateAlignment(align);
2591                 }
2592
2593                 protected HorizontalAlignment RtlTranslateHorizontal(HorizontalAlignment align) {
2594                         return RtlTranslateAlignment(align);
2595                 }
2596
2597                 protected LeftRightAlignment RtlTranslateLeftRight(LeftRightAlignment align) {
2598                         return RtlTranslateAlignment(align);
2599                 }
2600
2601                 protected virtual void ScaleCore(float dx, float dy) {
2602                         throw new NotImplementedException();
2603                 }
2604
2605                 protected virtual void Select(bool directed, bool forward) {
2606                         int     index;
2607                         bool    result;
2608
2609                         if (!directed) {
2610                                 // Select this control
2611                                 Select(this);
2612                         }
2613
2614                         if (parent == null) {
2615                                 return;
2616                         }
2617
2618                         index = parent.child_controls.IndexOf(this);
2619                         result = false;
2620
2621                         
2622
2623                         do {
2624                                 if (forward) {
2625                                         if ((index+1) < parent.child_controls.Count) {
2626                                                 index++;
2627                                         } else {
2628                                                 index = 0;
2629                                         }
2630                                 } else {
2631                                         if (index>0) {
2632                                                 index++;
2633                                         } else {
2634                                                 index = parent.child_controls.Count-1;
2635                                         }
2636                                 }
2637                                 result = Select(parent.child_controls[index]);
2638                         } while (!result && parent.child_controls[index] != this);
2639                 }
2640
2641                 protected virtual void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
2642                         // SetBoundsCore updates the Win32 control itself. UpdateBounds updates the controls variables and fires events, I'm guessing - pdb
2643                         if ((specified & BoundsSpecified.X) != BoundsSpecified.X) {
2644                                 x = Left;
2645                         }
2646
2647                         if ((specified & BoundsSpecified.Y) != BoundsSpecified.Y) {
2648                                 y = Top;
2649                         }
2650
2651                         if ((specified & BoundsSpecified.Width)!= BoundsSpecified.Width) {
2652                                 width = Width;
2653                         }
2654
2655                         if ((specified & BoundsSpecified.Height) != BoundsSpecified.Height) {
2656                                 height = Height;
2657                         }
2658
2659                         if (IsHandleCreated) {
2660                                 XplatUI.SetWindowPos(Handle, x, y, width, height);
2661                         }
2662                         UpdateBounds(x, y, width, height);
2663                 }
2664
2665                 protected virtual void SetClientSizeCore(int x, int y) {
2666                         // Calculate the actual window size from the client size (it usually stays the same or grows)
2667                         Rectangle       ClientRect;
2668                         Rectangle       WindowRect;
2669                         CreateParams    cp;
2670
2671                         ClientRect = new Rectangle(0, 0, x, y);
2672                         cp = this.CreateParams;
2673
2674                         if (XplatUI.CalculateWindowRect(Handle, ref ClientRect, cp.Style, false, out WindowRect)==false) {
2675                                 return;
2676                         }
2677
2678                         this.client_size = new Size(x, y);
2679                         SetBoundsCore(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
2680                 }
2681
2682                 protected void SetStyle(ControlStyles flag, bool value) {
2683                         if (value) {
2684                                 control_style |= flag;
2685                         } else {
2686                                 control_style &= ~flag;
2687                         }
2688                 }
2689
2690                 protected virtual void SetVisibleCore(bool value) {
2691                         if (value!=is_visible) {
2692                                 is_visible=value;
2693                                 XplatUI.SetVisible(Handle, value);
2694                                 OnVisibleChanged(EventArgs.Empty);
2695                                 if (!is_visible) {
2696                                         if (dc_mem != null) {
2697                                                 dc_mem.Dispose();
2698                                                 dc_mem = null;
2699                                         }
2700
2701                                         if (bmp_mem != null) {
2702                                                 bmp_mem.Dispose();
2703                                                 bmp_mem = null;
2704                                         }
2705                                 } else {
2706                                         this.CreateBuffers(bounds.Width, bounds.Height);
2707                                 }
2708
2709                                 // FIXME - deal with focus
2710
2711                                 if (parent != null) {
2712                                         parent.PerformLayout(this, "visible");
2713                                 } else {
2714                                         PerformLayout(this, "visible");
2715                                 }
2716                         }
2717                 }
2718         
2719                 protected void UpdateBounds() {
2720                         int     x;
2721                         int     y;
2722                         int     width;
2723                         int     height;
2724                         int     client_width;
2725                         int     client_height;
2726
2727                         if (!IsHandleCreated) {
2728                                 CreateHandle();
2729                         }
2730
2731                         XplatUI.GetWindowPos(this.Handle, out x, out y, out width, out height, out client_width, out client_height);
2732                         UpdateBounds(x, y, width, height, client_width, client_height);
2733                 }
2734
2735                 protected void UpdateBounds(int x, int y, int width, int height) {
2736                         // UpdateBounds only seems to set our sizes and fire events but not update the GUI window to match
2737                         bool    moved   = false;
2738                         bool    resized = false;
2739
2740                         int     client_x_diff = this.bounds.Width-this.client_size.Width;
2741                         int     client_y_diff = this.bounds.Height-this.client_size.Height;
2742
2743                         // Needed to generate required notifications
2744                         if ((this.bounds.X!=x) || (this.bounds.Y!=y)) {
2745                                 moved=true;
2746                         }
2747
2748                         if ((this.Bounds.Width!=width) || (this.Bounds.Height!=height)) {
2749                                 resized=true;
2750                         }
2751
2752                         bounds.X=x;
2753                         bounds.Y=y;
2754                         bounds.Width=width;
2755                         bounds.Height=height;
2756
2757                         // Update client rectangle as well
2758                         if (this.layout_suspended==0) {
2759                                 prev_size.Width=client_size.Width;
2760                                 prev_size.Height=client_size.Height;
2761                         }
2762
2763                         client_size.Width=width-client_x_diff;
2764                         client_size.Height=height-client_y_diff;
2765
2766                         if (moved) {
2767                                 OnLocationChanged(EventArgs.Empty);
2768                         }
2769
2770                         if (resized) {
2771                                 OnSizeChanged(EventArgs.Empty);
2772                         }
2773                 }
2774
2775                 protected void UpdateBounds(int x, int y, int width, int height, int clientWidth, int clientHeight) {
2776                         UpdateBounds(x, y, width, height);
2777
2778                         this.client_size.Width=clientWidth;
2779                         this.client_size.Height=clientHeight;
2780                 }
2781
2782                 [MonoTODO]
2783                 protected virtual void WndProc(ref Message m) {
2784                         EventArgs       e = new EventArgs();
2785
2786 #if debug
2787                         Console.WriteLine("Received message {0}", m);
2788 #endif
2789
2790                         switch((Msg)m.Msg) {
2791                         case Msg.WM_WINDOWPOSCHANGED: {
2792                                 if (Visible) {
2793                                         UpdateBounds();
2794                                         if (GetStyle(ControlStyles.ResizeRedraw)) {
2795                                                 Invalidate();
2796                                         }
2797                                 }
2798                                 break;
2799                         }
2800
2801                         case Msg.WM_PAINT: {                            
2802                                 PaintEventArgs  paint_event;
2803
2804                                 paint_event = XplatUI.PaintEventStart(Handle);
2805                                 OnPaint(paint_event);
2806                                 XplatUI.PaintEventEnd(Handle);
2807                                 DefWndProc(ref m);      
2808                                 break;
2809                         }
2810                                 
2811                         case Msg.WM_ERASEBKGND:{
2812                                 if (GetStyle (ControlStyles.UserPaint)){                                                
2813                                         if (!GetStyle(ControlStyles.AllPaintingInWmPaint)) {
2814                                                 PaintEventArgs eraseEventArgs = new PaintEventArgs (Graphics.FromHdc (m.WParam), new Rectangle (new Point (0,0),Size));
2815                                                 OnPaintBackground (eraseEventArgs);
2816                                         }
2817                                         m.Result = (IntPtr)1;
2818                                 } else {
2819                                         m.Result = IntPtr.Zero;
2820                                         DefWndProc (ref m);     
2821                                 }                                       
2822                                         
2823                                 break;
2824                         }
2825
2826                         case Msg.WM_LBUTTONUP: {
2827                                 OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Left, 
2828                                         mouse_clicks, 
2829                                         LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2830                                         0));
2831                                 if (mouse_clicks > 1) {
2832                                         mouse_clicks = 1;
2833                                 }
2834                                 break;
2835                         }
2836                                 
2837                         case Msg.WM_LBUTTONDOWN: {                                      
2838                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2839                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2840                                         0));
2841                                         
2842                                 break;
2843                         }
2844
2845                         case Msg.WM_LBUTTONDBLCLK: {
2846                                 mouse_clicks++;
2847                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2848                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2849                                         0));
2850                                 break;
2851                         }
2852
2853                         case Msg.WM_MBUTTONUP: {
2854                                 OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Middle, 
2855                                         mouse_clicks, 
2856                                         LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2857                                         0));
2858                                 if (mouse_clicks > 1) {
2859                                         mouse_clicks = 1;
2860                                 }
2861                                 break;
2862                         }
2863                                 
2864                         case Msg.WM_MBUTTONDOWN: {                                      
2865                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2866                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2867                                         0));
2868                                         
2869                                 break;
2870                         }
2871
2872                         case Msg.WM_MBUTTONDBLCLK: {
2873                                 mouse_clicks++;
2874                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2875                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2876                                         0));
2877                                 break;
2878                         }
2879
2880                         case Msg.WM_RBUTTONUP: {
2881                                 OnMouseUp (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()) | MouseButtons.Right, 
2882                                         mouse_clicks, 
2883                                         LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2884                                         0));
2885                                 if (mouse_clicks > 1) {
2886                                         mouse_clicks = 1;
2887                                 }
2888                                 break;
2889                         }
2890                                 
2891                         case Msg.WM_RBUTTONDOWN: {                                      
2892                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2893                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2894                                         0));
2895                                         
2896                                 break;
2897                         }
2898
2899                         case Msg.WM_RBUTTONDBLCLK: {
2900                                 mouse_clicks++;
2901                                 OnMouseDown (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2902                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2903                                         0));
2904                                 break;
2905                         }
2906
2907                         case Msg.WM_MOUSEWHEEL: {                               
2908
2909                                 OnMouseWheel (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2910                                         mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2911                                         HighOrder(m.WParam.ToInt32())));
2912                                 break;
2913                         }
2914
2915                                 
2916                         case Msg.WM_MOUSEMOVE: {                                        
2917                                 OnMouseMove  (new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
2918                                         mouse_clicks, 
2919                                         LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 
2920                                         0));
2921                                 break;
2922                         }
2923
2924                         case Msg.WM_MOUSE_ENTER: {
2925                                 if (is_entered) {
2926                                         return;
2927                                 }
2928                                 is_entered = true;
2929                                 OnMouseEnter(EventArgs.Empty);
2930                                 break;
2931                         }
2932
2933                         case Msg.WM_MOUSE_LEAVE: {
2934                                 is_entered=false;
2935                                 OnMouseLeave(EventArgs.Empty);
2936                                 break;
2937                         }
2938
2939                         case Msg.WM_MOUSEHOVER: {
2940                                 OnMouseHover(EventArgs.Empty);
2941                                 break;
2942                         }
2943                         
2944                         case Msg.WM_KEYDOWN: {
2945                                 if (!ProcessKeyMessage(ref m)) {
2946                                         DefWndProc (ref m);
2947                                 }
2948
2949                                 break;                                  
2950                         }
2951
2952                         case Msg.WM_KEYUP: {
2953                                 if (!ProcessKeyMessage(ref m)) {
2954                                         DefWndProc (ref m);
2955                                 }
2956
2957                                 break;                                  
2958                         }               
2959
2960                         case Msg.WM_CHAR: {
2961                                 if (!ProcessKeyMessage(ref m)) {
2962                                         DefWndProc (ref m);
2963                                 }
2964
2965                                 break;                                  
2966                         }               
2967                                 
2968
2969 #if notyet                              
2970                                 case Msg.WM_WINDOWPOSCHANGED:   throw new NotImplementedException();    break;
2971                                 case Msg.WM_SYSCOLORCHANGE:     throw new NotImplementedException();    break;
2972                                 
2973 #endif
2974
2975                         default:
2976                                 DefWndProc(ref m);      
2977                                 break;
2978                         }
2979                         
2980                         
2981                         
2982                 }
2983                 #endregion      // Public Instance Methods
2984
2985                 #region OnXXX methods
2986                 protected virtual void OnBackColorChanged(EventArgs e) {
2987                         if (BackColorChanged!=null) BackColorChanged(this, e);
2988                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentBackColorChanged(e);
2989                 }
2990
2991                 protected virtual void OnBackgroundImageChanged(EventArgs e) {
2992                         if (BackgroundImageChanged!=null) BackgroundImageChanged(this, e);
2993                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentBackgroundImageChanged(e);
2994                 }
2995
2996                 protected virtual void OnBindingContextChanged(EventArgs e) {
2997                         if (BindingContextChanged!=null) BindingContextChanged(this, e);
2998                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentBindingContextChanged(e);
2999                 }
3000
3001                 protected virtual void OnCausesValidationChanged(EventArgs e) {
3002                         if (CausesValidationChanged!=null) CausesValidationChanged(this, e);
3003                 }
3004
3005                 protected virtual void OnChangeUICues(UICuesEventArgs e) {
3006                         if (CausesValidationChanged!=null) CausesValidationChanged(this, e);
3007                 }
3008
3009                 protected virtual void OnClick(EventArgs e) {
3010                         if (Click!=null) Click(this, e);
3011                 }
3012
3013                 protected virtual void OnContextMenuChanged(EventArgs e) {
3014                         if (ContextMenuChanged!=null) ContextMenuChanged(this, e);
3015                 }
3016
3017                 protected virtual void OnControlAdded(ControlEventArgs e) {
3018                         if (ControlAdded!=null) ControlAdded(this, e);
3019                 }
3020
3021                 protected virtual void OnControlRemoved(ControlEventArgs e) {
3022                         if (ControlRemoved!=null) ControlRemoved(this, e);
3023                 }
3024
3025                 protected virtual void OnCreateControl() {
3026                         // Override me!
3027                 }
3028
3029                 protected virtual void OnCursorChanged(EventArgs e) {
3030                         if (CursorChanged!=null) CursorChanged(this, e);
3031                 }
3032
3033                 protected virtual void OnDockChanged(EventArgs e) {
3034                         if (DockChanged!=null) DockChanged(this, e);
3035                 }
3036
3037                 protected virtual void OnDoubleClick(EventArgs e) {
3038                         if (DoubleClick!=null) DoubleClick(this, e);
3039                 }
3040
3041                 protected virtual void OnDragDrop(DragEventArgs drgevent) {
3042                         if (DragDrop!=null) DragDrop(this, drgevent);
3043                 }
3044
3045                 protected virtual void OnDragEnter(DragEventArgs drgevent) {
3046                         if (DragEnter!=null) DragEnter(this, drgevent);
3047                 }
3048
3049                 protected virtual void OnDragLeave(EventArgs e) {
3050                         if (DragLeave!=null) DragLeave(this, e);
3051                 }
3052
3053                 protected virtual void OnDragOver(DragEventArgs drgevent) {
3054                         if (DragOver!=null) DragOver(this, drgevent);
3055                 }
3056
3057                 protected virtual void OnEnabledChanged(EventArgs e) {
3058                         if (EnabledChanged!=null) EnabledChanged(this, e);
3059                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentEnabledChanged(e);
3060                 }
3061
3062                 protected virtual void OnEnter(EventArgs e) {
3063                         if (Enter!=null) Enter(this, e);
3064                 }
3065
3066                 protected virtual void OnFontChanged(EventArgs e) {
3067                         if (FontChanged!=null) FontChanged(this, e);
3068                 }
3069
3070                 protected virtual void OnForeColorChanged(EventArgs e) {
3071                         if (ForeColorChanged!=null) ForeColorChanged(this, e);
3072                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentForeColorChanged(e);
3073                 }
3074
3075                 protected virtual void OnGiveFeedback(GiveFeedbackEventArgs gfbevent) {
3076                         if (GiveFeedback!=null) GiveFeedback(this, gfbevent);
3077                 }
3078                 
3079                 protected virtual void OnGotFocus(EventArgs e) {
3080                         if (GotFocus!=null) GotFocus(this, e);
3081                 }
3082
3083                 protected virtual void OnHandleCreated(EventArgs e) {
3084                         if (HandleCreated!=null) HandleCreated(this, e);
3085                 }
3086
3087                 protected virtual void OnHandleDestroyed(EventArgs e) {
3088                         if (HandleDestroyed!=null) HandleDestroyed(this, e);
3089                 }
3090
3091                 protected virtual void OnHelpRequested(HelpEventArgs hevent) {
3092                         if (HelpRequested!=null) HelpRequested(this, hevent);
3093                 }
3094
3095                 protected virtual void OnImeModeChanged(EventArgs e) {
3096                         if (ImeModeChanged!=null) ImeModeChanged(this, e);
3097                 }
3098
3099                 protected virtual void OnInvalidated(InvalidateEventArgs e) {
3100                         if (Invalidated!=null) Invalidated(this, e);
3101                 }
3102
3103                 protected virtual void OnKeyDown(KeyEventArgs e) {                      
3104                         if (KeyDown!=null) KeyDown(this, e);
3105                 }
3106
3107                 protected virtual void OnKeyPress(KeyPressEventArgs e) {
3108                         if (KeyPress!=null) KeyPress(this, e);
3109                 }
3110
3111                 protected virtual void OnKeyUp(KeyEventArgs e) {
3112                         if (KeyUp!=null) KeyUp(this, e);
3113                 }
3114
3115                 protected virtual void OnLayout(LayoutEventArgs levent) {
3116                         if (Layout!=null) Layout(this, levent);
3117                 }
3118
3119                 protected virtual void OnLeave(EventArgs e) {
3120                         if (Leave!=null) Leave(this, e);
3121                 }
3122
3123                 protected virtual void OnLocationChanged(EventArgs e) {
3124                         if (LocationChanged!=null) LocationChanged(this, e);
3125                 }
3126
3127                 protected virtual void OnLostFocus(EventArgs e) {
3128                         if (LostFocus!=null) LostFocus(this, e);
3129                 }
3130
3131                 protected virtual void OnMouseDown(MouseEventArgs e) {
3132                         if (MouseDown!=null) MouseDown(this, e);
3133                 }
3134
3135                 protected virtual void OnMouseEnter(EventArgs e) {
3136                         if (MouseEnter!=null) MouseEnter(this, e);
3137                 }
3138
3139                 protected virtual void OnMouseHover(EventArgs e) {
3140                         if (MouseHover!=null) MouseHover(this, e);
3141                 }
3142
3143                 protected virtual void OnMouseLeave(EventArgs e) {
3144                         if (MouseLeave!=null) MouseLeave(this, e);
3145                 }
3146
3147                 protected virtual void OnMouseMove(MouseEventArgs e) {                  
3148                         if (MouseMove!=null) MouseMove(this, e);
3149                 }
3150
3151                 protected virtual void OnMouseUp(MouseEventArgs e) {
3152                         if (MouseUp!=null) MouseUp(this, e);
3153                 }
3154
3155                 protected virtual void OnMouseWheel(MouseEventArgs e) {
3156                         if (MouseWheel!=null) MouseWheel(this, e);
3157                 }
3158
3159                 protected virtual void OnMove(EventArgs e) {
3160                         if (Move!=null) Move(this, e);
3161                 }
3162
3163                 protected virtual void OnNotifyMessage(Message m) {
3164                         // Override me!
3165                 }
3166
3167                 protected virtual void OnPaint(PaintEventArgs e) {
3168                         if (Paint!=null) Paint(this, e);
3169                 }
3170
3171                 protected virtual void OnPaintBackground(PaintEventArgs pevent) {
3172                         // Override me!
3173                 }
3174
3175                 protected virtual void OnParentBackColorChanged(EventArgs e) {
3176                         if (background_color.IsEmpty && background_image==null) {
3177                                 Invalidate();
3178                                 OnBackColorChanged(e);
3179                         }
3180                 }
3181
3182                 protected virtual void OnParentBackgroundImageChanged(EventArgs e) {
3183                         if (background_color.IsEmpty && background_image==null) {
3184                                 Invalidate();
3185                                 OnBackgroundImageChanged(e);
3186                         }
3187                 }
3188
3189                 protected virtual void OnParentBindingContextChanged(EventArgs e) {
3190                         if (binding_context==null) {
3191                                 binding_context=Parent.binding_context;
3192                                 OnBindingContextChanged(e);
3193                         }
3194                 }
3195
3196                 protected virtual void OnParentChanged(EventArgs e) {
3197                         if (ParentChanged!=null) ParentChanged(this, e);
3198                 }
3199
3200                 protected virtual void OnParentEnabledChanged(EventArgs e) {
3201                         if ((is_enabled && !Parent.is_enabled) || (!is_enabled && Parent.is_enabled)) {
3202                                 is_enabled=false;
3203                                 Invalidate();
3204                                 EnabledChanged(this, e);
3205                         }
3206                 }
3207
3208                 protected virtual void OnParentFontChanged(EventArgs e) {
3209                         if (font==null) {
3210                                 Invalidate();
3211                                 OnFontChanged(e);
3212                         }
3213                 }
3214
3215                 protected virtual void OnParentForeColorChanged(EventArgs e) {
3216                         if (foreground_color.IsEmpty) {
3217                                 Invalidate();
3218                                 OnForeColorChanged(e);
3219                         }
3220                 }
3221
3222                 protected virtual void OnParentRightToLeftChanged(EventArgs e) {
3223                         if (right_to_left==RightToLeft.Inherit) {
3224                                 Invalidate();
3225                                 OnRightToLeftChanged(e);
3226                         }
3227                 }
3228
3229                 protected virtual void OnParentVisibleChanged(EventArgs e) {
3230                         if (is_visible!=Parent.is_visible) {
3231                                 is_visible=false;
3232                                 Invalidate();
3233                                 OnVisibleChanged(e);
3234                         }
3235                 }
3236
3237                 protected virtual void OnQueryContinueDrag(QueryContinueDragEventArgs e) {
3238                         if (QueryContinueDrag!=null) QueryContinueDrag(this, e);
3239                 }
3240
3241                 protected virtual void OnResize(EventArgs e) {
3242                         if (Resize!=null) Resize(this, e);
3243
3244                         PerformLayout(this, "bounds");
3245
3246                         if (parent != null) {
3247                                 parent.PerformLayout();
3248                         }
3249                 }
3250
3251                 protected virtual void OnRightToLeftChanged(EventArgs e) {
3252                         if (RightToLeftChanged!=null) RightToLeftChanged(this, e);
3253                         for (int i=0; i<child_controls.Count; i++) child_controls[i].OnParentRightToLeftChanged(e);
3254                 }
3255
3256                 protected virtual void OnSizeChanged(EventArgs e) {
3257                         InvalidateBuffers ();
3258                         OnResize(e);
3259                         if (SizeChanged!=null) SizeChanged(this, e);
3260                 }
3261
3262                 protected virtual void OnStyleChanged(EventArgs e) {
3263                         if (StyleChanged!=null) StyleChanged(this, e);
3264                 }
3265
3266                 protected virtual void OnSystemColorsChanged(EventArgs e) {
3267                         if (SystemColorsChanged!=null) SystemColorsChanged(this, e);
3268                 }
3269
3270                 protected virtual void OnTabIndexChanged(EventArgs e) {
3271                         if (TabIndexChanged!=null) TabIndexChanged(this, e);
3272                 }
3273
3274                 protected virtual void OnTabStopChanged(EventArgs e) {
3275                         if (TabStopChanged!=null) TabStopChanged(this, e);
3276                 }
3277
3278                 protected virtual void OnTextChanged(EventArgs e) {
3279                         if (TextChanged!=null) TextChanged(this, e);
3280                 }
3281
3282                 protected virtual void OnValidated(EventArgs e) {
3283                         if (Validated!=null) Validated(this, e);
3284                 }
3285
3286                 protected virtual void OnValidating(System.ComponentModel.CancelEventArgs e) {
3287                         if (Validating!=null) Validating(this, e);
3288                 }
3289
3290                 protected virtual void OnVisibleChanged(EventArgs e) {
3291                         if (!is_visible) {
3292                                 if (dc_mem!=null) {
3293                                         dc_mem.Dispose ();
3294                                         bmp_mem=null;
3295                                 }
3296
3297                                 if (bmp_mem!=null) {
3298                                         bmp_mem.Dispose();
3299                                         bmp_mem=null;
3300                                 }
3301                         } else {
3302                                 if (!is_disposed) {
3303                                         if (!this.IsHandleCreated) {
3304                                                 this.CreateHandle();
3305                                         }
3306                                         PerformLayout();
3307                                 }
3308                         }
3309                         
3310                         if (VisibleChanged!=null) VisibleChanged(this, e);
3311
3312                         // We need to tell our kids
3313                         for (int i=0; i<child_controls.Count; i++) {
3314                                 child_controls[i].OnParentVisibleChanged(e);
3315                         }
3316                 }
3317                 #endregion      // OnXXX methods
3318
3319                 #region Events
3320                 public event EventHandler               BackColorChanged;
3321                 public event EventHandler               BackgroundImageChanged;
3322                 public event EventHandler               BindingContextChanged;
3323                 public event EventHandler               CausesValidationChanged;
3324                 public event UICuesEventHandler         ChangeUICues;
3325                 public event EventHandler               Click;
3326                 public event EventHandler               ContextMenuChanged;
3327                 public event ControlEventHandler        ControlAdded;
3328                 public event ControlEventHandler        ControlRemoved;
3329                 public event EventHandler               CursorChanged;
3330                 public event EventHandler               DockChanged;
3331                 public event EventHandler               DoubleClick;
3332                 public event DragEventHandler           DragDrop;
3333                 public event DragEventHandler           DragEnter;
3334                 public event EventHandler               DragLeave;
3335                 public event DragEventHandler           DragOver;
3336                 public event EventHandler               EnabledChanged;
3337                 public event EventHandler               Enter;
3338                 public event EventHandler               FontChanged;
3339                 public event EventHandler               ForeColorChanged;
3340                 public event GiveFeedbackEventHandler   GiveFeedback;
3341                 public event EventHandler               GotFocus;
3342                 public event EventHandler               HandleCreated;
3343                 public event EventHandler               HandleDestroyed;
3344                 public event HelpEventHandler           HelpRequested;
3345                 public event EventHandler               ImeModeChanged;
3346                 public event InvalidateEventHandler     Invalidated;
3347                 public event KeyEventHandler            KeyDown;
3348                 public event KeyPressEventHandler       KeyPress;
3349                 public event KeyEventHandler            KeyUp;
3350                 public event LayoutEventHandler         Layout;
3351                 public event EventHandler               Leave;
3352                 public event EventHandler               LocationChanged;
3353                 public event EventHandler               LostFocus;
3354                 public event MouseEventHandler          MouseDown;
3355                 public event EventHandler               MouseEnter;
3356                 public event EventHandler               MouseHover;
3357                 public event EventHandler               MouseLeave;
3358                 public event MouseEventHandler          MouseMove;
3359                 public event MouseEventHandler          MouseUp;
3360                 public event MouseEventHandler          MouseWheel;
3361                 public event EventHandler               Move;
3362                 public event PaintEventHandler          Paint;
3363                 public event EventHandler               ParentChanged;
3364                 public event QueryAccessibilityHelpEventHandler QueryAccessibilityHelp;
3365                 public event QueryContinueDragEventHandler      QueryContinueDrag;
3366                 public event EventHandler               Resize;
3367                 public event EventHandler               RightToLeftChanged;
3368                 public event EventHandler               SizeChanged;
3369                 public event EventHandler               StyleChanged;
3370                 public event EventHandler               SystemColorsChanged;
3371                 public event EventHandler               TabIndexChanged;
3372                 public event EventHandler               TabStopChanged;
3373                 public event EventHandler               TextChanged;
3374                 public event EventHandler               Validated;
3375                 public event CancelEventHandler         Validating;
3376                 public event EventHandler               VisibleChanged;
3377                 #endregion      // Events
3378         }
3379 }