Windows 编程/MDI 程序
多文档界面 (MDI) 应用程序是十分常见且受欢迎的应用程序类型。MDI 应用程序允许一个单一的程序窗口同时包含多个打开的工作区。创建它们并不特别困难,本章将尝试详细解释这一过程。
以下步骤用于创建 MDI 应用程序。我们将解释每个步骤。
- 注册框架和子窗口类。
- 修改消息循环。
- 创建框架窗口。
- 创建 MDI 客户区
- 使用客户区创建 MDI 子窗口。
像任何其他 Windows 应用程序一样,我们需要注册窗口类。主窗口(框架,或“父”窗口)需要创建。框架窗口就像任何其他窗口一样,但它们通常具有 COLOR_APPWORKSPACE 的背景色。此外,MDI 应用程序中的子窗口不允许拥有自己的菜单,因此框架窗口必须管理应用程序菜单。请记住,不同的子窗口通常需要不同的菜单选项(或完全不同的菜单),因此框架窗口需要维护一个当前活动子窗口的记录,并相应地设置菜单。
子窗口类(所有子窗口)需要使用 WS_CHILD 类创建。MDI 应用程序可以拥有任意数量的不同类型子窗口(一个著名的例子是 Microsoft Excel 中使用电子表格和图表),它们都需要在使用前注册。
MDI 应用程序使用一个几乎正常的消息循环,但如果你想在程序中使用加速键,你需要添加一个新的步骤
while(GetMessage(&msg, hwndFrame, 0, 0)) { if(!TranslateMDISysAccel(hwndClient, &msg) && !TranslateAccelerator(hwndFrame, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
这样,加速键就会被路由到所有不同子窗口中的正确目标。如果你没有使用加速键,你就不需要担心这一步。
框架窗口的创建方式与其他窗口相同。但是,请记住,框架窗口只是子窗口中发生的动作的背景,因此你应该避免在你的背景艺术上过于疯狂或花哨。
你需要创建一个类型为“MDICLIENT”的窗口。MDICLIENT 窗口在 Windows 内部定义,因此你不必担心它是什么或它做什么。当你创建 MDI 客户区窗口时,首先需要填写 CLIENTCREATESTRUCT 结构中的字段。你将指向该结构的指针作为 LPARAM 数据字段传递到 CreateWindow 函数中。
创建 MDI 子窗口与创建普通窗口略有不同。要创建 MDI 子窗口,你必须填写 MDICREATESTRUCT 数据结构。MDICREATESTRUCT 与 WNDCLASS 结构非常相似,只是它更加有限。创建此结构后,你必须将其作为消息发送到 MDICLIENT 窗口
hwndChild = (HWND)SendMessage(hwndClient, WM_MDICREATE, 0, (LPARAM)mdicreatestruct);
消息函数将返回一个指向新创建子窗口的句柄。
许多 MDI 应用程序会在菜单栏上提供一个“窗口”弹出菜单,以管理 MDI 子窗口。此菜单通常包含“平铺”或“层叠”子窗口的选项,并且它通常会维护一个当前应用程序中可用子窗口的列表。事实证明,如果你只是将正确的菜单句柄传递给它,MDI 客户区窗口会为你管理这个菜单。