Reputation: 947
I have a child window in a parent window. I want the child window not go out of the parent border when I drag and move the child window.
Here is my current working code in child's callback:
case WM_MOVE:
RECT rect = getLocalCoordinates(hWnd);
RECT rectFather;
GetWindowRect(hWndFather, &rectFather);
if (rect.left < 0)
rect.left = 0;
if (rect.top < 0)
rect.top = 0;
if (rect.bottom > rectFather.bottom - rectFather.top - 60)
rect.top = rectFather.bottom - rectFather.top - 341;
if (rect.right > rectFather.right - rectFather.left - 35)
rect.left = rectFather.right - rectFather.left - 110;
SetWindowPos(hWnd, NULL,rect.left, rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
break;
The only thing I miss is that when dragging my child window over the parent border, the child window keeps blinking.
It is because the child window first moved out of border, than the WM_MOVE
message triggers my SetWindowPos
.
My question is: how could I prevent this, maybe by overriding the mouse drag event?
Upvotes: 2
Views: 2882
Reputation: 65
From what I understand, the better and simpler solution for this would be when you are creating the child window, which is when calling the "CreateWindow()" method.
Under "dwStyle" parameter, you can set the child's style to WS_CHILD | WS_OVERLAPPEDWINDOW | WS_VISIBLE
Example: CreateWindow(lpClassName, lpWindowName, WS_CHILD | WS_OVERLAPPEDWINDOW | WS_VISIBLE, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
where:
lpClassName
= child's window class name,
lpWindowName
= child's window name,
x
= child window x position,
y
= child window y position,
nWidth
= child window width,
nHeight
= child window height,
hWndParent
= parent window of the child's window,
hMenu
= nullptr | identifier of the child window,
hInstance
= nullptr,
pParam
= nullptr.
Upvotes: 0
Reputation: 51355
While handling the WM_WINDOWPOSCHANGING it is possible to confine window movement, it has the unpleasant effect to break the visual connection between the mouse cursor and the dragged window, once you move the mouse outside the allowed area.
Another solution to the problem is to confine the cursor movement, by calling ClipCursor, passing in an appropriately sized bounding rectangle. This ensures that the cursor will always be in the same location relative to the dragged window.
Upvotes: 3
Reputation: 947
Thanks to RbMm, WM_WINDOWPOSCHANGING
message is what I need.
The new working code:
case WM_WINDOWPOSCHANGING:
WINDOWPOS *pos = (WINDOWPOS *)lParam;
RECT rectFather;
GetWindowRect(hWndFather, &rectFather);
if (pos->x < 0)
pos->x = 0;
if (pos->y < 0)
pos->y = 0;
if (pos->y > rectFather.bottom - rectFather.top - 341)
pos->y = rectFather.bottom - rectFather.top - 341;
if (pos->x > rectFather.right - rectFather.left - 110)
pos->x = rectFather.right - rectFather.left - 110;
break;
Upvotes: 3