Click here to Skip to main content
15,883,901 members
Articles / Web Development / HTML

Integrating with Google Maps via a Desktop Application

Rate me:
Please Sign up or sign in to vote.
4.93/5 (9 votes)
15 Jan 2018CPOL4 min read 17.9K   16  
How to integrate with Google Maps via an MFC dialog based application
A while ago, we were asked to create a small Desktop application that will go over photos and extract any Meta Data from them, including the location where each photo was taken (which is a topic for a separate article). To display the result, I looked for a way to display a map, powered by Google Maps, in an MFC application. Here is the solution I have found.

About Google Maps API

According to the Google Maps API "Getting Started" page, "Google Maps APIs are categorized by platform: Web, Android and iOS. These native platform APIs are complemented by our suite of HTTP web services.". As usual, especially these days, you almost never found API code samples for Windows Desktop application, and especially C++ ones.

Hosting a Web Browser in an MFC Application

In order to implement my solution, you would need to host a Web Browser in your MFC application:

  1. Choose an application type.

    Open Visual C++ and follow these steps:

    1. Choose New from the File menu.
    2. Select MFC AppWizard (EXE).
    3. Enter the project name and select a location.
    4. Click OK.
    5. When the dialog box for Step 1 appears, select the application type that is appropriate for your application—single document, multiple document, or dialog-based. Select "Dialog-based" for this example.
    6. Click Next.
  2. Select application features and support.

    The dialog box for Step 2 asks you to select any features and support your application will need—an About box or automation support, for example. The WebBrowser control is an ActiveX control, so select ActiveX Controls. Click Next to go to the next step.

  3. Select the project style.

    The dialog box for Step 3 is used to define your project. You have only one project style option, Standard MFC. But you can indicate whether you want the IDE to generate comments in the source code, and you can specify how you want to use the MFC library. The default selections are appropriate for most applications. Click Next to go to the next step.

  4. Name the files and classes.

    The dialog box for Step 4 displays the names of all the files and classes that Visual C++ created. You can change these to more descriptive names or to names required by your specification. Click Finish.

  5. Add a WebBrowser control.

    You now have a skeleton application. Because this example uses a dialog-based application, a dialog box with OK and CANCEL buttons appears in the Dialog Editor. Follow these steps to add an ActiveX control to the dialog box.

    1. Right-click the Dialog Editor.
    2. Select Insert ActiveX Control from the menu.
    3. Select Microsoft Web Browser.
    4. Click OK.
    5. Position and size the WebBrowser control in the Dialog Editor.
    6. Delete the default OK and CANCEL buttons if your application does not require them.
  6. Add a WebBrowser class and a member variable.

    When you insert a WebBrowser control, an identifier for the control is automatically assigned, but you must provide a member variable to access the control. To add a variable:

    1. Right-click the WebBrowser control.
    2. Select ClassWizard.
    3. Click the Member Variables tab to display the control identifiers.
    4. Select IDC_EXPLORER1.
    5. Click Add Variable, and the following dialog box appears:

      Warning Message

    6. Click OK to display a Confirm Classes dialog box.
    7. Click OK again to add a CWebBrowser2 class to your project.
    8. Enter a name for the control variable.

    You now have an application containing a browser. However, if you compile the code generated by Visual C++ and run the executable file, a browser does not appear.

Obtain Your Google Maps API

Please read the instructions to obtain your API KEY which will be needed for this code.

The Solution

First define a global variable:

C++
//
CExplorer1 m_Browser;
//

After conducting some research, I have found out that the most efficient way to interact with Google Maps would be via a WebBrowser control, and the best way of doing so, is to maintain a temporary HTML file which will then be opened by the WebBrowser control.

We will be using this HTML file during runtime, so we assign its path using the following code:

C++
wchar_t FileName[2048];
GetCurrentDirectory(2048, FileName);
wcscat(FileName, L"\\test.html");

The first building block would be a function for generating (or updating) this file.

Method 1

C++
void WriteHTML(const wchar_t* html)
{
   IDispatch* pHtmlDoc = m_Browser.get_Document();
   if (!pHtmlDoc)
       return;
   CComPtr<IHTMLDocument2> doc1 = NULL;
   doc1.Detach();
   doc1.Attach((IHTMLDocument2*)pHtmlDoc);
   if (!doc1)
       return;

   // Creates a new one-dimensional array
   SAFEARRAY* psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
   if (!psaStrings)
       return;

   BSTR bstr = SysAllocString(html);
   if (bstr)
   {
       VARIANT* param;
       HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
       if (SUCCEEDED(hr))
       {
           param->vt = VT_BSTR;
           param->bstrVal = bstr;
           hr = SafeArrayUnaccessData(psaStrings);
           if (SUCCEEDED(hr))
           {
               doc1->write(psaStrings);
               doc1->close();
           }
       }
   }

   // SafeArrayDestroy calls SysFreeString for each BSTR!
   if (psaStrings)
       SafeArrayDestroy(psaStrings);
 }

Method 2

Assuming you have defined the Longitude and the Latitude along with the level of Zoom (set to "10" in my example), and obtained the API_KEY, you should use the following code:

C++
CoInitialize(NULL);
m_Browser.put_Silent(TRUE);
CString HTML_TEXT;
CRect rect;
CWnd *pWnd = GetDlgItem(IDC_SGWEBBROWSER);
pWnd->GetWindowRect(&rect);
int w = rect.Width()-50, h = rect.Height()-50;

HTML_TEXT.Format(L"<!DOCTYPE html><html>
<meta http-equiv=\"IE X-UA-Compatible\" content=\"IE = edge\">
<body><div id =\"googleMap\" style=\"width:%dpx;height:%dpx\">
<script>function myMap(){var mapProp = {center:new google.maps.LatLng(%f, %f),
zoom : 10};var map = new google.maps.Map(document.getElementById(\"googleMap\"),
mapProp);marker = new google.maps.Marker({position: new google.maps.LatLng(%f, %f),
map: map});}</script>
<script src = \"https://maps.googleapis.com/maps/api/js?key=%s&callback=myMap\">
</script></div></body></html>",
w, h, Latitude, Longitude, Latitude, Longitude, API_KEY);

FILE *fp = _wfopen(FileName, L"w");
fwprintf(fp, L"%s", HTML_TEXT.GetBuffer());
fclose(fp);
m_Browser.Navigate(FileName, 0, 0, 0, 0);

Web Browser Compatibility Issues

Recently, it became harder to use the WebBrowser control for interfacing with APIs such as Google Maps. Read the following article and following the instructions there, you get an error message when trying to display a Google Map in the WebBrowser control.

Basically, you need to manipulate the following Registry key:

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\
Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION

Alternatively, add the META TAG

IE X-UA-Compatible

Displaying the Map

Then, when you wish to display the Google Map in your WebBrowser control, you just call:

C++
m_Browser.Navigate(FileName, 0, 0, 0, 0);

History

  • 15th January, 2018: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Secured Globe, Inc.
United States United States
Michael Haephrati is a music composer, an inventor and an expert specializes in software development and information security, who has built a unique perspective which combines technology and the end user experience. He is the author of a the book Learning C++ , which teaches C++ 20, and was published in August 2022.

He is the CEO of Secured Globe, Inc., and also active at Stack Overflow.

Read our Corporate blog or read my Personal blog.





Comments and Discussions

 
-- There are no messages in this forum --