WorldWind系列三 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

简单功能分析——主窗体的键盘监听处理及拷贝和粘贴位置坐标功能

在分析功能时发现,各功能都有自己的快捷键相应,比如今天要分析的 Copy Coordinates (Ctrl+C)和Paste Coordinates (Ctrl+P),以及主窗体的全屏功能也是通过快捷键(Alt+Enter),

WorldWind系列三

。这就使我需要彻底分析一下主窗体的键盘监听处理啦。

主窗体的键盘监听处理

与WorldWind系列三:功能分析——截屏功能和“关于”窗体分析 中AboutDialog.cs分析类似,WorldWind主窗体也是重载了OnKeyUp,使窗体接受键盘响应。

936行

protected override void OnKeyUp(KeyEventArgs e)
         {
             if (this.webBrowserPanel.IsTyping()) //如果是在“网页窗体”(稍后介绍)里输入地址,则主窗体处不相应键盘事件,将 e.Handled = true;表示已经处理事件啦。
                 e.Handled = true;
             else e.Handled = HandleKeyUp(e);  //此处HandleKeyUp()是真正处理主窗口的键盘响应

             base.OnKeyUp(e);
         }

HandleKeyUp函数

真正处理键盘响应函数

/// 


         /// Handles key up events.
         /// 

         /// 
         /// Returns true if the key is handled.
         protected bool HandleKeyUp(KeyEventArgs e)
         {
             // keep keypresses inside browser url bar
             if(e.Handled)
                 return true;
             if (e.Alt)  //处理Alt 组合键
             {
                 // Alt key down
                 switch(e.KeyCode)
                 {
                     case Keys.A:
                         menuItemAlwaysOnTop_Click(this,e);
                         return true;
                     case Keys.Q:
                         using( PropertyBrowserForm. worldWindSettings = new PropertyBrowserForm( Settings, "World Wind Settings" ) )
                         {
                             worldWindSettings.Icon = this.Icon;
                             worldWindSettings.ShowDialog();
                         }
                         return true;
                     case Keys.W:
                         menuItemOptions_Click(this, EventArgs.Empty);
                         return true;
                     case Keys.Enter: // 实现全屏功能,稍后看看如何实现??
                         this.FullScreen = !this.FullScreen;
                         return true;
                     case Keys.F4:
                         Close();
                         return true;
                 }
             }
             else if (e.Control)   //处理Ctrl组合键
             {
                 // Control key down
                 switch(e.KeyCode)
                 {
                     case Keys.C:
                     case Keys.Insert:  //调用拷贝坐标功能,即Copy Coordinates (Ctrl+C)
                         menuItemCoordsToClipboard_Click(this, e);
                         return true;
                     case Keys.F:
                         return true;
                     case Keys.H:
                         if (progressMonitor != null)
                         {
                             bool wasVisible = progressMonitor.Visible;
                             progressMonitor.Close();
                             progressMonitor.Dispose();
                             progressMonitor = null;
                             if (wasVisible)
                                 return true;
                         }
                         progressMonitor = new ProgressMonitor();
                         progressMonitor.Icon = this.Icon;
                         progressMonitor.Show();
                         return true;
                     case Keys.I:
                         menuItemConfigWizard_Click(this,e);
                         return true;
                     case Keys.N:
                         menuItemOptions_Click(this,e);
                         return true;
                     case Keys.T: //控制工具栏的显示。
                         menuItemShowToolbar_Click(this,e);
                         return true;
                     case Keys.V: //粘贴坐标,并转向粘贴的坐标位置。今天分析
                         menuItemEditPaste_Click(this,e);
                         return true;
                     case Keys.S: //保存截屏,已经分析
                         menuItemSaveScreenShot_Click(this, e);
                         return true;
                 }
             }
             else if (e.Shift)
             {
                 // Shift key down
                 switch(e.KeyCode)
                 {
                     case Keys.Insert:
                         menuItemEditPaste_Click(this,e);
                         return true;
                     case Keys.S:
                         menuItemSunShading_Click(this, e);
                         return true;
                     case Keys.A:
                         menuItemAtmosphericScattering_Click(this, e);
                         return true;
                 }
             }
             else
             {
                 // Other or no modifier key
                 switch(e.KeyCode)
                 {
                     //case Keys.B:
                     //    menuItemWMS_Click(this, e);
                     //    return true;
                     case Keys.G:
                         return true;
                     case Keys.L:
                         menuItemLayerManager_Click(this, e);
                         return true;
                     case Keys.P:
                         if(this.pathMaker == null)
                         {
                             this.pathMaker = new PathMaker(this.worldWindow);
                             this.pathMaker.Icon = this.Icon;
                         }
                         this.pathMaker.Visible = !this.pathMaker.Visible;
                         return true;
                     case Keys.V:   
                         if(this.placeBuilderDialog == null)
                         {
                             this.placeBuilderDialog = new PlaceBuilder( this.worldWindow );
                             this.placeBuilderDialog.Icon = this.Icon;
                         }
                         this.placeBuilderDialog.Visible = !this.placeBuilderDialog.Visible;
                         return true;
                     case Keys.Escape:  //退出全屏快捷键 ESC
                         if (this.FullScreen)
                         {
                             this.FullScreen = false;
                             return true;
                         }
                         break;
                     case Keys.D1:
                     case Keys.NumPad1:
                         this.VerticalExaggeration = 1.0f;
                         return true;
                     case Keys.D2:
                     case Keys.NumPad2:
                         this.VerticalExaggeration = 2.0f;
                         return true;
                     case Keys.D3:
                     case Keys.NumPad3:
                         this.VerticalExaggeration = 3.0f;
                         return true;
                     case Keys.D4:
                     case Keys.NumPad4:
                         this.VerticalExaggeration = 4.0f;
                         return true;
                     case Keys.D5:
                     case Keys.NumPad5:
                         this.VerticalExaggeration = 5.0f;
                         return true;
                     case Keys.D6:
                     case Keys.NumPad6:
                         this.VerticalExaggeration = 6.0f;
                         return true;
                     case Keys.D7:
                     case Keys.NumPad7:
                         this.VerticalExaggeration = 7.0f;
                         return true;
                     case Keys.D8:
                     case Keys.NumPad8:
                         this.VerticalExaggeration = 8.0f;
                         return true;
                     case Keys.D9:
                     case Keys.NumPad9:
                         this.VerticalExaggeration = 9.0f;
                         return true;
                     case Keys.D0:
                     case Keys.NumPad0:
                         this.VerticalExaggeration = 0.0f;
                         return true;
                     case Keys.F1:
                         this.menuItemAnimatedEarth_Click(this,e);
                         return true;
                     case Keys.F2:
                         this.menuItemModisHotSpots_Click(this,e);
                         return true;
                     case Keys.F5:
                         this.menuItemRefreshCurrentView_Click(this,e);
                         return true;
                     case Keys.F6:
                         return true;
                     case Keys.F7:
                         this.menuItemShowLatLonLines_Click(this,e);
                         return true;
                     case Keys.F8:
                         this.menuItemPlanetAxis_Click(this,e);
                         return true;
                     case Keys.F9:
                         this.menuItemShowCrosshairs_Click(this,e);
                         return true;
                     case Keys.F10:
                         this.menuItemShowPosition_Click(this,e);
                         return true;
                     case Keys.F11:
                         this.menuItemConstantMotion_Click(this,e);
                         return true;
                     case Keys.F12:
                         this.menuItemPointGoTo_Click(this,e);
                         return true;
                 }
             }
             return false;
         }

