【问题标题】:How can you design a 1920px by 1080px WinForm on a computer with a maximum resolution of 1366x768?如何在最大分辨率为 1366x768 的计算机上设计 1920 x 1080 像素的 WinForm?
【发布时间】:2019-02-21 19:59:08
【问题描述】:

我正在笔记本上开发一个 winforms 应用程序(屏幕分辨率:1366x768)。该应用程序的终端设备是windows surface(屏幕分辨率1920x1080)。现在我想让我的表单和用户控件更大,以便它们可以在表面上全屏显示。我已经在我的主窗体上使用此代码完成了此操作:

        Left = Top = 0;
        Width = Screen.PrimaryScreen.WorkingArea.Width;
        Height = Screen.PrimaryScreen.WorkingArea.Height;

但在我的 UserControls 中,我需要将按钮文本框等放在正确的位置。否则,应用程序的大部分区域都未使用。所以我需要使用户控件和表单的大小更大,但我的笔记本的屏幕分辨率太小,所以它不允许超过 1366x768 像素的数字。我该如何设计应用程序以适应表面的屏幕分辨率?

【问题讨论】:

  • 请一次一个问题。关于您的标题问题,为什么您不能将分辨率设置为高于笔记本电脑?你在用设计师吗?
  • 对不起,双重问题,但问题在某种程度上彼此相关。是的,我正在使用视觉工作室的设计师。我只是注意到我可以将用户控件的大小更改为比我的屏幕分辨率更高的数字,但不能更改我的主窗体的大小。为什么会这样?
  • 您可以避免使用设计器。有时我看到它施加了奇怪的约束。我建议简单地在代码中分配所需的值。不要在设计器文件中更改它们,因为它是自动生成的。
  • 好吧,我可以避开设计师。但是如何在该表单上放置一些按钮。如何在没有看到设计器的全部布局的情况下做到这一点?
  • 使用 TableLayoutPanel 相对于表单的大小来定位和调整控件的大小。

标签: c# winforms


【解决方案1】:

以下代码是从 VB.Net answer that I posted several years ago on CodeProject 直接翻译(通过工具),所以从当前 C# 时尚趋势的角度来看,它会看起来很奇怪。但是它在基于 Windows 的 PC 上可以正常工作。

将此Form 定义添加到您的项目中。执行构建。然后,您可以使用 Inherited Form 项模板添加从该表单派生的表单。通过 propertygrid,将 MaxDesignWidthMaxDesignHeight 属性设置为与您的目标分辨率匹配的值。

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

public class FormWithDesignSize : Form
{
    private const Int32 DefaultMax = 2000; //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);
        }
    }

    private const Int32 WMGETMINMAXINFO = 0x24;
    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        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(System.Runtime.InteropServices.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);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多