• 关于响应ActiveX组件方法


    相关内容搜集自网络:

    一、CDialog类响应ActiveX事件的实现

     
    在大多数ATL工程中,客户端为了能够响应服务的事件,往往需要继承于IDispEventImpl或IDispEventSimpleImpl的模板类;由于服务本身实现了IDispatch接口,它可以很方便得通过BEGIN_SINK_MAP和END_SINK_MAP实现对事件的分发响应。但当我们为MFC的对话框里添加一个ActiveX后,会发现尽管CDialog并不继承与这两个模板类,却仍然可以实现对事件的响应;而且简单到似乎仅仅只是添加了BEGIN_EVENTSINK_MAP和END_EVENTSINK_MAP。那么问题就是,服务端既然必须通过IDispatch接口来分发事件,那CDialog的IDispatch接口实现在了哪里? 
      通过在事件响应函数里下断点,观察CallStack,已经可以比较清楚得看出端倪,实际上这不是CDialog的专利,而已由CWnd实现的,它没有继承IDispatch接口,却包含和一个继承于IDispatch接口的成员,通过这个成员告诉CWnd该调用哪个响应函数;这样大大简化了CWnd的实现。 

      具体的实现情况是: 

    1,BEGIN_EVENTSINK_MAP和END_EVENTSINK_MAP的作用仅仅是把事件响应函数放到对话框的窗口函数; 

    2,CWnd 拥有一个COleControlContainer型成员m_pCtrlCont; 

    3,m_pCtrlCont拥有多个COleControlSite成员,这样可以保证一个对话框上有多个ActiveX而不会互相干扰;

    4,每个COleControlSite拥有一个继承于IDispatch的嵌套类XEventSink及其成员m_xEventSink。通过以下这样一段宏实现: 

    BEGIN_INTERFACE_PART(EventSink, IDispatch) 

    INIT_INTERFACE_PART(COleControlSite, EventSink) 

    STDMETHOD(GetTypeInfoCount)(unsigned int*); 

    STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo**); 

    STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, unsigned int, LCID, DISPID*); 

    STDMETHOD(Invoke)(DISPID, REFIID, LCID, unsigned short, DISPPARAMS*, VARIANT*, EXCEPINFO*, unsigned int*); 

    END_INTERFACE_PART(EventSink) 
      在Invoke中,实际上就是调用对话框的OnCmdMsg,从而很方便得实现了事件的分发,而对客户端而言却丝毫感觉不到影响。 

      从这个实现,可以发现使用包含的设计方式往往比继承更具有灵活性;同时也提供了另一种客户端对事件响应的实现方式。实际上,不需要一定要通过宏修改窗口函数,而只要适当修改Invoke令其实现事件分发即可。
     
    ATL中,使用Begin_Sink_map   mfc中,使用Begin_eventSink_map。
     
    更多关于网页端、MFC、ATL的dispatch实现
    http://blog.csdn.net/kuanghong/article/details/1765119
     
    二、关于参数vtsparam
    The vtsParams argument is a space-separated list of values from the VTS_ constants. 
  • 相关阅读:
    JavaScript学习笔记(六)----内置对象Global 和Math
    JavaScript学习笔记(五)--- String类型
    线性筛素数
    线性筛欧拉函数
    POJ 3090 Visble Lattice Points
    1091 合唱队形(最长上升子序列模板)
    P1018 乘积最大
    P1020 导弹拦截(弱数据)
    P2757 导弹的召唤(数据加强)
    P1313 计算系数
  • 原文地址:https://www.cnblogs.com/ice-arrow/p/12974237.html
Copyright © 2020-2023  润新知