Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to maintain the aspect ratio when resizing a Window Forms application?

I need some help with a window form resize, this Form1 opens by default with a size of 800x600, but it changes its size programatically, with the code bellow I'm trying to keep the aspect of the window form using the new size values, but my problem is that when re-sizing the window form it looses its intended aspect, and I can't figure out how to fix it.

A quick example, the current window size is width 800, height 600, and if re-sizing it should preserve the aspect. Say if the window form was re-sized to width 850, I would expect the height is 650. Right?

    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
like image 337
AJ152 Avatar asked Nov 14 '25 23:11

AJ152


2 Answers

The aspect ratio is a ratio, meaning, the result from height / width should be the same value for the aspect to be maintained. Simply changing by the same amount won't keep the aspect unless the height and the width are the same value (i.e. a square).

Thus, you need to change the height (or the width) by first getting the aspect ratio (which is height / width) and then multiplying that value by the height to get the width (or vice versa).

const double Ratio = height / width;

...

height = height + 50;  // This works the same if you change the 'width'
width = height * Ratio;
like image 102
rae1 Avatar answered Nov 17 '25 21:11

rae1


For 850 it is 637.5 (round to 638). As 600 is 75% of 800. So height = width * 0.75

That would keep the aspect ratio for you.

like image 30
fishmong3r Avatar answered Nov 17 '25 21:11

fishmong3r



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!