1.MFC Object和Windows Object的关系

MFC中最首要的封装是对Win32 API的封装,是以,懂得Windows Object和MFC Object (C++对象,一个C++类的实例)之间的关系是懂得MFC的关键之一。所谓Windows Object(Windows对象)是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窗口可以被一个法度烧毁,也可以被用户的动作烧毁

(1)从数据布局上斗劲

MFC Object是响应C++类的实例,这些类是MFC或者法度员定义的;

Windows Object是Windows体系的内部布局,经由过程一个句柄来引用;

MFC给这些类定义了一个成员变量来保存MFC Object对应的Windows Object的句柄。对于设备描述表CDC类,将保存两个HDC句柄。

(2)从层次上斗劲

MFC Object是高层的,Windows Object是低层的;

MFC Object封装了Windows Object的大项目组或全部功能,MFC Object的应用者不须要直策应用Windows Object的HANDLE(句柄)应用Win32 API,庖代它的是引用响应的MFC Object的成员函数。

(3)从创建上斗劲

MFC Object经由过程机关函数由法度直接创建;Windows Object由响应的SDK函数创建。

MFC中,应用这些MFC Object,一般分两步:起首,创建一个MFC Object,或者在STACK中创建,或者在HEAP中创建,这时,MFC Object的句柄实例变量为空,或者说不是一个有效的句柄。然后,调用MFC Object的成员函数创建响应的Windows Object,MFC的句柄变量存储一个有效句柄。

CDC(设备描述表类)的创建有所不合

当然,可以在MFC Object的机关函数中创建响应的Windows对象,MFC的GDI类就是如此实现的,但从本质上讲,MFC Object的创建和Windows Object的创建是两回事。

(4)从转换上斗劲

可以从一个MFC Object获得对应的Windows Object的句柄;一般应用MFC Object的成员函数GetSafeHandle获得对应的句柄。

可以从一个已存在的Windows Object创建一个对应的MFC Object; 一般应用MFC Object的成员函数Attach或者FromHandle来创建,前者获得一个永远性对象,后者获得的可能是一个姑且对象。

(5)从应用局限上斗劲

MFC Object对体系的其他过程来说是不成见、不成用的;而Windows Object一旦创建,其句柄是全部Windows体系全局的。一些句柄可以被其他过程应用。典范地,一个过程可以获得另一过程的窗口句柄,并给该窗口发送消息。

对同一个过程的线程来说,只可以应用本线程创建的MFC Object,不克不及应用其他线程的MFC Object。

(6)从烧毁上斗劲

MFC Object跟着析构函数的调用而消散;但Windows Object必须由响应的Windows体系函数烧毁。

设备描述表CDC类的对象有所不合,它对应的HDC句柄对象可能不是被烧毁,而是被开释。

当然,可以在MFC Object的析构函数中完成Windows Object的烧毁,MFC Object的GDI类等就是如此实现的,然则,应当看到:两者的烧毁是不合的。

每类Windows Object都有对应的MFC Object,下面用表格的情势列出它们之间的对应关系,如下表所示:

描述

Windows句柄 MFC Object

窗口

HWND CWnd and CWnd-derived classes
设备高低文

HDC

CDC and CDC-derived classes
菜单

HMENU

CMenu

HPEN

CGdiObject类,CPen和CPen-derived classes
刷子

HBRUSH

CGdiObject类,CBrush和CBrush-derived classes
字体

HFONT

CGdiObject类,CFont和CFont-derived classes
位图

HBITMAP

CGdiObject类,CBitmap和CBitmap-derived classes
调色板

HPALETTE

CGdiObject类,CPalette和CPalette-derived classes
区域 HRGN

CGdiObject类,CRgn和CRgn-derived classes

图像列表 HimageLIST

CimageList和CimageList-derived classes

套接字 SOCKET

CSocket,CAsynSocket及其派生类

从广义上来看,文档对象和文件可以看作一对MFC Object和Windows Object,分别用CDocument类和文件句柄描述。

