在普通的mfc工程中常常需要添加com接口支持.最典型的应用就是使用
com中的连接点机制时,需要在客户端实现事件接受器.简单说来,就是要实现在com服务器端声明的事件接口.这个接口由server端暴露给client,然后由client实现之,并在适当的时候由server端触发事件达到通知client的目的.这个过程就是连接点的回调.
    支持IDispatch的接口,就是通常所说的双接口.支持IUnknown的接口通过vtbl来调用接口方法.vtbl是c++中类的内存结构形式,因而在vb,asp及各种script中只能通过组件暴露的IDispatch接口来调用接口方法.
    以实现连接点为例,我们分别用上面所说的两种形式(客户端sink组件实现IDispatch接口以及不实现IDispatch接口)来说说在mfc工程中如何添加com接口支持.
1.sink组件不支持IDispatch
(1)Server:
    在server端实现组件对事件回调的支持的步骤就不累述.这里说说关键地方在于,IDL文件需要这样修改几处:  
library CONNECTIONCOMLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");

[
  uuid(AFE854B0-246F-4B66-B26F-A1060225C71C),
  helpstring("_IxxxEvents Interface")
]
// Old block - take this out
// dispinterface _IxxxEvents
// {
// properties:
// methods:
// [id(1), helpstring("method ExecutionOver")]
// HRESULT ExecutionOver(intResult);
// };
//To this one -put this in
interface _Ixxxvents : IUnknown
  {
  [id(1), helpstring("method ExecutionOver")] HRESULT
          ExecutionOver(intResult);
  };
  [
    uuid(630B3CD3-DDB1-43CE-AD2F-4F57DC54D5D0),
    helpstring("xxx Class")
  ]
  coclass xxx
  {
  [default] interface Ixxx;
  //[default, source] dispinterface _IxxxEvents; take this line
  //out and put the line below in
  [default, source] interface _IxxxEvents ;
  };
};
目的是取消对IDispatch接口的支持.
    在适当的地方添加Fire_xxx()即可触发client实现的事件函数.
(2)Client:
    在client端添加一个新类,继承自_IxxxEvent,然后实现其成员函数:InterfaceQuery(),AddRef(),Release(),还有当然就是在server端定义的事件触发成员函数.
2.sink组件支持双接口.
mfc和atl中不一样.示例如下:
用ClassWizaed添加一个Automation类

.h中
class CProxyEvents : public CCmdTarget
{
 DECLARE_DYNCREATE(CProxyEvents)

CProxyEvents();           // protected constructor used by dynamic creation

// Attributes
public:
 void OnOption(VARIANT *Option); 
 void OnData(VARIANT *Data);
 void OnError(int ErrorCode);
 void OnConnectStatus(int ConnectStatus);
 void OnErrorMessage(BSTR ErrorMessage);
 void OnNews(BSTR News);
 void OnKeepAlive(BSTR AckResponse);
 HWND hwnd; 
// Operations
public:
 virtual ~CProxyEvents();
// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CProxyEvents)
 public:
 virtual void OnFinalRelease();
 //}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
 //{{AFX_MSG(CProxyEvents)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

DECLARE_MESSAGE_MAP()
 // Generated OLE dispatch map functions
 //{{AFX_DISPATCH(CProxyEvents)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_DISPATCH
 DECLARE_DISPATCH_MAP()
 DECLARE_INTERFACE_MAP()
};

.cpp中
BEGIN_MESSAGE_MAP(CProxyEvents, CCmdTarget)
 //{{AFX_MSG_MAP(CProxyEvents)
  // NOTE - the ClassWizard will add and remove mapping macros here.
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_DISPATCH_MAP(CProxyEvents, CCmdTarget)
 DISP_FUNCTION_ID(CProxyEvents, "Option",8,OnOption, VT_EMPTY, VTS_PVARIANT)
 DISP_FUNCTION_ID(CProxyEvents, "Data",2,OnData, VT_EMPTY, VTS_PVARIANT)

