Choisir son icône depuis un fichier ico

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Choisir son icône depuis un fichier ico

Message par Anonyme2 »

J'avais besoin de pouvoir extraire une icône depuis un fichier .ico qui contient plusieurs icônes, j'ai cherché et j'ai écrit quelques procédures que voici et un fichier d'exemple.
Il y a 8 procédures, 4 pour travailler depuis un fichier sur le disque et les 4 mêmes mais pour travailler depuis les fichiers en datas ou en mémoire.
Je n'ai testé que sous Vista, les icônes Vista ne sont pas supportés ni les icônes supérieurs à 255 de côté.
Les fonctions sont les suivantes :

Code : Tout sélectionner

IconNumberFromFile(File$)
IconNumberFromMemory(AdresseMemoire.l)
EnumereIconFormatFromFile(File$, buffer.l)
EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
LoadIconEx(File$, size.l, Format.l)
LoadIconFromFile(File$, IconPos.l)
CatchIconEx(Memory_Add_1, size.l, Format.l)
CatchIcon(Memory_Add_1.l, IconPos.l)

Code : Tout sélectionner

IconNumberFromFile(File$)
retourne le nombre d'icônes du fichier icône
File$ est le chemin complet du fichier .ico

Code : Tout sélectionner

IconNumberFromMemory(AdresseMemoire.l)
retourne le nombre d'icônes du fichier icône situé en data ou que vous avez chargé en mémoire
AdresseMemoire.l est l'adresse ou est située le fichier en data ou en mémoire
Ces deux fonctions retournent une valeur négative en cas d'échec

Code : Tout sélectionner

EnumereIconFormatFromFile(File$, buffer.l)
va énumérer pour l'ensemble des icônes du fichier, certains renseignements que l'ou peut exploiter ensuite.
File$ est le chemin complet du fichier .ico
buffer est une zone mémoire allouée avec la fonction AllocateMemory() et typiquement on la dimensionne avant l'appel de la fonction puis on la libère ensuite comme ceci

Code : Tout sélectionner

*IconInfo.IconFormat, mem.l
*IconInfo = AllocateMemory(SizeOf(IconFormat) * Nb_Icones)
 If *IconInfo
    mem = *IconInfo
    ; on énumère les infos de chaque icône
    EnumereIconFormatFromMemory(MemoryIcon, *IconInfo)
    
    ; ici la zone mémoire contient les données de chaque icône
    ;  on fait ce que l'on a à faire avec les données
    ;  ...
    ;
    ; on libère la mémoire    
    FreeMemory(mem)
 EndIf
La mémoire allouée est le produit du nombre d'icônes retrouvé par la taille de la structure IconFormat
Cette Structure mémorise pour chaque icône :
- La largeur de l'icône courant (élément width.w)
- La hauteur de l'icône courant (élément height.w)
- Le Format de l'icône courant qui est une valeur ou une combinaison des valeurs de l'énumération IconFormat (élément ColorFormat.w)
- La position de l'icône dans le fichier avec le 1er icône à la position 1 (élément position.w)

Pour le format, seule la valeur #Format_Custom peut être combinée avec une des autres valeurs.

Code : Tout sélectionner

EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
va énumérer pour l'ensemble des icônes du fichier, certains renseignements que l'ou peut exploiter ensuite.
Memory_Add.l est l'adresse ou est située le fichier en data ou en mémoire

C'est exactement le même fonctionnement que la fonction ci-dessus EnumereIconFormatFromFile(File$, buffer.l)

Code : Tout sélectionner

LoadIconEx(File$, size.l, Format.l)
permet de créer une image PureBasic
File$ est le chemin complet du fichier .ico
size est la taille de l'icône recherchée
Format est une combinaison d'un ou de plusieurs éléments de l'énumération IconFormat, seule la valeur #Format_Custom peut être combinée avec une des autres valeurs.

Cette fonction ne fonctionne qu'avec des icônes carrés

