About the Custom scene navigation commands Sample
[C#]
Navigate.cs
using System; using System.Drawing; using ESRI.ArcGIS.Analyst3D; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.ADF.BaseClasses; using ESRI.ArcGIS.ADF.CATIDs; using System.Runtime.InteropServices; namespace sceneTools { [ClassInterface(ClassInterfaceType.None)] [Guid("9A3B648E-4543-438c-84C1-41CC6AD29A81")] public sealed class Navigate : BaseTool { [DllImport("user32")] public static extern int SetCapture(int hwnd); [DllImport("user32")] public static extern int SetCursor(int hCursor); [DllImport("user32")] public static extern int GetClientRect(int hwnd, ref Rectangle lpRect); [DllImport("user32")] public static extern int GetCapture(int fuFlags); [DllImport("user32")] public static extern int ReleaseCapture(int hwnd); #region COM Registration Function(s) [ComRegisterFunction()] [ComVisible(false)] static void RegisterFunction(Type registerType) { // Required for ArcGIS Component Category Registrar support ArcGISCategoryRegistration(registerType); // // TODO: Add any COM registration code here // } [ComUnregisterFunction()] [ComVisible(false)] static void UnregisterFunction(Type registerType) { // Required for ArcGIS Component Category Registrar support ArcGISCategoryUnregistration(registerType); // // TODO: Add any COM unregistration code here // } #region ArcGIS Component Category Registrar generated code /// <summary> /// Required method for ArcGIS Component Category registration - /// Do not modify the contents of this method with the code editor. /// </summary> private static void ArcGISCategoryRegistration(Type registerType) { string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); ControlsCommands.Register(regKey); } /// <summary> /// Required method for ArcGIS Component Category unregistration - /// Do not modify the contents of this method with the code editor. /// </summary> private static void ArcGISCategoryUnregistration(Type registerType) { string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID); ControlsCommands.Unregister(regKey); } #endregion #endregion private ISceneHookHelper m_pSceneHookHelper; private bool m_bInUse; private bool m_bGesture; private bool bCancel = false; private long m_lMouseX, m_lMouseY; private bool m_bSpinning; private double m_dSpinStep; private System.Windows.Forms.Cursor m_pCursorNav; private System.Windows.Forms.Cursor m_pCursorPan; private System.Windows.Forms.Cursor m_pCursorZoom; private System.Windows.Forms.Cursor m_pCursorGest; public Navigate() { base.m_category = "Sample_SceneControl(C#)"; base.m_caption = "Navigate"; base.m_toolTip = "Navigate"; base.m_name = "Sample_SceneControl(C#)/Navigate"; base.m_message = "Navigates the scene"; //Load resources string[] res = GetType().Assembly.GetManifestResourceNames(); if(res.GetLength(0) > 0) { base.m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream("sceneTools.Navigation.bmp")); } m_pCursorNav = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("sceneTools.navigation.cur")); m_pCursorPan = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("sceneTools.movehand.cur")); m_pCursorZoom = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("sceneTools.ZOOMINOUT.CUR")); m_pCursorGest = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("sceneTools.gesture.cur")); m_pSceneHookHelper = new SceneHookHelperClass (); } public override void OnCreate(object hook) { m_pSceneHookHelper.Hook = hook; if(m_pSceneHookHelper != null) { m_bGesture = m_pSceneHookHelper.ActiveViewer.GestureEnabled; m_bSpinning = false; } } public override bool Enabled { get { //Disable if orthographic (2D) view if(m_pSceneHookHelper.Hook == null || m_pSceneHookHelper.Scene == null) return false; else { ICamera pCamera = (ICamera) m_pSceneHookHelper.Camera; if(pCamera.ProjectionType == esri3DProjectionType.esriOrthoProjection) return false; else return true; } } } public override int Cursor { get { if(m_bGesture == true) return m_pCursorGest.Handle.ToInt32(); else return m_pCursorNav.Handle.ToInt32(); } } public override bool Deactivate() { return true; } public override void OnMouseDown(int Button, int Shift, int X, int Y) { if (Button == 3) bCancel = true; else { m_bInUse = true; SetCapture(m_pSceneHookHelper.ActiveViewer.hWnd); m_lMouseX = X; m_lMouseY = Y; } } public override void OnMouseMove(int Button, int Shift, int X, int Y) { if(m_bInUse == false) return; if(X - m_lMouseX == 0 && Y - m_lMouseY == 0) return; long dx, dy; dx = X - m_lMouseX; dy = Y - m_lMouseY; //If right mouse clicked if (Button == 2) { //Set the zoom cursor SetCursor(m_pCursorZoom.Handle.ToInt32()); if (dy < 0) m_pSceneHookHelper.Camera.Zoom(1.1); else if (dy > 0) m_pSceneHookHelper.Camera.Zoom(0.9); } //If two mouse buttons clicked if(Button == 3) { //Set the pan cursor SetCursor(m_pCursorPan.Handle.ToInt32()); //Create a point with previous mouse coordinates IPoint pStartPoint; pStartPoint = new PointClass(); pStartPoint.PutCoords((double) m_lMouseX, (double) m_lMouseY); //Create point with a new mouse coordinates IPoint pEndPoint; pEndPoint = new PointClass(); pEndPoint.PutCoords((double) X, (double) Y); //Pan camera m_pSceneHookHelper.Camera.Pan(pStartPoint, pEndPoint); } //If left mouse clicked if(Button == 1) { //If scene viewer gesturing is disabled move the camera observer if(m_bGesture == false) m_pSceneHookHelper.Camera.PolarUpdate(1, dx, dy, true); else { //if camera already spinning if(m_bSpinning == true) { //Move the camera observer m_pSceneHookHelper.Camera.PolarUpdate(1, dx, dy, true); } else { //Windows API call to get windows client coordinates Rectangle rect; rect = new Rectangle(); GetClientRect(m_pSceneHookHelper.ActiveViewer.hWnd, ref rect); //Recalculate the spin step if(dx < 0) m_dSpinStep = (180.0 / rect.Right - rect.Left ) * (dx - m_pSceneHookHelper.ActiveViewer.GestureSensitivity); else m_dSpinStep = (180.0 / rect.Right - rect.Left) * (dx + m_pSceneHookHelper.ActiveViewer.GestureSensitivity); //Start spinning StartSpin(); } } } //Set Mouse coordinates for the next //OnMouse Event m_lMouseX = X; m_lMouseY = Y; //Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(true); } public override void OnMouseUp(int Button, int Shift, int X, int Y) { //Set the navigation cursor if(m_bGesture == true) SetCursor(m_pCursorGest.Handle.ToInt32()); else SetCursor(m_pCursorNav.Handle.ToInt32()); if(GetCapture(m_pSceneHookHelper.ActiveViewer.hWnd) != 0) ReleaseCapture(m_pSceneHookHelper.ActiveViewer.hWnd); } public void StartSpin() { m_bSpinning = true; //Get IMessageDispatcher interface IMessageDispatcher pMessageDispatcher; pMessageDispatcher = new MessageDispatcherClass(); //Set the ESC key to be seen as a cancel action pMessageDispatcher.CancelOnClick = false; pMessageDispatcher.CancelOnEscPress = true; do { //Move the camera observer m_pSceneHookHelper.Camera.PolarUpdate(1, m_dSpinStep, 0, true); //Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(true); //Dispatch any waiting messages: OnMouseMove/ OnMouseDown/ OnKeyUp/ OnKeyDown events object b_oCancel; pMessageDispatcher.Dispatch(m_pSceneHookHelper.ActiveViewer.hWnd, false, out b_oCancel); if(bCancel == true) m_bSpinning = false; } while(bCancel == false); bCancel = false; } public override void OnKeyDown(int keyCode, int Shift) { if (keyCode == 27) { bCancel = true; SetCursor(m_pCursorNav.Handle.ToInt32()); } switch(Shift) { case 1: //Shift key //Set pan cursor SetCursor(m_pCursorPan.Handle.ToInt32()); break; case 2: //Control key //Set ZoomIn/Out cursor SetCursor(m_pCursorZoom.Handle.ToInt32()); break; case 3: //shift + control keys //Set scene viewer gesture enabled property if(m_bSpinning == false) { if(m_bGesture == true) { m_pSceneHookHelper.ActiveViewer.GestureEnabled = false; m_bGesture = false; SetCursor(m_pCursorNav.Handle.ToInt32()); } else { m_pSceneHookHelper.ActiveViewer.GestureEnabled = true; m_bGesture = true; SetCursor(m_pCursorGest.Handle.ToInt32()); } } break; default: return; } } public override void OnKeyUp(int keyCode, int Shift) { if(Shift == 1) //Shift key { //Pan the camera switch(keyCode) { case 38: //Up key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveDown, 0.01); break; case 40: //Down key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveUp, 0.01); break; case 37: //Left key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveRight, 0.01); break; case 39: // Right key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveLeft, 0.01); break; default: return; } } else if(Shift == 2) //Control key { //Move camera in/out or turn camera around the observer switch(keyCode) { case 38: m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveAway, 0.01); break; case 40: m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveToward, 0.01); break; case 37: m_pSceneHookHelper.Camera.HTurnAround(-1); break; case 39: m_pSceneHookHelper.Camera.HTurnAround(1); break; default: return; } } else { double d = 5, dAltitude = 2, dAzimuth = 2; //Move the camera observer by the given polar //increments or increase/decrease the spin speed switch(keyCode) { case 38: m_pSceneHookHelper.Camera.PolarUpdate(1, 0, -dAltitude * d, true); break; case 40: m_pSceneHookHelper.Camera.PolarUpdate(1, 0, dAltitude * d, true); break; case 37: m_pSceneHookHelper.Camera.PolarUpdate(1, dAzimuth * d, 0, true); break; case 39: m_pSceneHookHelper.Camera.PolarUpdate(1, -dAzimuth * d, 0, true); break; case 33: //Page Up m_dSpinStep = m_dSpinStep * 1.1; break; case 34: //Page Down m_dSpinStep = m_dSpinStep / 1.1; break; default: return; } } //Set the navigation cursor if(m_bGesture == true) SetCursor(m_pCursorGest.Handle.ToInt32()); else SetCursor(m_pCursorNav.Handle.ToInt32()); //Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(true); } } }
[Visual Basic .NET]
Navigate.vb
Imports System.Drawing Imports ESRI.ArcGIS.Analyst3D Imports ESRI.ArcGIS.GeomeTry Imports ESRI.ArcGIS.Controls Imports ESRI.ArcGIS.ADF.BaseClasses Imports ESRI.ArcGIS.ADF.CATIDs Imports System.Runtime.InteropServices <ComClass(Navigate.ClassId, Navigate.InterfaceId, Navigate.EventsId)> _ Public NotInheritable Class Navigate Inherits BaseTool #Region "COM GUIDs" ' These GUIDs provide the COM identity for this class ' and its COM interfaces. If you change them, existing ' clients will no longer be able to access the class. Public Const ClassId As String = "E4BDFC47-0845-4DF1-B4B4-637EF86C299A" Public Const InterfaceId As String = "12F31942-BCB1-487C-9790-DB497983B5C7" Public Const EventsId As String = "2D9B12D3-59E9-4C0E-8218-FBD220446757" #End Region #Region "COM Registration Function(s)" <ComRegisterFunction(), ComVisibleAttribute(False)> _ Public Shared Sub RegisterFunction(ByVal registerType As Type) ' Required for ArcGIS Component Category Registrar support ArcGISCategoryRegistration(registerType) 'Add any COM registration code after the ArcGISCategoryRegistration() call End Sub <ComUnregisterFunction(), ComVisibleAttribute(False)> _ Public Shared Sub UnregisterFunction(ByVal registerType As Type) ' Required for ArcGIS Component Category Registrar support ArcGISCategoryUnregistration(registerType) 'Add any COM unregistration code after the ArcGISCategoryUnregistration() call End Sub #Region "ArcGIS Component Category Registrar generated code" ''' <summary> ''' Required method for ArcGIS Component Category registration - ''' Do not modify the contents of this method with the code editor. ''' </summary> Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type) Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID) ControlsCommands.Register(regKey) End Sub ''' <summary> ''' Required method for ArcGIS Component Category unregistration - ''' Do not modify the contents of this method with the code editor. ''' </summary> Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type) Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID) ControlsCommands.Unregister(regKey) End Sub #End Region #End Region Declare Function GetClientRect Lib "user32" (ByVal hwnd As Integer, ByRef lpRect As Rectangle) As Integer Declare Function GetCapture Lib "user32" (ByVal fuFlags As Integer) As Integer Declare Function SetCapture Lib "user32" (ByVal hwnd As Integer) As Integer Declare Function SetCursor Lib "user32" (ByVal hCursor As Integer) As Integer Declare Function ReleaseCapture Lib "user32" (ByVal hwnd As Integer) As Integer Private m_pSceneHookHelper As ISceneHookHelper Private m_bInUse As Boolean Private m_bGesture As Boolean Private bCancel As Boolean = False Private m_lMouseX, m_lMouseY As Long Private m_bSpinning As Boolean Private m_dSpinStep As Double Private m_pCursorNav As System.Windows.Forms.Cursor Private m_pCursorPan As System.Windows.Forms.Cursor Private m_pCursorZoom As System.Windows.Forms.Cursor Private m_pCursorGest As System.Windows.Forms.Cursor ' A creatable COM class must have a Public Sub New() ' with no parameters, otherwise, the class will not be ' registered in the COM registry and cannot be created ' via CreateObject. Public Sub New() MyBase.New() MyBase.m_category = "Sample_SceneControl(VB.NET)" MyBase.m_caption = "Navigate" MyBase.m_toolTip = "Navigate" MyBase.m_name = "Sample_SceneControl(VB.NET)/Navigate" MyBase.m_message = "Navigates the scene" 'Load resources Dim res() As String = GetType(Navigate).Assembly.GetManifestResourceNames() If res.GetLength(0) > 0 Then MyBase.m_bitmap = New System.Drawing.Bitmap(GetType(Navigate).Assembly.GetManifestResourceStream("SceneToolsVB.Navigation.bmp")) End If m_pCursorNav = New System.Windows.Forms.Cursor(GetType(Navigate).Assembly.GetManifestResourceStream("SceneToolsVB.navigation.cur")) m_pCursorPan = New System.Windows.Forms.Cursor(GetType(Navigate).Assembly.GetManifestResourceStream("SceneToolsVB.movehand.cur")) m_pCursorZoom = New System.Windows.Forms.Cursor(GetType(Navigate).Assembly.GetManifestResourceStream("SceneToolsVB.ZOOMINOUT.CUR")) m_pCursorGest = New System.Windows.Forms.Cursor(GetType(Navigate).Assembly.GetManifestResourceStream("SceneToolsVB.gesture.cur")) m_pSceneHookHelper = New SceneHookHelperClass End Sub Public Overrides Sub OnCreate(ByVal hook As Object) m_pSceneHookHelper.Hook = hook If (Not m_pSceneHookHelper Is Nothing) Then m_bGesture = m_pSceneHookHelper.ActiveViewer.GestureEnabled m_bSpinning = False End If End Sub Public Overrides ReadOnly Property Enabled() As Boolean Get 'Disable if orthographic (2D) view If (m_pSceneHookHelper.Hook Is Nothing Or m_pSceneHookHelper.Scene Is Nothing) Then Return False Else Dim pCamera As ICamera = CType(m_pSceneHookHelper.Camera, ICamera) If (pCamera.ProjectionType = esri3DProjectionType.esriOrthoProjection) Then Return False Else Return True End If End If End Get End Property Public Overrides ReadOnly Property Cursor() As Integer Get If (m_bGesture = True) Then Return m_pCursorGest.Handle.ToInt32() Else Return m_pCursorNav.Handle.ToInt32() End If End Get End Property Public Overrides Function Deactivate() As Boolean Return True End Function Public Overrides Sub OnMouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer) If (Button = 3) Then bCancel = True Else m_bInUse = True SetCapture(m_pSceneHookHelper.ActiveViewer.hWnd) m_lMouseX = X m_lMouseY = Y End If End Sub Public Overrides Sub OnMouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer) If (m_bInUse = False) Then Return End If If (X - m_lMouseX = 0 And Y - m_lMouseY = 0) Then Return End If Dim dx, dy As Long dx = X - m_lMouseX dy = Y - m_lMouseY 'If right mouse clicked If (Button = 2) Then 'Set the zoom cursor SetCursor(m_pCursorZoom.Handle.ToInt32()) If (dy < 0) Then m_pSceneHookHelper.Camera.Zoom(1.1) ElseIf (dy > 0) Then m_pSceneHookHelper.Camera.Zoom(0.9) End If End If 'If two mouse buttons clicked If (Button = 3) Then 'Set the pan cursor SetCursor(m_pCursorPan.Handle.ToInt32()) 'Create a point with previous mouse coordinates Dim pStartPoint As IPoint pStartPoint = New PointClass pStartPoint.PutCoords(m_lMouseX, m_lMouseY) 'Create point with a new mouse coordinates Dim pEndPoint As IPoint pEndPoint = New PointClass pEndPoint.PutCoords(X, Y) 'Pan camera m_pSceneHookHelper.Camera.Pan(pStartPoint, pEndPoint) End If 'If left mouse clicked If (Button = 1) Then 'If scene viewer gesturing is disabled move the camera observer If (m_bGesture = False) Then m_pSceneHookHelper.Camera.PolarUpdate(1, dx, dy, True) Else 'If camera already spinning If (m_bSpinning = True) Then 'Move the camera observer m_pSceneHookHelper.Camera.PolarUpdate(1, dx, dy, True) Else 'Windows API call to get windows client coordinates Dim rect As Rectangle rect = New Rectangle GetClientRect(m_pSceneHookHelper.ActiveViewer.hWnd, rect) 'Recalculate the spin step If (dx < 0) Then m_dSpinStep = (180.0 / rect.Right - rect.Left) * (dx - m_pSceneHookHelper.ActiveViewer.GestureSensitivity) Else m_dSpinStep = (180.0 / rect.Right - rect.Left) * (dx + m_pSceneHookHelper.ActiveViewer.GestureSensitivity) End If 'Start spinning StartSpin() End If End If End If 'Set Mouse coordinates for the next 'OnMouse Event m_lMouseX = X m_lMouseY = Y 'Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(True) End Sub Public Sub StartSpin() m_bSpinning = True 'Get IMessageDispatcher interface Dim pMessageDispatcher As IMessageDispatcher pMessageDispatcher = New MessageDispatcherClass 'Set the ESC key to be seen as a cancel action pMessageDispatcher.CancelOnClick = False pMessageDispatcher.CancelOnEscPress = True Do 'Move the camera observer m_pSceneHookHelper.Camera.PolarUpdate(1, m_dSpinStep, 0, True) 'Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(True) 'Dispatch any waiting messages: OnMouseMove/ OnMouseDown/ OnKeyUp/ OnKeyDown events Dim b_oCancel As Object = Nothing pMessageDispatcher.Dispatch(m_pSceneHookHelper.ActiveViewer.hWnd, False, b_oCancel) If (bCancel = True) Then m_bSpinning = False End If Loop While (bCancel = False) bCancel = False End Sub Public Overrides Sub OnKeyDown(ByVal keyCode As Integer, ByVal Shift As Integer) If (keyCode = 27) Then bCancel = True SetCursor(m_pCursorNav.Handle.ToInt32()) End If Select Case Shift Case 1 'Shift key SetCursor(m_pCursorPan.Handle.ToInt32()) Case 2 'Control key SetCursor(m_pCursorZoom.Handle.ToInt32()) Case 3 'shift + control key 'Set scene viewer gesture enabled property If (m_bSpinning = False) Then If (m_bGesture = True) Then m_pSceneHookHelper.ActiveViewer.GestureEnabled = False m_bGesture = False SetCursor(m_pCursorNav.Handle.ToInt32()) Else m_pSceneHookHelper.ActiveViewer.GestureEnabled = True m_bGesture = True SetCursor(m_pCursorGest.Handle.ToInt32()) End If End If Case Else Return End Select End Sub Public Overrides Sub OnKeyUp(ByVal keyCode As Integer, ByVal Shift As Integer) If (Shift = 1) Then 'Pan the camera Select Case keyCode Case 38 'Up key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveDown, 0.01) Case 40 ' Down key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveUp, 0.01) Case 37 'Left key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveRight, 0.01) Case 39 'Right key m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveLeft, 0.01) Case Else Return End Select ElseIf (Shift = 2) Then 'Control key 'Move camera in/out or turn camera around the observer Select Case keyCode Case 38 m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveAway, 0.01) Case 40 m_pSceneHookHelper.Camera.Move(esriCameraMovementType.esriCameraMoveToward, 0.01) Case 37 m_pSceneHookHelper.Camera.HTurnAround(-1) Case 39 m_pSceneHookHelper.Camera.HTurnAround(1) Case Else Return End Select Else Dim d, dAltitude, dAzimuth As Double d = 5 dAltitude = 2 dAzimuth = 2 'Move the camera observer by the given polar 'increments or increase/decrease the spin speed Select Case keyCode Case 38 m_pSceneHookHelper.Camera.PolarUpdate(1, 0, -dAltitude * d, True) Case 40 m_pSceneHookHelper.Camera.PolarUpdate(1, 0, dAltitude * d, True) Case 37 m_pSceneHookHelper.Camera.PolarUpdate(1, dAzimuth * d, 0, True) Case 39 m_pSceneHookHelper.Camera.PolarUpdate(1, -dAzimuth * d, 0, True) Case 33 ' Page up m_dSpinStep = m_dSpinStep * 1.1 Case 34 ' Page down m_dSpinStep = m_dSpinStep / 1.1 Case Else Return End Select End If 'Set the navigation cursor If (m_bGesture = True) Then SetCursor(m_pCursorGest.Handle.ToInt32()) Else SetCursor(m_pCursorNav.Handle.ToInt32()) End If 'Redraw the scene viewer m_pSceneHookHelper.ActiveViewer.Redraw(True) End Sub Public Overrides Sub OnMouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer) 'Set the navigation cursor If (m_bGesture = True) Then SetCursor(m_pCursorGest.Handle.ToInt32()) Else SetCursor(m_pCursorNav.Handle.ToInt32()) End If If (GetCapture(m_pSceneHookHelper.ActiveViewer.hWnd) <> 0) Then ReleaseCapture(m_pSceneHookHelper.ActiveViewer.hWnd) End If End Sub End Class