CMDIFrameWnd 类

提供 Windows 多文档界面 (MDI) 框架窗口功能,并提供管理窗口的成员。

语法

class CMDIFrameWnd : public CFrameWnd

成员

公共构造函数

名称 描述
CMDIFrameWnd::CMDIFrameWnd 构造一个 CMDIFrameWnd

公共方法

名称 描述
CMDIFrameWnd::CreateClient 为此 CMDIFrameWnd 创建 Windows MDICLIENT 窗口。 由 CWndOnCreate 成员函数调用。
CMDIFrameWnd::CreateNewChild 创建一个新的子窗口。
CMDIFrameWnd::GetWindowMenuPopup 返回窗口弹出菜单。
CMDIFrameWnd::MDIActivate 激活其他 MDI 子窗口。
CMDIFrameWnd::MDICascade 以级联格式排列所有子窗口。
CMDIFrameWnd::MDIGetActive 检索当前活动的 MDI 子窗口,以及指示子窗口是否最大化的标志。
CMDIFrameWnd::MDIIconArrange 排列所有最小化的文档子窗口。
CMDIFrameWnd::MDIMaximize 最大化 MDI 子窗口。
CMDIFrameWnd::MDINext 立即激活当前活动子窗口后面的子窗口,并将当前活动子窗口置于所有其他子窗口后面。
CMDIFrameWnd::MDIPrev 激活上一个子窗口,并将当前处于活动状态的子窗口置于其后面。
CMDIFrameWnd::MDIRestore 从最大化或最小化大小还原 MDI 子窗口。
CMDIFrameWnd::MDISetMenu 替换 MDI 框架窗口菜单、窗口弹出菜单或两者的菜单。
CMDIFrameWnd::MDITile 以平铺格式排列所有子窗口。

注解

若要为应用程序创建有用的 MDI 框架窗口,请从 CMDIFrameWnd 派生一个类。 将成员变量添加到该派生类,以存储特定于应用程序的数据。 可派生类中实现消息处理程序成员函数和消息映射,以指定在消息定向到窗口时所发生的情况。

可以通过调用 CFrameWndCreateLoadFrame 成员函数来构造 MDI 框架窗口。

在调用 CreateLoadFrame 之前,必须使用 C++ new 运算符在堆上构造框架窗口对象。 在调用 Create 之前,还可以向 AfxRegisterWndClass 全局函数注册窗口类,以设置框架的图标和类样式。

使用 Create 成员函数将框架的创建参数作为即时自变量传递。

LoadFrame 需要的自变量少于 Create,并且是从资源检索其大部分默认值,包括框架的标题、图标、快捷键表和菜单。 若要由 LoadFrame 访问,所有这些资源都必须具有相同的资源 ID(例如 IDR_MAINFRAME)。

虽然 MDIFrameWnd 派生自 CFrameWnd,但派生自 CMDIFrameWnd 的框架窗口类不需要使用 DECLARE_DYNCREATE 声明。

CMDIFrameWnd 类从 CFrameWnd 中继承了其大部分默认实现。 有关这些功能的详细列表,请参阅 CFrameWnd 类说明。 CMDIFrameWnd 类具有下列附加功能:

  • MDI 框架口管理 MDICLIENT 窗口,与控件条结合对其进行重新定位。 MDI 客户端窗口是 MDI 子框架窗口的直接父级。 在 CMDIFrameWnd 上指定的 WS_HSCROLL 和 WS_VSCROLL 窗口样式会应用于 MDI 客户端窗口而不是主框架窗口,以便用户可以滚动 MDI 工作区(例如在 Windows 程序管理器中)。

  • MDI 框架窗口拥有一个默认菜单,该菜单可在没有活动 MDI 子窗口时用作菜单栏。 当存在活动状态的 MDI 子级时,MDI 框架窗口的菜单栏将自动替换为 MDI 子窗口菜单。

  • MDI 框架窗口与当前 MDI 子窗口(如果有的话)结合使用。 例如,命令消息在 MDI 框架窗口之前委托给当前活动的 MDI 子项。

  • MDI 框架窗口具有以下标准窗口菜单命令的默认处理程序:

    • ID_WINDOW_TILE_VERT

    • ID_WINDOW_TILE_HORZ

    • ID_WINDOW_CASCADE

    • ID_WINDOW_ARRANGE

  • MDI 框架窗口还有 ID_WINDOW_NEW 实现,用于在当前文档中创建新框架和视图。 应用程序可以重写这些默认命令实现来自定义 MDI 窗口处理。

