码迷,mamicode.com
首页 > 编程语言 > 详细

MFC实现原理剖析

时间:2018-11-09 13:45:49      阅读:45      评论:0      收藏:0      [点我收藏+]

标签:相互   而且   原理   变化   求和   技巧   att   应用程序   开发人员   

“现在已经是人工智能、大数据的时代,云+端才是王道,桌面程序设计已经过时了,还有没有必要学习MFC?”
这是许多困扰刚刚入行朋友的问题,不可否认,由于python、Java等开发语言和环境的流行,Visual C++的应用范围也相应缩小。
“有人说现在c++越来越接近边缘性语言?c++程序员以后的发展方向在那里,我学习MFC会不会被淘汰?”
的确C++作为普及性应用程序设计语言的地位已经不再,但是它作为系统程序设计语言的地位没变。 笔者个人的浅见在于:一个系统程序员的核心优势之一就是对计算机装置的透彻理解。在笔者求学阶段,笔者的导师曾经有过这样的指导,对于本人的影响非常深刻:
“你们觉得你们学计算机这个专业最大的优势是什么?是会编程序吗?会写算法吗?”
“论写算法,你们不如数学方向的同学,他们天天接受逻辑思维训练,抽象能力的培养,你们不占优势”
“论写业务逻辑,比如信息管理系统,你们不如有行业经验的懂开发技术的人员,因为你们在业务理解上不占优势”
“写操作硬件,你们不如写自动化,机电一体化的,不如通信的,他们理解协议,用代码指挥硬件的能力比你们也要强”
“那么,计算机专业的核心优势在哪里?”
“我认为一定是在你们对整个计算机装置的理解,这个才是你们要强化的技能核心”
正是因为此,笔者才对进入行业领域的C++学习者不断建议:从各种角度提升自己的对计算机装置的核心理解。
那么理解计算机装置的一种可选路径在哪里呢?笔者认为莫过于对操作系统的学习和探索。毫无疑问,当前在PC市场中最为人们所熟知的操作系统就是windows了。对于普通用户来说,当他双击word图标,启动word,开始打字,排版,插入图片的时候,他一定认为是自己在处理办公业务。当这个用户按下键盘a,打出一个字母,按下鼠标,圈出一段文字,他一定认为是自己“在写,在画”这个内容。但是作为一名开发人员来说,你又是如何理解这种行为呢?
实际上,真正在写,在画的并不是这位用户,而是word这个程序。从运行原理来说,恐怕这样的描述更加精准。
技术分享图片
其实,这个呈现出来的过程中word与windows操作系统交互被用户从逻辑上忽略了。而我们程序开发人员的任务实际上是在两端编程
一方面,我们接受用户的输入,让操作系统感知到我们应用程序的存在,并将其做相应的处理逻辑;
另一方面,我们将处理好的逻辑通过windows操作系统的帮助以友好的方式呈现给用户。
这两个方面都涉及到编写代码的工作,这才是我们编码的逻辑所在。
接下来的问题就是,windows感知到用户的输入好理解,那么如何理解windows感知到应用程序的存在呢?还是以word为例
技术分享图片
打个比方,就像一所学校,每一个学员都有一个代号供学校管理调度,要求你听课,考试。有了hwnd这个概念,我们就知道了,同样,windows操作系统需要显示,销毁这个窗体,都需要通过hwnd来操作。我们编程的时候,就可以把自己需要操作的hwnd给windows操作系统,让windows操作系统实现我们的目的。很显然,一个hwnd是一个窗口的表示,同样的,呈现一个窗口肯定需要一套复杂的结构,就好比一个在学校的学生,有学号,有出生年年月,有性别,有专业,各种各样的分量信息。一个窗口结构,肯定也是一个复杂的分量组合。对应到语言层面,一定是一个C语言的struct的结构。
C语言是开发操作系统的核心语言,很显然,Windows API是面向C语言风格的。大家都知道C++是C语言的超集,微软为了方便当时的开发人员将已经存在的C语言开发方式,封装成了一套类库,这个就是MFC的由来,我们可以认为MFC是Windows C++的API。于是,这个就带来了一个新的问题:如何用C++的语义来替代C风格的开发方式。
最直接的方式就是建立面向对象的语义到实际开发概念的映射,实质今日,许多老的软件需要维护的工作,依然会从msdn中查找mfc的类结构,其中最重要的一个结构就是CWnd,这个又称为窗口类,我们来看下微软是怎么做的。
class CWnd :public CCmdTarget {
DELCARE_DYNCREATE(CWnd)
public:
CWnd();
virtual ~CWnd();

HWND m_hWnd;
operator HWND() const { return m_hWnd; }
HWND GetSafeHwnd() { return this == NULL ? NULL : m_hWnd; }

//窗口句柄映射
static CWnd* FromeHandle(HWND hWnd);
static CWnd* FormHandlePermanet(HWND hWnd);
BOOL Attach(HWND hWndNew);
HWND Detach();

…}
在C++的语义看来,用来交互的一定是一系列的对象,这些对象与对象之间的交互运动完成软件的工作过程。比如我们做这样一个想象,图示中是内存中已经存在的一系列对象,这些对象之间相互调用,只要合理安排好这些调用的先后秩序,同时这些对象的数据进行加工处理,得到结果就是这个软件系统运行过程。
技术分享图片

