Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : ARexx - Écrans, fenêtres et messages
(Article écrit par François Gueugnon et extrait d'Amiga News Tech - avril 1992)
|
|
Les considérations théoriques de l'article précédent vont trouver
leur application dans celui-ci. Pour illustrer les différentes possibilités, nous avons écrit un programme dont
l'utilité est discutable...
Le programme suivant construit deux écrans (Screens) de définitions différentes, l'un au-dessus de l'autre. Celui
du haut (en basse résolution) est divisé en deux fenêtres égales, celui du bas (en haute résolution) ne présente
qu'une seule fenêtre. Les intitulés de chaque écran et fenêtre rappellent ces caractéristiques.
Dès le lancement, dans l'écran nommé "Basse résolution" et dans la fenêtre nommée "Fenêtre 0",
apparaissent le texte "Ecrire ci-dessous" et un gadget contenant la phrase "Ecrire ici !".
Si l'on écrit dans la ligne du gadget et que l'on appui sur la touche "Entrée", on voit s'inscrire dans la
fenêtre de droite, nommée "Fenêtre 1", la phrase "Gadget lu", quelle qu'ait pu être la phrase
tapée dans la ligne du gadget. Puis la fenêtre de gauche s'efface au bout de quelques instants
pour se réouvrir dans les mêmes conditions, avec les modifications suivantes : la phrase
"Ecrire ci-dessous" a disparu et, dans le gadget texte, on peut lire "Ecrire à nouveau ici".
Tant que l'on ne fera rien, il ne se passera rien... Si l'on écrit une phrase quelconque dans le gadget,
elle sera reportée in extenso dans la limite de la largeur de la fenêtre de gauche dès l'appui sur
la touche "Entrée". On verra aussi apparaître un gadget intitulé "SORTIE" dans la fenêtre du bas,
elle-même nommée "Fenêtre 2".
A partir de cet instant, chaque fois que l'on appuiera sur le bouton de la souris, et si le pointeur
est dans la boîte du gadget texte de la fenêtre 0, il apparaîtra un segment de droite vert placé
au hasard dans la fenêtre du bas. Le titre de l'écran aura pris la même couleur verte dès le tracé
de la première droite. Dans la fenêtre de droite, on écrira la phrase "Coordonnées :" suivie des
deux chiffres représentant des valeurs tirées des coordonnées du pointeur au moment de l'appui sur
"Entrée".
Lorsqu'on appuiera sur le gadget "SORTIE", au moment où il sera relâché, la couleur du titre de
l'écran et celle des droites tracées deviendra bleue, et une phrase s'inscrira, en bleu également :
"J'ai compris, je sors (dans quelques secondes)". Tous les écrans et fenêtres se refermeront.
Sic transit gloria !
Description détaillée du fonctionnement
La ligne 1 rappelle que toutes les bibliothèques ARexx doivent être présentes. On n'a pas
placé ici le rituel de vérification pour limiter la taille du programme. Les deux écrans basse et
haute résolution sont ouverts respectivement aux lignes 12 et 13. On y voit les noms apparaissant
dans la ligne d'intitulé et, ligne 13 le mot "TRUNCATE". Cette spécification est nécessaire pour
limiter à la partie visible un écran (SCREEN) qui ne commencerait pas en haut de l'écran cathodique
puisque, hélas, il n'y a pas de possibilité de définir une hauteur d'écran.
Les lignes 15 à 20, prises deux par deux, créent des paires de ports nécessaires à la communication
dans les deux sens avec chacune des fenêtres. Le type "ECRITx" permet d'écrire dans la fenêtre,
le type "LITx" permet de lire ce qui vient de la fenêtre. "ADDRESS" permet de demander au résident
ARexx de créer les ports. "WaitForPort()" accorde le délai nécessaire pour leur création.
Les lignes 22 à 27 préparent les drapeaux de description de la partie visible de chaque fenêtre et
les IDCMP, qui sont les messages qui seront envoyés par la fenêtre le cas échéant. Ici, nous n'avons
prévu que les IDCMP "GADGETUP" qui déclenchent le processus au moment où le gadget est relâché.
Il vous est loisible d'y mettre autre chose, conformément aux règles de définition des fenêtres.
Les lignes 29 à 31 ouvrent les trois fenêtres citées précédemment avec leur port d'écriture respectif
en début d'instruction, leurs dimensions et leurs positions, ainsi que, juste à la fin, le nom de
l'intitulé qui sera visualisé. Les drapeaux et les IDCMP sont représentés par les variables définies
juste au-dessus.
Les lignes 33 et 34 forment un groupe fréquent qui positionne par "Move" le curseur x et y en coordonnées
relatives à la fenêtre, et qui écrit un texte dans la fenêtre précisée par le nom du port,
ici "ECRIT0", à la position débutant par la position du curseur.
La ligne 36 construit un gadget dans la fenêtre précisée par son port "ECRIT0", à la position
donnée en coordonnées relatives à la fenêtre, contenant la phrase "Ecrire ici". C'est un gadget
texte parce qu'on lui a attribué une longueur précisée en fin d'instruction, sinon ce serait
un gadget bouton dont le texte serait alors écrit à son sommet. Le "1" est le "GadgetID",
c'est-à-dire un identificateur qui permet de le retrouver précisément lorsque plusieurs gadgets
sont associés à une même fenêtre. La phrase "Gadget lu" est le message que peut retourner le gadget
en cas de sollicitation.
En ligne 38, on ouvre le port lecture de messages venant de la fenêtre déclarée "LIT0".
Le port écriture correspondant a été ouvert au moment de l'ouverture de la fenêtre et,
comme il n'est pas possible de n'ouvrir qu'un port, cette fonction permet d'activer ou non
l'autre port. Attention, en cas de défaut en mise au point de programme par exemple, il se
peut que ce port ne soit pas fermé. Restant ouvert, il s'oppose passivement à sa recréation
lors d'essais suivants. Ce n'est pas de la paranoïa que de prévoir ce cas sinon c'est le
redémarrage obligatoire !
Plus généralement, tout ce qui a été ouvert par "OPEN..." doit être fermé par le "CLOSE..."
correspondant. Si la fin du programme est accidentelle, il est nécessaire d'avoir prévu un moyen
de tout fermer par ailleurs, sinon c'est la punition précitée.
Les lignes 40 à 43 représentent la méthode simplifiée pour recevoir et interpréter un message
émanant d'une fenêtre. La ligne 40 arrête le déroulement du programme en attendant un éventuel message
venant de la fenêtre (du port) considérée, ici "LIT0". En 41, lorsque cet évènement a eu lieu, on
récupère l'adresse du message par "GETPKT(NomduPort)" et on extrait le message par "GETARG(adresse)",
en ligne 42. Le message étant récupéré, on répond à l'envoyeur nommément désigné par "REPLY".
Dans le cas présent, c'est l'usage du gadget texte qui a déclenché l'envoi du message. Comme rien
d'autre n'avait été précisé, c'est le message inclus dans la définition du gadget "Gadget lu"
qui est retourné, et non le texte contenu dans le gadget. C'est la raison de l'appellation simplifiée
précisée plus haut.
Les lignes 44 et 45 s'emparent du texte reçu et l'envoient dans la fenêtre de droite pour affichage.
La ligne 46 impose une attente de cinquante cinquantièmes de seconde, soit donc d'une seconde complète,
avant de fermer les ports et la fenêtre de droite comme il a été décrit précédemment.
Aux lignes 54 à 56, la fenêtre est reconstruite selon la méthode précédente. Cependant, des différences
notables vont être apportées. En ligne 58, on a ajouté un message à l'IDCMP : "MOUSEMOVE",
qui donne les coordonnées du pointeur de la souris. La ligne 57 précise ce que l'on veut et comment on
veut recevoir le message après l'activation du gadget. La chaîne de la ligne 57 peut se lire ainsi :
dans la zone 1 (%1), mettre le contenu de la ligne texte (%g), dans la zone 5 (%5), les coordonnées du
pointeur de souris x (%x) et y (%y) séparées par une virgule (%x,%y). Alors on peut ouvrir la fenêtre
avec la définition des types de messages qu'elle doit émettre le cas échéant (ligne 59) et décrire le
gadget ainsi que le format du message souhaité.
Le message peut être composé de seize zones différentes dont le choix dépend de la facilité d'exploitation
souhaitée. Si l'on ne précise rien, le résultat n'est qu'un résultat générique sans précisions et
placé dans la zone 0.
Les lignes 62 à 65 récupèrent le message selon le mécanisme déjà-vu, attente en 62, adresse en 63,
récupération du message en 64. Cependant, à cette ligne, on voit apparaître le moyen de trier la
zone désirée, "GETARG(message,1)" le "1" représentant la zone à extraire. La ligne 65 remercie
l'émetteur du message et assure ainsi qu'il n'y aura pas accumulation de messages au port dont on se
doute bien qu'il n'a pas une taille infinie. Les lignes 66 et 67, désormais familières, s'occupent
de la présentation.
La ligne 69 ouvre un autre port à lire éventuellement.
La ligne 70 ajoute le gadget bouton "SORTIE" dans la fenêtre du bas. La chaîne émise par ce
gadget est placée en fin de description du gadget et contient les indications suivantes :
en zone 1 (%1) chaîne de texte "J'ai compris, je sors !" et ensuite la chaîne du gadget (%g).
Ensuite, on entre dans la boucle à sortie conditionnelle qui débute en 74. Cette boucle se termine
ligne 110. A l'intérieur, on trouve deux opérations similaires dans la forme : l'acquisition de
l'action sur le gadget "SORTIE" dans la fenêtre haute résolution du bas et celle de l'action sur le
gadget texte de la fenêtre basse résolution du haut à gauche. Comme on ne peut plus attendre l'arrivée
de l'un ou l'autre des évènements en bloquant le déroulement du programme, le procédé est le suivant :
la boucle se déroule sans arrêt et il faut saisir les messages éventuels au vol. Cependant, tenter
d'acquérir par "GETARG", un message qui n'est pas arrivé et dont on n'a donc pas l'adresse, conduit à
la faute. Tenter d'y répondre dans les mêmes conditions conduit au même résultat. D'où la séquence
suivante : on demande l'adresse d'un éventuel message "GETPKT" puis on vérifie que cette adresse
existe : "IF adresse ~== NULL() THEN...." Le terme "~==" signifie non égal au sens égalité et non au
sens affectation, la différence est subtile et pas toujours nécessaire, quant à "NULL()",
c'est une fonction qui fournit à la comparaison une valeur nulle au format de l'adresse obtenue par
"GETPKT". Indispensable !
Dans le premier test, on s'intéresse au gadget "SORTIE". S'il y a eu un message on l'extrait ligne 78,
on répond ligne 79, on prépare la sortie de boucle en 80 (on aurait tout aussi bien pu renvoyer
directement à un sous-programme de sortie).
Dans le deuxième test, qui débute en ligne 83, on extrait de la même façon le contenu du message issu
du gadget texte de la fenêtre du haut et en ligne 85, on s'intéresse à la zone 5. Comme on avait
(finement !) demandé que les coordonnées x et y soient séparées par une virgule, il est facile de les
séparer en 87 par une instruction "PARSE" dont le séparateur est la virgule, justement !
En lignes 88 et 89, on prépare la couleur et le pinceau associés puis, de 90 à 109, on tente de faire
varier les coordonnées de départ et d'arrivée des segments. En 90 et 91, on calcule deux nombres
aléatoires répartis entre 0 et 10, puis l'on effectue diverses opérations dont l'intérêt est minime dans
notre optique. De 105 à 109, on place le pointeur "Move" en 105, on trace le segment entre les
coordonnées de "Move" et celle de "Draw", on place le pointeur dans une autre fenêtre et on écrit
texte et valeurs. Ces opérations se reproduisent tant que le gadget "SORTIE" n'est pas sollicité.
Lorsque cela a été réalisé, dans les lignes 113 à 116, on prépare la couleur et le texte de l'inscription
de sortie. En ligne 116, on voit l'association d'un texte contenu dans le gadget défini en 70,
extrait en 78 et combiné avec une chaîne (dans quelques secondes) en 116.
Le texte écrit, la ligne 119 impose un délai de 250e de seconde avant d'entamer
le processus de fermeture des fenêtres et des écrans, en lignes 121 à 125, avant la sortie par
"EXIT".
Ce programme se lance comme à l'accoutumée par "rx chemin:nomprogramme".
Il est nommé "écrans.rexx". Cependant le nom est sans importance.
/*******************************/
/* */
/* ECRANS FENETRES et MESSAGES */
/* */
/* F.GUEUGNON 3-2-1992 */
/* */
/*******************************/
/* Vérifiez que toutes les librairies AREXX sont bien installées ! */
CALL OpenScreen(0,5,'LORES','ECRAN 0: Basse résolution',ECRAN0)
CALL OpenScreen(150,4,'HIRES+TRUNCATE','ECRAN 2: Haute résolution',ECRAN2)
ADDRESS AREXX "'CALL CreateHost(ECRIT0,LIT0,ECRAN0)'"
WaitforPort ECRIT0
ADDRESS AREXX "'CALL CreateHost(ECRIT1,LIT1,ECRAN0)'"
WaitforPort ECRIT1
ADDRESS AREXX "'CALL CreateHost(ECRIT2,LIT2,ECRAN2)'"
WaitforPort ECRIT2
flags0=''
idcmp0='GADGETUP'
flags1=''
idcmp1=''
flags2=''
idcmp2='GADGETUP'
CALL OpenWindow(ECRIT0,0,10,159,137,idcmp0,flags0,'Fenêtre 0')
CALL OpenWindow(ECRIT1,161,10,159,137,idcmp1,flags1,'Fenêtre 1')
CALL OpenWindow(ECRIT2,0,10,640,80,idcmp2,flags2,'Fenêtre 2')
CALL Move(ECRIT0,10,30)
CALL Text(ECRIT0,'Ecrire ci-dessous')
CALL AddGadget(Ecrit0,20,50,'1','Ecrire ici !','Gadget lu',120)
CALL OpenPort(LIT0)
CALL WAITPKT (LIT0)
message=GETPKT(LIT0)
contenu=GETARG(message)
CALL REPLY(message,10)
CALL Move(ECRIT1,40,57)
CALL Text(ECRIT1,contenu)
CALL DELAY 50
CALL ClosePort(LIT0)
CALL ClosePort(ECRIT0)
CALL CloseWindow(ECRIT0)
/****************************************************************/
ADDRESS AREXX "'CALL CreateHost(ECRIT0,LIT0,ECRAN0)'"
WaitforPort ECRIT0
CALL OpenPort(LIT0)
resultat='%1%g%5%x,%y'
idcmp0='GADGETUP MOUSEMOVE'
CALL OpenWindow(ECRIT0,0,10,159,137,idcmp0,flags0,'Fenêtre 0')
CALL AddGadget(Ecrit0,5,50,'1','Ecrire encore ici !',resultat,150)
CALL WAITPKT (LIT0)
message=GETPKT(LIT0)
contenu=GETARG(message,1)
CALL REPLY(message,10)
CALL Move(ECRIT1,5,57)
CALL Text(ECRIT1,contenu)
CALL OpenPort(LIT2)
CALL AddGadget(ECRIT2,5,20,2,'SORTIE',"%1J'ai compris, je sors !%g")
boucle=0
DO WHILE boucle=0
action=GETPKT(LIT2)
IF action ~== NULL() THEN DO
Texte=GETARG(action,1)
CALL Reply action,10
boucle=1
END
coordonnees=GETPKT(LIT0)
IF coordonnees ~== NULL() THEN DO
coor=GETARG(coordonnees,5)
CALL REPLY coordonnees,10
PARSE VAR coor x ',' y
CALL SetRGB4(ECRIT2,1,0,12,0)
CALL SetAPen(ECRIT2,1)
nb1=RANDOM(0,10)
nb2=RANDOM(0,10)
IF nb1 > nb2 THEN DO
a1=nb1*60
a2=nb2*8
b1=x
b2=y
END
ELSE DO
a1=nb1*50
a2=nb2*5
b1=y+nb1
b2=x+nb2
END
CALL Move(ECRIT2,a1,a2)
CALL Draw(ECRIT2,b1,b2)
CALL Move(ECRIT1,5,90)
texte='Cordonnées:'
CALL Text(ECRIT1,texte b1','b2' ')
END
END
CALL SetRGB4(ECRIT2,1,0,10,15)
CALL SetApen(ECRIT2,1)
CALL Move(ECRIT2, 200,50)
CALL Text(ECRIT2,texte' (dans quelques secondes)')
CALL DELAY 200
CALL CloseWindow(ECRIT0)
CALL CloseWindow(ECRIT1)
CALL CloseWindow(ECRIT2)
CALL CloseScreen(ECRAN0)
CALL CloseScreen(ECRAN2)
EXIT
|
|