打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
vc++访问javascript(5)
在VC++中绑定网页元素的事件(如onclick),通常会使用HTMLElementEvents2事件接口进行。大致如下:
void   CSomeObject:ConnectElement(IHTMLElement*   pElement)
{
//取得连接点容器
CComQIPtr<IConnectionPointContainer> pCPC=pElement;
//查找连接点
CComPtr<IConnectionPoint> pCP;
pCPC->FindConnectionPoint( DIID_HTMLElementEvents2, &pCP);
//连接事件接口
IUnknownPtr pUnk=this; //由CSomeObject实现HTMLElementEvents2事件接口
DWORD dwCookie;
pCP->Advise( pUnk, &dwCookie);
}
而在javascript中使用attachEvent绑定网页元素事件的方式却显得更自然,实现也更直接,我们是否也可以用VC++实现呢?
function fn_onclick()
{
alert("Hello world!");
}
document.all("button1").attachEvent("onclick",fn_onclick);
document.all("button1").detachEvent("onclick",fn_onclick);
先看看在PIMShell中用VC++是怎样实现以上功能的。
class ATL_NO_VTABLE CVCEventSinkDemo:
public IDispatchImpl<IVCEventSinkDemo>
{
public:
CVCEventSinkDemo()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
private:
//代理对象
PIMShellCore::IAjaxDelegatePtr m_pDelegate_onevents;
//回调函数
static HRESULT CALLBACK Sink_onevents( VARIANT vEvent, VARIANT vContext, IUnknown* pInstance, VARIANT* pvarResult);
//绑定事件或取消绑定
void __attachEvents(bool bAttach);
};
////////////////////////////////////////////////////
void CVCEventSinkDemo::__attachEvents(bool bAttach)
{
if(bAttach)
{
//生成一个代理对象,传入this指针和回调函数
IUnknownPtr pThis=this;
m_pDelegate_onevents = o->Sys2->CreateDelegateVC1( pThis, (LONGLONG)&Sink_onevents);
//绑定事件
o->Control->AttachEvent(L"onclick", m_pDelegate_onevents);
}
else
{
if(m_pDelegate_onevents!=NULL)
{
//取消绑定
o->Control->DetachEvent( L"onclick", m_pDelegate_onevents);
//
m_pDelegate_onevents=NULL;
}
}
}
//当事件发生时,调用此函数
HRESULT CVCEventSinkDemo::Sink_onevents( VARIANT vEvent, VARIANT vContext, IUnknown* pInstance, VARIANT* pvarResult)
{
__SAFECALL_BEGIN;
//取得this指针
CVCEventSinkDemo* pThis=dynamic_cast<CVCEventSinkDemo*>(pInstance);
//取得event对象
MSHTML::IHTMLEventObjPtr e=vEvent.pdispVal;
//event.type
CString sType=e->type;
//
if(sType==L"click")
{
//执行响应代码
}
__SAFECALL_END;
}
1、先生成一个代理对象,这个对象记录CVCEventSinkDemo的实例指针和回调函数,与C#中delegate的设计理念一致。
2、将代理对象传入attachEvent实现对onclick事件的绑定。
3、当事件发生时,系统调用代理对象的0方法,
4、在代理对象的0方法中,调用先前记录的回调函数,并将CVCEventSinkDemo的实例指针传入。
我们接下来看看CreateDelegateVC1是如何生成代理对象的。
HRESULT CreateDelegateVC1( IUnknown* pInstance, LONGLONG lnCallback, IDispatch** ppDelegate)
{
//生成代理对象
CComObject<CVCDelegateDemo>* pDelegate;
HRESULT hr=CComObject<CVCDelegateDemo>::CreateInstance(&pDelegate);
if(FAILED(hr))
return hr;
//记录实例指针和回调函数
pDelegate->__record(pInstance,lnCallback);
//ok
return pDelegate->QueryInterface(IID_IDispatch,(void**)ppDelegate);
}
接下来,我们看CVCDelegateDemo的0方法是如何实现的
class ATL_NO_VTABLE CVCDelegateDemo:
public IDispatchImpl<CVCDelegateDemo>
{
public:
CVCDelegateDemo()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
//声明回调函数的格式
typedef HRESULT (CALLBACK* _delegateVC1)( VARIANT vParam1, VARIANT vContext, IUnknown* pInstance, VARIANT* pvarResult);
private:
IUnknownPtr       m_pInstance;
_delegateVC1      m_pCallback1;
public:
//record
void __record(IUnknown* pInstance,LONGLONG lnCallback)
{
//记录实例指针和回调函数
this->m_pInstance=pInstance;
this->m_pCallback1=(_delegateVC1)lnCallback;
}
public:
//实现0方法,并调用回调函数
STDMETHOD(Invoke)( DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
DISPPARAMS* pDispParams, VARIANT* pvarResult,
EXCEPINFO*  pExcepInfo,  UINT* puArgErr)
{
//只支持0方法
if(dispidMember!=0)
return E_INVALIDARG;
//如果是通过attachEvent绑定网页元素的事件,那么传入的第一个参数就是event对象
_variant_t vEvent=pDispParams->rgvarg[0];
//调用回调函数,传入event对象和实例指针
(*m_pCallback1)(vEvent,vtMissing,m_pInstance,pvarResult);
//ok
return  S_OK;
}
};
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
VC知识库文章 - COM 组件设计与应用(三)——数据类型
用vc将js响应函数绑定到网页元素的办法
ExcelのRTDサーバーを、VC++で書いてみた。 - しがないプログラマ の日記
请问如何访问本程序里webbrowser里javascript的函数? 谢谢
怎样用attachEvent绑定带参数的函数?
在COM中使用数组参数-SafeArray
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服