elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: (TUTORIAL) Aprende a emular Sentinel Dongle By Yapis


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  [APORTE] Ejemplo de un LL-Hook para el Mouse.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [APORTE] Ejemplo de un LL-Hook para el Mouse.  (Leído 2,803 veces)
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
[APORTE] Ejemplo de un LL-Hook para el Mouse.
« en: 28 Junio 2014, 08:14 am »

Hola

Para todos los que estén interesados en iniciarse en los Hooks de bajo nivel (en lo cual yo no soy ningún experto) esto les podría servir, ya que considero haberlo dejado muy bien documentado y se puede aprender algo solo leyendo los comentarios XML.

Simplemente es un Hook que intercepta los eventos del ratón, pudiendo suscribirse a ellos, nada más que eso.

Código
  1. ' ***********************************************************************
  2. ' Author           : Elektro
  3. ' Last Modified On : 05-13-2014
  4. ' ***********************************************************************
  5. ' <copyright file="MouseHook.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Instructions "
  11.  
  12. ' Go to page:
  13. ' Project > Properties > Debug
  14. '
  15. ' And uncheck the option:
  16. ' Enable the Visual Studio Hosting Process
  17.  
  18. #End Region
  19.  
  20. #Region " Usage Examples "
  21.  
  22. ' ''' <summary>
  23. ' ''' A low level mouse hook that captures mouse events.
  24. ' ''' </summary>
  25. 'Private WithEvents MouseEvents As MouseHook = Nothing
  26.  
  27. ' ''' <summary>
  28. ' ''' Handles the 'MouseLeftDown' event of the Mouse Hook.
  29. ' ''' </summary>
  30. ' ''' <param name="MouseLocation">Indicates the mouse [X,Y] coordinates.</param>
  31. 'Private Sub MouseEvents_MouseLeftDown(ByVal MouseLocation As Point) Handles MouseEvents.MouseLeftDown
  32. '
  33. '    Debug.WriteLine(String.Format("Mouse Left Down At: x={0}, y={1}", CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  34. '
  35. 'End Sub
  36.  
  37. ' ''' <summary>
  38. ' ''' Handles the 'MouseLeftUp' event of the Mouse Hook.
  39. ' ''' </summary>
  40. ' ''' <param name="MouseLocation">Indicates the mouse [X,Y] coordinates.</param>
  41. 'Private Sub MouseEvents_MouseLeftUp(ByVal MouseLocation As Point) Handles MouseEvents.MouseLeftUp
  42. '
  43. '    Debug.WriteLine(String.Format("Mouse Left Up At: x={0}, y={1}", CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  44. '
  45. 'End Sub
  46.  
  47. ' ''' <summary>
  48. ' ''' Handles the 'MouseMove' event of the Mouse Hook.
  49. ' ''' </summary>
  50. ' ''' <param name="MouseLocation">Indicates the mouse [X,Y] coordinates.</param>
  51. 'Private Sub MouseEvents_MouseMove(ByVal MouseLocation As Point) Handles MouseEvents.MouseMove
  52. '
  53. '    Debug.WriteLine(String.Format("Mouse Moved To: x={0}, y={1}", CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  54. '
  55. 'End Sub
  56.  
  57. ' ''' <summary>
  58. ' ''' Handles the 'Click' event of the 'ButtonStartHook' control.
  59. ' ''' </summary>
  60. 'Private Sub ButtonStartHook() Handles ButtonStartHook.Click
  61.  
  62. '    ' Start the Mouse Hook.
  63. '    MouseEvents = New MouseHook
  64.  
  65. 'End Sub
  66.  
  67. ' ''' <summary>
  68. ' ''' Handles the 'Click' event of the 'ButtonStopHook' control.
  69. ' ''' </summary>
  70. 'Private Sub ButtonStopHook() Handles ButtonStopHook.Click
  71.  
  72. '    ' Stop the Mouse Hook.
  73. '    MouseEvents = Nothing
  74.  
  75. 'End Sub
  76.  
  77. #End Region
  78.  
  79. #Region " Imports "
  80.  
  81. Imports System.ComponentModel
  82. Imports System.Reflection
  83. Imports System.Runtime.InteropServices
  84.  
  85. #End Region
  86.  
  87. #Region " MouseHook "
  88.  
  89. ''' <summary>
  90. ''' A low level mouse hook class that captures mouse events.
  91. ''' </summary>
  92. Public Class MouseHook
  93.  
  94. #Region " WinAPI "
  95.  
  96. #Region " Methods "
  97.  
  98.    ''' <summary>
  99.    ''' Passes the hook information to the next hook procedure in the current hook chain.
  100.    ''' A hook procedure can call this function either before or after processing the hook information.
  101.    ''' For more info see here:
  102.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
  103.    ''' </summary>
  104.    ''' <param name="idHook">
  105.    ''' This parameter is ignored.
  106.    ''' </param>
  107.    ''' <param name="nCode">
  108.    ''' The hook code passed to the current hook procedure.
  109.    ''' The next hook procedure uses this code to determine how to process the hook information.
  110.    ''' </param>
  111.    ''' <param name="wParam">
  112.    ''' The wParam value passed to the current hook procedure.
  113.    ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  114.    ''' </param>
  115.    ''' <param name="lParam">
  116.    ''' The lParam value passed to the current hook procedure.
  117.    ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  118.    ''' </param>
  119.    ''' <returns>
  120.    ''' This value is returned by the next hook procedure in the chain.
  121.    ''' The current hook procedure must also return this value.
  122.    ''' The meaning of the return value depends on the hook type.
  123.    ''' For more information, see the descriptions of the individual hook procedures.
  124.    ''' </returns>
  125.    <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  126.    Private Shared Function CallNextHookEx(
  127.           ByVal idHook As Integer,
  128.           ByVal nCode As Integer,
  129.           ByVal wParam As Integer,
  130.           ByVal lParam As MSLLHOOKSTRUCT
  131.    ) As Integer
  132.    End Function
  133.  
  134.    ''' <summary>
  135.    ''' Installs an application-defined hook procedure into a hook chain.
  136.    ''' You would install a hook procedure to monitor the system for certain types of events.
  137.    ''' These events are associated either with a specific thread
  138.    ''' or with all threads in the same desktop as the calling thread.
  139.    ''' For more info see here:
  140.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  141.    ''' </summary>
  142.    ''' <param name="idHook">
  143.    ''' The type of hook procedure to be installed.
  144.    ''' </param>
  145.    ''' <param name="lpfn">
  146.    ''' A pointer to the hook procedure.
  147.    ''' If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process,
  148.    ''' the lpfn parameter must point to a hook procedure in a DLL.
  149.    ''' Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
  150.    ''' </param>
  151.    ''' <param name="hInstance">
  152.    ''' A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
  153.    ''' The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by
  154.    ''' the current process and if the hook procedure is within the code associated with the current process.
  155.    ''' </param>
  156.    ''' <param name="threadId">
  157.    ''' The identifier of the thread with which the hook procedure is to be associated.
  158.    ''' For desktop apps, if this parameter is zero, the hook procedure is associated
  159.    ''' with all existing threads running in the same desktop as the calling thread.
  160.    ''' </param>
  161.    ''' <returns>
  162.    ''' If the function succeeds, the return value is the handle to the hook procedure.
  163.    ''' If the function fails, the return value is NULL.
  164.    ''' </returns>
  165.    <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  166.    Private Shared Function SetWindowsHookEx(
  167.           ByVal idHook As HookType,
  168.           ByVal lpfn As MouseProcDelegate,
  169.           ByVal hInstance As IntPtr,
  170.           ByVal threadId As Integer
  171.    ) As Integer
  172.    End Function
  173.  
  174.    ''' <summary>
  175.    ''' Removes a hook procedure installed in a hook chain by the 'SetWindowsHookEx' function.
  176.    ''' For more info see here:
  177.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
  178.    ''' </summary>
  179.    ''' <param name="idHook">
  180.    ''' A handle to the hook to be removed.
  181.    ''' This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
  182.    ''' </param>
  183.    ''' <returns>
  184.    ''' If the function succeeds, the return value is nonzero.
  185.    ''' If the function fails, the return value is zero.
  186.    ''' </returns>
  187.    <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  188.    Private Shared Function UnhookWindowsHookEx(
  189.           ByVal idHook As Integer
  190.    ) As Boolean
  191.    End Function
  192.  
  193. #End Region
  194.  
  195. #Region " Enums "
  196.  
  197.    ''' <summary>
  198.    ''' Indicates a type of Hook procedure to be installed.
  199.    ''' </summary>
  200.    <Description("Enum used in 'idHook' parameter of 'SetWindowsHookEx' function")>
  201.    Private Enum HookType As Integer
  202.  
  203.        ' **************************************
  204.        ' This enumeration is partially defined.
  205.        ' **************************************
  206.  
  207.        ''' <summary>
  208.        ''' Installs a hook procedure that monitors low-level mouse input events.
  209.        ''' For more information, see the LowLevelMouseProc hook procedure.
  210.        ''' </summary>
  211.        WH_MOUSE_LL = 14
  212.  
  213.    End Enum
  214.  
  215. #End Region
  216.  
  217. #Region " Structures "
  218.  
  219.    ''' <summary>
  220.    ''' Contains information about a low-level mouse input event.
  221.    ''' </summary>
  222.    <Description("Structure used in 'lParam' parameter of 'CallNextHookEx' function")>
  223.    Private Structure MSLLHOOKSTRUCT
  224.  
  225.        ''' <summary>
  226.        ''' The ptThe x- and y-coordinates of the cursor, in screen coordinates.
  227.        ''' </summary>
  228.        Public pt As Point
  229.  
  230.        ''' <summary>
  231.        ''' If the message is 'WM_MOUSEWHEEL', the high-order word of this member is the wheel delta.
  232.        ''' The low-order word is reserved.
  233.        ''' A positive value indicates that the wheel was rotated forward, away from the user;
  234.        ''' a negative value indicates that the wheel was rotated backward, toward the user.
  235.        ''' One wheel click is defined as 'WHEEL_DELTA', which is '120'.
  236.        ''' </summary>
  237.        Public mouseData As Integer
  238.  
  239.        ''' <summary>
  240.        ''' The event-injected flag.
  241.        ''' </summary>
  242.        Public flags As Integer
  243.  
  244.        ''' <summary>
  245.        ''' The time stamp for this message.
  246.        ''' </summary>
  247.        Public time As Integer
  248.  
  249.        ''' <summary>
  250.        ''' Additional information associated with the message.
  251.        ''' </summary>
  252.        Public dwExtraInfo As Integer
  253.  
  254.    End Structure
  255.  
  256. #End Region
  257.  
  258. #End Region
  259.  
  260. #Region " Variables "
  261.  
  262.    ''' <summary>
  263.    '''
  264.    ''' </summary>
  265.    Private MouseHook As Integer
  266.  
  267. #End Region
  268.  
  269. #Region " Delegates "
  270.  
  271.    ''' <summary>
  272.    ''' Delegate MouseProcDelegate
  273.    ''' </summary>
  274.    ''' <returns>System.Int32.</returns>
  275.    Private Delegate Function MouseProcDelegate(
  276.            ByVal nCode As Integer,
  277.            ByVal wParam As Integer,
  278.            ByRef lParam As MSLLHOOKSTRUCT
  279.    ) As Integer
  280.  
  281.    ''' <summary>
  282.    ''' </summary>
  283.    Private MouseHookDelegate As MouseProcDelegate
  284.  
  285. #End Region
  286.  
  287. #Region " Enums "
  288.  
  289.    ''' <summary>
  290.    ''' Indicates a Windows Message related to a mouse events.
  291.    ''' For more info see here:
  292.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877%28v=vs.85%29.aspx
  293.    ''' </summary>
  294.    Private Enum MouseWindowsMessages As Integer
  295.  
  296.        ''' <summary>
  297.        ''' Posted to a window when the cursor moves.
  298.        ''' If the mouse is not captured, the message is posted to the window that contains the cursor.
  299.        ''' Otherwise, the message is posted to the window that has captured the mouse
  300.        ''' </summary>
  301.        WM_MOUSEMOVE = &H200
  302.  
  303.        ''' <summary>
  304.        ''' Posted when the user presses the left mouse button while the cursor is in the client area of a window.
  305.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  306.        ''' Otherwise, the message is posted to the window that has captured the mouse
  307.        ''' </summary>
  308.        WM_LBUTTONDOWN = &H201
  309.  
  310.        ''' <summary>
  311.        ''' Posted when the user releases the left mouse button while the cursor is in the client area of a window.
  312.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  313.        ''' Otherwise, the message is posted to the window that has captured the mouse
  314.        ''' </summary>
  315.        WM_LBUTTONUP = &H202
  316.  
  317.        ''' <summary>
  318.        ''' Posted when the user double-clicks the left mouse button while the cursor is in the client area of a window.
  319.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  320.        ''' Otherwise, the message is posted to the window that has captured the mouse
  321.        ''' </summary>
  322.        WM_LBUTTONDBLCLK = &H203
  323.  
  324.        ''' <summary>
  325.        ''' Posted when the user presses the right mouse button while the cursor is in the client area of a window.
  326.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  327.        ''' Otherwise, the message is posted to the window that has captured the mouse
  328.        ''' </summary>
  329.        WM_RBUTTONDOWN = &H204
  330.  
  331.        ''' <summary>
  332.        ''' Posted when the user releases the right mouse button while the cursor is in the client area of a window.
  333.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  334.        ''' Otherwise, the message is posted to the window that has captured the mouse
  335.        ''' </summary>
  336.        WM_RBUTTONUP = &H205
  337.  
  338.        ''' <summary>
  339.        ''' Posted when the user double-clicks the right mouse button while the cursor is in the client area of a window.
  340.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  341.        ''' Otherwise, the message is posted to the window that has captured the mouse
  342.        ''' </summary>
  343.        WM_RBUTTONDBLCLK = &H206
  344.  
  345.        ''' <summary>
  346.        ''' Posted when the user presses the middle mouse button while the cursor is in the client area of a window.
  347.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  348.        ''' Otherwise, the message is posted to the window that has captured the mouse
  349.        ''' </summary>
  350.        WM_MBUTTONDOWN = &H207
  351.  
  352.        ''' <summary>
  353.        ''' Posted when the user releases the middle mouse button while the cursor is in the client area of a window.
  354.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  355.        ''' Otherwise, the message is posted to the window that has captured the mouse
  356.        ''' </summary>
  357.        WM_MBUTTONUP = &H208
  358.  
  359.        ''' <summary>
  360.        ''' Posted when the user double-clicks the middle mouse button while the cursor is in the client area of a window.
  361.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  362.        ''' Otherwise, the message is posted to the window that has captured the mouse
  363.        ''' </summary>
  364.        WM_MBUTTONDBLCLK = &H209
  365.  
  366.        ''' <summary>
  367.        ''' Sent to the active window when the mouse's horizontal scroll wheel is tilted or rotated.
  368.        ''' The DefWindowProc function propagates the message to the window's parent.
  369.        ''' There should be no internal forwarding of the message,
  370.        ''' since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
  371.        ''' </summary>
  372.        WM_MOUSEWHEEL = &H20A
  373.  
  374.    End Enum
  375.  
  376.    ''' <summary>
  377.    ''' Indicates the whell direction of the mouse.
  378.    ''' </summary>
  379.    Public Enum WheelDirection
  380.  
  381.        ''' <summary>
  382.        ''' The wheel is moved up.
  383.        ''' </summary>
  384.        WheelUp
  385.  
  386.        ''' <summary>
  387.        ''' The wheel is moved down.
  388.        ''' </summary>
  389.        WheelDown
  390.  
  391.    End Enum
  392.  
  393. #End Region
  394.  
  395. #Region " Events "
  396.  
  397.    ''' <summary>
  398.    ''' Occurs when the mouse moves.
  399.    ''' </summary>
  400.    Public Event MouseMove(ByVal MouseLocation As Point)
  401.  
  402.    ''' <summary>
  403.    ''' Occurs when the mouse left button is pressed.
  404.    ''' </summary>
  405.    Public Event MouseLeftDown(ByVal MouseLocation As Point)
  406.  
  407.    ''' <summary>
  408.    ''' Occurs when the mouse left button is released.
  409.    ''' </summary>
  410.    Public Event MouseLeftUp(ByVal MouseLocation As Point)
  411.  
  412.    ''' <summary>
  413.    ''' Occurs when the mouse left button is double-clicked.
  414.    ''' </summary>
  415.    Public Event MouseLeftDoubleClick(ByVal MouseLocation As Point)
  416.  
  417.    ''' <summary>
  418.    ''' Occurs when the mouse right button is pressed.
  419.    ''' </summary>
  420.    Public Event MouseRightDown(ByVal MouseLocation As Point)
  421.  
  422.    ''' <summary>
  423.    ''' Occurs when the mouse right button is released.
  424.    ''' </summary>
  425.    Public Event MouseRightUp(ByVal MouseLocation As Point)
  426.  
  427.    ''' <summary>
  428.    ''' Occurs when the mouse right button is double-clicked.
  429.    ''' </summary>
  430.    Public Event MouseRightDoubleClick(ByVal MouseLocation As Point)
  431.  
  432.    ''' <summary>
  433.    ''' Occurs when the mouse middle button is pressed.
  434.    ''' </summary>
  435.    Public Event MouseMiddleDown(ByVal MouseLocation As Point)
  436.  
  437.    ''' <summary>
  438.    ''' Occurs when the mouse middle button is released.
  439.    ''' </summary>
  440.    Public Event MouseMiddleUp(ByVal MouseLocation As Point)
  441.  
  442.    ''' <summary>
  443.    ''' Occurs when the mouse middle button is double-clicked.
  444.    ''' </summary>
  445.    Public Event MouseMiddleDoubleClick(ByVal MouseLocation As Point)
  446.  
  447.    ''' <summary>
  448.    ''' Occurs when [mouse move].
  449.    ''' </summary>
  450.    Public Event MouseWheel(ByVal MouseLocation As Point,
  451.                            ByVal WheelDirection As WheelDirection)
  452.  
  453. #End Region
  454.  
  455. #Region " Constructors "
  456.  
  457.    ''' <summary>
  458.    ''' Initializes a new instance of this class.
  459.    ''' </summary>
  460.    Public Sub New()
  461.  
  462.        MouseHookDelegate = New MouseProcDelegate(AddressOf MouseProc)
  463.  
  464.        MouseHook = SetWindowsHookEx(HookType.WH_MOUSE_LL,
  465.                                     MouseHookDelegate,
  466.                                     Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
  467.    End Sub
  468.  
  469. #End Region
  470.  
  471. #Region " Protected Methods "
  472.  
  473.    ''' <summary>
  474.    ''' Allows an object to try to free resources
  475.    ''' and perform other cleanup operations before it is reclaimed by garbage collection.
  476.    ''' </summary>
  477.    Protected Overrides Sub Finalize()
  478.  
  479.        UnhookWindowsHookEx(MouseHook)
  480.        MyBase.Finalize()
  481.  
  482.    End Sub
  483.  
  484. #End Region
  485.  
  486. #Region " Private Methods "
  487.  
  488.    ''' <summary>
  489.    ''' Processes the mouse windows messages and raises it's corresponding events.
  490.    ''' </summary>
  491.    ''' <returns>System.Int32.</returns>
  492.    Private Function MouseProc(ByVal nCode As Integer,
  493.                               ByVal wParam As Integer,
  494.                               ByRef lParam As MSLLHOOKSTRUCT
  495.    ) As Integer
  496.  
  497.        If nCode = 0 Then
  498.  
  499.            Select Case wParam
  500.  
  501.                Case MouseWindowsMessages.WM_MOUSEMOVE
  502.                    RaiseEvent MouseMove(lParam.pt)
  503.  
  504.                Case MouseWindowsMessages.WM_LBUTTONDOWN
  505.                    RaiseEvent MouseLeftDown(lParam.pt)
  506.  
  507.                Case MouseWindowsMessages.WM_LBUTTONUP
  508.                    RaiseEvent MouseLeftUp(lParam.pt)
  509.  
  510.                Case MouseWindowsMessages.WM_LBUTTONDBLCLK
  511.                    RaiseEvent MouseLeftDoubleClick(lParam.pt)
  512.  
  513.                Case MouseWindowsMessages.WM_RBUTTONDOWN
  514.                    RaiseEvent MouseRightDown(lParam.pt)
  515.  
  516.                Case MouseWindowsMessages.WM_RBUTTONUP
  517.                    RaiseEvent MouseRightUp(lParam.pt)
  518.  
  519.                Case MouseWindowsMessages.WM_RBUTTONDBLCLK
  520.                    RaiseEvent MouseRightDoubleClick(lParam.pt)
  521.  
  522.                Case MouseWindowsMessages.WM_MBUTTONDOWN
  523.                    RaiseEvent MouseMiddleDown(lParam.pt)
  524.  
  525.                Case MouseWindowsMessages.WM_MBUTTONUP
  526.                    RaiseEvent MouseMiddleUp(lParam.pt)
  527.  
  528.                Case MouseWindowsMessages.WM_MBUTTONDBLCLK
  529.                    RaiseEvent MouseMiddleDoubleClick(lParam.pt)
  530.  
  531.                Case MouseWindowsMessages.WM_MOUSEWHEEL
  532.                    Dim wDirection As WheelDirection
  533.                    If lParam.mouseData < 0 Then
  534.                        wDirection = WheelDirection.WheelDown
  535.                    Else
  536.                        wDirection = WheelDirection.WheelUp
  537.                    End If
  538.                    RaiseEvent MouseWheel(lParam.pt, wDirection)
  539.  
  540.            End Select
  541.  
  542.        End If
  543.  
  544.        Return CallNextHookEx(MouseHook, nCode, wParam, lParam)
  545.  
  546.    End Function
  547.  
  548. #End Region
  549.  
  550. End Class
  551.  
  552. #End Region


« Última modificación: 28 Junio 2014, 08:36 am por Eleкtro » En línea


AgnesBlack

Desconectado Desconectado

Mensajes: 44


Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #1 en: 28 Junio 2014, 19:55 pm »

perdona mi ignorancia pero en si, con esto se puede grabar los eventos del mouse??


En línea

engel lex
Moderador Global
***
Desconectado Desconectado

Mensajes: 15.514



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #2 en: 28 Junio 2014, 20:02 pm »

si puedes, grabar y simular por lo que veo... pero esto como tal no es un programa, es una "librería" para usar en tu codigo
En línea

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.
Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #3 en: 28 Junio 2014, 21:31 pm »

El código puede subscribirse a los eventos del mouse, eso significa que si, puedes grabar cada acontecimiento y el orden de ellos, pero claro, eso requieriría hacer unas modificaciones para que el código se adapten a tus necesidades que "graben" los eventos en un objeto o archivo que contenga ese "set" de eventos, y lo mismo que para reproducir esas acciones.

Hace tiempo escribí un código para automatizar ambas tareas, la de grabar y la de reproducir, pero es un código que no reviso desde hace mucho tiempo, lo escribí cuando me estuve iniciando en .NET y usé técnicas inapropiadas (un timer) para grabar los eventos así que puede tener sus fallos, de todas formas te dejo el código por si te sirve:

Código
  1. #Region " Record Mouse Class "
  2.  
  3. ' [ Record Mouse Functions ]
  4. '
  5. ' // By Elektro H@cker
  6. '
  7. ' Examples :
  8. ' Record_Mouse.Start_Record()
  9. ' Record_Mouse.Stop_Record()
  10. ' Record_Mouse.Play() : While Not Record_Mouse.Play_Is_Completed : Application.DoEvents() : End While
  11. ' Record_Mouse.Mouse_Speed = 50
  12.  
  13. Public Class Record_Mouse
  14.  
  15.    ''' <summary>
  16.    ''' Sets the speed of recording/playing the mouse actions.
  17.    ''' Default value is 25.
  18.    ''' </summary>
  19.    Public Shared Mouse_Speed As Long = 30L
  20.  
  21.    ''' <summary>
  22.    ''' Gets the status pf the current mouse play.
  23.    ''' False = Mouse task is still playing.
  24.    ''' True = Mouse task play is done.
  25.    ''' </summary>
  26.    Public Shared Play_Is_Completed As Boolean
  27.  
  28.    ' Where the mouse coordenates will be stored:
  29.    Private Shared Coordenates_List As New List(Of Point)
  30.  
  31.    ' Where the mouse clicks will be stored:
  32.    Private Shared Clicks_Dictionary As New Dictionary(Of Long, MouseButton)
  33.  
  34.    ' Timer to record the mouse:
  35.    Private Shared WithEvents Record_Timer As New Timer
  36.  
  37.    ' Button click count to rec/play clicks:
  38.    Private Shared Click_Count As Int32 = 0
  39.  
  40.    ' Thread to reproduce the mouse actions:
  41.    Private Shared Thread_MousePlay_Var As System.Threading.Thread = New Threading.Thread(AddressOf Thread_MousePlay)
  42.  
  43.    ' API to record the current mouse button state:
  44.    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
  45.  
  46.    ' API to reproduce a mouse button click:
  47.    Private Declare Sub Mouse_Event Lib "User32" Alias "mouse_event" (ByVal dwFlags As MouseButton, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As Integer)
  48.  
  49.    ' GetAsyncKeyState buttons status
  50.    Private Shared Last_ClickState_Left As Long = -1L
  51.    Private Shared Last_ClickState_Right As Long = -1L
  52.    Private Shared Last_ClickState_Middle As Long = -1L
  53.  
  54.    Enum MouseButton
  55.  
  56.        Left_Down = &H2    ' Left button (hold)
  57.        Left_Up = &H4      ' Left button (release)
  58.  
  59.        Right_Down = &H8   ' Right button (hold)
  60.        Right_Up = &H10    ' Right button (release)
  61.  
  62.        Middle_Down = &H20 ' Middle button (hold)
  63.        Middle_Up = &H40   ' Middle button (release)
  64.  
  65.        Left               ' Left   button (press)
  66.        Right              ' Right  button (press)
  67.        Middle             ' Middle button (press)
  68.  
  69.    End Enum
  70.  
  71.    ''' <summary>
  72.    ''' Starts recording the mouse actions over the screen.
  73.    ''' It records the position of the mouse and left/right button clicks.
  74.    ''' </summary>
  75.    Public Shared Sub Start_Record()
  76.  
  77.        ' Reset vars:
  78.        Play_Is_Completed = False
  79.        Coordenates_List.Clear() : Clicks_Dictionary.Clear()
  80.        Last_ClickState_Left = -1 : Last_ClickState_Right = -1 : Last_ClickState_Middle = -1
  81.        Click_Count = 0
  82.  
  83.        ' Set Mouse Speed
  84.        Record_Timer.Interval = Mouse_Speed
  85.  
  86.        ' Start Recording:
  87.        Record_Timer.Start()
  88.  
  89.    End Sub
  90.  
  91.    ''' <summary>
  92.    ''' Stop recording the mouse actions.
  93.    ''' </summary>
  94.    Public Shared Sub Stop_Record()
  95.        Record_Timer.Stop()
  96.    End Sub
  97.  
  98.    ''' <summary>
  99.    ''' Reproduce the mouse actions.
  100.    ''' </summary>
  101.    Public Shared Sub Play()
  102.        Thread_MousePlay_Var = New Threading.Thread(AddressOf Thread_MousePlay)
  103.        Thread_MousePlay_Var.IsBackground = True
  104.        Thread_MousePlay_Var.Start()
  105.    End Sub
  106.  
  107.    ' Procedure used to store the mouse actions
  108.    Private Shared Sub Record_Timer_Tick(sender As Object, e As EventArgs) Handles Record_Timer.Tick
  109.  
  110.        Coordenates_List.Add(Control.MousePosition)
  111.  
  112.        ' Record Left click
  113.        If Not Last_ClickState_Left = GetAsyncKeyState(1) Then
  114.            Last_ClickState_Left = GetAsyncKeyState(1)
  115.            If GetAsyncKeyState(1) = 32768 Then
  116.                Click_Count += 1
  117.                Coordenates_List.Add(Nothing)
  118.                Clicks_Dictionary.Add(Click_Count, MouseButton.Left_Down)
  119.            ElseIf GetAsyncKeyState(1) = 0 Then
  120.                Click_Count += 1
  121.                Coordenates_List.Add(Nothing)
  122.                Clicks_Dictionary.Add(Click_Count, MouseButton.Left_Up)
  123.            End If
  124.        End If
  125.  
  126.        ' Record Right click
  127.        If Not Last_ClickState_Right = GetAsyncKeyState(2) Then
  128.            Last_ClickState_Right = GetAsyncKeyState(2)
  129.            If GetAsyncKeyState(2) = 32768 Then
  130.                Click_Count += 1
  131.                Coordenates_List.Add(Nothing)
  132.                Clicks_Dictionary.Add(Click_Count, MouseButton.Right_Down)
  133.            ElseIf GetAsyncKeyState(2) = 0 Then
  134.                Click_Count += 1
  135.                Coordenates_List.Add(Nothing)
  136.                Clicks_Dictionary.Add(Click_Count, MouseButton.Right_Up)
  137.            End If
  138.        End If
  139.  
  140.        ' Record Middle click
  141.        If Not Last_ClickState_Middle = GetAsyncKeyState(4) Then
  142.            Last_ClickState_Middle = GetAsyncKeyState(4)
  143.            If GetAsyncKeyState(4) = 32768 Then
  144.                Click_Count += 1
  145.                Coordenates_List.Add(Nothing)
  146.                Clicks_Dictionary.Add(Click_Count, MouseButton.Middle_Down)
  147.            ElseIf GetAsyncKeyState(4) = 0 Then
  148.                Click_Count += 1
  149.                Coordenates_List.Add(Nothing)
  150.                Clicks_Dictionary.Add(Click_Count, MouseButton.Middle_Up)
  151.            End If
  152.        End If
  153.  
  154.    End Sub
  155.  
  156.    ' Procedure to play a mouse button (click)
  157.    Private Shared Sub Mouse_Click(ByVal MouseButton As MouseButton)
  158.        Select Case MouseButton
  159.            Case MouseButton.Left : Mouse_Event(MouseButton.Left_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Left_Up, 0, 0, 0, 0)
  160.            Case MouseButton.Right : Mouse_Event(MouseButton.Right_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Right_Up, 0, 0, 0, 0)
  161.            Case MouseButton.Middle : Mouse_Event(MouseButton.Middle_Down, 0, 0, 0, 0) : Mouse_Event(MouseButton.Middle_Up, 0, 0, 0, 0)
  162.            Case Else : Mouse_Event(MouseButton, 0, 0, 0, 0)
  163.        End Select
  164.    End Sub
  165.  
  166.    ' Thread used for reproduce the mouse actions
  167.    Private Shared Sub Thread_MousePlay()
  168.  
  169.        Click_Count = 0
  170.        Clicks_Dictionary.Item(0) = Nothing
  171.  
  172.        For Each Coordenate In Coordenates_List
  173.  
  174.            Threading.Thread.Sleep(Mouse_Speed)
  175.  
  176.            If Coordenate = Nothing Then
  177.                Click_Count += 1
  178.                If Click_Count > 1 Then
  179.                    Mouse_Click(Clicks_Dictionary.Item(Click_Count))
  180.                End If
  181.            Else
  182.                Cursor.Position = Coordenate
  183.            End If
  184.  
  185.        Next
  186.  
  187.        Mouse_Click(MouseButton.Left_Up)
  188.        Mouse_Click(MouseButton.Right_Up)
  189.        Mouse_Click(MouseButton.Middle_Up)
  190.  
  191.        Play_Is_Completed = True
  192.  
  193.    End Sub
  194.  
  195. End Class
  196.  
  197. #End Region



