Using the KnownFolderManager Object
oleexp (VB6, twinBASIC) and WinDevLib (twinBASIC) include the IKnownFolderManager and IKnownFolder interfaces.
If plan on doing any work with the Known Folders that replaced CSIDL Special Locations and you're working exclusively with Vista and higher, there's now the IKnownFolderManager interface, for which Windows provides a default instance of, which makes your job much easier.
Now you have a ready-to-use manager that gives you the following:Code:Dim pKFM as KnownFolderManager Set pKFM = New KnownFolderManager
.FindFolderFromPath /IDList - Have the path of a special folder and want to get its IKnownFolder interface to find out information about it? You can specify a full or partial path. If you work with PIDLs, e.g. the result from a folder browser that you could use here directly without converting back and forth to a string path, there's a function to get a known folder directly from that as well.
.FolderIdFromCsidl - Still working with CSIDLs? This will ease the transition into support Known Folders.
.GetFolder / .GetFolderByName - You can use either the GUID or canonical name to return a Known Folder object.
Once you have a Known Folder, in the form of a IKnownFolder object, you can get tons of information about it:Code:Dim pikf As IKnownFolder pKFM.FindFolderFromPath StrPtr("C:\Users\Jon\Downloads"), FFFP_EXACTMATCH, pikf
From the main IKnownFolder object, you can get all its file system information, like its PROPERTYKEY, path, pidl, or even an IShellItem interface for it (you can also change the path with SetPath), then there's a significant subset of information in the description:
This is by far the easiest way to work with these special folders on newer versions of Windows.Code:pikf.GetFolderDefinition desc pikf.GetId pid PrintGUID pid Debug.Print "Icon=" & BStrFromLPWStr(desc.pszIcon, False) Debug.Print "Name=" & BStrFromLPWStr(desc.pszName, False) Debug.Print "Description=" & BStrFromLPWStr(desc.pszDescription, False) Debug.Print "LocalizedName=" & BStrFromLPWStr(desc.pszLocalizedName, False) Debug.Print "ToolTip=" & BStrFromLPWStr(desc.pszToolTip, False) Debug.Print "Category=" & desc.category 'peruser, common, etc Debug.Print "Attributes=" & desc.dwAttributes FreeKnownFolderDefinitionFields desc
Most of the oleexp projects use this, but again:
Code:Public Declare Function SysReAllocString Lib "oleaut32.dll" (ByVal pBSTR As LongPtr, Optional ByVal pszStrPtr As LongPtr) As Long Public Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As LongPtr) ' Frees memory allocated by the shell Public Function BStrFromLPWStr(lpWStr As LongPtr, Optional ByVal CleanupLPWStr As Boolean = True) As String SysReAllocStringW VarPtr(BStrFromLPWStr), lpWStr If CleanupLPWStr Then CoTaskMemFree lpWStr End Function Public Sub FreeKnownFolderDefinitionFields(pKFD As KNOWNFOLDER_DEFINITION) Call CoTaskMemFree(pKFD.pszName) Call CoTaskMemFree(pKFD.pszDescription) Call CoTaskMemFree(pKFD.pszRelativePath) Call CoTaskMemFree(pKFD.pszParsingName) Call CoTaskMemFree(pKFD.pszToolTip) Call CoTaskMemFree(pKFD.pszLocalizedName) Call CoTaskMemFree(pKFD.pszIcon) Call CoTaskMemFree(pKFD.pszSecurity) End Sub 'also handy, Public Declare Function StringFromGUID2 Lib "ole32.dll" (ByRef rguid As Any, ByVal lpsz As String, ByVal cchMax As Long) As Long Public Sub PrintGUID(TempGUID As UUID) Dim GuidStr As String Dim lLen As Long GuidStr = Space(80) lLen = StringFromGUID2(TempGUID, GuidStr, 80) If (lLen) Then GuidStr = StrConv(Left$(GuidStr, (lLen - 1) * 2), vbFromUnicode) Debug.Print GuidStr End If End Sub




Reply With Quote