3

我想让用户只在桌面的工作区域内拖动我的 Win32 窗口。换句话说,他们不应该让窗口的任何部分延伸到监视器之外,也不应该让窗口与任务栏重叠。

我想以一种确实会导致口吃的方式来做。处理 WM_MOVE 消息并调用 MoveWindow() 以在窗口关闭时重新定位窗口有效,但我不喜欢由 MoveWindow() 引起的闪烁效果。

我还尝试处理 WM_MOVING,它通过在实际发生移动之前更改目标矩形来防止调用 MoveWindow() 的需要。这解决了闪烁问题,但我遇到的另一个问题是,当发生拖动时光标有时会离开窗口,从而允许用户在光标甚至不在窗口内时拖动窗口。

如何在不遇到这些问题的情况下限制我的窗口?

4

4 回答 4

3

最终,Windows 是通过SetWindowPos API 定位的。

SetWindowPos 首先通过发送正在调整大小或移动窗口的WM_WINDOWPOSCHANGING消息来验证其参数,然后发送WM_WINDOWPOSCHANGED消息通知窗口 proc 已更改的大小和/或位置。

DefWindowProc对这些消息的处理是依次发送WM_GETMINMAXINFO和然后WM_SIZEWM_MOVE消息。

无论如何,处理WM_WINDOWPOSCHANGING过滤用户和代码,基于尝试将窗口定位到边界之外。

于 2010-03-09T05:24:10.937 回答
2

请记住,具有多显示器设置的用户的桌面可能会延伸到负 x 和 y 坐标,或者不是矩形的。此外,一些用户使用替代的窗口管理器,例如 LiteStep,通过将虚拟桌面移出屏幕来实现虚拟桌面;如果你试图解决这个问题,你的应用程序就会被这些用户破坏。

于 2010-03-10T00:28:25.283 回答
0

您可以通过处理WM_MOVING消息并更改 lParam 指向的 RECT 来做到这一点。

lParam:指向具有窗口当前位置的 RECT 结构的指针,以屏幕坐标表示。要更改拖动矩形的位置,应用程序必须更改此结构的成员。

您可能还想处理WM_ENTERSIZEMOVE以了解窗口何时开始移动,并且WM_EXITSIZEMOVE

于 2010-03-09T02:14:12.053 回答
0

WM_GETMINMAXINFO是您似乎正在寻找的东西。

于 2010-03-09T04:37:50.523 回答