VC中禁用“指令碼錯誤除錯”視窗的解決方法
最近,忙於寫“抽取QQ相簿圖片URL”模組,沒有多大時間寫心得。早在曾同學給我下單的第二天,我就已經寫好了模組的一個初始版本,可是我的模組始終存在著三個問題:無法遮蔽“指令碼錯誤除錯”視窗、記憶體消耗太大、速度不快。速度不快,這是因為對於一個給定的QQ號,騰訊需要從資料庫裡面提取相關資料,然後再傳回到客戶端,網速如果不快,或者騰訊伺服器忙,必然會導致我的模組速度變慢。不過,通過設定瀏覽器的控制選項,禁止圖片、視訊、FLASH、控制元件的下載,可以比較明顯地提高速度。
速度的問題解決了,我就一直想解決“遮蔽‘指令碼錯誤除錯”對話方塊“這個問題。微軟的KB261003、KB317024兩篇文章提供了兩種解決方法。KB261003提供的方法是重寫IOleCommanTarget介面,並在IOleCommandTarget::Exec介面中處理OLECMDID_SHOWSCRIPTERROR事件,一般是直接返回S_OK。我寫的模組是一個基於對話方塊的MFC程式,在主對話方塊中嵌入WebBrowser控制元件。至今,我還不清楚,應該在哪個類裡面重寫這個介面,是在主對話方塊、還是WebBrowser控制元件對應的那個類呢?在我的程式裡面,我兩個類都重寫了,可是問題依然沒有解決。按照微軟官方的說法,有些機器可以接收到這個事件、有些機器不行。(我暈死,這是蝦米系統,爛)。但是MS也只說是IE5.5、IE6.0會存在這個問題,可是我的是IE7.0,依然還是沒有接收到這個事件。這個方法不行,還有另外一個方法,於是我按照KB317024中所說的方法,在主對話方塊的DocumentComplete事件中,注入錯誤處理指令碼。鬱悶的是,這種方法依然不能解決問題。至此,我對MS徹底失望,日死,什麼破作業系統。這個問題整整困擾了我三、四天。今天星期日,我還是在公司奮戰,就是為了解決這個問題。經過多次的心灰意冷,終於網上有個哥們說了一句,把“注入指令碼”的程式碼放在NavigateComplet事件中就可以了
(他的部落格是http://www.cnblogs.com/zhangqingping/archive/2009/06/16/1504260.html)。我立馬CTRL+C、CTRL+V,果然問題解決了。我愛死你了,哥們。
為了避免他人像我這樣受折磨,現將程式碼貼出:
void CQQAlbumDlg::NavigateComplete2Explorer1(LPDISPATCH pDisp, VARIANT* URL)
{
DisableDebug(pDisp); //禁用指令碼除錯
}
// 禁用除錯
void CQQAlbumDlg::DisableDebug(LPDISPATCH pDisp)
{
CComQIPtr < IWebBrowser2 > thisBrowser;
CComQIPtr < IDispatch > docDisp;
CComQIPtr < IHTMLDocument3 > doc;
CComQIPtr < IHTMLElement > elem;
HRESULT hr = S_OK;
hr = pDisp->QueryInterface(IID_IWebBrowser2, reinterpret_cast<void **>(&thisBrowser));
hr = thisBrowser->get_Document(&docDisp);
hr = docDisp->QueryInterface(IID_IHTMLDocument3, reinterpret_cast<void**>(&doc));
hr = doc->get_documentElement(&elem);
hr = elem->insertAdjacentHTML(L"afterBegin", L" <SCRIPT For=/"window/" Event=/"onerror/" defer=/"false/">var noOp = null;</SCRIPT>");
}
PS:由於我的WebBrowse控制元件的ID是IDC_EXPLORER1,因此NavigateComplete2函式名變成NavigateComplete2Explorer1,大家不要誤解,等會找不到這個函式過載。