Expanding Dialogs
An expanding dialog is a dialog that can appear in two sizes. In its small size, the dialog presents the user controls that are used to perform common tasks. In its large size, the dialog presents controls that are used to perform tasks that are not used ordinarily or used only by advanced users. Window’s Calculator is an example of expanding dialog. Because it is expected that most of the users will use the calculator to carry out simple arithmetic functions, the calculator's standard dialog provides only with simple controls.
A user wanting to perform more sophisticated calculations must put the calculator in the scientific mode causing it to provide additional functions.
This behavior is desirable because we do not want to overwhelm our users with options and functions that are not applicable to the task on hand.
Implementing an expanding dialog, in principle, is very straightforward. Using the dialog editor you create a dialog containing all the controls in expanded mode and the relevant part of the dialog is displayed depending on the mode requested by the user. The important question is how do we display only a part of the dialog.
Any window is displayed on the screen within a rectangular region. In Visual C++, a rectangle is an instance of the class CRect. A rectangle is identified by specifying the offsets of its sides from x-axis and y-axis.
A window is displayed within that rectangle using the function
void MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE)
where lpRect is the rectangle within which the window must be moved (displayed) and bRepaint is a flag indicating whether or not the dialog must be repainted after the move.
If lpRect is smaller than the dialog, then windows automatically clips the dialog to fit in the specified rectangle
If lpRect is larger than the dialog then the dialog is padded into the larger rectangle.
To implement an expanding dialog, we must consider and implement two key issues:
- What are the characteristics of the display rectangle for the dialog in its expanded mode?
- What are the characteristics of the display rectangle for the dialog in its standard mode?
The rectangle within which a window is currently being displayed can be obtained by inquiring the dialog as follows:
CRect rect;
GetWindowRect(rect);
After the call to GetWindowRect, the parameter rect represents the current display rectangle. Recall that, a rectangle is identified with its displacements from x-axis and y-axis, left, top, right, and bottom. A rectangle’s, displacements is modified using the function:
void SetRect( int left, int top, int right, int bottom);
Depending on whether the dialog is designed to expand vertically or horizontally, the display rectangle’s right or bottom must be displaced by a fixed amount. Assume the current mode of the dialog is represented by a Boolean variable, “mode” and let an integer variable, “offset,” represent the desired displacement. Assuming the dialog is to expand or shrink horizontally, the following fragment would get the job done.
If (mode == STANDARD)
rect.SetRect(rect.left, rect.top, rect.right+offset, rect.bottom); //expanding the dialog
else
rect.SetRect(rect.left, rect.top, rect.right-offset, rect.bottom); //shrinking the dialog
MoveWindow(rect, TRUE);
Clearly, the correct value for the offset can be built into the program. (For example, offset = 250.)
However, hand calculating the correct value of offset is tedious and if the dialog is changed, the offset must be recalculated. A better approach would be to calculate the value of the offset during program execution as follows:
- Place a static text control (IDC_STATIC_BORDER) within the dialog at the boundary between its standard and expanded mode.
- Using the class wizard, associate a control variable, m_border, with IDC_STARTIC_BORDER
- Get the bounding rectangle of the border marker
CRect borderRect;
m_border. GetWindowRect(borderRect);
- Calculate the offset
offset = borderRect.right – rect.right
Obviously, offset needs to be calculated only once at the beginning of the program. So onInitDialog is a good place for the above code. Shrinking or expanding the dialog is done on users request. Where do you place the code for shrinking or expanding the dialog is Obvious!!
One final note. When the dialog is in standard mode, many of its controls are not visible. Not being visible means just that! They are not visible. They exist and can react to messages that they receive. They can receive focus using TAB key or respond to hot keys. You must avoid this by disabling all invisible controls.
1