直接訪問WebBrowser控件中的HTML源碼 (收藏)

發表于:2007-07-01來源:作者:點擊數: 標簽:
直接訪問WebBrowser控件中的HTML源碼 作者: 評價: 上站日期: 2002-05-22 內容說明: 來源: -------------------------------------------------------------------------------- html webbrowser.OleObject.document.documentelement.innerhtml; Text web

直接訪問WebBrowser控件中的HTML源碼
作者:  評價:  上站日期: 2002-05-22 
內容說明: 
來源: 

--------------------------------------------------------------------------------

html
webbrowser.OleObject.document.documentelement.innerhtml;
Text
webbrowser.OleObject.document.documentelement.innerText;
********************
為了實現在自己的程序中顯示HTML文檔,我們一般采用IE(Inte.net Explorer本文中簡稱為IE)發行時附帶的一個ActiveX控件TWebBrowser。

這個控件使用和IE相同的內核,功能強大,并從Delphi5開始,正式得到Inprise公司的支持,取代了原來的那個THTML控件,成為Delphi中顯

示HTML文檔的首選控件。
但是在實際編程過程中,我發現這個控件提供的功能有很多限制,比如對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}
                      IPersistStream = interface(IPersist)
                      [´{00000109-0000-0000-C000-000000000046}´]
                      function IsDirty: HResult; stdcall;   
                      // 最后一次存盤后是否被修改
                      function Load(const stm: IStream): HResult; stdcall;
                      // 從流中載入
                      function Save(const stm: IStream;
                      fClearDirty: BOOL): HResult; stdcall;
                      // 保存到流
                      function GetSizeMax(out cbSize: Largeint):
                      HResult; stdcall; // 取得保存所需空間大小
                      end;

                      { IPersistStreamInit interface }

                      {$EXTERNALSYM IPersistStreamInit}
                      IPersistStreamInit = interface(IPersistStream)

                      [´{7FD52380-4E07-101B-AE2D-08002B2EC713}´]
                      function InitNew: HResult; stdcall; // 初始化
                      end;

                      首先來實現寫,因為這是最迫切的要求:
                      procedure SetHtml(const WebBrowser:
                      TWebBrowser; const Html: string);
                      var
                      Stream: IStream;
                      hHTMLText: HGLOBAL;
                      psi: IPersistStreamInit;
                      begin
                      if not Assigned(WebBrowser.Document) then Exit;


                      hHTMLText := GlobalAlloc(GPTR, Length(Html) + 1);
                      if 0 = hHTMLText then RaiseLastWin32Error;

                      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函數引發一個異常,提示用戶;然后用CreateStreamOn
HGlobal函數建立一個基于全局堆內存塊的流,第二個參數如果為True則流在釋放時自動釋放所占全局堆內存。如果 建立成功則此流和剛剛建

立的內存塊共用同一塊內存區域。接著用WebBrowser.Document.QueryInterface函數建立一個IPersistStreamInit接口。然后              

       就可以直接使用此接口,psi.InitNew初始化狀態;psi.Load(Stream)從流中載入HTML源碼。
---- 至此,以Html參數指定的HTML源碼就在WebBrowser參數指定的控件中顯示出來。
---- 值得注意的是,每個關于COM接口的函數調用,也就是那些返回類型為HResult的函數,都必須以OleCheck包裝,因為一個不檢查返回狀

態的COM接口操作實在太危險了;此外接口的釋放,雖然Delphi可以在后臺自動完成,但作為一個好的編程習慣,還是應該顯式地手工釋放,

釋放只需將接口設為nil即可。
---- 接著來實現HTML源碼的讀:
function GetHtml(const WebBrowser: TWebBrowser): string;
const
  BufSize = $10000;
var
  Size: Int64;
  Stream: IStream;
  hHTMLText: HGLOBAL;
  psi: IPersistStreamInit;
begin
  if not Assigned(WebBrowser.Document) then Exit;
  OleCheck(WebBrowser.Document.QueryInterface (IPersistStreamInit, psi));
  try
  //OleCheck(psi.GetSizeMax(Size));
  hHTMLText := GlobalAlloc(GPTR, BufSize);
  if 0 = hHTMLText then RaiseLastWin32Error;
  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源碼的大?。罕緛響撌褂?/P>

IPersistStreamInit接口的GetSizeMax函數,但在我的機器上測試,這個函數范圍值衡為0,無效。因此只能先定義一個足夠大的緩沖區,如

BufSize = $10000字節(注意此緩沖區應該足夠大);然后同樣地分配全局堆內存塊,建立流,然后將HTML文本寫到流中。因為此HTML文本在流

中是以#0結尾的字符串,因此可以用Size := StrLen(PChar(hHTMLText))取得實際長度,用SetLength(Result, Size);設置返回字符串長度為

HTML源碼實際長度,最后復制字符串到返回字符串中。
---- 至此,直接訪問WebBrowser控件中的HTML源碼所需的兩個函數全部解析完畢。
---- 不過需要注意的時,在使用這兩個函數前,最好對WebBrowser.Document對象進行初始化。下面提供一個函數,通過顯示一個空白頁面實

現WebBrowser.Document對象 初始化。
procedure ShowBlankPage(WebBrowser: TWebBrowser);
var
URL: OleVariant;
begin
URL := ´about:blank´;
WebBrowser.Navigate2(URL);
end;
---- 建議在你有WebBrowser控件的Form的FormCreate事
件里調用此函數,初始化
WebBrowser.Document對象。
---- 本文程序在Win NT + Delphi 5 環境下調試通過 
 
 WebBrowser類和WebBrowser_V1類的區別

 

編號:QA002749
建立日期: 2000年3月20日 最后修改日期:2000年3月20日
所屬類別:

Visual Basic - Web瀏覽器

 xyjun:
    操作系統: win98
    編程工具: VB6.0
    問題: 請問在vb對象瀏覽器中的WebBrowser類和WebBrowser_V1類的區別。
    我在窗體中插入了一個WebBrowser控件,但是只有newWindow2事件,而沒有newWindow事件,請問如何用newwindow事件將網頁上打開的新

網頁在同一窗口顯示(禁止開新窗口)?以及事件newWindow2與newWindow的區別?

回答:

    WebBrowser_V1是IE3的類,而IE4以后版本使用WebBrowser類。
    如果你希望新打開的網頁出現在同一個窗口,可以這樣做:
    Private Sub WebBrowser1_NewWindow2(ppDisp As Object, Cancel As Boolean)
     Set ppDisp = WebBrowser1.Object
    End Sub
    事件NewWindow2與newWindow的區別有較大區別,使用事件NewWindow你可以知道點擊的鏈接是什么,而使用事件NewWindow2無法知道。而

NewWindow只有在用戶選擇“在新窗口打開鏈接”時才會激發,而NewWindow2除了在此時激發外,當網頁使用window.open打開新窗口時也激發

。上面的工作也可以使用NewWindow實現:
    Dim WithEvents Web_V1 As SHDocVwCtl.WebBrowser_V1
    
    Private Sub Form_Load()
     Set Web_V1 = WebBrowser1.Object
     WebBrowser1.Navigate2 ""
    End Sub
    
    Private Sub Web_V1_NewWindow(ByVal URL As String, _
     ByVal Flags As Long, _
     ByVal TargetFrameName As String, _
     PostData As Variant, _
     ByVal Headers As String, _
     Processed As Boolean)
     Processed = True
     WebBrowser1.Navigate URL
    End Sub

 


原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97