« Última modificación: 28 Junio 2014, 21:33 pm por Eleкtro » En línea


Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #4 en: 26 Septiembre 2014, 01:34 am »

El código que posteé hace tiempo (en el primer mensaje de este hilo) tenia unos fallos de los que no me percaté, he estado actualizando y corrigiendo el código ya que va a formar parte de la aplicación que presentaré en el EHN-DEv.

Aquí les dejo el código actualizado, estoy seguro que a alguien le servirá ya que a muchos nos apasiona los global-system hooks para Keyloggers y demás :) :

Código
  1. ' ***********************************************************************
  2. ' Author           : Elektro
  3. ' Last Modified On : 09-25-2014
  4. ' ***********************************************************************
  5. ' <copyright file="MouseHook.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Instructions "
  11.  
  12. ' Go to page:
  13. ' Project > Properties > Debug
  14. '
  15. ' Then uncheck the option:
  16. ' "Enable the Visual Studio Hosting Process"
  17.  
  18. #End Region
  19.  
  20. #Region " Imports "
  21.  
  22. Imports System.ComponentModel
  23. Imports System.Reflection
  24. Imports System.Runtime.InteropServices
  25.  
  26. #End Region
  27.  
  28. #Region " MouseHook "
  29.  
  30. ''' <summary>
  31. ''' A low level mouse hook class that captures mouse events.
  32. ''' </summary>
  33. Friend NotInheritable Class MouseHook : Implements IDisposable
  34.  
  35. #Region " P/Invoke "
  36.  
  37.    ''' <summary>
  38.    ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  39.    ''' This class does not suppress stack walks for unmanaged code permission.
  40.    ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/>  must not be applied to this class.
  41.    ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  42.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/ms182161.aspx
  43.    ''' </summary>
  44.    Protected NotInheritable Class NativeMethods
  45.  
  46. #Region " Methods "
  47.  
  48.        ''' <summary>
  49.        ''' Passes the hook information to the next hook procedure in the current hook chain.
  50.        ''' A hook procedure can call this function either before or after processing the hook information.
  51.        ''' For more info see here:
  52.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
  53.        ''' </summary>
  54.        ''' <param name="idHook">
  55.        ''' This parameter is ignored.
  56.        ''' </param>
  57.        ''' <param name="nCode">
  58.        ''' The hook code passed to the current hook procedure.
  59.        ''' The next hook procedure uses this code to determine how to process the hook information.
  60.        ''' </param>
  61.        ''' <param name="wParam">
  62.        ''' The wParam value passed to the current hook procedure.
  63.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  64.        ''' </param>
  65.        ''' <param name="lParam">
  66.        ''' The lParam value passed to the current hook procedure.
  67.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  68.        ''' </param>
  69.        ''' <returns>
  70.        ''' This value is returned by the next hook procedure in the chain.
  71.        ''' The current hook procedure must also return this value.
  72.        ''' The meaning of the return value depends on the hook type.
  73.        ''' For more information, see the descriptions of the individual hook procedures.
  74.        ''' </returns>
  75.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  76.        Friend Shared Function CallNextHookEx(
  77.               ByVal idHook As IntPtr,
  78.               ByVal nCode As Integer,
  79.               ByVal wParam As IntPtr,
  80.               ByVal lParam As IntPtr
  81.        ) As IntPtr
  82.        End Function
  83.  
  84.        ''' <summary>
  85.        ''' Installs an application-defined hook procedure into a hook chain.
  86.        ''' You would install a hook procedure to monitor the system for certain types of events.
  87.        ''' These events are associated either with a specific thread
  88.        ''' or with all threads in the same desktop as the calling thread.
  89.        ''' For more info see here:
  90.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  91.        ''' </summary>
  92.        ''' <param name="idHook">
  93.        ''' The type of hook procedure to be installed.
  94.        ''' </param>
  95.        ''' <param name="lpfn">
  96.        ''' A pointer to the hook procedure.
  97.        ''' If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process,
  98.        ''' the lpfn parameter must point to a hook procedure in a DLL.
  99.        ''' Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
  100.        ''' </param>
  101.        ''' <param name="hInstance">
  102.        ''' A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
  103.        ''' The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by
  104.        ''' the current process and if the hook procedure is within the code associated with the current process.
  105.        ''' </param>
  106.        ''' <param name="threadId">
  107.        ''' The identifier of the thread with which the hook procedure is to be associated.
  108.        ''' For desktop apps, if this parameter is zero, the hook procedure is associated
  109.        ''' with all existing threads running in the same desktop as the calling thread.
  110.        ''' </param>
  111.        ''' <returns>
  112.        ''' If the function succeeds, the return value is the handle to the hook procedure.
  113.        ''' If the function fails, the return value is NULL.
  114.        ''' </returns>
  115.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  116.        Friend Shared Function SetWindowsHookEx(
  117.               ByVal idHook As HookType,
  118.               ByVal lpfn As LowLevelMouseProcDelegate,
  119.               ByVal hInstance As IntPtr,
  120.               ByVal threadId As UInteger
  121.        ) As IntPtr
  122.        End Function
  123.  
  124.        ''' <summary>
  125.        ''' Removes a hook procedure installed in a hook chain by the 'SetWindowsHookEx' function.
  126.        ''' For more info see here:
  127.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
  128.        ''' </summary>
  129.        ''' <param name="idHook">
  130.        ''' A handle to the hook to be removed.
  131.        ''' This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
  132.        ''' </param>
  133.        ''' <returns>
  134.        ''' If the function succeeds, the return value is nonzero.
  135.        ''' If the function fails, the return value is zero.
  136.        ''' </returns>
  137.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  138.        Friend Shared Function UnhookWindowsHookEx(
  139.               ByVal idHook As IntPtr
  140.        ) As Boolean
  141.        End Function
  142.  
  143.        ''' <summary>
  144.        ''' Retrieves the current double-click time for the mouse.
  145.        ''' A double-click is a series of two clicks of the mouse button,
  146.        ''' the second occurring within a specified time after the first.
  147.        ''' The double-click time is the maximum number of milliseconds that may occur
  148.        ''' between the first and second click of a double-click.
  149.        ''' The maximum double-click time is 5000 milliseconds.
  150.        ''' </summary>
  151.        ''' <returns>
  152.        ''' The return value specifies the current double-click time, in milliseconds.
  153.        ''' The maximum return value is 5000 milliseconds.
  154.        ''' </returns>
  155.        <DllImport("user32.dll", CharSet:=CharSet.Auto)>
  156.        Friend Shared Function GetDoubleClickTime() As Integer
  157.        End Function
  158.  
  159. #End Region
  160.  
  161. #Region " Enumerations "
  162.  
  163.        ''' <summary>
  164.        ''' Indicates a type of Hook procedure to be installed.
  165.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  166.        ''' </summary>
  167.        <Description("Enum used in 'idHook' parameter of 'SetWindowsHookEx' function")>
  168.        Friend Enum HookType As Integer
  169.  
  170.            ' **************************************
  171.            ' This enumeration is partially defined.
  172.            ' **************************************
  173.  
  174.            ''' <summary>
  175.            ''' Installs a hook procedure that monitors low-level mouse input events.
  176.            ''' For more information, see the LowLevelMouseProc hook procedure.
  177.            ''' </summary>
  178.            WH_MOUSE_LL = 14I
  179.  
  180.        End Enum
  181.  
  182. #End Region
  183.  
  184. #Region " Structures "
  185.  
  186.        ''' <summary>
  187.        ''' Contains information about a low-level mouse input event.
  188.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
  189.        ''' </summary>
  190.        <Description("Structure used in 'lParam' parameter of 'CallNextHookEx' function")>
  191.        Friend Structure MSLLHOOKSTRUCT
  192.  
  193.            ''' <summary>
  194.            ''' The ptThe x- and y-coordinates of the cursor, in screen coordinates.
  195.            ''' </summary>
  196.            Friend pt As Point
  197.  
  198.            ''' <summary>
  199.            ''' If the message is 'WM_MOUSEWHEEL', the high-order word of this member is the wheel delta.
  200.            ''' The low-order word is reserved.
  201.            ''' A positive value indicates that the wheel was rotated forward, away from the user;
  202.            ''' a negative value indicates that the wheel was rotated backward, toward the user.
  203.            ''' One wheel click is defined as 'WHEEL_DELTA', which is '120'.
  204.            ''' </summary>
  205.            Friend mouseData As Integer
  206.  
  207.            ''' <summary>
  208.            ''' The event-injected flag.
  209.            ''' </summary>
  210.            Friend flags As UInteger
  211.  
  212.            ''' <summary>
  213.            ''' The time stamp for this message.
  214.            ''' </summary>
  215.            Friend time As UInteger
  216.  
  217.            ''' <summary>
  218.            ''' Additional information associated with the message.
  219.            ''' </summary>
  220.            Friend dwExtraInfo As IntPtr
  221.  
  222.        End Structure
  223.  
  224. #End Region
  225.  
  226. #Region " Delegates "
  227.  
  228.        ''' <summary>
  229.        ''' Delegate LowLevelMouseProc
  230.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  231.        ''' </summary>
  232.        ''' <returns>
  233.        ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  234.        ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  235.        ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  236.        ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  237.        ''' and may behave incorrectly as a result.
  238.        ''' If the hook procedure processed the message,
  239.        ''' 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.
  240.        ''' </returns>
  241.        Friend Delegate Function LowLevelMouseProcDelegate(
  242.                ByVal nCode As IntPtr,
  243.                ByVal wParam As IntPtr,
  244.                ByRef lParam As NativeMethods.MSLLHOOKSTRUCT
  245.        ) As IntPtr
  246.  
  247. #End Region
  248.  
  249. #Region " Hidden Methods "
  250.  
  251.        ''' <summary>
  252.        ''' Determines whether the specified System.Object instances are considered equal.
  253.        ''' </summary>
  254.        <EditorBrowsable(EditorBrowsableState.Never)>
  255.        Public Shadows Sub Equals()
  256.        End Sub
  257.  
  258.        ''' <summary>
  259.        ''' Determines whether the specified System.Object instances are the same instance.
  260.        ''' </summary>
  261.        <EditorBrowsable(EditorBrowsableState.Never)>
  262.        Private Shadows Sub ReferenceEquals()
  263.        End Sub
  264.  
  265. #End Region
  266.  
  267.    End Class
  268.  
  269. #End Region
  270.  
  271. #Region " Objects "
  272.  
  273.    ''' <summary>
  274.    ''' Handle to the hook procedure.
  275.    ''' </summary>
  276.    Private MouseHook As IntPtr
  277.  
  278.    ''' <summary>
  279.    ''' The mouse hook delegate.
  280.    ''' </summary>
  281.    Private MouseHookDelegate As NativeMethods.LowLevelMouseProcDelegate
  282.  
  283. #End Region
  284.  
  285. #Region " Properties "
  286.  
  287.    ''' <summary>
  288.    ''' ** ONLY FOR TESTING PURPOSES **
  289.    ''' Gets or sets a value indicating whether to suppress the last MouseUp event of
  290.    ''' the specified clicked button when a double-click fires.
  291.    '''
  292.    ''' If this value is set to <c>true</c>, the application will send the events in this order for a Double-Click:
  293.    ''' MouseDown, MouseUp, MouseDown, MouseDoubleClick
  294.    '''
  295.    ''' If this value is set to <c>false</c>, the application will send the events in this order for a Double-Click:
  296.    ''' MouseDown, MouseUp, MouseDown, MouseUp, MouseDoubleClick
  297.    '''
  298.    ''' </summary>
  299.    ''' <value><c>true</c> if MouseUp event is suppressed; otherwise <c>false</c>.</value>
  300.    Friend Property SuppressMouseUpEventWhenDoubleClick As Boolean = False
  301.  
  302. #End Region
  303.  
  304. #Region " Enumerations "
  305.  
  306.    ''' <summary>
  307.    ''' Indicates a Windows Message related to a mouse events.
  308.    ''' For more info see here:
  309.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877%28v=vs.85%29.aspx
  310.    ''' </summary>
  311.    Private Enum MouseMessages As UInteger
  312.  
  313.        ''' <summary>
  314.        ''' Posted to a window when the cursor moves.
  315.        ''' If the mouse is not captured, the message is posted to the window that contains the cursor.
  316.        ''' Otherwise, the message is posted to the window that has captured the mouse
  317.        ''' </summary>
  318.        WM_MOUSEMOVE = &H200UI
  319.  
  320.        ''' <summary>
  321.        ''' Posted when the user presses the left mouse button while the cursor is in the client area of a window.
  322.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  323.        ''' Otherwise, the message is posted to the window that has captured the mouse
  324.        ''' </summary>
  325.        WM_LBUTTONDOWN = &H201UI
  326.  
  327.        ''' <summary>
  328.        ''' Posted when the user releases the left mouse button while the cursor is in the client area of a window.
  329.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  330.        ''' Otherwise, the message is posted to the window that has captured the mouse
  331.        ''' </summary>
  332.        WM_LBUTTONUP = &H202UI
  333.  
  334.        ''' <summary>
  335.        ''' Posted when the user presses the right mouse button while the cursor is in the client area of a window.
  336.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  337.        ''' Otherwise, the message is posted to the window that has captured the mouse
  338.        ''' </summary>
  339.        WM_RBUTTONDOWN = &H204UI
  340.  
  341.        ''' <summary>
  342.        ''' Posted when the user releases the right mouse button while the cursor is in the client area of a window.
  343.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  344.        ''' Otherwise, the message is posted to the window that has captured the mouse
  345.        ''' </summary>
  346.        WM_RBUTTONUP = &H205UI
  347.  
  348.        ''' <summary>
  349.        ''' Posted when the user presses the middle mouse button while the cursor is in the client area of a window.
  350.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  351.        ''' Otherwise, the message is posted to the window that has captured the mouse
  352.        ''' </summary>
  353.        WM_MBUTTONDOWN = &H207UI
  354.  
  355.        ''' <summary>
  356.        ''' Posted when the user releases the middle mouse button while the cursor is in the client area of a window.
  357.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  358.        ''' Otherwise, the message is posted to the window that has captured the mouse
  359.        ''' </summary>
  360.        WM_MBUTTONUP = &H208UI
  361.  
  362.        ''' <summary>
  363.        ''' Sent to the active window when the mouse's horizontal scroll wheel is tilted or rotated.
  364.        ''' The DefWindowProc function propagates the message to the window's parent.
  365.        ''' There should be no internal forwarding of the message,
  366.        ''' since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
  367.        ''' </summary>
  368.        WM_MOUSEWHEEL = &H20AUI
  369.  
  370.    End Enum
  371.  
  372.    ''' <summary>
  373.    ''' Indicates the whell direction of the mouse.
  374.    ''' </summary>
  375.    Public Enum WheelDirection As Integer
  376.  
  377.        ''' <summary>
  378.        ''' The wheel is moved up.
  379.        ''' </summary>
  380.        WheelUp = 1
  381.  
  382.        ''' <summary>
  383.        ''' The wheel is moved down.
  384.        ''' </summary>
  385.        WheelDown = 2
  386.  
  387.    End Enum
  388.  
  389. #End Region
  390.  
  391. #Region " Events "
  392.  
  393.    ''' <summary>
  394.    ''' Occurs when the mouse moves.
  395.    ''' </summary>
  396.    Friend Event MouseMove(ByVal sender As Object,
  397.                           ByVal MouseLocation As Point)
  398.  
  399.    ''' <summary>
  400.    ''' Occurs when the mouse left button is pressed.
  401.    ''' </summary>
  402.    Friend Event MouseLeftDown(ByVal sender As Object,
  403.                               ByVal MouseLocation As Point)
  404.  
  405.    ''' <summary>
  406.    ''' Occurs when the mouse left button is released.
  407.    ''' </summary>
  408.    Friend Event MouseLeftUp(ByVal sender As Object,
  409.                             ByVal MouseLocation As Point)
  410.  
  411.    ''' <summary>
  412.    ''' Occurs when the mouse left button performs a double-click.
  413.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  414.    ''' </summary>
  415.    Friend Event MouseLeftDoubleClick(ByVal sender As Object,
  416.                                      ByVal MouseLocation As Point)
  417.  
  418.    ''' <summary>
  419.    ''' Occurs when the mouse right button is pressed.
  420.    ''' </summary>
  421.    Friend Event MouseRightDown(ByVal sender As Object,
  422.                                ByVal MouseLocation As Point)
  423.  
  424.    ''' <summary>
  425.    ''' Occurs when the mouse right button is released.
  426.    ''' </summary>
  427.    Friend Event MouseRightUp(ByVal sender As Object,
  428.                              ByVal MouseLocation As Point)
  429.  
  430.    ''' <summary>
  431.    ''' Occurs when the mouse right button performs a double-click.
  432.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  433.    ''' </summary>
  434.    Friend Event MouseRightDoubleClick(ByVal sender As Object,
  435.                                       ByVal MouseLocation As Point)
  436.  
  437.    ''' <summary>
  438.    ''' Occurs when the mouse middle button is pressed.
  439.    ''' </summary>
  440.    Friend Event MouseMiddleDown(ByVal sender As Object,
  441.                                 ByVal MouseLocation As Point)
  442.  
  443.    ''' <summary>
  444.    ''' Occurs when the mouse middle button is released.
  445.    ''' </summary>
  446.    Friend Event MouseMiddleUp(ByVal sender As Object,
  447.                               ByVal MouseLocation As Point)
  448.  
  449.    ''' <summary>
  450.    ''' Occurs when the mouse middle button performs a double-click.
  451.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  452.    ''' </summary>
  453.    Friend Event MouseMiddleDoubleClick(ByVal sender As Object,
  454.                                        ByVal MouseLocation As Point)
  455.  
  456.    ''' <summary>
  457.    ''' Occurs when the mouse wheel is moved up or down.
  458.    ''' </summary>
  459.    Friend Event MouseWheel(ByVal sender As Object,
  460.                            ByVal MouseLocation As Point,
  461.                            ByVal WheelDirection As WheelDirection)
  462.  
  463. #End Region
  464.  
  465. #Region " Constructors "
  466.  
  467.    ''' <summary>
  468.    ''' Prevents a default instance of the <see cref="MouseHook"/> class from being created.
  469.    ''' </summary>
  470.    Private Sub New()
  471.    End Sub
  472.  
  473.    ''' <summary>
  474.    ''' Initializes a new instance of the <see cref="MouseHook"/> class.
  475.    ''' </summary>
  476.    ''' <param name="AutoStart">
  477.    ''' If set to <c>true</c>, the Hook starts instantly for this <see cref="MouseHook"/> instance.
  478.    ''' </param>
  479.    Friend Sub New(Optional ByVal AutoStart As Boolean = False)
  480.  
  481.        If AutoStart Then
  482.            Me.[Start]()
  483.        End If
  484.  
  485.    End Sub
  486.  
  487. #End Region
  488.  
  489. #Region " Public Methods "
  490.  
  491.    ''' <summary>
  492.    ''' Starts the Mouse Hook, then start processing messages to fire events.
  493.    ''' </summary>
  494.    Friend Sub [Start]()
  495.  
  496.        Me.MouseHookDelegate = New NativeMethods.LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)
  497.  
  498.        Try
  499.            Me.MouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.HookType.WH_MOUSE_LL,
  500.                                                          Me.MouseHookDelegate,
  501.                                                          Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
  502.  
  503.        Catch ex As Exception
  504.            Throw
  505.  
  506.        End Try
  507.  
  508.    End Sub
  509.  
  510.    ''' <summary>
  511.    ''' Stops the Mouse Hook and free all resources, then stop processing messages to fire events.
  512.    ''' </summary>
  513.    Friend Sub [Stop]()
  514.  
  515.        Me.Finalize()
  516.  
  517.    End Sub
  518.  
  519. #End Region
  520.  
  521. #Region " Private Methods "
  522.  
  523.    ''' <summary>
  524.    ''' Processes the mouse windows messages and raises it's corresponding events.
  525.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  526.    ''' </summary>
  527.    ''' <param name="nCode">
  528.    ''' A code the hook procedure uses to determine how to process the message.
  529.    ''' If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function
  530.    ''' without further processing and should return the value returned by CallNextHookEx.
  531.    ''' </param>
  532.    ''' <param name="wParam">The identifier of the mouse message.</param>
  533.    ''' <param name="lParam"> A pointer to an <see cref="NativeMethods.MSLLHOOKSTRUCT"/> structure.</param>
  534.    ''' <returns>
  535.    ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  536.    ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  537.    ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  538.    ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  539.    ''' and may behave incorrectly as a result.
  540.    ''' If the hook procedure processed the message,
  541.    ''' it may return a nonzero value to prevent the system from passing the
  542.    ''' message to the rest of the hook chain or the target window procedure.
  543.    ''' </returns>
  544.    Private Function LowLevelMouseProc(ByVal nCode As Integer,
  545.                                       ByVal wParam As MouseMessages,
  546.                                       ByRef lParam As NativeMethods.MSLLHOOKSTRUCT) As Integer
  547.  
  548.        Static LeftClickTime As Integer = 0I ' Determines a left button double-click.
  549.        Static RightClickTime As Integer = 0I ' Determines a right button double-click.
  550.        Static MiddleClickTime As Integer = 0I ' Determines a middle button double-click.
  551.  
  552.        If nCode = 0I Then
  553.  
  554.            Select Case wParam
  555.  
  556.                Case MouseMessages.WM_MOUSEMOVE
  557.                    RaiseEvent MouseMove(Me, lParam.pt)
  558.  
  559.                Case MouseMessages.WM_LBUTTONDOWN
  560.                    RaiseEvent MouseLeftDown(Me, lParam.pt)
  561.  
  562.                Case MouseMessages.WM_LBUTTONUP
  563.                    If LeftClickTime <> 0 Then
  564.                        LeftClickTime = Environment.TickCount() - LeftClickTime
  565.                    End If
  566.  
  567.                    If (LeftClickTime <> 0) AndAlso (LeftClickTime < NativeMethods.GetDoubleClickTime()) Then
  568.                        LeftClickTime = 0
  569.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  570.                            RaiseEvent MouseLeftUp(Me, lParam.pt)
  571.                        End If
  572.                        RaiseEvent MouseLeftDoubleClick(Me, lParam.pt)
  573.  
  574.                    Else
  575.                        LeftClickTime = Environment.TickCount()
  576.                        RaiseEvent MouseLeftUp(Me, lParam.pt)
  577.  
  578.                    End If
  579.  
  580.                Case MouseMessages.WM_RBUTTONDOWN
  581.                    RaiseEvent MouseRightDown(Me, lParam.pt)
  582.  
  583.                Case MouseMessages.WM_RBUTTONUP
  584.                    If RightClickTime <> 0 Then
  585.                        RightClickTime = Environment.TickCount() - RightClickTime
  586.                    End If
  587.  
  588.                    If (RightClickTime <> 0) AndAlso (RightClickTime < NativeMethods.GetDoubleClickTime()) Then
  589.                        RightClickTime = 0
  590.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  591.                            RaiseEvent MouseRightUp(Me, lParam.pt)
  592.                        End If
  593.                        RaiseEvent MouseRightDoubleClick(Me, lParam.pt)
  594.  
  595.                    Else
  596.                        RightClickTime = Environment.TickCount()
  597.                        RaiseEvent MouseRightUp(Me, lParam.pt)
  598.  
  599.                    End If
  600.  
  601.                Case MouseMessages.WM_MBUTTONDOWN
  602.                    RaiseEvent MouseMiddleDown(Me, lParam.pt)
  603.  
  604.                Case MouseMessages.WM_MBUTTONUP
  605.                    If MiddleClickTime <> 0 Then
  606.                        MiddleClickTime = Environment.TickCount() - MiddleClickTime
  607.                    End If
  608.  
  609.                    If (MiddleClickTime <> 0) AndAlso (MiddleClickTime < NativeMethods.GetDoubleClickTime()) Then
  610.                        MiddleClickTime = 0
  611.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  612.                            RaiseEvent MouseMiddleUp(Me, lParam.pt)
  613.                        End If
  614.                        RaiseEvent MouseMiddleDoubleClick(Me, lParam.pt)
  615.  
  616.                    Else
  617.                        MiddleClickTime = Environment.TickCount()
  618.                        RaiseEvent MouseMiddleUp(Me, lParam.pt)
  619.  
  620.                    End If
  621.  
  622.                Case MouseMessages.WM_MOUSEWHEEL
  623.                    RaiseEvent MouseWheel(Me, lParam.pt, If(lParam.mouseData < 0,
  624.                                                            WheelDirection.WheelDown,
  625.                                                            WheelDirection.WheelUp))
  626.  
  627.                Case Else
  628.                    Exit Select ' Do Nothing
  629.  
  630.            End Select
  631.  
  632.            Return 0
  633.  
  634.        ElseIf nCode < 0I Then
  635.  
  636.            ' Initialize unmanged memory to hold the 'MSLLHOOKSTRUCT' structure.
  637.            Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(lParam))
  638.  
  639.            Try ' MSDN Documentation: http://msdn.microsoft.com/en-us/library/vstudio/4ca6d5z7%28v=vs.100%29.aspx
  640.  
  641.                ' Copy the struct to unmanaged memory.
  642.                Marshal.StructureToPtr(lParam, pnt, False)
  643.  
  644.                ' Return
  645.                Return NativeMethods.CallNextHookEx(MouseHook, nCode, wParam, pnt)
  646.  
  647.            Finally
  648.                ' Free the unmanaged memory.
  649.                Marshal.FreeHGlobal(pnt)
  650.            End Try
  651.  
  652.        Else ' nCode > 0
  653.  
  654.            Return -1I
  655.  
  656.        End If
  657.  
  658.    End Function
  659.  
  660. #End Region
  661.  
  662. #Region " Hidden Methods "
  663.  
  664.    ''' <summary>
  665.    ''' Serves as a hash function for a particular type.
  666.    ''' </summary>
  667.    <EditorBrowsable(EditorBrowsableState.Never)>
  668.    Public Shadows Sub GetHashCode()
  669.    End Sub
  670.  
  671.    ''' <summary>
  672.    ''' Gets the System.Type of the current instance.
  673.    ''' </summary>
  674.    ''' <returns>The exact runtime type of the current instance.</returns>
  675.    <EditorBrowsable(EditorBrowsableState.Never)>
  676.    Public Shadows Function [GetType]()
  677.        Return Me.GetType
  678.    End Function
  679.  
  680.    ''' <summary>
  681.    ''' Determines whether the specified System.Object instances are considered equal.
  682.    ''' </summary>
  683.    <EditorBrowsable(EditorBrowsableState.Never)>
  684.    Public Shadows Sub Equals()
  685.    End Sub
  686.  
  687.    ''' <summary>
  688.    ''' Determines whether the specified System.Object instances are the same instance.
  689.    ''' </summary>
  690.    <EditorBrowsable(EditorBrowsableState.Never)>
  691.    Private Shadows Sub ReferenceEquals()
  692.    End Sub
  693.  
  694.    ''' <summary>
  695.    ''' Returns a String that represents the current object.
  696.    ''' </summary>
  697.    <EditorBrowsable(EditorBrowsableState.Never)>
  698.    Public Shadows Sub ToString()
  699.    End Sub
  700.  
  701. #End Region
  702.  
  703. #Region "IDisposable Support"
  704.  
  705.    ''' <summary>
  706.    ''' Flag to detect redundant calls at <see cref="Dispose"/> method.
  707.    ''' </summary>
  708.    Private disposedValue As Boolean
  709.  
  710.    ''' <summary>
  711.    ''' Releases unmanaged and optionally managed resources.
  712.    ''' </summary>
  713.    ''' <param name="disposing">
  714.    ''' <c>true</c> to release both managed and unmanaged resources;
  715.    ''' <c>false</c> to release only unmanaged resources.
  716.    ''' </param>
  717.    Protected Sub Dispose(ByVal disposing As Boolean)
  718.  
  719.        If Not Me.disposedValue Then
  720.  
  721.            If disposing Then ' Dispose managed state (managed objects).
  722.  
  723.            Else ' Free unmanaged resources (unmanaged objects).
  724.                NativeMethods.UnhookWindowsHookEx(Me.MouseHook)
  725.  
  726.            End If
  727.  
  728.        End If
  729.  
  730.        Me.disposedValue = True
  731.  
  732.    End Sub
  733.  
  734.    ''' <summary>
  735.    ''' Allows an object to try to free resources
  736.    ''' and perform other cleanup operations before it is reclaimed by garbage collection.
  737.    ''' </summary>
  738.    Protected Overrides Sub Finalize()
  739.  
  740.        ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  741.  
  742.        Me.Dispose(disposing:=False)
  743.        MyBase.Finalize()
  744.  
  745.    End Sub
  746.  
  747.    ''' <summary>
  748.    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  749.    ''' </summary>
  750.    Private Sub Dispose() Implements IDisposable.Dispose
  751.  
  752.        ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  753.  
  754.        Me.Dispose(disposing:=True)
  755.        GC.SuppressFinalize(obj:=Me)
  756.  
  757.    End Sub
  758.  
  759. #End Region
  760.  
  761. End Class
  762.  
  763. #End Region
