#4 コマンドボタンのイベント

ここに出てくるイベント
  • Click/クリック時
  • DblClick/ダブルクリック時
  • MouseDown/マウスボタンクリック時
  • MouseMove/マウスボタン移動時
  • MouseUp/マウスボタン解放時


コマンドボタンのイベントについて

イベントプロシージャをコーディングするにせよ、マクロを割り当てるにせよ、初心者が一番初めにトライしてみるのが、このコマンドボタンの"クリック時"イベントではないでしょうか。また、フォームを閉じる、別のフォームを開く、レポートを開くなど、1つのフォームに必ず1ケはあるといってもよいのがコマンドボタンコントロールであり、その"クリック時"イベントであるといってもよいでしょう。コマンドボタンには、"フォーカス取得時"イベントや"キークリック時"イベントなど、マウス操作以外のイベントもありますが、やはり何といっても、既定のイベント(注)である"クリック時"イベントがその代表格です。むしろ、このイベントしか使ったことがないという人も少なくないのではないでしょうか。

しかし、コマンドボタンのプロパティシートのイベントタブを見てみると、マウス操作に関連したイベントは全部で5つもあります。
  • クリック時
  • ダブルクリック時
  • マウスボタンクリック時
  • マウスボタン移動時
  • マウスボタン解放時

"ダブルクリック時"イベントはすぐにイメージが湧くと思いますが、それ以外のイベントはどのように発生しているのでしょうか?。今回はその点にスポットを当てて、イベントをトレースしてみたいと思います。
コマンドボタンのイベントプロパティ

※注:既定のイベントとは、オブジェクトを選択して右ボタンをクリック、[イベントのビルド]、[コード ビルダ]を選択することによって作られる、そのオブジェクトを代表する(一番使われる)イベントのことです。"フォーム"では"Load/読み込み時"、"テキストボックス"コントロールでは"BeforeUpdate/更新前処理"イベントなどがそれに当たります。





通常のクリック時の動作は?

それでは、まず初めに、最も一般的な操作として、フォーム上のあるコマンドボタンを1回だけクリックしてみましょう。

その結果は次の通りです。


発生順序 オブジェクト名 イベント名
1 コマンドボタン マウスボタンクリック時
2 コマンドボタン マウスボタン解放時
3 コマンドボタン クリック時


最も頻繁に使われる"クリック時"イベントの発生前には、"マウスボタンクリック時"イベントと"マウスボタン解放時"イベントが発生していることが分かります。これは、マウスのボタンの押し下げと、ボタンを離すという操作をゆっくりと行うと分かるのですが、ボタンを押し下げたままの状態では、"マウスボタンクリック時"イベントだけが発生しています。そして、ボタンを離すと、"マウスボタン解放時"と"クリック時"イベントが連続して発生するのです。つまり、マウス操作において、『クリック=マウスボタンの押し下げと解放』と定義すれば納得できるでしょう。



ボタンを押したままずらしてみる

Windowsでは一般に、「ボタンを押し下げて、そのままの状態でマウスカーソルをボタン上から外れた位置に移動して、指を離す」という操作を行うと、クリックしたときに起こるべき動作は実行されません。うっかり違うボタンを押しても、マウスのボタンを離す位置がそのボタン上になければ、クリックしたことにはならないのです。

このような操作を行った際の、イベントの発生状況は次のようになっています。
実行結果のイミディエイトウィンドウ

確かに、"マウスボタンクリック時"と"マウスボタン解放時"イベントだけで、"クリック時"イベントは発生していません

このことから、同じような名前だからといって、もし、"マウスボタンクリック時"と"クリック時"イベントを混同してコーディングしてしまうと、一度押してしまったコマンドボタンの操作を、マウスの移動によってキャンセルすることができなくなってしまいます。逆に、マウスボタンの押し下げと同時にアクションを起こしたいときには、"マウスボタンクリック時"イベントを使えばよいということになります(あとで説明しますが、これ以外にも、VBAのイベントプロシージャにおいては、"マウスボタンクリック時"イベントを使った方がよい場合があります)。



ダブルクリックしたときの動作は?
今度は、コマンドボタンをダブルクリックしてみましょう。その結果は次の通りです。

発生順序 オブジェクト名 イベント名
1 コマンドボタン マウスボタンクリック時
2 コマンドボタン マウスボタン解放時
3 コマンドボタン クリック時
4 コマンドボタン ダブルクリック時
5 コマンドボタン マウスボタン解放時
6 コマンドボタン クリック時


ここで、1〜3まではシングルクリックのときとまったく同じです。特徴的なのは、そのあとのイベント発生順序です。マウスの操作から考えると、"マウスボタンクリック時"イベントと"マウスボタン解放時"イベントが、一定時間内に2回発生することによって「ダブルクリック」されたと判断され、"ダブルクリック時"イベントが発生してもよさそうなのですが、そういう結果にはなっていません。まず、1回目の"クリック時"イベントが発生し、その直後に"ダブルクリック時"イベントが、"マウスボタン解放時"イベントに先行する形で発生しているのです。さらにどういうわけか、最後に2回目のクリックによる"クリック時"イベントが発生していることが分かります。

