Windows Develop Bookmark and Share   
 index > Windows Forms General > Virtual Earth control - works in VB - not in C# "'Window.External' is null or not an object"
 

Virtual Earth control - works in VB - not in C# "'Window.External' is null or not an object"

Joshua Trupin posted a nice piece of VB code - http://msdn.microsoft.com/msdnmag/code/default.aspx?level=root%2cGeoPegger&url=http%3a%2f%2fmsdn.microsoft.com%2fmsdnmag%2fissues%2f07%2f04%2fEndBracket%2fdefault.aspx- which uses a Browser control to run Virtual Earth. When I try to duplicate in C#, the map displays, but when I try and use the mouse anywhere on the map, I imediately get a string of "'Window.External' is null or not an object" errors.

Has anyone experienced this problem and do you know what I'm bumping up against? It won't debug.

Entire code is as follows:

public Form1()

{

InitializeComponent();

SetVEScript();

}

private void Form1_Load(object sender, EventArgs e)

{

VEBrowse.AllowWebBrowserDrop = false;

VEBrowse.IsWebBrowserContextMenuEnabled = false;

VEBrowse.WebBrowserShortcutsEnabled = false;

VEBrowse.ObjectForScripting = this;

}

private void SetVEScript()

{

string vehtml = "<html><head><title></title>" + Environment.NewLine;

vehtml += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" + Environment.NewLine;

vehtml += "<script src=\"http://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js\"></script>" + Environment.NewLine;

vehtml += "<script>var map = null;" + Environment.NewLine;

vehtml += "function GetMap()" + Environment.NewLine;

vehtml += "{ ";

vehtml += " map = new VEMap('myMap');";

vehtml += " map.LoadMap(); ";

vehtml += " map.AttachEvent(\"onclick\", MapClick);";

vehtml += "}" + Environment.NewLine;

vehtml += "function MapGoTo(lat,lng)" + Environment.NewLine;

vehtml += "{ ";

vehtml += " map.SetCenterAndZoom(new VELatLong(lat,lng),15);";

vehtml += "}" + Environment.NewLine;

vehtml += "function MapClick(e) ";

vehtml += "{ ";

vehtml += "window.external.NewLoc(\" \" + e.view.latlong.latitude + \",\" + e.view.latlong.longitude );";

vehtml += " }" + Environment.NewLine;

vehtml += "</script>" + Environment.NewLine;

vehtml += "</head>" + Environment.NewLine;

vehtml += "<body onload=\"GetMap();\">" + Environment.NewLine;

vehtml += "<div id='myMap' style=\"position:relative; width:" + (VEBrowse.Width - 10) + "px; height:" + (VEBrowse.Height - 10) + "px;\"></div>" + Environment.NewLine;

vehtml += "</body> </html>" + Environment.NewLine;

VEBrowse.DocumentText = vehtml;

}

private void VEBrowse_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)

{

}

private void button1_Click(object sender, EventArgs e)

{

SetVEScript();

}

Tony H  Thursday, April 26, 2007 6:11 PM

The initial class was missing the following statement . . .

Load += new EventHandler(Form1_Load);

So it should have looked like

public Form1()

{

InitializeComponent();

Load += new EventHandler(Form1_Load);

}

All fixed now.

Tony H  Monday, April 30, 2007 2:21 PM
It could be due to a problem in the generated html, instead of doing the +=, do this with the @ to make sure that the \ does not act an escape such as

Code Snippet


VEBrowse.DocumentText = string.Format(@"<Title>{0}function GetMap(){0}
position:relative; width:{1}</Title>{0}",

System.Environment.NewLine, // 0

(VEBrowse.Width - 10)); // 1




I use {0} to be a new line and it can be replicated across many lines. If you do it this way with the values passed in as variables, it is much easier to read and maintain.


OmegaMan  Thursday, April 26, 2007 7:48 PM
While the string.format might help, the example you cite loses the " that I'm trying to include in the string. SInce the html I'm loading is quite long and builds several functions to execute, I think the += works better. It appears to fail in the mapclick function which need to return a logitude lattitude pair.
Tony H  Thursday, April 26, 2007 9:16 PM
Tony H wrote:
While the string.format might help, the example you cite loses the " that I'm trying to include in the string. SInce the html I'm loading is quite long and builds several functions to execute, I think the += works better. It appears to fail in the mapclick function which need to return a logitude lattitude pair.


That is fine, no problem with that, just add the @ the the quotes so anytime there is a \ it is not interpreted as an escape and sending the wrong info to the service.

I recommend that you view the generated html to make sure it is what should be sent...
OmegaMan  Thursday, April 26, 2007 9:33 PM

I have isolated the error to this line -

function MapClick(e) ";

vehtml += "{ ";

vehtml += "window.external.NewLoc(\" \" + e.view.latlong.latitude + \",\" + e.view.latlong.longitude );";

vehtml += " }" + Environment.NewLine;

Specifically the window.external.NewLoc(string) call. I think the issue is the reference type I'm using for NewLoc. It needs to be a by value string and NewLoc(string str) doesn't work.
Tony H  Thursday, April 26, 2007 9:51 PM

The initial class was missing the following statement . . .

Load += new EventHandler(Form1_Load);

So it should have looked like

public Form1()

{

InitializeComponent();

Load += new EventHandler(Form1_Load);

}

All fixed now.

Tony H  Monday, April 30, 2007 2:21 PM

Hi, Tony!

I can't run similar code (after failure I'd tried your exact example too). I am getting:

"ObjectForScripting's class must be visible to COM. Verify that the object is public, or consider adding the ComVisible attribute to your class."

Any ideas how this can be resolved? I already tried to chnage VEBrowser's private to public, same result...

Thank you

olelukoyya  Wednesday, July 30, 2008 8:39 PM
Yea i have been banging my head against the wall looking for an answer for days, and all my searching turned up nothing helpful! Finally I decide to ask for help on a forum and a little search window pops up with possibly useful threads, so i click this one and it gave me a strange half working link to working code. I had to figure where the url was supposed to be going (april '07 geoPegger, by the way) before i could even get the code. but once i found it i trialed and erred to figure it out.

sorry i had to tell someone about my problems cause theres noone here who will listen

any ways

I looked at the working code and copied his header into mine.
You need to include system.security.permissions, and specify some things in your class declaration. Here is mine

Code Snippet

Imports System.Security.Permissions

<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Form1


You must also specify the objectForScripting,


Code Snippet

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
wbVEMap.ObjectForScripting = Me
wbVEMap.Navigate("file:///C:/VirtualEarthProject/VirtualEarth.html") ' I have my script in its own html file
' it works either way
End Sub

Then finally, because i want to put it all in one place so anybody else banging their head against a wall can hopefully stop, in your script simply callwindow.external.methodName(params) to access "methodName" in your vb code.

note: IDispatch is totally unneeded and i hate MSDN for telling me i might need to implement it

I hope that helps

Josh
im_still_learning  Wednesday, August 06, 2008 11:28 PM

You can use google to search for other answers

Custom Search

More Threads

• Source Safe, IIS, and Apache
• Changing the form title text programmatically
• browser control
• Rulers.........
• Problem with the webbrowser Control when Navigating
• ComboBox and HashTable
• How to run a form in a loop
• web browser control (WebBrowserControl) and history.
• retreiving treeview nodes
• Problem with MSword docs that automatically opens in ie7