Application.SendKeysメソッドの不具合への素人的対応

ち~んw珍現象を解決する

SendKeysメソッドで勝手に[Num Lock]キーが押されたみたいになる現象への対応

前回、

akashi-keirin.hatenablog.com

コチラで、SendKeysメソッドを実行すると、なぜか[Num Lock]が切り替わってしまうという珍現象をご紹介した。

コチラによると、どうもバグっぽい。

ただ、別にそんなに複雑なキーストロークを指示しているわけでもないのになあ。

とはいえ、いちいち右クリックメニューを選択するたびに[Num Lock]が切り替わったんではうっとうしいことこの上ない。

[Num Lock]の状態を調べて実行するごとに[Num Lock]を切り替え直すという対応がまず思いついたが、

SendKeys が実行される前に NumLock キーの設定を行います。次に、NumLock キーを SendKeys の実行前にオフにします。
SendKeys が実行されたら、NumLock キーの設定を SendKeys の実行前の状態に戻します。
この手順を実行するには、GetKeyboardState、keybd_event、および SetKeyboardState の各 API 関数を使用します。

ということで、どうもWindowsAPIとか使わないといけないっぽいので、パス(←コラ!)。

あくまでもSendKeysメソッドでどうにかする

よく考えたら、今までApplication.SendKeysメソッドなんて使ったことがなかった。

んで、SendKeysメソッドについて調べてみた。

コチラによると、

Enter キーや Tab キーのように、押しても画面に文字が表示されないキーを指定するときは、次に示すコードを使います。各コードは、キーボードの 1 つのキーに対応します。
キー コード
NumLock {NUMLOCK}

……って、オイ!

SendKeysメソッドで[Num Lock]押しゃあいーじゃん!!!!!!!!

……。

やってみた

前回のリスト1に、次のように付け加える。

リスト1 フォームモジュール
Private Sub TextBoxMain_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, _
                                  ByVal X As Single, ByVal Y As Single)
  Static flg As Boolean
  If Button = xlSecondaryButton Then
    flg = Not flg
    If flg Then contextMenu.ShowPopup
    Application.SendKeys "{NUMLOCK}"    '……(*)'
    DoEvents
  End If
End Sub

見たら分かると思うけれど、(*)を追加。

たったコレだけ。

実行結果

テキストボックス上で右クリック。

f:id:akashi_keirin:20180103232035j:plain

この状態で、「貼り付け」をクリック。

f:id:akashi_keirin:20180103232100j:plain

無事、コマンドが実行され、[Num Lock]の状態もキープされている。画像では全く伝わらないがw

おわりに

コマンド実行時に[Num Lock]のランプが一瞬点滅するのが悲しい。

右クリック→左クリックでメニューが「逃げる」問題や、今回の「勝手に[Num Lock]が切り替わる」問題に、その場しのぎの対応をしているので、コードがどんどん不細工になっていくのがちょっとね……。

WindowsAPIに挑戦するチャンスかも知れないので、そのあたりは宿題ということで……。

@akashi_keirin on Twitter