ホーム ] TIPS ウィンドウズ系 ] TIPS グラフィックス系 ] TIPS メルチメディア系 ] TIPS 理数系 ] TIPS 総覧 ]

上へ
W0001 時間を自動計測する
W0101 MDIメニュー
W0102 外部とのドラッグ&ドロップ

VB.NET2005 TIPS / ウィンドウズ系

W0102 外部とのドラッグ&ドロップ

最終更新:2006/11/12 統合再掲

●解説

 昔、OLEDragDropと言っていたもの。.NETでは アプリ内外の区別がなくなり、方式も変更されている。他のアプリケーション(IE(インタネット)、一般的な画像表示アプリ(Word、PDFアプリ)、ファイルエクスプローラなど) とで、 単数ないし複数の画像やファイルをDrag&Dropする。 外部と題しているが内部でも一向に構わない。

 全く相互が限定されていて暗黙的であるなら、この形式は自由で良いが、一応、Windowsのルールに従った方法を紹介する。

●原理

 Dataオブジェクトにて形式を確定して、D&Dする。代表的なデータ形式は以下の通り。

  • DataFormats.FileDrop :ファイルリスト(ファイルパスを入れた配列)

  • DataFormats.Bitmap    :ビットマップそのもの

  • DataFormats.Text        :ANSI文字列    

●方法

○クライアント (情報を受け取る側)

  1. フォームなどをターゲットとする。AllowDropをTrueにして置く。

  2. DragOverイベントでデータ形式をチェックし反応する。
    OKかNGで、これによりマウスカーソル形状が自動的に変化する。

  3. DragDropイベントでデータ形式をチェックし、OKなら受け取る。

  4. 自分がサーバになっている場合もあるので、注意方。

○サーバ (情報を送る側)

  1. フォーム などにてユーザがマウスダウンし、ある程度の距離のドラッグがあればD&Dを開始させるなどする。
    →マウスダウンのみで開始すると他のUI処理ができなくなる。

  2. ドラッグすべき情報のリストを作成し、そのリストをDataオブジェク化し、適当なコントロールにてD&Dを発行(DoDragDrop)する。あとは、相手次第。
    適当なコントロール:何でも良い。ダミーでもOK

  3. ファイルの移動であるなら、完了イベント(GiveFeedback)にて、元のファイルを削除など行う。

  4. 自分がクライアントでもあるなら、自身の情報も処理する必要がある。受け入れないとか、内部フォーム間での移動などの処理。

●実例 

○クライアント

 この例では、PictureBox(picM)をターゲットで、 画像のコピーのみ可能の場合。 

    Private Sub picM_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles picM.DragOver
        If e.Data.GetDataPresent(DataFormats.FileDrop, False) Then
            e.Effect = DragDropEffects.Copy             'FileDropならコピー可能を知らせる

       
ElseIf e.Data.GetDataPresent(DataFormats.Bitmap, False) Then
            e.Effect = DragDropEffects.Copy
             'あるいはBitmapならコピー可能を知らせる
        Else

            e.Effect = DragDropEffects.None             'これによりマウスカーソルは禁止マークとなる
        End If
    End Sub 

    Private Sub picM_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles picM.DragDrop
    If e.Data.GetDataPresent(DataFormats.FileDrop, False) Then
        Dim s() As String = e.Data.GetData(DataFormats.FileDrop, False)    'ファイルのパス一覧を得る
        Dim ff, i As Integer, fp, FN As String
        Dim fi As FileInfo, bmp As Bitmap
        Me.Cursor = Cursors.WaitCursor
        ff = 0
        For i = 0 To s.Length - 1
            fp = s(i)
            fi = New FileInfo(fp)
            Select Case fi.Extension                          'ファイル拡張子をチェックする
                Case ".bmp", ".jpg", ".jpeg", ".gif", ".tif", ".png"
                    (bmp = Bitmap.FromFile(fp))
                    ・・・・・・・・・・・・・・・・・・      '必要な処理をする。受け取った画像の保存、表示など
                    ff = ff + 1
                Case Else
                    'NOP
            End Select
        Next
        If ff > 0 Then
            ・・・・・・・・・・・・・・・・・・・・・・
            Me.Cursor = Cursors.Default
        Else
            Me.Cursor = Cursors.Default
            MsgBox("有効なファイルがありませんでした。", MsgBoxStyle.Critical)
        End If

   
ElseIf e.Data.GetDataPresent(DataFormats.Bitmap, False) Then
       
Dim bmp As Bitmap = e.Data.GetData(DataFormats.Bitmap, False)   '画像を獲得する
       
・・・・・・・・・・・・・・・・・・         '必要な処理をする。受け取った画像の保存、表示など
    End If
 End Sub

○サーバ

  ピクチャボックスpicMに複数の画像を代表する画像群が表示されており、その一つに対してマウスダウンがあったとする。

Private Sub picM_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picM.MouseDown
    dX = e.X
    dY = e.Y          'ダウン座標を記憶
    If (特定の画像の上) Then
        (ドラッグ開始可能とする。)
    Else
        (ドラッグなしとする。)
    End If
End Sub

Private Sub picM_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles picM.MouseMove
    If e.Button = MouseButtons.Left And (ドラッグ可能) Then
        If Abs(e.X - dX) > 20 And Abs(e.Y - dY) > 20 Then       'ある程度移動したか?

           
Dim s() As String
           
Dim d As New DataObject()                   'D&DのDataオブジェクト
           
s() = (画像のパスのリストを作成)
            d.SetData(DataFormats.FileDrop, False, s)    'インスタンスに形式を登録
           
picM.DoDragDrop(d,DragDropEffects.Copy)    'メソッドを発行
        End If
    End If
End Sub

→DataFormats.FileDrop を他の形式にすれば、その形式でD&Dできる。