// BHO 中添加下面的函数,设置UIHandler
// BHO 包含如下成员变量:

// CDocDispatch m_docDispatch;
// CComPtr<IDocHostUIHandler> m_spDefaultDocHostUIHandler;

// CComPtr<IOleCommandTarget> m_spDefaultOleCommandTarget;

HRESULT CBHO::SetDocHostUIHandler(IDispatch *pWebBrowser)
{
HRESULT hr = S_OK; if(NULL == pWebBrowser){
hr = S_FALSE;
}
else{
CComQIPtr<IWebBrowser2> spTempWebBrowser = pWebBrowser;
// only deal with the main window
if (spTempWebBrowser && m_spWebBrowser && m_spWebBrowser.IsEqualObject(spTempWebBrowser))
{
CComPtr<IDispatch> spDispDoc = NULL;
hr = spTempWebBrowser->get_Document(&spDispDoc);
if (SUCCEEDED(hr) && NULL != spDispDoc)
{
CComQIPtr<IHTMLDocument2> spDoc2 = spDispDoc;
if (spDoc2)
{
// Request default handler from MSHTML client site
CComQIPtr<IOleObject> spOleObject = spDispDoc;
if (spOleObject)
{
CComPtr<IOleClientSite> spClientSite = NULL;
hr = spOleObject->GetClientSite(&spClientSite);
if (SUCCEEDED(hr) && spClientSite)
{
m_spDefaultDocHostUIHandler = spClientSite;
m_spDefaultOleCommandTarget = spClientSite;
}
}
// Set the new custom IDocHostUIHandler
CComQIPtr<ICustomDoc> spCustomDoc = spDoc2;
if (spCustomDoc)
{
hr = spCustomDoc->SetUIHandler(this);
}
}
}
}
}
return hr;
}

在CBHO::Invoke中调用上面的函数

... ...
switch (dispidMember)
{
case DISPID_NAVIGATECOMPLETE2:
{
IDispatch* pDisp = pDispParams->rgvarg[1].pdispVal;
SetDocHostUIHandler(pDisp);
}
break;
}
... ...

CBHO实现IID_IDocHostUIHandler::GetExternal接口

HRESULT STDMETHODCALLTYPE CBHO::GetExternal(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch)
{
*ppDispatch = (IDispatch*)(&m_docDispatch);
return S_OK;
}

CBHO::SetSite中设置m_docDispatch

STDMETHODIMP CBHO::SetSite(IUnknown* pUnkSite)
{
if (pUnkSite != NULL)
{
pUnkSite->QueryInterface(IID_IWebBrowser2, (void**)&m_spWebBrowser);
if (m_spWebBrowser)
{
m_docDispatch.SetSite(this);
... ...
}
}
else
{
m_docDispatch.SetSite(NULL);
... ...
} ... ...
return IObjectWithSiteImpl<CBHOMain>::SetSite(pUnkSite);
}

实现CDocDispatch::GetIDsOfNames

HRESULT STDMETHODCALLTYPE CDocDispatch::GetIDsOfNames(
REFIID riid,
LPOLESTR __RPC_FAR *rgszNames,
UINT cNames,
LCID lcid,
DISPID __RPC_FAR *rgDispId)
{
UNREFERENCED_PARAMETER(riid);
UNREFERENCED_PARAMETER(lcid); HRESULT hr = S_OK; for (UINT i=0; i < cNames; i++)
{
CComBSTR bsName = rgszNames[i]; if (0 == _tcsicmp(bsName, _T("Func1")))
{
rgDispId[i] = ID_OF_FUNC1;
}
else if(0 == _tcsicmp(bsName, _T("Func2")))
{
rgDispId[i] = ID_OF_FUNC2;
}
else
{
// One or more are unknown so set the return code accordingly
hr = ResultFromScode(DISP_E_UNKNOWNNAME);
rgDispId[i] = DISPID_UNKNOWN;
hr = E_NOTIMPL;
}
} ... ...
return hr;
}

实现CDocDispatch::Invoke

