傳統 Delphi 開發自動化對象(IDispatch)需建立 ActiveX Library、編寫類型庫(TLB)、註冊 COM 組件,流程繁瑣。實際上,利用未文檔化的編譯指令 {$METHODINFO ON} 配合 TObjectDispatch(位於 ObjComAuto.pas),即可在幾行代碼內創建支援 GetIDsOfNames/Invoke 的輕量級自動化對象,無需註冊、無 TLB、無 ActiveX 專案。
{$METHODINFO ON}:指示編譯器為類生成公開/發布方法的 RTTI(運行時類型信息),供 GetIDsOfNames 枚舉。TObjectDispatch:實現 IDispatch 介面的基類,內部利用 RTTI 將方法名解析為 DISPID 並調用 Invoke。TObjectDispatch 並開啟 METHODINFO 的類,其所有 public/published 方法自動成為可被腳本/宿主調用的自動化方法。uses ObjComAuto; {包含 TObjectDispatch}
{$METHODINFO ON}
TScriptableObject = class(TObjectDispatch)
public
constructor Create;
end;
{$METHODINFO OFF}
constructor TScriptableObject.Create;
begin
inherited Create(Self, False); {Self 為 IDispatch 實現者, False 表示不自動釋放}
end;
TWebBrowser 的 IDocHostUIHandler.GetExternal 需返回 IDispatch 介面供網頁腳本調用。使用上述類:
type
TMyExternal = class(TScriptableObject)
public
procedure ShowMessage(const Msg: WideString);
function Add(a, b: Integer): Integer;
end;
procedure TMyExternal.ShowMessage(const Msg: WideString);
begin
Vcl.Dialogs.ShowMessage(Msg);
end;
function TMyExternal.Add(a, b: Integer): Integer;
begin
Result := a + b;
end;
{在 WebBrowser DocumentComplete 事件中}
procedure TForm1.WebBrowser1DocumentComplete(Sender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var Ext: TMyExternal;
begin
Ext := TMyExternal.Create;
try
(WebBrowser1.ControlInterface.Document as IHTMLDocument2).Set_external(Ext);
finally
Ext.Free; {注意:WebBrowser 會 AddRef,這裡釋放自身引用即可}
end;
end;
網頁 JavaScript 即可調用:window.external.ShowMessage('Hello')、window.external.Add(1,2)。
| 維度 | 傳統 ActiveX Library | $METHODINFO + TObjectDispatch |
|---|---|---|
| 部署 | 需註冊 (regsvr32)、TLB | 無需註冊、純 DLL/EXE 內部使用 |
| 跨進程 | 支援 (Out-of-proc) | 僅進程內 (In-proc) |
| 類型安全 | IDL 定義、編譯期檢查 | 運行時解析、無編譯期類型檢查 |
| 效能 | 標準 COM 調用開銷 | RTTI 反射調用,略慢但可忽略 |
| 適用場景 | 系統級組件、多語言調用 | 宿主應用內部腳本綁定、WebBrowser 外部對象、插件系統 |
private/protected 方法不會生成 METHODINFO,不可被調用。WideString、OleVariant、IDispatch、IUnknown、記錄類型需手工處理。TObjectDispatch.Create(Self, False) 表示不自動釋放,宿主需自行管理引用計數。$METHODINFO 為內部指令,雖長期穩定但官方不保證向後兼容。利用 {$METHODINFO ON} + TObjectDispatch 可在幾分鐘內為 Delphi 應用添加強大的腳本綁定能力,特別適合 WebBrowser 宿主場景、內部插件系統、快速原型開發,極大降低了 COM 自動化對象的開發門檻。