如果当前工程不支持 atl,则先要向工程中添加对 atl 的支持
1> 在调用 atl 服务之前(通常是在工程的 stdafx.h 中) 加入下面代码:
#include <atlbase.h>
class cexemodule : public ccommodule
{
public:
dword dwthreadid;
};
extern cexemodule _module; // 不要企图去修变这个变量的名称 !
#include <atlcom.h>
#include <atlwin.h>
2> 在实现文件(.cpp)的开关添加下列代码:
// 这里的 libid_mycomlibrary 是事件源对象所在的组件库 uuid
_module.init(null, hinstance, &libid_mycomlibrary);
_module.dwthreadid = getcurrentthreadid();
3> 最后,使用 #import 指令将组件库导入到工程中,例如:
#import "e:\test\mycomlibrary.tlb" amed_guids no_namespace
参考资料:
msdn knowledge base : howto: add atl support to an mfc exe
使用 atl 中提供的 idispeventimpl 模板来实现事件接收对象,并用和 sink_entry_ex 宏
在事件槽映射表添加事件处理条目。
i> 创建一个类用来实现 idispeventimpl 接口,以下称之为事件接收类,也就是说从
idispeventimpl 模板实例中派生一个类。举例说明如下:
// 为事件接收类所要实现的每个事件接口定义一个唯一的 id
#define idc_srcobj 1
// 声明并实现事件接收类, 这个类使用 idispeventimpl 模板,同时将 typelibrary 作
// 为参数传递给模板。它在事件映射槽中使用 sink_entry_ex() 宏来为每个事件源指定事
// 件处理函数。
class csinkobj :
public idispeventimpl<idc_srcobj, csinkobj,
&__uuidof(myeventsinterface), &libid_mycomlibrary, 1, 0>
{
public:
csinkobj()
{
// do nothing
}
// 事件接口映射接口表声明,表中的每个条目对应接口中的一个事件处理函数
begin_sink_map(csinkobj)
sink_entry_ex(idc_srcobj, __uuidof(myeventsinterface), 1, myeventhandler)
sink_entry_ex(idc_srcobj, __uuidof(myeventsinterface), 2, myevent2handler)
end_sink_map()
stdmethodimp myeventhandler(_bstr_t strparam, long nparam)
{
messagebox(null, "get myevent !", " from csinkobj", mb_ok);
return s_ok;
}
stdmethodimp myevent2handler(_bstr_t strparam)
{
messagebox(null, "get myevent2 !", " from csinkobj", mb_ok);
return s_ok;
}
};
ii> 使用上面实现的事件接收类
// 创建事件接收对象
csinkobj *psink = new csinkobj();
// 创建事件源对象的一个接口
myclassinterface* pclassinterface = null;
hresult hr = cocreateinstance(__uuidof(mycomclass),
null, clsctx_inproc_server,
__uuidof(myclassinterface),
(void**)&pclassinterface);
if(succeeded(hr))
{
// 通过事件源组件对象的一个接口,将事件接收对象与事件源组件对象连接起来
psink->dispeventadvise(pclassinterface);
// 在这里我们调用事件源对象的接口中的一个方法,用来激发一个事件
pclassinterface->hello(l"tom");
}
// 解除事件接收对象与事件源组件对象的连接
if(psink)
{
if (psink->m_dweventcookie != 0xfefefefe)
psink->dispeventunadvise(pclassinterface);
delete psink; // 释放事件接收对象
}