科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件利用MFC实现浏览器的定制与扩展

利用MFC实现浏览器的定制与扩展

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

由于本人在开发中经常要在程序中嵌入浏览器,为了符合自己的需求经常要对浏览器进行扩展和定制。

作者:李汉鹏 来源:VCKBASE 2007年10月19日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
实现脚本扩展(很重要的external接口)

  在你嵌入了浏览器的工程中,如果网页的脚本中能调用C++代码,那将是一件很惬意的事情,要实现这种交互,就必须实现脚本扩展。实现脚本扩展就是在程序中实现一个IDispatch接口,通过CHtmlView类的OnGetExternal虚函数返回此接口指针,这样就可以在脚本中通过window.external.XXX(关键字window可以省略)来 引用接口暴露的方法或属性(XXX为方法或属性名)。在MFC中从CCmdTarget派生的类都可以实现自动化,而不必在MFC工程中引入繁杂的ATL。从CCmdTarget派生的类实现自动化接口的时候不要忘了在构造函数中调用EnableAutomation函数。

  要使虚函数OnGetExternal发挥作用必须在 自定义的控制站点类中实现IDocHostUIHandler,在接口IDocHostUIHandler的GetExternal方法中调用浏览器类的OnGetExternal虚函数,我们在浏览器类的派生类重载OnGetExternal虚函数, 通过参数lppDispatch返回一个IDispatch指针,这样脚本中引用window.external时就是引用的返回的接口,参见代码
HRESULT CDocHostSite::XDocHostUIHandler::GetExternal(IDispatch ** ppDispatch) 
{ 
 METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler); 
 return pThis->m_pView->OnGetExternal( ppDispatch ); 
} 

CLhpHtmlView::CLhpHtmlView(BOOL isview) 
{ 
 ...... 
 EnableAutomation();// 允许自动化 
} 

HRESULT CLhpHtmlView::OnGetExternal(LPDISPATCH *lppDispatch) 
{ 
 *lppDispatch = GetIDispatch(TRUE);// 返回自身的IDispatch接口 
 return S_OK; 
}      
  请注意上面代码中,在OnGetExternal返回的是自身IDispatch接口, 这样就不比为脚本扩展而另外写一个从CCmdTarget派生的新类, CLhpHtmlView本身就是从CCmdTarget派生,直接在上面实现接口就是。

  下用具体示例来说明怎样实现脚本扩展

  示例会在网页上点击一个按钮而使整个窗口发生抖动

  从CLhpHtmlView派生一个类CDemoView,在类中实现IDispatch, 并通过IDispatch暴露方法WobbleWnd
--------------------------------------------------------------------------- 
文件 DemoView.h 
--------------------------------------------------------------------------- 
....... 
class CDemoView : public CLhpHtmlView 
{ 
 ...... 
 DECLARE_DISPATCH_MAP() // 构建dispatch映射表以暴露方法或属性 
 ...... 
 void WobbleWnd();// 抖动窗口 
}; 

--------------------------------------------------------------------------- 
文件 DemoView.cpp 
--------------------------------------------------------------------------- 

...... 

// 把成员函数映射到Dispatch映射表中,暴露方法给脚本 
BEGIN_DISPATCH_MAP(CDemoView, CLhpHtmlView) 
 DISP_FUNCTION(CDemoView, "WobbleWnd", WobbleWnd, VT_EMPTY, VTS_NONE) 
END_DISPATCH_MAP() 

...... 

void CDemoView::WobbleWnd() 
{ 
 // 在这里实现抖动窗口 
 ...... 
} 

--------------------------------------------------------------------------- 
文件 Demo.htm 
--------------------------------------------------------------------------- 

...... onclick="external.WobbleWnd()" ......  
  这里我要介绍一下DISP_FUNCTION宏,它的作用是将一个函数映射到Dispatch映射表中,我们看
DISP_FUNCTION(CDemoView, "WobbleWnd", WobbleWnd, VT_EMPTY, VTS_NONE)

  CDemoView是宿主类名, "WobbleWnd"是暴露给外面的名字(脚本调用时使用的名字), VT_EMPTY是返回值得类型为空,VTS_NONE说明此方法没有参数,如果要映射的函数有返回值和参数该 如何映射,通过下面举例来说明

DISP_FUNCTION(CCalendarView,"TestFunc",TestFunc,VT_BOOL,VTS_BSTR VTS_I4 VTS_I4) 

BOOL TestFunc(LPCSTR param1, int param2, int param3) 
{ 
 ..... 
}  
  参数表VTS_BSTR VTS_I4 VTS_I4是用空格分隔,他们的类型映射请参考MSDN,这要提醒的是不要把VTS_BSTR与CString对应,而应与LPCSTR对应。

  C++代码中如何调用网页脚本中的函数

  IHTMLDocument2::scripts属性表示HTML文档中所有脚本对象。使用脚本对象的IDispatch接口的GetIDsOfNames方法可以得到脚本函数的 DispID,得到DispID后,使用IDispatch的Invoke函数可以调用对应的脚本函数。CLhpHtmlView提供了方便的调用JavaScript的函数,请参考CLhpHtmlView中有关键字“JScript”的代码。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章