【问题标题】:How to get the url from Chrome using delphi如何使用delphi从Chrome获取url
【发布时间】:2011-07-10 11:42:23
【问题描述】:

如何使用 Delphi 从正在运行的 Chrome 实例中获取 url?

我正在尝试做一个 Delphi 应用程序来获取浏览器(IE、Mozilla 等)的活动选项卡的 url。我正在使用适用于 IE 的代码:

 procedure TForm1.GetCurrentURL (var URL, Title : string);
 var
   DDEClient : TDDEClientConv;
   s : string;
 begin
   s := '';
   try
     DDEClient := TDDEClientConv.Create(self);
     with DDEClient do
     begin
       if SetLink('IExplore','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle')
       else
       if SetLink('Netscape','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle')
       else
       if SetLink('Mosaic','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle')
       else
       if SetLink('Netscp6','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle')
       else
       if SetLink('Mozilla','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle')
       else
       if SetLink('Firefox','WWW_GetWindowInfo') then
         s := RequestData('0xFFFFFFFF,sURL,sTitle');
     end;
     if s <> '' then
     begin
       delete(s,1,1);
       URL := copy(s,1,pos('","',s)-1);
       delete(s,1,pos('","',s)+2);
       Title := copy(s,1,pos('"',s) - 1);
     end;
     exit;
   except
     MessageDlg('URL attempt failed!',mtError,[mbOK],0);
   end;
 end;

但此代码不适用于 Chrome。

谢谢。

【问题讨论】:

  • 你从哪里得到的代码?它有内存泄漏——不会释放 DDE 客户端。
  • 仅供参考,issue 70184 跟踪 Chrome 缺乏 DDE 支持。
  • 这在我看来肯定像 reuse by copy-paste anti pattern
  • @Ian: 好吧,但是Self 将会存在相当长的一段时间......
  • 啊,我明白了,@Ian。不完全是通常意义上的泄漏,但与真正的泄漏也没有明显不同。如果真的是泄漏,那就是操作系统在程序结束时清理了内存。在这种情况下,它是在程序结束前一刻清理内存的主窗体。但无论哪种方式,该对象都远远超过了它的用处,因为它永远不会在这个函数之外被访问。 (它可以被访问,但我们都知道它不会。)

标签: delphi


【解决方案1】:

这是我之前从 active 选项卡中检索 URL 的方法。您可能可以扩展它以包括所有 Chrome 的标签。

另一个注意事项,如您所见,它抓住了它找到的 chrome.exe 的第一个句柄。要让它适应运行的多个 Chrome 实例,您需要调整它以获取每个 Chrome 实例的句柄。

我很快就把它放在一起,所以不要考虑这种“生产”质量。只需创建一个新的 vcl 应用程序并在表单上放置一个 TMemo 和一个 TButton 并将 Button1Click 分配给 TButton 的 OnClick 事件。

unit main;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Controls,
  Forms,
  StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function GetActivePageUrlFromChrome(Handle: HWnd; Param: LParam): Bool; stdcall;

var
  Form1             : TForm1;

implementation

{$R *.dfm}

function GetActivePageUrlFromChrome(Handle: HWnd; Param: LParam): Bool; stdcall;
var
  List: TStrings;
  hWndChrome, hWndChromeChild: HWND;
  Buffer            : array[0..255] of Char;
begin
  List := TStrings(Param);
  //get the window caption
  SendMessage(Handle, WM_GETTEXT, Length(Buffer), integer(@Buffer[0]));
  //look for the chrome window with "Buffer" caption
  hWndChrome := FindWindow('Chrome_WidgetWin_0', Buffer);
  if hWndChrome <> 0 then
  begin
    hWndChromeChild := FindWindowEx(hWndChrome, 0, 'Chrome_AutocompleteEditView', nil);
    if hWndChromeChild <> 0 then
    begin
      SendMessage(hWndChromeChild, WM_GETTEXT, Length(Buffer), integer(@Buffer));
      List.Add(Buffer);
    end;
  end;
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  slChromeUrl      : TStringList;
begin
  slChromeUrl := TStringList.Create;
  try
    EnumWindows(GetActivePageUrlFromChrome, LParam(slChromeUrl));
    Memo1.Lines.AddStrings(slChromeUrl);
  finally
    FreeAndNil(slChromeUrl);
  end;
end;

end.

【讨论】:

  • 不用说,这可能不适用于 Google Chrome 的未来版本。不过,+1。
  • 你的GetProcessHandle 功能很特别。尽管它的名字,它实际上并没有获得进程句柄。它得到一个工具帮助快照句柄。即使调用者从不使用句柄,它也会让调用者关闭该句柄。它还返回一个进程 ID,但调用者也从不使用它。我怀疑您在错误的印象中保持快照句柄处于打开状态,即这样做会防止 Chrome 进程在 Button1Click 尝试与之交互时被破坏,但这不是快照句柄的工作方式。
  • @Rob - 实际上,GetProcessHandle 函数是我为这个示例从网上提取的。获取 Chrome URL 的代码来自我的一个项目,该项目以不同的方式获取进程的句柄。这就是为什么我说这不是“生产”质量代码,而只是作为从 Chrome 的活动标签中提取 URL 的示例。
  • @Mick:我希望您向GetProcessHandle 的作者请求允许复制代码并在此处显示,而无需任何归属或来源...
  • @Andreas 是的,我该停下来了。我必须说,我真的不赞成发布如此低质量的代码。把它做好并不难。
【解决方案2】:

显然有一个问题可以通过 chrome/chromium 请求 DDE 支持,如果未来的版本会提供它,请留意那里:

http://code.google.com/p/chromium/issues/detail?id=70184

【讨论】:

    【解决方案3】:

    错误:

    try
        EnumWindows(GetActivePageUrlFromChrome, LParam(slChromeUrl));
        Memo1.Lines.AddStrings(slChromeUrl);
    

    作品:

    try
        EnumWindows(@GetActivePageUrlFromChrome, LParam(slChromeUrl));
        Memo1.Lines.AddStrings(slChromeUrl);
    

    【讨论】:

      猜你喜欢
      • 2010-11-16
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 2020-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多