unit MouseKeyboard; // //利用WinIo模拟鼠标键盘的输入 //作者:yeye55 2010年1月8日 // //版权 2010,由 yeye55 拥有,保留所有权利。 //本文件中的代码是免费程序,无需任何授权或许可即可用于个人和商业目的。使用者一切后果自负。 // //如果你转载了本文件中的代码,请注明代码出处和代码作者; //如果你修改了本文件中的代码,请注明修改位置和修改作者。 // //本文件最早在http://www.programbbs.com/bbs/上发布 // interface uses Windows, SysUtils, IniFiles; type //数据包 TMKPacketData = array [0..3] of Byte; //104键盘代码,注:“Pause”键被忽略 TMKKeyCode = ( kcA, //“A”和“a” kcB, //“B”和“b” kcC, //“C”和“c” kcD, //“D”和“d” kcE, //“E”和“e” kcF, //“F”和“f” kcG, //“G”和“g” kcH, //“H”和“h” kcI, //“I”和“i” kcJ, //“J”和“j” kcK, //“K”和“k” kcL, //“L”和“l” kcM, //“M”和“m” kcN, //“N”和“n” kcO, //“O”和“o” kcP, //“P”和“p” kcQ, //“Q”和“q” kcR, //“R”和“r” kcS, //“S”和“s” kcT, //“T”和“t” kcU, //“U”和“u” kcV, //“V”和“v” kcW, //“W”和“w” kcX, //“X”和“x” kcY, //“Y”和“y” kcZ, //“Z”和“z” kc0, //“0”和“)” kc1, //“1”和“!” kc2, //“2”和“@” kc3, //“3”和“#” kc4, //“4”和“$” kc5, //“5”和“%” kc6, //“6”和“^” kc7, //“7”和“&” kc8, //“8”和“*” kc9, //“9”和“(” kc_C0, //“`”和“~” kc_BD, //“-”和“_” kc_BB, //“=”和“+” kc_DC, //“/”和“|” kc_DB, //“[”和“{” kc_DD, //“]”和“}” kc_BA, //“;”和“:” kc_DE, //“'”和“"” kc_BC, //“,”和“<” kc_BE, //“.”和“>” kc_BF, //“/”和“?” kcBack, //退格键 Backspace kcSpace, //空格键 kcTab, //“Tab”键 kcCaps, //大写锁定键 kcLShift, //左“Shift”键 kcLCtrl, //左“Ctrl”键 kcLWin, //左开始菜单键 L_GUI kcLAlt, //左“Alt”键 kcRShift, //右“Shift”键 kcRCtrl, //右“Ctrl”键 kcRWin, //右开始菜单键 R_GUI kcRAlt, //右“Alt”键 kcApps, //快捷菜单键 kcEnter, //回车键 kcEsc, //“Esc”健 kcF1, //“F1”键 kcF2, //“F2”键 kcF3, //“F3”键 kcF4, //“F4”键 kcF5, //“F5”键 kcF6, //“F6”键 kcF7, //“F7”键 kcF8, //“F8”键 kcF9, //“F9”键 kcF10, //“F10”键 kcF11, //“F11”键 kcF12, //“F12”键 kcSysRq, //截屏键 PrintScreen kcScroll, //锁定键 kcPause, //暂停键,Pause/Break kcInsert, //插入键 kcHome, //行首键 kcPageUp, //向上翻页键 kcDelete, //删除键 kcEnd, //行末键 kcPageDown, //向下翻页键 kcUp, //向上光标键 kcLeft, //向左光标键 kcDown, //向下光标键 kcRight, //向右光标键 kcNum, //数字键盘锁定键 kcNumDivide, //数字键盘“/” kcNumMultiply, //数字键盘“*” kcNumSubtract, //数字键盘“-” kcNumAdd, //数字键盘“+” kcNumEnter, //数字键盘回车 kcNumDecimal, //数字键盘“.” kcNum0, //数字键盘“0” kcNum1, //数字键盘“1” kcNum2, //数字键盘“2” kcNum3, //数字键盘“3” kcNum4, //数字键盘“4” kcNum5, //数字键盘“5” kcNum6, //数字键盘“6” kcNum7, //数字键盘“7” kcNum8, //数字键盘“8” kcNum9 //数字键盘“9” ); //键盘码数据 TMKKeyData = record Code : TMKKeyCode; //键码 Char : array [0..1] of AnsiChar; //键码对应的字符 Length : Byte; //高4位为通码长度,低4位为断码长度 Make : TMKPacketData; //通码 Break : TMKPacketData; //断码 end; const //第一套键盘扫描码,101、102和104键的键盘,注:“Pause”键被忽略。 MKKeyCount = 104; MKKeyData : array [0..MKKeyCount-1] of TMKKeyData = ( (Code : kcA; Char : 'aA'; Length : $11; Make : ($1E,$00,$00,$00); Break : ($9E,$00,$00,$00)), (Code : kcB; Char : 'bB'; Length : $11; Make : ($30,$00,$00,$00); Break : ($B0,$00,$00,$00)), (Code : kcC; Char : 'cC'; Length : $11; Make : ($2E,$00,$00,$00); Break : ($AE,$00,$00,$00)), (Code : kcD; Char : 'dD'; Length : $11; Make : ($20,$00,$00,$00); Break : ($A0,$00,$00,$00)), (Code : kcE; Char : 'eE'; Length : $11; Make : ($12,$00,$00,$00); Break : ($92,$00,$00,$00)), (Code : kcF; Char : 'fF'; Length : $11; Make : ($21,$00,$00,$00); Break : ($A1,$00,$00,$00)), (Code : kcG; Char : 'gG'; Length : $11; Make : ($22,$00,$00,$00); Break : ($A2,$00,$00,$00)), (Code : kcH; Char : 'hH'; Length : $11; Make : ($23,$00,$00,$00); Break : ($A3,$00,$00,$00)), (Code : kcI; Char : 'iI'; Length : $11; Make : ($17,$00,$00,$00); Break : ($97,$00,$00,$00)), (Code : kcJ; Char : 'jJ'; Length : $11; Make : ($24,$00,$00,$00); Break : ($A4,$00,$00,$00)), (Code : kcK; Char : 'kK'; Length : $11; Make : ($25,$00,$00,$00); Break : ($A5,$00,$00,$00)), (Code : kcL; Char : 'lL'; Length : $11; Make : ($26,$00,$00,$00); Break : ($A6,$00,$00,$00)), (Code : kcM; Char : 'mM'; Length : $11; Make : ($32,$00,$00,$00); Break : ($B2,$00,$00,$00)), (Code : kcN; Char : 'nN'; Length : $11; Make : ($31,$00,$00,$00); Break : ($B1,$00,$00,$00)), (Code : kcO; Char : 'oO'; Length : $11; Make : ($18,$00,$00,$00); Break : ($98,$00,$00,$00)), (Code : kcP; Char : 'pP'; Length : $11; Make : ($19,$00,$00,$00); Break : ($99,$00,$00,$00)), (Code : kcQ; Char : 'qQ'; Length : $11; Make : ($10,$00,$00,$00); Break : ($90,$00,$00,$00)), //断码$19改为$90 (Code : kcR; Char : 'rR'; Length : $11; Make : ($13,$00,$00,$00); Break : ($93,$00,$00,$00)), (Code : kcS; Char : 'sS'; Length : $11; Make : ($1F,$00,$00,$00); Break : ($9F,$00,$00,$00)), (Code : kcT; Char : 'tT'; Length : $11; Make : ($14,$00,$00,$00); Break : ($94,$00,$00,$00)), (Code : kcU; Char : 'uU'; Length : $11; Make : ($16,$00,$00,$00); Break : ($96,$00,$00,$00)), (Code : kcV; Char : 'vV'; Length : $11; Make : ($2F,$00,$00,$00); Break : ($AF,$00,$00,$00)), (Code : kcW; Char : 'wW'; Length : $11; Make : ($11,$00,$00,$00); Break : ($91,$00,$00,$00)), (Code : kcX; Char : 'xX'; Length : $11; Make : ($2D,$00,$00,$00); Break : ($AD,$00,$00,$00)), (Code : kcY; Char : 'yY'; Length : $11; Make : ($15,$00,$00,$00); Break : ($95,$00,$00,$00)), (Code : kcZ; Char : 'zZ'; Length : $11; Make : ($2C,$00,$00,$00); Break : ($AC,$00,$00,$00)), (Code : kc0; Char : '0)'; Length : $11; Make : ($0B,$00,$00,$00); Break : ($8B,$00,$00,$00)), (Code : kc1; Char : '1!'; Length : $11; Make : ($02,$00,$00,$00); Break : ($82,$00,$00,$00)), (Code : kc2; Char : '2@'; Length : $11; Make : ($03,$00,$00,$00); Break : ($83,$00,$00,$00)), (Code : kc3; Char : '3#'; Length : $11; Make : ($04,$00,$00,$00); Break : ($84,$00,$00,$00)), (Code : kc4; Char : '4$'; Length : $11; Make : ($05,$00,$00,$00); Break : ($85,$00,$00,$00)), (Code : kc5; Char : '5%'; Length : $11; Make : ($06,$00,$00,$00); Break : ($86,$00,$00,$00)), (Code : kc6; Char : '6^'; Length : $11; Make : ($07,$00,$00,$00); Break : ($87,$00,$00,$00)), (Code : kc7; Char : '7&'; Length : $11; Make : ($08,$00,$00,$00); Break : ($88,$00,$00,$00)), (Code : kc8; Char : '8*'; Length : $11; Make : ($09,$00,$00,$00); Break : ($89,$00,$00,$00)), (Code : kc9; Char : '9('; Length : $11; Make : ($0A,$00,$00,$00); Break : ($8A,$00,$00,$00)), (Code : kc_C0; Char : '`~'; Length : $11; Make : ($29,$00,$00,$00); Break : ($89,$00,$00,$00)), (Code : kc_BD; Char : '-_'; Length : $11; Make : ($0C,$00,$00,$00); Break : ($8C,$00,$00,$00)), (Code : kc_BB; Char : '=+'; Length : $11; Make : ($0D,$00,$00,$00); Break : ($8D,$00,$00,$00)), (Code : kc_DC; Char : '/|'; Length : $11; Make : ($2B,$00,$00,$00); Break : ($AB,$00,$00,$00)), (Code : kc_DB; Char : '[{'; Length : $11; Make : ($1A,$00,$00,$00); Break : ($9A,$00,$00,$00)), (Code : kc_DD; Char : ']}'; Length : $11; Make : ($1B,$00,$00,$00); Break : ($9B,$00,$00,$00)), (Code : kc_BA; Char : ';:'; Length : $11; Make : ($27,$00,$00,$00); Break : ($A7,$00,$00,$00)), (Code : kc_DE; Char : #39+'"'; Length : $11; Make : ($28,$00,$00,$00); Break : ($A8,$00,$00,$00)), (Code : kc_BC; Char : ',<'; Length : $11; Make : ($33,$00,$00,$00); Break : ($B3,$00,$00,$00)), (Code : kc_BE; Char : '.>'; Length : $11; Make : ($34,$00,$00,$00); Break : ($B4,$00,$00,$00)), (Code : kc_BF; Char : '/?'; Length : $11; Make : ($35,$00,$00,$00); Break : ($B5,$00,$00,$00)), (Code : kcBack; Char : #0#0; Length : $11; Make : ($0E,$00,$00,$00); Break : ($8E,$00,$00,$00)), (Code : kcSpace; Char : ' '+#0; Length : $11; Make : ($39,$00,$00,$00); Break : ($B9,$00,$00,$00)), (Code : kcTab; Char : #9#0; Length : $11; Make : ($0F,$00,$00,$00); Break : ($8F,$00,$00,$00)), (Code : kcCaps; Char : #0#0; Length : $11; Make : ($3A,$00,$00,$00); Break : ($BA,$00,$00,$00)), (Code : kcLShift; Char : #0#0; Length : $11; Make : ($2A,$00,$00,$00); Break : ($AA,$00,$00,$00)), (Code : kcLCtrl; Char : #0#0; Length : $11; Make : ($1D,$00,$00,$00); Break : ($9D,$00,$00,$00)), (Code : kcLWin; Char : #0#0; Length : $22; Make : ($E0,$5B,$00,$00); Break : ($E0,$DB,$00,$00)), (Code : kcLAlt; Char : #0#0; Length : $11; Make : ($38,$00,$00,$00); Break : ($B8,$00,$00,$00)), (Code : kcRShift; Char : #0#0; Length : $11; Make : ($36,$00,$00,$00); Break : ($B6,$00,$00,$00)), (Code : kcRCtrl; Char : #0#0; Length : $22; Make : ($E0,$1D,$00,$00); Break : ($E0,$9D,$00,$00)), (Code : kcRWin; Char : #0#0; Length : $22; Make : ($E0,$5C,$00,$00); Break : ($E0,$DC,$00,$00)), (Code : kcRAlt; Char : #0#0; Length : $22; Make : ($E0,$38,$00,$00); Break : ($E0,$B8,$00,$00)), (Code : kcApps; Char : #0#0; Length : $22; Make : ($E0,$5D,$00,$00); Break : ($E0,$DD,$00,$00)), (Code : kcEnter; Char : #13#0; Length : $11; Make : ($1C,$00,$00,$00); Break : ($9C,$00,$00,$00)), (Code : kcEsc; Char : #0#0; Length : $11; Make : ($01,$00,$00,$00); Break : ($81,$00,$00,$00)), (Code : kcF1; Char : #0#0; Length : $11; Make : ($3B,$00,$00,$00); Break : ($BB,$00,$00,$00)), (Code : kcF2; Char : #0#0; Length : $11; Make : ($3C,$00,$00,$00); Break : ($BC,$00,$00,$00)), (Code : kcF3; Char : #0#0; Length : $11; Make : ($3D,$00,$00,$00); Break : ($BD,$00,$00,$00)), (Code : kcF4; Char : #0#0; Length : $11; Make : ($3E,$00,$00,$00); Break : ($BE,$00,$00,$00)), (Code : kcF5; Char : #0#0; Length : $11; Make : ($3F,$00,$00,$00); Break : ($BF,$00,$00,$00)), (Code : kcF6; Char : #0#0; Length : $11; Make : ($40,$00,$00,$00); Break : ($C0,$00,$00,$00)), (Code : kcF7; Char : #0#0; Length : $11; Make : ($41,$00,$00,$00); Break : ($C1,$00,$00,$00)), (Code : kcF8; Char : #0#0; Length : $11; Make : ($42,$00,$00,$00); Break : ($C2,$00,$00,$00)), (Code : kcF9; Char : #0#0; Length : $11; Make : ($43,$00,$00,$00); Break : ($C3,$00,$00,$00)), (Code : kcF10; Char : #0#0; Length : $11; Make : ($44,$00,$00,$00); Break : ($C4,$00,$00,$00)), (Code : kcF11; Char : #0#0; Length : $11; Make : ($57,$00,$00,$00); Break : ($D7,$00,$00,$00)), (Code : kcF12; Char : #0#0; Length : $11; Make : ($58,$00,$00,$00); Break : ($D8,$00,$00,$00)), (Code : kcSysRq; Char : #0#0; Length : $44; Make : ($E0,$2A,$E0,$37); Break : ($E0,$B7,$E0,$AA)), (Code : kcScroll; Char : #0#0; Length : $11; Make : ($46,$00,$00,$00); Break : ($C6,$00,$00,$00)), (Code : kcPause; Char : #0#0; Length : $33; Make : ($E1,$1D,$45,$00); Break : ($E1,$9D,$C5,$00)), (Code : kcInsert; Char : #0#0; Length : $22; Make : ($E0,$52,$00,$00); Break : ($E0,$D2,$00,$00)), (Code : kcHome; Char : #0#0; Length : $22; Make : ($E0,$47,$00,$00); Break : ($E0,$97,$00,$00)), (Code : kcPageUp; Char : #0#0; Length : $22; Make : ($E0,$49,$00,$00); Break : ($E0,$C9,$00,$00)), (Code : kcDelete; Char : #0#0; Length : $22; Make : ($E0,$53,$00,$00); Break : ($E0,$D3,$00,$00)), (Code : kcEnd; Char : #0#0; Length : $22; Make : ($E0,$4F,$00,$00); Break : ($E0,$CF,$00,$00)), (Code : kcPageDown; Char : #0#0; Length : $22; Make : ($E0,$51,$00,$00); Break : ($E0,$D1,$00,$00)), (Code : kcUp; Char : #0#0; Length : $22; Make : ($E0,$48,$00,$00); Break : ($E0,$C8,$00,$00)), (Code : kcLeft; Char : #0#0; Length : $22; Make : ($E0,$4B,$00,$00); Break : ($E0,$CB,$00,$00)), (Code : kcDown; Char : #0#0; Length : $22; Make : ($E0,$50,$00,$00); Break : ($E0,$D0,$00,$00)), (Code : kcRight; Char : #0#0; Length : $22; Make : ($E0,$4D,$00,$00); Break : ($E0,$CD,$00,$00)), (Code : kcNum; Char : #0#0; Length : $11; Make : ($45,$00,$00,$00); Break : ($C5,$00,$00,$00)), (Code : kcNumDivide; Char : #0#0; Length : $22; Make : ($E0,$35,$00,$00); Break : ($E0,$B5,$00,$00)), (Code : kcNumMultiply; Char : #0#0; Length : $11; Make : ($37,$00,$00,$00); Break : ($B7,$00,$00,$00)), (Code : kcNumSubtract; Char : #0#0; Length : $11; Make : ($4A,$00,$00,$00); Break : ($CA,$00,$00,$00)), (Code : kcNumAdd; Char : #0#0; Length : $11; Make : ($4E,$00,$00,$00); Break : ($CE,$00,$00,$00)), (Code : kcNumEnter; Char : #0#0; Length : $22; Make : ($E0,$1C,$00,$00); Break : ($E0,$9C,$00,$00)), (Code : kcNumDecimal; Char : #0#0; Length : $11; Make : ($53,$00,$00,$00); Break : ($D3,$00,$00,$00)), (Code : kcNum0; Char : #0#0; Length : $11; Make : ($52,$00,$00,$00); Break : ($D2,$00,$00,$00)), (Code : kcNum1; Char : #0#0; Length : $11; Make : ($4F,$00,$00,$00); Break : ($CF,$00,$00,$00)), (Code : kcNum2; Char : #0#0; Length : $11; Make : ($50,$00,$00,$00); Break : ($D0,$00,$00,$00)), (Code : kcNum3; Char : #0#0; Length : $11; Make : ($51,$00,$00,$00); Break : ($D1,$00,$00,$00)), (Code : kcNum4; Char : #0#0; Length : $11; Make : ($4B,$00,$00,$00); Break : ($CB,$00,$00,$00)), (Code : kcNum5; Char : #0#0; Length : $11; Make : ($4C,$00,$00,$00); Break : ($CC,$00,$00,$00)), (Code : kcNum6; Char : #0#0; Length : $11; Make : ($4D,$00,$00,$00); Break : ($CD,$00,$00,$00)), (Code : kcNum7; Char : #0#0; Length : $11; Make : ($47,$00,$00,$00); Break : ($C7,$00,$00,$00)), (Code : kcNum8; Char : #0#0; Length : $11; Make : ($48,$00,$00,$00); Break : ($C8,$00,$00,$00)), (Code : kcNum9; Char : #0#0; Length : $11; Make : ($49,$00,$00,$00); Break : ($C9,$00,$00,$00))); type //鼠标代码 TMKMouseCode = ( mcLeft, //左键 mcMiddle, //中键 mcRight //右键 ); //鼠标移动换算表 TMKMoveConversion = array [1..255] of Integer; //数据包类型 TMKDataType = (dtMouse, dtKey); //功能函数 function MKInitMouseKey: Boolean; procedure MKFreeMouseKey; function MKSendData(const Data : TMKPacketData; Len : Byte; Typ : TMKDataType): Boolean; function MKFindKeyCode(Code : TMKKeyCode): Integer; function MKFindKeyChar(Char : AnsiChar): Integer; function MKKeyDown(Code : TMKKeyCode): Boolean; function MKKeyUp(Code : TMKKeyCode): Boolean; function MKKeyPress(Code : TMKKeyCode; Interval : Cardinal = 0): Boolean; function MKKeyInput(const Text : String; Interval : Cardinal = 0): Boolean; function MKMouseDown(Code : TMKMouseCode): Boolean; function MKMouseUp(Code : TMKMouseCode): Boolean; function MKMouseClick(Code : TMKMouseCode; Interval : Cardinal = 0): Boolean; function MKMouseWheel(cZ : Integer): Boolean; function MKMouseMove(cX,cY : Integer): Boolean; procedure MKInitConversion(var Con : TMKMoveConversion); function MKTestConversion(var Con : TMKMoveConversion; MaxMove : Integer = 0): Boolean; function MKConversionToIni(const Con : TMKMoveConversion; IniFile : TIniFile; const Section : String): Boolean; function MKConversionFromIni(var Con : TMKMoveConversion; IniFile : TIniFile; const Section : String): Boolean; procedure MKLoadConversion(const Con : TMKMoveConversion); function MKMouseMoveTo(X,Y : Integer; const Con : TMKMoveConversion; MaxMove : Integer = 0; Interval : Cardinal = 0): Boolean; overload; function MKMouseMoveTo(X,Y : Integer; MaxMove : Integer = 0; Interval : Cardinal = 0): Boolean; overload; implementation var MKInitAlready : Boolean; //是否经过初始化 MKPacketLength : Integer; //鼠标数据包长度 MKButtons : array [mcLeft..mcRight] of Boolean; //鼠标键是否按下 MKConversion : TMKMoveConversion; //默认鼠标移动换算表 function InitializeWinIo(): BOOL; stdcall; external 'WinIo.dll' name 'InitializeWinIo'; procedure ShutdownWinIo(); stdcall; external 'WinIo.dll' name 'ShutdownWinIo'; {功能函数} //对加载驱动程序,对相关变量进行初始化。 function MKInitMouseKey: Boolean; var IniFile : TIniFile; begin result:=InitializeWinIo(); MKInitAlready:=result; if not result then exit; if (GetSystemMetrics(SM_CMOUSEBUTTONS)>=5) or (GetSystemMetrics(SM_MOUSEWHEELPRESENT)<>0) then MKPacketLength:=4 else MKPacketLength:=3; MKButtons[mcLeft]:=false; MKButtons[mcMiddle]:=false; MKButtons[mcRight]:=false; IniFile:=TIniFile.Create(GetCurrentDir+'/Mouse.ini'); if not MKConversionFromIni(MKConversion,IniFile,'Conversion') then MKInitConversion(MKConversion); IniFile.Free; end; //释放驱动程序 procedure MKFreeMouseKey; begin if not MKInitAlready then ShutdownWinIo; MKInitAlready:=false; end; //向指定的键盘鼠标端口发送数据包,返回是否成功, //Len为数据包的字节长度。 function MKSendData(const Data : TMKPacketData; Len : Byte; Typ : TMKDataType): Boolean; var i,b : Byte; procedure fSetByte(Por,Cod : Byte); begin Sleep(1); asm PUSH EAX PUSH EDX //等待状态寄存器标志位OBF置0 @Loop: IN AL,$64 AND AL,01b JNZ @Loop //写入数据 MOV AL,Cod MOV DL,Por MOV DH,0 OUT DX,AL POP EDX POP EAX end; end; begin if not MKInitAlready then begin result:=MKInitMouseKey; if not result then exit; end; if Typ=dtMouse then b:=$D3 else b:=$D2; for i:=0 to Len-1 do begin fSetByte($64,b); fSetByte($60,Data[i]); end; result:=true; end; //查找指定键码在MKKeyData中的id,找到返回id,没找到返回-1。 function MKFindKeyCode(Code : TMKKeyCode): Integer; var i : Integer; begin for i:=0 to MKKeyCount-1 do if MKKeyData[i].Code=Code then break; if i