国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > HTML > 正文

直接訪問WebBrowser控件中的HTML源碼

2020-03-24 16:06:45
字體:
來源:轉載
供稿:網友
為了實現在自己的程序中顯示HTML文檔,我們一般采用IE(Internet Explorer本文中簡稱為IE)發行時附帶的一個ActiveX控件WebBrowser。這個控件使用和IE相同的內核,功能強大,并從Delphi5開始,正式得到Inprise公司的支持,取代了原來的那個THTML控件,成為Delphi中顯示HTML文檔的首選控件。

但是在實際編程過程中,這個控件提供的功能有很多限制,比如對HTML文檔的瀏覽,只能通過指定URL或文件名來實現,不能像以往使用THTML控件那樣直接讀寫HTML源碼。因此如果程序動態生成了一段HTML文本,就必須把文本內容先寫到一個臨時文件,然后再將此文件的文件名傳遞給WebBrowser控件,實現顯示。走這一個彎路使程序響應速度受到很大影響,而且容易遺留下一些 垃圾 (臨時文件)。

在考察了一些使用了WebBrowser控件的程序后,發現大部分程序,如著名國產軟件FoxMail,都是使用的通過臨時文件傳遞HTML文檔的方法;但一些國外的軟件,如MS自己的OutLook Express則不存在這個問題,而因為其無需產生臨時文件,因此對HTML文檔的顯示速度明顯超過Foxmail。

其實,WebBrowser控件中的Document對象,這個對象提供了一個IPersistStreamInit接口,通過此接口,我們可以方便地實現對HTML源碼的讀寫。

以下是IPersistStreamInit接口的相關定義及說明:


{IPersistStreaminterface}

{$EXTERNALSYMIPersistStream}
IPersistStream=interface(IPersist)
['{00000109-0000-0000-C000-000000000046}']
functionIsDirty:HResult;stdcall;
//最后一次存盤后是否被修改
functionLoad(conststm:IStream):HResult;stdcall;
//從流中載入
functionSave(conststm:IStream;
fClearDirty:BOOL):HResult;stdcall;
//保存到流
functionGetSizeMax(outcbSize:Largeint):
HResult;stdcall;//取得保存所需空間大小
end;

{IPersistStreamInitinterface}

{$EXTERNALSYMIPersistStreamInit}
IPersistStreamInit=interface(IPersistStream)
['{7FD52380-4E07-101B-AE2D-08002B2EC713}']
functionInitNew:HResult;stdcall;//初始化
end;
procedureSetHtml(constWebBrowser:
TWebBrowser;constHtml:string);
var
Stream:IStream;
hHTMLText:HGLOBAL;
psi:IPersistStreamInit;
begin
ifnotAssigned(WebBrowser.Document)thenExit;

hHTMLText:=GlobalAlloc(GPTR,Length(Html)+1);
if0=hHTMLTextthenRaiseLastWin32Error;

CopyMemory(Pointer(hHTMLText),
PChar(Html),Length(Html));

OleCheck(CreateStreamOnHGlobal
(hHTMLText,True,Stream));
try
OleCheck(WebBrowser.Document.
QueryInterface(IPersistStreamInit,psi));
try
OleCheck(psi.InitNew);
OleCheck(psi.Load(Stream));
finally
psi:=nil;
end;
finally
Stream:=nil;
end;
end;

首先,此過程需要的兩個參數,WebBrowser是顯示目的控件,Html是需要顯示的HTML源碼;

然后,先檢查WebBrowser.Document對象是否有效,無效則退出;

接著在系統全局堆里分配一塊內存,將需要顯示的HTML源碼復制進去。

這是因為下一步需要建立一個WebBrowser控件可以讀取的流。GlobalAlloc函數的參數GPTR表示需要分配一塊固定的以0初始化過的內存區域,如果分配失敗則返回0,則通過RaiseLastWin32Error函數引發一個異常,提示用戶;然后用CreateStreamOnHGlobal函數建立一個基于全局堆內存塊的流,第二個參數如果為True則流在釋放時自動釋放所占全局堆內存。如果建立成功則此流和剛剛建立的內存塊共用同一塊內存區域。接著用WebBrowser.Document.QueryInterface函數建立一個IPersistStreamInit接口。然后就可以直接使用此接口,psi.InitNew初始化狀態;psi.Load(Stream)從流中載入HTML源碼。

