Constraining window position to desktop working ar

2019-05-16 16:16发布

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?

4条回答
做个烂人
2楼-- · 2019-05-16 16:33

WM_GETMINMAXINFO is what you seem to be looking for.

查看更多
戒情不戒烟
3楼-- · 2019-05-16 16:44

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.

查看更多
神经病院院长
4楼-- · 2019-05-16 16:45

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, send WM_GETMINMAXINFO and then WM_SIZE or WM_MOVE messages.

Anyway, handle WM_WINDOWPOSCHANGING to filter both user, and code, based attempts to position a window out of bounds.

查看更多
ゆ 、 Hurt°
5楼-- · 2019-05-16 16:45

You can do this by handling the WM_MOVING message and changing the RECT pointed to by the lParam.

lParam: Pointer to a RECT structure with the current position of the window, in screen coordinates. To change the position of the drag rectangle, an application must change the members of this structure.

you may also want to handle WM_ENTERSIZEMOVE to know when the window is beginning to move, and WM_EXITSIZEMOVE

查看更多
登录 后发表回答