Windows SDK笔记(七):创建MDI窗口

Winform MDI编程-获得MDI窗体中的MDI控件的方法  我的MDI窗体默认是灰色很难看,项目也要求窗体要有背景,我找遍了winform类都没有找到这个MDI背景在哪于是上网搜索了一下,发现原来winform不提供直接的调用,MDI窗口以一个控件的形似放入在winform中,于是乎我在winform类的构造函数中的InitializeComponent()方法后写了遍历窗体中所有控件直到找到这个MDI控件代码如下:   public MainFor 阅读详情

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 (hwndChild))
			SendMessage (hwndChild, WM_COMMAND, wParam, lParam) ;
               
               break ;        //..and then to DefFrameProc
}
break ;  //跳出针对WM_COMMAND的case分支,又DefFrameProc处理剩下的命令
五、子窗口的管理
1.概述
给MDI客户区窗口发控制消息即可
如:
case WM_COMMAND:
switch (LOWORD (wParam))
{
	case IDM_WINDOW_TILE:
		SendMessage (hwndClient, WM_MDITILE, 0, 0) ;
		return 0 ;
               
	case IDM_WINDOW_CASCADE:
		SendMessage (hwndClient, WM_MDICASCADE, 0, 0) ;
		return 0 ;
               
	case IDM_WINDOW_ARRANGE:
		SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0) ;			
		return 0;
               
        //...
        //...
}
break;
2.当前子窗口的关闭
关闭当前激活窗口时,先向该窗口发送查询消息:WM_QUERYENDSESSION。
子窗口的消息处理循环中响应此消息,作关闭前的一些处理,若能关闭,返回真
否则返回假。
框架窗口中根据此返回值决定是否关闭窗口。

如果用户直接按下子窗口的关闭按钮,则WM_CLOSE消息直接发送到了子窗口消息处理函数。

例如:
框架窗口命令处理中:

case IDM_FILE_CLOSE:          
//获得当前激活窗口
hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0);
//询问通过后,销毁窗口
if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0))
     SendMessage (hwndClient, WM_MDIDESTROY, (WPARAM) hwndChild, 0);
return 0;
子窗口的消息处理函数中:
LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message, 
                               WPARAM wParam, LPARAM lParam)
{
     switch (message)
     {
	//...
	//...

     case WM_QUERYENDSESSION:
     case WM_CLOSE:
          if (IDOK != MessageBox (hwnd, TEXT ("OK to close window?"),
                                  TEXT ("Hello"), 
                                  MB_ICONQUESTION | MB_OKCANCEL))
               return 0 ;
               
          break ;   // i.e., call DefMDIChildProc
     }
     return DefMDIChildProc (hwnd, message, wParam, lParam) ;
}
3.关闭所有子窗口
当使用命令方式关闭所有子窗口时,需要枚举所有子窗口进行关闭。
例:
框架窗口响应命令:
case IDM_WINDOW_CLOSEALL:    
	//针对所有子窗口执行CloseEnumProc
	EnumChildWindows (hwndClient, CloseEnumProc, 0) ;
	return 0 ;
枚举函数:
BOOL CALLBACK CloseEnumProc (HWND hwnd, LPARAM lParam)
{
     if (GetWindow (hwnd, GW_OWNER))         // Check for icon title
          return TRUE ;
     
     SendMessage (GetParent (hwnd), WM_MDIRESTORE, (WPARAM) hwnd, 0) ;
     
     if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0))
          return TRUE ;
     
     SendMessage (GetParent (hwnd), WM_MDIDESTROY, (WPARAM) hwnd, 0) ;
     return TRUE ;
}
六、菜单控制
在MDI程序中,可以根据激活的子窗口而切换框架窗口的菜单。
并且,可以将窗口列表添加到菜单中去。所添加的菜单项命令是又框架对应的缺省消息处理函数完成的。
1.为每种窗口类准备一套菜单资源
2.装载菜单,得到菜单句柄
3.框架在建立时,使用框架菜单的句柄作为参数。
4.子窗口在激活时,加载自己菜单到框架窗口
失去焦点时,还原框架菜单。
使用向MDI客户区窗口发送WM_MDISETMENU或WM_MDISETMENU消息。
wParam为菜单句柄,lParam为欲添加窗口列表的子菜单句柄
case WM_MDIACTIVATE:
         //激活时,设置框架菜单
         if (lParam == (LPARAM) hwnd)
               SendMessage (hwndClient, WM_MDISETMENU,
                            (WPARAM) hMenuHello, (LPARAM) hMenuHelloWindow) ;
               
               
          //失去焦点时,将框架菜单还原
         if (lParam != (LPARAM) hwnd)
               SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit,
                            (LPARAM) hMenuInitWindow) ;
               
          DrawMenuBar (hwndFrame) ;
          
          //注: hwndFrame的得到方法:
          //hwndClient = GetParent (hwnd) ;
          //hwndFrame  = GetParent (hwndClient) ;
          
          return 0 ;
