如何实现按下一个键时执行操作,松开一个键时停止操作?

2025-02-27 14:24:26
推荐回答(2个)
回答1:

想要实现按下F3时执行操作,例如:按下F3时提示按住了F3。松开的时候提示没有按住F3。可是按键里没有监控键盘按键是否按下松开的命令?那怎么办?小编脑袋里的第一反应就是,要不,我们用WaitKey 命令来试试?哦呵呵,瞬间觉得自己好聪明~哈哈然后……


产生了这样的代码思路:

1. 进入Do循环 (使用Do循环每秒一次的监控按键的状态变化)

2.   2. 使用WaitKey命令获取到当前按下的按键的键值

3.   判断变量key的值是否等于114 (这里的114是 F3的键值)

如果变量key的值等于114,那么执行想要执行的代码

如果变量key的值不等于114,那么就不执行

代码:

Do

    Key=WaitKey()  //  WaitKey 等待按任意键

    If Key = 114 Then   //判断是否按下F3

        //执行   

        TracePrint "按住了F3"

    Else

        //不执行

        TracePrint "松开了F3"

    End If

    Delay 1000

Loop

执行结果:


执行的结果和预期的不一样?

看到执行结果,小编笑不出来了,这样写当第一次按下F3键放开之后,key的值一直都是F3,也就是说不管你松没松开f3键,If key <> 114 Then这一句都不会成立,WaitKey  命令可以获取你按下了什么键,但是却不能获取这个按键的一个状态。按一次、按很多次、松开了、还按着、WaitKey  命令不区分这些,它就返回一个键值。

怎么办怎么办?这时候小编脑子里飘过了很多想法,最后想到了api,通过调用api的 GetAsyncKeyState 函数( Get-得到  Async-端口   KeyState-键盘按键状态 合起来就是——获取键盘按键状态的端口) 来获取指定键的一个状态,根据获取到的状态,就能得知指定键是按下还是松开的。瞬间觉得自己又变聪明了,哦呵呵,有了想法马上实施行动,先了解下 GetAsyncKeyState 函数的声明和返回值:


GetAsyncKeyState 函数 的声明,返回值

声明

   

Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Long) As Integer

   


返回值

   

       GetAsyncKeyState 返回值等于1 说明键已经被按过并且当前是松开的状态
       GetAsyncKeyState  返回值等于0 说明键是松开的状态 
       GetAsyncKeyState  返回值等于- 32767  说明键是按下的状态  

   

 

说到这里可能有些同学还不太了解api是神马, 那……什么是api呢?——

API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

API与系统调用的区别:

系统调用代码都处于内核态,API是操作系统提供的一组函数,通常以库的形式存在,供用户调用,所以,API代码可能是完全是用户空间代码,也有的API调用了系统调用。

     白话版解释——

Api就是把操作系统上一些没有开放出来给用户的一些系统命令,做成函数,就像一个中介,我们调用api函数,api函数再把消息反馈给操作系统。

好兴奋~,有一种终于找到组织找到方向的感觉。方法我们找到了,api函数也找到了,接着要怎么用它呢?

铛铛铛~上代码思路以及代码~


代码思路:

1. 声明GetAsyncKeyState 函数

2. 进入Do循环 (使用Do循环每秒一次的监控按键的状态——通过GetAsyncKeyState 函数,判断按键当前的状态)

3. 用GetAsyncKeyState 函数,获取F3(114)按键的状态,并且把返回值复制给变量x

4. 使用select case 判断语句 判断变量x的值 

    如果变量x的值等于1,那么不执行

    如果变量x的值等于0,那么不执行

    如果变量x的值等于- 32767,那么执行


代码:

Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Long) As Integer

//上面这句至关重要的,调用api接口的声明, 声明好之后,就可以愉快的调用api函数

///////////////////////////////用循环 每秒判断一次按键的状态/////////////////////////

Do                     

    x = GetAsyncKeyState(114)  // GetAsyncKeyState 参数类型是long数值类型,所以不支持直接写F3

    Select Case x

    Case 1

        TracePrint "没按住F3"  //这里需要注意下,按住按键的时候返回值是-32767,松开的时候进入判断会先返回一个1,然后再次判断的时候返回值才是0.这样我们松开按键的情况下,会造成多判断一次的延迟。所以这里将返回值1也归类为没按住按键进行判断。

        //不执行

    Case 0

        TracePrint "没按住F3"

        //不执行

    Case - 32767

        TracePrint "按住了F3"

        //执行

    End Select

    Delay 1000

Loop


执行结果:

       按键状态检测不支持多线程(多线程启动,只会检测第一个启动的线程中的按键状态监控),不支持同时判断多个按键的状态。

    很感动。总算实现了。

回答2:

给你的键盘按键增加监听就行了