马上加入TC
您需要 登录 才可以下载或查看,没有帐号?立即注册  
 
x
 
 本帖最后由 剑仙十号 于 2018-3-23 00:00 编辑  
 
【hook教程】按住某键_则高速连发,松开即停止。 
  
求一个脚本,按住某键_能高速连续触发,松开即停止。 
活着_viva_  
1楼6-14 23:23 
萌新急用,有大佬发个教程或者有现成的都行。 
 
======================================================= 
这个必须用hook。拦截真实按键,放行模拟按键。 
按键精灵没有回调函数,不能写hook。 
tc简单开发 有回调函数,可以写hook。百度搜索:tc简单开发。 
 
======================================================= 
低层键盘钩子,WH_KEYBOARD_LL, 
回调函数的lParam(参数3),是一个KBDLLHOOKSTRUCT结构。 
先看看该结构,在MSDN中的解释 
typedef struct tagKBDLLHOOKSTRUCT { 
  DWORD     vkCode; 
  DWORD     scanCode; 
  DWORD     flags; 
  DWORD     time; 
  ULONG_PTR dwExtraInfo; 
} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT; 
这个结构.flags(成员3),是一个二进制0--7位。 
// 
结构体各成员的意义如下: 
VkCode:按键的虚拟键码。键盘上的每个按键对应一个虚拟键码 
ScanCode:硬件的扫描码 
Flags:按键消息的详细信息。是一些标识位的组合 
Time:时间。 
DwExtraInfo:扩展到按键消息的信息 
======================================================= 
结构.Flags,是一个二进制0--7位。各位值的标识信息如下: 
从右到左数起。 
位0:扩展键的标识位。 
1表示该键是扩展键;0表示不是。 
位1~3:保留位,一般为0。 
位4:消息类型的标识位。 
1表示消息是模拟的;0表示消息是真实的。 
. 
位5:Alt键的标识位。 
1表示Alt是按住的;0表示Alt键没有被按下 
位6:保留位,一般是0 
位7:按键的状态标识位。1表示按键是弹起的,0表示按键是按住的 
从位0 开始数起的,所以8位二进制,是从位0到位7。 
 
 
 
 
例如:1个32位 二进制数: 
00000000 00000000 00000000 01111100  
用计算器换成十进制是124。 
手动计算,过程是怎样操作的? 
. 
二进制数从右到左 读起: 
第0位是1,则表示2的0次幂,是0则忽略不计。 
第1位是1,则表示2的1次幂,是0则忽略不计。 
第2位是2的2次幂,按此类推。 
…… 
…… 
01111100  
从右往左  
位0是 0 忽略不计。 (2的0次幂 = 1) 
位1是 0 忽略不计。 (2的1次幂 = 2) 
位2是 1 。2的2次幂 = 4 
位3是 1 。2的3次幂 = 8 
位4是 1 。2的4次幂 = 16 
位5是 1 。2的5次幂 = 32 
位6是 1 。2的6次幂 = 64 
后面的都是0,则忽略不计。二进制有效位的结果相加,得出十进制结果:124。 
 
假设本次是模拟按键,位4标记为1, 
var 位4十进制 = 数学求幂(2, 4) 
2的4次幂 = 16 
 
下一步,用二进制.位与运算,判断按键来源。 
if(键盘.Flags & 16==16) 
  traceprint(“模拟按键。不拦截该按键。”) 
  拦截值 = 0 //0值为不处理消息。 
elseif(键盘.Flags & 16==0) 
  traceprint(“物理按键。拦截该按键。”) 
  拦截值 = 1 //非0值为处理该消息。 
end 
 
======================================================= 
代码例子: 
var Key = 数组() 
功能 连发脚本_初始化() 
//把数组定义成结构体. 
Key["vkCode"]  = 数组("long" = 1 ,"value" = 0) 
Key["ScanCode"]  = 数组("long" = 1 ,"value" = 0) 
Key["Flags"]  = 数组("long" = 1 ,"value" = 0) 
Key["Time"]  = 数组("long" = 1 ,"value" = 0) 
Key["DwExtraInfo"]  = 数组("long" = 1 ,"value" = 0) 
结束 
 
功能 Keyback(ncode, wparam, lparam) 
var 拦截值 
/* 
aj,tc,易语言的变量,都没有指针类型。 
所以调用系统API,RtlMoveMemory(),把回调函数_参数3中的数据,复制到刚才定义的结构体中。 
查询MSDN,RtlMoveMemory()参数1是结构体指针。参数1的数据类型,定义为上一步的结构体1。勾选传址。 
var bool_va= dllcall("kernel32.dll","long","RtlMoveMemory", "pstruct",Key, "long",lparam, "long",20) 
*/ 
 
/* 
tc中没有二进制.位运算,先用易语言封装一个二进制.位与运算,编译生存dll文件,放到tc资源目录中调用。 
var ret = dllcall("rc:Bit.dll", "long", "Bitand", "long", Key["Flags"]["value"], "long", 16) 
if(ret==16) 
traceprint(“模拟按键。不拦截按键。”) 
拦截值 = 1 
elseif(ret==0) 
traceprint(“真实按键。拦截该按键。”) 
拦截值 = CallNextHookEx(0, ncode, wparam, lparam) 
end 
*/ 
return 拦截值 
结束 
 
功能 sethook() 
  //代码. 
结束 
 
功能 unsethook() 
  //代码. 
结束 
 |