Re: Register C# methods with the SVG event model?
- Hi Waynehet,
Thanks so much for the insight. Your explanation is very detailed and
well explained and exactly what I have been looking for. I will give
this a shot. I'll let you know if I'm successful. Thanks a bunch!
--- In firstname.lastname@example.org, "waynehet" <waynehet@...> wrote:
> --- In email@example.com, "pavoturkey" <pavoturkey@>
> > I have embedded an IE WebBrowser control inside a windows C# form. I
> > am using the WebBrowser control to load in an svg document. I was
> > wondering if there is any way to register methods in my C# form to the
> > svg document events? I want to be able to listen to svg "onmouseclick,
> > onmouseover, etc." events occuring within the svg document in my
> > WebBrowser control and trigger a method call present in my C#
> > application. Does anyone know if this is possible or if you have had
> > success implementing something of this nature? Thanks.
> Yes this is possible. I have been working on something very similar
> in Delphi for the past while and have finally gotten it working! I
> have an html file that defines an embedded svg file which I load into
> the Webbrowser control (EI6 with ASV3.03) on a form. Then I hook up
> event listeners to capture click events.
> The first confusing part was the fact that you must wait until the
> browser control finishes loading the file (which happens async) before
> you can get at the svg file. Use the DocumentComplete event of the
> browser control for this.
> Once the document is loaded you can get a reference to the html
> document in the browser using the browser.document property. Then you
> can use the html dom to get a reference to the svg document using the
> 'embeds' property and the 'getSVGDocument' method. Note that .NET has
> no idea what objects/methods are available in the dom so you have to
> use reflection to get the object types and InvokeMember to call methods.
> Now that you have the svg document you can use svg dom methods (via
> reflection) to capture click events. The dom addEventListener method
> takes three arguments: 1. The name of the event you wish to capture -
> in this case 'click' 2. The object that handles the event - in this
> case it will be the .NET form that contains the browser control 3. A
> boolean flag to indicate if the event should continue to bubble up -
> normally false unless you have multiple event handlers. These three
> parameters need to be put into an object that can be passed in the
> InvokeMember call. I made myself a record of the type 'object array'
> which could hold the parameters and then just passed the record into
> the invoke of the addEventListner.
> The only remaining part is the actual event handler. Define a
> function on the browser form like this: 'handleEvent(evt: TObject)'.
> This function acts as a delegate and will end up getting called
> whenever a click happens. The parameter of the event is an object
> that is the svg shape that was clicked on. Once you have the object
> you can do whatever you like with it - such as get its ID or name.
> One other thing that I found really confusing at first was that the
> svg dom is case sensitive and you must follow the odd capitalization
> exactly or the functions won't get called properly.
> Hope this helps, Wayne
> Code Samples:
> This is the record to hold the parameters for addEventListener.
> type ThreeParam = array[0..2] of TObject;
> This is the code to hook the form up as the handler of svg events.
> params3 : ThreeParam;
> HTMLDocument : MShtml.IHTMLDocument2;
> SVGViewer : TObject;
> SVGDocument : TObject;
> SVGRootElement : TObject;
> // The following snippet can be used in the
> "AxWebBrowser1_DocumentComplete" event of an embedded
> // webbrowser window to obtain a reference to a SVG document
> that had been loaded into a web browser's
> // ASV plugin.
> // The webbrowser has just finished loading the basic html
> document which embeds the SVG shell.
> HTMLDocument := Self.AxWebBrowser1.Document;
> // Get a reference to the SVGWindow, SVGDocument and the
> SVGViewer := HTMLDocument.embeds.item('svgShell',0);
> SVGDocument := SVGViewer.GetType.InvokeMember('getSVGDocument',
> BindingFlags.InvokeMethod, nil, SVGViewer, nil);
> SVGRootElement :=
> BindingFlags.GetProperty, nil, SVGDocument, nil);
> // Add the Event Listner here.
> params3 := TObject('click'); // The event will be the mouse
> click event.
> params3 := TObject(Self); // This form will be the object
> that catches the event.
> params3 := TObject(false); // Event bubbling is false.
> // Run the addEventListener method of the rootElement to have
> this form start listening for clicks.
> BindingFlags.InvokeMethod, nil, SVGRootElement, params3);
> Debug.Write('Cannot add event listener.');
> This is the code that actually receives the click event.
> procedure TSVGMapWindow.handleEvent(evt: TObject);
> targetElement : TObject;
> if Assigned(evt) then
> targetElement := nil;
> // Make sure we have a valid event and can get at the
> targetElement of the event.
> targetElement := evt.GetType.InvokeMember('target',
> BindingFlags.GetProperty, nil, evt, nil);
> Debug.Write('No target for this event.');