Windows Object:用SDK的Win32 API编写各类Windows应用法度,有其共同的规律:起首是编写WinMain函数,编写处理惩罚消息和事务的窗口过程WndProc,在WinMain里头注册窗口(Register Window),创建窗口,然后开端应用法度的消息轮回。

MFC应用法度也不例外,因为MFC是一个建树在SDK API根蒂根基上的编程框架。对法度员来说所不合的是:一般景象下,MFC框架主动完成了Windows挂号、创建等工作。

2.MFC 窗口对Windows 窗口的封装

(1)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中。该域是一个固定长度的缓冲区,依次存放模块注册的“窗口类”的名字(每个名字是以“ ”结尾的字符串)。之所以如许做,是为了DLL退出时能主动作废(Unregister)它注册的窗口类。

最后,返回TRUE默示成功注册。

②调用AfxRegisterWndClass注册

AfxRegisterWndClass函数也是MFC全局函数。AfxRegisterWndClass的函数原型:

LPCTSTR AFXAPI AfxRegisterWndClass(UINT nClassStyle,HCURSOR hCursor, HBRUSH hbrBackground, HICON hIcon);

参数1指定窗口类风格;参数2、3、4分别指定该窗口类应用的光标、靠山刷、像标的句柄,缺省值是0。

此函数按照窗口类属性动态地产生窗口类的名字,然后,断定是否该类已经注册,是则返回窗口类名;不然用指定窗口类的属性(窗口过程指定为缺省窗口过程),调用AfxRegisterCalss注册窗口类,返回类名。

③调用::RegisterWndClass注册

直接调用Win32的窗口注册函数::RegisterWndClass注册“窗口类”,如许做有一个毛病:若是是DLL模块,如许注册的“窗口类”在法度退出时不会主动的被作废注册(Unregister)。所以必须记得在DLL模块退出时作废它所注册的窗口类。

子类化   子类化(Subclass)一个“窗口类”,可主动地获得它的“窗口类”属性。

(2)MFC窗口类CWnd

在Windows体系里,一个窗口的属性分两个处所存放:一项目组放在“窗口类”里头,如上所述的在注册窗口时指定;另一项目组放在Windows Object本身,如:窗口的尺寸,窗口的地位(X,Y轴),窗口的Z轴次序,窗口的状况(ACTIVE,MINIMIZED,MAXMIZED,RESTORED…),和其他窗口的关系(父窗口,子窗口…),窗口是否可以接管键盘或鼠标消息,等等。

为了表达所有这些窗口的共性,MFC设计了一个窗口基类CWnd。有一点很是首要,那就是CWnd供给了一个标准而通用的MFC窗口过程,MFC下所有的窗口都应用这个窗口过程。至于通用的窗口过程却能为各个窗话柄现不合的操纵,那就是MFC消息映射机制的奥秘和感化了。

CWnd供给了一系列成员函数,或者是对Win32相干函数的封装,或者是CWnd新设计的一些函数。这些函数大致如下。

窗口创建函数

这里首要评论辩论函数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调用了成员函数CreateEx。CWnd::CreateEx的原型如下

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,

  LPCTSTR lpszWindowName, DWORD dwStyle,

  int x, int y, int nWidth, int nHeight,

  HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)

CreateEx有11个参数,它将调用::CreateWindowEx完成窗口的创建,这11个参数对应地传递给::CreateWindowEx。参数指定了窗口扩大风格、“窗口类”、窗口名、窗口大小和地位、父窗口句柄、窗口菜单和窗口创建参数。

窗口创建时发送WM_CREATE消息,消息参数lParam指向一个CreateStruct布局的变量,该布局有11个域,Windows应用和CreateEx参数一样的内容填充该变量。

窗口烧毁函数

DestroyWindow函数, 烧毁窗口

PostNcDestroy( ),烧毁窗口后调用,虚拟函数

用于设定、获取、改变窗口属性的函数

SetWindowText(CString tiltle) 设置窗口题目

GetWindowText() 获得窗口题目

SetIcon(HICON hIcon, BOOL bBigIcon);设置窗口像标