至此,以Html參數指定的HTML源碼就在WebBrowser參數指定的控件中顯示出來。

值得注意的是,每個關于COM接口的函數調用,也就是那些返回類型為HResult的函數,都必須以OleCheck包裝,因為一個不檢查返回狀態的COM接口操作實在太危險了;此外接口的釋放,雖然Delphi可以在后臺自動完成,但作為一個好的編程習慣,還是應該顯式地手工釋放,釋放只需將接口設為nil即可。

接著來實現HTML源碼的讀:


functionGetHtml(constWebBrowser:
TWebBrowser):string;
const
BufSize=$10000;
var
Size:Int64;
Stream:IStream;
hHTMLText:HGLOBAL;
psi:IPersistStreamInit;
begin
ifnotAssigned(WebBrowser.Document)thenExit;

OleCheck(WebBrowser.Document.QueryInterface
(IPersistStreamInit,psi));
try
//OleCheck(psi.GetSizeMax(Size));
hHTMLText:=GlobalAlloc(GPTR,BufSize);
if0=hHTMLTextthenRaiseLastWin32Error;

OleCheck(CreateStreamOnHGlobal(hHTMLText,
True,Stream));
try
OleCheck(psi.Save(Stream,False));

Size:=StrLen(PChar(hHTMLText));
SetLength(Result,Size);
CopyMemory(PChar(Result),Pointer(hHTMLText),
Size);
finally
Stream:=nil;
end;
finally
psi:=nil;
end;
end;

此函數有一個參數WebBrowser指定從那個控件讀取HTML源碼,返回一個字符串為此控件中的HTML源碼。首先還是要先檢查WebBrowser.Document對象是否有效,無效則退出;然后取得IPersistStreamInit接口;接著取得HTML源碼的大小:本來應該使用IPersistStreamInit接口的GetSizeMax函數,但在我的機器上測試,這個函數范圍值衡為0,無效。因此只能先定義一個足夠大的緩沖區,如BufSize = $10000字節(注意此緩沖區應該足夠大);然后同樣地分配全局堆內存塊,建立流,然后將HTML文本寫到流中。因為此HTML文本在流中是以#0結尾的字符串,因此可以用Size := StrLen(PChar(hHTMLText))取得實際長度,用SetLength(Result, Size);設置返回字符串長度為HTML源碼實際長度,最后復制字符串到返回字符串中。

至此,直接訪問WebBrowser控件中的HTML源碼所需的兩個函數全部解析完畢。

不過需要注意的時,在使用這兩個函數前,最好對WebBrowser.Document對象進行初始化。下面提供一個函數,通過顯示一個空白頁面實現WebBrowser.Document對象初始化。


procedureShowBlankPage(WebBrowser:
TWebBrowser);
var
URL:OleVariant;
begin
URL:='about:blank';
WebBrowser.Navigate2(URL);
end;

建議在有WebBrowser控件的Form的FormCreate事件里調用此函數,初始化WebBrowser.Document對象。本文程序在Win NT + Delphi 5 環境下調試通過。更多編程語言

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 南靖县| 四平市| 青龙| 陈巴尔虎旗| 灵石县| 罗定市| 曲阜市| 灌云县| 长泰县| 娱乐| 旅游| 巴南区| 晋宁县| 长泰县| 湘西| 竹溪县| 邯郸市| 龙江县| 扶绥县| 达拉特旗| 潼南县| 侯马市| 丹棱县| 沧州市| 金乡县| 分宜县| 榆林市| 宁晋县| 磐石市| 如东县| 宣武区| 曲水县| 尼玛县| 济南市| 汾西县| 铜梁县| 吴忠市| 龙岩市| 莱西市| 揭西县| 元江|