设为首页收藏本站

SKY外语、计算机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3313|回复: 2
打印 上一主题 下一主题

vb万分迷惑 求解

[复制链接]

0

主题

2

好友

139

积分

注册会员

Rank: 2

性别
保密
楼主
发表于 2012-5-18 23:50:45 |显示全部楼层
本帖最后由 sky_yx 于 2015-12-30 14:21 编辑

  • Dim mkey() As Integer    ’ 定义一个动态数组
  • Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)  '窗体按键按下时触发
  •     If UBound(mkey) = 0 Then GoTo  1  '第一次按键,则转到标签号1: 执行
  •         If mkey(UBound(mkey) - 1) <> KeyCode Then           ’如果不是第一次按下按键并且没有按下之前按过的键
  • l:
  •             mkey(UBound(mkey)) = KeyCode                   '将新增的按键码存到数组末尾
  •             ReDim Preserve mkey(UBound(mkey) + 1) As Integer      '动态分配数组大小。保留原有元素,数组下标上限增1
  •             mkey(UBound(mkey)) = 0   '数组末尾元素置零
  •         End If
  • For i = 0 To UBound(mkey)       '不管多少按键被按下,只要有相应的方向键被按下,就执行移动语句
  • If mkey(i) = 37 Then c1.Left = c1.Left - 20
  • If mkey(i) = 40 Then c1.Top = c1.Top + 20
  • If mkey(i) = 39 Then c1.Left = c1.Left + 20
  • If mkey(i) = 38 Then c1.Top = c1.Top - 20
  • Next i
  • Dim aaa As String       '调试输出字符串变量
  •     For i = 0 To UBound(mkey)
  •      aaa = aaa & mkey(i) & " | "
  •     Next
  •     Debug.Print aaa    '调试输出字符串(目前所有被按下的按键的键盘码)
  • End Sub
  • Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)     '松开按键时触发
  • For i = 0 To UBound(mkey) - 1      '数组末尾为零,所以从数组首到数组倒数第二个元素(也就是对所有按下的按键进行分
  •                                                      '析,越早按下的按键码也靠近数组首)
  •     If mkey(i) = KeyCode Then     '哪个按键被松开了,就从这个按键码在数组中的位置开始修改数组的元素的值直到数组结尾
  •         If UBound(mkey) = 1 Or UBound(mkey) = 0 Then  '如果此时数组里只有一个按键的记录,那么就是说这个按键又被松开
  •                                                                                        '那么就将数组再初始化,同Form_Load事件的处理
  •             ReDim mkey(0) As Integer
  •             mkey(0) = 0
  •         Else                                                                        '如果此时,数组里有多个按键码(之前有不止一个按键被按下)
  •             For a = i To UBound(mkey) - 1                        '那么就将此时松开的那个按键的按键码从数组里删除
                                                                     '这是数组的删除元素操作,就是把要删除的数组元素所在的位置用后面的
  •                                                                 '数组元素来移位填充,数组长度减一
  •                 mkey(a) = mkey(a + 1)           ’例如 之前数组为(38 55 26 0)
  •                                           '删除一个按键码 55 后,   数组为 (38 26 0)
  •             Next a
  •         ReDim Preserve mkey(UBound(mkey) - 1) As Integer      '因为删除了一个数组元素,所以数组长度减一
  •         End If
  •     End If
  • Next i
  • End Sub
  • Private Sub Form_Load()
  • ReDim mkey(0) As Integer      '动态分配数组大小为一位动态数组,且当前数组长度为1
  • End Sub



回复

使用道具 评分 举报

0

主题

2

好友

139

积分

注册会员

Rank: 2

性别
保密
沙发
发表于 2012-5-19 01:14:05 |显示全部楼层
本帖最后由 sky_yx 于 2015-12-30 14:21 编辑

经测试,当按下一个按键接着又松开同一按键时,WINDOWS系统会产生中断重复按键的消息接收。
什么意思呢?
找了一下资料,大概意思是,键盘的按键消息处理,每个按键keydown必然对应有keyup.
但系统接收到keydown消息,而没有接收到Keyup消息时,会自动重载keydow消息。(你按下一个键时,没有反复按,只是按着不松开,其实,你只按了一次按键,但是只要没有松开,系统会是作重复按这个键,按一定间隔,重载keydown消息,直到收到对应的keyup消息)而windows消息队列是有序的,一旦有同一按键的KEYDOWN和KEYUP之间没有别的按键的KEYDOWN事件,则会中断重载KEYDOWN消息。等待下一次KEYDOWN消息到达,才再次开启重载机制(就像是一个开关机制,特定条件下开启,特定条件下关闭响应机制)
不知道,我理解的对不.(这种情况与VB程序无关,而与WINDOWS消息机制有关)
看看下面的例子,参考一下:

回复

使用道具 评分 举报

0

主题

2

好友

139

积分

注册会员

Rank: 2

性别
保密
板凳
发表于 2012-5-19 01:18:59 |显示全部楼层
本帖最后由 sky_yx 于 2015-12-30 14:21 编辑

Dim mkey() As Integer
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    If UBound(mkey) = 0 Then GoTo l
        If mkey(UBound(mkey) - 1) <> KeyCode Then
l:
            mkey(UBound(mkey)) = KeyCode
            ReDim Preserve mkey(UBound(mkey) + 1) As Integer
            mkey(UBound(mkey)) = 0
        End If
For i = 0 To UBound(mkey)
If mkey(i) = 37 Then c1.Left = c1.Left - 20
If mkey(i) = 40 Then c1.Top = c1.Top + 20
If mkey(i) = 39 Then c1.Left = c1.Left + 20
If mkey(i) = 38 Then c1.Top = c1.Top - 20
Next i
Dim aaa As String
    For i = 0 To UBound(mkey)
     aaa = aaa & mkey(i) & " | "
    Next
    Debug.Print aaa
    Form1.Cls
    Print aaa
   
End Sub
Private Sub Form_KeyUp(KeyCode As Integer, Shift As Integer)
For i = 0 To UBound(mkey) - 1
    If mkey(i) = KeyCode Then
        If UBound(mkey) = 1 Or UBound(mkey) = 0 Then
            ReDim mkey(0) As Integer
            mkey(0) = 0
        Else
            For a = i To UBound(mkey) - 1
               
                mkey(a) = mkey(a + 1)
               
            Next a
        ReDim Preserve mkey(UBound(mkey) - 1) As Integer
        
       Dim bbb As String
    For n = 0 To UBound(mkey)
     bbb = bbb & mkey(n) & " | "
    Next
    Print bbb
   
        End If
    End If
Next i
End Sub
Private Sub Form_Load()
ReDim mkey(0) As Integer
End Sub
可以看出,我们的程序没问题,数组删除元素正常,是系统消息机制的影响,没有达到预期的效果,当按下一个键有松开同一个键后,系统自动停止了之前按键的消息重载.此时,数组里一切正常,KEYUP  KEYDOWN 事件正常,但是系统代劳的按键消息重载(类似系统记忆之前按下了哪些键没松开)失灵了

回复

使用道具 评分 举报

您需要登录后才可以回帖 登录 | 立即注册


手机版|SKY外语计算机学习 ( 粤ICP备12031577 )    

GMT+8, 2024-5-17 11:35 , Processed in 0.172248 second(s), 26 queries .

回顶部