Option Strict On
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.ComTypes
Public Class Form1
'<ComImport>
'<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
'<Guid("00000122-0000-0000-C000-000000000046")>
'Interface IDropTarget
' Sub DragEnter(ByVal pDataObj As System.Runtime.InteropServices.ComTypes.IDataObject, ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
' Sub DragOver(ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
' Sub DragLeave()
' Sub Drop(ByVal pDataObj As System.Runtime.InteropServices.ComTypes.IDataObject, ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
'End Interface
<ComImport>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<Guid("00000122-0000-0000-C000-000000000046")>
Interface IDropTarget
Sub DragEnter(ByVal pDataObj As IDataObject, ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
Sub DragOver(ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
Sub DragLeave()
Sub Drop(ByVal pDataObj As IDataObject, ByVal grfKeyState As Integer, ByVal pt As Point, ByRef pdwEffect As Integer)
End Interface
' re-defined to use FORMATETC.cfFormat As UShort instead of Short (overflow otherwise)
<ComImport, Guid("0000010e-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IDataObject
Sub GetData(ByRef pformatetcIn As FORMATETC, ByRef pmedium As STGMEDIUM)
Sub GetDataHere(ByRef formatetc As FORMATETC, ByRef pmedium As STGMEDIUM)
Function QueryGetData(ByRef pformatetc As FORMATETC) As HRESULT
Function GetCanonicalFormatEtc(ByRef pformatectIn As FORMATETC, ByRef pformatetcOut As FORMATETC) As HRESULT
Sub SetData(ByRef pformatetc As FORMATETC, pmedium As STGMEDIUM, fRelease As Boolean)
Function EnumFormatEtc(dwDirection As Integer, ByRef ppenumFormatEtc As IEnumFORMATETC) As HRESULT
Function DAdvise(ByRef pformatetc As FORMATETC, advf As Integer, pAdvSink As IAdviseSink, ByRef pdwConnection As Integer) As HRESULT
Sub DUnadvise(dwConnection As Integer)
Function EnumDAdvise(ByRef ppenumAdvise As IEnumSTATDATA) As HRESULT
End Interface
Friend Class DropTarget
Implements IDropTarget
Public Sub DragEnter(pDataObj As IDataObject, grfKeyState As Integer, pt As Point, ByRef pdwEffect As Integer) Implements IDropTarget.DragEnter
Console.Beep(1000, 100)
End Sub
Public Sub DragOver(grfKeyState As Integer, pt As Point, ByRef pdwEffect As Integer) Implements IDropTarget.DragOver
'Console.Beep(5000, 10)
End Sub
Public Sub DragLeave() Implements IDropTarget.DragLeave
Console.Beep(2000, 100)
End Sub
Public Sub Drop(pDataObj As IDataObject, grfKeyState As Integer, pt As Point, ByRef pdwEffect As Integer) Implements IDropTarget.Drop
'Console.Beep(8000, 100)
Dim cp_format_descriptor As UInteger = RegisterClipboardFormat(CFSTR_SHELLIDLIST)
Dim descriptor_format As FORMATETC = New FORMATETC With {.cfFormat = CUShort(cp_format_descriptor), .dwAspect = DVASPECT.DVASPECT_CONTENT, .lindex = -1, .tymed = TYMED.TYMED_HGLOBAL}
Dim hr As HRESULT = CType(pDataObj.QueryGetData(descriptor_format), HRESULT)
If (hr = HRESULT.S_OK) Then
Dim storage As STGMEDIUM = New STGMEDIUM()
pDataObj.GetData(descriptor_format, storage)
Dim pida As IntPtr = GlobalLock(storage.unionmember)
Dim cida As CIDA = CType(Marshal.PtrToStructure(pida, GetType(CIDA)), CIDA)
Dim nNbItems As UInteger = cida.cidl
Dim nOffset As Integer = Marshal.SizeOf(GetType(UInteger))
Dim pidlParent As IntPtr = CType((CInt(pida) + CType(Marshal.ReadInt32(pida, nOffset), UInteger)), IntPtr)
For nIndice As UInteger = 1 To nNbItems
nOffset += Marshal.SizeOf(GetType(UInteger))
Dim pidlTarget As IntPtr = CType((CInt(pida) + CType(Marshal.ReadInt32(pida, nOffset), UInteger)), IntPtr)
Dim pidlAbs As IntPtr = ILCombine(pidlParent, pidlTarget)
'Dim sSBPath As System.Text.StringBuilder = New System.Text.StringBuilder(260)
'Dim bRet As Boolean = SHGetPathFromIDList(pidlAbs, sSBPath)
'Console.WriteLine("Path : {0}", sSBPath.ToString())
Dim psf As IShellFolder = Nothing
hr = SHGetDesktopFolder(psf)
Dim pidlChild As IntPtr
Dim IID_IShellFolder As Guid = New Guid("000214E6-0000-0000-C000-000000000046")
hr = SHBindToParent(pidlAbs, IID_IShellFolder, psf, pidlChild)
If (hr = HRESULT.S_OK) Then
Dim strRet As STRRET
Dim sDisplayName As String = Nothing
hr = psf.GetDisplayNameOf(pidlChild, SHGDNF.SHGDN_FORPARSING, strRet)
If (hr = HRESULT.S_OK) Then
Dim sbDisplayName As System.Text.StringBuilder
sbDisplayName = New System.Text.StringBuilder(256)
StrRetToBuf(strRet, pidlChild, sbDisplayName, CType(sbDisplayName.Capacity, UInteger))
sDisplayName = sbDisplayName.ToString()
Console.WriteLine("Name for parsing : {0}", sDisplayName)
End If
sDisplayName = Nothing
hr = psf.GetDisplayNameOf(pidlChild, SHGDNF.SHGDN_FORADDRESSBAR, strRet)
If (hr = HRESULT.S_OK) Then
Dim sbDisplayName As System.Text.StringBuilder
sbDisplayName = New System.Text.StringBuilder(256)
StrRetToBuf(strRet, pidlChild, sbDisplayName, CType(sbDisplayName.Capacity, UInteger))
sDisplayName = sbDisplayName.ToString()
Console.WriteLine("Name for address bar: {0}", sDisplayName)
End If
End If
ILFree(pidlAbs)
Next
End If
End Sub
End Class
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
End Enum
<DllImport("Ole32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function RegisterDragDrop(hwnd As IntPtr, pDropTarget As IDropTarget) As HRESULT
End Function
<DllImport("Ole32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function OleInitialize(pvReserved As IntPtr) As HRESULT
End Function
<DllImport("Ole32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Sub OleUninitialize()
End Sub
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function RegisterClipboardFormat(lpszFormat As String) As UInteger
End Function
Public Const CFSTR_SHELLIDLIST As String = "Shell IDList Array" ' CF_IDLIST
Public Enum tagDVASPECT
DVASPECT_CONTENT = 1
DVASPECT_THUMBNAIL = 2
DVASPECT_ICON = 4
DVASPECT_DOCPRINT = 8
End Enum
Public Enum tagTYMED
TYMED_HGLOBAL = 1
TYMED_FILE = 2
TYMED_ISTREAM = 4
TYMED_ISTORAGE = 8
TYMED_GDI = 16
TYMED_MFPICT = 32
TYMED_ENHMF = 64
TYMED_NULL = 0
End Enum
Public Structure FORMATETC
Public cfFormat As UShort
Public ptd As IntPtr
Public dwAspect As DVASPECT
Public lindex As Integer
Public tymed As TYMED
End Structure
' format of CF_IDLIST
<StructLayout(LayoutKind.Sequential)>
Public Structure CIDA
Public cidl As UInteger
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)>
Public aoffset As UInteger()
End Structure
<DllImport("Kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function GlobalLock(ByVal handle As IntPtr) As IntPtr
End Function
<DllImport("Kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function GlobalUnlock(ByVal handle As IntPtr) As Boolean
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function ILCombine(pidl1 As IntPtr, pidl2 As IntPtr) As IntPtr
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Sub ILFree(pidl As IntPtr)
End Sub
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SHGetPathFromIDList(ByVal pidl As IntPtr, ByVal pszPath As System.Text.StringBuilder) As Boolean
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Friend Shared Function SHGetDesktopFolder(<Out(), MarshalAs(UnmanagedType.Interface)> ByRef ppshf As IShellFolder) As HRESULT
End Function
<DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Public Shared Function SHBindToParent(ByVal pidl As IntPtr, ByRef riid As Guid, ByRef ppv As IShellFolder, ByRef ppidlLast As IntPtr) As HRESULT
End Function
<DllImport("Shlwapi.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
Friend Shared Function StrRetToBuf(ByRef pstr As STRRET, ByVal pidl As IntPtr, ByVal pszBuf As System.Text.StringBuilder, <MarshalAs(UnmanagedType.U4)> ByVal cchBuf As UInteger) As HRESULT
End Function
<ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214E6-0000-0000-C000-000000000046")>
Interface IShellFolder
Function ParseDisplayName(ByVal hwnd As IntPtr, ByVal pbc As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal pszDisplayName As String, <[In], Out> ByRef pchEaten As UInteger, <Out> ByRef ppidl As IntPtr, <[In], Out> ByRef pdwAttributes As SFGAO) As HRESULT
Function EnumObjects(ByVal hwnd As IntPtr, ByVal grfFlags As SHCONTF, <Out> ByRef ppenumIDList As IEnumIDList) As HRESULT
Function BindToObject(ByVal pidl As IntPtr, ByVal pbc As IntPtr, <[In]> ByRef riid As Guid, <Out> <MarshalAs(UnmanagedType.[Interface])> ByRef ppv As Object) As HRESULT
Function BindToStorage(ByVal pidl As IntPtr, ByVal pbc As IntPtr, <[In]> ByRef riid As Guid, <Out> <MarshalAs(UnmanagedType.[Interface])> ByRef ppv As Object) As HRESULT
Function CompareIDs(ByVal lParam As IntPtr, ByVal pidl1 As IntPtr, ByVal pidl2 As IntPtr) As HRESULT
Function CreateViewObject(ByVal hwndOwner As IntPtr, <[In]> ByRef riid As Guid, <Out> <MarshalAs(UnmanagedType.[Interface])> ByRef ppv As Object) As HRESULT
Function GetAttributesOf(ByVal cidl As UInteger, ByVal apidl As IntPtr, <[In], Out> ByRef rgfInOut As SFGAO) As HRESULT
Function GetUIObjectOf(ByVal hwndOwner As IntPtr, ByVal cidl As UInteger, ByRef apidl As IntPtr, <[In]> ByRef riid As Guid, <[In], Out> ByRef rgfReserved As UInteger, <Out> ByRef ppv As IntPtr) As HRESULT
Function GetDisplayNameOf(ByVal pidl As IntPtr, ByVal uFlags As SHGDNF, <Out> ByRef pName As STRRET) As HRESULT
Function SetNameOf(ByVal hwnd As IntPtr, ByVal pidl As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal pszName As String, ByVal uFlags As SHGDNF, <Out> ByRef ppidlOut As IntPtr) As HRESULT
End Interface
Public Enum SHCONTF
SHCONTF_CHECKING_FOR_CHILDREN = &H10
SHCONTF_FOLDERS = &H20
SHCONTF_NONFOLDERS = &H40
SHCONTF_INCLUDEHIDDEN = &H80
SHCONTF_INIT_ON_FIRST_NEXT = &H100
SHCONTF_NETPRINTERSRCH = &H200
SHCONTF_SHAREABLE = &H400
SHCONTF_STORAGE = &H800
SHCONTF_NAVIGATION_ENUM = &H1000
SHCONTF_FASTITEMS = &H2000
SHCONTF_FLATLIST = &H4000
SHCONTF_ENABLE_ASYNC = &H8000
End Enum
Public Enum SFGAO
CANCOPY = &H1
CANMOVE = &H2
CANLINK = &H4
STORAGE = &H8
CANRENAME = &H10
CANDELETE = &H20
HASPROPSHEET = &H40
DROPTARGET = &H100
CAPABILITYMASK = &H177
ENCRYPTED = &H2000
ISSLOW = &H4000
GHOSTED = &H8000
LINK = &H10000
SHARE = &H20000
[READONLY] = &H40000
HIDDEN = &H80000
DISPLAYATTRMASK = &HFC000
STREAM = &H400000
STORAGEANCESTOR = &H800000
VALIDATE = &H1000000
REMOVABLE = &H2000000
COMPRESSED = &H4000000
BROWSABLE = &H8000000
FILESYSANCESTOR = &H10000000
FOLDER = &H20000000
FILESYSTEM = &H40000000
HASSUBFOLDER = &H80000000
CONTENTSMASK = &H80000000
STORAGECAPMASK = &H70C50008
PKEYSFGAOMASK = &H81044000
End Enum
Public Enum SHGDNF
SHGDN_NORMAL = 0
SHGDN_INFOLDER = &H1
SHGDN_FOREDITING = &H1000
SHGDN_FORADDRESSBAR = &H4000
SHGDN_FORPARSING = &H8000
End Enum
<StructLayout(LayoutKind.Explicit, Size:=264)>
Public Structure STRRET
<FieldOffset(0)>
Public uType As UInteger
<FieldOffset(4)>
Public pOleStr As IntPtr
<FieldOffset(4)>
Public uOffset As UInteger
<FieldOffset(4)>
Public cString As IntPtr
End Structure
<ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F2-0000-0000-C000-000000000046")>
Interface IEnumIDList
<PreserveSig()>
Function [Next](ByVal celt As UInteger, <Out> ByRef rgelt As IntPtr, <Out> ByRef pceltFetched As Integer) As HRESULT
<PreserveSig()>
Function Skip(ByVal celt As UInteger) As HRESULT
Sub Reset()
Function Clone() As IEnumIDList
End Interface
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
OleInitialize(IntPtr.Zero)
Dim drop As New DropTarget()
Dim hr As HRESULT = RegisterDragDrop(Me.Handle, drop)
End Sub
End Class