在網上查了很多相關資料,都無法實現全局鉤子,最後找到一個C#的鏈接,於是費了點功夫將其轉為VB來實現,測試通過的環境為:VB2005 express edtion beta2, Windows 2003 english。下表為兩都轉換的對比。  
注:轉換過程是本人無師自通所為,難免有錯誤和效能問題,如有見解請跟貼糾正。
 

Class對比

 

C#

VB

using System;

using System.Runtime.InteropServices;

using System.Reflection;

using System.Threading;

using System.Windows.Forms;

 

namespace GlobalHookDemo  {

                public class UserActivityHook : object {

                public UserActivityHook() {

                        Start();

                }

                ~UserActivityHook() {

                        Stop();

                }

 

                public event MouseEventHandler OnMouseActivity;

                public event KeyEventHandler KeyDown;

                public event KeyPressEventHandler KeyPress;

                public event KeyEventHandler KeyUp;

static int hMouseHook = 0; //Declare mouse hook handle as int.

static int hKeyboardHook = 0; //Declare keyboard hook handle as int.

                public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

                //values from Winuser.h in Microsoft SDK.

                public const int WH_MOUSE_LL   = 14;        //mouse hook constant

                public const int WH_KEYBOARD_LL = 13;   //keyboard hook constant

                HookProc MouseHookProcedure;

                HookProc KeyboardHookProcedure;

                       

                [StructLayout(LayoutKind.Sequential)]

                public class POINT

                {

                        public int x;

                        public int y;

                }

                [StructLayout(LayoutKind.Sequential)]

                public class MouseHookStruct

                {

                        public POINT pt;

                        public int hwnd;

                        public int wHitTestCode;

                        public int dwExtraInfo;

                }

                //Declare wrapper managed KeyboardHookStruct class.

                [StructLayout(LayoutKind.Sequential)]

                public class KeyboardHookStruct

                {

                        public int vkCode;    //Specifies a virtual-key code. The code must be a value in the range 1 to 254.

                        public int scanCode; // Specifies a hardware scan code for the key.

                        public int flags;  // Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.

                        public int time; // Specifies the time stamp for this message.

                        public int dwExtraInfo; // Specifies extra information associated with the message.

                }

       

                [DllImport("user32.dll",CharSet=CharSet.Auto,

                        CallingConvention=CallingConvention.StdCall)]

                public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

                [DllImport("user32.dll",CharSet=CharSet.Auto,

                         CallingConvention=CallingConvention.StdCall)]

                public static extern bool UnhookWindowsHookEx(int idHook);

                [DllImport("user32.dll",CharSet=CharSet.Auto,

                         CallingConvention=CallingConvention.StdCall)]

                public static extern int CallNextHookEx(int idHook, int nCode,        Int32 wParam, IntPtr lParam); 

 

                public void Start()

                {

                        // install Mouse hook

                        if(hMouseHook == 0)

                        {

                        MouseHookProcedure = new HookProc(MouseHookProc);

hMouseHook = SetWindowsHookEx( WH_MOUSE_LL,MouseHookProcedure,         Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);

                if(hMouseHook == 0 )     {

                                        Stop();

                                        throw new Exception("SetWindowsHookEx failed.");                        }

                        }

                        // install Keyboard hook

        if(hKeyboardHook == 0)

        {KeyboardHookProcedure = new HookProc(KeyboardHookProc);

        hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL,

KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),        0);

