#include <Array.au3>
$aSelected_Info = _ExplorerGetSelectedItems("[CLASS:CabinetWClass]")
If @error Then Exit MsgBox(48, "Error", "There is no selected items." & @LF & @LF & "OK ==> EXIT")
_ArrayDisplay($aSelected_Info, "_ExplorerGetSelectedItems") 
;[0][0] = Total items count
;[N][0] = Selected element Index
;[N][1] = Selected element is Directory
;[N][2] = Selected element string (full path to the file/dir)
Func _ExplorerGetSelectedItems($sCabinetWClass="[CLASS:CabinetWClass]")
	Local $aRetInfo[1][1]
	Local $aIndexes, $iIndex, $iCount, $sSelected, $sSelected_Path
	Local $hSearch, $sCurrentFile
	
	$sSelected_Path = _GetWindowsExplorerPath(WinGetHandle($sCabinetWClass))
	$sSelected_Path = StringRegExpReplace($sSelected_Path, "\\+$", "")
	$aIndexes = StringSplit(ControlListView($sCabinetWClass, "", "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($sCabinetWClass, "", "SysListView321", "GetText", $aIndexes[$i])
		$sCurrentFile = $sSelected_Path & "\" & $sSelected
		
		If Not FileExists($sCurrentFile) Then ;Search the extension for file...
			$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] ;Index
		$aRetInfo[$aRetInfo[0][0]][1] = Number(StringInStr(FileGetAttrib($sCurrentFile), "D") > 0) ;Is Directory
		$aRetInfo[$aRetInfo[0][0]][2] = $sCurrentFile ;Selected file / dir
	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)
;
; Function to get the path currently being explored by a Windows Explorer window
;
; $hWnd = Handle to the Windows Explorer window
;
; Returns:
;   Success: String - Path being explored by this window
;   Failure: "" empty string, with @error set:
;      @error = 1 = This is not a valid explorer window
;      @error = 2 = DLL call error, use _WinAPI_GetLastError()
;
; Author: WideBoyDixon
; ==================================================================================================
Func _GetWindowsExplorerPath($hWnd)
    Local $pv, $pidl, $return = "", $ret, $hMem, $pid, $folderPath = DllStructCreate("char[260]"), $className
    Local $bPIDL = False
    Local Const $CWM_GETPATH = 0x400 + 12;
    ; Check the classname of the window first
    $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, "")
    
    ; Retrieve the process ID for our process
    $pid = DllCall("kernel32.dll", "int", "GetCurrentProcessId")
    If @error Then Return SetError(2, 0, "")
    ; Send the CWM_GETPATH message to the window
    $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, "")
    
    ; Lock the shared memory
    $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]) ; Clone the PIDL
        If @error Then Return SetError(2, 0, "")
        $bPIDL = True
        DllCall("shell32.dll", "int", "SHUnlockShared", "uint", $pv) ; Unlock the shared memory
    EndIf
    DllCall("shell32.dll", "int", "SHFreeShared", "uint", $hMem, "uint", $pid) ; Free the shared memory
    
    If $bPIDL Then
        ; Retrieve the path from the PIDL
        $ret = DllCall("shell32.dll", "int", "SHGetPathFromIDList", "ptr", $pidl[0], "ptr", DllStructGetPtr($folderPath))
        If (@error = 0) And ($ret[0] <> 0) Then $return = DllStructGetData($folderPath, 1) ; Retrieve the value
        DllCall("shell32.dll", "none", "ILFree", "ptr", $pidl[0]) ; Free up the PIDL that we cloned
        Return SetError(0, 0, $return) ; Success
    EndIf
    
    Return SetError(2, 0, "") ; Failed a WinAPI call
EndFunc