如何让最大化状态下的无边框Windows Form窗体禁止调整大小
解决Windows Form无边框窗体最大化时仍可调整大小的问题
这个问题我之前做无边框窗体时也碰到过,核心思路很简单:在处理窗口消息时,先判断窗体是否处于最大化状态——如果是,直接告诉系统鼠标处于客户区域,就能避免触发边缘调整大小的逻辑。
你只需要在现有的WndProc方法里添加一个最大化状态的判断,修改后的完整代码如下:
protected override void WndProc(ref Message m) { const int RESIZE_HANDLE_SIZE = 10; const int WM_NCHITTEST = 0x0084; const int HTCLIENT = 0x01; // 先判断是否处于最大化状态,如果是,直接返回客户区标识 if (this.WindowState == FormWindowState.Maximized) { if (m.Msg == WM_NCHITTEST) { m.Result = (IntPtr)HTCLIENT; return; } } // 保留原有的非最大化状态下的调整大小逻辑 switch (m.Msg) { case WM_NCHITTEST: base.WndProc(ref m); if ((int)m.Result == HTCLIENT) { Point screenPoint = new Point(m.LParam.ToInt32()); Point clientPoint = this.PointToClient(screenPoint); if (clientPoint.X <= RESIZE_HANDLE_SIZE && clientPoint.Y <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)13; // HTTOPLEFT else if (clientPoint.X >= this.ClientSize.Width - RESIZE_HANDLE_SIZE && clientPoint.Y <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)14; // HTTOPRIGHT else if (clientPoint.X <= RESIZE_HANDLE_SIZE && clientPoint.Y >= this.ClientSize.Height - RESIZE_HANDLE_SIZE) m.Result = (IntPtr)16; // HTBOTTOMLEFT else if (clientPoint.X >= this.ClientSize.Width - RESIZE_HANDLE_SIZE && clientPoint.Y >= this.ClientSize.Height - RESIZE_HANDLE_SIZE) m.Result = (IntPtr)17; // HTBOTTOMRIGHT else if (clientPoint.X <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)10; // HTLEFT else if (clientPoint.X >= this.ClientSize.Width - RESIZE_HANDLE_SIZE) m.Result = (IntPtr)11; // HTRIGHT else if (clientPoint.Y <= RESIZE_HANDLE_SIZE) m.Result = (IntPtr)12; // HTTOP else if (clientPoint.Y >= this.ClientSize.Height - RESIZE_HANDLE_SIZE) m.Result = (IntPtr)15; // HTBOTTOM } return; default: base.WndProc(ref m); break; } }
关键逻辑说明:
WM_NCHITTEST消息是系统用来检测鼠标位置对应的窗口区域的,我们在处理它之前先检查WindowState是否为Maximized。如果是,就把消息结果设为HTCLIENT(客户区),这样系统会认为鼠标在窗体内容区域,不会触发边缘调整大小的操作。- 原有的边缘检测逻辑只会在窗体处于正常状态时生效,完美保留了非最大化时的可调整大小功能。
修改后,你的窗体在最大化状态下就会完全“冻结”,鼠标移到边缘不会出现调整大小的光标,只有恢复到正常状态时才能继续调整尺寸。
内容的提问来源于stack exchange,提问作者Siddharth Chabra
相关产品推荐
相关产品推荐

