// 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. linux gcc头文件搜索路径

    #include <>: 直接到系统指定的某些目录中去找某些头文件.#include "": 先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件 1. ...

  2. volley_之基本使用

    Volley的基本使用-------------- 本人初学,如有纰缪,望指正~ Volley是Google在2003年的I/O大会上推出的通信框架,结合了AsyncHttpClient和Univer ...

  3. 企业架构(Enterprise Architecture)

    ylbtech-Miscellaneos: 企业架构(Enterprise Architecture) A,返回顶部 1, 简称EA.是指对企业事业信息管理系统中具有体系的.普遍性的问题而提供的通用解 ...

  4. 第五周PSP

    16号 类别c 内容c 开始时间s 结束e 中断I 净时间T GUI 学习QT视频 20:00 21:42 20m 82m 17号 类别c 内容c 开始时间s 结束e 中断I 净时间T GUI 学习Q ...

  5. js实现图片的淡入淡出

    思想: 其实是运动的一种,就是当鼠标移入div中时,将div的透明度变大, 当鼠标移动出来的时候透明度变回原来. 你可以尝试写一下,不会再看看代码 <style> #div1{ width ...

  6. CSS中的相对定位和绝对定位

    1.元素的position属性的值默认为static 就是没有定位,元素出现在正常的文档流中,,这个时候你给这个元素设置的left,right,bottom,top这些偏移属性都是没有效果的, 使用相 ...

  7. [前端_EasyUI]给easyui的datebox设置默认值,获取不到 的解决方法

    //给eayui datebox设置初始值 $("#ctime").datebox("setValue", function(){ var date = new ...

  8. Python之路【第十六篇】:Django【基础篇】

    Python之路[第十六篇]:Django[基础篇]   Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了O ...

  9. ps 使用说明

    ps基本介绍 linux 版本 centos 1511  x64 汇报当前所有进程的快照.report a snapshot of the current processes. 能够显示F, S, U ...

  10. 块级格式化上下文(block formatting context)、浮动和绝对定位的工作原理详解

    CSS的可视化格式模型中具有一个非常重要地位的概念——定位方案.定位方案用以控制元素的布局,在CSS2.1中,有三种定位方案——普通流.浮动和绝对定位: 普通流:元素按照先后位置自上而下布局,inli ...