Adding Control Bars to Dialog Boxes in MFC
ID: Q141751
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), used with:
-
Microsoft Visual C++, 32-bit Editions, versions 4.0, 4.1, 4.2, 5.0, 6.0
This is the 32-bit version of this sample.
SUMMARY
In a Microsoft Foundation Classes (MFC) application, you can attach
control bars such as status bars and toolbars to a frame window. However,
for many applications a simple dialog box-based user interface is
sufficient. MFC does not provide built-in support for adding control bars
to dialog boxes.
DLGCBR32 is a sample application that demonstrates how to add a status
bar and toolbar to a dialog box. In addition, it demonstrates a number of
techniques related to using a modeless dialog box as the main window of an
MFC application.
The following files are available for download from the Microsoft
Download Center. Click the file names below to download the files:
Dlgcbr32.exe
For more information about how to download files from the Microsoft
Download Center, please visit the Download Center at the following Web
address
http://www.microsoft.com/downloads/search.asp
and then click How to use the Microsoft Download Center.
MORE INFORMATION
To add a control bar to a dialog box, you must create the control bar as
usual, and then make room for the control bar within the client area of
the dialog box. For the control bar to function properly, the dialog box
must duplicate some of the functionality of frame windows. If you want
ON_UPDATE_COMMAND_UI handlers to work for the control bars, you also need
to derive new control bar classes, and handle the WM_IDLEUPDATECMDUI
message. If your dialog box is not the main window of your application,
you will also need to modify its parent frame window to pass the
WM_IDLEUPDATECMDUI message on to the dialog box's control bars.
To make room for a control bar within the client area of the dialog box,
follow these steps in your dialog box's OnInitDialog() function:
- Create the control bars.
- Figure out how much room the control bars will take by using the
reposQuery option of RepositionBars():
CRect rcClientStart;
CRect rcClientNow;
GetClientRect(rcClientStart);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,
AFX_IDW_CONTROLBAR_LAST,
0, reposQuery, rcClientNow);
- Move all the controls in your dialog box to account for space used by
control bars at the top or left of the client area. If your dialog box
contains a menu, you also need to account for the space used by the
menu:
CPoint ptOffset(rcClientNow.left - rcClientStart.left,
rcClientNow.top - rcClientStart.top);
CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);
while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild, FALSE);
pwndChild = pwndChild->GetNextWindow();
}
- Increase the dialog box window dimensions by the amount of space used
by the control bars:
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
MoveWindow(rcWindow, FALSE);
- Position the control bars using RepositionBars().
To update the first pane of a status bar with menu item text, you must
handle WM_MENUSELECT, WM_ENTERIDLE, and WM_SETMESSAGESTRING in your dialog
box class. You need to duplicate the functionality of the CFrameWnd
handlers for these messages. See the CModelessMain class in the sample
program for examples of these message handlers.
To allow ON_UPDATE_COMMAND_UI handlers to work for other status bar panes
and for toolbar buttons, you must derive new control bar classes and
implement a message handler for WM_IDLEUPDATECMDUI. This is necessary
because the default control bar implementations of OnUpdateCmdUI() assume
the parent window is a frame window. However, it doesn't do anything but
pass the parent window pointer on to a function which only requires a
CCmdTarget pointer. Therefore, you can temporarily tell OnUpdateCmdUI()
that the parent window pointer you are giving it is a CFrameWnd pointer to
meet the compiler requirements. Here's an example:
LRESULT CDlgToolBar::OnIdleUpdateCmdUI(WPARAM wParam,
LPARAM lParam)
{
if (IsWindowVisible())
{
CFrameWnd* pParent = (CFrameWnd*)GetParent();
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}
To pass WM_IDLEUPDATECMDUI messages on to dialog boxes other than the main
window, save dialog pointers in your frame window class and create a
WM_IDLEUPDATECMDUI handler in that class. The handler should send the
WM_IDLEUPDATECMDUI message on to the dialog child windows by using
CWnd::SendMessageToDescendants(). Then perform default processing for the
message within the frame window.
Additional query words:
Keywords : kbcode kbfile kbsample kbMFC KbUIDesign kbVC kbVC400 kbVC410 kbVC420 kbVC500 kbVC600 kbDialog
Version : winnt:4.0,4.1,4.2,5.0,6.0
Platform : winnt
Issue type :
|