微软基础类库MFC概述

微软基础类库(MFC:Microsoft Foundation Class)是微软为Windows程序员提供的一个面向对象的Windows编程接口,它大大简化了Windows编程工作。使用MFC类库的好处是:首先,MFC提供了一个标准化的结构,这样开发人员不必从头设计创建和管理一个标准Windows应用程序所需的程序,而是“站在巨人肩膀上”,从一个比较高的起点编程,故节省了大量的时间;其次,它提供了大量的代码,指导用户编程时实现某些技术和功能。
  对用户来说,用MFC开发的最终应用程序具有标准的、熟悉的Windows界面,这样的应用程序易学易用;另外,新的应用程序还能立即支持所有标准Windows特性,而且是用普通的、明确定义的形式。事实上,也就是在Windows应用程序界面基础上定义了一种新的标准——MFC标准。
  一、MFC类库概念和组成
  类库是一个可以在应用中使用的相互关联的C++类的集合。Microsoft提供了一个基础类库MFC,其中包含用来开发C++和C++
Windows应用程序的一组类。基础类库的核心是以C++形式封装了大部分的Windows
API。类库表示窗口、对话框、设备上下文、公共GDI对象如画笔、调色板、控制框和其他标准的Windows部件。这些类提供了一个面向Windows中结构的简单的C++成员函数的接口。
  MFC可分为两个主要部分:(1)基础类(2)宏和全程函数。
  1、MFC基础类:MFC中的类按功能来分可划分为以下几类:
      基类 应用程序框架类 应用程序类 命令相关类 文档/视类
      线程类 可视对象类 窗口类 视类 对话框类
      属性表 控制类 菜单类 设备描述表 绘画对象类
      通用类 文件 诊断 异常 收集
      模板收集 其他支持类      OLE2类 OLE基类 OLE可视编辑包装程序类
      OLE可视编辑服务器程序类 OLE数据传输类 OLE对话框类 其他OLE类 数据库类
  2、宏和全局函数:若某个函数或变量不是某个类的一个成员,那么它是一个全程函数或变量。Microsoft基本宏和全程函数提供以下功能:
      数据类型运行时刻对象类型服务诊断服务异常处理
      CString格式化及信息框显示消息映射应用消息和管理对象连接和嵌入(OLE)服务
      标准命令和Windows IDs  
  3、约定:全程函数以“Afx”为前缀,所有全程变量都是以“afx”为前缀,宏不带任何特别前缀,但是全部大写
  常见的全局函数和宏有:AfxGetApp,AfxGetMainWnd,AfxMessageBox,DEBUG_NEW等,我们会在后面的章节中用到并对它们进行介绍。
  从继承关系来看,又可将MFC中的类分成两大类:大多数的MFC类是从CObject继承下来;另外一些类则不是从CObject类继承下来,这些类包括:字符串类CString,日期时间类CTime,矩形类CRect,点CPoint等,它们提供程序辅助功能。
  由于MFC中大部分类是从CObject继承下来的,CObject类描述了几乎所有的MFC中其他类的一些公共特性,因此我们有必要理解CObject类。
  我们首先查看一下CObject类的定义,CObject类定义如下清单2.1所示:
  清单2.1CObject类的定义
  // class CObject is the root of all compliant(顺从的、适应的) objects
  class CObject
  {
  public:
  // Object model (types, destruction, allocation)
  virtual CRuntimeClass* GetRuntimeClass() const;
  virtual ~CObject(); // virtual destructors are necessary
  // Diagnostic(诊断的) allocations(配置)
  void* PASCAL operator new(size_t nSize);
  void* PASCAL operator new(size_t, void* p);
  void PASCAL operator delete(void* p);
  #if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
  // for file name/line number tracking using DEBUG_NEW
  void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
  #endif
  // Disable the copy constructor and assignment by default so you will get
  // compiler errors instead of unexpected behaviour if you pass objects
  // by value or assign objects.
  protected:
  CObject();
  private:
  CObject(const CObject& objectSrc); // no implementation(执行)
  void operator=(const CObject& objectSrc); // no implementation
  // Attributes
  public:
  BOOL IsSerializable() const;
  BOOL IsKindOf(const CRuntimeClass* pClass) const;
  // Overridables
  virtual void Serialize(CArchive& ar);
  // Diagnostic Support
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
  // Implementation
  public:
  static const AFX_DATA CRuntimeClass classCObject;
  #ifdef _AFXDLL
  static CRuntimeClass* PASCAL _GetBaseClass();
  #endif
  };
  CObject类为派生类提供了下述服务:
  1、对象诊断。MFC提供了许多诊断特性,它可以:
  输出对象内部信息:CDumpContext类与CObject的成员函数Dump配合,用于在调试程序时输出对象内部数据
  对象有效性检查:重载基类的AssertValid成员函数,可以为派生类的对象提供有效性检查
  运行时访问类的信息:MFC提供了一个非常有用的特性,它可以进行运行时的类型检查。如果从CObject派生出一个类,并使用了以下三个宏(IMPLEMENT_DYNAMIC,IMPLEMENT_DYNCREATE或IMPLEMENT_SERIAL)之一,就可以:
  运行时访问类名
  安全可靠的把通用的CObject指针转化为派生类的指针
  比如,我们定义一个主窗口类
  CMyFrame:public CFrameWnd
  {
  ......
  }
  然后我们使用这个类:
  CMyFrame *pFrame=(CMyFrame*)AfxGetMainWnd();
  pFrame->DoSomeOperation();
  AfxGetMainWnd是一个全局函数,返回指向应用程序的主窗口的指针,类型为CWnd*,因此我们必须对它进行强制类型转换,但我们如何知道是否转换成功了呢?我们可以使用CObject的IsKindOf()成员函数检查pFrame的类型,用法如下:
  ASSERT(pFrame->IsKindOf(RUN_TIMECLASS(CMyFrame)));
  将上一语句插入到pFrame->DoSomeOperation()之前,就可以在运行时作类型检查,当类型检查失败时,引发一个断言(ASSERT[断言声称]),中断程序执行。
  2、对象持续性
  通过与非CObject派生的档案类CArchive相结合,提供将多个不同对象以二进制形式保存到磁盘文件(Serilization)中以及根据磁盘文件中的对象状态数据在内存中重建对象(Deserilization)的功能。
  然而,MFC不仅仅是一个类库,它还提供了一层建立在Windows API的C++封装上的附加应用程序框架。该框架提供了Windows程序需要的多数公共用户界面。
  所谓应用程序框架指的是为了生成一般的应用所必须的各种软组件的集成。应用框架是类库的一种超集。一般的类库只是一种可以用来嵌入任何程序中的、提供某些特定功能(如图象处理、串行通信)的孤立的类的集合,但应用框架却定义了应用程序的结构,它的类既相互独立,又相互依赖,形成一个统一的整体,可以用来构造大多数应用程序。中国用户熟悉的Borland C++的DOS下的Turbo Vision和Windows下OWL(Object Windows Language)都是应用框架的例子。
  下面我们举个具体的例子来说明MFC所提供的应用程序框架,程序如清单2.2。
  清单2.2应用程序框架示例
  #include
  //derived(起源) an application class
  class CMinMFCApp:public CWinApp
  {
  public:
  BOOL InitInstance();
  };
  //Derive the main window class
  class CMainWindow:public CFrameWnd
  {
  public:
  CMainWindow();
  DECLARE_MESSAGE_MAP()
  };
  BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
  END_MESSAGE_MAP()
  /*CMinMFCApp Member Functions*/
  BOOL CMinMFCApp::InitInstance()
  {
  m_pMainWnd=new CMainWindow();
  m_pMainWnd->ShowWindow(m_nCmdShow);
      m_pMainWnd->UpdateWindow();
  return TRUE;
  }
  /*CMainWindow member functions*/
  CMainWindow::CMainWindow()//constructor
  {
  Create(NULL,"Min MFC Application",WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL);
  }
  /*an instance of type CMinMFCApp*/
  CMinMFCApp ThisApp;
  清单2.2程序段定义了一个最小的MFC应用程序所需的框架程序。其中声明了CMinMFCApp类,它是从应用程序类CWinApp中派生下来的;和窗口CMainWindow类,它是从框架窗口CFrameWnd类派生出来。我们还用CMinMFCApp定义了一个全局对象ThisApp。读者也许会问,为什么没有WinMain函数?因为MFC已经把它封装起来了。在程序运行时,MFC应用程序首先调用由框架提供的标准的WinMain函数。在WinMain函数中,首先初始化由CMinMFCApp定义的唯一的实例,然后调用CMinMFCApp继承CWinApp的Run成员函数,进入消息循环。退出时调用CWinApp的ExitInstance函数。
  由上面的说明可以看到,应用程序框架不仅提供了构建应用程序所需要的类(CWinApp,CFrameWnd等),还定义了程序的基本执行结构。所有的应用程序都在这个基本结构基础上完成不同的功能。
  MFC除了定义程序执行结构之外,还定义了三种基本的主窗口模型:单文档窗口,多文档窗口和对话框作为主窗口。
  Visual C++提供了两个重要的工具,用于支持应用程序框架,它们就是前面提到AppWizard和ClassWizard。AppWizard用于在应用程序框架基础上迅速生成用户的应用程序基本结构。ClassWizard用于维护这种应用程序结构。
  二、MFC的优点
  Microsoft MFC具有以下不同于其它类库的优势:
          完全支持Windows所有的函数、控件、消息、GDI基本图形函数,菜单及对话框。类的设计以及同API函数的结合相当合理。
          使用与传统的Windows API同样的命名规则,即匈牙利命名法。
          进行消息处理时,不使用易产生错误的switch/case语句,所有消息映射到类的成员函数,这种直接消息到方法的映射对所有的消息都适用它通过宏来实现消息到成员函数的映射,而且这些函数不必是虚拟的成员函数,这样不需要为消息映射函数生成一个很大的虚拟函数表(V表),节省内存。
          通过发送有关对象信息到文件的能力提供更好的判定支持,也可确认成员变量。
          支持异常错误的处理,减少了程序出错的机会
          运行时确定数据对象的类型。这允许实例化时动态操作各域
          有较少的代码和较快的速度。MFC库只增加了少于40k的目标代码,效率只比传统的C Windows程序低5%。
          可以利用与MFC紧密结合的AppWizard和ClassWizard等工具快速开发出功能强大的应用程序。
          另外,在使用MFC时还允许混合使用传统的函数调用。
  三、MFC对消息的管理
  Windows消息的管理包括消息发送和处理。为了支持消息发送机制,MFC提供了三个函数:SendMessage、PostMessage和SendDlgItemMessage。而消息处理则相对来说显得复杂一些。MFC采用了一种新的机制取代C语言编程时对Windows消息的Switch/Case分支,简化了Windows编程,使程序可读性、可维护性大大提高。
  1、MFC对消息的处理
  MFC采用一种消息映射机制来决定如何处理特定的消息。这种消息映射机制包括一组宏,用于标识消息处理函数、映射类成员函数和对应的消息等。其中,用afx_msg放在函数返回类型前面,用以标记它是一个消息处理成员函数。类若至少包含了一个消息处理函数,那么还需要加上一个DECLARE_MESSAGE_MAP()宏,该宏对程序执行部分所定义的消息映射进行初始化。清单2.3演示了消息处理函数的例子:
  清单2.3 消息处理函数例子
  class CMainFrame:CFrameWnd{
  public:
  CMainFrame();
  protected:
  //{ {AFX_MSG(CMainFrame)
  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  afx_msg void OnEditCopy();
  afx_msg void OnClose();
  //}}AFX_MSG
  DECLARE_MESSAGE_MAP()
  };
  成员函数OnCreate,OnEditCopy,OnClose分别用来处理消息WM_CREATE、ID_EDIT_COPY和WM_CLOSE。其中,WM_CREATE和WM_CLOSE是系统预定义消息,包含在Windows.h中。而ID_EDIT_COPY是菜单Edit->Copy的标识,也就是用户选择Edit->Copy菜单项时产生的消息,一般在资源文件头文件中定义。在类的实现部分给出这三个成员函数的定义,以及特殊的消息映射宏。上面的例子的消息映射宏定义如下:
  BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值