You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm:FormBorderStyle=None时如何实现窗体可缩放?

隐藏窗体标题栏同时保留缩放功能的实现技巧

当把FormBorderStyle设为None隐藏标题栏后,默认会失去缩放功能,以下是两种实用实现方式:

方法一:重写WndProc拦截系统消息

通过拦截Windows系统消息WM_NCHITTEST,让窗体的边缘区域被系统识别为可缩放的边框,从而保留原生缩放体验。

在窗体类中添加以下代码:

protected override void WndProc(ref Message m)
{
    const int WM_NCHITTEST = 0x0084;
    const int HTLEFT = 10;
    const int HTRIGHT = 11;
    const int HTTOP = 12;
    const int HTTOPLEFT = 13;
    const int HTTOPRIGHT = 14;
    const int HTBOTTOM = 15;
    const int HTBOTTOMLEFT = 16;
    const int HTBOTTOMRIGHT = 17;

    base.WndProc(ref m);

    if (m.Msg == WM_NCHITTEST && (int)m.Result == 1)
    {
        Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
        pos = this.PointToClient(pos);
        if (pos.X <= 5)
            if (pos.Y <= 5)
                m.Result = (IntPtr)HTTOPLEFT;
            else if (pos.Y >= ClientSize.Height - 5)
                m.Result = (IntPtr)HTBOTTOMLEFT;
            else
                m.Result = (IntPtr)HTLEFT;
        else if (pos.X >= ClientSize.Width - 5)
            if (pos.Y <= 5)
                m.Result = (IntPtr)HTTOPRIGHT;
            else if (pos.Y >= ClientSize.Height - 5)
                m.Result = (IntPtr)HTBOTTOMRIGHT;
            else
                m.Result = (IntPtr)HTRIGHT;
        else if (pos.Y <= 5)
            m.Result = (IntPtr)HTTOP;
        else if (pos.Y >= ClientSize.Height - 5)
            m.Result = (IntPtr)HTBOTTOM;
    }
}

说明:代码中5是可缩放区域的宽度,可根据需求调整;设置FormBorderStyle = None后,运行窗体就能通过边缘拖拽缩放。

方法二:手动处理鼠标事件

通过监听鼠标的按下、移动、释放事件,手动计算窗体的大小变化,适合需要更自定义缩放逻辑的场景。

步骤如下:

  • 定义全局变量记录状态:
    private bool isResizing = false;
    private int resizeBorderWidth = 5;
    private enum ResizeDirection { None, Left, Right, Top, Bottom, TopLeft, TopRight, BottomLeft, BottomRight }
    private ResizeDirection currentResizeDir = ResizeDirection.None;
    
  • 实现MouseDown事件:
    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        currentResizeDir = GetResizeDirection(e.Location);
        isResizing = currentResizeDir != ResizeDirection.None;
        if (isResizing)
            Cursor = GetResizeCursor(currentResizeDir);
    }
    
  • 实现MouseMove事件:
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!isResizing)
        {
            var dir = GetResizeDirection(e.Location);
            Cursor = GetResizeCursor(dir);
            return;
        }
    
        switch (currentResizeDir)
        {
            case ResizeDirection.Right:
                Width = Math.Max(MinimumSize.Width, e.X);
                break;
            case ResizeDirection.Bottom:
                Height = Math.Max(MinimumSize.Height, e.Y);
                break;
            case ResizeDirection.BottomRight:
                Width = Math.Max(MinimumSize.Width, e.X);
                Height = Math.Max(MinimumSize.Height, e.Y);
                break;
            case ResizeDirection.Left:
                int newX = Left + e.X;
                int newWidth = Width - e.X;
                if (newWidth >= MinimumSize.Width)
                {
                    Left = newX;
                    Width = newWidth;
                }
                break;
            case ResizeDirection.Top:
                int newY = Top + e.Y;
                int newHeight = Height - e.Y;
                if (newHeight >= MinimumSize.Height)
                {
                    Top = newY;
                    Height = newHeight;
                }
                break;
            case ResizeDirection.TopLeft:
                newX = Left + e.X;
                newWidth = Width - e.X;
                newY = Top + e.Y;
                newHeight = Height - e.Y;
                if (newWidth >= MinimumSize.Width && newHeight >= MinimumSize.Height)
                {
                    Left = newX;
                    Width = newWidth;
                    Top = newY;
                    Height = newHeight;
                }
                break;
            case ResizeDirection.TopRight:
                newWidth = Math.Max(MinimumSize.Width, e.X);
                newY = Top + e.Y;
                newHeight = Height - e.Y;
                if (newHeight >= MinimumSize.Height)
                {
                    Top = newY;
                    Height = newHeight;
                    Width = newWidth;
                }
                break;
            case ResizeDirection.BottomLeft:
                newX = Left + e.X;
                newWidth = Width - e.X;
                newHeight = Math.Max(MinimumSize.Height, e.Y);
                if (newWidth >= MinimumSize.Width)
                {
                    Left = newX;
                    Width = newWidth;
                    Height = newHeight;
                }
                break;
        }
    }
    
  • 实现MouseUp事件:
    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        isResizing = false;
        Cursor = Cursors.Default;
        currentResizeDir = ResizeDirection.None;
    }
    
  • 辅助方法:
    private ResizeDirection GetResizeDirection(Point pos)
    {
        bool isLeft = pos.X <= resizeBorderWidth;
        bool isRight = pos.X >= ClientSize.Width - resizeBorderWidth;
        bool isTop = pos.Y <= resizeBorderWidth;
        bool isBottom = pos.Y >= ClientSize.Height - resizeBorderWidth;
    
        if (isLeft && isTop) return ResizeDirection.TopLeft;
        if (isRight && isTop) return ResizeDirection.TopRight;
        if (isLeft && isBottom) return ResizeDirection.BottomLeft;
        if (isRight && isBottom) return ResizeDirection.BottomRight;
        if (isLeft) return ResizeDirection.Left;
        if (isRight) return ResizeDirection.Right;
        if (isTop) return ResizeDirection.Top;
        if (isBottom) return ResizeDirection.Bottom;
        return ResizeDirection.None;
    }
    
    private Cursor GetResizeCursor(ResizeDirection dir)
    {
        switch (dir)
        {
            case ResizeDirection.Left:
            case ResizeDirection.Right:
                return Cursors.SizeWE;
            case ResizeDirection.Top:
            case ResizeDirection.Bottom:
                return Cursors.SizeNS;
            case ResizeDirection.TopLeft:
            case ResizeDirection.BottomRight:
                return Cursors.SizeNWSE;
            case ResizeDirection.TopRight:
            case ResizeDirection.BottomLeft:
                return Cursors.SizeNESW;
            default:
                return Cursors.Default;
        }
    }
    

说明:同样需要设置FormBorderStyle = None,运行后拖拽窗体边缘即可缩放,还可自定义缩放区域宽度和光标样式。

内容的提问来源于stack exchange,提问作者Mahbub Alam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:44:59