javascrip for 语句访问Idispatch 对应的过程是什么

hbs_biscuit 2008-04-23 12:30:06
我在javascript 中想用 FOR 语句循环找到 activex 公布出来的 DISPATCH 接口数据

从 javascript 中传入 对象数组的过程如下:
var oParams=new Object();
oParams["LoginName"]="test";
oParams["Password"]="123";
oParams["VerifyCode"]="12PQ";
TestActiveX.SendMsg("test",oParams);

activex 中定义的方法如下:
[id(7)] long SendMsg(BSTR TYPE, VARIANT Name);
long CInfoTCtrl::SendMsg(LPCTSTR TYPE, const VARIANT FAR& Name)

现在需要ACTIVEX 公开一个事件:
[id(1)] void RecvMsg(BSTR TYPE, VARIANT* Name);
void FireRecvMsg(LPCTSTR TYPE, VARIANT FAR* Name)
{FireEvent(eventidRecvMsg,EVENT_PARAM(VTS_BSTR VTS_PVARIANT ), TYPE, Name);}

然后在JAVASCRIPT 中接收:
<script language="JavaScript1.2" for="TestActiveX" event="RecvMsg(sTYPE,Msg)">
var ocx=sTYPE;
alert("sTYPE : "+ocx) ;

for(prop in Msg)
{
alert("event :"+prop+"="+Msg[prop]);
}

如果我直接在 ACTIVEX 中sendmsg 中调用 FireRecvMsg 是可以成功的,JAVASCRIP 这边也可以正常接收到,
但是现在的问题是我需要在ACTIVEX 的其他函数中实现 调用FireRecvMsg 的功能,但是当JAVASCRIPT 运行到
for(prop in Msg)
这一行的时候报错“对象不支持此属性和方法”
根据上一贴
http://topic.csdn.net/u/20080418/12/3c09eb2c-fbb4-419f-8a6e-50d78ba8ff2d.html
蒋老大的指示,我的对象继承了 IdispatchEx 的所有接口方法,但是似乎JAVASCRIPT 就没有调用我实现的方法,现在有些迷惑,到底JAVASCRIP 解析 for 语句的时候做了一些什么动作呢,这个过程是怎么样的?

恳求蒋老大给指点一下,各路神仙有知道的也给支个招,
多谢!!!!
...全文
145 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbs_biscuit 2008-04-23
  • 打赏
  • 举报
回复
我的猜想如下:
0. 首先 通过 VARIANT 找到 DISPATCHEX 指针
1. 猜想JAVA SCRIPT 中会首先调用 GetNextDispID 找到第一个 DISPID
2. 然后 通过disp id 找到 NAME 采用 :调用DISPATCHEX指向的 getMemberName 找到 名字 也就是数组下标
3. 然后通过 DISPATCHEX 指向的INVOKEEX 通过 DISPID 找到 对象的值 也就是 数组的元素。

不知道对不对
蒋晟 2008-04-23
  • 打赏
  • 举报
回复
>不知道是不是应该用 ADDREF ,RELEASE 处理一下

>在javascript 中想用 FOR 语句循环
Invoke里面实现DISPID_NEWENUM属性,返回一个支持IEnumVARIANT的对象
hbs_biscuit 2008-04-23
  • 打赏
  • 举报
回复
VARIANT variant; 
HRESULT hr;
variant.vt=VT_DISPATCH;
//调用类型库,为创建dispatchex 接口的对象而准备
ITypeLib * mTypeLib;
hr=LoadTypeLib(L"d:\\My Documents\\My Prog\\HarborH\\InfoT\\Debug\\Msg.tlb",&mTypeLib);
if(SUCCEEDED(hr))
{
//创建 dispatchex 接口继承下来的对象
CMsgOb* pMsgOb=new CMsgOb(mTypeLib);
//将消息内容值赋值给这个对象
SetMsg(pMsgOb,msg);
hr=pMsgOb->QueryInterface(IID_IDispatch,(void**)&variant.ppdispVal);
if(SUCCEEDED(hr))
{
//将事件分发给javascript
FireRecvMsg(msg.m_msgTYPE,&variant);
}
//删除就会出错
// delete pMsgOb;
}
hbs_biscuit 2008-04-23
  • 打赏
  • 举报
回复
另外有个问题:
就是当我动态建立对象,调用完激发事件的时候 就删除那个对象,发现 IE 会报 JSCRIPT.EXE 错误,建立对象后不删除是不报错的,不知道是不是应该用 ADDREF ,RELEASE 处理一下,但是还不知道怎么处理,有这方面经验的可以指导一下,多些 !!

有感兴趣的跟帖啊!!!

调用事件的代码如下
====================================================
VARIANT variant;
HRESULT hr;
variant.vt=VT_DISPATCH;
//调用类型库,为创建dispatchex 接口的对象而准备
ITypeLib * mTypeLib;
hr=LoadTypeLib(L"d:\\My Documents\\My Prog\\HarborH\\InfoT\\Debug\\Msg.tlb",&mTypeLib);
if(SUCCEEDED(hr))
{
//创建 dispatchex 接口继承下来的对象
CMsgOb* pMsgOb=new CMsgOb(mTypeLib);
//将消息内容值赋值给这个对象
SetMsg(pMsgOb,msg);
hr=pMsgOb->QueryInterface(IID_IDispatch,(void**)&variant.ppdispVal);
if(SUCCEEDED(hr))
{
//将事件分发给javascript
FireRecvMsg(msg.m_msgTYPE,&variant);
}
//删除就会出错
// delete pMsgOb;

}
====================================================
hbs_biscuit 2008-04-23
  • 打赏
  • 举报
回复
应该搞定了, 由于用了 陆其明老大的代码,发现了两个小错误,系统可以应该运行了

更改了两处:
IDispatchExImpl.h
HRESULT GetStartDispID(DISPID* pDispID)
{
// Default to no entries available
HRESULT hr = S_FALSE;

bool bDone = false;
MapDispidToEntry::iterator it, itEnd(m_mapDispidToEntry.end());
int i=m_mapDispidToEntry.size();
for (it = m_mapDispidToEntry.begin(); it != itEnd && !bDone; ++it)
{
DISPID dispid = -1;

// Determine if this item is not deleted
CDynamicDispatchEntry* pEntry = (*it).second;
if (pEntry->IsDeleted() == false && pEntry->UseTypeInfo()== false)
{
// No need to look further
bDone = true;
// Return the dispid
*pDispID = pEntry->GetDispID();
// Change the HRESULT to S_OK so that the caller does not
// think that we have no members
hr = S_OK;
}
}
return hr;


HRESULT GetNextDispID(DISPID dispid, DISPID* pDispID)
{
// Default to no entries available
HRESULT hr = S_FALSE;

// Search until we have no more entries or found the next item
DISPID curDispid = dispid;
bool bDone = false;
while (!bDone)
{
// Move to what we think is the next dispid
curDispid++;

MapDispidToEntry::const_iterator it = m_mapDispidToEntry.find(curDispid);
if (it != m_mapDispidToEntry.end())
{
CDynamicDispatchEntry* const pEntry = (*it).second;
// Determine if this item is not deleted
if (pEntry->IsDeleted() == false && pEntry->UseTypeInfo()== false) {
// No need to look further
bDone = true;
// Return the dispid
*pDispID = pEntry->GetDispID();
// Change the HRESULT to S_OK so that the caller does not
// think that we have no members
hr = S_OK;
}
}
else
{
bDone = true;
}
}
return hr;
}

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