X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FForm.cs;h=ebf99667a65ad78c47f0c4b8a6b549800f0192cb;hb=82a3eedf58cb2a3ee6f6870c235ea34e7310af6c;hp=45baec9a15ffae37dced3d369d75cfd4f8814e71;hpb=406c377bf51942b4283ef31499560d59b1d59c50;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs index 45baec9a15f..ebf99667a65 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Form.cs @@ -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 @@ -86,27 +84,32 @@ namespace System.Windows.Forms { private double opacity; internal ApplicationContext context; Color transparency_key; - internal MenuTracker active_tracker; 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 { @@ -139,40 +142,57 @@ namespace System.Windows.Forms { // Convenience method for fire BOTH OnClosing and OnFormClosing events // Returns the value of Cancel, so true means the Close was cancelled, // and you shouldn't close the form. - internal bool FireClosingEvents (CloseReason reason) + internal bool FireClosingEvents (CloseReason reason, bool cancel) { - CancelEventArgs cea = new CancelEventArgs (); + 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); + this.OnFormClosed (new FormClosedEventArgs (reason)); } -#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); } @@ -180,21 +200,15 @@ namespace System.Windows.Forms { [EditorBrowsable (EditorBrowsableState.Advanced)] protected override Rectangle GetScaledBounds (Rectangle bounds, SizeF factor, BoundsSpecified specified) { - // Never change the Form's location - specified &= ~BoundsSpecified.Location; - - if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width && !GetStyle (ControlStyles.FixedWidth)) - bounds.Width = (int)Math.Round (bounds.Width * factor.Width); - if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height && !GetStyle (ControlStyles.FixedHeight)) - bounds.Height = (int)Math.Round (bounds.Height * factor.Height); - - Size size = ClientSizeFromSize (bounds.Size); + if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width) { + int border = Size.Width - ClientSize.Width; + bounds.Width = (int)Math.Round ((bounds.Width - border) * factor.Width) + border; + } + if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height) { + int border = Size.Height - ClientSize.Height; + bounds.Height = (int)Math.Round ((bounds.Height - border) * factor.Height) + border; + } - if ((specified & BoundsSpecified.Width) == BoundsSpecified.Width && !GetStyle (ControlStyles.FixedWidth)) - bounds.Width -= (int)((bounds.Width - size.Width) * (factor.Width - 1)); - if ((specified & BoundsSpecified.Height) == BoundsSpecified.Height && !GetStyle (ControlStyles.FixedHeight)) - bounds.Height -= (int)((bounds.Height - size.Height) * (factor.Height - 1)); - return bounds; } @@ -206,11 +220,8 @@ namespace System.Windows.Forms { [EditorBrowsable (EditorBrowsableState.Advanced)] protected override void ScaleControl (SizeF factor, BoundsSpecified specified) { - Rectangle new_bounds = GetScaledBounds (bounds, factor, specified); - - SetBounds (new_bounds.X, new_bounds.Y, new_bounds.Width, new_bounds.Height, specified); + base.ScaleControl (factor, specified); } -#endif internal void OnActivatedInternal () { @@ -306,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); @@ -317,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 (); @@ -350,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; @@ -377,7 +385,7 @@ namespace System.Windows.Forms { #region Public Constructor & Destructor public Form () { - SizeF current_scale = GetAutoScaleSize (DeviceContext, Font); + SizeF current_scale = GetAutoScaleSize (Font); autoscale = true; autoscale_base_size = new Size ((int)Math.Round (current_scale.Width), (int)Math.Round(current_scale.Height)); @@ -407,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 @@ -489,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 { @@ -504,34 +506,25 @@ namespace System.Windows.Forms { } set { - autoscale = value; - -#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 } } @@ -550,7 +543,6 @@ namespace System.Windows.Forms { return this.AutoScroll != false; } -#if NET_2_0 [Browsable (true)] [EditorBrowsable (EditorBrowsableState.Always)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Visible)] @@ -591,7 +583,6 @@ namespace System.Windows.Forms { get { return base.AutoValidate; } set { base.AutoValidate = value; } } -#endif public override Color BackColor { get { @@ -685,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. } } @@ -743,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); } } @@ -816,7 +808,6 @@ namespace System.Windows.Forms { } } -#if NET_2_0 [DefaultValue (null)] [TypeConverter (typeof (ReferenceConverter))] public MenuStrip MainMenuStrip { @@ -835,7 +826,6 @@ namespace System.Windows.Forms { get { return base.Margin; } set { base.Margin = value; } } -#endif [DefaultValue(true)] [MWFCategory("Window Style")] @@ -855,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; } @@ -867,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); @@ -930,17 +925,6 @@ namespace System.Windows.Forms { } } - internal MenuTracker ActiveTracker { - get { return active_tracker; } - set { - if (value == active_tracker) - return; - - Capture = value != null; - active_tracker = value; - } - } - internal MdiClient MdiContainer { get { return mdi_container; } } @@ -949,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 { @@ -979,6 +961,9 @@ namespace System.Windows.Forms { } } else UpdateBounds (); + + // UIA Framework Event: Menu Changed + OnUIAMenuChanged (EventArgs.Empty); } } } @@ -1039,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; } @@ -1058,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)); } @@ -1154,8 +1140,8 @@ namespace System.Windows.Forms { } } -#if NET_2_0 [Browsable (false)] + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public Rectangle RestoreBounds { get { return restore_bounds; } } @@ -1181,8 +1167,7 @@ namespace System.Windows.Forms { } } } - } -#endif + } [DefaultValue(true)] [MWFCategory("Window Style")] @@ -1244,7 +1229,6 @@ namespace System.Windows.Forms { set { base.TabIndex = value; } } -#if NET_2_0 [Browsable(false)] [DefaultValue (true)] [DispIdAttribute (-516)] @@ -1253,7 +1237,6 @@ namespace System.Windows.Forms { get { return base.TabStop; } set { base.TabStop = value; } } -#endif [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] @@ -1282,6 +1265,9 @@ namespace System.Windows.Forms { topmost = value; if (IsHandleCreated) XplatUI.SetTopmost(window.Handle, value); + + // UIA Framework: Raises internal event + OnUIATopMostChanged (); } } } @@ -1337,6 +1323,10 @@ namespace System.Windows.Forms { XplatUI.SetWindowState(Handle, value); } + + // UIA Framework: Raises internal event + if (old_state != window_state) + OnUIAWindowStateChanged (); } } @@ -1350,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; @@ -1493,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) { @@ -1516,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; @@ -1532,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; } } @@ -1574,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); @@ -1601,28 +1573,9 @@ namespace System.Windows.Forms { #endregion // Public Static Methods #region Public Instance Methods - internal SizeF GetAutoScaleSize (Graphics g, Font font) - { - // - // The following constants come from the dotnet mailing list - // discussion: http://discuss.develop.com/archives/wa.exe?A2=ind0203A&L=DOTNET&P=R3655 - // - // The magic number is "Its almost the length - // of the string with a smattering added in - // for compat with earlier code". - // - - string magic_string = "The quick brown fox jumped over the lazy dog."; - double magic_number = 44.549996948242189; - float width = (float) (g.MeasureString (magic_string, font).Width / magic_number); - - return new SizeF (width, font.Height); - } public void Activate () { - Form active; - if (IsHandleCreated) { if (IsMdiChild) { MdiParent.ActivateMdiChild (this); @@ -1645,11 +1598,16 @@ namespace System.Windows.Forms { if (IsDisposed) return; - if (!IsHandleCreated) + if (!IsHandleCreated) { + base.Dispose (); return; + } + + if (Menu != null) + XplatUI.SetMenu (window.Handle, null); XplatUI.SendMessage(this.Handle, Msg.WM_CLOSE, IntPtr.Zero, IntPtr.Zero); - + closed = true; } @@ -1671,7 +1629,6 @@ namespace System.Windows.Forms { DesktopLocation = new Point(x, y); } -#if NET_2_0 public void Show (IWin32Window owner) { if (owner == null) @@ -1690,28 +1647,27 @@ namespace System.Windows.Forms { base.Show (); } -#endif public DialogResult ShowDialog() { return ShowDialog (null); } - public DialogResult ShowDialog(IWin32Window ownerWin32) { + public DialogResult ShowDialog(IWin32Window owner) { Rectangle area; bool confined; IntPtr capture_window; Form owner_to_be = null; - if ((ownerWin32 == null) && (Application.MWFThread.Current.Context != null)) { + if ((owner == null) && (Application.MWFThread.Current.Context != null)) { IntPtr active = XplatUI.GetActive (); if (active != IntPtr.Zero) { - ownerWin32 = Control.FromHandle (active) as Form; + owner = Control.FromHandle (active) as Form; } } - if (ownerWin32 != null) { - Control c = Control.FromHandle (ownerWin32.Handle); + if (owner != null) { + Control c = Control.FromHandle (owner.Handle); if (c != null) owner_to_be = c.TopLevelControl as Form; } @@ -1744,7 +1700,11 @@ namespace System.Windows.Forms { } if (owner_to_be != null) - owner = owner_to_be; + 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 @@ -1757,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 @@ -1770,9 +1740,9 @@ namespace System.Windows.Forms { Application.RunLoop(true, new ApplicationContext(this)); - if (owner != null) { + if (this.owner != null) { // Cannot use Activate(), it has a check for the current active window... - XplatUI.Activate(owner.window.Handle); + XplatUI.Activate(this.owner.window.Handle); } if (IsHandleCreated) { @@ -1787,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 () @@ -1804,7 +1773,6 @@ namespace System.Windows.Forms { { return base.ValidateChildren (validationConstraints); } -#endif #endregion // Public Instance Methods #region Protected Instance Methods @@ -1820,15 +1788,11 @@ 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 (DeviceContext, Font); + SizeF current_size_f = GetAutoScaleSize (Font); Size current_size = new Size ((int)Math.Round (current_size_f.Width), (int)Math.Round (current_size_f.Height)); float dx; float dy; @@ -1845,19 +1809,19 @@ namespace System.Windows.Forms { // http://blogs.msdn.com/mharsh/archive/2004/01/25/62621.aspx // but it makes things larger without looking better. // - if (current_size_f.Width != AutoScaleBaseSize.Width) { - dx = current_size_f.Width / AutoScaleBaseSize.Width + 0.08f; + if (current_size.Width != AutoScaleBaseSize.Width) { + dx = (float)current_size.Width / AutoScaleBaseSize.Width + 0.08f; } else { dx = 1; } - if (current_size_f.Height != AutoScaleBaseSize.Height) { - dy = current_size_f.Height / AutoScaleBaseSize.Height + 0.08f; + if (current_size.Height != AutoScaleBaseSize.Height) { + dy = (float)current_size.Height / AutoScaleBaseSize.Height + 0.08f; } else { dy = 1; } - Scale (new SizeF (dx, dy)); + Scale (dx, dy); AutoScaleBaseSize = current_size; } @@ -1946,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); } @@ -1980,6 +1945,12 @@ namespace System.Windows.Forms { wm = window_manager as MdiWindowManager; wm.RaiseActivated (); + + // We need to tell everyone who may have just been deactivated to redraw their titlebar + if (MdiParent != null) + foreach (Form form in MdiParent.MdiChildren) + if (form != this && form.IsHandleCreated) + XplatUI.InvalidateNC (form.Handle); } if (window_state != FormWindowState.Normal) { @@ -2001,7 +1972,7 @@ namespace System.Windows.Forms { ((Form)owned_forms[i]).Owner = null; owned_forms.Clear (); - + Owner = null; base.Dispose (disposing); Application.RemoveForm (this); @@ -2055,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)] @@ -2120,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); @@ -2141,11 +2110,11 @@ namespace System.Windows.Forms { } [EditorBrowsable(EditorBrowsableState.Advanced)] - protected override void OnPaint (PaintEventArgs pevent) { - base.OnPaint (pevent); + protected override void OnPaint (PaintEventArgs e) { + base.OnPaint (e); if (size_grip != null) { - size_grip.HandlePaint (this, pevent); + size_grip.HandlePaint (this, e); } } @@ -2174,7 +2143,12 @@ namespace System.Windows.Forms { if (Visible) { if (window_manager != null) - window_manager.SetWindowState (WindowState, WindowState); + if (WindowState == FormWindowState.Normal) + window_manager.SetWindowState (WindowState, WindowState); + else + // We don't really have an old_state, and if we pass the same thing, + // it may not really change the state for us + window_manager.SetWindowState ((FormWindowState)(-1), WindowState); } } @@ -2194,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) { @@ -2212,6 +2195,10 @@ namespace System.Windows.Forms { case Keys.Control | Keys.Shift | Keys.F6: MdiParent.MdiContainer.ActivatePreviousChild (); return true; + case Keys.Alt | Keys.OemMinus: + case Keys.Alt | Keys.Subtract: + (this.WindowManager as MdiWindowManager).ShowPopup (Point.Empty); + return true; } } @@ -2234,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) { @@ -2245,13 +2235,13 @@ namespace System.Windows.Forms { return base.ProcessDialogKey(keyData); } - protected override bool ProcessKeyPreview(ref Message msg) { + protected override bool ProcessKeyPreview(ref Message m) { if (key_preview) { - if (ProcessKeyEventArgs(ref msg)) { + if (ProcessKeyEventArgs(ref m)) { return true; } } - return base.ProcessKeyPreview (ref msg); + return base.ProcessKeyPreview (ref m); } protected override bool ProcessTabKey(bool forward) { @@ -2266,43 +2256,10 @@ namespace System.Windows.Forms { return control_activated; } -#if NET_2_0 - [EditorBrowsable(EditorBrowsableState.Never)] -#else - [EditorBrowsable(EditorBrowsableState.Advanced)] -#endif - protected override void ScaleCore(float dx, float dy) { - try { - SuspendLayout(); - - // We can't scale max or min windows - if (WindowState == FormWindowState.Normal) { - // We cannot call base since base also adjusts X/Y, but - // a form is toplevel and doesn't move - Size size; - - size = ClientSize; - if (!GetStyle(ControlStyles.FixedWidth)) { - size.Width = (int)(size.Width * dx); - } - - if (!GetStyle(ControlStyles.FixedHeight)) { - size.Height = (int)(size.Height * dy); - } - - ClientSize = size; - } - - /* Now scale our children */ - Control [] controls = Controls.GetAllControls (); - for (int i=0; i < controls.Length; i++) { - controls[i].Scale (new SizeF (dx, dy)); - } - } - - finally { - ResumeLayout(); - } + [EditorBrowsable (EditorBrowsableState.Never)] + protected override void ScaleCore (float x, float y) + { + base.ScaleCore (x, y); } protected override void Select(bool directed, bool forward) { @@ -2330,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); @@ -2352,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)] @@ -2389,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; @@ -2429,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() { @@ -2466,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); @@ -2524,27 +2490,18 @@ namespace System.Windows.Forms { break; } - case Msg.WM_MOUSEMOVE: { - WmMouseMove (ref m); + case Msg.WM_GETMINMAXINFO: { + WmGetMinMaxInfo (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_ENTERSIZEMOVE: { + OnResizeBegin (EventArgs.Empty); + break; } - - case Msg.WM_GETMINMAXINFO: { - WmGetMinMaxInfo (ref m); + + case Msg.WM_EXITSIZEMOVE: { + OnResizeEnd (EventArgs.Empty); break; } @@ -2566,25 +2523,28 @@ namespace System.Windows.Forms { base.WndProc (ref m); } - internal bool RaiseCloseEvents (bool last_check) + internal bool RaiseCloseEvents (bool last_check, bool cancel) { if (last_check && Visible) { Hide (); } - if (last_check && closed) { + if (close_raised || (last_check && closed)) { return false; } - bool cancelled = FireClosingEvents (CloseReason.UserClosing); + bool cancelled = FireClosingEvents (CloseReason.UserClosing, cancel); if (!cancelled) { if (!last_check || DialogResult != DialogResult.None) { - OnClosed (EventArgs.Empty); -#if NET_2_0 - OnFormClosed (new FormClosedEventArgs (CloseReason.UserClosing)); -#endif + if (mdi_container != null) + foreach (Form mdi_child in mdi_container.MdiChildren) + mdi_child.FireClosedEvents (CloseReason.UserClosing); + + FireClosedEvents (CloseReason.UserClosing); } closing = true; + close_raised = true; + shown_raised = false; } else { DialogResult = DialogResult.None; closing = false; @@ -2592,9 +2552,12 @@ namespace System.Windows.Forms { return cancelled; } - + 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) { @@ -2609,17 +2572,25 @@ namespace System.Windows.Forms { } } - if (mdi_container != null) { - foreach (Form mdi_child in mdi_container.MdiChildren) { - mdi_child.FireClosingEvents (CloseReason.MdiFormClosing); - } - } + bool mdi_cancel = false; + + // Give any MDI children the opportunity to cancel the close + if (mdi_container != null) + foreach (Form mdi_child in mdi_container.MdiChildren) + mdi_cancel = mdi_child.FireClosingEvents (CloseReason.MdiFormClosing, mdi_cancel); - if (suppress_closing_events || !RaiseCloseEvents (false)) { + bool validate_cancel = false; + if (!suppress_closing_events) + validate_cancel = !ValidateChildren (); + + if (suppress_closing_events || + !RaiseCloseEvents (false, validate_cancel || mdi_cancel)) { if (is_modal) { Hide (); } else { - Dispose (); + Dispose (); + if (act != null && act != this) + act.SelectActiveControl (); } mdi_parent = null; } else { @@ -2632,15 +2603,31 @@ namespace System.Windows.Forms { private void WmWindowPosChanged (ref Message m) { - base.WndProc (ref m); + // When a form is minimized/restored: + // * Win32: X and Y are set to negative values/restored, + // size remains the same. + // * X11: Location and Size remain the same. + // + // In both cases we have to fire Resize explicitly here, + // because of the unmodified Size due to which Control + // doesn't fire it. + // + if (window_state != FormWindowState.Minimized && WindowState != FormWindowState.Minimized) + base.WndProc (ref m); + 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 @@ -2649,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 (); @@ -2662,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; } } @@ -2762,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 @@ -2778,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); } @@ -2802,78 +2789,6 @@ namespace System.Windows.Forms { 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)); - } - } - - return; - } - - 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: - mb |= MouseButtons.Middle; - break; - case Msg.WM_RBUTTONUP: - mb |= MouseButtons.Right; - break; - } - - MouseEventArgs args = new MouseEventArgs ( - mb, - mouse_clicks, - Control.MousePosition.X, - Control.MousePosition.Y, - 0); - - active_tracker.OnMouseUp (args); - mouse_clicks = 1; - return; - } - base.WndProc (ref m); - } - private void WmGetMinMaxInfo (ref Message m) { MINMAXINFO mmi; @@ -2904,6 +2819,15 @@ namespace System.Windows.Forms { #endregion #region Internal / Private Methods + internal void ActivateFocusCues () + { + bool need_refresh = !show_focus_cues; + show_focus_cues = true; + + if (need_refresh) + ActiveControl.Invalidate (); + } + internal override void FireEnter () { // do nothing - forms don't generate OnEnter @@ -2951,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; } @@ -2996,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); } @@ -3049,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); } @@ -3078,7 +3004,6 @@ namespace System.Windows.Forms { remove { base.TabIndexChanged -= value; } } -#if NET_2_0 [SettingsBindable (true)] public override string Text { get { @@ -3202,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. @@ -3213,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) { @@ -3234,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); } } @@ -3269,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 } }