当前位置: 首页 > article >正文

MFC深入-MFC和win32

MFC和Win32MFC Object和Windows Object的关系MFC中最重要的封装是对Win32 API的封装因此理解Windows Object和MFC Object (C对象一个C类的实例)之间的关系是理解MFC的关键之一。所谓Windows ObjectWindows对象是Win32下用句柄表示的Windows操作系统对象所谓MFC Object (MFC对象)是C对象是一个C类的实例这里本书范围内MFC Object是有特定含义的指封装Windows Object的C Object并非指任意的C Object。MFC Object 和Windows Object是不一样的但两者紧密联系。以窗口对象为例一个MFC窗口对象是一个C CWnd类或派生类的实例是程序直接创建的。在程序执行中它随着窗口类构造函数的调用而生成随着析构函数的调用而消失。而Windows窗口则是Windows系统的一个内部数据结构的实例由一个“窗口句柄”标识Windows系统创建它并给它分配系统资源。Windows窗口在MFC窗口对象创建之后由CWnd类的Create成员函数创建“窗口句柄”保存在窗口对象的m_hWnd成员变量中。Windows窗口可以被一个程序销毁也可以被用户的动作销毁。MFC窗口对象和Windows窗口对象的关系如图2-1所示。其他的Windows Object和对应的MFC Object也有类似的关系。下面对MFC Object和Windows Object作一个比较。有些论断对设备描述表(MFC类是CDC句柄是HDC)可能不适用但具体涉及到时会指出。从数据结构上比较MFC Object是相应C类的实例这些类是MFC或者程序员定义的Windows Object是Windows系统的内部结构通过一个句柄来引用MFC给这些类定义了一个成员变量来保存MFC Object对应的Windows Object的句柄。对于设备描述表CDC类将保存两个HDC句柄。从层次上讲比较MFC Object是高层的Windows Object是低层的MFC Object封装了Windows Object的大部分或全部功能MFC Object的使用者不需要直接应用Windows Object的HANDLE句柄使用Win32 API代替它的是引用相应的MFC Object的成员函数。从创建上比较MFC Object通过构造函数由程序直接创建Windows Object由相应的SDK函数创建。MFC中使用这些MFC Object一般分两步首先创建一个MFC Object或者在STACK中创建或者在HEAP中创建这时MFC Object的句柄实例变量为空或者说不是一个有效的句柄。然后调用MFC Object的成员函数创建相应的Windows ObjectMFC的句柄变量存储一个有效句柄。CDC(设备描述表类)的创建有所不同在后面的2.3节会具体说明CDC及其派生类的创建和使用。当然可以在MFC Object的构造函数中创建相应的Windows对象MFC的GDI类就是如此实现的但从实质上讲MFC Object的创建和Windows Object的创建是两回事。从转换上比较可以从一个MFC Object得到对应的Windows Object的句柄一般使用MFC Object的成员函数GetSafeHandle得到对应的句柄。可以从一个已存在的Windows Object创建一个对应的MFC Object 一般使用MFC Object的成员函数Attach或者FromHandle来创建前者得到一个永久性对象后者得到的可能是一个临时对象。从使用范围上比较MFC Object对系统的其他进程来说是不可见、不可用的而Windows Object一旦创建其句柄是整个Windows系统全局的。一些句柄可以被其他进程使用。典型地一个进程可以获得另一进程的窗口句柄并给该窗口发送消息。对同一个进程的线程来说只可以使用本线程创建的MFC Object不能使用其他线程的MFC Object。从销毁上比较MFC Object随着析构函数的调用而消失但Windows Object必须由相应的Windows系统函数销毁。设备描述表CDC类的对象有所不同它对应的HDC句柄对象可能不是被销毁而是被释放。当然可以在MFC Object的析构函数中完成Windows Object的销毁MFC Object的GDI类等就是如此实现的但是应该看到两者的销毁是不同的。每类Windows Object都有对应的MFC Object下面用表格的形式列出它们之间的对应关系如表2-1所示表2-1 MFC Object和Windows Object的对应关系描述Windows句柄MFC Object窗口HWNDCWnd and CWnd-derived classes设备上下文HDCCDC and CDC-derived classes菜单HMENUCMenu笔HPENCGdiObject类CPen和CPen-derived classes刷子HBRUSHCGdiObject类CBrush和CBrush-derived classes字体HFONTCGdiObject类CFont和CFont-derived classes位图HBITMAPCGdiObject类CBitmap和CBitmap-derived classes调色板HPALETTECGdiObject类CPalette和CPalette-derived classes区域HRGNCGdiObject类CRgn和CRgn-derived classes图像列表HimageLISTCimageList和CimageList-derived classes套接字SOCKETCSocket,CAsynSocket及其派生类表2-1中的OBJECT分以下几类Windows对象设备上下文对象GDI对象BITMAPBRUSHFONTPALETTEPENRGN菜单图像列表网络套接字接口。从广义上来看文档对象和文件可以看作一对MFC Object和Windows Object分别用CDocument类和文件句柄描述。后续几节分别对前四类作一个简明扼要的论述。Windows Object用SDK的Win32 API编写各种Windows应用程序有其共同的规律首先是编写WinMain函数编写处理消息和事件的窗口过程WndProc在WinMain里头注册窗口Register Window创建窗口然后开始应用程序的消息循环。MFC应用程序也不例外因为MFC是一个建立在SDK API基础上的编程框架。对程序员来说所不同的是一般情况下MFC框架自动完成了Windows登记、创建等工作。下面简要介绍MFC Window对Windows Window的封装。Windows的注册一个应用程序在创建某个类型的窗口前必须首先注册该“窗口类”(Windows Class)。注意这里不是C类的类。Register Window把窗口过程、窗口类型以及其他类型信息和要登记的窗口类关联起来。“窗口类”的数据结构“窗口类”是Windows系统的数据结构可以把它理解为Windows系统的类型定义而Windows窗口则是相应“窗口类”的实例。Windows使用一个结构来描述“窗口类”其定义如下typedef struct _WNDCLASSEX {UINT cbSize; //该结构的字节数UINT style; //窗口类的风格WNDPROC lpfnWndProc; //窗口过程int cbClsExtra;int cbWndExtra;HANDLE hInstance; //该窗口类的窗口过程所属的应用实例HICON hIcon; //该窗口类所用的像标HCURSOR hCursor; //该窗口类所用的光标HBRUSH hbrBackground; //该窗口类所用的背景刷LPCTSTR lpszMenuName; //该窗口类所用的菜单资源LPCTSTR lpszClassName; //该窗口类的名称HICON hIconSm; //该窗口类所用的小像标} WNDCLASSEX;从“窗口类”的定义可以看出它包含了一个窗口的重要信息如窗口风格、窗口过程、显示和绘制窗口所需要的信息等等。关于窗口过程将在后面消息映射等有关章节作详细论述。Windows系统在初始化时会注册(Register)一些全局的“窗口类”例如通用控制窗口类。应用程序在创建自己的窗口时首先必须注册自己的窗口类。在MFC环境下有几种方法可以用来注册“窗口类”下面分别予以讨论。调用AfxRegisterClass注册AfxRegisterClass函数是MFC全局函数。AfxRegisterClass的函数原型BOOL AFXAPI AfxRegisterClass(WNDCLASS *lpWndClass);参数lpWndClass是指向WNDCLASS结构的指针表示一个“窗口类”。首先AfxRegisterClass检查希望注册的“窗口类”是否已经注册如果是则表示已注册返回TRUE否则继续处理。接着调用::RegisterClass(lpWndClass)注册窗口类然后如果当前模块是DLL模块则把注册“窗口类”的名字加入到模块状态的域m_szUnregisterList中。该域是一个固定长度的缓冲区依次存放模块注册的“窗口类”的名字每个名字是以“\n\0”结尾的字符串。之所以这样做是为了DLL退出时能自动取消(Unregister)它注册的窗口类。至于模块状态将在后面第9章详细的讨论。最后返回TRUE表示成功注册。调用AfxRegisterWndClass注册AfxRegisterWndClass函数也是MFC全局函数。AfxRegisterWndClass的函数原型LPCTSTR AFXAPI AfxRegisterWndClass(UINT nClassStyle,HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon)参数1指定窗口类风格参数2、3、4分别指定该窗口类使用的光标、背景刷、像标的句柄缺省值是0。此函数根据窗口类属性动态地产生窗口类的名字然后判断是否该类已经注册是则返回窗口类名否则用指定窗口类的属性窗口过程指定为缺省窗口过程调用AfxRegisterCalss注册窗口类返回类名。动态产生的窗口类名字由以下几部分组成包括冒号分隔符如果参数2、3、4全部为NULL则由三部分组成。“Afx”“:”模块实例句柄”“:”“窗口类风格”否则由六部分组成“Afx”“:”模块实例句柄“:”“窗口类风格”“:”光标句柄“:”背景刷句柄“:”像标句柄。比如“Afx:400000:b:13de:6:32cf”。该函数在MFC注册主边框或者文档边框“窗口类”时被调用。具体怎样用在5.3.3.3节会指出。隐含的使用MFC预定义的的窗口类MFC4.0以前的版本提供了一些预定义的窗口类4.0以后不再预定义这些窗口类。但是MFC仍然沿用了这些窗口类例如用于子窗口的“AfxWnd”用于边框窗口(SDI主窗口或MDI子窗口)或视的“AfxFrameOrView”用于MDI主窗口的“AfxMDIFrame”用于标准控制条的“AfxControlBar”。这些类的名字就 是“AfxWnd”、“AfxFrameOrView”、“AfxMdiFrame”、 “AfxControlBar”加上前缀和后缀用来标识版本号或是否调试版等。它们使用标准应用程序像标、标准文档像标、标准光标等标准资源。为了使用这些“窗口类”MFC会在适当的时候注册这些类或者要创建该类的窗口时或者创建应用程序的主窗口时等等。MFC内部使用了函数BOOL AFXAPI AfxEndDeferRegisterClass(short fClass)来帮助注册上述原MFC版本的预定义“窗口类”。参数fClass区分了那些预定义窗口的类型。根据不同的类型使用不同的窗口类风格、窗口类名字等填充WndClass的域然后调用AfxRegisterClass注册窗口类。并且注册成功之后通过模块状态的m_fRegisteredClasses记录该窗口类已经注册这样该模块在再次需要注册这些窗口类之前可以查一下m_fRegisteredClasses如果已经注册就不必浪费时间了。为此MFC内部使用宏AfxDeferRegisterClass(short fClass)来注册“窗口类”如果m_fRegisteredClasses记录了注册的窗口类返回TRUE否则调用AfxEndDeferRegisterClass注册。注册这些窗口类的例子MFC在加载边框窗口时会自动地注册“AfxFrameOrView”窗口类。在创建视时就会使用该“窗口类”创建视窗口。当然如果创建视窗口时该“窗口类”还没有注册MFC将先注册它然后使用它创建视窗口。不过MFC并不使用”AfxMDIFrame”来创建MDI主窗口因为在加载主窗口时一般都指定了主窗口的资源MFC使用指定的像标注册新的MDI主窗口类通过函数AfxRegisterWndClass完成因此“窗口类”的名字是动态产生的。MDI子窗口类似于上述MDI主窗口的处理。在MFC创建控制窗口时如工具栏窗口如果“AfxControlBar”类还没有注册则注册它。注册过程很简单就是调用::InitCommonControl加载通用控制动态连接库。调用::RegisterWndClass。直接调用Win32的窗口注册函数::RegisterWndClass注册“窗口类”这样做有一个缺点如果是DLL模块这样注册的“窗口类”在程序退出时不会自动的被取消注册(Unregister)。所以必须记得在DLL模块退出时取消它所注册的窗口类。子类化子类化Subclass一个“窗口类”可自动地得到它的“窗口类”属性。MFC窗口类CWnd在Windows系统里一个窗口的属性分两个地方存放一部分放在“窗口类”里头如上所述的在注册窗口时指定另一部分放在Windows Object本身如窗口的尺寸窗口的位置XY轴窗口的Z轴顺序窗口的状态ACTIVEMINIMIZEDMAXMIZEDRESTORED…和其他窗口的关系父窗口子窗口…窗口是否可以接收键盘或鼠标消息等等。为了表达所有这些窗口的共性MFC设计了一个窗口基类CWnd。有一点非常重要那就是CWnd提供了一个标准而通用的MFC窗口过程MFC下所有的窗口都使用这个窗口过程。至于通用的窗口过程却能为各个窗口实现不同的操作那就是MFC消息映射机制的奥秘和作用了。这些将在后面有关章节详细论述。CWnd提供了一系列成员函数或者是对Win32相关函数的封装或者是CWnd新设计的一些函数。这些函数大致如下。1窗口创建函数这里主要讨论函数Create和CreateEx。它们封装了Win32窗口创建函数::CreateWindowEx。Create的原型如下BOOL CWnd::Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,const RECT rect,CWnd* pParentWnd, UINT nID,CCreateContext* pContext)Create是一个虚拟函数用来创建子窗口不能创建桌面窗口和POP UP窗口。CWnd的基类可以覆盖该函数例如边框窗口类等覆盖了该函数以实现边框窗口的创建视类则使用它来创建视窗口。Create调用了成员函数Cre

相关文章:

MFC深入-MFC和win32

MFC和Win32 MFC Object和Windows Object的关系 MFC中最重要的封装是对Win32 API的封装,因此,理解Windows Object和MFC Object (C对象,一个C类的实例)之间的关系是理解MFC的关键之一。所谓Windows Object(Windows对象)是…...

终极指南:boardgame.io v0.50重大更新,打造更强大的回合制游戏框架

终极指南:boardgame.io v0.50重大更新,打造更强大的回合制游戏框架 【免费下载链接】boardgame.io State Management and Multiplayer Networking for Turn-Based Games 项目地址: https://gitcode.com/gh_mirrors/bo/boardgame.io boardgame.io是…...

AI编程技能自学习:构建Claude与Cursor的智能协同开发环境

1. 项目概述:当Claude遇上Cursor,一场关于AI编程技能的自我进化最近在GitHub上看到一个挺有意思的项目,叫Self-Learning-Claude-Skill。虽然项目描述和正文都还是空的,但光看这个标题和关键词——claude-code、cursor、skills——…...

openclaw gateway网关运行详解

📘 Gateway 网关运行手册 — 关键内容与操作流程 1) Gateway 是什么 Gateway 网关服务 是一款长期运行的进程,用于处理连接控制、事件平面,与底层 Baileys / Telegram 等协议对接,为客户端提供 RPC/HTTP 接口。它自身启动后持续运…...