Par exemple, on veut créer une image avec l'icône au format XP (c'est-à-dire qui supporte la transparence partielle, la couche alpha) d'une taille de 32
Si ce format existe, l'image sera crée depuis le fichier icône mais sans créer de fichier sur le disque, c'est transparent pour l'utilisateur.
La fonction retourne l'identifiant statique de la fontion PB catchImage utilisée en interne et non pas le handle de l'image.

Les commandes PureBasic des images sont utilisables, ne pas oublier FreeImage() pour détruire l'image
Pour cet exemple, voici comment utiliser la fonction

Code : Tout sélectionner

Fichier.s = "C:\MonIco.ico"
Img.l = 0

Img = LoadIconEx(Fichier, 32, #Format_XP_Colors)

If img 
   ; ici c'est OK
   ; on peut utiliser ImageID(img)
Else
   ; ici l'icône 32x32 au format XP n'existe pas dans le fichier ico
EndIf

Code : Tout sélectionner

LoadIconFromFile(File$, IconPos.l)
permet de créer une image PureBasic
File$ est le chemin complet du fichier .ico
IconPos est la position de l'icône recherchée dans le fichier

Le fonctionnement est identique à la fonction LoadIconEx(File$, size.l, Format.l)

Code : Tout sélectionner

CatchIconEx(Memory_Add_1, size.l, Format.l)
Memory_Add.l est l'adresse ou est située le fichier en data ou en mémoire
size est la taille de l'icône recherchée
Format est une combinaison d'un ou de plusieurs éléments de l'énumération IconFormat, seule la valeur #Format_Custom peut être combinée avec une des autres valeurs.

Pour le reste, Le fonctionnement est identique à la fonction LoadIconEx(File$, size.l, Format.l)

Code : Tout sélectionner

CatchIcon(Memory_Add_1.l, IconPos.l)
Memory_Add.l est l'adresse ou est située le fichier en data ou en mémoire
IconPos est la position de l'icône recherchée dans le fichier

Pour le reste, Le fonctionnement est identique à la fonction CatchIconEx(Memory_Add_1, size.l, Format.l)


************************************************************************
Il faut absolument tester le résultat des fonctions car les fonctions
utilisent des zones mémoire et des fichiers, il y a risque de plantage
************************************************************************



Voici le code des procédures :

Code : Tout sélectionner

; code PB de Franky ici  -->  http://www.purebasic.fr/english/viewtopic.php?t=13306
;
; Bonnes explications du format ici  -->  http://www.whisqu.se/per/docs/graphics52.htm
;
;
; http://www.developpez.net/forums/archive/index.php/t-370305.html
; http://www.developpez.net/forums/showthread.php?t=370305
; http://www.winmatrix.com/forums/index.php?showtopic=5461
; http://en.wikipedia.org/wiki/ICO_(icon_image_file_format)
; http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap
; http://www.codeguru.com/csharp/.net/net_general/graphics/article.php/c12787/

EnableExplicit

;- Enumeration IconFormat
Enumeration
     #Format_XP_Colors = 1 ; couleurs avec couche alpha
     #Format_True_Colors = 2 ; 16,8 millions de couleurs
     #Format_256_Colors = 4 ; 256 couleurs indexées
     #Format_16_Colors = 8 ; 16 couleurs
     #Format_Monochrome = 16 ; noir et blanc
     #Format_Custom = 32 ; format personnalisé, peut être combiné avec une des autres valeur
     #Format_UnKnow = 64 ; ne devrait pas arriver, format inconnu
EndEnumeration

;- Structures
Structure IconDirectoryEntry
     bWidth.b ; largeur de l'icône en pixels
     bHeight.b ; hauteur de l'icône en pixels
     bColorCount.b ; nombre de couleurs de l'icône (2, 8 ou 16 ?)
     bReserved.b ; réservé, doit être à 0
     wPlanes.w ;
     wBitCount.w ; nombre de bits utilisé pour définir les couleurs de l'icône
     dwBytesInRes.l ; Taille en octets de l'icône
     dwImageOffset.l ; offset de l'icône en octets à partir du début du fichier jusqu'à l'image de l'icône
EndStructure

Structure IconDir
     idReserved.w
     idType.w
     idCount.w
     idEntries.IconDirectoryEntry[1]
EndStructure

Structure IconFormat
     width.w ; largeur de l'icône
     height.w ; hauteur de l'icône
     ColorFormat.w ; un des formats de l'énumération IconFormat
     position.w ; position de l'icône dans le fichier
EndStructure

;- declarations
Declare.l IconNumberFromFile(File$)
Declare.l IconNumberFromMemory(AdresseMemoire.l)
Declare.l EnumereIconFormatFromFile(File$, buffer.l)
Declare.l EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
Declare.l LoadIconEx(File$, size.l, Format.l)
Declare.l LoadIconFromFile(File$, IconPos.l)
Declare.l CatchIconEx(Memory_Add_1, size.l, Format.l)
Declare.l CatchIcon(Memory_Add_1.l, IconPos.l)

;- Procedures
Procedure.l IconNumberFromFile(File$)
     ; retourne le nombre d'icônes contenu dans le fichier ico passé en paramètre
     ; retourne une valeur négative en cas d'erreur
     
     ; File$ est le nom complet du fichier au format ico
     
     Protected IconNumber.l  ; mémorise le nombre d'icône
     Protected FileId.l      ; mémorise l'identifiant du fichier utilisé
     
     FileId = ReadFile(#PB_Any, File$)
     If FileId = 0
          ProcedureReturn - 1
     EndIf
     
     ; positionne le pointeur du fichier sur le bon élément
     FileSeek(FileId, Loc(FileId) + OffsetOf(IconDir\idCount))
     ; lecture du nombre d'icônes
     IconNumber = ReadWord(FileId)
     ; fermeture du fichier
     CloseFile(FileId)
     ; retourne la valeur
     ProcedureReturn IconNumber
     
EndProcedure

Procedure.l IconNumberFromMemory(AdresseMemoire.l)
     ; La procedure retourne le nombre d'icônes contenu dans le fichier Ico en mémoire ou en datas
     ; retourne une valeur négative en cas d'erreur
     
     ; AdresseMemoire est l'adresse mémoire ou est situé le fichier au format ico

     Protected Img.l         ; mémorise l'identifiant de l'image interne utilisée
     Protected ObjectType.l  ; mémorise le résultat d'une API Windows
     Protected ico.ICONINFO  ; variable stockant les infos de l'icône à tester
     
     ; on défini avec les fonction PB si l'image est une icône
     Img = CatchImage(#PB_Any, AdresseMemoire)
     If Img = 0
          ProcedureReturn - 1
     EndIf
     
     ObjectType = GetIconInfo_(ImageID(Img), @ico)
     If ObjectType = 0
          FreeImage(Img)
          ProcedureReturn - 2
     EndIf
     
     FreeImage(Img)
     DeleteObject_(ico\hbmMask)
     DeleteObject_(ico\hbmColor)
     
     If ico\fIcon = #False ; curseur et pas icône
          ProcedureReturn - 3
     EndIf
     
     ; ici c'est bien un fichier icône, on retourne le nombre d'icônes
     ProcedureReturn PeekW(AdresseMemoire + OffsetOf(IconDir\idCount))
EndProcedure

Procedure.l EnumereIconFormatFromFile(File$, buffer_1.l)
     ; retourne en mémoire les types de chaque icône du fichier au format ico
     ; retourne une valeur négative en cas d'erreur
     
     ; File$ est le nom complet du fichier au format ico
     ; buffer_1 est l'adresse mémoire de la zone qui recevra les infos sur chaque icône.
     ; chaque icône aura ses informations sosu la forme de valeur basées sur la structure IconFormat
     ; buffer_1 sera dimensionné par le produit du nombre d'icône et de la taille de la stucture IconFormat
     ; buffer_1 doit être alloué et détruit par le programmeur
     ; voir la fonction EnumereIconFormatFromMemory(Memory_Add.l, buffer.l) pour un exemple de dimensionnement du buffer
     
     Protected FileId.l
     ; on retrouve le nombre d'icônes du fichier en mémoire
     Protected FileSize.l
     ; on retrouve le nombre d'icônes du fichier en mémoire
     Protected IconNumber.l = IconNumberFromFile(File$)
     ; mémoire allouée pour stocker le fichier
     Protected Memory.l
     ; teste la quantité de données lue dans le fichier et le résultat de la fonction
     Protected Result.l
     
     
     If IconNumber <= 0
          ProcedureReturn - 2
     EndIf
     
     FileSize = FileSize(File$)
     If Filesize < SizeOf(IconDir) ; il y a au moins 1 icône
          ProcedureReturn - 3
     EndIf
     
     FileId = ReadFile(#PB_Any, File$)
     If FileId = 0
          ProcedureReturn - 4
     EndIf
     
     Memory = AllocateMemory(Filesize)
     If Memory = 0
          CloseFile(FileId)
          ProcedureReturn - 5
     EndIf
     
     Result = ReadData(FileId, Memory, FileSize)
     If Result <> FileSize
          CloseFile(FileId)
          FreeMemory(Memory)
          ProcedureReturn - 6
     EndIf
     
     ; ici la copie est Ok, on appelle la fonction EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
     
     Result = EnumereIconFormatFromMemory(Memory, buffer_1)
     
     CloseFile(FileId)
     FreeMemory(Memory)
     
     ProcedureReturn Result
     
EndProcedure

Procedure.l EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
     ; Enumère les formats d'icône du fichier
     ; buffer doit avoir été dimensionné de manière suffisante avant l'appel de la fonction
     ; par le codeur et doit être détruit par le codeur lorsque ce buffer devient inutile
     ;
     ; buffer doit être dimentionné de cette manière
     ; d'abord, il faut retrouver le nombre d'icônes contenu dans le fichier ou en data
     ; Ensuite il faut allouer de la mémoire avec la taille de la structure IconFormat
     ; multiplié par le nombre d'icônes
     
     ; Voici un exemple d'utilisation avec le fichier en datas (tester le résultat des fonctions !)
     ; IconNumber = IconNumberFromMemory(?Ico)
     ; if IconNumber > 0
     ;    memory = AllocateMemory(SizeOf(IconFormat) * IconNumber)
     ;    if memory
     ;       result = EnumereIconFormatFromMemory(?Ico, memory)
     ;       ici on peut utiliser les résultats contenus dans memory
     ;       FreeMemory(memory)
     ;    else
     ;       debug "erreur"
     ;    endif
     ; endif
     ;
     
     
     ; on retrouve le nombre d'icônes du fichier en mémoire
     Protected IconNumber.l = IconNumberFromMemory(Memory_Add)
     ; compteur de boucle
     Protected i.l
     ; pointeur sur le fichier en mémoire à partir de la 1ere entrée dans le fichier
     Protected * Pt_memory.IconDirectoryEntry = Memory_Add + OffsetOf(IconDir\idEntries)
     ; pointeur sur le buffer passé en paramètre
     Protected * Pt_buffer.IconFormat = buffer
     
     
     If IconNumber <= 0
          ProcedureReturn - 1
     EndIf
     
     For i = 1 To IconNumber
          ; lecture de la largeur
          *Pt_buffer\width = *Pt_memory\bWidth
          ; lecture de la hauteur
          *Pt_buffer\height = *Pt_memory\bHeight
          ; écriture de la position de l'icône dans le fichier
          *Pt_buffer\position = i
          
          ; écriture du format de l'icône
          If *Pt_buffer\width <> * Pt_buffer\height
               *Pt_buffer\ColorFormat = #Format_Custom
          EndIf
          
          Select *Pt_memory\wBitCount
               Case 1
                    *Pt_buffer\ColorFormat | #Format_Monochrome
                    
               Case 4
                    *Pt_buffer\ColorFormat | #Format_16_Colors
                    
               Case 8
                    *Pt_buffer\ColorFormat | #Format_256_Colors
                    
               Case 24
                    *Pt_buffer\ColorFormat | #Format_True_Colors
                    
               Case 32
                    *Pt_buffer\ColorFormat | #Format_XP_Colors
                    
               Default
                    *Pt_buffer\ColorFormat | #Format_UnKnow
          EndSelect
          
          ; positionnement du pointeur *Pt_memory
          *Pt_memory + SizeOf(IconDirectoryEntry)
          
          ; positionnement du pointeur *Pt_buffer
          *Pt_buffer + SizeOf(IconFormat)
     Next
     ProcedureReturn #ERROR_SUCCESS
EndProcedure

Procedure.l LoadIconEx(File$, size.l, Format.l)
     ; Permet de charger l'icône définie par les 2 paramètres size et Format s'il existe
     ; retourne -1 en cas d'échec, sinon l'identifiant statique PureBasic de l'icône choisie
     ; Si la fonction réussie, les commandes PB s'appliquent à l'image retournée, en particulier FreeImage()
     ; L'image retournée n'existe pas sur le disque
     ; 
     ; Paramètres :
     ; ----------
     ;    File$  --> le nom complet du fichier au format .ico
     ;    size   --> La valeur en pixel de l'icône carré :
     ;               valeurs possible, toutes jusqu'à 128
     ;    Format --> Une des valeur de l'énumération IconFormat ci-dessus
     
     ; on énumère les éléments jusqu'à ce que l'on trouve l'icône
     ; si elle est rouvée, on utilise LoadIconFromFile(File$, IconPos.l)
     ; sinon on retourne une erreur
     
     Protected IconNumber.l = IconNumberFromFile(File$)
     ; compteur de boucle
     Protected i.l
     ; mémoire allouée pour énumérer le fichier
     Protected *Memory, *Memory1.IconFormat
     If IconNumber <= 0
          ProcedureReturn - 1
     EndIf
     
     *Memory = AllocateMemory(SizeOf(IconFormat) * IconNumber)
     If *Memory = 0
          ProcedureReturn - 2
     EndIf
     
     *Memory1 = *Memory
     
     If EnumereIconFormatFromFile(File$, *Memory) <> #ERROR_SUCCESS
        FreeMemory(*Memory)
        ProcedureReturn -3
     EndIf     


     For i = 1 To IconNumber
        If (*Memory1\width = size) And (*Memory1\height = size) And (*Memory1\ColorFormat = Format)
           FreeMemory(*Memory)
           ProcedureReturn LoadIconFromFile(File$, i)
        EndIf
;           ; on incémente le pointeur
           *Memory1 + SizeOf(IconFormat)
     Next
     
     FreeMemory(*Memory)
     ProcedureReturn -4
EndProcedure

Procedure.l LoadIconFromFile(File$, IconPos.l)
     ; Permet de charger l'icône en position 'Position' qui est contenue dans le fichier disque 'File$'
     ; retourne -1 en cas d'échec, sinon l'identifiant statique PureBasic de l'icône choisie
     ; Si la fonction réussie, les commandes PB s'appliquent à l'image retournée, en particulier FreeImage()
     ; L'image retournée n'existe pas sur le disque
     
     Protected FileId.l
     ; on retrouve le nombre d'icônes du fichier en mémoire
     Protected FileSize.l
     ; on retrouve le nombre d'icônes du fichier en mémoire
     Protected IconNumber.l = IconNumberFromFile(File$)
     ; mémoire allouée pour stocker le fichier
     Protected Memory.l
     ; teste la quantité de données lue dans le fichier et le résultat de la fonction
     Protected Result.l
     
     
     If IconNumber <= 0
          ProcedureReturn - 2
     EndIf
     
     FileSize = FileSize(File$)
     If Filesize < SizeOf(IconDir) ; il y a au moins 1 icône
          ProcedureReturn - 3
     EndIf
     
     FileId = ReadFile(#PB_Any, File$)
     If FileId = 0
          ProcedureReturn - 4
     EndIf
     
     Memory = AllocateMemory(Filesize)
     If Memory = 0
          CloseFile(FileId)
          ProcedureReturn - 5
     EndIf
     
     Result = ReadData(FileId, Memory, FileSize)
     If Result <> FileSize
          CloseFile(FileId)
          FreeMemory(Memory)
          ProcedureReturn - 6
     EndIf
     
     ; ici la copie est Ok, on appelle la fonction EnumereIconFormatFromMemory(Memory_Add.l, buffer.l)
     
     Result = CatchIcon(Memory, IconPos.l)
     
     CloseFile(FileId)
     FreeMemory(Memory)
     
     ProcedureReturn Result
     
EndProcedure

Procedure.l CatchIconEx(Memory_Add_1, size.l, Format.l)
     ; Permet de charger l'icône définie par les 2 paramètres size et Format s'il existe
     ; retourne -1 en cas d'échec, sinon l'identifiant statique PureBasic de l'icône choisie
     ; Si la fonction réussie, les commandes PB s'appliquent à l'image retournée, en particulier FreeImage()
     ; L'image retournée n'existe pas sur le disque
     ; 
     ; Paramètres :
     ; ----------
     ;    File$  --> le nom complet du fichier  .ico
     ;    size   --> La valeur en pixel de l'icône carré :
     ;               valeurs possible, toutes jusqu'à 128
     ;    Format --> Une des valeur de l'énumération IconFormat ci-dessus
     
     ; on énumère les éléments jusqu'à ce que l'on trouve l'icône
     ; si elle est rouvée, on utilise LoadIconFromFile(File$, IconPos.l)
     ; sinon on retourne une erreur
     
     Protected IconNumber.l = IconNumberFromMemory(Memory_Add_1)
     ; compteur de boucle
     Protected i.l
     ; mémoire allouée pour énumérer le fichier
     Protected *Memory, *Memory1.IconFormat
     If IconNumber <= 0
          ProcedureReturn - 1
     EndIf
     
     *Memory = AllocateMemory(SizeOf(IconFormat) * IconNumber)
     If *Memory = 0
          ProcedureReturn - 2
     EndIf
     
     *Memory1 = *Memory
     
     If EnumereIconFormatFromMemory(Memory_Add_1, *Memory) <> #ERROR_SUCCESS
        FreeMemory(*Memory)
        ProcedureReturn -3
     EndIf     


     For i = 1 To IconNumber
        If (*Memory1\width = size)  And (*Memory1\height = size) And (*Memory1\ColorFormat = Format)
           FreeMemory(*Memory)
           ProcedureReturn CatchIcon(Memory_Add_1, i)
        EndIf
;           ; on incémente le pointeur
           *Memory1 + SizeOf(IconFormat)
     Next
     
     FreeMemory(*Memory)
     ProcedureReturn -4
     
EndProcedure

Procedure.l CatchIcon(Memory_Add_1.l, IconPos.l)
     ; Permet de charger l'icône en position 'Position' qui est contenue dans le fichier icône en data ou mémoire
     ; retourne -1 en cas d'échec, sinon l'identifiant statique PureBasic de l'icône choisie
     ; Si la fonction réussie, les commandes PB s'appliquent à l'image retournée, en particulier FreeImage()
     
     
     Protected IconNumber.l = IconNumberFromMemory(Memory_Add_1)
     ; taille de l'icône coureante
     Protected IconSize.l
     ; position des données de l'icône dans le fichier
     Protected IconOffset.l
     ; mémoire allouée pour créer l'icône
     Protected *IconMemory.IconDir, Mem.l
     ; identifiant statique de l'image PB retournée
     Protected Img.l
     ; pointeur sur le fichier en mémoire à partir de la 1ere entrée dans le fichier
     Protected *Pt_memory.IconDirectoryEntry
     
     If (IconNumber <= 0) Or (IconPos <= 0) Or ((IconNumber > 0) And (IconPos > IconNumber))
          ProcedureReturn - 1
     EndIf
     
     IconPos - 1
     ; on se positionne sur la structure correspondante
     *Pt_memory.IconDirectoryEntry = Memory_Add_1 + (OffsetOf(IconDir\idEntries) + (SizeOf(IconDirectoryEntry) * IconPos))
     
     ; on récupère la taille et l'offset de l'icône dans le fichier
     IconSize   = *Pt_memory\dwBytesInRes
     IconOffset = *Pt_memory\dwImageOffset
     
     ; on alloue de la mémoire pour créer l'icône en mémoire
     Mem = AllocateMemory(SizeOf(IconDir) + IconSize)
     
     If Mem = 0
          ProcedureReturn - 2
     EndIf
     
     ; Mem va mémoriser l'adresse permettant de libérer la mémoire
     ; *IconMemory va permettre d'accéder aux données
     *IconMemory = Mem
     
     ; on copie les données en mémoire, d'abord les données définissant le type du fichier
     *IconMemory\idReserved = 0 ; toujours à 0
     *IconMemory\idType = 1 ; resource type, toujours à 1
     *IconMemory\idCount = 1 ; nombre d'icône dans le fichier --> 1 seul pour cette fonction
     
     ; ensuite les données propres définissant l'icône  (la structure IconDirectoryEntry)
     CopyMemory(*Pt_memory, *IconMemory\idEntries, SizeOf(IconDirectoryEntry))
     
     ; écriture en mémoire du nouvel offset des données de l'icône
     ; ces deonnées se trouve immédiatement après la structure  IconDir qui ne contient  
     ; qu'une seule structure IconDirectoryEntry
     *IconMemory\idEntries\dwImageOffset = SizeOf(IconDir)
     
     ; positionne le pointeur de destination sur la zone des datas à écrire
     *IconMemory + SizeOf(IconDir)
     ; écriture en mémoire des données de l'icône
      CopyMemory(Memory_Add_1 + IconOffset, *IconMemory, IconSize)
     
     Img = CatchImage(#PB_Any, Mem)
     FreeMemory(Mem)
     If img
        ProcedureReturn Img
     Else
        ProcedureReturn -3  ; erreur
     EndIf
     
EndProcedure
Et voici un fichier d'exemple, n'oubliez pas de créer le fichier correspondant à l'includefile de l'exemple
IncludeFile "Select_icones.pb"

L'exemple est trop long pour le forum, alors voila un lien
Dernière modification par Anonyme2 le mer. 26/déc./2007 19:21, modifié 1 fois.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Merci.. :)

super boulot comme d'hab :)

l'idéal serai que Purebasic puisse sauver en *.ico !!
nous pourrions aisément faire un extracteur d'icone alors ;)
Dernière modification par Backup le mer. 26/déc./2007 12:36, modifié 1 fois.
Avatar de l’utilisateur
venom
Messages : 3137
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Message par venom »

a oui c'est du long mais c'est très bon bravo Denis


@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci,

j'avais la flemme d'écrire un chm mais je voulais aussi mettre le code dispo.

Comme je l'ai dis, je n'ai pas fait de tests sous XP, W98 et tout le reste mais ça devrait tourner.

Pour le format Vista, je n'ai pas trouvé assez d'infos (absolument rien chez Microsoft si ce n'est les explication de la structure BITMAPINFOHEADER) et mes tests sur les fichiers ne me permettent pas encore d'écrire une fonction qui va bien.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Dobro a écrit :Merci.. :)

super boulot comme d'hab :)

l'idéal serai que Purebasic puisse sauver en *.ico !!
nous pourrions aisément faire un extracteur d'icone alors ;)
Il faut regarder de plus près le code, je fais une icone en mémoire pour pouvoir utiliser ensuite catchimage, donc pour sauvegarder une icône seule, c'est simple, il faut bricoler un peu le code.

Pour faire un ico multiple, c'est un peu plus compliqué. Je n'ai pas beaucoup de temps pour regarder (je bosse sur ma librairie des menus en couleur avec pas mal de fonctions et la gestion correcte des ico --> d'ou mon code). mais qui sait ...
Répondre