首页 > 编程开发 > Objective-C编程 >
-
c# 调用 Google Earch 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开发到此为止,请读者继续等待后面的精彩文章…
不好意思,刚才忘记上传源程序了!
http://files.cnblogs.com/wpwen/GEDemo_2009-05-22.rar
图片看不清楚?请点击这里查看原图(大图)。
图片看不清楚?请点击这里查看原图(大图)。
系列文章:
C#调用 GoogleEarth COM API开发(一)
C# 调用 Google Earth Com API开发(二)
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: }