通过记录键盘和鼠标位置和输入信息,然后模拟发送,就能够创建一个按键精灵!

主要代码如下:

 library KeyBoardHook;

 { Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. } uses
SysUtils,
Classes,
Windows,
Messages; type
TCallBackFun=procedure(info:PChar);
TKeyBoardHook=record
isrun:Bool;
hook:HHook;
callBackFun:TCallBackFun;
end; var
myKeyBoardHook:TKeyBoardHook;
{$R *.res} function GetKeyBoardInfo(code:Integer;wp:WPARAM;lp:LPARAM):LRESULT;stdcall;
var
info:string;
begin
if code< then
begin
Result:=CallNextHookEx(myKeyBoardHook.hook,code,wp,lp);
Exit;
end;
info:='';
if ((DWord(lp) shr )=) and (code=HC_ACTION) then
if ((DWord(lp) shr )=) then
info:='WM_SYSKEYUP'
else
info:='WM_KEYUP'
else
if ((DWord(lp) shr )=) then
info:='WM_SYSKEYDOWN'
else
info:='WM_KEYDOWN';
info:=info+','+inttostr(wp)+','+inttostr(lp);
if Assigned(myKeyBoardHook.callbackFun) then
myKeyBoardHook.callbackFun(pchar(info));
Result := CallNextHookEx(myKeyBoardHook.hook,code,wp,lp);
end; procedure InstallKeyBoardHook(callback:TCallBackFun);stdcall;
begin
if not myKeyBoardHook.isrun then
begin
myKeyBoardHook.hook:=SetWindowsHookEx(WH_KEYBOARD,@GetKeyBoardInfo,HInstance,);
myKeyBoardHook.callBackFun:=callBack;
myKeyBoardHook.isrun:=not myKeyBoardHook.isrun;
end;
end; procedure UninstallKeyBoardHook();stdcall;
begin
if myKeyBoardHook.isrun then
begin
UnHookWindowsHookEx(myKeyBoardHook.hook);
myKeyBoardHook.callBackFun:=nil;
myKeyBoardHook.isrun:=not myKeyBoardHook.isrun;
end;
end; Procedure DLLEntryPoint(dwReason:DWord);
begin
Case dwReason of
DLL_PROCESS_ATTACH:begin
myKeyBoardHook.isrun:=false;
end;
DLL_PROCESS_DETACH:;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
End;
end; exports
InstallKeyBoardHook,
UninstallKeyBoardHook; begin
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

以上是创建一个全局钩子函数的Dll来记录按键信息

