windows程序设计学习笔记-多文档界面

多文档界面

多文档界面是一个针对文档处理应用程序的一套规范。
MDI程序构成:
标题栏,菜单,边框。
客户区,在MDI中又称工作区,其中可有多个子窗口(文档窗口)。

MDI程序特点:
1.文档窗口最小化时,变成位于工作区底部一带图标的小标题栏。
2.MDI文档窗口最大化时,文档窗口标题栏消失,文件名加在主窗口标题栏后。
他的系统菜单图标出现在主窗口顶级菜单最前面。文档窗口关闭按钮出现在主窗口顶级菜单右端。
3.文档窗口系统快捷键。Ctrl+?
4.光标在菜单上移动时,焦点。
5.菜单和文档对应。
6.顶级菜单有窗口子菜单,用于在客户区安排文档窗口位置。

MDI支持:
MDI下主应用程序窗口称为 框架窗口。
MDI会创建基于预定义窗口类 MDICLIENT的 客户窗口。
文档窗口的创建,须初始化一个 MDICREATESTRUCT结构,然后向客户窗口发送一个 WM_MDICREATE消息。

Windows对MDI的支持含 一个窗口类,五个函数,两个数据结构,十二个消息。
窗口类:MDICLIENT
数据结构:CLIENTCREATESTRUCT,MDICREATESTRUCT
函数:
框架窗口的窗口过程的默认消息处理函数:DefFrameProc。
子窗口的窗口过程的默认消息处理函数:DefMDIChildProc
TranslateMDISysAccel,ArrangeIconicWindows
CreateMDIWindow:用于在一个独立的执行线程中创建子窗口。
// 适用于工作区背景画刷
wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1) ;

// 通过指定的菜单条目,取得下拉菜单或子菜单句柄。
HMENU WINAPI GetSubMenu(
  _In_ HMENU hMenu,
  _In_ int   nPos
 // 基于0
);

返回值 :
成功,下拉菜单或子菜单句柄
失败,NUL

