delphi利用SendInput模拟鼠标键盘

合集下载

Delphi中鼠标键盘消息模拟

Delphi中鼠标键盘消息模拟

Delphi中鼠标键盘消息模拟Delphi中鼠标键盘消息模拟2008-03-04 11:13 1291人阅读评论(0) 收藏举报delphiintegerbuttonformsinterfacewindows鼠标模拟的例子:例子:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs;typeTForm1 = class(TForm)procedure FormCreate(Sender: TObject);procedure FormMouseDown(Sender: TObject; Butto n: TMouseButton;Shift: TShiftState; X, Y: Integer);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);varrect:TRect;x,y,lPara:Integer;beginGetWindowRect(Self.Handle,rect);//获得当前窗口的位置x:=rect.Left+10; //当前窗口左上角x坐标加10y:=rect.T op+10; //当前窗口左上角y坐标加10lPara:=x+(y shl 16); //就算出lParam的值//向当前窗口发送左键按下消息,相当于鼠标在相对窗口(10,10)的位置按下PostMessage(Self.Handle,WM_LBUTTONDOWN,MK_LBUTT ON,lpara);end;//相应鼠标按下事件procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);beginshowmessage('WM_lbuttondown 在 ' + IntToStr(X ) + ','+ IntToStr(y));end;end./////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////简单点的可以用键盘/鼠标事件给你个键盘事件的例子:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)edit1: TEdit;Button1: TButton;procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);constvk_o=79;vk_k=75;beginedit1.SetFocus;keybd_event (VK_O, 0, 0, 0); //press Hkeybd_event (VK_O, 0, KEYEVENTF_KEYUP, 0); // release Hkeybd_event (VK_K, 0, 0, 0); //press Hkeybd_event (VK_K, 0, KEYEVENTF_KEYUP, 0); // release Hend;end./////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// procedure TForm1.Button1Click(Sender: TObject);beginwinexec('notepad',1);//把记事本窗口激活setforegroundwindow(findwindow(nil,'无标题-记事本'));//模拟输入 'abc'keybd_event(65,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(65,0,KEYEVENTF_EXTENDEDKEY or KEYEV ENTF_KEYUP,0);keybd_event(66,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(66,0,KEYEVENTF_EXTENDEDKEY or KEYEV ENTF_KEYUP,0);keybd_event(67,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(67,0,KEYEVENTF_EXTENDEDKEY or KEYEV ENTF_KEYUP,0);//模拟 alt + F 打开文件菜单keybd_event(VK_MENU,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(70,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(70,0,KEYEVENTF_EXTENDEDKEY or KEYEV ENTF_KEYUP,0);keybd_event(VK_MENU,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);//模拟输入按 s 保存keybd_event(83,0,KEYEVENTF_EXTENDEDKEY or 0,0);keybd_event(83,0,KEYEVENTF_EXTENDEDKEY or KEYEV ENTF_KEYUP,0);end;更多0•上一篇用Delphi学写外挂•下一篇WINIO驱动方式模拟按键。

delphi模拟按键

delphi模拟按键