                        if(hKeyboardHook == 0 )        {

                                        Stop();

                                        throw new Exception("SetWindowsHookEx ist failed.");

                                }

                        }

                }

        public void Stop()

                {      bool retMouse =true;

                        bool retKeyboard = true;

                        if(hMouseHook != 0)

                        {

                                retMouse = UnhookWindowsHookEx(hMouseHook);

                                hMouseHook = 0;

                        }

                        if(hKeyboardHook != 0)

                {retKeyboard = UnhookWindowsHookEx(hKeyboardHook);

                hKeyboardHook = 0;

                        }

                       

                        //If UnhookWindowsHookEx fails.

                        if (!(retMouse && retKeyboard)) throw new Exception("UnhookWindowsHookEx failed.");

                }

 

          private const int WM_MOUSEMOVE = 0x200;

          private const int WM_LBUTTONDOWN = 0x201;

          private const int WM_RBUTTONDOWN = 0x204;

          private const int WM_MBUTTONDOWN = 0x207;

          private const int WM_LBUTTONUP = 0x202;

          private const int WM_RBUTTONUP = 0x205;

          private const int WM_MBUTTONUP = 0x208;

          private const int WM_LBUTTONDBLCLK = 0x203;

          private const int WM_RBUTTONDBLCLK = 0x206;

                private const int WM_MBUTTONDBLCLK = 0x209;

 

                private int MouseHookProc(int nCode, Int32 wParam, IntPtr lParam)

                {

                        // if ok and someone listens to our events

                        if ((nCode >= 0) && (OnMouseActivity!=null)) {

                               

                                MouseButtons button=MouseButtons.None;

                                switch (wParam)

                                {

                                        case WM_LBUTTONDOWN:

                                        //case WM_LBUTTONUP:

                                        //case WM_LBUTTONDBLCLK:

                                                button=MouseButtons.Left;

                                                break;

                                        case WM_RBUTTONDOWN:

                                        //case WM_RBUTTONUP:

                                        //case WM_RBUTTONDBLCLK:

                                                button=MouseButtons.Right;

                                                break;

                                }

                                int clickCount=0;

                                if (button!=MouseButtons.None)

                                        if (wParam==WM_LBUTTONDBLCLK || wParam==WM_RBUTTONDBLCLK) clickCount=2;

                                        else clickCount=1;

                MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

                        MouseEventArgs e=new MouseEventArgs( button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y,                             0 );

                        OnMouseActivity(this, e);                 }

        return CallNextHookEx(hMouseHook, nCode, wParam, lParam); }

        [DllImport("user32")]

                public static extern int ToAscii(int uVirtKey, int uScanCode, byte[] lpbKeyState,byte[] lpwTransKey,int fuState);

        [DllImport("user32")]

        public static extern int GetKeyboardState(byte[] pbKeyState);

 

                private const int WM_KEYDOWN                 = 0x100;

                private const int WM_KEYUP                        = 0x101;

                private const int WM_SYSKEYDOWN         = 0x104;

                private const int WM_SYSKEYUP                 = 0x105;

 

                private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)

                {

                        // it was ok and someone listens to events

                        if ((nCode >= 0) && (KeyDown!=null || KeyUp!=null || KeyPress!=null))

                        {

                                KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

                                // raise KeyDown

                                if ( KeyDown!=null && ( wParam ==WM_KEYDOWN || wParam==WM_SYSKEYDOWN ))

                                {

                                        Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;

                                        KeyEventArgs e = new KeyEventArgs(keyData);

                                        KeyDown(this, e);

                                }

                               

                                // raise KeyPress

                                if ( KeyPress!=null &&  wParam ==WM_KEYDOWN )

                                {

                                        byte[] keyState = new byte[256];

                                        GetKeyboardState(keyState);

 

                                        byte[] inBuffer= new byte[2];

                                        if (ToAscii(MyKeyboardHookStruct.vkCode,

                                            MyKeyboardHookStruct.scanCode,

                                            keyState,

                                            inBuffer,

                                            MyKeyboardHookStruct.flags)==1)

                                            {

                                                    KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);

                                                                KeyPress(this, e);

                                            }

                                }

                               

                                // raise KeyUp

                                if ( KeyUp!=null && ( wParam ==WM_KEYUP || wParam==WM_SYSKEYUP ))

                                {

                                        Keys keyData=(Keys)MyKeyboardHookStruct.vkCode;

                                        KeyEventArgs e = new KeyEventArgs(keyData);

                                        KeyUp(this, e);

                                }

 

                        }

                        return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);

                }}}

 

 

 

 

