DLGCBR32 示例:演示如何向对话框添加状态栏和工具栏

更新:2007 年 11 月

DLGCBR32 示例阐释如何将状态栏和工具栏添加到对话框。另外,它还说明若干与将无模式对话框用作 MFC 应用程序主窗口有关的方法。

在 MFC 应用程序中,可以将控制条(如状态栏和工具栏)附加到框架窗口。然而,对于很多应用程序来说,一个基于对话框的简单用户界面已足够了。MFC 不提供将控制条添加到对话框的内置支持。

安全说明:

提供该示例代码是为了阐释一个概念,并不代表着最安全的编码实践,因此不应在应用程序或网站中使用该示例代码。对于超出本示例代码的预期用途以外的使用所造成的偶然或继发性损失,Microsoft 不承担任何责任。

获取示例和安装示例的说明:

  • 在 Visual Studio 的“帮助”菜单上,单击“示例”。

    有关更多信息,请参见定位示例文件

  • 示例的最新版本和完整列表可以从 Visual Studio 2008 Samples page(Visual Studio 2008 示例页面)联机获取。

  • 还可以在计算机的硬盘上查找示例。默认情况下,示例和自述文件将复制到 \Program Files\Visual Studio 9.0\Samples\ 下的文件夹中。对于 Visual Studio 速成版,所有示例都位于联机位置。

生成并运行示例

生成并运行 DLGCBR32 示例

  1. 打开解决方案 Dlgcbr32.sln。

  2. 在“生成”菜单中单击“生成”。

  3. 在“调试”菜单中,单击“开始执行(不调试)”。

将控制条添加到对话框

若要将控制条添加到对话框,请照常创建一个控制条,然后在对话框的工作区内为控制条留出空间。为使控制条正常运行,对话框必须复制框架窗口的某些功能。如果希望 ON_UPDATE_COMMAND_UI 处理程序适用于控制条,还需要派生新控制条类并处理 WM_IDLEUPDATECMDUI 消息。如果对话框不是应用程序的主窗口,则还需要修改它的父框架窗口,以将 WM_IDLEUPDATECMDUI 消息传递给对话框的控制条。

若要在对话框的工作区内为控制条留出空间,请在对话框的 OnInitDialog 函数中遵循下列步骤:

  1. 创建控制条。使用 RepositionBars 的 reposQuery 选项确定控制条将占用的空间量。

    CRect rcClientStart;
    CRect rcClientNow;
    GetClientRect(rcClientStart);
    RepositionBars(AFX_IDW_CONTROLBAR_FIRST,
                   AFX_IDW_CONTROLBAR_LAST,
                   0, reposQuery, rcClientNow);
    
  2. 在对话框中移动控件,确定控制条在工作区的顶部或左侧占用的空间。如果对话框包含菜单,则还需确定菜单占用的空间。

    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();
        }
    
  3. 根据控制条占用的空间量,增加对话框窗口的尺寸。

    CRect rcWindow;
    GetWindowRect(rcWindow);
    rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
    rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
    MoveWindow(rcWindow, FALSE);
    
  4. 使用 RepositionBars 定位控制条。

若要用菜单项文本更新状态栏的第一个窗格,必须处理对话框类中的 WM_MENUSELECTWM_ENTERIDLEWM_SETMESSAGESTRINGWM_POPMESSAGESTRING。需要为这些消息复制 CFrameWnd 处理程序的功能。有关这些消息处理程序的示例,请参见示例程序中的 CModelessMain 类。

若要显示工具栏按钮的工具提示,必须处理 TTN_NEEDTEXTWTTN_NEEDTEXTA 通知。

若要使 ON_UPDATE_COMMAND_UI 处理程序可以适用于其他状态栏窗格和工具栏按钮,必须派生新的控制条类并实现 WM_IDLEUPDATECMDUI 的消息处理程序。这是必需的,因为 OnUpdateCmdUI 的默认控制条实现假定父窗口是框架窗口。然而,OnUpdateCmdUI 除了向只需要 CCmdTarget 指针的函数传递父窗口指针外,不执行其他任何操作。因此,可以临时通知 OnUpdateCmdUI 给它提供的父窗口指针是 CFrameWnd 指针以满足编译器要求。例如:

LRESULT CDlgToolBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM lParam)
{
   if (IsWindowVisible())
   {
      CFrameWnd* pParent = (CFrameWnd*)GetParent();
      if (pParent)
         OnUpdateCmdUI(pParent, (BOOL)wParam);
   }
   return OL;
}

若要将 WM_IDLEUPDATECMDUI 消息传递给主窗口以外的对话框,请在框架窗口类中保存对话框指针并在该类中创建 WM_IDLEUPDATECMDUI 处理程序。该处理程序应使用 CWnd::SendMessageToDescendantsWM_IDLEUPDATECMDUI 消息发送给对话框的子窗口。然后在框架窗口内对消息执行默认处理。

说明:

某些示例(如此示例)尚未经过修改以反映 Visual C++ 向导、库和编译器中所做的更改,但仍演示了如何完成所需的任务。

请参见

其他资源

MFC 示例