delphi模拟按键delphi 模拟按键delphi模拟键盘输入可以通过发消息来实现,比如下面消息在编辑框formul中写入字符q:SENDMESSAGE(formula.HANDLE,WM_KEYDOWN,Ord('q'),0) ;当然还有其他多种实现方法,下面转载一个程序,里面用的方法很不错unit FrmKeyboard;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, te_controls, ksthemebuttons, ksthemeengine, ksthemeforms,StdCtrls, ExtCtrls;typeTKeyboardFrm = class(TForm)bttnQ: TButton;bttnW: TButton;bttnE: TButton;bttnR: TButton;bttnTab: TButton;bttnO: TButton;bttnP: TButton;bttnCapsLock: TButton; bttnBracketL: TButton; bttnT: TButton;bttnI: TButton;bttnY: TButton;bttnU: TButton; ttemKey: TTeThemeEngine; bttnS: TButton;bttnD: TButton;bttnF: TButton;bttnG: TButton;bttnA: TButton; bttnColon: TButton; bttnQuotation: TButton; bttnH: TButton;bttnL: TButton;bttnJ: TButton;bttnK: TButton; bttnShiftL: TButton; bttnX: TButton;bttnC: TButton;bttnV: TButton;bttnB: TButton;bttnZ: TButton; bttnSlash: TButton; bttnN: TButton; bttnFullStop: TButton; bttnM: TButton; bttnComma: TButton; bttnCtrlL: TButton;bttnAltL: TButton;bttnSpace: TButton;bttnWinL: TButton;bttnWinR: TButton;bttnAltR: TButton;bttnNull: TButton;bttnShiftR: TButton;bttnDoc: TButton;bttnCtrlR: TButton;TeThemeForm1: TT eThemeForm;bttnBracketR: TButton;bttn1: TButton;bttn2: TButton;bttn3: TButton;bttn4: TButton;bttnRipple: TButton;bttn9: TButton;bttn0: TButton;bttnSubtract: TButton;bttn5: TButton;bttn8: TButton;bttn6: TButton;bttn7: TButton;bttnEqual: TButton;bttnUnSlash: TButton;bttnBackSpace: TButton;bttnEnter: TButton;procedure bttnAClick(Sender: TObject);//模拟键盘procedure FormCreate(Sender: TObject);//创建窗口procedure myWM_ACTIVATE(var Message: TMessage);message WM_ACTIVATE;//截获消息private{ Private declarations }procedure LoadGlyph;//装入图标public{ Public declarations }end;TStateMeal= (Ctrl,Alt,Shift);//定义一个集合TStateArray= array[Ctrl..Shift] of Boolean;//定义一个数组(数组下标为集合类型)varKeyboardFrm: TKeyboardFrm;StateArray: TStateArray;gblIcoFilePath: string;//图标文件路径,位于程序的key目录下HActWin,Hself: HWND;implementation{$R *.dfm}{***********************************************************} {* 模拟键盘 *}{***********************************************************} {* 功能:模拟键盘 *}{* 说明:1.按纽的T ag属性存放相应键的虚拟键值(十进制) *}{* 2.根据相应的按纽传递其Tag值,(即虚拟键值键值) *}{* 3.程序以case语句为主,便于判断与理解 *}{* 4.所有按纽的OnClick事件均为按纽"A"的OnClick事件 *}{*=========================================================*}procedure TKeyboardFrm.bttnAClick(Sender: TObject);varfocushld,windowhld:hwnd;threadld:dword;Key: integer;begin//焦点定位,以便接受键盘输入SetActiveWindow(HActWin);windowhld:=GetForegroundWindow;threadld:=GetWindowThreadProcessId(Windowhld,nil);//WindowhldAttachThreadInput(GetCurrentThreadId,threadld,true);Focushld:=getfocus;AttachThreadInput(GetCurrentThreadId,threadld,false);if focushld = 0 then Exit;//开始模拟键盘Key:= (Sender as TButton).Tag;case Key of//双字符键的模拟48..57,65..90,111,188..190,186,187,220,221,222,219 :beginkeybd_event(key,MapVirtualKey(key,0),KEYEVENTF_KEYUP,0) ;//释放键keybd_event(key,MapVirtualKey(key,0),0,0);//按下键//释放控制键if StateArray[Ctrl] then keybd_event(17,MapVirtualKey(17,0),KEYEVENTF_KEYUP,0);if StateArray[Alt] then keybd_event(18,MapVirtualKey(18,0),KEYEVENTF_KEYUP,0);if StateArray[Shift]then keybd_event(16,MapVirtualKey(16,0),KEYEVENTF_KEYUP,0);end;//按制键的模拟(Shift,Ctrl,Alt)16 :beginkeybd_event(key,MapVirtualKey(key,0),0,0);//按下键StateArray[Shift]:=true;end;17 :beginkeybd_event(key,MapVirtualKey(key,0),0,0);//按下键StateArray[Ctrl]:=true;end;18 :beginkeybd_event(key,MapVirtualKey(key,0),0,0);//按下键StateArray[Alt]:=true;end;//Tab键的模拟{这里考虑到了Alt+Tab的模拟}9 :beginkeybd_event(key,MapVirtualKey(key,0),0,0);//按下键keybd_event(key,MapVirtualKey(key,0),0,0);//释放键if StateArray[Shift] then {考虑Alt+Tab的模拟}keybd_event(18,MapVirtualKey(18,0),0,0);//释放键//其它键的模拟{简单的按下然后释放}elsebeginkeybd_event(key,MapVirtualKey(key,0),0,0);//按下键keybd_event(key,MapVirtualKey(key,0),KEYEVENTF_KEYUP,0) ;//释放键end;end;end;{***********************************************************} {* 截获 WM_ACTIVATE 消息 *}{***********************************************************} {* 功能:获得输入句柄 *}{* 日期:2002年11月20日 *}{* 作者: *}{*===================================== ====================*}procedure TKeyboardFrm.myWM_ACTIVATE(var Message: TMessage);beginif Message.wParam = WA_CLICKACTIVE thenbegin//SetActiveWindow(message.lParam);if (HActWin<>message.lParam) and (message.lParam<>Hself) thenHActWin:=message.lParam;end;{***********************************************************} {* 程序初始化 *}{***********************************************************} {* 功能:数组变量赋初值false *}{* 日期:2002年11月20日 *}{* 作者: *}{*===================================== ====================*}procedure TKeyboardFrm.FormCreate(Sender: TObject);beginStateArray[Ctrl]:= false;StateArray[Alt]:= false;StateArray[Shift]:= false;Hself:= KeyboardFrm.Handle;KeyboardFrm.LoadGlyph;end;。

