locked
How to do a Drag out operation RRS feed

  • Question

  • I want to Drag out an item from the program to the draged out Location ie. Desktop.
    Mainly its a picture in a picture box that needs to be Draged and Droped from the program to the droped location on explorer
    Monday, August 17, 2009 11:01 PM

Answers

  • Drag and drop of images can be straighforward.  However, your situation is complicated in that you want to be able to drop into Windows Explorer.

    The following code is based on Riquel_Dong (MSFT)'s post, which dealt with text files, here: http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/afb07df0-3da4-49c6-9196-52b357abf701

    Option Explicit On
    Option Strict On
    
    Imports System.IO
    
    Public Class Form1
    
        Private m_CurrentDataObject As ImageShellDataObject
    
        Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
            If m_CurrentDataObject Is Nothing Then 'No drag and drop already in progress...
                'The specified filename is what will be created by explorer when the drop occurs.
                DoPictureBoxDragDrop(PictureBox1, "test.jpg")
            End If
        End Sub
    
        Private Sub PictureBox1_QueryContinueDrag(ByVal sender As System.Object, ByVal e As System.Windows.Forms.QueryContinueDragEventArgs) Handles PictureBox1.QueryContinueDrag
            'ESC pressed 
            If e.EscapePressed Then
                e.Action = DragAction.Cancel
                Return
            End If
            'Drop!
            If e.KeyState = 0 Then
                m_CurrentDataObject.SetData(ShellClipboardFormats.CFSTR_INDRAGLOOP, 0)
                e.Action = DragAction.Drop
                Return
            End If
            e.Action = DragAction.Continue
        End Sub
    
        Private Sub DoPictureBoxDragDrop(ByVal pb As PictureBox, ByVal fileNameToAppearInExplorer As String)
            Dim tempPath As String = Path.Combine(System.IO.Path.GetTempPath(), Path.GetRandomFileName())
            Dim fileName As String = Path.Combine(tempPath, fileNameToAppearInExplorer)
    
            Directory.CreateDirectory(tempPath)
    
            m_CurrentDataObject = New ImageShellDataObject
            m_CurrentDataObject.SetData(DataFormats.FileDrop, New String() {fileName})
            m_CurrentDataObject.SetData(ShellClipboardFormats.CFSTR_INDRAGLOOP, 1)
            m_CurrentDataObject.SetData(pb.Image)
            pb.DoDragDrop(m_CurrentDataObject, DragDropEffects.Copy)
    
            'Delete temporary file.
            If File.Exists(fileName) Then
                File.Delete(fileName)
            End If
            If System.IO.Directory.Exists(tempPath) Then
                Directory.Delete(tempPath, False)
            End If
    
            m_CurrentDataObject = Nothing
        End Sub
    
    End Class
    
    'Constant declarations. Please refer to "shlobj.h" 
    Public Class ShellClipboardFormats
        Public Const CFSTR_SHELLIDLIST As String = "Shell IDList Array"
        Public Const CFSTR_SHELLIDLISTOFFSET As String = "Shell Object Offsets"
        Public Const CFSTR_NETRESOURCES As String = "Net Resource"
        Public Const CFSTR_FILEDESCRIPTORA As String = "FileGroupDescriptor"
        Public Const CFSTR_FILEDESCRIPTORW As String = "FileGroupDescriptorW"
        Public Const CFSTR_FILECONTENTS As String = "FileContents"
        Public Const CFSTR_FILENAMEA As String = "FileName"
        Public Const CFSTR_FILENAMEW As String = "FileNameW"
        Public Const CFSTR_PRINTERGROUP As String = "PrinterFreindlyName"
        Public Const CFSTR_FILENAMEMAPA As String = "FileNameMap"
        Public Const CFSTR_FILENAMEMAPW As String = "FileNameMapW"
        Public Const CFSTR_SHELLURL As String = "UniformResourceLocator"
        Public Const CFSTR_INETURLA As String = CFSTR_SHELLURL
        Public Const CFSTR_INETURLW As String = "UniformResourceLocatorW"
        Public Const CFSTR_PREFERREDDROPEFFECT As String = "Preferred DropEffect"
        Public Const CFSTR_PERFORMEDDROPEFFECT As String = "Performed DropEffect"
        Public Const CFSTR_PASTESUCCEEDED As String = "Paste Succeeded"
        Public Const CFSTR_INDRAGLOOP As String = "InShellDragLoop"
        Public Const CFSTR_DRAGCONTEXT As String = "DragContext"
        Public Const CFSTR_MOUNTEDVOLUME As String = "MountedVolume"
        Public Const CFSTR_PERSISTEDDATAOBJECT As String = "PersistedDataObject"
        Public Const CFSTR_TARGETCLSID As String = "TargetCLSID"
        Public Const CFSTR_LOGICALPERFORMEDDROPEFFECT As String = "Logical Performed DropEffect"
        Public Const CFSTR_AUTOPLAY_SHELLIDLISTS As String = "Autoplay Enumerated IDList Array"
    End Class
    
    Public Class ImageShellDataObject
        Inherits DataObject
    
        'This flag is used to prevent multiple callings to "GetData" when dropping in Explorer. 
    
        Private downloaded As Boolean = False
    
        Public Overloads Overrides Function GetData(ByVal format As String) As Object
            Dim obj As Object = MyBase.GetData(format)
            If System.Windows.Forms.DataFormats.FileDrop = format AndAlso Not InDragLoop() AndAlso Not downloaded Then
                Dim i As Integer
                Dim files As String() = DirectCast(obj, String())
                For i = 0 To files.Length - 1
                    DownloadFile(files(i))
                Next
                downloaded = True
            End If
    
            Return obj
        End Function
    
        Private Sub DownloadFile(ByVal filename As String)
            'Put the code to write image to the specified filename here.
            Me.GetImage().Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg)
        End Sub
    
        Private Function InDragLoop() As Boolean
            Return (0 <> CInt(GetData(ShellClipboardFormats.CFSTR_INDRAGLOOP)))
        End Function
    
    End Class
    
    • Marked as answer by Zakukashi Friday, August 21, 2009 1:42 AM
    Tuesday, August 18, 2009 12:06 AM

