Binding the Resizing Behavior of Dialog and Control

Environment: Visual C++ 6.0

Using a resizable dialog is a great way to make a dialog behave like a traditional window,
but sometimes there’s a need to have a control resize along with the dialog, particularily when you’re attempting to use the
control as a psuedo-document view. Here’s one solution on how to make the control’s resizing behavior follow that of the
dialog’s. Because dialogs and controls inherit from CWnd, we’ll use that knowledge to our advantage in order to attain the
desired behavior. We’ll hook into the dialog’s WM_SIZE message, override the default
message handler, and pass the dialog’s updated size information on to the control. With this information we can then resize
the control to completely fill the dialog client area, ensuring that the control will always fill the dialog client area
regardless of the dialog size or what method was used to resize it.

Warning: This example is not intended for dialogs that contain multiple controls. While some of the steps of this example
may apply to a solution for controlling the positioning of multiple controls in a dialog, that subject is beyond the scope
of this example.

Step One:
First, we’ll need to set up our example by creating a resizable dialog that contains one control. In keeping with the theme
of a psuedo-document view, we’ll use the CEditBox control for our example.
Fire up VC++ and create a new Dialog based App Wizard (.exe) project. Name it “Example”. Remove all of the controls from the
dialog (buttons and static text). Right click on the dialog and set the properties to include the following – Style:
overlapping, Border: resizing, System Menu, Minimize/Maximize box, and ensure that Visible is checked. Now place a CEditBox
control on the dialog form. Resize the CEditBox control so that it covers the entire dialog form. Right click on the control
and set the properties to include the following – Multiline, Visible, Auto HScroll, and AutoVScroll.
Now that we have all the things in place that are needed to explore a solution, let’s test what we have so far. Execute the
program and resize the dialog by dragging it’s border, and by using the maximize and restore buttons. The dialog resizes as
a typical window should. But the CEditBox control always remains the same size and in a fixed position. Let’s fix this
behavior to match that of the dialog’s.

Step Two:
We need a way of manipulating the CEditBox control’s size attributes at runtime, so let’s set up a control member variable.
Open Class Wizard and select the Member Variables tab. Make sure CExampleDlg is the current class. Click on your control’s
ID. If you can’t remember what it was, you’ll be able to find it in the CEditBox control’s properties (see Step One). Now
click Add Variable. When the dialog box appears, ensure that the category is “control”. Finally, name your control variable
“m_editbox” and click OK to add the variable. Click OK to close the Class Wizard.

Step Three:
Next, we need a way to let the CEditBox control know that the dialog has been resized and that it needs to resize itself,
too. We’ll do this by overriding the default message handler of the dialog’s OnSize message. This method is called whenever
the dialog is resized, and this is exactly where we want to implement our new control behavior. In the developer studio, go
to Class View and right click on the CExampleDlg class. Select Add Windows Message Handler. When the dialog box appears,
select WM_SIZE and make sure the Class or Object to handle is set to CExampleDlg. Click Add and Edit.

Step Four:
The last thing we need to do before re-testing our example is to add the code for the desired behavior to our message handler.


void CExampleDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here

// ADD THE FOLLOWING CODE

CRect rect;
GetWindowRect(&rect);
m_editbox.SetWindowPos(&m_editbox,
0, 0,
rect.right,
rect.bottom,
SWP_NOZORDER | SWP_SHOWWINDOW);
}

Step Five:
Execute the program. Resize the dialog.

Let’s take a closer look at the code and see how it works:


// call the default message handler
CDialog::OnSize(nType, cx, cy);

// create an instance of the CRect object
CRect rect;

// store the dialog’s new size information in the object
GetWindowRect(&rect);

// set the control size to match the dialog client area size
m_editbox.SetWindowPos(&m_editbox,
0, 0,
rect.right,
rect.bottom,
SWP_NOZORDER | SWP_SHOWWINDOW);

Note: the SWP_NOZORDER flag must be included or the control will not resize. The flag causes the first parameter of
SetWindowPos to be ignored and retains the current z-order of the window. In the example the first parameter is a reference
to m_editbox, but this parameter can be any valid pointer to CWnd or a class that inherits from it.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read