Mise à jour du code pour l'exemple du dossier 'Send to'
Fonctionne sous seven 7 pro x86-x64, PB 5.10, Vista x86 et XP x86 avec tous les pack
Sous Seven, les 2 drives lecteur DVD et le disque amovible (clée USB 32 Go n'apparaissent pas

)
Code : Tout sélectionner
;// Auteur : Denis
;// Version de PB : 3.91
;// Date : 02 juin 2004
;// Testé sous WIN98 SE x86
;// Modifié le 10 août 2008
;// Version de PB : 4.20
;// Testé sous VISTA home edition + SP1 x86
;// Modifié le 22 février 2012
;// Version de PB : 5.10
;// Testé sous Seven pro + SP1 x86/x64
;
;// Explication du programme :
;// Utilisation des interfaces IShellFolder et IEnumIDList pour afficher le contenu
;// du dossier 'Send to' pour cet exemple
Define .i
;// constantes possibles utilisables par la méthode EnumObjects de l'interface IShellFolder
#SHCONTF_FOLDERS = $0020
#SHCONTF_NONFOLDERS = $0040
#SHCONTF_INCLUDEHIDDEN = $0080
#SHCONTF_INIT_ON_FIRST_NEXT = $0100
#SHCONTF_NETPRINTERSRCH = $0200
#SHCONTF_SHAREABLE = $0400
#SHCONTF_STORAGE = $0800
;// constantes possibles utilisables par la méthode GetDisplayNameOf de l'interface IShellFolder
#SHGDN_NORMAL = $0000
#SHGDN_INFOLDER = $0001
;// #SHGDN_FOREDITING = 2
;// #SHGDN_FORADDRESSBAR = 3
;// #SHGDN_FORPARSING = 4
;// constantes possibles pour le paramètre uType de la structure STRRET
#STRRET_WSTR = 0
#STRRET_OFFSET = 1
#STRRET_CSTR = 2
;// quelques constantes possibles pour l'API SHGetSpecialFolderLocation
#CSIDL_DESKTOP = 0
#CSIDL_PRINTERS = 4
#CSIDL_RECENT = 8
#CSIDL_SENDTO = 9
#CSIDL_STARTMENU = 11
;// #CSIDL_FONTS = $14
#CSIDL_INTERNET_CACHE = $0020
#CSIDL_INTERNET = $0001
;// constantes possibles pour l'API CoInitializeEx
#COINIT_MULTITHREADED = 0
#COINIT_APARTMENTTHREADED = 2
#COINIT_DISABLE_OLE1DDE = 4
#COINIT_SPEED_OVER_MEMORY = 8
;- Constantes utilisateur
Enumeration
#MainWindow ;// fenêtre principale
#ListIconGadget = 1
#shlwapi_dll = 0 ;// identifiant dll
EndEnumeration
Macro msg(valeur)
MessageRequester("Erreur", valeur,16)
EndMacro
;- Structure
Structure STRRET
uType.l
StructureUnion
*pOleStr
uOffset.l
cStr.u[#MAX_PATH]
EndStructureUnion
EndStructure
;// typedef struct _STRRET {
;// UINT uType;
;// union {
;// LPWSTR pOleStr;
;// UINT uOffset;
;// CHAR cStr[MAX_PATH];
;// };
;// } STRRET, *LPSTRRET;
;- Variables globales
CompilerIf #PB_Compiler_Unicode
StrRetToBuf$ = "StrRetToBufW"
CompilerElse
StrRetToBuf$ = "StrRetToBufA"
CompilerEndIf
Prototype StrRetToBuf(*_strDispName, _pidlItems, *_pszDisplayName, MemorySize_of_pszDisplayName)
Global *StrRetToBuf.StrRetToBuf ;// pointeur sur l'interface Shell IMalloc
;// /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
;// \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;- Debut prog
If OpenWindow(#MainWindow, 0, 0, 600, 400, "Explorer les dossiers avec IShellFolder", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
IdListIcon = ListIconGadget(#ListIconGadget, 10, 10, 580, 380, "Contenu du Dossier SEND TO", 575, #LVS_SHAREIMAGELISTS)
HideGadget(#ListIconGadget, 1)
CoInitializeEx_(0, #COINIT_SPEED_OVER_MEMORY) ;// Initialise la librairie COM pour le thread courant
shlwapiDll = OpenLibrary(#shlwapi_dll, "shlwapi.dll")
If shlwapiDll = #Null
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'ouvrir la dll shlwapi.dll")
End
EndIf
*StrRetToBuf = GetFunction(#shlwapi_dll, StrRetToBuf$)
If *StrRetToBuf = #Null
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'obtenir l'adresse e la fonction 'StrRetToBuf' à partir de la dll shlwapi.dll")
End
EndIf
*pszDisplayName = AllocateMemory((#MAX_PATH * SizeOf(character)) + 2)
If *pszDisplayName = #Null
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'allouer de la mémoire")
End
EndIf
;// l'API SHGetSpecialFolderLocation retourne #S_OK en cas de succès sinon une erreur
;// Cette API est remplacée par l'API SHGetFolderLocation depuis Windows 2000, mais
;// fonctionne avec les nouveaux OS
;// L'API retourne dans ppidl un pointeur sur un élément identifiant une liste specifiant
;// la localisation du dossier relatif à la racine du 'name space' (le bureau)
If SHGetSpecialFolderLocation_(0, #CSIDL_SENDTO, @ppidl) <> #NOERROR
FreeMemory(*pszDisplayName)
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'obtenir le pointeur sur l'objet 'ppidl'")
End
EndIf
;// SHGetDesktopFolder retourne dans ppshf le pointeur sur l'interface IShellFolder
;// pour le dossier 'Send To'
If SHGetDesktopFolder_(@ppshf.IShellFolder) <> #NOERROR
FreeMemory(*pszDisplayName)
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'obtenir le pointeur sur l'objet 'IShellFolder' de l'API SHGetDesktopFolder_()")
End
EndIf
;// la méthode BindToObject de l'interface IShellFolder retrouve un object IShellFolder
;// pour un sous-dossier
If ppshf\BindToObject(ppidl, 0, ?IID_IShellFolder, @ppvOut.IShellFolder) <> #NOERROR
ppshf\Release() ;// on libère l'interface IShellFolder retournée par SHGetDesktopFolder
FreeMemory(*pszDisplayName)
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'obtenir le pointeur sur l'objet 'IShellFolder' de la méthode BindToObject")
End
EndIf
ppshf\Release() ;// on libère l'interface IShellFolder retournée par
;// SHGetDesktopFolder, on n'en a plus besoin
;// La méthode BindToObject de l'interface IShellFolder a retourné dans ppvOut
;// un pointeur sur une interface IShellFolder pour un sous-dossier
;// on peut donc commencer l'énumération avec la méthode EnumObjects (interface IShellFolder)
;// EnumObjects permet de déterminer le contenu d'un dossier en créant un élément
;// identifiant un object 'énumeration' et retournant son interface IEnumIDList.
;// Les méthodes supportée par cette interface peuvent être utilisées pour énumérer
;// le contenu d'un dossier.
If ppvOut\EnumObjects(0, #SHCONTF_FOLDERS | #SHCONTF_NONFOLDERS, @ppenum.IEnumIDList) <> #S_OK
FreeMemory(*pszDisplayName)
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
msg("Impossible d'obtenir le contenu du dossier")
End
EndIf
;// La méthode Next de l'interface IEnumIDList permet de commencer l'énumération
;// La méthode Next énumère dans notre cas les éléments un par un (1er paramètre quui indique
;// aussi que pidlItems est un tableau à un élément. Pour retrouver plus d'éléments à la fois,
;// il faut dimensionner le tableau avec SHGetMalloc
;// celtFetched retourne une valeur qui indique combien d'éléments sont retournés par
;// la fonction et dans notre cas au max 1 sinon 0 si plus d'éléments
hr = ppenum\Next(1, @pidlItems, @celtFetched)
;// on teste dans la boucle qu'il n'y a pas d'erreur et qu'il y a bien un élément
While ((hr = #NOERROR) And (celtFetched = 1))
;// la méthopde GetDisplayNameOf de l'interface IShellFolder retrouve
;// le nom d'affichage pour le dossier)fichier object spécifié.
;// le 3ème paramètre est une variable basée sur la structure STRRET
strDispName.STRRET\uType = #STRRET_OFFSET
If ppvOut\GetDisplayNameOf(pidlItems, #SHGDN_INFOLDER, @strDispName.STRRET) = #NOERROR
;// La chaine retournée par GetDisplayNameOf doit être formatée avant d'être
;// affichée correctement avec l'API StrRetToBufA ou StrRetToBufW de la dll shlwapi.dll
;// *pszDisplayName est le buffer qui recevra la chaine à afficher
*StrRetToBuf(@strDispName, pidlItems, *pszDisplayName, MemorySize(*pszDisplayName))
;// on affiche dans la Listicon
AddGadgetItem(#ListIconGadget, 0, PeekS(*pszDisplayName))
;
hr = ppenum\Next(1, @pidlItems, @celtFetched)
EndIf
Wend
CloseLibrary(#shlwapi_dll) ;// ferme shlwapi.dll
EndIf
If *pszDisplayName
FreeMemory(*pszDisplayName)
EndIf
HideGadget(#ListIconGadget, 0)
CoTaskMemFree_(ppidl) ;// libère la mémoire pointée par ppidl
;// on affiche le nombre d'éléments dans la barre de la listeicongadget
SetGadgetItemText(#ListIconGadget, -1, GetGadgetItemText(#ListIconGadget, -1, 0)+" - "+Str(CountGadgetItems(#ListIconGadget))+ " objets trouvés")
;- boucle evenements
While WaitWindowEvent() <> #PB_Event_CloseWindow And EventWindow() <> WindowID(#MainWindow)
Wend
CoUninitialize_() ;// ferme la librairie COM pour le thread courant
End
DataSection
;// Interface IShellFolder;
;// helpstring("IShellFolder"),
;// uuid(000214E6-0000-0000-C000-000000000046)
IID_IShellFolder : ;// clée IShellFolder mise sous la forme de DATA
Data.l $000214E6
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection