Resolved No longer able to see a Google Map in a WebBrowser

jackrabbit

Member
Joined
Jan 29, 2018
Messages
5
Programming Experience
10+
I have a program that has been running fine for years (VisualStudio 2015, Framework 4.6.1). As part of the program, I have a WebBrowser that can run a PHP page that draws a Google Map at a specific Map type / Longitude / Latitude / Zoom. Unfortunatly, everything when to a halt in February 2022, it just started showing java script errors instead of displaying the map.

For example, to display a map of Central Park, NY, my C# code looks like:

C# program:
string Map = "N";
string Lon = "-73.9665";
string Lat = "40.7812";
string Zoom = "14";
string Url = string.Format("http://MySite.com/MyMap.php?v={0}&x={1}&y={2}&z={3}", Map, Lon, Lat, Zoom);
webBrowser1.Navigate(Url);

This would call my PHP script with the URL "http://MySite.com/MyMap.php?v=N&x=-73.9665&y=40.7812&z=14". Here is what my PHP page looks like:

PHP:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<style type="text/css">
  html { height: 100% }
  body { height: 100%; margin: 0px; padding: 0px }
  #map_canvas { height: 100% }
  .infomsg { display:none }
</style>

<script type="text/javascript"
    src="https://maps.google.com/maps/api/js?key={GoogleKEY}">
</script>

<script type="text/javascript">
var map;
var mapOptions = { tilt: 0, disableDefaultUI: true };

// Redraw map in a new location
function redraw(newview, newlat, newlon, newzoom) {
  if (newview == 'H')
    mapOptions.mapTypeId = google.maps.MapTypeId.HYBRID;
  else if (newview == 'P')
    mapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN;
  else
    mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;

  mapOptions.zoom = newzoom;
  mapOptions.center = new google.maps.LatLng(newlat, newlon);

  if (!map)
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  else
    map.setOptions(mapOptions);
}

// Open map with requested URL parameters
function initialize() {
  var view = '<?php echo $_GET["v"]; ?>';
  var lon = <?php echo $_GET["x"]; ?> + 0;
  var lat = <?php echo $_GET["y"]; ?> + 0;
  var zoom = <?php echo $_GET["z"]; ?> + 0;
  redraw(view, lat, lon, zoom);
}
</script>

</head>
<body onload="initialize()">
  <div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>

Instead of getting my Google map as before, I now only get the popup. No changes were made to my program, so Google must have changed a script within the map:

ScriptError.png


If I call my PHP script with any browser, it displays my Google Map properly, except for IE 11 where I get a blank screen with the following error on the Console:

IeError.png


I know for a fact that the WebBrowser uses Internet Explorer internally, which support stops in August 2022. Somehow, it looks like Google decided to pull the plug a few months before that deadline.

What will happen with the WebBrowser after that, will it become unusable?
Is there an alternative way to call a PHP script that draws a Google map in a VisualStudio application?
Is there anyone that has a piece of code that still works to display a Google Map?

I know I can still use the following code without a PHP script, but the resulting map if clothered with unwanted popups, and I sill get a warning about Internet Explorer:

C#:
webBrowser1.Navigate("https://www.google.ca/maps/@40.7812,-73.9665,14z");

Alternative.png
 
Moved over to GUI...

Basically you need to find a replacement for the WinForms WebBrowser control with defaults to the Trident engine. I suspect that you aren't the only one with this problem considering that Microsoft has extended the life of WinForms by including it in .NET Core 3.0 and higher.
 
I had some problem with the webBrowser (can't remember exactly what) which made me switch to the CEF browser. This works correctly except hat it refuses to access local images (i.e. on your computer) unless you write a handler for that. It took me some time to sort that out but it works fine now.
 
Wow I did not know about the new WebView2 control! Thanks

I quickly replace my "WebBrowser1.Navigate("...") to a WebView21.Source = new Uri("...") and my map was being drawned again !!!

Now the only thing I can't figure out is to replace the call to my JavaScript function when I want to change the View, Lat, LOn or Zoom of my map by calling the "redraw" JavaScript function:

Old code:
C#:
 WebBrowser1.Document.InvokeScript("redraw", New Object() {NewView, NewLat, NewLon, NewZoom})
NewCode inspired by what I read in different example, compiles but still does not produce any result:
C#:
        using Newtonsoft.Json; // Added NuGet package
        private void btnZoom_Click(object sender, EventArgs e)
        {
            NewZoom++;
            dynamic Obj = new System.Dynamic.ExpandoObject();
            Obj.newview = NewView;
            Obj.newlat = NewLat;
            Obj.newlon = NewLon;
            Obj.newzoom = NewZoom;
            string Data = JsonConvert.SerializeObject(Obj);
            string Script = $"redraw({Data})";
            webView.ExecuteScriptAsync(Script);
        }
Any idea? Easier ways to call a JavaScript function, ideally that would work in C# and VB.NET (one of my programs is still in VB.NET) ?
 
Last edited by a moderator:
I had some problem with the webBrowser (can't remember exactly what) which made me switch to the CEF browser. This works correctly except hat it refuses to access local images (i.e. on your computer) unless you write a handler for that. It took me some time to sort that out but it works fine now.

I also looked at this solution which looks interesting. I still can't managed a call to my JavaScript function "redraw(NewView, NewLat, NewLon, NewZoom)" with this package, Do you have any simple example of a call with strings, floats and integer parameters?
 
I'm no JavaScript expert, but my reading of your redraw() function on post #1 is that it takes 4 parameters:
C#:
function redraw(newview, newlat, newlon, newzoom)

So why pussyfoot around with trying to pass in an object? Why not just call it straight on passing parameters?
C#:
private void btnZoom_Click(object sender, EventArgs e)
{
    NewZoom++;
    webView.ExecuteScriptAsync($"redraw({NewView}, {NewLat}, {NowLon}, {NewZoom})");
}
 
Never mind, I accidentally came accross the solution when I Googled the meaning of that $ (string interpolation).

I rewrote my code and it now works perfectly in both WebView2 and CefSharp solutions. I finally chose to use the WebView2 solution because it only adds a few files totalling 0.3 Mb to my deployment package, while the CefSharp solution adds 100 files totalling 72 Mb to my deployment package.
C#:
        private void btnZoom_Click(object sender, EventArgs e)
        {
            NewZoom++;
            string Script = $"redraw(\"{NewView}\", {NewLat}, {NewLon}, {NewZoom})";
            webView.ExecuteScriptAsync(Script);
        }
Thanks for all your input !!!
 
Last edited:
Back
Top Bottom