
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

bernard13 a écrit :je vois pas l'interet de faire ça
Merci Régis, je vas regarder les flottants.Le Soldat Inconnu a écrit :Bon, j'ai essayé, c'est pas mal![]()
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
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 ;}
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 ;
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