您的位置:首页 > Web前端 > JavaScript

COM动态添加删除成员,类似JavaScript中调用的对象

2014-03-17 00:03 666 查看
在JavaScript中调用对象时,可动态添加删除成员如:

var obj=new Object;
obj.member1='aaaaa';
obj.fun1=function()
{
alert('fun1');
}


查了好些资料,原来Object这个COM对象,是实现了IDispatchEx接口

JS在调用对象成员之前,先利用IDispatchEx::GetDispID(成员名) 判断成员是否存在

那么在VC++中编写COM对象时即可以这样 在GetDispID中 添加对应的成员即可

//类头文件
class CSRObject	:public IDispatchEx
{
CSRObject(void);
~CSRObject(void);
virtual HRESULT STDMETHODCALLTYPE GetDispID( __RPC__in BSTR bstrName, DWORD grfdex, __RPC__out DISPID *pid );

virtual HRESULT STDMETHODCALLTYPE InvokeEx( DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller );

virtual HRESULT STDMETHODCALLTYPE DeleteMemberByName( __RPC__in BSTR bstrName, DWORD grfdex );
virtual HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void **ppvObject );
//省略若干虚函数实现...
}


HRESULT STDMETHODCALLTYPE CSRObject::QueryInterface( REFIID riid, void **ppvObject )
{
if (riid==IID_IUnknown)
{
*ppvObject = (CSRObject *)this;
}else if (riid==IID_IDispatch)
{
*ppvObject = (CSRObject *)this;
}else if (riid==IID_IDispatchEx)
{
*ppvObject = (CSRObject *)this;
//IDispatchEx接口
}else{
*ppvObject = NULL;
return(E_NOINTERFACE);
}
return S_OK;
}

//这里是JS按照成员名字查成员DISPID
//JS在调用成员前会先调用该函数
HRESULT STDMETHODCALLTYPE CSRObject::GetDispID( __RPC__in BSTR bstrName, DWORD grfdex, __RPC__out DISPID *pid )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

if(grfdex & fdexNameCaseInsensitive)
//如果有fdexNameCaseInsensitive标志,查找成员名时忽略大小写

if (成员不存在 && grfdex & fdexNameEnsure)
//如果成员不存在且有fdexNameEnsure标志,你需要动态的创建这个成员名

//存在成员返回S_OK,并且 *pid=该成员ID

//没有该成员返回 DISP_E_UNKNOWNNAME
}

//这里才是真正的调用函数
HRESULT STDMETHODCALLTYPE CSRObject::InvokeEx( DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

//参数:id 就是JS通过GetDispID得到的DISPID,你需要按照该ID判断此次调用的是什么函数

if (wFlags & DISPATCH_PROPERTYGET && wFlags & DISPATCH_METHOD)
{
//比如在JS中的代码:
//var n=xxx.getvalue([param]);
//那么将会到这里来
}else if (wFlags & DISPATCH_PROPERTYGET)	//获取属性值
{
//比如在JS中的代码:
//var n=xxx.value;
//那么将会到这里来
}else if (wFlags & DISPATCH_PROPERTYPUT) //设置属性值
{
//比如在JS中的代码:
//xxx.value=n;
//那么将会到这里来
}else if (wFlags & DISPATCH_METHOD) //调用成员
{
//比如在JS中的代码:
//xxx.getvalue();
//那么将会到这里来
}else{
//其它情况暂时没遇到过
return DISP_E_MEMBERNOTFOUND;
}

return hr;
}


备份:http://www.silenceret.com/view.asp?id=12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