以面到点的学习MFC
市面上讲解学习MFC的书籍不胜其多,但是阅读的同学呢,看了一些内容以后,就无法阅读下去了,觉得MFC好难,有的呢,就会直接去看别人写的程序,不管是大或小,有时候也能明白一点点,但是总是走不出自己开发设计的第一步,不知道如何实现自己的思想。我本身自己也一开始阅读了一些如何学习MFC的书籍和视频教程,但是总归起来,效果并不明显,也可以说我的口头禅“残废”。我分析了一下,在这里我谈谈我的看法。
我们大家都知道,mfc是一个从win32 sdk上抽象出来的一个层,引入了类和对象的概念。用面向对像的思想管理win32代码。原来的win32api和机制就是基本的元素,用来构成了MFC这个框架。既然是框架,那么它已经为我们写好了很多默认的程序行为,当我们用mfc向导生成一个基本程序框架的时候,里面有一些类,还有很多初始化代码。首先这样一些代码就看得头痛,对于刚刚接触的人来说就会出现以下问题,不知道为何这些代码会出现在这个地方,它起了什么作用,我放到别的地方可以不可以,我改变他们的执行顺序可不可以,有些由框架生成的东西,我不需要,如何才可以不让它初始化,有些元素我需要自定义,如程序图标,我如何才可以,在哪里修改等等一系列的问题。也许你通过在某本书上讲过了,那么你学习到了,你就会了,但是这只是一个点,举个例子,你想修改程序的图标,在你完全不知道如何去修改的情况下,你参考了一本书,它刚好讲述了如何修改程序图标的问题,那么你看了,你学习到了。但是如果现在要你修改默认的菜单选项,你可能又不会了,你可能又想到去书上找一个可以修改菜单的文章了。其实这样是一种以“点”为主的学习方法,这样的学习方法,其实是很死板的,为什么这么多呢,因为你可能学习了如何修改程序图标,那么你可能只会像你看的那本书上讲的那样去修改,那么你想过没有,还没有别的修改方法,我添加别的资源和代码的时候,我还是用这样的方法修改,会不会有什么异常发生呢。如果你这样学习,当然是不知道的。你这样的学习方法,犹如高考的同学再打题海战术,累死不讨好的工作,那么我们不熟学习方法,灵活的使用方法,举一反三的方法。
前面我说过很多讲MFC的书,都犯了大致相同的一个问题,那么它们的讲解是从某个点开始的,如,CObject类,它是所有类的基类,那么很多书会从它开始,对它的功能以及相关的宏进行详细的讲解。接着又讲app类,wnd类,等等,讲到每个类的时候,都会详细的讲解它的常用成员函数和数据什么的,这样其实学到的都是一个一个离散的(分散的)点,点与点的关系,根本不清楚,越到后来,学习到的东西由于无法联系起来,在我们的脑海了非常混乱,而且,说实话,有关类及相关资源的讲解,其实在msdn有更加详细的讲解,我们不必如此一一的,就像小学生学习汉字一样,都完全学习。这里我就举一例子,在小学我们是学习基本的汉字,学习如何使用字典,基本的句子结构等等,这个过程很像我们学习c及c++语言,在我们学习c和c++语言的时候,我们学习了基本的语法及基本输入输出语句。到了中学的时候,大学的时候,还有谁会天天背某个字的读音和写法,然后叫你听写的,没有了吧,而且用小学学的的基本方法,学习表达能力,如果有不认识的字,我们可以查字典嘛。编程也是这样,如果你掌握了方法,那么就是一个能力提升的过程,什么能力呢,就是你的程序设计能力和编写能力,这时候你所关注的就是编写一个什么样的程序,如何编写的问题,而不是某个函数什么意思,某个类怎么用,这些在msdn中有详细的介绍,不需要我们都学习,而是我们需要的时候,查询msdn。就可以了。
下面我说说今天我要说的主题,就是由面到点的学习,从一个面出发,而不再是一个个单独的知识点。也可以说是先整体后局部的学习方法,例如,我们开始接触到MFC,那么我们不用去管单个类或是方法如何使用,而是从整体,去把握它的实现原理,从哪里开始执行,先后它执行了那些语句,类对象的构造顺序,每个初始化函数中所做的工作等等,也就是从原理上去学习,至于具体一个类的对象如何使用,某个函数的参数又是什么意思等等,这样的细节我们先不用去管。但是 这个时候又有一个问题,mfc很多工作都是在底层完成,我们无法查看或是即使可以查看,由于其复杂的逻辑关系,我们也理不清到底是个什么情况。那么我们应该如何去知道它底层的运行,以及这些运行的顺序和职能等等。举个例子,比如我们用mfc向导生成一个单文档程序的框架,一出来,默认情况下就有5个类,分别是app类,mainframe类,document类,view类,还有一个可选的about类。那么这些类的相互关系是什么,从哪儿开始,我要添加一个功能到程序中,应该在哪个类的哪个函数中添加等等的问题。这样的问题,应该说是困扰着大家的,大部分使用者呢,估计就是只能使用view类,因为它代表了这个窗口的客户区,可以在这个客户区里面绘制文本或图像等等操作,而额外的几个类,就知道的很少,如果我要再添加一个类型应该如何做,在什么地方添加,mfc会如何对待他等等,估计很多都不知道,所以,如果是这样情况,根本说无法做到随心所欲的设计程序。因为你不知道它的底层到底发生了什么事情。那么接下来我做一个假设,假设你明白5个类之间的关系及其中的原理,那么现在我要改变菜单上默认的“打开”命令,我们知道默认的打开命令是执行的CWinapp类OnFileOpen操作的,那么现在我要实现自定义的打开命令,当我点击一个打开命令的时候,我要显示一个自己的打开对话框,那么首先我们就要删掉映射到CWinapp类的打开命令映射项目,然后添加自己的映射项目映射到我们继承的app类的打开命令处理函数中,那么剩下的就是在这个命令函数中写代码实现打开这个命令,当然是要显示一个打开对话框,要实现这个打开对话框,其实就相当于一个点,我们从一个面找到了如何实现自己的设想,寻找到我们的实现点,要实现这个点,其实就很简单了,只用查询msdn,例如,通过查GetOpenFIleName,IFileDialog,CFileDialog等等,都可以实现,甚至在msdn中你直接就可以找到已经写好的代码,你直接复制,稍微做一点修改,如修改要打开的文件类型的扩展名,是多选还是单选等等,就可以满足你的要求,这样,你就完成了你要完成的想改变默认打开命令的要求。
上面只是举了一个简单的例子,还留了一个问题,就是底层很复杂的代码,如果要我去看底层的代码来知道mfc到底为了做了什么,怎么做的,是相当的困难的。那么我们就可以在msdn中找到这一切,如下图:
这个图来自msdn在讲解mfc文档视图框架的时候中的一个图,为我们阐述了内部各个类之间的关系,相互的构造顺序等等。如此,我们就可以层层深入,例如,我们再看到doucment类的时候,我们就会接触到串行化,然后就会讲到CObject这个类,通过这种方法,你在不知不觉中已经就学会了CObject,而不像书本中,一来就给你讲CObject这个类要来的合理些。这里也就是说,通过msdn,我们了解我们要使用的对象的基本原理,然后分析出如何才能实现我们的想法,最后书写代码实现。
最后,还是要说,我们要自己培养自己归纳总结的能力,也不要希望mfc一次性就把所有的原理性的东西都给你,比如,由mfc向导生成的基本框架,你不可能在msdn一个地方就找到所有你需要的,而是分散在各个地方,比如,你可以查app类,cwnd类,document类,mfc概念,c++编程方法(msdn中的)找到相应的知识,在查看它们的时候,我们不要把注意力注意到单个方法的实现, 而是要理清相互的关系,通过自己不断的分析总结,归纳,对mfc的理解就会越来越完整,越来越深入。