Delphi 的 TWebBrowser 封裝了 Microsoft WebBrowser ActiveX 控件(SHDocVw.dll),提供了在 Win32 應用中嵌入 IE 引擎的能力。配合 MSHTML.pas(MSHTML 類型庫導入單元),你可以獲得完整的代碼提示、類型檢查與早期綁定優勢,像寫 JavaScript 一樣操作 DOM,極大提升開發效率。
TWebBrowser(自動引用 SHDocVw、OleCtrls)。uses 子句添加 MSHTML。FWindow: IHTMLWindow2;unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, OleCtrls, SHDocVw, StdCtrls, MSHTML;
type
TForm1 = class(TForm)
WebBrowser1: TWebBrowser;
btnOpen: TButton;
btnModify: TButton;
procedure FormCreate(Sender: TObject);
procedure btnOpenClick(Sender: TObject);
procedure btnModifyClick(Sender: TObject);
procedure WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
private
FWindow: IHTMLWindow2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Self.Position := poScreenCenter;
WebBrowser1.Align := alClient;
btnOpen.Caption := '打開頁面';
btnModify.Caption := '修改內容';
btnModify.Enabled := False;
end;
procedure TForm1.btnOpenClick(Sender: TObject);
begin
WebBrowser1.Navigate('https://www.example.com');
btnModify.Enabled := False; // 重新導航時禁用,待 DocumentComplete 重新啟用
end;
// 核心:主框架加載完成時獲取 Window
procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var
Doc: IHTMLDocument2;
begin
if pDisp = (ASender as TWebBrowser).Application then
begin
Doc := (ASender as TWebBrowser).Document as IHTMLDocument2;
if Assigned(Doc) then
begin
FWindow := Doc.parentWindow;
btnModify.Enabled := True; // 允許後續操作
end;
end;
end;
procedure TForm1.btnModifyClick(Sender: TObject);
begin
if not Assigned(FWindow) then Exit;
// 1. 修改 body 內容
FWindow.document.body.innerHTML :=
'
萬一的 Delphi 博客
' +
'這是從 Delphi 通過 MSHTML 動態注入的內容。
';
// 2. 呼叫 JavaScript 原生 alert
FWindow.alert('JavaScript 提示:DOM 修改成功!');
// 3. 進階:執行任意 JS 代碼
// FWindow.execScript('console.log("從 Delphi 執行 JS")', 'JavaScript');
end;
end.
object Form1: TForm1
ClientHeight = 400
ClientWidth = 600
Caption = 'TWebBrowser MSHTML Demo'
object WebBrowser1: TWebBrowser
Align = alClient
TabOrder = 0
end
object btnOpen: TButton
Left = 10
Top = 10
Width = 100
Height = 30
Caption = '打開頁面'
TabOrder = 1
OnClick = btnOpenClick
end
object btnModify: TButton
Left = 120
Top = 10
Width = 100
Height = 30
Caption = '修改內容'
Enabled = False
TabOrder = 2
OnClick = btnModifyClick
end
end
有時需要自動化已打開的 IE 視窗,而非嵌入控件:
uses ComObj, MSHTML;
var
IE: OleVariant; // 晚綁定,簡化代碼
Win: IHTMLWindow2; // 早綁定介面,享受代碼提示
procedure TForm1.btnAttachClick(Sender: TObject);
begin
// 連接現有 IE 進程(需已運行一個 IE 實例)
IE := CreateOleObject('InternetExplorer.Application');
IE.Visible := True;
IE.Navigate('https://www.example.com');
// 注意:外部 IE 無 DocumentComplete 事件,需輪詢 ReadyState
while IE.ReadyState <> 4 do Application.ProcessMessages;
Win := (IDispatch(IE.Document) as IHTMLDocument2).parentWindow;
end;
procedure TForm1.btnModifyExternalClick(Sender: TObject);
begin
if Assigned(Win) then
Win.document.body.innerHTML := '外部 IE 也被 Delphi 控制了!
';
end;
| 現象 | 原因 | 解決 |
|---|---|---|
| 編譯錯誤「Undefined identifier: IHTMLWindow2」 | 缺少 MSHTML 在 uses 中 | 添加 uses MSHTML; |
| 運行時「Interface not supported」 | Document 尚未就緒或非 HTML 頁面 | 在 DocumentComplete 中獲取,判斷 Assigned(Doc) |
| 修改 innerHTML 無效果 | 頁面含框架,操作了錯誤的 document | 用 pDisp = Application 過濾主框架 |
| alert 不彈出 | IE 安全區域阻腳本彈窗 | 將目標站點加入「受信任站點」,或降低安全級別 |
IHTMLWindow3.attachEvent 監聽頁面點擊、提交等事件,回調 Delphi 代碼。window.external 暴露 Delphi 對象給 JS,實現雙向通訊(需實現 IDispatch)。TWebBrowser 隱藏屬性,構建後台爬蟲/測試工具。WebView2(Chromium 內核),API 風格相似但更現代。本文展示了從零開始,在 Delphi 中利用 TWebBrowser + MSHTML 獲取 IHTMLWindow2 的完整路徑:拖入控件 → 引用單元 → 等待 DocumentComplete → 轉型 Document → 取 parentWindow。掌握這套流程,你就擁有了在原生 Win32 應用中「像操作 JavaScript 一樣操作網頁」的超能力。