65.9K
CodeProject 正在变化。 阅读更多。
Home

移动受限的对话框窗体

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.39/5 (10投票s)

2008年2月19日

CPOL

3分钟阅读

viewsIcon

73285

downloadIcon

2189

如何限制对话框窗体的移动区域。 适用于 MDI 应用程序。

引言

此代码允许您限制对话框窗体的移动区域。 我使用了 VS2008,目标框架是 2.0,但如果更改为 3.0 或 3.5,它也能正常工作

背景

这个想法来自 C# 消息板上的一篇帖子。 发帖人的老板抱怨说,对话框窗体没有包含在他为他开发的 MDI 应用程序中。

我最初的想法是“他有什么问题?”,但稍加思考后,我有点同意他的看法。 我们开发 MDI 应用程序是为了能够在同一个定义的环境中拥有多个窗口。 为什么任何对话框不应该也被限制在其中呢?

最初两个显而易见的事情是处理 MoveLocationChanged 事件,但这两个事件都发生在窗体移动之后,因此窗体“跳回” - 不是很优雅。 解决方案来自重写 WndProc 并捕获一些 Windows 消息。 一点点 Marshalling,就这样。

实际上,限制窗体的移动相当简单,但稍微复杂的是,即使窗体停止了,鼠标光标仍然继续移动。

使用代码

所有代码都有注释,应该是不言自明的。

Form1 中,将对话框要限制到的相关 Form 传递给 Form2(受限制的对话框)构造函数。 我在源代码/演示中提供了三个不同的例子。 还有一个第四个例子,它创建一个子窗体 (Form3),该窗体又在点击按钮时调用 Form2

Form2 是真正发生的地方。 重写了三个 Windows 消息:WM_NCLBUTTONDOWNWM_ENTERSIZEMOVEWM_MOVING

当标题栏( 客户端 区域)被键单击时,会发生 WM_NCLBUTTONDOWN。 在这里,我根据提供的限制、大小、对话框的位置和光标的当前位置,设置了一个适合光标的矩形。

WM_ENTERSIZEMOVE 发生时,我只是将光标剪裁到上面设置的矩形。

当移动窗体时,会重复发送 WM_MOVING。 每次收到此消息时,都会将左、上、右和下坐标与传递的矩形进行比较,如果超出限制,则使用 Marshalling 来禁止移动。

用法

可能,使用此方法最简单的方法是将 Form2 保存为模板,这样就可以根据需要在项目中轻松添加多次。

致谢

感谢 Luc Pattyn 最初帮助我找到了 WndProc,以及 Harvey Saayman 提出了最初的问题!

Bug

如果使用箭头键移动窗体,则不会完全按照预期响应(我将继续研究这个问题)。

历史

  • 2008 年 2 月 19 日 v1.00。
  • 2008 年 2 月 22 日 v.1.01:添加了一个 MDI 子示例来解决 Harvey 的问题,在下面的消息中。 我将很多代码从调用窗体移到对话框窗体(这样更有意义),并添加了关闭按钮禁用和边框宽度允许的选项。
  • 2008 年 2 月 25 日 v1.02:添加了启用、禁用或隐藏窗体的系统上下文菜单关闭项的选项(以及禁用关闭按钮),并且如果上面禁用或隐藏,则禁用通过 Alt+F4 关闭。
© . All rights reserved.