请勿使用 C++ delete 运算符销毁框架窗口。 请改用 CWnd::DestroyWindow。 当销毁窗口时,PostNcDestroyCFrameWnd 实现删除 C++ 对象。 当用户关闭框架窗口时,默认 OnClose 处理程序将调用 DestroyWindow

有关 CMDIFrameWnd 的详细信息,请参阅框架窗口

继承层次结构

CObject

CCmdTarget

CWnd

CFrameWnd

CMDIFrameWnd

要求

标头:afxwin.h

CMDIFrameWnd::CMDIFrameWnd

构造 CMDIFrameWnd 对象。

CMDIFrameWnd();

备注

调用 CreateLoadFrame 成员函数以创建可见的 MDI 框架窗口。

示例

// Create main MDI Frame window. CMainFrame is a CMDIFrameWnd-derived
// class. The default CFrameWnd::PostNcDestroy() handler will delete this
// object when destroyed.
CMainFrame *pMainFrame = new CMainFrame;

CMDIFrameWnd::CreateClient

创建管理 CMDIChildWnd 对象的 MDI 客户端窗口。

virtual BOOL CreateClient(
    LPCREATESTRUCT lpCreateStruct,
    CMenu* pWindowMenu);

参数

lpCreateStruct
指向 CREATESTRUCT 结构的长指针。

pWindowMenu
指向窗口弹出菜单的指针。

返回值

如果成功,则不为 0;否则为 0。

注解

如果直接重写 OnCreate 成员函数,则应调用此成员函数。

示例

// The code below is from winmdi.cpp. It shows how to
// call CMDIFrameWnd::CreateClient(). CMainFrame is a
// CMDIFrameWnd-derived class.
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext * /*pContext*/)
{
   CMenu *pMenu = NULL;
   if (m_hMenuDefault == NULL)
   {
      // default implementation for MFC V1 backward compatibility
      pMenu = GetMenu();
      ASSERT(pMenu != NULL);
      // This is attempting to guess which sub-menu is the Window menu.
      // The Windows user interface guidelines say that the right-most
      // menu on the menu bar should be Help and Window should be one
      // to the left of that.
      int iMenu = pMenu->GetMenuItemCount() - 2;

      // If this assertion fails, your menu bar does not follow the guidelines
      // so you will have to override this function and call CreateClient
      // appropriately or use the MFC V2 MDI functionality.
      ASSERT(iMenu >= 0);
      pMenu = pMenu->GetSubMenu(iMenu);
      ASSERT(pMenu != NULL);
   }

   return CreateClient(lpcs, pMenu);
}

CMDIFrameWnd::CreateNewChild

创建一个新的子窗口。

CMDIChildWnd* CreateNewChild(
    CRuntimeClass* pClass,
    UINT nResource,
    HMENU hMenu = NULL,
    HACCEL hAccel = NULL);

参数

pClass
要创建的子窗口的运行时类。

nResource
与子窗口关联的共享资源的 ID。

hMenu
子窗口的菜单。

hAccel
子窗口的加速器。

备注

使用此函数可创建 MDI 框架窗口的子窗口。

示例

// CMainFrame is a CMDIFrameWnd-derived class,
// OnNewDraw is a menu command handler,
// CDrawFrame is a CMDIChildWnd-derived class.
void CMainFrame::OnNewDraw()
{
   CreateNewChild(RUNTIME_CLASS(CDrawFrame), IDR_DRAW, m_hDrawMenu,
                  m_hDrawAccel);
}

