T-07 マウスポインタ下のイメージを自動で移動させる2022.05.03
次の書籍の第1章~5章を公開しています。
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」
次図は、マウスポインタの位置に応じて、Imageコントロールの位置が上下するサンプルです。
位置が上になっているImageコントロールをクリックすると、別のImageコントロールに画像がコピーされます。フォームをクリックすると、画像は削除されます。
今回はこの動作を再現します。
このような動作の実現にはいくつかの方法が考えられますが、最も簡単だと思われる方法で実装します。
サンプルファイル ダウンロード
準備
ユーザーフォームを挿入し、次のコントロールを追加します。
■Imageコントロール
役割:画像表示用
オブジェクト名:Image_Main
個数:1
幅:60
高さ:42
BackColor:&H00FFFFFF&
BackStyle:1 - fmBackStyleOpaque
BorderStyle:1 - fmBorderStyleSingle
■Imageコントロール
役割:画像格納用
オブジェクト名:Image1/Image2/Image3/Image4
個数:4
幅:60
高さ:42
Picture:任意の画像
BackColor:&H00FFFFFF&
BackStyle:1 - fmBackStyleOpaque
BorderStyle:1 - fmBorderStyleSingle
■Labelコントロール
役割:イベント感知用
オブジェクト名:Label_Main
個数:1
幅:240
高さ:60
BackStyle:0 - fmBackStyleTransparent
BorderStyle:0 - fmBorderStyleNone
Labelの下辺がImage1~4の下辺と重なるように配置します。
Labelコントロールの重なり順序は一番手前にします。
感知用Labelが一番手前でない場合は、感知用Labelを選択した状態で、メニューバーの「書式」→「順序」→「最前面へ移動」を選択します。
サンプルコード
フォームモジュールに記述します。
'マウスポインタの下にあるImageコントロールを自動で移動させる Option Explicit '変数 Private strImageName As String 'イメージ名 格納用
'■ラベルイベント(Label_Main) '+++ MouseDownイベント +++ Private Sub Label_Main_MouseDown(ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal X As Single, _ ByVal Y As Single) If strImageName = "" Then Exit Sub 'Imageコントロール(Image_Main)に画像反映 Image_Main.Picture = Controls(strImageName).Picture End Sub
'+++ MouseMoveイベント +++ Private Sub Label_Main_MouseMove(ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal X As Single, _ ByVal Y As Single) Dim objC As MSForms.Control For Each objC In Me.Controls If TypeName(objC) = "Image" Then 'Imageコントロールに限定 With objC If IsNumeric(Right$(.Name, 1)) Then 'オブジェクト名の最後が数字の場合 'Imageコントロールの位置をLabel_Mainの下辺に合わせる .Top = Label_Main.Top + Label_Main.Height - .Height 'マウスポインタとImageコントロールの横位置重なりを判定 If .Left < (Label_Main.Left + X) Then If (Label_Main.Left + X) < (.Left + .Width) Then strImageName = .Name End If End If End If End With End If Next If strImageName = "" Then Exit Sub Controls(strImageName).Top = Label_Main.Top End Sub
'■フォームイベント(UserFrom1) '+++ Clickイベント +++ Private Sub UserForm_Click() Image_Main.Picture = Nothing End Sub
'+++ MouseMoveイベント +++ Private Sub UserForm_MouseMove(ByVal Button As Integer, _ ByVal Shift As Integer, _ ByVal X As Single, _ ByVal Y As Single) If strImageName = "" Then Exit Sub With Controls(strImageName) .Top = Label_Main.Top + Label_Main.Height - .Height End With strImageName = "" End Sub
簡単な解説
■移動と移動制限・配置
イベント感知用のLabelコントロールを、Image1~4の下辺に重なるようにかぶせて、Labelのイベントで処理を実行しています。
LabelコントロールのMouseMoveイベントは、そのラベル上のX位置・Y位置を取得できるため、マウスポインタと重なっているImageコントロールを検索します。
検索対象はフォーム上の全てのコントロールですが、判定でImageコントロールで、かつオブジェクト名の最後が数値のものに絞っています。
該当するコントロールは全てLabel_Mainの下辺の位置に移動します。
マウスポインタと重なっているImageコントロールが見つかった場合は、strImageName変数にオブジェクト名を格納し、MouseMoveイベントの最後でLabel_Mainコントロールの上辺の位置に移動します。
マウスポインタがLabel_Mainの範囲外に移動した場合を考慮し、UserFormのMouseMoveイベントにstrImageNameのコントロールを下辺に移動する処理を入れています。
■イメージの変更
Label_Main上でマウスボタンが押された場合、strImageNameに格納されている(持ち上がっている)Imageコントロールの画像を、Image_Mainにコピーします。
ユーザーフォームをクリックすると、Image_Mainの画像をクリアします。
この方法を用いたゲーム例
2010年頃にユーザーフォームを用いた麻雀ゲームを作成しました。
その中で今回の内容を用いています。
※画像をクリックするとYoutubeのサンプル動画(48秒)に飛びます
書籍紹介140以上のサンプルファイル付き!
知りたいがすぐわかる! やりたいがすぐできる!
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」(Kindle版)
ユーザーフォームを扱えると、VBAでできることが大きく広がります!
本書では、知りたいこと、やりたいことから、逆引きで学びを深められます。
■ 購入:amazon