ATL(ActiveX)中用户线程与主线程之间的交互,可以通过两种方法实现:
1、消息机制:此需要一个隐藏窗口支持;
2、线程监听传递消息(主线程、用户线程),多数建议使用_beginthreadex(...)进行线程的创建
下面主要介绍第二种方法:其实现大致有三种
1、容器-》连接点-》相应的接口函数(例如:onClickbutton())中,启用线程; 容器可以控制线程的创建
2、如果线程的创建都是由插件来进行管理,则可以再FinalConst 里面可以进行线程的创建
线程具体创建方法
1、接口函数来创建
注意onClickbutton()是接口类COsip_Ax的一个成员函数,
在成员函数中启用线程threadtask(),则此threadtask()必须满足两个条件1、为COsip_Ax的成员函数 2、静态函数;
其调用大致如下
在类中定义:
static unsigned __stdcall osip_zh_thread_event(LPVOID arg); 必须要定位为static 否则不能再接口函数中触发
具体实现:
unsigned __stdcall COsip_Ax::osip_zh_thread_event(LPVOID arg)
在此函数中,可以调用Fire_XXX_Event()
2、FinalConst 创建
a、static unsigned __stdcall osip_zh_thread_inclass_public_static(LPVOID arg);//LPVOID arg
friend unsigned __stdcall osip_zh_thread_friend(LPVOID arg);//友元函数实际上不属于任何类
b、hThread = (HANDLE)_beginthreadex(NULL,NULL,osip_zh_thread_outclass,this,NULL,&threadID); //与类无关,不能调用类中对象和函数
c、hThread = (HANDLE)_beginthreadex(NULL,NULL,osip_zh_thread_inclass_friend,this,NULL,&threadID);//友元函数,可以调用类中的对象和函数
其中a和c能够直接对Fire_XXX_Event函数进行操作。
但是vs2008中自动生成的代码中,能够调用Fire_XXX_Event() ,但是实际上不能触发里面的Invoke函数,必须做如下的修改:
下载:#include "ATLCPImplMT.h" 文件 //http://support.microsoft.com/kb/280512
把事件接口文件 XXX_CP.h修改如下
template<class T>
class CProxy_IOsip_AxEvents :
// public IConnectionPointImpl<T, &__uuidof(_IOsip_AxEvents)>
public IConnectionPointImplMT<T, &__uuidof(_IOsip_AxEvents),CComDynamicUnkArray>
同时必须修改两处:
其一:
在VS2008中会有调用静态函数的错误,需要在修改ATLCPImplMT.h
DWORD dwGITCookie = (DWORD)_CDV::GetUnknown(dwCookie);修改为
DWORD dwGITCookie = (DWORD)m_vec.GetUnknown(dwCookie);
pend->dwCookie = _CDV::GetCookie(reinterpret_cast<IUnknown **>(pDWCookie));修改为
pend->dwCookie = m_vec.GetCookie(reinterpret_cast<IUnknown **>(pDWCookie));
其二:(待验证,貌似好几种都可以用)
改下面:pT->Lock();CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);pT->Unlock();
改成:CComPtr<IUnknown> sp;sp.Attach (GetInterfaceAt(nConnectionIndex));
IDispatch * pConnection = static_cast<IDispatch *>(punkConnection.p);
//IDispatch * pConnection = reinterpret_cast<IDispatch*>(punkConnection.p);
//CComQIPtr< IDispatch > pConnection( punkConnection );
经过上述的修改,就可以实现 在新线程中,调用Fire_XX_Event(),并能够成功触发!
//传递unsigned char的方法如下
//avarParams[0].byref = "a";//result;
//avarParams[0].vt = VT_VARIANT;//VT_I1|VT_BYREF;
//传递字符串
//avarParams[0] = param; //(char * param)
联系客服