(全文完)

 

MFC MDI静态切分窗口实现:多视图界面布局与文档视图架构详解 在桌面应用开发中,多文档界面(MDI)与窗口切分技术是构建复杂数据展示系统的核心方案。MDI允许用户同时操作多个文档窗口,而窗口切分技术则能在单个窗口内划分多个独立视图区域,实现数据的多角度同步展示。其技术原理在于通过框架窗口管理视图容器,利用切分窗口控件(如MFC的CSplitterWnd)对客户区进行几何划分,每个窗格可承载不同类型的视图对象。这种架构的价值在于提升信息密度与操作效率,尤其适合监控系统、数据分析工具等需要同时展示统计图表、列表、详情的场景。本文以MFC框架为例,深入解析如何在MDI子框架 阅读详情

相关推荐

深入解析MFC创建窗口实例的完整流程

MFC(Microsoft Foundation Classes)是一组封装了Windows API的C++类库,旨在简化Windows应用程序的开发流程。通过面向对象的方式,MFC提供了对窗口、消息处理、图形界面控件等核心功能的封装,使开发者能够以更高层次的抽象进行编程。在现代Windows桌面应用开发中,尽管有.NET Framework和UWP等新兴框架,但MFC因其性能优越、与原生API高度集成,仍广泛应用于企业级软件和遗留系统的维护与升级中。

weixin_42581846的博客 987

C# Windows 窗体编程入门详解

通过学习 WinForms 框架的开发技术,你会发现很多乐趣,可以实现自己真正想要的各种 Web 无法实现的功能,实现各种桌面工具。从中领略开发带来的快乐和成就。

张赐荣的技术博客 7088

重访MdiClient

使用100%托管代码(包括设计时间支持)绘制MDI窗口的背景。

如何让MDIClient(对应于文档灰色客户区)响应系统消息

一、MDIClient是什么? 二、如何向MDIClient传递消息(以鼠标消息为例) 三、让MDIClient响应系统消息的三种方式1.为MDIClient添加消息响应函数2.将消息传递给其父窗口MainFrame3.

ke_yang的专栏 1064

MaxEnt物种分布预测中的常见误区与优化技巧:如何提高模型准确率

本文深入探讨了MaxEnt物种分布预测模型从基础应用到精准预测的进阶实践。针对模型准确率提升,文章系统分析了环境变量筛选、模型参数调优、结果批判性解读等核心环节的常见误区,并提供了基于生态位模型原理的深度优化技巧,帮助研究者产出更可靠、可解释的预测结果。

weixin_29219539的博客 594

Silvaco Atlas入门指南——从零开始掌握半导体器件仿真

本文为Silvaco Atlas半导体器件仿真软件的入门指南,详细介绍了从零开始掌握该工具的核心流程。内容涵盖Atlas的基本概念、仿真流程、核心文件(输入、结构、输出文件)、交互式与批处理两种操作模式,并逐步演示了如何从定义网格、划分区域、设置电极到进行掺杂、选择物理模型并求解,最终获取和分析器件特性的完整步骤。旨在帮助微电子相关专业人员和工程师快速上手这一强大的“数字实验室”,提升半导体器件设计与研发效率。

