Récupérer l'image d'un fichier

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
pat
Messages : 412
Inscription : mar. 24/nov./2009 15:13

Récupérer l'image d'un fichier

Message par pat »

Bonjour à tous,

Dans l'Explorateur Windows, quand vous cliquez sur un fichier, parfois vous obtenez son image.
C'est le cas par exemple quand on clique sur un fichier avec l'extension ".pb".
Je souhaiterais récupérer cet image et je pense que les API sont indispensables et, bien sûr, je ne sais pas comment faire.
Je m'en remets donc à ceux qui savent et qui sont souvent très doués avec les API.
Si c'est possible, je souhaiterais (j'en demande peut-être beaucoup) que le code soit le plus concis possible, donc que le code soit le plus simple et le plus dans le vif du sujet.
Un grand merci à ceux qui voudront m'aider.
gnozal
Messages : 832
Inscription : mar. 07/déc./2004 17:35
Localisation : France
Contact :

Re: Récupérer l'image d'un fichier

Message par gnozal »

Code : Tout sélectionner

;
; Retrieve the icon associated to a file
;
Procedure GetAssociatedFileIcon(IconPath.s, IconSize) ;  Retrieves the icon associated to a file
  Protected FileInfo.SHFILEINFO
  ; http://msdn.microsoft.com/en-us/library/bb762179%28VS.85%29.aspx
  ; #SHGFI_SMALLICON     -> small (usually 16x16) icon
  ; #SHGFI_LARGEICON     -> large (usually 32x32) icon
  ; #SHGFI_SHELLICONSIZE -> shell default icon size
  SHGetFileInfo_(IconPath, 0, @FileInfo, SizeOf(SHFILEINFO), #SHGFI_ICON | IconSize) 
  ProcedureReturn FileInfo\hIcon 
EndProcedure
;
If OpenWindow(0, 0, 0, 200, 150, "Associated File Icon", #PB_Window_SystemMenu|#PB_Window_ScreenCentered) 
  ButtonGadget(0, 5, 5, 190, 25, "Choose file") 
  ImageGadget(1, 92, 45, 16, 16, #Null)
  ImageGadget(2, 84, 70, 32, 32, #Null)
  ImageGadget(3, 84, 110, 32, 32, #Null)
  Repeat 
    Event = WaitWindowEvent() 
    If Event = #PB_Event_Gadget 
      Select EventGadget()
        Case 0
          IconPath.s = OpenFileRequester("", "", "*.*", 0) 
          If IconPath
            SetGadgetState(1, GetAssociatedFileIcon(IconPath, #SHGFI_SMALLICON))
            SetGadgetState(2, GetAssociatedFileIcon(IconPath, #SHGFI_LARGEICON)) 
            SetGadgetState(3, GetAssociatedFileIcon(IconPath, #SHGFI_SHELLICONSIZE)) 
          EndIf 
      EndSelect 
    EndIf 
  Until Event = #PB_Event_CloseWindow 
EndIf
pat
Messages : 412
Inscription : mar. 24/nov./2009 15:13

Re: Récupérer l'image d'un fichier

Message par pat »

Merci gnozal.
Il ne me reste plus qu'à saisir ton programme sur PB car je ne possède pas Internet chez moi et je ne peux qu'imprimer ton code.
Ton code est concis, semble clair et va à l'essentiel, comme je le souhaite.
Je pense qu'il doit fonctionner correctement.
Un grand merci à toi et beaucoup aussi apprécieront ton code.
Avatar de l’utilisateur
Ar-S
Messages : 9546
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Récupérer l'image d'un fichier

Message par Ar-S »

Je fais partie de ceux qui apprécient aussi ^^
Merci Gnozal :)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Récupérer l'image d'un fichier

Message par Le Soldat Inconnu »

Tu peux regarder ma librairie GetIcon sur mon site aussi (les sources sont incluses)
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)]
pat
Messages : 412
Inscription : mar. 24/nov./2009 15:13

Re: Récupérer l'image d'un fichier

Message par pat »

Bonjour à tous,

J'ai rentré tout le code de Gnozal dans PB et je peux dire que tout fonctionne correctement.
Maintenant je me pose une autre question :

Le code de Gnozal permet de récupérer l'icône d'un fichier dans l'Explorateur Windows mais uniquement en affichage liste ou détails.
L'affichage de Windows permet d'obtenir des images de fichiers beaucoup plus grands comme les icônes de taille moyenne ou grandes tailles, par exemple.
Alors tout naturellement, est-il possible de récupérer ces icônes de tailles plus grandes avec au choix des tailles (icônes moyennes, grandes icônes, très grandes icônes).
Merci à ceux qui savent pour leur réponse.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Récupérer l'image d'un fichier

Message par Le Soldat Inconnu »

Récupère ma libraire sur mon site, tu trouveras tous ce que tu cherches dedans. Le code est inclus dans le ZIP avec la librairie
Elle permet d'extraire les icônes 16, 32, 48 et 128 d'une DLL ou d'un fichier comme l'explorateur.
C'est ici :
http://www.lsi-dev.com/index.php?mod=articles&ref=43
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)]
pat
Messages : 412
Inscription : mar. 24/nov./2009 15:13

Re: Récupérer l'image d'un fichier

Message par pat »

Merci LSI.
Je suis entré dans ton site et il semble vraiment très bien fait et très agréable.
Hélas pour moi, je suis dans un lieu public et Internet est bridé et donc je ne peux pas télécharger quoi que ce soit.
Pourrais-tu m'aider en postant le code à la suite de ma réponse. Cela me serait d'une grande aide.
Je sais que tu es quelqu'un de très fort dans le domaine de la programmation alors que moi je souffre pour avoir des infos sur les API vu mon incompétence en Anglais. Je ne me considère pas pour autant pour un nul mais j'ai des progrès à faire.
En tout cas je serais très satisfait si j'avais ton aide, que j'estime précieuse.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Récupérer l'image d'un fichier

Message par Le Soldat Inconnu »

regarde ici :
http://www.purebasic.fr/french/viewtopi ... it=GetIcon


Sinon, le code de la librairie :

Code : Tout sélectionner

#SHIL_SMALL = $1
#SHIL_LARGE = $0
#SHIL_EXTRALARGE = $2
#SHIL_JUMBO = $4

#LOAD_LIBRARY_AS_DATAFILE = 2

DataSection
  IID_IImageList:
  Data.l $46EB5926
  Data.w $582E,$4017
  Data.b $9F,$DF,$E8,$99,$8D,$AA,$09,$50
EndDataSection 
Structure IMAGELISTDRAWPARAMS
  cbSize.l
  himl.l
  i.l
  hdcDst.l
  x.l
  y.l
  cx.l
  cy.l
  xBitmap.l
  yBitmap.l
  rgbBk.l
  rgbFg.l
  fStyle.l
  dwRop.l
  fState.l
  frame.l
  crEffect.l
EndStructure
Interface IImageList2 Extends iUnknown
  Add(hbmImage, hbmMask, pi)
  ReplaceIcon(i, hIcon, pi)
  SetOverlayImage(iImage, iOverlay)
  Replace(i, hbmImage, hbmMask)
  AddMasked(hbmImage, crMask, pi)
  Draw(pimldp.IMAGELISTDRAWPARAMS)
  Remove(i)
  GetIcon(i, flags, picon)
  GetImageInfo(i, pImageInfo.IMAGEINFO)
  Copy(iDst, punkSrc.IImageList, iSrc, uFlags)
  Merge(i1, punk2.IImageList, i2, dx, dy, riid, ppv)
  Clone(riid, ppv)
  GetImageRect(i, prc.RECT)
  GetIconSize(cx, cy)
  SetIconSize(cx, cy)
  GetImageCount(pi)
  SetImageCount(uNewCount)
  SetBkColor(clrBk, pclr)
  GetBkColor(pclr)
  BeginDrag(iTrack, dxHotspot, dyHotspot)
  EndDrag()
  DragEnter(hwndLock, x, y)
  DragLeave(hwndLock)
  DragMove(x, y)
  SetDragCursorImage(punk.IImageList, iDrag, dxHotspot, dyHotspot)
  DragShowNolock(fShow)
  GetDragImage(ppt.POINT, pptHotspot.POINT, riid, ppv)
  GetItemFlags(i, dwFlags)
  GetOverlayImage(iOverlay, piIndex)
EndInterface

Global OS
ProcedureDLL GetIcon_Init()
  OS = OSVersion()
EndProcedure
ProcedureDLL.l GetIconFile(IconFile.s, Size.l) ; Get icon 16*16, 32*32 or 48*48
  Protected hIcon.l, FileInfo.SHFILEINFO, dll_Shell32.l, hResult.l, *Guid.l
  Select Size
    Case #SHIL_SMALL, 16
      SHIL = #SHIL_SMALL
    Case #SHIL_LARGE, 32
      SHIL = #SHIL_LARGE
    Case #SHIL_EXTRALARGE, 48
      SHIL = #SHIL_EXTRALARGE
    Case #SHIL_JUMBO, 128, 256
      If OS >= #PB_OS_Windows_Vista
        SHIL = #SHIL_JUMBO
      Else
        SHIL = #SHIL_EXTRALARGE
      EndIf
    Default
      SHIL = #SHIL_SMALL
  EndSelect
  If OS >= #PB_OS_Windows_XP ; Pour Windows XP et plus, toute taille d'icône
    dll_Shell32 = OpenLibrary(#PB_Any, "Shell32.dll")
    If dll_Shell32
      *Guid = ?IID_IImageList
      SHGetFileInfo_(IconFile, 0, @FileInfo, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX)
      hResult = CallFunction(dll_Shell32, "SHGetImageList", SHIL, *Guid, @ImageList.IImageList2)
      If hResult = 0
        ImageList\GetIcon(FileInfo\iIcon, #ILD_TRANSPARENT, @hIcon)
        ImageList\Release()
      EndIf
      CloseLibrary(dll_Shell32)
    EndIf
  Else ; Avant windows XP, icône 16*16 ou 32*32
    If SHIL = #SHIL_EXTRALARGE Or SHIL = #SHIL_LARGE
      SHGetFileInfo_(IconFile, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_LARGEICON)
      hIcon = InfosFile\hIcon
    Else
      SHGetFileInfo_(IconFile, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_SMALLICON)
      hIcon = InfosFile\hIcon
    EndIf
  EndIf
  ProcedureReturn hIcon
EndProcedure
ProcedureDLL.l GetSmallIconFile(IconFile.s) ; Get icon 16*16
  ; Cette procedure permet d'extraire l'ID de l'icône 16*16 associée au type de fichier ou au dossier dont l'adresse est IconFile
  ProcedureReturn GetIconFile(IconFile.s, 16)
EndProcedure
ProcedureDLL.l GetLargeIconFile(IconFile.s) ; Get icon 32*32
  ; Cette procedure permet d'extraire l'ID de l'icône 32*32 associée au type de fichier ou au dossier dont l'adresse est IconFile
  ProcedureReturn GetIconFile(IconFile.s, 32)
EndProcedure
ProcedureDLL.l GetExtraLargeIconFile(IconFile.s) ; Get icon 48*48
  ; Cette procedure permet d'extraire l'ID de l'icône 48*48 associée au type de fichier ou au dossier dont l'adresse est IconFile
  ProcedureReturn GetIconFile(IconFile.s, 48)
EndProcedure
ProcedureDLL.l GetJumboIconFile(IconFile.s) ; Get icon 128*128 or 256*256
  ; Cette procedure permet d'extraire l'ID de l'icône 128*128 ou 256*256 associée au type de fichier ou au dossier dont l'adresse est IconFile
  ProcedureReturn GetIconFile(IconFile.s, 128)
EndProcedure

Procedure GetIconIndexList_Enumerate(hLibrary, lpszType, lpszName, *Memory.Long)
  Protected Result.l, Name.s
  *Memory\l = ReAllocateMemory(*Memory\l, MemorySize(*Memory\l) + 4)
  If *Memory\l
    If lpszName >> 16
      Name = PeekS(lpszName) 
      lpszName = AllocateMemory(StringByteLength(Name + "0"))
      Debug Name
      PokeS(lpszName, Name)
    EndIf
    Debug lpszName
    PokeL(*Memory\l + MemorySize(*Memory\l) - 8, lpszName)
    Result = #True
  Else
    Result = #False
  EndIf 
  ProcedureReturn Result
EndProcedure
ProcedureDLL.l GetIconIndexList(IconFile.s) ; Get icon index list
  Protected hLibrary, Memory.l
  hLibrary = LoadLibraryEx_(IconFile, #NULL, #LOAD_LIBRARY_AS_DATAFILE)
  If hLibrary <> #NULL
    *Memory = AllocateMemory(4)
    If *Memory
      EnumResourceNames_(hLibrary, #RT_GROUP_ICON, @GetIconIndexList_Enumerate(), @*Memory)
    EndIf
    FreeLibrary_(hLibrary)
  EndIf
  ProcedureReturn *Memory
EndProcedure
ProcedureDLL FreeIconIndexList(Memory.l) ; Free icon index list
  Protected Index.l, Value.l
  Index = 0
  Repeat
    Value = PeekL(Memory + Index * 4) ; Numéro de l'icône
    If Value > 0
      If Value >> 16
        FreeMemory(Value)
      EndIf
      Index + 1
    EndIf
  Until Value = 0
  FreeMemory(Memory)
EndProcedure
ProcedureDLL ExtractIconFile(IconFile.s, IconIndex.l, Size.l) ; Extract icon from library or exe
  Protected hLibrary, hIcon.l
  If IconIndex > 0
    hLibrary = LoadLibraryEx_(IconFile, #Null, #LOAD_LIBRARY_AS_DATAFILE)
    If hLibrary <> #Null
      If IconIndex >> 16
        hIcon = LoadImage_(hLibrary, PeekS(IconIndex), #IMAGE_ICON, Size, Size, 0)
      Else
        hIcon = LoadImage_(hLibrary, IconIndex & $FFFF, #IMAGE_ICON, Size, Size, 0)
      EndIf
      FreeLibrary_(hLibrary)
    EndIf
  Else
    hIcon = GetIconFile(IconFile, Size)
  EndIf
  ProcedureReturn hIcon
EndProcedure
ProcedureDLL ExtractSmallIconFile(IconFile.s, IconIndex.l) ; Extract icon 16*16 from library or exe
  ProcedureReturn ExtractIconFile(IconFile.s, IconIndex.l, 16)
EndProcedure
ProcedureDLL ExtractLargeIconFile(IconFile.s, IconIndex.l) ; Extract icon 32*32 from library or exe
  ProcedureReturn ExtractIconFile(IconFile.s, IconIndex.l, 32)
EndProcedure
ProcedureDLL ExtractExtraLargeIconFile(IconFile.s, IconIndex.l) ; Extract icon 48*48 from library or exe
  ProcedureReturn ExtractIconFile(IconFile.s, IconIndex.l, 48)
EndProcedure

ProcedureDLL.l GetSpecialFolderIcon(CSIDL.l, Size.l) ; Get special folder icon
	Protected hIcon.l, FileInfo.SHFILEINFO, dll_Shell32.l, hResult.l, *Guid.l, IconFile.l
  Select Size
		Case #SHIL_SMALL, 16
      SHIL = #SHIL_SMALL
		Case #SHIL_LARGE, 32
      SHIL = #SHIL_LARGE
		Case #SHIL_EXTRALARGE, 48
      SHIL = #SHIL_EXTRALARGE
		Case #SHIL_JUMBO, 128, 256
      If OS >= #PB_OS_Windows_Vista
        SHIL = #SHIL_JUMBO
			Else
        SHIL = #SHIL_EXTRALARGE
			EndIf
		Default
      SHIL = #SHIL_SMALL
	EndSelect
	If SHGetSpecialFolderLocation_(0, CSIDL, @IconFile) = 0
		If OS >= #PB_OS_Windows_XP ; Pour Windows XP et plus, toute taille d'icône
			dll_Shell32 = OpenLibrary(#PB_Any, "Shell32.dll")
			If dll_Shell32
				*Guid = ?IID_IImageList
				SHGetFileInfo_(IconFile, 0, @FileInfo, SizeOf(SHFILEINFO), #SHGFI_SYSICONINDEX | #SHGFI_PIDL)
				hResult = CallFunction(dll_Shell32, "SHGetImageList", SHIL, *Guid, @ImageList.IImageList2)
				If hResult = 0
					ImageList\GetIcon(FileInfo\iIcon, #ILD_TRANSPARENT, @hIcon)
					ImageList\Release()
				EndIf
				CloseLibrary(dll_Shell32)
			EndIf
		Else ; Avant windows XP, icône 16*16 ou 32*32
			If SHIL = #SHIL_EXTRALARGE Or SHIL = #SHIL_LARGE
				SHGetFileInfo_(IconFile, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_PIDL | #SHGFI_LARGEICON)
				hIcon = InfosFile\hIcon
			Else
				SHGetFileInfo_(IconFile, 0, @InfosFile.SHFILEINFO, SizeOf(SHFILEINFO), #SHGFI_ICON | #SHGFI_PIDL | #SHGFI_SMALLICON)
				hIcon = InfosFile\hIcon
			EndIf
		EndIf
	EndIf
  ProcedureReturn hIcon
EndProcedure
ProcedureDLL.l GetSpecialFolderSmallIcon(CSIDL.l) ; Get special folder icon 16*16
  ProcedureReturn GetSpecialFolderIcon(CSIDL.l, 16)
EndProcedure
ProcedureDLL.l GetSpecialFolderLargeIcon(CSIDL.l) ; Get special folder icon 32*32
  ProcedureReturn GetSpecialFolderIcon(CSIDL.l, 32)
EndProcedure
ProcedureDLL.l GetSpecialFolderExtraLargeIcon(CSIDL.l) ; Get special folder icon 48*48
  ProcedureReturn GetSpecialFolderIcon(CSIDL.l, 48)
EndProcedure
ProcedureDLL.l GetSpecialFolderJumboIcon(CSIDL.l) ; Get special folder icon 128*128 or 256*256
  ProcedureReturn GetSpecialFolderIcon(CSIDL.l, 128)
EndProcedure
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)]
pat
Messages : 412
Inscription : mar. 24/nov./2009 15:13

Re: Récupérer l'image d'un fichier

Message par pat »

Un supermerci pour ton aide LSI.
Il ne me reste plus qu'à rentrer ton code dans PB.
En tout cas cela semble fabuleux.
Je pense que beaucoup apprécieront ton code et, peut-être, auront envie d'aller voir ton site qui est, selon ce que j'ai vu, pas mal du tout.
Quand je pourrais télécharger la version 4.60 de PB j'irais faire un tour dans ton site car certains programmes semblent intéressants.
Répondre