C# 调用 Google Earth Com API开发(二)

继《C#调用GoogleEarth Com API开发(一)》,我Neil又带给大家第二篇文章。这一篇文章在第一篇的基础上,展示如何调用Windows API将GoogleEarth的界面隐藏掉,并将GoogleEarth的地图显示在自定义的窗体上。废话少说,直接上代码。

1、主窗口代码:

   1: // 功能:GE实例(二)
   2: // 描述:GE COM API 网址:http://earth.google.com/comapi/index.html
   3: // 作者:温伟鹏
   4: // 日期:2009-02-08
   5:  
   6: using System;
   7: using System.Collections.Generic;
   8: using System.ComponentModel;
   9: using System.Data;
  10: using System.Drawing;
  11: using System.Text;
  12: using System.Windows.Forms;
  13: using EARTHLib;
  14:  
  15: namespace GEDemo
  16: {
  17:     public partial class Form2 : Form
  18:     {
  19:         /// <summary>
  20:         /// 用来关闭GoogleEarth的消息定义
  21:         /// </summary>
  22:         static readonly Int32 WM_QUIT = 0x0012; 
  23:  
  24:         private IntPtr GEHWnd = (IntPtr)5;
  25:         private IntPtr GEHrender = (IntPtr)5;
  26:         private IntPtr GEParentHrender = (IntPtr)5;
  27:         /// <summary>
  28:         /// 定义GE应用程序类
  29:         /// </summary>
  30:         private ApplicationGEClass GeApp;
  31:  
  32:         public Form2()
  33:         {
  34:             InitializeComponent();
  35:         }
  36:  
  37:         protected override void OnLoad(EventArgs e)
  38:         {
  39:             base.OnLoad(e);
  40:  
  41:             if (!this.DesignMode)
  42:             {
  43:                 GeApp = new ApplicationGEClass();
  44:  
  45:                 GEHWnd = (IntPtr)GeApp.GetMainHwnd();
  46:  
  47:                 NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0,
  48:                     NativeMethods.SWP_NOSIZE + NativeMethods.SWP_HIDEWINDOW);
  49:  
  50:                 GEHrender = (IntPtr)GeApp.GetRenderHwnd();
  51:                 GEParentHrender = (IntPtr)NativeMethods.GetParent(GEHrender);
  52:  
  53:                 NativeMethods.MoveWindow(GEHrender, 0, 0, this.Width, this.Height, true);
  54:  
  55:                 NativeMethods.SetParent(GEHrender, this.Handle);
  56:             }
  57:         }
  58:  
  59:         protected override void OnClosing(CancelEventArgs e)
  60:         {
  61:             base.OnClosing(e);
  62:  
  63:             NativeMethods.PostMessage(GeApp.GetMainHwnd(), WM_QUIT, 0, 0);
  64:         }
  65:     }
  66: }

2、NativeMethods类定义:

   1: // 功能:Windows API调用
   2: // 描述:大家可以参照MSDN
   3: // 作者:温伟鹏
   4: // 日期:2009-02-08
   5:  
   6: using System;
   7: using System.Collections.Generic;
   8: using System.Text;
   9: using System.Runtime.InteropServices;
  10:  
  11: namespace GEDemo
  12: {
  13:     public class NativeMethods
  14:     {
  15:         [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  16:         public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, UInt32 uflags);
  17:  
  18:         [DllImport("user32.dll", CharSet = CharSet.Auto)]
  19:         public static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam);
  20:  
  21:         #region 预定义
  22:  
  23:         public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
  24:         public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
  25:         public static readonly IntPtr HWND_TOP = new IntPtr(0);
  26:         public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
  27:         public static readonly UInt32 SWP_NOSIZE = 1;
  28:         public static readonly UInt32 SWP_NOMOVE = 2;
  29:         public static readonly UInt32 SWP_NOZORDER = 4;
  30:         public static readonly UInt32 SWP_NOREDRAW = 8;
  31:         public static readonly UInt32 SWP_NOACTIVATE = 16;
  32:         public static readonly UInt32 SWP_FRAMECHANGED = 32;
  33:         public static readonly UInt32 SWP_SHOWWINDOW = 64;
  34:         public static readonly UInt32 SWP_HIDEWINDOW = 128;
  35:         public static readonly UInt32 SWP_NOCOPYBITS = 256;
  36:         public static readonly UInt32 SWP_NOOWNERZORDER = 512;
  37:         public static readonly UInt32 SWP_NOSENDCHANGING = 1024;
  38:  
  39:         #endregion
  40:  
  41:         public delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
  42:  
  43:         [DllImport("user32", CharSet = CharSet.Auto)]
  44:         public extern static IntPtr GetParent(IntPtr hWnd);
  45:  
  46:         [DllImport("user32", CharSet = CharSet.Auto)]
  47:         public extern static bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
  48:  
  49:         [DllImport("user32", CharSet = CharSet.Auto)]
  50:         public extern static IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
  51:  
  52:         [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
  53:         public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
  54:  
  55:         public static int GW_CHILD = 5;
  56:         public static int GW_HWNDNEXT = 2;
  57:     }
  58: }

