views:

643

answers:

2

I'm using this code to get all the links from an IHTMLDocument2:

procedure DoDocumentComplete(const pDisp: IDispatch; var URL: OleVariant);
var
  Document:IHTMLDocument2;
  Body:IHTMLElement;
  Links:IHTMLElementCollection;
  i:integer;
  tmp:IHTMLElement;
begin
  try
  Document := (pDisp as  IWebbrowser2).Document AS IHTMLDocument2;
  Body := Document.body;
  Links := Document.links;
  for i := 0 to (Links.length-1) do
    begin
      tmp := (Links.item(i, 0) as IHTMLElement);
      //tmp.onclick := HOW SHOULD I ADD THE CALLBACK HERE?
      //ShowMessage(tmp.innerText);
    end;
  except
    on E : Exception do
      ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
  end;
end;

How could I attach a function/procedure to .onclick to do a simple task like show an alert with the anchor text when the link is clicked?

+3  A: 

One way is to sink events from the TWebBrowser with an object which implements IDispatch (like http://groups.google.com/group/borland.public.delphi.oleautomation/msg/a57d99e0e52c78ce)

you would set

tmp.onclick := TEventObject.Create(callbackProcedure) as IDispatch;
jasonpenny
Thanks, that looks useful. I will try it out.
Sebastian
+1  A: 

I wouldn't recommend using the onXXX-handlers (like onClick) directly as this will replace any previouly attached handler. This can actually change/destroy behavior of the page. If you are working with a web page which is not under your control you better use attachEvent:

(tmp as IHTMLElement2).attachEvent('onclick', callbackProcedureDisp);

And don't forget to detach with detachEvent:

(tmp as IHTMLElement2).detachEvent('onclick', callbackProcedureDisp);

Attention: it is possible to attach the same handler multiple times. In this case your handler would also be called multiple times.

If you are only interested in onclick you could just add one handler to the root element and don't have to travel through all elements. MSDN states the event bubbles, so you could just attach one event handler to the document element and check the srcElement member of the IHTMLEventObj every time the event fires.

Heinrich Ulbricht
good answer! probably didn't receive any upvotes yet because it was late..
Wouter van Nifterick