借助这样的思想,微软在改造C语言的编程风格的时候,他就要考虑概念的转移,以前,程序原只需要操作hwnd就可以直接和操作系统交互,现在则不然,首先,要刻画一个c++的观念与hwnd对应。这个观念的就是CWnd类设计的初衷。CWnd是批量制造窗体对象的类。他可以批量的new 出一堆窗体对象来。
首先,CWnd对象就必须有Hwnd,这个就是
技术分享图片
设计的由来。
那么,这些函数又是什么设计语义呢?
技术分享图片
这个就要谈MFC的体系了。
我们首先看下拥有了mfc之后,应用程序与操作系统的交互发生了什么样的变化:
技术分享图片
在没有MFC的时候,所有的应用程序的消息都是直接和windows系统打交道。而MFC应用程序则不然,它像一个楔子一样加载了应用程序与操作系统之间。如果我们写一个mfc的word,所有的windows消息的截获和感知,都是通过mfc来完成的。这就好像以前你可以直接和老板对话,而现在你的所有的请求和应答都只能委托给mfc来操作。
有了这个概念,再理解上面的代码就顺畅了。以前我们自己的应用程序要提请windows操作系统操作,直接访问hwnd就可以了。但是现在我们按照c++语法,我们用的是Cwnd对象。这个CWnd是一个C++对象,而且是MFC创造出来的c++对象,并不是windows的对象。所以,MFC有责任管理好这个对象,这个对象的出生与消亡都跟随的是C++语义。因此,当我们需要一个表达一个窗体的概念的时候,我们很自然的就会new一个Cwnd的对象出来。但是,这个CWnd对象是有风险的——如果这个CWnd对象先于windows的窗体出现怎么办?(CWnd对象的内存已经构建好了,但是hwnd还为空,所以它的m_hWnd为空)。同样的CWnd对象概念的出现将windows窗体的hWnd概念和CWnd的概念进行了剥离,那么从理论上讲CWnd对象可以结合任意的hWnd对象。(只要将m_hWnd赋予不同的值就可以了)。
这又是MFC的一个高超之处,就是要将hWnd和CWnd进行观念解耦,当应用程序需要用CWnd对象的观念表达Windows窗体的时候,用参数传入就可以了。以BOOL Attach(HWND hWndNew);为例,程序开发人员大可以将一个已经存在的windows窗体的hwnd传给当前的CWnd对象,通过attch方法,灵活的将windows窗体附着在Cwnd这个C++对象上。这种设计技巧是十分精妙的,既可以在不变更已有系统的情况下,灵活的用C++的方法进行开发。

http://edu.51cto.com/sd/18816
技术分享图片

MFC实现原理剖析

标签:相互   而且   原理   变化   求和   技巧   att   应用程序   开发人员   

原文地址:http://blog.51cto.com/xiacaojun/2314953

(0)
(0)
   
举报
评论 一句话评论(0
0条  
登录后才能评论!
© 2014 mamicode.com 版权所有 京ICP备13008772号-2
迷上了代码!