---- 但是在實際編程過程中,我發現這個控件提供的功能有很多限制,比如對HTML文檔的瀏覽,只能通過指定URL或文件名來實現,不能像以往使用THTML控件那樣直接讀寫HTML源碼。因此如果程序動態生成了一段HTML文本,就必須把文本內容先寫到一個臨時文件,然後再將此文件的文件名傳遞給WebBrowser控件,實現顯示。走這一個彎路使程序響應速度受到很大影響,而且容易遺留下一些"垃圾"(臨時文件)。 ---- 在考察了一些使用了WebBrowser控件的程序後,我發現大部分程序,如著名國產軟件FoxMail,都是使用的通過臨時文件傳遞HTML文檔的方法;但一些國外的軟件,如MS自己的OutLook Express則不存在這個問題,而因爲其無需產生臨時文件,因此對HTML文檔的顯示速度明顯超過Foxmail。 ---- 爲此,我查閱了一些相關資料,最後在網友的幫助下找到了實現直接訪問WebBrowser控件中的HTML源碼的方法。在此要特別感謝白雲黃鶴BBS(bbs.whnet.edu.cn)上的網友AngleFalls提供線索。 ---- 其實,WebBrowser控件中的Document對象,這個對象提供了一個IPersistStreamInit接口,通過此接口,我們可以方便地實現對HTML源碼的讀寫。 ---- 以下是IPersistStreamInit接口的相關定義及說明: { IPersistStream interface } {$EXTERNALSYM IPersistStream} { IPersistStreamInit interface } {$EXTERNALSYM IPersistStreamInit} 首先來實現寫,因爲這是最迫切的要求: hHTMLText := GlobalAlloc(GPTR, Length(Html) + 1); CopyMemory(Pointer(hHTMLText), OleCheck(CreateStreamOnHGlobal ---- 首先,此過程需要的兩個參數,WebBrowser是顯示目的控件,Html是需要顯示的HTML源碼;然後,先檢查WebBrowser.Document對象是否有效,無效則退出;接着在系統全局堆裏分配一塊內存,將需要顯示的HTML源碼複製進去。這是因爲下一步需要建立一個WebBrowser控件可以讀取的流。GlobalAlloc函數的參數GPTR表示需要分配一塊固定的以0初始化過的內存區域,如果分配失敗則返回0,則通過RaiseLastWin32Error函數引發一個異常,提示用戶;然後用CreateStreamOnHGlobal函數建立一個基於全局堆內存塊的流,第二個參數如果爲True則流在釋放時自動釋放所佔全局堆內存。如果建立成功則此流和剛剛建立的內存塊共用同一塊內存區域。接着用WebBrowser.Document.QueryInterface函數建立一個IPersistStreamInit接口。然後就可以直接使用此接口,psi.InitNew初始化狀態;psi.Load(Stream)從流中載入HTML源碼。 ---- 值得注意的是,每個關於COM接口的函數調用,也就是那些返回類型爲HResult的函數,都必須以OleCheck包裝,因爲一個不檢查返回狀態的COM接口操作實在太危險了;此外接口的釋放,雖然Delphi可以在後臺自動完成,但作爲一個好的編程習慣,還是應該顯式地手工釋放,釋放只需將接口設爲nil即可。 ---- 接着來實現HTML源碼的讀: function GetHtml(const WebBrowser: OleCheck(WebBrowser.Document.QueryInterface OleCheck(CreateStreamOnHGlobal(hHTMLText, Size := StrLen(PChar(hHTMLText)); ---- 此函數有一個參數WebBrowser指定從那個控件讀取HTML源碼,返回一個字符串爲此控件中的HTML源碼。首先還是要先檢查WebBrowser.Document對象是否有效,無效則退出;然後取得IPersistStreamInit接口;接着取得HTML源碼的大小:本來應該使用IPersistStreamInit接口的GetSizeMax函數,但在我的機器上測試,這個函數範圍值衡爲0,無效。因此只能先定義一個足夠大的緩衝區,如BufSize = $10000字節(注意此緩衝區應該足夠大);然後同樣地分配全局堆內存塊,建立流,然後將HTML文本寫到流中。因爲此HTML文本在流中是以#0結尾的字符串,因此可以用Size := StrLen(PChar(hHTMLText))取得實際長度,用SetLength(Result, Size);設置返回字符串長度爲HTML源碼實際長度,最後複製字符串到返回字符串中。 ---- 不過需要注意的時,在使用這兩個函數前,最好對WebBrowser.Document對象進行初始化。下面提供一個函數,通過顯示一個空白頁面實現WebBrowser.Document對象初始化。 procedure ShowBlankPage(WebBrowser: ---- 建議在你有WebBrowser控件的Form的FormCreate事件裏調用此函數,初始化WebBrowser.Document對象。 |
直接訪問WebBrowser控件中的HTML源碼
直接訪問WebBrowser控件中的HTML源碼
2008-02-26 15:59
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.