2007-04-30 Jonathan Pobst <monkey@jpobst.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Form.cs
index 7e358ea953d3956511a35b66069174f3a2fafef1..88414bfb40435e160de931dd5b6bf98341ddf3d1 100644 (file)
@@ -49,6 +49,7 @@ namespace System.Windows.Forms {
                #region Local Variables
                internal bool                   closing;
                FormBorderStyle                 form_border_style;
+               private bool                    is_active;
                private bool                    autoscale;
                private Size                    clientsize_set;
                private Size                    autoscale_base_size;
@@ -87,11 +88,11 @@ namespace System.Windows.Forms {
                private bool                    is_loaded;
                internal bool                   is_changing_visible_state;
                internal bool                   has_been_visible;
+               private bool                    shown_raised;  // The shown event is only raised once
 
 #if NET_2_0
                private MenuStrip               main_menu_strip;
                private bool                    show_icon = true;
-               private bool                    shown_raised;  // The shown event is only raised once
 #endif
                #endregion      // Local Variables
 
@@ -101,6 +102,25 @@ namespace System.Windows.Forms {
                        default_icon = Locale.GetResource("mono.ico") as Icon;
                }
 
+               internal bool IsActive {
+                       get {
+                               return is_active;
+                       }
+                       set {
+                               if (is_active == value || IsRecreating) {
+                                       return;
+                               }
+                               
+                               is_active = value;
+                               if (is_active) {
+                                       Application.AddForm (this);
+                                       OnActivated (EventArgs.Empty);
+                               } else {
+                                       OnDeactivate (EventArgs.Empty);
+                               }
+                       }
+               }
+
                // warning: this is only hooked up when an mdi container is created.
                private void ControlAddedHandler (object sender, ControlEventArgs e)
                {
@@ -125,6 +145,25 @@ namespace System.Windows.Forms {
                        return cea.Cancel;
 #endif
                }
+               internal void OnActivatedInternal ()
+               {
+                       OnActivated (EventArgs.Empty);
+               }
+
+               internal override void UpdateWindowText ()
+               {
+                       if (!IsHandleCreated) {
+                               return;
+                       }
+                       
+                       if (shown_raised) {
+                               /* we need to call .SetWindowStyle here instead of just .Text
+                                  because the presence/absence of Text (== "" or not) can cause
+                                  other window style things to appear/disappear */
+                               XplatUI.SetWindowStyle (window.Handle, CreateParams);
+                       }
+                       base.UpdateWindowText ();
+               }
                
                private void SelectActiveControl ()
                {
@@ -151,7 +190,7 @@ namespace System.Windows.Forms {
                        }
                }
                
-               private void UpdateSizeGripVisible ()
+               private new void UpdateSizeGripVisible ()
                {
                        // Following link explains when to show size grip:
                        // http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=138687&SiteID=1
@@ -177,16 +216,50 @@ namespace System.Windows.Forms {
                                        size_grip.Visible = false;
                        } else {
                                if (size_grip == null) {
-                                       size_grip = new SizeGrip ();
-                                       this.Controls.AddImplicit (size_grip);
+                                       size_grip = new SizeGrip (this);
+                                       size_grip.Virtual = true;
+                                       size_grip.FillBackground = false;
                                }
-                               size_grip.Width = SystemInformation.VerticalScrollBarWidth;
-                               size_grip.Height = SystemInformation.HorizontalScrollBarHeight;
-                               size_grip.Location = new Point (ClientSize.Width - size_grip.Width, ClientSize.Height - size_grip.Height);
                                size_grip.Visible = true;
                        }
                }
                
+               internal void ChangingParent (Control new_parent)
+               {
+                       if (IsMdiChild) {
+                               return;
+                       }
+                       
+                       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);
+                       } else {
+                               window_manager = new FormWindowManager (this);
+                               recreate_necessary = true;
+                       }
+                       
+                       if (recreate_necessary && IsHandleCreated) {
+                               RecreateHandle ();
+                       }
+               
+                       if (window_manager != null) {
+                               window_manager.UpdateWindowState (window_state, window_state, true);
+                       }
+               }
+
+               internal override bool FocusInternal (bool skip_check)
+               {
+                       if (IsMdiChild) {
+                               // MS always creates handles when Focus () is called for mdi clients.
+                               if (!IsHandleCreated)
+                                       CreateHandle ();
+                       } 
+                       return base.FocusInternal (skip_check);
+               }
                #endregion      // Private & Internal Methods
 
                #region Public Classes
@@ -247,10 +320,7 @@ namespace System.Windows.Forms {
                        default_maximized_bounds = Rectangle.Empty;
                        owned_forms = new Form.ControlCollection(this);
                        transparency_key = Color.Empty;
-
-                       // FIXME: this should disappear just as soon as the handle creation is done in the right place (here is too soon()
-                       UpdateBounds();
-
+                       InternalClientSize = new Size (this.Width - (SystemInformation.FrameBorderSize.Width * 2), this.Height - (SystemInformation.FrameBorderSize.Height * 2) - SystemInformation.CaptionHeight);
                }
                #endregion      // Public Constructor & Destructor
 
@@ -480,8 +550,13 @@ namespace System.Windows.Forms {
                                        window_manager.UpdateBorderStyle (value);
                                }
 
+                               Size current_client_size = ClientSize;
                                UpdateStyles();
-                               this.Size = SizeFromClientSize (this.ClientSize);
+                               
+                               if (this.IsHandleCreated) {
+                                       this.Size = InternalSizeFromClientSize (current_client_size);
+                                       XplatUI.InvalidateNC (this.Handle);
+                               }
                        }
                }
 
