将窗口位置限制在桌面工作区域
我希望允许用户仅在桌面工作区域内拖动我的 Win32 窗口。换句话说,他们不应该让窗口的任何部分延伸到监视器之外,窗口也不应该与任务栏重叠。
我想以一种不会导致口吃的方式来做到这一点。处理 WM_MOVE 消息并调用 MoveWindow() 来重新定位窗口(如果窗口关闭),但我不喜欢 MoveWindow() 引起的闪烁效果。
我还尝试处理 WM_MOVING,这可以防止在移动实际发生之前通过更改目标矩形来调用 MoveWindow()。这解决了闪烁问题,但我遇到的另一个问题是,当发生拖动时,光标有时会远离窗口,从而允许用户在光标甚至不在窗口内部时拖动窗口。
如何限制我的窗口而不遇到这些问题?
I want to allow a user to drag my Win32 window around only inside the working area of the desktop. In other words, they shouldn't be able to have any part of the window extend outside the monitor(s) nor should the window overlap the taskbar.
I'd like to do it in a way that does cause any stuttering. Handling WM_MOVE messages and calling MoveWindow() to reposition the window if it goes off works, but I don't like the flickering effect that's caused by MoveWindow().
I also tried handling WM_MOVING which prevents the need to call MoveWindow() by altering the destination rectangle before the move actually happens. This resolves the flickering problem, but another issue I run into is that the cursor some times gets aways from the window when a drag occurs allowing the user to drag the window around while the cursor is not even inside the window.
How do I constrain my window without running into these issues?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Windows 最终通过 SetWindowPos 进行定位API。
SetWindowPos 首先通过发送正在调整大小或移动的窗口来验证其参数 WM_WINDOWPOSCHANGING 消息,然后是 WM_WINDOWPOSCHANGED 消息通知窗口过程更改的大小和/或位置。
DefWindowProc
对这些消息的处理是依次发送WM_GETMINMAXINFO
和WM_SIZE
或WM_MOVE
消息。不管怎样,处理
WM_WINDOWPOSCHANGING
来过滤用户和代码,基于尝试将窗口定位到越界。Windows are, ultimately, positioned via the SetWindowPos API.
SetWindowPos starts by validating its parameters by sending the window being sized or moved a WM_WINDOWPOSCHANGING message, and then a WM_WINDOWPOSCHANGED message notifying the window proc of the changed size and/or position.
DefWindowProc
handling of these messages is to, in turn, sendWM_GETMINMAXINFO
and thenWM_SIZE
orWM_MOVE
messages.Anyway, handle
WM_WINDOWPOSCHANGING
to filter both user, and code, based attempts to position a window out of bounds.请记住,具有多显示器设置的用户的桌面可能会延伸到负 x 和 y 坐标,或者不是矩形。此外,一些用户使用替代窗口管理器,例如 LiteStep,它通过将桌面移出屏幕来实现虚拟桌面;如果您尝试解决此问题,您的应用程序将对这些用户造成破坏。
Keep in mind that users with multi-monitor setups may have a desktop that extends into negative x- and y-coordinates, or that is not rectangular. Also, some users use alternative window managers such as LiteStep, which implement virtual desktops by moving them off-screen; if you try to fight this, your application will break for these users.
您可以通过处理 WM_MOVING 消息来执行此操作并更改 lParam 指向的 RECT。
您可能还需要处理 WM_ENTERSIZEMOVE 来了解当窗口开始移动时,
WM_EXITSIZEMOVE
You can do this by handling the WM_MOVING message and changing the RECT pointed to by the lParam.
you may also want to handle WM_ENTERSIZEMOVE to know when the window is beginning to move, and
WM_EXITSIZEMOVE
WM_GETMINMAXINFO
似乎是您正在寻找的内容。WM_GETMINMAXINFO
is what you seem to be looking for.