gpt4 book ai didi

delphi - Chromium嵌入式: TCefDomVisitorOwn.访问()方法从未被执行

转载 作者:行者123 更新时间:2023-12-01 19:36:47 27 4
gpt4 key购买 nike

我正在使用CEF4Delphi并尝试获取页面的确定 html input 元素,然后使用下面的代码将值设置为相同的值,但碰巧方法 TElementNameVisitor.visit(const document: ICefDomDocument); 永远不会被执行。

我该如何解决这个问题?

uses
uCEFChromium, uCEFWindowParent,
uCEFChromiumWindow, uCEFInterfaces, uCEFDomVisitor;

type
TElementNameVisitor = class(TCefDomVisitorOwn)
private
FName: string;
protected
procedure visit(const document: ICefDomDocument); override;
public
constructor Create(const AName: string); reintroduce;
end;

type
TForm2 = class(TForm)
Chromium1: TChromium;
CEFWindowParent1: TCEFWindowParent;
procedure FormShow(Sender: TObject);
procedure Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

constructor TElementNameVisitor.Create(const AName: string);
begin
inherited Create;
FName := AName;
end;

procedure ProcessElementsByName(const AFrame: ICefFrame; const AName: string);
var
Visitor: TElementNameVisitor;
begin
if Assigned(AFrame) then
begin
Visitor := TElementNameVisitor.Create(AName);
AFrame.VisitDom(Visitor);
end;
end;

procedure TElementNameVisitor.visit(const document: ICefDomDocument);

procedure ProcessNode(ANode: ICefDomNode);
var
Node: ICefDomNode;
begin
if Assigned(ANode) then
begin
Node := ANode.FirstChild;
while Assigned(Node) do
begin
if Node.GetElementAttribute('name') = FName then
begin
Node.SetElementAttribute('value', '-15.792253570362445');
ShowMessage(Node.GetElementAttribute('value'));
end;
ProcessNode(Node);
Node := Node.NextSibling;
end;
end;
end;

begin
ProcessNode(document.Body);
end;

procedure TForm2.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer);
var
CefStringVisitor: ICefStringVisitor;
begin
ProcessElementsByName(Chromium1.browser.MainFrame, 'latitude'); // "latitude" = name of field that i want set a value
end;

procedure TForm2.FormShow(Sender: TObject);
begin
while not(Chromium1.CreateBrowser(CEFWindowParent1, '')) and
(Chromium1.Initialized) do
begin
Sleep(100);
Application.ProcessMessages;
end;
Application.MessageBox('CEFWindowParent1 created!', 'Success', MB_OK + MB_ICONINFORMATION);
Chromium1.LoadURL('file:///' + ReplaceStr(ExtractFilePath(Application.ExeName) + 'gmaps.html', '\', '/'));
end;

最佳答案

此代码在浏览器进程中创建 DOM 访问者,但 DOM 访问者函数在渲染进程中调用,如 CEF3 code comments 中所示。

如果您使用“单进程”模式,但该模式不受 CEF3 支持,它会导致错误,您应该仅将该模式用于调试目的。

您需要使用多个进程。使用DOMVisitor demo作为您的应用程序的模板,并阅读该演示中的所有代码注释。

必须在渲染过程中创建 DOM 访问者。为此,您需要从浏览器进程向渲染进程发送一条进程消息,然后在接收该进程消息的事件内创建 TCefDomVisitorOwn 子类。

DOMVisitor 演示使用 GlobalCEFApp.OnProcessMessageReceived 事件来接收渲染进程中的消息,并在该事件内创建一个 TCefFastDomVisitor2。

TCefFastDomVisitor2 构造函数有一个名为“proc”的过程参数,该参数在触发 TCefDomVisitorOwn.visit 事件时执行。

在这些过程中,您可以搜索 DOM 中的节点,然后将结果发送回调用 browser.SendProcessMessage(PID_BROWSER, msg) 的浏览器进程

浏览器将在 TChromium.OnProcessMessageReceived 事件中接收这些消息。

如您所知,Delphi 只能调试一个进程。如果您需要调试渲染过程中执行的代码,您需要:

  • 使用“单进程”模式,但请记住,您不应在最终版本中使用此模式。
  • 使用 Delphi 中的“运行而不调试...”选项并选择渲染进程。

关于delphi - Chromium嵌入式: TCefDomVisitorOwn.访问()方法从未被执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52247661/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com