前言
由于本人在开发中经常要在程序中嵌入浏览器,为了符合自己的 需求经常要对浏览器进行扩展和定制,解决这些问题需在网上找资料和学习的过 程,我想可能很多开发者或许会遇到同样的问题,特写此文,以供大家参考。
在MFC中使用浏览器
在MFC中微软为我们提供了CHtmlView、 CDHtmlDialog类让我们的程序很方便的嵌入浏览器和进行浏览器的二次开发,这 比直 接使用WebBrowser控件要方便很多,所以本文中讨论的浏览器的问题都是 针对CHtmlView来讨论的。文中将提到一个类CLhpHtmlView, 它是CHtmlView的派 生类,文中提及的扩展或定制都将在CLhpHtmlView类(或派生类)上实现。
怎样扩展或定制浏览器
浏览器定义了一些扩展接口(如 IDocHostUIHandler可以定制浏览器界面有关的行为),以便开发者进行定制和 扩展。浏览 器会在需要的时候向他的控制站点查询这些接口,在控制站点里实 现相应的接口就可以进行相应的扩展。在MFC7.01类 库中,CHtmlView使用的控 制站点是CHtmlControlSite的,在CHtmlControlSite类中 只实现了接口 IDocHostUIHandler,而要实现更多的扩展接口,必须用自定义的控制站类来取 代CHtmlControlSite,在下文中提及的类CDocHostSite即为自定义 的控制站类 。
关于接口的介绍请参考: http://dev.csdn.net/develop/article/48/48483.shtm
如何 使自定义的控制站点来替换默认的控制站点呢?在MFC7.0中只需重载CHtmlView 的虚函数CreateControlSite即可:
BOOL CLhpHtmlView::CreateControlSite(COleControlContainer * pContainer,
VC6.0要替换控制站要复杂的多,这里就不讨论了,如需要6.0版本的请 给我发邮件到yourshine@21cn.com。
COleControlSite ** ppSite, UINT /*nID*/, REFCLSID /*clsid*/)
{
*ppSite = new CDocHostSite(pContainer, this);// 创建自己的 控制站点实例
return (*ppSite) ? TRUE : FALSE;
}
定制鼠标右键弹出出菜单
要 定制浏览器的鼠标右键弹出菜单,必须在自定义的控制站点类中实现 IDocHostUIHandler2接口,并且IE的 版本是5.5或以上。在接口 IDocHostUIHandler2的ShowContextMenu方法中调用浏览器类的 OnShowContextMenu虚函数,我们 在浏览器类的派生类重载此虚函数即可实现右 键菜单的定制,参见代码
HRESULT CDocHostSite::XDocHostUIHandler::ShowContextMenu(DWORD dwID,
POINT * ppt,
IUnknown * pcmdtReserved,
IDispatch * pdispReserved)
{
METHOD_PROLOGUE (CDocHostSite, DocHostUIHandler);
return pThis->m_pView- >OnShowContextMenu( dwID, ppt, pcmdtReserved,pdispReserved );
}
HRESULT CLhpHtmlView::OnShowContextMenu(DWORD dwID,
LPPOINT ppt,
LPUNKNOWN pcmdtReserved,
LPDISPATCH pdispReserved)
{
HRESULT result = S_FALSE;
switch(m_ContextMenuMode)
{
case NoContextMenu: // 无菜单
result=S_OK;
break;
case DefaultMenu: // 默认菜单
break;
case TextSelectionOnly: // 仅文本选择菜单
if(!(dwID == CONTEXT_MENU_TEXTSELECT || dwID == CONTEXT_MENU_CONTROL))
result=S_OK;
break;
case CustomMenu: // 自定义菜单
if(dwID! =CONTEXT_MENU_TEXTSELECT)
result=OnShowCustomContextMenu(ppt,pcmdtReserved,pdispReserved);
break;
}
return result;
}