delphi利用SendInput模拟鼠标键盘

delphi利用SendInput模拟鼠标键盘

delphi利用SendInput模拟鼠标键盘delphi 利用SendInput模拟鼠标键盘作者:admin 来源:日期:2011-8-18 13:21:17 人气:1250 标签:QQ空间新浪微博腾讯微博腾讯朋友QQ收藏百度空间百度贴吧更多0前言一、SendInputSendInput可以将指定的鼠标键盘消息插入到系统消息队列,从而实现对鼠标键盘的模拟。

有很多程序对SendInput进行了屏蔽,但不是所有的。

所以这里介绍一下SendInput的使用。

我已经将主要的模拟功能写在了一个单元文件中:SIMouseKeyboard.pas,调用该单元文件中的相关函数就可以实现鼠标键盘的模拟。

该单元文件的下载见本楼末尾。

SendInput的参数其实很简单,在Windows.pas就有函数的声明如下:function SendInput(cInputs: UINT; var pInputs: TInput; cbSize: Integer): UINT; stdcall;cInputs:定义pInputs中记录数组的元素数目。

pInputs:TInput类型记录数组的第1个元素。

每个元素代表插人到系统消息队列的键盘或鼠标事件。

cbSize:定义TInput的大小,一般为SizeOf(TInput)。

函数返回成功插入系统消息队列中事件的数目,失败返回0。

调用SendInput关键的就是要搞清楚它的几个记录结构的意思,在Windows.pas中对TInput的声明如下:tagINPUT = packed recordItype: DWORD;case Integer of0: (mi: TMouseInput);1: (ki: TKeybdInput);2: (hi: THardwareInput);end;TInput = tagINPUT;其中mi、ki、hi是3个共用型的记录结构,Itype指出记录结构中所使用的类型,它有3个值。

C#模拟键盘鼠标事件-SendKeys

C#模拟键盘鼠标事件-SendKeys

C#模拟键盘鼠标事件-SendKeys2007-09-18 15:13 7689人阅读评论(1) 收藏举报1.模拟键盘事件System.Windows.Forms.SendKeys以下是SendKeys 的一些特殊键代码表。

