[TUTO] Annuaire téléphonique avec sa base de donnée

Informations pour bien débuter en PureBasic
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

[TUTO] Annuaire téléphonique avec sa base de donnée

Message par Guimauve »

Je viens de passer 3h00 environ à faire un exemple sur comment faire un annuaire téléphonique qui créer et utilise sa propre base de données pour les contacts. La seule chose qui manque pour le moment c'est la fenètre d'édition/Modification d'un contact. Je donne quand même le code pour que vous puissiez commencer à l'étudier. Je ferai les derniers ajustement ce soir ou demain. Le source est tout de même assez long et sur plusieurs fichiers. Copier les dans le même répertoire et faite attention aux noms des sources.

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Read Write Binary String.pbi

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
LoopLong.pbi

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Address Book - Contants.pb

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Address Book - Hook.pb

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) <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Address Book - Contact.pb

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Address Book - Address Book.pb

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 <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<<
Dernière modification par Guimauve le mar. 16/mars/2010 23:54, modifié 2 fois.
Francis13
Messages : 18
Inscription : dim. 21/févr./2010 7:29
Localisation : Marseille

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Francis13 »

Bonjour Guimauve
J'ai voulu testé ton programme pour étudier PB et la base de données
mais il ne se compile pas.
ReadBinaryString()) n'est pas pris en compte ligne 131
:?: Je vais étudier le sql pour essayer de trouver une solution
A+
Geo Trouvpatou
Messages : 471
Inscription : dim. 23/déc./2007 18:10

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Geo Trouvpatou »

Salut.

Sinon tu peux aller là : Gestion bibliothèques avec sqlite par Comtois
Ou ici : Gérer ses contacts via SQLite en PureBasic par Progi1984

L'avantage d'utiliser SQLite c'est la portabilité. Tu distribues ton soft avec sa Bdd.

Bye.
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Guimauve »

Francis13 a écrit :Bonjour Guimauve
J'ai voulu testé ton programme pour étudier PB et la base de données
mais il ne se compile pas.
ReadBinaryString()) n'est pas pris en compte ligne 131
:?: Je vais étudier le sql pour essayer de trouver une solution
A+
Je ne suis pas chez moi en ce moment mais durant la soirée je vais mettre une version fonctionnelle de mon programme. Pour l'instant voici les procédures manquantes :

Code : Tout sélectionner

Procedure WriteBinaryString(String$)
  
  WriteLong(Len(String$)) 
  WriteData(String$, Len(String$)) 
  
EndProcedure 

Procedure.s ReadBinaryString()
  
  Length = ReadLong()
  String$ = Space(Length)
  ReadData(String$, Length) 
  
  ProcedureReturn String$
EndProcedure 
À faire attention, mon programme utilise un fichier binaire pour enregistrer les données et non une base de donnée de type standard (SQL ou autre).

A+
Guimauve
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Guimauve »

@ Francis13

Oublie la version présente dans le premier message, ce code ne fonctionnera pas dans la version actuelle de PureBasic Je vais procéder à une mise à jour complète d'ici peu.

A+
Guimauve
Francis13
Messages : 18
Inscription : dim. 21/févr./2010 7:29
Localisation : Marseille

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Francis13 »

Bonjour guimauve
J'ai essayé de faire tourner le programme mais il y a trop
de problèmes de mise à jour avec la version 441.
Un tel programme ,bien que simple en apparence,
demande beaucoup de temps et permet d'étudier
le PureBasic.
Je te remercie
A+
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par cederavic »

Salut,
C'est un tres bon code, bien structurer etc du bon boulot!
Mais ça ne ressemble pas du tout à un tuto... :? Il faudrait développer un peut plus les explications en dehors du code je pense :)
Bon courage
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Guimauve »

J'ai presque terminé la mise à jour. Je vais également prendre le temps d'ajouter des commentaires explicatifs sur les parties complexe du code.

A+
Guimauve
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Backup »

Guimauve a écrit :J'ai presque terminé la mise à jour. Je vais également prendre le temps d'ajouter des commentaires explicatifs sur les parties complexe du code.

A+
Guimauve
je pourrai alors le mettre dans l'index :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Backup »

Comme je viens de te l'expliquer en message privé
je ne considère pas encore ton code comme etant un Tuto ... :)

il manque l'essentiel , le dialogue du prof , qui s'adresse aux programmeur lambda
et qui explique le cheminement , et éventuellement le pourquoi

il ne s'agit pas de poster un code qui marche , mais aussi de faire en sorte que les gens qui te lise le comprenne :)

je t'invite a lire les autres Tuto , pour comprendre ce dont je parle :)
Francis13
Messages : 18
Inscription : dim. 21/févr./2010 7:29
Localisation : Marseille

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Francis13 »

bonsoir Guimauve
C'est super.
Je suis également agréablement surpris par la taille réduite de l'exe (40 ko.
Encore merci pour ce joli programme. :D
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Re: [TUTO] Annuaire téléphonique avec sa base de donnée

Message par Guimauve »

Bonjour Francis13,

Oui effectivement, PureBasic produit des exe de petite taille. Dans le cas du code que j'ai écrit plus haut, je n'ai pas utilisé les listes chainées standard pour deux raisons.

Primo, l'utilisation des listes chainées standard fait grossir l'exécutable.
Deusio, il est impossible de créer une liste chainée standard dans une structure comme ceci :

Code : Tout sélectionner

Structure AddressBook
  
  ContactFileID.l 
  ContactFileName.s 
  ContactID.l 
  NewList ContactList.Contact()
  Language.s[#ADDRESSBOOK_LANGUAGE_MAX] 
  
EndStructure 
C'est pour cette raison que la structure ressemble plutôt à ceci :

Code : Tout sélectionner

Structure AddressBook
   
  ContactFileID.l 
  ContactFileName.s 
  ContactID.l 
  ContactList.Hook ; Contact 
  Language.s[#ADDRESSBOOK_LANGUAGE_MAX]
  
EndStructure 
La structure "Hook" (Crochet si on traduit en français) est l'entête d'une liste chainée. Je me suis inspiré d'un code écrit en C++ pour le fonctionnement. Il est certains que l'utilisation d'une liste chainée de ce type est moins performant que les listes standards. Mais c'est le prix à payer quand on écrit le code a ma façon. Et je dois dire que ma méthode de faire est assez rigide et ne convient pas à tout le monde. Le style ressemble à celui qui était utilisé en C avant l'avènement du C++ et la Programmation Orienté Objet (POO). On parle ici d'un style de Programmation Basé Objet (PBO) qui à mon sens est bien plus claire et bien plus facile à lire.

Un autre point qui me semble important à mentionner, c'est que dans mes codes l'utilisation des variables Globales est proscrit. Mise à part les variables de contrôle ou de gestion des boucles il n'y a aucune variables déclarées à la volé dans le code.

Un dernier point, j'utilise un logiciel de ma conception pour générer une grande partie du code. C'est pour cette raison que l'on retrouve ces commentaires dans certains codes sources :

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é en : 00.007 secondes (17142.86 lignes/seconde) <<<<< 
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Malheureusement, ce programme n'est pas disponible au publique pour le moment. (Pour la version Windows, je ne suis pas sûr qu'il y en aura une, pour la version Linux pas avant que le problème du WebGadget() ne soit résolut. C'est-à-dire pas avant PB 4.50 au moins)

A+
Guimauve
Répondre