[bugfix: 664695] Calling Dispose on ToolStrip emit events. Doesn't on .NET
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Form.cs
index 508eb6c9c35fa14b668457790c08afb89b130ce9..ebf99667a65ad78c47f0c4b8a6b549800f0192cb 100644 (file)
@@ -39,12 +39,10 @@ namespace System.Windows.Forms {
        [DesignTimeVisible(false)]
        [Designer("System.Windows.Forms.Design.FormDocumentDesigner, " + Consts.AssemblySystem_Design, typeof(IRootDesigner))]
        [DefaultEvent("Load")]
-#if NET_2_0
        [ClassInterface (ClassInterfaceType.AutoDispatch)]
        [InitializationEvent ("Load")]
        [ComVisible (true)]
        [ToolboxItemFilter ("System.Windows.Forms.Control.TopLevel")]
-#endif
        [ToolboxItem(false)]
        public class Form : ContainerControl {
                #region Local Variables
@@ -89,23 +87,29 @@ namespace System.Windows.Forms {
                private bool                    is_loaded;
                internal int                    is_changing_visible_state;
                internal bool                   has_been_visible;
-               private bool                    shown_raised;  // The shown event is only raised once
+               private bool                    shown_raised;
+               private bool                    close_raised;
                private bool                    is_clientsize_set;
                internal bool                   suppress_closing_events;
-
-#if NET_2_0
-               private MenuStrip               main_menu_strip;
+               internal bool                   waiting_showwindow; // for XplatUIX11
+               private bool                    is_minimizing;
                private bool                    show_icon = true;
+               private MenuStrip               main_menu_strip;
                private bool                    right_to_left_layout;
                private Rectangle               restore_bounds;
                private bool                    autoscale_base_size_set;
-#endif
+               internal ArrayList disabled_by_showdialog = new ArrayList();
+               internal static ArrayList modal_dialogs = new ArrayList();
                #endregion      // Local Variables
 
                #region Private & Internal Methods
                static Form ()
                {
-                       default_icon = Locale.GetResource("mono.ico") as Icon;
+                       default_icon = ResourceImageLoader.GetIcon ("mono.ico");
+               }
+
+               internal bool IsLoaded {
+                       get { return is_loaded; }
                }
 
                internal bool IsActive {
@@ -143,46 +147,53 @@ namespace System.Windows.Forms {
                        CancelEventArgs cea = new CancelEventArgs (cancel);
                        this.OnClosing (cea);
                        
-#if NET_2_0
                        FormClosingEventArgs fcea = new FormClosingEventArgs (reason, cea.Cancel);
                        this.OnFormClosing (fcea);
                        return fcea.Cancel;
-#else
-                       return cea.Cancel;
-#endif
                }
 
                // Convenience method for fire BOTH OnClosed and OnFormClosed events
                private void FireClosedEvents (CloseReason reason)
                {
                        this.OnClosed (EventArgs.Empty);
-
-#if NET_2_0
                        this.OnFormClosed (new FormClosedEventArgs (reason));
-#endif
                }
                
-#if NET_2_0
                internal override Size GetPreferredSizeCore (Size proposedSize)
                {
                        Size retsize = Size.Empty;
                        
                        foreach (Control child in Controls) {
+                               Size child_preferred_size;
+                               if (child.AutoSize)
+                                       child_preferred_size = child.PreferredSize;
+                               else
+                                       child_preferred_size = child.ExplicitBounds.Size;
+                               int child_right = child.Bounds.X + child_preferred_size.Width;
+                               int child_bottom = child.Bounds.Y + child_preferred_size.Height;
+
                                if (child.Dock == DockStyle.Fill) {
-                                       if (child.Bounds.Right > retsize.Width)
-                                               retsize.Width = child.Bounds.Right;
+                                       if (child_right > retsize.Width)
+                                               retsize.Width = child_right;
                                } 
-                               else if (child.Dock != DockStyle.Top && child.Dock != DockStyle.Bottom && (child.Bounds.Right + child.Margin.Right) > retsize.Width)
-                                       retsize.Width = child.Bounds.Right + child.Margin.Right;
+                               else if (child.Dock != DockStyle.Top && child.Dock != DockStyle.Bottom && child_right > retsize.Width)
+                                       retsize.Width = child_right + child.Margin.Right;
 
                                if (child.Dock == DockStyle.Fill) {
-                                       if (child.Bounds.Bottom > retsize.Height)
-                                               retsize.Height = child.Bounds.Bottom;
+                                       if (child_bottom > retsize.Height)
+                                               retsize.Height = child_bottom;
                                }
-                               else if (child.Dock != DockStyle.Left && child.Dock != DockStyle.Right && (child.Bounds.Bottom + child.Margin.Bottom) > retsize.Height)
-                                       retsize.Height = child.Bounds.Bottom + child.Margin.Bottom;
+                               else if (child.Dock != DockStyle.Left && child.Dock != DockStyle.Right && child_bottom > retsize.Height)
+                                       retsize.Height = child_bottom + child.Margin.Bottom;
                        }
 
+                       if (retsize == Size.Empty) { // no child controls
+                               retsize.Height += this.Padding.Top;
+                               retsize.Width += this.Padding.Left;
+                       }
+                       retsize.Height += this.Padding.Bottom;
+                       retsize.Width += this.Padding.Right;
+
                        return SizeFromClientSize (retsize);
                }
 
@@ -211,7 +222,6 @@ namespace System.Windows.Forms {
                {
                        base.ScaleControl (factor, specified);
                }
-#endif
 
                internal void OnActivatedInternal ()
                {
@@ -307,7 +317,6 @@ namespace System.Windows.Forms {
                        bool recreate_necessary = false;
                        
                        if (new_parent == null) {
-                               recreate_necessary = window_manager is FormWindowManager;
                                window_manager = null;
                        } else if (new_parent is MdiClient) {
                                window_manager = new MdiWindowManager (this, (MdiClient) new_parent);
@@ -318,7 +327,7 @@ namespace System.Windows.Forms {
                        
                        if (recreate_necessary) {
                                if (IsHandleCreated) {
-                                       if (new_parent.IsHandleCreated) {
+                                       if (new_parent != null && new_parent.IsHandleCreated) {
                                                RecreateHandle ();
                                        } else {
                                                DestroyHandle ();
@@ -351,9 +360,7 @@ namespace System.Windows.Forms {
                #endregion      // Private & Internal Methods
 
                #region Public Classes
-#if NET_2_0
                [ComVisible (false)]
-#endif         
                public new class ControlCollection : Control.ControlCollection {
                        Form    form_owner;
 
@@ -408,11 +415,9 @@ namespace System.Windows.Forms {
                        default_maximized_bounds = Rectangle.Empty;
                        owned_forms = new Form.ControlCollection(this);
                        transparency_key = Color.Empty;
+                       CreateDockPadding ();
                        InternalClientSize = new Size (this.Width - (SystemInformation.FrameBorderSize.Width * 2), this.Height - (SystemInformation.FrameBorderSize.Height * 2) - SystemInformation.CaptionHeight);
-                       
-#if NET_2_0
                        restore_bounds = Bounds;
-#endif
                }
                #endregion      // Public Constructor & Destructor
 
@@ -490,14 +495,10 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [Obsolete ("This property has been deprecated in favor of AutoScaleMode.")]
-#else
-               [DefaultValue(true)]
-#endif
                [MWFCategory("Layout")]
                public bool AutoScale {
                        get {
@@ -505,34 +506,25 @@ namespace System.Windows.Forms {
                        }
 
                        set {
-#if NET_2_0
                                if (value)
                                        AutoScaleMode = AutoScaleMode.None;
-#endif
 
                                autoscale = value;
                        }
                }
 
-#if NET_2_0
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                [EditorBrowsable(EditorBrowsableState.Never)]
-#else
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
                [Localizable(true)]
                [Browsable(false)]
                public virtual Size AutoScaleBaseSize {
                        get {
                                return autoscale_base_size;
                        }
-
+                       [MonoTODO ("Setting this is probably unintentional and can cause Forms to be improperly sized.  See http://www.mono-project.com/FAQ:_Winforms#My_forms_are_sized_improperly for details.")]
                        set {
                                autoscale_base_size = value;
-                               
-#if NET_2_0
                                autoscale_base_size_set = true;
-#endif
                        }
                }
 
@@ -551,7 +543,6 @@ namespace System.Windows.Forms {
                        return this.AutoScroll != false;
                }
 
-#if NET_2_0
                [Browsable (true)]
                [EditorBrowsable (EditorBrowsableState.Always)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)]
@@ -592,7 +583,6 @@ namespace System.Windows.Forms {
                        get { return base.AutoValidate; }
                        set { base.AutoValidate = value; }
                }
-#endif
 
                public override Color BackColor {
                        get {
@@ -686,7 +676,8 @@ namespace System.Windows.Forms {
                                                        typeof (DialogResult));
 
                                dialog_result = value;
-                               closing = (dialog_result != DialogResult.None && is_modal);
+                               if (dialog_result != DialogResult.None && is_modal)
+                                       RaiseCloseEvents (false, false); // .Net doesn't send WM_CLOSE here.
                        }
                }
 
@@ -744,13 +735,13 @@ namespace System.Windows.Forms {
                        }
 
                        set {
-                               if (icon != value) {
-                                       icon = value;
-
-                                       if (IsHandleCreated) {
-                                               XplatUI.SetIcon(Handle, icon == null ? default_icon : icon);
-                                       }
-                               }
+                               if (value == null)
+                                       value = default_icon;
+                               if (icon == value)
+                                       return;
+                               icon = value;
+                               if (IsHandleCreated)
+                                       XplatUI.SetIcon (Handle, icon);
                        }
                }
 
@@ -817,7 +808,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if NET_2_0
                [DefaultValue (null)]
                [TypeConverter (typeof (ReferenceConverter))]
                public MenuStrip MainMenuStrip {
@@ -836,7 +826,6 @@ namespace System.Windows.Forms {
                        get { return base.Margin; }
                        set { base.Margin = value; }
                }
-#endif
 
                [DefaultValue(true)]
                [MWFCategory("Window Style")]
@@ -856,11 +845,7 @@ namespace System.Windows.Forms {
                [Localizable(true)]
                [RefreshProperties(RefreshProperties.Repaint)]
                [MWFCategory("Layout")]
-               public
-#if NET_2_0
-               override
-#endif
-               Size MaximumSize {
+               public override Size MaximumSize {
                        get {
                                return maximum_size;
                        }
@@ -868,6 +853,15 @@ namespace System.Windows.Forms {
                        set {
                                if (maximum_size != value) {
                                        maximum_size = value;
+
+                                       // If this is smaller than the min, adjust the min
+                                       if (!minimum_size.IsEmpty) {
+                                               if (maximum_size.Width <= minimum_size.Width)
+                                                       minimum_size.Width = maximum_size.Width;
+                                               if (maximum_size.Height <= minimum_size.Height)
+                                                       minimum_size.Height = maximum_size.Height;
+                                       }
+                                               
                                        OnMaximumSizeChanged(EventArgs.Empty);
                                        if (IsHandleCreated) {
                                                XplatUI.SetWindowMinMax(Handle, maximized_bounds, minimum_size, maximum_size);
@@ -939,10 +933,8 @@ namespace System.Windows.Forms {
                        get { return window_manager; }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [TypeConverter (typeof (ReferenceConverter))]
-#endif
                [DefaultValue(null)]
                [MWFCategory("Window Style")]
                public MainMenu Menu {
@@ -969,6 +961,9 @@ namespace System.Windows.Forms {
                                                }
                                        } else
                                                UpdateBounds ();
+
+                                       // UIA Framework Event: Menu Changed
+                                       OnUIAMenuChanged (EventArgs.Empty);
                                }
                        }
                }
@@ -1029,17 +1024,10 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if !NET_2_0
-               [DefaultValue("{Width=0, Height=0}")]
-#endif
                [Localizable(true)]
                [RefreshProperties(RefreshProperties.Repaint)]
                [MWFCategory("Layout")]
-               public
-#if NET_2_0
-               override
-#endif
-               Size MinimumSize {
+               public override Size MinimumSize {
                        get {
                                return minimum_size;
                        }
@@ -1048,6 +1036,14 @@ namespace System.Windows.Forms {
                                if (minimum_size != value) {
                                        minimum_size = value;
 
+                                       // If this is bigger than the max, adjust the max
+                                       if (!maximum_size.IsEmpty) {
+                                               if (minimum_size.Width >= maximum_size.Width)
+                                                       maximum_size.Width = minimum_size.Width;
+                                               if (minimum_size.Height >= maximum_size.Height)
+                                                       maximum_size.Height = minimum_size.Height;
+                                       }
+                                       
                                        if ((Size.Width < value.Width) || (Size.Height < value.Height)) {
                                                Size = new Size(Math.Max(Size.Width, value.Width), Math.Max(Size.Height, value.Height));
                                        }
@@ -1144,7 +1140,6 @@ namespace System.Windows.Forms {
                        }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
                public Rectangle RestoreBounds {
@@ -1172,8 +1167,7 @@ namespace System.Windows.Forms {
                                        }
                                }
                        }
-               }                       
-#endif
+               }
        
                [DefaultValue(true)]
                [MWFCategory("Window Style")]
@@ -1235,7 +1229,6 @@ namespace System.Windows.Forms {
                        set { base.TabIndex = value; }
                }
 
-#if NET_2_0
                [Browsable(false)]
                [DefaultValue (true)]
                [DispIdAttribute (-516)]
@@ -1244,7 +1237,6 @@ namespace System.Windows.Forms {
                        get { return base.TabStop; }
                        set { base.TabStop = value; }
                }
-#endif
 
                [Browsable(false)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
@@ -1273,6 +1265,9 @@ namespace System.Windows.Forms {
                                        topmost = value;
                                        if (IsHandleCreated)
                                                XplatUI.SetTopmost(window.Handle, value);
+
+                                       // UIA Framework: Raises internal event
+                                       OnUIATopMostChanged ();
                                }
                        }
                }
@@ -1328,6 +1323,10 @@ namespace System.Windows.Forms {
 
                                        XplatUI.SetWindowState(Handle, value);
                                }
+
+                               // UIA Framework: Raises internal event
+                               if (old_state != window_state) 
+                                       OnUIAWindowStateChanged ();
                        }
                }
 
@@ -1341,7 +1340,7 @@ namespace System.Windows.Forms {
                                if (Text != null)
                                        cp.Caption = Text.Replace (Environment.NewLine, string.Empty);
                                
-                               cp.ClassName = XplatUI.DefaultClassName;
+                               cp.ClassName = XplatUI.GetDefaultClassName (GetType ());
                                cp.ClassStyle = 0;
                                cp.Style = 0;
                                cp.ExStyle = 0;
@@ -1484,11 +1483,10 @@ namespace System.Windows.Forms {
                                        cp.Style |= (int)WindowStyles.WS_SYSMENU;
                                }
 
-#if NET_2_0
                                if (!this.show_icon) {
                                        cp.ExStyle |= (int)WindowExStyles.WS_EX_DLGMODALFRAME;
                                }
-#endif
+
                                cp.ExStyle |= (int)WindowExStyles.WS_EX_CONTROLPARENT;
 
                                if (HelpButton && !MaximizeBox && !MinimizeBox) {
@@ -1507,7 +1505,8 @@ namespace System.Windows.Forms {
                                //only do this when on Windows, since X behaves weirdly otherwise
                                //modal windows appear below their parent/owner/ancestor.
                                //(confirmed on several window managers, so it's not a wm bug).
-                               bool is_unix = ((int) Environment.OSVersion.Platform) == 128 || ((int) Environment.OSVersion.Platform == 4);
+                               int p = (int) Environment.OSVersion.Platform;
+                               bool is_unix = (p == 128) || (p == 4) || (p == 6);
                                if ((VisibleInternal && (is_changing_visible_state == 0 || is_unix)) || this.IsRecreating)
                                        cp.Style |= (int)WindowStyles.WS_VISIBLE;
 
@@ -1523,15 +1522,6 @@ namespace System.Windows.Forms {
                                        cp.WindowStyle &= ~WindowStyles.WS_DLGFRAME;
                                }
                                
-                               // Fake the window styles for mdi and parented forms
-                               if (cp.HasWindowManager && !cp.IsSet (WindowExStyles.WS_EX_TOOLWINDOW)) {
-                                       // Remove all styles but WS_VISIBLE.
-                                       cp.WindowStyle &= WindowStyles.WS_VISIBLE;
-                                       // Set styles that enables us to use the window manager.
-                                       cp.WindowStyle |= WindowStyles.WS_CHILD | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS;
-                                       cp.ExStyle = 0;
-                               }
-                               
                                return cp;
                        }
                }
@@ -1565,25 +1555,16 @@ namespace System.Windows.Forms {
                        }
                }
                
-#if !NET_2_0
-               internal
-#else
                [Browsable (false)]
                [MonoTODO ("Implemented for Win32, needs X11 implementation")]
-               protected 
-#endif
-               virtual bool ShowWithoutActivation {
+               protected virtual bool ShowWithoutActivation {
                        get { return false; }
                }
                #endregion      // Protected Instance Properties
 
                #region Public Static Methods
-#if NET_2_0
                [EditorBrowsable(EditorBrowsableState.Never)]
                [Obsolete ("This method has been deprecated.  Use AutoScaleDimensions instead")]
-#else
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
                public static SizeF GetAutoScaleSize (Font font)
                {
                        return XplatUI.GetAutoScaleSize(font);
@@ -1617,8 +1598,10 @@ namespace System.Windows.Forms {
                        if (IsDisposed)
                                return;
 
-                       if (!IsHandleCreated)
+                       if (!IsHandleCreated) {
+                               base.Dispose ();
                                return;
+                       }
  
                        if (Menu != null)
                                XplatUI.SetMenu (window.Handle, null);
@@ -1646,7 +1629,6 @@ namespace System.Windows.Forms {
                        DesktopLocation = new Point(x, y);
                }
 
-#if NET_2_0
                public void Show (IWin32Window owner)
                {
                        if (owner == null)
@@ -1665,7 +1647,6 @@ namespace System.Windows.Forms {
 
                        base.Show ();
                }
-#endif
 
                public DialogResult ShowDialog() {
                        return ShowDialog (null);
@@ -1721,6 +1702,10 @@ namespace System.Windows.Forms {
                        if (owner_to_be != null)
                                this.owner = owner_to_be;
                                
+                       // If our owner is topmost, we better be too, or else we'll show up under our owner
+                       if (this.owner != null && this.owner.TopMost)
+                               this.TopMost = true;
+                               
                        #if broken
                        // Can't do this, will screw us in the modal loop
                        form_parent_window.Parent = this.owner;
@@ -1732,6 +1717,16 @@ namespace System.Windows.Forms {
                                XplatUI.UngrabWindow(capture_window);
                        }
 
+                       foreach (Form form in Application.OpenForms)
+                       {
+                               if (form.Enabled == true)
+                               {
+                                       disabled_by_showdialog.Add(form);
+                                       form.Enabled = false;
+                               }
+                       }
+                       modal_dialogs.Add(this);
+
 #if not
                        // Commented out; we instead let the Visible=true inside the runloop create the control
                        // otherwise setting DialogResult inside any of the events that are triggered by the
@@ -1762,10 +1757,9 @@ namespace System.Windows.Forms {
                }
 
                public override string ToString() {
-                       return GetType().FullName.ToString() + ", Text: " + Text;
+                       return GetType().FullName + ", Text: " + Text;
                }
 
-#if NET_2_0
                [Browsable (true)]
                [EditorBrowsable (EditorBrowsableState.Always)]
                public override bool ValidateChildren ()
@@ -1779,35 +1773,6 @@ namespace System.Windows.Forms {
                {
                        return base.ValidateChildren (validationConstraints);
                }
-#else
-               private bool ValidateChildren ()
-               {
-                       return ValidateChildren (this);
-               }
-
-               private bool ValidateChildren (Control c)
-               {
-                       if (!ValidateControl (c))
-                               return false;
-
-                       foreach (Control child in c.Controls) {
-                               if (!ValidateChildren (child))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               private bool ValidateControl (Control c)
-               {
-                       CancelEventArgs e = new CancelEventArgs ();
-                       c.FireValidating (e);
-                       if (e.Cancel)
-                               return false;
-                       c.FireValidated ();
-                       return true;
-               }
-#endif
                #endregion      // Public Instance Methods
 
                #region Protected Instance Methods
@@ -1823,12 +1788,8 @@ namespace System.Windows.Forms {
                        base.AdjustFormScrollbars (displayScrollbars);
                }
 
-#if NET_2_0
                [EditorBrowsable(EditorBrowsableState.Never)]
                [Obsolete ("This method has been deprecated")] // XXX what to use instead?
-#else
-               [EditorBrowsable(EditorBrowsableState.Advanced)]
-#endif
                protected void ApplyAutoScaling()
                {
                        SizeF current_size_f = GetAutoScaleSize (Font);
@@ -1949,7 +1910,8 @@ namespace System.Windows.Forms {
                        }
 
                        XplatUI.SetWindowMinMax(window.Handle, maximized_bounds, minimum_size, maximum_size);
-                       if ((FormBorderStyle != FormBorderStyle.FixedDialog) && (icon != null)) {
+                       
+                       if (show_icon && (FormBorderStyle != FormBorderStyle.FixedDialog) && (icon != null)) {
                                XplatUI.SetIcon(window.Handle, icon);
                        }
 
@@ -2010,7 +1972,7 @@ namespace System.Windows.Forms {
                                ((Form)owned_forms[i]).Owner = null;
 
                        owned_forms.Clear ();
-                       
+                       Owner = null;
                        base.Dispose (disposing);
                        
                        Application.RemoveForm (this);
@@ -2064,12 +2026,10 @@ namespace System.Windows.Forms {
                protected override void OnFontChanged(EventArgs e) {
                        base.OnFontChanged (e);
                        
-#if NET_2_0
                        if (!autoscale_base_size_set) {
                                SizeF sizef = Form.GetAutoScaleSize (Font);
                                autoscale_base_size = new Size ((int)Math.Round (sizef.Width), (int)Math.Round (sizef.Height));
                        }
-#endif
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -2129,7 +2089,7 @@ namespace System.Windows.Forms {
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
-               protected virtual void OnMenuComplete(EventArgs e) {
+               protected internal virtual void OnMenuComplete(EventArgs e) {
                        EventHandler eh = (EventHandler)(Events [MenuCompleteEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2208,7 +2168,16 @@ namespace System.Windows.Forms {
 
                        // Give our menu a shot
                        if (ActiveMenu != null) {
-                               return ActiveMenu.ProcessCmdKey(ref msg, keyData);
+                               if (ActiveMenu.ProcessCmdKey (ref msg, keyData))
+                                       return true;
+                       }
+
+                       // Detect any active ContextMenu for a child control that
+                       // can't receive focus (which means: both input and preprocess)
+                       if (ActiveTracker != null && ActiveTracker.TopMenu is ContextMenu) {
+                               ContextMenu cmenu = ActiveTracker.TopMenu as ContextMenu;
+                               if (cmenu.SourceControl != this && cmenu.ProcessCmdKey (ref msg, keyData))
+                                       return true;
                        }
 
                        if (IsMdiChild) {
@@ -2252,7 +2221,10 @@ namespace System.Windows.Forms {
                                                return true;
                                        }
                                        else if (accept_button != null) {
-                                               accept_button.PerformClick();
+                                               // Set ActiveControl to force any Validation to take place.
+                                               ActiveControl = (accept_button as Control);
+                                               if (ActiveControl == accept_button) // else Validation failed
+                                                       accept_button.PerformClick();
                                                return true;
                                        }
                                } else if (keyData == Keys.Escape && cancel_button != null) {
@@ -2284,11 +2256,7 @@ namespace System.Windows.Forms {
                        return control_activated;
                }
 
-#if NET_2_0
                [EditorBrowsable (EditorBrowsableState.Never)]
-#else
-               [EditorBrowsable (EditorBrowsableState.Advanced)]
-#endif
                protected override void ScaleCore (float x, float y)
                {
                        base.ScaleCore (x, y);
@@ -2319,20 +2287,23 @@ namespace System.Windows.Forms {
                protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) {
                        Size min_size;
                        
-                       switch (FormBorderStyle) {
-                               case FormBorderStyle.None:
-                                       min_size = XplatUI.MinimumNoBorderWindowSize;
-                                       break;
-                               case FormBorderStyle.FixedToolWindow:
-                                       min_size = XplatUI.MinimumFixedToolWindowSize;
-                                       break;
-                               case FormBorderStyle.SizableToolWindow:
-                                       min_size = XplatUI.MinimumSizeableToolWindowSize;
-                                       break;
-                               default:
-                                       min_size = SystemInformation.MinimumWindowSize;
-                                       break;
-                       }
+                       if (WindowState == FormWindowState.Minimized)
+                               min_size = SystemInformation.MinimizedWindowSize;
+                       else
+                               switch (FormBorderStyle) {
+                                       case FormBorderStyle.None:
+                                               min_size = XplatUI.MinimumNoBorderWindowSize;
+                                               break;
+                                       case FormBorderStyle.FixedToolWindow:
+                                               min_size = XplatUI.MinimumFixedToolWindowSize;
+                                               break;
+                                       case FormBorderStyle.SizableToolWindow:
+                                               min_size = XplatUI.MinimumSizeableToolWindowSize;
+                                               break;
+                                       default:
+                                               min_size = SystemInformation.MinimumWindowSize;
+                                               break;
+                               }
                        
                        if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width)
                                width = Math.Max (width, min_size.Width);
@@ -2341,13 +2312,11 @@ namespace System.Windows.Forms {
                                
                        base.SetBoundsCore (x, y, width, height, specified);
 
-#if NET_2_0
                        int restore_x = (specified & BoundsSpecified.X) == BoundsSpecified.X ? x : restore_bounds.X;
                        int restore_y = (specified & BoundsSpecified.Y) == BoundsSpecified.Y ? y : restore_bounds.Y;
                        int restore_w = (specified & BoundsSpecified.Width) == BoundsSpecified.Width ? width : restore_bounds.Width;
                        int restore_h = (specified & BoundsSpecified.Height) == BoundsSpecified.Height ? height : restore_bounds.Height;
                        restore_bounds = new Rectangle (restore_x, restore_y, restore_w, restore_h);
-#endif                 
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -2378,6 +2347,9 @@ namespace System.Windows.Forms {
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void SetVisibleCore(bool value)
                {
+                       if (value)
+                               close_raised = false;
+
                        if (IsMdiChild && !MdiParent.Visible) {
                                if (value != Visible) {
                                        MdiWindowManager wm = (MdiWindowManager) window_manager;
@@ -2418,11 +2390,18 @@ namespace System.Windows.Forms {
                        
                        // Shown event is only called once, the first time the form is made visible
                        if (value && !shown_raised) {
-#if NET_2_0
                                this.OnShown (EventArgs.Empty);
-#endif
                                shown_raised = true;
                        }
+                       
+                       if (value && !IsMdiChild) {
+                               if (ActiveControl == null)
+                                       SelectNextControl (null, true, true, true, false);
+                               if (ActiveControl != null)
+                                       SendControlFocus (ActiveControl);
+                               else
+                                       this.Focus ();
+                       }
                }
 
                protected override void UpdateDefaultButton() {
@@ -2455,12 +2434,10 @@ namespace System.Windows.Forms {
                                return;
                        }
 
-#if NET_2_0
                        case Msg.WM_SYSCOMMAND: {
                                WmSysCommand (ref m);
                                break;
                        }
-#endif
 
                        case Msg.WM_ACTIVATE: {
                                WmActivate (ref m);
@@ -2518,7 +2495,6 @@ namespace System.Windows.Forms {
                                break;
                        }
                        
-#if NET_2_0
                        case Msg.WM_ENTERSIZEMOVE: {
                                OnResizeBegin (EventArgs.Empty);
                                break;
@@ -2528,7 +2504,6 @@ namespace System.Windows.Forms {
                                OnResizeEnd (EventArgs.Empty);
                                break;
                        }
-#endif
 
                        default: {
                                base.WndProc (ref m);
@@ -2554,7 +2529,7 @@ namespace System.Windows.Forms {
                                Hide ();
                        }
                        
-                       if (last_check && closed) {
+                       if (close_raised || (last_check && closed)) {
                                return false;
                        }
                        
@@ -2568,6 +2543,8 @@ namespace System.Windows.Forms {
                                        FireClosedEvents (CloseReason.UserClosing);
                                }
                                closing = true;
+                               close_raised = true;
+                               shown_raised = false;
                        } else {
                                DialogResult = DialogResult.None;
                                closing = false;
@@ -2578,6 +2555,9 @@ namespace System.Windows.Forms {
 
                private void WmClose (ref Message m)
                {
+                       if (this.Enabled == false)
+                               return; // prevent closing a disabled form.
+
                        Form act = Form.ActiveForm;
                        // Don't close this form if there's another modal form visible.
                        if (act != null && act != this && act.Modal == true) {
@@ -2634,16 +2614,20 @@ namespace System.Windows.Forms {
                        // 
                        if (window_state != FormWindowState.Minimized && WindowState != FormWindowState.Minimized)
                                base.WndProc (ref m);
-                       else // minimized or restored
-                               OnSizeChanged (EventArgs.Empty);
+                       else { // minimized or restored
+                               if (!is_minimizing) {
+                                       // Avoid recursive calls here as code in OnSizeChanged might 
+                                       // cause a WM_WINDOWPOSCHANGED to be sent.
+                                       is_minimizing = true;
+                                       OnSizeChanged (EventArgs.Empty);
+                                       is_minimizing = false;
+                               }
+                       }
 
-#if NET_2_0
                        if (WindowState == FormWindowState.Normal)
                                restore_bounds = Bounds;
-#endif
                }
 
-#if NET_2_0
                private void WmSysCommand (ref Message m)
                {
                        // Let *Strips know the app's title bar was clicked
@@ -2652,9 +2636,15 @@ namespace System.Windows.Forms {
 
                        base.WndProc (ref m);
                }
-#endif 
+
                private void WmActivate (ref Message m)
                {
+                       if (!this.Enabled && modal_dialogs.Count > 0)
+                       {
+                               (modal_dialogs[modal_dialogs.Count -1] as Form).Activate ();
+                               return; // prevent Activating of disabled form.
+                       }
+
                        if (m.WParam != (IntPtr)WindowActiveFlags.WA_INACTIVE) {
                                if (is_loaded) {
                                        SelectActiveControl ();
@@ -2665,10 +2655,8 @@ namespace System.Windows.Forms {
 
                                IsActive = true;
                        } else {
-#if NET_2_0
                                if (XplatUI.IsEnabled (Handle) && XplatUI.GetParent (m.LParam) != Handle)
                                        ToolStripManager.FireAppFocusChanged (this);
-#endif
                                IsActive = false;
                        }
                }
@@ -2765,11 +2753,8 @@ namespace System.Windows.Forms {
                private void WmNcPaint (ref Message m)
                {
                        if (ActiveMenu != null) {
-                               PaintEventArgs pe;
-                               Point pnt;
-
-                               pe = XplatUI.PaintEventStart (ref m, Handle, false);
-                               pnt = XplatUI.GetMenuOrigin (window.Handle);
+                               PaintEventArgs pe = XplatUI.PaintEventStart (ref m, Handle, false);
+                               Point pnt = XplatUI.GetMenuOrigin (window.Handle);
 
                                // The entire menu has to be in the clip rectangle because the 
                                // control buttons are right-aligned and otherwise they would
@@ -2781,9 +2766,8 @@ namespace System.Windows.Forms {
 
                                ActiveMenu.Draw (pe, new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0));
 
-                               if (ActiveMaximizedMdiChild != null) {
+                               if (ActiveMaximizedMdiChild != null)
                                        ActiveMaximizedMdiChild.DrawMaximizedButtons (ActiveMenu, pe);
-                               }
 
                                XplatUI.PaintEventEnd (ref m, Handle, false);
                        }
@@ -2891,8 +2875,18 @@ namespace System.Windows.Forms {
                        }
 
                        if (!IsDisposed) {
-                               OnLoad (e);
+                               OnSizeInitializedOrChanged ();
                                
+                               // We do this here because when we load the MainForm,
+                               // it happens before the exception catcher in NativeWindow,
+                               // so the user can error in handling Load and we wouldn't catch it.
+                               try {
+                                       OnLoad (e);
+                               }
+                               catch (Exception ex) {
+                                       Application.OnThreadException (ex);
+                               }
+
                                if (!IsDisposed)
                                        is_visible = true;
                        }
@@ -2936,19 +2930,15 @@ namespace System.Windows.Forms {
                        remove { Events.RemoveHandler (ActivatedEvent, value); }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
                public event EventHandler Closed {
                        add { Events.AddHandler (ClosedEvent, value); }
                        remove { Events.RemoveHandler (ClosedEvent, value); }
                }
 
-#if NET_2_0
                [Browsable (false)]
                [EditorBrowsable (EditorBrowsableState.Never)]
-#endif
                public event CancelEventHandler Closing {
                        add { Events.AddHandler (ClosingEvent, value); }
                        remove { Events.RemoveHandler (ClosingEvent, value); }
@@ -2989,17 +2979,13 @@ namespace System.Windows.Forms {
                        remove { Events.RemoveHandler (MdiChildActivateEvent, value); }
                }
 
-#if NET_2_0
                [Browsable (false)]
-#endif
                public event EventHandler MenuComplete {
                        add { Events.AddHandler (MenuCompleteEvent, value); }
                        remove { Events.RemoveHandler (MenuCompleteEvent, value); }
                }
 
-#if NET_2_0
                [Browsable (false)]
-#endif
                public event EventHandler MenuStart {
                        add { Events.AddHandler (MenuStartEvent, value); }
                        remove { Events.RemoveHandler (MenuStartEvent, value); }
@@ -3018,7 +3004,6 @@ namespace System.Windows.Forms {
                        remove { base.TabIndexChanged -= value; }
                }
 
-#if NET_2_0
                [SettingsBindable (true)]
                public override string Text {
                        get {
@@ -3142,6 +3127,14 @@ namespace System.Windows.Forms {
                        FormClosedEventHandler eh = (FormClosedEventHandler)(Events[FormClosedEvent]);
                        if (eh != null)
                                eh (this, e);
+
+                       foreach (Form form in disabled_by_showdialog)
+                       {
+                               form.Enabled = true;
+                       }
+                       disabled_by_showdialog.Clear();
+                       if (modal_dialogs.Contains(this))
+                               modal_dialogs.Remove(this);
                }
                
                // Consider calling FireClosingEvents instead of calling this directly.
@@ -3153,7 +3146,7 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 
-               [MonoTODO ("Not hooked up to event")]
+               [MonoTODO ("Will never be called")]
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected virtual void OnHelpButtonClicked (CancelEventArgs e)
                {
@@ -3174,7 +3167,8 @@ namespace System.Windows.Forms {
                                }
                                if (new_size == Size)
                                        return;
-                               SetBounds (bounds.X, bounds.Y, new_size.Width, new_size.Height, BoundsSpecified.None);
+
+                               SetBoundsInternal (bounds.X, bounds.Y, new_size.Width, new_size.Height, BoundsSpecified.None);
                        }
                }
 
@@ -3209,7 +3203,48 @@ namespace System.Windows.Forms {
                        if (eh != null)
                                eh (this, e);
                }
-#endif
+
+               #region UIA Framework Events
+               static object UIAMenuChangedEvent = new object ();
+               static object UIATopMostChangedEvent = new object ();
+               static object UIAWindowStateChangedEvent = new object ();
+
+               internal event EventHandler UIAMenuChanged {
+                       add { Events.AddHandler (UIAMenuChangedEvent, value); }
+                       remove { Events.RemoveHandler (UIAMenuChangedEvent, value); }
+               }
+
+               internal event EventHandler UIATopMostChanged {
+                       add { Events.AddHandler (UIATopMostChangedEvent, value); }
+                       remove { Events.RemoveHandler (UIATopMostChangedEvent, value); }
+               }
+
+               internal event EventHandler UIAWindowStateChanged {
+                       add { Events.AddHandler (UIAWindowStateChangedEvent, value); }
+                       remove { Events.RemoveHandler (UIAWindowStateChangedEvent, value); }
+               }
+
+               internal void OnUIAMenuChanged (EventArgs e)
+               {
+                       EventHandler eh = (EventHandler) Events [UIAMenuChangedEvent];
+                       if (eh != null)
+                               eh (this, e);
+               }
+
+               internal void OnUIATopMostChanged ()
+               {
+                       EventHandler eh = (EventHandler) Events [UIATopMostChangedEvent];
+                       if (eh != null)
+                               eh (this, EventArgs.Empty);
+               }
+
+               internal void OnUIAWindowStateChanged ()
+               {
+                       EventHandler eh = (EventHandler) Events [UIAWindowStateChangedEvent];
+                       if (eh != null)
+                               eh (this, EventArgs.Empty);
+               }
+               #endregion      // UIA Framework Events
                #endregion      // Events
        }
 }