//  [id(3), helpstring("method Error")] void Error(int ErrorCode);
 DISP_FUNCTION_ID(CProxyEvents, "Error",3,OnError, VT_EMPTY, VTS_I4) 
//  [id(4), helpstring("method ConnectStatus")] void ConnectStatus(int ConnectStatus);
 DISP_FUNCTION_ID(CProxyEvents, "ConnectStatus",4,OnConnectStatus, VT_EMPTY, VTS_I4) 
//  [id(5), helpstring("method ErrorMessage")] void ErrorMessage(BSTR ErrorMessage);
 DISP_FUNCTION_ID(CProxyEvents, "ErrorMessage",5,OnErrorMessage, VT_EMPTY, VTS_BSTR) 
//  [id(6), helpstring("method News")] void News(BSTR News);
 DISP_FUNCTION_ID(CProxyEvents, "News",6,OnNews, VT_EMPTY, VTS_BSTR) 
//  [id(7), helpstring("method KeepAlive")] void KeepAlive(BSTR AckResponse);
 DISP_FUNCTION_ID(CProxyEvents, "KeepAlive",7,OnKeepAlive, VT_EMPTY, VTS_BSTR) 
END_DISPATCH_MAP()

// Note: we add support for IID_IProxyEvents to support typesafe binding
//  from VBA.  This IID must match the GUID that is attached to the
//  dispinterface in the .ODL file.

// {1F2E2D8A-7CE3-4BCA-A360-C66C46A86626}

BEGIN_INTERFACE_MAP(CProxyEvents, CCmdTarget)
 INTERFACE_PART(CProxyEvents, DIID__IServerProxyEvents, Dispatch)
END_INTERFACE_MAP()

代码中用
    LPUNKNOWN unknown=pProxyEvents->GetIDispatch(FALSE);
    m_dwCookie=0;
    int ret=AfxConnectionAdvise(m_ServerProxy, DIID__IServerProxyEvents, unknown, FALSE, &m_dwCookie);建立连接.

一般地,使一个mfc类支持IDispatch接口(添加自动化支持)可以通过以下步骤:
1.在CMyDialog的类声明中(即.h)加入
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
两个宏,再在源文件(.cpp)中添加
BEGIN_INTERFACE_MAP( CMyDialog, CDialog )
    INTERFACE_PART( CMyDialog, IID_IDispatch, Dispatch )
END_INTERFACE_MAP()

BEGIN_DISPATCH_MAP( CMyDialog, CDialog )
    //这里添加属性或方法
END_DISPATCH_MAP()
并在构造函数调用EnableAutomation();即可.在BEGIN_DISPATCH_MAP和END_DISPATCH_MAP宏之间加入想加的DISP_FUNCTION之类的宏以建立映射.如果觉得手动添加DISP_FUNCTION之类的宏麻烦,可如下修改即可使用ClassWizard来对这个类添加方法和属性了

在.cpp中
BEGIN_DISPATCH_MAP( CMyDialog, CDialog )
    //{{AFX_DISPATCH_MAP( CMyDialog )
    //}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
在.h中,在类声明中的任何一个地方加入
    //{{AFX_DISPATCH( CMyDialog )
    //}}AFX_DISPATCH
如上后就可通过ClassWizard来添加方法和属性了.

