65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Win32、C++ 和 WinInet 下载 Google 地图

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (15投票s)

2011 年 3 月 20 日

CPOL

4分钟阅读

viewsIcon

53395

downloadIcon

2544

我们使用纯 Win32、WinInet 和 STL 向量,建立 Internet 连接,下载并显示 Windows Mobile 手机上的 Google 地图。

引言

最近在一个嵌入式 Windows CE 项目(没有,它还没有死,至少现在还没有)上工作时,一位同事的任务是从文件系统中读取 JPEG 和 PNG 图像,但他需要将它们转换为纯 Win32 HBITMAP 图像,以匹配他需要调用的第三方库函数的签名。我建议他使用 COM IImagingFactory 将图片加载到 IImage 对象中,然后简单地将它们绘制到 GDI 设备上下文中,并从中提取生成的位图。他不确定如何做到这一点,所以在 4 个小时和几瓶比利时啤酒的时间里,我为他写了一个小示例。

背景

为了使项目更有趣,并向他展示正在工作的代码,我决定为我可以在办公室带来的 Windows Mobile 6.5 手机编写示例。我没有仅仅从文件系统或嵌入式资源读取图像,而是扩展了这个示例来解决一个常见问题,即通过无线 Internet 读取 Google 地图。

以下是完成应用程序的一些屏幕截图。第一个简单地显示了程序的说明,即从“帮助 -> 获取地图”菜单中选择一个要显示的城市,第二个显示了在屏幕上检索到的西雅图的 Google 地图。请注意,这些屏幕截图是从 Windows Mobile 6.5 QVGA 模拟器中拍摄的,该模拟器从 Visual Studio 启动,并且您必须通过模拟器路由网络连接才能实际下载和显示地图。

这可以通过选择模拟器“文件”菜单中的“配置”选项,单击“网络”选项卡,然后选中“启用 NE2000 PCMCIA 网络适配器并绑定到:”复选框,并选择一个有效的网络适配器来轻松完成。网上有很多文章介绍了如何配置 Windows Mobile 模拟器以进行 Internet 连接,所以我在这里就不详细介绍了。

图 1 - 开始屏幕
图 2 - 西雅图地图

Using the Code

代码内部有很好的文档记录,并说明了许多有趣且有用的技术,例如使用 std::vector 来保存指向动态分配的内存块的指针,这些内存块用于从 Internet 读取 Google 地图图像,使用 IImagingFactory 将此内存转换为 IImage ,然后将生成的图像绘制到设备上下文中,并通过 C++ 引用返回 HBITMAP

其他有用的部分包括创建和销毁字体、在屏幕上居中绘制文本和图像,以及注册/响应用于指示用户更改默认系统字体大小的 Windows CE SH_UIMETRIC_CHANGE 消息。

为了方便起见,我们在 DisplayInstructions 函数中使用了 ATL CString 对象,它非常类似于 MFC 的 CString ,并且我展示了如何使用 Win32 的 GetTextExtentPoint32 来计算 string 的像素大小,以便我们可以在屏幕中央显示它。

最有趣的功能是 GetGoogleMap ,它展示了如何在手机上建立 Internet 连接,连接到 maps.google.com,并检索地图图像。

关注点

尽管 Windows Mobile 6 已被 Windows Phone 7 所取代,但我发现很有趣的是,在撰写本文时(2011 年 3 月),旧的 Windows Mobile 型号的销量仍是 Windows Phone 7 的 2 到 1 倍。微软决定通过禁止在其新平台上的原生代码开发来摧毁其 Windows Mobile 开发生态系统,这尚未转化为任何成功的迹象,只是促使大多数经验丰富的 C++ 开发人员转向 Android、iPhone 或 RIM。但是,随着智能手机市场的规模不断增长,以及台式机和笔记本电脑平台的持续缓慢下降,微软别无选择,只能继续其移动设备方面的努力。

历史

  • 2011 年 3 月 20 日:初次发布
  • 2011 年 3 月 24 日:更新了 GetGoogleMap 函数,以便在创建兼容位图后释放屏幕设备上下文
  • 2011 年 4 月 14 日:对 GetGoogleMap 函数进行了更改。以前,我们为从 Internet 读取的文件的每个块分配一个新的 IOVEC 结构,并将其推送到 readBufferArray 向量中。但是,当您将 struct 或对象 push_back 到向量时,实际上是在创建副本,因此没有必要像以前那样为每个块动态分配一个新的 IOVEC 结构。这导致我们泄漏了从未删除的 IOVEC struct。现在,我们使用在堆栈上创建的单个 IOVEC struct 来保存指向动态分配的内存块的指针,并且每次读取一个块时,这个单个 struct 都会被推送到 readBufferArray 向量中,从而消除了动态分配的 IOVEC struct的泄漏。
© . All rights reserved.