I : Introduction à la programmation événementielle

En programmation classique (C sous DOS par exemple), le programmeur crée souvent une fonction dite fonction principale, appelée au démarrage du programme, qui gère les entrées utilisateur (clavier-souris...) et appelle suivant ces entrées un certain nombre de fonctions (procédures) du programme. Cela marche très bien dans un environnement mono-tâche (ou multi-tâche préemptif) puisque notre programme ne rend la main au système que lorsqu’il est fini. Sinon, il s’installe dans une boucle pour traiter les entrées utilisateur. Ceci n’est pas très efficace, puisque le temps passé à attendre une pression du clavier (par exemple) est perdu, le CPU ne pouvant rien faire d’autre pendant ce temps. De plus, la complexité du programme avançant, la boucle de traitement des entrées peut devenir gigantesque, donc illisible.

En programmation événementielle, il n’y a pas de boucle de gestion, ni à vrai dire de programme principal. Tout le programme est constitué de fonctions (procédures) dont certaines servent à répondre à un évènement (clic souris par ex.). Tant qu’il n’y a aucun événement, le programme rend la main au système et économise ainsi du temps CPU.

 

  • I.1 : Environnements et systèmes graphiques
  • Dans un système comme DOS (ou UNIX en mode console), le programme est normalement en mode texte. Mais les utilisateurs d’aujourd’hui veulent une interface plus conviviale, plus pratique, plus rapide à utiliser. Donc des images, des fenêtres, des menus, des icônes...

    Un programme peut bien sur créer et gérer tout ceci. Mais quel temps perdu ! En effet, le mieux pour l’utilisateur (comme pour le développeur) est que TOUS les programmes se ressemblent (au niveau de l’interface bien sur) avec les mêmes automatismes, les mêmes possibilités graphiques. Pour cela, il faut que ce soit le système d’exploitation qui fournisse ces services, non le programme !

     

  • I.2 : Différents environnements graphiques
  • Sur compatibles PC : GEM, OS/2 , Windows, X-Window (UNIX)

    Sur Apple Mac : MacOS

    Sur Atari : GEM

    Sur Amiga : AmigaOS et Workbench

    Et autres : NextStep, BeOS, ....

    Tous ces environnements graphiques comportent bien sur des différences, mais également beaucoup de similitudes. Notamment le fait de gérer un certain nombre d’objets graphiques mis à la disposition du développeur, ainsi qu’une bibliothèque de fonctions pour traiter ces objets.

     

  • I.3 : La bibliothèque du système : l’API
  • Par API on désigne Application Programmer Interface. Il s’agit d’une ou plusieurs bibliothèques de fonctions et d’objets pour gérer simplement les services du système. Un programme n’a plus qu’à les appeler, en respectant bien sur leur syntaxe.

    Pour le système Windows sur PC, l’API comporte plus d’un millier de fonctions. C’est autant de moins à écrire !

     

  • I.4 : Les Objets du système
  • Un système graphique comporte toujours un grand nombre d’objets, ce qui le rend plus simple à programmer en POO bien sur..

    L’objet de base de ces systèmes est la fenêtre. Une fenêtre est l’espace de travail d’une application, normalement elle ne peut rien afficher en dehors de celle-ci. Pour un programme, l’écran se résume souvent à sa fenêtre.

    C’est le système qui gère les fenêtres. Il suffit d’appeler la fonction de création d’une fenêtre (CreateWindow par ex) et celle-ci est créé ! Le système s’occupe de la dessiner, de la redessiner, d’afficher ses attributs (barre de titre, menu, cases...), de la redimensionner, etc...

    Il y a une quantité d’autres objets dans le système Windows : des boutons, des menus déroulants, des listes, ....

    Pour chacun de ses objets, le système attribue un numéro d’identification unique, le handle, qui lui permet de s’y repérer... une application peut contenir plusieurs centaines d’objets, et le système doit gérer plusieurs applications (dont lui-même...).

     

  • I.5 : L’outil C++ Builder
  • Pour programmer sous Windows, n’importe quel langage fait l’affaire (même l’assembleur) ! Il suffit de connaître le millier de fonctions de l’API, de les appeler correctement, de gérer tous les événements associés à ces objets... bref c’est un peu long et fastidieux.

    Plus simplement, le fait d’employer un langage orienté objet, comme le C++, permet de simplifier grandement la programmation (et la lisibilité) du programme.

    Mais même en POO, la gestion d’un programme Windows devient très vite fastidieuse. C’est pourquoi les éditeurs de compilateurs ont créé des aides pour le programmeurs, des classes (objets) encapsulant directement les fonctions de l’API Windows. Simplifiant grandement le développement, ces aides sont devenus pratiquement indispensables.

    Il en existe plusieurs : OWL (Object Windows Library), MFC (Microsoft Fondation Classes), VCL (Visual Control Library).

    Le C++ Builder, comme d’ailleurs son équivalent Delphi (et dans une moindre mesure Visual C++ et Visual Basic) comporte la VCL, et de plus offre une présentation visuelle de programmation qui simplifie grandement le développement de l’interface utilisateur du programme.

    En Builder, les objets du système sont représentés par des classes C++, contenant en plus des attributs (propriétés) des objets, les fonctions permettant de les gérer (méthodes). La POO permet également une hiérarchisation de ces objets, ce qui permet aisément d’en créer de nouveaux, en dérivant ceux existant.

     

  • I.6 : Une classe non VCL : AnsiString
  • La programmation en C n’est pas très pratique pour gérer les chaînes de caractères. Le C++ Builder apporte une réponse en donnant la classe AnsiString.

    La classe AnsiString gère les chaînes de caractères de taille quelconque, vérifie leur taille et leur emplacement mémoire, et définit des opérateurs pour manipuler simplement les chaînes.

    AnsiString s ; // déclaration

    s= " Ceci est une chaîne " ; // affectation

    s+= "  spéciale AnsiString " ; // concaténation

    s= " Valeur de " +IntToStr(50) ;

    s= " Somme en francs :" +FloatToStr(23.25) ;

    Possibilité d’utilisation avec des fonctions classiques C :

    s= " Chaine";

    if( strcmp(s.c_str(), " Chaine "))....

    Grâce à AnsiString, la manipulation des chaînes de caractères devient aussi simple que celle des entiers.

    Un grand nombre de classes de la VCL utilisent AnsiString au lieu d’un char* pour manipuler les chaînes.

    Si le besoin s’en fait ressentir, AnsiString fournit la fonction c_str() qui renvoie un char* permettant de manipuler la chaîne comme en C classique. Attention, ce pointeur n’est valable que juste après l’appel de c_str().