我正在关注 How to call Delphi code from scripts running in a TWebBrowser DelphiDabbler 教程(作者:Peter Johnson)允许 Delphi 监听 TWebBrowser
JavaScript 事件。
这直到我看到我的 Delphi 程序被调用为止。但是,从那里我需要更新一些表单标签,并且我看不到如何从这些过程访问我的表单。
DelphiDabbler 示例代码通过 creating 很好地规避了“直接表单访问” THintAction.Create(nil);
这将完成它的事情:
This let's us decouple our external object implementation quite nicely from the program's form
但我想访问我的表单!传递的数据有整数和字符串。
我可以使用 PostMessage() 和 WM_COPYDATA 消息,但这些消息仍然需要表单句柄。难道没有一个“直接”的途径来填写表格吗?
相关代码:
type
TWebBrowserExternal = class(TAutoIntfObject, IWebBrowserExternal, IDispatch)
protected
procedure SetVanLabel(const ACaption: WideString); safecall; // My 3 procedures that are called...
procedure SetNaarLabel(const AValue: WideString); safecall; // ... declared in the type library.
procedure SetDistanceLabel(AValue: Integer); safecall;
public
constructor Create;
destructor Destroy; override;
end;
type
TExternalContainer = class(TNulWBContainer, IDocHostUIHandler, IOleClientSite)
private
fExternalObj: IDispatch; // external object implementation
protected
{ Re-implemented IDocHostUIHandler method }
function GetExternal(out ppDispatch: IDispatch): HResult; stdcall;
public
constructor Create(const HostedBrowser: TWebBrowser);
end;
constructor TExternalContainer.Create(const HostedBrowser: TWebBrowser);
begin
inherited Create(HostedBrowser);
fExternalObj := TWebBrowserExternal.Create;
end;
表单有一个属性FContainer: TExternalContainer;
,在FormCreate中我做fContainer := TExternalContainer.Create(WebBrowser);
(参数是设计时TWebBrowser
),所以
TExternalContainer.fExternalObj
已分配给它。
问题:
procedure TWebBrowserExternal.SetDistanceLabel(AValue: Integer);
begin
// **From here, how do I send AValue to a label caption on my form?**
end;
我必须承认接口(interface)不是我的强项;-)
[补充:]注意:我的表单都是动态创建的,当前单元没有TForm实例。
最佳答案
您说您想要访问您的表单,但您实际上并不这样做 - 至少不是直接这样做。您确实希望“将我们的外部对象实现与程序的形式很好地分离”。您真正需要做的就是编写一个函数或过程来在程序中执行您想要的操作,然后从 Web 浏览器调用该函数或过程。这就是解耦和接口(interface)的意义所在。您永远不会直接从另一个应用程序处理属于一个应用程序的数据。相反,您使用函数和过程作为界面。顺便说一句,这就是为什么接口(interface)只包含函数和过程原型(prototype)(以及属性 - 但它们只是在内部转换为函数和过程) - 而不是数据。
现在讨论你的具体问题。当然,您可以访问您的表单 - 它是一个全局变量。假设你的主窗体是 TMainForm 类型,在一个名为 Main.pas 的单元中,将会有一个名为 MainForm 的全局变量
var
MainForm : TMainForm;
因此,在您的网络浏览器单元中,您将在实现部分中放置
implementation
uses Main;
...
procedure TWebBrowserExternal.SetDistanceLabel(AValue: Integer);
begin
// **From here, how do I send AValue to a label caption on my form?**
FormMain.MyLabel.Caption := StrToInt( AValue );
end;
就我所说的而言,SetDistanceLabel 是接口(interface)函数,并且只能从 Delphi 应用程序中直接访问 Form。
关于delphi - 扩展TWebBrowser外部对象来执行Delphi代码: how to access my form components?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37964716/