3、执行效果:

image

posted @ 2009-02-22 00:09 温伟鹏 阅读(7242) 评论(27) 编辑 收藏

 回复 引用 查看   
#1楼2009-03-14 14:03 | 守护心中彩虹      
太强了,如果有源码或编译后的程序可供下载,就够爽了!
 回复 引用 查看   
#2楼[楼主]2009-03-17 22:25 | wpwen      
直接用上面的代码复制下来就可以运行了!
现在此系列还没完呢,这些都不算是完整的代码,不久就会有第三节

 回复 引用   
#3楼2009-03-26 09:33 | 左渤
博主你好,我最近也在学习这方面的东西,我一直用vs2005,请问能用vs2005开发吗?多谢赐教。
 回复 引用 查看   
#4楼[楼主]2009-03-26 19:23 | wpwen      
@左渤
你将代码复制到VS2005中试试!呵呵。

上面给出的代码就是2005中写出来的

 回复 引用 查看   
#5楼2009-05-01 00:36 | prolove2      
楼主的代码写的好工整啊.. 佩服!
 回复 引用   
#6楼2009-05-14 11:46 | 许[未注册用户]
可能是vs2008的
都一样

 回复 引用   
#7楼2009-06-02 13:55 | flute0316[未注册用户]
你好,不知道为什么,GE没出来,用的代码一样,也没报错
 回复 引用   
#8楼2009-06-11 16:17 | NetFarmer
楼主我比葫芦画瓢的写了一个demo 可是GE有的时候启动,有的时候不启动。并且启动的出来的节目也地球距离标题栏那空着一块距离。
 回复 引用 查看   
#9楼2009-06-26 14:57 | prolove2      
你好, 看了你写的文章,很受用。我自己也试着测了一下。发现 IApplicationGE 中的方法: loadkmldata 加载的 kml 中,如果包含中文,就会报错,gb2321, utf8, uncode 都试了, 全不行!
代码如下:

OpenFileDialog openDlg = new OpenFileDialog();
openDlg.Filter = "kml文件|*.kml";
if (openDlg.ShowDialog() == DialogResult.OK)
{
System.IO.StreamReader sr = new System.IO.StreamReader(openDlg.FileName);
string strData = sr.ReadToEnd().Trim();
sr.Close();
GEApp.LoadKmlData(ref strData);
}

kml 保存时,选择了文字的格式。

 回复 引用 查看   
#10楼2009-07-17 16:59 | prolove2      
NetFarmer 的问题,我也遇到过, 我的决解办法是中启动和退出时,都做一次杀掉 googleearth.exe 进程的方法。这样可以保证每次都可以正常启动。

启动后出现空白,我的解决方法是在启动时,配制一下参数:修改注册表,将HKEY_CURRENT_USER\Software\Google\Google Earth Plus 中: shown_LeftPanel 改为: false。

作用是隐藏左边的侧栏。这样,启动时,就没再出现空白的情况。



我要继续问一下: LoadKmlData 中有中文的情况,如何处理? 哪位高手解决了?

 回复 引用   
