当鼠标移过TWebBrowser文档时,获取超链接的网址

The TWebBrowser Delphi component provides access to the Web browser functionality from your Delphi applications.

TWebBrowser Delphi组件可从您的Delphi应用程序访问Web浏览器功能。

In most situations you use the TWebBrowser to display HTML documents to the user - thus creating your own version of the (Internet Explorer) Web browser. Note that the TWebBrowser can also display Word documents, for example.

在大多数情况下,您可以使用TWebBrowser向用户显示HTML文档-从而创建您自己的(Internet Explorer)Web浏览器版本。 注意,例如,TWebBrowser也可以显示Word文档。

A very nice feature of a Browser is to display link information, for example, in the status bar, when the mouse hovers over a link in a document.

浏览器的一个很好的功能是当鼠标悬停在文档中的链接上时,例如在状态栏中显示链接信息。

The TWebBrowser does not expose an event like "OnMouseMove". Even if such an event would exist it would be fired for the TWebBrowser component - NOT for the document being displayed inside the TWebBrowser.

TWebBrowser不会公开“ OnMouseMove”之类的事件。 即使存在此类事件,也会为TWebBrowser组件触发该事件,而不是为TWebBrowser内部显示的文档触发事件。

In order to provide such information (and much more, as you will see in a moment) in your Delphi application using the TWebBrowser component, a technique called "events sinking" must be implemeted.

为了使用TWebBrowser组件在Delphi应用程序中提供此类信息(以及更多信息,您将在稍后看到),必须实现一种称为“ 事件下沉 ”的技术。

WebBrowser事件接收器 ( WebBrowser Event Sink )

To navigate to a web page using the TWebBrowser component you call the Navigate method. The Document property of the TWebBrowser returns an IHTMLDocument2 value (for web documents). This interface is used to retrieve information about a document, to examine and modify the HTML elements and text within the document, and to process related events.

要使用TWebBrowser组件导航到网页,请调用Navigate方法。 该TWebBrowser的文档属性返回的IHTMLDocument2值(网页文件)。 此接口用于检索有关文档的信息,检查和修改文档中HTML元素和文本以及处理相关事件。

To get the "href" attribute (link) of an "a" tag inside a document, while the mouse hovers over a document, you need to react on the "onmousemove" event of the IHTMLDocument2.

为了获得文档内“ a”标签的“ href”属性(链接),当鼠标悬停在文档上时,您需要对IHTMLDocument2的“ onmousemove”事件作出React。

Here are the steps to sink events for the currently loaded document:

以下是接收当前加载的文档事件的步骤:

  1. Sink the WebBrowser control's events in the DocumentComplete event raised by the TWebBrowser. This event is fired when the document is fully loaded into the Web Browser.

    在TWebBrowser引发的DocumentComplete事件中接收WebBrowser控件的事件。 将文档完全加载到Web浏览器时,将触发此事件。

  2. Inside DocumentComplete, retrieve the WebBrowser's document object and sink the HtmlDocumentEvents interface.

    在DocumentComplete内,检索WebBrowser的文档对象并接收HtmlDocumentEvents接口。
  3. Handle the event you are interested in.

    处理您感兴趣的事件。
  4. Clear the sink in the in BeforeNavigate2 - that is when the new document is loaded in the Web Browser.

    清除BeforeNavigate2中的接收器 -也就是在Web浏览器中加载新文档时。

HTML文档OnMouseMove ( HTML Document OnMouseMove )

Since we are interested in the HREF attribute of an A element - in order to show the URL of a link the mouse is over, we will sink the "onmousemove" event.

由于我们对A元素的HREF属性感兴趣-为了显示鼠标悬停的链接的URL,我们将沉入“ onmousemove”事件。

The procedure to get the tag (and its attributes) "below" the mouse can be defined as:

可以在鼠标“下方”获取标签(及其属性)的过程可以定义为:

var
  htmlDoc : IHTMLDocument2;
...
procedure TForm1.Document_OnMouseOver;
var
   element : IHTMLElement;
begin
   if htmlDoc = nil then Exit;
   element := htmlDoc.parentWindow.event.srcElement;
   elementInfo.Clear;
   if LowerCase(element.tagName) = 'a' then
   begin
     ShowMessage('Link, HREF : ' + element.getAttribute('href',0)]) ;
   end
   else if LowerCase(element.tagName) = 'img' then
   begin
     ShowMessage('IMAGE, SRC : ' + element.getAttribute('src',0)]) ;
   end
   else
   begin
     elementInfo.Lines.Add(Format('TAG : %s',[element.tagName])) ;
   end;
end; (*Document_OnMouseOver*)

As explained above, we attach to the onmousemove event of a document in the OnDocumentComplete event of a TWebBrowser:

如上所述,我们在TWebBrowser的OnDocumentComplete事件中附加到文档的onmousemove事件:

procedure TForm1.WebBrowser1DocumentComplete(   ASender: TObject;
  const pDisp: IDispatch;
  var URL: OleVariant) ;