HRESULT STDMETHODCALLTYPE CDocDispatch::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS __RPC_FAR *pDispParams,
VARIANT __RPC_FAR *pvarResult,
EXCEPINFO __RPC_FAR *pexcepinfo,
UINT __RPC_FAR *puArgErr)
{
HRESULT hr = S_OK; switch(dispIdMember)
{
case ID_OF_FUNC1:
if(m_pSite)
{
// 如果调用其他js函数,需要注意参数顺序
m_pSite->CallToJsFunction(pDispParams->rgvarg[1].bstrVal, pDispParams->rgvarg[0].bstrVal);
}
break;
case ID_OF_FUNC2:
if(m_pSite)
{
// 设置返回值
long result = ...
CComVariant varResult(result );
hr = varResult.Detach(pvarResult);
}
break;
default:
break; } ... ... return hr;
}

  

  

JS调用BHO的更多相关文章

  1. BHO插件操作IE浏览器,js调用C#方法

    BHO是IE浏览器的扩展程序,全名Browser Helper Object,文件格式为DLL文件.可对IE浏览器的界面和访问内容进行修改操作.BHO只适用于IE浏览器,对其他任何浏览器都没有作用.( ...

  2. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  3. 如何通过JS调用某段SQL语句

    如何通过JS调用某段SQL语句,这样的需求在报表.数据平台开发中很常见.以报表平台FineReport开发为例,例如在点击某个按钮之后,来判断一下数据库条数,再决定下一步操作.那这在后台如何实现呢? ...

  4. iOS开发--JS调用原生OC篇

    JS调用原生OC篇 方式一(反正我不用) 第一种方式是用JS发起一个假的URL请求,然后利用UIWebView的代理方法拦截这次请求,然后再做相应的处理. 我写了一个简单的HTML网页和一个btn点击 ...

  5. 通过js调用android原生方法

    有时候我们有这样一个需求,监听html中控件的一些事件.例如点击html中某个按钮,跳转到别的activity,复制某段文本. 首先是对webview的设置: myWebView = (WebView ...

  6. js调用php和php调用js的方法举例

    js调用php和php调用js的方法举例1 JS方式调用PHP文件并取得php中的值 举一个简单的例子来说明: 如在页面a.html中用下面这句调用: <script type="te ...

  7. android webView开发之js调用java代码示例

    1.webView设置 webView.getSettings().setJavaScriptEnabled(true);//设置支持js webView.addJavascriptInterface ...

  8. c#JS调用

    using MSScriptControl; using System; using System.Collections.Generic; using System.Reflection; usin ...

  9. Android 使用js调用Java

    效果如: 主要用到一个接口类:MyObject package com.example.jsdemo; import android.content.Context; import android.s ...

随机推荐

  1. BRD

    搜索 复制

  2. c#深拷贝

    /// <summary> /// 对象拷贝 /// </summary> /// <param name="obj">被复制对象</pa ...

  3. 使用jQuery清空file文件域的解决方案(转)

    对一个文件域(input type=file)使用了验证后,我们总会希望把文件域中的值给清空了,在IE中,由于安全设置的原因,是不允许更改文件域的值的(也就是不能使用val("") ...

  4. 第四周psp

    10号 类别c 内容c 开始时间s 结束e 中断I 净时间T GUI 查资料 12:10 12:40 0m 30m GUI 安装QT 19:10 21:00 20m 90m GUI 学习QT 23:0 ...

  5. js实现基础运动

    首先我定义3个div每个div当我鼠标放上去的时候,他的宽度就表达,如下图 首先是样式和html代码 <style> div{ width:100px; height:50px; back ...

  6. 【转】用C#调用Windows API向指定窗口发送

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  7. 使用 Intellij Idea 导出JavaDoc

    使用/* ...... /来注释代码,解释方法参数,返回参数,类的功能及用法. 常用的注释标签: @author 作者 @version 版本 @see 参考转向 @param 参数说明 @retur ...

  8. Windows7 IE10运行不了JavaScript的问题

    如题,我的环境是Windows7 + IE10,JavaScript怎么也运行不了.郁闷了好一段时间. 后来发现一种办法终于可以让JavaScript运行起来. 具体:  点击 [工具] => ...

  9. PHP 程序员的技术成长规划

    [导读] 按照了解的很多PHP LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序 ...

  10. 加密和ssl机制细节

    1.1 背景知识 对称加密:加密解密使用同一密钥,加解密速度快.随着人数增多,密钥数量急增n(n-1)/2 非对称加密:使用公私钥配对加解密,速度慢.公钥是从私钥中提取出来的,一般拿对方公钥加密来保证 ...