找回密码
 立即注册
首页 业界区 业界 C# 调用 Google Earth Com API开发(三)

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

厌外 2025-5-29 20:33:10
好久没有更新《C#调用Google Earth Com API开发》系列文章了,今天带给大家的是第三篇,本篇相对于第二篇主要改进了三个方面。
1) 实现GoogleEarth显示画面随窗口大小改变而改变
2) 截获GoogleEarth鼠标消息,实现单击、双击功能;鼠标滚轮缩放现在只能放大!O(∩_∩)O~
3) 实现GoogleEarth彩色截图(测试环境:Windows 2003 Server ,Vista与Win7中不可用,XP未测)
下面还是继续看代码:
1、GoogleEarth动态改变大小
  1.    1: /// <summary><summary><summary>
复制代码
  1.    2: /// 重新改变GoogleEarth视图的大小
复制代码
  1.    3: /// </summary></summary>
复制代码
  1.    4: private void ResizeGoogleControl()
复制代码
  1.    5: {
复制代码
  1.    6:     NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_PAINT, 0);
复制代码
  1.    7:     NativeMethods.PostMessage(GEHWnd, NativeMethods.WM_QT_PAINT, 0, 0);
复制代码
  1.    8: 
复制代码
  1.    9:     RECT mainRect = new RECT();
复制代码
  1.   10:     NativeMethods.GetWindowRect(GEHWnd, out mainRect);
复制代码
  1.   11:     clientRect = new RECT();
复制代码
  1.   12:     NativeMethods.GetClientRect(GEHrender, out clientRect);
复制代码
  1.   13: 
复制代码
  1.   14:     int offsetW = mainRect.Width - clientRect.Width;
复制代码
  1.   15:     int offsetH = mainRect.Height - clientRect.Height;
复制代码
  1.   16: 
复制代码
  1.   17:     int newWidth = this.Control.Width + (int)offsetW;
复制代码
  1.   18:     int newHeight = this.Control.Height + (int)offsetH;
复制代码
  1.   19: 
复制代码
  1.   20:     NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_TOP,
复制代码
  1.   21:         0, 0, newWidth, newHeight,
复制代码
  1.   22:         NativeMethods.SWP_FRAMECHANGED);
复制代码
  1.   23: 
复制代码
  1.   24:     NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_SIZE, 0);
复制代码
  1.   25: }
复制代码
2、鼠标消息
此例子中对于鼠标消息到处理使用了钩子,调用HookAPI.dll实现。
  1.    1:          /// <summary>
复制代码
  1.    2:          /// 鼠标钩子
复制代码
  1.    3:          /// </summary>
复制代码
  1.    4:          private MouseHook mouseHook;
复制代码
  1.    5:   
复制代码
  1.    6:          // 设置鼠标钩子
复制代码
  1.    7:          mouseHook = new MouseHook();
复制代码
  1.    8:          mouseHook.MouseClick += new MouseEventHandler(mouseHook_MouseClick);
复制代码
  1.    9:          mouseHook.MouseDbClick += new MouseEventHandler(mouseHook_MouseDbClick);
复制代码
  1.   10:          mouseHook.MouseWheel += new MouseEventHandler(mouseHook_MouseWheel);
复制代码
  1.   11:         // 启动鼠标钩子
复制代码
  1.   12:          mouseHook.StartHook(HookType.WH_MOUSE_LL, 0);
复制代码
单击事件:
  1.    1: /// <summary><summary><summary>
复制代码
  1.    2: /// 鼠标钩子。鼠标单击事件
复制代码
  1.    3: /// </summary></summary>
复制代码
  1.    4: /// <param name="sender"></param>
复制代码
  1.    5: /// <param name="e"></param>
复制代码
  1.    6: void mouseHook_MouseClick(object sender, MouseEventArgs e)
复制代码
  1.    7: {
复制代码
  1.    8:     IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
复制代码
  1.    9:     if (hWnd == this.GeRenderHWnd)
复制代码
  1.   10:     {
复制代码
  1.   11:         Point point = this.Control.PointToClient(e.Location);
复制代码
  1.   12:         // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
复制代码
  1.   13:         if (this.Control.ClientRectangle.Contains(point))
复制代码
  1.   14:         {
复制代码
  1.   15:             Console.WriteLine("点击了GoogleEarth...");
复制代码
  1.   16: 
复制代码
  1.   17:             DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
复制代码
  1.   18: 
复制代码
  1.   19:             ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseClickPoint);
复制代码
  1.   20: 
复制代码
  1.   21:             Thread thread = new Thread(pts);
复制代码
  1.   22:             thread.Start(dp);
复制代码
  1.   23: 
复制代码
  1.   24:         }
复制代码
  1.   25:     }