All replies

  • Drag and drop of images can be straighforward.  However, your situation is complicated in that you want to be able to drop into Windows Explorer.

    The following code is based on Riquel_Dong (MSFT)'s post, which dealt with text files, here: http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/afb07df0-3da4-49c6-9196-52b357abf701

    Option Explicit On
    Option Strict On
    
    Imports System.IO
    
    Public Class Form1
    
        Private m_CurrentDataObject As ImageShellDataObject
    
        Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
            If m_CurrentDataObject Is Nothing Then 'No drag and drop already in progress...
                'The specified filename is what will be created by explorer when the drop occurs.
                DoPictureBoxDragDrop(PictureBox1, "test.jpg")
            End If
        End Sub
    
        Private Sub PictureBox1_QueryContinueDrag(ByVal sender As System.Object, ByVal e As System.Windows.Forms.QueryContinueDragEventArgs) Handles PictureBox1.QueryContinueDrag
            'ESC pressed 
            If e.EscapePressed Then
                e.Action = DragAction.Cancel
                Return
            End If
            'Drop!
            If e.KeyState = 0 Then
                m_CurrentDataObject.SetData(ShellClipboardFormats.CFSTR_INDRAGLOOP, 0)
                e.Action = DragAction.Drop
                Return
            End If
            e.Action = DragAction.Continue
        End Sub
    
        Private Sub DoPictureBoxDragDrop(ByVal pb As PictureBox, ByVal fileNameToAppearInExplorer As String)
            Dim tempPath As String = Path.Combine(System.IO.Path.GetTempPath(), Path.GetRandomFileName())
            Dim fileName As String = Path.Combine(tempPath, fileNameToAppearInExplorer)
    
            Directory.CreateDirectory(tempPath)
    
            m_CurrentDataObject = New ImageShellDataObject
            m_CurrentDataObject.SetData(DataFormats.FileDrop, New String() {fileName})
            m_CurrentDataObject.SetData(ShellClipboardFormats.CFSTR_INDRAGLOOP, 1)
            m_CurrentDataObject.SetData(pb.Image)
            pb.DoDragDrop(m_CurrentDataObject, DragDropEffects.Copy)
    
            'Delete temporary file.
            If File.Exists(fileName) Then
                File.Delete(fileName)
            End If
            If System.IO.Directory.Exists(tempPath) Then
                Directory.Delete(tempPath, False)
            End If
    
            m_CurrentDataObject = Nothing
        End Sub
    
    End Class
    
    'Constant declarations. Please refer to "shlobj.h" 
    Public Class ShellClipboardFormats
        Public Const CFSTR_SHELLIDLIST As String = "Shell IDList Array"
        Public Const CFSTR_SHELLIDLISTOFFSET As String = "Shell Object Offsets"
        Public Const CFSTR_NETRESOURCES As String = "Net Resource"
        Public Const CFSTR_FILEDESCRIPTORA As String = "FileGroupDescriptor"
        Public Const CFSTR_FILEDESCRIPTORW As String = "FileGroupDescriptorW"
        Public Const CFSTR_FILECONTENTS As String = "FileContents"
        Public Const CFSTR_FILENAMEA As String = "FileName"
        Public Const CFSTR_FILENAMEW As String = "FileNameW"
        Public Const CFSTR_PRINTERGROUP As String = "PrinterFreindlyName"
        Public Const CFSTR_FILENAMEMAPA As String = "FileNameMap"
        Public Const CFSTR_FILENAMEMAPW As String = "FileNameMapW"
        Public Const CFSTR_SHELLURL As String = "UniformResourceLocator"
        Public Const CFSTR_INETURLA As String = CFSTR_SHELLURL
        Public Const CFSTR_INETURLW As String = "UniformResourceLocatorW"
        Public Const CFSTR_PREFERREDDROPEFFECT As String = "Preferred DropEffect"
        Public Const CFSTR_PERFORMEDDROPEFFECT As String = "Performed DropEffect"
        Public Const CFSTR_PASTESUCCEEDED As String = "Paste Succeeded"
        Public Const CFSTR_INDRAGLOOP As String = "InShellDragLoop"
        Public Const CFSTR_DRAGCONTEXT As String = "DragContext"
        Public Const CFSTR_MOUNTEDVOLUME As String = "MountedVolume"
        Public Const CFSTR_PERSISTEDDATAOBJECT As String = "PersistedDataObject"
        Public Const CFSTR_TARGETCLSID As String = "TargetCLSID"
        Public Const CFSTR_LOGICALPERFORMEDDROPEFFECT As String = "Logical Performed DropEffect"
        Public Const CFSTR_AUTOPLAY_SHELLIDLISTS As String = "Autoplay Enumerated IDList Array"
    End Class
    
    Public Class ImageShellDataObject
        Inherits DataObject
    
        'This flag is used to prevent multiple callings to "GetData" when dropping in Explorer. 
    
        Private downloaded As Boolean = False
    
        Public Overloads Overrides Function GetData(ByVal format As String) As Object
            Dim obj As Object = MyBase.GetData(format)
            If System.Windows.Forms.DataFormats.FileDrop = format AndAlso Not InDragLoop() AndAlso Not downloaded Then
                Dim i As Integer
                Dim files As String() = DirectCast(obj, String())
                For i = 0 To files.Length - 1
                    DownloadFile(files(i))
                Next
                downloaded = True
            End If
    
            Return obj
        End Function
    
        Private Sub DownloadFile(ByVal filename As String)
            'Put the code to write image to the specified filename here.
            Me.GetImage().Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg)
        End Sub
    
        Private Function InDragLoop() As Boolean
            Return (0 <> CInt(GetData(ShellClipboardFormats.CFSTR_INDRAGLOOP)))
        End Function
    
    End Class
    
    • Marked as answer by Zakukashi Friday, August 21, 2009 1:42 AM
    Tuesday, August 18, 2009 12:06 AM
  • Thank you so much I have been after this for so long!!
    Friday, August 21, 2009 1:42 AM