library Mousehook;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library's USES clause AND your project's (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. } uses
SysUtils,
Classes,
Windows,
Messages,
ShellAPI; type
TCallbackFun=procedure(info:pchar);
TMouseHook=record
isrun:Bool;
hook:HHook;
callbackFun:TCallbackFun;
end; var
myMouseHook:TMouseHook; {$R *.res}
//.定义自定义的HOOK函数,函数必须和需要HOOK的钩子类型保持同样的参数列表
function GetHookInfo(code:Integer;wp:WPARAM;lp:LPARAM):LResult;stdcall;
var
info:String;
begin
if code< then
begin
Result:=CallNextHookEx(myMouseHook.hook,code,wp,lp);
Exit;
end;
info:='';
case wp of
//鼠标消息共有21种,其中10种点击是客户区,种是非客户区也就是消息名以NC开头的消息。和一个命中测试消息
WM_LBUTTONDOWN:begin
info:='WM_LBUTTONDOWN';
end;
WM_LBUTTONUP:begin
info:='WM_LBUTTONUP';
end;
WM_LBUTTONDBLCLK:begin
info:='WM_LBUTTONDBLCLK';
end;
WM_RBUTTONDOWN:begin
info:='WM_RBUTTONDOWN';
end;
WM_RBUTTONUP:begin
info:='WM_RBUTTONUP';
end;
WM_RBUTTONDBLCLK:begin
info:='WM_RBUTTONDBLCLK';
end;
WM_MBUTTONDOWN:begin
info:='WM_MBUTTONDOWN';
end;
WM_MBUTTONUP:begin
info:='WM_MBUTTONUP';
end;
WM_MBUTTONDBLCLK:begin
info:='WM_MBUTTONDBLCLK';
end;
WM_MOUSEMOVE:begin
info:='WM_MOUSEMOVE';
end;
WM_NCMouseMove:begin
info:='WM_NCMouseMove';
end;
WM_MOUSEWHEEL:
begin
info:='WM_MOUSEWHEEL';
end;
WM_NCHITTEST:begin
info:='WM_NCHITTEST';
end;
WM_NCLBUTTONDOWN:BEGIN
info:='WM_NCLBUTTONDOWN';
end;
WM_NCLBUTTONUP:BEGIN
info:='WM_NCLBUTTONUP';
end;
WM_NCLBUTTONDBLCLK:BEGIN
info:='WM_NCLBUTTONDBLCLK';
end;
WM_NCRBUTTONDOWN:BEGIN
info:='WM_NCRBUTTONDOWN';
end;
WM_NCRBUTTONUP:BEGIN
info:='WM_NCRBUTTONUP';
end; WM_NCRBUTTONDBLCLK:BEGIN
info:='WM_NCRBUTTONDBLCLK';
end;
end;
info:=info+','+inttostr(PMouseHookStruct(lp)^.wHitTestCode)+ ','+inttostr(MakeLParam(PMouseHookStruct(lp)^.pt.x,PMouseHookStruct(lp)^.pt.Y));
if Assigned(myMouseHook.callbackFun) then
myMouseHook.callbackFun(pchar(info));
Result := CallNextHookEx(myMouseHook.hook,code,wp,lp);
end; procedure InstallMouseHook(callbackF:Tcallbackfun);stdcall;
begin
if not myMouseHook.isrun then
begin
{2.设置钩子函数
setwindowhookEx参数说明
参数idHook指定建立的监视函数类型。
参数lpfn指定消息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为:
Hookproc (code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT stdcall;
其中code为系统指示标记(对应于idHook),wParam和lParam为附加参数,根据不同的消息监视类型而不同。
只要在程序中建立这样一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。
}
myMouseHook.hook:=setwindowshookex(WH_MOUSE,@gethookinfo,HInstance,);
myMouseHook.callbackfun:=callbackf;
myMouseHook.isrun:=not mymousehook.isrun;
end;
end; procedure UninstallMouseHook();stdcall;
begin
if myMouseHook.isrun then
begin
UnHookWindowsHookEx(mymousehook.hook);
myMouseHook.callbackfun :=nil;
myMouseHook.isrun:=not myMouseHook.isrun;
end;
end; Procedure DLLEntryPoint(dwReason:DWord);
begin
Case dwReason of
DLL_PROCESS_ATTACH:begin
myMouseHook.isrun:=false;
end;
DLL_PROCESS_DETACH:;
DLL_THREAD_ATTACH:;
DLL_THREAD_DETACH:;
End;
end; exports
InstallMouseHook,
UninstallMouseHook; begin
DLLProc := @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
end.

以上是捕获鼠标消息的全局钩子DLL

使用一个新的线程来模拟发送消息

procedure TPlayThread.Execute;
var
directive:string;
i:integer;
ForgroundForm:TForm;
procedure ExecuteDir(directive:string);
var
tempList:TStringList;
Wp,Lp:integer;
wmtype:String;
focusControl:string;
duration:Cardinal;
winCtl:TWinControl;
tempHandle,focusHandle:THandle;
classname:String;
mousPoint:TPOINT;
procedure findFocus;
var
temp:TWinControl;
finded:Boolean;
begin
if ((wmtype='WM_MOUSEMOVE') or (wmtype='WM_NCMouseMove')) then Exit;
winCtl:=TWinControl(ForgroundForm.FindChildControl(focusControl)); if winCtl<>nil then
begin
focusHandle:= winCtl.Handle;
AttachThreadInput(GetWindowThreadProcessId(ForgroundForm.Handle,nil),Self.ThreadID,True);
Ferrorinfo:=SysErrorMessage(GetLastError);
winCtl.SetFocus;
AttachThreadInput(GetWindowThreadProcessId(ForgroundForm.Handle,nil),Self.ThreadID,False);
Ferrorinfo:=SysErrorMessage(GetLastError);
Exit;
end;
temp:=nil;
finded:=False;
while not finded do
begin
GetCursorPos(mousPoint);
tempHandle := WindowFromPoint(mousPoint);
if tempHandle = then
begin
Sleep();
Continue;
end;
temp:=FindControl(tempHandle);
if temp=nil then
begin
Sleep();
Continue;
end;
if (temp.Name = focusControl) or (classname=temp.ClassName) then
finded:=True;
end;
focusHandle := temp.Handle;
AttachThreadInput(GetWindowThreadProcessId(ForgroundForm.Handle,nil),Self.ThreadID,True);
Ferrorinfo:=SysErrorMessage(GetLastError);
temp.SetFocus;
AttachThreadInput(GetWindowThreadProcessId(ForgroundForm.Handle,nil),Self.ThreadID,False);
Ferrorinfo:=SysErrorMessage(GetLastError);
end;
begin
tempList:=TStringList.Create;
try
tempList.CommaText:=directive;
tempList.Delimiter:=',';
wmtype:=tempList[];
focusHandle:=;
Wp:=StrToIntDef(tempList[],); //wParam
Lp:=StrToIntDef(tempList[],); //Lparam duration:= StrToIntDef(tempList[],);
if (duration=) and (wmtype='WM_NCMouseMove') then Exit; //小于线程调度时间片的话就不延时---以免 sleep()直接放弃时间进入内核态
if (wmtype='') or (tempList.Count<) then Exit;
focusControl :=tempList[];
classname := tempList[]; findFocus;
//鼠标消息
if wmtype='WM_LBUTTONDOWN' then TInputHelper.MouseLButtonDown(focusHandle,Wp,Lp)
else if wmtype='WM_LBUTTONUP' then TInputHelper.MouseLButtonUp(focusHandle,Wp,Lp,True)
else if wmtype='WM_LBUTTONDBLCLK' then TInputHelper.MouseLButtonDbClick(focusHandle,Wp,Lp,True)
else if wmtype='WM_RBUTTONDOWN' then TInputHelper.MouseRButtonDown(focusHandle,Wp,Lp,True)
else if wmtype='WM_RBUTTONUP' then TInputHelper.MouseRButtonUp(focusHandle,Wp,Lp,True)
else if wmtype='WM_RBUTTONDBLCLK' then TInputHelper.MouseRButtonDbClick(focusHandle,Wp,Lp,True)
else if wmtype='WM_MBUTTONDOWN' then TInputHelper.MouseMButtonDown(focusHandle,Wp,Lp,True)
else if wmtype='WM_MBUTTONUP' then TInputHelper.MouseMButtonUp(focusHandle,Wp,Lp,True)
else if wmtype='WM_MBUTTONDBLCLK' then TInputHelper.MouseMButtonDbClick(focusHandle,Wp,Lp,True)
else if wmtype='WM_MOUSEMOVE' then TInputHelper.MouseMove(focusHandle,Wp,Lp,True)
else if wmtype='WM_MOUSEWHEEL' then TInputHelper.MouseWHEEL(focusHandle,Wp,Lp,True)
//鼠标非客户区
else if wmtype='WM_NCMouseMove' then TInputHelper.MouseNCMouseMove(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCHITTEST' then TInputHelper.MouseNCHITTEST(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCLBUTTONDOWN' then TInputHelper.MouseNCLBUTTONDOWN(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCLBUTTONUP' then TInputHelper.MouseNCLBUTTONUP(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCLBUTTONDBLCLK' then TInputHelper.MouseNCLBUTTONDBLCLK(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCRBUTTONDOWN' then TInputHelper.MouseNCRBUTTONDOWN(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCRBUTTONUP' then TInputHelper.MouseNCRBUTTONUP(focusHandle,Wp,Lp,True)
else if wmtype='WM_NCRBUTTONDBLCLK' then TInputHelper.MouseRButtonDbClick(focusHandle,Wp,Lp,True)
//键盘消息
else if wmtype='WM_KEYDOWN' then TInputHelper.KeyDown(focusHandle,Wp,Lp,True)
else if wmtype='WM_KEYUP' then TInputHelper.KEYUP(focusHandle,Wp,Lp,True)
else if wmtype='WM_SYSKEYDOWN' then TInputHelper.KeySYSKEYDOWN(focusHandle,Wp,Lp,True)
else if wmtype='WM_SYSKEYUP' then TInputHelper.KeySYSKEYUP(focusHandle,Wp,Lp,True);
Application.ProcessMessages;
Sleep(duration);
finally
tempList.Free;
end;
end;
begin
Sleep();
try
ForgroundForm :=InputRecord.ForgroundForm;
for i:= to PosList.Count- do
begin
directive:=PosList[i];
ExecuteDir(directive);
end;
finally
InputRecord.FIsPlay:=False;
end; end;

点击这里下载代码

【笨嘴拙舌WINDOWS】实践检验之按键精灵【Delphi】的更多相关文章

  1. 按键精灵 句柄 获得句柄 控制windows窗口 后台

    新建一个文本文档,打开,Windows就会给这个文本文档的窗口临时分配唯一的一串数字来标识这个窗体,以区别于其他窗口,这串数字就叫句柄.   因为句柄是临时随机分配的,所以每次虽然是打开同一个文件,但 ...

  2. [教程] 以本论坛为例,手把手教你使用按键精灵POST登陆网页

    本帖最后由 isaacc 于 2012-2-26 11:08 编辑 整个操作,很无脑.只要你够勤快,你学不会,你来咬我.懒人和伸手党就直接复制代码去玩吧,但我不是叫你拿去干坏事. 准备工具:WPE和I ...

  3. 按键精灵对APP自动化测试(下)

    上一篇介绍了安卓app上使用按键精灵的实践,这里再来说说苹果上的app. 由于iOS相关工具对操作系统的限制,目前在iOS10.0.2系统上应用成功. 二.       苹果手机按键精灵APP录制 适 ...

  4. QQ2008自动聊天精灵delphi源码

    QQ2008自动聊天精灵delphi源码   unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Grap ...

  5. 【按键精灵篇】如何做一个自动打开APP进入注册页面自动输入自己手机号

    按键精灵,虽然很早听过,但是一直没有真正使用过,所以最近有点时间也简单试一下,通过脚本自动清理APP缓存,打开百家号并自动进入注册页面输入自己的手机号. 软件清单 1. 雷电手机模拟器:https:/ ...

  6. 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)

    本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...

  7. 按键精灵*ff

    Function gethttp(URL) Set objXML=CreateObject("Microsoft.XMLHTTP") objXML.Open "Get&q ...

  8. 按键精灵对APP自动化测试(上)

    简单介绍下应用背景:测试安卓app时发现重复点击某一按钮的时候会出现报错,开发修复后提交测试.如果采用手动点击按钮,效率不高,在领导提示下使用按键精灵实现自动操作. 一.       安卓手机按键精灵 ...

  9. 按键精灵与逍遥安卓ADB连接重键方法

    1.按键精灵与逍遥安卓ADB连接安装按键精灵与逍遥安卓这两个软件我不用多说了.安装好后把逍遥安卓安装目录下的三个文件adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll 全部复 ...

随机推荐

  1. 在centos 6.5 在virtual box 上 安装增强版工具

    centos 6.5 在virtual box 上 安装增强版工具: 出现:centos unable to find the source of your current linux kernel ...

  2. POJ 1986 Distance Queries (最近公共祖先,tarjan)

    本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE.后来果断尝试下开了400000的大小,AC.题意:给出n个 ...

  3. UITableView多选删除

    设置一个在编辑状态下点击可改变图片的cell FileItemTableCell.h #import <UIKit/UIKit.h> @interface FileItemTableCel ...

  4. AwSnap:让全版本(Windows、iOS、Android)Chrome浏览器崩溃的有趣漏洞

    彩蛋爆料直击现场 几周前,我们曾报道了13个字符导致Chrome崩溃的漏洞.然而,这个漏洞有个小小的遗憾,那就是它只在MAC OS X下生效,其他系统并不受影响. 现在,我们又有了一个更有趣的漏洞.黑 ...

  5. DF学Mysql(二)——数据表的基本操作

    1.创建数据表 先使用“USE <数据库名>”指定在哪个数据库中操作 CREATE TABLE <表名> ( 字段1 数据类型 [列级别约束条件] [默认值], 字段2 数据类 ...

  6. linux查看硬件信息及驱动设备相关整理

    查看声卡设备:cat /proc/asound/cards 查看USB设备:cat /proc/bus/usb/devices 常用命令整理如下:用硬件检测程序kuduz探测新硬件:service k ...

  7. hdu 4111 Alice and Bob(中档博弈题)

    copy VS study 1.每堆部是1的时候,是3的倍数时输否则赢: 2.只有一堆2其他全是1的时候,1的堆数是3的倍数时输否则赢: 3.其他情况下,计算出总和+堆数-1,若为偶数,且1的堆数是偶 ...

  8. MDK5.01百度云下载,安装微软雅黑混合字体,字体效果很棒,解决显示中文的BUG

    微软雅黑字体http://pan.baidu.com/s/1nt9Epuh 初步尝试,以前的小BUG都已经解决了.下面是安装雅黑字体后的字体效果,很爽.第一步:安装雅黑字体.第二步:选择Edit--- ...

  9. WordPress插件:幻灯片Meta Slider

    在wordpress中添加幻灯片的方法很简单,通过使用Meta Slider就可以简单地给wordpress添加幻灯片. 插件下载>> 安装后启用插件,根据提示创建幻灯片: 设置幻灯片样式 ...

  10. intellij idea搭建ssh开发框架之绑定数据源

    原文:intellij idea搭建ssh开发框架之绑定数据源 在intellij idea中绑定数据源并生成hibernate实体对象.在IDE中的右边找到Database标签. 点击弹出窗口中的图 ...