Loading ...
Sorry, an error occurred while loading the content.

Re: Register C# methods with the SVG event model?

Expand Messages
  • pavoturkey
    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
    Message 1 of 3 , Jun 23, 2006
      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 svg-developers@yahoogroups.com, "waynehet" <waynehet@...> wrote:
      > --- In svg-developers@yahoogroups.com, "pavoturkey" <pavoturkey@>
      > wrote:
      > >
      > > 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.
      > var
      > params3 : ThreeParam;
      > HTMLDocument : MShtml.IHTMLDocument2;
      > SVGViewer : TObject;
      > SVGDocument : TObject;
      > SVGRootElement : TObject;
      > begin
      > try
      > // 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
      > RootElement.
      > SVGViewer := HTMLDocument.embeds.item('svgShell',0);
      > SVGDocument := SVGViewer.GetType.InvokeMember('getSVGDocument',
      > BindingFlags.InvokeMethod, nil, SVGViewer, nil);
      > SVGRootElement :=
      > SVGDocument.GetType.InvokeMember('rootElement',
      > BindingFlags.GetProperty, nil, SVGDocument, nil);
      > // Add the Event Listner here.
      > params3[0] := TObject('click'); // The event will be the mouse
      > click event.
      > params3[1] := TObject(Self); // This form will be the object
      > that catches the event.
      > params3[2] := TObject(false); // Event bubbling is false.
      > // Run the addEventListener method of the rootElement to have
      > this form start listening for clicks.
      > SVGRootElement.GetType.InvokeMember('addEventListener',
      > BindingFlags.InvokeMethod, nil, SVGRootElement, params3);
      > except
      > Debug.Write('Cannot add event listener.');
      > end;
      > end;
      > ---
      > This is the code that actually receives the click event.
      > procedure TSVGMapWindow.handleEvent(evt: TObject);
      > var
      > targetElement : TObject;
      > begin
      > if Assigned(evt) then
      > begin
      > targetElement := nil;
      > try
      > // 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);
      > except
      > Debug.Write('No target for this event.');
      > end;
      > end;
    Your message has been successfully submitted and would be delivered to recipients shortly.