游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5248|回复: 6

键盘勾子源码~~~

[复制链接]

4

主题

11

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2007-11-24 17:35:00 | 显示全部楼层 |阅读模式
请问怎样实现模拟键盘啊,网上找了N天,没有一个有实例的,全是记录键盘的例子,都只说用WH_JOURNALPLAYBACK参数可以实现模拟键盘,可我不知道以下代码该怎么写:

SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf PlaybackProc, App.hInstance, 0)

Public Function PlaybackProc (ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    '是不是要在这里写入代码实现啊
    '高手帮帮忙啦!搞了一个星期了都没搞定~~
End function
                                    [em4]

187

主题

6490

帖子

6491

积分

论坛元老

团长

Rank: 8Rank: 8

积分
6491
发表于 2007-11-25 12:20:00 | 显示全部楼层

Re:键盘勾子源码~~~

钩子一般是用来截取消息的。

模拟按键可以用SendKeys。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2007-12-28 13:35:00 | 显示全部楼层

Re:键盘勾子源码~~~

自己写一个消息队列。(使用链表数据结构就可以实现)
在Form_MouseDown()中 MyPostMsg(...)就可以了。

26

主题

537

帖子

537

积分

高级会员

Rank: 4

积分
537
发表于 2007-12-28 17:10:00 | 显示全部楼层

Re:键盘勾子源码~~~

以下这篇文章是我过去收集的,但没细看更没测试过。

----------------------------------------------------------------------------


如何使键盘、Mouse失效(JournalPlayBack Hook)

来源:cww

我们常见一些导览系统或教学系统,会自动移动Mouse与Keyin字,而那个时候,我们
不管Keyin或动Mouse都没有效,直到完成了导览系统的某个动作後才让使用者可以移
动Mouse与做Keyin的动作;想做到这个,要借重JournalPlayBack Hook。

JournalPlayBack Hook,它和JournalRecord Hook合称Journal Hook,它们作用
的范围是整个System,也就是挂上这个Hook後,影响的层面不单是这个Process,而是
所有的Process,而这两Hook又不用写在Dll之中,所以很好用。

首先我们要知道由键盘和Mouse输入等的硬体讯息,会存到一个System Queue而後OS会
到该System Queue看有没有讯息在其中,若有则撷取出来,看目前Active的Window是谁
而将讯息Post给它。而挂上JournalRecord Hook时,当有讯息被撷取出来时,会先执行
我们所设定的Hook Function(在vb中,一定要放在.BAS档之中)。这可以做什麽事呢?
例如们可以Check整个系统是否有按了键盘或有没有移动Mouse(一般来说,KeyUp,KeyDown
, MouseMove等Event只有Form在Active 时才收得到,挂上JournalRecord hook後,执行
Hook的thread便能收到所有这些讯息)。再如,它既然能收到Keyboard、Mouse的讯息,那
便可以将收到的讯息记录起来(记录於Memory或Disk都可以),之後再依方才的顺序重新
将讯息放送出来,可重新执行方才的动作(这不就是巨集的作法吗),或许
它叫JournalRecord便是这个原因。再来便是播放记录讯息的问题了,如果一面播放,一
面有其他讯息插队(如移动Mouse),那就不对了,所以JournalPlayBack这个Hook它会
让Mouse、Keyboard都失效,当OS 要求读System Queue时,便会启动这个Hook,就在此
时,我们可以把方才记录起来的讯息丢出一个出来,OS再要求读System Queue时,再丢
下一个讯息,如此达重播的效果(所以才叫JournalPlayBack),正因它会让键盘、Mouse
失效,拿它来做导览、教学系统的自动Move Mouse或文字显示是最适合的了。

'以下在.Bas中
Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)
Const WM_MOUSELAST = &H209
Const WM_MOUSEFIRST = &H200
Public Const WM_KEYLAST = &H108
Public Const WM_KEYFIRST = &H100
Public Const WH_JOURNALRECORD = 0
Public Const WH_JOURNALPLAYBACK = 1

