Programmation en GFA (4)
OLE et OLGA sont dans un avion. Qui se trouve largué ?
Heureusement Zorro est arrivé. Son nom est Thomas Much, allemand de son état, qui nous a concocté un équivalent des liens OLE qui existent du côté obscur de l'informatique.
"Object Linking for GEM Applications" permet de lier pas deux (voire plusieurs) applications entre elles, et d'informer sur l'état d'un fichier commun à toutes ces applications.
Il existe plusieurs niveaux de communication pour OLGA. La plus spectaculaire consiste dans le protocole ID4, qui permet de lier des données en temps réel. Ainsi, la dernière version d'ANI Player fait tourner des animations dans la fenêtre de CAB (version 2.7). Très spectaculaire à ce qu'on m'a dit.
En ce qui nous concerne aujourd'hui, nous allons étudier la méthode de plus bas niveau. C'est le minimum pour pouvoir dire "ce programme gère un peu les liens OLGA", il s'agit de faire un serveur OLGA (ce sont mes routines dans Joe qui me servent à interfacer CAB).
Soyons diplomates, respectons le protocole.
PROCEDURE ole_init id_olga&=APPL_FIND("OLGA ") IF id_olga&>0 INT{m_adr%}=18768 ! OLE_INIT INT{m_adr%+2}=mon_ap_id& INT{m_adr%+4}=0 INT{m_adr%+6}=1 ! 1=serveur 2=client 3=les deux ' ! il existe d'autres codes INT{m_adr%+8}=0 INT{m_adr%+10}=0 INT{m_adr%+12}=0 INT{m_adr%+14}=CVI("ED") ~APPL_WRITE(id_olga&,16,m_adr%) ENDIF RETURNm_adr% est, comme vous l'avez deviné, un buffer de 16 octets alloué par votre programme. On met dans l'offset(+14) une chaîne de texte convertie en décimale, qui correspond au type de notre application. Les codes sont les suivants :
Un problème se pose sûrement si OLGA n'est pas en mémoire. il faut alors le rechercher dans le tampon de l'AES et chercher la fameuse ligne (sous MagiC dans MAGX.INF) :
#_ENV OLGA=chemin+nom_de_OLGAOn charge ensuite par SHEL_WRITE OLGA et on commence sa déclaration à OLGA. J'avoue que cette méthode est peu rébartative, n'étant pas un féru de la ligne de commande. Je place OLGA.APP et ses fichiers annexes dans le dossier de démarrage de MagiC (ou MiNT). Ça marche très bien, mais il est vrai que ça occupe de la mémoire même si l'on ne l'utilise pas.
Après votre déclaration, vous recevrez un récépicé par l'intermédiaire de EVNT_MULTI dans votre buffer message :
IF BTST(evnt&,4) SELECT INT{m_adr%} CASE 10 ! gestion menu CASE 20 ! redraw CASE 4679 ! OLGA_GETINFO mon_index_olga&=INT{m_adr%+10} ENDSELECT ENDIFOn récupéré un identificateur "olguien", qui nous permettra de nous identifier lors des appels ultérieurs à OLGA.
Le service minimum d'OLGA consiste à avertir toutes les applications qui gèrent le même fichier que vous lors que vous sauvez celui-ci. Par exemple, lors de la sauvegarde automatique du fichier HTML dans Joe, si CAB possède le même fichier en mémoire, il sera prévenu par OLGA que ce fichier a été modifié et qu'il faut le recharger.
Donc chez vous le serveur, après l'initialisation de votre application à OLGA :
id_olga&=APPL_FIND("OLGA ") IF id_olga&>0 INT{m_adr%}=4664 ! OLGA_UPDATE INT{m_adr%+2}=mon_ap_id& INT{m_adr%+4}=0 LONG{m_adr%+6}=aa_start% INT{m_adr%+10}=mon_index_olga& LONG{m_adr%+12}=0 ~APPL_WRITE(id_olga&,16,m_adr%) ENDIF(aa_start% est un buffer contenant le nom entier du fichier et placé dans la mémoire "globale" GEMDOS(68,L:taille%,W:32) si possible, GEMDOS(72,L:taille%) sinon).
Allez, quand nous, serveur, quittons et nettoyons proprement les allocations mémoires que nous avions faites, il ne faut pas aussi de dire au revoir à OLGA.
PROCEDURE ole_exit id_olga&=APPL_FIND("OLGA ") IF id_olga&>0 INT{m_adr%}=18769 ! OLE_EXIT INT{m_adr%+2}=mon_ap_id& LONG{m_adr%+4}=0 LONG{m_adr%+8}=0 LONG{m_adr%+12}=0 ~APPL_WRITE(id_olga&,16,m_adr%) ENDIF RETURNVous aurez bien compris que cette méthode est le minimum, il n'y a pas changement automatique et en temps réel dans toutes les applications gérant un même fichier. Il faut ici passer par une sauvegarde sur disque, mais c'est ici plus confortable. CAB n'aura pas, par exemple, à refaire toute sa pagination HTML à chaque changement d'un caractère dans l'éditeur de texte.
N'allons pas coincer la bulle tout de suite...
Première façon d'activer ses bulles d'aide : cliquer sur le bouton droit. Il
faut donc ruser avec EVNT_MULTI puisque cette fonction ne sait pas bien gérer ce bouton
(on fait alors evnt&=EVNT_MULTI(&X110011,258,3,0,... au lieu de
evnt&=EVNT_MULTI(&X110011,2,1,1..., bidouillage légal et officialisé
par Atari Corp pour contourner le problème).
vous récupérer les coordonnées de votre souris, et déterminez la
nature de ce que vous allez mettre en bulle (par exemple avec WIND_FIND et OBJC_FIND).
Viens ensuite l'appel de BubbleGEM :
bubble_id&=APPL_FIND("BUBBLE ") IF bubble_id&>0 AND bubble%>0 CHAR{bubble%}=LEFT$(message$,255) INT{m_adr%}=47803 ! BUBBLEGEM_SHOW INT{m_adr%+2}=mon_ap_id& INT{m_adr%+4}=0 INT{m_adr%+6}=mo_x& ! coords X du curseur souris INT{m_adr%+8}=mo_y& ! la meme chose en Y LONG{m_adr%+10}=bubble% ! adresse d'un buffer de 256 octets ' ! qui va contenir le message$ INT{m_adr%+14}=0 ~APPL_WRITE(bubble_id&,16,m_adr%) ENDIFLe buffer bubble% doit être si possible être en mémoire globale (échanges, pour les OS en mémoire protégée) (voir plus haut). BubbleGEM ouvrira une petite et zolie boîte dans lequel le mesage va s'inscrire. Si vous voulez provoquer un retour à la ligne dans la bulle d'aide, il faut écrire "|" dans la chaîne.
BubbleGem est sensé vous répondre par l'intermédiaire d'EVNT_MULTI pour libérer votre buffer. Je n'en tiens pas compte puisque ce buffer est permanent (il est libéré quand je quitte). Allez donc voir la doc-dev de BubbleGEM qui, à l'instar d'OLGA, est fournie d'office avec le programme.
Les configurations se font en général dans un CPX fourni avec bubbleGEM. Le protocole est assez étendu et concerne par exemple la gestion des fontes, la gestion des bulles dans les formulaires bloquants, mais le plus fort dans tout ça, c'est que :
Le démon de la bulle viendra t'envelopper de son manteau irisé !
IF BTST(evnt&,4) SELECT INT{m_adr%} CASE 10 ! menu CASE 20 ! redraw CASE -17734,48802 ! BUBBLEGEM_REQUEST handle_win%=INT{m_adr%+6} mo_x&=INT{m_adr%+8} mo_y&=INT{m_adr%+10} mo_k&=INT{m_adr%+12} boucle_bubbling ENDSELECT ENDIFboucle_bubbling est en fait la fonction citée plus haut : recherche de l'objet sous les coordonnées de la souris, le handle de la fenêtre... et l'appel à BubbleGEM. (j'emploie -17734 et 48802 car je fait en réalité un dummy&=INT{m_adr%} et je ne sais plus si le mot est signé ou pas).
Le mot de la fin.
Le mont Fuji se trouve bien au Japon ? A quand les Threads dans CAB comme dans Netscape ou WenSuite ?
Rajah Lone
nef@mygale.org
écrit le 29 Juin 1998