如何在调整Window Forms应用程序大小时保持纵横比?

时间:2014-06-03 14:58:12

标签: c# winforms size aspect-ratio

我需要一些窗口形式调整大小的帮助,这个Form1默认打开,大小为800x600,但它以编程方式更改其大小,代码如下我试图保持窗口形式的方面使用新的大小值,但我的问题是,当重新调整窗口形式时,它会失去其预期的方面,我无法弄清楚如何解决它。

一个简单的例子,当前窗口大小是宽度800,高度600,如果重新调整大小,它应该保留方面。如果窗口形状重新调整为宽度850,我预计高度为650.对吗?

    public Form1()
    {
        InitializeComponent();

        // Default Window Size
        ClientSize = new Size(800, 600);
        chromeWidth = Width - ClientSize.Width;
        chromeHeight = Height - ClientSize.Height;


    }

    // Window form Size changes programatically from a size handler, updating "ClientSize".


    //////////////////////////// Resize /////////////////////////////////////

    #region Resizer
    private float constantWidth = 1;//16;
    private float constantHeight = 1;//9;

    private int chromeWidth;
    private int chromeHeight;

    // From Windows SDK
    private const int WM_SIZING = 0x214;

    private const int WMSZ_LEFT = 1;
    private const int WMSZ_RIGHT = 2;
    private const int WMSZ_TOP = 3;
    private const int WMSZ_BOTTOM = 6;

    struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }



    protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        if (m.Msg == WM_SIZING)
        {
            RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));

            int w = rc.Right - rc.Left - chromeWidth;
            int h = rc.Bottom - rc.Top - chromeHeight;

            switch (m.WParam.ToInt32()) // Resize handle
            {
                case WMSZ_LEFT:
                case WMSZ_RIGHT:
                    // Left or right handles, adjust height                        
                    rc.Bottom = rc.Top + chromeHeight + (int)(constantHeight * w / constantWidth);
                    break;

                case WMSZ_TOP:
                case WMSZ_BOTTOM:
                    // Top or bottom handles, adjust width
                    rc.Right = rc.Left + chromeWidth + (int)(constantWidth * h / constantHeight);
                    break;

                case WMSZ_LEFT + WMSZ_TOP:
                case WMSZ_LEFT + WMSZ_BOTTOM:
                    // Top-left or bottom-left handles, adjust width
                    rc.Left = rc.Right - chromeWidth - (int)(constantWidth * h / constantHeight);
                    break;

                case WMSZ_RIGHT + WMSZ_TOP:
                    // Top-right handle, adjust height
                    rc.Top = rc.Bottom - chromeHeight - (int)(constantHeight * w / constantWidth);
                    break;

                case WMSZ_RIGHT + WMSZ_BOTTOM:
                    // Bottom-right handle, adjust height
                    rc.Bottom = rc.Top + chromeHeight + (int)(constantHeight * w / constantWidth);
                    break;
            }

            Marshal.StructureToPtr(rc, m.LParam, true);
        }

        base.WndProc(ref m);
    }
    #endregion

4 个答案:

答案 0 :(得分:4)

宽高比是一个比率,意味着height / width的结果应该与要维护的方面的值相同。除非高度和宽度是相同的值(即正方形),否则简单地改变相同的量不会保持方面。

因此,您需要先改变高度(或宽度),首先获取宽高比(height / width),然后将该值乘以高度以获得宽度(反之亦然)。 / p>

const double Ratio = height / width;

...

height = height + 50;  // This works the same if you change the 'width'
width = height * Ratio;

答案 1 :(得分:1)

如果窗口分辨率为800 x 600并且你想将它的宽度增加到850,那么你需要像这样进行计算

Int32 newWidth = 850;
Int32 newHeight = (this.Height * newWidth) / this.Width;
this.Size = new Size(newWidth, newHeight);

//Basic Calculation
//newHeight = (oldHeight x newWidth) / oldWidth
//638 = (600 * 850) / 800

答案 2 :(得分:1)

对于850,它是637.5(舍入到638)。 600是75的75%。 所以height = width * 0.75

这样可以保持宽高比。

答案 3 :(得分:0)

您可以尝试以下方法:

public void ResizeWidth(int newWidth)
{
   this.Height = (int)((double)newWidth / (double)((double)this.Width / (double)this.Height));
   this.Width = newWidth;
}

public void ResizeHeight(int newHeight)
{
   this.Width = (int)((double)newHeight * (double)((double)this.Width / (double)this.Height));
   this.Height = newHeight;
}