如何阻止双击窗口标题栏将FormBorderStyle.FixedToolWindow窗口最大化?

19
我很烦恼,因为我被承诺一个用户无法调整大小的固定窗口,但当然他们可以双击标题栏将这个“不可调整大小”的窗口最大化。我该如何关闭这个功能?我能用winforms代码做到吗,还是必须回到Win32?
谢谢!
6个回答

33

您可以将表单的MaximizeBox属性设置为false。


1
我没有想到这样做,因为可点击的“最大化按钮”已经隐藏在这个边框样式中了。 - Isaac Bolinger
5
不要为我提供DoubleClick的帮助。 - Petr
2
当您使用 ControlBox = false 从窗体中删除所有按钮时,此答案也非常有用。需要同时设置两个属性才能正确执行。 - ygoe
2
令人沮丧的是,这只是隐藏了指定的框/控件。它并没有删除或禁用底层功能,双击标题栏仍将正常工作。 - NetXpert

24

你可以在一般情况下禁用标题栏的双击消息(或更改默认行为,即最大化窗口),它适用于任何FormBorderStyle:

private const int WM_NCLBUTTONDBLCLK = 0x00A3; //double click on a title bar a.k.a. non-client area of the form

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_NCLBUTTONDBLCLK)
            {
                m.Result = IntPtr.Zero;
                return;
            }
            base.WndProc(ref m);
        }

MSDN源代码

干杯!


1
这就是实际答案,仅仅移除最大化框或控件并不能阻止事件的发生。 - tfcmad

9

/// /// 我们正在覆盖基本的WIN32窗口过程,以防止通过鼠标移动窗体以及通过鼠标双击调整窗体大小。 /// ///

    protected override void WndProc(ref Message m)
    {
        const int WM_SYSCOMMAND = 0x0112;
        const int SC_MOVE = 0xF010;
        const int WM_NCLBUTTONDBLCLK = 0x00A3; //double click on a title bar a.k.a. non-client area of the form

        switch (m.Msg)
        {
            case WM_SYSCOMMAND:             //preventing the form from being moved by the mouse.
                int command = m.WParam.ToInt32() & 0xfff0;
                if (command == SC_MOVE)
                    return;
                break;
        }

       if(m.Msg== WM_NCLBUTTONDBLCLK)       //preventing the form being resized by the mouse double click on the title bar.
        {
            m.Result = IntPtr.Zero;                   
            return;                   
        }

        base.WndProc(ref m);
    }

3

我知道我来晚了,但这可能会帮助正在寻找同样信息的人。

private const int WM_NCLBUTTONDBLCLK = 0x00A3; //double click on a title bar a.k.a. non-client area of the form

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{

    switch (msg)
    {                
        case WM_NCLBUTTONDBLCLK:    //preventing the form being resized by the mouse double click on the title bar.
            handled = true;
            break;                
        default:
            break;
    }
    return IntPtr.Zero;
}

3

我刚在VB.Net中检查过了。以下代码对我有效。

Private Const Win_FormTitleDoubleClick As Integer = 163

Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg = Win_FormTitleDoubleClick Then
        m.Result = IntPtr.Zero
        Return
    End If
    MyBase.WndProc(m)
End Sub

注意:163是事件代码。

0
我稍微以不同的方式解决了这个问题。首先,我通过MaximizeBoxMinimizeBox属性从控制框中删除了最小化和最大化选项,就像您所期望的那样。
然后,我添加了以下OnResizeEnd()事件,并将其附加到窗体的ResizeEnd事件处理程序中:
/// <summary>Locks the form to fill the screen that it's placed on and remain in that state as long as it's open.</summary>
private void GuiMain_ResizeEnd( object sender, EventArgs e )
{
    this.Location = Screen.WorkingArea.Location;
    this.Size = Screen.WorkingArea.Size;
    this.MaximizedBounds = Screen.WorkingArea;
    this.MinimumSize = Screen.WorkingArea.Size;
    this.WindowState = FormWindowState.Normal;
}

这个解决方案必须依赖于以下访问器的存在,您可以复制它,或者您可以简单地将上面的每个实例中的Screen.替换为Screen.FromHandle( this.Handle ).

protected Screen Screen => Screen.FromHandle( this.Handle );

显然,具有讽刺意味的是,这实际上将表单保持在FormWindowState.Normal状态,但它模仿了最大化的效果,并在任何尝试更改它后重置此全屏状态。

有趣的是,由于使用了Screen.FromHandle()设置(而不是硬编码的设置),您实际上可以将表单从一个显示器拖动到另一个显示器,然后它立即“捕捉”以填充那个屏幕。我发现这很方便,但如果您不希望在应用程序中使用该功能,则可能需要额外的代码进行更正。


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