сохранить соотношение сторон формы при изменении размера в c # - PullRequest
4 голосов
/ 03 августа 2010

Как сделать так, чтобы форма имела фиксированное соотношение сторон, которое сохраняется при изменении ее размера?

Я знаю, что это можно сделать, переопределив OnSizeChanged и вручную изменив [новое] Высота / Ширина,но это вызывает мерцание, поскольку оно изменяется один раз перед вызовом события (до размера, не соответствующего соотношению сторон), а затем снова изменяет размер (до правильного соотношения сторон).Есть ли лучший способ?

Ответы [ 2 ]

11 голосов
/ 03 августа 2010

Код для начала работы.Ключ должен ответить на сообщение WM_SIZING, это позволяет вам изменить прямоугольник окна.Этот пример грубый, вы действительно хотите обратить внимание на то, какой угол или край перетаскивается пользователем, доступный из m.WParam.Пользовательский интерфейс никогда не будет отличным, вы не можете сделать ничего разумного, когда пользователь тянет за угол.Создание макета вашей формы достаточно гибким, чтобы вы не заботились о соотношении сторон, является реальным решением.Отображение полосы прокрутки, когда содержимое не подходит, позволяет пользователю автоматически делать правильные вещи.

using System.Runtime.InteropServices;
// etc..

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    protected override void WndProc(ref Message m) {
        if (m.Msg == 0x216 || m.Msg == 0x214) { // WM_MOVING || WM_SIZING
            // Keep the window square
            RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
            int w = rc.Right - rc.Left;
            int h = rc.Bottom - rc.Top;
            int z = w > h ? w : h;
            rc.Bottom = rc.Top + z;
            rc.Right = rc.Left + z;
            Marshal.StructureToPtr(rc, m.LParam, false);
            m.Result = (IntPtr)1;
            return;
        }
        base.WndProc(ref m);
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
}
0 голосов
/ 23 августа 2015

Чтобы расширить принятый ответ:

protected override void WndProc(ref Message m)
    {
        /*
        internal const int WMSZ_LEFT = 1;
        internal const int WMSZ_RIGHT = 2;
        internal const int WMSZ_TOP = 3;
        internal const int WMSZ_TOPLEFT = 4;
        internal const int WMSZ_TOPRIGHT = 5;
        internal const int WMSZ_BOTTOM = 6;
        internal const int WMSZ_BOTTOMLEFT = 7;
        internal const int WMSZ_BOTTOMRIGHT = 8;
        */

        if (m.Msg == 0x214)
        { // WM_MOVING || WM_SIZING
          // Keep the window square
            RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT));
            int w = rc.Right - rc.Left; // get width
            int h = rc.Bottom - rc.Top; // get height
            int z = w > h ? w : h; // z is greatest of the two (w/h)
            switch ((int)m.WParam)
            {
                case 1: //left
                    rc.Bottom = rc.Top + w;//define width
                    rc.Top = rc.Top + (h - (rc.Bottom - rc.Top)) / 2;//define width
                    break;
                case 2: //right
                    rc.Bottom = rc.Top + w;//define width
                    rc.Top = rc.Top + (h - (rc.Bottom - rc.Top)) / 2;//define width
                    break;
                case 3: //top
                    rc.Right = rc.Left + h;//define width
                    rc.Left = rc.Left + (w - (rc.Right - rc.Left)) / 2;//define width
                    break;
                case 4:
                    rc.Top = rc.Bottom - z;//define height
                    rc.Left = rc.Right - z;//define width
                    break;
                case 5:
                    rc.Top = rc.Bottom - z;//define height
                    rc.Right = rc.Left + z;//define width
                    break;
                case 6:
                    rc.Right = rc.Left + h;//define width
                    rc.Left = rc.Left + (w-(rc.Right - rc.Left))/2;//define width
                    break;
                case 7:
                    rc.Bottom = rc.Top + z;//define height
                    rc.Left = rc.Right - z;//define width
                    break;
                case 8:
                    rc.Bottom = rc.Top + z;//define height
                    rc.Right = rc.Left + z;//define width
                    break;
                default:
                    break;
            }
            Marshal.StructureToPtr(rc, m.LParam, false);
            m.Result = (IntPtr)1;
            return;
        }
        base.WndProc(ref m);
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...