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
相关产品推荐
相关产品推荐