Laravel Permission 缓存系统终极指南:如何构建高性能多级缓存策略

Laravel Permission 缓存系统终极指南:如何构建高性能多级缓存策略 【免费下载链接】laravel-permission Associate users with roles and permissions 项目地址: https://gitcode.com/gh_mirrors/la/laravel-permission Laravel Permission 是一个功能强大的…...

VSCode跨IDE代码搜索工具:原理、配置与高效开发实践

1. 项目概述:一个为多IDE开发者量身定制的代码搜索利器如果你和我一样,日常开发需要在 Visual Studio Code 和 JetBrains 系列 IDE(如 IntelliJ IDEA、PyCharm、WebStorm 等)之间频繁切换,那你一定对“代码搜索”这件事…...

zotero-pdf-translate自动翻译失效:5步快速诊断与修复指南

zotero-pdf-translate自动翻译失效:5步快速诊断与修复指南 【免费下载链接】zotero-pdf-translate Translate PDF, EPub, webpage, metadata, annotations, notes to the target language. Support 20 translate services. 项目地址: https://gitcode.com/gh_mirr…...

Minecraft世界优化终极指南:5分钟掌握免费区块管理神器

Minecraft世界优化终极指南:5分钟掌握免费区块管理神器 【免费下载链接】mcaselector A tool to select chunks from Minecraft worlds for deletion or export. 项目地址: https://gitcode.com/gh_mirrors/mc/mcaselector 你是否曾为Minecraft世界无限膨胀而…...