GetIcon( BOOL bBigIcon ) ;获得窗口像标

GetDlgItem( int nID);获得窗口类指定ID的把握子窗口

GetDC(); 获得窗口的设备高低文

SetMenu(CMenu *pMenu); 设置窗口菜单

GetMenu();获得窗口菜单

。。。

用于完成窗口动作的函数,用于更新窗口,迁移转变窗口,等等。一项目构成员函数设计成或可重载(Overloaded)函数,或虚拟(Overridden)函数,或MFC消息处理惩罚函数。这些函数或者实现了一项目组功能,或者仅仅是一个空函数。如:

有关消息发送的函数:

SendMessage( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );给窗口发送发送消息,立即调用体式格式

PostMessage(( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );给窗口发送消息,放进消息队列

有关改变窗口状况的函数:

MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );移动窗口到指定地位

ShowWindow(BOOL );显示窗口,使之可见或不成见

实现MFC消息处理惩罚机制的函数:

virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); 窗口过程,虚拟函数

virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );处理惩罚号令消息

消息处理惩罚函数:

OnCreate( LPCREATESTRUCT lpCreateStruct );MFC窗口消息处理惩罚函数,窗口创建时由MFC框架调用

OnClose();MFC窗口消息处理惩罚函数,窗口创建时由MFC框架调用

CWnd的导出类是类型更具体、功能更完美的窗口类,它们持续了CWnd的属性和办法,并供给了新的成员函数(消息处理惩罚函数、虚拟函数、等等)

3.在MFC下创建一个窗口对象

MFC下创建一个窗口对象分两步,起首创建MFC窗口对象,然后创建对应的Windows窗口。在内存应用上,MFC窗口对象可以在栈或者堆(应用new创建)中创建。具体表述如下:

创建MFC窗口对象。经由过程定义一个CWnd或其派生类的实例变量或者动态创建一个MFC窗口的实例,前者在栈空间创建一个MFC窗口对象,后者在堆空间创建一个MFC窗口对象。

在MFC中,还供给了一种动态创建技巧。动态创建的过程实际上也如上所述分两步,只不过MFC应用这个技巧是由框架主动地完成全部过程的。凡是框架窗口、文档框架窗口、视应用了动态创建。

在Windows窗口的创建过程中,将发送一些消息,如:

在创建了窗口的非客户区(Nonclient area)之后,发送消息WM_NCCREATE;

在创建了窗口的客户区(client area)之后,发送消息WM_CREATE;

窗口的窗口过程在窗口显示之前收到这两个消息。

若是是子窗口,在发送了上述两个消息之后,还给父窗口发送WM_PARENATNOTIFY消息。其他类或风格的窗口可能发送更多的消息,具体拜见SDK开辟文档。

4.MFC窗口的应用

MFC供给了多量的窗口类,其功能和用处各别。法度员应当选择哪些类来应用,以及怎么应用他们呢?

直接应用MFC供给的窗口类或者先从MFC窗口类派生一个新的C++类然后应用它,这些在凡是景象下都不须要法度员供给窗口注册的代码。是否须要派生新的C++类,视MFC已有的窗口类是否能满足应用请求而定。派生的C++类持续了基类的特点并改变或扩大了它的功能,例如增长或者改变对消息、事务的特别处理惩罚等。

首要应用或持续以下一些MFC窗口类:

  框架类CFrameWnd,CMdiFrameWnd;

  文档框架CMdiChildWnd;

  视图CView和CView派生的有特别功能的视图如:列表CListView,编辑CEditView,树形列表CTreeView,支撑RTF的CRichEditView,基于对话框的视CFormView等等。

