在 VC++ 6.0 中使用 ATL 实现对 COM 对像的事件处理

类别:VC语言 点击:0 评论:0 推荐:

如果当前工程不支持 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; // 释放事件接收对象
 } 

本文地址:http://com.8s8s.com/it/it167.htm