WorldWind学习系列三:简单功能分析——主窗体的键盘监听处理及拷贝和粘贴位置坐标功能...

it2024-11-08  10

  在分析功能时发现,各功能都有自己的快捷键相应,比如今天要分析的 Copy Coordinates (Ctrl+C)和Paste Coordinates (Ctrl+P),以及主窗体的全屏功能也是通过快捷键(Alt+Enter)。这就使我需要彻底分析一下主窗体的键盘监听处理啦。

主窗体的键盘监听处理     

     与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函数 

 

真正处理键盘响应函数                  ///   <summary>          ///  Handles key up events.         ///   </summary>          ///   <param name="e"></param>          ///   <returns> Returns true if the key is handled. </returns>          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 ;        }

 

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

      我们看看如何实现全屏功能的,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.1worldwind://goto/world=Earth&lat=-41.38362&lon=101.15747&alt=48652548&dir=0.2worldwind://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          ///   <summary>          ///  Moves to specified location.         ///   </summary>          ///   <param name="latitude"> Latitude in degrees of target position. (-90 - 90). </param>          ///   <param name="longitude"> Longitude in degrees of target position. (-180 - 180). </param>          ///   <param name="heading"> Camera heading in degrees (0-360) or double.NaN for no change. </param>          ///   <param name="altitude"> Camera altitude in meters or double.NaN for no change. </param>          ///   <param name="perpendicularViewRange"></param>          ///   <param name="tilt"> Camera tilt in degrees (-90 - 90) or double.NaN for no change. </param>          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类。

 

希望网友能有所收获,其他部分:

WorldWind学习系列三:功能分析——截屏功能和“关于”窗体分析

WorldWind学习系列二:擒贼先擒王篇2

WorldWind学习系列二:擒贼先擒王篇1

WorldWind学习系列一:顺利起航篇

 

    

转载于:https://www.cnblogs.com/wuhenke/archive/2009/12/12/1622404.html

相关资源:数据结构—成绩单生成器
最新回复(0)