This is my first blog post EVER so I hope some one finds it usefull. I'm trying to give back to the community since I have benifitted so much from other people's posts.
Background:
I have been trying to display a context menu when a user right-clicks anywhere in the window and I've had problems similar to those described by mikemcc
Specifically the "mini-navigation control" is displayed and the mouse up event does not seem to be activated.
The application I am writing is in Windows Presentation Foundation (WPF) and I am hosting a Google Earth enabled web page in a WebBrowser control.
In the JavaScript page for google earth I am using windows extensions so I can write the bulk of the code in C# since I am more familliar with this than JavaScript.
The code is similar enough that it should be understandable. For people who want to do this all in JavaScript there is no reason my C# functions could not be ported ito the JavaScript event handlers.
If anyone is interested in taking the C# combined with JavaScript approach that I am using be WARNED that the windows extensions will not work with older versions of Google Earth Plugin.
I'm not sure which versions don't work but I think you have to use at least version 6.
I'm using Google Earth Plugin version 6.0.3.2197.
If anything is not clear or you have problems let me know.
Solution:
The basic solution is that you HAVE to have a mousedown event handler with e.preventDefault() in it and the context menu MUST be opened in a mouseup event handler.
See code sections below.
I know it looks easy now but I spent a lot of time trying different approaches to get this to work.
Question:
I'm not sure what the defaults are for the left, middle, and right mouse clicks and therefore I'm not sure when to use e.preventDefault().
I've been using a trial and err approach.
If anyone knows about this I would be happy to see a post.
JavaScript Code:
//standard Google Earth Plugin creation function.
function init() {
google.earth.createInstance('map3d', initCallback, failureCallback);
}
function initCallback(pluginInstance) {
ge = pluginInstance;
ge.getWindow().setVisibility(true);
// tell the application the plugin is ready
window.external.JSInitSuccessCallback_(pluginInstance); //this calls a C# function that returns the plugin instance object and allows me to do other initialization in the C# code.
//setup javascript mousedown and mouseup event handlers.
google.earth.addEventListener(ge.getWindow(), 'mousedown', MouseDownEventHandler, false);
google.earth.addEventListener(ge.getWindow(), 'mouseup', MouseUpEventHandler, false);
}
function MouseDownEventHandler(event) {
window.external.csGE_MouseDown_EventHandler(event); //Handler in C# code see below.
}
function MouseUpEventHandler(event) {
window.external.csGE_MouseUp_EventHandler(event); //Handler in C# code see below.
}
C# Code:
public void csGE_MouseDown_EventHandler(KmlMouseEventCoClass e)
{
e.preventDefault(); //This is needed to prevent going into navigation mode when the mouse is right clicked.
//Without this the first right-click will bring up the context menu like it should but after that
//it display's the mini-navigation control and does not work right.
}
//This was originally tied to the MouseDown event but this caused a problem.
//When used with the wb.ContextMenu the mouse up event was not captured by GE and the globe would move around after the context menu was closed.
public void csGE_MouseUp_EventHandler(KmlMouseEventCoClass e)
{
if (e.getTarget().getType().Equals("KmlPlacemark"))
{
KmlPlacemarkCoClass pm = (KmlPlacemarkCoClass)e.getTarget();
if (e.getButton().Equals(KmlMouseButton.Left) )//if left click and placemark show the description info in full( with css/html/javascript)
{
// Prevent the default balloon from appearing. This didn't seem to be needed.
//e.preventDefault();
string descriptionStr = pm.getDescription();
GEHtmlStringBalloonCoClass balloon = ge.createHtmlStringBalloon("");
balloon.setFeature(pm);
balloon.setContentString(descriptionStr);
ge.setBalloon(balloon);
}
else if (e.getButton().Equals(KmlMouseButton.Right) )
{
IKmlObject ko = pm.getParentNode();
string pmName = pm.getName();
object ro = pm.getRootObject();
string r = ro.ToString();
//these didn't seem to be needed here.
//e.preventDefault();
//e.stopPropagation();
// check to see if this is a KmlFolder.
string s = ko.getType();
if (ko.getType().Equals("KmlFolder")) //make sure this is a folder.
{
//there was some other code here but it was not relevant to the solution being demonstrated.
wb.ContextMenu.IsOpen = true; //This causes the WebBrowser's Context menu to be displayed when a placemark is right-clicked. //
//The Context Menu is defined elsewhere and not shown here.
}
}
}
else if (e.getButton().Equals(KmlMouseButton.Right))
{
//these didn't seem to be needed here.
//e.preventDefault();
//e.stopPropagation();
wb.ContextMenu.IsOpen = true; //This causes the WebBrowser's Context menu to be displayed a user right-clicks on anything that is not a placemark.
}
}