初学者这样分析MFC代码(Dialog based工程)- -

来源:互联网 发布:js newarray 编辑:程序博客网 时间:2024/04/28 05:19
导读:

  

  在MFC瘦身代码中,你或者已经发现有两个特殊的文件,StdAfx.hS和tdAfx.cpp,它

  们仅仅是include头文件,什么也没做。如果你够细心,你还会发现在每个cpp文件最上面

  都include了StdAfx.h,这到底是干什么的呢?可以去掉吗?我们在Test1.cpp把#include

  "stdafx.h"这一句去掉,编译发现出现这样的错误:fatal error C1010: unexpected

  end of file while looking for precompiled header directive。意思大概是找不到预

  编译指示。这个文件到底是干什么用的?其实wizard已经告诉我们答案了,答案就在

  “注释” 里面!什么?注释?不是已经删掉了吗?是的,就是在我们删掉的注释里面

  ,所以,wizard所做的每一件事都是有道理的。那我们为什么要删掉注释?不就是为了能

  让你集中注意力看关键的东西嘛!还记得我们一开始备份的工程吗?打开看看:

  // stdafx.h : include file for standard system include files,

  // or project specific include files that are used frequently, but

  // are changed infrequently

  哦,原来它是用来包含一些标准的系统头文件以及在工程中一些经常用到的但又很少改动

  的头文件(到此看到我说的话,你应该体会到英语的重要性了)。再看StdAfx.cpp的注释

  :

  // stdafx.cpp : source file that includes just the standard includes

  // Test1.pch will be the pre-compiled header

  // stdafx.obj will contain the pre-compiled type information

  看第一行,的确如此,在stdafx.cpp只有一行#include "StdAfx.h"。Test1.pch是预编译

  头(可以在工程目录下的debug文件夹找到),到底有什么作用呢?答案是这样的:VC++

  程序一般包含的头文件都比较复杂,如果每次编译都分析每一行代码(其中很多代码是一

  直不变的),将耗费大量时间在重复分析上面,因此,有必要把一些不变的结果暂时保存

  起来,留待下次使用,以节省编译时间。怎么使用Test1.pch呢?我们要指定一个头文件

  StdAfx.h,当然,也可以是别的名字,在Project->settings里的c/c++页,Category选择

  Precompiled Headers,选中Use precompiled header file,在Through header里就可以

  修改名字了。我猜是因为.h文件不能编译,因此还需要一个cpp(stdafx.cpp)文件来生

  成pch文件。

  既然这个pch预编译头是用来节省时间的,是不是说我们也可以不用?当然,我们有

  的是时间。首先在Project->settings里的c/c++页,Category选择Precompiled Headers

  ,选中Not using precompiled headers,然后在Test1.cpp和Test1Dlg.cpp中把#include

  "stdafx.h"去掉,加上StdAfx.h中的内容,跟着在工程里面删掉StdAfx.h和StdAfx.cpp,

  编译运行都没有问题!当然,这不是一个聪明的做法!不要胡闹了,把关于预编译的修改

  复原。

  还有一个小问题:为什么StdAfx.h要在cpp中include而不在.h中?那是为了避免头文

  件的重复包含。

  下面我们来看看这个程序到底是怎么执行的。对于初学者来说,我有一个比较好的方

  法,姑且称之为“断点大法”。我们把所有代码都加上断点,然后F5进行调试。当然,这

  样做你会发现vc会提示你有些断点是无效的。好了,GO,一直到程序运行,出来窗口,然

  后关闭。我把程序执行步骤列出来:

  ////////////////////////////////////////////////////////

  Test1.cpp:

  #include .....

  CTest1App theApp;/*第1步*/

  BOOL CTest1App::InitInstance()

  {/*第2步*/

  CTest1Dlg dlg;/*第3步*/

  dlg.DoModal();/*第6步*/

  return FALSE;/*第7步*/

  }/*第8步*/

  ////////////////////////////////////////////////////////

  Test1Dlg.cpp:

  #include .....

  CTest1Dlg::CTest1Dlg(CWnd* pParent )

  : CDialog(CTest1Dlg::IDD, pParent)

  {/*第4步*/

  }/*第5步*/

  其中,第6步到第7步之间需要你在对话框中点“确定”或“取消”按钮或者点标题栏中的

  “×”退出程序。

  第1步:

  先看看CTest1App theApp的注释:// The one and only CTest1App object。又看注

  释?呵呵,你可以打开另一个vc,然后打开一开始的工程查看。theApp是应用程序类的一个对象,代表了一个应用程序,这是一个单独的全局的对象。提示:你也可以改为其它的名字。

  第2步:

  进入应用程序类的一个InitInstance()函数(注释:// CTest1App initialization

  ,从函数名也能看出来)。

  第3步:

  跟着声明一个CTest1Dlg对象dlg。

  第4、5步:

  CTest1Dlg类声明一个对象后,立即调用其构造函数(关于构造函数,你需要看相关

  c++书籍),而这又引起其父类CDialog构造函数的调用。这里要提醒你注意,我们原来的

  代码是这样的:

  在.h中的声明 CTest1Dlg(CWnd* pParent = NULL);

  在.cpp中的实现

  CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)

  : CDialog(CTest1Dlg::IDD, pParent)

  注意到了吗?pParent为NULL。(详细信息请查看MSDN中CDialog::CDialog)

  我们着重关注CTest1Dlg::IDD这个参数。IDD从何而来?在头文件中:enum { IDD =

  IDD_TEST1_DIALOG },你尽可以把名字改掉,例如改成MYIDD:

  enum { MYIDD = IDD_TEST1_DIALOG };

  CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)

  : CDialog(CTest1Dlg::MYIDD, pParent)

  还可以这样:

  CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)

  : CDialog(MYIDD, pParent)

  甚至,你可以打开Resource.h找到IDD_TEST1_DIALOG的定义:

  #define IDD_TEST1_DIALOG 102

  那么你可以这样:

  CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)

  : CDialog(102, pParent)

  这说明了什么?说明这个参数不过是对话框模板资源的ID而已,那么我们可以更改这个ID

  让程序装载另外一个对话框模板资源。在ResourceView 的Dialog文件夹上右键->insert

  dialog插入一个对话框,它的默认ID是IDD_DIALOG1,我们这样做:

  enum { IDD = IDD_DIALOG1 };

  CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)

  : CDialog(CTest1Dlg::IDD, pParent)

  运行看看。于是我们得到一个启发:在InitInstance()函数里面可以根据不同的条件显示

  不同的面板。

  第6步:

  CTest1Dlg对象dlg调用其成员函数DoModal()显示对话框。

  第7、8步:

  退出程序。

  MFC程序的流程如此简单(至少目前我们表面上看到的是这样),你还有什么好怕的

  呢?学习MFC也很容易啊,呵呵,事实并非如此,下次我会结合F10、F11让你看到更多的

  东西。

  - 作者: 咸零蛋访问统计: 2005年06月14日, 星期二 11:01 加入博采打印



本文转自

http://bjtuwei.bokee.com/1914355.html
原创粉丝点击