V : Gestions système

Windows fournit bien sur des fonctions pour gérer le système (mémoire, fichiers....). Pour simplifier leur utilisation, le builder les encapsule dans des classes VCL.

 

  • V-1 : Gestion de la mémoire
  • Pour tous les composants que vous posez sur votre fiche, le builder gère les allocations et désallocations mémoire. Si par contre vous avez besoin dans votre programme d’un espace mémoire, il faut le demander au système.

    La mémoire est a tout le monde, et dans un système multi-tâche toutes les applications en ont besoin. Il incombe au système de contrôler qu’une application n’écrit pas dans une zone mémoire qui ne lui appartient pas. Pour cela, le système (dit protégé) peut fermer une application qui ne se plie pas à cette règle.

    En DOS, on a parfois l’habitude d’utiliser les pointeurs (qui pointent directement sur la mémoire) un peu comme on veut. Sous Windows, c’est impossible car trop dangereux pour le système.

    Au lieu de cela, le système utilise des identificateurs pour pointer sur des blocs mémoire. (type HANDLE) Le programme lui-même ignore dans quel emplacement exact se situe son bloc mémoire.

     

    Windows distingue deux types : la mémoire globale et locale.

    La mémoire globale se situe dans un espace partagé par tous les programmes, et vous pouvez demander un bloc aussi gros que la mémoire disponible. Cette mémoire se demande par la fonction GlobalAlloc :

    HANDLE hMem ;

    hMem=GlobalAlloc(65536,...) ; // demande 64 kO de mémoire

    Si le système peut les allouer, hMem n’est pas nul et identifie le bloc mémoire. Sinon, hMem vaut NULL.

    Pour ce servir de ce bloc, certaines fonctions demandent un pointeur. Il faut donc verrouiller le bloc, demander à Windows de le fixer en mémoire. Windows renvoie un pointeur permettant de se servir du bloc. Il faut le déverrouiller ensuite pour permettre à Windows de déplacer le bloc si le besoin s’en fait sentir.

    On verrouille par la méthode GlobalLock, l’opération inverse se fait par GlobalUnlock.

    void far *ptr ;

    ptr=GlobalLock(hMem) ;

    // on peut se servir du pointeur

    GlobalUnlock(hMem) ;

    // maintenant on ne peut plus, le pointeur n’est plus valide. hMem l’est toujours.

    Une fois qu’on a fini de se servir de la mémoire, il faut la libérer :

    GlobalFree(hMem) ;

    La mémoire Locale est plus petite, réservée au programme dans son espace mémoire particulier. Elle ne peut dépasser 64 kO. (segment de données)

    Les fonctions sont similaires, mais commencent par Local au lieu de Global.

    Un bloc mémoire est appelé un SEGMENT mémoire. Contrairement à la programmation DOS, un segment mémoire Windows (global) peut avoir une taille comprise entre 4 kO et 4 GO.

    Chaque segment alloué appartient au programme et ne peut être modifié que par lui (puisqu’en dehors du système, il est le seul à connaître le HANDLE du segment mémoire).

    Pour augmenter la taille mémoire, Windows utilise le disque comme mémoire VIRTUELLE. Plus importante que la mémoire vive physique, elle est par contre beaucoup plus lente.

    C’est pour cela que Windows ne place en mémoire virtuelle que les segments de mémoires les moins utilisés.

    Les propriétés d’un segment mémoire (définies à l’allocation) sont les suivantes :

    Un segment peut être relogeable (MOVEABLE), c’est à dire que Windows peut le déplacer pour regrouper (défragmenter) la mémoire physique.

    Un segment peut être jetable (DISCARDABLE), c’est à dire que Windows peut utiliser l’espace mémoire si besoin est. Bien sur, il vous informe qu’il a effacé votre segment !

     

  • V-2 : Gestion de fichiers
  • Pour accéder aux fichiers, on doit utiliser les fonctions de l’API Windows. Avant de lire ou d’écrire dans un fichier, il faut l’ouvrir. Windows attribue alors un numéro au fichier, c’est ce numéro (unique) qui est utilisé.

    Pour ouvrir un fichier, on utilise la fonction FileOpen :

    AnsiString Nomdufichier ;

    int FileHandle ;

    Nomdufichier= "bidon.fic" ;

    FileHandle=FileOpen(Nomdufichier,fmOpenRead) ; // ouvre en lecture

    // si FileHandle est négatif, le fichier n’a pas pu être ouvert.

    Le fichier peut être ouvert en lecture (fmOpenRead) ou en écriture (fmOpenWrite), en mode binaire (fmOpenBinary) ou texte (fmOpenText).

    Pour lire dans un fichier, on utilise la fonction FileRead , pour écrire la fonction FileWrite.

    Une fois toutes les opérations terminées, on DOIT fermer le fichier par FileClose.

    On peut bien sur utiliser les fonctions standard du C comme fopen, fclose, ...

     

  • V-3 : Les Timers
  • On a souvent besoin dans un programme d’exécuter une opération à intervalles réguliers. Prenons le cas d’un simple programme d’horloge par exemple.

    Au lieu, comme sous DOS, de faire une boucle, on utilise un Timer du système qui créé à intervalles réguliers, un évènement.

    Le Builder encapsule les Timers Windows dans un composant TTimer.

     

    Le composant TTimer possède comme propriétés principales Enabled (validé) et Interval (intervalle en millisecondes entre deux évènements OnTimer).

    Une fois le Timer validé (Enabled vaut true), le système génère tous les <Interval> ms un évènement OnTimer.

    Il faut noter que les évènements étant asynchrones, rien ne garantit que le laps de temps soit exactement celui spécifié. Un programme horloge devra donc lire régulièrement la valeur de l’horloge système.

    On peut utiliser les timers pour lancer une tâche en fond, pour scruter régulièrement une valeur... en bref pour réaliser au sein d’un même programme, du multi-tâches.

    Il faut noter que Windows n’autorise qu’un nombre limité de Timers actifs en même temps.

     

     

  • V-4 : Les Threads
  • Pour réaliser plus proprement du multi-tâches à l’intérieur d’un même processus, on utilise plutôt les Threads.

    Un Thread est en fait une fonction, s’exécutant en parallèle de votre programme, mais lui appartenant néanmoins.

    Le Builder utilise l’objet TThread pour gérer ce système.

    La classe TThread contient les méthodes suivantes pour gérer les threads :

    Execute, Suspend, Resume, Terminate.

    Un Thread peut avoir des variables locales, et utiliser les variables globales de l’application.

     

  • V-4 : Informations sur la configuration
  • Windows fournit un ensemble de fonctions destinées à gérer la configuration du système, ainsi que les paramètres propres à chaque programme.

    Vous pouvez avoir besoin en effet de sauvegarder des paramètres propres à votre programme, pour les utiliser à chaque session de celui-ci.

    Windows 3.x utilisait des fichiers texte, les fichiers .INI, organisés en sections :

    [section1]

    parametre1=valeur1

    parametre2=valeur2

    [section2]

    ....

    Bien qu’il n’est pas conseillé d’utiliser les fichiers INI sous Win32, le builder fournit une classe pour les traiter : la classe TIniFile.

    La classe TIniFile contient les méthodes ReadBool, ReadInteger, ReadString pour lire des données, ainsi que WriteBool... pour les modifier. D’autres méthodes permettent de créer ou d’effacer les sections.

    Par exemple, pour sauvegarder les informations utilisateur (Nom et Prénom) :

    TIniFile *Ini ;

    Ini=new TIniFile("fichier.ini") ;

    Ini->WriteString(" utilisateur ","Nom",Nom) ; // Nom est une AnsiString contenant le nom

    Ini->WriteString(" utilisateur ","Prenom",Prenom) ; // Prenom est une AnsiString

    delete Ini ;

    Pour lire ces mêmes informations, on utiliserait ReadString.

    Mais Windows 95/98/NT fournit une structure mieux adaptée : la base de registres (registry). C’est une base de données relationnelle, en mode binaire, hiérarchisée et protégée par le système. Il est conseillé de sauvegarder les informations ici plutôt que dans un fichier INI.

    Le Builder fournit une classe pour gérer la base de registres : TRegistry .

    On utilise TRegistry de manière très proche de TIniFile. La principale différence est qu’il n’y a pas de fichier propre à l’application, et qu’il peut y avoir autant de sous-sections (on parle de clés) que voulues. Il faut noter que sous Windows NT, seule une partie de la base de registres est accessible si l’on a pas les droits administrateur.

    La base est organisée autour de 3 clés principales :

    HKEY_CLASSES_ROOT contient des informations sur les classes enregistrés (id les types de fichiers reconnus par le système).

    HKEY_LOCAL_MACHINE contient des informations sur la machine, matérielles et logicielles.

    HKEY_CURRENT_USER contient des informations propres à l’utilisateur en cours. Cette clé permet de sauvegarder des informations propres à un utilisateur (profil).

    En général, on n’utilise que la clé HKEY_CURRENT_USER.

    Il est conseillé de respecter l’organisation de cette clé, qui préconise, pour chaque application, d’enregistrer ses informations dans la clé :

    HKEY_CURRENT_USER\Software\Compagnie\Logiciel\Version

    Par exemple, pour le programme MONPROGRAMME version 3.5, édité par la société MASOCIETE, il est recommandé d’utiliser la clé

    HKEY_CURRENT_USER\Software\MASOCIETE\MONPROGRAMME\3.5

    Dans une clé (sous-clé) peuvent être enregistrées des valeurs binaires, entières, chaînes...

    Si on utilise le même exemple que précédemment :

    TRegistry *Reg ;

    Reg=new TRegistry() ;

    Reg->RootKey=HKEY_CURRENT_USER ;

    Reg->OpenKey("Software\\MASOCIETE\\MONPROGRAMME\\3.5") ;

    Reg->WriteString(" Nom ",Nom) ;

    Reg->WriteString(" Prenom ",Prenom) ;

    Reg->CloseKey() ;

    delete Reg ;