键盘钩子(转载)

本文提供了一段在.NET环境下使用的系统键盘与鼠标钩子代码,详细解释了如何使用和扩展该代码,以及如何通过事件处理来响应键盘和鼠标操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是真正的.NET环境下的全局键盘鼠标Hook代码!
本代码是我从codeproject中翻来的,原作者Michael Kennedy,C#编码。
我将该段C#源码翻译为了VB代码,因为这两种语言的内部机制有一些区别,所以我做了较大的改动。不容易啊~~
下面的代码是我修改和扩展后的代码,保留所有的权利,翻版不究,盗版可耻。

使用方法很简单,先新建一个类文件,将代码复制进取,然后在一个窗体的空白区域添加一个类型实例。
Dim WithEvents MyHook As New SystemHook()
然后使用静态绑定事件就可以了。
Hook的所有信息已经被封装在了事件的参数中,非常方便哦~

版权归属:http://woshishuixjht.blog.163.com/blog/static/36127269201043011559147/


'非常不容易才翻译过来的。
'
保留所有权利。

'夜闻香原创,转载请保留此信息,万分感谢!
'
博客:http://hi.baidu.com/clso
'
论坛:http://cleclso.cn/
'
QQ:315514678E-mail:clso@qq.com
'
欢迎技术交流!


ImportsSystem.Reflection,System.Threading,System.ComponentModel,System.Runtime.InteropServices

'''<summary>本类可以在.NET环境下使用系统键盘与鼠标钩子</summary>
Public
ClassSystemHook

#Region"定义结构"

PrivateStructureMouseHookStruct
DimPTAs
POINT
DimHwndAsInteger

DimWHitTestCodeAsInteger
DimDwExtraInfoAsInteger
EndStructure


PrivateStructureMouseLLHookStruct
DimPTAs
POINT
DimMouseDataAsInteger

DimFlagsAsInteger
DimTimeAsInteger
DimDwExtraInfoAsInteger
EndStructure


PrivateStructureKeyboardHookStruct
DimvkCodeAsInteger

DimScanCodeAsInteger
DimFlagsAsInteger
DimTimeAsInteger
DimDwExtraInfoAsInteger
EndStructure


#EndRegion


#Region"API声明导入"

PrivateDeclareFunctionSetWindowsHookExLib"user32"Alias"SetWindowsHookExA"(ByValidHookAsInteger,ByVallpfnAsHookProc,ByValhModAsIntPtr,ByValdwThreadIdAsInteger)AsInteger
PrivateDeclareFunctionUnhookWindowsHookExLib"user32"(ByValidHookAsInteger)AsInteger
PrivateDeclareFunctionCallNextHookExLib"user32"(ByValidHookAsInteger,ByValnCodeAsInteger,ByValwParamAsInteger,ByVallParamAsIntPtr)AsInteger
PrivateDeclareFunctionToAsciiLib"user32"(ByValuVirtKeyAsInteger,ByValuScancodeAsInteger,ByVallpdKeyStateAsByte(),ByVallpwTransKeyAsByte(),ByValfuStateAsInteger)AsInteger
PrivateDeclareFunctionGetKeyboardStateLib"user32"(ByValpbKeyStateAsByte())AsInteger
PrivateDeclareFunctionGetKeyStateLib"user32"(ByValvKeyAsInteger)AsShort

PrivateDelegateFunctionHookProc(ByValnCodeAsInteger,ByValwParamAsInteger,ByVallParamAsIntPtr)AsInteger

#EndRegion


#Region"常量声明"

PrivateConstWH_MOUSE_LL=14
PrivateConstWH_KEYBOARD_LL=13
PrivateConstWH_MOUSE=7
PrivateConstWH_KEYBOARD=2
PrivateConstWM_MOUSEMOVE=&H200
PrivateConstWM_LBUTTONDOWN=&
H201
PrivateConstWM_RBUTTONDOWN=&
H204
PrivateConstWM_MBUTTONDOWN=&
H207
PrivateConstWM_LBUTTONUP=&
H202
PrivateConstWM_RBUTTONUP=&
H205
PrivateConstWM_MBUTTONUP=&
H208
PrivateConstWM_LBUTTONDBLCLK=&
H203
PrivateConstWM_RBUTTONDBLCLK=&
H206
PrivateConstWM_MBUTTONDBLCLK=&
H209
PrivateConstWM_MOUSEWHEEL=&
H20A
PrivateConstWM_KEYDOWN=&
H100
PrivateConstWM_KEYUP=&
H101
PrivateConstWM_SYSKEYDOWN=&
H104
PrivateConstWM_SYSKEYUP=&
H105

PrivateConstVK_SHIFTAsByte=&
H10
PrivateConstVK_CAPITALAsByte=&
H14
PrivateConstVK_NUMLOCKAsByte=&
H90

#EndRegion


#Region"事件委托处理"

PrivateeventsAsNewSystem.ComponentModel.EventHandlerList

'''<summary>鼠标激活事件</summary>
PublicCustomEventMouseActivityAs
MouseEventHandler
AddHandler(ByValvalueAs
MouseEventHandler)
events.AddHandler(
"MouseActivity"
,value)
EndAddHandler

