KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q123158: Adding Control Bars to Foundation Classes Dialogs

Article: Q123158
Product(s): Microsoft C Compiler
Version(s): 1.0,1.5,1.51,2.0
Operating System(s): 
Keyword(s): kbfile kbProgramming kbSample kbMFC kbToolbar KbUIDesign kbVC kbFAQ kbGrpDSMFCATL
Last Modified: 11-FEB-2002

-------------------------------------------------------------------------------
The information in this article applies to:

- The Microsoft Foundation Classes (MFC), used with:
   - Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5, 1.51 
   - Microsoft Visual C++, 32-bit Editions, version 2.0 
-------------------------------------------------------------------------------

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-based user interface is sufficient. MFC does not
provide built-in support for adding control bars to dialogs.

DLGCBR is a sample application that demonstrates how to add a status bar and
toolbar to a dialog. In addition, it demonstrates a number of techniques related
to using a modeless dialog as the main window of an MFC application.

The following files are available for download from the Microsoft Download
Center:

Dlgcbr.exe

For additional information about how to download Microsoft Support files, click
the article number below to view the article in the Microsoft Knowledge Base:

  Q119591 How to Obtain Microsoft Support Files from Online Services

Microsoft used the most current virus detection software available on the date of
posting to scan this file for viruses. Once posted, the file is housed on secure
servers that prevent any unauthorized changes to the file.


For additional information on Visual C++ versions 4.0 and greater, please see the
following article in the Microsoft Knowledge Base:

  Q141751 Adding Control Bars to Dialog Boxes in MFC

MORE INFORMATION
================

To add a control bar to a dialog, you must create the control bar as usual, and
then make room for the control bar within the client area of the dialog. For the
control bar to function properly, the dialog 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 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's control bars.

To make room for a control bar within the client area of the dialog, follow these
steps in your dialog's OnInitDialog() function:

1. Create the control bars.

2. 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);

3. Move all the controls in your dialog to account for space used by control
  bars at the top or left of the client area. If your dialog contains a menu,
  you also need to account for the space used by the menu:

     CPoint ptOffset(rcClientStart.left - rcClientNow.left,
                     rcClientStart.top - rcClientNow.top);
     ptOffset.y += ::GetSystemMetrics(SM_CYMENU);

     CRect rcChild;
     CWnd* pwndChild = GetWindow(GW_CHILD);
     while (pwndChild)
     {
        pwndChild->GetWindowRect(rcChild);
        rcChild.OffsetRect(ptOffset);
        pwndChild->MoveWindow(rcChild, FALSE);
        pwndChild = pwndChild->GetNextWindow();
     }

4. Increase the dialog 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);

5. 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 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 dialogs 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: CDialog CStatusBar CToolBar kbMFCCtrlBars

======================================================================
Keywords          : kbfile kbProgramming kbSample kbMFC kbToolbar KbUIDesign kbVC kbFAQ kbGrpDSMFCATL 
Technology        : kbAudDeveloper kbMFC
Version           : :1.0,1.5,1.51,2.0

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.