在MFC應用中深入定製WebBrowser控制項(轉)

來源:互聯網
上載者:User
web|webbrowser控制項 正如VC ++ 6.0的示範程式MFCIE所示,用應用程式嚮導建立一個具有Web導航能力的MFC應用可謂輕而易舉。本文在此基礎上,進一步討論兩個問題:資源自包含的實現,操作功能表以及快速鍵的完全控制。
一、資源自包含及res協議

   所謂的資源自包含,指的是在最終產品中HTML文檔(包括相關資源如指令碼、圖片)成為執行檔案的一部分,就象其它資源(如應用程式圖示)一樣,而不是以獨立檔案形式分發。

   資源自包含不僅使產品分發更為方便,而且在終端使用者面前隱藏了更多的實現細節,具有一定的現實意義。

   MFC類CHtmlView不僅把WebBrowser控制項的所有功能(如導航,使用者介面配置等)重新整理成為C++方法和MFC事件映射,還提供了許多“原創”的功能。其中之一便是從包含它的應用程式中讀取Web頁面的能力。完成這個任務的主要方法為CHtmlView::LoadFromResource(),其原型如下:

 BOOL LoadFromResource( LPCTSTR lpszResource ); //用字串指定資源ID
 BOOL LoadFromResource( UINT nRes ); //用數字指定資源ID
   LoadFromResource()依賴於res://協議(IE在找不到URL指定的伺服器時,所顯示的錯誤提示頁面即使用res協議引出。)res協議的URL和常見的http或ftp協議所用URL格式不同,它的完整文法為:

 res://resource_file[/resource_type]/resource_id
   其中resource_file為包含目標資源的執行檔案名稱字。resource_type為資源類型,它可能用數字表示,也可能用字串表示。當資源為定製或不直接支援類型時用字串指出資源類型(如GIF,JPEG等,可在.RC檔案中定義);當資源為已知類型時該值往往用數字表示(如位元影像為2,HTML為23)。已知資源類型的完整列表可以參見winuser.h,它是一組RT_常量。

   CHtmlView::LoadFromResource()總是假定目標資源所在的執行檔案為當前模組。但在實際應用中,我們往往要把資源分類放在不同檔案中。為解決此問題,可以定義一個衍生類別CHtmlViewEx覆蓋此方法,只需要對原方法略作修改引入模組參數即可:

 『清單1』
 BOOL CHtmlViewEx::LoadFromResource(LPCTSTR lpszModule, LPCTSTR lpszResource)
 {
   CString strResourceURL;
   strResourceURL.Format(_T("res://%s/%s"), lpszModule, lpszResource);
   Navigate(strResourceURL, 0, 0, 0);
   return TRUE;
 }
   二、操作功能表和快速鍵控制

   在實際應用中,為了避免使用者查看頁面源檔案或防止使用者用快速鍵開啟當前頁面的另外一個視窗,我們往往要對由WebBrowser控制項提供的操作功能表(在頁面上按滑鼠右鍵)或快速鍵(如Ctrl+N開啟新視窗)加以定製。

   無論是WebBrowser控制項還是CHtmlView類都沒有直接提供定製上述操作的方法,因而必須通過實現IDocHostUIHandler介面來完成。在該介面中,可以實現操作功能表和快速鍵控制的方法分別為ShowContextMenu()和TranslateAccelerator()。

   由於使用MFC封裝類CHtmlView比直接應用WebBrowser控制項更為方便,因而可以考慮把定製之後的介面支援功能整合到MFC架構內。具體實現的基本思路如下:

建立一個新的OLE客戶站並在其中實現介面IDocUIHandler
在InitInstance()中用一個新的管理類取代預設配置以引入該客戶站
   基於以上思路,我們可以從COleControlSite建立衍生類別CCustomWebBrowserSite,並在衍生類別中實現IDocHostUIHandler。COleControlSite在VC++的mfcsrcoccimpl.h中定義,用於封裝控制項客戶站。新的客戶站定義為:

 『清單2』
 class CCustomWebBrowserSite : public COleControlSite
 {
 public:
   CCustomWebBrowserSite(COleControlContainer *pCnt):   
      COleControlSite(pCnt){}
 protected:
 DECLARE_INTERFACE_MAP();
 BEGIN_INTERFACE_PART(DocHostUIHandler, IDocHostUIHandler)
   STDMETHODIMP ShowContextMenu(DWORD, POINT*, IUnknown*, IDispatch*);
   STDMETHODIMP TranslateAccelerator(LPMSG, const GUID*, DWORD);
   STDMETHODIMP GetHostInfo(DOCHOSTUIINFO);
   STDMETHODIMP EnableModeless(BOOL);
   STDMETHODIMP OnDocWindowActivate(BOOL);
   STDMETHODIMP OnFrameWindowActivate(BOOL);
   STDMETHODIMP ResizeBorder(LPCRECT, IOleInPlaceUIWindow*, BOOL);
   STDMETHODIMP GetOptionKeyPath(LPOLESTR*, DWORD);
   STDMETHODIMP GetDropTarget(IDropTarget*, IDropTarget**);
   STDMETHODIMP GetExternal(IDispatch**);
   STDMETHODIMP TranslateUrl(DWORD, OLECHAR*, OLECHAR**);
   STDMETHODIMP FilterDataObject(IDataObject*, IDataObject**);
   STDMETHODIMP ShowUI(DWORD, IOleInPlaceActiveObject*,
       IOleCommandTarget*, IOleInPlaceFrame*, IOleInPlaceUIWindow*);
   STDMETHODIMP HideUI(void);
   STDMETHODIMP UpdateUI(void);
 END_INTERFACE_PART(DocHostUIHandler)
 };
   如上所介紹,在這個介面中我們感興趣的方法主要有ShowContextMenu()和TranslateAccelerator()兩個。以完全禁止操作功能表顯示為例,在衍生類別CCustomWebBrowserSite中ShowContextMenu()的實現代碼為:

 『清單3』
 STDMETHODIMP CCustomWebBrowserSite::XDocHostUIHandler::ShowContextMenu(
     DWORD, POINT*, IUnknown*, IDispatch*)
 {
     METHOD_PROLOGUE(CCustomWebBrowserSite, DocHostUIHandler)
      return S_OK; // 禁止菜單顯示
 }
   用類似的方法可以關閉由控制項直接響應的快速鍵:

 『清單4』
 STDMETHODIMP CustomWebBrowserSite::XDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg,const GUID __RPC_FAR *pguidCmdGroup, DWORD nCmdID)
 {
     METHOD_PROLOGUE(CCustomWebBrowserSite, DocHostUIHandler)
         return S_OK;  // 關閉快速鍵
 }
   在IDocHostUIHandler介面實現之後,我們還需要一個管理類CCustomOccManager來支援CCustomWebBrowserSite,新的管理類CCustomOccManager從COccManager派生,COccManager也在mfcsrcoccimpl.h中定義:

 『清單5』
 class CCustomOccManager : public COccManager
 {
 public:
   CCustomOccManager() {}
   COleControlSite* CreateSite(COleControlContainer* pCC)
 



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。