首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

activex调用javascript函数解决方法

2012-04-07 
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, 
&params, &varResult, NULL, NULL);


}

也许是是最好的,但是肯定可以使用,楼长注意回调函数参数的个数和相应代码的变化。
我的资源里ReportCtrl有相应的代码,你去下了看看。


热点排行
Bad Request.