因为开始复工的缘故,好久没有更新了,说来可笑,明明前几天还在家无聊盼着早点上班去,可是开工没几天又开始羡慕那些还呆在家里的小伙伴。
好了,言归正传,最近网上看到有大神有excel写游戏,我也准备折腾一下,搞一个游戏出来,之前没有游戏相关的编程经验,所以只能按照自己的想法来了。虽然没吃过猪肉但咱还是见过猪跑的,玩游戏最离不开的当然是键盘操作了,所以作者觉得设计游戏的第一步应该是能够监听键盘事件。
在网上查了很多资料,发现VBA并没有监听键盘的函数,好在VBA可以调用windows api,从而实现对键盘的监听。鉴于有可能有和我一样的小白,所以先从基础的windows api开始讲起吧。
- 什么是windows api
WINDOWS API是WINDOWS自带的一套函数集,可以直接访问操作系统的底层
- API声明
VB声明格式如下:
Declare Function 函数别名 Lib “DLL文件名” Alisa “函数名” (ByVal/ByRef 变量名 As 类型,…) As 输出数据类型。
只要在程序头部安装上面的格式申明一下,就可以开始使用这些函数了。
- 键盘监听函数
这里我们就是通过window api 中的getkeyboardstate函数来实现键盘的监听
查找api手册(手册连接拿走不谢:http://www.vbgood.com/api.html)可以直接得到该函数的用法。
从参数类型及说明介绍可以看出GetKeyboardState总共包含了256个条目的字节数组,分别对应某个键 ,每个数组都是一个7位二进制数,开关键打开的情况下第一位是1(不要问我什么是开关键,你知道按下键后第一位是1就对了),如果某个键当时按下了,则位7为1,如果某个键松开,则为0。
再直白一点
某个键未被按下,你得到的数组应该是这样的,对应十进制的0:
当其按下后,你得到的数组应该是这样的,对应十进制的129:
当其松开后,你得到的数组应该是这样的,对应十进制的128:
前面只是原理,下面上代码(注意,因为用到了Worksheet_SelectionChange函数,所以要把代码放到sheet下才可以使用):
‘声明windows api接口
Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long
‘Worksheet_SelectionChange函数,当工作表上的选定区域发生改变时发生函数内事件。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Application.EnableEvents = False
Dim keycode(0 To 255) As Byte ‘定义256个二进制数组
GetKeyboardState keycode(0) ‘将getkeyboardstate api获取的数组分别赋予keycode数组
If keycode(38) > 127 Then ‘如上文所述keycode等于128或129时表示按键被按下过
‘或正在按下
Call go(0) 'go是自建的键盘执行函数,上键按下时带入0值
Cells(2, 3) = keycode(38)
Cells(3, 3) = keycode(39)
Cells(4, 3) = keycode(40)
Cells(5, 3) = keycode(37)
End If
If keycode(39) > 127 Then
Call go(1) 'go是自建的键盘执行函数,上键按下时带入1值
Cells(2, 3) = keycode(38)
Cells(3, 3) = keycode(39)
Cells(4, 3) = keycode(40)
Cells(5, 3) = keycode(37)
End If
If keycode(40) > 127 Then
Call go(2) 'go是自建的键盘执行函数,上键按下时带入2值
Cells(2, 3) = keycode(38)
Cells(3, 3) = keycode(39)
Cells(4, 3) = keycode(40)
Cells(5, 3) = keycode(37)
End If
If keycode(37) > 127 Then
Call go(3) 'go是自建的键盘执行函数,上键按下时带入3值
Cells(2, 3) = keycode(38)
Cells(3, 3) = keycode(39)
Cells(4, 3) = keycode(40)
Cells(5, 3) = keycode(37)
End If
Sheet1.Range("AC18").Select ‘将ac列18行作为键盘原点,每次移动结束后回到原点
Application.EnableEvents = True
End Sub
Public Function go(s) '键盘执行函数
If s = 0 Then Cells(2, 2) = "上"
If s = 1 Then Cells(2, 2) = "右"
If s = 2 Then Cells(2, 2) = "下"
If s = 3 Then Cells(2, 2) = "左"
End Function
代码很简单,解释最后一个疑惑点,为什么keycode(37)、keycode(38)、keycode(39)、keycode(40)分别代表了上、下、左、右键,直接看下图: