Jack Admin
Nombre de messages : 2394 Date d'inscription : 28/05/2007
| Sujet: Structure pour un programme Windows 3/4 Jeu 24 Mar 2011 - 17:04 | |
| Ce tutoriel a été écrit par Klaus. Structure pour un programme Windows Leçon 3Dans cette leçon, nous allons reprendre le programme réalisé dans la leçon précédente (3/4) et le faire évoluer. Nous allons lui ajouter un menu système et une fenêtre A-propos. Nous allons procéder étape par étape, avec des explications détaillées à chaque niveau, et un code source Panoramic évoluant en conséquence, jusqu'au programme complet. Pour mémoire, voici le programme réalisé dans la léçon précédente. Il permettait de saisir un mot, et le click sur un bouton affichait le nombre de lettres contenues dans ce mot. On a aussi une liste des mots analysés qui peut être triée en ordre ascendant ou descendant, et elle peut être effacée. - Code:
-
' Tutoriel sur la structure pour un programme Windows
' tous les labels du programme label analyser_mot : ' déclarer la routine événement: label trier_liste : ' déclencher le tri des mots traités label effacer_liste : ' effacer la liste des mots traités label saisie_mot : ' saisie du mot en cours
' toutes les variables du programme dim longueur%, mot_a_analyser$, i%
' toutes les initialisations
' champ de saisie edit 10 : ' champ de saisie top 10,20 : left 10,120 : ' position du coin en haut à gauche du champ dans la fenêtre on_change 10,saisie_mot : ' placé après la création de l'objet 30 pour informer Panoramic
' affichage du nombre de caractères ALPHA 20 : ' zone d'affichage top 20,80 : left 20,120 : ' position du coin en haut à gauche de la zone d'affichage dans la fenêtre font_size 20,12 : ' pour avoir une taille lisible facilement
' libellés des champs affichés alpha 1 : top 1,20 : left 1,10 : caption 1,"Mot à analyser:" alpha 2 : top 2,80 : left 2,10 : caption 2,"Nombre de lettres:"
' bouton déclenchant l'analyse button 30 : ' bouton déclenchant l'analyse top 30,50 : left 30,120 : ' position du coin en haut à gauche du bouton caption 30,"Analyse" : ' libellé du bouton ON_CLICK 30,analyser_mot : ' placé après la création de l'objet 30 pour informer Panoramic
' liste d'affichage des mots traités list 40 : ' zone d'affichage top 40,10 : left 40,300 : ' position du coin en haut à gauche de la liste
' détermination de la direction du tri option 50 : ' option pour tri ascendant top 50,10 : left 50,450 : ' placement à l'écran caption 50,"Tri ascendant" option 51 : ' option pour tri ascendant top 51,30 : left 51,450 : ' placement à l'écran caption 51,"Tri descendant" MARK_ON 50 : ' cocher l'option tri ascendant par défaut
' bouton déclenchant le tri button 60 : ' bouton déclenchant l'analyse top 60,50 : left 60,450 : ' position du coin en haut à gauche du bouton caption 60,"Tri" : ' libellé du bouton ON_CLICK 60,trier_liste : ' placé après la création de l'objet 60 pour informer Panoramic inactive 60 : ' bouton inactif par défaut
' bouton effaçant la liste button 70 : ' bouton déclenchant l'analyse top 70,80 : left 70,450 : ' position du coin en haut à gauche du bouton caption 70,"Effacer" : ' libellé du bouton ON_CLICK 70,effacer_liste : ' placé après la création de l'objet 70 pour informer Panoramic inactive 70 : ' bouton inactif par défaut
' liste invisible pour le tri descendant dlist 80 : ' liste invisible
end
' traitement des événements analyser_mot: mot_a_analyser$ = text$(10) : ' récupérer le mot saisi ' et afficher le résultat dans l'objet 20 longueur% = len(mot_a_analyser$) caption 20,"Ce mot a "+str$(longueur%)+" lettres." text 10,"" : ' effacer le champ de saisie if mot_a_analyser$<>"" item_add 40,mot_a_analyser$ : ' ajouter le mot traité à la liste active 60 : ' bouton actif active 70 : ' bouton actif end_if set_focus 10 : ' placer le curseur dans le champ de saisie return
trier_liste: if checked(50)=1 : ' tri ascendant choisi ? SORT 40 : ' alors trier normalement else : ' ici, tri descendant choisi ! clear 80 : ' effacer la DLIST par précaution for i%=1 to count(40) : ' boucler sur le contenu de la liste item_add 80,item_read$(40,i%) : ' et copier chaque élément next i% sort 80 clear 40 : ' effacer notre liste for i%=count(80) to 1 step -1 : ' boucler sur le contenu de la DLIST item_add 40,item_read$(80,i%) : ' et copier chaque élément next i% end_if return
effacer_liste: clear 40 : ' effacer la liste inactive 60 : ' bouton inactif inactive 70 : ' bouton inactif return
saisie_mot: ' activation conditonnelle des boutons if text$(10)="" active 60 active 70 else inactive 60 inactive 70 end_if return
La plupart des programmes Windows disposent d'un menu système, permettant d'accéder aux fonctions essentielles du programme, souvent en doublant des fonctions accessibles par des boutons de commande. La commande MAIN_MENU est utilisée pour créer le point de départ du menu. Elle crée un objet référencé comme n'importe quel autre objet Panoramic, par un numéro: - Code:
-
' menu système main_menu 100 : ' racine du menu
Pour le moment, rien n'apparaît à l'écran. Nous allons maintenant ajouter 3 rubriques dans ce menu, qui aura ainsi l'aspect suivant: Fichers Fonctions A-Propos. La commande SUB_MENU réalise cela. Elle crée également des objets. Mais maintenant, il y aura une nouveauté: ces sous-menus doivent être "attachés" au menu principal. On dit que le menu principal doit être le "parent" de ses sous-menus. Par défaut, la fenêtre principale (FORM 0) est le parent de tous les objets (voir leçon 1). Il faut donc spécifier explicitement le menu principal comme parent. Deux solutions: utiliser la commmande PARENT pour chaque sous-menu, ou utiliser la commande COMMAND_TARGET_IS qui change le parent de façon permanente. Ici, nous utiliserons la première méthode: - Code:
-
' définir les sous-menus sub_menu 101 : parent 101,100 : caption 101,"Fichiers" sub_menu 102 : parent 102,100 : caption 102,"Fonctions" sub_menu 103 : parent 103,100 : caption 103,"A-Propos"
Le menu est apparu, en décalant automatiquement tous les objets vers le bas. Nous n'avons pas besoin de modifier le positionnement des champs et boutons pour faire la place pour le menu ! Nous allons maintenant ajouter des lignes aux sous-menus, de façon à obtenir des menus déroulants. Commençons par le menu "Fichiers". Conventionnellement, c'est le premier sous-menu à gauche sur la barre de menus qui reçoit la ligne "Sortie", quelques soient ses autres fonctions. Nous allons donc commencer par cela. Mais attention: le parent de la ligne "Sortie" doit être le sous-menu 101, par le menu système 100. Nous allons lui donner aussi une routine ON_CLICK pour exécuter la fonction demandée: - Code:
-
' sous-menu Fichiers sub_menu 104 : parent 104,101 : caption 104,"Sortie" on_click 104,sortir
Bien sûr, comme nous le savons déjà, il faut ajouter la commande LABEL et la routine elle-même, en fin de programme. La commande TERMINATE sort immédiatement du programme. Rien n'est exécuté au-delà, mais nous placerons quand-même la commande RETURN pour que la structure du sous-programme événement soit complète: - Code:
-
label sortir : ' sortir du programme
et en fin de programme
sortir: terminate : ' arrêt immédiat du programme return : ' on n'arrive jamais ici - présent juste pour la forme
Maintenant, ce sera le tour du menu "Fonctions". Nous pouvons identifier 4 fonctions dans notre programme: - analyser un mot - trier la liste en ordre ascendant - trier la liste en ordre descendant - effacer la liste La première et la quatrième fonction sont directement accessibles sous forme de routines événement. Mais nous n'avons qu'une seule routine événement pour les deux tris, dont la direction est déterminée par les options 50 et 51. Nous allons donc modifier la liste des fonctions comme suit: - analyser un mot - tri descendant - trier la liste - effacer la liste La deuxième fonction (tri descendant) sera une ligne "à cocher". Un clic que cette ligne va "cocher" cette ligne et passer en mode "tri descendant", un autre clic sur la même ligne va "décocher" cette ligne et repasser en mode "tri ascendant". Dès lors, une seule routine événement suffit. Notons que le parent de ces lignes est le sous-menu 102: - Code:
-
' sous-menu Fonctions sub_menu 105 : parent 105,102 : caption 105,"Analyser mot" on_click 105,analyser_mot sub_menu 106 : parent 106,102 : caption 106," Tri descendant" on_click 106,inverser_sens sub_menu 107 : parent 107,102 : caption 107,"Trier liste" on_click 107,trier_liste sub_menu 108 : parent 108,102 : caption 108,"Effacer liste" on_click 108,effacer_liste
avec bien sûr la commande LABEL et l'amorce de la routine "inverser_sens": - Code:
-
label inverser_sens : ' inverser le sens du tri
et en fin de programme
inverser_sens:
return
Il reste à créer le traitement de la routine "inverser_sens". C'est simple: si l'option 50 est cochée, on coche l'option 51, sinon on coche 51, et on ajuste le libellé de la ligne de menu en conséquence: - Code:
-
text 10,"" : ' effacer le champ de saisie if checked(50)=1 : ' actuellement en mode ascendant ? mark_on 51 : ' oui, alors passer en mode descendant caption 106,"* Tri descendant" else : ' non mark_on 50 : ' alors passer en mode ascendant caption 106," Tri descendant" end_if
Bien. Le dernier sous-menu à réaliser est le menu A-propos. Et là, nous allons introduire une nouvelle notion: celle des fenêtres supplémentaires. En effet, comme tous les programmes Windows, Panoramic peut gérer plusieurs fenêtres, pas seulement une seule qui est ouverte par défaut, au début du programme. Petit rappel de la première leçon: lorsqu'un programme Panoramic démarre, un seul objet est toujours défini: c'est la FORM 0 qui représente la fenêtre principale. Mais à l'aide de la commande FORM, nous pouvons créer d'autres fenêtres (sans limitation), et nous allons utiliser cela pour créer notre fenêtre A-propos. Bien sûr, si positions et dimensions par défaut ne conviennent pas, on peut les changer dans la foulée. On peut créer cette fenêtre au début du programme, comme les autres objets, puis la cacher, et en cliquant sur le menu "A-propos", on le montre par la commande SHOW. La fenêtre sera créée comme suit: - Code:
-
' fenêtre A-propos form 200 : ' créer une fenêtre top 200,300 : left 200,300 width 200,400 : height 200,200 caption 200,"A-propos"
Il faut donc créer une routine événement qui sera appelée par un clic sur le menu "A-propos": - Code:
-
label a_propos : ' montrer la fenêtre A-propos
et après la définition du menu 103: on_click 103,a_propos
en en fin de programme:
a_propos: show 200 : ' montrer la fenêtre A-propos return
Maintenant, nous avons en apparence un problème. En fermant la fenêtre par la croix rouge, elle est supprimée et ne peut plus être réactivée par notre menu. Une solution consisterait à la recréer chaque fois. Ici toutefois, nous allonns enlever la bordure et les boutons système de cette fenêtre et la fermer par un bouton de validation qui en réalité va la cacher au lieu de la supprimer. Donc, à la création de la fenêtre, nous pourrions utiliser la commande BORDER_HIDE et cacher la fenêtre par HIDE. En l'état actuel de Panoramic cependant, la croix rouge ferme la fenêtre, mais ne supprime pas les objets. Donc, une commande show suffit pour la faire réapparaître. Cependant, pour rester cohérent, nous allons maintenir la commande BORDER_HIDE, mais en commentaire. On pourra ainsi l'activer en cas de besoin: - Code:
-
hide 200 : ' et la cacher tout de suite ' border_hide 200 : ' supprimer le bord et les boutons système
Maintenant, il faut ajouter un bouton de fermeture avec sa routine ON_CLICK, la commande LABEL correspondante et la routine événement correspondante contenant la commande HIDE. Nous savons déjà faire tout cela: - Code:
-
label cacher_a_propos : ' cacher la fenêtre a_propos
et après la création de la form 200: button 210 : ' créer le bouton de fermeture parent 210,200 : ' il appartient à la fenêtre 200 ! top 210,170 : left 210,180 : ' positionner ce bouton dans la fenêtre caption 210,"Fermer" on_click 210,cacher_a_propos
et en fin de programme: cacher_a_propos: hide 200 return
Il reste à afficher le contenu de la fenêtre A-propos. En général, une fenêtre A-propos contient des informations constantes sur le programme: le nom du programme, l'auteur, la version, date, copyright, site web, etc. Nous allons placer nom et objet du programme, l'auteur, la version et la date. Pour placer ces informations, de simples champs d'affichage suffisent. Ce sont les objets ALPHA que nous connaissons déjà. Il est pratique de garder les informations dans des variables, chargées au début du programme: ainsi, en passant d'une version à une autre, la modification est plus facile à apporter: - Code:
-
dim nom_programme$, auteur$, date_creation$, version_programme$
nom_programme$ = "Tutoriel leçon 3" auteur$ = "Klaus" date_creation$ = "18 mars 2011" version_programme$ = "V01.00"
Il faut maintenant placer ces informations dans la fenêtre A-propos. Pour cela, il suffit de créer des objets ALPHA en indiquant la fenêtre (objet 200) comme parent, et en plaçant les variables à l'aide de la commande CAPTION: - Code:
-
' afficher les informations fixes alpha 211 : parent 211,200 top 211,10 : left 211,10 : caption 211,nom_programme$ alpha 212 : parent 211,200 top 212,30 : left 212,10 : caption 212,auteur$ alpha 213 : parent 213,200 top 213,50 : left 213,10 : caption 213,date_creation$ alpha 214 : parent 214,200 top 214,70 : left 214,10 : caption 214,version_programme$
Nous constatons maintenant que si nous lançons notre programme par l'éditeur Panoramic, tout fonctionne bien, mais en fermant la fenêtre A-propos, c'est la fenêtre de l'éditeur qui est en avant-plan et non plus la fenêtre principale de notre programme. La commande TO_FOREGROUND nous permet de rappeler notre programme en avant-plan. Ceci n'a d'utilité que dans le cas d'exécution à partir de l'éditeur; si nous construisons un exécutable, le problème ne se pose plus: - Code:
-
to_foreground 0 : ' replacer la fenêtre principale en avant-plan
Il nous reste une dernière difficulté: la fenêtre A-propos se place en avant-plan, mais un clic sur la fenêtre principale la fait recouvrir par la fenêtre principale qui reste active. On dit que la fenêtre A-propos est une "fenêtre non-modale". Une "fenêtre modale" garderait le focus jusqu'à la fermeture, sans pouvoir cliquer dans une autre fenêtre. Panoramic n'a pas de commande spécifique pour cela. Nous allons simuler cela en rendant la form 0 inactive lors de l'affichage de la form 200, et inversement. Cela se fait par des commandes ACTIVE et INACTIVE. Nous obtenons ainsi le résultat final: - Code:
-
' Tutoriel sur la structure pour un programme Windows
' tous les labels du programme label analyser_mot : ' déclarer la routine événement: label trier_liste : ' déclencher le tri des mots traités label effacer_liste : ' effacer la liste des mots traités label saisie_mot : ' saisie du mot en cours label sortir : ' sortir du programme label inverser_sens : ' inverser le sens du tri label a_propos : ' montrer la fenêtre A-propos label cacher_a_propos : ' cacher la fenêtre a_propos
' toutes les variables du programme dim longueur%, mot_a_analyser$, i% dim nom_programme$, auteur$, date_creation$, version_programme$
' toutes les initialisations
nom_programme$ = "Tutoriel leçon 3" auteur$ = "Klaus" date_creation$ = "18 mars 2011" version_programme$ = "V01.00"
' champ de saisie edit 10 : ' champ de saisie top 10,20 : left 10,120 : ' position du coin en haut à gauche du champ dans la fenêtre on_change 10,saisie_mot : ' placé après la création de l'objet 30 pour informer Panoramic
' affichage du nombre de caractères alpha 20 : ' zone d'affichage top 20,80 : left 20,120 : ' position du coin en haut à gauche de la zone d'affichage dans la fenêtre font_size 20,12 : ' pour avoir une taille lisible facilement
' libellés des champs affichés alpha 1 : top 1,20 : left 1,10 : caption 1,"Mot à analyser:" alpha 2 : top 2,80 : left 2,10 : caption 2,"Nombre de lettres:"
' bouton déclenchant l'analyse button 30 : ' bouton déclenchant l'analyse top 30,50 : left 30,120 : ' position du coin en haut à gauche du bouton caption 30,"Analyse" : ' libellé du bouton ON_CLICK 30,analyser_mot : ' placé après la création de l'objet 30 pour informer Panoramic
' liste d'affichage des mots traités list 40 : ' zone d'affichage top 40,10 : left 40,300 : ' position du coin en haut à gauche de la liste
' détermination de la direction du tri option 50 : ' option pour tri ascendant top 50,10 : left 50,450 : ' placement à l'écran caption 50,"Tri ascendant" option 51 : ' option pour tri ascendant top 51,30 : left 51,450 : ' placement à l'écran caption 51,"Tri descendant" MARK_ON 50 : ' cocher l'option tri ascendant par défaut
' bouton déclenchant le tri button 60 : ' bouton déclenchant l'analyse top 60,50 : left 60,450 : ' position du coin en haut à gauche du bouton caption 60,"Tri" : ' libellé du bouton ON_CLICK 60,trier_liste : ' placé après la création de l'objet 60 pour informer Panoramic inactive 60 : ' bouton inactif par défaut
' bouton effaçant la liste button 70 : ' bouton déclenchant l'analyse top 70,80 : left 70,450 : ' position du coin en haut à gauche du bouton caption 70,"Effacer" : ' libellé du bouton ON_CLICK 70,effacer_liste : ' placé après la création de l'objet 70 pour informer Panoramic inactive 70 : ' bouton inactif par défaut
' liste invisible pour le tri descendant dlist 80 : ' liste invisible
' menu système main_menu 100 : ' racine du menu ' définir les sous-menus sub_menu 101 : parent 101,100 : caption 101,"Fichiers" sub_menu 102 : parent 102,100 : caption 102,"Fonctions" sub_menu 103 : parent 103,100 : caption 103,"A-Propos" on_click 103,a_propos
' sous-menu Fichiers sub_menu 104 : parent 104,101 : caption 104,"Sortie" on_click 104,sortir
' sous-menu Fonctions sub_menu 105 : parent 105,102 : caption 105,"Analyser mot" on_click 105,analyser_mot sub_menu 106 : parent 106,102 : caption 106," Tri descendant" on_click 106,inverser_sens sub_menu 107 : parent 107,102 : caption 107,"Trier liste" on_click 107,trier_liste sub_menu 108 : parent 108,102 : caption 108,"Effacer liste" on_click 108,effacer_liste
form 200 : ' créer une fenêtre hide 200 : ' et la cacher tout de suite top 200,300 : left 200,300 width 200,400 : height 200,200 caption 200,"A-propos" ' border_hide 200 : ' supprimer le bord et les boutons système button 210 : ' créer le bouton de fermeture parent 210,200 : ' il appartient à la fenêtre 200 ! top 210,140 : left 210,180 : ' positionner ce bouton dans la fenêtre caption 210,"Fermer" on_click 210,cacher_a_propos
' afficher les informations fixes alpha 211 : parent 211,200 top 211,10 : left 211,10 : caption 211,"Programme : "+nom_programme$ alpha 212 : parent 212,200 top 212,30 : left 212,10 : caption 212,"Auteur : "+auteur$ alpha 213 : parent 213,200 top 213,50 : left 213,10 : caption 213,"Créé le : "+date_creation$ alpha 214 : parent 214,200 top 214,70 : left 214,10 : caption 214,"Version : "+version_programme$
end
' traitement des événements analyser_mot: mot_a_analyser$ = text$(10) : ' récupérer le mot saisi ' et afficher le résultat dans l'objet 20 longueur% = len(mot_a_analyser$) caption 20,"Ce mot a "+str$(longueur%)+" lettres." text 10,"" : ' effacer le champ de saisie if mot_a_analyser$<>"" item_add 40,mot_a_analyser$ : ' ajouter le mot traité à la liste active 60 : ' bouton actif active 70 : ' bouton actif end_if set_focus 10 : ' placer le curseur dans le champ de saisie return
trier_liste: if checked(50)=1 : ' tri ascendant choisi ? SORT 40 : ' alors trier normalement else : ' ici, tri descendant choisi ! clear 80 : ' effacer la DLIST par précaution for i%=1 to count(40) : ' boucler sur le contenu de la liste item_add 80,item_read$(40,i%) : ' et copier chaque élément next i% sort 80 clear 40 : ' effacer notre liste for i%=count(80) to 1 step -1 : ' boucler sur le contenu de la DLIST item_add 40,item_read$(80,i%) : ' et copier chaque élément next i% end_if return
effacer_liste: clear 40 : ' effacer la liste inactive 60 : ' bouton inactif inactive 70 : ' bouton inactif return
saisie_mot: ' activation conditonnelle des boutons if text$(10)="" active 60 active 70 else inactive 60 inactive 70 end_if return
sortir: terminate : ' arrêt immédiat du programme return : ' on n'arrive jamais ici - présent juste pour la forme
inverser_sens: text 10,"" : ' effacer le champ de saisie if checked(50)=1 : ' actuellement en mode ascendant ? mark_on 51 : ' oui, alors passer en mode descendant caption 106,"* Tri descendant" else : ' non mark_on 50 : ' alors passer en mode ascendant caption 106," Tri descendant" end_if return
a_propos: show 200 : ' montrer la fenêtre A-propos inactive 0 : ' bloquer la fenêtre principale return
cacher_a_propos: hide 200 : ' cacher le fenêtre A-propos active 0 : ' et réactiver la fenêtre principale to_foreground 0 : ' replacer la fenêtre principale en avant-plan return
Récapitulons les éléments importants de ce tutoriel: - construction d'un menu système, avec des sous-menus déroulants - déclenchement d'une action à partir d'une ligne de menu - adaptation dynamique du menu au contexte - création et gestion d'une autre fenêtre - distinction entre fenêtre modale et non-modale Dans la leçon suivante, nous allons voir plus en détail l'aspect présentation, avec la gestion des couleurs, polices et tailles du texte, structuration de la fenêtre etc. | |
|