Lecture et affichage du contenu des fichiers res (résident)

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Bon, j'ai essayé, c'est pas mal :D

Par contre, une erreur, j'ai un resident nommé Pi avec #Pi=3.1415
et l'affichage ne marche pas avec les floats ;)
a vérifier avec les contantes au format texte

Sinon, faudrait mettre une recherche :)
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 »

bernard13 a écrit :je vois pas l'interet de faire ça

Déjà tu as la liste de toutes les constantes déclarées en PB, qu'elles soient PureBasic ou qu'elles viennent des lib utilisateurs.

Je n'ai pas fait ce code et tout le temps passé pour me faire plaisir Bernard.
J'ai écrit un outil qui permet de créer un squelette de fichier assembleur au format FASM et on peut déclarer des variables basées sur des structures ou interfaces ou classiques et mon outil génère automatiquement les déclarations des adresses en assembleur, il calcule les offsets et crée l'ensemble des déclarations pour créer un librairie en asm, que les variables soient locales ou globales.

C'est opérationnel à 90% pourcents.

Voilà le pourquoi du comment :wink:
Dernière modification par Anonyme2 le jeu. 10/mars/2005 22:13, modifié 1 fois.
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Le Soldat Inconnu a écrit :Bon, j'ai essayé, c'est pas mal :D

Par contre, une erreur, j'ai un resident nommé Pi avec #Pi=3.1415
et l'affichage ne marche pas avec les floats ;)
a vérifier avec les contantes au format texte

Sinon, faudrait mettre une recherche :)
Merci Régis, je vas regarder les flottants.

Pour la recherche, vais voir . :D
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Voilà le code avec 2 fonctions de recherche, une pour les constantes et l'autre pour les structures.

Je n'ai pas encore trouvé la solution pour les flottants :roll:

Code : Tout sélectionner

; Auteur : Denis
; Version de PB : 3.93
; Librairie utilisée : Aucune
; Date : 13 janvier 2005
; Modifié le 10 mars pour le support résident version 1
; Modifié le 11 mars pour le support de recherche
;
; Explication du code :
; Affiche le contenu des fichiers résidents PB et utilisateurs, constantes et structures
; Les interfaces ne sont pas analysées, ça pourrait planter, c'est la prochaine étape
; Les constantes sont dans une liste chainée nommée Constantes
; Pour chaque constante, on retrouve :
;- le nom de la constante
;- le nom du fichier ou est déclarée la constantes
;- la valeur numérique dans Valeur ou la chaine dans Valeur$ lorsqu'il s'agit d'une constante chaine
; Pour savoir si c'est un constantes chaine il faut tester la longueur de la chaine

