去掉討厭的異常警告
在程序中使用了CHtmlView以後,我們在調整窗口大小的時候經常會看到輸出窗口輸出的異常警告: ReusingBrowser.exe 中的 0x77e53887 處最可能的異常: Microsoft C++ exception: COleException @ 0x0012e348 。
Warning: constructing COleException, scode = DISP_E_MEMBERNOTFOUND($80020003).
這是由於CHtmlView在處理WM_SIZE消息時的一點小問題引起的,採用如下代碼處理WM_SIZE消息就不會有此警告了
void CLhpHtmlView::OnSize(UINT nType, int cx, int cy) { CFormView::OnSize(nType, cx, cy); if (::IsWindow(m_wndBrowser.m_hWnd)) { CRect rect; GetClientRect(rect); // 就這一句與CHtmlView的不同 ::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_EX_CLIENTEDGE); m_wndBrowser.SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER); } }
怎樣處理瀏覽器內的拖放
有時可能有這樣的需求,我們希望在資源管理器裏託一個文件到瀏覽器而做出相應的處理,甚至是將文件拖到某一個網頁元素上來做出相應的處理,而瀏覽器默認的處理拖放文件操作是將文件打開,但WebBrowser控件給了我們一個自己處理拖放的機會。 那就是在自定義的控制站點類中實現IDocHostUIHandler,在接口IDocHostUIHandler的GetDropTarget方法中調用 瀏覽器類的OnGetDropTarget虛函數。要處理網頁內的拖放,必需在OnGetDropTarget函數中返回一個自己定義的IDropTarget接口指針, 所以我們自己寫一個類CMyOleDropTarget從COleDropTarget類派生,並且在實現IDropTarget接口,此類的代碼在這就不列出了,請下載演示 程序,參考文件MyOleDropTarget.h和MyOleDropTarget.cpp。我們看CLhpHtmlView中OnGetDropTarget的代碼
HRESULT CLhpHtmlView::OnGetDropTarget(LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget ) { m_DropTarget.SetIEDropTarget(pDropTarget); LPDROPTARGET pMyDropTarget; pMyDropTarget = (LPDROPTARGET)m_DropTarget.GetInterface(&IID_IDropTarget); if(pMyDropTarget) { *ppDropTarget = pMyDropTarget; pMyDropTarget->AddRef(); return S_OK; } return S_FALSE; }
m_DropTarget即爲自定義的處理拖放的對象。這樣就能通過在從CLhpHtmlView派生的類中重載OnDragEnter、OnDragOver、 OnDrop、OnDragLeave虛函數來處理拖放了。在這裏順帶講一下視圖是怎樣處理拖放的。 要使視圖處理拖放,首先在視圖裏添加一個COleDropTarget(或派生類)成員變量,如CLhpHtmlView中的“CMyOleDropTarget m_DropTarget;”,再在 視圖創建時調用COleDropTarget對象的ReGISter,即把視圖與COleDropTarget對象關聯起來,如CLhpHtmlView中的“m_DropTarget.Register(this);”,再對拖放 觸發的事件進行相應的處理, OnDragEnter 把某對象拖入到視圖時觸發,在此檢測拖入的對象是不是視圖想接受的對象,如是返回“DROPEFFECT_MOVE”表示接受此對象,如
if(pDataObject->IsDataAvailable(CF_HDROP))// 被拖對象是文件嗎? return DROPEFFECT_MOVE;
OnDragOver 被拖對象在視圖上移動,同OnDragEnter一樣檢測拖入對象,如果要接受此對象返回“DROPEFFECT_MOVE”。 OnDrop 拖着被拖對象在視圖上放開鼠標,在這裏對拖入對象做出處理; OnDragLeave 拖着被拖對象離開視圖。 C++的代碼寫好了,但事情還沒完,還必須在網頁裏用腳本對拖放事件進行處理, 即頁面裏哪個元素要接受拖放對象哪個元素就要處理ondragenter、ondragover、ondrop,代碼其實很簡單,讓事件的返回值爲false即可,這樣 C++的代碼纔有機會處理拖放事件,代碼如下:
...... <td οndragenter="event.returnValue = false" οndragοver="event.returnValue = false" / οndrοp="event.returnValue = false"> ......
如果要使整個視圖都接受拖放,則在Body元素中處理此三個事件。 注意:別忘了讓工程對OLE的支持即在初始化應用程序時調用AfxOleInit()。
怎樣禁止網頁元素的選取
用網頁做界面時多數情況下是不希望網頁上的元素是能夠被鼠標選中的, 要使網頁元素不能被選中做法是:給瀏覽器的“宿主信息標記”加上DOCHOSTUIFLAG_DIALOG標記。
“宿主信息標記”用N個標記位來控制瀏覽器的許多性質,如:
- 禁用瀏覽器的3D的邊緣;
- 禁止滾動條;
- 禁用腳本;
- 定義雙擊處理的方式;
- 禁用瀏覽器的自動完成功能;
...... 更多詳情請參考MSDN的DOCHOSTUIFLAG幫助。
怎樣修改“宿主信息標記”?
在CDocHostSite中實現IDocHostUIHandler, 在GetHostInfo方法中調用瀏覽器的OnGetHostInfo虛函數,在虛函數OnGetHostInfo中便可指定“宿主信息標記”,如:
HRESULT CLhpHtmlView::OnGetHostInfo(DOCHOSTUIINFO * pInfo) { pInfo->cbSize = sizeof(DOCHOSTUIINFO); pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_THEME | DOCHOSTUIFLAG_NO3DBORDER | DOCHOSTUIFLAG_SCROLL_NO; pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; return S_OK; }
用腳本也可實現: 在Head中加入腳本:
document.onselectstart=new Function(’’return false’’);
或者
<body onselectstart="return false">。
其它
在CLhpHtmlView中還提供了幾個函數, 修改網頁元素的內容:
BOOL PutElementHtml(CString ElemID,CString Html);
取表單元素的值:
BOOL GetElementValue(CString ElemID,CString& Value);
設置表單元素的值:
BOOL PutElementValue(CString ElemID,CString Value);
給表單元素設置焦點:
void ElementSetFocus(CString EleName);