begin
   if Assigned(WebBrowser1.Document) then
   begin
     htmlDoc := WebBrowser1.Document as IHTMLDocument2;
     htmlDoc.onmouseover := (TEventObject.Create(Document_OnMouseOver) as IDispatch) ;
   end;
end; (*WebBrowser1DocumentComplete*)

And this is where the problems arise! As you might guess the "onmousemove" event is *not* a usual event - as are those we are used to work with in Delphi.

这就是问题出现的地方! 您可能会猜到“ onmousemove”事件不是一个常见事件,就像我们在Delphi中使用的那些事件一样。

The "onmousemove" expects a pointer to a variable of type VARIANT of type VT_DISPATCH that receives the IDispatch interface of an object with a default method that is invoked when the event occurs.

“ onmousemove”期望指向类型为VT_DISPATCH的VARIANT类型的变量的指针,该变量使用事件发生时调用的默认方法接收对象的IDispatch接口。

In order to attach a Delphi procedure to "onmousemove" you need to create a wrapper that implements IDispatch and raises your event in its Invoke method.

为了将Delphi过程附加到“ onmousemove”,您需要创建一个包装器,该包装器实现IDispatch并在其Invoke方法中引发事件。

Here's the TEventObject interface:

这是TEventObject接口:

TEventObject =class(TInterfacedObject, IDispatch)
private
   FOnEvent: TObjectProcedure;
protected
   function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
   function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
   function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
   function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
public
   constructor Create(const OnEvent: TObjectProcedure) ;
   property OnEvent: TObjectProcedure read FOnEvent write FOnEvent;
   end;

Here's how to implement event sinking for a document displayed by the TWebBrowser component - and get the info of a HTML element below the mouse.

这是为TWebBrowser组件显示的文档实现事件接收的方法-并在鼠标下方获取HTML元素的信息。

TWebBrowser文档事件下沉示例 ( TWebBrowser Document Event Sinking Example )

Download

下载

Drop a TWebBrowser ("WebBrowser1") on a Form ("Form1"). Add a TMemo ("elementInfo")...

将一个TWebBrowser(“ WebBrowser1”)放到窗体(“ Form1”)上。 添加TMemo(“ elementInfo”)...

unit Unit1;interfaceuses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, OleCtrls, SHDocVw, MSHTML, ActiveX, StdCtrls;type   TObjectProcedure = procedure of object;   TEventObject = class(TInterfacedObject, IDispatch)   private     FOnEvent: TObjectProcedure;   protected     function GetTypeInfoCount(out Count: Integer): HResult; stdcall;     function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;     function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;     function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;   public     constructor Create(const OnEvent: TObjectProcedure) ;     property OnEvent: TObjectProcedure read FOnEvent write FOnEvent;   end;   TForm1 = class(TForm)     WebBrowser1: TWebBrowser;     elementInfo: TMemo;     procedure WebBrowser1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool) ;     procedure WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant) ;     procedure FormCreate(Sender: TObject) ;   private     procedure Document_OnMouseOver;   public     { Public declarations }   end;var   Form1: TForm1;   htmlDoc : IHTMLDocument2;implementation{$R *.dfm}procedure TForm1.Document_OnMouseOver;var   element : IHTMLElement;begin   if htmlDoc = nil then Exit;   element := htmlDoc.parentWindow.event.srcElement;   elementInfo.Clear;   if LowerCase(element.tagName) = 'a' then   begin     elementInfo.Lines.Add('LINK info...') ;     elementInfo.Lines.Add(Format('HREF : %s',[element.getAttribute('href',0)])) ;   end   else if LowerCase(element.tagName) = 'img' then   begin     elementInfo.Lines.Add('IMAGE info...') ;     elementInfo.Lines.Add(Format('SRC : %s',[element.getAttribute('src',0)])) ;   end   else   begin     elementInfo.Lines.Add(Format('TAG : %s',[element.tagName])) ;   end;end; (*Document_OnMouseOver*)procedure TForm1.FormCreate(Sender: TObject) ;begin   WebBrowser1.Navigate('http://delphi.about.com') ;   elementInfo.Clear;   elementInfo.Lines.Add('Move your mouse over the document...') ;end; (*FormCreate*)procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool) ;begin   htmlDoc := nil;end; (*WebBrowser1BeforeNavigate2*)procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant) ;begin   if Assigned(WebBrowser1.Document) then   begin     htmlDoc := WebBrowser1.Document as IHTMLDocument2;     htmlDoc.onmouseover := (TEventObject.Create(Document_OnMouseOver) as IDispatch) ;   end;end; (*WebBrowser1DocumentComplete*){ TEventObject }constructor TEventObject.Create(const OnEvent: TObjectProcedure) ;begin   inherited Create;   FOnEvent := OnEvent;end;function TEventObject.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;begin   Result := E_NOTIMPL;end;function TEventObject.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult;begin   Result := E_NOTIMPL;end;function TEventObject.GetTypeInfoCount(out Count: Integer): HResult;begin   Result := E_NOTIMPL;end;function TEventObject.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;begin   if (DispID = DISPID_VALUE) then   begin     if Assigned(FOnEvent) then FOnEvent;     Result := S_OK;   end   else Result := E_NOTIMPL;end;end.