#11楼2009-07-19 13:02 | 狂奔一蜗牛[未注册用户]
关注中,期待第三节。
 回复 引用   
#12楼2009-07-19 13:07 | 狂奔一蜗牛[未注册用户]
楼上遇到的中文问题可以试着用OpenKmlFile,我的kml中也有中文,没有遇到问题。
 回复 引用 查看   
#13楼2009-07-20 14:06 | prolove2      
12楼的方法是可以解决, 如果大量使用这个方法, 有出现内存泄露的风险。并且,如果有重复的地标,会被重复标记多次。
目前, 这是唯一的解决方法吗? 真不知道 Google 的那些高手们是如何做的汉化。先用这个方法挺着吧!只能期望GOOGLE 的开发团队了!

 回复 引用 查看   
#14楼2009-07-21 11:28 | prolove2      
哪位兄弟如何可以删掉某一个地标啊!
 回复 引用   
#15楼2009-09-02 09:37 | LouisZhu[未注册用户]
博主能详细解释下NativeMethods里的内容吗?对那块内容不是很了解
 回复 引用   
#16楼2009-09-02 09:47 | LouisZhu[未注册用户]
有做google earth com api 开发的兄弟大家多讨论下。我的QQ:58118161
 回复 引用   
#17楼2009-10-23 07:12 | zxshen[未注册用户]
请问下如何通过双击TreeNode定位KML中的Feature? 好像没有效果?通过GOOGLE EARTH的标注功能新增的FeaTure就可以定位。
 回复 引用 查看   
#18楼2009-10-27 14:20 | 章伟立      
请问,如何不隐藏Google界面啊??
 回复 引用 查看   
#19楼2009-11-08 13:21 | 屠龙宝刀      
怎么把google street view集成进来呢?
 回复 引用   
#20楼2009-11-08 17:57 | bmoonlu[未注册用户]
你好,博主,这样还是要先显示googleEarth的初始化界面,如何能不让这个googleEarth的初始化界面显示亚??
 回复 引用   
#21楼2009-12-04 11:03 | bmoonlu[未注册用户]
如何能不让这个googleEarth的初始化界面显示亚,谁能告诉我,我以身相许
 回复 引用 查看   
#22楼2010-04-26 17:55 | 刘跃      
博主好,我碰到的问题是,winForm中只能显示earth 的一角,就是说Google earth没能全屏显示,然后winForm最大化时earth依然是一角,Google earth不随着winForm的最大化最大化,出现很多空白,不知道怎么解决
 回复 引用 查看   
#23楼2011-03-20 15:10 | wangdy2011      
以请问一下C# 调用 Google Earth Com API开发(三)的那个下载下来的代码怎么运行不了啊
有下面的错误
“SharpPlatform.Core.Services.ServiceManager”的类型初始值设定项引发异常。
请给我说一下啊 谢谢 qq346574203

 回复 引用 查看   
#24楼2011-05-11 08:36 | newstar01      
现在好像不能在GOOGLE EARTH 6.0下成功嵌入窗口,不只楼主有没有遇到同样的问题。
 回复 引用 查看   
#25楼2011-07-26 18:57 | 黑色贝雷帽      
您好!前辈不知道你能不能看到,能否看看您所写的所有的源码,或者给我一个源码也行,现在急需,谢谢前辈啦!我的QQ号:420710690
 回复 引用 查看   
#26楼2011-12-07 14:08 | 丶Y尐畅      
楼主你好,我照着您的上面的写了,但是报了“无法嵌入互操作类型“EARTHLib.ApplicationGEClass”。请改用适用的接口。 ”的错误,请问是什么原因啊?
 回复 引用 查看   
#27楼2011-12-26 13:54 | tamphoenix      
引用wangdy2011:
以请问一下C# 调用 Google Earth Com API开发(三)的那个下载下来的代码怎么运行不了啊
有下面的错误
“SharpPlatform.Core.Services.ServiceManager”的类型初始值设定项引发异常。
请给我说一下啊 谢谢 qq346574203


我也遇到这个问题啊,我的环境是VS2010和GoogleEarth 6.0,不知道怎么什么问题,请学长指教啊