WinForm 表单大小

问题描述 投票:0回答:1

我正在开发一个用于工作的 WinForms 仪表板应用程序,我正在尝试设计 UI 以适应超高清屏幕 (3840x2160),一旦完成,仪表板将在该屏幕上运行。问题是我正在使用的计算机(以及公司中的所有其他 PC)都是全高清的。我知道表单大小的实施限制,并且无法将表单的高度或宽度设置为大于屏幕大小 +12,但在仪表板将运行的屏幕上进行设计并不是一种选择对我来说,所以我需要一个解决方法。

到目前为止,我尝试的是将 AutoScoll 属性设置为 true,如其他线程中所建议的那样,但这仅在运行时创建滚动条,而不是设计。 我发现奇怪的是,尽管我遇到的每一篇关于表单大小的帖子都提到屏幕大小不能超过 12 像素,但出于某种原因,当我尝试将表单大小调整为 3840x2160 时,这将其设置为3840x1100,我觉得很奇怪,而且我似乎也找不到延长高度的方法。

c# .net winforms
1个回答
0
投票

最大表单大小由 Form.SetboundsCore 方法控制。该方法中相关代码如下:

        // Enforce maximum size...
        //
        if (WindowState == FormWindowState.Normal
            && (this.Height != height || this.Width != width)) {

            Size max = SystemInformation.MaxWindowTrackSize;
            if (height > max.Height) {
                height = max.Height;
            }
            if (width > max.Width) {
                width = max.Width;
            }
        }

SystemInformation.MaxWindowTrackSize 属性 是限制值,它会根据计算机的配置而变化。

处理此内置限制的一种方法是定义一个继承自 System.Windows.Forms.Form 的类并重写 SetWindowsCore 方法以允许超过 MaxWindowTrackSize 的值。

我最初在 CodeProject 上发布了这种方法,但该实现是在 VB.Net 中实现的。下面的代码是原始代码的 C# 翻译。

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class FormWithDesignSize : Form
{
    private const Int32 DefaultMax = 10000; //set this to whatever you need

    private Int32 _MaxDesignWidth = DefaultMax;
    private Int32 _MaxDesignHeight = DefaultMax;

    [Category("Design"), DisplayName("MaxDesignWidth")]
    public Int32 aaa_MaxDesignWidth //Prefix aaa_ is to force Designer code placement before ClientSize setting
    {
        get // avoids need to write customer serializer code
        {
            return _MaxDesignWidth;
        }
        set
        {
            _MaxDesignWidth = value;
        }
    }

    [Category("Design"), DisplayName("MaxDesignHeight")]
    public Int32 aaa_MaxDesignHeight //Prefix aaa_ is to force Designer code placement before ClientSize setting
    {
        get // avoids need to write customer serializer code
        {
            return _MaxDesignHeight;
        }
        set
        {
            _MaxDesignHeight = value;
        }
    }


    protected override void SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified)
    {
        if (this.DesignMode)
        {
            // The Forms.Form.SetBoundsCore method limits the size based on SystemInformation.MaxWindowTrackSize

            // From the GetSystemMetrics function documentation for SMCXMINTRACK: 
            //   "The minimum tracking width of a window, in pixels. The user cannot drag the window frame to a size 
            //    smaller than these dimensions. A window can override this value by processing the WMGETMINMAXINFO
            //    message."
            // See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385%28v=vs.85%29.aspx

            // This message also appears to control the size set by the MoveWindow API, 
            // so it is intercepted and the maximum size is set to MaxWidth by MaxHeight
            // in the WndProc method when in DesignMode.

            // Form.SetBoundsCore ultimately calls Forms.Control.SetBoundsCore that calls SetWindowPos but, 
            // MoveWindow will be used instead to set the Window size when in the designer as it requires less
            // parameters to achieve the desired effect.

            MoveWindow(this.Handle, this.Left, this.Top, width, height, true);
        }
        else
        {
            base.SetBoundsCore(x, y, width, height, specified);
        }
    }

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        const Int32 WMGETMINMAXINFO = 0x24;
        base.WndProc(ref m);
        if (this.DesignMode && m.Msg == WMGETMINMAXINFO)
        {

            MINMAXINFO MMI = new MINMAXINFO();
            // retrieve default MINMAXINFO values from the structure pointed to by m.LParam
            Marshal.PtrToStructure(m.LParam, MMI);

            // reset the ptMaxTrackSize value
            MMI.ptMaxTrackSize = new POINTAPI(_MaxDesignWidth, _MaxDesignHeight);

            // copy the modified structure back to LParam
            Marshal.StructureToPtr(MMI, m.LParam, true);
        }

    }

    [StructLayout(LayoutKind.Sequential)]
    private class MINMAXINFO
    {
        public POINTAPI ptReserved;
        public POINTAPI ptMaxSize;
        public POINTAPI ptMaxPosition;
        public POINTAPI ptMinTrackSize;
        public POINTAPI ptMaxTrackSize;
    }

    [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
    public struct POINTAPI
    {
        public Int32 X;
        public Int32 Y;

        public POINTAPI(Int32 X, Int32 Y)
            : this()
        {
            this.X = X;
            this.Y = Y;
        }

        public override string ToString()
        {
            return "(" + X.ToString() + ", " + Y.ToString() + ")";
        }
    }

    [DllImport("user32.dll")]
    private extern static bool MoveWindow(IntPtr hWnd, Int32 x, Int32 y, Int32 nWidth, Int32 nHeight, bool bRepaint);

}

将上述代码添加到您的项目中并执行构建。然后你可以根据FormWithDesignSize添加一个“继承的表单”。

© www.soinside.com 2019 - 2024. All rights reserved.