RemoveHandler(ByValvalueAsMouseEventHandler)
events.RemoveHandler(
"MouseActivity"
,value)
EndRemoveHandler

RaiseEvent(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.MouseEventArgs)
DimehAsMouseEventHandler=TryCast(events("MouseActivity"
),MouseEventHandler)
IfehIsNotNothingThen
eh.Invoke(sender,e)
EndRaiseEvent

EndEvent
'''<summary>键盘按下事件</summary>
PublicCustomEventKeyDownAs
KeyEventHandler
AddHandler(ByValvalueAs
KeyEventHandler)
events.AddHandler(
"KeyDown"
,value)
EndAddHandler

RemoveHandler(ByValvalueAsKeyEventHandler)
events.RemoveHandler(
"KeyDown"
,value)
EndRemoveHandler

RaiseEvent(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.KeyEventArgs)
DimehAsKeyEventHandler=TryCast(events("KeyDown"
),KeyEventHandler)
IfehIsNotNothingThen
eh.Invoke(sender,e)
EndRaiseEvent

EndEvent
'''<summary>键盘输入事件</summary>
PublicCustomEventKeyPressAs
KeyPressEventHandler
AddHandler(ByValvalueAs
KeyPressEventHandler)
events.AddHandler(
"KeyPress"
,value)
EndAddHandler

RemoveHandler(ByValvalueAsKeyPressEventHandler)
events.RemoveHandler(
"KeyPress"
,value)
EndRemoveHandler

RaiseEvent(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.KeyPressEventArgs)
DimehAsKeyPressEventHandler=TryCast(events("KeyPress"
),KeyPressEventHandler)
IfehIsNotNothingThen
eh.Invoke(sender,e)
EndRaiseEvent

EndEvent
'''<summary>键盘松开事件</summary>
PublicCustomEventKeyUpAs
KeyEventHandler
AddHandler(ByValvalueAs
KeyEventHandler)
events.AddHandler(
"KeyUp"
,value)
EndAddHandler

RemoveHandler(ByValvalueAsKeyEventHandler)
events.RemoveHandler(
"KeyUp"
,value)
EndRemoveHandler

RaiseEvent(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.KeyEventArgs)
DimehAsKeyEventHandler=TryCast(events("KeyUp"
),KeyEventHandler)
IfehIsNotNothingThen
eh.Invoke(sender,e)
EndRaiseEvent

EndEvent

#EndRegion


PrivatehMouseHookAsInteger
PrivatehKeyboardHookAsInteger

PrivateSharedMouseHookProcedureAsHookProc
PrivateSharedKeyboardHookProcedureAs
HookProc

#Region"创建与析构类型"

'''<summary>创建一个全局鼠标键盘钩子(请使用Start方法开始监视)</summary>
SubNew()
'留空即可

EndSub

'''<summary>创建一个全局鼠标键盘钩子,决定是否安装钩子</summary>
'''<paramname="InstallAll">是否立刻挂钩系统消息</param>

SubNew(ByValInstallAllAsBoolean)
IfInstallAllThenStartHook(True,True
)
EndSub

