Beispiel #1
0
        protected override void OnLayout(LayoutEventArgs levent)
        {
            var clientSize = ClientSize;

            currentMetrics.TotalWidth  = clientSize.Width;
            currentMetrics.TotalHeight = clientSize.Height;

            // If maximized, Windows will make a Form bigger than the screen to hide the drop shadow used for resizing.
            // If a Form such as this one is drawn without that drop shadow, we need to compensate for that.
            if (WindowState == FormWindowState.Maximized)
            {
                currentMetrics.IsMaximized = true;
                currentMetrics.HorizontalResizeBorderThickness = SystemInformation.HorizontalResizeBorderThickness * 2;
                currentMetrics.VerticalResizeBorderThickness   = SystemInformation.VerticalResizeBorderThickness * 2;
            }
            else
            {
                currentMetrics.IsMaximized = false;
                currentMetrics.HorizontalResizeBorderThickness = SystemInformation.HorizontalResizeBorderThickness;
                currentMetrics.VerticalResizeBorderThickness   = SystemInformation.VerticalResizeBorderThickness;
            }

            currentMetrics.CaptionHeight = CaptionHeight;

            if (MainMenuStrip != null && MainMenuStrip.Visible)
            {
                currentMetrics.MainMenuWidth = MainMenuHorizontalMargin +
                                               MainMenuStrip.Items
                                               .OfType <ToolStripItem>()
                                               .Where(x => x.Visible)
                                               .Select(x => x.Width)
                                               .Sum();
            }
            else
            {
                currentMetrics.MainMenuWidth = 0;
            }

            if (currentMetrics.MainMenuWidth > 0)
            {
                MainMenuStrip.SetBounds(
                    currentMetrics.MainMenuLeft,
                    currentMetrics.MainMenuTop,
                    currentMetrics.MainMenuWidth,
                    currentMetrics.MainMenuHeight);
            }

            maximizeButton.Visible = MaximizeBox;
            minimizeButton.Visible = MinimizeBox;
            currentMetrics.UpdateSystemButtonMetrics(saveButton.Visible, MaximizeBox, MinimizeBox);

            closeButton.SetBounds(
                currentMetrics.CloseButtonLeft,
                currentMetrics.SystemButtonTop,
                currentMetrics.SystemButtonWidth,
                currentMetrics.SystemButtonHeight);

            if (saveButton.Visible)
            {
                saveButton.SetBounds(
                    currentMetrics.SaveButtonLeft,
                    currentMetrics.SystemButtonTop,
                    currentMetrics.SystemButtonWidth,
                    currentMetrics.SystemButtonHeight);
            }

            if (maximizeButton.Visible)
            {
                maximizeButton.SetBounds(
                    currentMetrics.MaximizeButtonLeft,
                    currentMetrics.SystemButtonTop,
                    currentMetrics.SystemButtonWidth,
                    currentMetrics.SystemButtonHeight);
            }

            if (minimizeButton.Visible)
            {
                minimizeButton.SetBounds(
                    currentMetrics.MinimizeButtonLeft,
                    currentMetrics.SystemButtonTop,
                    currentMetrics.SystemButtonWidth,
                    currentMetrics.SystemButtonHeight);
            }

            // Do a null-check in case this is called from our constructor, it may not yet been set.
            DockedAsControl?.SetBounds(
                currentMetrics.ClientAreaLeft,
                currentMetrics.ClientAreaTop,
                currentMetrics.ClientAreaWidth,
                currentMetrics.ClientAreaHeight);

            // Setting MinimumSize on an inactive Form will activate it.
            // To work around this issue, I tried delaying updates to MinimumSize until the window is active.
            // However, this prevents a window from being restored to a maximized state from an auto-save file,
            // even if e.g. a nonce is used.
            //
            // See also:
            // https://github.com/dotnet/winforms/issues/3020
            // https://social.msdn.microsoft.com/Forums/en-US/9625570d-4bd7-48f2-b158-15dcbd96c60b/bug-in-form-class-setting-formminimumsize-triggers-an-activated-event-even-when-the-form-is
            // https://social.msdn.microsoft.com/Forums/en-US/31f9d493-f8d6-4b39-92c9-912399ed3964/why-parentformdeactivate-event-getting-triggered-when-try-to-set-the-minimum-size-for-child-form
            //
            // An appopriate MinimumSize is a size which allows the entire menu and the system buttons to be displayed,
            // taking border thickness into account. Using the current metrics:
            //
            // MinimumWidth  = MainMenuLeft + MainMenuWidth + TotalWidth - MinimizeButtonLeft
            // MinimumHeight = CaptionHeight + VerticalResizeBorderThickness * 2
            // MinimumSize   = new Size(MinimumWidth, MinimumHeight)
            //
            // Setting MinimumSize to a fixed size for the time being, since a likely fix is going to be to trap
            // the property getters and setters, and reimplementing what they do by hand.
            MinimumSize = new Size(500, 80);

            // Update maximize button because Aero snap changes the client size directly and updates
            // the window state, but does not seem to call WndProc with e.g. a WM_SYSCOMMAND.
            UpdateMaximizeButtonIcon();
        }