zoukankan      html  css  js  c++  java
  • C# 调用 Google Earth Com API开发(三)

    好久没有更新《C#调用Google Earth Com API开发》系列文章了,今天带给大家的是第三篇,本篇相对于第二篇主要改进了三个方面。

    1) 实现GoogleEarth显示画面随窗口大小改变而改变

    2) 截获GoogleEarth鼠标消息,实现单击、双击功能;鼠标滚轮缩放现在只能放大!O(∩_∩)O~

    3) 实现GoogleEarth彩色截图(测试环境:Windows 2003 Server ,Vista与Win7中不可用,XP未测)

    下面还是继续看代码:

    1、GoogleEarth动态改变大小

       1: /// <summary>
       2: /// 重新改变GoogleEarth视图的大小
       3: /// </summary>
       4: private void ResizeGoogleControl()
       5: {
       6:     NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_PAINT, 0);
       7:     NativeMethods.PostMessage(GEHWnd, NativeMethods.WM_QT_PAINT, 0, 0);
       8:  
       9:     RECT mainRect = new RECT();
      10:     NativeMethods.GetWindowRect(GEHWnd, out mainRect);
      11:     clientRect = new RECT();
      12:     NativeMethods.GetClientRect(GEHrender, out clientRect);
      13:  
      14:     int offsetW = mainRect.Width - clientRect.Width;
      15:     int offsetH = mainRect.Height - clientRect.Height;
      16:  
      17:     int newWidth = this.Control.Width + (int)offsetW;
      18:     int newHeight = this.Control.Height + (int)offsetH;
      19:  
      20:     NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_TOP,
      21:         0, 0, newWidth, newHeight, 
      22:         NativeMethods.SWP_FRAMECHANGED);
      23:  
      24:     NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_SIZE, 0);
      25: }

    2、鼠标消息

    此例子中对于鼠标消息到处理使用了钩子,调用HookAPI.dll实现。

       1:          /// <summary>
       2:          /// 鼠标钩子
       3:          /// </summary>
       4:          private MouseHook mouseHook;
       5:   
       6:          // 设置鼠标钩子
       7:          mouseHook = new MouseHook();
       8:          mouseHook.MouseClick += new MouseEventHandler(mouseHook_MouseClick);
       9:          mouseHook.MouseDbClick += new MouseEventHandler(mouseHook_MouseDbClick);
      10:          mouseHook.MouseWheel += new MouseEventHandler(mouseHook_MouseWheel);
      11:         // 启动鼠标钩子
      12:          mouseHook.StartHook(HookType.WH_MOUSE_LL, 0);

    单击事件:

       1: /// <summary>
       2: /// 鼠标钩子。鼠标单击事件
       3: /// </summary>
       4: /// <param name="sender"></param>
       5: /// <param name="e"></param>
       6: void mouseHook_MouseClick(object sender, MouseEventArgs e)
       7: {
       8:     IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
       9:     if (hWnd == this.GeRenderHWnd)
      10:     {
      11:         Point point = this.Control.PointToClient(e.Location);
      12:         // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
      13:         if (this.Control.ClientRectangle.Contains(point))
      14:         {
      15:             Console.WriteLine("点击了GoogleEarth...");
      16:  
      17:             DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
      18:  
      19:             ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseClickPoint);
      20:  
      21:             Thread thread = new Thread(pts);
      22:             thread.Start(dp);
      23:  
      24:         }
      25:     }
      26: }
      27:  
      28: protected void ShowMouseClickPoint(object obj)
      29: {
      30:     //Thread.Sleep(20);
      31:     DoublePoint dp = (DoublePoint)obj;
      32:     PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
      33:     Console.WriteLine("鼠标点击了:Lnt=" + pGe.Longitude.ToString() 
      34:         + ";Lat=" + pGe.Latitude.ToString());
      35: }

    双击事件:

       1: /// <summary>
       2:  /// 鼠标钩子。鼠标双击事件
       3:  /// </summary>
       4:  /// <param name="sender"></param>
       5:  /// <param name="e"></param>
       6:  void mouseHook_MouseDbClick(object sender, MouseEventArgs e)
       7:  {
       8:      IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
       9:      if (hWnd == this.GeRenderHWnd)
      10:      {
      11:          Point point = this.Control.PointToClient(e.Location);
      12:          // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
      13:          if (this.Control.ClientRectangle.Contains(point))
      14:          {
      15:              Console.WriteLine("xx双击了GoogleEarth...");
      16:  
      17:              DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
      18:  
      19:              ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseDbClickPoint);
      20:  
      21:              Thread thread = new Thread(pts);
      22:              thread.Start(dp);
      23:  
      24:          }
      25:      }
      26:  }
      27:  
      28:  protected void ShowMouseDbClickPoint(object obj)
      29:  {
      30:      //Thread.Sleep(20);
      31:      DoublePoint dp = (DoublePoint)obj;
      32:      PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
      33:      Console.WriteLine("xx鼠标双击了:Lnt=" + pGe.Longitude.ToString()
      34:          + ";Lat=" + pGe.Latitude.ToString());
      35:  
      36:      MessageBox.Show("我还是出来一下吧!省得你不知道你已经双击了鼠标!");
      37:  }

    这两处代码还比较简陋,比如未添加主窗口焦点检测,相信读者可以自行添加。O(∩_∩)O~

    3、截图

    程序中有两种截图功能,一种是GoogleEarth自带的截图功能,只能截取黑白图片;另一种为彩色截图,但是Vista以上操作系统不支持,还未找到合适的方法实现Vista与Win7兼容。

    1) GoogleEarth自带截图功能:

       1: GEViewContent view = GetGEView();
       2:  
       3: if (view != null)
       4: {
       5:     ApplicationGE ge = view.GeApplication;
       6:     if (ge != null && ge.IsInitialized() > 0)
       7:     {
       8:         using (SaveFileDialog sfd = new SaveFileDialog())
       9:         {
      10:             sfd.Filter = "jpg图片|*.jpg";
      11:             sfd.AddExtension = true;
      12:             sfd.CheckPathExists = true;
      13:             sfd.Title = "保存Google Earth截图";
      14:  
      15:             if (sfd.ShowDialog() == DialogResult.OK)
      16:             {
      17:                 ge.SaveScreenShot(sfd.FileName, 100);
      18:             }
      19:         }
      20:     }
      21: }

    2) 彩色截图:

       1: GEViewContent view = GetGEView();
       2: if (view != null)
       3: {
       4:     int nWidth = view.Control.Width;
       5:     int nHeight = view.Control.Height;
       6:     Point pt = view.Control.PointToScreen(view.Control.Location);
       7:     int nXSrc = pt.X;
       8:     int nYSrc = pt.Y;
       9:  
      10:     IntPtr hRender = view.GeRenderHWnd;
      11:  
      12:     if (hRender != IntPtr.Zero)
      13:     {
      14:         // 取得Render DC
      15:         IntPtr hRenderDC = NativeMethods.GetWindowDC(hRender);
      16:         // 创建hBitmap
      17:         IntPtr hBitmap = NativeMethods.CreateCompatibleBitmap(hRenderDC, nWidth, nHeight);
      18:         // 创建MEM DC
      19:         IntPtr hMemDC = NativeMethods.CreateCompatibleDC(hRenderDC);
      20:         // 将Bitmap Select到MemDC
      21:         NativeMethods.SelectObject(hMemDC, hBitmap);
      22:         // 直接拷屏
      23:         NativeMethods.BitBlt(hMemDC, 0, 0, nWidth, nHeight,
      24:             hRenderDC, 0, 0, 13369376);
      25:  
      26:         using(Bitmap bmp = Bitmap.FromHbitmap(hBitmap))
      27:         {
      28:             using(SaveFileDialog sfd = new SaveFileDialog())
      29:             {
      30:                 sfd.Filter = "JPG图片|*.jpg|PNG图片|*.png";
      31:                 sfd.AddExtension = true;
      32:                 sfd.CheckPathExists = true;
      33:                 sfd.Title = "保存Google Earth截图";
      34:  
      35:                 if (sfd.ShowDialog() == DialogResult.OK)
      36:                 {
      37:                     ImageFormat imgFormat = null;
      38:                     // 默认选择JPG
      39:                     if (sfd.FilterIndex == 0)
      40:                     {
      41:                         imgFormat = ImageFormat.Jpeg;
      42:                     }
      43:                     // 选择PNG
      44:                     else
      45:                     {
      46:                         imgFormat = ImageFormat.Png;
      47:                     }
      48:                     bmp.Save(sfd.FileName, imgFormat);
      49:                 }
      50:             }
      51:             
      52:             //销毁资源
      53:             NativeMethods.DeleteDC(hRenderDC);
      54:             NativeMethods.DeleteDC(hMemDC);
      55:         }
      56:     }

    OK,这篇GE开发到此为止,请读者继续等待后面的精彩文章…

    不好意思,刚才忘记上传源程序了!

    https://files.cnblogs.com/wpwen/GEDemo_2009-05-22.rar

    GeDemo

    GeDemo

  • 相关阅读:
    IsPostBack
    多次点击Button后DropDownList选中的值变为默认值?
    数据表数据的复制
    使用DriverManager获取数据库连接
    通过Driver获取数据库连接
    URL学习笔记
    使用UDP进行数据发送的实例一
    利用Socket 客户端---->服务端 传送文件到指定路径,并返回一个友好的回馈
    关于TCP的两个小练习_第一个博客~
    oracle-19c-单实例安装-一键式脚本
  • 原文地址:https://www.cnblogs.com/wpwen/p/1486892.html
Copyright © 2011-2022 走看看