♣
关于在IE中响应ActiveX事件的问题,谁能找到社区对应贴子,或者给出一些参考代码。
http://community.csdn.net/expert/faq/faq_index.asp?id=187805
q : 关于在ie中响应activex事件的问题。100分
主要解答者: lop5712 提交人: freeshoot
感谢:
审核者: wangweixing2000 社区对应贴子: 查看
a :
在mfc activex wizzard基础上class wizzard 添加了若干method和event。
如果通过html中的vbscript调用activex控件的method,然后在method中
firexxevent,一切都正常。通过vbscript能正确响应该事件。
然而,当用控件内部自己创建的工作线程firexxevent时,ie却不能正确
响应该事件,在调试状态,还能看见异常发生,控件内的invoke
方法没返回正确值。(在tstcon32中调试时,能看见事件发生)
---------------------------------------------------------------
那是因为fireevent实际上是调用客户端实现的一个接口(在这就是ie实现的idispatch接口)的方法,而activex控件一定是放在sta套间(虽然也可以,但应该没人实现为放在mta)的,因此工作线程调用ie的idispatch接口一定且必须是代理接口,这个接口必须通过汇集得到(以创建代理对象)。
即需要在主线程调用comarshalinterface来列集ie的那个idispatch接口,再在工作线程调用counmarshalinterface来散集idispatch接口,进而在工作线程中通过散集的idispatch接口发起事件。由于楼主是在线程间汇集接口,所以可以使用comarshalinterthreadinterfaceinstream和cogetinterfaceandreleasestream代替上面的两个函数进行汇集,效率会有所提高。
而这样做(即建立代理对象)的实际工作工程,与楼主说的“另外”是异曲同工的,所以楼主要是闲上面麻烦,可以按照楼主说的“另外”来实现。
还有就是colecontrol是mfc的包装类,其中使用了一些mfc的底层的机制(如线程状态等),所以当欲跨线程传递activex对象的指针时,不可直接传递colecontrol*之类,否则就有可能发生断言失败,而应该通过fromhandle和detach来传递句柄(不过这样就不能使用派生类的相关成员函数)。因此楼主如果想使用上面的方法,需先获得客户的接口指针(即idispatch),然后将其列集得到的istream*作为线程参数传递给工作线程,而不要使用直接的this。
· 网友精彩回答:
给你一个我写的atl 线程类, 已经包装了 接口指针列集,可以直接在run 中使用 传入的接口来触发事件:
// comthread.h: interface for the ccomthread class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(afx_comthread_h__050cc613_79d4_4257_93cf_4e67f98b2b82__included_)
#define afx_comthread_h__050cc613_79d4_4257_93cf_4e67f98b2b82__included_
#if _msc_ver > 1000
#pragma once
#endif // _msc_ver > 1000
#include <windows.h>
template<class devied, class interface, const iid* piid = &__uuidof(interface)>
class ccomthread
{
protected:
ccomthread()
{
m_hthread = null;
m_dwthreadid = 0;
m_pstream = null;
}
virtual ~ccomthread()
{
close();
}
public:
bool start()
{
if(m_hthread != null)
return false;
devied* pdevied = ((devied*)this);
m_pstream = null;
hresult hr = 0;
hr = comarshalinterthreadinterfaceinstream(*piid,
static_cast<interface*>(pdevied), &m_pstream);
// create thread and pass the thend process the this ptr
m_hthread = createthread(null, 0, threadfnc, (lpvoid) this, 0, &m_dwthreadid);
return s_ok;
}
bool wait(dword dwtime = infinite)
{
return atlwaitwithmessageloop(m_hthread);
}
void terminate(dword dwexitcode)
{
if(m_hthread != null)
terminatethread(m_hthread, dwexitcode);
}
void close()
{
if(m_hthread != null)
{
closehandle(m_hthread);
m_hthread = null;
}
}
private:
handle m_hthread;
dword m_dwthreadid;
lpstream m_pstream;
static dword winapi threadfnc(lpvoid lp)
{
ccomthread<devied, interface, piid>* pthis =
(ccomthread<devied, interface, piid>*)lp;
return pthis->_run();
}
dword _run()
{
ccominit cominit;
hresult hr;
ccomqiptr<interface, piid> spitf;
if(m_pstream)
hr = cogetinterfaceandreleasestream(m_pstream, *piid, (lpvoid*)&spitf);
dword dw = static_cast<devied*>(this)->run(spitf);
spitf.release();
return dw;
}
};
#endif // !defined(afx_comthread_h__050cc613_79d4_4257_93cf_4e67f98b2b82__included_)
使用很简单,象其它模板一样添加到继承列表:
class atl_no_vtable cremote :
public ccomobjectrootex<ccomsinglethreadmodel>,
public ccomcoclass<cremote, &clsid_remote>,
public iconnectionpointcontainerimpl<cremote>,
public idispatchimpl<iremote, &iid_iremote,
&libid_remotelinklib, rllibvermaj, rllibvermin>,
public iremoteeventsfire,
public ccomthread<cremote, iremoteeventsfire, &iid_iremoteeventsfire>,
public cproxy_iremoteevents< cremote >
{
public:
.....
dword run(iremoteeventsfire* pfireitf) // 这个是线程函数,必需实现, 否则编译不了
{
....
pfireitf->firethreadstart(); // 事件
...
return 0;
}
};
- 更多问题:
- · 现在2005搬QQ谁能设计个软件,一运行可以三个号同时登陆?
- · 问一个shell运行环境的问题
- · 从本地SQL数据库导入数据到网站SQL数据库完成后,远程那个数据库没得索引、主键等
- · 图片用<marquee></marquee>加了滚动后还想在各个图片上加链接
- · iis6.0+php
- · Tobjectlist能不能这样呀?
- · 帮我看看这个问题怎么解决,单步执行和普通执行程序结果不同~郁闷
- · 求一客户端(winform)连接远程数据库系统应用程序的源码,谢谢!!
- · 求助,急,在线等待,谢谢。[Linker Fatal Error] F1009 Unable to open input file F:\tes\componnets\uccc.cpp
- · 实时错误“713” 类没有注册
- · 怎么判断字符串是否为数值?
- · 如何把TC写的图形代码运行结果,屏幕图形保存在WORD文档中?
- · 两点了,我睡不着! 是数学还是习题? 想听听大家的意见
- · 如何使非模式对话框 (showModelessDialog())隐藏在主窗口背后?
- · 如何屏蔽“ctrl+v”和“右键的粘贴功能”??
- · 如何使非模式对话框 (showModelessDialog())隐藏在主窗口背后?
- · java编程
- · 网页技术 | 网页
- · 路由器配置
- · 特效大全
- · 数据库服务 | 数据库
- · 设置篇
- · apache教程
- · apache windows
- · ie缓存
- · 漏洞扫描
- · 漏洞扫描器
- · svchost.exe 魔波
- · windows进程
- · apache支持asp
- · apache的配置
- · fso 方法
- · 在R5的管理客户端,如何用server.id来签名设计元素
- · 全球知名3D设计软件行业盛会首度移师中国
- · 形象设计
- · 三维自然景观设计大师Vue 5 Esprit
- · 程序设计
- · Photoshop7.0之系统优化策略
- · 速成高手 Photoshop中文版数码全攻略
- · photoshop字体
- · 火狐下载