键代码BACKSPACE {BACKSPACE}、{BS} 或{BKSP}BREAK {BREAK}CAPS LOCK {CAPSLOCK}DEL 或DELETE {DELETE} 或{DEL}DOWN ARROW(下箭头键){DOWN}END {END}ENTER {ENTER} 或~ESC {ESC}HELP {HELP}HOME {HOME}INS 或INSERT {INSERT} 或{INS}LEFT ARROW(左箭头键){LEFT}NUM LOCK {NUMLOCK}PAGE DOWN {PGDN}PAGE UP {PGUP}PRINT SCREEN {PRTSC}(保留,以备将来使用)RIGHT ARROW(右箭头键){RIGHT}SCROLL LOCK {SCROLLLOCK}TAB {TAB}UP ARROW(上箭头键){UP}F1 {F1}F2 {F2}F3 {F3}F4 {F4}F5 {F5}F6 {F6}F7 {F7}F8 {F8}F9 {F9}F10 {F10}F11 {F11}F12 {F12}F13 {F13}F14 {F14}F15 {F15}F16 {F16}数字键盘加号{ADD}数字键盘减号{SUBTRACT}数字键盘乘号{MULTIPLY}数字键盘除号{DIVIDE}若要指定与SHIFT、CTRL 和ALT 键的任意组合一起使用的键,请在这些键代码之前加上以下一个或多个代码:键代码SHIFT + (SHIFT="+")CTRL ^ (CTRL="^") 如果输入ALT % private void button1_Click(object sender, System.EventArgs e) {//英文输入this.richTextBox1.Focus();for(int i=65;i<91;i++){char Letter=(char)i;SendKeys.Send(Letter.ToString());System.Threading.Thread.Sleep(100);SendKeys.Flush();}for(int i=97;i<123;i++){char Letter=(char)i;SendKeys.Send(Letter.ToString());System.Threading.Thread.Sleep(100);SendKeys.Flush();}private void button3_Click(object sender, System.EventArgs e) {//数字输入this.richTextBox1.Focus();for(int i=0;i<10;i++){SendKeys.Send(i.ToString());System.Threading.Thread.Sleep(100);SendKeys.Flush();}}private void button4_Click(object sender, System.EventArgs e) {//Backspacethis.richTextBox1.Focus();SendKeys.Send("{Backspace}");}private void button5_Click(object sender, System.EventArgs e) {//Homethis.richTextBox1.Focus();SendKeys.Send("{Home}");}private void button6_Click(object sender, System.EventArgs e) {//Endthis.richTextBox1.Focus();SendKeys.Send("{End}");}private void button7_Click(object sender, System.EventArgs e) {//Enterthis.richTextBox1.Focus();SendKeys.Send("{Enter}");private void button8_Click(object sender, System.EventArgs e) {//Deletethis.richTextBox1.Focus();SendKeys.Send("{Delete}");}private void button2_Click(object sender, System.EventArgs e) {//Shift+Homethis.richTextBox1.Focus();SendKeys.Send("+{Home}");}private void button9_Click(object sender, System.EventArgs e) {//Shift+Endthis.richTextBox1.Focus();SendKeys.Send("+{End}");}看下方法的说明public class SendKeys : System.ObjectSystem.Windows.Forms 的成员摘要:提供将键击发送到应用程序的方法。

SendInput模拟键盘输入的问题

SendInput模拟键盘输入的问题

SendInput模拟键盘输入的问题最近接触到这个函数,因此了解了一下,总结一下列在这。

我了解它的出发点是如何通过它向活动窗口输入字符,这是很多程序都有的功能(我猜Visual Assist X就用了这个功能)。

根据MSDN,此函数模拟按键操作,将一些消息插入键盘或鼠标的输入流中,Windows对它进行处理,生成相应的WM_KEYDOWN或WM_KEYUP事件,这些事件与普通键盘输入一起进入应用程序的消息循环,它们不仅可以转换为WM_CHAR消息,还可以转换为其它(诸如加速键)等消息。

使用它来发送字符消息,并没有看起来那么简单。

这有两个需要考虑的问题:1. 输入法的转换。

例如需要向活动窗口发送一些英文字符,我们可能想象这样来实现:获取对应键盘字符的虚拟键码,发送一个SendInput。

但是如果活动窗口正在使用一个输入法,那么我们发送出去的消息,会进入输入法的Composition窗口,最终被转换为象形文字或被丢弃。

只有当输入法关闭时,程序运行的效果才会像我们期望的那样,在活动窗口中显示出英文字符。

2. 对于中文字符,应该怎么发送给活动窗口?由于SendInput模拟的是WM_KEYDOWN和WM_KEYUP事件,按照一般的思路,我们是否应该获取中文字符的输入法编码(拼音或五笔码),然后向活动窗口发送编码相关的SendInput?那这不仅要求活动窗口开启输入法,甚至还要获知它的编码方式。

如上所述,若直接如想象中那样使用SendInput来输入字符,则必须分析活动窗口的输入法状态。

而且输入英文时,要求关闭输入法,输入中文时,又要求打开输入法。

若真要以这样的思路来实现,则必定是难以成功的。

那么,有没有不依赖活动窗口输入法状态的方式呢?其实是有的,使用SendInput模拟键盘输入时,其参数是KEYBDINPUT结构,通过将其dwFlags成员设置KEYEVENTF_UNICODE就可以了。

使用此方式,只需将KEYBDINPUT.wScan设置为字符的Unicode编码即可。

C++,WIN32模拟鼠标键盘操作的功能封装代码

C++,WIN32模拟鼠标键盘操作的功能封装代码
} else if (operationSelect == 2) {//释放
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
if (SendInput(1, &input, sizeof(INPUT)) <= 0) { cout << "鼠标左键释放失败,错误码为: " << GetLastError() << endl; return false;
cout << "鼠标滚轮垂直滚动失败,错误码为: " << GetLastError() << endl;
return false; } } else {//水平滚动 input.mi.dwFlags = MOUSEEVENTF_HWHEEL; input.mi.mouseData = (int)(scrollNum * 1.2); if (SendInput(1, &input, sizeof(INPUT)) <= 0) {
/*【功能】:鼠标左,右键的点击,释放,连击,滚动.
*【参数】:①USHORT:要操作的鼠标对象:1,鼠标左键;2鼠标右键;3,鼠标中键(滚轮) ②USHORT:要操作
的对应功能:1,按下;2释放;3,按下+释放;4,对于左键:按下+释放+按下+释放;对于中键:滚轮滚动 ③ scrollNum:滚轮滚动的像素值(垂直滚动时,正值向上滚动,负值向下滚动;水平滚动时,正值向右滚动,负
if (b) {//绝对移动 if (!SetCursorPos(x, y)) { cout << "鼠标位置移动失败,错误码为:" << GetLastError() << endl; return false; }

delphi通过代码实现模拟按键的函数

delphi通过代码实现模拟按键的函数

delphi通过代码实现模拟按键的函数Windows API 的keybd_event 函数,它可以产生键盘消息。

实现向其他窗口模拟真实的按键动作。

例如:{按下A键}Edit1.SetFocus;keybd_event(VK_SHIFT, 0, 0, 0);keybd_event(ord('A'), 0, 0, 0);keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);{按下左Window键然后选择“运行”}keybd_event(VK_LWIN, 0, 0, 0);keybd_event(ord('R'), 0, 0, 0);keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);KEYBD_EVENT 的函数说明:函数功能:该函数合成一次击键事件。

系统可使用这种合成的击键事件来产生WM_KEYUP或WM_KEYDOWN消息,键盘驱动程序的中断处理程序调用keybd_event函数。

在Windows NT中该函数己被使用Sendlhput来替代它。

函数原型;VOID keybd_event(BYTE bVk,BYTE bScan,DWORD dwFlags,DWORD dwExtralnfo);参数:bVk:定义一个虚据拟键码。

键码值必须在1~254之间。

bScan:定义该键的硬件扫描码。

dwFlags:定义函数操作的名个方面的一个标志位集。

应用程序可使用如下一些预定义常数的组合设置标志位。

KEYEVENTF_EXETENDEDKEY:若指定该值,则扫描码前一个值为OXEO(224)的前缀字节。

DEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键交被接下。

dwExtralnfo:定义与击键相关的附加的32位值。

根据这个API函数,整理一个完整的函数,方便操作:procedure PostKey(const mKey: Word; mShiftState: TShiftState; mCount: Integer = 1);constcExtended: set of Byte = [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_HOME, VK_END, VK_PRIOR, VK_NEXT, VK_INSERT, VK_DELETE];procedure pKeyboardEvent(mKey, mScanCode: Byte; mFlags: Longint);varvKeyboardMsg: TMsg;beginkeybd_event(mKey, mScanCode, mFlags, 0);while PeekMessage(vKeyboardMsg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) dobeginTranslateMessage(vKeyboardMsg);DispatchMessage(vKeyboardMsg);end;end;procedure pSendKeyDown(mKey: Word; mGenUpMsg: Boolean);varvScanCode: Byte;vNumState: Boolean;vKeyBoardState: TKeyboardState;beginif (mKey = VK_NUMLOCK) thenbeginvNumState := ByteBool(GetKeyState(VK_NUMLOCK) and 1);GetKeyBoardState(vKeyBoardState);if vNumState thenvKeyBoardState[VK_NUMLOCK] := (vKeyBoardState[VK_NUMLOCK] and not 1)elsevKeyBoardState[VK_NUMLOCK] := (vKeyBoardState[VK_NUMLOCK] or 1);SetKeyBoardState(vKeyBoardState);Exit;end;vScanCode := Lo(MapVirtualKey(mKey, 0));if (mKey in cExtended) thenbeginpKeyboardEvent(mKey, vScanCode, KEYEVENTF_EXTENDEDKEY);if mGenUpMsg thenpKeyboardEvent(mKey, vScanCode, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP)end elsebeginpKeyboardEvent(mKey, vScanCode, 0);if mGenUpMsg then pKeyboardEvent(mKey, vScanCode, KEYEVENTF_KEYUP);end;end; { pSendKeyDown }procedure pSendKeyUp(mKey: Word);varvScanCode: Byte;beginvScanCode := Lo(MapVirtualKey(mKey, 0));if mKey in cExtended thenpKeyboardEvent(mKey, vScanCode, KEYEVENTF_EXTENDEDKEY and KEYEVENTF_KEYUP) elsepKeyboardEvent(mKey, vScanCode, KEYEVENTF_KEYUP);end;varI: Integer;beginfor I := 1 to mCount dobeginif ssShift in mShiftState then pSendKeyDown(VK_SHIFT, False);if ssCtrl in mShiftState then pSendKeyDown(VK_CONTROL, False);if ssAlt in mShiftState then pSendKeyDown(VK_MENU, False);pSendKeyDown(mKey, True);if ssShift in mShiftState then pSendKeyUp(VK_SHIFT);if ssCtrl in mShiftState then pSendKeyUp(VK_CONTROL);if ssAlt in mShiftState then pSendKeyUp(VK_MENU);end;end;另外一处函数也可以实现类似功能。

C#SendInput模拟鼠标操作的实现方法

C#SendInput模拟鼠标操作的实现方法

C#SendInput模拟⿏标操作的实现⽅法刚刚开始学习C#,想⾃⼰做⼀个⽹页游戏的挂。

游戏⾥⾯有收钱的动作,⼀个建筑物⼀个建筑物的点,很累啊。

于是想⽤C#模拟⿏标操作替我收钱,想着学习这个对以后的测试⼯作也有帮助,于是有了动⼒。

学习过程也是曲折的,因为⽹上搜了半天资料很少。

该游戏是Flash的,⽤sendmessage不⾏,因为取不到⾥⾯的对象。

查到有些介绍Mouse_Event的⽂章,但是msdn 上说已经过时。

于是查到了SendInput函数。

废话少说,上代码:⾸先看下 Win API 中SendInput函数描述:复制代码代码如下:UINT WINAPI SendInput(__in UINT nInputs,__in LPINPUT pInputs,__in int cbSize);对应的C#代码:复制代码代码如下:[DllImport("user32.dll")]public static extern UInt32 SendInput(UInt32 nInputs,Input[] pInputs, int cbSize);其中参数pInputs是的数组类型,数组元素INPUT结构,所以我们下⾯还要在C#中定义对应的INPUT结构或者对象。

INPUT结构中主要是定义你需要的⿏标或者键盘等操作。

nInputs指明pInputs数组长度。

cbSize指明INPUT结构的⼤⼩。

定义INPUT结构,下⾯是Win API 中INPUT结构描述:复制代码代码如下:typedef struct tagINPUT {DWORD type;union {MOUSEINPUT mi;KEYBDINPUT ki;HARDWAREINPUT hi;} ;} INPUT, *PINPUT;对应的C#代码复制代码代码如下:[StructLayout(LayoutKind.Explicit)]public struct Input{[FieldOffset(0)]public Int32 type;[FieldOffset(4)]public MouseInput mi;[FieldOffset(4)]public tagKEYBDINPUT ki;[FieldOffset(4)]public tagHARDWAREINPUT hi;}上⾯看到,还有MOUSEINPUT,KEYBDINPUT,HARDWAREINPUT结构需要定义。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

delphi利用SendInput模拟鼠标键盘delphi 利用SendInput模拟鼠标键盘作者:admin 来源:日期:2011-8-18 13:21:17 人气:1250 标签:QQ空间新浪微博腾讯微博腾讯朋友QQ收藏百度空间百度贴吧更多0前言一、SendInputSendInput可以将指定的鼠标键盘消息插入到系统消息队列,从而实现对鼠标键盘的模拟。

有很多程序对SendInput进行了屏蔽,但不是所有的。

所以这里介绍一下SendInput的使用。

我已经将主要的模拟功能写在了一个单元文件中:SIMouseKeyboard.pas,调用该单元文件中的相关函数就可以实现鼠标键盘的模拟。

该单元文件的下载见本楼末尾。

SendInput的参数其实很简单,在Windows.pas就有函数的声明如下:function SendInput(cInputs: UINT; var pInputs: TInput; cbSize: Integer): UINT; stdcall;cInputs:定义pInputs中记录数组的元素数目。

pInputs:TInput类型记录数组的第1个元素。

每个元素代表插人到系统消息队列的键盘或鼠标事件。

cbSize:定义TInput的大小,一般为SizeOf(TInput)。

函数返回成功插入系统消息队列中事件的数目,失败返回0。

调用SendInput关键的就是要搞清楚它的几个记录结构的意思,在Windows.pas中对TInput的声明如下:tagINPUT = packed recordItype: DWORD;case Integer of0: (mi: TMouseInput);1: (ki: TKeybdInput);2: (hi: THardwareInput);end;TInput = tagINPUT;其中mi、ki、hi是3个共用型的记录结构,Itype指出记录结构中所使用的类型,它有3个值。

INPUT_MOUSE:表示使用mi记录结构,忽略ki和hi;INPUT_KEYBOARD:表示使用ki记录结构,忽略mi和hi。

二、键盘模拟TKeybdInput记录结构的声明如下:tagKEYBDINPUT = packed recordwVk: WORD;wScan: WORD;dwFlags: DWORD;time: DWORD;dwExtraInfo: DWORD;end;TKeybdInput = tagKEYBDINPUT;其中wVk是将要操作的按键的虚键码。

wScan是安全码,一般不用。

dwFlags指定键盘所进行的操作,为0时表示按下某键,KEYEVENTF_KEYUP表示放开某键。

time是时间戳,可以使用API函数GetTickCount的返回值。

dwExtraInfo是扩展信息,可以使用API 函数GetMessageExtraInfo的返回值。

例如击键“A”的程序如下:procedure KeyPressA;varInputs : array [0..1] of TInput;beginInputs[0].Itype:=INPUT_KEYBOARD;with Inputs[0].ki dobeginwVk:=VK_A;wScan:=0;dwFlags:=0;time:=GetTickCount;dwExtraInfo:=GetMessageExtraInfo;end;Inputs[1].Itype:=INPUT_KEYBOARD;with Inputs[1].ki dobeginwVk:=VK_A;wScan:=0;dwFlags:=KEYEVENTF_KEYUP;time:=GetTickCount;dwExtraInfo:=GetMessageExtraInfo;end;SendInput(2,Inputs[0],SizeOf(TInput));end;注意:在Windows.pas单元中并没有字母和数字的虚键码的声明,在我写的SIMouseKeyboard.pas单元文件中对所有的虚键码进行了重新声明,包含了字母、数字和标点符号。

三、鼠标模拟TMouseInput记录结构的声明如下:tagMOUSEINPUT = packed recorddx: Longint;dy: Longint;mouseData: DWORD;dwFlags: DWORD;time: DWORD;dwExtraInfo: DWORD;end;TMouseInput = tagMOUSEINPUT;其中dx、dy是鼠标移动时的坐标差(不是象素单位),在鼠标移动时有效。

mouseData是鼠标滚轮滚动值,在滚动鼠标滚轮时有效。

当mouseData小于0时向下滚动,当mouseData大于0时向上滚动,mouseData的绝对值一般设为120。

dwFlags指定鼠标所进行的操作,例如,MOUSEEVENTF_MOVE表示移动鼠标,MOUSEEVENTF_LEFTDOWN表示按下鼠标左键,MOUSEEVENTF_LEFTUP表示放开鼠标左键。

time是时间戳,可以使用API函数GetTickCount的返回值。

dwExtraInfo是扩展信息,可以使用API函数GetMessageExtraInfo的返回值。

例如单击鼠标左键的程序如下:procedure MouseClick;varInputs : array [0..1] of TInput;beginInputs[0].Itype:=INPUT_MOUSE;with Inputs[0].mi dobegindx:=0;dy:=0;mouseData:=0;dwFlags:=MOUSEEVENTF_LEFTDOWN;time:=GetTickCount;dwExtraInfo:=GetMessageExtraInfo;end;Inputs[1].Itype:=INPUT_MOUSE;with Inputs[1].mi dobegindx:=0;dy:=0;mouseData:=0;dwFlags:=MOUSEEVENTF_LEFTUP;time:=GetTickCount;dwExtraInfo:=GetMessageExtraInfo;end;SendInput(2,Inputs[0],SizeOf(TInput));end;鼠标的移动总是很麻烦,上面的dx、dy不是以象素为单位的,而是以鼠标设备移动量为单位的,它们之间的比值受鼠标移动速度设置的影响。

具体的解决方法我已经在《Delphi下利用WinIo模拟鼠标键盘详解》一文中进行了讨论,这里不再重复。

dwFlags可以设置一个MOUSEEVENTF_ABSOLUTE标志,这使得可以用另外一种方法移动鼠标。

当dwFlags设置了MOUSEEVENTF_ABSOLUTE标志,dx、dy 为屏幕坐标值,表示将鼠标移动到dx,dy的位置。

但是这个坐标值也不是以象素为单位的。

这个值的范围是0到65535($FFFF),当dx 等于0、dy等于0时表示屏幕的最左上角,当dx等于65535、dy等于65535时表示屏幕的最右下角,相当于将屏幕的宽和高分别65536等分。

API函数GetSystemMetrics(SM_CXSCREEN)可以返回屏幕的宽度,函数GetSystemMetrics(SM_CYSCREEN)可以返回屏幕的高度,利用屏幕的宽度和高度就可以将象素坐标换算成相应的dx、dy。

注意:这种换算最多会出现1象素的误差。

例如:将鼠标指针移动到屏幕150,120坐标处的程序如下:procedure MouseMove;varInput : TInput;beginInput.Itype:=INPUT_MOUSE;with Input.mi dobegindx:=($FFFF div (GetSystemMetrics(SM_CXSCREEN)-1)) * 150;dy:=($FFFF div (GetSystemMetrics(SM_CYSCREEN)-1)) * 120;mouseData:=0;dwFlags:=MOUSEEVENTF_MOVE or MOUSEEVENTF_ABSOLUTE;time:=GetTickCount;dwExtraInfo:=GetMessageExtraInfo;end;SendInput(1,Input,SizeOf(TInput));end;四、SendInput与WInIo的对比在《Delphi下利用WinIo模拟鼠标键盘详解》一文中我已经说了WinIo的很多缺点,SendInput几乎没有这些缺点。

SendInput的模拟要比WinIo简单的多。

事件是被直接插入到系统消息队列的,所以它的速度比WinIo要快。

系统也会保证数据的完整性,不会出现数据包混乱的情况。

利用“绝对移动”可以将鼠标指针移动到准确的位置,同鼠标的配置隔离不会出现兼容性的问题。

SendInput的缺点也是最要命的,它会被一些程序屏蔽。

所以说在SendInput与WInIo都可以使用的情况下优先考虑SendInput。

另外SendInput与WInIo可以接合使用,一些程序对鼠标左键单击敏感,可以使用WinIo模拟鼠标左键单击,其它操作由SendInput模拟。

五、SIMouseKeyboard.pas的使用我在SIMouseKeyboard.pas单元文件中对所有的虚键码进行了重新声明,包含了Windows.pas单元中没有声明的字母、数字和标点符号。

在SIMouseKeyboard.pas单元文件中共有9个函数,使用方法如下:1、procedure SIKeyDown(Key : WORD);按下指定的键。

Key为虚键码。

2、procedure SIKeyUp(Key : WORD);放开指定的键。

Key为虚键码。

3、procedure SIKeyPress(Key : WORD; Interval : Cardinal);按下并放开指定的键,Interval为按下和放开之间的时间间隔。

注意:本函数不支持重复机打,即无论Interval设的多么大都只有一次按键。

4、procedure SIKeyInput(const Text : String; Interval : Cardinal);模拟键盘输入指定的文本,返回是否成功。

文本中只能是单字节字符(#32~#126)、Tab(#9)键和回车键(#13),即可以从键盘上输入的字符,不能是汉字,其它字符会被忽略。

Interval为按下和放开键之间的时间间隔,单位毫秒。

相关文档
最新文档