VBAのち~んw現象

ち~んw珍現象あれこれ

右クリックメニューが逃げる問題

前回の

akashi-keirin.hatenablog.com

でご紹介した珍現象。TextBoxコントロールのMouseDownイベントを用いて、ショートカットキー押下と同じ現象を引き起こすプロシージャを呼び出しているのに、なぜか処理を呼び出す前にもう1回クリックイベントが起こったみたいになって、まるで1度右クリックメニューが逃げたみたいになっていた。

この文章では何のことか分からないので整理すると、

コードに書いた(はずの)処理
  1. テキストボックス上で右クリック。
  2. MouseDownイベント発生。
  3. 右クリックなので、「Button = 2」がTrueになり、ShowPopupメソッドが実行される。
  4. 右クリックメニューが表示される。
  5. メニューのどれかを左クリック
  6. 左クリックした(CommandBarオブジェクト配下の)ControlオブジェクトのOnActionプロパティに登録されたプロシージャが呼び出される。
実際に起こっていること
  1. テキストボックス上で右クリック。
  2. MouseDownイベント発生。
  3. 右クリックなので、「Button = 2」がTrueになり、ShowPopupメソッドが実行される。
  4. 右クリックメニューが表示される。
  5. メニューのどれかを左クリック
  6. なぜか再度ShowPopupメソッドが発動。
  7. 5.でクリックした位置を基準として右クリックメニューが表示される。
  8. 以下省略(意図した通りの動きになる)。

何でこうなるのか、サッパリ分かりまへん。

とりあえずの対応

id:imihito さんからのアドヴァイスに沿って、MouseDownイベントのコードに少し記述を追加した。

前回のリスト3を、次のように変える。

リスト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
  End If
End Sub

コメント欄で id:imihito さんが教えてくださった通りなので、説明はごく簡潔に。

このプロシージャが終了しただけでは死なないStatic変数 flg を用意して、右クリックされるたびにNot演算することにより、TrueとFalseを1回ごとに切り替えている。これによって2回に1回だけShowPopupが起こるようにしている。

もちろん、これは単なる対症療法に過ぎなくて、全然根本的な解決ではない。

しかし、なんであんなわけの分からないことが起こるのかが分からない以上、どうしようもないとも言える。

実行

f:id:akashi_keirin:20180101204834j:plain

右クリックで出てきたメニューを左クリック!

f:id:akashi_keirin:20180101204844j:plain

ウホッ! 無事一発で貼り付けができ……

って、コラ!!!!!!!!

何でNum Lockが勝手にOffになるねん!!!!!!!!

ちなみに、ちょっとggってみると、これはSendKeysメソッドのバグ(?)らしく、従ってSendKeysメソッドを使わない

「煽る」メニュー(なんちゅう名前やねん)

をクリックしても、NumLockのOn、Off切り替えは起こらない。

f:id:akashi_keirin:20180101204853j:plain

う~ん……。何ともはや……。

おわりに

VBAの闇は深うおますなあ。

@akashi_keirin on Twitter