C# 如何编写程序监控键盘,即使程序的窗体不是当前活动窗体

C# 如何编写程序监控键盘,即使程序的窗体不是当前活动窗体,第1张

必须使用Windows api,用键盘钩子函数截取键盘按键记录,然后把这个EXE程序注册为系统服务就能自动运行了

C#中键盘钩子的使用 [转帖]

public class Win32Hook

{

[DllImport("kernel32")]

public static extern int GetCurrentThreadId();

[DllImport( "user32",

CharSet=CharSetAuto,CallingConvention=CallingConventionStdCall)]

public static extern int SetWindowsHookEx(

HookType idHook,

HOOKPROC lpfn,

int hmod,

int dwThreadId);

public enum HookType

{

WH_KEYBOARD = 2

}

public delegate int HOOKPROC(int nCode, int wParam, int lParam);

public void SetHook()

{

// set the keyboard hook

SetWindowsHookEx(HookTypeWH_KEYBOARD,

new HOOKPROC(thisMyKeyboardProc),

0,

GetCurrentThreadId());

}

public int MyKeyboardProc(int nCode, int wParam, int lParam)

{

//在这里放置你的处理代码 return 0;

}

}

使用方法

可以在Form的构造函数里放入

Win32Hook hook = new Win32Hook();

hookSetHook();

改了半个小时才发现这个题只有0分……还是给你贴出来吧。

把模块代码改为这样即可。

=================

Option Explicit

Public Const WH_KEYBOARD = 13

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

Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long

Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long

Public hNextHookProc As Long

Public Type KBDLLHOOKSTRUCT

vkCode As Long

scanCode As Long

flags As Long

time As Long

dwExtraInfo As Long

End Type

Public Sub UnHookKBD()

If hNextHookProc <> 0 Then

UnhookWindowsHookEx hNextHookProc

hNextHookProc = 0

End If

End Sub

Public Function EnableKBDHook()

If hNextHookProc <> 0 Then

Exit Function

End If

hNextHookProc = SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKBHFunc, ApphInstance, 0)

If hNextHookProc <> 0 Then

EnableKBDHook = hNextHookProc

End If

End Function

Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, lParam As KBDLLHOOKSTRUCT) As Long

MyKBHFunc = 0

If iCode < 0 Then

MyKBHFunc = CallNextHookEx(hNextHookProc, iCode, wParam, lParam)

Exit Function

End If

If lParamvkCode = vbKeySnapshot Then

MyKBHFunc = 1

MsgBox "!!!"

Else

Call CallNextHookEx(hNextHookProc, iCode, wParam, lParam)

End If

End Function

你可以在钩子过程中,用GetLocalTime来获取当前的时间,也就是键盘消息发出的时间了。分别处理按下和松开的键盘消息的时间。

当然,你还可以使用WH_GETMESSAGE消息来钩WM_KEYDOWN和WM_KEYUP消息,你可以通过WH_GETMESSAGE类型的钩子的MSG结构体中的time成员来获取这些消息产生的时间。如:

LRESULT WINAPI GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)

{

PMSG pMsg=(PMSG)lParam;

if(pMsg->==WM_KEYDOWN)

{

DWORD dwTime=pMsg->time

}

}

}

}

VB6没有什么做不到,谁说VB6不如VBnet,只是方法的使用而已,其实这些都是可以VB6都是可以做到的,可以交流!vb中设置全局热键的方法很多,我介绍几种吧:第一种回调用,添加模块复制下面代码Private Declare Function CallNextHookEx Lib "user32" _

(ByVal hHook As Long, _

ByVal nCode As Long, _

ByVal wParam As Long, _

lParam As Any) As Long

Private Declare Function SetWindowsHookEx Lib "user32" _

Alias "SetWindowsHookExA" _

(ByVal idHook As Long, _

ByVal lpfn As Long, _

ByVal hmod As Long, _

ByVal dwThreadId As Long) As Long

Private Declare Function UnhookWindowsHookEx Lib "user32" _

(ByVal hHook As Long) As Long

Private Declare Sub CopyMemory Lib "kernel32" _

Alias "RtlMoveMemory" _

(Destination As Any, _

Source As Any, _

ByVal Length As Long)

Private Type PKBDLLHOOKSTRUCT

vkCode As Long

scanCode As Long

flags As Long

time As Long

dwExtraInfo As Long

End Type

Private Const WM_KEYDOWN = &H100

Private Const WM_SYSKEYDOWN = &H104

Private Const WM_KEYUP = &H101

Private Const WM_SYSKEYUP = &H105

Private Const HC_ACTION = 0

Private Const WH_KEYBOARD_LL = 13

Private lngHook As Long

Public Function HotKey(ByVal nCode As Long, _

ByVal wParam As Long, _

ByVal lParam As Long) As Long

Dim p As PKBDLLHOOKSTRUCT

If nCode = HC_ACTION Then

Select Case wParam

Case WM_KEYDOWN, WM_SYSKEYDOWN

Call CopyMemory(p, ByVal lParam, Len(p))

If pvkCode = vbKeyF10 Then '这里定义热键

MsgBox "你按下了F10" '这里,执行你要执行的程序,我这里示范msgbox

End If '如果你想定义多个热键就复制上面3行代码然后把vbKeyF10 改成你想要的就可以了。

Case Else

End Select

End If

Call CallNextHookEx(WH_KEYBOARD_LL, nCode, wParam, lParam)

End Function

Public Sub HooK()

lngHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf HotKey, ApphInstance, 0)

End Sub

Public Sub UnHooK()

Call UnhookWindowsHookEx(lngHook)

End Sub

'窗体中代码

Private Sub Form_Load()

HooK

End Sub

Private Sub Form_Unload(Cancel As Integer)

UnHooK

End Sub

