IExtractIcon - Interfaces, aie

Programmation d'applications complexes
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

IExtractIcon - Interfaces, aie

Message 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 :wink:
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message 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
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message 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?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

ben je ne sais pas, j'y comprends rien, alors j'essaie de faire par analogie
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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).
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message 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(
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Cette interface n'est pas déclarer, a toi de le faire.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

OK OK, ça s'éclaircie :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

L'interface IExtractIcon est déclarée de 2 manières

IExtractIconA

et

IExtractIconW
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Tu as vu ça ou ? j'ai pas vu ça sur msdn ?
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message 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?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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)
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Merci chef :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message 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 :roll:
Je finirais par trouver (l'espoir fait vivre). :D

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.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

C'est encourageant :D on va triompher de ces satanés interfaces
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Répondre