[[20200422001834]] 『キーバッファをクリアしたい』(minoco) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『キーバッファをクリアしたい』(minoco)

初めまして
OnKeyメソッドにて、特定のキーにマクロをアサインしていますが、
キーが押されてからマクロが実行されるまでに遅延が生じます。
どうも、キーが連続して押される(=キーを押下したまま)の状態だと
遅延しているようです。
そこで、キーバッファをクリアすれば即時実行されるのではないかと
考えましたが、ExcelのVBAからキーバッファをする方法が分かりません。

Win32APIの「PeekMessage」を使って、以下の様なコードを実装して
みましたが、Excelが以上終了してしまいます。

特定のキーが入力される度にキーバッファをする方法をご教示いただけ
ないでしょうか。

以上です。

< 使用 Excel:Office365、使用 OS:Windows10 >


 メッセージキューのクリアについては分かりませんが、(回答じゃなくってスミマセン)
 異常終了が気になったので、再現できるかなーと思って書いてみました。
 あ、でもウチはExcel2010なんで、hwndに関連する挙動がそもそも違うかもしれませんね。
 再現にならないかな....

    Option Explicit
    Type POINTAPI
            x As Long
            y As Long
    End Type
    Type MSG
        hwnd As LongPtr
        message As Long
        wParam As LongPtr
        lParam As LongPtr
        time As Long
        pt As POINTAPI
    End Type

    Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
    Private Declare PtrSafe Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As MSG, ByVal hwnd As LongPtr, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
    Private Declare PtrSafe Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)
    'Private Declare PtrSafe Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Long
    Const PM_NOREMOVE = &H0
    Const PM_REMOVE = &H1
    Const PM_NOYIELD = &H2

    Const WM_KEYFIRST = &H100
    Const WM_KEYLAST = &H109

    Sub test()
        Dim m As MSG, h As LongPtr
        Dim ks As Long
    '    h = FindWindow("XLMAIN", Application.Caption)
    '    Debug.Print Timer, h, Application.hwnd
        Do While PeekMessage(m, Application.hwnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)
            Debug.Print Timer, m.hwnd, m.lParam, m.message, m.time, m.wParam
        Loop
    '    Do While GetAsyncKeyState(vbKeyF1) And &H8000
    '    Loop
        Debug.Print Timer, "Main"
        Sleep 1000
        Debug.Print Timer, "test End"
    End Sub

    Sub SetOnKey()
        Application.OnKey "{F1}", "test"
    End Sub
    Sub UnSetOnkey()
        Application.OnKey "{F1}"
    End Sub

 F1をポンと1回押した結果 PeekMessageが端っからゼロで、1回もループしませんでした。
 やっぱ再現にならなかった^^;
 (まぁこんだけしか書いてないし)

 F1を1秒くらい押しっぱなしにしてみたら、PeekMessageがゼロ以外を返してきましたが、
 異常終了にはならなかったものの、
 testが3回連続で実行されてしまいました。

 試しにループ抜けの条件をGetAsyncKeyStateでの判定に変えてみましたが、
 それでもF1を1秒くらい押しっぱなしにするとtestが2回は実行されてしまいます。

 何でしょう。なんとなくの勘ですけど、
 そもそも
 >キーが押されてからマクロが実行されるまでに遅延が生じます
 そう見えるだけで、実はそうじゃなかったりしないかなー?
 なんて思ったりしてます。

(白茶) 2020/04/22(水) 19:33


コメントありがとうございました。

>そう見えるだけで、実はそうじゃなかったりしないかなー?
そうかもしれません。もう少し状況を整理してみます。
何か分かりましたら、この掲示板で報告させていただきます。

取り急ぎ。
(minoco) 2020/04/22(水) 19:53


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.