@@ -607,9 +682,6 @@ namespace System.Windows.Forms {
                        set {
                                if (maximize_box != value) {
                                        maximize_box = value;
-                                       if (IsHandleCreated) {
-                                               RecreateHandle();
-                                       }
                                        UpdateStyles();
                                }
                        }
@@ -668,13 +740,15 @@ namespace System.Windows.Forms {
 
                                if (value != null) {
                                        mdi_parent = value;
-                                       window_manager = new MdiWindowManager (this,
-                                                       mdi_parent.MdiContainer);
+                                       if (window_manager == null) {
+                                               window_manager = new MdiWindowManager (this, mdi_parent.MdiContainer);
+                                       }
+                                       
                                        mdi_parent.MdiContainer.Controls.Add (this);
                                        mdi_parent.MdiContainer.Controls.SetChildIndex (this, 0);
-
-                                       RecreateHandle ();
-
+                                       
+                                       if (IsHandleCreated)
+                                               RecreateHandle ();
                                } else if (mdi_parent != null) {
                                        mdi_parent = null;
 
@@ -682,8 +756,10 @@ namespace System.Windows.Forms {
                                        window_manager = null;
                                        FormBorderStyle = form_border_style;
 
-                                       RecreateHandle ();
+                                       if (IsHandleCreated)
+                                               RecreateHandle ();
                                }
+                               is_toplevel = mdi_parent == null;
                        }
                }
 
@@ -791,9 +867,6 @@ namespace System.Windows.Forms {
                        set {
                                if (minimize_box != value) {
                                        minimize_box = value;
-                                       if (IsHandleCreated) {
-                                               RecreateHandle();
-                                       }
                                        UpdateStyles();
                                }
                        }
@@ -899,9 +972,9 @@ namespace System.Windows.Forms {
                                                owner.AddOwnedForm(this);
                                        if (IsHandleCreated) {
                                                if (owner != null && owner.IsHandleCreated) {
-                                                       XplatUI.SetTopmost(this.window.Handle, owner.window.Handle, true);
+                                                       XplatUI.SetOwner(this.window.Handle, owner.window.Handle);
                                                } else {
-                                                       XplatUI.SetTopmost(this.window.Handle, IntPtr.Zero, false);
+                                                       XplatUI.SetOwner(this.window.Handle, IntPtr.Zero);
                                                }
                                        }
                                }
@@ -917,8 +990,10 @@ namespace System.Windows.Forms {
                                        this.show_icon = value;
                                        UpdateStyles ();
                                        
-                                       XplatUI.SetIcon (this.Handle, value == true ? this.Icon : null);
-                                       XplatUI.InvalidateNC (this.Handle);
+                                       if (IsHandleCreated) {
+                                               XplatUI.SetIcon (this.Handle, value == true ? this.Icon : null);
+                                               XplatUI.InvalidateNC (this.Handle);
+                                       }
                                }
                        }
                }                       