Imports System.Runtime.InteropServices

Imports System.Reflection

 

Public Class UserActivityHook

    Public Sub New()

        StartHook()

    End Sub

 

    Protected Overrides Sub Finalize()

        StopHook()

    End Sub

 

    Public Event OnMouseActivity As MouseEventHandler

    Public Event KeyDown As KeyEventHandler

    Public Event KeyPress As KeyPressEventHandler

    Public Event KeyUp As KeyEventHandler

    Dim hMouseHook As Integer = 0       '//Declare mouse hook handle as int.

    Dim hKeyboardHook As Integer = 0    '//Declare keyboard hook handle as int.

#Region "Define parameters"

    Public Delegate Function HookProc(ByVal nCode As Integer, ByVal wParam As Int32, ByVal lParam As IntPtr) As Integer

    Public Const WH_MOUSE_LL As Integer = 14       '//mouse hook constant

    Public Const WH_KEYBOARD_LL As Integer = 13    '//keyboard hook constant    

  

 

 Public MouseHookProcedure As HookProc

    Public KeyboardHookProcedure As HookProc

 

    Public Structure Point

        Public x As Integer

        Public y As Integer

    End Structure

 

    Public Structure MouseHookStruct

        Public pt As Point

        Public hwnd As Integer

        Public wHitTestCode As Integer

        Public dwExtraInfo As Integer

    End Structure

 

    Public Structure KeyboardHookStruct

        Public vkCode As Integer          '//Specifies a virtual-key code. The code must be a value in the range 1 to 254.

        Public scanCode As Integer        '// Specifies a hardware scan code for the key.

        Public flags As Integer           '// Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.

        Public time As Integer            '// Specifies the time stamp for this message.

        Public dwExtraInfo As Integer     '// Specifies extra information associated with the message.

    End Structure

 

 

 

 

 

 

 Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA"  (ByVal idHook As Integer, ByVal lpfn As HookProc, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer

 

 Public Declare Function CallNextHookEx Lib "user32" Alias "CallNextHookEx" (ByVal idHook As Integer, ByVal ncode As Integer, ByVal wParam As Int32, ByVal lParam As IntPtr) As Integer   

 

Public Declare Function UnhookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal idHook As Integer) As Boolean

 

