【问题标题】:Prevent MaxSized C# WinForm from moving when being maximized防止 MaxSized C# WinForm 在最大化时移动
【发布时间】:2016-05-13 09:11:14
【问题描述】:

我有一个限制 MaxSize 的 WinForm 表单。如果我按下最大化按钮,此窗口会弹出到位置 0,0(左上角),并具有正确的 MaxSize。有没有办法防止表单移动?

我可以在表单被移动后(通过操作系统)设置一个新的位置,但是用户可以看到表单在屏幕上弹出,这不是很整洁。 (我更改了 FormName 以在此处发布代码)。 SuspendLayout 在这里没有帮助,我也不一定要禁用最大化按钮。

void frmWinForm_SizeChanged(object sender, EventArgs e)
{
    if (WindowState == FormWindowState.Maximized)
    {
        var x = ... // some calculated or original x position
        var y = ... // some calculated or original y position
        WindowState = FormWindowState.Normal;
        SetBounds(x, y, MaxSize.X, MaxSize.Y);
    }
}

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    重写 WndProc 函数。检查最大化事件。手动设置您喜欢的最大尺寸并从函数返回。这样您就可以覆盖预定义的最大化行为:

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x0112) // WM_SYSCOMMAND
        {
            if (m.WParam == new IntPtr(0xF030)) // Maximize event
            {
                Size = MaximumSize; //Set size manually and return
                return;
            }
        }
        base.WndProc(ref m);
    }
    

    这将防止最大化按钮变为标准化按钮。使用以下代码不会阻止按钮更改:

    struct MinMaxInfo
    {
        public Point ptReserved;
        public Point ptMaxSize;
        public Point ptMaxPosition;
        public Point ptMinTrackSize;
        public Point ptMaxTrackSize;
    }
    
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m); //do that first: "'Who is the boss' applies. You'd typically want to be the one that has the last say in this case."
        if (m.Msg == 0x0024) //WM_GETMINMAXINFO
        {
            MinMaxInfo minMaxInfo = (MinMaxInfo)m.GetLParam(typeof(MinMaxInfo));
            minMaxInfo.ptMaxSize.X = MaximumSize.Width; //Set size manually
            minMaxInfo.ptMaxSize.Y = MaximumSize.Height;
            minMaxInfo.ptMaxPosition.X = Location.X; //Stay at current position
            minMaxInfo.ptMaxPosition.Y = Location.Y;
            Marshal.StructureToPtr(minMaxInfo, m.LParam, true);
        }
    }
    

    【讨论】:

    • 这很好用,感谢您的快速回答。
    • 工作不正常,窗口无法恢复。改为拦截 WM_GETMINMAXINFO,更改 ptMaxPosition 值。
    • 你很快,做得很好。但是,您必须在 调用 base.WndProc() 之后执行此操作。
    • @HansPassant 我之前和之后都试过了,而且都在工作。有什么区别?
    • “谁是老板”适用。在这种情况下,您通常希望成为最后发言权。
    猜你喜欢
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2013-02-24
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    相关资源
    最近更新 更多