Page 1 sur 1
IExtractIcon - Interfaces, aie
Publié : dim. 30/janv./2005 0:50
par Le Soldat Inconnu
Salut,
je pense avoir trouvé la fonction pour résoudre mon problème avec SHGetFileInfo
voir ici :
http://purebasic.hmt-forum.com/viewtopi ... 1830#21830
mais c'est des interfaces et j'ai un peu beaucoup de mal
http://msdn.microsoft.com/library/defau ... cation.asp
2 solution s'offre à moi :
- Récupérer l'adresse du fichier qui contient l'icône associé à un type de fichier avec SHGetFileInfo mais je n'y arrive pas sauf pour des dossiers et fichiers systèmes
Code : Tout sélectionner
File.s = "c:\test.txt"
Debug File
CreateFile(0, File)
CloseFile(0)
SHGetFileInfo_(@File, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICONLOCATION)
Debug InfosFile\hIcon
Debug InfosFile\iIcon
If @InfosFile\szDisplayName
Debug Str(@InfosFile\szDisplayName) + " : " + PeekS(@InfosFile\szDisplayName, 260)
Else
Debug @InfosFile\szDisplayName
EndIf
If @InfosFile\szTypeName
Debug Str(@InfosFile\szTypeName) + " : " + PeekS(@InfosFile\szTypeName, 80)
Else
Debug @InfosFile\szTypeName
EndIf
DeleteFile(File)
Debug ""
File.s = "c:\"
Debug File
SHGetFileInfo_(@File, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICONLOCATION)
Debug InfosFile\hIcon
Debug InfosFile\iIcon
If @InfosFile\szDisplayName
Debug Str(@InfosFile\szDisplayName) + " : " + PeekS(@InfosFile\szDisplayName, 260)
Else
Debug @InfosFile\szDisplayName
EndIf
If @InfosFile\szTypeName
Debug Str(@InfosFile\szTypeName) + " : " + PeekS(@InfosFile\szTypeName, 80)
Else
Debug @InfosFile\szTypeName
EndIf
DeleteFile(File)
ou alors passez par les interfaces cités ci dessus mais la, j'y comprend rien pour l'instant
un petit coup de main ne serait pas de refus, merci

