Creating a window with size restraints is an easier task than you might initially think. Interestingly enough, it only involves overriding the WM_GETMINMAXINFO
event handler. Since the user resizes a frame window that contains a view (rather than resizing the view itself), we need to add this override to the appropriate parent frame class. This is, in most cases, usually the CMainFrame
class, so this article will use that as the example. Here is how we handle limiting the size of an SDI program to a minimum of 600 pixels by 300 pixels:
void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
CFrameWnd::OnGetMinMaxInfo(lpMMI);
lpMMI->ptMinTrackSize.x = 600;
lpMMI->ptMinTrackSize.y = 300;
}
First, we allow the default window processing to fill in the lpMMI
structure (which keeps information on how large or small a window can get). Then, we simply modify the size fields in this structure to limit the window's size. The ptMinTrackSize
field is where the minimum window size information is kept. Likewise, the ptMaxTrackSize
field is where the maximum window size information is kept. You would therefore use that field to keep a window from becoming too large.
Handling Child Windows
Let's look at an example of this field in an MDI based application that limits the size of its child windows:
void CChildFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
CFrameWnd::OnGetMinMaxInfo(lpMMI);
// Calculate the nonclient overhead of the frame window
CRect client;
GetClientRect(&client);
CRect window;
GetWindowRect(&window);
int widthOverhead = window.Width() - client.Width();
int heightOverhead = window.Height() - client.Height();
lpMMI->ptMaxTrackSize.x = 800 + widthOverhead;
lpMMI->ptMaxTrackSize.y = 600 + heightOverhead;
}
Here we are calculating the "nonclient" overhead associated with the parent frame: toolbars, scroll bars, frame widths, etc. Then we limit the maximum size of a child window to 800 pixels by 600 pixels. Fairly simple, right? Using this method, child windows can be limited just like their parents.