单位 Unit1; 界面 使用 Windows,消息,SysUtils,变体,类,图形,控件,表单,对话框,OleCtrls,SHDocVw,MSHTML,ActiveX,StdCtrls; 键入 TObjectProcedure = 对象 程序 ; TEventObject = (TInterfacedObject,IDispatch) 私有 FOnEvent:TObjectProcedure; 受保护的函数 GetTypeInfoCount(out Count:Integer):HResult; stdcall; 函数 GetTypeInfo(Index,LocaleID:Integer; out TypeInfo):HResult; stdcall; 函数 GetIDsOfNames( const IID:TGUID;名称:指针; NameCount,LocaleID:整数; DispIDs:指针):HResult; stdcall; 函数 Invoke(DispID:Integer; const IID:TGUID; LocaleID:Integer; Flags:Word; var Params; VarResult,ExcepInfo,ArgErr:Pointer):HResult; stdcall; 公共 构造函数 Create( const OnEvent:TObjectProcedure); 属性 OnEvent:TObjectProcedure读取FOnEvent写入FOnEvent; 结束 ; TForm1 = (TForm)WebBrowser1:TWebBrowser; elementInfo:TMemo; 过程 WebBrowser1BeforeNavigate2(ASender:TObject; const pDisp:IDispatch; var URL,Flags,TargetFrameName,PostData,Headers:OleVariant; var Cancel:WordBool); 过程 WebBrowser1DocumentComplete(ASender:TObject; const pDisp:IDispatch; var URL:OleVariant); 过程 FormCreate(Sender:TObject); 私有 过程 Document_OnMouseOver; 公开 { 公开声明} 结尾 ; var Form1:TForm1; htmlDoc:IHTMLDocument2; 实现 {$ R * .dfm} 过程 TForm1.Document_OnMouseOver; var element:IHTMLElement; 如果 htmlDoc = nil 开始 然后退出; 元素:= htmlDoc.parentWindow.event.srcElement; elementInfo.Clear; 如果 LowerCase(element.tagName)='a', 开始 elementInfo.Lines.Add('LINK info ...'); elementInfo.Lines.Add(Format('HREF:%s',[element.getAttribute('href',0)]))); 结束 否则 如果小写(element.tagName)= 'IMG' 然后 开始 elementInfo.Lines.Add( '图片资料...'); elementInfo.Lines.Add(Format('SRC:%s',[element.getAttribute('src',0)]))); 其他方式 开始 elementInfo.Lines.Add(Format('TAG:%s',[element.tagName]))); 结束 ; 结束 ; (* Document_OnMouseOver *) 过程 TForm1.FormCreate(Sender:TObject); 开始 WebBrowser1.Navigate('http://delphi.about.com'); elementInfo.Clear; elementInfo.Lines.Add('将鼠标移到文档上...'); 结束 ; (* FormCreate *) 过程 TForm1.WebBrowser1BeforeNavigate2(ASender:TObject; const pDisp:IDispatch; var URL,Flags,TargetFrameName,PostData,Headers:OleVariant; var Cancel:WordBool); 开始 htmlDoc:= nil ; 结束 ; (* WebBrowser1BeforeNavigate2 *) 过程 TForm1.WebBrowser1DocumentComplete(ASender:TObject; const pDisp:IDispatch; var URL:OleVariant); 如果 开始分配(WebBrowser1.Document) 然后 开始 HTMLDOC:= WebBrowser1.Document 的IHTMLDocument2; htmlDoc.onmouseover:=(TEventObject.Create(Document_OnMouseOver) as IDispatch); 结束 ; 结束 ; (* WebBrowser1DocumentComplete *) {TEventObject} 构造函数 TEventObject.Create( const OnEvent:TObjectProcedure); 开始 继承 Create; FOnEvent:= OnEvent; 结束 ; 函数 TEventObject.GetIDsOfNames( const IID:TGUID;名称:指针; NameCount,LocaleID:整数; DispIDs:指针):HResult; 开始结果:= E_NOTIMPL; 结束 ; 函数 TEventObject.GetTypeInfo(Index,LocaleID:Integer; out TypeInfo):HResult; 开始结果:= E_NOTIMPL; 结束 ; 函数 TEventObject.GetTypeInfoCount(out Count:Integer):HResult; 开始结果:= E_NOTIMPL; 结束 ; 函数 TEventObject.Invoke(DispID:Integer; const IID:TGUID; LocaleID:Integer; Flags:Word; var Params; VarResult,ExcepInfo,ArgErr:Pointer):HResult; 如果 开始 (DISPID = DISPID_VALUE) 然后 开始 如果已分配(FOnEvent) 然后 FOnEvent; 结果:= S_OK; 结束 else结果:= E_NOTIMPL; 结束 ; 结束

翻译自: https://www.thoughtco.com/url-hyperlink-twebbrowser-document-1058415

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值