#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <File.au3>
$hGUI = GUICreate("Drop GUI", 200, 200, -1, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
GUICtrlCreateLabel("Drop Files Here", 0, 0, 200, 200, BitOR($SS_CENTER, $SS_CENTERIMAGE))
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOWNOACTIVATE, $hGUI)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $GUI_EVENT_DROPPED
_ExplorerClearFoldersSelection(1)
EndSwitch
WEnd
Func _ExplorerClearFoldersSelection($iEmptyFoldersMode = 1)
$hExplorer = WinGetHandle("[CLASS:ExplorerWClass]")
If @error Then $hExplorer = WinGetHandle("[CLASS:CabinetWClass]")
$aSelected_Files = _ExplorerGetSelectedItems($hExplorer)
If @error Then
MsgBox(48, "Error", "It seems that there is no selected files, but also it can be an internal function error.")
Return
EndIf
For $i = 1 To $aSelected_Files[0][0]
Switch $iEmptyFoldersMode
Case 1
If $aSelected_Files[$i][1] = 1 Then
$aFiles = _FileListToArray($aSelected_Files[$i][2], "*", 2)
EndIf
If $aSelected_Files[$i][1] = 0 Or UBound($aFiles) <= 1 Then
ControlListView($hExplorer, "", "SysListView321", "DeSelect", $aSelected_Files[$i][0])
EndIf
Case 2
If $aSelected_Files[$i][1] = 0 Or _WinAPI_PathIsDirectoryEmpty($aSelected_Files[$i][2]) Then
ControlListView($hExplorer, "", "SysListView321", "DeSelect", $aSelected_Files[$i][0])
EndIf
EndSwitch
Next
EndFunc
Func _ExplorerSelectAll()
$hExplorer = WinGetHandle("[CLASS:ExplorerWClass]")
If @error Then $hExplorer = WinGetHandle("[CLASS:CabinetWClass]")
ControlListView($hExplorer, "", "SysListView321", "SelectAll")
EndFunc
Func _ExplorerGetSelectedItems($hWnd="[CLASS:CabinetWClass]")
Local $aRetInfo[1][1]
Local $aIndexes, $iIndex, $iCount, $sSelected, $sSelected_Path
Local $hSearch, $sCurrentFile
If Not IsHWnd($hWnd) Then
$hWnd = WinGetHandle($hWnd)
EndIf
$sSelected_Path = _GetWindowsExplorerPath($hWnd)
$sSelected_Path = StringRegExpReplace($sSelected_Path, "\\+$", "")
$aIndexes = StringSplit(ControlListView($hWnd, "", "SysListView321", "GetSelected", 1), "|")
If $aIndexes[1] = "" Then
Return SetError(1, 0, 0)
EndIf
Dim $aRetInfo[$aIndexes[0]+1][3]
For $i = 1 To $aIndexes[0]
$sSelected = ControlListView($hWnd, "", "SysListView321", "GetText", $aIndexes[$i])
$sCurrentFile = $sSelected_Path & "\" & $sSelected
If Not FileExists($sCurrentFile) Then
$hSearch = FileFindFirstFile($sCurrentFile & ".*")
If $hSearch <> -1 Then
$sCurrentFile = $sSelected_Path & "\" & FileFindNextFile($hSearch)
FileClose($hSearch)
EndIf
EndIf
$aRetInfo[0][0] += 1
$aRetInfo[$aRetInfo[0][0]][0] = $aIndexes[$i]
$aRetInfo[$aRetInfo[0][0]][1] = Number(StringInStr(FileGetAttrib($sCurrentFile), "D") > 0)
$aRetInfo[$aRetInfo[0][0]][2] = $sCurrentFile
Next
If $aRetInfo[0][0] = 0 Then
Return SetError(2, 0, 0)
EndIf
ReDim $aRetInfo[$aRetInfo[0][0]+1][3]
Return $aRetInfo
EndFunc
Func _GetWindowsExplorerPath($hWnd)
Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
Local $bPIDL = False
Local Const $CWM_GETPATH = 0x400 + 12
$className = DllCall("user32.dll", "int", "GetClassName", "hwnd", $hWnd, "str", "", "int", 4096)
If @error Then Return SetError(2, 0, "")
If ($className[2] <> "ExploreWClass" And $className[2] <> "CabinetWClass") Then Return SetError(1, 0, "")
$pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
If @error Then Return SetError(2, 0, "")
$hMem = DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWnd, "int", $CWM_GETPATH, "wparam", $pid[0], "lparam", 0)
If @error Then Return SetError(2, 0, "")
If $hMem[0] = 0 Then Return SetError(1, 0, "")
$pv = DllCall("shell32.dll", "ptr", "SHLockShared", "uint", $hMem[0], "uint", $pid[0])
If @error Then Return SetError(2, 0, "")
If $pv[0] Then
$pidl = DllCall("shell32.dll", "ptr", "ILClone", "uint", $pv[0])
If @error Then Return SetError(2, 0, "")
$bPIDL = True
DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv)
EndIf
DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid)
If $bPIDL Then
$ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1)
DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0])
Return SetError(0, 0, $return)
EndIf
Return SetError(2, 0, "")
EndFunc
Func _WinAPI_PathIsDirectoryEmpty($sPath)
Local $Ret = DllCall('shlwapi.dll', 'int', 'PathIsDirectoryEmptyW', 'wstr', $sPath)
If @error Then
Return SetError(1, 0, 0)
EndIf
Return $Ret[0]
EndFunc