Closed GoogleCodeExporter closed 9 years ago
If you actually read the StackTrace - you can clearly see that you are getting
errors in the native browser web browser control...
'System.Windows.Forms.UnsafeNativeMethods.IHTMLDocument2.GetLocation()'
This is *not* called by the control library - it is something in your code.
The same is true for...
XXX.PlacemarkFactory.CreatePlacemark() in XXX.PlacemarkFactory.cs:line 48
So the fault is in code that is not part of the library.
If general, if you are calling `GEWebBrowser.AddEventListener` outside the
plugin ready event then you should ensure that the plug-in is really ready
before calling the method.
i.e.
if(geWebBrowser1.pluginIsReady)
{
geWebBrowser1.AddEventListener(...
Original comment by fraser.c...@gmail.com
on 29 Mar 2013 at 3:19
Also, if you are testing code you should try compiling with the debug flag set
and check for any error messages.
Original comment by fraser.c...@gmail.com
on 29 Mar 2013 at 3:35
I understand that the exception is coming from the native web browser. I am
definitely calling after the browser plugin in ready and the globe is fully
displayed. The work-around I have for this issue is to pre-generate a bulk set
of placemarks in the plugin ready callback and register for events then. After
I do that I can just grab the placemarks and fill in what I need and things
work fine. It just seems weird that I can register for events during the plugin
ready callback, but after things fail.
From the debugger window, I have no inner exceptions. The exception raised is
System.InvalidCastException, and the stack trace provided earlier.
Original comment by john.s.o...@gmail.com
on 29 Mar 2013 at 3:47
[deleted comment]
> If you do get errors - check the objects you are passing to AddEventListener,
are they all initialized, etc?
This is the what I am doing internally when I create the placemark and register
for events. The placemark is successfully generated as I get back a type of
"KmlPlacemark".
dynamic placemark = this.ge.createPlacemark("");
string type = placemark.GetType();
this.browser.AddEventListener(placemark, EventId.Click);
this.browser.AddEventListener(placemark, EventId.DblClick);
this.browser.AddEventListener(placemark, EventId.MouseDown);
this.browser.AddEventListener(placemark, EventId.MouseMove);
this.browser.AddEventListener(placemark, EventId.MouseOut);
this.browser.AddEventListener(placemark, EventId.MouseUp);
> It very much sounds like you are trying to do something; create placemarks,
add events, etc - *before* the plugin is ready - if it works when it is ready
(you are 100% in the ready callback) but not otherwise then I would be fairly
sure that this is the issue.
Again, I doing this well after the plugin ready event has been fired. I even
added a pause in the method where the placemark is generated to wait if the
browser PluginIsReady property is false, ie,
while (this.browser.PluginIsReady == false)
System.Threading.Thread.Sleep(100);
...
// create and register for placemarks
And I'm fairly certain the placemarks are valid, since if I don't attempt to
register for events, I am able to successfully fill in geometries and what not
and have the placemarks appear in the Google Earth plugin and interact with
them in the standard click the object and get a balloon.
Original comment by john.s.o...@gmail.com
on 29 Mar 2013 at 4:22
So what code is making a call to the native GetLocation() method? It isn't part
of this library.
As I indicated, it very much sounds to me like you are trying to do something;
create placemarks, add events, work with KML/DOM objects, etc - before either
the plugin/document is fully ready - somewhere, somehow in code that isn't part
of this library you are probably trying to work with something that isn't
initialised...
If it works when it is ready (you are 100% in the ready callback) but not
otherwise then I would be fairly sure that this is the issue.
If you are making calls on IHTMLDocument2 then are you sure the document is
ready, accessible, etc? How are you sure? The following simple test will show
you can add an event outside the actual plugin ready method.
Move all and only the event adding code from your current plugin ready method
to a new one, i.e.
void foo(dynamic ge) {
geWebBrowser1.AddEventListener( ...
}
Then call this new method from the one you just modified, i.e.
void MyPluginReady(object o, GEEventArgs e) {
//...
foo(e.ApiObject);
}
Does this work? It really should, but if not and you do get errors with this
simple case then check the objects you are passing to AddEventListener, are
they all initialized, etc? Also, what else are you doing in your 'PluginReady'
event handler? If you redirect debug/trace to the console, what is the output?
Original comment by fraser.c...@gmail.com
on 29 Mar 2013 at 4:27
This works, but it always has. Maybe there's a misunderstanding. I've wrapped
the GoogleEarth API into a Winform App. So the user is able to create new
objects at any time. So where I'm getting errors is after the Google Earth
Plugin has fired up and the PluginReady event has completed, ie, all the event
handler methods have completed and the app is now just waiting for the user to
do something.
So after Google Earth is up and running, the user creates a new object, foo,
which results in a new placemark being created in Google Earth. At that time, I
can successfully create the placemark, fill in its geometry / styles, etc, and
get Google Earth to render that object. What I cannot successfully do is
register for events, which is where the exception is getting raised.
Does that help clarify ?
// Updated to register for events
public void GEPluginReady(object sender, GEEventArgs e)
{
this.browser = sender as GEWebBrowser;
this.ge = e.ApiObject;
this.browser.KmlEvent += EventBroadcaster.Instance.KmlEventHandler;
for (int i = 0; i < PlacemarkCount; ++i)
{
dynamic placemark = this.ge.createPlacemark("");
this.RegisterForEvents(placemark);
this.placemarks.Push(placemark);
}
}
private void RegisterForEvents(dynamic placemark)
{
this.browser.AddEventListener(placemark, EventId.Click);
this.browser.AddEventListener(placemark, EventId.DblClick);
this.browser.AddEventListener(placemark, EventId.MouseDown);
this.browser.AddEventListener(placemark, EventId.MouseMove);
this.browser.AddEventListener(placemark, EventId.MouseOut);
this.browser.AddEventListener(placemark, EventId.MouseUp);
}
Original comment by john.s.o...@gmail.com
on 29 Mar 2013 at 4:42
So I guess the overarching question I have is
Is the Google Earth Plugin in some special state during the plugin callback
that allows you to successfully register for events? I understand that there is
some magic / handwaving going on in the background to bind the JavaScript
events to C# events. Is the time you are able to do that binding specific to
the PluginReady callback event ?
Original comment by john.s.o...@gmail.com
on 29 Mar 2013 at 4:46
No there is no special state...there is nothing to stop one adding events
outside the ready method in the library...
Could it be that you are simply trying to add events to 'foo' before you have
added it to the plugin...For example, are you calling
ge.getFeatures().appendChild(foo);
before you call...
this.browser.AddEventListener(foo, EventId.Click);
Also, how are you creating the actual Placemarks, what dos the "factory" do?
Original comment by fraser.c...@gmail.com
on 30 Mar 2013 at 3:12
Original comment by fraser.c...@gmail.com
on 8 Apr 2013 at 6:41
Original issue reported on code.google.com by
john.s.o...@gmail.com
on 27 Mar 2013 at 1:41Attachments: