ATTENTION, IL Y A DES PROCÉDURES INUTILES ELLES SERONT SUPPRIMÉES DANS LA VERSION FINALE !!!
EDIT
Je viens de terminer le programme, c'est pas très beau comme interface. Mais pour un exemple c'est plus que très bien. Le programme est fonctionnel. Il est fort possible que le Compilateur signle que les Procédures WriteBinaryString() et ReadBinaryString() sont inconnues. Il suffit de décommenté la section de ces deux commandes. Dans le fichier Structure Annuaire.pb
Amusez-vous bien !!
Modification du 16-03-2010
Voilà, je viens de terminer la mise à jour pour le code soit compatible avec la version 4.41 de PureBasic. Le code est divisé en plusieurs fichiers, il faut prendre le temps de tous les enregistrer dans le même répertoire.
A+
Guimauve
Address Book - Main.pb
Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Carnet d'adresse simple
; Nom du fichier : Address Book - Main.pb
; Version du fichier : 1.0.0
; Programmation : En cours
; Programmé par : Guimauve
; Date : 11-03-2010
; Mise à jour : 11-03-2010
; Code PureBasic : 4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
IncludeFile "Read Write Binary String.pbi"
IncludeFile "LoopLong.pbi"
IncludeFile "Address Book - Constants.pb"
IncludeFile "Address Book - Hook.pb"
IncludeFile "Address Book - Contact.pb"
IncludeFile "Address Book - Address Book.pb"
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Initialisation des paramètres par défaut <<<<<
InitializeAddressBook(AddressBook.AddressBook)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Ouverture de la fenètre principale <<<<<
OpenAddressBookWindow(AddressBook)
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Gestion des évènements <<<<<
AddressBookEventManager(AddressBook)
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Read & Write Binary String
; Fichier : Read Write Binary String.pbi
; Version : 2.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 24-03-2006
; Mise à jour : 12-11-2008
; Codé avec PureBasic V4.41
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Notes : Read/Write Binary String
;
; Afin de rendre les chaines de caractères 
; illisibles, la constante #BINARY_STRING_OFFSET
; à été ajoutée. La valeur de cette constante est
; additionnée ou soustraite de à la valeur du code
; ASCII. Ceci rend la chaine impossible à lire 
; facilement, avec Bloc-Note par exemple. Mais 
; attention, cette méthode de faire est très facile
; à déchiffrer. Si un minimum de sécurité est 
; requis utilisez plutôt la librairie Read/Write 
; Encoded String.
;
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
#BINARY_STRING_OFFSET = 999999
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< WriteBinaryString <<<<<
    