; Les structures sont en suivants dans la liste chainées, y compris les mots Structure, Endstructure
; StructureUnion et EndStructureUnion
;
; J'ai mis en commentaire l'offset de chaque élément, ca peut servir pour ceux qui voudraient utiliser
; ce code.
;
; il reste des champs dont je n'ai pas saisi l'utilité (mais pour mon besoin ce n'est pas grave)

Enumeration
   #Fenetre_Principale
   #ListIconConstantes
   #StringGadgetCst
   #StringGadgetStruc
   #Container1
   #ListIconStructures
   #BoutonRechercherCst
   #BoutonRechercherStruc
   #gadSplitter
EndEnumeration

#res1 = 1 ; format resident version 1
#res2 = 2 ; format resident version 2
#res3 = 3 ; format resident version 3

; codage des éléments des structures du fichier res
; pour différencier un élément qui est un tableau d'un élément qui
; ne l'est pas, on lit le long précédant le nom de la structure (valeur collée
; au nom de l'élément). Si le long vaut -1 (=$FFFFFFFF) ce n'est pas un tableau
; on a donc 2 long pour différencier par exemple un #byte d'un #Tableau_byte
; les codes suivants correspondent au codage des éléments en fonction de leur type
; j'ai eu dans tous mes tests un valeur hexa qui revenait mais je ne suis pas arrivé
; à savoir pourquoi. Parfois j'avais $207 au lieu de $7, mais si c'est un pointeur
; j'avais de toute façon $107, je teste si la valeur appartient à l'intervalle
; $100 <--> $10A et si oui c'est un pointeur. Avec les byte, long etc je n'ai pas cette
; valeur $200 ajouté au code de base


; byte                        = $1
; word                        = $3
; long                        = $5
; Structure                   = $7
; String                      = $8
; flottant                    = $9
;
; Tableau_byte                = $1
; Tableau_word                = $3
; Tableau_long                = $5
; Tableau_Structure           = $7
; Tableau_String              = $8
; Tableau_flottant            = $9
;
; Pointeur_byte               = $101  --> 257 en déci
; Pointeur_word               = $103
; Pointeur_long               = $105
; Pointeur_Structure          = $107
; Pointeur_String             = $108
; Pointeur_flottant           = $109  --> 265 en déci
;
; Pointeur_Tableau_byte       = $101
; Pointeur_Tableau_word       = $103
; Pointeur_Tableau_long       = $105
; Pointeur_Tableau_Structure  = $107
; Pointeur_Tableau_String     = $108
; Pointeur_Tableau_flottant   = $109

Structure Constante
   Nom$
   FichierResident$
   Valeur.l
   Valeur$ ; cas des constantes de texte
EndStructure

Structure Structures
   Nom$
EndStructure

NewList Constantes.Constante()
NewList Structures.Structures()

Global Nb_Structures ; comptabilise le nombre total de structures de tous les fichiers

;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.s CheminPureBasic()
   Buffer$ = Space(260) : BufferSize = 259
   If GetVersion_() & $FF0000 ; Windows NT/XP
      clef = #HKEY_CLASSES_ROOT
      Adresse = @"Applications\PureBasic.exe\shell\open\command"
   Else ; La même chose pour Win9x
      clef = #HKEY_LOCAL_MACHINE
      Adresse = @"Software\Classes\PureBasic.exe\shell\open\command"
   EndIf
   
   If RegOpenKeyEx_(clef, Adresse, 0, #KEY_ALL_ACCESS, @Key) = #ERROR_SUCCESS
      If RegQueryValueEx_(Key, "", 0, @type, @Buffer$, @BufferSize) = #ERROR_SUCCESS
         OutputDirectory$ = GetPathPart(Mid(Buffer$, 2, Len(Buffer$) - 7))
      EndIf
      RegCloseKey_(Key)
   EndIf
   ProcedureReturn OutputDirectory$
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure LectureResident()
   PbConstantFolder$ = CheminPureBasic() + "Residents\"
   If ExamineDirectory(0, PbConstantFolder$, "*.res")
      CheminDir = NextDirectoryEntry()
      While CheminDir
         ; les interfaces pas pris en compte, on passe les fichiers
         If CheminDir = 1 And LCase(DirectoryEntryName()) <> "interface.res"And LCase(DirectoryEntryName()) <> "interfacedx.res"
            If ReadFile(0, PbConstantFolder$ + DirectoryEntryName())
               TailleFichier = Lof()
               *ConstantsHeader = AllocateMemory(TailleFichier)
               ; *ConstantsHeader est un pointeur sur le début du texte en mémoire
               ReadData(*ConstantsHeader, TailleFichier)
               CloseFile(0)
               *ConstantsEnd = *ConstantsHeader + TailleFichier
               *SymbolCourant = *ConstantsHeader
               ; *SymbolCourant va permettre de lire les symboles en suivant
               ; Le fichier commmence par les 16 caractères suivant, si Ok on continue
               ; 'ERUP'+0,0,0,0+'3SER'+'TCRS' ou 'ERUP'+0,0,0,0+'1SER'+'TCRS'
               If CompareMemory(*SymbolCourant, ?Fichier_Res3, 16)
                  RES = #res3
               ElseIf CompareMemory(*SymbolCourant, ?Fichier_Res1, 16)
                  RES = #res1
               Else
                  RES = 0
               EndIf
               If RES
                  *SymbolCourant + 16
                  ; le fichier commence par des structures s'il y en a sinon par les constantes
                  Select PeekL(*SymbolCourant)
                     Case 0 ; il n'y a que des constantes, pas de structures ou interfaces
                        If PeekL(*SymbolCourant + 4) = 'CNST'
                           *SymbolCourant + 12
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$" ; je ne sais pas pourquoi on retrouve
                                 ; une copie de la chaine avec $ à la fin mais pas toujours (?)
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                 If RES <> #res1
                                    If PeekW(*SymbolCourant)
                                       ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                       ; alphanumérique
                                       *SymbolCourant + 2
                                       Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                       *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                    Else
                                       ; ici c'est une valeur et pas une chaine
                                       *SymbolCourant + 2
                                       Constantes()\Valeur = PeekL(*SymbolCourant)
                                       *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                    EndIf
                                 Else
                                    Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                    *SymbolCourant + 5
                                 EndIf
                              EndIf
                           Wend
                        Else
                           MessageRequester("Erreur1", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
                        EndIf
                        
                     Default ; on débute par les structures
                        ; Debug "Fichier :   " + DirectoryEntryName()
                        ; TotalCaracteresToutesStructures est la longueur total utilisée dans le fichier res
                        ; pour stocker toutes les infos des structures
                        TotalCaracteresToutesStructures = PeekL(*SymbolCourant)
                        *SymbolCourant + 4 ; on avance le pointeur
                        *DernierSymbol = *SymbolCourant + TotalCaracteresToutesStructures
                        ; les 4 caractères qui commences à *SymbolCourant+TotalCaracteresToutesStructures
                        ; sont TSNC  --> les constantes s'il y en a ou sinon une autre chaine
                        
                        Repeat
                           ; le champ suivant est le nom de la structure sous forme de string classique
                           Nom_Structure$ = PeekS(*SymbolCourant)
                           *SymbolCourant + Len(Nom_Structure$) + 1 ; on avance le pointeur
                           Nb_Structures + 1 ; on incrémente le compteur de structure
                           ; le champ suivant est un long donnant la taille de la structure
                           TailleStructure = PeekL(*SymbolCourant)
                           *SymbolCourant + 4 ; on avance le pointeur
                           ; le champ suivant est un word donnant le nombre d'éléments de la structure
                           Nombre_Elements = PeekW(*SymbolCourant)
                           If RES = #res1
                              *SymbolCourant + 4 ; on avance le pointeur
                           Else
                              *SymbolCourant + 3 ; on avance le pointeur
                           EndIf
                           
                           AddElement(Structures())
                           ; les lignes suivantes c'est pour mettre ou non un s à la fin des mots (pluriel)
                           If Nombre_Elements > 1
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : " + Str(TailleStructure) + " octets,  constituée de " + Str(Nombre_Elements) + " éléments"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : 1 octet,  constituée de " + Str(Nombre_Elements) + " éléments"
                              EndIf
                           Else
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : " + Str(TailleStructure) + " octets,  constituée d'un élément"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : 1 octet,  constituée d'un élément"
                              EndIf
                           EndIf
                           Structures()\Nom$ + "  -  déclaré dans le fichier " + DirectoryEntryName() + ")"
                           ; le champ suivant est un Long donnant le nombre de caractères jusqu'au 0 de fin de chaine inclus
                           ; chaine représentant le type de l'élément
                           FinStructureCourante = *SymbolCourant + PeekL(*SymbolCourant) + 4 - 1
                           Decale$ = ""
                           StructureUnion_Courante = #false ; permet d'inclure les mots StructureUnion ou EndStructureUnion
                           Offset = 0 ; Offset de l'élément courant par rapport à l'origine
                           OffsetMax = 0 ; OffsetMax va être modifié dans la boucle for suivante si pas une StructureUnion
                           ; OffsetMax mémorise l'offset max en cours, on lit pour chaque élément son offset respectif
                           ; situé dans le fichier et on compare, si offset > OffsetMax alors OffsetMax = Offset
                           ; si Offset > OffsetMax on n'est pas dans une StructureUnion, sinon c'est un élément de la StructureUnion
                           For i = 1 To Nombre_Elements
                              ; on va lire à "rebrousse poil" d'abord le type de l'élément puis son nom
                              *SymbolCourant = FinStructureCourante - 1
                              Type$ = ""
                              Char.b = PeekB(*SymbolCourant)
                              While Char
                                 Type$ = Chr(Char) + Type$
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              ; normalement ici Char vaut 0 et Type$ vaut le nom du type de l'élément
                              ; on on va lire à "rebrousse poil" le nom de l'élément et le caractère
                              ; d'arrêt est soit 255 ($FF) soit 0 donc > 0
                              ; si c'est $FF ce n'est pas un tableau ($FF = -1 sur 1 octet)
                              *SymbolCourant - 1 ; on remonte avant le 0 de fin de chaine
                              Char = PeekB(*SymbolCourant)
                              While Char > 0
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              *SymbolCourant + 1
                              AddElement(Structures())
                              If Char = -1 ; ce n'est pas un tableau
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion, on ne modifie pas OffsetMax
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       OffsetMax = Offset
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$
                              Else ; sinon c'est un tableau, le long précédant est <> de $FFFF
                                 ; la valeur du tableau est située à *SymbolCourant-4 juste avant le nom de l'élément
                                 ; l'offset de l'élément est situé à *SymbolCourant-12
                                 ; le codage pointeur est un long situé à *SymbolCourant-16, si = 5 pointeur
                                 Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          If ListIndex(Structures()) - 2 >= 0 ; on teste que l'élément existe
                                             SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          Else
                                             FirstElement(Structures())
                                          EndIf
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       OffsetMax = Offset
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    TailleTableau = PeekW(*SymbolCourant - 2)
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    TailleTableau = PeekL(*SymbolCourant - 4)
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$ + "[" + Str(TailleTableau) + "]"
                              EndIf
                              If i < Nombre_Elements
                                 FinStructureCourante + PeekL(FinStructureCourante + 1) + 4
                              EndIf
                           Next i
                           AddElement(Structures())
                           If StructureUnion_Courante = #true
                              Structures()\Nom$ = Decale$ + " EndStructureUnion"
                              Decale$ = ""
                              AddElement(Structures())
                           EndIf
                           Structures()\Nom$ = "EndStructure"
                           AddElement(Structures())
                           AddElement(Structures())
                           *SymbolCourant = FinStructureCourante + 1
                        Until *SymbolCourant >= *DernierSymbol
                        ; ici on en a fini avec les structures, on regarde s'il y a des constantes
                        ; en arrivant ici, les 4 premiers octets de la chaine que l'on va lire doivent
                        ; valoir TSNC, on teste
                        *SymbolCourant = *DernierSymbol ; on positionne le pointeur
                        If PeekL(*SymbolCourant) = 'CNST'
                           ; il peut y avoir plus de deux 0, donc on supprime tous les 0
                           If RES = #res1
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 3
                           Else
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Char.b = PeekB(*SymbolCourant)
                              While Char = 0
                                 *SymbolCourant + 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                           EndIf
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$"
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                 If RES <> #res1
                                    If PeekW(*SymbolCourant)
                                       ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                       ; alphanumérique
                                       *SymbolCourant + 2
                                       Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                       *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                    Else
                                       ; ici c'est une valeur et pas une chaîne
                                       *SymbolCourant + 2
                                       Constantes()\Valeur = PeekL(*SymbolCourant)
                                       *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                    EndIf
                                 Else
                                    Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                    *SymbolCourant + 5
                                 EndIf
                              EndIf
                           Wend
                        EndIf
                  EndSelect
               Else
                  MessageRequester("Erreur", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
               EndIf
               FreeMemory(*ConstantsHeader)
            EndIf
         EndIf
         CheminDir = NextDirectoryEntry()
      Wend
   EndIf
EndProcedure

Procedure.l GetListPos(Gadget.l)
  ProcedureReturn SendMessage_(GadgetID(Gadget), #LVM_GETTOPINDEX, 0, 0)
EndProcedure

Procedure.l SetListPos(Gadget.l, Position.l)
  Protected Pos.POINT
  SendMessage_(GadgetID(Gadget), #LVM_GETITEMPOSITION, Position - 1, Pos)
  SendMessage_(GadgetID(Gadget), #LVM_SCROLL, 0, Pos\y)
  Debug Pos\y
EndProcedure


Procedure  RechercheStruc()
Protected a$
   a$ = UCase(GetGadgetText(#StringGadgetStruc))
   If Len(a$)
      compt = CountGadgetItems(#ListIconStructures)
      If compt > 0
         compt - 1
         StructureExiste = #false
         For i = 0 To compt
            If UCase("Structure  "+a$) = Left(UCase(GetGadgetItemText(#ListIconStructures, i, 0)), Len("Structure  "+a$))
               TopIdex =  GetListPos(#ListIconStructures)
               If i > TopIdex 
                   SetListPos(#ListIconStructures, i)
               ElseIf i< TopIdex 
                   SetListPos(#ListIconStructures, -1)
                   SetListPos(#ListIconStructures, i)
               EndIf
               StructureExiste = #true
               SetGadgetItemState(#ListIconStructures, GetListPos(#ListIconStructures), #PB_ListIcon_Selected)
               ActivateGadget(#ListIconStructures)
               Break
            EndIf
         Next
         If StructureExiste = #false
            MessageRequester("Erreur", "La structure " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure

Procedure RechercheCst()
Protected a$
   a$ = UCase(GetGadgetText(#StringGadgetCst))
   If Len(a$)
      compt = CountGadgetItems(#ListIconConstantes)
      If compt > 0
         compt - 1
         ConstanteExiste = #false
         For i = 0 To compt
            If a$ = UCase(GetGadgetItemText(#ListIconConstantes, i, 0))
               TopIdex =  GetListPos(#ListIconConstantes)
               If i > TopIdex 
                   SetListPos(#ListIconConstantes, i)
               ElseIf i< TopIdex 
                   SetListPos(#ListIconConstantes, -1)
                   SetListPos(#ListIconConstantes, i)
               EndIf
               ConstanteExiste = #true
               SetGadgetItemState(#ListIconConstantes, GetListPos(#ListIconConstantes), #PB_ListIcon_Selected)
               ActivateGadget(#ListIconConstantes)
               Break
            EndIf
         Next
         If ConstanteExiste = #false
            MessageRequester("Erreur", "La constante " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\

If OpenWindow(#Fenetre_Principale, 0, 0, 660, 428, #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Lecture des fichiers résidents PureBasic")
   If CreateGadgetList(WindowID(#Fenetre_Principale))
      Nb_Structures = 0
      LectureResident()
      ; Tri des constantes
      Dim Cst.s(CountList(Constantes()) - 1)
      ForEach Constantes()
         If Len(Constantes()\Valeur$)
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£" + Constantes()\Valeur$ + "£" + Constantes()\FichierResident$
         Else
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£$" + Hex(Constantes()\Valeur) + "£" + Constantes()\FichierResident$
         EndIf
      Next
      ; on trie; Méthode du soldat inconnu
      SortArray(Cst.s(), 2)
      
      If ListIconGadget(#ListIconConstantes, 0, 0, 440, 104, " Constante  (" + Str(CountList(Constantes())) + " références)", 220, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         AddGadgetColumn(#ListIconConstantes, 1, " Valeur", 80)
         AddGadgetColumn(#ListIconConstantes, 21, " Fichier résident", 140 - 22)
         HideGadget(#ListIconConstantes, 1)
         For i = 0 To ListIndex(Constantes()) ; Affichage  des constantes
            AddGadgetItem(#ListIconConstantes, -1, StringField(Cst.s(i), 1, "£") + Chr(10) + StringField(Cst.s(i), 2, "£") + Chr(10) + StringField(Cst.s(i), 3, "£"))
         Next
         HideGadget(#ListIconConstantes, 0)
      EndIf
      If ContainerGadget(#Container1, 0, 0, 215, 104, #PB_Container_Flat)
            StringGadget(#StringGadgetCst, 20, 20, 180, 20, "")
            ButtonGadget(#BoutonRechercherCst, 20, 45, 180, 40, "Rechercher une constante")
            StringGadget(#StringGadgetStruc, 20, 120, 180, 20, "")
            ButtonGadget(#BoutonRechercherStruc, 20, 145, 180, 40, "Rechercher une structure")
         CloseGadgetList()
      EndIf
      
      SplitterGadget(#gadSplitter, 0, 0, 660, 225, #Container1, #ListIconConstantes, #PB_Splitter_Vertical | #PB_Splitter_Separator)
      SetGadgetState(#gadSplitter, 220)
      Dim cst.s(0)
      If ListIconGadget(#ListIconStructures, 0, 225, 660, 204, " Structures   (" + Str(Nb_Structures) + " références)", 640, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         HideGadget(#ListIconStructures, 1)
         
         If ListIndex(Structures()) > 0
            ForEach Structures() ; Affichage  des structures
               AddGadgetItem(#ListIconStructures, -1, Structures()\nom$)
               A$ = A$ + Structures()\nom$ + Chr(10)
            Next
         EndIf
         HideGadget(#ListIconStructures, 0)
      EndIf
   EndIf
   
   HideWindow(#Fenetre_Principale, 0)
   Repeat
      event = WaitWindowEvent()
      Select event
         Case #PB_EventCloseWindow
            quit + 1
            
         Case #PB_eventGadget
            Select EventGadgetID()
               Case #BoutonRechercherCst
                  RechercheCst()
               Case #BoutonRechercherStruc
                     RechercheStruc()
            EndSelect
            
         Case #WM_KEYDOWN
            Select EventwParam()
               Case #PB_Shortcut_Return
                  If GetFocus_() = GadgetID(#StringGadgetCst)
                     RechercheCst()
                  ElseIf GetFocus_() = GadgetID(#StringGadgetStruc)
                     RechercheStruc()
                  EndIf
            EndSelect
            
      EndSelect
   Until quit
   
EndIf

DataSection
   Fichier_Res3 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $33, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res2 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $32, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res1 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $31, $53, $45, $52, $54, $43, $52, $53
EndDataSection ;}
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

c super ton truc denis.

dans jaPBe il y a un visualiseur de structures et d'interfaces.
je le trouve plutot bien fait d'ailleurs, simple mais efficace.
pour autant ton visualiseur fournit plus d'informations (outre les constantes bien sûr, tu as aussi la taille, le fichier d'origine, ...
un mix des 2 me plairais beaucoup :D
Image
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

C'est vrai que ça peut être TRES utile! Il faudrait l'intégrer au menu outils de l'éditeur pure, en dessous du truc pour les interfaces (moi c'est fait)

Merci Denis!
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci :D

Le code est perfectible car pour l'instant les flottants ne sont pas pris en compte correctement (je cherche) et la version2 des résidents non plus (il doit y en avoir peu ??)
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Voilà le code modifié et qui transcrit correctement les constantes format flottant, sauf pour la version 1 des résidents car je pense qu'ils ne sont pas supportés par cette version de résidents (ni les strings je pense).

Code : Tout sélectionner

; Auteur : Denis
; Version de PB : 3.93
; Librairie utilisée : Aucune
; Date : 13 janvier 2005
; Modifié le 10 mars pour le support résident version 1
; Modifié le 14 mars pour le support des constantes "flottant"
;
; Explication du code :
; Affiche le contenu des fichiers résidents PB et utilisateurs, constantes et structures
; Les interfaces ne sont pas analysées, ça pourrait planter, c'est la prochaine étape
; Les constantes sont dans une liste chainée nommée Constantes
; Pour chaque constante, on retrouve :
;- le nom de la constante
;- le nom du fichier ou est déclarée la constantes
;- la valeur numérique dans Valeur ou la chaine dans Valeur$ lorsqu'il s'agit d'une constante chaine
; Pour savoir si c'est un constantes chaine il faut tester la longueur de la chaine

; Les structures sont en suivants dans la liste chainées, y compris les mots Structure, Endstructure
; StructureUnion et EndStructureUnion
;
; J'ai mis en commentaire l'offset de chaque élément, ca peut servir pour ceux qui voudraient utiliser
; ce code.
;
; il reste des champs dont je n'ai pas saisi l'utilité (mais pour mon besoin ce n'est pas grave)

Enumeration
   #Fenetre_Principale
   #ListIconConstantes
   #StringGadgetCst
   #StringGadgetStruc
   #Container1
   #ListIconStructures
   #BoutonRechercherCst
   #BoutonRechercherStruc
   #gadSplitter
EndEnumeration

#res1 = 1 ; format resident version 1
#res2 = 2 ; format resident version 2
#res3 = 3 ; format resident version 3

; codage des éléments des structures du fichier res
; pour différencier un élément qui est un tableau d'un élément qui
; ne l'est pas, on lit le long précédant le nom de la structure (valeur collée
; au nom de l'élément). Si le long vaut -1 (=$FFFFFFFF) ce n'est pas un tableau
; on a donc 2 long pour différencier par exemple un #byte d'un #Tableau_byte
; les codes suivants correspondent au codage des éléments en fonction de leur type
; j'ai eu dans tous mes tests un valeur hexa qui revenait mais je ne suis pas arrivé
; à savoir pourquoi. Parfois j'avais $207 au lieu de $7, mais si c'est un pointeur
; j'avais de toute façon $107, je teste si la valeur appartient à l'intervalle
; $100 <--> $10A et si oui c'est un pointeur. Avec les byte, long etc je n'ai pas cette
; valeur $200 ajouté au code de base


; byte                        = $1
; word                        = $3
; long                        = $5
; Structure                   = $7
; String                      = $8
; flottant                    = $9
;
; Tableau_byte                = $1
; Tableau_word                = $3
; Tableau_long                = $5
; Tableau_Structure           = $7
; Tableau_String              = $8
; Tableau_flottant            = $9
;
; Pointeur_byte               = $101  --> 257 en déci
; Pointeur_word               = $103
; Pointeur_long               = $105
; Pointeur_Structure          = $107
; Pointeur_String             = $108
; Pointeur_flottant           = $109  --> 265 en déci
;
; Pointeur_Tableau_byte       = $101
; Pointeur_Tableau_word       = $103
; Pointeur_Tableau_long       = $105
; Pointeur_Tableau_Structure  = $107
; Pointeur_Tableau_String     = $108
; Pointeur_Tableau_flottant   = $109

Structure Constante
   Nom$
   FichierResident$
   Valeur.l
   Valeur$ ; cas des constantes de texte
EndStructure

Structure Structures
   Nom$
EndStructure

NewList Constantes.Constante()
NewList Structures.Structures()

Global Nb_Structures ; comptabilise le nombre total de structures de tous les fichiers
Global ValeurF$, ValeurHexa.l
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.s CheminPureBasic()
   Buffer$ = Space(260) : BufferSize = 259
   If GetVersion_() & $FF0000 ; Windows NT/XP
      clef = #HKEY_CLASSES_ROOT
      Adresse = @"Applications\PureBasic.exe\shell\open\command"
   Else ; La même chose pour Win9x
      clef = #HKEY_LOCAL_MACHINE
      Adresse = @"Software\Classes\PureBasic.exe\shell\open\command"
   EndIf
   
   If RegOpenKeyEx_(clef, Adresse, 0, #KEY_ALL_ACCESS, @Key) = #ERROR_SUCCESS
      If RegQueryValueEx_(Key, "", 0, @type, @Buffer$, @BufferSize) = #ERROR_SUCCESS
         OutputDirectory$ = GetPathPart(Mid(Buffer$, 2, Len(Buffer$) - 7))
      EndIf
      RegCloseKey_(Key)
   EndIf
   ProcedureReturn OutputDirectory$
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
   Procedure ConversionFloat2String(Nombre.l)
      !extrn  _PB_StrF@4
      !PUSH  dword [PB_StringBase]
      !PUSH  dword[esp+4]
      !CALL  _PB_StrF@4
      !LEA  ecx,[v_ValeurF$]
      !POP  edx
      !CALL  SYS_AllocateString
   EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure LectureResident()
   PbConstantFolder$ = CheminPureBasic() + "Residents\"
   If ExamineDirectory(0, PbConstantFolder$, "*.res")
      CheminDir = NextDirectoryEntry()
      While CheminDir
         ; les interfaces pas pris en compte, on passe les fichiers
         If CheminDir = 1 And LCase(DirectoryEntryName()) <> "interface.res"And LCase(DirectoryEntryName()) <> "interfacedx.res"
            If ReadFile(0, PbConstantFolder$ + DirectoryEntryName())
               TailleFichier = Lof()
               *ConstantsHeader = AllocateMemory(TailleFichier)
               ; *ConstantsHeader est un pointeur sur le début du texte en mémoire
               ReadData(*ConstantsHeader, TailleFichier)
               CloseFile(0)
               *ConstantsEnd = *ConstantsHeader + TailleFichier
               *SymbolCourant = *ConstantsHeader
               ; *SymbolCourant va permettre de lire les symboles en suivant
               ; Le fichier commmence par les 16 caractères suivant, si Ok on continue
               ; 'ERUP'+0,0,0,0+'3SER'+'TCRS' ou 'ERUP'+0,0,0,0+'1SER'+'TCRS'
               If CompareMemory(*SymbolCourant, ?Fichier_Res3, 16)
                  RES = #res3
               ElseIf CompareMemory(*SymbolCourant, ?Fichier_Res1, 16)
                  RES = #res1
               Else
                  RES = 0
               EndIf
               If RES
                  *SymbolCourant + 16
                  ; le fichier commence par des structures s'il y en a sinon par les constantes
                  Select PeekL(*SymbolCourant)
                     Case 0 ; il n'y a que des constantes, pas de structures ou interfaces
                        If PeekL(*SymbolCourant + 4) = 'CNST'
                           *SymbolCourant + 12
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$" ; je ne sais pas pourquoi on retrouve
                                 ; une copie de la chaine avec $ à la fin mais pas toujours (?)
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                    If RES <> #res1
                                       If PeekW(*SymbolCourant) = $800
                                          ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                          ; alphanumérique
                                          *SymbolCourant + 2
                                          Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                          *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                       ElseIf PeekW(*SymbolCourant) = $400  ; c'est un flottant
                                       Debug Constantes()\nom$
                                          *SymbolCourant + 2
                                          ConversionFloat2String(PeekL(*SymbolCourant))
                                          Constantes()\Valeur$ = ValeurF$
                                          *SymbolCourant + 4
                                       Else
                                          ; ici c'est une valeur et pas une chaine
                                          *SymbolCourant + 2
                                          Constantes()\Valeur = PeekL(*SymbolCourant)
                                          *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                       EndIf
                                    Else
                                       Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                       *SymbolCourant + 5
                                    EndIf
                              EndIf
                           Wend
                        Else
                           MessageRequester("Erreur1", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
                        EndIf
                        
                     Default ; on débute par les structures
                        ; Debug "Fichier :   " + DirectoryEntryName()
                        ; TotalCaracteresToutesStructures est la longueur total utilisée dans le fichier res
                        ; pour stocker toutes les infos des structures
                        TotalCaracteresToutesStructures = PeekL(*SymbolCourant)
                        *SymbolCourant + 4 ; on avance le pointeur
                        *DernierSymbol = *SymbolCourant + TotalCaracteresToutesStructures
                        ; les 4 caractères qui commences à *SymbolCourant+TotalCaracteresToutesStructures
                        ; sont TSNC  --> les constantes s'il y en a ou sinon une autre chaine
                        
                        Repeat
                           ; le champ suivant est le nom de la structure sous forme de string classique
                           Nom_Structure$ = PeekS(*SymbolCourant)
                           *SymbolCourant + Len(Nom_Structure$) + 1 ; on avance le pointeur
                           Nb_Structures + 1 ; on incrémente le compteur de structure
                           ; le champ suivant est un long donnant la taille de la structure
                           TailleStructure = PeekL(*SymbolCourant)
                           *SymbolCourant + 4 ; on avance le pointeur
                           ; le champ suivant est un word donnant le nombre d'éléments de la structure
                           Nombre_Elements = PeekW(*SymbolCourant)
                           If RES = #res1
                              *SymbolCourant + 4 ; on avance le pointeur
                           Else
                              *SymbolCourant + 3 ; on avance le pointeur
                           EndIf
                           
                           AddElement(Structures())
                           ; les lignes suivantes c'est pour mettre ou non un s à la fin des mots (pluriel)
                           If Nombre_Elements > 1
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : " + Str(TailleStructure) + " octets,  constituée de " + Str(Nombre_Elements) + " éléments"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : 1 octet,  constituée de " + Str(Nombre_Elements) + " éléments"
                              EndIf
                           Else
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : " + Str(TailleStructure) + " octets,  constituée d'un élément"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$ + "   (taille : 1 octet,  constituée d'un élément"
                              EndIf
                           EndIf
                           Structures()\Nom$ + "  -  déclaré dans le fichier " + DirectoryEntryName() + ")"
                           ; le champ suivant est un Long donnant le nombre de caractères jusqu'au 0 de fin de chaine inclus
                           ; chaine représentant le type de l'élément
                           FinStructureCourante = *SymbolCourant + PeekL(*SymbolCourant) + 4 - 1
                           Decale$ = ""
                           StructureUnion_Courante = #false ; permet d'inclure les mots StructureUnion ou EndStructureUnion
                           Offset = 0 ; Offset de l'élément courant par rapport à l'origine
                           OffsetMax = 0 ; OffsetMax va être modifié dans la boucle for suivante si pas une StructureUnion
                           ; OffsetMax mémorise l'offset max en cours, on lit pour chaque élément son offset respectif
                           ; situé dans le fichier et on compare, si offset > OffsetMax alors OffsetMax = Offset
                           ; si Offset > OffsetMax on n'est pas dans une StructureUnion, sinon c'est un élément de la StructureUnion
                           For i = 1 To Nombre_Elements
                              ; on va lire à "rebrousse poil" d'abord le type de l'élément puis son nom
                              *SymbolCourant = FinStructureCourante - 1
                              Type$ = ""
                              Char.b = PeekB(*SymbolCourant)
                              While Char
                                 Type$ = Chr(Char) + Type$
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              ; normalement ici Char vaut 0 et Type$ vaut le nom du type de l'élément
                              ; on on va lire à "rebrousse poil" le nom de l'élément et le caractère
                              ; d'arrêt est soit 255 ($FF) soit 0 donc > 0
                              ; si c'est $FF ce n'est pas un tableau ($FF = -1 sur 1 octet)
                              *SymbolCourant - 1 ; on remonte avant le 0 de fin de chaine
                              Char = PeekB(*SymbolCourant)
                              While Char > 0
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              *SymbolCourant + 1
                              AddElement(Structures())
                              If Char = -1 ; ce n'est pas un tableau
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion, on ne modifie pas OffsetMax
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       OffsetMax = Offset
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$
                              Else ; sinon c'est un tableau, le long précédant est <> de $FFFF
                                 ; la valeur du tableau est située à *SymbolCourant-4 juste avant le nom de l'élément
                                 ; l'offset de l'élément est situé à *SymbolCourant-12
                                 ; le codage pointeur est un long situé à *SymbolCourant-16, si = 5 pointeur
                                 Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          If ListIndex(Structures()) - 2 >= 0 ; on teste que l'élément existe
                                             SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          Else
                                             FirstElement(Structures())
                                          EndIf
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       OffsetMax = Offset
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    TailleTableau = PeekW(*SymbolCourant - 2)
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    TailleTableau = PeekL(*SymbolCourant - 4)
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$ + "[" + Str(TailleTableau) + "]"
                              EndIf
                              If i < Nombre_Elements
                                 FinStructureCourante + PeekL(FinStructureCourante + 1) + 4
                              EndIf
                           Next i
                           AddElement(Structures())
                           If StructureUnion_Courante = #true
                              Structures()\Nom$ = Decale$ + " EndStructureUnion"
                              Decale$ = ""
                              AddElement(Structures())
                           EndIf
                           Structures()\Nom$ = "EndStructure"
                           AddElement(Structures())
                           AddElement(Structures())
                           *SymbolCourant = FinStructureCourante + 1
                        Until *SymbolCourant >= *DernierSymbol
                        ; ici on en a fini avec les structures, on regarde s'il y a des constantes
                        ; en arrivant ici, les 4 premiers octets de la chaine que l'on va lire doivent
                        ; valoir TSNC, on teste
                        *SymbolCourant = *DernierSymbol ; on positionne le pointeur
                        If PeekL(*SymbolCourant) = 'CNST'
                           ; il peut y avoir plus de deux 0, donc on supprime tous les 0
                           If RES = #res1
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 3
                           Else
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Char.b = PeekB(*SymbolCourant)
                              While Char = 0
                                 *SymbolCourant + 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                           EndIf
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$"
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                    If RES <> #res1
                                       If PeekW(*SymbolCourant) = $800
                                          ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                          ; alphanumérique
                                          *SymbolCourant + 2
                                          Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                          *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                       ElseIf PeekW(*SymbolCourant) = $400  ; c'est un flottant
                                       Debug Constantes()\nom$
                                          *SymbolCourant + 2
                                          ConversionFloat2String(PeekL(*SymbolCourant))
                                          Constantes()\Valeur$ = ValeurF$
                                          *SymbolCourant + 4
                                       Else
                                          ; ici c'est une valeur et pas une chaine
                                          *SymbolCourant + 2
                                          Constantes()\Valeur = PeekL(*SymbolCourant)
                                          *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                       EndIf
                                    Else
                                       Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                       *SymbolCourant + 5
                                    EndIf
                              EndIf
                           Wend
                        EndIf
                  EndSelect
               Else
                  MessageRequester("Erreur", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
               EndIf
               FreeMemory(*ConstantsHeader)
            EndIf
         EndIf
         CheminDir = NextDirectoryEntry()
      Wend
   EndIf
EndProcedure

Procedure.l GetListPos(Gadget.l)
  ProcedureReturn SendMessage_(GadgetID(Gadget), #LVM_GETTOPINDEX, 0, 0)
EndProcedure

Procedure.l SetListPos(Gadget.l, Position.l)
  Protected Pos.POINT
  SendMessage_(GadgetID(Gadget), #LVM_GETITEMPOSITION, Position - 1, Pos)
  SendMessage_(GadgetID(Gadget), #LVM_SCROLL, 0, Pos\y)
EndProcedure

Procedure  RechercheStruc()
Protected a$
   a$ = GetGadgetText(#StringGadgetStruc)
   If Len(a$)
      compt = CountGadgetItems(#ListIconStructures)
      If compt > 0
         compt - 1
         StructureExiste = #false
         For i = 0 To compt
            If UCase("Structure  "+a$+" ") = Left(UCase(GetGadgetItemText(#ListIconStructures, i, 0)), Len("Structure  "+a$)+1)
               TopIdex =  GetListPos(#ListIconStructures)
               If i > TopIdex 
                   SetListPos(#ListIconStructures, i)
               ElseIf i< TopIdex 
                   SetListPos(#ListIconStructures, -1)
                   SetListPos(#ListIconStructures, i)
               EndIf
               StructureExiste = #true
               SetGadgetItemState(#ListIconStructures, GetListPos(#ListIconStructures), #PB_ListIcon_Selected)
               ActivateGadget(#ListIconStructures)
               Break
            EndIf
         Next
         If StructureExiste = #false
            MessageRequester("Erreur", "La structure " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure

Procedure RechercheCst()
Protected a$
   a$ = UCase(GetGadgetText(#StringGadgetCst))
   If Len(a$)
      compt = CountGadgetItems(#ListIconConstantes)
      If compt > 0
         compt - 1
         ConstanteExiste = #false
         For i = 0 To compt
            If a$ = UCase(GetGadgetItemText(#ListIconConstantes, i, 0))
               TopIdex =  GetListPos(#ListIconConstantes)
               If i > TopIdex 
                   SetListPos(#ListIconConstantes, i)
               ElseIf i< TopIdex 
                   SetListPos(#ListIconConstantes, -1)
                   SetListPos(#ListIconConstantes, i)
               EndIf
               ConstanteExiste = #true
               SetGadgetItemState(#ListIconConstantes, GetListPos(#ListIconConstantes), #PB_ListIcon_Selected)
               ActivateGadget(#ListIconConstantes)
               Break
            EndIf
         Next
         If ConstanteExiste = #false
            MessageRequester("Erreur", "La constante " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
If OpenWindow(#Fenetre_Principale, 0, 0, 660, 428, #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Lecture des fichiers résidents PureBasic")
   If CreateGadgetList(WindowID(#Fenetre_Principale))
      Nb_Structures = 0
      LectureResident()
      ; Tri des constantes
      Dim Cst.s(CountList(Constantes()) - 1)
      ForEach Constantes()
         If Len(Constantes()\Valeur$)
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£" + Constantes()\Valeur$ + "£" + Constantes()\FichierResident$
         Else
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£$" + Hex(Constantes()\Valeur) + "£" + Constantes()\FichierResident$
         EndIf
      Next
      ; on trie; Méthode du soldat inconnu
      SortArray(Cst.s(), 2)
      
      If ListIconGadget(#ListIconConstantes, 0, 0, 440, 104, " Constante  (" + Str(CountList(Constantes())) + " références)", 220, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         AddGadgetColumn(#ListIconConstantes, 1, " Valeur", 80)
         AddGadgetColumn(#ListIconConstantes, 21, " Fichier résident", 140 - 22)
         HideGadget(#ListIconConstantes, 1)
         For i = 0 To ListIndex(Constantes()) ; Affichage  des constantes
            AddGadgetItem(#ListIconConstantes, -1, StringField(Cst.s(i), 1, "£") + Chr(10) + StringField(Cst.s(i), 2, "£") + Chr(10) + StringField(Cst.s(i), 3, "£"))
         Next
         HideGadget(#ListIconConstantes, 0)
      EndIf
      If ContainerGadget(#Container1, 0, 0, 215, 104, #PB_Container_Flat)
            StringGadget(#StringGadgetCst, 20, 20, 180, 20, "")
            ButtonGadget(#BoutonRechercherCst, 20, 45, 180, 40, "Rechercher une constante")
            StringGadget(#StringGadgetStruc, 20, 120, 180, 20, "")
            ButtonGadget(#BoutonRechercherStruc, 20, 145, 180, 40, "Rechercher une structure")
         CloseGadgetList()
      EndIf
      
      SplitterGadget(#gadSplitter, 0, 0, 660, 225, #Container1, #ListIconConstantes, #PB_Splitter_Vertical | #PB_Splitter_Separator)
      SetGadgetState(#gadSplitter, 220)
      Dim cst.s(0)
      If ListIconGadget(#ListIconStructures, 0, 225, 660, 204, " Structures   (" + Str(Nb_Structures) + " références)", 640, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         HideGadget(#ListIconStructures, 1)
         
         If ListIndex(Structures()) > 0
            ForEach Structures() ; Affichage  des structures
               AddGadgetItem(#ListIconStructures, -1, Structures()\nom$)
               A$ = A$ + Structures()\nom$ + Chr(10)
            Next
         EndIf
         HideGadget(#ListIconStructures, 0)
      EndIf
   EndIf
   
   HideWindow(#Fenetre_Principale, 0)
   Repeat
      event = WaitWindowEvent()
      Select event
         Case #PB_EventCloseWindow
            quit + 1
            
         Case #PB_eventGadget
            Select EventGadgetID()
               Case #BoutonRechercherCst
                  RechercheCst()
               Case #BoutonRechercherStruc
                     RechercheStruc()
            EndSelect
            
         Case #WM_KEYDOWN
            Select EventwParam()
               Case #PB_Shortcut_Return
                  If GetFocus_() = GadgetID(#StringGadgetCst)
                     RechercheCst()
                  ElseIf GetFocus_() = GadgetID(#StringGadgetStruc)
                     RechercheStruc()
                  EndIf
            EndSelect
            
      EndSelect
   Until quit
   
EndIf

DataSection
   Fichier_Res3 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $33, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res2 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $32, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res1 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $31, $53, $45, $52, $54, $43, $52, $53
EndDataSection ;
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Nouvelle version avec :

Les interfaces (Merci à Fred pour l'aide sur le padding en C)
Les 3 versions de résident (j'espère que tout est Ok)
En cliquant sur la colonne des valeurs des constantes, on affiche ses valeurs en décimal et si on reclique, en hexadécimal etc. (procedure hexa--> décimal d'Erix14)
Ajout de couleurs (chacun peut les modifier)
Correction d'un petit bug sur la recheche des constantes et structures.

Les structures et interfaces ne sont toujours pas triées.

Le code sur les interfaces est un peu lourd avec 2 listes chainées car c'est dérivé d'un autre code ou j'utilise ces interfaces pour un meilleur affichage.
Je ne voulais pas tout réécrire, alors c'est un peu bourrin...

Code : Tout sélectionner

; Auteur : Denis
; Version de PB : 3.93
; Librairie utilisée : Aucune
; Date : 13 janvier 2005
; Modifié le 10 mars pour le support résident version 1
; Modifié le 14 mars pour le support des constantes "flottant" 
; Modifié le 20 mars pour le support des interfaces et et des 3 versions de résidents


; Explication du code :
; Affiche le contenu des fichiers résidents PB et utilisateurs, constantes, structures et interfaces
; il reste des champs dont je n'ai pas saisi l'utilité (mais pour mon besoin ce n'est pas grave)

Enumeration
   #Fenetre_Principale
   #ListIconConstantes
   #StringGadgetCst
   #StringGadgetStruc
   #StringGadgetInterface
   #Container1
   #ListIconStructures
   #ListIconInterfaces
   #BoutonRechercherCst
   #BoutonRechercherStruc
   #BoutonRechercherInterface
   #gadSplitter
EndEnumeration

Enumeration
   #DebutInterface = 1
   #FinInterface
   #InterfaceMethode
EndEnumeration

#res1 = 1 ; format resident version 1
#res2 = 2 ; format resident version 2
#res3 = 3 ; format resident version 3
#SFLG_Interface = 1 << 2

#LVM_GETHEADER  =  $101F


; codage des éléments des structures du fichier res
; pour différencier un élément qui est un tableau d'un élément qui
; ne l'est pas, on lit le long précédant le nom de la structure (valeur collée
; au nom de l'élément). Si le long vaut -1 (=$FFFFFFFF) ce n'est pas un tableau
; on a donc 2 long pour différencier par exemple un #byte d'un #Tableau_byte
; les codes suivants correspondent au codage des éléments en fonction de leur type
; j'ai eu dans tous mes tests un valeur hexa qui revenait mais je ne suis pas arrivé
; à savoir pourquoi. Parfois j'avais $207 au lieu de $7, mais si c'est un pointeur
; j'avais de toute façon $107, je teste si la valeur appartient à l'intervalle
; $100 <--> $10A et si oui c'est un pointeur. Avec les byte, long etc je n'ai pas cette
; valeur $200 ajouté au code de base


; byte                        = $1
; word                        = $3
; long                        = $5
; Structure                   = $7
; String                      = $8
; flottant                    = $9
;
; Tableau_byte                = $1
; Tableau_word                = $3
; Tableau_long                = $5
; Tableau_Structure           = $7
; Tableau_String              = $8
; Tableau_flottant            = $9
;
; Pointeur_byte               = $101  --> 257 en déci
; Pointeur_word               = $103
; Pointeur_long               = $105
; Pointeur_Structure          = $107
; Pointeur_String             = $108
; Pointeur_flottant           = $109  --> 265 en déci
;
; Pointeur_Tableau_byte       = $101
; Pointeur_Tableau_word       = $103
; Pointeur_Tableau_long       = $105
; Pointeur_Tableau_Structure  = $107
; Pointeur_Tableau_String     = $108
; Pointeur_Tableau_flottant   = $109

Structure Constante
   Nom$
   FichierResident$
   Valeur.l
   Valeur$ ; cas des constantes de texte
EndStructure

Structure Structures
   Nom$
EndStructure

Structure InsterfacesListe
  NomInterface$ ; le nom de l'interface
  FichierOrigine$ ; le nom du fichier res ou est déclarée l'interface
  IndexInterfaceDansListe.l ; stocke l'index du champs #DebutInterface dans la liste globale
      ; pour atteindre directement l'élément
EndStructure

Structure Interface
      NomInterface$ ; le nom de l'interface
      Definition.l ; permet de définir le début de l'interface et la fin de l'interface
      TailleInterface.l ; la taille de l'interface
      Nb_Methode.l ; le nombre de méthode de l'interface
      Adresse_InfosElement.l ; adresse de la zone mémoire allouée par PB pour stocker les infos des éléménts
      NomMethode$ ; le nom de la méthode
      Nb_Args.l ; le nombre d'arguments pour chaque méthode
      ArgsMethode$ ; la chaine représentant les types d'arguments de la méthode
EndStructure

Structure PB_InterfaceMethod
   Name.l
   types.l
   NbParameters.b
   flags.b
   Pad.w
EndStructure

NewList Constantes.Constante()
NewList Structures.Structures()
NewList Interfaces.Interface()
NewList ListeInterfaces.InsterfacesListe()

Global Nb_Structures ; comptabilise le nombre total de structures de tous les fichiers
Global Nb_Interfares ; comptabilise le nombre total d'interfaces de tous les fichiers
Global ValeurF$, ValeurHexa.l
Global font
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.s CheminPureBasic()
   Buffer$ = Space(260) : BufferSize = 259
   If GetVersion_() & $FF0000 ; Windows NT/XP
      clef = #HKEY_CLASSES_ROOT
      Adresse = @"Applications\PureBasic.exe\shell\open\command"
   Else ; La même chose pour Win9x
      clef = #HKEY_LOCAL_MACHINE
      Adresse = @"Software\Classes\PureBasic.exe\shell\open\command"
   EndIf
   
   If RegOpenKeyEx_(clef, Adresse, 0, #KEY_ALL_ACCESS, @Key) = #ERROR_SUCCESS
      If RegQueryValueEx_(Key, "", 0, @type, @Buffer$, @BufferSize) = #ERROR_SUCCESS
         OutputDirectory$ = GetPathPart(Mid(Buffer$, 2, Len(Buffer$) - 7))
      EndIf
      RegCloseKey_(Key)
   EndIf
   ProcedureReturn OutputDirectory$
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.l Hex2Dec(Chaine.s)
; ; Procedure d'erix14
          Valeur.l
          MOV ecx,Chaine
          CMP byte [ecx],'$'
          JNZ NonChaineHexa
          !LEA ebx,[TableValeur]
          MOV edx,0
          XOR eax,eax
          !Encore:
                    INC ecx
                    MOV al,byte [ecx]
                    CMP al,0
                    JE FinChaineHexa
                    XLATB
                    CMP al,$FF
                    JE NonChaineHexa
                    ROL edx,4
                    ADD edx,eax
                    JMP Encore
          !FinChaineHexa:
                    MOV Valeur,edx
                    ProcedureReturn Valeur
          !NonChaineHexa:
          ProcedureReturn 0
          !TableValeur:
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$0A,$0B,$0C,$0D,$0E,$0F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
                    ! DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
EndProcedure 
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure AfficheHexaDeci()
   Protected i, elements, Hexa, text$
    elements = CountGadgetItems(#ListIconConstantes)-1
    Hexa = -1
    If elements > -1
       For z = 0 To elements
          If GetGadgetItemText(#ListIconConstantes, z, 3) = "0"
           text$ = GetGadgetItemText(#ListIconConstantes, 3, 1)
           Char.b = PeekB(@text$)
            If Char = '$'
               Hexa = #true
               Break
            Else
               Hexa = #false
            EndIf
          EndIf
       Next z
      If Hexa = #true
            For i = 0 To elements
                   If GetGadgetItemText(#ListIconConstantes, i, 3) = "0"
                           SetGadgetItemText(#ListIconConstantes, i, Str(Hex2Dec(GetGadgetItemText(#ListIconConstantes, i, 1))),1)
                   EndIf
            Next i
      ElseIf Hexa = #false
         For i = 0 To elements
            If GetGadgetItemText(#ListIconConstantes, i, 3) = "0"
               SetGadgetItemText(#ListIconConstantes, i, "$"+Hex(Val(GetGadgetItemText(#ListIconConstantes, i, 1))),1)
            EndIf
         Next i
      EndIf
    EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
   Procedure ConversionFloat2String(Nombre.l)
      !extrn  _PB_StrF@4
      !PUSH  dword [PB_StringBase]
      !PUSH  dword[esp+4]
      !CALL  _PB_StrF@4
      !LEA  ecx,[v_ValeurF$]
      !POP  edx
      !CALL  SYS_AllocateString
   EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure LectureResident()
   PbConstantFolder$ = CheminPureBasic() + "Residents\"
   If ExamineDirectory(0, PbConstantFolder$, "*.res")
      CheminDir = NextDirectoryEntry()
      While CheminDir
         If CheminDir = 1
            If ReadFile(0, PbConstantFolder$ + DirectoryEntryName())
               TailleFichier = Lof()
               *ConstantsHeader = AllocateMemory(TailleFichier)
               ; *ConstantsHeader est un pointeur sur le début du texte en mémoire
               ReadData(*ConstantsHeader, TailleFichier)
               CloseFile(0)
               *ConstantsEnd = *ConstantsHeader + TailleFichier
               *SymbolCourant = *ConstantsHeader
               ; *SymbolCourant va permettre de lire les symboles en suivant
               ; Le fichier commmence par les 16 caractères suivant, si Ok on continue
               ; 'ERUP'+0,0,0,0+'3SER'+'TCRS' ou 'ERUP'+0,0,0,0+'1SER'+'TCRS'
                  If CompareMemory(*SymbolCourant, ?Fichier_Res3, 16)
                     RES = #res3
                  ElseIf CompareMemory(*SymbolCourant, ?Fichier_Res2, 16) 
                     RES = #res2
                  ElseIf CompareMemory(*SymbolCourant, ?Fichier_Res1, 16) 
                     RES = #res1
                  Else
                     RES = 0
                  EndIf
               If RES
                  *SymbolCourant + 16
                  ; le fichier commence par des structures s'il y en a sinon par les constantes
                  Select PeekL(*SymbolCourant)
                     Case 0 ; il n'y a que des constantes, pas de structures ou interfaces
                        If PeekL(*SymbolCourant + 4) = 'CNST'
                           *SymbolCourant + 12
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$" ; je ne sais pas pourquoi on retrouve
                                 ; une copie de la chaine avec $ à la fin mais pas toujours (?)
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                    If RES <> #res1
                                       If PeekW(*SymbolCourant) = $800
                                          ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                          ; alphanumérique
                                          *SymbolCourant + 2
                                          Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                          *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                       ElseIf PeekW(*SymbolCourant) = $400  ; c'est un flottant
                                          *SymbolCourant + 2
                                          ConversionFloat2String(PeekL(*SymbolCourant))
                                          Constantes()\Valeur$ = ValeurF$
                                          *SymbolCourant + 4
                                       Else
                                          ; ici c'est une valeur et pas une chaine
                                          *SymbolCourant + 2
                                          Constantes()\Valeur = PeekL(*SymbolCourant)
                                          *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                       EndIf
                                    Else
                                       Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                       *SymbolCourant + 5
                                    EndIf
                              EndIf
                           Wend
                        Else
                           MessageRequester("Erreur1", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
                        EndIf
                        
                     Default ; on débute par les structures ou les interfaces
                        ; TotalCaracteresToutesStructures est la longueur total utilisée dans le fichier res
                        ; pour stocker toutes les infos des structures
                        TotalCaracteresToutesStructures = PeekL(*SymbolCourant)
                        *SymbolCourant + 4 ; on avance le pointeur
                        *DernierSymbol = *SymbolCourant + TotalCaracteresToutesStructures
                        ; les 4 caractères qui commences à *SymbolCourant+TotalCaracteresToutesStructures
                        ; sont TSNC  --> les constantes s'il y en a ou sinon une autre chaine
                        Repeat
                           ; le champ suivant est le nom de la structure sous forme de string classique
                           Nom_Structure$ = PeekS(*SymbolCourant)
                           *SymbolCourant + Len(Nom_Structure$) + 1 ; on avance le pointeur
                           ; le champ suivant est un long donnant la taille de la structure
                           TailleStructure = PeekL(*SymbolCourant)
                           *SymbolCourant + 4 ; on avance le pointeur
                           ; le champ suivant est un word donnant le nombre d'éléments de la structure
                           Nombre_Elements = PeekW(*SymbolCourant)
                           If RES = #res1
                              *SymbolCourant + 4 ; on avance le pointeur
                           Else
                              *SymbolCourant + 2 ; on avance le pointeur
                           EndIf
                                 ;- Debut Interfaces
                              If PeekB(*SymbolCourant) & #SFLG_Interface
                                 ; c'est une interface
                                 AddElement(Interfaces())
                                 AddElement(ListeInterfaces())
                                 Nb_Interfares+ 1
                                 *SymbolCourant + 1
                                 LongueurInfos = Nombre_Elements * (SizeOf(PB_InterfaceMethod))
                                 Interfaces()\NomInterface$ = Nom_Structure$
                                 ListeInterfaces()\NomInterface$ = "Interface  "+Nom_Structure$
                                 AddElement(ListeInterfaces())
                                 ListeInterfaces()\NomInterface$ = "  - Constituée de "+Str(Nombre_Elements)+" méthodes"
                                 AddElement(ListeInterfaces())
                                 ListeInterfaces()\NomInterface$ = "  - Déclaré dans le fichier " + DirectoryEntryName()
                                 ListeInterfaces()\FichierOrigine$ = DirectoryEntryName()
                                 ListeInterfaces()\IndexInterfaceDansListe = ListIndex(Interfaces())
                                 Interfaces()\Definition = #DebutInterface
                                 Interfaces()\TailleInterface = Taille_Structure_Interface
                                 Interfaces()\Nb_Methode = Nombre_Elements

                                 If LongueurInfos
                                    Interfaces()\Adresse_InfosElement = AllocateMemory(LongueurInfos)
                                 Else
                                    Interfaces()\Adresse_InfosElement = 0
                                 EndIf
                                 
                                 If Interfaces()\Adresse_InfosElement
                                    ; on copie les Nombre_Elements*SizeOf(PB_InterfaceMethod) octets
                                    CopyMemory(*SymbolCourant, Interfaces()\Adresse_InfosElement, LongueurInfos)
                                    ; on passe sans enregistrer, pas d'allocation mémoire
                                    Dim NbParameters.l(Nombre_Elements)
                                    For k = 0 To Nombre_Elements - 1
                                       If LongueurInfos < 0
                                          MessageRequester("Erreur", "Le nombre de méthode de l'interface  " + Interfaces()\NomInterface$ + "   " + Chr(10) + "est inférieur à 0", 16)
                                       EndIf
                                       NbParameters(k) = PeekB(*SymbolCourant + 8)
                                       *SymbolCourant + 12
                                    Next k
                                    For k = 0 To Nombre_Elements - 1
                                       AddElement(ListeInterfaces())
                                       ListeInterfaces()\NomInterface$ =  "        "+PeekS(*SymbolCourant)+"("
                                       AddElement(Interfaces())
                                       Interfaces()\NomMethode$ = PeekS(*SymbolCourant)
                                       Interfaces()\Definition = #InterfaceMethode
                                       *SymbolCourant + Len(Interfaces()\NomMethode$) + 1
                                       Arg$ = ""
                                       For l = 1 To NbParameters(k) 
                                            Arg$ + Chr(96 + l)
                                            If l <> NbParameters(k) 
                                                 Arg$ + ","
                                            EndIf
                                       Next l
                                    ListeInterfaces()\NomInterface$ + Arg$+")"
                                       If NbParameters(k) > 0
                                          Interfaces()\Nb_Args = NbParameters(k)
                                          *SymbolCourant + NbParameters(k)
                                       ElseIf NbParameters(k) < 0
                                          MessageRequester("NbParameters", "<0 !", 16)
                                       EndIf
                                    Next
                                    AddElement(Interfaces()) ; un élément indiquant simplement fin Interface
                                    Interfaces()\Definition = #FinInterface
                                    AddElement(ListeInterfaces())
                                    ListeInterfaces()\NomInterface$ =  "EndInterface"
                                    AddElement(ListeInterfaces())
                                    ListeInterfaces()\NomInterface$ =  ""
                                    AddElement(ListeInterfaces())
                                    ListeInterfaces()\NomInterface$ =  ""
                                 EndIf
                              Else ; c'est une structure
                                 ;- Debut Structures
                                 If RES <> #res1
                                    *SymbolCourant + 1
                                 EndIf
                           AddElement(Structures())
                           Nb_Structures + 1 ; on incrémente le compteur de structure
                           ; les lignes suivantes c'est pour mettre ou non un s à la fin des mots (pluriel)
                           If Nombre_Elements > 1
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Taille : " + Str(TailleStructure) + " octets"
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Constituée de " + Str(Nombre_Elements) + " éléments"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Taille : 1 octet"
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Constituée de " + Str(Nombre_Elements) + " éléments"
                              EndIf
                           Else
                              If TailleStructure > 1
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Taille : " + Str(TailleStructure) + " octets"
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Constituée d'un élément"
                              Else
                                 Structures()\Nom$ = "Structure  " + Nom_Structure$
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Taille : 1 octet"
                                 AddElement(Structures())
                                 Structures()\Nom$ = "  - Constituée d'un élément"
                              EndIf
                           EndIf
                           AddElement(Structures())
                           Structures()\Nom$ + "  - Déclaré dans le fichier " + DirectoryEntryName()
                           ; le champ suivant est un Long donnant le nombre de caractères jusqu'au 0 de fin de chaine inclus
                           ; chaine représentant le type de l'élément
                           FinStructureCourante = *SymbolCourant + PeekL(*SymbolCourant) + 4 - 1
                           Decale$ = ""
                           StructureUnion_Courante = #false ; permet d'inclure les mots StructureUnion ou EndStructureUnion
                           Offset = 0 ; Offset de l'élément courant par rapport à l'origine
                           OffsetMax = 0 ; OffsetMax va être modifié dans la boucle for suivante si pas une StructureUnion
                           ; OffsetMax mémorise l'offset max en cours, on lit pour chaque élément son offset respectif
                           ; situé dans le fichier et on compare, si offset > OffsetMax alors OffsetMax = Offset
                           ; si Offset > OffsetMax on n'est pas dans une StructureUnion, sinon c'est un élément de la StructureUnion
                           For i = 1 To Nombre_Elements
                              ; on va lire à "rebrousse poil" d'abord le type de l'élément puis son nom
                              *SymbolCourant = FinStructureCourante - 1
                              Type$ = ""
                              Char.b = PeekB(*SymbolCourant)
                              While Char
                                 Type$ = Chr(Char) + Type$
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              ; normalement ici Char vaut 0 et Type$ vaut le nom du type de l'élément
                              ; on on va lire à "rebrousse poil" le nom de l'élément et le caractère
                              ; d'arrêt est soit 255 ($FF) soit 0 donc > 0
                              ; si c'est $FF ce n'est pas un tableau ($FF = -1 sur 1 octet)
                              *SymbolCourant - 1 ; on remonte avant le 0 de fin de chaine
                              Char = PeekB(*SymbolCourant)
                              While Char > 0
                                 *SymbolCourant - 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                              *SymbolCourant + 1
                              AddElement(Structures())
                              If Char = -1 ; ce n'est pas un tableau
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion, on ne modifie pas OffsetMax
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       OffsetMax = Offset
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$
                              Else ; sinon c'est un tableau, le long précédant est <> de $FFFF
                                 ; la valeur du tableau est située à *SymbolCourant-4 juste avant le nom de l'élément
                                 ; l'offset de l'élément est situé à *SymbolCourant-12
                                 ; le codage pointeur est un long situé à *SymbolCourant-16, si = 5 pointeur
                                 Offset = PeekL(*SymbolCourant - 12) ; lecture de l'offset par rapport à l'adrese de base
                                 If RES > #res1 ; structureunion seulement si version > 1
                                    ; on comparare à la valeur précédante pour déterminer ou non la StructureUnion
                                    If Offset <= OffsetMax And i > 1 ; c'est une StructureUnion
                                       If StructureUnion_Courante = #false ; on va écrire le mot StructureUnion
                                          StructureUnion_Courante = #true
                                          Decale$ = "  "
                                          ; il faut insérer un élément avant l'élément courant
                                          If ListIndex(Structures()) - 2 >= 0 ; on teste que l'élément existe
                                             SelectElement(Structures(), ListIndex(Structures()) - 2)
                                          Else
                                             FirstElement(Structures())
                                          EndIf
                                          AddElement(Structures())
                                          Structures()\Nom$ = Decale$ + " StructureUnion"
                                          NextElement(Structures()) ; on va ajouter 3 espaces devant l'élément qui n'était pas dans la structureUnion
                                          Structures()\Nom$ = Decale$ + Structures()\Nom$
                                          LastElement(Structures())
                                          ; Else ; on est déjà dans la StructureUnion
                                       EndIf
                                    Else
                                       ; on vérifie si on est dans une StructureUnion,
                                       ; si oui on écrit "EndStructureUnion"
                                       OffsetMax = Offset
                                       If StructureUnion_Courante = #true
                                          StructureUnion_Courante = #false
                                          Structures()\Nom$ = Decale$ + " EndStructureUnion"
                                          Decale$ = ""
                                          AddElement(Structures())
                                       EndIf
                                    EndIf
                                 EndIf
                                 If RES = #res1
                                    TailleTableau = PeekW(*SymbolCourant - 2)
                                    type = PeekB(*SymbolCourant - 12)
                                 Else
                                    TailleTableau = PeekL(*SymbolCourant - 4)
                                    type = PeekW(*SymbolCourant - 16)
                                 EndIf
                                 If type >= 256 And type <= 266 ; c'est un pointeur
                                    Point$ = "*"
                                 Else
                                    Point$ = ""
                                 EndIf
                                 Structures()\Nom$ = Decale$ + "   " + Point$ + PeekS(*SymbolCourant) + "." + Type$ + "[" + Str(TailleTableau) + "]"
                              EndIf
                              If i < Nombre_Elements
                                 FinStructureCourante + PeekL(FinStructureCourante + 1) + 4
                              EndIf
                           Next i
                           AddElement(Structures())
                           If StructureUnion_Courante = #true
                              Structures()\Nom$ = Decale$ + " EndStructureUnion"
                              Decale$ = ""
                              AddElement(Structures())
                           EndIf
                           Structures()\Nom$ = "EndStructure"
                           AddElement(Structures())
                           AddElement(Structures())
                           *SymbolCourant = FinStructureCourante + 1
                        EndIf
                        Until *SymbolCourant >= *DernierSymbol
                        ; ici on en a fini avec les structures, on regarde s'il y a des constantes
                        ; en arrivant ici, les 4 premiers octets de la chaine que l'on va lire doivent
                        ; valoir TSNC, on teste
                        *SymbolCourant = *DernierSymbol ; on positionne le pointeur
                        If PeekL(*SymbolCourant) = 'CNST'
                           ; il peut y avoir plus de deux 0, donc on supprime tous les 0
                           If RES = #res1
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 3
                           Else
                              *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Char.b = PeekB(*SymbolCourant)
                              While Char = 0
                                 *SymbolCourant + 1
                                 Char = PeekB(*SymbolCourant)
                              Wend
                           EndIf
                           While *SymbolCourant < * ConstantsEnd
                              If Len(PeekS(*SymbolCourant)) = 0
                                 ; on sort s'il n'y a plus de chaines à traiter
                                 Break
                              EndIf
                              If Right(PeekS(*SymbolCourant), 1) = "$"
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                                 *SymbolCourant + Len(PeekS(*SymbolCourant)) + 1
                              Else
                                 AddElement(Constantes())
                                 Constantes()\nom$ = PeekS(*SymbolCourant) ; lecture nom constante
                                 Constantes()\FichierResident$ = DirectoryEntryName()
                                 *SymbolCourant + Len(Constantes()\nom$) ; déplacement du pointeur
                                    If RES <> #res1
                                       If PeekW(*SymbolCourant) = $800
                                          ; ici le word qui suit est égal à 800 au lieu de 0, c'est une valeur
                                          ; alphanumérique
                                          *SymbolCourant + 2
                                          Constantes()\Valeur$ = PeekS(*SymbolCourant)
                                          *SymbolCourant + Len(Constantes()\Valeur$) + 1
                                       ElseIf PeekW(*SymbolCourant) = $400  ; c'est un flottant
                                          *SymbolCourant + 2
                                          ConversionFloat2String(PeekL(*SymbolCourant))
                                          Constantes()\Valeur$ = ValeurF$
                                          *SymbolCourant + 4
                                       Else
                                          ; ici c'est une valeur et pas une chaine
                                          *SymbolCourant + 2
                                          Constantes()\Valeur = PeekL(*SymbolCourant)
                                          *SymbolCourant + 4 ; on arrive sur la nouvelle chaine
                                       EndIf
                                    Else
                                       Constantes()\Valeur = PeekL(*SymbolCourant + 1)
                                       *SymbolCourant + 5
                                    EndIf
                              EndIf
                           Wend
                        EndIf
                  EndSelect
               Else
                  MessageRequester("Erreur", "Le fichier " + DirectoryEntryName() + " n'est pas au format resident PureBasic", 16)
               EndIf
               FreeMemory(*ConstantsHeader)
            EndIf
         EndIf
         CheminDir = NextDirectoryEntry()
      Wend
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.l SetListPos(Gadget.l, Position.l)
  Protected Pos.POINT
  SendMessage_(GadgetID(Gadget), #LVM_GETITEMPOSITION, Position - 1, Pos)
  SendMessage_(GadgetID(Gadget), #LVM_SCROLL, 0, Pos\y)
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure  RechercheStruc()
Protected a$, i
   a$ = GetGadgetText(#StringGadgetStruc)
   If Len(a$)
      compt = CountGadgetItems(#ListIconStructures)
      If compt > 0
         compt - 1
         StructureExiste = #false
         For i = 0 To compt
            If UCase("Structure  "+a$) = Left(UCase(GetGadgetItemText(#ListIconStructures, i, 0)), Len("Structure  "+a$))
               SetListPos(#ListIconStructures, -1)
               SetListPos(#ListIconStructures, i)
               StructureExiste = #true
               SetGadgetItemState(#ListIconStructures, i, #PB_ListIcon_Selected)
               ActivateGadget(#ListIconStructures)
               Break
            EndIf
         Next
         If StructureExiste = #false
            MessageRequester("Erreur", "La structure " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure  RechercheInterface()
Protected a$, i
   a$ = GetGadgetText(#StringGadgetInterface)
   If Len(a$)
      compt = CountGadgetItems(#ListIconInterfaces)
      If compt > 0
         compt - 1
         StructureExiste = #false
         For i = 0 To compt
            If UCase("Interface  "+a$) = Left(UCase(GetGadgetItemText(#ListIconInterfaces, i, 0)), Len("Interface  "+a$))
               SetListPos(#ListIconInterfaces, -1)
               SetListPos(#ListIconInterfaces, i)
               StructureExiste = #true
               SetGadgetItemState(#ListIconInterfaces, i, #PB_ListIcon_Selected)
               ActivateGadget(#ListIconInterfaces)
               Break
            EndIf
         Next
         If StructureExiste = #false
            MessageRequester("Erreur", "L'interface " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure RechercheCst()
Protected a$, i
   a$ = UCase(GetGadgetText(#StringGadgetCst))
   If Len(a$)
      compt = CountGadgetItems(#ListIconConstantes)
      If compt > 0
         compt - 1
         ConstanteExiste = #false
         For i = 0 To compt
            If a$ = UCase(GetGadgetItemText(#ListIconConstantes, i, 0))
               SetListPos(#ListIconConstantes, -1)
               SetListPos(#ListIconConstantes, i)
               SetGadgetItemState(#ListIconConstantes, i, #PB_ListIcon_Selected)
               ConstanteExiste = #true
               ActivateGadget(#ListIconConstantes)
               Break
            EndIf
         Next
         If ConstanteExiste = #false
            MessageRequester("Erreur", "La constante " + a$ + " n'existe pas", 16)
         EndIf
      EndIf
   Else
      Beep_(1000, 50)
   EndIf
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure Mycallback(WindowID, message, wParam, lParam)
   Resultat = #PB_ProcessPureBasicEvents
   If message = #WM_NOTIFY
      *lpnmia.NMLISTVIEW = lParam
      Select *lpnmia\hdr\Code
         Case #LVN_COLUMNCLICK
               If *lpnmia\hdr\hwndFrom = GadgetID(#ListIconConstantes) And *lpnmia\iSubItem = 1
                    AfficheHexaDeci()
               EndIf
         Case #HDN_BEGINTRACKW 
               HeaderHwnd = SendMessage_(GadgetID(#ListIconConstantes),#LVM_GETHEADER,0,0)
               If *lpnmia\hdr\hwndFrom = HeaderHwnd And *lpnmia\iItem = 3
                  Resultat = #True
               EndIf

         Case #HDN_BEGINTRACK
               HeaderHwnd = SendMessage_(GadgetID(#ListIconConstantes),#LVM_GETHEADER,0,0)
               If *lpnmia\hdr\hwndFrom = HeaderHwnd And *lpnmia\iItem = 3
                  Resultat = #True
               EndIf
      EndSelect
   EndIf
   ProcedureReturn Resultat 
EndProcedure 
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
Procedure.l Boutoncouleur(TextBouton$)
   ImageBouton = CreateImage(#PB_Any, 180, 30)
   If ImageBouton And StartDrawing(ImageOutput())
       Box(0, 0, 180, 30, $840AA9)
       DrawingFont(UseFont(Font))
       FrontColor(Red(#white), Green(#white), Blue(#white))
       DrawingMode(1)
       Locate((180-TextLength(TextBouton$))/2, 7)
       DrawText(TextBouton$)
       StopDrawing()
   EndIf
 ProcedureReturn ImageBouton 
EndProcedure
;/ /\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
If OpenWindow(#Fenetre_Principale, 0, 0, 660, 428, #PB_Window_MinimizeGadget | #PB_Window_Invisible | #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Lecture des fichiers résidents PureBasic")
   If CreateGadgetList(WindowID(#Fenetre_Principale))
      Nb_Structures = 0
      LectureResident()
      ; Tri des constantes
      Dim Cst.s(CountList(Constantes()) - 1)
      ForEach Constantes()
         If Len(Constantes()\Valeur$)
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£" + Constantes()\Valeur$ + "£" + Constantes()\FichierResident$+ "£"+"1"
         Else
            Cst.s(ListIndex(Constantes())) = Right(Constantes()\Nom$, Len(Constantes()\Nom$)) + "£$" + Hex(Constantes()\Valeur) + "£" + Constantes()\FichierResident$+ "£"+"0"
         EndIf
      Next
      ; on trie; Méthode du soldat inconnu
      SortArray(Cst.s(), 2)
      
      If ListIconGadget(#ListIconConstantes, 0, 0, 440, 104, " Constante  (" + Str(CountList(Constantes())) + " références)", 220, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         AddGadgetColumn(#ListIconConstantes, 1, " Valeur", 80)
         AddGadgetColumn(#ListIconConstantes, 2, " Fichier résident", 140 - 28)
         AddGadgetColumn(#ListIconConstantes, 3, "", 0)
         HideGadget(#ListIconConstantes, 1)
         For i = 0 To ListIndex(Constantes()) ; Affichage  des constantes
            AddGadgetItem(#ListIconConstantes, -1, StringField(Cst.s(i), 1, "£") + Chr(10) + StringField(Cst.s(i), 2, "£") + Chr(10) + StringField(Cst.s(i), 3, "£")+ Chr(10) + StringField(Cst.s(i), 4, "£"))
         Next
         HideGadget(#ListIconConstantes, 0)
      EndIf
      SendMessage_(GadgetID(#ListIconConstantes), #LVM_SETBKCOLOR, 0, $F2D9E8)
      SendMessage_(GadgetID(#ListIconConstantes), #LVM_SETTEXTBKCOLOR, 0, $F2D9E8)
      Font = LoadFont(#Pb_any,"Times New Roman", 9, #PB_Font_HighQuality)
      
      If ContainerGadget(#Container1, 0, 0, 215, 104, #PB_Container_Flat)
            StringGadget(#StringGadgetCst, 20, 13, 180, 20, "")
            ButtonImageGadget(#BoutonRechercherCst, 20, 38, 180, 30, UseImage(Boutoncouleur("Rechercher une Structure")))
            StringGadget(#StringGadgetStruc, 20, 85, 180, 20, "")
            ButtonImageGadget(#BoutonRechercherStruc, 20, 110, 180, 30, UseImage(Boutoncouleur("Rechercher une structure")))
            StringGadget(#StringGadgetInterface, 20, 85+80-10, 180, 20, "")
            ButtonImageGadget(#BoutonRechercherInterface, 20, 110+80-10, 180, 30, UseImage(Boutoncouleur("Rechercher une interface")))
         CloseGadgetList()
      EndIf
      
      SplitterGadget(#gadSplitter, 0, 0, 660, 225, #Container1, #ListIconConstantes, #PB_Splitter_Vertical | #PB_Splitter_Separator)
      SetGadgetState(#gadSplitter, 220)
      Dim cst.s(0)
      If ListIconGadget(#ListIconStructures, 0, 225, WindowWidth()/2, WindowHeight()/2-10, " Structures   (" + Str(Nb_Structures) + " références)", WindowWidth()/2-22, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         HideGadget(#ListIconStructures, 1)
         SendMessage_(GadgetID(#ListIconStructures), #LVM_SETBKCOLOR, 0, $E3E5D9)
         SendMessage_(GadgetID(#ListIconStructures), #LVM_SETTEXTBKCOLOR, 0, $E3E5D9)
         If ListIndex(Structures()) > 0
            ForEach Structures() ; Affichage  des structures
               AddGadgetItem(#ListIconStructures, -1, Structures()\nom$)
            Next
         EndIf
         HideGadget(#ListIconStructures, 0)
      EndIf
      If ListIconGadget(#ListIconInterfaces, WindowWidth()/2+1, 225, WindowWidth()/2, WindowHeight()/2-10, " Interfaces   (" + Str(Nb_Interfares) + " références)", WindowWidth()/2-22, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection)
         HideGadget(#ListIconInterfaces, 1)
         SendMessage_(GadgetID(#ListIconInterfaces), #LVM_SETBKCOLOR, 0, $CBE2CD)
         SendMessage_(GadgetID(#ListIconInterfaces), #LVM_SETTEXTBKCOLOR, 0, $CBE2CD)
         If ListIndex(ListeInterfaces()) > 0
            ForEach ListeInterfaces() ; Affichage  des interfaces
               SelectElement(Interfaces(), ListeInterfaces()\IndexInterfaceDansListe)
               AddGadgetItem(#ListIconInterfaces, -1, ListeInterfaces()\NomInterface$)
            Next
         EndIf
         HideGadget(#ListIconInterfaces, 0)
      EndIf
   EndIf
   
   HideWindow(#Fenetre_Principale, 0)
   SetWindowCallback(@Mycallback())
   Repeat
      event = WaitWindowEvent()
      Select event
         Case #PB_EventCloseWindow
            quit + 1
            
         Case #PB_eventGadget
            Select EventGadgetID()
               Case #BoutonRechercherCst
                  RechercheCst()
               Case #BoutonRechercherStruc
                     RechercheStruc()
               Case #BoutonRechercherInterface
                     RechercheInterface()
            EndSelect
            
         Case #WM_KEYDOWN
            Select EventwParam()
               Case #PB_Shortcut_Return
                  If GetFocus_() = GadgetID(#StringGadgetCst)
                     RechercheCst()
                  ElseIf GetFocus_() = GadgetID(#StringGadgetStruc)
                     RechercheStruc()
                  ElseIf GetFocus_() = GadgetID(#StringGadgetInterface)
                     RechercheInterface()
                  EndIf
            EndSelect
            
      EndSelect
   Until quit
   
EndIf

DataSection
   Fichier_Res3 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $33, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res2 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $32, $53, $45, $52, $54, $43, $52, $53
   Fichier_Res1 :
      Data .b $45, $52, $55, $50, $00, $00, $00, $00, $31, $53, $45, $52, $54, $43, $52, $53
EndDataSection
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

c de + en + joli et fonctionnel :wink:
Image
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

:D
Dorian
Messages : 489
Inscription : mar. 15/mars/2005 15:33

Message par Dorian »

Bonjour, je ne pense pas que je suis dans le bon sujet pour demander ça, mais pouvez-vous m'expliquer ce que sont ces fichiers résidants s'il vous plait.

Merci

PS: Je suis tout nouveau dans le monde du PureBasic et je trouve que c'est un langage très intéressant par rapport à ces capacités et sa facilité de développement.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

les fichiers resident servent à déclarer des constances et des structures.

ensuite elles sont directement applicable dans le code sans avoir besion de les déclarer de nouveau.
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)]
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Message par Kwai chang caine »

ça avait l'air super comme outil ça, bravo denis

Moi non plus j'ai pas tout compris (comme dab) mais comme j'ai un bleme de doublon de constantes entre 2 .res ton super programme pourrait peut etre m'aider.

Quelqu'un peut il le convertir en v4.0, parce que j'ai essayé avec PbConverter et ça plante.

Ligne 134 "clef = #HKEY_CLASSES_ROOT "
il ne connait pas la constante. :?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Ne cherche pas à convertir en version 4, les nouveaux résidents ne seraient pas pris en compte. J'ai un code qui marche pour la version 4.00 mais il fait partie de mes outils perso et je n'ai pas fait un code pour le forum.
Répondre