// 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. Spark RDD类源码阅读

    每天进步一点点~开搞~ abstract class RDD[T: ClassTag]( //@transient 注解表示将字段标记为瞬态的 @transient private var _sc: ...

  2. Win32程序和控制台应用程序的项目互转设置

    一般情况下,如果是windows程序,那么WinMain是入口函数,在VS2010中新建项目为"win32项目" 如果是dos控制台程序,那么main是入口函数,在VS2010中新 ...

  3. Celery 和 Redis 入门

    Celery 是一个广泛应用于网络应用程序的任务处理系统. 它可以在以下情况下使用: 在请求响应周期中做网络调用.服务器应当立即响应任何网络请求.如果在请求响应周期内需要进行网络调用,则应在周期外完成 ...

  4. ucenter 整合外部网站,实现登录等操作

    最近公司网站要出手机版,由于与论坛要有互通,实现会员的共享,由于对discuz不熟悉,起先考虑的是直接读取discuz的用户表,然后进行判断等操作,发现过于复杂,而且安全也不好. 前一段时间进行过论坛 ...

  5. c#lock语句及在单例模式中应用

    C#中的lock语句是怎么回事,有什么作用? C#中的lock语句将lock中的语句块视为临界区,让多线程访问临界区代码时,必须顺序访问.他的作用是在多线程环境下,确保临界区中的对象只被一个线程操作, ...

  6. Oracle时间戳 与时间之间的相互转换

    Unix时间戳记是从'1970-01-01 00:00:00'GMT开始的秒数,表现为整数型. Oracle中的时间是Date型,以下函数提供了两种时间转换的Oracle函数 (1)从Unix时间戳记 ...

  7. Blackfin DSP(二):寄存器操作与GPIO

    BlackfinDSP的寄存器是通过指针操作的,与51.ARM等MCU一样,通过“或”操作来置1,通过“与”操作清零. 在DSP上最简单的外设非IO口莫属,但是由于其功能强大,远非一般IO口可比,因此 ...

  8. python3实现简单爬虫功能

    本文参考虫师python2实现简单爬虫功能,并增加自己的感悟. #coding=utf-8 import re import urllib.request def getHtml(url): page ...

  9. JQ怎么获取margin-left的值

    var margin =$("#Modules .list").css('marginLeft');

  10. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...