版本 2
DLL命令 api_设置系统钩子, 整数型, "user32dll", "SetWindowsHookExA", , , SetWindowsHookEx
参数 钩子类型, 整数型, , idHook
参数 回调函数地址, 整数型, , lpfn
参数 实例句柄, 整数型, , hmod
参数 线程ID, 整数型, , dwThreadId
DLL命令 api_呼叫下一钩子, 整数型, "user32dll", "CallNextHookEx", , , CallNextHookEx
参数 钩子句柄, 整数型, , hHook
参数 回调函数参数1, 整数型, , ncode
参数 回调函数参数2, 整数型, , wParam
参数 回调函数参数3, 整数型, , lParam
DLL命令 api_释放系统钩子, 整数型, "user32dll", "UnhookWindowsHookEx", , , UnhookWindowsHookEx
参数 钩子句柄, 整数型, , hHook
DLL命令 api_取实例句柄, 整数型, , "GetModuleHandleA", , ,
参数 程序名, 整数型
DLL命令 api_拷贝内存, 整数型, "kernel32", "RtlMoveMemory", , , RtlMoveMemory
参数 回调结构, 鼠标结构, , lpvDest
参数 钩子回调函数参数3, 整数型, , lpvSource
参数 尺寸, 整数型, , cbCopy
版本 2
数据类型 鼠标结构, 公开
成员 成员1, 整数型
成员 成员2, 坐标结构
成员 成员3, 整数型
数据类型 坐标结构
成员 x, 整数型
成员 y, 整数型
版本 2
支持库 spec
程序集 窗口程序集1
程序集变量 钩子句柄, 整数型
子程序 _按钮1_被单击
钩子句柄 = api_设置系统钩子 (14, 取子程序地址 (&鼠标钩子回调函数), api_取实例句柄 (0), 0)
子程序 鼠标钩子回调函数, 整数型
参数 参数1
参数 参数2
参数 参数3
局部变量 鼠标信息, 鼠标结构
局部变量 坐标z, 坐标结构
判断开始 (参数2 = 513)
_启动窗口标题 = “你按下了鼠标左键”
默认
判断结束
判断开始 (参数2 = 514)
_启动窗口标题 = “你放开了鼠标左键”
默认
判断结束
判断开始 (参数2 = 516)
_启动窗口标题 = “你按下了鼠标右键”
默认
判断结束
判断开始 (参数2 = 517)
_启动窗口标题 = “你放开了鼠标右键”
默认
判断结束
如果真 (参数2 = 512)
api_拷贝内存 (鼠标信息, 参数3, 10)
坐标z = 鼠标信息成员2
输出调试文本 (“x=” + 到文本 (坐标zx))
输出调试文本 (“y=” + 到文本 (坐标zx))
如果真结束
返回 (api_呼叫下一钩子 (钩子句柄, 参数1, 参数2, 参数3))
子程序 _按钮2_被单击
api_释放系统钩子 (钩子句柄)
如果你只HOOK本进程得消息,可以把消息回调函数和调用钩子的函数写在一起,也就是只需要写个EXE就可以了。如果要HOOK全局消息,需要全局钩子,这样,需要把你的HOOK代码注入到系统每个进程里面去。而实现这个最好的方法,就是用DLL来实现。系统会自动把该DLL注入到所有的进程空间中。所以,不一定是必须要写DLL来HOOK
其实Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的。而钩子是Windows系统中非常重要的系统接口,用它可以截获并处理送给 其他应用程序的消息,来完成普通应用程序难以实现的功能。
可见,利用钩子可以实现许多特殊而有用的功能。因此,对于高级编程人员来说,掌握钩子的编程方法是很有必要的。
钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等。
如图所示是一全局钩子示意图
在实例程序中运用WH_GETMESSAGE钩子,这个钩子监视投递到消息队列中的Windows消息。
钩子可以分为线程钩子和系统钩子, 线程钩子监视指定线程的事件消息, 系统钩子监视系统中的所有线程的事件消息。因为系统钩子会影响系统中所有的应用程序,所以钩子函数必须放在独立的动态链接库(DLL) 中。 1. windows的钩子程序,需要用到几个sdk中的api函数。下面列出这几个函数的原型及说明:
hhook setwindowshookex(int idhook,hook_proc lpfn,hinstance hmod,dword dwthreadid);
参数说明如下:
idhook:钩子的类型
lpfn:钩子处理函数地址
hmod:包含钩子函数的模块句柄
dwthreadid:钩子的监控线程
函数说明:函数将在系统中挂上一个由idhook指定类型的钩子,监控并处理相应的特定消息。
bool unhookwindowshookex(hhook hhk);
函数说明:函数将撤销由hhk指定的钩子。
lresult callnexthookex( hhook hhk, int ncode,wparam wparam,lparam lparam );
函数说明:函数将消息向下传递,下一个钩子处理将截获这一消息。
2. 由于钩子的处理涉及到模块及进程间的数据地址问题,一般情况是把钩子整合到一个动态链接库(dll)中,VC中有三种形式的MFC DLL可供选择,即Regular statically linked to MFC DLL(标准静态链接MFC DLL)、Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。第一种DLL在编译时把使用的MFC代码链接到DLL中,执行程序时不需要其他MFC动态链接类库的支持,但体积较大;第二种DLL在运行时动态链接到MFC类库,因而体积较小,但却依赖于MFC动态链接类库的支持;这两种DLL均可被MFC程序和Win32程序使用。第三种DLL的也是动态连接,但做为MFC类库的扩展,只能被MFC程序使用。
另外,要设立一个全局数据共享数据段,以存贮一些全局变量,保留上次钩子消息事件发生时的状态。
3. Win32 DLL的入口和出口函数都是DLLMain。只要有进程或线程载入和卸载DLL时,都会调用该函数,其原型是:
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved); 其中,第一个参数表示DLL的实例句柄;第三个参数系统保留;第二个参数指明了当前调用该动态连接库的状态,它有四个可能的值:DLL_PROCESS_ATTACH(进程载入)、DLL_THREAD_ATTACH(线程载入)、DLL_THREAD_DETACH(线程卸载)、DLL_PROCESS_DETACH(进程卸载)。在DLLMain函数中可以通过对传递进来的这个参数的值进行判别,根据不同的参数值对DLL进行必要的初始化或清理工作。由于在Win32环境下,所有进程的空间都是相互独立的,这减少了应用程序间的相互影响,但大大增加了编程的难度。当进程在动态加载DLL时,系统自动把DLL地址映射到该进程的私有空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间,每个进程所拥有的相同的DLL的全局数据其值却并不一定是相同的。当DLL内存被映射到进程空间中,每个进程都有自己的全局内存拷贝,加载DLL的每一个新的进程都重新初始化这一内存区域,也就是说进程不能再共享DLL。因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。一种方法便是把这些需要共享的数据单独分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,建立一个内存共享的DLL。 建立钩子程序时需要把钩子处理整合到动态链接库中,所以例程中需要建立两个project。
1. 钩子处理动态链接库
(1) 选择mfc appwizard(dll)创建一个新project,命名为“spy”。
(2) 选择mfc extension dll类型。
(3) 创建一个新的头文件,命名为“hookh”,修改它的代码如下:
extern C LRESULT CALLBACK mouseproc(int code,WPARAM wparam,LPARAM lparam); //钩子处理函数
extern C bool WINAPI starthook(); //启动钩子函数
extern C bool WINAPI stophook(); //撤销钩子函数
extern C int WINAPI getresultl(); //取得鼠标左键单击次数的函数
extern C int WINAPI getresultr(); //取得鼠标右键单击次数的函数
(4) 修改spycpp程序代码如下:
#include hookh //包含头文件hook
#pragma data_seg(publicdata) //定义全局数据段
HHOOK hhook=NULL; //钩子句柄
HINSTANCE pinstance=NULL;//钩子模块句柄
UINT mouseclickl=0; //记录鼠标左键单击次数的变量
UINT mouseclickr=0;//记录鼠标右键单击次数
#pragma data_seg()
extern C int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ if (dwReason == DLL_PROCESS_ATTACH)
{…… //省略部分机器生成代码
new CDynLinkLibrary(SpyDLL);
pinstance=hInstance;//取得模块句柄
}
……;
}
extern C LRESULT CALLBACK mouseproc(int code, WPARAM wparam,LPARAM lparam)//钩子处理函
{
if (code<0) //若code〈0,则直接调用callnexthookex返回
return CallNextHookEx(hhook, code, wparam, lparam);
if(wparam==WM_LBUTTONDOWN)
{ mouseclickl++;//记录鼠标左键单击次数 }
if(wparam==WM_RBUTTONDOWN)
{ mouseclickr++;//记录鼠标右键单击次数 }
return CallNextHookEx(hhook, code, wparam,lparam);
}
extern C bool WINAPI starthook()//启动钩子函数
{
hhook=SetWindowsHookEx(WH_MOUSE,mouseproc,pinstance,0);//挂上钩子
if(hhook!=NULL)
return true;
else return false;
}
extern C bool WINAPI stophook() //撤销钩子函数
{ return UnhookWindowsHookEx(hhook); //撤销钩子}
extern C int WINAPI getresultl()//返回鼠标左键单击次数
{ return mouseclickl;}
extern C int WINAPI getresultr()//返回鼠标右键单击次数
{ return mouseclickr;}
(5) 修改spydef程序代码如下:
exports
stophook @2
starthook @1
getresultl @3
getresultr @4
(6) 编译project,生成spydll文件和spylib文件。 2. 建立使用钩子的应用程序
(1) 生成一个单文档的可执行文件(exe)的project。
(2) 修改资源中的主选单,增加一个选单项“监控”,下有三个子选单项,分别为“启动”、“撤销”和“取出”。
(3) 在project中加入spylib文件。
(4) 分别修改“启动”、“撤销”和“取出”选单项的command响应函数如下:
#include E:\DevStudio\MyProjects\spy\hookh //路径可不同
void CMainFrame::OnMenuitem32771() //“启动”选单项的响应函数
{ starthook(); }
void CMainFrame::OnMenuitem32772() //“撤销”选单项的响应函数
{ stophook();}
void CMainFrame::OnMenuitem32773() //“取出”选单项的响应函数
{ int resultl=getresultl();
int resultr=getresultr();
char buffer[80];
wsprintf(buffer,在程序运行期间,你共单击鼠标左键%d次,右键%d次!,resultl,resultr);
::MessageBox(this->m_hWnd,buffer,message,MB_OK);
}
编译这个project,并把spydll放到生成的可执行文件目录下,便可运行程序。运行时,选择“监控”选单中的“启动”选单项,钩子便开始工作,监视鼠标的活动情况;选择“撤销”选单项,系统便撤销钩子;选择“取出”选单项,程序便报告在监控期间,用户分别单击鼠标左键和右键的次数。
下面是我的《记录鼠标》Form1frm ,其中也用到了键盘快捷键
VERSION 500
Begin VBForm Form1
BorderStyle = 1 'Fixed Single
Caption = "记录鼠标"
ClientHeight = 4500
ClientLeft = 45
ClientTop = 435
ClientWidth = 7620
FillColor = &H000000FF&
Icon = "Form1frx":0000
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 4500
ScaleWidth = 7620
StartUpPosition = 3 '窗口缺省
Begin VBCheckBox Check1
Caption = " *** 作时是否可以看到本软件"
Height = 255
Left = 4560
TabIndex = 14
Top = 240
Value = 1 'Checked
Width = 3015
End
Begin VBTextBox Tttex
Alignment = 2 'Center
Appearance = 0 'Flat
Height = 270
Left = 3480
Locked = -1 'True
TabIndex = 13
Text = "0<>0"
Top = 570
Width = 1815
End
Begin VBCommandButton Command6
Caption = "退出 (&E)"
Height = 375
Left = 6120
TabIndex = 12
Top = 3960
Width = 1335
End
Begin VBTimer Timer3
Enabled = 0 'False
Interval = 1000
Left = 3600
Top = 4320
End
Begin VBTextBox Text2
Alignment = 2 'Center
Appearance = 0 'Flat
Height = 270
Left = 3480
TabIndex = 7
Text = "20"
Top = 240
Width = 615
End
Begin VBCommandButton Command5
Caption = "清空录制 (&Z)"
Height = 375
Left = 3000
TabIndex = 6
Top = 3480
Width = 1335
End
Begin VBTextBox Text1
Appearance = 0 'Flat
Height = 270
Left = 3480
TabIndex = 5
Text = "D:\鼠标记录text"
Top = 900
Width = 3975
End
Begin VBCommandButton Command4
Caption = "打开录制 (&V)"
Height = 375
Left = 3000
TabIndex = 4
Top = 3960
Width = 1335
End
Begin VBCommandButton Command3
Caption = "保存录制 (&B)"
Height = 375
Left = 4560
TabIndex = 3
Top = 3960
Width = 1335
End
Begin VBListBox List1
Height = 4200
ItemData = "Form1frx":324A
Left = 120
List = "Form1frx":324C
TabIndex = 2
Top = 120
Width = 2295
End
Begin VBCommandButton Command2
Caption = "回放录制 (&C)"
Height = 375
Left = 6120
TabIndex = 1
Top = 3480
Width = 1335
End
Begin VBTimer Timer2
Enabled = 0 'False
Interval = 20
Left = 3000
Top = 4320
End
Begin VBTimer Timer1
Enabled = 0 'False
Interval = 20
Left = 2400
Top = 4320
End
Begin VBCommandButton Command1
Caption = "开始录制 (&X)"
Height = 375
Left = 4560
TabIndex = 0
Top = 3480
Width = 1335
End
Begin VBLabel Label5
Caption = "用法"
Height = 1935
Left = 2520
TabIndex = 11
Top = 1440
Width = 4935
End
Begin VBLabel Label4
Caption = "保存地址:"
Height = 255
Left = 2520
TabIndex = 10
Top = 960
Width = 1575
End
Begin VBLabel Label3
Caption = "当前位置:"
Height = 255
Left = 2520
TabIndex = 9
Top = 600
Width = 1455
End
Begin VBLabel Label2
Caption = "回放速度:"
Height = 255
Left = 2520
TabIndex = 8
Top = 300
Width = 1215
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
'获得鼠标点
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
'移到鼠标点
Private Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
'按下键盘
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
'鼠标键 - 要求按下
Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Private Const MOUSEEVENTF_LEFTDOWN = &H2 ' left button down
Private Const MOUSEEVENTF_LEFTUP = &H4 ' left button up
Private Const MOUSEEVENTF_RIGHTDOWN = &H8 ' right button down
Private Const MOUSEEVENTF_RIGHTUP = &H10 ' right button up
Private Const MOUSEEVENTF_MIDDLEDOWN = &H20 ' middle button down
Private Const MOUSEEVENTF_MIDDLEUP = &H40 ' middle button up
'锁定,鼠标和键盘
Private Declare Function BlockInput Lib "user32" (ByVal fEnable As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'定义
Dim xxx, yyy
Dim SSSDDD As String
Dim CC
'鼠标点类型
Private Type POINTAPI
x As Long
y As Long
End Type
'获得键盘按下
Private Function MyHotKey(vKeyCode) As Boolean
MyHotKey = (GetAsyncKeyState(vKeyCode))
End Function
'获得鼠标键按下
Private Function MyKey(vbKeyLButton) As Boolean
MyKey = GetAsyncKeyState(vbKeyLButton)
End Function
Private Sub Form_Load()
CC = "记录鼠标"
SSSDDD = "0"
Timer1Enabled = True
Timer2Enabled = False
Timer3Enabled = False
Label5Caption = "用法:1 开始录制时按下 A 键停止录制;" & vbCrLf & _
" 2 本软件还可以按下 S 锁定鼠标和键盘,不可移动;" & vbCrLf & _
" 3 本软件还可以按下 D 锁定鼠标和键盘,可移动;" & vbCrLf & _
" 4 每个控制都有一个快捷键,就是每个按钮后括号内。" & vbCrLf & _
vbCrLf & vbCrLf & vbCrLf & vbCrLf & vbCrLf & _
" " & AppTitle + "( 版本 " & AppMajor & "" & AppMinor & "" & AppRevision & " )" '当前版本号是
End Sub
'速度
Private Sub Text2_KeyPress(KeyAscii As Integer)
'文本中只能输入( 0123456789 )数字
If InStr(1, "0123456789", UCase(Chr(KeyAscii)), 1) <= 0 Then KeyAscii = 0
End Sub
Private Sub Text2_Change()
If Text2Text > 0 Then Timer2Interval = Text2Text
End Sub
'读保文件
Private Sub Command3_Click() 'List1 保存 txt
Dim fn As Integer, i As Integer
fn = FreeFile
Open Text1Text For Output As #1
For i = 0 To List1ListCount - 1
Print #1, List1List(i)
Next
Close #1
MsgBox "成功保存到: " & Text1Text
End Sub
Private Sub Command4_Click() 'List1 读取 txt
List1Clear '清空
Open Text1Text For Input As #1
Do While Not EOF(1)
Line Input #1, Temp
List1AddItem Temp
Loop
Close #1
End Sub
'清空List1
Private Sub Command5_Click()
List1Clear
End Sub
'回放录制
Private Sub Command2_Click()
ShFu
If List1ListCount > 0 Then
List1ListIndex = 1
Form1Caption = "记录鼠标 - 正在回放"
Timer2Enabled = True
End If
End Sub
Private Sub Timer2_Timer()
Dim x
List1ListIndex = List1ListIndex - 0 + 1
x = Split(List1Text, "<>")
SetCursorPos x(0), x(1) '你所需要点的位置
If x(2) = "左" Then ZuoDanJi
If x(2) = "中" Then ZongDanJi
If x(2) = "右" Then YouDanJi
If List1ListIndex >= List1ListCount - 1 Then Form1Caption = "记录鼠标": CC = "停锁记录鼠标": YhFu: Timer2Enabled = False
End Sub
'鼠标左键点击
Private Sub ZuoDanJi()
mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0&, 0&, 0&, 0& '模拟鼠标点击
End Sub
'鼠标中键点击
Private Sub ZongDanJi()
mouse_event MOUSEEVENTF_MIDDLEDOWN Or MOUSEEVENTF_MIDDLEUP, 0&, 0&, 0&, 0& '模拟鼠标点击
End Sub
'鼠标右键点击
Private Sub YouDanJi()
mouse_event MOUSEEVENTF_RIGHTDOWN Or MOUSEEVENTF_RIGHTUP, 0&, 0&, 0&, 0& '模拟鼠标点击
End Sub
'开始录制
Private Sub Command1_Click()
ShFu
Form1Caption = "记录鼠标 - 正在录制(按下A键停止)"
End Sub
'录制
Private Sub Tttex_Change()
If Form1Caption = "记录鼠标 - 正在录制(按下A键停止)" Then List1AddItem TttexText
End Sub
Private Sub Timer1_Timer()
Dim MousG
If MyKey(vbKeyLButton) Then MousG = "左"
If MyKey(vbKeyMButton) Then MousG = "中"
If MyKey(vbKeyRButton) Then MousG = "右"
Dim P1 As POINTAPI
GetCursorPos P1
TttexText = P1x & "<>" & P1y & "<>" & MousG
MousG = "0"
'快捷键
If MyHotKey(vbKeyA) Then Form1Caption = "记录鼠标": CC = "停锁记录鼠标": YhFu 'A键盘按下
If MyHotKey(vbKeyX) Then Command1_Click: ShFu
If MyHotKey(vbKeyC) Then Command2_Click: ShFu
If MyHotKey(vbKeyB) Then Command3_Click
If MyHotKey(vbKeyV) Then Command4_Click
If MyHotKey(vbKeyZ) Then Command5_Click
If MyHotKey(vbKeyE) Then Command6_Click
If MyHotKey(vbKeyS) Then SSS: ShFu
If MyHotKey(vbKeyD) Then DDD: ShFu
End Sub
'锁定,鼠标和键盘
Private Sub Timer3_Timer()
If SSSDDD > 0 Then SSSDDD = SSSDDD - 1
If CC = "不可移动" Then Form1Caption = "记录鼠标 - 锁定鼠标和键盘不可移动 " & SSSDDD & "秒后解锁"
If CC = "可移动" Then Form1Caption = "记录鼠标 - 锁定鼠标和键盘可移动 " & SSSDDD & "秒后解锁"
If SSSDDD < 1 Then
BlockInput (0)
Form1Caption = "记录鼠标"
CC = "停锁记录鼠标"
Timer3Enabled = False
YhFu
End If '恢复
End Sub
Private Sub SSS()
Form1Caption = "记录鼠标 - 锁定鼠标和键盘,不可移动"
SSSDDD = InputBox("提示", "请问你想锁定多少秒?", "10")
CC = "不可移动"
Timer3Enabled = True
BlockInput (5) '锁定,不可移动
End Sub
Private Sub DDD()
Form1Caption = "记录鼠标 - 锁定鼠标和键盘,可移动"
SSSDDD = InputBox("提示", "请问你想锁定多少秒?", "10")
CC = "可移动"
Timer3Enabled = True
Call Sleep(SSSDDD) '锁定,可移动
End Sub
' *** 作时是否可以看到本软件
Private Sub ShFu() '
If Check1Value = 0 Then Form1Hide '隐藏
End Sub
Private Sub YhFu() '
If CC = "停锁记录鼠标" Then
Form1Show '显示
CC = "鼠标记录"
End If
End Sub
'删除List1中的一行
Private Sub List1_DblClick() '
List1RemoveItem List1ListIndex
End Sub
'退出
Private Sub Command6_Click()
End
End Sub
简单来说钩子就是系统触发一定事件下要进行 *** 作的函数,但是不同的事件会有不同的附加信息,所以根据不同的事件也会在那个三个参数中传递不同的附加内容,就是处理方法的结构必须和系统定义好的结构相同才可以
下面是附加资料可以看一下
------------------------------------------------------------------------------------------------
首先说明一点,你的问题问得不是很恰当,因为钩子函数是回调函数,由系统规定参数,并传递参数,由你写好内容,然后由系统在一定触发条件下调用
例如你建立的是WH_MOUSE钩子, 那么MouseProc的三个参数由 *** 作系统(实际上是WIN32 平台)传递进来,意义分别是nCode怎么处理消息, wParam消息标识, lParam是一个MOUSEHOOKSTRUCT结构指针,而我们要做的就是利用这三个参数来完成自己想实现的功能,这正是回调函数的意义!
一般做钩子用到三个函数, 主要解决的是钩子函数的定义:
钩子有局部和远程两种类型, 与钩子相关的函数有:
1 建立钩子:SetWindowsHookEx, 其四个参数分别为钩子类型, 钩子函数地址, 钩子函数所在DLL的实例句柄,安装钩子后想监控的线程的ID号, 返回参数为钩子句柄
2 UnhookWindowsHookEx, 参数只有一个,为要卸载的钩子句柄
3 钩子函数(名称任意), 三个参数, 具体意义与钩子类型有关
下面再举一个简单例子:
比如你想写一个程序, 当鼠标移到哪里时就在主程序中显示鼠标所在窗口的名称
--------------------
(1)如果鼠标只是局限在窗口内, 那么以上1, 2, 3三个函数均写在运行的主程序中, 比如函数1可以写在按下某个按钮的消息响应函数中,函数 2 写在松开按扭的消息响应函数中,函数 3 只要不写在别的函数中就行, 因为它本生就是一个要定义的独立函数
(2)如果鼠标可以在屏幕任意位置移动, 那么以上函数1, 2位置同(1), 但函数3要写在一个另外写的DLL里, 因为此时安装的是全局钩子, 为了达到获取窗口名称的目的, 在DLL里可能还要做一些其他工作,比如设置共享段, 关于这些这里不细说了
------------------------
如果你想问的是如何填充SetWindowsHookEx的参数 或 钩子函数的三个参数的具体意义, 那么可以参考MSDN, 因为参数与钩子类型, 要挂钩的消息有关
键盘钩子分几种,有进程钩子,就是只是捕获某一个特定进程的键盘输入。有程序钩子,只捕获某一个程序的键盘输入。还有全局钩子,可以捕获所有进程或者程序的键盘输入。捕获就是说钩子程序能获取你输入的信息,比方说原来有一些QQ木马就是安装键盘钩子,用于记录你输入的QQ号和密码,又或者一些游戏的盗号程序就是这样的。
建议进行查杀
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)