【问题标题】:TWebBrowser: How to know the URL in a OnNewWindow2 event?TWebBrowser:如何知道 OnNewWindow2 事件中的 URL?
【发布时间】:2020-03-23 04:42:09
【问题描述】:

我们的 HTML 包含:

<A target="_blank" href="http://blabla.com">

当点击链接时,OnNewWindow2 被触发:

procedure TForm1.WebBrowser1NewWindow2(Sender: TObject;
  var ppDisp: IDispatch; var Cancel: WordBool);
begin
  Cancel := True;  
  // open in default browser
end;

我想在默认浏览器中打开链接: Opening TWebBrowser link in default browser

但在我的情况下没有BeforeNavigate2被解雇。
如何知道 TWebBrowser OnNewWindow2 事件中的预期 URL?


编辑:在较新版本的 Delphi 中,有一个 OnNewWindow3 事件,它提供了我需要的 URL。目前,我真的很难开始了解如何将此事件实施到现有的 TWebBrowser 中。
如果有人这样做,那么获得一些帮助会很棒。

【问题讨论】:

    标签: delphi delphi-7 twebbrowser


    【解决方案1】:

    您可以覆盖浏览器的InvokeEvent 方法并在那里等待DISPID_NEWWINDOW3 调度标识符。对于像 OnNewWindow3 这样的插入器类,可以这样实现:

    uses
      ActiveX, OleCtrls, SHDocVw;
    
    const
      DISPID_NEWWINDOW3 = 273;
    
    type
      TWebBrowserNewWindow3 = procedure(ASender: TObject; var ppDisp: IDispatch; var Cancel: WordBool;
        dwFlags: Longint; const bstrUrlContext: WideString; const bstrUrl: WideString) of object;
    
      TWebBrowser = class(SHDocVw.TWebBrowser)
      private
        FOnNewWindow3: TWebBrowserNewWindow3;
      protected
        procedure InvokeEvent(ADispID: TDispID; var AParams: TDispParams); override;
      public
        property OnNewWindow3: TWebBrowserNewWindow3 read FOnNewWindow3 write FOnNewWindow3;
      end;
    
    implementation
    
    procedure TWebBrowser.InvokeEvent(ADispID: TDispID; var AParams: TDispParams);
    begin
      if (ADispID = DISPID_NEWWINDOW3) and Assigned(FOnNewWindow3) then
      begin
        FOnNewWindow3(Self, AParams.rgvarg^[4].pdispVal^, AParams.rgvarg^[3].pbool^,
          AParams.rgvarg^[2].lVal, WideString(AParams.rgvarg^[1].bstrVal), WideString(AParams.rgvarg^[0].bstrVal));
      end
      else
        inherited;
    end;
    

    【讨论】:

    • 非常优雅有趣的解决方案!
    • 这几乎就是我在您发表评论后编写的代码,但处理TDispParams 对我来说实在是太多了。做得好! :) 一个问题,你是怎么知道数组中的参数是倒序的?
    • 好吧,我刚刚从我曾经参与过的论坛上的帖子中复制粘贴了这段代码:) 我是如何发现相反的顺序(也不是该代码所针对的确切 Delphi 版本)我不记得了。 [附:我现在手头没有任何 Delphi]
    【解决方案2】:

    我如何知道 TWebBrowser OnNewWindow2 事件中的预期 URL?

    您可以使用 DOM 的 getAttribute method。但是在您应该加载所需的页面之前并在此完成之后用您自己的替换特定事件。见以下代码:

    uses
      ...
      SHDocVw, MSHTML;
    
    type
      TForm1 = class(TForm)
        ...
        // Your auto-generated event handler
        procedure WebBrowser1DocumentComplete(ASender: TObject; 
          const pDisp: IDispatch; const URL: OleVariant);
    
      private
        // Your self-written event handlers
        procedure New_BeforeNavigate2(ASender: TObject;
          const pDisp: IDispatch; const URL, Flags, TargetFrameName, PostData, Headers: OleVariant; 
          var Cancel: WordBool);
        procedure New_NewWindow2(ASender: TObject; var ppDisp: IDispatch; var Cancel: WordBool);
      end;
    
    ...
    
    // Assign event handler in design-time
    procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; 
      const URL: OleVariant);
    begin
      (ASender as TWebBrowser).OnBeforeNavigate2 := New_BeforeNavigate2;
      (ASender as TWebBrowser).OnNewWindow2 := New_NewWindow2;
    end;
    
    procedure TForm1.New_BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; 
      const URL, Flags, TargetFrameName, PostData, Headers: OleVariant; 
      var Cancel: WordBool);
    begin
      ShowMessage('New URL will be: ' + URL);
      Cancel := true;
    end;
    
    procedure TForm1.New_NewWindow2(ASender: TObject; var ppDisp: IDispatch; var Cancel: WordBool);
    var
      S: String;
    begin
      S := ((TWebBrowser(ASender).Document as IHTMLDocument2).ActiveElement as IHTMLElement).GetAttribute('href', 0);
      ShowMessage('New window''s URL is: ' + S);
      Cancel := true;
    end;
    

    现在您可以通过OnNewWindow2 事件获取 URL。对于target="_self" 的情况,还有OnBeforeNavigate2 事件处理程序。如果我正确地回答了您的问题,它应该可以工作。

    【讨论】:

    • 这确实是一个不错的 hack。我会做一些测试看看它的一致性。
    • 这适用于我测试的案例,这确实是一个原创的想法! (虽然我想知道ActiveElement 是否会从您单击链接的那一刻起以及事件触发的那一刻起以某种方式发生变化......)但我认为@TLama 的解决方案是最终的方法。谢谢:)
    猜你喜欢
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    相关资源
    最近更新 更多