Procedure WriteBinaryString(FileID.l, String.s)
  
  MaxChar.l = Len(String)
  WriteLong(FileID, MaxChar)
  
  For Index = 0 To MaxChar - 1
    WriteLong(FileID, #BINARY_STRING_OFFSET + Asc(Mid(String, Index + 1, 1)))
  Next
  
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< ReadBinaryString <<<<<
Procedure.s ReadBinaryString(FileID.l)
  
  MaxChar.l = ReadLong(FileID)
  
  For Index = 0 To MaxChar - 1
    String.s = String + Chr(ReadLong(FileID) - #BINARY_STRING_OFFSET)
  Next
  
  ProcedureReturn String
EndProcedure
    
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : LoopLong Includefile
; Nom du fichier : LoopLong.pbi
; Version du fichier : 1.0.1
; Programmation : OK
; Programmé par : Guimauve
; Date : 26-10-2003
; Mise à jour : 23-01-2010
; Code PureBasic : V4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Procedure.l LoopLong(Nombre.l, Minimum.l, Maximum.l, Increment.l)
   
   Nombre + Increment
   
   If Nombre > Maximum
      
      Nombre = Minimum
      
   ElseIf Nombre < Minimum
      
      Nombre = Maximum
      
   EndIf
   
   ProcedureReturn Nombre
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Nom du projet : Carnet d'adresse simple
; Nom du fichier : Address Book - Contants.pb
; Version du fichier : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 11-03-2010
; Mise à jour : 11-03-2010
; Code PureBasic : 4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Enumeration
  #MainWin
  #EditWin
  
  #ComboBox_ContactName
 
  #Btn_Previous
  #Btn_Next
  #Btn_Modify
  #Btn_New
	
  #Frame_ContactInfo
  #Frame_ContactComments
	
  #Text_FirstName
  #Text_LastName
  #Text_Town
  #Text_Number
  #Text_Street
  #Text_ZipPostalCode
  #Text_Email
  #Text_PhoneNumber01
  #Text_PhoneNumber02
  
  #String_FirstName
  #String_LastName
  #String_Town
  #String_Number
  #String_Street
  #String_ZipPostalCode
  #String_Email
  #String_PhoneNumber01
  #String_PhoneNumber02
  #Edit_ContactComments
  #Text_Edit_FirstName
  #Text_Edit_LastName
  #Text_Edit_Town
  #Text_Edit_Number
  #Text_Edit_Street
  #Text_Edit_ZipPostalCode
  #Text_Edit_Email
  #Text_Edit_PhoneNumber01
  #Text_Edit_PhoneNumber02
 
  #String_Edit_FirstName
  #String_Edit_LastName
  #String_Edit_Town
  #String_Edit_Number
  #String_Edit_Street
  #String_Edit_ZipPostalCode
  #String_Edit_Email
  #String_Edit_PhoneNumber01
  #String_Edit_PhoneNumber02
  
  #Edit_Edit_ContactComments
  #Btn_Edit_OK
  #Btn_Edit_CANCEL
	
EndEnumeration 
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; CODE GÉNÉRÉ AUTOMATIQUEMENT, NE PAS MODIFIER À
; MOINS D'AVOIR UNE RAISON TRÈS TRÈS VALABLE !!!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code généré par : Dev-Type V2.0.0
; Nom du projet : Carnet d'adresse simple
; Nom du fichier : Address Book - Hook.pb
; Version du fichier : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 15-03-2010
; Mise à jour : 15-03-2010
; Codé pour PureBasic V4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure <<<<<
Structure Hook
  Counter.l
  CurrentPtr.i
  RootPtr.i
  TailPtr.i
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs <<<<<
Macro GetHookCounter(HookA)
  HookA\Counter
EndMacro
Macro GetHookCurrentPtr(HookA)
  HookA\CurrentPtr
EndMacro
Macro GetHookRootPtr(HookA)
  HookA\RootPtr
EndMacro
Macro GetHookTailPtr(HookA)
  HookA\TailPtr
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs <<<<<
Macro SetHookCounter(HookA, P_Counter)
  GetHookCounter(HookA) = P_Counter
EndMacro
Macro SetHookCurrentPtr(HookA, P_CurrentPtr)
  GetHookCurrentPtr(HookA) = P_CurrentPtr
EndMacro
Macro SetHookRootPtr(HookA, P_RootPtr)
  GetHookRootPtr(HookA) = P_RootPtr
EndMacro
Macro SetHookTailPtr(HookA, P_TailPtr)
  GetHookTailPtr(HookA) = P_TailPtr
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Reset <<<<<
Macro ResetHook(HookA)
  SetHookCounter(HookA, 0)
  SetHookCurrentPtr(HookA, 0)
  SetHookRootPtr(HookA, 0)
  SetHookTailPtr(HookA, 0)
  ; ClearStructure(HookA, Hook)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Copy : A = Source : B = Destination <<<<<
Macro CopyHook(HookA, HookB)
  SetHookCounter(HookB, GetHookCounter(HookA))
  SetHookCurrentPtr(HookB, GetHookCurrentPtr(HookA))
  SetHookRootPtr(HookB, GetHookRootPtr(HookA))
  SetHookTailPtr(HookB, GetHookTailPtr(HookA))
  ; CopyMemory(HookA, HookB, SizeOf(Hook))
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Swap <<<<<
Macro SwapHook(HookA, HookB)
  Swap GetHookCounter(HookA), GetHookCounter(HookB)
  Swap GetHookCurrentPtr(HookA), GetHookCurrentPtr(HookB)
  Swap GetHookRootPtr(HookA), GetHookRootPtr(HookB)
  Swap GetHookTailPtr(HookA), GetHookTailPtr(HookB)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.007 secondes (17714.29 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; CODE GÉNÉRÉ AUTOMATIQUEMENT, NE PAS MODIFIER À
; MOINS D'AVOIR UNE RAISON TRÈS TRÈS VALABLE !!!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code généré par : Dev-Type V2.0.0
; Nom du projet : Carnet d'adresse simple
; Nom du fichier : Address Book - Contact.pb
; Version du fichier : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 15-03-2010
; Mise à jour : 15-03-2010
; Codé pour PureBasic V4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Enumeration 
  #CONTACT_TRANSFER_NORMAL
  #CONTACT_TRANSFER_NEW
  #CONTACT_TRANSFER_EDIT
EndEnumeration 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure <<<<<
Structure Contact
  FirstName.s
  LastName.s
  Town.s
  Number.s
  Street.s
  ZipPostalCode.s
  Email.s
  PhoneNumber01.s
  PhoneNumber02.s
  Comments.s
  PreviousPtr.i
  NextPtr.i
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs <<<<<
Macro GetContactFirstName(ContactA)
  ContactA\FirstName
EndMacro
Macro GetContactLastName(ContactA)
  ContactA\LastName
EndMacro
Macro GetContactTown(ContactA)
  ContactA\Town
EndMacro
Macro GetContactNumber(ContactA)
  ContactA\Number
EndMacro
Macro GetContactStreet(ContactA)
  ContactA\Street
EndMacro
Macro GetContactZipPostalCode(ContactA)
  ContactA\ZipPostalCode
EndMacro
Macro GetContactEmail(ContactA)
  ContactA\Email
EndMacro
Macro GetContactPhoneNumber01(ContactA)
  ContactA\PhoneNumber01
EndMacro
Macro GetContactPhoneNumber02(ContactA)
  ContactA\PhoneNumber02
EndMacro
Macro GetContactComments(ContactA)
  ContactA\Comments
EndMacro
Macro GetContactPreviousPtr(ContactA)
  ContactA\PreviousPtr
EndMacro
Macro GetContactNextPtr(ContactA)
  ContactA\NextPtr
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs <<<<<
Macro SetContactFirstName(ContactA, P_FirstName)
  GetContactFirstName(ContactA) = P_FirstName
EndMacro
Macro SetContactLastName(ContactA, P_LastName)
  GetContactLastName(ContactA) = P_LastName
EndMacro
Macro SetContactTown(ContactA, P_Town)
  GetContactTown(ContactA) = P_Town
EndMacro
Macro SetContactNumber(ContactA, P_Number)
  GetContactNumber(ContactA) = P_Number
EndMacro
Macro SetContactStreet(ContactA, P_Street)
  GetContactStreet(ContactA) = P_Street
EndMacro
Macro SetContactZipPostalCode(ContactA, P_ZipPostalCode)
  GetContactZipPostalCode(ContactA) = P_ZipPostalCode
EndMacro
Macro SetContactEmail(ContactA, P_Email)
  GetContactEmail(ContactA) = P_Email
EndMacro
Macro SetContactPhoneNumber01(ContactA, P_PhoneNumber01)
  GetContactPhoneNumber01(ContactA) = P_PhoneNumber01
EndMacro
Macro SetContactPhoneNumber02(ContactA, P_PhoneNumber02)
  GetContactPhoneNumber02(ContactA) = P_PhoneNumber02
EndMacro
Macro SetContactComments(ContactA, P_Comments)
  GetContactComments(ContactA) = P_Comments
EndMacro
Macro SetContactPreviousPtr(ContactA, P_PreviousPtr)
  GetContactPreviousPtr(ContactA) = P_PreviousPtr
EndMacro
Macro SetContactNextPtr(ContactA, P_NextPtr)
  GetContactNextPtr(ContactA) = P_NextPtr
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Reset <<<<<
Macro ResetContact(ContactA)
  SetContactFirstName(ContactA, "")
  SetContactLastName(ContactA, "")
  SetContactTown(ContactA, "")
  SetContactNumber(ContactA, "")
  SetContactStreet(ContactA, "")
  SetContactZipPostalCode(ContactA, "")
  SetContactEmail(ContactA, "")
  SetContactPhoneNumber01(ContactA, "")
  SetContactPhoneNumber02(ContactA, "")
  SetContactComments(ContactA, "")
  SetContactPreviousPtr(ContactA, 0)
  SetContactNextPtr(ContactA, 0)
  ; ClearStructure(ContactA, Contact)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Copy : A = Source : B = Destination <<<<<
Macro CopyContact(ContactA, ContactB)
  SetContactFirstName(ContactB, GetContactFirstName(ContactA))
  SetContactLastName(ContactB, GetContactLastName(ContactA))
  SetContactTown(ContactB, GetContactTown(ContactA))
  SetContactNumber(ContactB, GetContactNumber(ContactA))
  SetContactStreet(ContactB, GetContactStreet(ContactA))
  SetContactZipPostalCode(ContactB, GetContactZipPostalCode(ContactA))
  SetContactEmail(ContactB, GetContactEmail(ContactA))
  SetContactPhoneNumber01(ContactB, GetContactPhoneNumber01(ContactA))
  SetContactPhoneNumber02(ContactB, GetContactPhoneNumber02(ContactA))
  SetContactComments(ContactB, GetContactComments(ContactA))
  ; CopyMemory(ContactA, ContactB, SizeOf(Contact))
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Swap <<<<<
Macro SwapContact(ContactA, ContactB)
  Swap GetContactFirstName(ContactA), GetContactFirstName(ContactB)
  Swap GetContactLastName(ContactA), GetContactLastName(ContactB)
  Swap GetContactTown(ContactA), GetContactTown(ContactB)
  Swap GetContactNumber(ContactA), GetContactNumber(ContactB)
  Swap GetContactStreet(ContactA), GetContactStreet(ContactB)
  Swap GetContactZipPostalCode(ContactA), GetContactZipPostalCode(ContactB)
  Swap GetContactEmail(ContactA), GetContactEmail(ContactB)
  Swap GetContactPhoneNumber01(ContactA), GetContactPhoneNumber01(ContactB)
  Swap GetContactPhoneNumber02(ContactA), GetContactPhoneNumber02(ContactB)
  Swap GetContactComments(ContactA), GetContactComments(ContactB)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Le Constructeur <<<<<
Procedure.i CreateNewContact()
  *NewContact.Contact = AllocateMemory(SizeOf(Contact))
  If *NewContact = #Null
    MessageRequester("Fatal Error", "CreateNewContact() - Impossible to Allocate Memory !")
    End
  EndIf
  ProcedureReturn *NewContact
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Ajout d'un Maillon à la chaîne <<<<<
Procedure.i AddLinkToChainOfContact(*HookA.Hook)
  *NewContact.Contact = CreateNewContact()
  If GetHookRootPtr(*HookA) = #Null
    SetHookRootPtr(*HookA, *NewContact)
    SetContactPreviousPtr(*NewContact, #Null)
  Else
    *Tail.Contact = GetHookTailPtr(*HookA)
    SetContactNextPtr(*Tail, *NewContact)
    SetContactPreviousPtr(*NewContact, *Tail)
  EndIf
  SetHookTailPtr(*HookA, *NewContact)
  SetHookCurrentPtr(*HookA, *NewContact)
  SetHookCounter(*HookA, GetHookCounter(*HookA) + 1)
  ProcedureReturn *NewContact
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Private - Destruction récursive de la chaîne <<<<<
Procedure PrivateDestroyChainOfContact(*ContactA.Contact)
  *NextContact.Contact = GetContactNextPtr(*ContactA)
  ResetContact(*ContactA)
  FreeMemory(*ContactA)
  If *NextContact <> #Null
    PrivateDestroyChainOfContact(*NextContact)
  EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Destruction de la chaîne <<<<<
Procedure DestroyChainOfContact(*HookA.Hook)
  *RootContact.Contact = GetHookRootPtr(*HookA)
  If *RootContact <> #Null
    PrivateDestroyChainOfContact(*RootContact)
    ResetHook(*HookA)
  EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Suppression d'un Maillon dans la chaîne <<<<<
Procedure DestroyLinkInChainOfContact(*HookA.Hook)
  If GetHookCurrentPtr(*HookA) = GetHookRootPtr(*HookA)
    *RootContact.Contact = GetHookRootPtr(*HookA)
    *NextContact.Contact = GetContactNextPtr(*RootContact)
    SetHookRootPtr(*HookA, *NextContact)
    SetHookCurrentPtr(*HookA, *NextContact)
    SetContactPreviousPtr(*NextContact, #Null)
    ResetContact(*RootContact)
    FreeMemory(*RootContact)
  ElseIf GetHookCurrentPtr(*HookA) = GetHookTailPtr(*HookA)
    *TailContact.Contact = GetHookTailPtr(*HookA)
    *NewTailContact.Contact = GetContactPreviousPtr(*TailContact)
    SetHookTailPtr(*HookA, *NewTailContact)
    SetHookCurrentPtr(*HookA, *NewTailContact)
    SetContactNextPtr(*NewTailContact, #Null)
    ResetContact(*TailContact)
    FreeMemory(*TailContact)
  Else
    *Before.Contact = GetHookRootPtr(*HookA)
    *Following.Contact = GetContactNextPtr(*Before)
    *After.Contact = GetContactNextPtr(*Following)
    While *Following <> #Null
      If *Following = GetHookCurrentPtr(*HookA)
        SetContactNextPtr(*Before, GetContactNextPtr(*Following))
        SetHookCurrentPtr(*HookA, *Before)
        SetContactPreviousPtr(*After, *Before)
        If *Following = GetHookTailPtr(*HookA)
          SetHookTailPtr(*HookA, *Before)
        EndIf
        ResetContact(*Following)
        FreeMemory(*Following)
        *Following = #Null
      EndIf
      *Before = GetContactNextPtr(*Before)
      If *Before <> #Null
        *Following = GetContactNextPtr(*Before)
      If *Following <> #Null
        *After = GetContactNextPtr(*Following)
      EndIf
      Else
        *Following = #Null
      EndIf
    Wend
  EndIf
  SetHookCounter(*HookA, GetHookCounter(*HookA) - 1)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Sélection d'un Maillon dans la chaîne <<<<<
Procedure.i SelectLinkInChainOfContact(*HookA.Hook, Index.l = 1)
  *SelectedContact.Contact = #Null
  If Index <= GetHookCounter(*HookA) And Index >= 1
    *ContactA.Contact = GetHookRootPtr(*HookA)
    Counter = 1
    While *ContactA <> #Null
      If Counter = Index
        SetHookCurrentPtr(*HookA, *ContactA)
        *SelectedContact = *ContactA
        *ContactA = #Null
      Else
        *ContactA = GetContactNextPtr(*ContactA)
        Counter + 1
      EndIf
    Wend
  EndIf
  ProcedureReturn *SelectedContact
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Maillon précédent dans la chaîne <<<<<
Procedure.i PreviousLinkInChainOfContact(*HookA.Hook, Looping.b = #False)
  If GetHookCurrentPtr(*HookA) <> #Null
    *ContactA.Contact = GetHookCurrentPtr(*HookA)
    *ContactB.Contact = GetContactPreviousPtr(*ContactA)
    If Looping = #True
      If *ContactB <> #Null
        SetHookCurrentPtr(*HookA, *ContactB)
      Else
        SetHookCurrentPtr(*HookA, GetHookTailPtr(*HookA))
      EndIf
    Else
      SetHookCurrentPtr(*HookA, *ContactB)
    EndIf
  EndIf
  ProcedureReturn GetHookCurrentPtr(*HookA)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Maillon suivant dans la chaîne <<<<<
Procedure.i NextLinkInChainOfContact(*HookA.Hook, Looping.b = #False)
  If GetHookCurrentPtr(*HookA) <> #Null
    *ContactA.Contact = GetHookCurrentPtr(*HookA)
    *ContactB.Contact = GetContactNextPtr(*ContactA)
    If Looping = #True
      If *ContactB <> #Null
        SetHookCurrentPtr(*HookA, *ContactB)
      Else
        SetHookCurrentPtr(*HookA, GetHookRootPtr(*HookA))
      EndIf
    Else
      SetHookCurrentPtr(*HookA, *ContactB)
    EndIf
  EndIf
  ProcedureReturn GetHookCurrentPtr(*HookA)
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Création d'un fichier binaire <<<<<
Procedure CreateChainOfContactBinaryFile(FileID.l, FileName.s, *HookA.Hook)
  If CreateFile(FileID, FileName)
    WriteLong(FileID, GetHookCounter(*HookA))
    *ContactA.Contact = GetHookRootPtr(*HookA)
    While *ContactA <> #Null
      WriteBinaryString(FileID, GetContactFirstName(*ContactA))
      WriteBinaryString(FileID, GetContactLastName(*ContactA))
      WriteBinaryString(FileID, GetContactTown(*ContactA))
      WriteBinaryString(FileID, GetContactNumber(*ContactA))
      WriteBinaryString(FileID, GetContactStreet(*ContactA))
      WriteBinaryString(FileID, GetContactZipPostalCode(*ContactA))
      WriteBinaryString(FileID, GetContactEmail(*ContactA))
      WriteBinaryString(FileID, GetContactPhoneNumber01(*ContactA))
      WriteBinaryString(FileID, GetContactPhoneNumber02(*ContactA))
      WriteBinaryString(FileID, GetContactComments(*ContactA))
      *ContactA = GetContactNextPtr(*ContactA)
    Wend
    CloseFile(FileID)
  EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Lecture d'un fichier binaire <<<<<
Procedure ReadChainOfContactBinaryFile(FileID.l, FileName.s, *HookA.Hook)
  If ReadFile(FileID, FileName)
    LinkMax.l = ReadLong(FileID)
    For LinkIndex = 0 To LinkMax - 1
      *ContactA.Contact = AddLinkToChainOfContact(*HookA)
      SetContactFirstName(*ContactA, ReadBinaryString(FileID))
      SetContactLastName(*ContactA, ReadBinaryString(FileID))
      SetContactTown(*ContactA, ReadBinaryString(FileID))
      SetContactNumber(*ContactA, ReadBinaryString(FileID))
      SetContactStreet(*ContactA, ReadBinaryString(FileID))
      SetContactZipPostalCode(*ContactA, ReadBinaryString(FileID))
      SetContactEmail(*ContactA, ReadBinaryString(FileID))
      SetContactPhoneNumber01(*ContactA, ReadBinaryString(FileID))
      SetContactPhoneNumber02(*ContactA, ReadBinaryString(FileID))
      SetContactComments(*ContactA, ReadBinaryString(FileID))
    Next
    CloseFile(FileID)
  EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Tri des Maillons Ascendant <<<<<
Procedure SortChainOfContactByFirstNameAscendant(*HookA.Hook, CaseSensitive.b = #False)
  If GetHookCounter(*HookA) >= 2
    SortSwapped.b = #True
    If CaseSensitive = #True
      While SortSwapped = #True
        *ContactA.Contact = GetHookRootPtr(*HookA)
        *ContactB.Contact = GetContactNextPtr(*ContactA)
        SortSwapped = #False
        While *ContactA <> #Null
          If UCase(GetContactFirstName(*ContactA)) > UCase(GetContactFirstName(*ContactB))
            SwapContact(*ContactA, *ContactB)
            SortSwapped = #True
          EndIf
          *ContactA = GetContactNextPtr(*ContactA)
          *ContactB = GetContactNextPtr(*ContactA)
          If *ContactB = #Null
            Break
          EndIf
        Wend
      Wend
    Else
      While SortSwapped = #True
        *ContactA.Contact = GetHookRootPtr(*HookA)
        *ContactB.Contact = GetContactNextPtr(*ContactA)
        SortSwapped = #False
        While *ContactA <> #Null
          If GetContactFirstName(*ContactA) > GetContactFirstName(*ContactB)
            SwapContact(*ContactA, *ContactB)
            SortSwapped = #True
          EndIf
          *ContactA = GetContactNextPtr(*ContactA)
          *ContactB = GetContactNextPtr(*ContactA)
          If *ContactB = #Null
            Break
          EndIf
        Wend
      Wend
    EndIf
  EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.028 secondes (44642.86 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Macro de déboguage <<<<<
Macro DebugContact(ContactA)
  Debug GetContactFirstName(ContactA)
  Debug GetContactLastName(ContactA)
  Debug GetContactTown(ContactA)
  Debug GetContactNumber(ContactA)
  Debug GetContactStreet(ContactA)
  Debug GetContactZipPostalCode(ContactA)
  Debug GetContactEmail(ContactA)
  Debug GetContactPhoneNumber01(ContactA)
  Debug GetContactPhoneNumber02(ContactA)
  Debug GetContactComments(ContactA)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Macro de formatage <<<<<
Macro FormatContactName(ContactA)
  GetContactFirstName(ContactA) + " " + GetContactLastName(ContactA)
  
EndMacro 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Initialize <<<<<
Procedure InitializeContact(*HookA.Hook)
  *ContactA.Contact = AddLinkToChainOfContact(*HookA)
  
  SetContactFirstName(*ContactA, "Road")
  SetContactLastName(*ContactA, "Runner")
  SetContactTown(*ContactA, "Texas")
  SetContactNumber(*ContactA, "3115")
  SetContactStreet(*ContactA, "55 th Highway")
  SetContactZipPostalCode(*ContactA, "J3W 1P9")
  SetContactEmail(*ContactA, "roadrunner@superfast.com")
  SetContactPhoneNumber01(*ContactA, "123-456-7890")
  SetContactPhoneNumber02(*ContactA, "321-654-0987")
  SetContactComments(*ContactA, "Personnage de dessin animé. Il court très très vite.")
  
  *ContactA = AddLinkToChainOfContact(*HookA)
  
  SetContactFirstName(*ContactA, "Will")
  SetContactLastName(*ContactA, "Coyote")
  SetContactTown(*ContactA, "Texas")
  SetContactNumber(*ContactA, "3225")
  SetContactStreet(*ContactA, "55 th hightway")
  SetContactZipPostalCode(*ContactA, "J4W 2F1")
  SetContactEmail(*ContactA, "willcoyote@superfast.com")
  SetContactPhoneNumber01(*ContactA, "514-569-3387")
  SetContactPhoneNumber02(*ContactA, "415-965-7833")
  SetContactComments(*ContactA, "Personnage de dessin animé. Il tente d'attaper Road Runner !")
EndProcedure
Procedure ChainOfContact_Name_To_GUI(*HookA.Hook, GadgetID.l)
  *ContactA.Contact = GetHookRootPtr(*HookA)
  While *ContactA <> #Null
    AddGadgetItem(GadgetID, Index, FormatContactName(*ContactA))
    *ContactA = GetContactNextPtr(*ContactA)
    Index + 1
  Wend
    
EndProcedure 
Procedure Contact_To_GUI(*HookA.Hook, Mode.b = #CONTACT_TRANSFER_NORMAL)
  *ContactA.Contact = GetHookCurrentPtr(*HookA)
  If *ContactA <> #Null
  
    Select Mode 
    
      Case #CONTACT_TRANSFER_NORMAL
      
        SetGadgetText(#String_FirstName, GetContactFirstName(*ContactA))
        SetGadgetText(#String_LastName, GetContactLastName(*ContactA))
        SetGadgetText(#String_Town, GetContactTown(*ContactA))
        SetGadgetText(#String_Number, GetContactNumber(*ContactA))
        SetGadgetText(#String_Street, GetContactStreet(*ContactA))
        SetGadgetText(#String_ZipPostalCode, GetContactZipPostalCode(*ContactA))
        SetGadgetText(#String_Email, GetContactEmail(*ContactA))
        SetGadgetText(#String_PhoneNumber01, GetContactPhoneNumber01(*ContactA))
        SetGadgetText(#String_PhoneNumber02, GetContactPhoneNumber02(*ContactA))
        SetGadgetText(#Edit_ContactComments, GetContactComments(*ContactA))
    
      Case #CONTACT_TRANSFER_EDIT
    
        SetGadgetText(#String_Edit_FirstName, GetContactFirstName(*ContactA))
        SetGadgetText(#String_Edit_LastName, GetContactLastName(*ContactA))
        SetGadgetText(#String_Edit_Town, GetContactTown(*ContactA))
        SetGadgetText(#String_Edit_Number, GetContactNumber(*ContactA))
        SetGadgetText(#String_Edit_Street, GetContactStreet(*ContactA))
        SetGadgetText(#String_Edit_ZipPostalCode, GetContactZipPostalCode(*ContactA))
        SetGadgetText(#String_Edit_Email, GetContactEmail(*ContactA))
        SetGadgetText(#String_Edit_PhoneNumber01, GetContactPhoneNumber01(*ContactA))
        SetGadgetText(#String_Edit_PhoneNumber02, GetContactPhoneNumber02(*ContactA))
        SetGadgetText(#Edit_Edit_ContactComments, GetContactComments(*ContactA))
    
      Case #CONTACT_TRANSFER_NEW
        SetGadgetText(#String_Edit_FirstName, "")
        SetGadgetText(#String_Edit_LastName, "")
        SetGadgetText(#String_Edit_Town, "")
        SetGadgetText(#String_Edit_Number, "")
        SetGadgetText(#String_Edit_Street, "")
        SetGadgetText(#String_Edit_ZipPostalCode, "")
        SetGadgetText(#String_Edit_Email, "")
        SetGadgetText(#String_Edit_PhoneNumber01, "")
        SetGadgetText(#String_Edit_PhoneNumber02, "")
        SetGadgetText(#Edit_Edit_ContactComments, "")
            
    EndSelect 
  
  EndIf 
  
EndProcedure 
Procedure GUI_To_Contact(*HookA.Hook)
  *ContactA.Contact = GetHookCurrentPtr(*HookA)
  If *ContactA <> #Null
    SetContactFirstName(*ContactA, GetGadgetText(#String_Edit_FirstName))
    SetContactLastName(*ContactA, GetGadgetText(#String_Edit_LastName))
    SetContactTown(*ContactA, GetGadgetText(#String_Edit_Town))
    SetContactNumber(*ContactA, GetGadgetText(#String_Edit_Number))
    SetContactStreet(*ContactA, GetGadgetText(#String_Edit_Street))
    SetContactZipPostalCode(*ContactA, GetGadgetText(#String_Edit_ZipPostalCode))
    SetContactEmail(*ContactA, GetGadgetText(#String_Edit_Email))
    SetContactPhoneNumber01(*ContactA, GetGadgetText(#String_Edit_PhoneNumber01))
    SetContactPhoneNumber02(*ContactA, GetGadgetText(#String_Edit_PhoneNumber02))
    SetContactComments(*ContactA, GetGadgetText(#Edit_Edit_ContactComments))
    
  EndIf 
  
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<Code : Tout sélectionner
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; CODE GÉNÉRÉ AUTOMATIQUEMENT, NE PAS MODIFIER À
; MOINS D'AVOIR UNE RAISON TRÈS TRÈS VALABLE !!!
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Code généré par : Dev-Type V2.0.0
; Nom du projet : Carnet d'adresse simple
; Nom du fichier : Address Book - Address Book.pb
; Version du fichier : 1.0.0
; Programmation : OK
; Programmé par : Guimauve
; Date : 15-03-2010
; Mise à jour : 15-03-2010
; Codé pour PureBasic V4.40
; Plateforme : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Constantes de dimensionnement <<<<<
#ADDRESSBOOK_LANGUAGE_MAX = 18
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Déclaration de la Structure <<<<<
Structure AddressBook
  ContactFileID.l
  ContactFileName.s
  ContactID.l
  ContactList.Hook ; Contact
  Language.s[#ADDRESSBOOK_LANGUAGE_MAX]
EndStructure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les observateurs <<<<<
Macro GetAddressBookContactFileID(AddressBookA)
  AddressBookA\ContactFileID
EndMacro
Macro GetAddressBookContactFileName(AddressBookA)
  AddressBookA\ContactFileName
EndMacro
Macro GetAddressBookContactID(AddressBookA)
  AddressBookA\ContactID
EndMacro
Macro GetAddressBookContactList(AddressBookA)
  AddressBookA\ContactList
EndMacro
Macro GetAddressBookLanguage(AddressBookA, Index)
  AddressBookA\Language[Index]
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Les mutateurs <<<<<
Macro SetAddressBookContactFileID(AddressBookA, P_ContactFileID)
  GetAddressBookContactFileID(AddressBookA) = P_ContactFileID
EndMacro
Macro SetAddressBookContactFileName(AddressBookA, P_ContactFileName)
  GetAddressBookContactFileName(AddressBookA) = P_ContactFileName
EndMacro
Macro SetAddressBookContactID(AddressBookA, P_ContactID)
  GetAddressBookContactID(AddressBookA) = P_ContactID
EndMacro
Macro SetAddressBookContactList(AddressBookA, P_ContactList)
  CopyHook(P_ContactList, GetAddressBookContactList(AddressBookA))
EndMacro
Macro SetAddressBookLanguage(AddressBookA, Index, P_Language)
  GetAddressBookLanguage(AddressBookA, Index) = P_Language
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Reset <<<<<
Macro ResetAddressBook(AddressBookA)
  SetAddressBookContactFileID(AddressBookA, 0)
  SetAddressBookContactFileName(AddressBookA, "")
  SetAddressBookContactID(AddressBookA, 0)
  DestroyChainOfContact(GetAddressBookContactList(AddressBookA))
  For Index = 0 To #ADDRESSBOOK_LANGUAGE_MAX - 1
    SetAddressBookLanguage(AddressBookA, Index, "")
  Next
  ; ClearStructure(AddressBookA, AddressBook)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Code généré en : 00.007 secondes (17142.86 lignes/seconde) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Triage par ordre alphabétique des contacts par prénom <<<<<
Macro SortAddressBookContactList(AddressBookA)
  SortChainOfContactByFirstNameAscendant(GetAddressBookContactList(AddressBookA))
EndMacro 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Enregistrement de la base de donnée <<<<<
Macro SaveAddressBookContactList(AddressBookA)
  CreateChainOfContactBinaryFile(GetAddressBookContactFileID(AddressBookA), GetAddressBookContactFileName(AddressBookA), GetAddressBookContactList(AddressBookA))
EndMacro 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Chargement de la base de donnée <<<<<
Macro LoadAddressBookContactList(AddressBookA)
  ReadChainOfContactBinaryFile(GetAddressBookContactFileID(AddressBookA), GetAddressBookContactFileName(AddressBookA), GetAddressBookContactList(AddressBookA))
  
EndMacro 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Initialisation de la combobox de sélection des contacts <<<<<
Macro AddressBookContactListName_To_GUI(AddressBookA)
  ClearGadgetItems(#ComboBox_ContactName)
  ChainOfContact_Name_To_GUI(GetAddressBookContactList(AddressBookA), #ComboBox_ContactName)
EndMacro
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Défilement des contacts avec l'aide des boutons précédent/suivant <<<<<
Procedure ScrollAddressBookContact(*AddressBookA.AddressBook, Scroll.b)
  If Scroll = -1
  
    PreviousLinkInChainOfContact(GetAddressBookContactList(*AddressBookA), #True)
    SetAddressBookContactID(*AddressBookA, LoopLong(GetAddressBookContactID(*AddressBookA), 0, GetHookCounter(GetAddressBookContactList(*AddressBookA))-1, Scroll))
    SetGadgetState(#ComboBox_ContactName, GetAddressBookContactID(*AddressBookA))
    Contact_To_GUI(GetAddressBookContactList(*AddressBookA))
    
  ElseIf Scroll = 0
  
    SetAddressBookContactID(*AddressBookA, 0)
    SelectLinkInChainOfContact(GetAddressBookContactList(*AddressBookA))
    SetGadgetState(#ComboBox_ContactName, GetAddressBookContactID(*AddressBookA))
    Contact_To_GUI(GetAddressBookContactList(*AddressBookA))
    
  ElseIf Scroll = 1 
  
    NextLinkInChainOfContact(GetAddressBookContactList(*AddressBookA), #True)
    SetAddressBookContactID(*AddressBookA, LoopLong(GetAddressBookContactID(*AddressBookA), 0, GetHookCounter(GetAddressBookContactList(*AddressBookA))-1, Scroll))
    SetGadgetState(#ComboBox_ContactName, GetAddressBookContactID(*AddressBookA))
    Contact_To_GUI(GetAddressBookContactList(*AddressBookA))
    
  EndIf 
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Sélection d'un contact depuis la combobox <<<<<
Procedure SelectAddressBookContact(*AddressBookA.AddressBook)
  SelectLinkInChainOfContact(GetAddressBookContactList(*AddressBookA), GetGadgetState(#ComboBox_ContactName) + 1)
  Contact_To_GUI(GetAddressBookContactList(*AddressBookA))
  SetAddressBookContactID(*AddressBookA, GetGadgetState(#ComboBox_ContactName))
  
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Traitement de la saisie depuis la fenètre d'édition <<<<<
Procedure EditAddressBookContact(*AddressBookA.AddressBook, Mode.b)
	If Mode = #CONTACT_TRANSFER_NEW
    AddLinkToChainOfContact(GetAddressBookContactList(*AddressBookA))
	EndIf 
  
  GUI_To_Contact(GetAddressBookContactList(*AddressBookA))
  SortAddressBookContactList(*AddressBookA)
  AddressBookContactListName_To_GUI(*AddressBookA)
  ScrollAddressBookContact(*AddressBookA, 0)
  
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< L'opérateur Initialize <<<<<
Procedure InitializeAddressBook(*AddressBookA.AddressBook)
  SetAddressBookContactFileID(*AddressBookA, 0)
  SetAddressBookContactFileName(*AddressBookA, "ContactList.dat")
  SetAddressBookContactID(*AddressBookA, 0)
  If FileSize(GetAddressBookContactFileName(*AddressBookA)) = -1
  
    InitializeContact(GetAddressBookContactList(*AddressBookA))
    SaveAddressBookContactList(*AddressBookA)
    
  Else 
  
    LoadAddressBookContactList(*AddressBookA)
    SortAddressBookContactList(*AddressBookA)
    
  EndIf 
  SetAddressBookLanguage(*AddressBookA, 00, "Carnet d'adresse")
  SetAddressBookLanguage(*AddressBookA, 01, "Précédent")
  SetAddressBookLanguage(*AddressBookA, 02, "Suivant")
  SetAddressBookLanguage(*AddressBookA, 03, "Éditer")
  SetAddressBookLanguage(*AddressBookA, 04, "Nouveau")
  SetAddressBookLanguage(*AddressBookA, 05, "Information à propos du contact")
  SetAddressBookLanguage(*AddressBookA, 06, "Commentaire à propos du contact")
  SetAddressBookLanguage(*AddressBookA, 07, "Prénom :")
  SetAddressBookLanguage(*AddressBookA, 08, "Nom :")
  SetAddressBookLanguage(*AddressBookA, 09, "Ville :")
  SetAddressBookLanguage(*AddressBookA, 10, "No. Civique :")
  SetAddressBookLanguage(*AddressBookA, 11, "Nom de la rue :")
  SetAddressBookLanguage(*AddressBookA, 12, "Code postal :")
  SetAddressBookLanguage(*AddressBookA, 13, "Courriel :")
  SetAddressBookLanguage(*AddressBookA, 14, "Téléphone maison :")
  SetAddressBookLanguage(*AddressBookA, 15, "Téléphone travail :")
  SetAddressBookLanguage(*AddressBookA, 16, "OK")
  SetAddressBookLanguage(*AddressBookA, 17, "Annuler")
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Routine de fermeture du programme <<<<<
Procedure AddressBookShutdown(*AddressBookA.AddressBook)
  SortAddressBookContactList(*AddressBookA)
  SaveAddressBookContactList(*AddressBookA)
  ResetAddressBook(*AddressBookA)
  
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Routine de génération des gadgets <<<<<
Procedure ButtonGadgetGroup(FirstButtonID.l, LastButtonID.l, X.l, Y.l, Width.l, Height.l, Gap_Between_Gadget.l)
	
	For GadgetID = FirstButtonID To LastButtonID
		ButtonGadget(GadgetID, X, Y, Width, Height, "")
		X + Width + Gap_Between_Gadget
	Next
	
EndProcedure
Procedure TextGadgetGroup(FirstTextID.l, LastTextID.l, X.l, Y.l, Width.l, Height.l, Gap_Between_Gadget.l)
	
	For GadgetID = FirstTextID To LastTextID
		TextGadget(GadgetID, X, Y, Width, Height, "",#PB_Text_Center)
		Y + Height + Gap_Between_Gadget
	Next
	
EndProcedure
Procedure StringGadgetGroup(FirstStringID.l, LastStringID.l, X.l, Y.l, Width.l, Height.l, Gap_Between_Gadget.l)
	
	For GadgetID = FirstStringID To LastStringID
		StringGadget(GadgetID, X, Y, Width, Height, "",#PB_String_ReadOnly)
		Y + Height + Gap_Between_Gadget
	Next
	
EndProcedure
Procedure StringGadgetGroupSTD(FirstStringID.l, LastStringID.l, X.l, Y.l, Width.l, Height.l, Gap_Between_Gadget.l)
	
	For GadgetID = FirstStringID To LastStringID
		StringGadget(GadgetID, X, Y, Width, Height, "")
		Y + Height + Gap_Between_Gadget
	Next
	
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Fenètre d'édition des contacts <<<<<
Procedure OpenAddressBookEditContactWindow(*AddressBookA.AddressBook, Mode.b)
	
	Select Mode
	
	  Case #CONTACT_TRANSFER_EDIT
	    TitleIndex = 3
	    
	  Case #CONTACT_TRANSFER_NEW
	    TitleIndex = 4
	
	EndSelect 
	
	HideWindow(#MainWin,1)
	
	If OpenWindow(#EditWin, 0, 0, 500, 480, GetAddressBookLanguage(*AddressBookA, 00) + " - " + GetAddressBookLanguage(*AddressBookA, TitleIndex), #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
		
		TextGadgetGroup(#Text_Edit_FirstName, #Text_Edit_PhoneNumber02, 5, 5, 125, 20, 5)
		StringGadgetGroupSTD(#String_Edit_FirstName, #String_Edit_PhoneNumber02, 140, 5, 350, 20, 5)
		EditorGadget(#Edit_Edit_ContactComments,5,GadgetY(#String_Edit_PhoneNumber02)+30,490,200)
		
		ButtonGadgetGroup(#Btn_Edit_OK, #Btn_Edit_CANCEL, 275, 445, 100, 25, 5)
		SetGadgetText(#Btn_Edit_OK, GetAddressBookLanguage(*AddressBookA, 16))
		SetGadgetText(#Btn_Edit_CANCEL, GetAddressBookLanguage(*AddressBookA, 17))
    Contact_To_GUI(GetAddressBookContactList(*AddressBookA), Mode)
    
    Language_Index = 7
	
  	For GadgetID = #Text_Edit_FirstName To #Text_Edit_PhoneNumber02
  		SetGadgetText(GadgetID, GetAddressBookLanguage(*AddressBookA, Language_Index))
  		Language_Index + 1
  	Next 
	EndIf
	
	Repeat
		
		EventID = WaitWindowEvent()
		
    Select EventID
    
      Case #PB_Event_Gadget
      
        Select EventGadget() ; La gestion des évenements                   
        
          Case #Btn_EDIT_OK
            EditAddressBookContact(*AddressBookA, Mode)
            EventID = #PB_Event_CloseWindow
          
          Case #Btn_EDIT_CANCEL
            EventID = #PB_Event_CloseWindow
        
        EndSelect
      
    EndSelect
		
	Until EventID = #PB_Event_CloseWindow
	
	HideWindow(#MainWin, 0)
	CloseWindow(#EditWin)
	
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Ouverture de la fenètre principale <<<<<
Procedure OpenAddressBookWindow(*AddressBookA.AddressBook)
  If OpenWindow(#MainWin, 50,50, 600, 480, GetAddressBookLanguage(*AddressBookA, 00), #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  
    ComboBoxGadget(#ComboBox_ContactName,5,5,280,25)
    ButtonGadgetGroup(#Btn_Previous, #Btn_New, 295, 5, 70, 25, 5)
    
    Frame3DGadget(#Frame_ContactInfo,5,35,590,250,"")
		TextGadgetGroup(#Text_FirstName,#Text_PhoneNumber02, 10, 55, 125, 20, 5)
		StringGadgetGroup(#String_FirstName, #String_PhoneNumber02, 140, 55, 440, 20, 5)
		
		Frame3DGadget(#Frame_ContactComments,5,290,590,185,"")
		EditorGadget(#Edit_ContactComments,10,310,580,160, #PB_Editor_ReadOnly)
   
    AddressBookContactListName_To_GUI(*AddressBookA)
    SetGadgetState(#ComboBox_ContactName, 0)
    
    Language_Index = 1
    
  	For GadgetID = #Btn_Previous To #Text_PhoneNumber02
  		SetGadgetText(GadgetID, GetAddressBookLanguage(*AddressBookA, Language_Index))
  		Language_Index + 1
  	Next 
	
	  ScrollAddressBookContact(*AddressBookA, 0)
	
  EndIf 
  
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Gestion des évènements <<<<<
Procedure AddressBookEventManager(*AddressBookA.AddressBook)
  Repeat
  	
  	EventID = WaitWindowEvent()
  	
  	Select EventID
  		
  		; Case #PB_EventMenu ; Il n'y a pas de menu déroulant pour le moment
  		; Select EventMenuID()
  		; EndSelect
  		
  		Case #PB_Event_Gadget
  			Select EventGadget()
  				
  				Case #ComboBox_ContactName
  					SelectAddressBookContact(*AddressBookA)
  					
  				Case #Btn_Previous
  					ScrollAddressBookContact(*AddressBookA, -1)
  					
  				Case #Btn_Next
  					ScrollAddressBookContact(*AddressBookA, 1)
  					
  				Case #Btn_New
  					OpenAddressBookEditContactWindow(*AddressBookA, #CONTACT_TRANSFER_NEW)
  				Case #Btn_Modify
  					OpenAddressBookEditContactWindow(*AddressBookA, #CONTACT_TRANSFER_EDIT)
  					
  			EndSelect
  		
  	EndSelect
  	
  Until EventID = #PB_Event_CloseWindow
  AddressBookShutdown(*AddressBookA)
EndProcedure 
; <<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< FIN DU FICHIER <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<