MFC(老古董)入门(p1)

主要内容

  • MFC简介

  • 句柄(handle)

  • 消息-响应模型

  • 基础中的仪式感"hello, world!"

    我只准备从一个初学者(我自己)的角度记录一些学习的过程(似乎没有任何学习计划?),和面向对象(object)可视化的一些思想,以供自己方便之故。 在记录过程中我不准备对MFC中的API(除非必要)进行深入探索,因为这些都可以在微软官方文档(或者因为过时而不太好找:p)中获得。还有一个原因是本学期开了一门以MFC为主要工具的可视化课(不知道系老师居然已经如此和实际脱节?),因而必须要掌握一些相关知识,在这之余也许会学习一下QT,但既然这已开篇,罗马之路也未必不通。

首先搜集了一些关于MFC之前需要理解的基础概念(多是“C+V”,不全面,而且不详细,不要细品)

MFC简介

MFC(Microsoft Foundation Classes)是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,vc++是微软公司开发的c/c++的集成开发环境,所谓集成开发环境,就是说利用它可以编辑,编译,调试,而不是使用多种工具轮换操作,灵活性较大。vc也指它的内部编译器,集成开发环境必须有一个编译器内核,例如DevC++其中一个编译器内核就是gcc。 MFC除了是一个类库以外,还是一个框架,在vc++里新建一个MFC的工程,开发环境会自动帮你产生许多文件,同时它使用了mfcxx.dll。xx是版本,它封装了mfc内核,所以你在你的代码看不到原本的SDK编程中的消息循环等等东西,因为MFC框架帮你封装好了,这样你就可以专心的考虑你程序的逻辑,而不是这些每次编程都要重复的东西,但是由于是通用框架,没有最好的针对性,当然也就丧失了一些灵活性和效率。但是MFC的封装很浅,所以效率上损失不大。

MFC类派生结构

MFC(老古董)入门(p1)

详情参见http://https://docs.microsoft.com/zh-cn/cpp/mfc/mfc-desktop-applications?view=vs-2019

句柄(handle)

含义

类比于UNIX中的文件指针,该指针指向FILE结构来完成对文件的读写操作而不用关心文件状态的细节。句柄(handle)是Windows用来标识被应用程序所建立或使用对象的唯一整数,即一个4字节(64位程序中为8字节)长的数值,Windows系统使用各种各样的句柄标识诸如应用程序实例,窗口,控件,位图,GDI对象,控件或者文件等等,应用程序能够通过句柄访问相应的对象的信息。但是句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不在I/O文件中,它是毫无用处的。

句柄与普通指针的区别在于,指针包含的是引用对象的内存地址,但是由于Windows系统引入了虚拟内存机制,因而对象的地址是不确定的,这就需要句柄记载数据地址的变更,一个由系统所管理的引用标识,可以被系统重新定位到一个内存地址上。这种间接访问对象的模式增强了系统对引用对象的控制同时封装了数据。

映射

句柄如何与对象映射
封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互转换。在windows中,存在两种映射方式:

  1. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转换而已。这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。

  2. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操作系统创建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找到空入口,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其在表中的入口被释放。

消息模型

消息机制

在Windows中发生的一切都可以用消息来表示,消息用于告诉操作系统发生了什么,所有的Windows应用程序都是消息驱动的。 一个消息是由消息的名称(UINT)和两个参数(WPARAM, LPARAM)组成。消息的参数中包含有重要的信息。例如对鼠标消息而言,LPARAM中一般包含鼠标的位置信息,而WPARAM参数中包含了发生该消息时,SHIFT、CTRL等键的状态信息,对于不同的消息类型来说,两个参数也都相应地具有明确意义。MFC库将很多底层的消息都屏蔽,使用户更加方便、简易地处理消息。例如,用户接收到诸如移动鼠标键(WM_MOUSEMOVE)消息或单击鼠标键(WM_LRBUTTONDOWN)消息时不必处理窗口和鼠标的重画工作,MFC及应用程序框架会替用户做这些工作。在使用MFC进行编程时,用户只需处理一些高层的消息,例如,“用户在单击窗口中的OK按扭”,“用户现在选中了下拉列表框中的第五项”等等,这样就大大减轻了程序员的负担。

##窗口句柄

系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。

仪式感的"hello, world!"

  1. 新建一个MFC项目
    MFC(老古董)入门(p1)

  2. 在CView的派生类中OnDraw()中添加TextOut()函数

MFC(老古董)入门(p1)

pDC是一个指向设备上下文类CDC类的指针,该类中其中提供了很多关于界面绘图的方法,本例只调用一个(TextOutW())

  1. 编译结果

MFC(老古董)入门(p1)

编译环境VS2017