Type EVENTMSG
message As Long
paramL As Long
paramH As Long
time As Long
hwnd As Long
End Type
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 hNxtHook As Long ' handle of Hook Procedure
Public msg As EVENTMSG

Sub EnableHook()
hNxtHook = SetWindowsHookEx(WH_JOURNALPLAYBACK, AddressOf HookProc, App.hInstance, 0)
End Sub
Sub FreeHook()
Dim ret As Long
ret = UnhookWindowsHookEx(hNxtHook)
End Sub
Function HookProc(ByVal code As Long, ByVal wParam As Long, _
ByVal lParam As Long) As Long
HookProc = CallNextHookEx(hNxtHook, code, wParam, lParam)
End Function

'以下在Form中,需求:一个Command1, 一个text1
Private Sub Command1_Click()
Dim str5 As String, len5 As Long, i As Long

Call EnableHook
str5 = "这是一个测试JournalPlayBackHook的程式"
len5 = Len(str5)
For i = 1 To len5
Text1.Text = Mid(str5, 1, i)
Text1.Refresh
Sleep (200)
Next
Call FreeHook
End Sub

如何让Window不接受键盘输入及Mouse Click

来源:cww

就好比呼叫MsgBox之後,Form就不接受Mouse Click与KeyPress,但是Form仍可处於
Activate的状态,即我们暂停了Mouse Click,KeyPress,等待我们要做事都做完了,
再将之回复。不过Mouse仍可自由的移动,若要让Mouse也不能动,就使用JournalPlayBack Hook
,而不是使用本方法。

EnableWindow()可达目的,第二个叁数传0进入则不能输入,传1则相反

Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As Long, ByVal fEnable As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Command1_Click()
Call EnableWindow(Me.hwnd, 0)
Me.Caption = "现在拒绝KeyPress, MouseClick"
Dim i As Long
For i = 1 To 100
Call Sleep(100)
DoEvents '虽有DoEvents,会发现,按Form的任何地方都没有反应
Next i
Me.Caption = "现在解除了"
Call EnableWindow(Me.hwnd, 1)
End Sub

如何拦截键盘输入

来源:cww

这是使用Keyboard Hook 的范例

'以下在.Bas
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, App.hInstance, 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这个名称只要和
'SetWindowsHookex()中 AddressOf後的名称一样便可,不一定叫什麽
'wParam 是传入按了哪个key的virtual-key code

'如果您将以下的两行unmark则所有键盘的输入皆没有作用
'MyKBHFunc = 1 '吃掉讯息
'Exit Function

MyKBHFunc = 0 '讯息要处理
If iCode < 0 Then
MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
Exit Function
End If
If wParam = vbKeySnapshot Then '侦测 有没有按到PrintScreen键
MyKBHFunc = 1 '在这个Hook便吃掉这个讯息
Debug.Print "haha"
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

9

主题

73

帖子

83

积分

注册会员

Rank: 2

积分
83
发表于 2008-1-20 22:26:00 | 显示全部楼层

Re:键盘勾子源码~~~

这个麻,最好用DLL来做。。。
一个插入DLL便可以全局了!虽然VB做的不是纯标准DLL。。。只是一个可以带运行库且易崩溃的一个东东而已!
但是做钩子是足够的啦!

23

主题

166

帖子

170

积分

注册会员

Rank: 2

积分
170
发表于 2008-1-26 12:31:00 | 显示全部楼层

Re:键盘勾子源码~~~

4楼的拦截键盘消息不能做全局钩子。

32

主题

1583

帖子

1589

积分

金牌会员

Rank: 6Rank: 6

积分
1589
发表于 2008-2-10 01:58:00 | 显示全部楼层

Re:键盘勾子源码~~~

要做全局钩子VB6比较勉强。由于Win32的地址空间的原理的问题,全局钩子的函数必须写在DLL中。而VB6恰好又不适合做标准DLL……
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 01:15

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表