weixin_29306317的博客 401

深入MDI客户窗口编程及改进

作者:北京工业大学计算机学院网络学科部 胡击在使用VC6.0/5.0的AppWizard生成MDI应用的时候,我们发现MDI主窗口的客户区背景千篇一律的是深灰的。VC6.0/5.0并没有提供修改其背景色的方法。甚至使用SDK编程也没有好的方法修改背景色。以至于微软的产品如Office也是灰蒙蒙的背景。那么,有没有办法将背景设置为自己喜欢的颜色呢?笔者在学习过程中摸索出一套随意改变客户区窗口颜色的方

闹市茅庐 1425

NVIDIA驱动装好了,Gazebo为啥还是卡?手把手教你用optirun搞定GPU加速

本文详细解析了NVIDIA驱动安装后Gazebo仍卡顿的原因,并提供三步精准诊断与GPU加速实战方案。通过optirun快速启用GPU加速,解决OpenGL与显示服务器的配置问题,显著提升仿真性能。适用于ROS、PX4等开发环境,帮助用户充分利用显卡性能。

weixin_30379531的博客 465

Windows SDK编程--创建MDI窗口

一、概述MDI窗口包含一个框架窗口和若干子窗口。实际上,框架窗口本身是一个普通主窗口,不过它的客户去被一个特殊窗口覆盖。这个特殊窗口是系统预定义的“窗口类”,类名称为:"MDICLIENT"。它负责各个MDI子窗口的管理。 二、窗口建立1.注册一个MDI框架窗口类,提供MDI框架窗口消息处理函数MDI框架窗口消息处理函数中,将未处理消息交由DefFrameProc处理//MDI框架窗口消

Tunix126的专栏 1454

YOLOv11旋转目标检测详解:从原理到实战的全面指南

本文介绍了YOLOv11旋转目标检测技术的核心概念、架构设计与应用场景。传统目标检测使用水平边界框(AABB)存在背景噪声大、定位精度低等问题,而旋转边界框(OBB)通过引入角度参数显著提升了检测精度,在遥感、OCR、工业质检等领域具有独特优势。YOLOv11-OBB采用改进的多尺度检测层、CSPDarknet53骨干网络和双通道角度输出机制,在保持实时性的同时实现精确的旋转目标检测。实验表明,该方法在DOTA数据集上达到81.3%的mAP,相比传统方法提升显著,特别适合处理具有旋转特性或高宽比悬殊的目标。

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 302

基于Transformer的股票市场多因子量化选股模型,深度解析:基于Transformer的股票市场多因子量化选股模型

传统多因子模型通常采用线性回归、岭回归或Lasso回归来估计因子权重,其核心假设是因子与未来收益之间存在线性关系。然而,现实中的股票市场具有典型的非线性、非平稳和高噪声特征。卷积神经网络(CNN)擅长提取局部特征,但难以捕捉全市场股票之间的全局依赖关系;循环神经网络(RNN)及其变体LSTM虽然能处理时间序列,但存在梯度消失问题且难以并行计算。Transformer的self-attention机制能够:直接建模任意两只股票之间的相关性动态计算因子权重而非静态线性组合。

YOLO 250

Windows SDK 笔记

[转载]Windows SDK笔记 应程序需求需要重写窗体内子控件某一特定消息,可怜我苦苦找了二天也没找到资料,到CDSN提问也没有得到满意答案。 终归是上天不负有心人啊,终于被我发现了博主的一篇文章,总算是满意的解决问题了;在此感谢作者!! 原文:http://www.cppblog.com/Lee7/archive/2008/11/07/66226.html     Windo

人生代码,代码人生。。。 722

YOLOv8进阶实战:融合SAHI超推理算法,在无人机应用中精准捕捉视频与图片中的微小目标