Publié : mer. 02/févr./2005 12:21
par Le Soldat Inconnu
J'ai fais quelques essais à partir d'un code de DENIS mais il ne reconnais l'interface dont j'ai besoin.
Voir au milieu du code, entre les ===========
Un petit coup de patte, merci
Code : Tout sélectionner
; Auteur : Denis
; Version de PB : 3.91
; Date : 02 juin 2004
; Testé sous WIN98 SE
;
; Explication du programme :
; Utilisation des interfaces IShellFolder et IEnumIDList pour afficher le contenu
; du dossier 'SEND TO' (envoyer vers) pour cet exemple
;- Constantes utilisateur
#Fenetre = 0
; 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 = $1000
#SHGDN_FORADDRESSBAR = $4000
#SHGDN_FORPARSING = $8000
; 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
; constantes possibles pour l'API CoInitializeEx
#COINIT_MULTITHREADED = 0
#COINIT_APARTMENTTHREADED = 2
#COINIT_DISABLE_OLE1DDE = 4
#COINIT_SPEED_OVER_MEMORY = 8
;- Structure
Structure STRRET
uType.l
StructureUnion
pOleStr.l
uOffset.l
cStr.b[#MAX_PATH]
EndStructureUnion
EndStructure
;- Variables globales
Global ppMalloc.l ; pointeur sur l'interface Shell IMalloc
; ; /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
; ; \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
;- Debut prog
If OpenWindow(0, 0, 0, 600, 400, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Explorer les dossiers avec IShellFolder")
If CreateGadgetList(WindowID())
IdListIcon = ListIconGadget(0, 10, 10, 580, 380, "Contenu du Dossier SEND TO", 575, #LVS_SHAREIMAGELISTS)
; AddGadgetColumn(0, 1, "Taille", 575 / 5)
; AddGadgetColumn(0, 2, "Type", 575 / 5 * 2)
CoInitializeEx_(0, #COINIT_SPEED_OVER_MEMORY) ; Initialise la librairie COM pour le thread courant
shlwapiDll = OpenLibrary(100, "shlwapi.dll")
SHGetMalloc_( @pMalloc)
pszDisplayName = AllocateMemory((#MAX_PATH * 2) + 2)
; 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.l) = #NOERROR And shlwapiDll
; SHGetDesktopFolder retourne dans ppshf le pointeur sur l'interface IShellFolder
; pour le dossier 'Bureau'
If SHGetDesktopFolder_(@ppshf.IShellFolder) = #NOERROR
; 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, 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.
;============================================================
;- C'est ici que je cherche à lire une icône
If ppvOut\GetUIObjectOf(WindowID(), 1, ppidl, ?IID_IExtractIcon, 0, @ppvIcon.IExtractIcon) = #S_OK
szBuf.s = Space(#MAX_PATH)
ppvIcon\GetIconLocation(0, @szBuf.s, #MAX_PATH, @piIndex.l, pwFlags.l)
EndIf
;============================================================
If ppvOut\EnumObjects(0, #SHCONTF_FOLDERS | #SHCONTF_NONFOLDERS, @ppenum.IEnumIDList) = #S_OK
; 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 de la dll shlwapi.dll
; pszDisplayName est le buffer qui recevra la chaine à afficher
CallFunction(100, "StrRetToBufA", @strDispName, pidlItems, pszDisplayName, #MAX_PATH)
; on affiche dans la Listicon
AddGadgetItem(0, 0, PeekS(pszDisplayName))
;
hr = ppenum\Next(1, @pidlItems, @celtFetched)
EndIf
Wend
FreeLibrary_(shlwapiDll) ; ferme shlwapi.dll
EndIf
EndIf
EndIf
EndIf
EndIf
CoTaskMemFree_(ppidl) ; libère la mémoire pointée par ppidl
;- boucle evenements
While WaitWindowEvent() <> #PB_EventCloseWindow
Wend
EndIf
CoUninitialize_() ; ferme la librairie COM pour le thread courant
End
DataSection
; Interface IShellFolder;
; helpstring("IShellFolder"),
; uuid(000214E6-0000-0000-C000-000000000046)
IID_IShellFolder : ; cléf du registre mise sous la forme de DATA
Data.l $000214E6
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
IID_IExtractIcon :
Data.l $000214EB
Data.w $0000, $0000
Data.b $C0, $00, $00, $00, $00, $00, $00, $46
EndDataSection
Publié : mer. 02/févr./2005 12:45
par nico
J'ai regardé vaguement, faut pas d'abord faire une recherche sur l'objet (le fichier dont on veut récupérer l'icone) et seulement ensuite faire appel à queryinterface sur IID_IExtractIcon pour travaillé sur cette interface et l'objet en question?
Publié : mer. 02/févr./2005 13:54
par Le Soldat Inconnu
ben je ne sais pas, j'y comprends rien, alors j'essaie de faire par analogie
Publié : mer. 02/févr./2005 14:15
par Anonyme2
J'ai pas trop regardé mais le peu que j'en ai vu c'est comme le dit Nico, on récupère le pointeur sur l'ojet fichier voulu et ensuite on on extrait (comme ça ça semble simple mais ça doit être surement plus lourd à faire, rien n'est simpe avec les interfaces).
Publié : mer. 02/févr./2005 16:54
par Le Soldat Inconnu
rien n'est simpe avec les interfaces
oui, c'est certain.
J'ai finis par trouvé une solution avec la fonction SHGetFileInfo pour mon problème d'icône.
mais j'ai vu que les interfaces sont plus rapides, si c'est vrai, ça me serait fort utile.
on récupère le pointeur sur l'ojet fichier voulu et ensuite on on extrait
Ok, je vais essayer comme ça.
mais pourquoi le compilo ne reconnait pas les fonctions de l'interface ?
la :
@ppvIcon.IExtractIcon
et la :
GetIconLocation(
Publié : mer. 02/févr./2005 17:32
par nico
Cette interface n'est pas déclarer, a toi de le faire.
Publié : mer. 02/févr./2005 18:45
par Le Soldat Inconnu
OK OK, ça s'éclaircie

Publié : mer. 02/févr./2005 19:22
par Anonyme2
L'interface IExtractIcon est déclarée de 2 manières
IExtractIconA
et
IExtractIconW
Publié : mer. 02/févr./2005 19:25
par Le Soldat Inconnu
Tu as vu ça ou ? j'ai pas vu ça sur msdn ?
Publié : mer. 02/févr./2005 19:36
par hardy
J'ai l'impression que maintenant elles sont à peu près toutes déclarées en PB.
J'en utilise en ce moment, et c'est vrai que c'est carrément chiant.
Le plus simple, c'est quand même d'utiliser des scripts.
Y'a pas une lib pour utiliser des scripts vbs en PB?
Publié : mer. 02/févr./2005 19:40
par Anonyme2
Y a un outil dans PureBasic qui permet de voir les Interfaces, c'est tout.
Mis à part ça, dans la doc SDK de MS, fait une recherche sur IExtractIcon
Une fois la page apparue, tout en bas il y a un truc qui ressemble à ça
Interface Information
Minimum DLL Version shell32.dll version 4.0 or later
Custom Implementation Yes
Inherits from IUnknown
Header shlobj.h
Minimum operating systems Windows NT 4.0, Windows 95
La plupart du temps, on trouve toutes les infos dans le fichier ou les fichiers indiqués, ici
shlobj.h
Mais pas la valeur que tu as trouvé sur Internet. Peut-être dans le fichier ou les fichiers qui sont déclarés en include files.
Dans ce fichier h, on a ceci
#undef INTERFACE
#define INTERFACE IExtractIconA
DECLARE_INTERFACE_(IExtractIconA, IUnknown) // exic
{
// *** IUnknown methods ***
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
// *** IExtractIcon methods ***
STDMETHOD(GetIconLocation)(THIS_
UINT uFlags,
LPSTR szIconFile,
UINT cchMax,
int * piIndex,
UINT * pwFlags) PURE;
STDMETHOD(Extract)(THIS_
LPCSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize) PURE;
};
typedef IExtractIconA * LPEXTRACTICONA;
#undef INTERFACE
#define INTERFACE IExtractIconW
DECLARE_INTERFACE_(IExtractIconW, IUnknown) // exic
{
// *** IUnknown methods ***
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
// *** IExtractIcon methods ***
STDMETHOD(GetIconLocation)(THIS_
UINT uFlags,
LPWSTR szIconFile,
UINT cchMax,
int * piIndex,
UINT * pwFlags) PURE;
STDMETHOD(Extract)(THIS_
LPCWSTR pszFile,
UINT nIconIndex,
HICON *phiconLarge,
HICON *phiconSmall,
UINT nIconSize) PURE;
};
typedef IExtractIconW * LPEXTRACTICONW;
#ifdef UNICODE
#define IExtractIcon IExtractIconW
#define IExtractIconVtbl IExtractIconWVtbl
#define LPEXTRACTICON LPEXTRACTICONW
#else
#define IExtractIcon IExtractIconA
#define IExtractIconVtbl IExtractIconAVtbl
#define LPEXTRACTICON LPEXTRACTICONA
#endif
Je pense que Fred a utilisé son outil pour inclure cette interface
(il y a 1983 interfaces définies en standart par PB)
Publié : mer. 02/févr./2005 20:01
par Le Soldat Inconnu
Merci chef

Publié : dim. 06/févr./2005 12:27
par Anonyme2
J'ai fait quelques essais avec l'interface IExtractIcon, je réussi à extraire les 2 icônes, mais pas du fichier voulu. Je tourne un peu en rond.
Je n'extrait pour l'instant que l'icône (index 0) de l'explorer.exe
Je finirais par trouver (l'espoir fait vivre).
Ce qui me fait penser que j'ai peut-être oublié de libérer correctement la mémoire avec l'exemple que j'avais posté sur IShellFolder et IEnumIDList.
Faut que je vérifie.
Publié : dim. 06/févr./2005 23:55
par Le Soldat Inconnu
C'est encourageant

on va triompher de ces satanés interfaces