Introduction
For most applications, dragging a window around on the screen should be mostly uninhibited. There are, however, a few scenarios where you may want to restrict the window to some bounding rectangle. In this article, I'll lay out all of the steps necessary (both of them!) to accomplish this.
Step 1
The first thing we need to do is figure out the initial size of our window so when we go to adjust the window's position in step 2, we don't accidently change its size in the process. So, in the dialog's OnInitDialog()
method, simply make a call to GetWindowRect()
like:
SetOwner(CWnd::GetDesktopWindow());
CRect rc;
GetWindowRect(rc);
m_nWidth = rc.Width();
m_nHeight = rc.Height();
Step 2
The second (and final) step is to create a handler function for the WM_MOVING
message. In that function, we first need to get the position of the parent (bounding) rectangle. Then, we adjust the (child) dialog's four sides by ensuring they fall within each side of the parent. It looks sort of "mathy," but it's really straightforward.
CRect rcParent;
GetOwner()->GetWindowRect(rcParent);
pRect->left = min(pRect->left, rcParent.right - m_nWidth);
pRect->left = max(pRect->left, rcParent.left);
pRect->top = min(pRect->top, rcParent.bottom - m_nHeight);
pRect->top = max(pRect->top, rcParent.top);
pRect->right = min(pRect->right, rcParent.right);
pRect->right = max(pRect->right, rcParent.left + m_nWidth);
pRect->bottom = min(pRect->bottom, rcParent.bottom);
pRect->bottom = max(pRect->bottom, rcParent.top + m_nHeight);
That's all there is to it.
Summary
While my example used a modal dialog owned by the desktop, this same code can be employed in situations such as an About box owned by its application, or a frame within an MDI application. The only difference lies in the parent/owner of the window being restricted.
Enjoy!