この結果から、コーディングの際に十分注意しなければいけないポイントが浮かび上がってきます。それは、イベントとしては「クリック」と「ダブルクリック」は別扱いになってはいるものの、ダブルクリック操作を行うと、"クリック時"イベントも発生するということです。シングルクリックなら処理Aを実行し、ダブルクリックなら処理Bを実行するというプログラムを作ったつもりでも、ダブルクリックによって『A→B→A』という3つの処理が実行されてしまうことになります。

このことを、次のようなイベントプロシージャによって検証してみましょう。

Private Sub cmdTest_Click()
  Debug.Print "処理Aを実行します"

End Sub

Private Sub cmdTest_DblClick(Cancel As Integer)
  Debug.Print "処理Bを実行します"

End Sub

コマンドボタンのダブルクリックを実行後、イミディエイトウィンドウを確認してみます。やはり、『A→B→A』という3つの処理が実行されています。
実行結果のイミディエイトウィンドウ

以上の結果から、"クリック時"イベントと"ダブルクリック時"イベントは併用できないという結論になります。ダブルクリック時の処理を行いたい場合には、シングルクリック時の処理は使わないようにしなければなりません。

※注:仮に併用した場合でも、"クリック時"イベントプロシージャの処理に時間がかかると、"ダブルクリック時"イベントプロシージャが実行されないこともあります。



イベントプロシージャの違いと利用例

ここまでの説明で、コマンドボタンに対する、マウス操作によるイベントの発生状況は分かったと思いますが、イベントプロシージャのコーディング上で、もっと大きな違いはないのでしょうか?。ここで、各イベントプロシージャの宣言の違いを見てみることにしましょう。

プロパティシート上に記述された、TrackEvents()プロシージャの呼び出しをすべてクリアし、コードビルダを使って、モジュール上にイベントプロシージャを作成します。

その各宣言行を一覧にしたものが次の表です。コマンドボタンの名前は「cmdTest」としています。


イベント名 宣言
クリック時 Private Sub cmdTest_Click()
ダブルクリック時 Private Sub cmdTest_DblClick(Cancel As Integer)
マウスボタンクリック時 Private Sub cmdTest_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
マウスボタン解放時 Private Sub cmdTest_MouseUp(Button As Integer, Shift As Integer, As Single, Y As Single)


この表のポイントについてまとめてみました。
  1. "Click/クリック時"イベントプロシージャは引数を持たず、そのプロシージャの内容をそのまま実行する

  2. "DblClick/ダブルクリック時"イベントプロシージャは、引数「Cancel」を持っており、プロシージャ内でこれを"True"に設定することによって、イベントをキャンセルすることができる
    ※このとき、マウスのダブルクリックによって発生していた、2回目の"クリック時"イベントは発生しません。

  3. "MouseDown/マウスボタンクリック時"や"MouseUp/マウスボタン解放時"イベントプロシージャは4つの引数を持っており、押されたマウスのボタン(左Or右)や、同時にShiftキーやCtrlキーなどが押されていたか、どの位置でボタンが押されたかなどを引数として受け取ることができる


    引数 説明
    Button 押されたボタンまたは離されたボタンを表す引数。左ボタン(acLeftButton)・右ボタン(acRightButton)の定数のビットマスクによって調べます。
    Shift ボタンが押されたとき、または離されたときのShiftキー、Ctrlキー、Alt キーの状態を示す引数。それぞれ、定数 acShiftMask、acCtrlMask、acAltMask のビットマスクによって調べます。
    X マウスカーソルの現在のX座標値(twip単位)
    Y マウスカーソルの現在のY座標値(twip単位)

この中で、特に、「3」のキーボード操作の検出を利用することによって、コマンドボタンに対する多様な操作に対応することができます。例えば、同じコマンドボタンに対する押し下げ操作でも、
  • キーボードを使わずに左ボタンが押されたとき
  • キーボードを使わずに右ボタンが押されたとき
  • Shiftキーを押しながらボタンが押されたとき
  • CtrlキーとAltキーを押しながらボタンが押されたとき
などの処理の切り分けを行うことができます。その使用例が次のコードです。
これを応用すれば、より高機能なボタン操作の機能をアプリケーションに実装することができるでしょう。

【コーディング例】

Private Sub cmdTest_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

  If (Button = acLeftButton) And (Shift = 0) Then
    MsgBox "キーボードを使わずに左ボタンが押された"

  ElseIf (Button = acRightButton) And (Shift = 0) Then
    MsgBox "キーボードを使わずに右ボタンが押された"

  ElseIf (Shift And acShiftMask) > 0 Then
    MsgBox "Shiftキーを押しながらボタンが押された"

  ElseIf (Shift And acCtrlMask) > 0 And (Shift And acAltMask) > 0 Then
    MsgBox "CtrlキーとAltキーを押しながらボタンが押された"

実行結果のメッセージボックス   End If

End Sub

| Index | Prev | Next |

 

Copyright © T'sWare All rights reserved