复制代码
  1.   26: }
复制代码
  1.   27: 
复制代码
  1.   28: protected void ShowMouseClickPoint(object obj)
复制代码
  1.   29: {
复制代码
  1.   30:     //Thread.Sleep(20);
复制代码
  1.   31:     DoublePoint dp = (DoublePoint)obj;
复制代码
  1.   32:     PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
复制代码
  1.   33:     Console.WriteLine("鼠标点击了:Lnt=" + pGe.Longitude.ToString()
复制代码
  1.   34:         + ";Lat=" + pGe.Latitude.ToString());
复制代码
  1.   35: }
复制代码
 
双击事件:
  1.    1: /// <summary><summary><summary>
复制代码
  1.    2:  /// 鼠标钩子。鼠标双击事件
复制代码
  1.    3:  /// </summary>
复制代码
  1.    4:  /// <param name="sender"></param>
复制代码
  1.    5:  /// <param name="e"></param>
复制代码
  1.    6:  void mouseHook_MouseDbClick(object sender, MouseEventArgs e)
复制代码
  1.    7:  {
复制代码
  1.    8:      IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
复制代码
  1.    9:      if (hWnd == this.GeRenderHWnd)
复制代码
  1.   10:      {
复制代码
  1.   11:          Point point = this.Control.PointToClient(e.Location);
复制代码
  1.   12:          // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
复制代码
  1.   13:          if (this.Control.ClientRectangle.Contains(point))
复制代码
  1.   14:          {
复制代码
  1.   15:              Console.WriteLine("xx双击了GoogleEarth...");
复制代码
  1.   16: 
复制代码
  1.   17:              DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
复制代码
  1.   18: 
复制代码
  1.   19:              ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseDbClickPoint);
复制代码
  1.   20: 
复制代码
  1.   21:              Thread thread = new Thread(pts);
复制代码
  1.   22:              thread.Start(dp);
复制代码
  1.   23: 
复制代码
  1.   24:          }
复制代码
  1.   25:      }
复制代码
  1.   26:  }
复制代码
  1.   27: 
复制代码
  1.   28:  protected void ShowMouseDbClickPoint(object obj)
复制代码
  1.   29:  {
复制代码
  1.   30:      //Thread.Sleep(20);
复制代码
  1.   31:      DoublePoint dp = (DoublePoint)obj;
复制代码
  1.   32:      PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
复制代码
  1.   33:      Console.WriteLine("xx鼠标双击了:Lnt=" + pGe.Longitude.ToString()
复制代码
  1.   34:          + ";Lat=" + pGe.Latitude.ToString());
复制代码
  1.   35: 
复制代码
  1.   36:      MessageBox.Show("我还是出来一下吧!省得你不知道你已经双击了鼠标!");
复制代码
  1.   37:  }
复制代码
 
这两处代码还比较简陋,比如未添加主窗口焦点检测,相信读者可以自行添加。O(∩_∩)O~
3、截图
程序中有两种截图功能,一种是GoogleEarth自带的截图功能,只能截取黑白图片;另一种为彩色截图,但是Vista以上操作系统不支持,还未找到合适的方法实现Vista与Win7兼容。
1) GoogleEarth自带截图功能:
  1.    1: GEViewContent view = GetGEView();
复制代码
  1.    2: 
复制代码
  1.    3: if (view != null)
复制代码
  1.    4: {
复制代码
  1.    5:     ApplicationGE ge = view.GeApplication;
复制代码
  1.    6:     if (ge != null && ge.IsInitialized() > 0)
复制代码
  1.    7:     {
复制代码
  1.    8:         using (SaveFileDialog sfd = new SaveFileDialog())
复制代码
  1.    9:         {
复制代码
  1.   10:             sfd.Filter = "jpg图片|*.jpg";
复制代码
  1.   11:             sfd.AddExtension = true;
复制代码
  1.   12:             sfd.CheckPathExists = true;
复制代码
  1.   13:             sfd.Title = "保存Google Earth截图";
复制代码
  1.   14: 
复制代码
  1.   15:             if (sfd.ShowDialog() == DialogResult.OK)
复制代码
  1.   16:             {
复制代码
  1.   17:                 ge.SaveScreenShot(sfd.FileName, 100);
复制代码
  1.   18:             }
复制代码
  1.   19:         }
复制代码
  1.   20:     }
复制代码
  1.   21: }