#End Region

 

    Public Sub StartHook()

        '// install Mouse hook

        If (hMouseHook = 0) Then

            '// Create an instance of HookProc.

            MouseHookProcedure = New HookProc(AddressOf MouseHookProc)

            hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()(0)).ToInt32, 0)

            '//If SetWindowsHookEx fails.

            If (hMouseHook = 0) Then

                StopHook()

            End If

        End If

        '// install Keyboard hook

        If (hKeyboardHook = 0) Then

            KeyboardHookProcedure = New HookProc(AddressOf KeyboardHookProc)

 

            hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()(0)).ToInt32, 0)

            '//If SetWindowsHookEx fails.

            If (hKeyboardHook = 0) Then

                StopHook()

            End If

        End If

    End Sub

 

    Public Sub StopHook()

        Dim retMouse As Boolean = True

        Dim retKeyboard As Boolean = True

        If hMouseHook <> 0 Then

            retMouse = UnhookWindowsHookEx(hMouseHook)

            hMouseHook = 0

        End If

        If hKeyboardHook <> 0 Then

            retKeyboard = UnhookWindowsHookEx(hKeyboardHook)

            hKeyboardHook = 0

        End If

 

        '//If UnhookWindowsHookEx fails.

        If Not (retMouse And retKeyboard) Then

            Throw New Exception("UnhookWindowsHookEx failed.")

        End If

    End Sub

 

 

    Private Const WM_MOUSEMOVE As Integer = &H200 'Convert.ToInt32("0x200", 16)

    Private Const WM_LBUTTONDOWN As Integer = &H201

    Private Const WM_RBUTTONDOWN As Integer = &H204

    Private Const WM_MBUTTONDOWN As Integer = &H207

    Private Const WM_LBUTTONUP As Integer = &H202

    Private Const WM_RBUTTONUP As Integer = &H205

    Private Const WM_MBUTTONUP As Integer = &H208

    Private Const WM_LBUTTONDBLCLK As Integer = &H203

    Private Const WM_RBUTTONDBLCLK As Integer = &H206

    Private Const WM_MBUTTONDBLCLK As Integer = &H209

 

    Private Function MouseHookProc(ByVal nCode As Integer, ByVal wParam As Int32, ByVal lParam As IntPtr) As Integer

        If (nCode >= 0) And (OnMouseActivityEvent IsNot Nothing) Then

            Dim button As New MouseButtons

            button = MouseButtons.None

            Select Case wParam

                Case WM_LBUTTONDOWN

                    '//case WM_LBUTTONUP:

                    '//case WM_LBUTTONDBLCLK:

                    button = MouseButtons.Left

 

                Case WM_RBUTTONDOWN

                    '//case WM_RBUTTONUP:

                    '//case WM_RBUTTONDBLCLK:

                    button = MouseButtons.Right

            End Select

            Dim clickCount As Integer = 0

            If (button <> MouseButtons.None) Then

                If (wParam = WM_LBUTTONDBLCLK Or wParam = WM_RBUTTONDBLCLK) Then

                    clickCount = 2

                Else

                    clickCount = 1

                End If

            End If

            '//Marshall the data from callback.

            Dim MyMouseHookStruct As MouseHookStruct

            MyMouseHookStruct = Marshal.PtrToStructure(lParam, GetType(MouseHookStruct))

            Dim e As MouseEventArgs

            e = New MouseEventArgs(button, clickCount, MyMouseHookStruct.pt.x, MyMouseHookStruct.pt.y, 0)

            RaiseEvent OnMouseActivity(Me, e)

            Return CallNextHookEx(hMouseHook, nCode, wParam, lParam)

        End If

    End Function

 

 

#Region "Define keyboard parameters"

    Private Const WM_KEYDOWN As Integer = &H100  '0x100

    Private Const WM_KEYUP As Integer = &H101

    Private Const WM_SYSKEYDOWN As Integer = &H104

    Private Const WM_SYSKEYUP As Integer = &H105

#End Region

 

    Private Function KeyboardHookProc(ByVal nCode As Integer, ByVal wParam As Int32, ByVal lParam As IntPtr) As Integer

        If ((nCode >= 0) And (KeyDownEvent IsNot Nothing Or KeyUpEvent IsNot Nothing Or KeyPressEvent IsNot Nothing)) Then

            Dim MyKeyboardHookStruct As KeyboardHookStruct

            MyKeyboardHookStruct = Marshal.PtrToStructure(lParam, GetType(KeyboardHookStruct))

 

            '// raise KeyDown

            If (KeyDownEvent IsNot Nothing And (wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN)) Then

                Dim keyData As Keys

                keyData = MyKeyboardHookStruct.vkCode

                Dim e As KeyEventArgs

                e = New KeyEventArgs(keyData)

                RaiseEvent KeyDown(Me, e)

            End If

 

            '// raise KeyPress

            If (KeyPressEvent IsNot Nothing And wParam = WM_KEYDOWN) Then

                Dim keyState As Byte

                ZClsAPIs.GetKeyboardState(keyState)

                Dim inBuffer As Byte

                If (ZClsAPIs.ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) = 1) Then

                    Dim e As KeyPressEventArgs

                    e = New KeyPressEventArgs(CChar(CStr(inBuffer)))

                    RaiseEvent KeyPress(Me, e)

                End If

 

            End If

 

            '// raise KeyUp

            If (KeyUpEvent IsNot Nothing And (wParam = WM_KEYUP Or wParam = WM_SYSKEYUP)) Then

                Dim keyData As Keys

                keyData = MyKeyboardHookStruct.vkCode

                Dim e As KeyEventArgs

                e = New KeyEventArgs(keyData)

                RaiseEvent KeyUp(Me, e)

            End If

        End If

        Return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam)

 

    End Function

 