Timoni高级功能揭秘:类型验证、签名和OCI分发

Timoni高级功能揭秘:类型验证、签名和OCI分发 【免费下载链接】timoni Timoni is a package manager for Kubernetes, powered by CUE and inspired by Helm. 项目地址: https://gitcode.com/gh_mirrors/ti/timoni Timoni是一个基于CUE的Kubernetes包管理器&…...

从零开始使用Taotoken为你的爬虫项目添加AI解析功能

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 从零开始使用Taotoken为你的爬虫项目添加AI解析功能 在数据采集项目中,我们常常会遇到非结构化或半结构化的网页内容。…...

nlpcda高级配置:如何自定义词典和扩展同义词表

nlpcda高级配置:如何自定义词典和扩展同义词表 【免费下载链接】nlpcda 一键中文数据增强包 ; NLP数据增强、bert数据增强、EDA:pip install nlpcda 项目地址: https://gitcode.com/gh_mirrors/nl/nlpcda nlpcda是一款强大的中文数据增…...

如何在英雄联盟中节省70%的准备时间?这个本地工具告诉你答案

如何在英雄联盟中节省70%的准备时间?这个本地工具告诉你答案 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 想象一下这个场景&…...

React网格布局终极指南:3步掌握拖拽式界面开发

React网格布局终极指南:3步掌握拖拽式界面开发 【免费下载链接】react-grid-layout A draggable and resizable grid layout with responsive breakpoints, for React. 项目地址: https://gitcode.com/gh_mirrors/re/react-grid-layout React网格布局&#x…...

