VB.Net真的不支持全局钩子???

wyndham 2007-03-07 09:20:42
想在VB.Net中实现WH_KEYBOARD_LL和WH_MOUSE_LL的全局钩子。

我在网上已经找了很久,发现这两种钩子VB6和C#均可实现,唯独VB.Net不行!VB6中有App.hInstance可用,VB.Net没有,用“等效”的东东去替代,却不能达到同样的效果。

用hookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKeyboardProc, 0, GetCurrentThreadId())
可以轻松实现线程钩子,而无论如何WH_KEYBOARD_LL都实现不了,我试过下面几种方法:

1.hookproc = SetWindowsHookEx(WH_KEYBOARD_LL, New HOOKPROC(AddressOf MyKeyboardProc), Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)

2.hookproc = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf MyKeyboardProc, 0, GetCurrentThreadId())

3.hookproc = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf MyKeyboardProc, Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly().GetModules()(0)), 0)

4.hookproc = SetWindowsHookEx(WH_KEYBOARD_LL, New HOOKPROC(AddressOf MyKeyboardProc), Compatibility.VB6.GetHInstance.ToInt32(), 0)

hookproc始终为0.

不知是否有高人已经解决此问题?如果真是不行,是否有其它方法来获知键盘和鼠标的全部活动?
...全文
957 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
lujilei 2008-04-25
  • 打赏
  • 举报
回复
请问以上代码应该在什么地方编写,如何写一个完整的VB.NET程序,实现上面的代码?
wyndham 2007-03-12
  • 打赏
  • 举报
回复
谢谢,好几天没上网,我试试,成功了就给你分
snto 2007-03-12
  • 打赏
  • 举报
回复
问题的关键应该是GetModuleHandle函数,你查一下吧,怎么用。ps:代码也是从别人那里改的,全局对我做的一个项目没有帮助,所以也没详细的写注释,线程钩子写得比较详细
Red_angelX 2007-03-12
  • 打赏
  • 举报
回复
一般的方法不行
.Net FrameWork官方说法不支持全局Hook要使用一些特殊手段
wyndham 2007-03-12
  • 打赏
  • 举报
回复
hi,snto(神中神),多谢你啦,的确可用
我对VB.Net不是很了解,你能不能帮忙解释一下这里全局钩子的用法,为什么我以前用的方法不行呢?
snto 2007-03-08
  • 打赏
  • 举报
回复
线程键盘钩子,

Imports System.Runtime.InteropServices

Public Class MyHook

'Hook键盘
Private Const WH_KEYBOARD As Integer = 2
'Hook返回值
Private hHook As Integer = 0
'定义引用变量防止CallbackOnCollectedDelegate错误的产生
Private HookProc As CallBack
'回调函数
Public Delegate Function CallBack(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
'事件
Public Event KeyDown As System.Windows.Forms.KeyEventHandler
Public Event KeyUp As System.Windows.Forms.KeyEventHandler

'获取线程ID的API声明
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function GetCurrentThreadId() As Integer
End Function

'设置Hook的API声明
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As CallBack, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function

'处理下一Hook的API声明
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function

'移除Hook的API声明
<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function

'安装Hook,类型键盘线程钩子,失败返回0,成功返回钩子句柄
Public Function SetHook() As Integer
HookProc = New CallBack(AddressOf KeyBoardProc)
hHook = SetWindowsHookEx(WH_KEYBOARD, HookProc, IntPtr.Zero, GetCurrentThreadId)
Return hHook
End Function

'钩子处理子程
Private Function KeyBoardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
If nCode = 0 Then
If lParam.ToInt32 > 0 Then
RaiseEvent KeyDown(Me, New Windows.Forms.KeyEventArgs(CType(wParam, Windows.Forms.Keys)))
End If
If lParam.ToInt32 < 0 Then
RaiseEvent KeyUp(Me, New Windows.Forms.KeyEventArgs(CType(wParam, Windows.Forms.Keys)))
End If
End If

Return CallNextHookEx(hHook, nCode, wParam, lParam)

End Function

'移除Hook,成功返回True,失败返回False
Public Function UnHook() As Boolean
Return UnhookWindowsHookEx(hHook)
End Function

End Class
snto 2007-03-08
  • 打赏
  • 举报
回复
谁说不支持了,

Imports System.Runtime.InteropServices
Public Class MyHook

Private m_iKeyHandle As Integer = 0
Private m_clsHookCallback As HookCallBack

Private Const HC_ACTION As Integer = 0
Private Const WM_KEY_ENTER As Integer = &HD
Private Const WH_KEYBOARD_LL = 13
Private Const WM_KEYDOWN As Integer = &H100
Private Const WM_KeyUP As Integer = &H101
Private Const WM_SYSKEYDOWN As Integer = &H104
Private Const WM_SYSKEYUP As Integer = &H105
Private fix_COCD As HookCallBack '定义引用变量防止CallbackOnCollectedDelegate错误的产生

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

Public Declare Function GetModuleHandle Lib "kernel32.dll" Alias "GetModuleHandleA" (ByVal ModuleName As String) As IntPtr

<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As HookCallBack, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer
End Function

<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
End Function

<DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _
Public Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean
End Function

'Public Event KeyDown As System.Windows.Forms.KeyEventHandler
'Public Event KeyPress As System.Windows.Forms.KeyPressEventHandler
Public Event KeyUp As System.Windows.Forms.KeyEventHandler

Public Structure KeyboardHookStruct
' Specifies a virtual-key code. The code must be a value in the range 1 to 254.
Public vkCode As Integer
'Specifies a hardware scan code for the key.
Public scanCode As Integer
'Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
Public flags As Integer
'Specifies the time stamp for this message.
Public time As Integer
'Specifies extra information associated with the message.
Public dwExtraInfo As Integer
End Structure

Private Function KeyBoardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer
Dim newPtr As KeyboardHookStruct = CType(Marshal.PtrToStructure(lParam, newPtr.GetType()), KeyboardHookStruct)

If (nCode = HC_ACTION) Then
If wParam.ToInt32 = WM_KeyUP Or wParam.ToInt32 = WM_SYSKEYUP Then
If newPtr.vkCode = WM_KEY_ENTER Then
RaiseEvent KeyUp(Me, New Windows.Forms.KeyEventArgs(CType(newPtr.vkCode, Windows.Forms.Keys)))
End If
End If
End If

Return CallNextHookEx(m_iKeyHandle, nCode, wParam, lParam)

End Function

Public Sub SetHook()
fix_COCD = New HookCallBack(AddressOf KeyBoardProc)
m_iKeyHandle = SetWindowsHookEx(WH_KEYBOARD_LL, fix_COCD, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0)
If m_iKeyHandle = 0 Then
Throw New System.Exception("hook failed.")
Else
End If
End Sub

Public Sub UnHook()
If (m_iKeyHandle <> 0) Then UnhookWindowsHookEx(m_iKeyHandle)
End Sub

End Class
水如烟 2007-03-07
  • 打赏
  • 举报
回复
可以的.你把钩子类作为一个项目,编译成dll, 再给别的引用.
如果代码同在一个项目上,则没有效果.

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