保持窗体在C#中缩放时的纵横比

5

如何使一个表单具有固定的宽高比,在调整大小时保持不变?

我知道可以通过重写 OnSizeChanged 并手动修改 [new] 高度/宽度来实现,但这会导致闪烁,因为在事件被调用之前它会被重新调整大小一次(尺寸与宽高比不匹配),然后再次调整大小(到正确的宽高比)。是否有更好的方法?

1个回答

12

以下是一些代码供您参考。关键在于响应 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;
    }
}

哎呀,我不是想包含 WM_MOVING 的。 - Hans Passant
谢谢,这就做到了。不过我希望有更好的方法来处理拖动角落。 - yoyoyoyosef
1
// 保持窗口为正方形 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接