5大智能引擎:揭秘Illustrator批量替换脚本的自动化革命

5大智能引擎:揭秘Illustrator批量替换脚本的自动化革命 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts replaceItems.jsx是Adobe Illustrator脚本库中的专业级批量替换工…...

【深度解析】Hermes Agent 新版能力:后台 Computer Use、多智能体编排与 /goal 自主任务循环实战

摘要 本文解析 Hermes Agent 新版核心能力:后台电脑操控、多智能体协同、Kanban 工作流与 /goal 长任务模式,并用 Python 实现一个可运行的自主任务编排原型。背景介绍 AI Agent 正在从“单轮问答工具”演进为“长期运行的自主工作系统”。传统大模型应用…...

工业传动避坑:3 个皮带张力调节技巧,杜绝早期失效

工业传动避坑:3 个皮带张力调节技巧,杜绝早期失效在工业传动系统运维中,盖茨同步带、工业皮带的早期失效是高频痛点——不少工程师频繁更换皮带,却始终无法解决根本问题,反而增加运维成本。事实上,90%以上的…...

OctoSuite代码审查:深入理解GitHub数据模型设计的5个关键要点

OctoSuite代码审查:深入理解GitHub数据模型设计的5个关键要点 【免费下载链接】octosuite Terminal-based toolkit for GitHub data analysis. 项目地址: https://gitcode.com/gh_mirrors/oc/octosuite OctoSuite是一个强大的终端GitHub数据分析工具包&#…...