从上面,我们可以温故和强化窗体键盘响应功能如何实现的知识点,

电脑资料

WorldWind系列三》(https://www.unjs.com)。不再多说了。

我们看看如何实现全屏功能的,FullScreen属性控制的?注意不是函数,我想这是它值得我们学习的优点。

全屏属性

private bool FullScreen
         {
             get
             {
                 return this.FormBorderStyle. == FormBorderStyle.None;
             }
             set
             {
                 if (value)
                 {
                     // Enter full-screen.
                     this.normalWindowState = this.WindowState;
                     this.WindowState = FormWindowState.Normal;
                     this.FormBorderStyle. = FormBorderStyle.None;
                     this.Menu = null;
                     this.WindowState = FormWindowState.Maximized;
                 }
                 else
                 {
                     // Go back to normal
                     this.WindowState = normalWindowState;
                     this.FormBorderStyle. = FormBorderStyle.Sizable;
                     this.Menu = mainMenu;
                 }
             }
         }

原来Fullscreen属性只是封装了Form原有的 FormBorderStyle和WindowState,同时在里面控制了主菜单Menu的显示与否。这里就是写好属性的妙用,可以学习一下,写出更好的属性控制,而不是简单的带参数的函数控制。

拷贝位置坐标功能

WorldWind.cs

1790

拷贝代码

private void menuItemCoordsToClipboard_Click(object sender, System.EventArgs e)
{
if (this.worldWindow.CurrentWorld == null)
     return;
WorldWindUri uri = new WorldWindUri(worldWindow.CurrentWorld.Name,worldWindow.DrawArgs.WorldCamera);  //构建保存当前状态的WorldWindUri对象
string uriString = uri.ToString();
Clipboard.SetDataObject(uriString, true);//调用Form类的Clipboard.SetDataObject()方法,将字符串拷贝到粘贴板上
}

WorldWindUri对象保存的字符串例如为:

worldwind://goto/world=Earth&lat=34.25320&lon=-101.57184&alt=48652548&dir=0.1
worldwind://goto/world=Earth&lat=-41.38362&lon=101.15747&alt=48652548&dir=0.2
worldwind://goto/world=Earth&lat=-89.89754&lon=136.64324&alt=48652548&dir=-7.2

我们应该学会使用Form类的Clipboard.SetDataObject()方法 实现自己的拷贝功能,如拷贝图片等复杂对象。

粘贴位置坐标功能

粘贴坐标信息,并重新定位

2150
     void menuItemEditPaste_Click(object sender, System.EventArgs e)
     {
     //获取拷贝的对象
         IDataObject iData = Clipboard.GetDataObject();
         if(!iData.GetDataPresent(DataFormats.Text))
           return;
         //获取拷贝的字符串
         string clipBoardString = (string)iData.GetData(DataFormats.Text);
             try
             {
          //通过字符串,解析还原出对象。这原理很像对象XML序列化
                 worldWindUri = WorldWindUri.Parse(clipBoardString);
                 ProcessWorldWindUri();
             }
             catch (UriFormatException caught)
             {
                 MessageBox.Show(caught.Message, "Unable to paste - you are not stupid!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
             }

2439  ProcessWorldWindUri()方法分析
         private void ProcessWorldWindUri()
         {
             if (worldWindUri.RawUrl.IndexOf("wmsimage") >= 0)
                 ProcessWmsEncodedUri();
             if (worldWindUri.RawUrl.IndexOf("install") >= 0)
                 ProcessInstallEncodedUri();
             worldWindow.Goto(worldWindUri); //根据worldWindUri对象,实现定位
             worldWindUri = null;
         }

worldWindow.Goto实现最终是调用WorldWindow类的 GotoLatLon()。

转到特定的经纬度位置

WorldWindow类的 GotoLatLon()转到特定的位置
524
         /// 


         /// Moves to specified location.
         /// 

         /// Latitude in degrees of target position. (-90 - 90).
         /// Longitude in degrees of target position. (-180 - 180).
         /// Camera heading in degrees (0-360) or double.NaN for no change.
         /// Camera altitude in meters or double.NaN for no change.
         /// 
         /// Camera tilt in degrees (-90 - 90) or double.NaN for no change.
         public void GotoLatLon(double latitude, double longitude, double heading, double altitude, double perpendicularViewRange, double tilt)
         {
             if(!double.IsNaN(perpendicularViewRange))
                 altitude = m_World.EquatorialRadius * Math.Sin(MathEngine.DegreesToRadians(perpendicularViewRange * 0.5));
             if (altitude<1)
                 altitude = 1;
             this.drawArgs.WorldCamera.SetPosition(latitude, longitude, heading, altitude, tilt);
         }
关键是:this.drawArgs.WorldCamera.SetPosition(latitude, longitude, heading, altitude, tilt)其中调用了Camera.cs中的SetPosition函数,其中主要代码
Point3d p = Quaternion4d.QuaternionToEuler(m_Orientation);

             _latitude.Radians = p.Y;
             _longitude.Radians = p.X;
             _heading.Radians = p.Z;
此中用到Quaternion4d和Point3d类。

最新文章