[经验总结]在ATL中通过GIT让工作线程访问连接点

在用ATL开发的COM控件中,一般只有主线程能访问连接点, 也只有主线程才能向调用方触发事件,而利用GIT(全局接口列表)可以让COM控件中任意一个线程都能访问连接点,从而实现在从属线程中也能触发事件。 以下代码改编自:ATL: Firing Events from Worker Threads(操作方法详见此文),这篇文章中的代码不能通过编译,我做了一些修改。

#include "StdAfx.h" #include "resource.h" // main symbols #include <ATLBASE.H> #include <map> using namespace std; // 通过GIT找寻连接点,从而在工作线程中也能找到连接点。 class CComDynamicUnkArray_GIT : public CComDynamicUnkArray { private: IGlobalInterfaceTable* GIT; public: CComDynamicUnkArray_GIT() : CComDynamicUnkArray() { GIT = NULL; CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, __uuidof(IGlobalInterfaceTable), reinterpret_cast< void** >(&GIT) ); } ~CComDynamicUnkArray_GIT() { //clean up the class clear(); if( GIT != NULL ) { GIT->Release(); } } DWORD Add(IUnknown* pUnk); BOOL Remove(DWORD dwCookie); //The proxy code use this function to get the interface ! CComPtr<IUnknown> GetAt(int nIndex) { DWORD dwCookie = (DWORD)CComDynamicUnkArray::GetAt( nIndex ); if( dwCookie == 0 ) { return NULL; // CComPtr<IUnknown>(); } if( CookieMap.find( dwCookie ) == CookieMap.end() ) { return (IUnknown*)dwCookie; // return CComPtr<IUnknown>(); } if( GIT != NULL ) { CComPtr<IUnknown> ppv; HRESULT hr = GIT->GetInterfaceFromGlobal( CookieMap[dwCookie], //Cookie identifying the desired global //interface and its object __uuidof(IUnknown), //IID of the registered global interface reinterpret_cast< void** >(&ppv) //Indirect pointer //to the desired interface ); if( hr == S_OK ) { return ppv; } //Should never be reached, a ASSERT or exception is possible } return (IUnknown*)dwCookie; } //clean up the GIT void clear() { CComDynamicUnkArray::clear(); if( GIT != NULL ) { map< DWORD, DWORD >::iterator iter; for (iter = CookieMap.begin(); iter != CookieMap.end(); ++iter ) { GIT->RevokeInterfaceFromGlobal( iter->second //Cookie that was returned from //RegisterInterfaceInGlobal ); } } CookieMap.clear(); } protected: std::map< DWORD, DWORD > CookieMap; }; inline DWORD CComDynamicUnkArray_GIT::Add(IUnknown* pUnk) { DWORD Result = CComDynamicUnkArray::Add( pUnk ); HRESULT hr; DWORD pdwCookie = 0; if( GIT != NULL ) { hr = GIT->RegisterInterfaceInGlobal( pUnk, //Pointer to interface of type riid //of object containing global interface __uuidof(IUnknown), //IID of the interface to be registered &pdwCookie //Supplies a pointer to the cookie that //provides a caller in another apartment //access to the interface pointer ); } if( hr == S_OK ) { CookieMap[Result] = pdwCookie; } return Result; } inline BOOL CComDynamicUnkArray_GIT::Remove(DWORD dwCookie) { BOOL Result = CComDynamicUnkArray::Remove( dwCookie ); if( GIT != NULL ) { if( CookieMap.find( dwCookie ) != CookieMap.end() ) { GIT->RevokeInterfaceFromGlobal( CookieMap[dwCookie] //Cookie that was returned from //RegisterInterfaceInGlobal ); CookieMap.erase(dwCookie); } } return Result; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值