End Class

 

Form 代碼對比

 

C#

VB

void ButtonStartClick(object sender, System.EventArgs e)

                {

                        actHook.Start();

                }

               

                void ButtonStopClick(object sender, System.EventArgs e)

                {

                        actHook.Stop();

                }

               

               

                UserActivityHook actHook;

                void MainFormLoad(object sender, System.EventArgs e)

                {

                        actHook= new UserActivityHook(); // crate an instance

                        // hang on events

                        actHook.OnMouseActivity+=new MouseEventHandler(MouseMoved);

                        actHook.KeyDown+=new KeyEventHandler(MyKeyDown);

                        actHook.KeyPress+=new KeyPressEventHandler(MyKeyPress);

                        actHook.KeyUp+=new KeyEventHandler(MyKeyUp);

                }

               

                public void MouseMoved(object sender, MouseEventArgs e)

                {

                        labelMousePosition.Text=String.Format("x={0}  y={1}", e.X, e.Y);

                        if (e.Clicks>0) LogWrite("MouseButton   - " + e.Button.ToString());

                }

               

                public void MyKeyDown(object sender, KeyEventArgs e)

                {

                        LogWrite("KeyDown       - " + e.KeyData.ToString());

                }

               

                public void MyKeyPress(object sender, KeyPressEventArgs e)

                {

                        LogWrite("KeyPress        - " + e.KeyChar);

                }

               

                public void MyKeyUp(object sender, KeyEventArgs e)

                {

                        LogWrite("KeyUp           - " + e.KeyData.ToString());

                }

               

                private void LogWrite(string txt)

                {

                        textBox.AppendText(txt + Environment.NewLine);

                        textBox.SelectionStart = textBox.Text.Length;

                }

 

        }                     

Imports System.Runtime.InteropServices

Public Class A00FmLogin

    Dim actHook As UserActivityHook

 

    Private Sub BTNsubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNsubmit.Click

        Me.Hide()

        My.Forms.A00Main.Show()

    End Sub

    Private Sub BTNquit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNquit.Click

        Application.Exit()

    End Sub

    Private Sub BTNreset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNreset.Click

        'Call SetWallpaper(Me.BackgroundImage)

        actHook.StopHook()

    End Sub

    Private Sub A00FmLogin_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        actHook.StopHook()

    End Sub

    Private Sub A00FmLogin_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        actHook = New UserActivityHook() '// crate an instance

        '// hang on events

        AddHandler actHook.OnMouseActivity, New MouseEventHandler(AddressOf MouseMoved)

        AddHandler actHook.KeyDown, New KeyEventHandler(AddressOf MyKeyDown)

        AddHandler actHook.KeyPress, New KeyPressEventHandler(AddressOf MyKeyPress)

        AddHandler actHook.KeyUp, New KeyEventHandler(AddressOf MyKeyUp)

    End Sub

    Private Sub BTNoptions_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNoptions.Click

        actHook.StartHook()

    End Sub

    Public Sub MouseMoved(ByVal sender As Object, ByVal e As MouseEventArgs)

        LABwebsite.Text = "x=" & e.X & "  y=" & e.Y

        If (e.Clicks > 0) Then LogWrite("MouseButton - " + e.Button.ToString())

    End Sub

Public Sub MyKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)

        LogWrite("KeyDown - " + e.KeyData.ToString())

    End Sub    

    Public Sub MyKeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)

        LogWrite("KeyPress      - " + e.KeyChar)

    End Sub

    Public Sub MyKeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)

        LogWrite("KeyUp         - " + e.KeyData.ToString())

    End Sub

    Private Sub LogWrite(ByVal txt As String)

        TBOst.AppendText(txt + Environment.NewLine)

        TBOst.SelectionStart = TBOst.Text.Length

    End Sub

End Class

 

posted on 2005-04-05 13:27  James Wong   阅读(3601)  评论(4编辑  收藏  举报