厌外 发表于 2025-5-29 20:33:10

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><summary><summary>   2: /// 重新改变GoogleEarth视图的大小   3: /// </summary></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><summary><summary>   2: /// 鼠标钩子。鼠标单击事件   3: /// </summary></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><summary><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 DC15:         IntPtr hRenderDC = NativeMethods.GetWindowDC(hRender);16:         // 创建hBitmap17:         IntPtr hBitmap = NativeMethods.CreateCompatibleBitmap(hRenderDC, nWidth, nHeight);18:         // 创建MEM DC19:         IntPtr hMemDC = NativeMethods.CreateCompatibleDC(hRenderDC);20:         // 将Bitmap Select到MemDC21:         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:                     // 默认选择JPG39:                     if (sfd.FilterIndex == 0)40:                     {41:                         imgFormat = ImageFormat.Jpeg;42:                     }43:                     // 选择PNG44:                     else45:                     {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



来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: C# 调用 Google Earth Com API开发(三)