CMDIFrameWnd::GetWindowMenuPopup

调用此成员函数以获取当前名为“Window”的弹出菜单的句柄(含用于 MDI 窗口管理的菜单项的弹出菜单)。

virtual HMENU GetWindowMenuPopup(HMENU hMenuBar);

参数

hMenuBar
当前菜单栏。

返回值

如果存在,则为窗口弹出菜单;否则为 NULL。

备注

默认实现查找包含标准窗口菜单命令(例如 ID_WINDOW_NEW 和 ID_WINDOW_TILE_HORZ)的弹出菜单。

如果有不使用标准菜单命令 ID 的窗口菜单,则替代此成员函数。

示例

// CMainFrame::OnActivateFirstMDIChild() is a menu command handler for
// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It looks for the caption of the first created MDI child window from
// the Window popup menu, and then activate the child window.
void CMainFrame::OnActivateFirstMDIChild()
{
   // Get handle to the Window pop-up menu.
   CMenu *menubar = GetMenu();
   CMenu *wmenu = CMenu::FromHandle(GetWindowMenuPopup(menubar->GetSafeHmenu()));
   if (wmenu == NULL)
      return;

   // Get the caption of the first created MDI child window.
   CString caption;
   if (!wmenu->GetMenuString(AFX_IDM_FIRST_MDICHILD, caption, MF_BYCOMMAND))
      return;

   // Get the actual name of the first created MDI child window by
   // getting rid of the number and space, e.g. "&1 MDI 1".
   int pos = caption.FindOneOf(_T(" "));
   if (pos == -1)
      return;

   caption = caption.Right(caption.GetLength() - (pos + 1));

   // Get the CWnd* of the first created MDI child window by comparing
   // the caption of each MDI child window in the MDI application.
   // Activate the first created MDI child window if found.
   CMDIChildWnd *child = MDIGetActive();
   do
   {
      CString str;
      child->GetWindowText(str);
      if (str == caption)
      {
         child->MDIActivate(); // or MDIActivate(child);
         break;
      }

      child = (CMDIChildWnd*)child->GetWindow(GW_HWNDNEXT);
   } while (child);
}

CMDIFrameWnd::MDIActivate

激活其他 MDI 子窗口。

void MDIActivate(CWnd* pWndActivate);

参数

pWndActivate
指向要激活的 MDI 子窗口。

备注

此成员函数将 WM_MDIACTIVATE 消息发送到正在激活的子窗口和正在停用的子窗口。

如果用户使用鼠标或键盘将焦点更改为 MDI 子窗口,则发送相同的消息。

注意

MDI 子窗口独立于 MDI 框架窗口激活。 当框架变为活动状态时,将向最后激活的子窗口发送 WM_NCACTIVATE 消息以绘制活动窗口框架和标题栏,但它不会收到第二条 WM_MDIACTIVATE 消息。

示例

请参阅 CMDIFrameWnd::GetWindowMenuPopup 的示例。

CMDIFrameWnd::MDICascade

以级联格式排列所有 MDI 子窗口。

void MDICascade();
void MDICascade(int nType);

参数

nType
指定级联标志。 只能指定以下标志:MDITILE_SKIPDISABLED,这会阻止禁用的 MDI 子窗口进行级联。

注解

不带参数的 MDICascade 的第一个版本会级联所有 MDI 子窗口,包括禁用的子窗口。 如果为 nType 参数指定 MDITILE_SKIPDISABLED,则第二个版本可选择不级联禁用的 MDI 子窗口

示例

