import key.VK; namespace key; ::GetAsyncKeyState := ::User32.api("GetAsyncKeyState","word(int vKey)" ); ::GetKeyState := ::User32.api("GetKeyState","word(int vKey)" ); ::MapVirtualKey := ::User32.api("MapVirtualKey","INT(INT uCode,INT uMapType)" ); delayPress = 5; delayDown = 5; delayUp = 1; extraInfo = 0; getName = function(vk,ext,noLocation){ if(noLocation) vk = VK_NLR[vk] : vk; return ( ext ? VK_EXT2NAME[vk]) : VK_NAME[vk] } removeLocation = function(vk){ return VK_NLR[vk] : vk; } v2scan = lambda(v,e)::MapVirtualKey(v,e?4:0); scan2v = lambda(s,e)::MapVirtualKey(s,e?3:1); getCode = function(kn){ var vk = (type(kn)!="string")?kn:VK[kn ? ..string.upper(kn)] : VK_MAPSHIFT[kn] return (type(vk)=="number")?vk:null,VK_EXT[vk] : VK_EXT2[kn] : 0 } send = function(str,tk=0){ var chars = ..string.split(str); for(i=1;#chars){ var vk = getCode(chars[i]) if(vk){press(vk);} else{sendString(chars[i])} ..thread.delay(tk); } } class INPUTDATA { INT type = 1/*_INPUT_KEYBOARD*/; struct ki = { WORD vk; WORD scan; INT flags; INT time; ADDR extraInfo; INT reserve; INT reserve2; } } sendString = function(str,tk=0){ if(!str) return; var d = INPUTDATA(); var cbSize = ..raw.sizeof(d); var wstr = ..string.toUtf16(str); var c; for(i=1;#wstr/2;1){ c = wstr[i]; if(c > 31 ){ d.ki.scan = c; d.ki.flags = 4/*_KEYEVENTF_UNICODE*/; ::User32.SendInput(1,d, cbSize) ; d.ki.flags = 4/*_KEYEVENTF_UNICODE*/ | 2/*_KEYEVENTF_KEYUP*/; ::User32.SendInput(1,d, cbSize ) ; } else { if(c == '\n'#){ d.ki.vk = 0xD/*_VK_RETURN*/; } elseif(c == '\t'#)d.ki.vk = 0x9/*_VK_TAB*/; else continue; d.ki.flags = 0; d.ki.scan = null; ::User32.SendInput(1,d, cbSize) ; d.ki.flags = 2/*_KEYEVENTF_KEYUP*/; ::User32.SendInput(1,d, cbSize ) ; d.ki.vk = null; } ..thread.delay(tk); } } char = function(n){ var d = INPUTDATA(); var cbSize = ..raw.sizeof(d); d.ki.scan = n; d.ki.flags = 4/*_KEYEVENTF_UNICODE*/; ::User32.SendInput(1,d, cbSize) ; d.ki.flags = 4/*_KEYEVENTF_UNICODE*/ | 2/*_KEYEVENTF_KEYUP*/; ::User32.SendInput(1,d, cbSize ) ; } var kbEvent = ::User32.api("keybd_event","void(BYTE vk,BYTE scan,INT flags,INT extra)"); combine = function(...){ var vk,ext; var args ={ ... }; for(i=1;#args;1){ vk,ext = getCode(args[i]); if(!vk)error("输入的虚拟键名无效:" + args[i],2); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 8, extraInfo ); ..thread.delay(1) } ..thread.delay( delayDown ); for(i=#args;1;-1){ vk,ext = getCode(args[i]); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 0x2/*_KEYEVENTF_KEYUP*/ | 8, extraInfo ); ..thread.delay(1) } ..thread.delay( delayPress ); } pressEx = combine press = function(...){ //模拟键盘按键 var vk,ext; var args ={ ... }; for(i=1;#args;1){ vk,ext = getCode(args[i]); if(!vk)error("输入的虚拟键名无效:" + args[i],2); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 8, extraInfo ); ..thread.delay( delayDown ); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 0x2/*_KEYEVENTF_KEYUP*/ | 8, extraInfo ); ..thread.delay( delayPress ); } } repeat = function(k,rep=1,tk=0){ var vk,ext = getCode(k); if(!vk)error("输入的虚拟键名无效:" + args[i],2); tk := delayPress; for(i=1;rep){ kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 8, extraInfo ); ..thread.delay( delayDown ); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 0x2/*_KEYEVENTF_KEYUP*/ | 8, extraInfo ); ..thread.delay( tk ); } } down = function( ... ){ //按下按键 var vk,ext; var args = { ... }; for( i=1; #args; 1 ){ vk,ext = getCode(args[i]); if(!vk)error("输入的虚拟键名无效:" + args[i],2); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 8, extraInfo ); ..thread.delay(1); } ..thread.delay( delayDown ); } up = function( ... ){ //弹起按键 var vk,ext; var args = { ... }; for( i=1; #args; 1 ){ vk,ext = getCode(args[i]); if(!vk)error("输入的虚拟键名无效:" + args[i],2); kbEvent( vk, ::MapVirtualKey( vk ,0), ext | 0x2/*_KEYEVENTF_KEYUP*/ | 8, extraInfo ); ..thread.delay(1); } ..thread.delay( delayUp ); } waitUp = function(k){ var vk = getCode(k); if(!vk)error("输入的虚拟键名无效:" + k,2); //必须放开 while( ( ::GetAsyncKeyState( vk ) < 0) ){ ..thread.delay(1); //就一直等待 } } wait = function( k ){ var vk = getCode(k); if(!vk)error("输入的虚拟键名无效:" + k,2); var state = ::GetAsyncKeyState( vk ); //必须放开 while( ( ::GetAsyncKeyState( vk ) < 0) ){ ..thread.delay(1); //就一直等待 } //必须按下 while( ::GetAsyncKeyState( vk ) >= 0 ){ ..thread.delay(1); } //必须再次放开 while( ( ::GetAsyncKeyState( vk ) < 0) ){ //如果没有放开 ..thread.delay(1); //就一直等待 } } getState = function( k ){ var vk = getCode(k); if(!vk)error("输入的虚拟键名无效:" + k,2); var s = ::GetKeyState(vk); if(vk== 0x14/*_VK_CAPITAL*/ || vk== 0x90/*_VK_NUMLOCK*/ || vk==0x91/*_VK_SCROLL*/ ) return ( s & 1 ); else return ( s & 0x8000 == 0x8000),s & 1 == 1; } setState = function( state,... ){ var kbState = ..raw.buffer(256); ::User32.GetKeyboardState(kbState); var c; var args = { ... }; for( i=1; #args; 1 ){ vk,ext = getCode(args[i]); if(!vk) error("输入的虚拟键名无效:" + k,2); c = (vk== 0x14/*_VK_CAPITAL*/ || vk== 0x90/*_VK_NUMLOCK*/ || vk==0x91/*_VK_SCROLL*/ ) ? 1 : 2#10000000; if(state) kbState[vk+1] = kbState[vk+1] | c; else kbState[vk+1] = kbState[vk+1] & ~c; } return ::User32.SetKeyboardState(kbState); } getStateX = function( k ){ var vk = getCode(k); if(!vk)error("输入的虚拟键名无效:" + k,2); return ( ::GetAsyncKeyState(vk) & 0x8000 == 0x8000); } isCapsLk = function(){ return getState(0x14/*_VK_CAPITAL*/ ) } capsLk = function(lk=true){ if( ( ::GetKeyState( 0x14/*_VK_CAPITAL*/ ) & 0x01 ) != lk){ press( 0x14/*_VK_CAPITAL*/ ); ..thread.delay( delayPress ); } } scrLk = function(lk=true){ if( ( ::GetKeyState( 0x91/*_VK_SCROLL*/ ) & 0x01 )!= lk ){ press( 0x91/*_VK_SCROLL*/ ); ..thread.delay( delayPress ); } } nmLk = function(lk=true){ if( ( ::GetKeyState( 0x90/*_VK_NUMLOCK*/) & 0x01 )!= lk ){ press( 0x90/*_VK_NUMLOCK*/ ); ..thread.delay( delayPress ); } } block = function(blockIt=true){ ::User32.BlockInput(blockIt); } /**intellisense(key) v2scan(__) = 参数@1指定的键盘虚拟码转换为扫描码\n如果参数@2为 true,则返回扫描码区分左手键右手键 scan2v(__) = 参数@1指定的键盘扫描码转换为虚拟码\n如果参数@2为 true,则返回虚拟码区分左手键右手键 extraInfo = 发送消息的自定义附加值\n该值会传入键盘钩子的extraInfo参数 char(__/*字符编码*/) = 直接用编码发送字符,例:\nkey.char(65) repeat(.(虚拟键名或键码,重复次数) = 重复发送指定的击键\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) repeat(.(虚拟键名或键码,重复次数,间隔毫秒) = 重复发送指定的击键\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) sendString("__/*字符串*/") = 发送字符串,支持中英文字符串,\n此函数不受输入法影响直接发送字符。\n\n换行符发送回车键,制表符发送 tab 按键,\n回车与 tab 发送按键而非字符,要避免误触类似自动完成等快捷键。 sendString("__/*字符串*/",100) = 发送字符串,支持中英文字符串\n并在每次按键添加指定的延时(以毫秒为单位),\n此函数不受输入法影响直接发送字符 send( = 发送键名串指定的按键,\n发送按键而非字符串,不区分双字符键,\n发送字符串请改用 key.sendString 函数 send(.("键名串",延时) = 发送键名串指定的按键\n每个键名都只能使用单个字符,\n此函数发送按键而不是发送字符串,\n键名串包含双字符键上任一字符发送的是相同按键而非对应字符,\n如果打开了输入法,则由输入法确定输入的字符, \n单纯发送字符串请使用 key.sendString 函数(不受输入法影响)\n可选用参数@2指定每次按键之间的延时(以毫秒为单位) getName(.(vk,ext,noLocation) = 返回虚拟键代码码对应的虚拟键名称。\n除参数@ vk 以外,其他参数为可选参数\n如果@ext为true,允许返回扩展键名,主要指小键盘的回车键\n如果参数@noLocation为true,返回键名不区分左右控制键 removeLocation(__) = 对传入的虚拟键码,移除左右控制键的差别,\n返回转换后的虚拟键码,例如_VK_LCTRL转换_VK_为CTRL getCode("__") = 将参数 @1 指定的虚拟键名称或虚拟键代码统一返回为虚拟键码。\n第一个返回值为虚拟键码,第二个返回值表示是否扩展键 combine("CTRL","__") = 发送组合热键,参数个数不限.\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) press(__) = 发送按键,参数个数不限\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) down(__) = 发送键按下指令,参数个数不限\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) up(__) = 发送键弹起指令,参数个数不限\n参数可以是虚拟键名或虚拟键码( _VK 前缀常量) wait(__) = 等待指定按键\n参数可以是键名字,或者按键的虚拟码(_VK前缀常量 waitUp(__) = 等待一个按下的键放开\n参数可以是键名字,或者按键的虚拟码(_VK前缀常量 getStateX(__) = 参数 @1 指定虚拟键名或键码。\n返回指定物理按键的真实按下弹起状态。\n物理按键状态并不一定等于特定界面线程中的按键状态。\n\n此函数忽略键盘映射,可用于非 UI 线程,\n并且不能用于检测按键开关状态(nmlk,scrlk,capslk)。\n此函数内部调用 ::User32.GetAsyncKeyState 函数。 getState(__) = 参数 @1 指定虚拟键名或键码。\n自当前线程消息队列中检测指定按键的是否按下,不一定是物理按键的真实状态。\n仅可用于 U I线程,即使线徎或进程不是前台焦点,函数仍然可以工作,\n对于 NumLk,CapsLk,ScrLk 返回按键的开关状态。\n此函数内部调用 ::User32.GetKeyState 函数。 setState(true,__/*虚拟键名或键码*/) = 设置一个或多个键为按下状态。\nNumLk,CapsLk,ScrLk等键则置为开启状态。\n该函数仅影响当前输入队列,外部线程应先调用 winex.attach 共享输入状态 setState(false,__/*虚拟键名或键码*/) = 设置一个或多个键为松开状态。\nNumLk,CapsLk,ScrLk等键则置为关闭状态。 isCapsLk() = 判断 Caps Lock 键是否打开大写状态 nmLk() = 打开 Num Lock(数字键盘功能切换) nmLk(false) = 关闭 Num Lock(数字键盘功能切换) scrLk() = 打开 Scroll Lock(翻页键功能切换) scrLk(false) = 关闭 Scroll Lock(翻页键功能切换) capsLk() = 打开 Caps Lock,切找到大写状态 capsLk(false) = 关闭 Caps Lock,切换到小写状态 block() = 锁定键盘鼠标 block(false) = 解锁键盘鼠标 delayPress = 更改每次击键并松开后的时间间隔,默认为5毫秒 delayDown = 每次调用key.down函数的默认时间间隔,默认为5毫秒\n在调用press以及pressEx函数时,按下松开键之间也会按此设定延时 delayUp = 每次调用key.up函数后的时间间隔,默认为1毫秒 end intellisense**/