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

  • 相关阅读:
    convert image to base64 and post to RESTful wcf
    在android webview实现截屏的手动tounchmove裁剪图片
    How to use jquery ajax and android request security RESTful WCF
    using swfUpload in asp.net mvc
    using HttpClient and sending json data to RESTful server in adroind
    ODP.NET数据访问
    android image watermark
    解决国内不能访问github的问题
    idapro权威指南第二版阅读笔记第九章 交叉引用和绘图功能
    idapro权威指南第二版阅读笔记第二章 逆向和反汇编工具
  • 原文地址:https://www.cnblogs.com/wpwen/p/1486892.html
Copyright © 2011-2022 走看看