TChromium:GetSourceProc和不兼容的类型:'常规过程和方法指针'

时间:2015-12-23 16:57:46

标签: delphi chromium-embedded tchromium

我需要从TChromium中加载的页面获取源HTML,但我需要将源存储在另一个类的变量中。换句话说,回调函数需要在另一个类中,我不能这样做,因为这个例外:

E2009不兼容的类型:'常规程序和方法指针'

这是我的代码。它仅适用于' StringVisitor'功能超出了Form1'类。

有什么想法吗?

unit simple1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, cefvcl, ceflib;

type
  TForm1 = class(TForm)
    Chromium1: TChromium;
    procedure FormCreate(Sender: TObject);
    procedure Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame;
      httpStatusCode: Integer);
  public
  mySource : string;
  procedure StringVisitor(const str: ustring);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame;
  httpStatusCode: Integer);
begin
  Chromium1.Browser.MainFrame.GetSourceProc(StringVisitor);  // error on this line
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
chromium1.load('http://www.google.com');
end;

procedure TForm1.StringVisitor(const str: ustring);
begin
mySource := str;
end;

end.

1 个答案:

答案 0 :(得分:2)

Ok使用Delphi 7我能够重现这个问题。

在深入研究问题之后,我发现有两种diffrnet方法可以获取加载页面的来源:

1)procedure GetSourceProc(const proc: TCefStringVisitorProc);正如您所使用的那样。该解决方案的问题在于Dlephi 2009之前它只接受一个独立的过程,当你有多个你想要保留HTML的对象实例时会给你带来问题。

2)procedure GetSource(const visitor: ICefStringVisitor);

让我们先看一下预期的界面

  ICefStringVisitor = interface(ICefBase)
    ['{63ED4D6C-2FC8-4537-964B-B84C008F6158}']
    procedure Visit(const str: ustring);
  end;

所以我开始调查。我在unit ceflib;挖掘了TCefStringVisitorOwn,我找到了TCefStringVisitorOwn,这是解决问题的关键。

TCefStringVisitorOwn = class(TCefBaseOwn, ICefStringVisitor) protected procedure Visit(const str: ustring); virtual; public constructor Create; virtual; end; 的界面非常简单:

TCefStringVisitorOwn

所以我手边有了unit SourceContainerU; interface uses ceflib; type ISourceContainer = interface(ICefStringVisitor) function Source: ustring; end; TSourceContainer = class(TCefStringVisitorOwn, ISourceContainer) private FSource: ustring; protected procedure Visit(const str: ustring); override; public function Source: ustring; end; implementation { TSourceContainer } function TSourceContainer.Source: ustring; begin Result := FSource; end; procedure TSourceContainer.Visit(const str: ustring); begin FSource := str; end; end. 的后代:

TChromium

这里没什么了不起的。

唯一剩下的就是使用这个类创建一个演示项目。在我的示例中,我在运行时创建unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, cefvcl, ceflib, SourceContainerU; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } Chromium1: TChromium; SourceContainer : ISourceContainer; procedure Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; httpStatusCode: Integer); public end; var Form1: TForm1; implementation {$R *.dfm} { TForm1 } procedure TForm1.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; httpStatusCode: Integer); begin if Frame = nil then exit; SourceContainer := TSourceContainer.Create; Frame.GetSource(SourceContainer); end; procedure TForm1.FormCreate(Sender: TObject); begin Chromium1 := TChromium.Create(self); Chromium1.Parent := self; Chromium1.OnLoadEnd := Chromium1LoadEnd; Chromium1.load('http://www.google.com'); end; procedure TForm1.Button1Click(Sender: TObject); begin if Assigned(SourceContainer) then Memo1.Lines.Text := SourceContainer.Source; end; end. 。表单包含一个按钮和一个备忘录,然后是这段代码:

$u=$qq->fetch(PDO::FETCH_ASSOC);

此解决方案已经过测试,并且已经测试了最新版本的Chromium,并且已经在 Delphi 7 Delphi XE Delphi XE6 <中进行了测试/ strong>即可。我没有任何 Delphi 2007 安装,但我相信它应该在wotk中工作。