'''<summary>创建一个全局鼠标键盘钩子,并决定安装钩子的类型</summary>
'''<paramname="InstallKeyboard">挂钩键盘消息</param>
'''<paramname="InstallMouse">挂钩鼠标消息</param>

SubNew(ByValInstallKeyboardAsBoolean,ByValInstallMouseAsBoolean)
StartHook(InstallKeyboard,InstallMouse)
EndSub

'''<summary>析构函数</summary>
ProtectedOverrides
SubFinalize()
UnHook()
'卸载对象时反注册系统钩子

MyBase.Finalize()
EndSub


#EndRegion


'''<summary>开始安装系统钩子</summary>
'''<paramname="InstallKeyboardHook">挂钩键盘消息</param>
'''<paramname="InstallMouseHook">挂钩鼠标消息</param>

PublicSubStartHook(OptionalByValInstallKeyboardHookAsBoolean=True,OptionalByValInstallMouseHookAsBoolean=False)
'注册键盘钩子

IfInstallKeyboardHookAndAlsohKeyboardHook=0Then
KeyboardHookProcedure
=NewHookProc(AddressOfKeyboardHookProc)
hKeyboardHook
=SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)),0
)
IfhKeyboardHook=0Then'检测是否注册完成

UnHook(True,False)'在这里反注册
ThrowNewWin32Exception(Marshal.GetLastWin32Error)'报告错误
EndIf
EndIf
'注册鼠标钩子
IfInstallMouseHookAndAlsohMouseHook=0Then
MouseHookProcedure
=NewHookProc(AddressOfMouseHookProc)
hMouseHook
=SetWindowsHookEx(WH_MOUSE_LL,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly.GetModules()(0)),0
)
IfhMouseHook=0Then

UnHook(
False,True)
ThrowNew
Win32Exception(Marshal.GetLastWin32Error)
EndIf

EndIf
EndSub

'''<summary>立刻卸载系统钩子</summary>
'''<paramname="UninstallKeyboardHook">卸载键盘钩子</param>
'''<paramname="UninstallMouseHook">卸载鼠标钩子</param>
'''<paramname="ThrowExceptions">是否报告错误</param>

PublicSubUnHook(OptionalByValUninstallKeyboardHookAsBoolean=True,OptionalByValUninstallMouseHookAsBoolean=True,OptionalByValThrowExceptionsAsBoolean=False)
'卸载键盘钩子

IfhKeyboardHook<>0AndAlsoUninstallKeyboardHookThen
DimretKeyboardAsInteger=UnhookWindowsHookEx(hKeyboardHook)
hKeyboardHook
=0

IfThrowExceptionsAndAlsoretKeyboard=0Then'如果出现错误,是否报告错误
ThrowNewWin32Exception(Marshal.GetLastWin32Error)'报告错误
EndIf
EndIf
'卸载鼠标钩子
IfhMouseHook<>0AndAlsoUninstallMouseHookThen
DimretMouseAsInteger=UnhookWindowsHookEx(hMouseHook)
hMouseHook
=0

IfThrowExceptionsAndAlsoretMouse=0Then
ThrowNewWin32Exception(Marshal.GetLastWin32Error)
EndIf

EndIf
EndSub


'键盘消息的委托处理代码
PrivateFunctionKeyboardHookProc(ByValnCodeAsInteger,ByValwParamAsInteger,ByVallParamAsIntPtr)AsInteger
StatichandledAsBoolean:handled=False
IfnCode>=0AndAlso(events("KeyDown")IsNotNothingOrElseevents("KeyPress")IsNotNothingOrElseevents("KeyUp")IsNotNothing)Then
StaticMyKeyboardHookStructAsKeyboardHookStruct
MyKeyboardHookStruct
=DirectCast(Marshal.PtrToStructure(lParam,GetType
(KeyboardHookStruct)),KeyboardHookStruct)
'激活KeyDown

IfwParam=WM_KEYDOWNOrElsewParam=WM_SYSKEYDOWNThen'如果消息为按下普通键或系统键
DimeAsNewKeyEventArgs(MyKeyboardHookStruct.vkCode)
RaiseEventKeyDown(Me,e)'激活事件

handled=handledOre.Handled'是否取消下一个钩子
EndIf
'激活KeyUp
IfwParam=WM_KEYUPOrElsewParam=WM_SYSKEYUPThen
DimeAsNewKeyEventArgs(MyKeyboardHookStruct.vkCode)
RaiseEventKeyUp(Me
,e)
handled
=handledOr
e.Handled
EndIf

'激活KeyPress(TODO:此段代码还有BUG!)
IfwParam=WM_KEYDOWNThen
DimisDownShiftAsBoolean=(GetKeyState(VK_SHIFT)&&H80=&H80)
DimisDownCapslockAsBoolean=(GetKeyState(VK_CAPITAL)<>0
)
DimkeyState(256)AsByte

GetKeyboardState(keyState)
DiminBuffer(2)AsByte
IfToAscii(MyKeyboardHookStruct.vkCode,MyKeyboardHookStruct.ScanCode,keyState,inBuffer,MyKeyboardHookStruct.Flags)=1Then
StatickeyAsChar:key=Chr(inBuffer(0))
'BUG所在

'IfisDownCapslockXorisDownShiftAndChar.IsLetter(key)Then
'key=Char.ToUpper(key)
'EndIf
DimeAsNewKeyPressEventArgs(key)
RaiseEventKeyPress(Me
,e)
handled
=handledOr
e.Handled
EndIf

EndIf
'取消或者激活下一个钩子
IfhandledThenReturn1ElseReturnCallNextHookEx(hKeyboardHook,nCode,wParam,lParam)
EndIf

EndFunction

'鼠标消息的委托处理代码
PrivateFunctionMouseHookProc(ByValnCodeAsInteger,ByValwParamAsInteger,ByVallParamAsIntPtr)AsInteger
IfnCode>=0AndAlsoevents("MouseActivity")IsNotNothingThen
StaticmouseHookStructAsMouseLLHookStruct
mouseHookStruct
=DirectCast(Marshal.PtrToStructure(lParam,GetType
(MouseLLHookStruct)),MouseLLHookStruct)
StaticmoubutAsMouseButtons:moubut=MouseButtons.None'鼠标按键

StaticmouseDeltaAsInteger:mouseDelta=0'滚轮值
SelectCasewParam
Case
WM_LBUTTONDOWN
moubut
=
MouseButtons.Left
Case
WM_RBUTTONDOWN
moubut
=
MouseButtons.Right
Case
WM_MBUTTONDOWN
moubut
=
MouseButtons.Middle
Case
WM_MOUSEWHEEL
StaticintAsInteger:int=(mouseHookStruct.MouseData>>16)And&
HFFFF
'本段代码CLE添加,模仿C#的Short从Int弃位转换

Ifint>Short.MaxValueThenmouseDelta=int-65536ElsemouseDelta=int
EndSelect
StaticclickCountAsInteger:clickCount=0'单击次数
Ifmoubut<>MouseButtons.NoneThen
IfwParam=WM_LBUTTONDBLCLKOrElsewParam=WM_RBUTTONDBLCLKOrElsewParam=WM_MBUTTONDBLCLKThen
clickCount
=2
Else
clickCount
=1
EndIf
EndIf
DimeAsNewMouseEventArgs(moubut,clickCount,mouseHookStruct.PT.X,mouseHookStruct.PT.Y,mouseDelta)
RaiseEventMouseActivity(Me
,e)
EndIf

ReturnCallNextHookEx(hMouseHook,nCode,wParam,lParam)'激活下一个钩子
EndFunction


'''<summary>键盘钩子是否有效</summary>
Public
PropertyKeyHookEnabled()AsBoolean
Get
ReturnhKeyboardHook<>0
EndGet
Set(ByValvalueAsBoolean)
IfvalueThenStartHook(True,False)ElseUnHook(True,False
)
EndSet

EndProperty

'''<summary>鼠标钩子是否有效</summary>
Public
PropertyMouseHookEnabled()AsBoolean
Get
ReturnhMouseHook<>0
EndGet
Set(ByValvalueAsBoolean)
IfvalueThenStartHook(False,True)ElseUnHook(False,True
)
EndSet

EndProperty


EndClass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值