【发布时间】:2013-07-18 21:04:42
【问题描述】:
我正在尝试制作从工具栏弹出的无边框表单。我希望用户能够抓住右下角(“调整大小手柄”)并能够调整表单的大小,但不能以任何其他方式调整表单的大小或重新定位。
我听说我可以拦截发送到表单的WM_NCHITTEST 消息并将其结果设置为HTBOTTOMRIGHT,这将让操作系统处理表单的重新调整大小,就像它有一个相当大的框架。我的想法是检测鼠标指针是否进入了我在角落定义的框,如果进入则返回HTBOTTOMRIGHT 结果。
这并不像我预期的那样工作。我能够拦截该消息,但似乎只有当用户将鼠标光标放在表单的 1px 粗边框上时才会发送消息。这意味着它可以按照我的意愿工作,如果您将光标非常精确地定位在右下角。
这是我的WndProc 覆盖:
protected override void WndProc(ref Message m)
{
const UInt32 WM_NCHITTEST = 0x0084;
const UInt32 HTBOTTOMRIGHT = 17;
const int RESIZE_HANDLE_SIZE = 40;
bool handled = false;
if (m.Msg == WM_NCHITTEST)
{
Size formSize = this.Size;
Point screenPoint = new Point(m.LParam.ToInt32());
Point clientPoint = this.PointToClient(screenPoint);
Rectangle hitBox = new Rectangle(formSize.Width - RESIZE_HANDLE_SIZE, formSize.Height - RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE, RESIZE_HANDLE_SIZE);
if (hitBox.Contains(clientPoint))
{
m.Result = (IntPtr)HTBOTTOMRIGHT;
handled = true;
}
}
if (!handled)
base.WndProc(ref m);
}
我做错了什么还是有更好的方法来做我想做的事情?
非常感谢。
【问题讨论】:
-
我是不是在考虑这个问题,或者当您的用户将鼠标悬停在您的自定义 hitbox 上时,您不能将 FormBorderStyle 更改为 Sizeable,而当他们离开时,您就不能更改 FixedSingle 吗?处理来自 Rectangle 类的 MouseEnter 和 MouseLeave 事件。
-
@AntonSemenov:第二种解决方案绕过操作系统处理程序。第一个符合我想要的,但它不起作用。除了窗口的边缘,我没有收到
WM_NCHITTEST消息。 -
@glace:这会导致窗口边框明显改变,我真的不希望发生这种情况。
-
@Frank Weindel 我明白了。我使用了您示例中的设置,它对窗口外观没有明显影响,我想您还有其他自定义设置。
标签: c# winforms winapi window-resize