Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14523656
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:28:44

下载本文示例代码
  前言  由于本人在开发中经常要在程序中嵌入浏览器,为了符合自己的需求经常要对浏览器进行扩展和定制, 解决这些问题需在网上找资料和学习的过程,我想可能很多开发者或许会遇到同样的问题,特写此文,以供大家参考。   在MFC中使用浏览器  在MFC中微软为我们提供了CHtmlView、CDHtmlDialog类让我们的程序很方便的嵌入浏览器和进行浏览器的二次开发,这比直 接使用WebBrowser控件要方便很多,所以本文中讨论的浏览器的问题都是针对CHtmlView来讨论的。文中将提到一个类CLhpHtmlView, 它是CHtmlView的派生类,文中提及的扩展或定制都将在CLhpHtmlView类(或派生类)上实现。  怎样扩展或定制浏览器  浏览器定义了一些扩展接口(如IDocHostUIHandler可以定制浏览器界面有关的行为),以便开发者进行定制和扩展。浏览 器会在需要的时候向他的控制站点查询这些接口,在控制站点里实现相应的接口就可以进行相应的扩展。在MFC7.01类 库中,CHtmlView使用的控制站点是CHtmlControlSite的,在CHtmlControlSite类中 只实现了接口IDocHostUIHandler, 而要实现更多的扩展接口,必须用自定义的控制站类来取代CHtmlControlSite,在下文中提及的类CDocHostSite即为自定义 的控制站类。   如何使自定义的控制站点来替换默认的控制站点呢?在MFC7.0中只需重载CHtmlView的虚函数CreateControlSite即可: BOOL CLhpHtmlView::CreateControlSite(COleControlContainer * pContainer, COleControlSite ** ppSite, UINT /*nID*/, REFCLSID /*clsid*/){ *ppSite = new CDocHostSite(pContainer, this);// 创建自己的控制站点实例 return (*ppSite) ? TRUE : FALSE;}   VC6.0要替换控制站要复杂的多,这里就不讨论了。  定制鼠标右键弹出出菜单  要定制浏览器的鼠标右键弹出菜单,必须在自定义的控制站点类中实现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; } 在CLhpHtmlView中定义的枚举类型CONTEXT_MENU_MODE举出了定制右键弹出菜单的四种类型 enum CONTEXT_MENU_MODE // 上下文菜单 { NoContextMenu, // 无菜单 DefaultMenu, // 默认菜单 TextSelectionOnly, // 仅文本选择菜单 CustomMenu // 自定义菜单 };   通过CLhpHtmlView的函数SetContextMenuMode来设置右键菜单的类型。如果设定的右键弹出菜单是“自定义菜单”类型, 我们只要在CLhpHtmlView的派生类中重载OnShowCustomContextMenu虚函数即可,如下代码 CDemoView是CLhpHtmlView的派生类 HRESULT CDemoView::OnShowCustomContextMenu(LPPOINT ppt, LPUNKNOWN pcmdtReserved,LPDISPATCH pdispReserved) { if ((ppt==NULL)||(pcmdtReserved==NULL)||(pcmdtReserved==NULL)) return S_OK; HRESULT hr=0; IOleWindow *oleWnd=NULL; hr=pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&oleWnd); if((hr != S_OK)||(oleWnd == NULL)) return S_OK; HWND hwnd=NULL; hr=oleWnd->GetWindow(&hwnd); if((hr!=S_OK)||(hwnd==NULL)) { oleWnd->Release(); return S_OK; } IHTMLElementPtr pElem=NULL; hr = pdispReserved->QueryInterface(IID_IHTMLElement, (void**)&pElem); if(hr != S_OK) { oleWnd->Release(); return S_OK; } IHTMLElementPtr pParentElem=NULL; _bstr_t tagID; BOOL go=TRUE; pElem->get_id(&tagID.GetBSTR()); while(go && tagID.length()==0) { hr=pElem->get_parentElement(&pParentElem); if(hr==S_OK && pParentElem!=NULL) { pElem->Release(); pElem=pParentElem; pElem->get_id(&tagID.GetBSTR()); } else go=FALSE; }; if(tagID.length()==0) tagID="no id"; CMenu Menu,SubMenu; Menu.CreatePopupMenu(); CString strTagID = ToStr(tagID); if(strTagID == "red") Menu.AppendMenu(MF_BYPOSITION, ID_RED, "您点击的是红色"); else if(strTagID == "green") Menu.AppendMenu(MF_BYPOSITION, ID_GREEN, "您点击的是绿色"); else if(strTagID == "blue") Menu.AppendMenu(MF_BYPOSITION, ID_BLUE, "您点击的是蓝色"); else Menu.AppendMenu(MF_BYPOSITION, ID_NONE, "你点了也白点,请在指定的地方点击"); int MenuID=Menu.TrackPopupMenu(TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,ppt->x, ppt->y, this); switch(MenuID) { case ID_RED: MessageBox("红色"); break; case ID_GREEN: MessageBox("红色"); break; case ID_BLUE: MessageBox("红色"); break; case ID_NONE: MessageBox("haha"); break; } oleWnd->Release(); pElem->Release(); return S_OK; } 共4页。 1 2 3 4 :   前言  由于本人在开发中经常要在程序中嵌入浏览器,为了符合自己的需求经常要对浏览器进行扩展和定制, 解决这些问题需在网上找资料和学习的过程,我想可能很多开发者或许会遇到同样的问题,特写此文,以供大家参考。   在MFC中使用浏览器  在MFC中微软为我们提供了CHtmlView、CDHtmlDialog类让我们的程序很方便的嵌入浏览器和进行浏览器的二次开发,这比直 接使用WebBrowser控件要方便很多,所以本文中讨论的浏览器的问题都是针对CHtmlView来讨论的。文中将提到一个类CLhpHtmlView, 它是CHtmlView的派生类,文中提及的扩展或定制都将在CLhpHtmlView类(或派生类)上实现。  怎样扩展或定制浏览器  浏览器定义了一些扩展接口(如IDocHostUIHandler可以定制浏览器界面有关的行为),以便开发者进行定制和扩展。浏览 器会在需要的时候向他的控制站点查询这些接口,在控制站点里实现相应的接口就可以进行相应的扩展。在MFC7.01类 库中,CHtmlView使用的控制站点是CHtmlControlSite的,在CHtmlControlSite类中 只实现了接口IDocHostUIHandler, 而要实现更多的扩展接口,必须用自定义的控制站类来取代CHtmlControlSite,在下文中提及的类CDocHostSite即为自定义 的控制站类。   如何使自定义的控制站点来替换默认的控制站点呢?在MFC7.0中只需重载CHtmlView的虚函数CreateControlSite即可: BOOL CLhpHtmlView::CreateControlSite(COleControlContainer * pContainer, COleControlSite ** ppSite, UINT /*nID*/, REFCLSID /*clsid*/){ *ppSite = new CDocHostSite(pContainer, this);// 创建自己的控制站点实例 return (*ppSite) ? TRUE : FALSE;}   VC6.0要替换控制站要复杂的多,这里就不讨论了。  定制鼠标右键弹出出菜单  要定制浏览器的鼠标右键弹出菜单,必须在自定义的控制站点类中实现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; } 在CLhpHtmlView中定义的枚举类型CONTEXT_MENU_MODE举出了定制右键弹出菜单的四种类型 enum CONTEXT_MENU_MODE // 上下文菜单 { NoContextMenu, // 无菜单 DefaultMenu, // 默认菜单 TextSelectionOnly, // 仅文本选择菜单 CustomMenu // 自定义菜单 };   通过CLhpHtmlView的函数SetContextMenuMode来设置右键菜单的类型。如果设定的右键弹出菜单是“自定义菜单”类型, 我们只要在CLhpHtmlView的派生类中重载OnShowCustomContextMenu虚函数即可,如下代码 CDemoView是CLhpHtmlView的派生类 HRESULT CDemoView::OnShowCustomContextMenu(LPPOINT ppt, LPUNKNOWN pcmdtReserved,LPDISPATCH pdispReserved) { if ((ppt==NULL)||(pcmdtReserved==NULL)||(pcmdtReserved==NULL)) return S_OK; HRESULT hr=0; IOleWindow *oleWnd=NULL; hr=pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&oleWnd); if((hr != S_OK)||(oleWnd == NULL)) return S_OK; HWND hwnd=NULL; hr=oleWnd->GetWindow(&hwnd); if((hr!=S_OK)||(hwnd==NULL)) { oleWnd->Release(); return S_OK; } IHTMLElementPtr pElem=NULL; hr = pdispReserved->QueryInterface(IID_IHTMLElement, (void**)&pElem); if(hr != S_OK) { oleWnd->Release(); return S_OK; } IHTMLElementPtr pParentElem=NULL; _bstr_t tagID; BOOL go=TRUE; pElem->get_id(&tagID.GetBSTR()); while(go && tagID.length()==0) { hr=pElem->get_parentElement(&pParentElem); if(hr==S_OK && pParentElem!=NULL) { pElem->Release(); pElem=pParentElem; pElem->get_id(&tagID.GetBSTR()); } else go=FALSE; }; if(tagID.length()==0) tagID="no id"; CMenu Menu,SubMenu; Menu.CreatePopupMenu(); CString strTagID = ToStr(tagID); if(strTagID == "red") Menu.AppendMenu(MF_BYPOSITION, ID_RED, "您点击的是红色"); else if(strTagID == "green") Menu.AppendMenu(MF_BYPOSITION, ID_GREEN, "您点击的是绿色"); else if(strTagID == "blue") Menu.AppendMenu(MF_BYPOSITION, ID_BLUE, "您点击的是蓝色"); else Menu.AppendMenu(MF_BYPOSITION, ID_NONE, "你点了也白点,请在指定的地方点击"); int MenuID=Menu.TrackPopupMenu(TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,ppt->x, ppt->y, this); switch(MenuID) { case ID_RED: MessageBox("红色"); break; case ID_GREEN: MessageBox("红色"); break; case ID_BLUE: MessageBox("红色"); break; case ID_NONE: MessageBox("haha"); break; } oleWnd->Release(); pElem->Release(); return S_OK; } 共4页。 1 2 3 4 : 下载本文示例代码


利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展利用MFC实现浏览器的定制与扩展
阅读(175) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~