标题:[求助]关于全局HOOK的一点疑问
只看楼主
redice
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:902
专家分:0
注 册:2006-12-11
结帖率:72.73%
 问题点数:0 回复次数:0 
[求助]关于全局HOOK的一点疑问

关于全局HOOK的一点疑问
RedIce 2007.5.16
玩过HOOK的朋友都知道当SetWindowsHookEx函数的最后一个参数取值为0时,表示安装的是一个全局HOOK。同时该函数还要求当最后一个参数为0时,第三个参数必须为一DLL的句柄。用VB能写DLL吗?我以前只知道VC可以写。在网上搜索了一番我发现了一个宝贝”VB_DLL_LINK” 一个能用VB直接生成“能直接导出函数”的DLL。于是在这个程序帮助下我写了一个名为”Hook.dll”的DLL(其代码如下)。但是经过我测试该钩子并不是一个全局钩子,仔细检查仍无结果,很是疑惑,请高手指导….
附一:VB.dll 的代码
'************************************HOOK.DLL*****************************
'作者:Redice@轻风工作室
‘说明:该钩子过程将屏蔽A键
'******************************************************************************
'***********************************API函数声明*******************************
Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
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 CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
'******************************************************************************
'*********************************定义变量/常量********************************
Public HookId As Long
Public Const WH_KEYBOARD = 2
'******************************************************************************
'************************************DLL的入口代码***************************
‘按照“VB_DLL_LINK”的说明 在模块中需要加入这一“DLL的入口过程”
Function DLLMain(ByVal hInstDLL As Long, ByVal fdwReason As Long, ByVal lpwReserved As Long) As Long
DLLMain = 1
End Function
'******************************************************************************
‘按照“VB_DLL_LINK”的说明 在模块中需要加入这函数,否则编译将出错
Sub Main()
End Sub
'************************************自定义函数/过程****************************
Public Function SetHook() As Long
Dim Hmodule As Long
Hmodule = GetModuleHandle("HOOK.DLL")
HookId = SetWindowsHookEx(WH_KEYBOARD, AddressOf HookFunc, Hmodule, 0)
End Function
Public Function HookFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
HookFunc = 0 '表示要处理这个讯息
If wParam = vbKeyA Then
MsgBox "A被按下!", 0, "注意"
HookFunc = 1 '在这个Hook便吃掉这个讯息
End If
Call CallNextHookEx(HookId, iCode, wParam, lParam) '传给下一个Hook
End Function
Public Function UnHook() As Long
UnhookWindowsHookEx HookId
HookId = 0
End Function
'******************************************************************************
附 二 :测试程序”vbhook”代码
‘首先将上面生成的”hook.dll”放在 该测试程序vbhook的目录下
Private Declare Function SetHook Lib "hook.dll" () As Long
Private Declare Function UnHook Lib "hook.dll" () As Long
Private Sub Command1_Click()
Call SetHook
End Sub
Private Sub Command2_Click()
Call UnHook
End Sub
‘运行后 点击 Command1安装Hook 然后按下”A” 果然出现了MsgBox "A被按下!" 但是当我将该程序最小化后 ,再按下”A”键 却没有看到该提示 再打开一个记事本 竟然还能输入”A” 郁闷 为什么是这样 ????

附 三:VB_DLL_LINK 说明
VB制作可输出函数的通用DLL---VB_DLL_Link用法

大家知道,VB6只能制作ActiveX DLL文件,制作能输出函数的通用DLL文件通常要用到VC等工具。实际上,VB在编译的时候加以控制,经过适当处理也是可以制作通用DLL的。使用VB_DLL_Link程序就可以利用VB编译出通用的DLL文件,此DLL文件可以被其他程序调用,例如在VB中用Declare语句调用并执行DLL中的函数。下面介绍VB_DLL_Link的使用方法:

1、安装:
本软件为纯绿色软件。下载VB_DLL_Link.exe后,双击它就可以自动安装了。你也可以手动将它复制到VB6程序目录下,将原Link.exe改名为Link2.exe,再将VB_DLL_Link.exe改名为Link.exe即可。


2、生成DLL:
安装好VB_DLL_Link后,打开VB6,新建标准exe工程,工程菜单>>移除Form1,添加一个标准模块如Module1.bas,首先向其中写入DLL的入口代码:
Function DLLMain(ByVal hInstDLL As Long, ByVal fdwReason As Long, ByVal lpwReserved As Long) As Long
DLLMain = 1
End Function
注意参数形式一定要正确,否则编译失败。高级编程时这些参数很有用。在首次调用DLL和调用DLL的原程序退出时均会执行DLLMain函数。这个函数是必须的。

为了使VB不报错,还需加入以下代码:
Sub Main()
'确保VB能编译
End Sub


然后就可以向Module1.bas中写入自定义函数代码了,如:
Function Add(ByVal A As Double, ByVal B As Double) As Double
MsgBox A + B
Add = A + B
End Function
Private Sub M(s As String)
MsgBox s, vbInformation
End Sub


编写好代码后,保存工程,选择文件菜单>>生成exe,注意将文件扩展名改为.dll,否则本软件不能调出。然后本程序就会运行,出现一个对话框提示选择此工程需要导出的函数所在的模块文件,此例即Module1.bas,选择好后本程序主窗口会列出Module1.bas中所有的函数名。如果有多个模块,可以选择"从模块添加"按钮继续添加函数名。"添加函数名"按钮可手动添加现存的函数的名称。然后勾选需要导出的函数名,点击"编译为能输出函数的DLL"按钮,即可编译出通用DLL文件了,它能输出函数列表中打勾的所有函数。若不需要编译为通用DLL,请点击"常规编译"或按Esc键。


3、应用DLL:
编译好的通用DLL文件,可按常规DLL文件的调用方法加以调用。如上述的例子在VB中调用方法如下(请将Lib后的字符串改为上面编译的Dll文件名):
Private Declare Function Add Lib "编译好的DLL文件的路径及名称" (ByVal A As Double, ByVal B As Double) As Double
Private Declare Sub M Lib "编译好的DLL文件的路径及名称" (s As String)
Private Sub main()
Add 9, 2 '调用DLL中的函数
M StrConv("By 同济黄正", vbUnicode) '字符串需转换成Unicode再传递
End Sub


试试看,效果怎样?


4、注意事项:
*向DLL传递字符参数时,需转换成Unicode形式StrConv(yourString, vbUnicode),才能正确使用。
*输出函数的模块建议用标准模块bas,虽然窗体模块frm和类模块cls中的函数也可以用,但有时会出错且限制多多。
*一个工程可以有多个bas模块,其间的函数均能直接输出。
*建议用Public类型的Function或Sub作为输出函数。
*上例只是一个简单的示例,实际应用中可以在DLL工程(VB的exe工程)中加入窗体、控件、模块、类模块等,实现复杂的功能。
附四 :上面所提到的测试程序”vbhook”,”hook.dll”,”VB_DLL_LINK.exe”

sPjNsQZr.rar (26.71 KB) [求助]关于全局HOOK的一点疑问


搜索更多相关主题的帖子: HOOK 全局 疑问 
2007-06-30 16:01



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-151606-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.333810 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved