Pan Tool

Created:9/20/2000
Description:

There are two approaches to panning - TrackPan and the group PanStart, PanMoveTo, and PanStop. TrackPan is the easiest to use as it takes care of all the mouse events, performs the pan, and refreshes the display when the pan is complete. This sample shows how to use the PanStart group which gives developers more control. This pan tool works very much like ArcMap's pan tool working with whatever view is currently acitve: the focus map, an activated view, the layout view, and magnifier windows.

See the TrackPan tip for a sample showing how TrackPan works.


How to use:
  1. Add a UIToolControl to any toolbar.
  2. Paste this code in for the control. Make sure the name of the new control matches the sample code. The sample code assumes the control's name is UIToolControl1.
  3. Load some data and after zooming in, use the new Pan tool.
  4. Add several magnifier windows and notice how the pan works only when they are in snap shot mode.
Option Explicit

Private m_pMxApp As IMxApplication
Private m_pMxDocument As IMxDocument
Private m_pScreenDisplay As IScreenDisplay
Private m_pMapInsetWindow As IMapInsetWindow
Private m_bMouseDown As Boolean

Private Sub UIToolControl1_MouseDown(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
  Dim pStartPoint As IPoint

  If Not button = 1 Then Exit Sub 'Check for single click
  
  'Get the screen display currently with focus
  Set m_pScreenDisplay = GetFocusDisplay
  'Check if this screen display is a magnification window
  Set m_pMapInsetWindow = GetMapInset(m_pScreenDisplay)
  If Not m_pMapInsetWindow Is Nothing Then
    'Don't allow user to pan if mag. window doesn't have a snap shot
    If m_pMapInsetWindow.IsLive Then Exit Sub
  End If
  
  'Start the pan
  m_bMouseDown = True
  Set pStartPoint = m_pScreenDisplay.DisplayTransformation.ToMapPoint(x, y)
  m_pScreenDisplay.PanStart pStartPoint

End Sub

Private Sub UIToolControl1_MouseMove(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
  Dim pMoveToPoint As IPoint
  If Not m_bMouseDown Then Exit Sub
  Set pMoveToPoint = m_pScreenDisplay.DisplayTransformation.ToMapPoint(x, y)
  m_pScreenDisplay.PanMoveTo pMoveToPoint
End Sub

Private Sub UIToolControl1_MouseUp(ByVal button As Long, ByVal shift As Long, ByVal x As Long, ByVal y As Long)
  Dim pEnvelope As IEnvelope
  Dim pActiveView As IActiveView
  Dim pMapInset As IMapInset
  Dim pMapInsetWindow As IMapInsetWindow
  
  If Not m_bMouseDown Then Exit Sub
  
  m_bMouseDown = False
  Set pEnvelope = m_pScreenDisplay.PanStop 'Stop panning
  If pEnvelope Is Nothing Then Exit Sub
  
  'Check if the screen display with focus is a magnification window
  If Not m_pMapInsetWindow Is Nothing Then
    'We already know that if we have a mag window, it has a snap shot so do the pan
    Set pMapInset = m_pMapInsetWindow.MapInset
    pMapInset.VisibleBounds = pEnvelope
    m_pMapInsetWindow.Refresh
    Exit Sub
  'Otherwise, check if we are in data view or layout view
  Else
    Set pActiveView = m_pMxDocument.ActiveView
    If TypeOf pActiveView Is IMap Then
      pActiveView.Extent = pEnvelope 'Change the extent of the map
      pActiveView.Refresh 'Refresh the screen
    Else 'Must be in layout view
      Set pActiveView = pActiveView.FocusMap
      pActiveView.Extent = pEnvelope
      pActiveView.Refresh
    End If
  End If

End Sub

Private Sub UIToolControl1_Select()
  m_bMouseDown = False
  Set m_pMxApp = Application
  Set m_pMxDocument = Application.Document
End Sub

Private Function GetFocusDisplay() As IScreenDisplay
  Dim pActiveView As IActiveView
  Dim pActiveMap As IMap
  
  'Check if we are in layout or data view
  Set pActiveView = m_pMxDocument.ActiveView
  If TypeOf pActiveView Is IMap Then
    'Return the ScreenDisplay of the FocusScreen.  This could be the main
    'map window or a lens (magnifier window).
    Set GetFocusDisplay = m_pMxApp.Display.FocusScreen
  Else
    'Must be in Layout view.  Return the ScreenDisplay of FocusMap
    Set pActiveView = pActiveView.FocusMap
    Set GetFocusDisplay = pActiveView.ScreenDisplay
  End If
End Function

Private Function GetMapInset(pScreenDisplay As IScreenDisplay) As IMapInsetWindow
  Dim pAppWindows As IApplicationWindows
  Dim pWindowsSet As ISet
  Dim pDataWindow As IDataWindow
  Dim pLensWindow As ILensWindow
  
  'Determine which data window the screen display belongs to
  Set pAppWindows = m_pMxApp 'QI
  Set pWindowsSet = pAppWindows.DataWindows
  pWindowsSet.Reset
  Set pDataWindow = pWindowsSet.Next
  Do While Not pDataWindow Is Nothing
    'Only look at lens windows
    If TypeOf pDataWindow Is ILensWindow Then
      Set pLensWindow = pDataWindow
      If pLensWindow.ScreenDisplay Is m_pScreenDisplay Then
        'Double check that we are indeed working with a MapInsetWindow object
        If TypeOf pLensWindow Is IMapInsetWindow Then
          Set GetMapInset = pLensWindow
          Exit Function
        End If
      End If
      
    End If
    Set pDataWindow = pWindowsSet.Next
  Loop
  
  'Couldn't find a data window that matched
  Set GetMapInset = Nothing
  
End Function