CMDIFrameWnd 类
提供 Windows 多文档界面 (MDI) 框架窗口功能,并提供管理窗口的成员。
语法
class CMDIFrameWnd : public CFrameWnd
成员
公共构造函数
名称 | 描述 |
---|---|
CMDIFrameWnd::CMDIFrameWnd | 构造一个 CMDIFrameWnd 。 |
公共方法
名称 | 描述 |
---|---|
CMDIFrameWnd::CreateClient | 为此 CMDIFrameWnd 创建 Windows MDICLIENT 窗口。 由 CWnd 的 OnCreate 成员函数调用。 |
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
派生一个类。 将成员变量添加到该派生类,以存储特定于应用程序的数据。 可派生类中实现消息处理程序成员函数和消息映射,以指定在消息定向到窗口时所发生的情况。
可以通过调用 CFrameWnd
的 Create 或 LoadFrame 成员函数来构造 MDI 框架窗口。
在调用 Create
或 LoadFrame
之前,必须使用 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
。 当销毁窗口时,PostNcDestroy
的 CFrameWnd
实现删除 C++ 对象。 当用户关闭框架窗口时,默认 OnClose
处理程序将调用 DestroyWindow
。
有关 CMDIFrameWnd
的详细信息,请参阅框架窗口。
继承层次结构
CMDIFrameWnd
要求
标头:afxwin.h
CMDIFrameWnd::CMDIFrameWnd
构造 CMDIFrameWnd
对象。
CMDIFrameWnd();
备注
调用 Create
或 LoadFrame
成员函数以创建可见的 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
后,应用程序必须调用 CWnd
的 DrawMenuBar 成员函数来更新菜单栏。
如果此调用替换窗口弹出窗口菜单,则将从上一个窗口菜单中删除 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 类