第二种方法 1、建立一个模块代码如下:

'

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long, ByVal fskey_Modifiers As Long, ByVal vk As Long) As Long

Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long) As Long

Const WM_HOTKEY = &H312

Const MOD_ALT = &H1

Const MOD_CONTROL = &H2

Const MOD_SHIFT = &H4

Const GWL_WNDPROC = (-4) '窗口函数的地址

Dim key_preWinProc As Long '用来保存窗口信息

Dim key_Modifiers As Long, key_uVirtKey As Long, key_idHotKey As Long

Dim key_IsWinAddress As Boolean '是否取得窗口信息的判断

Function keyWndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If Msg = WM_HOTKEY Then

Select Case wParam 'wParam 值就是 key_idHotKey

Case 1 '激活 3 个热键后,3 个热键所对应的 *** 作,大家在其他的程序中,只要修改此处就可以了

MsgBox "alt+1"

Case 2

MsgBox "alt+2"

Case 3

MsgBox "alt+3"

Case 4

MsgBox "alt+4"

End Select

End If

' 将消息传送给指定的窗口

keyWndproc = CallWindowProc(key_preWinProc, hwnd, Msg, wParam, lParam)

End Function

Function SetHotkey(ByVal KeyId As Long, ByVal KeyAss0 As String, ByVal Action As String)

Dim KeyAss1 As Long

Dim KeyAss2 As String

Dim i As Long

i = InStr(1, KeyAss0, ",")

If i = 0 Then

KeyAss1 = Val(KeyAss0)

KeyAss2 = ""

Else

KeyAss1 = Right(KeyAss0, Len(KeyAss0) - i)

KeyAss2 = Left(KeyAss0, i - 1)

End If

key_idHotKey = 0

key_Modifiers = 0

key_uVirtKey = 0

If key_IsWinAddress = False Then '判断是否需要取得窗口信息,如果重复取得,再最后恢复窗口时,将会造成程序死掉

' 记录原来的window程序地址

key_preWinProc = GetWindowLong(Form1hwnd, GWL_WNDPROC)

' 用自定义程序代替原来的window程序

SetWindowLong Form1hwnd, GWL_WNDPROC, AddressOf keyWndproc

End If

key_idHotKey = KeyId

Select Case Action

Case "Add"

If KeyAss2 = "Ctrl" Then key_Modifiers = MOD_CONTROL

If KeyAss2 = "Alt" Then key_Modifiers = MOD_ALT

If KeyAss2 = "Shift" Then key_Modifiers = MOD_SHIFT

If KeyAss2 = "Ctrl+Alt" Then key_Modifiers = MOD_CONTROL + MOD_ALT

If KeyAss2 = "Ctrl+Shift" Then key_Modifiers = MOD_CONTROL + MOD_SHIFT

If KeyAss2 = "Ctrl+Alt+Shift" Then key_Modifiers = MOD_CONTROL + MOD_ALT + MOD_SHIFT

If KeyAss2 = "Shift+Alt" Then key_Modifiers = MOD_SHIFT + MOD_ALT

key_uVirtKey = Val(KeyAss1)

RegisterHotKey Form1hwnd, key_idHotKey, key_Modifiers, key_uVirtKey '向窗口注册系统热键

key_IsWinAddress = True '不需要再取得窗口信息

Case "Del"

SetWindowLong Form1hwnd, GWL_WNDPROC, key_preWinProc '恢复窗口信息

UnregisterHotKey Form1hwnd, key_uVirtKey '取消系统热键

key_IsWinAddress = False '可以再次取得窗口信息

End Select

End Function

2、form中的代码:

'

Private Sub Form_Load()

SetHotkey 1, "Alt,49", "Add"

SetHotkey 2, "Alt,50", "Add"

SetHotkey 3, "Alt,51", "Add"

SetHotkey 4, "Alt,52", "Add"

End Sub

Private Sub Form_Unload(Cancel As Integer)

SetHotkey 1, "", "Del"

SetHotkey 2, "", "Del"

SetHotkey 3, "", "Del"

SetHotkey 4, "", "Del"

End Sub

当然还有别的方法。方法真的很多。托盘程序呢,这个就没必要发了吧。网上多的数不清,基本都是有右键的。如果你找不到你就搜一下vb托盘控件,那些都能直接当成控件调用方便的可以。 >

我用F10键做例子啦。。具体自己做

'模块中

Option Explicit

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

Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long

Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long

Public hnexthookproc As Long

Public Const HC_ACTION = 0

Public Const WH_KEYBOARD = 2

Public Sub UnHookKBD()

If hnexthookproc <> 0 Then

UnhookWindowsHookEx hnexthookproc

hnexthookproc = 0

End If

End Sub

Public Function EnableKBDHook()

If hnexthookproc <> 0 Then

Exit Function

End If

hnexthookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf MyKBHFunc, ApphInstance, 0)

If hnexthookproc <> 0 Then

EnableKBDHook = hnexthookproc

End If

End Function

Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

MyKBHFunc = 0 '讯息要处理

If iCode < 0 Then

MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam)

Exit Function

End If

If wParam = 121 Then '侦测 有没有按到F10键

Form1Check1Value = 1 'Check选中

Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam)

Else

Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam)

End If

End Function

'以下在Form

Private Sub Form_Load()

Call EnableKBDHook

End Sub

Private Sub Form_Unload(Cancel As Integer)

Call UnHookKBD

End Sub

以上就是关于C# 如何编写程序监控键盘,即使程序的窗体不是当前活动窗体全部的内容,包括:C# 如何编写程序监控键盘,即使程序的窗体不是当前活动窗体、VB截获键盘输入,按了Print Screen没输出,帮忙修改下、用钩子函数做键盘监听,怎样获得输入字符的时间呢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9718932.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存