通过桌面应用程序与 Google 地图集成






4.93/5 (9投票s)
如何通过基于 MFC 对话框的应用程序与 Google 地图集成
关于谷歌地图 API
根据谷歌地图 API 的“入门”页面,“谷歌地图 API 按平台分类:Web、Android 和 iOS。这些原生平台 API 由我们的 HTTP Web 服务套件提供补充。” 一如既往,尤其是在当今,你几乎找不到适用于 Windows 桌面应用程序的 API 代码示例,尤其是 C++ 的。
在 MFC 应用程序中托管 Web 浏览器
为了实现我的解决方案,你需要在你的 MFC 应用程序中托管一个 Web 浏览器
- 选择应用程序类型。
打开 Visual C++ 并按照以下步骤操作
- 从“文件”菜单中选择“**新建**”。
- 选择“**MFC 应用程序向导(EXE)**”。
- 输入项目名称并选择一个位置。
- 点击**确定**。
- 当出现第 1 步的对话框时,选择适合你应用程序的应用程序类型——单文档、多文档或基于对话框。在本示例中,请选择“**基于对话框**”。
- 点击**下一步**。
- 选择应用程序功能和支持。
第 2 步的对话框会询问你选择应用程序所需的功能和支持——例如,“**关于**”框或自动化支持。 **WebBrowser** 控件是一个 ActiveX 控件,因此请选择 ActiveX 控件。单击“**下一步**”进入下一步。
- 选择项目样式。
第 3 步的对话框用于定义你的项目。你只有一个项目样式选项,标准 MFC。但是,你可以指示是否希望 IDE 在源代码中生成注释,并指定如何使用 MFC 库。默认选择适用于大多数应用程序。单击“**下一步**”进入下一步。
- 命名文件和类。
第 4 步的对话框显示了 Visual C++ 创建的所有文件和类的名称。你可以将它们更改为更具描述性的名称,或更改为你的规范所需的名称。单击“**完成**”。
- 添加一个 **WebBrowser** 控件。
现在你已经有了一个骨架应用程序。由于本示例使用的是基于对话框的应用程序,因此一个带有“**确定**”和“**取消**”按钮的对话框会出现在“**对话框编辑器**”中。按照以下步骤将 ActiveX 控件添加到对话框。
- 右键单击“**对话框编辑器**”。
- 从菜单中选择“**插入 ActiveX 控件**”。
- 选择“**Microsoft Web Browser**”。
- 点击**确定**。
- 在“**对话框编辑器**”中定位和调整 **WebBrowser** 控件的大小。
- 如果你的应用程序不需要默认的“**确定**”和“**取消**”按钮,请删除它们。
- 添加一个
WebBrowser
类和一个成员变量。当你插入一个 **WebBrowser** 控件时,会为其自动分配一个标识符,但你必须提供一个成员变量来访问该控件。要添加变量
- 右键单击 **WebBrowser** 控件。
- 选择“**类向导**”。
- 单击“**成员变量**”选项卡以显示控件标识符。
- 选择“**IDC_EXPLORER1**”。
- 单击“**添加变量**”,然后出现以下对话框
- 单击“**确定**”以显示“**确认类**”对话框。
- 再次单击“**确定**”以将
CWebBrowser2
类添加到你的项目中。 - 为控件变量输入一个名称。
现在你有一个包含浏览器的应用程序。但是,如果你编译 Visual C++ 生成的代码并运行可执行文件,浏览器不会出现。
获取你的谷歌地图 API
请阅读说明以获取你代码所需的 API KEY。
解决方案
首先定义一个全局变量
//
CExplorer1 m_Browser;
//
经过一些研究,我发现与谷歌地图交互最有效的方式是通过 WebBrowser
控件,而做到这一点的最佳方法是维护一个临时 HTML 文件,然后由 WebBrowser
控件打开。
我们将在此运行时使用此 HTML 文件,因此我们使用以下代码为其分配路径
wchar_t FileName[2048];
GetCurrentDirectory(2048, FileName);
wcscat(FileName, L"\\test.html");
第一个构建块将是一个用于生成(或更新)此文件的函数。
方法 1
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*)¶m);
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);
}
方法 2
假设你已经定义了 Longitude
和 Latitude
以及缩放级别(在我的示例中设置为“10
”),并且已经获取了 API_KEY
,你应该使用以下代码
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 浏览器兼容性问题
最近,使用 WebBrowser
控件与谷歌地图等 API 进行接口变得更加困难。请阅读以下文章并按照其中的说明操作,当你尝试在 WebBrowser 控件中显示谷歌地图时会收到一条错误消息。
基本上,你需要修改以下注册表项
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\
Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
或者,添加 META 标记
IE X-UA-Compatible
显示地图
然后,当你希望在 WebBrowser
控件中显示谷歌地图时,只需调用
m_Browser.Navigate(FileName, 0, 0, 0, 0);
历史
- 2018 年 1 月 15 日:初始版本