YOLOv8改进是一种先进的目标检测算法,通过引入辅助超推理算法SAHI推理,使得小目标无法逃避检测。SAHI推理算法结合视频和图片的特点,利用先进的超推理技术,提高了目标检测的准确性和鲁棒性。不仅如此,YOLOv8改进还支持对视频和图片进行实时的目标检测,将检测结果直观地呈现给用户。这一技术的应用范围广泛,可以用于安防领域,提升监控设备的性能和效率;也可以用于无人驾驶领域,实现精准的目标识别和跟踪。总之,YOLOv8改进是一项具有突破性的技术,为目标检测领域带来了重大的进展。

weixin_51988935的博客 808

转: Windows SDK笔记

原文: http://www.cppblog.com/Lee7/archive/2008/11/07/66226.html Windows SDK笔记(一):Windows程序基本结构 一、概述Windows程序具有相对固定的结构,对编写者而言,不需要书写整个过程,大部分过程由系统完成。 程序中只要按一定的格式填写系统留给客户的那一小部分。 所需要完成的有: 窗口类的定义、窗口的建立...

akkcy26820的专栏 190

Cilium动手实验室: 精通之旅---1.Getting Started with Cilium

我们需要在 HTTP 层的第 7 层实施策略,以限制允许 tiefighter 调用的确切 API,以及不允许调用哪些 API。上仅需要的 API 资源的访问,从而为微服务之间的通信实施“最低权限”安全方法。船只上进行匹配,因此我们需要在该标签上进行匹配,此外,我们必须确保来自带有标签。为了模拟我们的连接测试,我们将使用 curl 执行简单的 API 调用。在我们立即开始更改策略之前,让我们考虑一下相应的网络策略应该是什么样子。的规则,该规则将通过 L3-L4 策略对死星的访问限制为仅帝国船只。

Q先生 1126

基于 ESP32 的宿舍洗浴热水余量预测与智能排队提醒系统设计与实现

本系统以 ESP32 为主控核心,通过超声波液位传感器实时监测储热水箱剩余水量,配合 DS18B20 温度传感器采集水温数据,建立热水余量预测模型估算可用洗浴时长;同时通过红外人体传感器统计浴室排队人数,结合人均洗浴时长计算预计等待时间,并通过 OLED 屏本地显示 + WiFi Web 服务器远程推送的方式实现排队提醒功能。

weixin_42300449的博客 45

Windows SDK笔记

<br /><br />Windows SDK笔记(一):Windows程序基本结构<br />一、概述<br /><br />Windows程序具有相对固定的结构,对编写者而言,不需要书写整个过程,大部分过程由系统完成。<br />程序中只要按一定的格式填写系统留给客户的那一小部分。<br />所需要完成的有:<br />窗口类的定义、窗口的建立、消息函数的书写、消息循环。<br /> <br />二、消息处理函数<br /><br />Windows程序是事件驱动的,对于一个窗口,它的大部分例行维护是由

狼心狗肺猪肾的专栏 661

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

[转载]Windows SDK笔记

[转载]Windows SDK笔记<br />应程序需求需要重写窗体内子控件某一特定消息,可怜我苦苦找了二天也没找到资料,到CDSN提问也没有得到满意答案。<br />终归是上天不负有心人啊,终于被我发现了博主的一篇文章,总算是满意的解决问题了;在此感谢作者!!<br />原文:http://www.cppblog.com/Lee7/archive/2008/11/07/66226.html<br /> <br /> <br />Windows SDK笔记(一):Windows程序基本结构<br />一、概

haiyan2012的专栏 533

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Windows SDK笔记(经典--一定要看)

Windows SDK笔记(一):Windows程序基本结构 一、概述 Windows程序具有相对固定的结构,对编写者而言,不需要书写整个过程,大部分过程由系统完成。程序中只要按一定的格式填写系统留给客户的那一小部分。所需要完成的有:窗口类的定义、窗口的建立、消息函数的书写、消息循环。 二、消息处理函数 Windows程序是事件驱动的,对于一个窗口,它的大部分例行维护是由系统维护的。没个窗口都有...

SurpassLi的专栏 52

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: Windows SDK笔记(六):使用对话框资源建立窗口
下一篇: Windows SDK编程初探
cpusoft
博客等级 码龄22年 8粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值