构建聚合搜索与阅读工具:一站式信息处理中枢的设计与实践

1. 项目概述:一个聚合搜索与阅读的“信息中枢”最近在折腾一个挺有意思的项目,叫all-net-search-read。光看名字,你可能会觉得这又是一个“聚合搜索”工具,市面上这类工具确实不少。但当我深入去研究和使用它时,发现它…...

私域团队如何用企业微信 API 提升客户维护效率?

一、 场景描述:为什么你的团队每天都在“瞎忙”? 很多私域团队看似忙碌,实则效率低下。典型的现象包括: • 重复回答:每天 70% 的时间在复制粘贴相同的话术(如:发货时间、优惠券怎么领&#xff…...

AI短视频生成引擎:从文章到视频的自动化流水线实战

1. 项目概述:一个能“读懂”文章的AI视频工厂最近在折腾短视频内容创作的朋友,估计都经历过一个共同的痛点:找选题、写脚本、找素材、配音、剪辑……一套流程下来,几个小时就没了,效率低得让人抓狂。尤其是想把一篇深度…...

嵌入式实战:STM32智能温度控制系统的算法优化与工程实现

嵌入式实战:STM32智能温度控制系统的算法优化与工程实现 【免费下载链接】STM32 项目地址: https://gitcode.com/gh_mirrors/stm322/STM32 在工业自动化、医疗设备和智能家居领域,温度控制系统的精度和稳定性直接影响着设备性能和用户体验。传统…...

Loguru性能优化秘籍:10个技巧让你的日志系统快如闪电

Loguru性能优化秘籍:10个技巧让你的日志系统快如闪电 【免费下载链接】loguru A lightweight C logging library 项目地址: https://gitcode.com/gh_mirrors/log/loguru Loguru是一个轻量级、高性能的C日志库,专为追求极致性能的开发者设计。在当…...

Daptin状态机管理:企业级工作流自动化的核心

Daptin状态机管理:企业级工作流自动化的核心 【免费下载链接】daptin Daptin - Backend As A Service - GraphQL/JSON-API Headless CMS 项目地址: https://gitcode.com/gh_mirrors/da/daptin Daptin作为后端即服务(Backend As A Service&#xf…...

hover-effect 性能优化:确保你的 WebGL 扭曲效果流畅运行

hover-effect 性能优化:确保你的 WebGL 扭曲效果流畅运行 【免费下载链接】hover-effect Javascript library to draw and animate images on hover 项目地址: https://gitcode.com/gh_mirrors/ho/hover-effect hover-effect 是一款基于 WebGL 的 JavaScript…...

MQTT-Client-Framework测试策略:单元测试、集成测试与多Broker兼容性

MQTT-Client-Framework测试策略:单元测试、集成测试与多Broker兼容性 【免费下载链接】MQTT-Client-Framework iOS, macOS, tvOS native ObjectiveC MQTT Client Framework 项目地址: https://gitcode.com/gh_mirrors/mq/MQTT-Client-Framework MQTT-Client-…...

10个必备的Solidity安全技巧:Secureum-mind_map实践经验分享

10个必备的Solidity安全技巧:Secureum-mind_map实践经验分享 【免费下载链接】secureum-mind_map Central Repository for the Epoch 0 coursework and quizzes. Contains all the content, cross-referenced and linked. 项目地址: https://gitcode.com/gh_mirr…...

TrollInstallerX终极指南:iOS 14-16.6.1越狱工具一键部署全解析

TrollInstallerX终极指南:iOS 14-16.6.1越狱工具一键部署全解析 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 想要在iOS 14.0到16.6.1系统上轻松安装Troll…...

Windows 11终极性能调优指南:一键告别卡顿,重获流畅体验 [特殊字符]

Windows 11终极性能调优指南:一键告别卡顿,重获流畅体验 🚀 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other …...

Battle City碰撞检测算法:精准命中与躲避的核心技术解析

Battle City碰撞检测算法:精准命中与躲避的核心技术解析 【免费下载链接】battle-city 🎮 Battle city remake built with react. 项目地址: https://gitcode.com/gh_mirrors/ba/battle-city 在经典的Battle City坦克大战游戏中,碰撞检…...

OpenArk:Windows系统安全检测的终极完整解决方案指南 [特殊字符]️

OpenArk:Windows系统安全检测的终极完整解决方案指南 🛡️ 【免费下载链接】OpenArk The Next Generation of Anti-Rookit(ARK) tool for Windows. 项目地址: https://gitcode.com/GitHub_Trending/op/OpenArk OpenArk是一款强大的Windows开源反R…...