Advertisement
PiToLoKo

mousehook by Elektro

Mar 6th, 2015
477
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 50.18 KB | None | 0 0
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 16-February-2015
  4. ' ***********************************************************************
  5. ' <copyright file="MouseHook.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Option Statements "
  11.  
  12. Option Strict On
  13. Option Explicit On
  14. Option Infer Off
  15.  
  16. #End Region
  17.  
  18. #Region " Instructions "
  19.  
  20. ' Go to page:
  21. ' Project > Properties > Debug
  22. '
  23. ' Then uncheck the option:
  24. ' "Enable the Visual Studio Hosting Process"
  25.  
  26. #End Region
  27.  
  28. #Region " Usage Examples "
  29.  
  30. ' ''' <summary>
  31. ' ''' A low level mouse hook that intercepts mouse events.
  32. ' ''' </summary>
  33. 'Private WithEvents mouseEvents As New MouseHook(Install:=False) With
  34. '    {
  35. '        .WorkingArea = SystemInformation.VirtualScreen,
  36. '        .SuppressMouseUpEventWhenDoubleClick = False
  37. '    }
  38.  
  39. ' ''' <summary>
  40. ' ''' Handles the Load event of the Form1.
  41. ' ''' </summary>
  42. ' ''' <param name="sender">The source of the event.</param>
  43. ' ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  44. 'Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  45.  
  46. '    ' Install Mouse Hook on the System.
  47. '    Me.MouseEvents.Install()
  48.  
  49. '    ' Start processing mouse events.
  50. '    Me.MouseEvents.Enable()
  51.  
  52. 'End Sub
  53.  
  54. ' ''' <summary>
  55. ' ''' Handles the FormClosing event of the Form1.
  56. ' ''' </summary>
  57. ' ''' <param name="sender">The source of the event.</param>
  58. ' ''' <param name="e">The <see cref="FormClosingEventArgs"/> instance containing the event data.</param>
  59. 'Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) _
  60. 'Handles MyBase.FormClosing
  61.  
  62. '    ' Stop processing mouse events.
  63. '    Me.MouseEvents.Disable()
  64.  
  65. '    ' Uninstall the mouse hook from system.
  66. '    Me.MouseEvents.Uninstall()
  67.  
  68. 'End Sub
  69.  
  70. ' ''' <summary>
  71. ' ''' Handles the 'MouseMove' event of the Mouse Hook.
  72. ' ''' </summary>
  73. ' ''' <param name="sender">The source of the event.</param>
  74. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  75. 'Private Sub MouseEvents_MouseMove(ByVal sender As Object, ByVal MouseLocation As Point) _
  76. 'Handles MouseEvents.MouseMove
  77.  
  78. '    Debug.WriteLine(String.Format("Mouse Moved To: x={0}, y={1}",
  79. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  80.  
  81. 'End Sub
  82.  
  83. ' ''' <summary>
  84. ' ''' Handles the 'MouseLeftDown' event of the MouseHook.
  85. ' ''' </summary>
  86. ' ''' <param name="sender">The source of the event.</param>
  87. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  88. 'Private Sub MouseEvents_MouseLeftDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  89. 'Handles MouseEvents.MouseLeftDown
  90.  
  91. '    Debug.WriteLine(String.Format("Mouse Left Down At: x={0}, y={1}",
  92. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  93.  
  94. 'End Sub
  95.  
  96. ' ''' <summary>
  97. ' ''' Handles the 'MouseLeftUp' event of the Mouse Hook.
  98. ' ''' </summary>
  99. ' ''' <param name="sender">The source of the event.</param>
  100. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  101. 'Private Sub MouseEvents_MouseLeftUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  102. 'Handles MouseEvents.MouseLeftUp
  103.  
  104. '    Debug.WriteLine(String.Format("Mouse Left Up At: x={0}, y={1}",
  105. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  106.  
  107. 'End Sub
  108.  
  109. ' ''' <summary>
  110. ' ''' Handles the 'MouseRightDown' event of the MouseHook.
  111. ' ''' </summary>
  112. ' ''' <param name="sender">The source of the event.</param>
  113. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  114. 'Private Sub MouseEvents_MouseRightDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  115. 'Handles MouseEvents.MouseRightDown
  116.  
  117. '    Debug.WriteLine(String.Format("Mouse Right Down At: x={0}, y={1}",
  118. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  119.  
  120. 'End Sub
  121.  
  122. ' ''' <summary>
  123. ' ''' Handles the 'MouseRightUp' event of the Mouse Hook.
  124. ' ''' </summary>
  125. ' ''' <param name="sender">The source of the event.</param>
  126. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  127. 'Private Sub MouseEvents_MouseRightUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  128. 'Handles MouseEvents.MouseRightUp
  129.  
  130. '    Debug.WriteLine(String.Format("Mouse Right Up At: x={0}, y={1}",
  131. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  132.  
  133. 'End Sub
  134.  
  135. ' ''' <summary>
  136. ' ''' Handles the 'MouseMiddleDown' event of the MouseHook.
  137. ' ''' </summary>
  138. ' ''' <param name="sender">The source of the event.</param>
  139. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  140. 'Private Sub MouseEvents_MouseMiddleDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  141. 'Handles MouseEvents.MouseMiddleDown
  142.  
  143. '    Debug.WriteLine(String.Format("Mouse Middle Down At: x={0}, y={1}",
  144. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  145.  
  146. 'End Sub
  147.  
  148. ' ''' <summary>
  149. ' ''' Handles the 'MouseMiddleUp' event of the Mouse Hook.
  150. ' ''' </summary>
  151. ' ''' <param name="sender">The source of the event.</param>
  152. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  153. 'Private Sub MouseEvents_MouseMiddleUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  154. 'Handles MouseEvents.MouseMiddleUp
  155.  
  156. '    Debug.WriteLine(String.Format("Mouse Middle Up At: x={0}, y={1}",
  157. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  158.  
  159. 'End Sub
  160.  
  161. ' ''' <summary>
  162. ' ''' Handles the 'MouseLeftDoubleClick' event of the Mouse Hook.
  163. ' ''' </summary>
  164. ' ''' <param name="sender">The source of the event.</param>
  165. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  166. 'Private Sub MouseEvents_MouseLeftDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  167. 'Handles MouseEvents.MouseLeftDoubleClick
  168.  
  169. '    Debug.WriteLine(String.Format("Mouse Left Double-Click At: x={0}, y={1}",
  170. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  171.  
  172. 'End Sub
  173.  
  174. ' ''' <summary>
  175. ' ''' Handles the 'MouseRightDoubleClick' event of the Mouse Hook.
  176. ' ''' </summary>
  177. ' ''' <param name="sender">The source of the event.</param>
  178. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  179. 'Private Sub MouseEvents_MouseRightDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  180. 'Handles MouseEvents.MouseRightDoubleClick
  181.  
  182. '    Debug.WriteLine(String.Format("Mouse Right Double-Click At: x={0}, y={1}",
  183. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  184.  
  185. 'End Sub
  186.  
  187. ' ''' <summary>
  188. ' ''' Handles the 'MouseMiddleDoubleClick' event of the Mouse Hook.
  189. ' ''' </summary>
  190. ' ''' <param name="sender">The source of the event.</param>
  191. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  192. 'Private Sub MouseEvents_MouseMiddleDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  193. 'Handles MouseEvents.MouseMiddleDoubleClick
  194.  
  195. '    Debug.WriteLine(String.Format("Mouse Middle Double-Click At: x={0}, y={1}",
  196. '                                  CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  197.  
  198. 'End Sub
  199.  
  200. ' ''' <summary>
  201. ' ''' Handles the 'MouseWheel' event of the Mouse Hook.
  202. ' ''' </summary>
  203. ' ''' <param name="sender">The source of the event.</param>
  204. ' ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  205. ' ''' <param name="WheelDirection">Contains the wheel direction (WheelUp or WheelDown).</param>
  206. 'Private Sub MouseEvents_MouseWheel(ByVal sender As Object,
  207. '                                   ByVal MouseLocation As Point,
  208. '                                   ByVal WheelDirection As MouseHook.WheelDirection) _
  209. 'Handles MouseEvents.MouseWheel
  210.  
  211. '    Debug.WriteLine(String.Format("Mouse Whell ({0}) At: x={1}, y={2}",
  212. '                                  WheelDirection.ToString, CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  213.  
  214. 'End Sub
  215.  
  216. #End Region
  217.  
  218. #Region " Imports "
  219.  
  220. Imports System.ComponentModel
  221. Imports System.Reflection
  222. Imports System.Runtime.InteropServices
  223.  
  224. #End Region
  225.  
  226. #Region " MouseHook "
  227.  
  228. Namespace Tools
  229.  
  230.     ''' <summary>
  231.     ''' A low level mouse hook that processes mouse input events.
  232.     ''' </summary>
  233.     Friend NotInheritable Class MouseHook : Implements IDisposable
  234.  
  235. #Region " P/Invoke "
  236.  
  237.         ''' <summary>
  238.         ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  239.         ''' This class does not suppress stack walks for unmanaged code permission.
  240.         ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/>  must not be applied to this class.
  241.         ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  242.         ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/ms182161.aspx
  243.         ''' </summary>
  244.         Protected NotInheritable Class NativeMethods
  245.  
  246. #Region " Methods "
  247.  
  248.             ''' <summary>
  249.             ''' Passes the hook information to the next hook procedure in the current hook chain.
  250.             ''' A hook procedure can call this function either before or after processing the hook information.
  251.             ''' For more info see here:
  252.             ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
  253.             ''' </summary>
  254.             ''' <param name="idHook">
  255.             ''' This parameter is ignored.
  256.             ''' </param>
  257.             ''' <param name="nCode">
  258.             ''' The hook code passed to the current hook procedure.
  259.             ''' The next hook procedure uses this code to determine how to process the hook information.
  260.             ''' </param>
  261.             ''' <param name="wParam">
  262.             ''' The wParam value passed to the current hook procedure.
  263.             ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  264.             ''' </param>
  265.             ''' <param name="lParam">
  266.             ''' The lParam value passed to the current hook procedure.
  267.             ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  268.             ''' </param>
  269.             ''' <returns>
  270.             ''' This value is returned by the next hook procedure in the chain.
  271.             ''' The current hook procedure must also return this value.
  272.             ''' The meaning of the return value depends on the hook type.
  273.             ''' For more information, see the descriptions of the individual hook procedures.
  274.             ''' </returns>
  275.             <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  276.             Public Shared Function CallNextHookEx(
  277.                ByVal idHook As IntPtr,
  278.                ByVal nCode As Integer,
  279.                ByVal wParam As IntPtr,
  280.                ByVal lParam As IntPtr
  281.         ) As IntPtr
  282.             End Function
  283.  
  284.             ''' <summary>
  285.             ''' Installs an application-defined hook procedure into a hook chain.
  286.             ''' You would install a hook procedure to monitor the system for certain types of events.
  287.             ''' These events are associated either with a specific thread
  288.             ''' or with all threads in the same desktop as the calling thread.
  289.             ''' For more info see here:
  290.             ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  291.             ''' </summary>
  292.             ''' <param name="idHook">
  293.             ''' The type of hook procedure to be installed.
  294.             ''' </param>
  295.             ''' <param name="lpfn">
  296.             ''' A pointer to the hook procedure.
  297.             ''' If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process,
  298.             ''' the lpfn parameter must point to a hook procedure in a DLL.
  299.             ''' Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
  300.             ''' </param>
  301.             ''' <param name="hInstance">
  302.             ''' A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
  303.             ''' The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by
  304.             ''' the current process and if the hook procedure is within the code associated with the current process.
  305.             ''' </param>
  306.             ''' <param name="threadId">
  307.             ''' The identifier of the thread with which the hook procedure is to be associated.
  308.             ''' For desktop apps, if this parameter is zero, the hook procedure is associated
  309.             ''' with all existing threads running in the same desktop as the calling thread.
  310.             ''' </param>
  311.             ''' <returns>
  312.             ''' If the function succeeds, the return value is the handle to the hook procedure.
  313.             ''' If the function fails, the return value is NULL.
  314.             ''' </returns>
  315.             <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  316.             Public Shared Function SetWindowsHookEx(
  317.                ByVal idHook As HookType,
  318.                ByVal lpfn As LowLevelMouseProcDelegate,
  319.                ByVal hInstance As IntPtr,
  320.                ByVal threadId As UInteger
  321.         ) As IntPtr
  322.             End Function
  323.  
  324.             ''' <summary>
  325.             ''' Removes a hook procedure installed in a hook chain by the 'SetWindowsHookEx' function.
  326.             ''' For more info see here:
  327.             ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
  328.             ''' </summary>
  329.             ''' <param name="idHook">
  330.             ''' A handle to the hook to be removed.
  331.             ''' This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
  332.             ''' </param>
  333.             ''' <returns>
  334.             ''' If the function succeeds, the return value is nonzero.
  335.             ''' If the function fails, the return value is zero.
  336.             ''' </returns>
  337.             <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  338.             Public Shared Function UnhookWindowsHookEx(
  339.                ByVal idHook As IntPtr
  340.         ) As Boolean
  341.             End Function
  342.  
  343.             ''' <summary>
  344.             ''' Retrieves the current double-click time for the mouse.
  345.             ''' A double-click is a series of two clicks of the mouse button,
  346.             ''' the second occurring within a specified time after the first.
  347.             ''' The double-click time is the maximum number of milliseconds that may occur
  348.             ''' between the first and second click of a double-click.
  349.             ''' The maximum double-click time is 5000 milliseconds.
  350.             ''' </summary>
  351.             ''' <returns>
  352.             ''' The return value specifies the current double-click time, in milliseconds.
  353.             ''' The maximum return value is 5000 milliseconds.
  354.             ''' </returns>
  355.             <DllImport("user32.dll", CharSet:=CharSet.Auto)>
  356.             Public Shared Function GetDoubleClickTime() As Integer
  357.             End Function
  358.  
  359. #End Region
  360.  
  361. #Region " Enumerations "
  362.  
  363.             ''' <summary>
  364.             ''' Specifies a System-Defined Message.
  365.             ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx#system_defined
  366.             ''' </summary>
  367.             Public Enum WindowsMessages As UInteger
  368.  
  369.                 ''' <summary>
  370.                 ''' Posted to a window when the cursor moves.
  371.                 ''' If the mouse is not captured, the message is posted to the window that contains the cursor.
  372.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  373.                 ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877%28v=vs.85%29.aspx
  374.                 ''' </summary>
  375.                 WM_MOUSEMOVE = &H200UI
  376.  
  377.                 ''' <summary>
  378.                 ''' Posted when the user presses the left mouse button while the cursor is in the client area of a window.
  379.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  380.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  381.                 ''' </summary>
  382.                 WM_LBUTTONDOWN = &H201UI
  383.  
  384.                 ''' <summary>
  385.                 ''' Posted when the user releases the left mouse button while the cursor is in the client area of a window.
  386.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  387.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  388.                 ''' </summary>
  389.                 WM_LBUTTONUP = &H202UI
  390.  
  391.                 ''' <summary>
  392.                 ''' Posted when the user presses the right mouse button while the cursor is in the client area of a window.
  393.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  394.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  395.                 ''' </summary>
  396.                 WM_RBUTTONDOWN = &H204UI
  397.  
  398.                 ''' <summary>
  399.                 ''' Posted when the user releases the right mouse button while the cursor is in the client area of a window.
  400.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  401.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  402.                 ''' </summary>
  403.                 WM_RBUTTONUP = &H205UI
  404.  
  405.                 ''' <summary>
  406.                 ''' Posted when the user presses the middle mouse button while the cursor is in the client area of a window.
  407.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  408.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  409.                 ''' </summary>
  410.                 WM_MBUTTONDOWN = &H207UI
  411.  
  412.                 ''' <summary>
  413.                 ''' Posted when the user releases the middle mouse button while the cursor is in the client area of a window.
  414.                 ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  415.                 ''' Otherwise, the message is posted to the window that has captured the mouse
  416.                 ''' </summary>
  417.                 WM_MBUTTONUP = &H208UI
  418.  
  419.                 ''' <summary>
  420.                 ''' Sent to the active window when the mouse's horizontal scroll wheel is tilted or rotated.
  421.                 ''' The DefWindowProc function propagates the message to the window's parent.
  422.                 ''' There should be no internal forwarding of the message,
  423.                 ''' since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
  424.                 ''' </summary>
  425.                 WM_MOUSEWHEEL = &H20AUI
  426.  
  427.             End Enum
  428.  
  429.             ''' <summary>
  430.             ''' Indicates a type of Hook procedure to be installed.
  431.             ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  432.             ''' </summary>
  433.             Public Enum HookType As UInteger
  434.  
  435.                 ' **************************************
  436.                 ' This enumeration is partially defined.
  437.                 ' **************************************
  438.  
  439.                 ''' <summary>
  440.                 ''' Installs a hook procedure that monitors low-level mouse input events.
  441.                 ''' For more information, see the LowLevelMouseProc hook procedure.
  442.                 ''' </summary>
  443.                 WH_MOUSE_LL = 14UI
  444.  
  445.             End Enum
  446.  
  447.             ''' <summary>
  448.             ''' The event-injected flags.
  449.             ''' An application can use the following values to test the flags.
  450.             ''' Testing LLMHF_INJECTED (bit 0) will tell you whether the event was injected.
  451.             ''' If it was, then testing LLMHF_LOWER_IL_INJECTED (bit 1) will tell you
  452.             ''' whether or not the event was injected from a process running at lower integrity level.
  453.             ''' </summary>
  454.             <Flags()>
  455.             Public Enum MsllHookStructFlags As Integer
  456.  
  457.                 ''' <summary>
  458.                 ''' Test the event-injected (from any process) flag.
  459.                 ''' </summary>
  460.                 LLMHF_INJECTED = 1I
  461.  
  462.                 ''' <summary>
  463.                 ''' Test the event-injected (from a process running at lower integrity level) flag.
  464.                 ''' </summary>
  465.                 LLMHF_LOWER_IL_INJECTED = 2I
  466.  
  467.             End Enum
  468.  
  469. #End Region
  470.  
  471. #Region " Structures "
  472.  
  473.             ''' <summary>
  474.             ''' The POINT structure defines the x- and y- coordinates of a point.
  475.             ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx
  476.             ''' </summary>
  477.             <StructLayout(LayoutKind.Sequential)>
  478.             Public Structure Point
  479.  
  480.                 ''' <summary>
  481.                 ''' The x-coordinate of the point.
  482.                 ''' </summary>
  483.                 Public X As Integer
  484.  
  485.                 ''' <summary>
  486.                 ''' The y-coordinate of the point.
  487.                 ''' </summary>
  488.                 Public Y As Integer
  489.  
  490.             End Structure
  491.  
  492.             ''' <summary>
  493.             ''' Contains information about a low-level mouse input event.
  494.             ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
  495.             ''' </summary>
  496.             Public Structure MsllHookStruct
  497.  
  498.                 ''' <summary>
  499.                 ''' The ptThe x- and y-coordinates of the cursor, in screen coordinates.
  500.                 ''' </summary>
  501.                 Public Pt As NativeMethods.Point
  502.  
  503.                 ''' <summary>
  504.                 ''' If the message is 'WM_MOUSEWHEEL', the high-order word of this member is the wheel delta.
  505.                 ''' The low-order word is reserved.
  506.                 ''' A positive value indicates that the wheel was rotated forward, away from the user;
  507.                 ''' a negative value indicates that the wheel was rotated backward, toward the user.
  508.                 ''' One wheel click is defined as 'WHEEL_DELTA', which is '120'.
  509.                 ''' </summary>
  510.                 Public MouseData As Integer
  511.  
  512.                 ''' <summary>
  513.                 ''' The event-injected flag.
  514.                 ''' </summary>
  515.                 Public Flags As MsllHookStructFlags
  516.  
  517.                 ''' <summary>
  518.                 ''' The time stamp for this message.
  519.                 ''' </summary>
  520.                 Public Time As UInteger
  521.  
  522.                 ''' <summary>
  523.                 ''' Additional information associated with the message.
  524.                 ''' </summary>
  525.                 Public DwExtraInfo As IntPtr
  526.  
  527.             End Structure
  528.  
  529. #End Region
  530.  
  531. #Region " Delegates "
  532.  
  533.             ''' <summary>
  534.             ''' Delegate LowLevelMouseProc
  535.             ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  536.             ''' </summary>
  537.             ''' <returns>
  538.             ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  539.             ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  540.             ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  541.             ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  542.             ''' and may behave incorrectly as a result.
  543.             ''' If the hook procedure processed the message,
  544.             ''' it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.
  545.             ''' </returns>
  546.             Public Delegate Function LowLevelMouseProcDelegate(
  547.                     ByVal nCode As Integer,
  548.                     ByVal wParam As NativeMethods.WindowsMessages,
  549.                     ByVal lParam As IntPtr
  550.             ) As Integer
  551.  
  552. #End Region
  553.  
  554. #Region " Hidden Methods "
  555.  
  556.             ''' <summary>
  557.             ''' Determines whether the specified System.Object instances are considered equal.
  558.             ''' </summary>
  559.             <EditorBrowsable(EditorBrowsableState.Never)>
  560.             Public Shadows Sub Equals()
  561.             End Sub
  562.  
  563.             ''' <summary>
  564.             ''' Determines whether the specified System.Object instances are the same instance.
  565.             ''' </summary>
  566.             <EditorBrowsable(EditorBrowsableState.Never)>
  567.             Private Shadows Sub ReferenceEquals()
  568.             End Sub
  569.  
  570. #End Region
  571.  
  572.         End Class
  573.  
  574. #End Region
  575.  
  576. #Region " Properties "
  577.  
  578.         ''' <summary>
  579.         ''' Handle to the hook procedure.
  580.         ''' </summary>
  581.         Private Property MouseHook As IntPtr
  582.  
  583.         ''' <summary>
  584.         ''' The mouse hook delegate.
  585.         ''' </summary>
  586.         Private Property MouseHookDelegate As NativeMethods.LowLevelMouseProcDelegate
  587.  
  588.         ''' <summary>
  589.         ''' Determines whether the Hook is installed.
  590.         ''' </summary>
  591.         Public Property IsInstalled As Boolean
  592.  
  593.         ''' <summary>
  594.         ''' Determines whether the Hook is enabled.
  595.         ''' </summary>
  596.         Public Property IsEnabled As Boolean = False
  597.  
  598.         ''' <summary>
  599.         ''' ** ONLY FOR TESTING PURPOSES **
  600.         ''' Gets or sets a value indicating whether to suppress the last MouseUp event of
  601.         ''' the specified clicked button when a double-click fires.
  602.         '''
  603.         ''' If this value is set to <c>true</c>, the application will send the events in this order for a Double-Click:
  604.         ''' MouseDown, MouseUp, MouseDown, MouseDoubleClick
  605.         '''
  606.         ''' If this value is set to <c>false</c>, the application will send the events in this order for a Double-Click:
  607.         ''' MouseDown, MouseUp, MouseDown, MouseUp, MouseDoubleClick
  608.         '''
  609.         ''' </summary>
  610.         ''' <value><c>true</c> if MouseUp event is suppressed; otherwise <c>false</c>.</value>
  611.         Public Property SuppressMouseUpEventWhenDoubleClick As Boolean = False
  612.  
  613.         ''' <summary>
  614.         ''' Gets or sets the screen's working area.
  615.         ''' The events fired by this <see cref="MouseHook"/> instance will be restricted to the bounds of the specified rectangle.
  616.         ''' </summary>
  617.         ''' <value>The screen's working area.</value>
  618.         Public Property WorkingArea As Rectangle
  619.             Get
  620.                 Return Me.workingarea1
  621.             End Get
  622.             Set(ByVal value As Rectangle)
  623.                 Me.workingarea1 = value
  624.             End Set
  625.         End Property
  626.  
  627.         ''' <summary>
  628.         ''' The screen's working area
  629.         ''' </summary>
  630.         Private workingarea1 As Rectangle = SystemInformation.VirtualScreen
  631.  
  632. #End Region
  633.  
  634. #Region " Enumerations "
  635.  
  636.         ''' <summary>
  637.         ''' Indicates the whell direction of the mouse.
  638.         ''' </summary>
  639.         Public Enum WheelDirection As Integer
  640.  
  641.             ''' <summary>
  642.             ''' The wheel is moved up.
  643.             ''' </summary>
  644.             WheelUp = 1I
  645.  
  646.             ''' <summary>
  647.             ''' The wheel is moved down.
  648.             ''' </summary>
  649.             WheelDown = 2I
  650.  
  651.         End Enum
  652.  
  653. #End Region
  654.  
  655. #Region " Events "
  656.  
  657.         ''' <summary>
  658.         ''' Occurs when the mouse moves.
  659.         ''' </summary>
  660.         Public Event MouseMove(ByVal sender As Object,
  661.                                ByVal mouseLocation As Point)
  662.  
  663.         ''' <summary>
  664.         ''' Occurs when the mouse left button is pressed.
  665.         ''' </summary>
  666.         Public Event MouseLeftDown(ByVal sender As Object,
  667.                                    ByVal mouseLocation As Point)
  668.  
  669.         ''' <summary>
  670.         ''' Occurs when the mouse left button is released.
  671.         ''' </summary>
  672.         Public Event MouseLeftUp(ByVal sender As Object,
  673.                                  ByVal mouseLocation As Point)
  674.  
  675.         ''' <summary>
  676.         ''' Occurs when the mouse left button performs a double-click.
  677.         ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  678.         ''' </summary>
  679.         Public Event MouseLeftDoubleClick(ByVal sender As Object,
  680.                                           ByVal mouseLocation As Point)
  681.  
  682.         ''' <summary>
  683.         ''' Occurs when the mouse right button is pressed.
  684.         ''' </summary>
  685.         Public Event MouseRightDown(ByVal sender As Object,
  686.                                     ByVal mouseLocation As Point)
  687.  
  688.         ''' <summary>
  689.         ''' Occurs when the mouse right button is released.
  690.         ''' </summary>
  691.         Public Event MouseRightUp(ByVal sender As Object,
  692.                                   ByVal mouseLocation As Point)
  693.  
  694.         ''' <summary>
  695.         ''' Occurs when the mouse right button performs a double-click.
  696.         ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  697.         ''' </summary>
  698.         Public Event MouseRightDoubleClick(ByVal sender As Object,
  699.                                            ByVal mouseLocation As Point)
  700.  
  701.         ''' <summary>
  702.         ''' Occurs when the mouse middle button is pressed.
  703.         ''' </summary>
  704.         Public Event MouseMiddleDown(ByVal sender As Object,
  705.                                      ByVal mouseLocation As Point)
  706.  
  707.         ''' <summary>
  708.         ''' Occurs when the mouse middle button is released.
  709.         ''' </summary>
  710.         Public Event MouseMiddleUp(ByVal sender As Object,
  711.                                    ByVal mouseLocation As Point)
  712.  
  713.         ''' <summary>
  714.         ''' Occurs when the mouse middle button performs a double-click.
  715.         ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  716.         ''' </summary>
  717.         Public Event MouseMiddleDoubleClick(ByVal sender As Object,
  718.                                             ByVal mouseLocation As Point)
  719.  
  720.         ''' <summary>
  721.         ''' Occurs when the mouse wheel is moved up or down.
  722.         ''' </summary>
  723.         Public Event MouseWheel(ByVal sender As Object,
  724.                                 ByVal mouseLocation As Point,
  725.                                 ByVal wheelDirection As WheelDirection)
  726.  
  727. #End Region
  728.  
  729. #Region " Exceptions "
  730.  
  731.         ''' <summary>
  732.         ''' Exception that is thrown when trying to enable or uninstall a mouse hook that is not installed.
  733.         ''' </summary>
  734.         <Serializable>
  735.         Friend NotInheritable Class MouseHookNotInstalledException : Inherits Exception
  736.  
  737.             ''' <summary>
  738.             ''' Initializes a new instance of the <see cref="MouseHookNotInstalledException"/> class.
  739.             ''' </summary>
  740.             Friend Sub New()
  741.                 MyBase.New("MouseHook is not installed.")
  742.             End Sub
  743.  
  744.             ''' <summary>
  745.             ''' Initializes a new instance of the <see cref="MouseHookNotInstalledException" /> class with a specified error message.
  746.             ''' </summary>
  747.             ''' <param name="message">The message that describes the error.</param>
  748.             Friend Sub New(message As String)
  749.                 MyBase.New(message)
  750.             End Sub
  751.  
  752.             ''' <summary>
  753.             ''' Initializes a new instance of the <see cref="MouseHookNotInstalledException"/> class.
  754.             ''' </summary>
  755.             ''' <param name="message">The message that describes the error.</param>
  756.             ''' <param name="inner">The inner exception.</param>
  757.             Friend Sub New(message As String, inner As Exception)
  758.                 MyBase.New(message, inner)
  759.             End Sub
  760.  
  761.         End Class
  762.  
  763.         ''' <summary>
  764.         ''' Exception that is thrown when trying to disable a mouse hook that is not enabled.
  765.         ''' </summary>
  766.         <Serializable>
  767.         Friend NotInheritable Class MouseHookNotEnabledException : Inherits Exception
  768.  
  769.             ''' <summary>
  770.             ''' Initializes a new instance of the <see cref="MouseHookNotEnabledException"/> class.
  771.             ''' </summary>
  772.             Friend Sub New()
  773.                 MyBase.New("MouseHook is not enabled.")
  774.             End Sub
  775.  
  776.             ''' <summary>
  777.             ''' Initializes a new instance of the <see cref="MouseHookNotEnabledException" /> class with a specified error message.
  778.             ''' </summary>
  779.             ''' <param name="message">The message that describes the error.</param>
  780.             Friend Sub New(message As String)
  781.                 MyBase.New(message)
  782.             End Sub
  783.  
  784.             ''' <summary>
  785.             ''' Initializes a new instance of the <see cref="MouseHookNotEnabledException"/> class.
  786.             ''' </summary>
  787.             ''' <param name="message">The message that describes the error.</param>
  788.             ''' <param name="inner">The inner exception.</param>
  789.             Friend Sub New(message As String, inner As Exception)
  790.                 MyBase.New(message, inner)
  791.             End Sub
  792.  
  793.         End Class
  794.  
  795.         ''' <summary>
  796.         ''' Exception that is thrown when trying to enable a mouse hook that is already enabled.
  797.         ''' </summary>
  798.         <Serializable>
  799.         Friend NotInheritable Class MouseHookEnabledException : Inherits Exception
  800.  
  801.             ''' <summary>
  802.             ''' Initializes a new instance of the <see cref="MouseHookEnabledException"/> class.
  803.             ''' </summary>
  804.             Friend Sub New()
  805.                 MyBase.New("MouseHook is already enabled.")
  806.             End Sub
  807.  
  808.             ''' <summary>
  809.             ''' Initializes a new instance of the <see cref="MouseHookEnabledException" /> class with a specified error message.
  810.             ''' </summary>
  811.             ''' <param name="message">The message that describes the error.</param>
  812.             Friend Sub New(message As String)
  813.                 MyBase.New(message)
  814.             End Sub
  815.  
  816.             ''' <summary>
  817.             ''' Initializes a new instance of the <see cref="MouseHookEnabledException"/> class.
  818.             ''' </summary>
  819.             ''' <param name="message">The message that describes the error.</param>
  820.             ''' <param name="inner">The inner exception.</param>
  821.             Friend Sub New(message As String, inner As Exception)
  822.                 MyBase.New(message, inner)
  823.             End Sub
  824.  
  825.         End Class
  826.  
  827. #End Region
  828.  
  829. #Region " Constructors "
  830.  
  831.         ''' <summary>
  832.         ''' Prevents a default instance of the <see cref="MouseHook"/> class from being created.
  833.         ''' </summary>
  834.         Private Sub New()
  835.         End Sub
  836.  
  837.         ''' <summary>
  838.         ''' Initializes a new instance of the <see cref="MouseHook"/> class.
  839.         ''' </summary>
  840.         ''' <param name="Install">
  841.         ''' If set to <c>true</c>, the Hook starts initialized for this <see cref="MouseHook"/> instance.
  842.         ''' </param>
  843.         Public Sub New(Optional ByVal install As Boolean = False)
  844.  
  845.             If install Then
  846.                 Me.Install()
  847.             End If
  848.  
  849.         End Sub
  850.  
  851. #End Region
  852.  
  853. #Region " Public Methods "
  854.  
  855.         ''' <summary>
  856.         ''' Installs the Mouse Hook, then start processing messages to fire events.
  857.         ''' </summary>
  858.         Public Sub Install()
  859.  
  860.             If Me.IsVisualStudioHostingProcessEnabled() Then
  861.                 Throw New Exception("Visual Studio Hosting Process should be deactivated.")
  862.                 Exit Sub
  863.             End If
  864.  
  865.             Me.MouseHookDelegate = New NativeMethods.LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)
  866.  
  867.             Try
  868.                 Me.MouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.HookType.WH_MOUSE_LL,
  869.                                                               Me.MouseHookDelegate,
  870.                                                               New IntPtr(Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32), 0)
  871.  
  872.                 Me.IsInstalled = True
  873.  
  874.             Catch ex As Exception
  875.                 Throw
  876.  
  877.             End Try
  878.  
  879.         End Sub
  880.  
  881.         ''' <summary>
  882.         ''' Uninstalls the Mouse Hook and free all resources, then stop processing messages to fire events.
  883.         ''' </summary>
  884.         Public Sub Uninstall()
  885.  
  886.             If Not Me.IsInstalled Then
  887.                 Throw New MouseHookNotInstalledException
  888.  
  889.             Else
  890.                 Me.IsEnabled = False
  891.                 Me.IsInstalled = False
  892.                 Me.Finalize()
  893.  
  894.             End If
  895.  
  896.         End Sub
  897.  
  898.         ''' <summary>
  899.         ''' Temporally disables the Mouse Hook events.
  900.         ''' To Re-enable the events, call the <see cref="Enable"/> method.
  901.         ''' </summary>
  902.         Public Sub Disable()
  903.  
  904.             If Not Me.IsInstalled Then
  905.                 Throw New MouseHookNotInstalledException
  906.  
  907.             ElseIf Not Me.IsEnabled Then
  908.                 Throw New MouseHookNotEnabledException
  909.  
  910.             Else
  911.                 Me.IsEnabled = False
  912.  
  913.             End If
  914.  
  915.         End Sub
  916.  
  917.         ''' <summary>
  918.         ''' Re-enables the Mouse Hook events.
  919.         ''' </summary>
  920.         Public Sub Enable()
  921.  
  922.             If Not Me.IsInstalled Then
  923.                 Throw New MouseHookNotInstalledException
  924.  
  925.             ElseIf Me.IsEnabled Then
  926.                 Throw New MouseHookEnabledException
  927.  
  928.             Else
  929.                 Me.IsEnabled = True
  930.  
  931.             End If
  932.  
  933.         End Sub
  934.  
  935. #End Region
  936.  
  937. #Region " Private Methods "
  938.  
  939.         ''' <summary>
  940.         ''' Determines whether the Visual Studio Hosting Process is enabled on the current application.
  941.         ''' </summary>
  942.         ''' <returns><c>true</c> if Visual Studio Hosting Process is enabled; otherwise, <c>false</c>.</returns>
  943.         Private Function IsVisualStudioHostingProcessEnabled() As Boolean
  944.             Return AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe", StringComparison.OrdinalIgnoreCase)
  945.         End Function
  946.  
  947.         ''' <summary>
  948.         ''' Processes the mouse windows messages and raises it's corresponding events.
  949.         ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  950.         ''' </summary>
  951.         ''' <param name="nCode">
  952.         ''' A code the hook procedure uses to determine how to process the message.
  953.         ''' If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function
  954.         ''' without further processing and should return the value returned by CallNextHookEx.
  955.         ''' </param>
  956.         ''' <param name="wParam">The identifier of the mouse message.</param>
  957.         ''' <param name="lParam"> A pointer to an <see cref="NativeMethods.MSLLHOOKSTRUCT"/> structure.</param>
  958.         ''' <returns>
  959.         ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  960.         ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  961.         ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  962.         ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  963.         ''' and may behave incorrectly as a result.
  964.         ''' If the hook procedure processed the message,
  965.         ''' it may return a nonzero value to prevent the system from passing the
  966.         ''' message to the rest of the hook chain or the target window procedure.
  967.         ''' </returns>
  968.         Private Function LowLevelMouseProc(ByVal nCode As Integer,
  969.                                            ByVal wParam As NativeMethods.WindowsMessages,
  970.                                            ByVal lParam As IntPtr) As Integer
  971.  
  972.             If Not Me.IsEnabled Then
  973.                 Return 0I
  974.             End If
  975.  
  976.             Static leftClickTime As Integer = 0I ' Determines a left button double-click.
  977.             Static rightClickTime As Integer = 0I ' Determines a right button double-click.
  978.             Static middleClickTime As Integer = 0I ' Determines a middle button double-click.
  979.  
  980.             If nCode = 0I Then
  981.  
  982.                 Dim x As Integer
  983.                 Dim y As Integer
  984.  
  985.                 Dim mouseStruct As NativeMethods.MsllHookStruct
  986.                 mouseStruct = CType(Marshal.PtrToStructure(lParam, mouseStruct.GetType()),
  987.                                     NativeMethods.MsllHookStruct)
  988.  
  989.                 ' Fix X coordinate.
  990.                 Select Case mouseStruct.Pt.X
  991.  
  992.                     Case Is <= 0I
  993.                         If mouseStruct.Pt.X >= Me.WorkingArea.Location.X Then
  994.                             x = mouseStruct.Pt.X
  995.  
  996.                         ElseIf mouseStruct.Pt.X <= Me.WorkingArea.Location.X Then
  997.  
  998.                             If mouseStruct.Pt.X <= (Me.WorkingArea.Location.X - Me.WorkingArea.Width) Then
  999.                                 x = (Me.WorkingArea.Location.X - Me.WorkingArea.Width)
  1000.                             Else
  1001.                                 x = mouseStruct.Pt.X
  1002.  
  1003.                             End If
  1004.  
  1005.                         End If
  1006.  
  1007.                     Case Is >= Me.WorkingArea.Width
  1008.                         x = Me.WorkingArea.Width
  1009.  
  1010.                     Case Else
  1011.                         x = mouseStruct.Pt.X
  1012.  
  1013.                 End Select
  1014.  
  1015.                 ' Fix Y coordinate.
  1016.                 Select Case mouseStruct.Pt.Y
  1017.  
  1018.                     Case Is >= Me.WorkingArea.Height
  1019.                         y = Me.WorkingArea.Height
  1020.  
  1021.                     Case Is <= 0I
  1022.                         y = 0I
  1023.  
  1024.                     Case Else
  1025.                         y = mouseStruct.Pt.Y
  1026.  
  1027.                 End Select
  1028.  
  1029.                 If x <= Me.WorkingArea.Width AndAlso
  1030.                    y < Me.WorkingArea.Height AndAlso
  1031.                    mouseStruct.Pt.X > Me.WorkingArea.Width Then
  1032.                     Return 0
  1033.  
  1034.                 ElseIf x <= Me.WorkingArea.Width AndAlso
  1035.                        y < Me.WorkingArea.Height AndAlso
  1036.                        mouseStruct.Pt.X < Me.WorkingArea.X Then
  1037.                     Return 0
  1038.  
  1039.                 ElseIf x = Me.WorkingArea.Width AndAlso
  1040.                        y < Me.WorkingArea.Height Then
  1041.  
  1042.                     If Not Me.WorkingArea.Contains(x - 1, y) Then
  1043.                         Return 0
  1044.                     End If
  1045.  
  1046.                 ElseIf x < Me.WorkingArea.Width AndAlso
  1047.                        y = Me.WorkingArea.Height Then
  1048.  
  1049.                     If Not Me.WorkingArea.Contains(x, y - 1) Then
  1050.                         Return 0
  1051.                     End If
  1052.  
  1053.                 End If
  1054.  
  1055.                 Select Case wParam
  1056.  
  1057.                     Case NativeMethods.WindowsMessages.WM_MOUSEMOVE
  1058.                         RaiseEvent MouseMove(Me, New Point(x, y))
  1059.  
  1060.                     Case NativeMethods.WindowsMessages.WM_LBUTTONDOWN
  1061.                         RaiseEvent MouseLeftDown(Me, New Point(x, y))
  1062.  
  1063.                     Case NativeMethods.WindowsMessages.WM_LBUTTONUP
  1064.                         If leftClickTime <> 0 Then
  1065.                             leftClickTime = Environment.TickCount() - leftClickTime
  1066.                         End If
  1067.  
  1068.                         If (leftClickTime <> 0I) AndAlso (leftClickTime < NativeMethods.GetDoubleClickTime()) Then
  1069.                             leftClickTime = 0I
  1070.                             If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  1071.                                 RaiseEvent MouseLeftUp(Me, New Point(x, y))
  1072.                             End If
  1073.                             RaiseEvent MouseLeftDoubleClick(Me, New Point(x, y))
  1074.  
  1075.                         Else
  1076.                             leftClickTime = Environment.TickCount()
  1077.                             RaiseEvent MouseLeftUp(Me, New Point(x, y))
  1078.  
  1079.                         End If
  1080.  
  1081.                     Case NativeMethods.WindowsMessages.WM_RBUTTONDOWN
  1082.                         RaiseEvent MouseRightDown(Me, New Point(x, y))
  1083.  
  1084.                     Case NativeMethods.WindowsMessages.WM_RBUTTONUP
  1085.                         If rightClickTime <> 0I Then
  1086.                             rightClickTime = Environment.TickCount() - rightClickTime
  1087.                         End If
  1088.  
  1089.                         If (rightClickTime <> 0I) AndAlso (rightClickTime < NativeMethods.GetDoubleClickTime()) Then
  1090.                             rightClickTime = 0I
  1091.                             If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  1092.                                 RaiseEvent MouseRightUp(Me, New Point(x, y))
  1093.                             End If
  1094.                             RaiseEvent MouseRightDoubleClick(Me, New Point(x, y))
  1095.  
  1096.                         Else
  1097.                             rightClickTime = Environment.TickCount()
  1098.                             RaiseEvent MouseRightUp(Me, New Point(x, y))
  1099.  
  1100.                         End If
  1101.  
  1102.                     Case NativeMethods.WindowsMessages.WM_MBUTTONDOWN
  1103.                         RaiseEvent MouseMiddleDown(Me, New Point(x, y))
  1104.  
  1105.                     Case NativeMethods.WindowsMessages.WM_MBUTTONUP
  1106.                         If middleClickTime <> 0I Then
  1107.                             middleClickTime = Environment.TickCount() - middleClickTime
  1108.                         End If
  1109.  
  1110.                         If (middleClickTime <> 0I) AndAlso (middleClickTime < NativeMethods.GetDoubleClickTime()) Then
  1111.                             middleClickTime = 0I
  1112.                             If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  1113.                                 RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  1114.                             End If
  1115.                             RaiseEvent MouseMiddleDoubleClick(Me, New Point(x, y))
  1116.  
  1117.                         Else
  1118.                             middleClickTime = Environment.TickCount()
  1119.                             RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  1120.  
  1121.                         End If
  1122.  
  1123.                     Case NativeMethods.WindowsMessages.WM_MOUSEWHEEL
  1124.                         RaiseEvent MouseWheel(Me, New Point(x, y), If(mouseStruct.MouseData < 0I,
  1125.                                                                      WheelDirection.WheelDown,
  1126.                                                                      WheelDirection.WheelUp))
  1127.  
  1128.                     Case Else
  1129.                         ' Do Nothing
  1130.                         Exit Select
  1131.  
  1132.                 End Select
  1133.  
  1134.                 Return 0I
  1135.  
  1136.             ElseIf nCode < 0I Then
  1137.                 Return CInt(NativeMethods.CallNextHookEx(MouseHook, nCode, New IntPtr(wParam), lParam))
  1138.  
  1139.             Else ' nCode > 0
  1140.                 Return -1I
  1141.  
  1142.             End If
  1143.  
  1144.         End Function
  1145.  
  1146. #End Region
  1147.  
  1148. #Region " Hidden Methods "
  1149.  
  1150.         ''' <summary>
  1151.         ''' Serves as a hash function for a particular type.
  1152.         ''' </summary>
  1153.         <EditorBrowsable(EditorBrowsableState.Never)>
  1154.         Public Shadows Sub GetHashCode()
  1155.         End Sub
  1156.  
  1157.         ''' <summary>
  1158.         ''' Gets the System.Type of the current instance.
  1159.         ''' </summary>
  1160.         ''' <returns>The exact runtime type of the current instance.</returns>
  1161.         <EditorBrowsable(EditorBrowsableState.Never)>
  1162.         Public Shadows Function [GetType]() As Type
  1163.             Return Me.GetType
  1164.         End Function
  1165.  
  1166.         ''' <summary>
  1167.         ''' Determines whether the specified System.Object instances are considered equal.
  1168.         ''' </summary>
  1169.         <EditorBrowsable(EditorBrowsableState.Never)>
  1170.         Public Shadows Sub Equals()
  1171.         End Sub
  1172.  
  1173.         ''' <summary>
  1174.         ''' Determines whether the specified System.Object instances are the same instance.
  1175.         ''' </summary>
  1176.         <EditorBrowsable(EditorBrowsableState.Never)>
  1177.         Private Shadows Sub ReferenceEquals()
  1178.         End Sub
  1179.  
  1180.         ''' <summary>
  1181.         ''' Returns a String that represents the current object.
  1182.         ''' </summary>
  1183.         <EditorBrowsable(EditorBrowsableState.Never)>
  1184.         Public Shadows Sub ToString()
  1185.         End Sub
  1186.  
  1187. #End Region
  1188.  
  1189. #Region "IDisposable Support"
  1190.  
  1191.         ''' <summary>
  1192.         ''' Flag to detect redundant calls at <see cref="Dispose"/> method.
  1193.         ''' </summary>
  1194.         Private disposedValue As Boolean
  1195.  
  1196.         ''' <summary>
  1197.         ''' Releases unmanaged and optionally managed resources.
  1198.         ''' </summary>
  1199.         ''' <param name="disposing">
  1200.         ''' <c>true</c> to release both managed and unmanaged resources;
  1201.         ''' <c>false</c> to release only unmanaged resources.
  1202.         ''' </param>
  1203.         Protected Sub Dispose(ByVal disposing As Boolean)
  1204.  
  1205.             Me.IsEnabled = False
  1206.  
  1207.             If Not Me.disposedValue Then
  1208.  
  1209.                 If disposing Then ' Dispose managed state (managed objects).
  1210.  
  1211.                 Else ' Free unmanaged resources (unmanaged objects).
  1212.                     NativeMethods.UnhookWindowsHookEx(Me.MouseHook)
  1213.  
  1214.                 End If
  1215.  
  1216.             End If
  1217.  
  1218.             Me.disposedValue = True
  1219.  
  1220.         End Sub
  1221.  
  1222.         ''' <summary>
  1223.         ''' Allows an object to try to free resources
  1224.         ''' and perform other cleanup operations before it is reclaimed by garbage collection.
  1225.         ''' </summary>
  1226.         Protected Overrides Sub Finalize()
  1227.  
  1228.             ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  1229.  
  1230.             Me.Dispose(disposing:=False)
  1231.             MyBase.Finalize()
  1232.  
  1233.         End Sub
  1234.  
  1235.         ''' <summary>
  1236.         ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  1237.         ''' </summary>
  1238.         Private Sub Dispose() Implements IDisposable.Dispose
  1239.  
  1240.             ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  1241.  
  1242.             Me.Dispose(disposing:=True)
  1243.             GC.SuppressFinalize(obj:=Me)
  1244.  
  1245.         End Sub
  1246.  
  1247. #End Region
  1248.  
  1249.     End Class
  1250.  
  1251. End Namespace
  1252.  
  1253. #End Region
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement