【笨嘴拙舌WINDOWS】实践检验之按键精灵【Delphi】
通过记录键盘和鼠标位置和输入信息,然后模拟发送,就能够创建一个按键精灵!
主要代码如下:
- 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】的更多相关文章
- 按键精灵 句柄 获得句柄 控制windows窗口 后台
新建一个文本文档,打开,Windows就会给这个文本文档的窗口临时分配唯一的一串数字来标识这个窗体,以区别于其他窗口,这串数字就叫句柄. 因为句柄是临时随机分配的,所以每次虽然是打开同一个文件,但 ...
- [教程] 以本论坛为例,手把手教你使用按键精灵POST登陆网页
本帖最后由 isaacc 于 2012-2-26 11:08 编辑 整个操作,很无脑.只要你够勤快,你学不会,你来咬我.懒人和伸手党就直接复制代码去玩吧,但我不是叫你拿去干坏事. 准备工具:WPE和I ...
- 按键精灵对APP自动化测试(下)
上一篇介绍了安卓app上使用按键精灵的实践,这里再来说说苹果上的app. 由于iOS相关工具对操作系统的限制,目前在iOS10.0.2系统上应用成功. 二. 苹果手机按键精灵APP录制 适 ...
- QQ2008自动聊天精灵delphi源码
QQ2008自动聊天精灵delphi源码 unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Grap ...
- 【按键精灵篇】如何做一个自动打开APP进入注册页面自动输入自己手机号
按键精灵,虽然很早听过,但是一直没有真正使用过,所以最近有点时间也简单试一下,通过脚本自动清理APP缓存,打开百家号并自动进入注册页面输入自己的手机号. 软件清单 1. 雷电手机模拟器:https:/ ...
- 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)
本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...
- 按键精灵*ff
Function gethttp(URL) Set objXML=CreateObject("Microsoft.XMLHTTP") objXML.Open "Get&q ...
- 按键精灵对APP自动化测试(上)
简单介绍下应用背景:测试安卓app时发现重复点击某一按钮的时候会出现报错,开发修复后提交测试.如果采用手动点击按钮,效率不高,在领导提示下使用按键精灵实现自动操作. 一. 安卓手机按键精灵 ...
- 按键精灵与逍遥安卓ADB连接重键方法
1.按键精灵与逍遥安卓ADB连接安装按键精灵与逍遥安卓这两个软件我不用多说了.安装好后把逍遥安卓安装目录下的三个文件adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll 全部复 ...
随机推荐
- Linux 配置网络
1.vi /etc/sysconfig/network-scripts/ifcfg-eth0 2. # Advanced Micro Devices [AMD] 79c970 [PCnet32 LA ...
- 强力重置ASP.NET membership加密后的密码![转]
公司网站的用户管理采用的是ASP.NET内置的membership管理,在web.config文件中的密码格式配置是加密了的,passwordFormat="Hashed",这样在 ...
- ZOJ 3555 Ice Climber(dp)
晦涩的题意+各种傻逼害我调了那么久,实际上题目就是一个dp[i][j],dp[i][j]表示第i层第j个最少需要多少时间,当我们去更新dp[i][j]的时候,考虑的是从第i+1层的某一个dp[i+1] ...
- Activity学习(五)——Bundle机制
上一篇文章我简单介绍了Activity之间简单切换,很简单,这一篇文章我们继续聊Android中程序页面互相跳转的Activity,不过这一次我们在Activity跳转时,携带一些简单的数据,然后在新 ...
- 深入浅出ES6(八):Symbols
作者 Jason Orendorff github主页 https://github.com/jorendorff 你是否知道ES6中的Symbols是什么,它有什么作用呢?我相信你很可能不知道, ...
- group_concat
分割字符串 group_concat(a.EvidencesID separator ',') as EvidencesID #在MySQL配置文件(my.ini)中默认无该配置项,使用默认值时,值为 ...
- Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input ...
- 传说中的WCF(3):多个协定
我们知道,WCF服务端是先定义服务协定,其实就是一个接口,然后通过实现接口来定义服务类.那么,有一个问题,如果一个服务类同时实现N个接口(也就是有N个协定)呢?结果会如何? 不必猜,我们还是通过实验来 ...
- Learn CSS
韩顺平老师的CSS讲的还是很简单的,仅作入门. div+css的介绍 div+css是什么. div元素是用来为HTML文档内大块(block-level)的内容提供结构和背景的元素. css是 ...
- MongoDB (六) MongoDB 集合操作
一. MongoDB 创建集合 createCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 cr ...