MDI客户窗口的加速键翻译:TranslateMDISysAccel (hwndClient, &msg
框架窗口的加速键翻译:TranslateAccelerator (hwndFrame, hAccel, &msg

把一个菜单的句柄放在CreateWindow 的菜单句柄参数位置后,此菜单句柄不用单独销毁。在窗口销毁时,会自动销毁与其绑定的菜单。

客户窗口创建:
1.使用预定义类:TEXT(“MDICLIENT”)
2.CreateWindow最后一个参数是一个指向CLIENTCREATESTRUCT结构指针。

// 包含菜单和第一个MDI客户窗口子窗口的信息。
// 应用传递一个此结构指针给MDI客户窗口CreateWindow的lpParam
typedef struct tagCLIENTCREATESTRUCT {
  HANDLE hWindowMenu;
  UINT   idFirstChild;
} CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT;

参数解释:
hWindowMenu:MDI应用的窗口菜单句柄。可以从MDI框架窗口用GetSubMeun取得。
idFirstChild:被创建的第一个MDI子窗口标识ID。
系统为每个额外创建的MDI子窗口增加ID,当应用销毁一个窗口时重新分配标识ID来保持ID范围邻近。
这些标识ID被用在WM_COMMAND消息,消息发给应用的MDI框架窗口,当子窗口从窗口菜单被选中,他们应该不和其他命令ID冲突。

子窗口(文档窗口创建):
文档窗口创建通过向客户窗口发消息WM_MDICREATE实现。

1.WM_MDICREATE:

wParam:不使用。
lParam:指向MDICREATESTRUCT结构,包含信息,系统用此信息来创建MDI子窗口。
返回值:
成功,新创建子窗口的句柄。
失败,NULL。
额外说明:
1.被创建的MDI子窗口,有窗口风格:WS_CHILD, WS_CLIPSIBLINGS, WS_CLIPCHILDREN, WS_SYSMENU, WS_CAPTION, WS_THICKFRAME, WS_MINIMIZEBOX, and WS_MAXIMIZEBOX。在MDICREATESTRUCT还可增加其他风格。
2.MDI子窗口被创建时,系统给窗口发WM_CREATE消息,消息的lParam参数是指向CREATESTRUCT结构指针。该结构的lpCreateParams是指向MDICREATESTRUCT结构的指针,该指针就是创建MDI子窗口时,传递给WM_MDICREATE的。

typedef struct tagMDICREATESTRUCT {
  LPCTSTR szClass;
  LPCTSTR szTitle;
  HANDLE  hOwner;
  int     x;
  int     y;
  int     cx;
  int     cy;
  DWORD   style;
  LPARAM  lParam;
} MDICREATESTRUCT, *LPMDICREATESTRUCT;

参数解释:
szClass:MDI子窗口的窗口类的名字。类名应该是已经注册的。
szTitle:MDI子窗口的标题。
hOwner:创建MDI客户窗口的应用的实例句柄。
x:初始水平位置,客户区坐标。CW_USEDEFAULT表示用默认值。
y:初始垂直位置,客户区坐标。CW_USEDEFAULT表示用默认值。
cx:初始宽度,设备单位。CW_USEDEFAULT表示用默认值。
cy:初始高度。设备单位。CW_USEDEFAULT表示用默认值。
style:MDI子窗口风格。
如果MDI客户窗口有风格MDIS_ALLCHILDSTYLES,该成员可取所有可能的窗口风格。
其他情况,只能取:WM_MINIMIZE,WS_MAXIMIZE,WS_HSCROLL,WS_VSCROLL。
lParam:应用定义值。

2.WM_MDIGETACTIVE

应用给多文档客户窗口发送此消息来取得活动的MDI子窗口的句柄。
wParam:不使用。
lParam:
若为NULL,忽略
非NULL,指向一个值来表明MDI子窗口是否是最大化的。TRUE,是。FALSE,不是。

返回值:
活动的MDI子窗口的句柄

3.WM_MDIDESTROY

应用发送WM_MDIDESTROY消息给MDI客户窗口来关闭一个MDI子窗口。
wParam:要被关闭的MDI子窗口的句柄。
lParam:未使用。

返回值:
0

4.WM_MDITILE

应用发送WM_MDITILE消息给MDI客户窗口来排列他的所有的MDI子窗口,以一个平铺格式。
wParam:平铺选项。
MDITILE_HORIZONTAL:水平
MDITILE_VERTICAL:垂直
MDITILE_SKIPDISABLED:非使能MDI子窗口不参与。
lParam:不使用

返回值:
成功,TRUE
失败,FALSE

5.WM_MDICASCADE

应用发送WM_MDICASCADE消息给MDI客户窗口来排列他的子窗口,以级联格式。
wParam:级联行为。
MDITILE_SKIPDISABLED:非使能MDI子窗口不参与。
MDITILE_ZORDER:Z序排列。
lParam:未使用。

返回值:
成功,TRUE
失败,FALSE

6.WM_MDIICONARRANGE

应用发送WM_MDIICONARRANGE消息给一个MDI客户窗口来排列所有最小化的MDI子窗口。对非最小化子窗口无影响。
wParam:0
lParam:0

7.WM_MDIRESTORE

应用发送WM_MDIRESTORE消息给MDI客户窗口来从最大或最小尺寸恢复一个MDI子窗口。
wParam:MDI子窗口句柄
lParam:未使用

返回值:
0

8.WM_MDIDESTROY

应用发送WM_MDIDESTROY消息给MDI客户窗口来关闭一个MDI子窗口
wParam:要被关闭的MDI子窗口的句柄
lParam:未使用

返回值:
0

9.WM_MDIACTIVATE

应用发送WM_MDIACTIVATE消息给MDI客户窗口来指导客户窗口激活一个不同的MDI子窗口。
wParam:要被激活的MDI子窗口句柄
lParam:未使用

返回值:
应用发送此消息给MDI客户窗口,返回值是0
MDI子窗口应该返回0,如果他处理了这个消息。

当客户窗口处理此消息,他发送WM_MDIACTIVATE给被激活的子窗口和当前被激活(下面变为非激活)的子窗口。MDI子窗口的消息参数是:
wParam:由激活要变为非激活的MDI子窗口的句柄
lParam:要被激活的MDI子窗口的句柄

额外说明:
框架窗口变为活动的,子窗口最后被激活的,取得WM_NCACTIVATE消息来绘制一个活动窗口框架和标题栏。

10.WM_MDISETMENU

应用发送WM_MDISETMENU消息给MDI客户窗口来替代MDI框架窗口的整个菜单。
wParam:一个指向新的框架窗口菜单的句柄。若为NULL,框架窗口菜单不变。
lParam:新的窗口菜单(框架窗口的菜单有一子菜单单独称为窗口菜单,windows会维护对此菜单做一些额外维护)。若为NULL,窗口菜单不变。

返回值:
成功,老的MDI框架窗口菜单句柄。
失败,NULL。

// 重绘指定窗口的菜单栏
// 在系统创建窗口后,菜单栏改变,需要用此函数来绘制改变的菜单栏
BOOL WINAPI DrawMenuBar(
  _In_ HWND hWnd
);

子窗口枚举

// 枚举子窗口,这些子窗口属于指定的父窗口,通过把每个子窗口句柄轮流传递给应用定义的回调函数实现枚举
// 函数继续直到最后一个子窗口被枚举或回调函数返回了FALSE
BOOL WINAPI EnumChildWindows(
  _In_opt_ HWND        hWndParent,
  _In_     WNDENUMPROC lpEnumFunc,
  _In_     LPARAM      lParam
);

参数解释:
hWndParent:父窗口
lpEnumFunc:应用定义的回调函数
lParam:应用定义值。被传递给回调函数。

返回值:
无意义

额外说明:
对子窗口的子窗口也会被枚举

BOOL CALLBACK EnumChildProc(
  _In_ HWND   hwnd,
  _In_ LPARAM lParam
);

参数解释:
hwnd:子窗口句柄
lParam:对应EnumChildWindows的lParam

返回值:
继续枚举,TRUE
停止枚举,FALSE

杂谈

1.

窗口类cbWndExtra表示为每个窗口提供额外空间来存放数据。
wndclass.cbWndExtra = sizeof (HANDLE) ;
// SetWindowLong wParam为0,其后数据可以被设置到窗口的额外数据空间
SetWindowLong (hwnd, 0, (long) pHelloData);
// GetWindowLong,参数2为0,取得的就是窗口额外空间的数据
pHelloData = (PHELLODATA) GetWindowLong (hwnd, 0) ;

2.

就算框架窗口拦截了WM_MENUCHAR,WM_SETFOCUS,WM_SIZE,也必须传给DefFrameProc。

不管子窗口对WM_CHILDACTIVATE,WM_GETMINMAXINFO,WM_MENUCHAR,WM_MOVE,WM_SETFOCUS,WM_SIZE,WM_SYSCOMMAND做了什么,这几个消息都须传给DefMDIChildProc。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

raindayinrain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值