mfc工程中添加com接口支持相关推荐

  1. 在MFC工程中新建一个对话框

    1.MFC简介 Microsoft Foundation Class微软基础类库,这个类集以层次结构组织起来,其中封装了发部分的Windows API函数和Windows控件,它所包含的功能设计整个W ...

  2. 非MFC工程中使用MFC库

    需求说明 C++工程的类型有很多,从VS(或VC)可以看到常见的有:Win32 Console Application.MFC Application.Win32 Project等.在创建MFC工程时 ...

  3. java工程加包_Java工程中添加依赖jar包不起作用问题总结

    Java工程中添加依赖jar包不起作用问题总结 此次总结两种方式的依赖问题 1 在Eclipse中添加依赖jar包不起作用问题 这种方式可能是Eclipse缓存,或者Eclipse还没有反应过来.例如 ...

  4. ios之Xcode工程中添加文件常用快捷键

    1.Xcode某个工程中添加文件 有两种方式: 方式一:"command"+"n",弹出添加文件对话框. 方式二:在需要添加文件的工程目录下右键,选择" ...

  5. 游戏建模控件Aspose.3D for Java最新版支持在Wavefront OBJ中添加点云支持

    Aspose.3D for Java是独立的Gameware和计算机辅助设计(CAD)API,用于处理3D文件.同时支持大多数流行的3D文件格式,应用程序可以轻松创建,读取,转换和修改3D文件.此外, ...

  6. MFC对话框中添加工具栏

    1. 在资源管理器中添加 ToolBar资源,资源 ID为 IDR_TOOLBAR1 加入两个工具栏按钮 2. 在对话框头文件 XxxDlg.h中添加工具栏变量 CToolBar m_toolBar; ...

  7. VS如何新建一个基于对话框的MFC工程并添加按钮

    学习MFC的初学者,入门的步骤很重要,新建一个基于对话框的MFC应用程序,并通过拖拉按钮等,初步搭建自己的MFC工程. 工具/原料 笔记本电脑 VS2010 方法/步骤 打开VS2010,并新建MFC ...

  8. windows10 vs2013控制台工程中添加并编译cuda8.0文件操作步骤

    一般有两种方法可以在vs2013上添加运行cuda8.0程序: 一.直接新建一个基于CUDA8.0的项目:如下图所示, 点击确定后即可生成test_cuda项目:默认会自动生成一个kernel.cu文 ...

  9. iOS在支持arc的工程中,导入不支持arc的第三方的插件

    首先将插件导入到工程中,然后点击工程名,在targets下面找到相应的条目,然后选择build phares,打开第二行compile sourses,然后找到不支持arc的.m文件,在后边添加上&q ...

最新文章

  1. Self20171218_TestNG+Maven+IDEA环境搭建
  2. DroidPilot 发布微信公众帐号啦~
  3. php 配置 关闭警告,php warning 关闭的方法
  4. 【干货】写给产品经理和设计师的用户体验说明书
  5. 2022.2.13java学习笔记
  6. 什么是用户账户?-联科教育
  7. 学习vue.js的自我梳理笔记
  8. jquery文件上传插件uploadify 讲解
  9. 空调开28度,一晚上会消耗多少电?空调耗电量与什么有关?
  10. 使用 PotPlayer 搭配 SVP 4 播放60帧电影
  11. 用 DiskGenius 和 HDD Regenerator 修复硬盘逻辑坏道和隐藏物理坏道
  12. 利用自定义注解,统计方法执行时间
  13. 10分钟搭建你的云端微信机器人️️️
  14. GIS应用技巧之联合
  15. Android开发之方向传感器的使用
  16. linux c语言lzma,LZMA 算法简介
  17. Flex语法和常用鼠标手势
  18. stm32常用数据类型 U8、U16、U32到底代表什么?
  19. 一张表告诉你木兰宽松许可证第二版(MulanPSL v2)与业界主流许可证的主要异同...
  20. iOS开发支付 — 内购(IAP)

热门文章

  1. Linux-目录结构说明
  2. Java中获取实体List中某时间属性离当前时间最近的实体类的某一属性
  3. SpringBoot+MyBatisPlus实现前端传递时间查询条件ajax请求后台并回显数据流程整理
  4. SpringBoot项目在Eclipse中实现打包发布
  5. 学习ribbon,进来看看吧
  6. 计算机网络总结:第四章 网络层
  7. 视图的概念以及使用视图的好处
  8. 线性拟合polyfit_6.数据分析(1) 描述性统计量和线性回归(2)
  9. 用matlab相关分析,基于matlab的逐像元偏相关分析
  10. ise 时钟约束_「新手入门」ISE工程升级到Vivado及板级信号调试技术