当前位置: 首页 > 图文教程 > 开发语言 > VC++ > Windows SDK笔记(七):创建MDI窗口

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 Windows SDK笔记(七):创建MDI窗口


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 352 ::
收藏到网摘: n/a

Windows SDK笔记(七):创建MDI窗口
作者:冯明德

一、概述
MDI窗口包含一个框架窗口和若干子窗口。
实际上,框架窗口本身是一个普通主窗口,不过它的客户去被一个特殊窗口覆盖。
这个特殊窗口是系统预定义的“窗口类”,类名称为:"MDICLIENT"。它负责各个MDI子窗口的管理。


二、窗口建立
1.注册一个MDI框架窗口类,提供MDI框架窗口消息处理函数
MDI框架窗口消息处理函数中,将未处理消息交由DefFrameProc处理

//MDI框架窗口消息处理函数LRESULT CALLBACK MDIFrameWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	//...	//其他消息交给由系统提供的缺省框架处理函数DefFrameProc	//其中,第二个参数是客户区窗口句柄	return ::DefFrameProc (hwnd,hwndClient, message, wParam, lParam) ;}
2.注册多个MDI子窗口类、对应提供各MDI子窗口的消息处理函数
子窗口消息处理函数中,将未处理消息交由MDIDefMDIChildProc处理
//MDI子窗口消息处理函数LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){	//...	//...	//其他消息交给由系统提供的缺省MDI子窗口处理函数	return ::DefMDIChildProc (hwnd, message, wParam, lParam) ;}
3.在框架窗口的客户区建立MDI管理子窗口
MDI子窗口的管理实际上是由框架窗口客户区的"MDILIENT"窗口完成的。
这是一个系统预定义的窗口。

在主窗口收到WM_CREATE消息后:

case WM_CREATE:{	hinst=((LPCREATESTRUCT) lParam)->hInstance;	//填充CLIENTCREATESTRUCT结构	CLIENTCREATESTRUCT clientcreate ;	clientcreate.hWindowMenu = hMenuInitWindow ; //用于添加窗口列表的菜单句柄	clientcreate.idFirstChild = 50000 ;	//起始ID	hwndClient =CreateWindowEx(0,	"MDICLIENT",	//类名称为"MDICLIENT"	NULL,	WS_CHILD |WS_CLIPCHILDREN| WS_VISIBLE,	0,	0,	0,	0,	hwnd,	(HMENU)1,//ID	hinst,	//实例句柄	&clientcreate);	//参数}return 0;
窗口的大小没有关系,缺省的框架窗口消息处理函数为让它覆盖整个客户区。
MDI客户区窗口建立后,通过向它发送消息管理子窗口的建立、销毁、排列等等。


4.MDI子窗口的建立
可以在菜单中添加命令项,以建立子窗口。
框架窗口的消息处理函数收到命令后,向MDI客户区窗口发建立命令。

case ID_NEW:{	MDICREATESTRUCT mdicreate;	mdicreate.szClass = szMDIChildName ;	//MDI子窗口的类名称	mdicreate.szTitle = TEXT ("Hello") ;	mdicreate.hOwner = hinst ;	mdicreate.x = CW_USEDEFAULT ;	mdicreate.y = CW_USEDEFAULT ;	mdicreate.cx = CW_USEDEFAULT ;	mdicreate.cy = CW_USEDEFAULT ;	mdicreate.style = 0 ;	mdicreate.lParam = 0 ;	SendMessage (	hwndClient, //MDI客户区窗口句柄	WM_MDICREATE, //创建MDI子窗口	0,	(LPARAM) (LPMDICREATESTRUCT) &mdicreate //创建参数	) ;}break;
三、消息循环中处理针对MDI的热键
在消息循环中,用TranslateMDISysAccel处理针对MDI的热键。
while (GetMessage (&msg, NULL, 0, 0)){ if (!TranslateMDISysAccel (hwndClient, &msg) && !TranslateAccelerator (hwndFrame, hAccel, &msg)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; }}
四、命令的流向
框架窗口在收到WM_COMMAND等通知消息后,应该给当前激活的MDI窗口提供处理机会。
case WM_COMMAND:switch (LOWORD (wParam)){	//针对框架的命令	case ID_ONE:	//...	return 0;	//针对MDI子窗口管理的命令	case IDM_WINDOW_TILE:	SendMessage (hwndClient, WM_MDITILE, 0, 0) ;	return 0 ;	//针对子窗口的命令又子窗口去处理	default:	hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0) ;	if (IsWindow (hwnd