近些天在duilib羣裏常常有朋友問起,怎麼讓duilib的IE控件能夠去邊框,去滾動條的問題,或者是如何去控件IE控件的行爲。爲了不重複的回答,我就寫一篇博文,把處理方法說明一下。c++
duilib中有Webbrowser控件,是繼承ActivexUI控件後針對IE進行的封裝,使用IE控件的話就用他了。這個控件留了一個接口名爲SetWebBrowserEventHandler,這個函數用了指定一個事件處理器,來控制IE的行爲。而這個函數須要一個CWebBrowserEventHandler對象指針,這個CWebBrowserEventHandler類在duilib的Utils目錄中已經寫好了,是一個基本的事件處理器框架,只要重寫這個CWebBrowserEventHandler類的GetHostInfo函數就能夠控制去掉IE瀏覽器的邊框和滾動條,同時還有其餘功能,好比控制是否能夠顯示IE右鍵菜單,NavigateComplete2來截獲瀏覽器加載完畢的事件等等。瀏覽器
因此咱們若是要去控制瀏覽器,那麼正確的作法就是寫一個類,繼承CWebBrowserEventHandler而後重寫你須要的函數。我簡單寫了一個名叫CCustomWebEventHandler,代碼以下:框架
#ifndef _CCUSTOM_WEBBROWSER_EVENT_HANDLER_H_ #define _CCUSTOM_WEBBROWSER_EVENT_HANDLER_H_ #pragma once class CCustomWebEventHandler:public CWebBrowserEventHandler { public: CCustomWebEventHandler() {} ~CCustomWebEventHandler() {} virtual void BeforeNavigate2( IDispatch *pDisp,VARIANT *&url,VARIANT *&Flags,VARIANT *&TargetFrameName,VARIANT *&PostData,VARIANT *&Headers,VARIANT_BOOL *&Cancel ) {} virtual void NavigateError(IDispatch *pDisp,VARIANT * &url,VARIANT *&TargetFrameName,VARIANT *&StatusCode,VARIANT_BOOL *&Cancel) {} virtual void NavigateComplete2(IDispatch *pDisp,VARIANT *&url){ } virtual void ProgressChange(LONG nProgress, LONG nProgressMax){} virtual void NewWindow3(IDispatch **pDisp, VARIANT_BOOL *&Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl){} virtual void CommandStateChange(long Command,VARIANT_BOOL Enable){} // interface IDocHostUIHandler virtual HRESULT STDMETHODCALLTYPE ShowContextMenu( /* [in] */ DWORD dwID, /* [in] */ POINT __RPC_FAR *ppt, /* [in] */ IUnknown __RPC_FAR *pcmdtReserved, /* [in] */ IDispatch __RPC_FAR *pdispReserved) { return S_OK; //return S_FALSE } virtual HRESULT STDMETHODCALLTYPE GetHostInfo( /* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo) { if (pInfo != NULL) { pInfo->cbSize = sizeof(DOCHOSTUIINFO); pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; pInfo->dwFlags |= DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_NO3DOUTERBORDER | DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_DISABLE_HELP_MENU;//| DOCHOSTUIFLAG_SCROLL_NO;; //這裏還能夠加其餘代碼來控制網頁 //LPWSTR m_pZoom = L"BODY{Zoom:100%;}"; //pInfo->pchHostCss = (LPWSTR)::CoTaskMemAlloc((lstrlenW(m_pZoom)+1)*2); //lstrcpyW(pInfo->pchHostCss, m_pZoom); } return S_OK; } virtual HRESULT STDMETHODCALLTYPE ShowUI( /* [in] */ DWORD dwID, /* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject, /* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget, /* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc) { return S_FALSE; } virtual HRESULT STDMETHODCALLTYPE HideUI( void) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE UpdateUI( void) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE EnableModeless( /* [in] */ BOOL fEnable) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate( /* [in] */ BOOL fActivate) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate( /* [in] */ BOOL fActivate) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE ResizeBorder( /* [in] */ LPCRECT prcBorder, /* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow, /* [in] */ BOOL fRameWindow) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( /* [in] */ LPMSG lpMsg, /* [in] */ const GUID __RPC_FAR *pguidCmdGroup, /* [in] */ DWORD nCmdID) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath( /* [out] */ LPOLESTR __RPC_FAR *pchKey, /* [in] */ DWORD dw) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE GetDropTarget( /* [in] */ IDropTarget __RPC_FAR *pDropTarget, /* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE GetExternal( /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE TranslateUrl( /* [in] */ DWORD dwTranslate, /* [in] */ OLECHAR __RPC_FAR *pchURLIn, /* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut) { return S_OK; } virtual HRESULT STDMETHODCALLTYPE FilterDataObject( /* [in] */ IDataObject __RPC_FAR *pDO, /* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet) { return S_OK; } // virtual HRESULT STDMETHODCALLTYPE GetOverrideKeyPath( // /* [annotation][out] */ // __deref_out LPOLESTR *pchKey, // /* [in] */ DWORD dw) // { // return E_NOTIMPL; // } // IDownloadManager virtual HRESULT STDMETHODCALLTYPE Download( /* [in] */ IMoniker *pmk, /* [in] */ IBindCtx *pbc, /* [in] */ DWORD dwBindVerb, /* [in] */ LONG grfBINDF, /* [in] */ BINDINFO *pBindInfo, /* [in] */ LPCOLESTR pszHeaders, /* [in] */ LPCOLESTR pszRedir, /* [in] */ UINT uiCP) { return S_OK; } }; #endif //_CCUSTOM_WEBBROWSER_EVENT_HANDLER_H_
使用他的方法以下:less
首先在xml中寫入一個Webbrowser控件而且在c++代碼中經過FindControl找到這個控件的指針,而後寫相似的代碼:ide
CWebBrowserUI* pActiveXUI = static_cast<CWebBrowserUI*>(m_PaintManager.FindControl(_T("ActiveXDemo1"))); if( pActiveXUI ) { pActiveXUI->SetDelayCreate(false); CCustomWebEventHandler *pWebHandle = new CCustomWebEventHandler; pActiveXUI->SetWebBrowserEventHandler(pWebHandle); pActiveXUI->Navigate2(L"about:blank"); //這行代碼,若是註釋掉,就不會去掉邊框,IE有bug,第二次加載網頁纔會讓事件處理器有效 pActiveXUI->Navigate2(L"http://www.kugou.com/"); }
我這裏強調兩點函數
第1、我這裏只是示範,爲了方便,我使用的是alberl的demo,簡單改了幾行代碼。能夠看到我new了一個CCustomWebEventHandler,可是沒有去delete,因此本身使用時千萬要注意代碼規範!!ui
第2、先加載了一個blank頁面,再跳轉到目標頁面,第一次加載頁面不會觸發事件處理器,第二次纔會,爲了避免影響效率我直接加載blank。關於這個bug的說明,在微軟官網有,具體地址我忘了~~url