IE里的探索之定制瀏覽器好助手(中) (作者:青蘋果工作室編譯 2001年02月08日 14:00)
檢測調用者 像前面提到的,如果你運行的外殼版本不低于471,BHO 就既能被Internet Explorer又能被Windows Explorer引用。在這個例子里,我們要是涉及一個專對 HTML 頁面起作用的助手對象,所以它應該對 Windows Explorer 不起任何作用。一個不想被特定的調用者加載的 DLL 可以在它發(fā)現(xiàn)誰是調用者后,簡單地在它的 DllMain() 函數(shù)中返回 False。當你將 NULL 作為 API 函數(shù) GetModuleFileName() 的第一個參數(shù)調用它時,它返回調用 DLL 的模塊名。這個參數(shù)是你想知道名字的模塊的句柄。NULL 表示你想知道調用 DLL 的進程的名字。
if (dwReason == DLL_PROCESS_ATTACH)
{
TCHAR pszLoader[MAX_PATH];
GetModuleFileName(NULL, pszLoader, MAX_PATH);
_tcslwr(pszLoader);
if (_tcsstr(pszLoader, _T("explorer.exe")))
return FALSE;
}
你知道了進程的名字,你就能在它是 Windows Explorer 時退出加載過程。注意采取更嚴格的淘汰是很危險的。實際上,其它進程可能視為一個正常的原因調用它但被拒絕。第一個受害者是 regsvr32.exe,這個程序用來自動注冊對象。如果 你是用不同的測試條件,比如說,只允許 Internet Explorer 可以執(zhí)行:
if (!_tcsstr(pszLoader, _T("iexplore.exe")))
你就不能注冊 DLL 了。實際上,當 regsvr32.exe 試圖加載 DLL 以調用DllRegisterServer() 函數(shù)時,調用被拒絕。
同 WebBrowser 建立聯(lián)系 SetSite() 方法是 BHO 進行初始化以及所有只進行一次任務的地方。當你用 Internet Explorer 瀏覽 URL 時,你需要等待一對事件以確保所需的文檔被完全下載并被初始化。只有在這一位置上你能通過可能存在的對象模型安全地訪問它的 內(nèi)容。這表示你需要獲得一對指針。第一個是指向 IWebBrowser2 的,它是處理 WebBrowser 對象的接口。第二個指針和事件有關。這個模塊必須注冊為瀏覽器的事件監(jiān)聽者,以便能夠接收關于下載和文檔相關事件的通知。通過使用 ATL 的靈巧指針:
CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> m_spWebBrowser2;
CComQIPtr<IConnectionPointContainer,
&IID_IConnectionPointContainer> m_spCPC;
源代碼類似于:
HRESULT CViewSource::SetSite(IUnknown *pUnkSite)
{
// 獲得并保存 IWebBrowser2 指針
m_spWebBrowser2 = pUnkSite;
if (m_spWebBrowser2 == NULL)
return E_INVALIDARG;
// 獲得并保存 IConnectionPointerContainer 指針
m_spCPC = m_spWebBrowser2;
if (m_spCPC == NULL)
return E_POINTER;
// 獲得并保存瀏覽器的 HWND。另外為以后的使用安裝鍵盤掛鉤。
RetrieveBrowserWindow();
// 連接到容器以接受事件通知
return Connect();
}
要獲得指向 IWebBrowser2 接口的指針,你只需要簡單地查詢。對事件處理的第一個步驟,獲得 IConnectionPointContainer 的指針,也用同樣的辦法。SetSite() 的代碼也查詢?yōu)g覽器的 HWND 并在當前線程上安裝鍵盤掛鉤。HWND 以后會被用以移動 Internet Explorer 窗口并改變它的尺寸。那個掛鉤,被用以提供一個熱鍵,以方便用戶顯示或隱藏 HTML 代碼窗口。
|