[开发总结]MFC/COM技术应用篇(八)

一、温故而知新—MFC框架

    1)RTTI & Dynamic Create

1

2

简要说明:

----------------------------------------------------------------------------------------------

 以上图用于说明MFC两项关键技术:RTTI(Runtime Type Information) 运行时类型识别和Dynamic Create对象动态生成。

实现机理:

       CRuntimeClass该结构为MFC内建类型,其主要作用:

        定义一个用户类型时,利用该结构记录该用户类型名和对象创建函数地址。系统中所有的用户类型信息通过该结构保存起来,并形成“类型识别网”(实际上就是链表)。

       如果一个用户类型的.h.CPP文件中加入了DECLARE_DYNCREATE()IMPLEMENT_DYNCREATE()宏,则相当于:

        1.创建了一个的CRuntimeClass结构类型的全局实例(名为:class##类名)。

        2.该实例记录了该用户类型的两项重要信息:

                   用户类型名(m_lpszClassName

                   对象创建函数指针(m_pfnCreateObject

         3.利用指针m_pBaseClass指向基类的“类型识别对象”(classBaseClass),利用m_pNextClass指向下一个“类型识别对象”,这样就将该用户类型的“类型识别对象”加入到全局的“类型识别网”(链表)中。

  4 .“类型识别网”(链表)的首指针为 :CRuntimeClass::pFirstRuntimClass ,此指针变量为全局类型。系统通过该全局指针遍历“类型识别网”(链表)。
RTTI 类型识别:
       遍历“类型识别网”(链表),比较 CRuntimeClass 类型指针或类型名 lpszClassName). 如: pObj->IsKindOf(RUNTIME_CLASS(CMyClass));
       
       Dynamic Create 动态创建:
              遍历“类型识别网”(链表),通过比较类型名( m_lpszClassName ),找到对应的对象创建函数指针 (m_pfnCreateObject) ,动态创建对象,返回“基类指针”。( 创建对象时,只需“类型识别网”中提供的信息,不依赖任何类型信息)
 
       以上与实际的应用可能存在细节上的出入,但大致的原理应该是这样。
   
        2)Message Mapping

          传统SDK程序的消息循环 
          在传统的SDK程序中,消息循环是很简单的,
在WinMain 中 CreateWindow通过一个参数将创建 的 窗口和窗口类联系起来,这样该窗口的所有消息都将发送到该窗口类的窗口函数WndProc,其后
WndProc根据不同的消息给予不同的动作。

             MFC期望的消息循环
       在传统的SDK程序中消息循环是非常简单的,并且将窗口和窗口函数绑定在一起。而在MFC中就出现了
问题,比如CDocument类,不是窗口,所以没有窗口类,但是我也想让它响应消息,怎办?问题不仅仅 如此,我们再看看MFC的消息,就会发现更多问题。
     
           MFC将消息分为三大类:
              1.标准消息,如WM_开头,任何派生自CWnd的类都可以接受该消息
              2.命令消息,即WM_COMMAND,任何派生自CCmdTarget的类,兼可接受该消息。
              3.通知类消息,Control Notification,也以WM_COMMAND形式出现,由控件产生,通知其
                   父窗口。
       
          MFC中,所有能够接受消息的类都必须继承于CCmdTarget类,因为这些类都一个共同的特征:
         含有DECLARE_MESSAGE_MAPBEGIN_MESSAGE_MAPEND_MESSAGE_MAP三个宏
      (宏的定义,在MFC中中查看很方便,这里不具体列出),就这三个宏组织了一张庞大的消息映射
        网。如下图:
                  messagemap

          从上图可以看出DECLARE_MESSAGE_MAPBEGIN_MESSAGE_MAPEND_MESSAGE_MAP三个宏的作用,其实就是创建了两个全局数据结构:

     “消息映射数组”:将消息和对应的处理函数记录下来。

      “映射表”:通过AFX_MSGMAP中的pBaseMap指针,将各类按继承顺序连接起来,从而形成消息映射网,以提供消息流动的道路。

        我们已经建立了一张消息流动网络,但是消息是怎样从产生到响应函数收到该消息?不管怎么说,对 Windows 系统来说都是一样的,它都是不断地用GetMessage(或者其它)从消息队列中取出消息,然后用DispatchMessage将消息发送到窗口函数中去。在"窗口类的诞生"中知道,MFC将所有的窗口处理函数都注册成DefWndProc,那是不是MFC将所有的消息都发送到DefWndProc中去了呢?很抱歉不是,而是都发送到了AfxWndProc函数去了。你可能要问为什么,这也是我想知道的,那我们就看看下面的序列图中窗口的创建过程吧:

CreateWnd

 
      消息的起点是AfxWndProc函数,所有的消息都被发送到AfxWndProc,也从AfxWndProc再次流向各自的消息响应函数的,怎么流的呢?看看下图就知道了:

messageflow

如果是“标准消息(WM_XXXX)”,则在CWnd::OnWndMsg函数内,直接发送到接收消息的目标窗口。
如果是"通知消息",则转到CCmdTarget::OnCmdMsg函数中(其内的GetMessageMap为虚函数),对自身的映射表中查找,简图如下:

msgloopgraph1.gif


图1 消息的拐弯流动
--------------------
二、自动化(Automation)对象———组件技术应用。
自动化,是基于COM技术的一个高级应用。
自动化的本质(最简单的理解):
是继承了IDispatch接口的接口。
说到底,自动化就是为了消除编译期的类型信息依赖性(COM也有CLSID/IID/tlb/h依赖性),
而通过“名字”来晚期(运行时)绑定函数地址和参数类型校验的技术。通常的COM就是通过内存中虚表来晚期帮定,但其编译时仍然需要导入类型信息(#import).
有了自动化这一技术后,在脚本语言和解释执行语言中,在不需要任何类型信息的情况下,就可以方便调用自动化对象。仅仅知道ProgID(字符串)就够了(ProgID = “组件名.类名”)
创建自动化对象:
在MFC中,为应用自动化技术提供了很大的便利,使用起来非常简单。
1。创建MFC的RegularDLL时,勾选"Automation"
2。创建一个用户类,继承于CCmdTarget。创建完后,MFC系统自动生成一个接口dispinterface,其信息保存在odl文件(与COM的idl文件类似),同时生成对应该接口的实现类,该类名与接口同名(接口与实现类是一对一关系)。他们之间的关联估计是通过宏或MFC内部机制来实现。
3。余下就是声明和实现接口,就这样,一个自动化对象创建完成了。
调用自动化对象:
在VC6.0下调用通常有两种方式:
1。COleDispatchDriver *pDriver = new ();
    pDriver->CreateDispatch(组件名.类名);
    pDirver->InvokeHelper(函数索引,DISPATCH_METHOD,。。。);
   此调用不存在类型依赖性,而是通过索引或函数名实现晚绑定。
2。生成自动化对象的包装类(COleDispatchDriver).
    在类创建向导窗口中,选择'Automation'页面,后点"Add Class...",选择你所包装自动化的tlb或DLL文件。 确定后,MFC系统自动生成一个继承于COleDispatchDriver的包装类,类名为tlb中的接口名。
MFC直接通过该包装类的函数,每个函数实际上还是调用InvokeHelper,转移到自动化对象中。
关键的地方是该包装类在调用CreateDispatch后,将自动化对象的接口指针保存到包装类的成员m_lpDispatch内,包装类就通过该成员进行调用转移。个人认为,该调用方式,仍然存在“tlb类型依赖性”。只是调用时避开了InvokeHelper那些麻烦参数,显得更简洁而已。
有点罗嗦。呵呵。
关于自动化,<ATL开发指南>书中,讲得清晰易懂.

--------------------- 

待续  ......
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Internet普及的今天,作为Internet工作基础的TCP/IP协议及其编程已经成了IT人业人员所要具备的基本知识与技能。打开国内外各大知名网站的招聘页面,都可以看到类似于“熟悉TCP/IP协议、掌握socket通讯开发”等字样的要求。本书就是为了满足读者在这方面知识的需求而编写的一本TCP/IP协议与基于TCP/IP编程方面的书籍。 本书有以下几个方面的特点: (1)内容的组织上按照协议原理与协议编程分为上、下。上主要介绍TCP/IP协议簇中的常用协议,下专门介绍网络编程知识与技能。 (2)具体在编写每一节的内容时将原理知识与实用技能融为一体。以方便读者学习。 (3)考虑到TCP/IP协议比较抽象,学习起来有一定的难度,所以全书尽量避免使用晦涩难懂专业术语,而用浅显易懂的语言说明问题,努力将书打造成一本人人都读懂书籍。 (4)初学网络程序设计的人员,往往感到网络程序设计内容多,学习进来比较复杂。针对这一问题,本书在讲解网络程序设计时,根据网络程序固有的特点,先总结了网络程序设计的通用模式,然后再举例说明网络程序的设计,使读者易于入手。 (5)Winsock函数内容多,使用起来比较复杂,针对这一问题,笔者在写作时将常用的Winsock函数分散到各种实例中去介绍,然后在最后一章将所有常用的Winsock函数一一作了较为详细说明,并在每个函数后面加入了其应用实例或使用说明。 本书分为上、下两内容,上内容包含6章,各章主要如下: 第1章:介绍了TCP/IP协议的产生、结构和工作原理,另外本章内容中还简要介绍一一下ISO/OSI RM。 第2章:介绍TCP/IP协议层次结构中网络接口层包含的内容,主要有物理层和数据链路的相关知识。 第3章:介绍TCP/IP协议层次结构中网络层及其相关知识。主要内容有IP数据报格式、IP层的功能、IP地址、ICMP协议、地址转换协议并介绍了IP的最新版本IP v6等。 第4章:介绍TCP/IP协议层次结构中传输层及其相关知识。主要内容有端口的概念、TCP协议和UDP协议的协议数据格式、协议原理和TCP协议与UDP协议的比较等内容。 第5章:介绍TCP/IP协议层次结构中应用层及其相关知识。主要内容有应用层常用协议DNS、FTP、Telnet、HTTP、POP和SMTP的格式、工作原理、协议实例等内容。 第6章:简要的介绍了一下TCP/IP协议在Windows和LINUX操作系统下的实现原理TCP/IP协议的二进制代码。 下包含以下6章内容: 第7章:介绍了网络程序设计有关的基础知识、一个网络程序入门实例和Winsock中编写网络程序常用的建立连接、传输数据、关闭连接等有关的函数。 第8章:介绍了TCP程序设计流程、基于C/C++的TCP程序设计实例和基于Java技术的TCP程序设计实例。 第9章:介绍了UDP程序设计流程、基于C/C++的UDP程序设计实例和基于Java技术的UDP程序设计实例。 第10章:介绍了使用MFC中提供的有关类进行网络程序设计知识。 第11章:介绍了Winsock API中各种函数的功能,并举例说明了些函数的使用方法。 本书在编写过程中得到了邮电出版和刘博等编辑的大力支持和帮助,在此表示感谢。由于作者水平有限,错漏之处在所难免,欢迎广大读者批评指正和提出宝贵的意见,可发邮件到。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值