Select Folder/File (_WinAPI_BrowseForFolderDlg()) mit Filter Option: PIDL (IDLIST) auslesen

  • Hey Leute,
    ich bin auf die Funktion _WinAPI_BrowseForFolderDlg() gestoßen, welche deutlich mehr Optionen hat als FileSelectFolder() oder FileOpenDialog(), denn man kann ein flag setzen, um auch Files auszuwählen. Leider fehlt ein Parameter, der es erlaubt die files zu filtern.

    Die Definition der Funktion sieht so aus:

    [autoit]

    Func _WinAPI_BrowseForFolderDlg($sRoot = '', $sText = '', $iFlags = 0, $pBrowseProc = 0, $lParam = 0, $hParent = 0)
    Local Const $tagBROWSEINFO = 'hwnd hwndOwner;ptr pidlRoot;ptr pszDisplayName; ptr lpszTitle;uint ulFlags;ptr lpfn;lparam lParam;int iImage'
    Local $tBROWSEINFO = DllStructCreate($tagBROWSEINFO & ';wchar[' & (StringLen($sText) + 1) & '];wchar[260]')
    Local $PIDL = 0, $Result = ''

    [/autoit][autoit][/autoit][autoit]

    If StringStripWS($sRoot, 3) Then
    Local $Path = _WinAPI_PathSearchAndQualify($sRoot, 1)
    If @error Then
    $Path = $sRoot
    EndIf
    $PIDL = _WinAPI_ShellILCreateFromPath($Path)
    If @error Then
    ; Nothing
    EndIf
    EndIf

    [/autoit][autoit][/autoit][autoit]

    DllStructSetData($tBROWSEINFO, 1, $hParent)
    DllStructSetData($tBROWSEINFO, 2, $PIDL)
    DllStructSetData($tBROWSEINFO, 3, DllStructGetPtr($tBROWSEINFO, 10))
    DllStructSetData($tBROWSEINFO, 4, DllStructGetPtr($tBROWSEINFO, 9))
    DllStructSetData($tBROWSEINFO, 5, $iFlags)
    DllStructSetData($tBROWSEINFO, 6, $pBrowseProc)
    DllStructSetData($tBROWSEINFO, 7, $lParam)
    DllStructSetData($tBROWSEINFO, 8, 0)
    DllStructSetData($tBROWSEINFO, 9, $sText)

    [/autoit][autoit][/autoit][autoit]

    Local $Ret = DllCall('shell32.dll', 'ptr', 'SHBrowseForFolderW', 'struct*', $tBROWSEINFO)
    If @error Or Not $Ret[0] Then Return SetError(@error, @extended, '')
    ; If Not $Ret[0] Then Return SetError(1000, 0, '')

    [/autoit][autoit][/autoit][autoit]

    $Result = _WinAPI_ShellGetPathFromIDList($Ret[0])
    _WinAPI_CoTaskMemFree($Ret[0])
    If $PIDL Then
    _WinAPI_CoTaskMemFree($PIDL)
    EndIf
    If Not $Result Then Return SetError(10, 0, '')

    [/autoit][autoit][/autoit][autoit]

    Return $Result
    EndFunc ;==>_WinAPI_BrowseForFolderDlg

    [/autoit]

    Dahinter steckt die Shell Funktion "SHBrowseForFolder" der man ein "BROWSEINFO" struct mitgibt.

    So weit alles verständlich. In der Beschreibung von "SHBrowseForFolder" ist erklärt, wie man den Inhalt im TreeView filtert und an dieser Stelle weiß ich nicht mehr weiter:

    Punkte 1-3 sind erledigt, sieht dann so aus:

    [autoit]

    #include <WinAPIDlg_test.au3>
    #include <APIDlgConstants.au3>
    #include <WinAPISys.au3>
    #include <MsgBoxConstants.au3>

    [/autoit][autoit][/autoit][autoit]

    Global Const $InitDir = @ProgramFilesDir

    [/autoit][autoit][/autoit][autoit]

    Local $hBrowseProc = DllCallbackRegister('_BrowseProc', 'int', 'hwnd;uint;lparam;ptr')
    Local $pBrowseProc = DllCallbackGetPtr($hBrowseProc)

    [/autoit][autoit][/autoit][autoit]

    Local $pText = _WinAPI_CreateString($InitDir)
    Local $Path = _WinAPI_BrowseForFolderDlg(_WinAPI_PathStripToRoot($InitDir), 'Select a folder from the list below.', BitOR($BIF_EDITBOX, $BIF_BROWSEINCLUDEFILES, $BIF_NEWDIALOGSTYLE), $pBrowseProc, $pText)
    _WinAPI_FreeMemory($pText)

    [/autoit][autoit][/autoit][autoit]

    If $Path Then
    ConsoleWrite('--------------------------------------------------' & @CRLF)
    ConsoleWrite($Path & @CRLF)
    EndIf

    [/autoit][autoit][/autoit][autoit]

    DllCallbackFree($hBrowseProc)

    [/autoit][autoit][/autoit][autoit]

    Func _BrowseProc($hWnd, $iMsg, $wParam, $lParam)
    Local $Path
    Switch $iMsg
    Case $BFFM_INITIALIZED
    _WinAPI_SetWindowText($hWnd, 'MyTitle')
    _SendMessage($hWnd, $BFFM_SETSELECTIONW, 1, $lParam)
    Case $BFFM_SELCHANGED
    $Path = _WinAPI_ShellGetPathFromIDList($wParam)
    If Not @error Then
    ConsoleWrite($Path & @CRLF)
    EndIf
    Case $BFFM_VALIDATEFAILED
    MsgBox(BitOR($MB_ICONERROR, $MB_SYSTEMMODAL), 'Error', _WinAPI_GetString($wParam) & ' is invalid.', 0, $hWnd)
    Return 1
    Case $BFFM_IUNKNOWN
    ConsoleWrite($lParam & @CRLF)
    EndSwitch
    Return 0
    EndFunc ;==>_BrowseProc

    [/autoit]


    Ich weiß, dass ich mit ObjCreateInterface ( "CLSID" , "IID" [, "interface_description",[flag = True]] )
    das IUnknown interface erstellen kann, aber nicht wie. Dann versteh ich nicht was ich bei QueryInterface als Parameter übergeben muss

    Zitat

    HRESULT QueryInterface(
    [in] REFIID riid,
    [out] void **ppvObject
    );

    Wo finde ich die 'riid'?

    Habt ihr da eine Idee wie ich das definieren muss?
    Danke Leute!