@@ -971,32 +1046,7 @@ namespace System.Windows.Forms {
                        }
 
                        set {
-                               if (start_position == FormStartPosition.WindowsDefaultLocation) {               // Only do this if it's not set yet
-                                       start_position = value;
-                                       if (IsHandleCreated) {
-                                               switch(start_position) {
-                                                       case FormStartPosition.CenterParent: {
-                                                               CenterToParent();
-                                                               break;
-                                                       }
-
-                                                       case FormStartPosition.CenterScreen: {
-                                                               CenterToScreen();
-                                                               break;
-                                                       }
-
-                                                       case FormStartPosition.Manual: {
-                                                               Left = CreateParams.X;
-                                                               Top = CreateParams.Y;
-                                                               break;
-                                                       }
-
-                                                       default: {
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                               }
+                               start_position = value;
                        }
                }
 
@@ -1046,7 +1096,7 @@ namespace System.Windows.Forms {
                                if (topmost != value) {
                                        topmost = value;
                                        if (IsHandleCreated)
-                                               XplatUI.SetTopmost(window.Handle, owner != null ? owner.window.Handle : IntPtr.Zero, value);
+                                               XplatUI.SetTopmost(window.Handle, value);
                                }
                        }
                }
@@ -1062,7 +1112,7 @@ namespace System.Windows.Forms {
 
                                AllowTransparency = true;
                                UpdateStyles();
-                               if ((XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0)
+                               if (IsHandleCreated && (XplatUI.SupportsTransparency () & TransparencySupport.Set) != 0)
                                        XplatUI.SetWindowTransparency(Handle, Opacity, transparency_key);
                        }
                }
@@ -1071,7 +1121,8 @@ namespace System.Windows.Forms {
                [MWFCategory("Layout")]
                public FormWindowState WindowState {
                        get {
-                               if (IsHandleCreated) {
+                               // Don't actually rely on the WM until we've been shown
+                               if (IsHandleCreated && shown_raised) {
 
                                        if (window_manager != null)
                                                return window_manager.GetWindowState ();
@@ -1087,7 +1138,7 @@ namespace System.Windows.Forms {
                        set {
                                FormWindowState old_state = window_state;
                                window_state = value;
-                               if (IsHandleCreated) {
+                               if (IsHandleCreated && shown_raised) {
 
                                        if (window_manager != null) {
                                                window_manager.SetWindowState (old_state, value);
@@ -1114,18 +1165,47 @@ namespace System.Windows.Forms {
                                cp.Param = 0;
                                cp.Parent = IntPtr.Zero;
                                cp.menu = ActiveMenu;
+                               cp.control = this;
 
-                               if (start_position == FormStartPosition.WindowsDefaultLocation && !IsMdiChild) {
-                                       cp.X = unchecked((int)0x80000000);
-                                       cp.Y = unchecked((int)0x80000000);
-                               } else {
+                               if (((Parent != null || !TopLevel) && !IsMdiChild)) {
+                                       // Parented forms and non-toplevel forms always gets the specified location, no matter what
                                        cp.X = Left;
                                        cp.Y = Top;
+                               } else {
+                                       switch (start_position) {
+                                       case FormStartPosition.Manual:
+                                               cp.X = Left;
+                                               cp.Y = Top;
+                                               break;
+                                       case FormStartPosition.CenterScreen:
+                                               if (IsMdiChild) {
+                                                       cp.X = Math.Max ((MdiParent.mdi_container.ClientSize.Width - Width) / 2, 0);
+                                                       cp.Y = Math.Max ((MdiParent.mdi_container.ClientSize.Height - Height) / 2, 0);
+                                               } else {
+                                                       cp.X = Math.Max ((Screen.PrimaryScreen.WorkingArea.Width - Width) / 2, 0);
+                                                       cp.Y = Math.Max ((Screen.PrimaryScreen.WorkingArea.Height - Height) / 2, 0);
+                                               }
+                                               break;
+                                       case FormStartPosition.CenterParent:
+                                       case FormStartPosition.WindowsDefaultBounds:
+                                       case FormStartPosition.WindowsDefaultLocation:
+                                               cp.X = int.MinValue;
+                                               cp.Y = int.MinValue;
+                                               break;
+                                       }
                                }
                                cp.Width = Width;
                                cp.Height = Height;
 
-                               cp.Style = (int)(WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_CLIPSIBLINGS);
+                               cp.Style = (int)(WindowStyles.WS_CLIPCHILDREN);
+                               if (!Modal) {
+                                       cp.WindowStyle |= WindowStyles.WS_CLIPSIBLINGS;
+                               }
+
+                               if (Parent != null) {
+                                       cp.Parent = Parent.Handle;
+                                       cp.Style |= (int) WindowStyles.WS_CHILD;
+                               }
 
                                if (IsMdiChild) {
                                        cp.Style |= (int)(WindowStyles.WS_CHILD | WindowStyles.WS_CAPTION);
@@ -1230,8 +1310,8 @@ namespace System.Windows.Forms {
                                if (HelpButton && !MaximizeBox && !MinimizeBox) {
                                        cp.ExStyle |= (int)WindowExStyles.WS_EX_CONTEXTHELP;
                                }
-                               
-                               if (Visible)
+
+                               if (VisibleInternal || this.IsRecreating)
                                        cp.Style |= (int)WindowStyles.WS_VISIBLE;
 
                                if (opacity < 1.0 || TransparencyKey != Color.Empty) {
@@ -1242,6 +1322,19 @@ namespace System.Windows.Forms {
                                        cp.Style |= (int)(WindowStyles.WS_DISABLED);
                                }
 
+                               if (!ControlBox && Text == string.Empty) {
+                                       cp.WindowStyle &= ~WindowStyles.WS_DLGFRAME;
+                               }
+                               
+                               // Fake the window styles for mdi, toolwindows and parented forms
+                               if (cp.HasWindowManager) {
+                                       // 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;
                        }
                }
@@ -1274,6 +1367,16 @@ namespace System.Windows.Forms {
                                }
                        }
                }
+               
+#if !NET_2_0
+               internal
+#else
+               [MonoTODO ("Implemented for Win32, needs X11 implementation")]
+               protected 
+#endif
+               virtual bool ShowWithoutActivation {
+                       get { return false; }
+               }
                #endregion      // Protected Instance Properties
 
                #region Public Static Methods
@@ -1339,7 +1442,7 @@ namespace System.Windows.Forms {
                        if (IsDisposed)
                                return;
 
-                       if (!is_visible)
+                       if (!IsHandleCreated)
                                return;
 
                        XplatUI.SendMessage(this.Handle, Msg.WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
@@ -1374,12 +1477,18 @@ namespace System.Windows.Forms {
                        if (owner == this)
                                throw new InvalidOperationException ("The 'owner' cannot be the form being shown.");
 
+                       if (TopLevelControl != this) {
+                               throw new InvalidOperationException ("Forms that are not top level"
+                                       + " forms cannot be displayed as a modal dialog. Remove the"
+                                       + " form from any parent form before calling Show.");
+                       }
+
                        base.Show ();
                }
 #endif
 
                public DialogResult ShowDialog() {
-                       return ShowDialog(this.owner);
+                       return ShowDialog (null);
                }
 
                public DialogResult ShowDialog(IWin32Window ownerWin32) {
@@ -1387,34 +1496,51 @@ namespace System.Windows.Forms {
                        bool            confined;
                        IntPtr          capture_window;
 
-                       owner = null;
+                       Form owner_to_be = null;
+
+                       if ((ownerWin32 == null) && (Application.MWFThread.Current.Context != null)) {
+                               IntPtr active = XplatUI.GetActive ();
+                               if (active != IntPtr.Zero) {
+                                       ownerWin32 = Control.FromHandle (active) as Form;
+                               }
+                       }
 
                        if (ownerWin32 != null) {
                                Control c = Control.FromHandle (ownerWin32.Handle);
                                if (c != null)
-                                       owner = c.TopLevelControl as Form;
+                                       owner_to_be = c.TopLevelControl as Form;
                        }
 
-                       if (owner == this) {
-                               throw new InvalidOperationException("The 'ownerWin32' cannot be the form being shown.");
+                       if (owner_to_be == this) {
+                               throw new ArgumentException ("Forms cannot own themselves or their owners.", "owner");
                        }
 
                        if (is_modal) {
-                               throw new InvalidOperationException("The form is already displayed as a modal dialog.");
+                               throw new InvalidOperationException ("The form is already displayed as a modal dialog.");
                        }
 
                        if (Visible) {
-                               throw new InvalidOperationException("Already visible forms cannot be displayed as a modal dialog. Set the Visible property to 'false' prior to calling Form.ShowDialog.");
+                               throw new InvalidOperationException ("Forms that are already "
+                                       + " visible cannot be displayed as a modal dialog. Set the"
+                                       + " form's visible property to false before calling"
+                                       + " ShowDialog.");
                        }
 
                        if (!Enabled) {
-                               throw new InvalidOperationException("Cannot display a disabled form as modal dialog.");
+                               throw new InvalidOperationException ("Forms that are not enabled"
+                                       + " cannot be displayed as a modal dialog. Set the form's"
+                                       + " enabled property to true before calling ShowDialog.");
                        }
 
                        if (TopLevelControl != this) {
-                               throw new InvalidOperationException("Can only display TopLevel forms as modal dialog.");
+                               throw new InvalidOperationException ("Forms that are not top level"
+                                       + " forms cannot be displayed as a modal dialog. Remove the"
+                                       + " form from any parent form before calling ShowDialog.");
                        }
 
+                       if (owner_to_be != null)
+                               owner = owner_to_be;
+                               
                        #if broken
                        // Can't do this, will screw us in the modal loop
                        form_parent_window.Parent = this.owner;
@@ -1516,6 +1642,12 @@ namespace System.Windows.Forms {
                        int     w;
                        int     h;
 
+                       // MS creates the handle here.
+                       if (TopLevel) {
+                               if (!IsHandleCreated)
+                                       CreateHandle ();
+                       }
+                       
                        if (Width > 0) {
                                w = Width;
                        } else {
@@ -1545,6 +1677,12 @@ namespace System.Windows.Forms {
                        int     w;
                        int     h;
 
+                       // MS creates the handle here.
+                       if (TopLevel) {
+                               if (!IsHandleCreated)
+                                       CreateHandle ();
+                       }
+                       
                        if (Width > 0) {
                                w = Width;
                        } else {
@@ -1570,7 +1708,9 @@ namespace System.Windows.Forms {
                protected override void CreateHandle() {
                        base.CreateHandle ();
 
-                       Application.AddForm (this);
+                       if (!IsHandleCreated) {
+                               return;
+                       }
                        
                        UpdateBounds();
 
@@ -1586,17 +1726,21 @@ namespace System.Windows.Forms {
                        }
 
                        if ((owner != null) && (owner.IsHandleCreated)) {
-                               XplatUI.SetTopmost(window.Handle, owner.window.Handle, true);
+                               XplatUI.SetOwner(window.Handle, owner.window.Handle);
+                       }
+
+                       if (topmost) {
+                               XplatUI.SetTopmost(window.Handle, topmost);
                        }
 
                        for (int i = 0; i < owned_forms.Count; i++) {
                                if (owned_forms[i].IsHandleCreated)
-                                       XplatUI.SetTopmost(owned_forms[i].window.Handle, window.Handle, true);
+                                       XplatUI.SetOwner(owned_forms[i].window.Handle, window.Handle);
                        }
                        
                        if (window_manager != null) {
                                if (window_state != FormWindowState.Normal) {
-                                       window_manager.SetWindowState (FormWindowState.Normal, window_state);
+                                       window_manager.SetWindowState ((FormWindowState) int.MaxValue, window_state);
                                }
                                XplatUI.RequestNCRecalc (window.Handle);
                        }
@@ -1655,10 +1799,6 @@ namespace System.Windows.Forms {
                        
                        // Send initial location
                        OnLocationChanged(EventArgs.Empty);
-
-                       if (IsMdiContainer) {
-                               mdi_container.LayoutMdi (MdiLayout.Cascade);
-                       }
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -1681,6 +1821,7 @@ namespace System.Windows.Forms {
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void OnHandleDestroyed(EventArgs e) {
+                       Application.RemoveForm (this);
                        base.OnHandleDestroyed (e);
                }
 
@@ -1699,7 +1840,9 @@ namespace System.Windows.Forms {
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
-               protected virtual void OnLoad(EventArgs e) {
+               protected virtual void OnLoad (EventArgs e){
+                       Application.AddForm (this);
+
                        if (AutoScale){
                                ApplyAutoScaling ();
                                AutoScale = false;
@@ -1771,16 +1914,16 @@ namespace System.Windows.Forms {
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void OnPaint (PaintEventArgs pevent) {
                        base.OnPaint (pevent);
+
+                       if (size_grip != null) {
+                               size_grip.HandlePaint (this, pevent);
+                       }
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
                protected override void OnResize(EventArgs e) {
                        base.OnResize(e);
 
-                       
-                       if (this.size_grip != null && this.size_grip.Visible) {
-                               this.size_grip.Location = new Point (ClientSize.Width - size_grip.Width, ClientSize.Height - size_grip.Height);
-                       }
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
@@ -1919,6 +2062,12 @@ namespace System.Windows.Forms {
                protected override void Select(bool directed, bool forward) {
                        Form    parent;
 
+
+                       // MS causes the handle to be created here.
+                       if (!IsHandleCreated)
+                               if (!IsHandleCreated)
+                                       CreateHandle ();
+                       
                        if (directed) {
                                base.SelectNextControl(null, forward, true, true, true);
                        }
@@ -1956,25 +2105,59 @@ namespace System.Windows.Forms {
 
                        clientsize_set = new Size(x, y);
 
-                       if (XplatUI.CalculateWindowRect(ref ClientRect, cp.Style, cp.ExStyle, cp.menu, out WindowRect)) {
+                       if (XplatUI.CalculateWindowRect(ref ClientRect, cp, cp.menu, out WindowRect)) {
                                SetBounds(bounds.X, bounds.Y, WindowRect.Width, WindowRect.Height, BoundsSpecified.Size);
                        }
                }
 
                [EditorBrowsable(EditorBrowsableState.Advanced)]
-               protected override void SetVisibleCore(bool value) {
-                       is_changing_visible_state = true;
-                       has_been_visible = value || has_been_visible;
-                       base.SetVisibleCore (value);
-                       is_changing_visible_state = false;
+               protected override void SetVisibleCore(bool value)
+               {
+                       if (IsMdiChild && !MdiParent.Visible) {
+                               if (value != Visible) {
+                                       MdiWindowManager wm = (MdiWindowManager) window_manager;
+                                       wm.IsVisiblePending = value;
+                                       OnVisibleChanged (EventArgs.Empty);
+                                       return;
+                               }
+                       } else {
+                               is_changing_visible_state = true;
+                               has_been_visible = value || has_been_visible;
+                               base.SetVisibleCore (value);
+                               if (value) {
+                                       Application.AddForm (this);
+                               }
+                               
+                               if (value && WindowState != FormWindowState.Normal)
+                                       XplatUI.SendMessage (Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+                                       
+                               is_changing_visible_state = false;
+                       }
+                       
+                       if (value && IsMdiContainer) {
+                               Form [] children = MdiChildren;
+                               for (int i = 0; i < children.Length; i++) {
+                                       Form child = children [i];
+                                       MdiWindowManager wm = (MdiWindowManager) child.window_manager;
+                                       if (!child.IsHandleCreated && wm.IsVisiblePending) {
+                                               wm.IsVisiblePending = false;
+                                               child.Visible = true;
+                                       }
+                               }
+                       }
+                       
+                       if (value && IsMdiChild){
+                               PerformLayout ();
+                               ThemeEngine.Current.ManagedWindowSetButtonLocations (window_manager);
+                       }
                        
-#if NET_2_0
                        // 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;
                        }
-#endif
                }
 
                protected override void UpdateDefaultButton() {
@@ -1987,327 +2170,448 @@ namespace System.Windows.Forms {
                        Console.WriteLine(DateTime.Now.ToLongTimeString () + " Form {0} ({2}) received message {1}", window.Handle == IntPtr.Zero ? this.Text : XplatUI.Window(window.Handle), m.ToString (), Text);
 #endif
 
-                       if (window_manager != null && window_manager.HandleMessage (ref m)) {
+                       if (window_manager != null && window_manager.WndProc (ref m)) {
                                return;
                        }
 
-                       switch((Msg)m.Msg) {
-                               case Msg.WM_DESTROY: {
-                                       base.WndProc(ref m);
-                                       if (!RecreatingHandle) {
-                                               this.closing = true;
-                                       }
-                                       return;
-                               }
-
-                               case Msg.WM_CLOSE_INTERNAL: {
-                                       DestroyHandle();
-                                       break;
-                               }
+                       switch ((Msg)m.Msg) {
+                       case Msg.WM_DESTROY: {
+                               WmDestroy (ref m);
+                               return;
+                       }
 
-                               case Msg.WM_CLOSE: {
-                                       Form act = Form.ActiveForm;
-                                       if (act != null && act != this && act.Modal == true) {
-                                               return;
-                                       }
+                       case Msg.WM_CLOSE: {
+                               WmClose (ref m);
+                               return;
+                       }
 
-                                       if (mdi_container != null) {
-                                               foreach (Form mdi_child in mdi_container.MdiChildren) {
-                                                       mdi_child.FireClosingEvents (CloseReason.MdiFormClosing);
-                                               }
-                                       }
+                       case Msg.WM_WINDOWPOSCHANGED: {
+                               WmWindowPosChanged (ref m);
+                               return;
+                       }
 
-                                       if (!is_modal) {
-                                               if (!FireClosingEvents (CloseReason.UserClosing)) {
-                                                       OnClosed (EventArgs.Empty);
-#if NET_2_0
-                                                       OnFormClosed (new FormClosedEventArgs (CloseReason.UserClosing));
-#endif
-                                                       closing = true;
-                                                       Dispose ();
-                                               }
-                                               else {
-                                                       closing = false;
-                                               }
-                                       } else {
-                                               if (FireClosingEvents (CloseReason.UserClosing)) {
-                                                       DialogResult = DialogResult.None;
-                                                       closing = false;
-                                               }
-                                               else {
-                                                       OnClosed (EventArgs.Empty);
 #if NET_2_0
-                                                       OnFormClosed (new FormClosedEventArgs (CloseReason.UserClosing));
+                       case Msg.WM_SYSCOMMAND: {
+                               WmSysCommand (ref m);
+                               break;
+                       }
 #endif
-                                                       closing = true;
-                                                       Hide ();
-                                               }
-                                       }
 
+                       case Msg.WM_ACTIVATE: {
+                               WmActivate (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_KILLFOCUS: {
+                               WmKillFocus (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_SETFOCUS: {
+                               WmSetFocus (ref m);
+                               return;
+                       }
+
+                       // Menu drawing
+                       case Msg.WM_NCHITTEST: {
+                               WmNcHitTest (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCLBUTTONDOWN: {
+                               WmNcLButtonDown (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCLBUTTONUP: {
+                               WmNcLButtonUp (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCMOUSELEAVE: {
+                               WmNcMouseLeave (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCMOUSEMOVE: {
+                               WmNcMouseMove (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCPAINT: {
+                               WmNcPaint (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_NCCALCSIZE: {
+                               WmNcCalcSize (ref m);
+                               break;
+                       }
+
+                       case Msg.WM_MOUSEMOVE: {
+                               WmMouseMove (ref m);
+                               break;
+                       }
+
+                       case Msg.WM_LBUTTONDOWN:
+                       case Msg.WM_MBUTTONDOWN:
+                       case Msg.WM_RBUTTONDOWN: {
+                               WmButtonDown (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_LBUTTONUP:
+                       case Msg.WM_MBUTTONUP:
+                       case Msg.WM_RBUTTONUP: {
+                               WmButtonUp (ref m);
+                               return;
+                       }
+
+                       case Msg.WM_GETMINMAXINFO: {
+                               WmGetMinMaxInfo (ref m);
+                               break;
+                       }
+
+                       default: {
+                               base.WndProc (ref m);
+                               break;
+                       }
+                       }
+               }
+               #endregion      // Protected Instance Methods
+
+#region WM methods
+
+               private void WmDestroy (ref Message m)
+               {
+                       if (!RecreatingHandle)
+                               this.closing = true;
+
+                       base.WndProc (ref m);
+               }
+               
+               private void WmClose (ref Message m)
+               {
+                       Form act = Form.ActiveForm;
+                       // Don't close this form if there's another modal form visible.
+                       if (act != null && act != this && act.Modal == true) {
+                               // Check if any of the parents up the tree is the modal form, 
+                               // in which case we can still close this form.
+                               Control current = this;
+                               while (current != null && current.Parent != act) {
+                                       current = current.Parent;
+                               }
+                               if (current == null || current.Parent != act) {
                                        return;
                                }
+                       }
 
-                               case Msg.WM_WINDOWPOSCHANGED: {
-                                       if (WindowState != FormWindowState.Minimized) {
-                                               base.WndProc(ref m);
-                                       }
-                                       return;
+                       if (mdi_container != null) {
+                               foreach (Form mdi_child in mdi_container.MdiChildren) {
+                                       mdi_child.FireClosingEvents (CloseReason.MdiFormClosing);
                                }
+                       }
 
+                       if (!is_modal) {
+                               if (!FireClosingEvents (CloseReason.UserClosing)) {
+                                       OnClosed (EventArgs.Empty);
 #if NET_2_0
-                               case Msg.WM_SYSCOMMAND: {
-                                       // Let *Strips know the app's title bar was clicked
-                                       if (XplatUI.IsEnabled (Handle))
-                                               ToolStripManager.FireAppClicked ();
-                                               
-                                       base.WndProc(ref m);
-                                       break;
+                                       OnFormClosed (new FormClosedEventArgs (CloseReason.UserClosing));
+#endif
+                                       closing = true;
+                                       Dispose ();
+                               } else {
+                                       closing = false;
                                }
+                       } else {
+                               if (FireClosingEvents (CloseReason.UserClosing)) {
+                                       DialogResult = DialogResult.None;
+                                       closing = false;
+                               } else {
+                                       OnClosed (EventArgs.Empty);
+#if NET_2_0
+                                       OnFormClosed (new FormClosedEventArgs (CloseReason.UserClosing));
 #endif
-       
-                               case Msg.WM_ACTIVATE: {
-                                       if (m.WParam != (IntPtr)WindowActiveFlags.WA_INACTIVE) {
-                                               if (is_loaded) {
-                                                       SelectActiveControl ();
+                                       closing = true;
+                                       Hide ();
+                               }
+                       }
 
-                                                       if (ActiveControl != null && !ActiveControl.Focused)
-                                                               SendControlFocus (ActiveControl);
-                                               }
 
-                                               OnActivated(EventArgs.Empty);
-                                       } else {
-                                               OnDeactivate(EventArgs.Empty);
-                                       }
-                                       return;
-                               }
+                       mdi_parent = null;
+               }
+               
+               private void WmWindowPosChanged (ref Message m)
+               {
+                       if (WindowState != FormWindowState.Minimized) {
+                               base.WndProc (ref m);
+                       }
+               }
 
-                               case Msg.WM_KILLFOCUS: {
-                                       base.WndProc(ref m);
-                                       return;
-                               }
+#if NET_2_0
+               private void WmSysCommand (ref Message m)
+               {
+                       // Let *Strips know the app's title bar was clicked
+                       if (XplatUI.IsEnabled (Handle))
+                               ToolStripManager.FireAppClicked ();
 
-                               case Msg.WM_SETFOCUS: {
-                                       if (ActiveControl != null && ActiveControl != this) {
-                                               ActiveControl.Focus();
-                                               return; // FIXME - do we need to run base.WndProc, even though we just changed focus?
-                                       }
-                                       if (IsMdiContainer) {
-                                               mdi_container.SendFocusToActiveChild ();
-                                               return;
-                                       }
-                                       base.WndProc(ref m);
-                                       return;
+                       base.WndProc (ref m);
+               }
+#endif 
+               private void WmActivate (ref Message m)
+               {
+                       if (m.WParam != (IntPtr)WindowActiveFlags.WA_INACTIVE) {
+                               if (is_loaded) {
+                                       SelectActiveControl ();
+
+                                       if (ActiveControl != null && !ActiveControl.Focused)
+                                               SendControlFocus (ActiveControl);
                                }
 
-                               // Menu drawing
-                               case Msg.WM_NCLBUTTONDOWN: {
-                                       if (XplatUI.IsEnabled (Handle) && ActiveMenu != null) {
-                                               ActiveMenu.OnMouseDown(this, new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), mouse_clicks, Control.MousePosition.X, Control.MousePosition.Y, 0));
-                                       }
+                               IsActive = true;
+                       } else {
+#if NET_2_0
+                               if (XplatUI.IsEnabled (Handle))
+                                       ToolStripManager.FireAppFocusChanged (this);
+#endif
+                               IsActive = false;
+                       }
+               }
+               
+               private void WmKillFocus (ref Message m)
+               {
+                       base.WndProc (ref m);
+               }
+               
+               private void WmSetFocus (ref Message m)
+               {
+                       if (ActiveControl != null && ActiveControl != this) {
+                               ActiveControl.Focus ();
+                               return; // FIXME - do we need to run base.WndProc, even though we just changed focus?
+                       }
+                       if (IsMdiContainer) {
+                               mdi_container.SendFocusToActiveChild ();
+                               return;
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcHitTest (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && ActiveMenu != null) {
+                               int x = LowOrder ((int)m.LParam.ToInt32 ());
+                               int y = HighOrder ((int)m.LParam.ToInt32 ());
 
-                                       if (ActiveMaximizedMdiChild != null) {
-                                               if (ActiveMaximizedMdiChild.HandleMenuMouseDown (ActiveMenu,
-                                                               LowOrder ((int) m.LParam.ToInt32 ()),
-                                                               HighOrder ((int) m.LParam.ToInt32 ()))) {
-                                                       // Don't let base process this message, otherwise we won't
-                                                       // get a WM_NCLBUTTONUP.
-                                                       return;
-                                               }
-                                       }
-                                       base.WndProc(ref m);
-                                       return;
-                               }
-                               case Msg.WM_NCLBUTTONUP: {
-                                       if (ActiveMaximizedMdiChild != null) {
-                                               ActiveMaximizedMdiChild.HandleMenuMouseUp (ActiveMenu,
-                                                               LowOrder ((int)m.LParam.ToInt32 ()),
-                                                               HighOrder ((int)m.LParam.ToInt32 ()));
-                                       }
-                                       base.WndProc (ref m);
-                                       return;
-                               }
+                               XplatUI.ScreenToMenu (ActiveMenu.Wnd.window.Handle, ref x, ref y);
 
-                               case Msg.WM_NCMOUSELEAVE: {
-                                       if (ActiveMaximizedMdiChild != null) {
-                                               ActiveMaximizedMdiChild.HandleMenuMouseLeave(ActiveMenu,
-                                                               LowOrder((int)m.LParam.ToInt32()),
-                                                               HighOrder((int)m.LParam.ToInt32()));
-                                       }
-                                       base.WndProc(ref m);
+                               // If point is under menu return HTMENU, it prevents Win32 to return HTMOVE.
+                               if ((x > 0) && (y > 0) && (x < ActiveMenu.Rect.Width) && (y < ActiveMenu.Rect.Height)) {
+                                       m.Result = new IntPtr ((int)HitTest.HTMENU);
                                        return;
                                }
-                               
-                               case Msg.WM_NCMOUSEMOVE: {
-                                       if (XplatUI.IsEnabled (Handle) && ActiveMenu != null) {
-                                               ActiveMenu.OnMouseMove(this, new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 0));
-                                       }
-                                       
-                                       if (ActiveMaximizedMdiChild != null) {
-                                               XplatUI.RequestAdditionalWM_NCMessages (Handle, false, true);
-                                               ActiveMaximizedMdiChild.HandleMenuMouseMove (ActiveMenu,
-                                                               LowOrder ((int)m.LParam.ToInt32 ()),
-                                                               HighOrder ((int)m.LParam.ToInt32 ()));
-                                       }
-                                       base.WndProc(ref m);
+                       }
+
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcLButtonDown (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && ActiveMenu != null) {
+                               ActiveMenu.OnMouseDown (this, new MouseEventArgs (FromParamToMouseButtons ((int)m.WParam.ToInt32 ()), mouse_clicks, Control.MousePosition.X, Control.MousePosition.Y, 0));
+                       }
+
+                       if (ActiveMaximizedMdiChild != null) {
+                               if (ActiveMaximizedMdiChild.HandleMenuMouseDown (ActiveMenu,
+                                               LowOrder ((int)m.LParam.ToInt32 ()),
+                                               HighOrder ((int)m.LParam.ToInt32 ()))) {
+                                       // Don't let base process this message, otherwise we won't
+                                       // get a WM_NCLBUTTONUP.
                                        return;
                                }
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcLButtonUp (ref Message m)
+               {
+                       if (ActiveMaximizedMdiChild != null) {
+                               ActiveMaximizedMdiChild.HandleMenuMouseUp (ActiveMenu,
+                                               LowOrder ((int)m.LParam.ToInt32 ()),
+                                               HighOrder ((int)m.LParam.ToInt32 ()));
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcMouseLeave (ref Message m)
+               {
+                       if (ActiveMaximizedMdiChild != null) {
+                               ActiveMaximizedMdiChild.HandleMenuMouseLeave (ActiveMenu,
+                                               LowOrder ((int)m.LParam.ToInt32 ()),
+                                               HighOrder ((int)m.LParam.ToInt32 ()));
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcMouseMove (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && ActiveMenu != null) {
+                               ActiveMenu.OnMouseMove (this, new MouseEventArgs (FromParamToMouseButtons ((int)m.WParam.ToInt32 ()), mouse_clicks, LowOrder ((int)m.LParam.ToInt32 ()), HighOrder ((int)m.LParam.ToInt32 ()), 0));
+                       }
 
-                               case Msg.WM_NCPAINT: {
-                                       if (ActiveMenu != null) {
-                                               PaintEventArgs  pe;
-                                               Point           pnt;
-
-                                               pe = XplatUI.PaintEventStart(Handle, false);
-                                               pnt = XplatUI.GetMenuOrigin(window.Handle);
+                       if (ActiveMaximizedMdiChild != null) {
+                               XplatUI.RequestAdditionalWM_NCMessages (Handle, false, true);
+                               ActiveMaximizedMdiChild.HandleMenuMouseMove (ActiveMenu,
+                                               LowOrder ((int)m.LParam.ToInt32 ()),
+                                               HighOrder ((int)m.LParam.ToInt32 ()));
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcPaint (ref Message m)
+               {
+                       if (ActiveMenu != null) {
+                               PaintEventArgs pe;
+                               Point pnt;
 
-                                               // The entire menu has to be in the clip rectangle because the 
-                                               // control buttons are right-aligned and otherwise they would
-                                               // stay painted when the window gets resized.
-                                               Rectangle clip = new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0);
-                                               clip = Rectangle.Union(clip, pe.ClipRectangle);
-                                               pe.SetClip(clip);
-                                               pe.Graphics.SetClip(clip);
-                                               
-                                               ActiveMenu.Draw (pe, new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0));
+                               pe = XplatUI.PaintEventStart (Handle, false);
+                               pnt = XplatUI.GetMenuOrigin (window.Handle);
 
-                                               if (ActiveMaximizedMdiChild != null) {
-                                                       ActiveMaximizedMdiChild.DrawMaximizedButtons (ActiveMenu, pe);
-                                               }
+                               // The entire menu has to be in the clip rectangle because the 
+                               // control buttons are right-aligned and otherwise they would
+                               // stay painted when the window gets resized.
+                               Rectangle clip = new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0);
+                               clip = Rectangle.Union (clip, pe.ClipRectangle);
+                               pe.SetClip (clip);
+                               pe.Graphics.SetClip (clip);
 
-                                               XplatUI.PaintEventEnd(Handle, false);
-                                       }
+                               ActiveMenu.Draw (pe, new Rectangle (pnt.X, pnt.Y, ClientSize.Width, 0));
 
-                                       base.WndProc(ref m);
-                                       return;
+                               if (ActiveMaximizedMdiChild != null) {
+                                       ActiveMaximizedMdiChild.DrawMaximizedButtons (ActiveMenu, pe);
                                }
 
-                               case Msg.WM_NCCALCSIZE: {
-                                       XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
-
-                                       if ((ActiveMenu != null) && (m.WParam == (IntPtr)1)) {
-                                               ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(XplatUIWin32.NCCALCSIZE_PARAMS));
+                               XplatUI.PaintEventEnd (Handle, false);
+                       }
 
-                                               // Adjust for menu
-                                               ncp.rgrc1.top += ThemeEngine.Current.CalcMenuBarSize (DeviceContext, ActiveMenu, ClientSize.Width);
-                                               Marshal.StructureToPtr(ncp, m.LParam, true);
-                                       }
-                                       DefWndProc(ref m);
-                                       break;
-                               }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmNcCalcSize (ref Message m)
+               {
+                       XplatUIWin32.NCCALCSIZE_PARAMS ncp;
 
-                               case Msg.WM_MOUSEMOVE: {
-                                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
-                                               MouseEventArgs args;
+                       if ((ActiveMenu != null) && (m.WParam == (IntPtr)1)) {
+                               ncp = (XplatUIWin32.NCCALCSIZE_PARAMS)Marshal.PtrToStructure (m.LParam, typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
 
-                                               args = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
-                                                       mouse_clicks,  LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()),  0);
-                                               active_tracker.OnMotion(new MouseEventArgs (args.Button, args.Clicks, Control.MousePosition.X, Control.MousePosition.Y, args.Delta));
-                                               break;
+                               // Adjust for menu
+                               ncp.rgrc1.top += ThemeEngine.Current.CalcMenuBarSize (DeviceContext, ActiveMenu, ClientSize.Width);
+                               Marshal.StructureToPtr (ncp, m.LParam, true);
+                       }
+                       DefWndProc (ref m);             
+               }
+               
+               private void WmMouseMove (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
+                               MouseEventArgs args = new MouseEventArgs (
+                                       FromParamToMouseButtons ((int)m.WParam.ToInt32 ()),
+                                       mouse_clicks,
+                                       Control.MousePosition.X,
+                                       Control.MousePosition.Y,
+                                       0);
+
+                               active_tracker.OnMotion (args);
+                               return;
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmButtonDown (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
+                               MouseEventArgs args = new MouseEventArgs (
+                                       FromParamToMouseButtons ((int)m.WParam.ToInt32 ()),
+                                       mouse_clicks,
+                                       Control.MousePosition.X,
+                                       Control.MousePosition.Y,
+                                       0);
+
+                               if (!active_tracker.OnMouseDown (args)) {
+                                       Control control = GetRealChildAtPoint (Cursor.Position);
+                                       if (control != null) {
+                                               Point pt = control.PointToClient (Cursor.Position);
+                                               XplatUI.SendMessage (control.Handle, (Msg)m.Msg, m.WParam, MakeParam (pt.X, pt.Y));
                                        }
-                                       base.WndProc(ref m);
-                                       break;
                                }
 
-                               case Msg.WM_LBUTTONDOWN:
-                               case Msg.WM_MBUTTONDOWN:
-                               case Msg.WM_RBUTTONDOWN: {                                      
-                                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
-                                               MouseEventArgs args;
-
-                                               args = new MouseEventArgs (FromParamToMouseButtons ((int) m.WParam.ToInt32()), 
-                                                       mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 0);
-                                               active_tracker.OnMouseDown(new MouseEventArgs (args.Button, args.Clicks, Control.MousePosition.X, Control.MousePosition.Y, args.Delta));
-                                               return;
-                                       }
-                                       base.WndProc(ref m);
-                                       return;
-                               }
+                               return;
+                       }
+#if NET_2_0
+                       ToolStripManager.FireAppClicked ();
+#endif
+                       base.WndProc (ref m);
+               }
+               
+               private void WmButtonUp (ref Message m)
+               {
+                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
+                               MouseButtons mb = FromParamToMouseButtons ((int)m.WParam.ToInt32 ());
 
+                               // We add in the button that was released (not sent in WParam)
+                               switch ((Msg)m.Msg) {
                                case Msg.WM_LBUTTONUP:
+                                       mb |= MouseButtons.Left;
+                                       break;
                                case Msg.WM_MBUTTONUP:
-                               case Msg.WM_RBUTTONUP: {
-                                       if (XplatUI.IsEnabled (Handle) && active_tracker != null) {
-                                               MouseEventArgs args;
-                                               MouseButtons mb = FromParamToMouseButtons ((int) m.WParam.ToInt32());
-                                               
-                                               // We add in the button that was released (not sent in WParam)
-                                               switch((Msg)m.Msg) {
-                                                       case Msg.WM_LBUTTONUP:
-                                                               mb |= MouseButtons.Left;
-                                                               break;
-                                                       case Msg.WM_MBUTTONUP:
-                                                               mb |= MouseButtons.Middle;
-                                                               break;
-                                                       case Msg.WM_RBUTTONUP:
-                                                               mb |= MouseButtons.Right;
-                                                               break;
-                                               }
-                                               
-                                               args = new MouseEventArgs (mb, mouse_clicks, LowOrder ((int) m.LParam.ToInt32 ()), HighOrder ((int) m.LParam.ToInt32 ()), 0);
-                                               active_tracker.OnMouseUp(new MouseEventArgs (args.Button, args.Clicks, Control.MousePosition.X, Control.MousePosition.Y, args.Delta));
-                                               mouse_clicks = 1;
-                                               return;
-                                       }
-                                       base.WndProc(ref m);
-                                       return;
+                                       mb |= MouseButtons.Middle;
+                                       break;
+                               case Msg.WM_RBUTTONUP:
+                                       mb |= MouseButtons.Right;
+                                       break;
                                }
 
-                               case Msg.WM_GETMINMAXINFO: {
-                                       MINMAXINFO      mmi;
+                               MouseEventArgs args = new MouseEventArgs (
+                                       mb,
+                                       mouse_clicks,
+                                       Control.MousePosition.X,
+                                       Control.MousePosition.Y,
+                                       0);
 
-                                       if (m.LParam != IntPtr.Zero) {
-                                               mmi = (MINMAXINFO)Marshal.PtrToStructure(m.LParam, typeof(MINMAXINFO));
-
-                                               default_maximized_bounds = new Rectangle(mmi.ptMaxPosition.x, mmi.ptMaxPosition.y, mmi.ptMaxSize.x, mmi.ptMaxSize.y);
-                                               if (maximized_bounds != Rectangle.Empty) {
-                                                       mmi.ptMaxPosition.x = maximized_bounds.Left;
-                                                       mmi.ptMaxPosition.y = maximized_bounds.Top;
-                                                       mmi.ptMaxSize.x = maximized_bounds.Width;
-                                                       mmi.ptMaxSize.y = maximized_bounds.Height;
-                                               }
+                               active_tracker.OnMouseUp (args);
+                               mouse_clicks = 1;
+                               return;
+                       }
+                       base.WndProc (ref m);
+               }
+               
+               private void WmGetMinMaxInfo (ref Message m)
+               {
+                       MINMAXINFO mmi;
 
-                                               if (minimum_size != Size.Empty) {
-                                                       mmi.ptMinTrackSize.x = minimum_size.Width;
-                                                       mmi.ptMinTrackSize.y = minimum_size.Height;
-                                               }
+                       if (m.LParam != IntPtr.Zero) {
+                               mmi = (MINMAXINFO)Marshal.PtrToStructure (m.LParam, typeof (MINMAXINFO));
 
-                                               if (maximum_size != Size.Empty) {
-                                                       mmi.ptMaxTrackSize.x = maximum_size.Width;
-                                                       mmi.ptMaxTrackSize.y = maximum_size.Height;
-                                               }
-                                               Marshal.StructureToPtr(mmi, m.LParam, false);
-                                       }
-                                       break;
-                               }
-                               
-#if NET_2_0
-                               case Msg.WM_MOUSEACTIVATE: {
-                                       // Let *Strips know the form or another control has been clicked
-                                       if (XplatUI.IsEnabled (Handle))
-                                               ToolStripManager.FireAppClicked ();
-                                               
-                                       base.WndProc (ref m);
-                                       break;                          
+                               default_maximized_bounds = new Rectangle (mmi.ptMaxPosition.x, mmi.ptMaxPosition.y, mmi.ptMaxSize.x, mmi.ptMaxSize.y);
+                               if (maximized_bounds != Rectangle.Empty) {
+                                       mmi.ptMaxPosition.x = maximized_bounds.Left;
+                                       mmi.ptMaxPosition.y = maximized_bounds.Top;
+                                       mmi.ptMaxSize.x = maximized_bounds.Width;
+                                       mmi.ptMaxSize.y = maximized_bounds.Height;
                                }
-                               
-                               case Msg.WM_ACTIVATEAPP: {
-                                       // Let *Strips know the app lost focus
-                                       if (m.WParam == (IntPtr)0) 
-                                               if (XplatUI.IsEnabled (Handle))
-                                                       ToolStripManager.FireAppFocusChanged (this);
-                                                       
-                                       base.WndProc (ref m);
-                                       break;                          
+
+                               if (minimum_size != Size.Empty) {
+                                       mmi.ptMinTrackSize.x = minimum_size.Width;
+                                       mmi.ptMinTrackSize.y = minimum_size.Height;
                                }
-#endif
 
-                               default: {
-                                       base.WndProc (ref m);
-                                       break;
+                               if (maximum_size != Size.Empty) {
+                                       mmi.ptMaxTrackSize.x = maximum_size.Width;
+                                       mmi.ptMaxTrackSize.y = maximum_size.Height;
                                }
+                               Marshal.StructureToPtr (mmi, m.LParam, false);
                        }
                }
-               #endregion      // Protected Instance Methods
+#endregion
 
                internal override void FireEnter ()
                {
@@ -2342,6 +2646,8 @@ namespace System.Windows.Forms {
                                }
                        }
                }
+
+               internal override bool ActivateOnShow { get { return !this.ShowWithoutActivation; } }
                
                #region Events
                static object ActivatedEvent = new object ();
@@ -2444,7 +2750,6 @@ namespace System.Windows.Forms {
                        add { base.TabIndexChanged += value; }
                        remove { base.TabIndexChanged -= value; }
                }
-               #endregion      // Events
 
 #if NET_2_0
                [SettingsBindable (true)]
@@ -2566,6 +2871,7 @@ namespace System.Windows.Forms {
 
                [EditorBrowsable (EditorBrowsableState.Advanced)]
                protected virtual void OnFormClosed (FormClosedEventArgs e) {
+                       Application.RemoveForm (this);
                        FormClosedEventHandler eh = (FormClosedEventHandler)(Events[FormClosedEvent]);
                        if (eh != null)
                                eh (this, e);
@@ -2618,5 +2924,6 @@ namespace System.Windows.Forms {
                                eh (this, e);
                }
 #endif
+               #endregion      // Events
        }
 }