MFC进修笔记2——MFC和Win32相关推荐

  1. C++MFC编程笔记day01 MFC介绍、创建MFC程序和重写消息处理

    一.MFC概念和作用 1.全称Microsoft Foundation Class Library,我们称为微软基础类库,封闭了绝大部分的win32 Api函数,C++语法中的数据结构,程序的执行流程 ...

  2. 深入浅出MFC学习笔记:MFC六大关键技术仿真之RTTI运行时类型识别

    RTTI(运行时类型识别) 参考文献:深入浅出MFC-侯捷 怎样去构造类别型录网? 一.定义数据结构: 其中pFirstClass指针属于痊愈变量,所以它应该以static修饰之. 而且我们最终希望达 ...

  3. C++ MFC 学习笔记+小型通讯录系统实现

    MFC 最详细入门教程 [MFC常用函数总结](https://www.cnblogs.com/jiu0821/p/4606639.html) [C++ & MFC]https://www.c ...

  4. snap7-c++/MFC开发笔记

    snap7-c++/MFC开发笔记 书接上文,通过对python-snap7的库的研究,笔者掌握了上位机与plc通讯的基本原理与方法,然工业现场上位机的用户界面基本上是以c++为底层语言制作的,pyt ...

  5. VC学习笔记---ATL MFC CLR三个库的区别

    MFC.ATL和CLR是VC2005内置的三大库,涵盖了Windows的各种开发方法和开发应用.当然关于C++开发的库不止这三个,不过这三个是微软推荐. 从编程所处层次而言,WIN32为最底层,其次是 ...

  6. MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结

    MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结 1.MFC单文档程序运行流程 1.首先利用全局变量对象 theApp 启动应用程序 (这是因为这个全局对象,基类CWinApp中 this ...

  7. 我的HEVC码流分析工具MFC小笔记:树形控件使用及窗口缩放

    大约1个半月前,发布了自己写的HEVC码流分析工具.当时的版本显示语法元素使用是的Edit控件.很多主流分析工具都使用树形控件,看上去觉得比较高端,于是在纠结一天后下定决心自己也实现树形的HEVC语法 ...

  8. 深入浅出MFC学习笔记

    深入浅出MFC学习笔记 ithzhang CSDN博客:http://blog.csdn.net/ithzhang/article/category/1159054 转载于:https://blog. ...

  9. MFC学习笔记--MFC创建窗口

    MFC创建窗口 基本说明 过程 消息映射机制 应用例子 利用模版创建窗口 文化建设 基本说明 mfc:微软基础类库(microsoft foundation classes)微软公司提供的类库,以 * ...

最新文章

  1. mqtt session保持 订阅消息_如何使用 MQTT 报文实现发布订阅功能
  2. 棱形旋转c语言程序_C 语言时隔 5 年重回巅峰,这 20 个热门项目拿去练手!
  3. Android 显示、隐藏状态栏和导航栏
  4. 相关Linux命令的学习
  5. linux tar命令 打包 解压
  6. 笔记-信息化与系统集成技术-供应链管理
  7. [HNOI 2011]卡农
  8. js中call与apply用法
  9. 利用均差的牛顿插值法(Newton)
  10. ASP.NETLinkButton的Click事件中获取CommandArgument的值
  11. Visualbox中linux的网络配置
  12. Intellj Idea 如何设置类头注释和方法注释
  13. MySQL高级知识(九)——慢查询日志
  14. ubuntu下安装JDK以及配置
  15. oracle修改asm参数文件,修改asm中的spfile参数
  16. tpadmin导入数据库问题
  17. activity关闭和dialog.dismiss冲突的解决(Activity has leaked window com.android.internal.p
  18. html5标签figure、figcaption
  19. 计算机维护记录软件,Take-1 Recorder(电脑操作记录软件)
  20. ubuntu安装QT依赖

热门文章

  1. H2数据库中的数据类型
  2. 赠与今年的大学毕业生 - 胡适
  3. android有多个活动,Android活动一探究竟
  4. php国际象棋棋盘,PHP实现国际象棋棋盘的样式效果(代码示例)
  5. 在OpenStack私有云上安装配置虚拟机
  6. Draggabilly中文文档
  7. CAD“左手键”快捷命令表,大大提高绘图效率
  8. MacTeX添加.sty文件
  9. easywechat (在thinkphp5中使用easywechat完成微信网页认证)
  10. html5文本框里插图片文字,word应用教程:在文本框内插入图片