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 = ''
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
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)
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, '')
$Result = _WinAPI_ShellGetPathFromIDList($Ret[0])
_WinAPI_CoTaskMemFree($Ret[0])
If $PIDL Then
_WinAPI_CoTaskMemFree($PIDL)
EndIf
If Not $Result Then Return SetError(10, 0, '')
Return $Result
EndFunc ;==>_WinAPI_BrowseForFolderDlg
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:
ZitatAlles anzeigenCustom Filtering
As of Windows XP, SHBrowseForFolder supports custom filtering on the contents of the dialog box. To create a custom filter, follow these steps.
1. Set the BIF_NEWDIALOGSTYLE flag in the ulFlags member of the BROWSEINFO structure pointed to by the lpbi parameter.
2. Specify a callback function in the lpfn member of that same BROWSEINFO structure.
3. Code the callback function to receive the BFFM_INITIALIZED and BFFM_IUNKNOWN messages. On receipt of the BFFM_IUNKNOWN message, the callback function's lParam parameter contains a pointer to the dialog box's implementation of IUnknown. Call QueryInterface on that IUnknown to obtain a pointer to an instance of IFolderFilterSite.
4. Create an object that implements IFolderFilter.
5. Call IFolderFilterSite::SetFilter, passing to it a pointer to your IFolderFilter. IFolderFilter methods can then be used to include and exclude items from the tree.
6. Once the filter is created, the IFolderFilterSite interface is no longer needed. Call IFolderFilterSite::Release if you have no further use for it.
Punkte 1-3 sind erledigt, sieht dann so aus:
[autoit]#include <WinAPIDlg_test.au3>
#include <APIDlgConstants.au3>
#include <WinAPISys.au3>
#include <MsgBoxConstants.au3>
Global Const $InitDir = @ProgramFilesDir
[/autoit][autoit][/autoit][autoit]Local $hBrowseProc = DllCallbackRegister('_BrowseProc', 'int', 'hwnd;uint;lparam;ptr')
Local $pBrowseProc = DllCallbackGetPtr($hBrowseProc)
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)
If $Path Then
ConsoleWrite('--------------------------------------------------' & @CRLF)
ConsoleWrite($Path & @CRLF)
EndIf
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
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
ZitatHRESULT QueryInterface(
[in] REFIID riid,
[out] void **ppvObject
);
Wo finde ich die 'riid'?
Habt ihr da eine Idee wie ich das definieren muss?
Danke Leute!