activex调用javascript函数activex内启动一个线程,怎么在线程内部调用javascript的函数。或者说怎么通知页
activex调用javascript函数
activex内启动一个线程,怎么在线程内部调用javascript的函数。或者说怎么通知页面
我的功能大致是这样子的:
页面调用activex的一个函数,函数启动一个线程,线程内部有n多操作。每一次操作完成,要求通知页面。
我用vs2008编辑的,mfcactivex。我添加事件的操作是 类视图,在ctrl类上右单击,添加-》事件 事件名字假设叫OneItemPassed 我在类的成员函数里调用这个方法,页面是能够感知到的,但是我如果启动线程,把this指针传给线程,通过这个指针调用OneItemPassed。但是一调用就崩溃。
cpp文件
- C/C++ code
// activeEventCtrl.cpp : CactiveEventCtrl ActiveX 控件类的实现。#include "stdafx.h"#include "activeEvent.h"#include "activeEventCtrl.h"#include "activeEventPropPage.h"#ifdef _DEBUG#define new DEBUG_NEW#endifIMPLEMENT_DYNCREATE(CactiveEventCtrl, COleControl)// 消息映射BEGIN_MESSAGE_MAP(CactiveEventCtrl, COleControl) ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)END_MESSAGE_MAP()// 调度映射BEGIN_DISPATCH_MAP(CactiveEventCtrl, COleControl) DISP_FUNCTION_ID(CactiveEventCtrl, "Test", dispidTest, Test, VT_EMPTY, VTS_NONE)END_DISPATCH_MAP()// 事件映射BEGIN_EVENT_MAP(CactiveEventCtrl, COleControl) EVENT_CUSTOM_ID("OK", eventidOK, OK, VTS_NONE)END_EVENT_MAP()// 属性页// TODO: 按需要添加更多属性页。请记住增加计数!BEGIN_PROPPAGEIDS(CactiveEventCtrl, 1) PROPPAGEID(CactiveEventPropPage::guid)END_PROPPAGEIDS(CactiveEventCtrl)// 初始化类工厂和 guidIMPLEMENT_OLECREATE_EX(CactiveEventCtrl, "ACTIVEEVENT.activeEventCtrl.1", 0xbd0b363, 0xb45e, 0x414f, 0x85, 0x1e, 0xb5, 0xa9, 0x70, 0x6a, 0xff, 0x7d)// 键入库 ID 和版本IMPLEMENT_OLETYPELIB(CactiveEventCtrl, _tlid, _wVerMajor, _wVerMinor)// 接口 IDconst IID BASED_CODE IID_DactiveEvent = { 0x91BFFB21, 0x3826, 0x4F51, { 0x80, 0x2F, 0xD7, 0x41, 0x37, 0x6B, 0x88, 0xC7 } };const IID BASED_CODE IID_DactiveEventEvents = { 0x2B04D24F, 0x3C4E, 0x4987, { 0x84, 0x22, 0xD5, 0xA4, 0xF5, 0x24, 0x8D, 0x3 } };// 控件类型信息static const DWORD BASED_CODE _dwactiveEventOleMisc = OLEMISC_INVISIBLEATRUNTIME | OLEMISC_ACTIVATEWHENVISIBLE | OLEMISC_SETCLIENTSITEFIRST | OLEMISC_INSIDEOUT | OLEMISC_CANTLINKINSIDE | OLEMISC_RECOMPOSEONRESIZE;IMPLEMENT_OLECTLTYPE(CactiveEventCtrl, IDS_ACTIVEEVENT, _dwactiveEventOleMisc)// CactiveEventCtrl::CactiveEventCtrlFactory::UpdateRegistry -// 添加或移除 CactiveEventCtrl 的系统注册表项BOOL CactiveEventCtrl::CactiveEventCtrlFactory::UpdateRegistry(BOOL bRegister){ // TODO: 验证您的控件是否符合单元模型线程处理规则。 // 有关更多信息,请参考 MFC 技术说明 64。 // 如果您的控件不符合单元模型规则,则 // 必须修改如下代码,将第六个参数从 // afxRegApartmentThreading 改为 0。 if (bRegister) return AfxOleRegisterControlClass( AfxGetInstanceHandle(), m_clsid, m_lpszProgID, IDS_ACTIVEEVENT, IDB_ACTIVEEVENT, afxRegApartmentThreading, _dwactiveEventOleMisc, _tlid, _wVerMajor, _wVerMinor); else return AfxOleUnregisterClass(m_clsid, m_lpszProgID);}// CactiveEventCtrl::CactiveEventCtrl - 构造函数CactiveEventCtrl::CactiveEventCtrl(){ InitializeIIDs(&IID_DactiveEvent, &IID_DactiveEventEvents); // TODO: 在此初始化控件的实例数据。}// CactiveEventCtrl::~CactiveEventCtrl - 析构函数CactiveEventCtrl::~CactiveEventCtrl(){ // TODO: 在此清理控件的实例数据。}// CactiveEventCtrl::OnDraw - 绘图函数void CactiveEventCtrl::OnDraw( CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid){ if (!pdc) return; // TODO: 用您自己的绘图代码替换下面的代码。 pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds);}// CactiveEventCtrl::DoPropExchange - 持久性支持void CactiveEventCtrl::DoPropExchange(CPropExchange* pPX){ ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor)); COleControl::DoPropExchange(pPX); // TODO: 为每个持久的自定义属性调用 PX_ 函数。}// CactiveEventCtrl::OnResetState - 将控件重置为默认状态void CactiveEventCtrl::OnResetState(){ COleControl::OnResetState(); // 重置 DoPropExchange 中找到的默认值 // TODO: 在此重置任意其他控件状态。}// CactiveEventCtrl 消息处理程序static UINT ThreadFunc(LPVOID lparam){ CactiveEventCtrl* cP=(CactiveEventCtrl*)lparam; cP->OK();//此处崩溃。 return 0;}void CactiveEventCtrl::Test(void){ AFX_MANAGE_STATE(AfxGetStaticModuleState()); HANDLE hThread = AfxBeginThread( ThreadFunc ,this , THREAD_PRIORITY_NORMAL ,0 ,0 ,NULL ); //OK();}
.h文件
- C/C++ code
#pragma once// activeEventCtrl.h : CactiveEventCtrl ActiveX 控件类的声明。// CactiveEventCtrl : 有关实现的信息,请参阅 activeEventCtrl.cpp。class CactiveEventCtrl : public COleControl{ DECLARE_DYNCREATE(CactiveEventCtrl)// 构造函数public: CactiveEventCtrl();// 重写public: virtual void OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid); virtual void DoPropExchange(CPropExchange* pPX); virtual void OnResetState();// 实现protected: ~CactiveEventCtrl(); DECLARE_OLECREATE_EX(CactiveEventCtrl) // 类工厂和 guid DECLARE_OLETYPELIB(CactiveEventCtrl) // GetTypeInfo DECLARE_PROPPAGEIDS(CactiveEventCtrl) // 属性页 ID DECLARE_OLECTLTYPE(CactiveEventCtrl) // 类型名称和杂项状态// 消息映射 DECLARE_MESSAGE_MAP()// 调度映射 DECLARE_DISPATCH_MAP()// 事件映射 DECLARE_EVENT_MAP()// 调度和事件 IDpublic: enum { dispidTest = 1L, eventidOK = 1L }; void OK(void) { FireEvent(eventidOK, EVENT_PARAM(VTS_NONE)); }protected: void Test(void);};测试html
- HTML code
<HTML><HEAD><TITLE>MyActiveX - Methods and Events</TITLE> <SCRIPT LANGUAGE="JavaScript">function PassParameter(){ MyActiveX.Test();}</SCRIPT></HEAD><BODY><center>MyActiveX - Methods and Events Example<p></p> <OBJECT ID="MyActiveX" CLASSID="CLSID:0BD0B363-B45E-414F-851E-B5A9706AFF7D"></OBJECT><p></p><INPUT TYPE="button" NAME="Submit" VALUE="Submit" ONCLICK=PassParameter()><SCRIPT FOR=MyActiveX EVENT=OK()><!-- { alert("事件被触发 ")--></SCRIPT></center></BODY>[解决办法]
组件在线程中使用最好进行列集与散集
http://www.vckbase.com/document/viewdoc/?id=1597
还有就是,不知道你的OK函数是什么,不要在线程中对控件界面进行直接操作,最好就是发送消息
[解决办法]
不就是回调js的函数嘛,
CComPtr<IDispatch> m_spCallback; //成员变量
添加ocx接口 SHORT RegisterCBFun(VARIANT &cbFunName); //
{
if (cbFunName.vt == VT_DISPATCH)
m_spCallback = cbFunName.pdispVal;
}
CComVariant varResult;
CComVariant avarParams[1];
string str;
avarParams[0] = tempItor->m_JsonStr.c_str();
avarParams[0].vt = VT_BSTR;
DISPPARAMS params = { avarParams, NULL, 1, 0 };
if(m_spCallback)
{
m_spCallback->Invoke(0,
IID_NULL,
LOCALE_USER_DEFAULT,
DISPATCH_METHOD,
¶ms, &varResult, NULL, NULL);
}
也许是是最好的,但是肯定可以使用,楼长注意回调函数参数的个数和相应代码的变化。
我的资源里ReportCtrl有相应的代码,你去下了看看。
