ATL控件从线程fire事件的解决方案

  使用microsoft提供的ATL Com Appwizard模板生成控件很方便,用户的灵活性也比较大,可如果想从一个工作线程中fire事件却总是出问题,有一些是在fire时出现内存错,有一些是事件是fire出去了,可却收不到。

查了很多资料才知道,vc现有的事件分发存在一定的缺陷,在线程发送事件时可能存在问题,(但奇怪的是,同一个控件,如果使用ms自带的Active X Control Test Container测试不管是从线程中发出的事件还是别的都能收到,而使用javascript写的脚本却收不到线程发出的时间,具体原因还不太清楚。)

为解决从线程中发送的事件不能被javascript等脚本语言接收的问题,好多人都提供了解决方法,经笔者测试发现下面解决方案为最佳,描述如下:

(1)从microsoft下载ATLCPImplMT.h文件(http://support.microsoft.com/kb/280512/zh-cn)

(2)改写工作线程函数

由原来的

void MyThreadProc( LPVOID pParam )
{

CThreadEvent * m_pThreadEvent = (CThreadEvent *)pParam;

m_pThreadEvent->Fire_SomeEvent();

return ;
}

改成

void MyThreadProc( LPVOID pParam )
{
HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);

CThreadEvent * m_pThreadEvent = (CThreadEvent *)pParam;

m_pThreadEvent->Fire_SomeEvent();

::CoUninitialize ();

return ;
}

(3)改变系统生成的XXXCP.h

先包含头文件#include "ATLCPImplMT.h"

将以前的template
class CProxy_IThreadEventEvents : public IConnectionPointImpl

改成

template
class CProxy_IThreadEventEvents : public IConnectionPointImplMT

(4)逐个改变系统生成的fire事件代码

pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();

更换成

CComPtr<IUnknown> sp;
sp.Attach (GetInterfaceAt(nConnectionIndex));

重新编译,从线程中发送事件应该可以使用了

注意:笔者使用的开发环境如下,winxp + sp2,

vc6.0 + sp6

另外,如果新添加了一些事件从新编译后会发现以前在fire部分做的更改全部消失,要重新更改代码,所以建议全部事件添加完成后再做代码更换工作,以免重复劳动
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值