// CMainFrame::OnWindowCommand() is a menu command handler for
// CMainFrame class, which is a CMDIFrameWnd-derived
// class. It handles menu commands for the Windows pop-up menu.
// Its entries in the message map are of the following form:
//    ON_COMMAND_EX(ID_WINDOW_ARRANGE, &CMainFrame::OnWindowCommand)
BOOL CMainFrame::OnWindowCommand(UINT nID)
{
   switch (nID)
   {
   case ID_WINDOW_ARRANGE: // For Window\Arrange Icons menu item, arrange
      MDIIconArrange();    // all minimized document child windows.
      break;

   case ID_WINDOW_CASCADE: // For Window\Cascade menu item, arrange
      MDICascade();        // all the MDI child windows in a cascade format.
      break;

   case ID_WINDOW_TILE_HORZ:       // For Window\Tile Horizontal menu item,
      MDITile(MDITILE_HORIZONTAL); // tile MDI child windows so that
      break;                       // one window appears above another.

   case ID_WINDOW_TILE_VERT:     // For Window\Tile Vertical menu item,
      MDITile(MDITILE_VERTICAL); // tile MDI child windows so that
      break;                     // one window appears beside another.
   }

   return TRUE;
}

CMDIFrameWnd::MDIGetActive

检索当前活动的 MDI 子窗口,以及指示子窗口是否最大化的标志。

CMDIChildWnd* MDIGetActive(BOOL* pbMaximized = NULL) const;

参数

pbMaximized
指向 BOOL 返回值的指针。 如果窗口已最大化,则返回时设置为 TRUE;否则为 FALSE。

返回值

指向活动的 MDI 子窗口的指针。

示例

请参阅 CMDIChildWnd::MDIMaximize 的示例。

CMDIFrameWnd::MDIIconArrange

排列所有最小化的文档子窗口。

void MDIIconArrange();

备注

它不会影响未最小化的子窗口。

示例

请参阅 CMDIFrameWnd::MDICascade 的示例。

CMDIFrameWnd::MDIMaximize

最大化指定的 MDI 子窗口。

void MDIMaximize(CWnd* pWnd);

参数

pWnd
指向要最大化的窗口。

备注

当子窗口最大化时,Windows 会调整其大小,使其工作区填充客户端窗口。 Windows 将子窗口的“控件”菜单放在框架的菜单栏中,以便用户可以还原或关闭子窗口。 它还会将子窗口的标题添加到框架窗口标题。

如果在当前活动 MDI 子窗口最大化时激活另一个 MDI 子窗口,则 Windows 将还原当前活动子窗口并最大化新激活的子窗口。

示例

请参阅 CMDIChildWnd::MDIMaximize 的示例。

CMDIFrameWnd::MDINext

立即激活当前活动子窗口后面的子窗口,并将当前活动子窗口置于所有其他子窗口后面。

void MDINext();

注解

如果当前活动的 MDI 子窗口为最大化状态,则成员函数将还原当前活动的子窗口并将新激活的子窗口最大化。

示例

// CMainFrame::OnActivateNextWindow() is a menu command handler for
// CMainFrame class, which in turn is a CMDIFrameWnd-derived class.
// It activates the child window immediately behind the currently
// active child window and places the currently active child window
// behind all other child windows.
void CMainFrame::OnActivateNextWindow()
{
   MDINext();
}

CMDIFrameWnd::MDIPrev

激活上一个子窗口,并将当前处于活动状态的子窗口置于其后面。

void MDIPrev();

备注

如果当前活动的 MDI 子窗口为最大化状态,则成员函数将还原当前活动的子窗口并将新激活的子窗口最大化。

CMDIFrameWnd::MDIRestore

从最大化或最小化大小还原 MDI 子窗口。

void MDIRestore(CWnd* pWnd);

参数

pWnd
指向要还原的窗口。

示例

请参阅 CMDIChildWnd::MDIRestore 的示例。

CMDIFrameWnd::MDISetMenu

替换 MDI 框架窗口菜单、窗口弹出菜单或两者的菜单。

CMenu* MDISetMenu(
    CMenu* pFrameMenu,
    CMenu* pWindowMenu);

参数

pFrameMenu
指定新框架窗口菜单的菜单。 如果为 NULL,则不会更改菜单。

pWindowMenu
指定新窗口弹出菜单的菜单。 如果为 NULL,则不会更改菜单。