复制代码
2) 彩色截图:
  1.    1: GEViewContent view = GetGEView();
复制代码
  1.    2: if (view != null)
复制代码
  1.    3: {
复制代码
  1.    4:     int nWidth = view.Control.Width;
复制代码
  1.    5:     int nHeight = view.Control.Height;
复制代码
  1.    6:     Point pt = view.Control.PointToScreen(view.Control.Location);
复制代码
  1.    7:     int nXSrc = pt.X;
复制代码
  1.    8:     int nYSrc = pt.Y;
复制代码
  1.    9: 
复制代码
  1.   10:     IntPtr hRender = view.GeRenderHWnd;
复制代码
  1.   11: 
复制代码
  1.   12:     if (hRender != IntPtr.Zero)
复制代码
  1.   13:     {
复制代码
  1.   14:         // 取得Render DC
复制代码
  1.   15:         IntPtr hRenderDC = NativeMethods.GetWindowDC(hRender);
复制代码
  1.   16:         // 创建hBitmap
复制代码
  1.   17:         IntPtr hBitmap = NativeMethods.CreateCompatibleBitmap(hRenderDC, nWidth, nHeight);
复制代码
  1.   18:         // 创建MEM DC
复制代码
  1.   19:         IntPtr hMemDC = NativeMethods.CreateCompatibleDC(hRenderDC);
复制代码
  1.   20:         // 将Bitmap Select到MemDC
复制代码
  1.   21:         NativeMethods.SelectObject(hMemDC, hBitmap);
复制代码
  1.   22:         // 直接拷屏
复制代码
  1.   23:         NativeMethods.BitBlt(hMemDC, 0, 0, nWidth, nHeight,
复制代码
  1.   24:             hRenderDC, 0, 0, 13369376);
复制代码
  1.   25: 
复制代码
  1.   26:         using(Bitmap bmp = Bitmap.FromHbitmap(hBitmap))
复制代码
  1.   27:         {
复制代码
  1.   28:             using(SaveFileDialog sfd = new SaveFileDialog())
复制代码
  1.   29:             {
复制代码
  1.   30:                 sfd.Filter = "JPG图片|*.jpg|PNG图片|*.png";
复制代码
  1.   31:                 sfd.AddExtension = true;
复制代码
  1.   32:                 sfd.CheckPathExists = true;
复制代码
  1.   33:                 sfd.Title = "保存Google Earth截图";
复制代码
  1.   34: 
复制代码
  1.   35:                 if (sfd.ShowDialog() == DialogResult.OK)
复制代码
  1.   36:                 {
复制代码
  1.   37:                     ImageFormat imgFormat = null;
复制代码
  1.   38:                     // 默认选择JPG
复制代码
  1.   39:                     if (sfd.FilterIndex == 0)
复制代码
  1.   40:                     {
复制代码
  1.   41:                         imgFormat = ImageFormat.Jpeg;
复制代码
  1.   42:                     }
复制代码
  1.   43:                     // 选择PNG
复制代码
  1.   44:                     else
复制代码
  1.   45:                     {
复制代码
  1.   46:                         imgFormat = ImageFormat.Png;
复制代码
  1.   47:                     }
复制代码
  1.   48:                     bmp.Save(sfd.FileName, imgFormat);
复制代码
  1.   49:                 }
复制代码
  1.   50:             }
复制代码
  1.   51:            
复制代码
  1.   52:             //销毁资源
复制代码
  1.   53:             NativeMethods.DeleteDC(hRenderDC);
复制代码
  1.   54:             NativeMethods.DeleteDC(hMemDC);
复制代码
  1.   55:         }
复制代码
  1.   56:     }
复制代码
 
OK,这篇GE开发到此为止,请读者继续等待后面的精彩文章…
不好意思,刚才忘记上传源程序了!
https://files.cnblogs.com/wpwen/GEDemo_2009-05-22.rar
1.png

2.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册