T-02 クリックでイメージを掴み・離す2022.05.03
次の書籍の第1章~5章を公開しています。
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」
フォーム上に配置されたイメージコントロールを、最初のクリックで掴み、次のクリックで離します。
イメージを掴んでいる間は、そのイメージを自由に移動させられます。
ドラッグ&ドロップとは異なるコントロールの移動です。
このような動作の実現にはいくつかの方法が考えられますが、最も簡単だと思われる方法で実装します。
サンプルファイル ダウンロード
準備
ユーザーフォームを挿入し、次のコントロールを追加します。
■Imageコントロール
役割:画像を表示
オブジェクト名:Image1~4
個数:4
幅:80(ポイント)
高さ:60(ポイント)
BackStyle:0 - fmBackStyleTransparent
BorderStyle:0 - fmBorderStyleNone
Picture:任意の画像を設定します 背面透過の場合は透過gifを使用します
PictureAlignment:2 - fmPictureAlignmentCenter
■Labelコントロール
役割:イベント感知用
オブジェクト名:Label_Main
個数:1
幅:252
高さ:180
BackStyle:0 - fmBackStyleTransparent
BorderStyle:0 - fmBorderStyleNone
イベント感知用のLabelコントロールは、重なり順を一番手前にします。
感知用Labelが一番手前でない場合は、感知用Labelを選択した状態で、メニューバーの「書式」→「順序」→「最前面へ移動」を選択します。
その後、フォームのクライアント領域左上隅に移動します。
サンプルコード
フォームモジュールに記述します。
'フォーム上のイメージをクリックで掴みクリックで離す Option Explicit Private strImageName As String
'■フォームイベント(UserForm1) '+++ Initializeイベント +++ Private Sub UserForm_Initialize() 'イベント感知用ラベルをフォームにぴったりと重ねる With Label_Main .Top = 0 .Left = 0 .Width = Me.InsideWidth 'クライアント領域幅 .Height = Me.InsideHeight 'クライアント領域高さ End With End Sub
'■ラベルイベント(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 strImageName = Get_ImageName(Label_Main.Left, Label_Main.Top, X, Y) Else strImageName = "" End If End Sub
'+++ MouseMoveイベント +++ Private Sub Label_Main_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) 'イメージの中心がマウスポインタ位置になるように調整 .Left = Label_Main.Left + X - (.Width / 2) .Top = Label_Main.Top + Y - (.Height / 2) End With End Sub
'■関数 '+++ イメージ名取得関数 +++++++++++++++++++++++++++++++++++++++++ 'マウスポインタがイメージと重なっている場合にそのイメージ名を返す '【引数】 ' L:イベント感知ラベルLeft位置 ' T:イベント感知ラベルTop位置 ' X:マウスポインタX位置 ' Y:マウスポインタY位置 '【戻り値】 ' イメージ名 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Private Function Get_ImageName(ByVal L As Single, ByVal T As Single, _ ByVal X As Single, ByVal Y As Single) As String Dim objC As MSForms.Control For Each objC In Me.Controls If TypeName(objC) = "Image" Then 'コントロールタイプ判定 With objC '重なり判定 If .Left < (L + X) And (L + X) < (.Left + .Width) Then If .Top < (T + Y) And (T + Y) < (.Top + .Height) Then Get_ImageName = .Name Exit Function End If End If End With End If Next End Function
簡単な解説
■UserFormのInitializeイベント
イベント感知用のLabelが移動した場合や、フォームの大きさが変更された場合を想定し、フォームの初期化イベントでLabel位置と大きさの設定を行っています。
■LabelのMouseDownイベント
マウスのボタンを押した時にstrImageName変数が空白であれば、マウスポインタの位置とイメージの重なりを計算します(Get_ImageName関数)。
マウスポインタとイメージが重なっていた場合は、そのコントロールの名前を取得し、strImageName変数に代入します。
マウスのボタンを押した時にstrImageName変数にイメージ名が格納されている場合は、変数を空白にします。
■LabelのMouseMoveイベント
strImageName変数にイメージ名が格納されている場合は、マウスポインタがイメージの中心になるよう、イメージの位置を調整します。
strImageName変数が空白の場合はイベントを抜けます。
書籍紹介140以上のサンプルファイル付き!
知りたいがすぐわかる! やりたいがすぐできる!
「Excel VBA 逆引きで学ぶ ユーザーフォーム&コントロール」(Kindle版)
ユーザーフォームを扱えると、VBAでできることが大きく広がります!
本書では、知りたいこと、やりたいことから、逆引きで学びを深められます。
■ 購入:amazon