返回值

指向此消息所替换的框架窗口菜单的指针。 该指针可能是暂时的,不应存储起来供将来使用。

备注

调用 MDISetMenu 后,应用程序必须调用 CWndDrawMenuBar 成员函数来更新菜单栏。

如果此调用替换窗口弹出窗口菜单,则将从上一个窗口菜单中删除 MDI 子窗口菜单项,并添加到新的窗口弹出窗口菜单中。

如果 MDI 子窗口已最大化,并且此调用将替换 MDI 框架窗口菜单,则会从上一个框架窗口菜单中删除控件菜单和还原控件,并将其添加到新菜单。

如果使用框架管理 MDI 子窗口,请不要调用此成员函数。

示例

// CMdiView::OnReplaceMenu() is a menu command handler for CMdiView
// class, which in turn is a CView-derived class. It loads a new
// menu resource and replaces the main application window's menu
// bar with this new menu.
void CMdiView::OnReplaceMenu()
{
   // Load a new menu resource named IDR_SHORT_MENU. m_hDefaultMenu is
   // a member variable of CMdiDoc class (a CDocument-derived class).
   // Its type is HMENU.
   CMdiDoc *pdoc = (CMdiDoc*)GetDocument();
   pdoc->m_hDefaultMenu =
       ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_SHORT_MENU));
   if (pdoc->m_hDefaultMenu == NULL)
      return;

   // Get the parent window of this view window. The parent window is
   // a CMDIChildWnd-derived class. We can then obtain the MDI parent
   // frame window using the CMDIChildWnd*. Then, replace the current
   // menu bar with the new loaded menu resource.
   CMDIFrameWnd *frame = ((CMDIChildWnd*)GetParent())->GetMDIFrame();
   frame->MDISetMenu(CMenu::FromHandle(pdoc->m_hDefaultMenu), NULL);
   frame->DrawMenuBar();
}

 

// GetDefaultMenu() is an undocumented virtual function for
// CDocument class. It allows the document to determine which
// menu to display. m_hDefaultMenu is of type HMENU. Its value
// is initialized to NULL either in the constructor or
// CDocument::OnNewDocument(). And the menu resource is destroyed
// in the destructor to avoid having too many menus loaded at once.
HMENU CMdiDoc::GetDefaultMenu()
{
   if (m_hDefaultMenu)
      return m_hDefaultMenu;

   return COleServerDoc::GetDefaultMenu();
}

// Initialize member variable(s) in the constructor. CMdiDoc is
// a CDocument-derived class.
CMdiDoc::CMdiDoc()
{
   // Use OLE compound files
   EnableCompoundFile();

   m_hDefaultMenu = NULL; // initialize to NULL
}

// Destroy menu resource in CMdiDoc's destructor. CMdiDoc is
// a CDocument-derived class.
CMdiDoc::~CMdiDoc()
{
   if (m_hDefaultMenu)
      ::DestroyMenu(m_hDefaultMenu);
}

CMDIFrameWnd::MDITile

以平铺格式排列所有子窗口。

void MDITile();
void MDITile(int nType);

参数

nType
指定平铺标志。 此参数可为以下任一标志:

  • MDITILE_HORIZONTAL 平铺 MDI 子窗口,使一个窗口显示在另一个窗口之上。

  • MDITILE_SKIPDISABLED 阻止禁用的 MDI 子窗口平铺。

  • MDITILE_VERTICAL 平铺 MDI 子窗口,使一个窗口显示在另一个窗口旁边。

备注

不带参数的 MDITile 的第一个版本在 Windows 版本 3.1 及更高版本中垂直平铺窗口。 第二个版本根据 nType 参数的值垂直或水平平铺窗口

示例

请参阅 CMDIFrameWnd::MDICascade 的示例。

另请参阅

MFC 示例 MDI
MFC 示例 MDIDOCVW
MFC 示例 SNAPVW
CFrameWnd 类
层次结构图
CWnd 类
CMDIChildWnd 类