En línea


Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #5 en: 26 Septiembre 2014, 01:36 am »

Hago este doble post (y perdón con antelación) para mostrar un ejemplo de uso, ya que no cabe más arriba.

Código
  1. Public Class Form1
  2.  
  3.    ''' <summary>
  4.    ''' A low level mouse hook that intercepts mouse events.
  5.    ''' </summary>
  6.    Friend WithEvents MouseEvents As New MouseHook(AutoStart:=False) With {.SuppressMouseUpEventWhenDoubleClick = False}
  7.  
  8.    ''' <summary>
  9.    ''' Handles the Load event of the Form1.
  10.    ''' </summary>
  11.    ''' <param name="sender">The source of the event.</param>
  12.    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
  13.    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  14.  
  15.        ' Start the Mouse Hook.
  16.        Me.MouseEvents.[Start]()
  17.  
  18.    End Sub
  19.  
  20.    ''' <summary>
  21.    ''' Handles the FormClosing event of the Form1.
  22.    ''' </summary>
  23.    ''' <param name="sender">The source of the event.</param>
  24.    ''' <param name="e">The <see cref="FormClosingEventArgs"/> instance containing the event data.</param>
  25.    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) _
  26.    Handles MyBase.FormClosing
  27.  
  28.        ' Stop and free the Mouse Hook resources.
  29.        Me.MouseEvents.[Stop]()
  30.  
  31.    End Sub
  32.  
  33.    ''' <summary>
  34.    ''' Handles the 'MouseMove' event of the Mouse Hook.
  35.    ''' </summary>
  36.    ''' <param name="sender">The source of the event.</param>
  37.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  38.    Private Sub MouseEvents_MouseMove(ByVal sender As Object, ByVal MouseLocation As Point) _
  39.    Handles MouseEvents.MouseMove
  40.  
  41.        Debug.WriteLine(String.Format("Mouse Moved To: x={0}, y={1}",
  42.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  43.  
  44.    End Sub
  45.  
  46.    ''' <summary>
  47.    ''' Handles the 'MouseLeftDown' event of the MouseHook.
  48.    ''' </summary>
  49.    ''' <param name="sender">The source of the event.</param>
  50.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  51.    Private Sub MouseEvents_MouseLeftDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  52.    Handles MouseEvents.MouseLeftDown
  53.  
  54.        Debug.WriteLine(String.Format("Mouse Left Down At: x={0}, y={1}",
  55.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  56.  
  57.    End Sub
  58.  
  59.    ''' <summary>
  60.    ''' Handles the 'MouseLeftUp' event of the Mouse Hook.
  61.    ''' </summary>
  62.    ''' <param name="sender">The source of the event.</param>
  63.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  64.    Private Sub MouseEvents_MouseLeftUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  65.    Handles MouseEvents.MouseLeftUp
  66.  
  67.        Debug.WriteLine(String.Format("Mouse Left Up At: x={0}, y={1}",
  68.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  69.  
  70.    End Sub
  71.  
  72.    ''' <summary>
  73.    ''' Handles the 'MouseRightDown' event of the MouseHook.
  74.    ''' </summary>
  75.    ''' <param name="sender">The source of the event.</param>
  76.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  77.    Private Sub MouseEvents_MouseRightDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  78.    Handles MouseEvents.MouseRightDown
  79.  
  80.        Debug.WriteLine(String.Format("Mouse Right Down At: x={0}, y={1}",
  81.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  82.  
  83.    End Sub
  84.  
  85.    ''' <summary>
  86.    ''' Handles the 'MouseRightUp' event of the Mouse Hook.
  87.    ''' </summary>
  88.    ''' <param name="sender">The source of the event.</param>
  89.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  90.    Private Sub MouseEvents_MouseRightUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  91.    Handles MouseEvents.MouseRightUp
  92.  
  93.        Debug.WriteLine(String.Format("Mouse Right Up At: x={0}, y={1}",
  94.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  95.  
  96.    End Sub
  97.  
  98.    ''' <summary>
  99.    ''' Handles the 'MouseMiddleDown' event of the MouseHook.
  100.    ''' </summary>
  101.    ''' <param name="sender">The source of the event.</param>
  102.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  103.    Private Sub MouseEvents_MouseMiddleDown(ByVal sender As Object, ByVal MouseLocation As Point) _
  104.    Handles MouseEvents.MouseMiddleDown
  105.  
  106.        Debug.WriteLine(String.Format("Mouse Middle Down At: x={0}, y={1}",
  107.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  108.  
  109.    End Sub
  110.  
  111.    ''' <summary>
  112.    ''' Handles the 'MouseMiddleUp' event of the Mouse Hook.
  113.    ''' </summary>
  114.    ''' <param name="sender">The source of the event.</param>
  115.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  116.    Private Sub MouseEvents_MouseMiddleUp(ByVal sender As Object, ByVal MouseLocation As Point) _
  117.    Handles MouseEvents.MouseMiddleUp
  118.  
  119.        Debug.WriteLine(String.Format("Mouse Middle Up At: x={0}, y={1}",
  120.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  121.  
  122.    End Sub
  123.  
  124.    ''' <summary>
  125.    ''' Handles the 'MouseLeftDoubleClick' event of the Mouse Hook.
  126.    ''' </summary>
  127.    ''' <param name="sender">The source of the event.</param>
  128.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  129.    Private Sub MouseEvents_MouseLeftDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  130.    Handles MouseEvents.MouseLeftDoubleClick
  131.  
  132.        Debug.WriteLine(String.Format("Mouse Left Double-Click At: x={0}, y={1}",
  133.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  134.  
  135.    End Sub
  136.  
  137.    ''' <summary>
  138.    ''' Handles the 'MouseRightDoubleClick' event of the Mouse Hook.
  139.    ''' </summary>
  140.    ''' <param name="sender">The source of the event.</param>
  141.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  142.    Private Sub MouseEvents_MouseRightDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  143.    Handles MouseEvents.MouseRightDoubleClick
  144.  
  145.        Debug.WriteLine(String.Format("Mouse Right Double-Click At: x={0}, y={1}",
  146.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  147.  
  148.    End Sub
  149.  
  150.    ''' <summary>
  151.    ''' Handles the 'MouseMiddleDoubleClick' event of the Mouse Hook.
  152.    ''' </summary>
  153.    ''' <param name="sender">The source of the event.</param>
  154.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  155.    Private Sub MouseEvents_MouseMiddleDoubleClick(ByVal sender As Object, ByVal MouseLocation As Point) _
  156.    Handles MouseEvents.MouseMiddleDoubleClick
  157.  
  158.        Debug.WriteLine(String.Format("Mouse Middle Double-Click At: x={0}, y={1}",
  159.                                      CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  160.  
  161.    End Sub
  162.  
  163.    ''' <summary>
  164.    ''' Handles the 'MouseWheel' event of the Mouse Hook.
  165.    ''' </summary>
  166.    ''' <param name="sender">The source of the event.</param>
  167.    ''' <param name="MouseLocation">Contains the mouse [X,Y] coordinates where the event fired.</param>
  168.    ''' <param name="WheelDirection">Contains the wheel direction (WheelUp or WheelDown).</param>
  169.    Private Sub MouseEvents_MouseWheel(ByVal sender As Object,
  170.                                       ByVal MouseLocation As Point,
  171.                                       ByVal WheelDirection As MouseHook.WheelDirection) _
  172.    Handles MouseEvents.MouseWheel
  173.  
  174.        Debug.WriteLine(String.Format("Mouse Whell ({0}) At: x={1}, y={2}",
  175.                                      WheelDirection.ToString, CStr(MouseLocation.X), CStr(MouseLocation.Y)))
  176.  
  177.    End Sub
  178.  
  179. End Class
  180.  
En línea


Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #6 en: 26 Septiembre 2014, 14:32 pm »

un último repaso definitivo a esta Class, para fijar un pequeño problema con las coordenadas.

Código
  1. ' ***********************************************************************
  2. ' Author           : Elektro
  3. ' Last Modified On : 09-26-2014
  4. ' ***********************************************************************
  5. ' <copyright file="MouseHook.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Instructions "
  11.  
  12. ' Go to page:
  13. ' Project > Properties > Debug
  14. '
  15. ' Then uncheck the option:
  16. ' "Enable the Visual Studio Hosting Process"
  17.  
  18. #End Region
  19.  
  20. #Region " Usage Examples "
  21.  
  22. #End Region
  23.  
  24. #Region " Imports "
  25.  
  26. Imports System.ComponentModel
  27. Imports System.Reflection
  28. Imports System.Runtime.InteropServices
  29.  
  30. #End Region
  31.  
  32. #Region " MouseHook "
  33.  
  34. ''' <summary>
  35. ''' A low level mouse hook that processes mouse input events.
  36. ''' </summary>
  37. Friend NotInheritable Class MouseHook : Implements IDisposable
  38.  
  39. #Region " P/Invoke "
  40.  
  41.    ''' <summary>
  42.    ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  43.    ''' This class does not suppress stack walks for unmanaged code permission.
  44.    ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/>  must not be applied to this class.
  45.    ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  46.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/ms182161.aspx
  47.    ''' </summary>
  48.    Protected NotInheritable Class NativeMethods
  49.  
  50. #Region " Methods "
  51.  
  52.        ''' <summary>
  53.        ''' Passes the hook information to the next hook procedure in the current hook chain.
  54.        ''' A hook procedure can call this function either before or after processing the hook information.
  55.        ''' For more info see here:
  56.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
  57.        ''' </summary>
  58.        ''' <param name="idHook">
  59.        ''' This parameter is ignored.
  60.        ''' </param>
  61.        ''' <param name="nCode">
  62.        ''' The hook code passed to the current hook procedure.
  63.        ''' The next hook procedure uses this code to determine how to process the hook information.
  64.        ''' </param>
  65.        ''' <param name="wParam">
  66.        ''' The wParam value passed to the current hook procedure.
  67.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  68.        ''' </param>
  69.        ''' <param name="lParam">
  70.        ''' The lParam value passed to the current hook procedure.
  71.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  72.        ''' </param>
  73.        ''' <returns>
  74.        ''' This value is returned by the next hook procedure in the chain.
  75.        ''' The current hook procedure must also return this value.
  76.        ''' The meaning of the return value depends on the hook type.
  77.        ''' For more information, see the descriptions of the individual hook procedures.
  78.        ''' </returns>
  79.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  80.        Friend Shared Function CallNextHookEx(
  81.               ByVal idHook As IntPtr,
  82.               ByVal nCode As Integer,
  83.               ByVal wParam As IntPtr,
  84.               ByVal lParam As IntPtr
  85.        ) As IntPtr
  86.        End Function
  87.  
  88.        ''' <summary>
  89.        ''' Installs an application-defined hook procedure into a hook chain.
  90.        ''' You would install a hook procedure to monitor the system for certain types of events.
  91.        ''' These events are associated either with a specific thread
  92.        ''' or with all threads in the same desktop as the calling thread.
  93.        ''' For more info see here:
  94.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  95.        ''' </summary>
  96.        ''' <param name="idHook">
  97.        ''' The type of hook procedure to be installed.
  98.        ''' </param>
  99.        ''' <param name="lpfn">
  100.        ''' A pointer to the hook procedure.
  101.        ''' If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process,
  102.        ''' the lpfn parameter must point to a hook procedure in a DLL.
  103.        ''' Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
  104.        ''' </param>
  105.        ''' <param name="hInstance">
  106.        ''' A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
  107.        ''' The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by
  108.        ''' the current process and if the hook procedure is within the code associated with the current process.
  109.        ''' </param>
  110.        ''' <param name="threadId">
  111.        ''' The identifier of the thread with which the hook procedure is to be associated.
  112.        ''' For desktop apps, if this parameter is zero, the hook procedure is associated
  113.        ''' with all existing threads running in the same desktop as the calling thread.
  114.        ''' </param>
  115.        ''' <returns>
  116.        ''' If the function succeeds, the return value is the handle to the hook procedure.
  117.        ''' If the function fails, the return value is NULL.
  118.        ''' </returns>
  119.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  120.        Friend Shared Function SetWindowsHookEx(
  121.               ByVal idHook As HookType,
  122.               ByVal lpfn As LowLevelMouseProcDelegate,
  123.               ByVal hInstance As IntPtr,
  124.               ByVal threadId As UInteger
  125.        ) As IntPtr
  126.        End Function
  127.  
  128.        ''' <summary>
  129.        ''' Removes a hook procedure installed in a hook chain by the 'SetWindowsHookEx' function.
  130.        ''' For more info see here:
  131.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
  132.        ''' </summary>
  133.        ''' <param name="idHook">
  134.        ''' A handle to the hook to be removed.
  135.        ''' This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
  136.        ''' </param>
  137.        ''' <returns>
  138.        ''' If the function succeeds, the return value is nonzero.
  139.        ''' If the function fails, the return value is zero.
  140.        ''' </returns>
  141.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  142.        Friend Shared Function UnhookWindowsHookEx(
  143.               ByVal idHook As IntPtr
  144.        ) As Boolean
  145.        End Function
  146.  
  147.        ''' <summary>
  148.        ''' Retrieves the current double-click time for the mouse.
  149.        ''' A double-click is a series of two clicks of the mouse button,
  150.        ''' the second occurring within a specified time after the first.
  151.        ''' The double-click time is the maximum number of milliseconds that may occur
  152.        ''' between the first and second click of a double-click.
  153.        ''' The maximum double-click time is 5000 milliseconds.
  154.        ''' </summary>
  155.        ''' <returns>
  156.        ''' The return value specifies the current double-click time, in milliseconds.
  157.        ''' The maximum return value is 5000 milliseconds.
  158.        ''' </returns>
  159.        <DllImport("user32.dll", CharSet:=CharSet.Auto)>
  160.        Friend Shared Function GetDoubleClickTime() As Integer
  161.        End Function
  162.  
  163. #End Region
  164.  
  165. #Region " Enumerations "
  166.  
  167.        ''' <summary>
  168.        ''' Indicates a type of Hook procedure to be installed.
  169.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  170.        ''' </summary>
  171.        <Description("Enum used in 'idHook' parameter of 'SetWindowsHookEx' function.")>
  172.        Friend Enum HookType As UInteger
  173.  
  174.            ' **************************************
  175.            ' This enumeration is partially defined.
  176.            ' **************************************
  177.  
  178.            ''' <summary>
  179.            ''' Installs a hook procedure that monitors low-level mouse input events.
  180.            ''' For more information, see the LowLevelMouseProc hook procedure.
  181.            ''' </summary>
  182.            WH_MOUSE_LL = 14UI
  183.  
  184.        End Enum
  185.  
  186.        ''' <summary>
  187.        ''' The event-injected flags.
  188.        ''' An application can use the following values to test the flags.
  189.        ''' Testing LLMHF_INJECTED (bit 0) will tell you whether the event was injected.
  190.        ''' If it was, then testing LLMHF_LOWER_IL_INJECTED (bit 1) will tell you
  191.        ''' whether or not the event was injected from a process running at lower integrity level.
  192.        ''' </summary>
  193.        <Flags()>
  194.        <Description("Enum used in 'flags' parameter of 'MSLLHOOKSTRUCT' structure.")>
  195.        Public Enum MSLLHOOKSTRUCTFlags As Integer
  196.  
  197.            ''' <summary>
  198.            ''' Test the event-injected (from any process) flag.
  199.            ''' </summary>
  200.            LLMHF_INJECTED = 1
  201.  
  202.            ''' <summary>
  203.            ''' Test the event-injected (from a process running at lower integrity level) flag.
  204.            ''' </summary>
  205.            LLMHF_LOWER_IL_INJECTED = 2
  206.  
  207.        End Enum
  208.  
  209. #End Region
  210.  
  211. #Region " Structures "
  212.  
  213.        ''' <summary>
  214.        ''' The POINT structure defines the x- and y- coordinates of a point.
  215.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx
  216.        ''' </summary>
  217.        <Description("Structure used in 'pt' parameter of 'MSLLHOOKSTRUCT' structure.")>
  218.        <StructLayout(LayoutKind.Sequential)>
  219.        Friend Structure POINT
  220.  
  221.            ''' <summary>
  222.            ''' The x-coordinate of the point.
  223.            ''' </summary>
  224.            Public X As Integer
  225.  
  226.            ''' <summary>
  227.            ''' The y-coordinate of the point.
  228.            ''' </summary>
  229.            Public Y As Integer
  230.  
  231.        End Structure
  232.  
  233.        ''' <summary>
  234.        ''' Contains information about a low-level mouse input event.
  235.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
  236.        ''' </summary>
  237.        <Description("Structure used in 'lParam' parameter of 'CallNextHookEx' function.")>
  238.        Friend Structure MSLLHOOKSTRUCT
  239.  
  240.            ''' <summary>
  241.            ''' The ptThe x- and y-coordinates of the cursor, in screen coordinates.
  242.            ''' </summary>
  243.            Friend pt As NativeMethods.POINT
  244.  
  245.            ''' <summary>
  246.            ''' If the message is 'WM_MOUSEWHEEL', the high-order word of this member is the wheel delta.
  247.            ''' The low-order word is reserved.
  248.            ''' A positive value indicates that the wheel was rotated forward, away from the user;
  249.            ''' a negative value indicates that the wheel was rotated backward, toward the user.
  250.            ''' One wheel click is defined as 'WHEEL_DELTA', which is '120'.
  251.            ''' </summary>
  252.            Friend mouseData As Integer
  253.  
  254.            ''' <summary>
  255.            ''' The event-injected flag.
  256.            ''' </summary>
  257.            Friend flags As MSLLHOOKSTRUCTFlags
  258.  
  259.            ''' <summary>
  260.            ''' The time stamp for this message.
  261.            ''' </summary>
  262.            Friend time As UInteger
  263.  
  264.            ''' <summary>
  265.            ''' Additional information associated with the message.
  266.            ''' </summary>
  267.            Friend dwExtraInfo As IntPtr
  268.  
  269.        End Structure
  270.  
  271. #End Region
  272.  
  273. #Region " Delegates "
  274.  
  275.        ''' <summary>
  276.        ''' Delegate LowLevelMouseProc
  277.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  278.        ''' </summary>
  279.        ''' <returns>
  280.        ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  281.        ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  282.        ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  283.        ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  284.        ''' and may behave incorrectly as a result.
  285.        ''' If the hook procedure processed the message,
  286.        ''' 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.
  287.        ''' </returns>
  288.        Friend Delegate Function LowLevelMouseProcDelegate(
  289.                ByVal nCode As IntPtr,
  290.                ByVal wParam As IntPtr,
  291.                ByVal lParam As IntPtr
  292.        ) As Integer
  293.  
  294. #End Region
  295.  
  296. #Region " Hidden Methods "
  297.  
  298.        ''' <summary>
  299.        ''' Determines whether the specified System.Object instances are considered equal.
  300.        ''' </summary>
  301.        <EditorBrowsable(EditorBrowsableState.Never)>
  302.        Public Shadows Sub Equals()
  303.        End Sub
  304.  
  305.        ''' <summary>
  306.        ''' Determines whether the specified System.Object instances are the same instance.
  307.        ''' </summary>
  308.        <EditorBrowsable(EditorBrowsableState.Never)>
  309.        Private Shadows Sub ReferenceEquals()
  310.        End Sub
  311.  
  312. #End Region
  313.  
  314.    End Class
  315.  
  316. #End Region
  317.  
  318. #Region " Objects "
  319.  
  320.    ''' <summary>
  321.    ''' Handle to the hook procedure.
  322.    ''' </summary>
  323.    Private MouseHook As IntPtr
  324.  
  325.    ''' <summary>
  326.    ''' The mouse hook delegate.
  327.    ''' </summary>
  328.    Private MouseHookDelegate As NativeMethods.LowLevelMouseProcDelegate
  329.  
  330. #End Region
  331.  
  332. #Region " Properties "
  333.  
  334.    ''' <summary>
  335.    ''' ** ONLY FOR TESTING PURPOSES **
  336.    ''' Gets or sets a value indicating whether to suppress the last MouseUp event of
  337.    ''' the specified clicked button when a double-click fires.
  338.    '''
  339.    ''' If this value is set to <c>true</c>, the application will send the events in this order for a Double-Click:
  340.    ''' MouseDown, MouseUp, MouseDown, MouseDoubleClick
  341.    '''
  342.    ''' If this value is set to <c>false</c>, the application will send the events in this order for a Double-Click:
  343.    ''' MouseDown, MouseUp, MouseDown, MouseUp, MouseDoubleClick
  344.    '''
  345.    ''' </summary>
  346.    ''' <value><c>true</c> if MouseUp event is suppressed; otherwise <c>false</c>.</value>
  347.    Friend Property SuppressMouseUpEventWhenDoubleClick As Boolean = False
  348.  
  349. #End Region
  350.  
  351. #Region " Enumerations "
  352.  
  353.    ''' <summary>
  354.    ''' Indicates a Windows Message related to a mouse events.
  355.    ''' For more info see here:
  356.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877%28v=vs.85%29.aspx
  357.    ''' </summary>
  358.    Private Enum MouseMessages As UInteger
  359.  
  360.        ''' <summary>
  361.        ''' Posted to a window when the cursor moves.
  362.        ''' If the mouse is not captured, the message is posted to the window that contains the cursor.
  363.        ''' Otherwise, the message is posted to the window that has captured the mouse
  364.        ''' </summary>
  365.        WM_MOUSEMOVE = &H200UI
  366.  
  367.        ''' <summary>
  368.        ''' Posted when the user presses the left mouse button while the cursor is in the client area of a window.
  369.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  370.        ''' Otherwise, the message is posted to the window that has captured the mouse
  371.        ''' </summary>
  372.        WM_LBUTTONDOWN = &H201UI
  373.  
  374.        ''' <summary>
  375.        ''' Posted when the user releases the left mouse button while the cursor is in the client area of a window.
  376.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  377.        ''' Otherwise, the message is posted to the window that has captured the mouse
  378.        ''' </summary>
  379.        WM_LBUTTONUP = &H202UI
  380.  
  381.        ''' <summary>
  382.        ''' Posted when the user presses the right mouse button while the cursor is in the client area of a window.
  383.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  384.        ''' Otherwise, the message is posted to the window that has captured the mouse
  385.        ''' </summary>
  386.        WM_RBUTTONDOWN = &H204UI
  387.  
  388.        ''' <summary>
  389.        ''' Posted when the user releases the right mouse button while the cursor is in the client area of a window.
  390.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  391.        ''' Otherwise, the message is posted to the window that has captured the mouse
  392.        ''' </summary>
  393.        WM_RBUTTONUP = &H205UI
  394.  
  395.        ''' <summary>
  396.        ''' Posted when the user presses the middle mouse button while the cursor is in the client area of a window.
  397.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  398.        ''' Otherwise, the message is posted to the window that has captured the mouse
  399.        ''' </summary>
  400.        WM_MBUTTONDOWN = &H207UI
  401.  
  402.        ''' <summary>
  403.        ''' Posted when the user releases the middle mouse button while the cursor is in the client area of a window.
  404.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  405.        ''' Otherwise, the message is posted to the window that has captured the mouse
  406.        ''' </summary>
  407.        WM_MBUTTONUP = &H208UI
  408.  
  409.        ''' <summary>
  410.        ''' Sent to the active window when the mouse's horizontal scroll wheel is tilted or rotated.
  411.        ''' The DefWindowProc function propagates the message to the window's parent.
  412.        ''' There should be no internal forwarding of the message,
  413.        ''' since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
  414.        ''' </summary>
  415.        WM_MOUSEWHEEL = &H20AUI
  416.  
  417.    End Enum
  418.  
  419.    ''' <summary>
  420.    ''' Indicates the whell direction of the mouse.
  421.    ''' </summary>
  422.    Public Enum WheelDirection As Integer
  423.  
  424.        ''' <summary>
  425.        ''' The wheel is moved up.
  426.        ''' </summary>
  427.        WheelUp = 1
  428.  
  429.        ''' <summary>
  430.        ''' The wheel is moved down.
  431.        ''' </summary>
  432.        WheelDown = 2
  433.  
  434.    End Enum
  435.  
  436. #End Region
  437.  
  438. #Region " Events "
  439.  
  440.    ''' <summary>
  441.    ''' Occurs when the mouse moves.
  442.    ''' </summary>
  443.    Friend Event MouseMove(ByVal sender As Object,
  444.                           ByVal MouseLocation As Point)
  445.  
  446.    ''' <summary>
  447.    ''' Occurs when the mouse left button is pressed.
  448.    ''' </summary>
  449.    Friend Event MouseLeftDown(ByVal sender As Object,
  450.                               ByVal MouseLocation As Point)
  451.  
  452.    ''' <summary>
  453.    ''' Occurs when the mouse left button is released.
  454.    ''' </summary>
  455.    Friend Event MouseLeftUp(ByVal sender As Object,
  456.                             ByVal MouseLocation As Point)
  457.  
  458.    ''' <summary>
  459.    ''' Occurs when the mouse left button performs a double-click.
  460.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  461.    ''' </summary>
  462.    Friend Event MouseLeftDoubleClick(ByVal sender As Object,
  463.                                      ByVal MouseLocation As Point)
  464.  
  465.    ''' <summary>
  466.    ''' Occurs when the mouse right button is pressed.
  467.    ''' </summary>
  468.    Friend Event MouseRightDown(ByVal sender As Object,
  469.                                ByVal MouseLocation As Point)
  470.  
  471.    ''' <summary>
  472.    ''' Occurs when the mouse right button is released.
  473.    ''' </summary>
  474.    Friend Event MouseRightUp(ByVal sender As Object,
  475.                              ByVal MouseLocation As Point)
  476.  
  477.    ''' <summary>
  478.    ''' Occurs when the mouse right button performs a double-click.
  479.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  480.    ''' </summary>
  481.    Friend Event MouseRightDoubleClick(ByVal sender As Object,
  482.                                       ByVal MouseLocation As Point)
  483.  
  484.    ''' <summary>
  485.    ''' Occurs when the mouse middle button is pressed.
  486.    ''' </summary>
  487.    Friend Event MouseMiddleDown(ByVal sender As Object,
  488.                                 ByVal MouseLocation As Point)
  489.  
  490.    ''' <summary>
  491.    ''' Occurs when the mouse middle button is released.
  492.    ''' </summary>
  493.    Friend Event MouseMiddleUp(ByVal sender As Object,
  494.                               ByVal MouseLocation As Point)
  495.  
  496.    ''' <summary>
  497.    ''' Occurs when the mouse middle button performs a double-click.
  498.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  499.    ''' </summary>
  500.    Friend Event MouseMiddleDoubleClick(ByVal sender As Object,
  501.                                        ByVal MouseLocation As Point)
  502.  
  503.    ''' <summary>
  504.    ''' Occurs when the mouse wheel is moved up or down.
  505.    ''' </summary>
  506.    Friend Event MouseWheel(ByVal sender As Object,
  507.                            ByVal MouseLocation As Point,
  508.                            ByVal WheelDirection As WheelDirection)
  509.  
  510. #End Region
  511.  
  512. #Region " Constructors "
  513.  
  514.    ''' <summary>
  515.    ''' Prevents a default instance of the <see cref="MouseHook"/> class from being created.
  516.    ''' </summary>
  517.    Private Sub New()
  518.    End Sub
  519.  
  520.    ''' <summary>
  521.    ''' Initializes a new instance of the <see cref="MouseHook"/> class.
  522.    ''' </summary>
  523.    ''' <param name="Install">
  524.    ''' If set to <c>true</c>, the Hook starts initialized for this <see cref="MouseHook"/> instance.
  525.    ''' </param>
  526.    Friend Sub New(Optional ByVal Install As Boolean = False)
  527.  
  528.        If Install Then
  529.            Me.Install()
  530.        End If
  531.  
  532.    End Sub
  533.  
  534. #End Region
  535.  
  536. #Region " Public Methods "
  537.  
  538.    ''' <summary>
  539.    ''' Installs the Mouse Hook, then start processing messages to fire events.
  540.    ''' </summary>
  541.    Friend Sub Install()
  542.  
  543.        Me.MouseHookDelegate = New NativeMethods.LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)
  544.  
  545.        Try
  546.            Me.MouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.HookType.WH_MOUSE_LL,
  547.                                                          Me.MouseHookDelegate,
  548.                                                          Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
  549.  
  550.        Catch ex As Exception
  551.            Throw
  552.  
  553.        End Try
  554.  
  555.    End Sub
  556.  
  557.    ''' <summary>
  558.    ''' Uninstalls the Mouse Hook and free all resources, then stop processing messages to fire events.
  559.    ''' </summary>
  560.    Friend Sub Uninstall()
  561.  
  562.        Me.Finalize()
  563.  
  564.    End Sub
  565.  
  566. #End Region
  567.  
  568. #Region " Private Methods "
  569.  
  570.    ''' <summary>
  571.    ''' Processes the mouse windows messages and raises it's corresponding events.
  572.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  573.    ''' </summary>
  574.    ''' <param name="nCode">
  575.    ''' A code the hook procedure uses to determine how to process the message.
  576.    ''' If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function
  577.    ''' without further processing and should return the value returned by CallNextHookEx.
  578.    ''' </param>
  579.    ''' <param name="wParam">The identifier of the mouse message.</param>
  580.    ''' <param name="lParam"> A pointer to an <see cref="NativeMethods.MSLLHOOKSTRUCT"/> structure.</param>
  581.    ''' <returns>
  582.    ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  583.    ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  584.    ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  585.    ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  586.    ''' and may behave incorrectly as a result.
  587.    ''' If the hook procedure processed the message,
  588.    ''' it may return a nonzero value to prevent the system from passing the
  589.    ''' message to the rest of the hook chain or the target window procedure.
  590.    ''' </returns>
  591.    Private Function LowLevelMouseProc(ByVal nCode As Integer,
  592.                                       ByVal wParam As MouseMessages,
  593.                                       ByVal lParam As IntPtr) As Integer
  594.  
  595.        Static LeftClickTime As Integer = 0I ' Determines a left button double-click.
  596.        Static RightClickTime As Integer = 0I ' Determines a right button double-click.
  597.        Static MiddleClickTime As Integer = 0I ' Determines a middle button double-click.
  598.  
  599.        If nCode = 0I Then
  600.  
  601.            Dim x As Integer
  602.            Dim y As Integer
  603.  
  604.            Dim MouseStruct As NativeMethods.MSLLHOOKSTRUCT
  605.            MouseStruct = CType(Marshal.PtrToStructure(lParam, MouseStruct.GetType()),
  606.                                NativeMethods.MSLLHOOKSTRUCT)
  607.  
  608.            ' Fix X coordinate.
  609.            Select Case MouseStruct.pt.X
  610.  
  611.                Case Is < 0I
  612.                    x = 0I
  613.  
  614.                Case Is > SystemInformation.VirtualScreen.Width
  615.                    x = SystemInformation.VirtualScreen.Width
  616.  
  617.                Case Else
  618.                    x = MouseStruct.pt.X
  619.  
  620.            End Select
  621.  
  622.            ' Fix Y coordinate.
  623.            Select Case MouseStruct.pt.Y
  624.  
  625.                Case Is > SystemInformation.VirtualScreen.Height
  626.                    y = SystemInformation.VirtualScreen.Height
  627.  
  628.                Case Is < 0I
  629.                    y = 0I
  630.  
  631.                Case Else
  632.                    y = MouseStruct.pt.Y
  633.  
  634.            End Select
  635.  
  636.            Select Case wParam
  637.  
  638.                Case MouseMessages.WM_MOUSEMOVE
  639.                    RaiseEvent MouseMove(Me, New Point(x, y))
  640.  
  641.                Case MouseMessages.WM_LBUTTONDOWN
  642.                    RaiseEvent MouseLeftDown(Me, New Point(x, y))
  643.  
  644.                Case MouseMessages.WM_LBUTTONUP
  645.                    If LeftClickTime <> 0 Then
  646.                        LeftClickTime = Environment.TickCount() - LeftClickTime
  647.                    End If
  648.  
  649.                    If (LeftClickTime <> 0) AndAlso (LeftClickTime < NativeMethods.GetDoubleClickTime()) Then
  650.                        LeftClickTime = 0
  651.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  652.                            RaiseEvent MouseLeftUp(Me, New Point(x, y))
  653.                        End If
  654.                        RaiseEvent MouseLeftDoubleClick(Me, New Point(x, y))
  655.  
  656.                    Else
  657.                        LeftClickTime = Environment.TickCount()
  658.                        RaiseEvent MouseLeftUp(Me, New Point(x, y))
  659.  
  660.                    End If
  661.  
  662.                Case MouseMessages.WM_RBUTTONDOWN
  663.                    RaiseEvent MouseRightDown(Me, New Point(x, y))
  664.  
  665.                Case MouseMessages.WM_RBUTTONUP
  666.                    If RightClickTime <> 0 Then
  667.                        RightClickTime = Environment.TickCount() - RightClickTime
  668.                    End If
  669.  
  670.                    If (RightClickTime <> 0) AndAlso (RightClickTime < NativeMethods.GetDoubleClickTime()) Then
  671.                        RightClickTime = 0
  672.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  673.                            RaiseEvent MouseRightUp(Me, New Point(x, y))
  674.                        End If
  675.                        RaiseEvent MouseRightDoubleClick(Me, New Point(x, y))
  676.  
  677.                    Else
  678.                        RightClickTime = Environment.TickCount()
  679.                        RaiseEvent MouseRightUp(Me, New Point(x, y))
  680.  
  681.                    End If
  682.  
  683.                Case MouseMessages.WM_MBUTTONDOWN
  684.                    RaiseEvent MouseMiddleDown(Me, New Point(x, y))
  685.  
  686.                Case MouseMessages.WM_MBUTTONUP
  687.                    If MiddleClickTime <> 0 Then
  688.                        MiddleClickTime = Environment.TickCount() - MiddleClickTime
  689.                    End If
  690.  
  691.                    If (MiddleClickTime <> 0) AndAlso (MiddleClickTime < NativeMethods.GetDoubleClickTime()) Then
  692.                        MiddleClickTime = 0
  693.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  694.                            RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  695.                        End If
  696.                        RaiseEvent MouseMiddleDoubleClick(Me, New Point(x, y))
  697.  
  698.                    Else
  699.                        MiddleClickTime = Environment.TickCount()
  700.                        RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  701.  
  702.                    End If
  703.  
  704.                Case MouseMessages.WM_MOUSEWHEEL
  705.                    RaiseEvent MouseWheel(Me, New Point(x, y), If(MouseStruct.mouseData < 0,
  706.                                                                 WheelDirection.WheelDown,
  707.                                                                 WheelDirection.WheelUp))
  708.  
  709.                Case Else
  710.                    Exit Select ' Do Nothing
  711.  
  712.            End Select
  713.  
  714.            Return 0
  715.  
  716.        ElseIf nCode < 0I Then
  717.            Return NativeMethods.CallNextHookEx(MouseHook, nCode, wParam, lParam)
  718.  
  719.        Else ' nCode > 0
  720.            Return -1I
  721.  
  722.        End If
  723.  
  724.    End Function
  725.  
  726. #End Region
  727.  
  728. #Region " Hidden Methods "
  729.  
  730.    ''' <summary>
  731.    ''' Serves as a hash function for a particular type.
  732.    ''' </summary>
  733.    <EditorBrowsable(EditorBrowsableState.Never)>
  734.    Public Shadows Sub GetHashCode()
  735.    End Sub
  736.  
  737.    ''' <summary>
  738.    ''' Gets the System.Type of the current instance.
  739.    ''' </summary>
  740.    ''' <returns>The exact runtime type of the current instance.</returns>
  741.    <EditorBrowsable(EditorBrowsableState.Never)>
  742.    Public Shadows Function [GetType]()
  743.        Return Me.GetType
  744.    End Function
  745.  
  746.    ''' <summary>
  747.    ''' Determines whether the specified System.Object instances are considered equal.
  748.    ''' </summary>
  749.    <EditorBrowsable(EditorBrowsableState.Never)>
  750.    Public Shadows Sub Equals()
  751.    End Sub
  752.  
  753.    ''' <summary>
  754.    ''' Determines whether the specified System.Object instances are the same instance.
  755.    ''' </summary>
  756.    <EditorBrowsable(EditorBrowsableState.Never)>
  757.    Private Shadows Sub ReferenceEquals()
  758.    End Sub
  759.  
  760.    ''' <summary>
  761.    ''' Returns a String that represents the current object.
  762.    ''' </summary>
  763.    <EditorBrowsable(EditorBrowsableState.Never)>
  764.    Public Shadows Sub ToString()
  765.    End Sub
  766.  
  767. #End Region
  768.  
  769. #Region "IDisposable Support"
  770.  
  771.    ''' <summary>
  772.    ''' Flag to detect redundant calls at <see cref="Dispose"/> method.
  773.    ''' </summary>
  774.    Private disposedValue As Boolean
  775.  
  776.    ''' <summary>
  777.    ''' Releases unmanaged and optionally managed resources.
  778.    ''' </summary>
  779.    ''' <param name="disposing">
  780.    ''' <c>true</c> to release both managed and unmanaged resources;
  781.    ''' <c>false</c> to release only unmanaged resources.
  782.    ''' </param>
  783.    Protected Sub Dispose(ByVal disposing As Boolean)
  784.  
  785.        If Not Me.disposedValue Then
  786.  
  787.            If disposing Then ' Dispose managed state (managed objects).
  788.  
  789.            Else ' Free unmanaged resources (unmanaged objects).
  790.                NativeMethods.UnhookWindowsHookEx(Me.MouseHook)
  791.  
  792.            End If
  793.  
  794.        End If
  795.  
  796.        Me.disposedValue = True
  797.  
  798.    End Sub
  799.  
  800.    ''' <summary>
  801.    ''' Allows an object to try to free resources
  802.    ''' and perform other cleanup operations before it is reclaimed by garbage collection.
  803.    ''' </summary>
  804.    Protected Overrides Sub Finalize()
  805.  
  806.        ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  807.  
  808.        Me.Dispose(disposing:=False)
  809.        MyBase.Finalize()
  810.  
  811.    End Sub
  812.  
  813.    ''' <summary>
  814.    ''' Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  815.    ''' </summary>
  816.    Private Sub Dispose() Implements IDisposable.Dispose
  817.  
  818.        ' Do not change this code. Put cleanup code in method: Dispose(ByVal disposing As Boolean)
  819.  
  820.        Me.Dispose(disposing:=True)
  821.        GC.SuppressFinalize(obj:=Me)
  822.  
  823.    End Sub
  824.  
  825. #End Region
  826.  
  827. End Class
  828.  
  829. #End Region
En línea


Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.700



Ver Perfil
Re: [APORTE] Ejemplo de un LL-Hook para el Mouse.
« Respuesta #7 en: 26 Septiembre 2014, 16:41 pm »

Otro repaso más a la Class, he añadido una funcionalidad experimental para restringir los eventos que envia la instancia del hook a los límites de un Rectangle (el Rectangle de la pantalla especificada, por ejemplo), lo he testeado en una pantalla normal, así como en Dual-Screen e invirtiendo el orden de la pantalla principal, todo parece haber ido sin irregularidades :).

Código
  1. ' ***********************************************************************
  2. ' Author           : Elektro
  3. ' Last Modified On : 09-26-2014
  4. ' ***********************************************************************
  5. ' <copyright file="MouseHook.vb" company="Elektro Studios">
  6. '     Copyright (c) Elektro Studios. All rights reserved.
  7. ' </copyright>
  8. ' ***********************************************************************
  9.  
  10. #Region " Instructions "
  11.  
  12. ' Go to page:
  13. ' Project > Properties > Debug
  14. '
  15. ' Then uncheck the option:
  16. ' "Enable the Visual Studio Hosting Process"
  17.  
  18. #End Region
  19.  
  20. #Region " Usage Examples "
  21.  
  22. #End Region
  23.  
  24. #Region " Imports "
  25.  
  26. Imports System.ComponentModel
  27. Imports System.Reflection
  28. Imports System.Runtime.InteropServices
  29.  
  30. #End Region
  31.  
  32. #Region " MouseHook "
  33.  
  34. ''' <summary>
  35. ''' A low level mouse hook that processes mouse input events.
  36. ''' </summary>
  37. Friend NotInheritable Class MouseHook : Implements IDisposable
  38.  
  39. #Region " P/Invoke "
  40.  
  41.    ''' <summary>
  42.    ''' Platform Invocation methods (P/Invoke), access unmanaged code.
  43.    ''' This class does not suppress stack walks for unmanaged code permission.
  44.    ''' <see cref="System.Security.SuppressUnmanagedCodeSecurityAttribute"/>  must not be applied to this class.
  45.    ''' This class is for methods that can be used anywhere because a stack walk will be performed.
  46.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/ms182161.aspx
  47.    ''' </summary>
  48.    Protected NotInheritable Class NativeMethods
  49.  
  50. #Region " Methods "
  51.  
  52.        ''' <summary>
  53.        ''' Passes the hook information to the next hook procedure in the current hook chain.
  54.        ''' A hook procedure can call this function either before or after processing the hook information.
  55.        ''' For more info see here:
  56.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
  57.        ''' </summary>
  58.        ''' <param name="idHook">
  59.        ''' This parameter is ignored.
  60.        ''' </param>
  61.        ''' <param name="nCode">
  62.        ''' The hook code passed to the current hook procedure.
  63.        ''' The next hook procedure uses this code to determine how to process the hook information.
  64.        ''' </param>
  65.        ''' <param name="wParam">
  66.        ''' The wParam value passed to the current hook procedure.
  67.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  68.        ''' </param>
  69.        ''' <param name="lParam">
  70.        ''' The lParam value passed to the current hook procedure.
  71.        ''' The meaning of this parameter depends on the type of hook associated with the current hook chain.
  72.        ''' </param>
  73.        ''' <returns>
  74.        ''' This value is returned by the next hook procedure in the chain.
  75.        ''' The current hook procedure must also return this value.
  76.        ''' The meaning of the return value depends on the hook type.
  77.        ''' For more information, see the descriptions of the individual hook procedures.
  78.        ''' </returns>
  79.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  80.        Friend Shared Function CallNextHookEx(
  81.               ByVal idHook As IntPtr,
  82.               ByVal nCode As Integer,
  83.               ByVal wParam As IntPtr,
  84.               ByVal lParam As IntPtr
  85.        ) As IntPtr
  86.        End Function
  87.  
  88.        ''' <summary>
  89.        ''' Installs an application-defined hook procedure into a hook chain.
  90.        ''' You would install a hook procedure to monitor the system for certain types of events.
  91.        ''' These events are associated either with a specific thread
  92.        ''' or with all threads in the same desktop as the calling thread.
  93.        ''' For more info see here:
  94.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  95.        ''' </summary>
  96.        ''' <param name="idHook">
  97.        ''' The type of hook procedure to be installed.
  98.        ''' </param>
  99.        ''' <param name="lpfn">
  100.        ''' A pointer to the hook procedure.
  101.        ''' If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process,
  102.        ''' the lpfn parameter must point to a hook procedure in a DLL.
  103.        ''' Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
  104.        ''' </param>
  105.        ''' <param name="hInstance">
  106.        ''' A handle to the DLL containing the hook procedure pointed to by the lpfn parameter.
  107.        ''' The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by
  108.        ''' the current process and if the hook procedure is within the code associated with the current process.
  109.        ''' </param>
  110.        ''' <param name="threadId">
  111.        ''' The identifier of the thread with which the hook procedure is to be associated.
  112.        ''' For desktop apps, if this parameter is zero, the hook procedure is associated
  113.        ''' with all existing threads running in the same desktop as the calling thread.
  114.        ''' </param>
  115.        ''' <returns>
  116.        ''' If the function succeeds, the return value is the handle to the hook procedure.
  117.        ''' If the function fails, the return value is NULL.
  118.        ''' </returns>
  119.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  120.        Friend Shared Function SetWindowsHookEx(
  121.               ByVal idHook As HookType,
  122.               ByVal lpfn As LowLevelMouseProcDelegate,
  123.               ByVal hInstance As IntPtr,
  124.               ByVal threadId As UInteger
  125.        ) As IntPtr
  126.        End Function
  127.  
  128.        ''' <summary>
  129.        ''' Removes a hook procedure installed in a hook chain by the 'SetWindowsHookEx' function.
  130.        ''' For more info see here:
  131.        ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
  132.        ''' </summary>
  133.        ''' <param name="idHook">
  134.        ''' A handle to the hook to be removed.
  135.        ''' This parameter is a hook handle obtained by a previous call to SetWindowsHookEx.
  136.        ''' </param>
  137.        ''' <returns>
  138.        ''' If the function succeeds, the return value is nonzero.
  139.        ''' If the function fails, the return value is zero.
  140.        ''' </returns>
  141.        <DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Auto)>
  142.        Friend Shared Function UnhookWindowsHookEx(
  143.               ByVal idHook As IntPtr
  144.        ) As Boolean
  145.        End Function
  146.  
  147.        ''' <summary>
  148.        ''' Retrieves the current double-click time for the mouse.
  149.        ''' A double-click is a series of two clicks of the mouse button,
  150.        ''' the second occurring within a specified time after the first.
  151.        ''' The double-click time is the maximum number of milliseconds that may occur
  152.        ''' between the first and second click of a double-click.
  153.        ''' The maximum double-click time is 5000 milliseconds.
  154.        ''' </summary>
  155.        ''' <returns>
  156.        ''' The return value specifies the current double-click time, in milliseconds.
  157.        ''' The maximum return value is 5000 milliseconds.
  158.        ''' </returns>
  159.        <DllImport("user32.dll", CharSet:=CharSet.Auto)>
  160.        Friend Shared Function GetDoubleClickTime() As Integer
  161.        End Function
  162.  
  163. #End Region
  164.  
  165. #Region " Enumerations "
  166.  
  167.        ''' <summary>
  168.        ''' Indicates a type of Hook procedure to be installed.
  169.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
  170.        ''' </summary>
  171.        <Description("Enum used in 'idHook' parameter of 'SetWindowsHookEx' function.")>
  172.        Friend Enum HookType As UInteger
  173.  
  174.            ' **************************************
  175.            ' This enumeration is partially defined.
  176.            ' **************************************
  177.  
  178.            ''' <summary>
  179.            ''' Installs a hook procedure that monitors low-level mouse input events.
  180.            ''' For more information, see the LowLevelMouseProc hook procedure.
  181.            ''' </summary>
  182.            WH_MOUSE_LL = 14UI
  183.  
  184.        End Enum
  185.  
  186.        ''' <summary>
  187.        ''' The event-injected flags.
  188.        ''' An application can use the following values to test the flags.
  189.        ''' Testing LLMHF_INJECTED (bit 0) will tell you whether the event was injected.
  190.        ''' If it was, then testing LLMHF_LOWER_IL_INJECTED (bit 1) will tell you
  191.        ''' whether or not the event was injected from a process running at lower integrity level.
  192.        ''' </summary>
  193.        <Flags()>
  194.        <Description("Enum used in 'flags' parameter of 'MSLLHOOKSTRUCT' structure.")>
  195.        Public Enum MSLLHOOKSTRUCTFlags As Integer
  196.  
  197.            ''' <summary>
  198.            ''' Test the event-injected (from any process) flag.
  199.            ''' </summary>
  200.            LLMHF_INJECTED = 1I
  201.  
  202.            ''' <summary>
  203.            ''' Test the event-injected (from a process running at lower integrity level) flag.
  204.            ''' </summary>
  205.            LLMHF_LOWER_IL_INJECTED = 2I
  206.  
  207.        End Enum
  208.  
  209. #End Region
  210.  
  211. #Region " Structures "
  212.  
  213.        ''' <summary>
  214.        ''' The POINT structure defines the x- and y- coordinates of a point.
  215.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx
  216.        ''' </summary>
  217.        <Description("Structure used in 'pt' parameter of 'MSLLHOOKSTRUCT' structure.")>
  218.        <StructLayout(LayoutKind.Sequential)>
  219.        Friend Structure POINT
  220.  
  221.            ''' <summary>
  222.            ''' The x-coordinate of the point.
  223.            ''' </summary>
  224.            Friend X As Integer
  225.  
  226.            ''' <summary>
  227.            ''' The y-coordinate of the point.
  228.            ''' </summary>
  229.            Friend Y As Integer
  230.  
  231.        End Structure
  232.  
  233.        ''' <summary>
  234.        ''' Contains information about a low-level mouse input event.
  235.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644970%28v=vs.85%29.aspx
  236.        ''' </summary>
  237.        <Description("Structure used in 'lParam' parameter of 'CallNextHookEx' function.")>
  238.        Friend Structure MSLLHOOKSTRUCT
  239.  
  240.            ''' <summary>
  241.            ''' The ptThe x- and y-coordinates of the cursor, in screen coordinates.
  242.            ''' </summary>
  243.            Friend pt As NativeMethods.POINT
  244.  
  245.            ''' <summary>
  246.            ''' If the message is 'WM_MOUSEWHEEL', the high-order word of this member is the wheel delta.
  247.            ''' The low-order word is reserved.
  248.            ''' A positive value indicates that the wheel was rotated forward, away from the user;
  249.            ''' a negative value indicates that the wheel was rotated backward, toward the user.
  250.            ''' One wheel click is defined as 'WHEEL_DELTA', which is '120'.
  251.            ''' </summary>
  252.            Friend mouseData As Integer
  253.  
  254.            ''' <summary>
  255.            ''' The event-injected flag.
  256.            ''' </summary>
  257.            Friend flags As MSLLHOOKSTRUCTFlags
  258.  
  259.            ''' <summary>
  260.            ''' The time stamp for this message.
  261.            ''' </summary>
  262.            Friend time As UInteger
  263.  
  264.            ''' <summary>
  265.            ''' Additional information associated with the message.
  266.            ''' </summary>
  267.            Friend dwExtraInfo As IntPtr
  268.  
  269.        End Structure
  270.  
  271. #End Region
  272.  
  273. #Region " Delegates "
  274.  
  275.        ''' <summary>
  276.        ''' Delegate LowLevelMouseProc
  277.        ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  278.        ''' </summary>
  279.        ''' <returns>
  280.        ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  281.        ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  282.        ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  283.        ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  284.        ''' and may behave incorrectly as a result.
  285.        ''' If the hook procedure processed the message,
  286.        ''' 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.
  287.        ''' </returns>
  288.        Friend Delegate Function LowLevelMouseProcDelegate(
  289.                ByVal nCode As IntPtr,
  290.                ByVal wParam As IntPtr,
  291.                ByVal lParam As IntPtr
  292.        ) As Integer
  293.  
  294. #End Region
  295.  
  296. #Region " Hidden Methods "
  297.  
  298.        ''' <summary>
  299.        ''' Determines whether the specified System.Object instances are considered equal.
  300.        ''' </summary>
  301.        <EditorBrowsable(EditorBrowsableState.Never)>
  302.        Public Shadows Sub Equals()
  303.        End Sub
  304.  
  305.        ''' <summary>
  306.        ''' Determines whether the specified System.Object instances are the same instance.
  307.        ''' </summary>
  308.        <EditorBrowsable(EditorBrowsableState.Never)>
  309.        Private Shadows Sub ReferenceEquals()
  310.        End Sub
  311.  
  312. #End Region
  313.  
  314.    End Class
  315.  
  316. #End Region
  317.  
  318. #Region " Objects "
  319.  
  320.    ''' <summary>
  321.    ''' Handle to the hook procedure.
  322.    ''' </summary>
  323.    Private MouseHook As IntPtr
  324.  
  325.    ''' <summary>
  326.    ''' The mouse hook delegate.
  327.    ''' </summary>
  328.    Private MouseHookDelegate As NativeMethods.LowLevelMouseProcDelegate
  329.  
  330. #End Region
  331.  
  332. #Region " Properties "
  333.  
  334.    ''' <summary>
  335.    ''' ** ONLY FOR TESTING PURPOSES **
  336.    ''' Gets or sets a value indicating whether to suppress the last MouseUp event of
  337.    ''' the specified clicked button when a double-click fires.
  338.    '''
  339.    ''' If this value is set to <c>true</c>, the application will send the events in this order for a Double-Click:
  340.    ''' MouseDown, MouseUp, MouseDown, MouseDoubleClick
  341.    '''
  342.    ''' If this value is set to <c>false</c>, the application will send the events in this order for a Double-Click:
  343.    ''' MouseDown, MouseUp, MouseDown, MouseUp, MouseDoubleClick
  344.    '''
  345.    ''' </summary>
  346.    ''' <value><c>true</c> if MouseUp event is suppressed; otherwise <c>false</c>.</value>
  347.    Friend Property SuppressMouseUpEventWhenDoubleClick As Boolean = False
  348.  
  349.    ''' <summary>
  350.    ''' ** ONLY FOR TESTING PURPOSES **
  351.    ''' Gets or sets the screen's working area.
  352.    ''' The events fired by <see cref="MouseHook"/> are restricted to the bounds of the specified rectangle.
  353.    ''' </summary>
  354.    ''' <value>The screen's working area.</value>
  355.    Friend Property WorkingArea As Rectangle
  356.        Get
  357.            Return Me._Workingarea
  358.        End Get
  359.        Set(ByVal value As Rectangle)
  360.            Me._Workingarea = value
  361.        End Set
  362.    End Property
  363.  
  364.    ''' <summary>
  365.    ''' The screen's working area
  366.    ''' </summary>
  367.    Private _Workingarea As Rectangle = SystemInformation.VirtualScreen
  368.  
  369. #End Region
  370.  
  371. #Region " Enumerations "
  372.  
  373.    ''' <summary>
  374.    ''' Indicates a Windows Message related to a mouse events.
  375.    ''' For more info see here:
  376.    ''' http://msdn.microsoft.com/en-us/library/windows/desktop/ff468877%28v=vs.85%29.aspx
  377.    ''' </summary>
  378.    Private Enum MouseMessages As UInteger
  379.  
  380.        ''' <summary>
  381.        ''' Posted to a window when the cursor moves.
  382.        ''' If the mouse is not captured, the message is posted to the window that contains the cursor.
  383.        ''' Otherwise, the message is posted to the window that has captured the mouse
  384.        ''' </summary>
  385.        WM_MOUSEMOVE = &H200UI
  386.  
  387.        ''' <summary>
  388.        ''' Posted when the user presses the left mouse button while the cursor is in the client area of a window.
  389.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  390.        ''' Otherwise, the message is posted to the window that has captured the mouse
  391.        ''' </summary>
  392.        WM_LBUTTONDOWN = &H201UI
  393.  
  394.        ''' <summary>
  395.        ''' Posted when the user releases the left mouse button while the cursor is in the client area of a window.
  396.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  397.        ''' Otherwise, the message is posted to the window that has captured the mouse
  398.        ''' </summary>
  399.        WM_LBUTTONUP = &H202UI
  400.  
  401.        ''' <summary>
  402.        ''' Posted when the user presses the right mouse button while the cursor is in the client area of a window.
  403.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  404.        ''' Otherwise, the message is posted to the window that has captured the mouse
  405.        ''' </summary>
  406.        WM_RBUTTONDOWN = &H204UI
  407.  
  408.        ''' <summary>
  409.        ''' Posted when the user releases the right mouse button while the cursor is in the client area of a window.
  410.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  411.        ''' Otherwise, the message is posted to the window that has captured the mouse
  412.        ''' </summary>
  413.        WM_RBUTTONUP = &H205UI
  414.  
  415.        ''' <summary>
  416.        ''' Posted when the user presses the middle mouse button while the cursor is in the client area of a window.
  417.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  418.        ''' Otherwise, the message is posted to the window that has captured the mouse
  419.        ''' </summary>
  420.        WM_MBUTTONDOWN = &H207UI
  421.  
  422.        ''' <summary>
  423.        ''' Posted when the user releases the middle mouse button while the cursor is in the client area of a window.
  424.        ''' If the mouse is not captured, the message is posted to the window beneath the cursor.
  425.        ''' Otherwise, the message is posted to the window that has captured the mouse
  426.        ''' </summary>
  427.        WM_MBUTTONUP = &H208UI
  428.  
  429.        ''' <summary>
  430.        ''' Sent to the active window when the mouse's horizontal scroll wheel is tilted or rotated.
  431.        ''' The DefWindowProc function propagates the message to the window's parent.
  432.        ''' There should be no internal forwarding of the message,
  433.        ''' since DefWindowProc propagates it up the parent chain until it finds a window that processes it.
  434.        ''' </summary>
  435.        WM_MOUSEWHEEL = &H20AUI
  436.  
  437.    End Enum
  438.  
  439.    ''' <summary>
  440.    ''' Indicates the whell direction of the mouse.
  441.    ''' </summary>
  442.    Public Enum WheelDirection As Integer
  443.  
  444.        ''' <summary>
  445.        ''' The wheel is moved up.
  446.        ''' </summary>
  447.        WheelUp = 1I
  448.  
  449.        ''' <summary>
  450.        ''' The wheel is moved down.
  451.        ''' </summary>
  452.        WheelDown = 2I
  453.  
  454.    End Enum
  455.  
  456. #End Region
  457.  
  458. #Region " Events "
  459.  
  460.    ''' <summary>
  461.    ''' Occurs when the mouse moves.
  462.    ''' </summary>
  463.    Friend Event MouseMove(ByVal sender As Object,
  464.                           ByVal MouseLocation As Point)
  465.  
  466.    ''' <summary>
  467.    ''' Occurs when the mouse left button is pressed.
  468.    ''' </summary>
  469.    Friend Event MouseLeftDown(ByVal sender As Object,
  470.                               ByVal MouseLocation As Point)
  471.  
  472.    ''' <summary>
  473.    ''' Occurs when the mouse left button is released.
  474.    ''' </summary>
  475.    Friend Event MouseLeftUp(ByVal sender As Object,
  476.                             ByVal MouseLocation As Point)
  477.  
  478.    ''' <summary>
  479.    ''' Occurs when the mouse left button performs a double-click.
  480.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  481.    ''' </summary>
  482.    Friend Event MouseLeftDoubleClick(ByVal sender As Object,
  483.                                      ByVal MouseLocation As Point)
  484.  
  485.    ''' <summary>
  486.    ''' Occurs when the mouse right button is pressed.
  487.    ''' </summary>
  488.    Friend Event MouseRightDown(ByVal sender As Object,
  489.                                ByVal MouseLocation As Point)
  490.  
  491.    ''' <summary>
  492.    ''' Occurs when the mouse right button is released.
  493.    ''' </summary>
  494.    Friend Event MouseRightUp(ByVal sender As Object,
  495.                              ByVal MouseLocation As Point)
  496.  
  497.    ''' <summary>
  498.    ''' Occurs when the mouse right button performs a double-click.
  499.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  500.    ''' </summary>
  501.    Friend Event MouseRightDoubleClick(ByVal sender As Object,
  502.                                       ByVal MouseLocation As Point)
  503.  
  504.    ''' <summary>
  505.    ''' Occurs when the mouse middle button is pressed.
  506.    ''' </summary>
  507.    Friend Event MouseMiddleDown(ByVal sender As Object,
  508.                                 ByVal MouseLocation As Point)
  509.  
  510.    ''' <summary>
  511.    ''' Occurs when the mouse middle button is released.
  512.    ''' </summary>
  513.    Friend Event MouseMiddleUp(ByVal sender As Object,
  514.                               ByVal MouseLocation As Point)
  515.  
  516.    ''' <summary>
  517.    ''' Occurs when the mouse middle button performs a double-click.
  518.    ''' A double click is considered as: (MouseLeftDown + MouseLeftUp) * 2
  519.    ''' </summary>
  520.    Friend Event MouseMiddleDoubleClick(ByVal sender As Object,
  521.                                        ByVal MouseLocation As Point)
  522.  
  523.    ''' <summary>
  524.    ''' Occurs when the mouse wheel is moved up or down.
  525.    ''' </summary>
  526.    Friend Event MouseWheel(ByVal sender As Object,
  527.                            ByVal MouseLocation As Point,
  528.                            ByVal WheelDirection As WheelDirection)
  529.  
  530. #End Region
  531.  
  532. #Region " Constructors "
  533.  
  534.    ''' <summary>
  535.    ''' Prevents a default instance of the <see cref="MouseHook"/> class from being created.
  536.    ''' </summary>
  537.    Private Sub New()
  538.    End Sub
  539.  
  540.    ''' <summary>
  541.    ''' Initializes a new instance of the <see cref="MouseHook"/> class.
  542.    ''' </summary>
  543.    ''' <param name="Install">
  544.    ''' If set to <c>true</c>, the Hook starts initialized for this <see cref="MouseHook"/> instance.
  545.    ''' </param>
  546.    Friend Sub New(Optional ByVal Install As Boolean = False)
  547.  
  548.        If Install Then
  549.            Me.Install()
  550.        End If
  551.  
  552.    End Sub
  553.  
  554. #End Region
  555.  
  556. #Region " Public Methods "
  557.  
  558.    ''' <summary>
  559.    ''' Installs the Mouse Hook, then start processing messages to fire events.
  560.    ''' </summary>
  561.    Friend Sub Install()
  562.  
  563.        Me.MouseHookDelegate = New NativeMethods.LowLevelMouseProcDelegate(AddressOf LowLevelMouseProc)
  564.  
  565.        Try
  566.            Me.MouseHook = NativeMethods.SetWindowsHookEx(NativeMethods.HookType.WH_MOUSE_LL,
  567.                                                          Me.MouseHookDelegate,
  568.                                                          Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
  569.  
  570.        Catch ex As Exception
  571.            Throw
  572.  
  573.        End Try
  574.  
  575.    End Sub
  576.  
  577.    ''' <summary>
  578.    ''' Uninstalls the Mouse Hook and free all resources, then stop processing messages to fire events.
  579.    ''' </summary>
  580.    Friend Sub Uninstall()
  581.  
  582.        Me.Finalize()
  583.  
  584.    End Sub
  585.  
  586. #End Region
  587.  
  588. #Region " Private Methods "
  589.  
  590.    ''' <summary>
  591.    ''' Processes the mouse windows messages and raises it's corresponding events.
  592.    ''' MSDN Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986%28v=vs.85%29.aspx
  593.    ''' </summary>
  594.    ''' <param name="nCode">
  595.    ''' A code the hook procedure uses to determine how to process the message.
  596.    ''' If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function
  597.    ''' without further processing and should return the value returned by CallNextHookEx.
  598.    ''' </param>
  599.    ''' <param name="wParam">The identifier of the mouse message.</param>
  600.    ''' <param name="lParam"> A pointer to an <see cref="NativeMethods.MSLLHOOKSTRUCT"/> structure.</param>
  601.    ''' <returns>
  602.    ''' If nCode is less than zero, the hook procedure must return the value returned by CallNextHookEx.
  603.    ''' If nCode is greater than or equal to zero, and the hook procedure did not process the message,
  604.    ''' it is highly recommended that you call CallNextHookEx and return the value it returns;
  605.    ''' otherwise, other applications that have installed WH_MOUSE_LL hooks will not receive hook notifications
  606.    ''' and may behave incorrectly as a result.
  607.    ''' If the hook procedure processed the message,
  608.    ''' it may return a nonzero value to prevent the system from passing the
  609.    ''' message to the rest of the hook chain or the target window procedure.
  610.    ''' </returns>
  611.    Private Function LowLevelMouseProc(ByVal nCode As Integer,
  612.                                       ByVal wParam As MouseMessages,
  613.                                       ByVal lParam As IntPtr) As Integer
  614.  
  615.        Static LeftClickTime As Integer = 0I ' Determines a left button double-click.
  616.        Static RightClickTime As Integer = 0I ' Determines a right button double-click.
  617.        Static MiddleClickTime As Integer = 0I ' Determines a middle button double-click.
  618.  
  619.        If nCode = 0I Then
  620.  
  621.            Dim x As Integer
  622.            Dim y As Integer
  623.  
  624.            Dim MouseStruct As NativeMethods.MSLLHOOKSTRUCT
  625.            MouseStruct = CType(Marshal.PtrToStructure(lParam, MouseStruct.GetType()),
  626.                                NativeMethods.MSLLHOOKSTRUCT)
  627.  
  628.            ' Fix X coordinate.
  629.            Select Case MouseStruct.pt.X
  630.  
  631.                Case Is <= 0I
  632.                    If MouseStruct.pt.X >= Me.WorkingArea.Location.X Then
  633.                        x = MouseStruct.pt.X
  634.  
  635.                    ElseIf MouseStruct.pt.X <= Me.WorkingArea.Location.X Then
  636.  
  637.                        If MouseStruct.pt.X <= (Me.WorkingArea.Location.X - Me.WorkingArea.Width) Then
  638.                            x = (Me.WorkingArea.Location.X - Me.WorkingArea.Width)
  639.                        Else
  640.                            x = MouseStruct.pt.X
  641.                        End If
  642.  
  643.                    End If
  644.  
  645.                Case Is >= Me.WorkingArea.Width
  646.                    x = Me.WorkingArea.Width
  647.  
  648.                Case Else
  649.                    x = MouseStruct.pt.X
  650.  
  651.            End Select
  652.  
  653.            ' Fix Y coordinate.
  654.            Select Case MouseStruct.pt.Y
  655.  
  656.                Case Is >= Me.WorkingArea.Height
  657.                    y = Me.WorkingArea.Height
  658.  
  659.                Case Is <= 0I
  660.                    y = 0I
  661.  
  662.                Case Else
  663.                    y = MouseStruct.pt.Y
  664.  
  665.            End Select
  666.  
  667.            If x <= Me.WorkingArea.Width _
  668.            AndAlso y < Me.WorkingArea.Height _
  669.            AndAlso MouseStruct.pt.X > Me.WorkingArea.Width Then
  670.  
  671.                Return 0
  672.  
  673.            ElseIf x <= Me.WorkingArea.Width _
  674.            AndAlso y < Me.WorkingArea.Height _
  675.            AndAlso MouseStruct.pt.X < Me.WorkingArea.X Then
  676.  
  677.                Return 0
  678.  
  679.            ElseIf x = Me.WorkingArea.Width _
  680.            AndAlso y < Me.WorkingArea.Height Then
  681.  
  682.                If Not Me.WorkingArea.Contains(x - 1, y) Then
  683.                    Return 0
  684.                End If
  685.  
  686.            ElseIf x < Me.WorkingArea.Width _
  687.            AndAlso y = Me.WorkingArea.Height Then
  688.  
  689.                If Not Me.WorkingArea.Contains(x, y - 1) Then
  690.                    Return 0
  691.                End If
  692.  
  693.            End If
  694.  
  695.            Select Case wParam
  696.  
  697.                Case MouseMessages.WM_MOUSEMOVE
  698.                    RaiseEvent MouseMove(Me, New Point(x, y))
  699.  
  700.                Case MouseMessages.WM_LBUTTONDOWN
  701.                    RaiseEvent MouseLeftDown(Me, New Point(x, y))
  702.  
  703.                Case MouseMessages.WM_LBUTTONUP
  704.                    If LeftClickTime <> 0 Then
  705.                        LeftClickTime = Environment.TickCount() - LeftClickTime
  706.                    End If
  707.  
  708.                    If (LeftClickTime <> 0I) AndAlso (LeftClickTime < NativeMethods.GetDoubleClickTime()) Then
  709.                        LeftClickTime = 0I
  710.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  711.                            RaiseEvent MouseLeftUp(Me, New Point(x, y))
  712.                        End If
  713.                        RaiseEvent MouseLeftDoubleClick(Me, New Point(x, y))
  714.  
  715.                    Else
  716.                        LeftClickTime = Environment.TickCount()
  717.                        RaiseEvent MouseLeftUp(Me, New Point(x, y))
  718.  
  719.                    End If
  720.  
  721.                Case MouseMessages.WM_RBUTTONDOWN
  722.                    RaiseEvent MouseRightDown(Me, New Point(x, y))
  723.  
  724.                Case MouseMessages.WM_RBUTTONUP
  725.                    If RightClickTime <> 0I Then
  726.                        RightClickTime = Environment.TickCount() - RightClickTime
  727.                    End If
  728.  
  729.                    If (RightClickTime <> 0I) AndAlso (RightClickTime < NativeMethods.GetDoubleClickTime()) Then
  730.                        RightClickTime = 0I
  731.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  732.                            RaiseEvent MouseRightUp(Me, New Point(x, y))
  733.                        End If
  734.                        RaiseEvent MouseRightDoubleClick(Me, New Point(x, y))
  735.  
  736.                    Else
  737.                        RightClickTime = Environment.TickCount()
  738.                        RaiseEvent MouseRightUp(Me, New Point(x, y))
  739.  
  740.                    End If
  741.  
  742.                Case MouseMessages.WM_MBUTTONDOWN
  743.                    RaiseEvent MouseMiddleDown(Me, New Point(x, y))
  744.  
  745.                Case MouseMessages.WM_MBUTTONUP
  746.                    If MiddleClickTime <> 0I Then
  747.                        MiddleClickTime = Environment.TickCount() - MiddleClickTime
  748.                    End If
  749.  
  750.                    If (MiddleClickTime <> 0I) AndAlso (MiddleClickTime < NativeMethods.GetDoubleClickTime()) Then
  751.                        MiddleClickTime = 0I
  752.                        If Not Me.SuppressMouseUpEventWhenDoubleClick Then
  753.                            RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  754.                        End If
  755.                        RaiseEvent MouseMiddleDoubleClick(Me, New Point(x, y))
  756.  
  757.                    Else
  758.                        MiddleClickTime = Environment.TickCount()
  759.                        RaiseEvent MouseMiddleUp(Me, New Point(x, y))
  760.  
  761.                    End If
  762.  
  763.                Case MouseMessages.WM_MOUSEWHEEL
  764.                    RaiseEvent MouseWheel(Me, New Point(x, y), If(MouseStruct.mouseData < 0I,
  765.                                                                 WheelDirection.WheelDown,
  766.                                                                 WheelDirection.WheelUp))
  767.  
  768.                Case Else
  769.                    Exit Select ' Do Nothing
  770.  
  771.            End Select
  772.  
  773.            Return 0I
  774.  
  775.        ElseIf nCode < 0I Then
  776.                Return NativeMethods.CallNextHookEx(MouseHook, nCode, wParam, lParam)
  777.  
  778.        Else ' nCode > 0
  779.                Return -1I
  780.  
  781.        End If
  782.  
  783.    End Function
  784.  
  785. #End Region
  786.  
  787. #Region " Hidden Methods "
  788.  
  789.    ''' <summary>
  790.    ''' Serves as a hash function for a particular type.
  791.    ''' </summary>
  792.    <EditorBrowsable(EditorBrowsableState.Never)>
  793.    Public Shadows Sub GetHashCode()
  794.    End Sub
  795.  
  796.    ''' <summary>
  797.    ''' Gets the System.Type of the current instance.
  798.    ''' </summary>
  799.    ''' <returns>The exact runtime type of the current instance.</returns>
  800.    <EditorBrowsable(EditorBrowsableState.Never)>
  801.    Public Shadows Function [GetType]()
  802.        Return Me.GetType
  803.    End Function
  804.  
  805.    ''' <summary>
  806.    ''' Determines whether the specified System.Object instances are considered equal.
  807.    ''' </summary>