Sign in to follow this  
Followers 0
line333

Help with SHMultiFileProperties

3 posts in this topic

_WinAPI_ShellObjectProperties from WinAPIEx.au3 is working fine for single files but when multiple files are selected SHMultiFileProperties windows api needs to be used.

Can anybody provide some help on how to call it?

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Figured it out.

;example
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Local $sFolder = @MyDocumentsDir, $aFiles[2] = ['File1.txt', 'File2.txt']
GUICreate("Multiple files properties", 300, 0)
GUISetState()
_WinAPI_SHMultiFileProperties($sFolder, $aFiles)
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE


; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_SHMultiFileProperties
; Description....: Displays a merged property sheet for a set of files.
; Syntax.........: _WinAPI_SHMultiFileProperties ($sPath, $aNames)
; Parameters.....: $sPath - Sting of the path containing the files.
;                  $aNames - Array of filenames.
; Return values..: Success - 1.
;                  Failure - 0 and sets the @error:
;                  1 - failed to show properties.
;                  2 - failed to create PIDL from path.
;                  3 - Name in $aFiles not found in $sPath.
;                  4 - failed to create IDataObject Interface.
; Author.........: line333
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================

Func _WinAPI_SHMultiFileProperties($sPath, $aNames)
    Local $sNames, $err = 0, $iCount = UBound($aNames), $PIDLChild
    Local $aPIDLAbsolute[$iCount]

    If StringRight($sPath, 1) = '\' Then $sPath = StringTrimRight($sPath, 1)
    $PIDL = _WinAPI_ShellILCreateFromPath($sPath)
    If @error Then Return SetError(2, 0, 0)

    For $i = 0 To $iCount - 1
        $sNames &= 'ptr;'
    Next

    $aPIDL = DllStructCreate($sNames)
    For $i = 0 To $iCount - 1
        $aPIDLAbsolute[$i] = _WinAPI_ShellILCreateFromPath($sPath & '\' & $aNames[$i])
        If @error Then
            $err = 2
            ExitLoop
        Else
            $PIDLChild = _WinAPI_ILFindChild($PIDL, $aPIDLAbsolute[$i])
            If @error Then
                $err = 3
                ExitLoop
            Else
                DLLStructSetData($aPIDL, $i+1, $PIDLChild)
            EndIf
        EndIf
    Next

    If $err = 0 Then
        $pDataObject = _WinAPI_CIDLData_CreateFromIDArray($PIDL, $iCount, $aPIDL)
        If @error Then
            $err = 4
        Else
            $Ret = DllCall('shell32.dll', 'uint', 'SHMultiFileProperties', 'ptr', DllStructGetData($pDataObject, 1), 'dword', 0)
            If @error Then $err = 1
        EndIf
    EndIf

    _WinAPI_CoTaskMemFree($PIDL)
    For $i = 0 To $iCount - 1
        $PIDL = DllStructGetData($aNames, $i+1)
        If $PIDL Then _WinAPI_CoTaskMemFree(DllStructGetData($aNames, $i+1))
        If $aPIDLAbsolute[$i] Then _WinAPI_CoTaskMemFree($aPIDLAbsolute[$i])
    Next

    If $err <> 0 Then Return SetError($err, 0, 0)
    Return 1
EndFunc   ;==>_WinAPI_SHMultiFileProperties

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_ILFindChild
; Description....: Determines whether a specified ITEMIDLIST structure is the child of another ITEMIDLIST structure and returns a pointer to the child's simple ITEMIDLIST.
; Syntax.........: _WinAPI_ILFindChild ($PIDLParent, $PIDLChild)
; Parameters.....: $PIDLParent - A pointer to the parent ITEMIDLIST structure.
;                  $PIDLChild - A pointer to the child ITEMIDLIST structure.
; Return values..: Success - ITEMIDLIST relative to the ITEMIDLIST or the parent.
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: line333
; Modified.......:
; Remarks .......: To free the returned PIDL, call the _WinAPI_CoTaskMemFree() function.
; Related .......:
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================

Func _WinAPI_ILFindChild($PIDLParent, $PIDLChild)
    Local $err = 0
    $Ret = DllCall('shell32.dll', 'ptr', 'ILFindChild', 'ptr', $PIDLParent, 'ptr', $PIDLChild)
    If @error Or $Ret[0] = 0 Then Return SetError(1, 0, 0)
    Return $Ret[0]
EndFunc   ;==>_WinAPI_ILFindChild

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_CIDLData_CreateFromIDArray
; Description....: Creates a data object with the default vtable pointer.
; Syntax.........: _WinAPI_CIDLData_CreateFromIDArray ($PIDL, $iItems, $aPIDL)
; Parameters.....: $PIDL - A fully qualified IDLIST for the root of the items specified in apidl.
;                  $iItems - Number of items in $aPIDL
;                  $aPIDL - The array of item IDs relative to $PIDL.
; Return values..: Success - IDataObject Interface.
;                  Failure - 0 and sets the @error flag to non-zero.
; Author.........: line333
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........: @@MsdnLink@@ IDataObject
; Example .......: Yes
; ===============================================================================================================================

Func _WinAPI_CIDLData_CreateFromIDArray($PIDL, $iItems, $aPIDL)
    Local $err = 0, $pDataObject = DllStructCreate('ptr')
    DllCall('shell32.dll', 'uint', 'CIDLData_CreateFromIDArray', 'ptr', $PIDL, 'uint', $iItems, 'ptr', DllStructGetPtr($aPIDL), 'ptr', DllStructGetPtr($pDataObject))
    If @error Then Return SetError(1, 0, 0)
    Return $pDataObject
EndFunc   ;==>_WinAPI_CIDLData_CreateFromIDArray

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_ShellILCreateFromPath
; Description....: Creates a pointer to an item identifier list (PIDL) from a path.
; Syntax.........: _WinAPI_ShellILCreateFromPath ( $sPath )
; Parameters.....: $sPath  - The path to be converted.
; Return values..: Success - The path in $sPath expressed as a PIDL.
;                  Failure - 0 and sets the @error flag to non-zero, @extended flag may contain the system error code.
; Author.........: Yashied
; Modified.......:
; Remarks........: To free the returned PIDL, call the _WinAPI_CoTaskMemFree() function.
; Related........:
; Link...........: @@MsdnLink@@ SHILCreateFromPath
; Example........: Yes
; ===============================================================================================================================

Func _WinAPI_ShellILCreateFromPath($sPath)
    Local $Ret = DllCall('shell32.dll', 'uint', 'SHILCreateFromPath', 'wstr', $sPath, 'ptr*', 0, 'dword*', 0)

    If @error Then
        Return SetError(1, 0, 0)
    Else
        If $Ret[0] Then
            Return SetError(1, $Ret[0], 0)
        EndIf
    EndIf
    Return $Ret[2]
EndFunc   ;==>_WinAPI_ShellILCreateFromPath

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_CoTaskMemFree
; Description....: Frees a block of task memory.
; Syntax.........: _WinAPI_CoTaskMemFree ( $hMemory )
; Parameters.....: $hMemory - The pointer to the memory block to be freed.
; Return values..: Success  - 1.
;                  Failure  - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: None
; Related........:
; Link...........: @@MsdnLink@@ CoTaskMemFree
; Example........: Yes
; ===============================================================================================================================

Func _WinAPI_CoTaskMemFree($hMemory)
    DllCall('ole32.dll', 'int', 'CoTaskMemFree', 'ptr', $hMemory)
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    Return 1
EndFunc   ;==>_WinAPI_CoTaskMemFree
Edited by line333

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Miss-post. Delete if possible.

Edited by line333

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0