想要实现按下F3时执行操作,例如:按下F3时提示按住了F3。松开的时候提示没有按住F3。可是按键里没有监控键盘按键是否按下松开的命令?那怎么办?小编脑袋里的第一反应就是,要不,我们用WaitKey命令来试试?哦呵呵,瞬间觉得自己好聪明~哈哈然后……
工具/原料产生了这样的代码思路:
1.进入Do循环(使用Do循环每秒一次的监控按键的状态变化)
2.2.使用WaitKey命令获取到当前按下的按键的键值
3.判断变量key的值是否等于114(这里的114是F3的键值)
如果变量key的值等于114,那么执行想要执行的代码
如果变量key的值不等于114,那么就不执行
代码:
Do
Key=WaitKey()//WaitKey等待按任意键
IfKey=114Then//判断是否按下F3
//执行
TracePrint"按住了F3"
Else
//不执行
TracePrint"松开了F3"
EndIf
Delay1000
Loop
执行结果:
执行的结果和预期的不一样?
看到执行结果,小编笑不出来了,这样写当第一次按下F3键放开之后,key的值一直都是F3,也就是说不管你松没松开f3键,Ifkey<>114Then这一句都不会成立,WaitKey命令可以获取你按下了什么键,但是却不能获取这个按键的一个状态。按一次、按很多次、松开了、还按着、WaitKey命令不区分这些,它就返回一个键值。
怎么办怎么办?这时候小编脑子里飘过了很多想法,最后想到了api,通过调用api的GetAsyncKeyState函数(Get-得到Async-端口KeyState-键盘按键状态合起来就是——获取键盘按键状态的端口)来获取指定键的一个状态,根据获取到的状态,就能得知指定键是按下还是松开的。瞬间觉得自己又变聪明了,哦呵呵,有了想法马上实施行动,先了解下GetAsyncKeyState函数的声明和返回值:
GetAsyncKeyState函数的声明,返回值
声明
DeclareFunctionGetAsyncKeyStateLib"user32"Alias"GetAsyncKeyState"(ByValvKeyAsLong)AsInteger
返回值
GetAsyncKeyState返回值等于1说明键已经被按过并且当前是松开的状态GetAsyncKeyState返回值等于0说明键是松开的状态GetAsyncKeyState返回值等于-32767说明键是按下的状态
说到这里可能有些同学还不太了解api是神马,那……什么是api呢?——
API(ApplicationProgrammingInterface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
API与系统调用的区别:
系统调用代码都处于内核态,API是操作系统提供的一组函数,通常以库的形式存在,供用户调用,所以,API代码可能是完全是用户空间代码,也有的API调用了系统调用。
白话版解释——
Api就是把操作系统上一些没有开放出来给用户的一些系统命令,做成函数,就像一个中介,我们调用api函数,api函数再把消息反馈给操作系统。
好兴奋~,有一种终于找到组织找到方向的感觉。方法我们找到了,api函数也找到了,接着要怎么用它呢?
铛铛铛~上代码思路以及代码~
代码思路:
1.声明GetAsyncKeyState函数
2.进入Do循环(使用Do循环每秒一次的监控按键的状态——通过GetAsyncKeyState函数,判断按键当前的状态)
3.用GetAsyncKeyState函数,获取F3(114)按键的状态,并且把返回值复制给变量x
4.使用selectcase判断语句判断变量x的值
如果变量x的值等于1,那么不执行
如果变量x的值等于0,那么不执行
如果变量x的值等于-32767,那么执行
代码:
DeclareFunctionGetAsyncKeyStateLib"user32"Alias"GetAsyncKeyState"(ByValvKeyAsLong)AsInteger
//上面这句至关重要的,调用api接口的声明,声明好之后,就可以愉快的调用api函数</font>
///////////////////////////////用循环每秒判断一次按键的状态/////////////////////////
Do
x=GetAsyncKeyState(114)//GetAsyncKeyState参数类型是long数值类型,所以不支持直接写F3
SelectCasex
Case1
TracePrint"没按住F3"//这里需要注意下,</font>按住按键的时候返回值是-32767,松开的时候进入判断会先返回一个1,然后再次判断的时候返回值才是0.这样我们松开按键的情况下,会造成多判断一次的延迟。所以这里将返回值1也归类为没按住按键进行判断。
//不执行
Case0
TracePrint"没按住F3"
//不执行
Case-32767
TracePrint"按住了F3"
//执行
EndSelect
Delay1000
Loop
执行结果:
按键状态检测不支持多线程(多线程启动,只会检测第一个启动的线程中的按键状态监控),不支持同时判断多个按键的状态。
很感动。总算实现了。