From comments, a translation of C++ code which works with native DoDragDrop API (Control.DoDragDrop does not seem to work well)
To be adapted/improved =>
(I had to remove an 'e' from Sleep or I could not post ...)
'Does not seem to work fine....
'Dim filesList As System.Collections.Specialized.StringCollection = New System.Collections.Specialized.StringCollection()
'filesList.Add("E:\test.txt")
'filesList.Add("E:\hulk.jpg")
'Dim dataObject As DataObject = New DataObject()
'dataObject.SetData(DataFormats.FileDrop, filesList)
'dataObject.SetFileDropList(filesList)
OleInitialize(IntPtr.Zero)
' Test with 2 files, in a same directory for pidlParent
Dim pItemIDL1 As IntPtr = ILCreateFromPath("E:\test.txt")
Dim pItemIDL2 As IntPtr = ILCreateFromPath("E:\hulk.jpg")
'Dim pItemIDL2 As IntPtr = ILCreateFromPath("E:\test2.txt")
Dim arrayPidl = New IntPtr(255) {}
Dim pidlParent As IntPtr = IntPtr.Zero, pidlItem As IntPtr = IntPtr.Zero
Dim nPidlNumber As Integer = 0
pidlItem = ILFindLastID(pItemIDL1)
arrayPidl(0) = ILClone(pidlItem)
nPidlNumber += 1
ILRemoveLastID(pItemIDL1)
pidlParent = ILClone(pItemIDL1)
ILFree(pItemIDL1)
pidlItem = ILFindLastID(pItemIDL2)
arrayPidl(1) = ILClone(pidlItem)
nPidlNumber += 1
ILRemoveLastID(pItemIDL2)
'pidlParent = ILClone(pItemIDL2)
ILFree(pItemIDL2)
Dim pDataObject As System.Runtime.InteropServices.ComTypes.IDataObject = Nothing
Dim hr As HRESULT = SHCreateFileDataObject(pidlParent, nPidlNumber, arrayPidl, Nothing, pDataObject)
If (hr = HRESULT.S_OK) Then
' Test with an IDropTarget app with window title = "Drop Target"
Dim hWndDest As IntPtr = FindWindow(Nothing, "Drop Target")
' Notepad only works with 1 file
'Dim hWndDest As IntPtr = FindWindow("Notepad", Nothing)
If (hWndDest <> IntPtr.Zero) Then
SwitchToThisWindow(hWndDest, True)
System.Threading.Thread.Slep(500)
Dim rcDest As New RECT()
GetWindowRect(hWndDest, rcDest)
' Move mouse cursor in the middle of the window
Dim nX As Integer = (rcDest.left + (rcDest.right - rcDest.left) / 2) * 65535 / GetSystemMetrics(SM_CXSCREEN)
Dim nY As Integer = (rcDest.top + (rcDest.bottom - rcDest.top) / 2) * 65535 / GetSystemMetrics(SM_CYSCREEN)
Dim mi() As INPUT = New INPUT(2) {}
mi(0).type = INPUT_MOUSE
mi(0).union.mi.dx = nX
mi(0).union.mi.dy = nY
mi(0).union.mi.dwFlags = MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_MOVE
'mi(1).union.mi.dwFlags = MOUSEEVENTF_LEFTDOWN
mi(1).union.mi.dwFlags = MOUSEEVENTF_LEFTUP
'mi(2).union.mi.dwFlags = MOUSEEVENTF_LEFTUP
'SendInput(3, mi, Marshal.SizeOf(mi(0)))
SendInput(2, mi, Marshal.SizeOf(mi(0)))
Dim pDropSource As CDropSource = New CDropSource()
Dim dwEffectDragDrop As UInteger = DragDropEffects.None
hr = OleDoDragDrop(pDataObject, pDropSource, DragDropEffects.Link Or DragDropEffects.Copy, dwEffectDragDrop)
Marshal.ReleaseComObject(pDataObject)
'Dim dde As System.Windows.Forms.DragDropEffects = Me.DoDragDrop(dataObject, DragDropEffects.Copy Or DragDropEffects.Link)
End If
End If
with declarations :
Public Enum HRESULT As Integer
S_OK = 0
S_FALSE = 1
E_NOINTERFACE = &H80004002
E_NOTIMPL = &H80004001
E_FAIL = &H80004005
E_UNEXPECTED = &H8000FFFF
E_OUTOFMEMORY = &H8007000E
DRAGDROP_S_CANCEL = &H40101
DRAGDROP_S_DROP = &H40100
DRAGDROP_S_USEDEFAULTCURSORS = &H40102
End Enum
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Public Shared Function SwitchToThisWindow(hWnd As IntPtr, fAltTab As Boolean) As Boolean
End Function
<DllImport("User32.dll", SetLastError:=True)>
Public Shared Function GetSystemMetrics(ByVal nIndex As Integer) As Integer
End Function
Public Const SM_CXSCREEN As Integer = 0
Public Const SM_CYSCREEN As Integer = 1
Public Const SM_XVIRTUALSCREEN As Integer = 76
Public Const SM_YVIRTUALSCREEN As Integer = 77
Public Const SM_CXVIRTUALSCREEN As Integer = 78
Public Const SM_CYVIRTUALSCREEN As Integer = 79
Public Const MOUSEEVENTF_MOVE As Integer = &H1
Public Const MOUSEEVENTF_LEFTDOWN As Integer = &H2
Public Const MOUSEEVENTF_LEFTUP As Integer = &H4
Public Const MOUSEEVENTF_ABSOLUTE As Integer = &H8000
<StructLayout(LayoutKind.Sequential)>
Public Structure MOUSEINPUT
Public dx As Integer
Public dy As Integer
Public mouseData As Integer
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure KEYBDINPUT
Public wVk As Short
Public wScan As Short
Public dwFlags As Integer
Public time As Integer
Public dwExtraInfo As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)>
Public Structure INPUT
Public type As Integer
Public union As INPUTUNION
End Structure
<StructLayout(LayoutKind.Explicit)>
Public Structure INPUTUNION
<FieldOffset(0)>
Public mi As MOUSEINPUT
<FieldOffset(0)>
Public ki As KEYBDINPUT
'<FieldOffset(0)>
'Public hi As HARDWAREINPUT
End Structure
Public Const INPUT_MOUSE As Integer = 0
Public Const INPUT_KEYBOARD As Integer = 1
<DllImport("User32.dll", SetLastError:=True)>
Public Shared Function SendInput(ByVal nInputs As Integer, <MarshalAs(UnmanagedType.LPArray)> ByVal pInputs() As INPUT, ByVal cbSize As Integer) As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Public Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
Public Sub New(
left As Integer,
top As Integer,
right As Integer,
bottom As Integer)
Me.left = left
Me.top = top
Me.right = right
Me.bottom = bottom
End Sub
End Structure
<DllImport("user32", SetLastError:=True)>
Public Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ILCreateFromPath(pszPath As String) As IntPtr
End Function
<DllImport("Shell32.dll", SetLastError:=True, EntryPoint:="#740", CharSet:=CharSet.Unicode)>
Public Shared Function SHCreateFileDataObject(ByVal pidlFolder As IntPtr, ByVal cidl As UInteger, ByVal apidl As IntPtr(), ByVal pdtInner As System.Runtime.InteropServices.ComTypes.IDataObject, <Out> ByRef ppdtobj As System.Runtime.InteropServices.ComTypes.IDataObject) As HRESULT
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ILFindLastID(pidl As IntPtr) As IntPtr
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ILClone(ByVal pidl As IntPtr) As IntPtr
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ILRemoveLastID(ByVal pidl As IntPtr) As Boolean
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Sub ILFree(pidl As IntPtr)
End Sub
<DllImport("Ole32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function OleInitialize(ByVal pvReserved As IntPtr) As HRESULT
End Function
<DllImport("Ole32.dll", EntryPoint:="DoDragDrop", SetLastError:=True, CharSet:=CharSet.Unicode, ExactSpelling:=True)>
Public Shared Function OleDoDragDrop(<MarshalAs(UnmanagedType.Interface)> pDataObj As System.Runtime.InteropServices.ComTypes.IDataObject, <MarshalAs(UnmanagedType.Interface)> pDropSource As IDropSource, dwOKEffects As UInteger, ByRef pdwEffect As UInteger) As HRESULT
End Function
<ComImport, Guid("00000121-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IDropSource
<PreserveSig>
Function QueryContinueDrag(<MarshalAs(UnmanagedType.Bool)> fEscapePressed As Boolean, grfKeyState As UInteger) As HRESULT
<PreserveSig>
Function GiveFeedback(dwEffect As UInteger) As HRESULT
End Interface
Public Class CDropSource
Implements IDropSource
Private Function QueryContinueDrag(fEscapePressed As Boolean, grfKeyState As UInteger) As HRESULT Implements IDropSource.QueryContinueDrag
If fEscapePressed Then
Return HRESULT.DRAGDROP_S_CANCEL
End If
If Not (grfKeyState And MK_LBUTTON) Then
Console.Beep(9000, 10) 'for test
Return HRESULT.DRAGDROP_S_DROP
End If
Return HRESULT.S_OK
End Function
Public Function GiveFeedback(dwEffect As UInteger) As HRESULT Implements IDropSource.GiveFeedback
Return HRESULT.DRAGDROP_S_USEDEFAULTCURSORS
End Function
End Class
Public Const MK_LBUTTON = &H1
Public Const MK_RBUTTON = &H2
Public Const MK_SHIFT = &H4
Public Const MK_CONTROL = &H8
Public Const MK_MBUTTON = &H10
Public Const MK_XBUTTON1 = &H20
Public Const MK_XBUTTON2 = &H40