juhara.com

  • Narrow screen resolution
  • Wide screen resolution
  • Decrease font size
  • Default font size
  • Increase font size
Home Articles Delphi Programming Monitoring web browser event
Monitoring web browser event PDF Print E-mail
Written by Zamrony P. Juhara   
Wednesday, 29 April 2009 12:22
Article Index
Monitoring web browser event
Connection code imlementation
All Pages

In this article, I will discuss about technique to catch events happened in a web browser. I wrote this article to answer a question posted by Johan Max at Delphindo about how to get notified when an anchor tag in a HTML document is clicked and also how to retrieve URL pointed by the anchor.

Of course we still use our favourite tool. Delphi. This tutorial only assumes web browser is IE, for other web browsers, this technique may not work. Source code is available for download on Download-Delphi Programming section.

Required unit.

First, import ActiveX MSHTML. If you already have MSHTML.pas or MSHTML_TLB.pas file on your system (look for it in Imports directory in your Delphi installation directory), it means you are ready to continue reading this article.

Step by step to monitor web browser events.

  • Create event sink implementation.
  • Load HTML document until it is complete.
  • Get HTML elements to monitor.
  • Connect event sink to HTML elements.

If you reach fourth step, then your application is ready to catch web browser events. When you want to stop monitoring events, last step is

  • Disconnect event sink.

Ok, let us discuss it one by one.

Creating event sink implementation

Event sink must be derived from IDispatch interface, because Invoke() will be called each time event occur. Following code snippet is IDispatch declaration (unit system.pas).

  IDispatch = interface(IUnknown)
['{00020400-0000-0000-C000-000000000046}']
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;
end;

All four methods must be implemented. IDispatch is derived from IUnknown, so we also need to implement IUnknown method. To avoid need to implement IUnknown, we can derived our implementation class from TInterfacedObject. Please note that, except Invoke(), other methods are less relevant to our goal, so we can set it unimplemented. Code snippet is as follow:

unit ueventsink;

interface
uses
classes,windows,sysutils,mshtml;

type
IEventSink=interface(IDispatch)
['{AC8E45D3-DABB-4DC0-AD94-D53FA67DD78A}']
procedure SetOnClick(const Value: THTMLElementOnClick);
function GetOnClick: THTMLElementOnClick;
procedure SetWebBrowser(const Value: IWebBrowser2);
function GetWebBrowser: IWebBrowser2;

property OnClick:THTMLElementOnClick read GetOnClick
write SetOnClick;
property WebBrowser:IWebBrowser2 read GetWebBrowser
write SetWebBrowser;
end;

TEventSink=class(TInterfacedObject,IDispatch,IEventSink)
public

procedure SetOnClick(const Value: THTMLElementOnClick);
function GetOnClick: THTMLElementOnClick;
procedure SetWebBrowser(const Value: IWebBrowser2);
function GetWebBrowser: IWebBrowser2;

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;

end;
implementation

{ TEventSink }

function TEventSink.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;
begin
result:=E_NOTIMPL;
end;

function TEventSink.GetTypeInfo(Index,
LocaleID: Integer;
out TypeInfo): HResult;
begin
result:=E_NOTIMPL;
end;

function TEventSink.GetTypeInfoCount(out Count: Integer): HResult;
begin
result:=E_NOTIMPL;
end;

function TEventSink.Invoke(DispID: Integer; const IID: TGUID;
LocaleID: Integer;
Flags: Word; var Params;
VarResult, ExcepInfo,
ArgErr: Pointer): HResult;
begin

end
;

end.

We will only pay attention to Invoke() implementation. Ok, now add an event property to TEventSink class.

type 
THTMLElementOnClick=procedure (Sender:TObject; Element:IHTMLElement;
var cancel:boolean) of object;

Add in published part, following code

property 
OnClick:THTMLElementOnClick;

Press Shift+Ctrl+C to complete class declaration. This is Invoke() implementation.

function TEventSink.Invoke(DispID: Integer; const IID: TGUID;
LocaleID: Integer; Flags: Word; var Params;
VarResult, ExcepInfo,
ArgErr: Pointer): HResult;
var cancel:boolean;
begin
case dispID of
-600:begin
if Assigned(FOnClick) then
begin
cancel:=false;
FOnClick(self,nil,cancel);
end;
end;
end;
result:=S_OK;
end;


Last Updated on Friday, 06 November 2009 14:44
 

Language

IndonesianEnglish (United Kingdom)

Game Institute
DAZ3D

Is this article helpful? Help this site improve by donating. Any amount is appreciated.