

/////////////////////////////////////////////////////////////////////////
////////////////-- I -- PREALABLE & MOTIVATIONS philosophiques //////////
/////////////////////////////////////////////////////////////////////////

a) BON!! IL FAUT BIEN DIRE QUELQUE CHOSE:
-----------------------------------------
EAZY_GEM est une bibliotheque de fonctions permettant une gestion
plus actuelle du GEM.

COPIEZ le fichier EAZY_GEM.LIB dans le dossier LIB     de votre PureC
       le fichier EAZY_GEM.H   dans le dossier INCLUDE de votre PureC

Le dossier DIDACTIC contient des exemples comments, dont je recommande
vivement la lecture des fichiers .C

Les fichiers sources des trois programmes de dmo: LIZEZMOI.C
                                                   WND_PROC.C et
                                                   RADIO.C
sont comments autant que faire se peut et sont aussi, riches des
techniques de programmation sous EAZY_GEM.                                                    

La programmation sous EAZY_GEM vous demande d'observer quelques rgles
indispensables  son fonctionnement correct.

Ces principes de programmation peuvent apparaitre difficiles pour ceux 
qui n'y sont pas habitus, mais aprs un effort d'adaptation vraiment   
minime, l'on regrette de ne pas l'avoir fait avant, tellement la     
programmation sous GEM semble ensuite facile !!!.                     

EASY_GEM tant programm avec PURE C, tout sera dcrit en fonction de
ce langage. C'est un parti pris un peu abrupt, mais je n'ai pas le
temps de faire autrement (dsol).


b) COMMENT EAZY_GEM NAQUIT:
--------------------------
Programmeur sur Atari depuis plusieurs annes, GFA, Assembleur et C,
je n'avais jamais vraiment compris ni russi  vraiment structurer mes
programmes de faon vraiment correcte vis  vis du GEM. 
Rcemment une exprience de programmation sous WINDAUBE m'a en fait 
curieusement clair sur le GEM !!!. et oui pardonnez moi cet incur-
sion chez l'ennemi.

L'aboutissement de cette exprience a t l'envie de clarifier le GEM
et de crer une mthode de programmation me permettant de GEMER avec
plus de facilits (au moins en ce qui me concerne).

Il en est sorti toute une bibliothque de fonctions permettant de
programmer sous GEM de faon adapte  mon fonctionnement. Mes ides
et ma faon de voir les choses me sont toutes personnelles mais j'ai
pens que cela pouvait intresser les autres. Aussi je mets  la 
disposition du public cette bibliothque, faites en ce que vous voulez
la seule chose que je vous demande est d'en signaler l'utilisation
dans vos programmes si le hazard fait que vous utilisiez EAZY_GEM
dans vos crations, et de m'en signaler les amliorations et corrections  
des BUGS et lourdeurs.

Certaines habitudes dans la presentation de l'interface des programmes
sous GEM sont modifies, mais apres tout c'est comme a que j'ai
pris plaisir  redecouvrir le GEM. Que les esprits chagrins restent sur
leurs sentiers battus. Je n'ai aucune intention de revolutionner
ni de gagner quoi que ce soit (gloire, argent, etc...) sur un systeme
dont le march ne permet plus aucune pretention si ce n'est le plaisir
pur de programmer et de se faire plaisir sur une machine qui reste 
la portee d'un particulier. 

L'Atari est encore une des rares machines pemettant  un particulier
d'apporter quelque chose par son travail de programmation. Et l je
justifie entirement les heures passes devant mon PURE C  attendre
le resultat d'une compilation.

Que faire en tant que programmeur particulier sur un PC 200 Mhz 
face  des buildings entiers de programmeurs ???. Se desoler devant
notre ridicule programme face  l'offre d'un march plthorique,
abandonner tous les efforts et toute notre culture informatique, 
tout jeter, et se dire que l'on a perdu de nombreuses annes a courir
apres une chimre obsedante et vaine. C'est le parti de la resignation.
Personnellement je prfre faire vivre une chimre...

Toutes choses n'tant pas parfaites, si vous apportez des amliora-
tions  cette bibliothque, faites le moi savoir, et mettez les  la
disposition du public.


c) SCREUGNEUGNEU (suite):
------------------------
J'ai pris le parti de considerer qu'actuellement il est vain de tenter
de faire de la programmation et de l'informatique sur une machine ne
disposant pas au minimum 2Mo de memoire vive, et d'un disque dur meme
de petite capacite (20Mo). Les ceusses qui n'ont pas franchis cette
limite n'ont qu'a s'en prendre  eux meme si leur Atari 512 ko lecteur
de disquette 720 ne leur sert plus  rien. Essayez de faire tourner
WINDAUBE 95 sur un 8086 1Mo 720 ko ....

De meme pour l'ecran, une rsolution de 640/400 me semble le minimum
raisonnable pour afficher un truc.

Un gestionnaire de polices vectorielles, ainsi qu'un accelerateur
graphique logiciel, me semblent aussi presque indispensables.
(prevoyez alors 4Mo de memoire vive pour ne pas etouffer).

Je conseille aussi l'utilisation de programmes etendant le GEM tel que
WINX, ou mieux MAGIC afin de disposer de plus de 8 fenetres  l'ecran.
De plus ces environnements sont tres instructifs concernant la 
programmation GEM. En effet les nombreuses hypothses simplistes que
nous sommes tentes de faire sur le GEM nous reservent d'etonnantes
surprises. Nous n'avons qu'a bien nous tenir !!! Rigueur Rigueur ...

d) DESCRIPTION DES POSSIBILITES:
--------------------------------

    CONCERNANT LES RESSOURCES: 
     -------------------------
Dans EAZY_GEM les ressources sont obligatoirement en fenetre. Ce n'est
pas une contrainte et permet la ralisation de programmes non premp-
tifs. L'utilisation classique des ressources reste bien sur possible
mais je n'ai rien trait  ce sujet. Cela reste  votre charge.
Les ressources sont entirement gnres avec un diteur de ressources
classique (Je vous recommande INTERFACE et ORCS chacun ayant leurs
avantages et inconvnients).


 Icones couleurs disponibles pour toutes les rsolutions y compris
   sur les ST de base .

 Les fichiers ressources suprieurs  64ko (gnrs par INTERFACE)   
   sont automatiquement reconnus .

 Possibilit de charger et grer plusieurs fichiers de ressources
   en meme temps. Cela permet par exemple de charger une ressource
   en mmoire pour une boite de dialogue, puis de la librer aprs
   fermeture et fin de l'utilisation  de la boite de dialogue.   
   Gain de place mmoire. On ne l'encombre plus avec un norme fichier
   mais on ne charge que le fichier necessaire au dialogue. Ceci n'est
   pas une obligation mais permet vraiment une souplesse fabuleuse.

 Possibilit d'afficher les ressources en inhibant la mise 
   l'echelle que fait le GEM selon les diffrentes rsolutions. Cela
   permet de dfinir qu'une ressource quelles que soient les rsolu-
   tions. Donc de nouveau qu'un seul fichier pour toutes les rsolu- 
   tions. L'affichage est en fait celui que le GEM opre lors des
   basses rsolutions, et que j'ai permis lors des hautes rsolutions.
   En basse rsolution la ressource est celle que vous avez l'habitude
   de voir, en haute rsolution elle apparait en caractres taille 9
   donc moins de place  l'cran, esthtiquement je prfre (ceci
   n'est qu'un avis personnel que vous n'etes pas oblig de partager). 
   La contrainte (minime) est qu'elle doit etre cre avec le mode
   grille caractre active. Personnellement je me mets sous MAGIC,
   je lance le programme de dmo que je fournis avec EAZY_GEM,
   je lance INTERFACE, cre ma ressource, la sauve, puis la recharge
   dans mon programme de dmo avec l'option mise  l'echelle non 
   active, et je vois ce que a donne, sans quitter INTERFACE !!,
   cela permet aussi de voir comment les objets tendus se prsentent.
   
 Menus en fenetre dfinissables entirement avec INTERFACE, gres
   et reconnus automatiquement par EAZY_GEM. Aspect remis au gout du
   jour selon les critres et la mode actuelle 3D et tout le fourbi.
   Il est possible de mettre plusieurs menus en fenetre !!!. Il est
   possible de positionner un menu en fenetre n'importe ou dans la
   boite de dialogue !!!. A vous de voir  quoi cela peut servir.
   
 Boutons radios, checkbox, listbox, Scrollbox, avec aspect remis  jour.

 concept fabuleux des PAINT_BOX permettant de redefinir simplement
   le trac d'un objet sans utiliser les G_USERDEF, tout en pouvant
   acceder  toutes les fonctions GEM.

 Gestion automatique des raccourcis claviers.

 Champs ditables avec slection de bloc possible !!, et gestion du
   copier/couper/coller et presse papier.

 Boites  onglets automatiques dfinissables avec un diteur de 
   ressources classique.   
   
 Boites d'alertes en fenetres bloquante pour l'application emettrice
   mais par pour les autres applications. Pas de limite pour la longueur
   des messages de boite d'alerte, tant pour la longueur de ligne que 
   pour le nombre de lignes!!.

    CONCERNANT LES FENETRES: 
   --------------------------
 Agrandissement possible par tous les cots de la fenetre. Plein
   cran par double click sur un bord de la fenetre.
   
 Gestion de l'iconification, du VA_START, du drag and drop.

 Incorporation automatique d'un dialogue complexe, avec barre d'outils,
   dialogue de bord gauche et droits, pied de fenetre, le tout 
   automatiquement redimensionn avec la fenetre, et suivi des bords !!
   
 Gestion simplifie et automatique d'un systeme de bulle d'aides.

 Programmation des fenetres selon le concept de fonction associes,
   avec messages constructeur, et destructeur.


/////////////////////////////////////////////////////////////////////////
////////////////-- II -- LE PROJET D'UN PROGRAMME EAZY_GEM //////////////
/////////////////////////////////////////////////////////////////////////

Le plus simple est de vous montrer un listing comment de projet.
Que les habitus de PURE C excusent certains commentaires leur parais-
sant vidents. Cette documentation se veut aussi pour les dbutants.
Il est evident que l'exemple montre des chemins arbitraires qu'il
faudra adapter  votre programme.

;............ DEBUT DU TEXTE COMPOSANT LE FICHiER PROJET.............
; le mieux est de sauver ce fichier projet avec le meme nom que le
; programme. Exemple: si votre programme s'appelle EXEMPLE.PRG
;                     sauvez le fichier projet avec le nom:
;                     EXEMPLE.PRJ et si possible mettez tous vos fichiers
;                     dans le meme dossier
; RAPPEL:
; dans un fichier de projet tout ce qui suit un point virgule n'est
; pas pris en compte et est considr comme un commentaire
;>>>>>>>>>>>>>>>>>> Projet d'exemple pour EAZY GEM <<<<<<<<<<<<<<<<<<<

EXEMPLE.PRG        ;-> Cette ligne doit etre le nom du programme que
                   ;   vous fabriquez.                       
;.C [ -Y ]         ;-> Ces lignes decrivent les options de compilation
;.L [ -L -Y ]      ;   ici elles sont en commentaire. et concernent 
;.S [ -Y ]         ;   les options de debugage. (voir help  ce sujet)

=                  ;-> Cette ligne comporte le signe '='  la suite
                   ;   duquel doivent etre indiques les fichiers 
                   ;   necessaires  la cration du programme
                   
PCSTART.O          ;-> Ici on indique que le fichier dmarrage devant
                   ;   etre link au programme est PCSTART.O
                   ;   a sert  initialiser le programme, le reloger
                   ;   recuperer les arguments..., et a appelle la
                   ;   fonction: main
                   
;------------------- indication des fichiers C et S ------------------
;                        composant le programme

;------------------ MODULES SPECIFIQUES A VOTRE EXEMPLE---------------

E:\TURBO_C\EAZY_GEM\EXEMPLE.C  ;-> Ici on indique au compilateur que
                               ;   le fichier dont le chemin est 
                               ;   indiqu, fait aussi partie du
                               ;   programme devant etre genere.
                               ;   Ce fichier sera celui des fonctions
                               ;   que nous ecrirons. C'est cette 
                               ;   partie que votre imagination doit
                               ;   produire pour creer le programme.
                               ;   Dans cet exemple il n'y a qu'un 
                               ;   fichier, mais rien ne vous empeche
                               ;   de la diviser en plusieurs fichiers
                               
; les lignes qui suivent servent  indiquer  PURE C les librairies
; necessaires au programme (pour les debutants ne cherchez pas, a
; marche comme a)
;--------------------- LIBRAIRIE NECESSAIRES -------------------------
PCFLTLIB.LIB       ; floating point library 
PCSTDLIB.LIB       ; standard library
PCEXTLIB.LIB       ; extended library
PCTOSLIB.LIB       ; TOS library
PCGEMLIB.LIB       ; AES and VDI library
EAZY_GEM.LIB       ; inclure librairie EAZY_GEM
;............ FIN DU TEXTE COMPOSANT LE FICHiER PROJET.............


/////////////////////////////////////////////////////////////////////////
////////////////-- III -- INITIALISATION DESINITIALISATION //////////////
/////////////////////////////////////////////////////////////////////////

a) INITIALISATION:
-----------------
Tout programme sous EAZY GEM doit commencer par l'appel de la fonction 
suivante. Elle initialise les variables globales indispensables  la 
poursuite et au bon droulement d'EAZY GEM.
 
/*--------------------------- InitEazyGem -----------------------------*/
/* ACTION: initialise sur des valeurs par defaut la structure WINDTAB  */
/*         et dclare l'application au gem                             */
/* elle declare notre programme  EAZY_GEM,                            */
/* Initialise l'application et son identificateur GEM: Appl_id,        */
/* Ouvre une station de travail VDI dont le handle est: VDIhandle,     */
/* Initialise le GDOS (si il existe), charge les polices de caracteres */
/*     Reserve et initialise la zone des donnees de fontes: FontTab,   */
/*     itialise la variable de nombre de fontes: NbFont,               */
/*     initialise le tableau d'identificateur de fontes: FontID[],     */
/*     initialise le tableau de nom des fontes: FontName,              */
/* Initialisation desvariables globales suivantes:                     */
/*                Appl_id  (identificateur GEM de l'application)       */
/*                VDIhandle (handle VDI de l'application)              */
/*                FontTab  (pointe sur zone memoire reservee pour les  */
/*                          variables lies aux fontes)                */
/*                FontID[] (tableau des identificateurs de fontes)     */
/*                FontName (zone des noms de fontes. Chaque nom de     */
/*                         fonte fait 36 caracteres y compris zero de  */
/*                         fin de chaine. EXP: Pour accder au nom de  */
/*                         la 12me fonte il faut faire, (le premier   */
/*                         lment commenant  zro):                 */
/*                         FontName + 11 * 36. L'adresse ainsi         */
/*                         calcule pointe sur le nom de la 12me      */
/*                         fonte charge.Ce nom est identique  celui  */
/*                         retourn par la fonction VDI: vqt_name      */ 
/*                         ouf !!)                                     */
/*                NbFont  (Nombre de fontes disponibles y compris la   */
/*                         fonte systme)                              */
/*                Ecran_l (largeur de l'ecran en pixels)               */
/*                Ecran_h (hauteur de l'ecran en pixels)               */    
/*                Nb_color(nombre de couleurs)                         */
/*                Nb_plan (nombre de plan de l'ecran)                  */
/*                NomAppli (pointe sur le nom du programme)            */
/*                AESversion (utile  tester pour certaines fonctions) */
/*                Screen_MFDB  (structure raster cran)                */
/*                MachineInfo  (structure renseignant sur la machine   */
/*                               et systme sur lequel l'on est)       */
/*                Gdos   contient: l'identificateur Gdos si ok         */
/*                                -2 si Gdos pas charg                */
/*                                '_FSM' si vectoriel possible         */
/* Initialisation de la structure WINDTAB sur zero et valeurs de defaut*/ 
/*                                                                     */ 
/* PROTOTYPE:   int InitEazyGem(char *nomappli);                       */ 
/* ENTREE:      char *nomappli   doit pointer sur le nom du programme  */ 
/* RETOUR:      un int  positif si reussite de l'operation, qui est    */ 
/*                         alors l'identificteur GEM de l'application  */
/*                      NEGATIF -2 alors station de travail VDI non     */
/*                                 ouverte il faut abandonner.          */
/*                      NEGATIF -1 alors tout est foutu il faut quitter */

b) DESINITIALISATION:
--------------------                                 

Tout programme sous EAZY GEM doit se terminer par l'appel de la fonction 
suivante.  
/*----------------------------- ExitEasyGem ---------------------------*/
/* ACTION: Libre la mmoire reserve par EAZY_GEM pour ses besoins    */ 
/*         internes, dcharge les polices de caractres, ferme la      */
/*         station VDI, libre l'application du GEM, et quitte.        */
/* PROTOTYPE: int ExitEasyGem(void);                                   */
/* ENTREE:    nant                                                    */
/* RETOUR:    sans intrt                                             */ 

////////////////////////////////////////////////////////////////////////
///////////////////////-- IV -- BOUCLE PRINCIPALE //////////////////////
////////////////////////////////////////////////////////////////////////
Tout programme sous EAZY GEM doit aprs initialisation, faire 
obligatoirement appel  la fonction suivante qui EST LE COEUR D'EAZY_GEM. 
En effet cette fonction gre tout l'vennementiel GEM et le redirige sur 
les fonctions adquates aprs filtrage et diverses manipulations qui ne 
sont plus  votre charge.  Cette fonction prend la main et ne communique 
avec votre programme que par l'intermdiaire des fonctions CALLBACK.

Pour mettre fin  cette fonction et donc terminer le programme il vous 
faut mettre la variable globale:
  EZGemRun  0  et alors une boite d'alerte demandera  l'utilisateur de 
                  confirmer la fin du programme et la fonction:           
                  BouclePrincipale  se terminera selon le choix.
            -1 et alors la fonction: BouclePrincipale se termine sans  
                  demande de confirmation (utile dans certains cas 
                  notamment lors des SHUTDOWN et assimils);

Lors de l'appel de cette fonction il est possible et conseill de 
spcifier le nom de la fonction que vous ddiez  la gestion par dfaut 
des vnements. 

En effet dans EAZY_GEM  un grand principe est de fournir au systme 
l'adresse de la fonction que vous souhaitez attribuer  la gestion de 
certains aspects du programme. Nous appelerons ces fonction donnes  
EAZY_GEM des fonctions de rappel ou fonctions CALLBACK.

Si cette fonction de rappel (ou CALLBACK) n'est pas fournie (NULL ou 0), 
 la fonction: BouclePrincipale,
l'vnementiel GEM sera alors transmis aux fonctions de rappel (ou 
CALLBACK) de fenetres ( condition qu'avant l'appel  la boucle   
principale elles aient t cres). 
 
Donc lors de l'appel  la fonction: BouclePrincipale:
     
     SOIT vous fournissez une fonction CALLBACK de traitement par dfaut 
et alors votre programme pourra ragir aux messages GEM sans fenetre 
cre, par exemple  un menu GEM, bien sur  condition de l'avoir 
install avant l'appel  la fonction: BouclePrincipale, ou  l'appui sur 
une touche clavier, au TIMER etc, aux messages AC_OPEN, AC_CLOSE etc..
     
     SOIT vous ne fournissez  pas de fonction CALLBACK de traitement par  
     dfaut et alors votre programme ne poura ragir aux messages GEM que 
     si au moins une fenetre a t cre et de prfrence ouverte. 

/*------------------------- BouclePrincipale  -------------------------*/
/* ACTION: Noyau d'EAZY_GEM cette fonction est celle qui gre          */
/*         l'vnementiel GEM le filtre, le redistribue aux diffrentes*/
/*         fonctions CALLBACK en les appelant                          */
/*         Pour mettre fin  cette boucle il faut mettre la variable   */
/*         globale: EZGemRun                                           */
/*                   0 (demande de confirmation avant sortie)         */
/*                   1 (sortie sans demande de confirmation)          */
/* ENTREE: CALLBACK (*MyEventProc)(int w_ind, void *adr) adresse de la */ 
/*                   fonction qui sera charge de grer l'vnmentiel  */ 
/*                   GEM par dfaut. Si cette valeur est NULL, alors   */ 
/*                   l'vnmentiel GEM ne pourra etre gr que par les */ 
/*                   fonctions CALLBACK  de fenetre                    */
/* RETOUR: nant                                                       */
/* PROTOTYPE:                                                          */

void BouclePrincipale(CALLBACK(*MyEventProc)(int w_ind,EVNT_O *Evnt));


////////////////////////////////////////////////////////////////////////
/////////-- V -- LES FONCTIONS DE RAPPEL OU FONCTIONS CALLBACK /////////
////////////////////////////////////////////////////////////////////////

   Dans EAZY_GEM,  chaque fenetre est associe une fonction CALLBACK.  
   CALLBACK veut dire mot  mot: appel arrire, en plus clair une       
   fonction CALLBACK, veut dire une fonction de rappel.                 
   Le principe est que vous DONNEZ  EAZY_GEM l'adresse de la fonction  
   de gestion qui va grer la fenetre que vous dsirez ouvrir, et que   
   c'est EAZY_GEM, qui RAPELLERA votre fonction selon les diffrentes   
   actions et vnements la concernant. L'intrt c'est qu'EAZY_GEM     
   traite pour vous tout un tas de choses ennuyeuses et difficiles, et  
   qu'il vous fait signe et laisse  votre charge ce qu'il ne peut pas  
   traiter ni prvoir, en rappelant votre fonction.                     
   Cette faon de faire permet aussi une meilleure structuration des    
   programmes car pour chaque fenetre il existe une seule fonction de   
   traitement.                                                          
   Toute la messagerie et l'vnementiel GEM classique est transmis    
   la fonction CALLBACK de Fenetre, plus d'autres messages spcifiques  
    EAZY_GEM, que nous verons petit  petit dans les exemples.         
   En rponse aux messages et vnements GEM il est possible de les     
   traiter tout  fait classiquement, ou comme je vous le conseille de  
   faire appel aux fonctions qu'EAZY_GEM met  votre disposition.       
   L'accs aux fonctions tendues de gestion de ressource en fenetre et 
   autres aspects pointus d'EAZY_GEM ne se fait bien videment qu'au     
   travers des fonctions prvues pour cela.                             

Nous avons vu plus haut qu'EAZY_GEM se servait de fonctions de rappel 
appeles aussi fonctions CALLBACK. Ce choix est je pense  la base de la 
puissance et de la souplesse d'EAZY_GEM. Il est utile de s'attarder un  
peu sur leur description et mode de fonctionnement.

Ces fonctions doivent etre cres et fournies  EAZY_GEM  deux occasions: 
    Lors de l'appel des fonctions: BouclePrincipale (voir plus haut) et                             
                                 : CreateWindow                    
Dans le premier cas pour indiquer  EAZY_GEM la fonction  qui sera charge 
              de traiter le flux vnementiel en l'absence de fenetre.
Dans le deuxime cas pour indiquer  EAZY_GEM la fonction qui sera charge 
              de grer le flux vnementiel pour la fenetre que l'on cre.
              Cette fonction  CALLBACK est alors associe a la fenetre 
              cre.
              
Lors de chaque vnement, EAZY_GEM appelle d'abord la fonction CALLBACK 
par dfaut puis la fonction CALLBACK lie  la fenetre active (au top), 
puis ensuite les fonctions CALLBACK lies aux autres fenetres de notre 
application.
Si une des fonctions CALLBACK retourne zro, alors la transmission de 
l'vnement et du flux vnementiel aux autres fenetres sera stopp.
              
Exemple de fonction CALLBACK:
            
/*------------------------  MyEventProc -------------------------------*/ 
/* ACTION: Gestion du flux vnementiel par dfaut ou associ  une    */ 
/*         fenetre.                                                    */
/* PROTOTYPE:                                                          */
/*         CALLBACK MyEventProc (int w_ind, EVNT_O *Evnt)              */
/* ENTREE: int w_ind  indice de la fenetre pour laquelle la fonction   */ 
/*                    est appele (inutile si fonction par dfaut)     */
/*         EVNT_O *Evnt  pointe sur la structure de flux vnementiel  */
/*                       pour lequel il est demand de ragir.         */ 
/* RETOURNE: un int qui doit etre l'vnement transmis en entree avec  */
/*                  Si la fonction ne le retourne pas et retourne zro */
/*                  alors l'vnement ne sera pas retransmis aux autres*/
/*                  fonctions CALLBACK. Cette possibilit est utile    */
/*                  par exemple pour empcher un click souris de se    */
/*                  transmettre aux fenetres de dessous...             */ 
/*                  Pour le message WM_CONSTRUCT il est possible de    */
/*                  retourner deux valeurs: WM_STANBY ou WM_ABORT afin */
/*                  de modifier le processus de creation de fenetre    */
/*                                                                     */
/*................ description de la structure EVNT_O..................*/
/*                  reprsentant le flux vnementiel                  */
/*  typedef struct                                                     */
/*      {int evnt;      */ /* type d'evenement GEM                     */
/*       int pipe[16];  */ /* table de parametres lors MU_MESAG        */
/*       int x;         */ /* coordonnee souris X                      */
/*       int y;         */ /* coordonnee souris Y                      */
/*       int k;         */ /* etat des boutons souris                  */
/*       int ksp;       */ /* etat des touches CONTRL,ALT,SHIFT,CAPS   */
/*       int key;       */ /* etat du clavier (comme evnt_multi)       */
/*       int click;     */ /* nombre de click (comme evnt_multi)       */
/*      }EVNT_O;                                                       */                           
/*                                                                     */            
/*                                                                     */ 


////////////////////////////////////////////////////////////////////////
/////////////-- VI  -- LES NOUVEAUX MESSAGES ET EVENEMENTS /////////////
////////////////////////////////////////////////////////////////////////
Les fonctions CALLBACK de fenetre et ou par dfaut reoivent donc un 
pointeur sur une structure de flux vnementiel de type EVNT_O. Par 
exemple notre fonction CALLBACK tant dfinie comme suit, l'analyse 
vnementielle devra se faire comme il est indiqu dans l'exemple 
ci-dessous:

a) LES EVENEMENTS:
-----------------

CALLBACK MyEventProc (int w_ind, EVNT_O *Evnt)
{
 if (Evnt->evnt & MU_KEYBD)  /* une touche clavier a t appuye     */
    {
    }
 if (Evnt->evnt & MU_BUTTON) /* un bouton  souris a t  enfonc     */
    {
    } 
 if (Evnt->evnt & MU_MOVE)   /* la souris a chang de position       */
    {
    } 
 if (Evnt->evnt & MU_TIMER)  /* le timer a avanc une unit de temps */
    {
    }
 if (Evnt->evnt & MU_MESAG)  /* un message nous est envoy           */
    {
    } 
 if (Evnt->evnt & MU_M1)     /* vnement  souris/rectangle 1        */
    {
    } 
 if (Evnt->evnt & MU_M2)     /* vnement  souris/rectangle 2        */
    {
    }                                                 

 return Evnt->evnt;          /* retransmission de l'vnement        */
}
      
Dans cet exemple le type d'vnement est rcupr avec: Evnt->evnt et les 
actions en sont dduites par un test. 

Les types possibles sont identiques  ceux que le GEM  gnre: 
        MU_KEYBD     /* une touche clavier a t appuye         */
        MU_BUTTON    /* un bouton de la souris a t  enfonc    */
        MU_TIMER     /* le timer a avanc d'une unit de temps   */
        MU_MESAG     /* un message nous est envoy               */
        MU_M1        /* il y a un vnement  souris/rectangle 1  */
        MU_M2        /* il y a un vnement  souris/rectangle 2  */
        
plus un vnement supplmentaire pour les mouvements souris: 
        MU_MOVE      /* la souris a chang de position           */
apparaissant chaque fois que la souris modifie sa position.
    
    
    
b) LES MESSAGES:
---------------
Reprenons la partie de notre exemple ddie aux messages:

  
if (Evnt->evnt & MU_MESAG)  /* un message nous est envoy           */
   {
   } 
    
    
Comme classiquement il doit etre fait avec tout message GEM, nous 
rcuprons le type de message en 1re position (premier mot) du buffer de 
message comme suit (MESG tant gal  0), les actions  faire en fonction  
de ce message sont dispatches  l'aide d'un switch/case.

if (Evnt->evnt & MU_MESAG)       /* un message nous est envoy         */
   {switch (Evnt->pipe[MESG])    /* action selon le type de message    */
       {/*.................. MESSAGES EAZY GEM ........................*/
        case WM_CONSTRUCT:
             break;
        case WM_MODAL_END:
             break;     
        case WM_DESTRUCT:
             break;
        case WM_TT_ON_OFF:
             break;
        case WM_TT_GET_TXT:
             break;
        case AID_REQUEST:
             break;     
        case WM_PAINT:
             break;
        case WM_PAINTBOX:
             break;     
        case WM_ONGLET_CHG:
             break;
        case WM_EXEFUNC:
             break;
        case WM_WND_MENU:
             break;
             
        /*.................. MESSAGES GEM .............................*/  
        case MN_SELECTED:           
             break;
        case WM_BOTTOM:
             break;                               
        case WM_TOPPED:
             break;
        case WM_CLOSED:
             break;        
        case WM_ICONIFY:
             break;                                                    
        case WM_UNICONIFY:            
             break;                              
        case WM_ARROWED:
             break;
        case WM_HSLID:
             break;
        case WM_VSLID:
             break;
        case WM_FULLED: 
             break;                  
        case WM_SIZED:    
             break;            
        case WM_MOVED:
             break;     
        case WM_NEWTOP:
             break;
        case AC_OPEN:
             break;
        case AC_CLOSE:
             break;                        
       }      
   }
 
..................... ANALYSE DES NOUVEAUX MESSAGES ....................
Dtaillons ci-dessous la faon de rpondre aux messages specifiques 
d'EAZY_GEM.

      WM_CONSTRUCT
       ------------
Ce message est envoy  notre fenetre avant sa cration et avant son 
affichage. Il sert  initialiser tout ce qui concerne notre fenetre avant 
son affichage.
Il est possible de:  Modifier les dimensions de la fenetre,
                     Charger ressource pour l'intgrer dans la fenetre,
                     Integrer une ressource deja presente en  memoire,
                     Initialiser les champs et objets d'une ressource
                     Modifier le titre de la fenetre,
                     Initialiser les ascenseurs de la fenetre,
                     Rserver et initialiser une zone mmoire de donnes,
                     Dclarer des bulles d'aide  EAZY_GEM,
                     Ouvrir une station de travail VDI spcifique,
                     etc... etc...

Lors de ce message il est donn dans:                   
                               Evnt->pipe[X_B]                        
                               Evnt->pipe[Y_B]                        
                               Evnt->pipe[W_B]                        
                               Evnt->pipe[H_B]                        
                                            les dim exterieures  maxi 
possibles d'ouverture de la fenetre sur l'ecran. c'est par defaut ces 
dimensions qui sont choisies pour ouvrir une fenetre.Si l'on veut  
d'autres dimensions c'est ces valeurs qu'il faudra modifier. 
                                   
                     il est aussi donn dans:                   
                               Evnt->pipe[X_G]                        
                               Evnt->pipe[Y_G]                        
                               Evnt->pipe[W_G]                        
                               Evnt->pipe[H_G]                        
                                            les dim interieures de la 
                                            surface de travail GEM 
                                            
                       
  Il est possible de repondre au message WM_CONSTRUCT  afin de:
  
      -- SOIT empecher l'ouverture de la fenetre, mais autoriser sa 
              cration, en faisant Soit: Evnt->evnt = WM_STANDBY;
                                   Soit: return WM_STANDBY; ces deux 
              faons de faire tant quivalentes.
      Pour ouvrir et afficher la fenetre ultrieurement il faudra
      utiliser la fonction:  OpenWindow.
      
      -- SOIT empecher la cration de la fenetre et interompre le 
              processus en faisant Soit: Evnt->evnt = WM_ABORT;
                                   Soit: return WM_ABORT; ces deux 
              faons de faire tant quivalentes.
      Cette possibilit d'interruption est utile en cas de problmes par 
      exemple si la mmoire souhaite n'a pu etre rserve, ou un fichier 
      de ressource non trouv, ou etc...
       
      -- SI il n'est donn aucune rponse ou la rponse suivante,
         return Evnt->evnt; 
         le processus se droulera comme prvu avec la cration et 
         l'ouverture et affichage de la fenetre. 
         
         
      WM_MODAL_END
     -------------
Ce message est envoy  une procdure de fenetre modale juste avant
de sortir de la modalit. C.A.D qu'apres avoir reu ce message la
fenetre n'est plus modale et est considere comme une fenetre normale.
C'est ce message qu'il faut envoyer a une fenetre modale pour la
fermer et debloquer l'acces aux autres fenetres.
C'est lors de la reception de ce message qu'il est recommand de
detruire la fenetre en faisant appel a la fonction: DestroyWindow();
Exple:
       case WM_MODAL_END:
            DestroyWindow(Windtab[w_ind].w_h); 
            break;
        
         
      WM_DESTRUCT              
     -------------
Ce message est envoy  notre procdure de fenetre juste avant la 
destruction d'une fenetre par EAZY_GEM. C'est lors de ce message qu'il 
convient de dsinitialiser tout ce qui concerne notre fenetre:
          Librer les bulles d'aide,
          Librer la mmoire,
          Fermer une ventuelle station de travail (autre que celle 
                                                     d'EASY_GEM)
          Dcharger les ressources,
          etc... etc...                                          
          
      WM_TT_ON_OFF      
     --------------
Ce message est envoy  notre procdure de fenetre chaque fois qu' 
EAZY_GEM active ou dsactive le systme de bulles d'aide, afin que notre 
fenetre puisse mettre  jour un ventuel tmoin d'activit de bulles 
d'aide. Nous verrons plus loin comment fonctionne le systme de bulles 
d'aide.

      WM_TT_GET_TXT    
     ---------------
Ce message est envoy  notre procdure de fenetre chaque fois que le 
systme de bulles d'aide, dsire afficher une bulle. Lors de ce message 
il convient de fournir au systme de bulles d'aide le texte  afficher.
Nous verrons plus loin comment fonctionne le systme de bulles d'aide.
     
      AID_REQUEST    
     -------------
Ce message est envoye a notre application chaque fois que DIDEROT nous 
demande une aide et une reference a afficher, pour la fenetre au dessus
de laquelle la souris se trouve. En general DIDEROT envoie ce message
lorsque etant au premier plan (fenetre active), la touche HELP a ete
appuyee. Nous verrons plus loin comment repondre a ce message.
             
      WM_PAINT
     ----------
Enfin le message que nous attendons tous !!! Enfin librs de 
l'effroyable horreur du message WM_REDRAW et de sa liste des rectangles, 
des rectangles d'intersections et autres clipping. EAZY_GEM fait tout 
pour nous !!!. 

En effet ce message est envoy  notre procdure de fenetre chaque fois 
qu'il est ncessaire de redessiner et regnerer un bout de notre fenetre. 
Il suffit de redessiner simplement le contenu de notre fenetre sans 
s'occuper de clipper et de faire appel  la liste des rectangles, et a 
marche !!!.

Le message est structur comme suit:

                en Evnt->pipe[X_G]                        
                   Evnt->pipe[Y_G]                        
                   Evnt->pipe[W_G]                        
                   Evnt->pipe[H_G]  
                   
                   l'on trouve le rectangle qu'il nous est demand de 
redessiner  (il est dj clipp par EAZY_GEM).

                en Evnt->pipe[X_B]                        
                   Evnt->pipe[Y_B]                        
                   Evnt->pipe[W_B]                        
                   Evnt->pipe[H_B]  
                   
                   l'on trouve le rectangle de notre surface client 
intrieur  la bordure de fenetre et aux ventuelles ressources associes 
 notre fenetre (barre d'outils, pied de fenetre, et autres) C'est dans 
lui qu'il faut dessiner.


      WM_PAINTBOX:
     -------------
 Ce nouveau message est envoy a notre procedure de fenetre lorsqu'il faut 
 retracer la surface d'une boite de type PAINT_BOX (ob-type etendu 
 PAINT_BOX (215). Enfin une faon simple de personnaliser les objets de
 votre ressource.
  
 Le message est structur comme suit:                                                 
                En: Evnt->pipe[X_G], 
                    Evnt->pipe[Y_G], 
                    Evnt->pipe[W_G], et  
                    Evnt->pipe[H_G], se trouve le rectangle de clipping                
 qui est dej clipp par EAZY_GEM. Cette donnee est juste la pour
 information et vous ne devrez normalment pas avoir a vous en servir.
                
                En: Evnt->pipe[X_B], 
                    Evnt->pipe[Y_B], 
                    Evnt->pipe[W_B], et  
                    Evnt->pipe[H_B], se trouve le rectangle de la surface      
 de l'objet qu'il est   votre charge de redessiner.
                
                En: Evnt->pipe[12]   se trouve le numero de l'objet dont  
 il faut retracer la surface. Cette donnee permet de reperer l'objet qu'il
 vous est demande de retracer.
             

      WM_REDRAW
     -----------
Encore lui !!! pourtant on m'avait bien dit que je ne le verrai plus !!! 
Pas de panique. Ce message apparait encore pour les masochistes qui 
veulent encore le traiter eux meme.
Pour viter d'avoir  le faire et faire en sorte que le message WM_PAINT 
fonctionne il faut juste faire comme suit:
         
         case WM_REDRAW:
              Lister_rectangles(w_h,(GRECT*)&Evnt->pipe[X_G]);             
              break;
              
et voil on ne s'occupe plus de lui !!.

      WM_ONGLET_CHG
     ---------------
Ce message est envoy  notre fenetre, chaque fois qu'un onglet d'une boite 
d'onglets d'une ressource a t clique et que le dialogue va changer.
Le message est compose comme suit:                         
             en  Evnt->pipe[MESG] = WM_ONGLET_CHG (message envoy)                      
                 Evnt->pipe[APPL] = identificateur de l'application        
                 Evnt->pipe[SUPL] = 0 (pas de surplus)                     
                 Evnt->pipe[WHND] = handle fenetre contenant ressource       
                 Evnt->pipe[X_G]  = indice du dialogue qui va etre activ  
                 Evnt->pipe[Y_G]  = indice du dialogue qui sera desactive     
                 *(long*)&Evnt->pipe[W_G] =  adr arbre ou sont les objets 
                                             dont les indices sont donnes. 
                                              

      WM_EXEFUNC
     ------------
Ce message est envoy lorsqu'il est demand au programme d'excuter une 
fonction rfrence par un numro de fonction.
Le message est compose comme suit:                         
              SI  Evnt->pipe[WHND]= RSC_DIAL; le message provient d'une  
                                               ressource.  ET ALORS                                
                  Evnt->pipe[X_G] = indice objet declenchant le message  
                  Evnt->pipe[Y_G] = numero de la fonction de referencee     
                  *(long*)&Evnt->pipe[W_G] =  adr arbre ou est l'objet   
                   
      WM_WND_MENU
     -------------
Ce message est envoy a notre procedure de fenetre lorsque 
une entree de menu deroulant en fenetre est clique.  
       
en Evnt->pipe[X_G] =  numero de l'item selectionn        
                      comme dans les menu GEM classiques.                           
en Evnt->pipe[Y_G] =  numero de l'arbre de menu                                                             
en *(long*)Evnt->pipe[W_G] adresse arbre menu, cela permet de distinguer 
                           le menu en fenetre dans le cas de plusieurs 
                           menus dans la meme  fenetre (c'est possible !!
                           !! avec EAZY_GEM)  
                                                  
////////////////////////////////////////////////////////////////////////
/////////////////////-- VII  -- LES RESSOURCES /////////////////////////
////////////////////////////////////////////////////////////////////////

a) CHARGEMENT ET LIBERATION D'UN FICHIER DE RESSOURCES:
------------------------------------------------------

Dans EAZY_GEM il est possible de charger plusieurs fichiers ressources 
differents en meme temps. 
A tout moment il est possible de liberer une ressource et de la recharger
afin de n'occuper la memoire temporairement que pendant l'utilisation de
la ressource.

INTERET: l'on est plus oblige de charger un gros fichier en debut et donc
d'occuper une grosse zone memoire meme pour des boites de dialogue ne
servant que peu frequement.
On peut fragmenter le fichier de ressource en plusieurs parties selon les
differentes parties du programme (meilleure structuration).
Finalement cela permet d'utiliser beaucoup plus facilement les dialogues
pour le programme sans avoir peur de trop occuper la memoire avec ceux ci.

Il est bien sur possible de ne charger classiquement qu'un seul fichier 
de ressource en debut de programme et de le liberer en fin de programme. 
A vous de choisir d'exploiter ce chargement dynamique ou pas.

MISE A L'ECHELLE GEM ou EAZY_GEM:

Lors d'un chargement de fichier de ressource, le GEM a l'habitude de 
faire un ajustage de la taille de la ressource en fonction de la resolution
courante. Cette mise a l'echelle impose a beaucoup de developpeurs de 
prevoir plusieurs fichiers de ressource pour un meme programme, un pour
chaque resolution. EAZY_GEM permet le forcage de cette mise a l'echelle
en obligeant le GEM a charger la ressource comme si elle etait en basse
resolution. Cela permet de definir qu'un seul fichier de ressource, pour
toutes les resolutions, un flag permet de choisir entre le mode GEM normal
(celui habituel du GEM) et le mode EAZY_GEM pour lequel les boite sont
affichees comme en basse resolution (donc en haute elle apparaissent avec
les caracteres en 9pts et reduites en hauteur de moitie) 

Donc deux modes de chargement: un normal    GEM:       SCALE/1
                               un universel EAZY_GEM:  NO_SCALE/0

Il est aussi possible de choisir la mise a l'echelle de chaque dialogue a
partir du ressource, et cela quelque soit le flag SCALE/NO_SCALE.

Il suffit de positionner le caractere de chaque boite racine sur:
   pour forcer la mise a l'echelle GEM normale,
   pour forcer la mise a l'echelle EAZY_GEM.


/* --------------------------- RscFicLoad ---------------------------- */
/* ACTION: charge un fichier ressource en memoire et l'adapte aux      */
/*         nouvelles specification d'EAZY_GEM.                         */
/*         La memoire est automatiquement reservee et la ressource est */
/*         relogee et convertie prete  l'emploi.                      */
/* ENTREE: char *path, char *name chemin et nom de la ressource        */
/*         int scale_flag = 1 SCALE affichage au standard GEM (normal) */
/*                        = 0 NO_SCALE affichage au standard EAZY_GEM  */      
/*                            (police moyenne taille 9)                */
/*         pour le menu GEM classique utilizez  SCALE ou 1             */
/*         pour un menu en fenetre ou une ressource en fenetre         */ 
/*              choisissez ce qui vous plait le plus.                  */           
/* RETOUR: adresse memoire o la ressource a t charge               */
/*         SI = 0 pas assez de memoire                                 */
/*            = 1 ce n'est pas un fichier de ressource                 */
/*            = 2 ouverture fichier impossible (fichier non trouv     */
/*                                              mauvais chemin ou nom) */
/*         il est fortement conseille de stocker cette adresse de      */
/*         chargement quelque part !!!                                 */
/* PROTOTYPE:                                                          */
/*           void *RscFicLoad(char *path, char *name, int scale_flag); */

/* ------------------------- RscFicUnLoad --------------------------------- */
/* ACTION: decharge la ressource et la memoire occupe par celle ci.        */
/*         il est obligatoire d'appeler cette fonction avant la fin du      */
/*         programme ou si l'on veut liberer et ejecter cette ressource     */         
/*         car l'on n'en a plus besoin. Il est evident que si l'on veut de  */
/*         nouveau utiliser cette ressource il faudra la recharger avec     */
/*         la fonction: RscFicLoad                                          */
/* ENTREE: void *adr_rsc adresse memoire o a t charge la ressource      */
/* SORTIE: void *adr_rsc est mise  zero                                    */        
/* PROTOTYPE:                                                               */
/*           void RscFicUnLoad(void *adr_rsc);                              */


b) ACCES AUX ELEMENTS D'UNE RESSOURCE:
-------------------------------------

/*------------------------ xrsrc_gaddr -------------------------------------*/
/* ACTION: permet d'obtenir l'adresse des differents elements de la         */
/*         ressource. Cette fonction fonctionne comme  rsrc_gaddr du GEM    */
/*         avec comme parametre suplementaire l'adresse de la ressource     */
/* ENTREE: int re_gtype  type d'element dont on veut l'adresse              */
/*                       (comme ceux du  rsrc_gaddr classique du GEM)       */        
/*         int re_gindex index de l'element dont on veut l'adresse          */
/*         int *pglobal  adresse de chargement de la ressource. C'est celle */
/*                       que l'on a obtenu avec la fonction: RscFicLoad     */ 
/* SORTIE: void *re_gaddr adresse de l'element recherch                    */
/* EXEMPLE: cet exemple indique comment obtenir l'adresse d'un arbre de     */
/*          ressource (dialogue, menu, etc..) Ici je desire avoir l'adresse */
/*          du premier objet du troisieme arbre (indexe  partie de zero)   */
/*          de la ressource chargee par: RscFicLoad  l'adresse: AdrRsc     */
/*          OBJECT *tree;   je declare un pointeur sur un objet             */
/*          xrsrc_gaddr (R_TREE, 2, &tree, AdrRsc);  j'appelle la fonction  */
/*          et apres cet appel, tree pointe sur le premier objet de la      */
/*                              ressource que je peux donc utiliser pour    */
/*                              affichage et autres  manipulations comme    */
/*                              dans le GEM traditionnel.                   */
/* PROTOTYPE:                                                               */
/*    int xrsrc_gaddr (int re_gtype, int re_gindex,                         */
/*                     void *re_gaddr, int *pglobal);                       */

c) LES EDITABLES AVEC EAZY GEM:
------------------------------
Les ditables sont dfinis classiquement avec un diteur de ressources. 

 SELECTION D'UN BLOC DE TEXTE:
  ----------------------------
  Slection possible d'un bloc de texte  la souris, en maintenant le bouton
  gauche de la souris appuy pour dfinir le premier caractre du bloc et
  tout en maintenant le bouton gauche de la souris appuy, se dplacer sur le
  dernier caractre  slectionner, et relacher le bouton gauche de la souris.
  Les caractres slectionns sont alors en vido inverse. 
  
  Un double clic permet de slectionner le mot sous lequel se trouve 
  la souris (CONTROL b agit de meme).
  
  Un double clic associ  la touche SHIFT permet de slectionner le texte
  entier.
  
 ACTIONS POSSIBLES SUR UN BLOC TEXTE:
  -----------------------------------
  -1- Couper: CONTROL X  l'appui sur la touche CONTROL en meme temps que la 
  touche X enlve le bloc de texte et le place dans le presse papier.
  -2- Copier: CONTROL C  l'appui sur la touche CONTROL en meme temps que la 
  touche C copie le bloc de texte dans le presse papier, sans l'effacer.
  -3- Coller: CONTROL V  l'appui sur la touche CONTROL en meme temps que la 
  touche V , insre le contenu du presse papier au niveau du curseur 
  texte clignotant et,
         SI celui-ci est dans ou juste devant un bloc texte, le bloc texte est 
            effac avant insertion du presse papier. 
         SI celui-ci n'est pas dans ni juste devant un bloc texte, l'insertion 
            du presse papier se fait sans effacement du bloc texte.
  -4- La saisie d'un caractre au clavier alors qu'un bloc texte est dfini,
  remplace le bloc texte par ce caractre, si le curseur texte est  
  l'intrieur ou juste devant ce bloc texte, sinon le caractre est insr sans 
  effacement du bloc texte.

 GESTION DU CURSEUR TEXTE:
  ------------------------
  Les touches flches <- et -> du clavier dplacent le curseur texte d'un 
  caractre vers la droite ou la gauche. Si associes  SHIFT le dplacement 
  se fait au dbut ou  la fin de l'ditable.
  Les touches flches haut et bas dplacent le curseur d'un ditable  
  l'autre.  
  
 CHAINE DE VALIDITE ETENDUE:
  --------------------------
  La chaine de validit permettant de filtrer la saisie des caractres a les
  memes caractristiques que celle habituelle du GEM. Quelques possibilits
  nouvelles peuvent etre employes:
  
        'c','C': Autorisent la saisie des:
                 chiffres "0  9" des virgules et point ".,", des signes 
                 "+-*/^", des accolades parenthses et crochets "(){}[]"
        'l','L': Uniquement les chiffres "0-9" sont autoriss et leur 
                 affichage est transform en caractres LED.
        '1'    : Seuls les "1 et 0" peuvent etre saisis pour les chiffres 
                 binaires.
        '7'    : Seuls les "01234567" peuvent etre saisis pour les chiffres
                 octaux.
        '9'    : Seuls les "0123456789" peuvent etre saisis pour les chiffres
                 dcimaux.                
        'h'    : Seuls les "0123456789" et "abcdef", pour la saisie des
                 chiffres hexadcimaux.
        'H'    : Seuls les "0123456789" et "ABCDEF", pour la saisie des
                 chiffres hexadcimaux.         
        'u',   : Saisie des ASCII 32  127 les majuscules sont transformes en  
                 minuscules.
        'U'    : Saisie des ASCII 32  127 les minuscules sont transformes  
                 en majuscules.
        'v',   : Saisie des ASCII 32  255 les majuscules sont transformes en  
                 minuscules.
        'V'    : Saisie des ASCII 32  255 les minuscules sont transformes  
                 en majuscules. 
        'w','W': Saisie des  ASCII 32-127 minuscules et majuscules sont 
                 possibles.
        'y','Y': Saisie des  ASCII 32-255 minuscules et majuscules sont 
                 possibles.
         


////////////////////////////////////////////////////////////////////////
/////////////////////-- VIII  -- LES OBJETS ETENDUS ////////////////////
////////////////////////////////////////////////////////////////////////

Ces nouveaux objets vont vous simplifier la programmation par leur puissance
et diversite. ILS NE FONCTIONNENT QUE SI ILS SONT MANIPULES AVEC LES NOUVELLES
FONCTIONS DE GESTION DE RESSOURCE EN FENETRE SELON EAZY_GEM !!!
Nous aborderons plus loin comment gerer une ressource en fenetre avec EAZY_GEM.

EAZY_GEM ajoute trois autres types de boutons. Ils ont la proprit  d'etre 
scalables lors des affichages en mode  non standard du GEM, de  plus  l'criture
en relief est possible.

Les cadres  de  groupe servent  entourer un groupe d'objets avec un cadre en 
relief, et un  titre inscrit dans la ligne suprieure du cadre, de faon   
signaler  l'utilisateur la nature des objets entours par le cadre.

    CADRE GROUPE  BORDS FINS       100
     -------------------------
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 100
                           bit 11 de ob_flags  1 pour effet texte grav
                           
les cadres de groupe se dfinissent en  crant un objet de type G_BOXTEXT  (type 
BoxText  sous  Interface) dont le  type  tendu doit etre: 100. Le style  relief
du texte  est  mis en plaant le bit 11 de ob_flags  1; La titre du cadre est  
celui de la chaine  de caractres de la G_BOXTEXT.

    CADRE GROUPE  BORDS EPAIS      101
     --------------------------
                          type G_BOXTEXT  (type BoxText sous Interface)
                          type tendu doit etre: 101
                          bit 11 de ob_flags  1 pour effet texte grav
                          
les cadres de groupe se dfinissent en  crant un objet de type G_BOXTEXT (type  
BoxText  sous Interface) dont le  type  tendu doit etre: 101. Le style  relief
du texte  est  mis en plaant le bit 11 de ob_flags  1; La titre du cadre est   
celui de la chaine de caractres de la G_BOXTEXT. 

    LES BOUTONS EAZY:              102
   ------------------ 
                         type G_BOXTEXT  (type BoxText sous Interface)
                         type tendu doit etre: 102
                         bit 11 de ob_flags  1 pour effet texte grav
                         drapeau Radiobutton pour agir en Radio Bouton
                         
Les boutons EAZY se dfinissent en crant un objet de type G_BOXTEXT, (type
BoxText sous Interface) dont le type tendu doit etre: 102. Le  style  relief
du texte est mis en plaant le bit 11 de ob_flags  1; Le drapeau Radiobutton 
doit etre plac pour avoir le fonctionnement en radio boutons GEM.

    LES BOUTONS RADIO:             103
   -------------------
                         type G_BOXTEXT  (type BoxText sous Interface)
                         type tendu doit etre: 103
                         bit 11 de ob_flags  1 pour effet texte grav
                         drapeau Radiobutton pour agir en Radio Bouton
                         
Les radios boutons se dfinissent en crant un objet de type G_BOXTEXT, (type
BoxText sous Interface) dont le type tendu doit etre: 103. Le  style  relief
du texte est mis en plaant le bit 11 de ob_flags  1; Le drapeau Radiobutton 
doit etre plac pour avoir le fonctionnement des radio boutons GEM.

    LES BOUTONS A COCHER:          104
   ----------------------
                            type G_BOXTEXT  (type BoxText sous Interface)
                            type tendu doit etre: 104
                            bit 11 de ob_flags  1 pour effet texte grav
                            drapeau Radiobutton pour agir en Radio Bouton
                            
Les boutons  cocher se dfinissent en crant un objet de type G_BOXTEXT, 
(type BoxText sous Interface) dont le type tendu doit etre: 104. Le  style  
relief du texte est mis en plaant le bit 11 de ob_flags  1; Le drapeau 
Radiobutton doit etre plac pour avoir le fonctionnement en radio boutons GEM.                            

    LE BOUTON ETAT DE LA BULLE     105
   ----------------------------
                            type G_BOXTEXT  (type BoxText sous Interface)
                            type tendu doit etre: 105
Cet  objet trs particulier sert   reprsenter  l'tat actif  ou inactif des 
bulles d'aide. Il permet  aussi d'activer ou de dsactiver le systme de bulles 
d'aide. Ce bouton se dfini en crant un objet de type G_BOXTEXT (type BoxText
sous Interface) dont le type  tendu  doit etre: 105. Ce bouton  tant de petite
taille, un rectangle de 16 par 16 suffit.

    LE CADRE VIDE                  109
   ---------------
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 109
les cadres vides se  dfinissent en   crant   un objet  de  type G_BOXTEXT 
(type    BoxText  sous Interface) dont le  type  tendu doit etre: 109. Ce  
cadre   n'est pas dssin. Cela est utile dans certains  cas  particuliers pour
les boites   onglets, lorsqu'on ne  veut  pas  faire apparaitre l'objet pre   
contenant les objets d'un dialogue.   

     LES PAINT_BOX                 215
    ---------------
                           Une PAINT_BOX (est un objet quelconque sauf:
                                          une G_CICON, une G_FTEXT editable ou
                                          ou G_FBOXTEXT  ditable)
                           Le type etendu doit etre: 215
Cet objet a la particularit lors de son redessin, d'envoyer  la procedure de
fenetre contenant la ressource a laquelle il appartient, un message WM_PAINTBOX
structure comme suit:

En: Evnt->pipe[X_G], Evnt->pipe[Y_G], Evnt->pipe[W_G], Evnt->pipe[H_G], se 
trouvent les coordonnes du rectangle de clipping (deja clipp par EAZY_GEM).
En: Evnt->pipe[X_B], Evnt->pipe[Y_B], Evnt->pipe[W_B], Evnt->pipe[H_B], se 
trouvent les coordonnes du rectangle de l'objet PAINT_BOX qu'il convient de
tracer.
En: Evnt->pipe[12]   se trouve le numero de l'objet qu'il faut retracer.                

Il est donc possible de creer des objets dont l'affichage est  votre charge et 
permet de laisser libre cours  votre imagination. l'avantage par rapport aux 
G_USERDEF, est que le redessin n'est pas en mode superviseur, et qu'il est 
possible d'appeler toutes les fonctions du GEM !!.

     LES LISTBOX:                 106
    -------------
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 106
                           Chaine de la G_BOXTEXT avec syntaxe particulire.

Une LIST_BOX  est  un  objet qui permet  l'affichage  d'une liste droulante,   
et la slection d'un lment de la liste. Cette liste peut scroller  l'aide    
de  deux flches de dfilement.
Leur fonctionnement et description en detail feront l'objet d'un chapitre  
part.

     LES SCROLLBOX                 111
    ---------------
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 111
                           Chaine de la G_BOXTEXT avec syntaxe particulire.
                           
Une SCROLLBOX  est un  objet qui permet  l'affichage  d'un document, dans une 
boite. Il est possible de faire scroller le document en vertical et horizontal  
l'aide de commandes de scrolling envoyes  l'aide d'une fonction ddie  cet
usage.
Leur fonctionnement et description en detail feront l'objet d'un chapitre  
part.

     LES CONTROLES DE SCROLLING    207 208 209 210 211 212 213 214 
    ----------------------------                  
                           Objet quelconque sauf une G_CICON, une G_FTEXT 
                           ditable ou G_FBOXTEXT  ditable, 

Un controle de scrolling est un objet quelconque sauf une G_CICON, une G_FTEXT 
ditable ou G_FBOXTEXT  ditable, auquel l'on rajoute l'un des types tendus 
suivants, selon l'action qu'on lui ddie. Ces objets servent  controler le
defilement des SCROLLBOX.

   Type       Symbole      Type de controle
   tendu     EAZY_GEM     activ


   207       SCROLLV_UP    fait defiler d'une ligne vers le haut               
   208       SCROLLV_DW    fait defiler d'une ligne vers le bas            
   209       SCROLLV_AS    ascenceur vertical  (fils de 210 SCROLLV_BAR)                              
   210       SCROLLV_BAR   barre de scrolling mere de l'objet precedent   

   211       SCROLLH_LF    fait defiler d'une ligne vers la gauche           
   212       SCROLLH_RG    fait defiler d'une ligne vers la droite         
   213       SCROLLH_AS    ascenceur horizontal (fils de 214 SCROLLH_BAR)                           
   214       SCROLLH_BAR   barre de scrolling mere de l'objet precedent    
                           
Pour faire scroller une SCROLBOX soit vous placez vos objets de scrolling, 
flches de dfilement, barre d'ascenseur etc..., et lors d' un click sur chacun  
de ces objets vous faites scroller la SCROLBOX, faites les mises  jour des 
ascenseurs vous meme, etc.. soit vous laissez EAZY_GEM s'occuper de tout !!!.

L'ascenceur doit etre obligatoirement  l'intrieur d'une barre de scrolling, 
donc fils de la barre de scrolling.
Le reste des objets doivent etre frres, de la SCROLBOX.

Si vous respectez ces rgles simples, la  SCROLBOX  sera automatiquement pilote 
par ces controles. Il est conseill de placer l'ensemble  SCROLBOX et ses 
controles comme fils d'un autre objet surtout si l'on veut placer plusieurs 
SCROLBOX au sein du meme dialogue.

     LES MENUS EN FENETRE:         107
    ----------------------
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 107
                           Chaine de la G_BOXTEXT avec le nom du menu.
                           TOUCHE EXIT et SELECTABLE.
Un menu en fenetre est compos de deux lments:
   
  -1- une  G_BOXTEXT  (type BoxText sous Interface) avec type tendu 107 (type 
      EAZY_GEM WINDMENU). La largeur de cette G_BOXTEXT doit etre de celle 
      qu'occuperont les titres de menus.  Les attributs de remplissage et de 
      texte seront ceux utiliss pour la reprsentation du menu. Cette G_BOXTEXT 
      doit etre place  l'endroit o doit etre affich le menu sur votre boite 
      de dialogue. C'est en quelque sorte un installateur de menu. 
      La chaine de caractres de cette G_BOXTEXT doit etre gale au premier 
      titre de l'arbre de menu que l'on dsire installer comme menu.
      L'attribut OUTLINED permet de souligner le menu.
  
  -2- Un  Arbre de menu classique, dont le premier titre (celui donnant accs 
      aux accessoires) comporte le nom de ce menu, qui doit etre le meme que le 
      texte de la chaine de caractres de la G_BOXTEXT, devant l'installer dans 
      un dialogue. Les accessoires tant inutiles dans un menu en fenetre, le 
      menu et les options correspondantes ne sont pas affichs.
      
CONSEQUENCES:

  Lors d'un click sur une option de ce menu il est gnr le message WM_WND_MENU 
  structur de la faon suivante:
  
  en  Evnt->pipe[MESG] = WM_WND_MENU (message envoy)                      
      Evnt->pipe[APPL] = identificateur de l'application        
      Evnt->pipe[SUPL] = 0 (pas de surplus)                     
      Evnt->pipe[WHND] = handle fenetre contenant ressource       
      Evnt->pipe[X_G]  = numero de l'item selectionn        
                         comme dans les menu GEM classiques.                           
      Evnt->pipe[Y_G]  = numero de l'arbre de menu                                                             
      *(long*)Evnt->pipe[W_G] adresse arbre menu, cela permet de distinguer 
                             le menu en fenetre dans le cas de plusieurs 
                             menus dans la meme  fenetre (c'est possible !!
                             !! avec EAZY_GEM) 
  
       
Vous voyez qu'il est possible de placer plusieurs menus dans la meme boite de 
dialogue en plaant plusieurs G_BOXTEXT WINDMENU (Xtented type 107) lies 
chacune par leurs chaines de caractres  un arbre de menu.

     LES DIALOGUES MULTIPLES:         
    -------------------------
    Leur fonctionnement et description en detail feront l'objet d'un chapitre  
part.

     LES BOITES A ONGLETS:            
    ----------------------
    Leur fonctionnement et description en detail feront l'objet d'un chapitre  
part.

////////////////////////////////////////////////////////////////////////
/////////////////////-- IX  -- LES LISTBOX /////////////////////////////
////////////////////////////////////////////////////////////////////////

a) DEFINITION:
-------------                   
                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 106
                           Chaine de la G_BOXTEXT avec syntaxe particulire.

Une LIST_BOX  est  un  objet qui permet  l'affichage  d'une liste droulante,   
et la slection d'un lment de la liste. Cette liste peut scroller  l'aide    
de  deux flches de dfilement.

Cette liste  possde deux tats:

Un tat ferm ou  elle se rduit   une  case  dans laquelle   se  trouve  le    
        rsultat du  choix. C'est la case de slection.

Un tat  ouvert  ou une liste de choix se droule sous la case de slection.     
        Cette liste est compose de cases de liste.


    Vue d'une LISBOX ferme:           Vue d'une LISBOX ouverte:
  _____________________________     _____________________________
 | case de slection       |  |   | case de slection       |  |
  -----------------------------    |-------------------------|---|
                                   | premiere case de liste  |  | 
                                   |-------------------------|---|
                                   | deuxieme case de liste  |   | 
                                   |-------------------------|   |
                                   | troisieme case de liste |   |
                                   |-------------------------|   |
                                   | quatrieme case de liste |   |
                                   |-------------------------|   |
                                   | cinquieme case de liste |   |
                                   |-------------------------|---|
                                   | dernire case de liste  |  |
                                    -----------------------------
 
Une LIST_BOX se  cre en plaant un objet de type G_BOXTEXT,(type BoxText sous 
Interface) dont le type tendu doit etre: 106

IMPORTANT:
---------
Lorsque vous placez  des LISTBOX sur  un  formulaire, dbrouillez
vous  ce qu'elles soient dessines en dernier, afin que ouver-
tes, elles ne soient  pas recouvertes  par   un  objet  dessin
aprs. Utilisez  la  fonction de tri invers d'Interface.

b) LES LISTBOX STANDARDS:
------------------------
                  
La chaine de  caractre de cette G_BOXTEXT  permet  de paramtrer le            
fonctionnement de la LIST_BOX en  fournissant  des  paramtres spars par des    
virgules.
Cette possibilit de paramtrage par l'intermdiaire de la chaine
de caractres des objets GEM est trs souvent utilise dans EAZY-GEM.

La syntaxe de  cette  chaine est la suivante:

le  premier  paramtre   indique le type  de LIST_BOX.  La  liste
des types  standards  est donne ci_dessous  avec   le  paramtre 
allant avec. (entre guillemets). Il  existe 6  types standards de
LIST_BOX pour: 
     Affichage et slection des 
      polices de caractres.
      "FntSel"
     Affichage et slection des 
      tailles polices de caractres.
      "FntPts"  
     Affichage et slection des 
      trames de remplissage.
      "Patern"
     Affichage et slection des 
      types de lignes.
      "LgnSel"
     Affichage et slection des 
      tailles de caractres.
      "LgnTyp"
     Affichage et slection des 
      effets de texte.
      "TxtEff"
     Affichage et slection des 
      couleurs.      
      "Color"

Le deuxime paramtre (spar du premier par une virgule) indique
le  nombre  d'lments que  doit afficher la LIST_BOX. Exemple si
c'est  6  la   LIST_BOX  ouverte s'affichera sur 6 lignes.

Le troisime paramtre (spar du deuxime par une virgule) indique
un nombre qu'il vous  est  libre de choisir, et qui sera retourn
avec le message WM_EXECFUNC lors d'un click sur  un lment de la
LIST_BOX. Cela permet d'orienter la rponse lors  d'un click, sur
un dispatcheur de fonctions. Cette  option  falcultative, est
l  pour  faciliter la  programmation.  

EXEMPLE:
Une  LISTBOX  pour  afficher les polices de caractres, sur  sept
lignes  et  devant  produire  un message WM_EXEFUNC  avec  comme
chiffre 254 doit avoir sa chaine de caractres comme suit:

    FntSel,7,254

Faites attention au paramtre du nombre de lignes. Si il est trop
grand et  que la liste  droule ne  peut  pas  tenir,  car  elle
dpasse le bas de sa fenetre, la LISTBOX ne  s'ouvrira  pas  lors 
d'un click sur son bouton  d'ouverture.


c) LES LISTBOX CUSTOM
---------------------
                    
En dehors des LISTBOX  standards prdfinies qu'offre EAZY_GEM il
est possible d'en  dfinir d'autres, adaptes  un usage parti-
culier. Pour  cela  il vous faut en crer une avec le premier pa-
ramtre  vide (un  espace  ou un mot  n'tant pas  gal   un  de 
ceux  vus  plus haut). Alors  la LISTBOX se contentera d'afficher
ligne 1, ligne 2, ligne 3... etc Pour  modifier  le  comportement
et cet affichage un peu sommaire EAZY_GEM met  votre disposition
plusieurs  fonctions  dont voici les prototypes et  les  descrip-
tions:

/*--------------------------- SetListCallBackFunc ----------------------------*/
/* ACTION: Cette  fonction  permet de modifier la fonction d'affichage        */
/*         la LIST_BOX, ou d'une SCROLLBOX.                                   */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/*         Dans le paramtre: void *func l'on  place l'adresse de la fonction */
/*                            devant afficher les cases de la LISTBOX. Cette  */
/*                            fonction doit bien sur etre ecrite par vous.    */
/* RETOUR: l'adresse de l'ancienne fonction de gestion.                       */                                                   
                         
void *SetListCallBackFunc ( OBJECT *tree, int   ind_ob, void *func ) 
        


/*--------------------------- SetListBoxParam --------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la LIST_BOX.                                                       */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la LISTBOX,                         */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/*         Dans le paramtre: int   select l'on  place le numero de l'lment */
/*                            de la  liste    reprsenter devant etre affich*/
/*                            dans la case de slection (premier lment de la*/
/*                            LISTBOX).                                       */
/*         Dans le paramtre: int first, l'on place le numero de l'lment de */
/*                            la liste  reprsenter,devant etre affich dans */
/*                            la premire  case de liste (celle situe sousla */
/*                            case de slection, soit le deuxime  lment de */
/*                            la LISTBOX).                                    */
/*         Dans le paramtre: int nbcases l'on  place le nombre d'lments que*/
/*                            doit comporter la  LISTBOX, y compris la case de*/
/*                            slection.                                      */
/*         Dans le paramtre: int nb_item l'on place le nombre d'lments     */
/*                            de la liste  reprsenter.                      */
/*         Dans le paramtre: int h_lign l'on  place la hauteur d'une case de */
/*                            la  LISTBOX.                                    */
/*         Dans le paramtre: void *LstBoxParam l'on peut placer ce que l'on  */
/*                            veut, une adresse de donnes, ou tout autre     */
/*                            chose. Ce  paramtre est transmis  la fonction */
/*                            d'affichage de la LISTBOX.                      */
/* RETOUR: 0 erreur (ce n'est pas une LISTBOX)                                */
/*         1 tout est Ok                                                      */
                                               
int SetListBoxParam 
     ( OBJECT *tree,
       int   ind_ob,
       int select,
       int first,
       int nbcases,
       int nb_item,
       int h_lign,   
       void *LstBoxParam    
     )
          
/*------------------------GetSelectedListBoxItem------------------------------*/
/* ACTION: cette fonction permet d'obtenir l'indice (base 0) de l'element     */
/*         selectionne dans une LISTBOX, cet indice pointe donc sur une       */
/*         donnee de la liste.                                                */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/* RETOUR: indice (base 0) de l'element selectionne dans une LISTBOX, cet     */
/*         indice pointe donc sur une donnee de la liste. C'est cette donne  */
/*         qui doit etre affichee dans la boite de selection.                 */
                                                 
int GetSelectedListBoxItem(OBJECT *object, int ind)



/*--------------------------- GetListBoxParam --------------------------------*/     
/* ACTION: Cette  fonction  permet d'obtenir les parametres de fonctionnement */
/*         la LIST_BOX.                                                       */
/*         Si vous fournissez la valeur 0, pour une adresse de parametre, le  */
/*         parametre correspondant ne sera pas retourn.                      */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *select, l'on reoit le numero de l'lment */
/*                            de la  liste    reprsenter devant etre affich*/
/*                            dans la case de slection (premier lment de la*/
/*                            LISTBOX).                                       */
/*         Dans le paramtre: int *first, l'on  reoit le numero de l'lment */
/*                            de la liste  reprsenter,devant etre affich   */
/*                            dans la premire  case  de  liste (celle situe */
/*                            sous la case de slection, soit le deuxime     */
/*                            lment  de la LISTBOX).                        */
/*         Dans le paramtre: int *nbcases, l'on reoit le nombre d'lments  */
/*                            que doit comporter la  LISTBOX, y compris la    */
/*                            case de slection.                              */
/*         Dans le paramtre: int *nb_item, l'on reoit le nombre d'lments  */
/*                            de la liste  reprsenter.                      */
/*         Dans le paramtre: int *h_lign, l'on reoit la hauteur d'une case  */
/*                            la  LISTBOX.                                    */
/*         Dans le paramtre: void *LstBoxParam, l'on reoit le parametre     */
/*                            optionnel.                                      */
/* RETOUR: 0 erreur (ce n'est pas une LISTBOX)                                */
/*         1 tout est Ok                                                      */

void *GetListBoxParam 
     ( OBJECT *tree,
       int   ind_ob,
       int *select,
       int *first,
       int *nbcases,
       int *nb_item,
       int *h_lign,   
       void *LstBoxParam    
     )


     
d) LA FONCTION D'AFFICHAGE LISTBOX CUSTOM:
-----------------------------------------

Cette fonction est  celle  qu'il est   votre  charge d'crire si
vous dsirez  crer une  LISTBOX adapte  un besoin particulier.
Cette  fonction   devra  pouvoir afficher chacune des cases de la
LISTBOX, et  sera appele par la LISTBOX chaque fois qu'elle aura
 afficher ou  mettre  jour une ou plusieurs de ses cases.
IMPORTANT:il est impossible d'utiliser des fonctions faisant des appels GEM dans
--------- ces fonctions. Tous les autres appels VDI, GEMDOS, XBIOS, BIOS sont
          autoriss.  
L'adresse de cette fonction doit etre fournie   la  LISTBOX  par
l'intermdiaire de la fonction: SetListCallBackFunc() vue plus haut.


La fonction d'affichage doit etre crite selon le prototype suivant:

/*------------------------ RoutineAffichage ----------------------------------*/
int RoutineAffichage(void *adr)

Le paramtre: void *adr transmis par la LISTBOX sert  nous rens-
seigner sur ce qu'il  faut afficher. Il pointe sur la structure
suivante:

typedef struct                                                          
 {int lign;  
  int preml;  
  int pointl; 
  int h_lign; 
  GRECT grect; 
  GRECT clipgrect; 
  void *LstBoxParam;                    
 }LIST_GET_TXT;     

Le paramtre:  int lign  est  le numro  de  la  case  afficher,
c'est  en   testant ce paramtre que l'on  sait la case qu'il est
demande d'afficher.
                           Si -1
c'est la case de slection qu'il convient d 'afficher, 
                           Si  0
c'est la  premire case de liste qu'il convient d'afficher,  
                           Si  1
c'est la deuxime  case de liste qu'il convient d'afficher, etc..

Le paramtre:  int preml  est le numro de l'lment de  la liste
 reprsenter devant  etre affich en deuxime case.

Le paramtre:  int pointl est le numro de l'lment de  la liste
 reprsenter, devant etre affich en case  de slection. C'est
ce numro  qui  est retourn par la fonction: GetSelectedListBoxItem
          
Le paramtre:  int h_lign est la hauteur en pixels  d'une case de   
la LISTBOX.

Le paramtre: GRECT grect est le rectangle indiquant les coordon-
nes en pixels de la liste.

Le  paramtre:  GRECT  clipgrect est le rectangle de clipping que
le GEM nous impose pour le redessin.

Le  paramtre: void *LstBoxParam est le  paramtre  optionnel tel
qu'il a t plac plus haut. 

La Rcupration des  coordonnes et  des  donnes    reprsenter
de la  case  afficher, se  fait de la faon suivante:

Petit exemple pour comprendre

int RoutineAffichageListBox(void *adr)
{
/*  dclarer un rectangle de  */
/*      de coordonnes.       */

RECT coord; 

/* dclarer un pointeur sur la structure de parametres  */
/* et l'initialiser sur les parametres d'entre         */

LIST_GET_TXT *LST;
LST =  (LIST_GET_TXT*) adr;

/* Calcul des coordonnes du rectangle de la case       */
/* qu'il faut afficher                                  */

coord.left   = LST->grect.g_x;  
                     
coord.top    = LST->grect.g_y +                     
               LST->h_lign    *                     
              (LST->lign + 1); 
                                     
coord.right  = LST->grect.g_x +                     
               LST->grect.g_w - 
              1;          
                       
coord.bottom = coord.top      + 
               LST->h_lign   -1;

/* l vous faites ce que vous voulez dans ce rectangle    */
/* en fonction du numero de case  afficher: LST->lign    */
/* et de la donne  afficher qui est:                    */
/*                                                        */
/*           Soit celle slectionne                      */
/*                (si LST->lign == -1) l'indice de donne */
/*                 est alors: LST->pointl                 */
/*                                                        */
/*           Soit une autre case                          */
/*                (si LST->lign > -1) l'indice de donne  */
/*                 est alors: LST->lign + LST->preml      */ 


 return 1;
}
 
////////////////////////////////////////////////////////////////////////
/////////////////////-- X  -- LES SCROLLBOX ////////////////////////////
////////////////////////////////////////////////////////////////////////

                           type G_BOXTEXT  (type BoxText sous Interface)
                           type tendu doit etre: 111
                           Chaine de la G_BOXTEXT avec syntaxe particulire.

a) DEFINITION:
-------------
                           
Une SCROLLBOX  est un  objet qui permet  l'affichage  d'un document, dans une 
boite. Il est possible de faire scroller le document en vertical et horizontal  
l'aide de commandes de scrolling envoyes  l'aide d'une fonction ddie:

 DoScrollBoxSlide(int w_ind, OBJECT *tree, int ind_ob, int n_vert, int n_hor ); 
    
Une SCROLLBOX se cre en plaant un objet de type G_BOXTEXT,(type BoxText sous  
Interface)  dont le type tendu doit etre: 111

b) LES SCROLLBOX STANDARDS:
--------------------------

SCROLTEXT: est une SCROLBOX avec affichage automatique d'un texte dont le 
           le nom de fichier et le paramtrage du style, taille, police, est 
           donn au travers de la chaine de la G_BOXTEXT.
                       
La chaine de  caractre de cette G_BOXTEXT  permet  de paramtrer le 
fonctionnement  de la SCROLBOX en  fournissant  des  paramtres spars par des  
virgules. Cette possibilit de paramtrage par l'intermdiaire de la chaine de  
caractres des objets GEM est trs souvent utilise dans EAZY-GEM.

La syntaxe de  cette  chaine est la suivante:

le premier paramtre indique  le nom du fichier ascii devant etre affich.
            Ce  fichier doit se trouver dans le meme repertoire que les fichiers 
            de ressources  de l'application.

Le deuxime paramtre (spar du premier par une virgule) indique le  nombre de  
            pixels de  hauteur sparant deux lignes de texte.

Le troisime paramtre(spar du deuxime par une virgule)indique La taille en   
            points de la police de caractre.  

Le quatrime paramtre(spar du deuxime par une virgule) indique le nom de la  
            police devant etre employe  pour  l'affichage.  Si elle n'est pas  
            active, la police sytme sera employe. 


    SCROLBOX.TXT,12,9,Courier



c) LES SCROLBOX CUSTOM:
----------------------
                     
En dehors des SCROLBOX standards prdfinies qu'offre EAZY_GEM il est possible  
d'en  dfinir d'autres, adaptes  un usage particulier. 
L'organisation de la surface d'une SCROLBOX est divis en lignes et colonnes, 
ceci pour pouvoir scroller latralement et verticalement. De meme cela permet de 
dfinir une surface quadrille, utile par exemple pour prsenter des rectangles 
de trames, ou de couleurs, ou tout autre dlire que votre imagination peut 
gnrer.
Pour crer une  SCROLBOX CUSTOM il faut crer une G_BOXTEXT ,(type BoxText sous  
Interface)  dont le type tendu doit etre: 111, comme pour une SCROLBOX standard 
mais avec le premier paramtre de la chaine, vide (espace  ou un mot n'tant pas  
gal  un nom de fichier valide). Alors  la  SCROLBOX se contentera d'afficher:
ligne 1, ligne 2, ligne 3... etc.

d) CONTROLER LES SCROLBOX CUSTOM:
--------------------------------

Pour  modifier  le  comportement et cet affichage un peu sommaire EAZY_GEM met 
 votre disposition plusieurs  fonctions dont voici les prototypes et  les  
descriptions:

/*--------------------------- SetListCallBackFunc ----------------------------*/
/* ACTION: Cette  fonction  permet de modifier la fonction d'affichage  d'une */
/*         LIST_BOX, ou d'une SCROLLBOX.                                      */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/*         Dans le paramtre: void *func l'on  place l'adresse de la fonction */
/*                            devant afficher les cases de la LISTBOX. Cette  */
/*                            fonction doit bien sur etre ecrite par vous.    */
/* RETOUR: l'adresse de l'ancienne fonction de gestion.                       */                                                   
                         
void *SetListCallBackFunc ( OBJECT *tree, int   ind_ob, void *func ) 

                        

/*--------------------------- SetScrollBoxParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLBOX.                                                       */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLBOX.                    */                                
/*         Dans le paramtre: int  LgnH  hauteur en pixels d'une ligne de     */
/*                             scrolling c'est de cette distance dont scrolle */
/*                             en vertical la boite.                          */
/*         Dans le paramtre: int  ClnW  largeur en pixels d'une colonne      */
/*                            scrolling  c'est de cette distance dont scrolle */
/*                            en horizontal la boite.                         */
/*         Dans le paramtre: int NbLgn nombre de lignes total (hauteur totale*/
/*                            du document / LgnH ).                           */
/*         Dans le paramtre: int NbCln nombre de colonnes total (largeur     */
/*                            totale du document / ClnW ).                    */     
/*         Dans le paramtre: int FstLgn indice de la ligne de scrolling     */
/*                            placer en haut e la boite  (offset d'affichage  */ 
/*                            vertical).                                      */
/*         Dans le paramtre: int FstCln indice de la colonne de scrolling   */
/*                            placer  droite de la boite  (offset d'affichage*/ 
/*                            horizontal).                                    */     
/*         Dans le paramtre: int LgnSlct indice de la ligne document         */
/*                            slectionne.                                   */
/*         Dans le paramtre: int ClnSlct indice de la colonne document       */
/*                            slectionne.                                   */
/*         Dans le paramtre: void *SclBoxParam  l'on  peut  placer  ce  que  */
/*                            l'on veut, une adresse de donnes, ou tout autre*/
/*                            chose. Ce  paramtre est transmis  la fonction */
/*                            d'affichage de la SCROLBOX.                     */
/*         Dans le paramtre: int Do, l'on  peut  placer une valeur qui       */
/*                            modifiera le comportement de la sroll_box lors  */
/*                            d'un affichages: si LST_DRAW elle sera dessinee */
/*                                             normalement.                   */
/*                                             si LST_NODRAW elle ne sera pas */
/*                                             redessinee.                    */                 
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         1 tout est Ok                                                      */     

int SetScrollBoxParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */
        int LgnH,          /* hauteur en pixels d'une ligne de scrolling      */
        int ClnW,          /* largeur en pixels d'une colonne scrolling       */
        int NbLgn,         /* Nombre total de lignes document                 */     
        int NbCln,         /* nombre total de colonnes document               */
        int FstLgn,        /* indice ligne document  afficher en 1er         */ 
        int FstCln,        /* indice colonne document  afficher  gauche     */
        int LgnSlct,       /* ligne selectionne ( mettre en surbrillance)   */ 
        int ClnSlct,       /* colonne selectionne ( mettre en surbrillance) */
        void *SclBoxParam, /* paramtre optionnel  type de pointeur          */    
        int Do,            /* parametre d'action                              */
      )  
                 
/*--------------------------- GetScrollBoxParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLBOX.                                                       */
/*         Si vous fournissez la valeur 0, pour une adresse de parametre, le  */
/*         parametre correspondant ne sera pas retourn.                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int ind_ob l'on doit placer l'indice de l'objet */
/*                            correspondant  la SCROLBOX.                    */                                
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *LgnH on reoit la hauteur en pixels d'une  */
/*                            ligne de scrolling c'est de cette distance dont */
/*                            scrolle en vertical la boite.                   */
/*         Dans le paramtre: int *ClnW  on reoit la largeur en pixels d'une */
/*                            colonne scrolling  c'est de cette distance dont */
/*                            scrolle en horizontal la boite.                 */
/*         Dans le paramtre: int *NbLgn l'on reoit le nombre de lignes total*/
/*                            (hauteur totale du document / LgnH ).           */
/*         Dans le paramtre: int *NbCln on reoit le nombre de colonnes total*/
/*                            (largeur totale du document / ClnW ).           */     
/*         Dans le paramtre: int *FstLgn l'on reoit l'indice de la ligne de */
/*                            scrolling  placer en haut e la boite  (offset  */ 
/*                            d'affichage vertical).                          */
/*         Dans le paramtre: int *FstCln on reoit l'indice de la colonne de */
/*                            scrolling  placer  droite de la boite  (offset*/ 
/*                            d'affichage horizontal).                        */     
/*         Dans le paramtre: int *LgnSlct l'on reoit l'indice de la ligne   */
/*                            document slectionne.                          */
/*         Dans le paramtre: int *ClnSlct l'on reoit indice de la colonne   */
/*                            document slectionne.                          */
/*         Dans le paramtre: long *SclBoxParam l'on reoit le parametre      */
/*                            optionnel.                                      */
/*         Dans le paramtre: int *NbCase l'on reoit le nombre de lignes       */
/*                            affichables dans la scrollbox                     */
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         adresse de la structure TEDINFO de cet objet                       */     

TEDINFO *GetScrollBoxParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */
        int *LgnH;         /* hauteur en pixels d'une ligne de scrolling      */
        int *ClnW;         /* largeur en pixels d'une colonne scrolling       */
        int *NbLgn;        /* Nombre total de lignes document                 */     
        int *NbCln;        /* nombre total de colonnes document               */
        int *FstLgn        /* indice ligne document  afficher en 1er         */ 
        int *FstCln        /* indice colonne document  afficher  gauche     */
        int *LgnSlct       /* ligne selectionne ( mettre en surbrillance)   */ 
        int *ClnSlct;      /* colonne selectionne ( mettre en surbrillance) */
        long *SclBoxParam  /* paramtre optionnel  type de pointeur          */          
        int *NbCase        /* nbr de cases afichables                         */     
      )
 
/*---------------------------- DoScrollBoxSlide ------------------------------*/     
/* ACTION: Cette fonction permet de modifier faire scroller la SCROLBOX, d'une*/
/*         certaine quantit de lignes en horizontal ou vertical.             */
/*         Si vous fournissez une valeur ngative le sens est vers le haut et */
/*         et la droite.                                                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int ind_ob l'on doit placer l'indice de l'objet */
/*                            correspondant  la SCROLBOX.                    */                                
/*         Dans le paramtre: int n_vert nbr de lignes verticales  scroller. */
/*         Dans le paramtre: int n_hori nbr de lignes horizontales  scroller*/
/*                            colonne scrolling  c'est de cette distance dont */
/*         Dans le paramtre: GRECT *clip_grect il doit etre donn            */
/*                            rectangle de clipping.                          */
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         1 tout est Ok                                                      */   

int DoScrollBoxSlide 
     ( 
      OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
      int ind_ob,        /* indice de l'objet dans l'arbre                  */
      int n_vert,        /* nombre de lignes  scroller                     */
      int n_hori,        /* nombre de colonnes  scroller                   */
      GRECT *clip_grect  /* rectangle de clipping                           */
     )

/*------------------------------ VascPosAdjust ---------------------------------------------*/
/* ACTION: calcule la position de l'ascenseur vertical d'une SCROLLBAR  partir des donnes */
/*         d'un objet de type SCROLLBOX.                                                    */
/* ENTREE: OBJECT *object:                                                                  */
/*            pointe sur le premier objet (objet racine) de l'arbre ou sont contenus les    */
/*            autres objets.                                                                */
/*         int ob_scroll: numero ou indice de l'objet SCROLLBOX dans cet arbre.             */
/*         int ob_Vbar:   numero ou indice de l'objet SCROLLBAR dans cet arbre.             */
/*                        une SCROLLBAR est un objet contenant un objet fils ascenseur.     */
/* RETOUR: int: position y de l'ascenseur. (en relatif  la SCROLLBAR ob_Vbar).             */

int VascPosAdjust(OBJECT *object, int ob_scroll, int ob_Vbar)

/*------------------------------ VascHeightAdjust ------------------------------------------*/
/* ACTION: calcule la taille de l'ascenseur vertical d'une SCROLLBAR  partir des donnes   */
/*         d'un objet de type SCROLLBOX. La donne: scrollboxblk->FstLgn est si besoin      */
/*         ajuste de facon  etre coherente.                                               */
/* ENTREE: OBJECT *object:                                                                  */
/*            pointe sur le premier objet (objet racine) de l'arbre ou sont contenus les    */
/*            autres objets.                                                                */
/*         int ob_scroll: numero ou indice de l'objet SCROLLBOX dans cet arbre.             */
/*         int ob_Vbar:   numero ou indice de l'objet SCROLLBAR dans cet arbre.             */
/*                        une SCROLLBAR est un objet contenant un objet fils ascenseur.     */
/* RETOUR: int: position y de l'ascenseur. (en relatif  la SCROLLBAR ob_Vbar).             */

int VascHeightAdjust(OBJECT *object, int ob_scroll, int ob_Vbar);

/*--------------------------- SetScrollTxtParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLTEXT.                                                      */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLTEXT,                       */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLTEXT.                   */                                
/*         Dans le paramtre: int  Clr  l'on  place la couleur du texte.      */
/*         Dans le paramtre: int Pts   l'on  place la taille du texte.       */
/*         Dans le paramtre: int Fnt   l'on  place l ID de la fonte.         */
/* RETOUR: 0 erreur (ce n'est pas une SCROLTEXT)                              */
/*         1 tout est Ok                                                      */ 

int SetScrollTxtParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */                
        int Clr,           /* couleur du texte                                */ 
        int Pts,           /* taille en point du texte                        */
        int Fnt            /* Police de caractere                             */             
      )

/*--------------------------- GetScrollTxtParam ------------------------------*/     
/* ACTION: Cette fonction permet de recuperer les parametres de fonctionnement*/
/*         la SCROLTEXT.                                                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLTEXT,                       */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLTEXT.                   */                                
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *Clr   l'on  reoit la couleur du texte.    */
/*         Dans le paramtre: int *Pts   l'on  reoit la taille du texte.     */
/*         Dans le paramtre: int *Fnt   l'on  reoit l'ID VDI de la fonte.   */
/* RETOUR: 0 erreur (ce n'est pas une SCROLTEXT)                              */
/*         adresse de la structure SCROLL_TXT_PRM                             */     
/* RAPPEL:                                                                    */
/*     typedef struct                                                         */
/*        { int Type;          type de donnes  afficher                     */
/*          char *txt;         adresse du texte                               */
/*          char **PtLgnTab;   adr. du tableau de pointeurs de lignes texte   */        
/*          int Pts;           taille en points des caractres                */
/*          int Color;         couleur des caractres                         */
/*          long FontId;       ID VDI de la police a employer pour l'affichage*/
/*        } SCROLL_TXT_PRM;                                                   */
SCROLL_TXT_PRM *GetScrollTxtParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */                
        int *Clr,           /* couleur du texte                               */ 
        int *Pts,           /* taille en point du texte                       */
        int *Fnt            /* Police de caractere                            */             
      )
                     
 e) LA FONCTION D'AFFICHAGE CUSTOM DES SCROLLBOX:
 -----------------------------------------------

Cette fonction est  celle  qu'il est   votre  charge d'crire si vous dsirez   
crer une SCROLBOX adapte  un besoin particulier. Cette  fonction devra 
pouvoir afficher chacune des lignes et colonnes de la SCROLBOX, et  sera appele 
par la SCROLBOX chaque fois qu'elle aura  afficher ou  mettre  jour une ou 
plusieurs de ses lignes ou colonnes (un parametre indiquera lesquelles).
Cette fonction est appele pour chaque ligne et ou colonne que la SCROLBOX aura
 dessiner. 
L'adresse de cette fonction doit etre fournie  la  SCROLBOX (afin qu'elle 
puisse l'appeler), par l'intermdiaire  de la fonction: SetListCallBackFunc, que 
nous avons vu plus haut. 
IMPORTANT:il est impossible d'utiliser des fonctions faisant des appels GEM dans
           ces fonctions. Tous les autres appels VDI, GEMDOS, XBIOS, BIOS sont
           autoriss.  
L'organisation de la surface d'une SCROLBOX est divis en lignes et colonnes, 
ceci pour pouvoir scroller latralement et verticalement. De meme cela permet de 
dfinir une surface quadrille, utile par exemple pour prsenter des rectangles 
de trames, ou de couleurs, ou tout autre dlire que votre imagination peut 
gnrer.    
Il est tout  fait possible de dfinir une SCROLBOX fonctionnant soit en 
vertical soit en horizontal en plaant les paramtres respectifs de lignes et de 
colonnes sur -1; 
           
La fonction d'affichage doit etre crite selon le prototype suivant:

int RoutineAffichageScrollBox(SCROLLBOX_GET_AFFI *SCRL);

Le paramtre: SCROLLBOX_GET_AFFI *SCRL transmis par la SCROLBOX sert  nous     
renseigner sur ce qu'il  faut afficher. Il pointe sur la structure suivante:

/* typedef struct                                                     */
/*  {int LgnH;               hauteur d'une ligne en pixel             */
/*   int ClnW;               largeur d'une colonne en pixel           */
/*   int FstLgn;             premiere ligne document en haut          */
/*   int FstCln;             premiere colonne document a gauche       */
/*   int LgnAff;             ligne SCROLBOX a afficher                */    
/*   int ClnAff;             colonne SCROLBOX a afficher              */
/*   int LgnSel;             ligne document selectionnee              */ 
/*   int ClnSel;             colonne document selectionnee            */  
/*   GRECT Grect;            dimensions rect affi SCROLBOX  en pixels */
/*   GRECT ClipGrect;        rectangle de cliping en cours            */
/*   void *ScrollBoxParam;   parametre de transmission optionnel      */
/*   int Back;               fond pour le redessin                    */
/*  }SCROLLBOX_GET_AFFI;                                              */


La fonction d'affichage doit pouvoir afficher soit une colonne soit une ligne 
soit les deux  la fois.

Si  SCRL->LgnAff  = -1 (ligne inactive)   alors on affiche une colonne,
Sinon il indique la ligne de  SCROLBOX   afficher.

Si  SCRL->ClnAff  = -1 (colonne inactive) alors on affiche une ligne.
Sinon il indique la colonne de  SCROLBOX   afficher.

Ces deux paramtres indiquent la portion du rectangle SCROLBOX qu'il 
nous est demand de rgnrer. 
      Si SCRL->LgnAff = 0 alors c'est un rectangle de SCRL->LgnH de haut et  
         de largeur du rectangle d'affichage de la SCROLBOX (SCRL->Grect.g_w),  
         et situ en haut de celui-ci.
      Si SCRL->LgnAff = 1 alors c'est un rectangle de SCRL->LgnH de haut et  
         de largeur du rectangle d'affichage de la SCROLBOX (SCRL->Grect.g_w),  
         et situ sous le prcdent.
         etc ...

Petit exemple pour comprendre

int RoutineAffichageScrolBox(SCROLLBOX_GET_AFFI *SCRL)
{
/*  dclarer un rectangle de  */
/*      de coordonnes.       */
/*  pour les lignes  et       */
/*  pour les colonnes.        */


GRECT Glgn,    /* rectangle pour les lignes   */
      Gcln;    /* rectangle pour les colonnes */


/* Calcul des coordonnes du rectangle de la ligne      */
/*  afficher                                           */
/* et afficher la ligne                                 */
if (SCRL->LgnAff > -1)
   {Glgn.g_x  = SCRL->Grect.g_x;                       
    Glgn.g_y  = SCRL->Grect.g_y +                     
                SCRL->LgnH      *                     
                SCRL->LgnAff;                                      
    Glgn.g_w  = SCRL->Grect.g_w - 1;                                 
    Glgn.g_h  = SCRL->LgnH      - 1;
    /* placez l les instructions de traage */
    /* de la ligne.                          */
   } 

/* Calcul des coordonnes du rectangle de la colonne    */
/*  afficher                                           */
/* et afficher la colonne                               */
if (SCRL->ClnAff > -1)
   {Gcln.g_x  = SCRL->Grect.g_x +;  
                SCRL->Clnw      * 
                SCRL->ClnAff;    
    Gcln.g_y  = SCRL->Grect.g_y;                                      
    Gcln.g_w  = SCRL->ClnW      - 1;                                 
    Gcln.g_h  = SCRL->Grect.g_h - 1; 
    /* placez l les instructions de traage */
    /* de la colonne.                        */
   } 

 return 1;
}

                  
////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XI  -- LES DIALOGUES MULTIPLES EN FENETRE //////////////
////////////////////////////////////////////////////////////////////////////////

a) DEFINITION:
-------------

Les dialogues multiples reprsentent une nouvelle faon d'utiliser les 
ressources GEM. Le principe repose sur l'utilisation d'un grand dialogue dont 
l'objet zero n'est pas reprsent, mais contient lui meme les dialogues  
activer et reprsenter. Cet objet zro est appel container racine.

Son contenu sera fonction de ce que vous dsirez faire, et notamment pour les
fenetres:
 
Qui n'a pas rv de pouvoir intgrer dans une fenetre une toolbar (en haut), une 
bottombar (en bas), une leftbar ( gauche), une rightbar ( droite) d'une 
fenetre, et que tout se redimensionne et suive lors des modifications de taille 
et position de fenetre ?. 

b) CONSTRUCTION:
---------------
 
--> dfinir un dialogue multiple ou container racine (1er objet): 
Pour dclarer un container racine il faut dfinir l'objet zro (le rectangle 
racine d'un dialogue) comme container de dialogues. Pour cela donnez lui le type 
tendu 201 ( type EAZY_GEM: MULTI_DIAL), et prvoyez le trs grand afin qu'il 
puisse contenir tous les autres dialogues enfants. Nous l'appelerons container 
racine. 

--> dfinir le dialogue du bord suprieur TOP_DIAL (enfant du container racine): 
Placez en haut  gauche du container racine (type tendu 201 MULTI_DIAL), une 
boite ayant le type tendu 202 (type EAZY_GEM TOP_DIAL). 
Cette boite peut etre d'un type quelconque en dehors d'une G_CICON, G_FTEXT 
ditable ou G_FBOXTEXT  ditable. Dans cette boite il est bien sur possible de 
placer n'importe quel objet, menu, boutons, listbox, scrollbox, boite  onglets. 
Ce dialogue sera plac en haut  gauche de la fenetre, et si la fenetre est 
redimensionnable, sa largeur sera ajuste  celle de la fenetre.

--> dfinir le dialogue du bord droit RIGHT_DIAL (enfant du container racine): 
Placez sous le dialogue TOP_DIAL, et  droite, une boite ayant le type tendu 
203  (type EAZY_GEM RIGHT_DIAL). 
Cette boite peut etre d'un type quelconque en dehors d'une G_CICON, G_FTEXT 
ditable ou G_FBOXTEXT  ditable. Dans cette boite il est bien sur possible de 
placer n'importe quel objet, menu, boutons, listbox, scrollbox, boite  onglets. 
Ce dialogue sera plac de faon  coller au bord droit de la fenetre, et si la 
fenetre est redimensionnable, sa hauteur sera ajuste  la fenetre.

--> dfinir le dialogue bord infrieur BOTTOM_DIAL (enfant du container racine): 
Placez en bas sous le dialogue RIGHT_DIAL une boite ayant le type tendu 204 
(type EAZY_GEM BOTTOM_DIAL). 
Cette boite peut etre d'un type quelconque en dehors d'une G_CICON, G_FTEXT 
ditable ou G_FBOXTEXT  ditable. Dans cette boite il est bien sur possible de 
placer n'importe quel objet, menu, boutons, listbox, scrollbox, boite  onglets. 
Ce dialogue sera plac en bas  gauche de la fenetre, collant au bord infrieur, 
et si la fenetre est redimensionnable, sa largeur sera ajuste  celle de la 
fenetre ainsi que la position de faon  coller au bord infrieur.

--> dfinir le dialogue du bord droit LEFT_DIAL (enfant du container racine): 
Placez sous le dialogue TOP_DIAL, et  gauche, une boite ayant le type tendu 
205  (type EAZY_GEM LEFT_DIAL). 
Cette boite peut etre d'un type quelconque en dehors d'une G_CICON, G_FTEXT 
ditable ou G_FBOXTEXT  ditable. Dans cette boite il est bien sur possible de 
placer n'importe quel objet, menu, boutons, listbox, scrollbox, boite  onglets. 
Ce dialogue sera plac de faon  coller au bord gauche de la fenetre, et si la 
fenetre est redimensionnable, sa hauteur sera ajuste  la fenetre.

c) LIMITES:
----------

Deux meme types ne peuvent cohabiter. On ne peut pas placer deux TOP_DIAL dans 
la meme fenetre.

Il est possible de ne placer qu'un seul type, ou quelconque combinaison de ces 
quatres types. Par exemple il est possible de dfinir une fenetre ne comportant 
qu'un BOTTOM_DIAL (barre de pied de fenetre), ou qu'un seul TOP_DIAL (barre 
d'outils), ou les deux  la fois etc....

d) CONSEQUENCES -> LA SURFACE CLIENT:
------------------------------------

Lorsque EAZY_GEM intgre un MULTI_DIAL dans une fenetre, il rajuste les 
diffrentes boites. La surface de travail USER, ou client, ou utilisateur, 
(chacun de ces termes tant quivalents) est donc le rectangle central laiss 
libre par ce cadre de dialogues. C'est ce rectangle qu'il est  votre charge de 
dessiner et qui vous est renvoy par la fonction dont voici le prototype:


/*------------------------------ GetClientGrect ----------------------------*/
/* ACTION: calcule l'espace de travail utilisateur laiss libre dans la     */
/*         fenetre, interieur au cadre epais et aux ressources de bords     */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre dont on recherche       */
/*                    l'espace client.                                      */
/*         GRECT *grect, adresse du rectangle devant recevoir les           */
/*                     coordonnes de l'espace client.                      */
/* SORTIE: GRECT *grect, est initialis sur l'espace de travail.            */
/* RETOUR: adresse du rectangle d'entree GRECT *grect initialise sur        */
/*               l'espace client, si il existe                              */
/*         zero sinon                                                       */
GRECT *GetClientGrect(int w_ind, GRECT *grect)


              
De plus lors du message WM_PAINT, il est donn le rectangle de notre surface 
client intrieur  la bordure de fenetre et aux ventuelles ressources associes  
 notre fenetre (barre d'outils, pied de fenetre, et autres) C'est dans 
lui qu'il faut dessiner et lors de ce message on le trouve:    

                en Evnt->pipe[X_B]                        
                   Evnt->pipe[Y_B]                        
                   Evnt->pipe[W_B]                        
                   Evnt->pipe[H_B]    

e) EXEMPLE DE DIALOGUE MULTI_DIAL:
---------------------------------
                          

  ________________Container racine MULTI_DIAL_201_________________________
 |                                                                        |
 |  _______________________Dialogue TOP_DIAL__202______________________   |
 | |                                                                   |  |
 | |                                                                   |  |
 |  -------------------------------------------------------------------   |                              
 |  ___LEFT_DIAL__205__                             __RIGHT_DIAL__203__   |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |         SURFACE           |                   |  |
 | |                   |                           |                   |  |
 | |                   |         CLIENT            |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |
 | |                   |                           |                   |  |                        
 | |                   |                           |                   |  |
 |  -------------------                             -------------------   |                   
 |  _____________________Dialogue BOTTOM_DIAL__204_____________________   |
 | |                                                                   |  |
 | |                                                                   |  |
 |  -------------------------------------------------------------------   |
 |                                                                        |
  ------------------------------------------------------------------------                 
                   
////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XII  -- LES BOITES A ONGLETS ///////////////////////////
////////////////////////////////////////////////////////////////////////////////


a) DEFINITION:
-------------

Une boite  onglet est un objet rectangulaire dont la partie suprieure comporte 
une srie de petits rectangles horizontaux ( appels onglets) contenant un texte 
indiquant le type de dialogue se mettant en place dans la partie infrieure de 
la boite lors d'un click sur l'onglet correspondant. Cette forme de dialogue 
permet de concentrer plusieurs dialogues dans le meme espace, et de les activer 
selon les besoins. La dfinition d'une boite  onglets et des dialogues 
correspondants se fait entirement avec un diteur de ressources.
La slection ,le fonctionnement et l'activation des diffrents dialogues 
composant la boite  onglets, se fait de faon entirement automatique sans 
aucune ligne de code supplmentaire de votre part !!! 
Dfinissez vos diffrents dialogues sous Interface en respectant les rgles 
nonces ci-aprs et c'est tout !!! (bien sur  condition que vous utilisiez la 
bibliothque d'EAZY_GEM, pour le chargement des ressources et leur intgration 
en fenetre).
Aidez vous des exemples de ressources fournis, et regardez avec un diteur de 
ressources comme elles sont organises.

b) CONSTRUCTION:
---------------

--> dfinir un dialogue multiple ou container racine (1er objet): 
Pour dclarer un dialogue multiple il faut dfinir l'objet zro (le rectangle 
racine d'un dialogue) comme container de dialogues. Pour cela donnez lui le type 
tendu 201 ( type EAZY_GEM: MULTI_DIAL), et prvoyez le trs grand afin qu'il 
puisse contenir tous les autres dialogues enfants. Nous l'appelerons container 
racine.

--> dfinir un dialogue principal (enfant du container racine): 
Placez en haut  gauche du container racine (type tendu 201 MULTI_DIAL), une 
boite ayant le type tendu 202 (type EAZY_GEM TOP_DIAL). Les dimensions de cette 
boite seront celles de la boite de dialogue qui sera affiche  l'cran. Cette 
boite peut etre d'un type quelconque en dehors d'une G_CICON, G_FTEXT 
ditable ou G_FBOXTEXT  ditable. Dans cette boite il est bien sur possible de 
placer n'importe quel objet, menu, boutons, listbox, scrollbox, boite  onglets.

--> y placer un objet de type boite  onglets
A l'intrieur de cette boite placez une une G_BOXTEXT ,(type BoxText sous  
Interface) qui sera celle qui affichera les onglets et les dialogues 
correspondant,  donnez lui le type tendu 108 ( type EAZY_GEM: ONGLET_MASTER). 
La chaine de caractres de cette boite doit commencer par 4 caracteres de votre 
choix, qui serviront  indiquer le container de dialogues onglets devant etre   
li  elle. Cet objet doit etre TOUCHE_EXIT ou SELECTABLE pour pouvoir ragir  
un click sur un onglet. Les attributs textes seront ceux utiliss pour afficher 
les onglets.
Il est possible de paramtrer le nombre de lignes sur lesquelles les onglets
devront se repartir, ainsi que la hauteur en pixels d'une ligne d'onglets.
Le nombre de ligne se place apres les 4 caracteres d'identification, (separe
d'eux par une virgule),ensuite vient la taille en pixels d'une boite (separe
du nombre de lignes par une virgule).
Exemple:   ONGL, 2, 16    est la chaine d'une boite  onglets de deux lignes,
           et de 14 pixels de haut, dont l'identificateur est ONGL.
           Il devra exister une boite container d'onglets portant le meme
           identificateur ONGL.
Si le paramtre de nombre de lignes est zero, alors les onglets ne seront
pas dessins, et il faudra changer les dialogues par programme.

--> dfinir le container de dialogues onglets (enfant du container racine):
    appel aussi container d'onglets.
Cet objet, contiendra tous les dialogues devant etre lis  une boite  onglets. 
A l'intrieur du container racine (type tendu 201 MULTI_DIAL) par exemple  
cot de la boite dialogue principale (type tendu 202 TOP_DIAL),  placez une 
G_BOXTEXT , (type BoxText sous Interface) donnez lui le type tendu 200 ( type 
EAZY_GEM: ONGLET_SLAVE), prvoyez la large pour pouvoir contenir tous les 
dialogues de la boite  onglets. La chaine de caractre de cette boite container 
d'onglets, doit commencer par 4 caractres d'identification, qui doivent etre 
les  memes que ceux de la boite  onglets dfinie plus haut. C'est par cet      
identificateur qu'EAZY_GEM sait qu'il faut relier tous les dialogues contenus,  
dans ce container d'onglets,  la boite  onglets dfinie plus haut. 

--> placer les dialogues de la boite  onglets (dialogues d'onglet) dans le     
    container d'onglets:
L'objet racine d'un dialogue d'onglets doit de prfrence contenir une 
chaine de caractres qui sera le titre du dialogue, et qui sera celle affiche 
dans un des petits rectangles de la boite  onglets. Cette chaine doit 
obligatoirement commencer par un espace. Cet objet racine d'un dialogue 
d'onglet, doit etre bien videment etre plac dans le container d'onglets.
Placez dans ce dialogue d'onglet tous les objets que vous souhaitez pour ce 
dialogue. IMPORTANT: Le dialogue d'onglet doit avoir sa hauteur infrieure d'au 
moins 20 pixels que celle de la boite  onglets devant l'afficher, cela pour 
permettre aux onglets de s'afficher. De meme il est souhaitable que la largeur 
soit infrieure ou gale  celle de la boite  onglets.

--> placer les autres dialogues d'onglet dans le container d'onglets.


c) EXEMPLE DE BOITE A ONGLETS:
-----------------------------

exemple d'une boite de dialogue type multidial contenant un dialogue principal, 
avec boite  deux onglets, de 16 pixels de haut et sur une ligne.


   
  __________________________container racine__201_________________________
 |                                                                        |
 | __Dialogue principal__202____    ______container d'onglets__200______  | 
 ||  __boite  onglets__108___  |  |                                    | |
 || |                         | |  |  __dialogue d'onglet 1__           | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |   ONGL,1,16             | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 || |                         | |  | |                       |          | |
 ||  -------------------------  |  |  -----------------------           | |
 ||  __________    ___________  |  |                                    | |
 || |  Bouton  |  |   Cancel  | |  |  ONGL                              | |
 ||  ----------    -----------  |  |                                    | |
 ||                             |  |                                    | |
 | -----------------------------   |  __dialogue d'onglet 2__           | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 | |                       |          | |
 |                                 |  -----------------------           | |
 |                                  ------------------------------------  |
 |                                                                        |
 |                                                                        |
  ________________________________________________________________________
  


d) CONTROLER LES BOITES A ONGLETS:
---------------------------------
  
Le fonctionnement des boites  onglets est automatique, mais il est possible
par la fonction dcrite ci-dessous d'activer par programme un dialogue d'onglet.


/*------------------------------ ActiveOnglet --------------------------------*/
/* ACTION: active un des dialogues d'une boite  onglet                       */
/* ENTREE: int w_ind,  indice EAZY_GEM de la fenetre contenant le dialogue    */
/*         int ob_onglet, numero d'objet de la boite  onglets                */
/*         int next_dial, numero du dialogue d'onglet  activer               */
/* SORTIE: neant                                                              */
void ActiveOnglet(int w_ind, int ob_onglet, int next_dial)     
 
 

////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XIII  -- LES STRUCTURES DE FENETRE /////////////////////
////////////////////////////////////////////////////////////////////////////////

a) INTRODUCTION:
---------------
Chaque fenetre possede une structure lui permettant de stocker des informations
indispensables  sa survie. Il est utile de connaitre ces structures, dont
certains lments vous serviront en permanence dans vos programmes.


b) LA STRUCTURE WINDTAB:
-----------------------
     DEFINITION:
      ----------
Voici la definition de la structure WINDTAB, telle que vous pouvez la trouver
dans le fichier EAZY_GEM.H : 

typedef struct
  {int ident;                          
   CALLBACK (*w_proc) (int w_ind, EVNT_O *Evnt);    
   long w_attr;                        
   int w_h;                                    
   int w_flag;                                  
   EVNT_I w_evnt_i;                             
   GRECT ExtGrectUse;                           
   GRECT GemWorkGrect;                          
   DLG_VAR DlgVar;                              
   char titre[256];                             
   void *UserPtr;                               
   char  MemSup[256];                           
  }WINDTAB;

Avant l'initialisation d'EAZY_GEM un tableau de cette structure est reservee
de faon  chaque fenetre du programme puisse disposer d'une structure
WINDTAB.

WINDTAB   Windtab[MAX_WIND];   /* declaration des tables de structures */
                               /* de fenetres EAZY_GEM.                */
  
EAZY_GEM reserve un tableau de cette structure , chaque fenetre 
est associ  un des lments de ce tableau, et y fait rfrence par l'indice 
de fenetre w_ind, transmis  la fonction CALLBACK par EAZY_GEM. La description 
suivante de WINDTAB, est l juste pour information. Normalement vous n'avez pas 
 intervenir sur cette structure.

Par exemple le handle GEM de la fenetre w_ind est:  Windtab[w_ind].w_h

    Description des membres de WINDTAB:
     ----------------------------------

int ident;   est un entier permettant au programmeur de typer la fenetre, afin 
             de pouvoir tester son existence, la retrouver par son type, 
             vrifier son ouverture etc... Ce typage peut paraitre contraignant 
             mais c'est une faon de donner un nom  votre fenetre, et par la 
             suite vous remarquerez que c'est indispensable.
             Plusieurs Fonctions permettent de retrouver l'indice d'une fenetre 
              partir du type et rciproquement dont voici les prototypes:
             
             int   IdentToIndice(int type);
             int   IndiceToIdent(int w_ind);
             
CALLBACK (*w_proc) (int w_ind, EVNT_O *Evnt);  c'est l qu'est stocke l'adresse 
             de la fonction associe  la fenetre. Vous n'avez normalement pas 
              vous procuper de cette donne (sauf bidouilles de haut vol) 
          
long w_attr; Ce sont les attributs GEM et EAZY_GEM dfinissant l'aspect et le 
             fonctionnement de la fenetre. C'est la combinaison des attributs 
             suivant:
             
             Les attributs GEM Classiques:             
             NAME, CLOSER, FULLER, MOVER, INFO, SIZER, UPARROW, DNARROW, VSLIDE,
             LFARROW, RTARROW, HSLIDE,  HOTCLOSEBOX, HOTCLOSE, SMALLER.
             
             Les attributs EAZY_GEM:
             BORDER  /* la fenetre est borde par un cadre pais         */
             XMOVER  /* le bord suprieur du cadre pais comporte        */
                     /* une poigne de dplacement                       */
             XSIZER  /* La fenetre est redimensionable par le bord pais */

             Exemple: Windtab[w_ind].w_attr = NAME | CLOSER | FULLER;

int w_h;     C'est l que lon trouve le handle GEM de la fenetre. il existe 
             plusieurs fonctions pour obtenir l'indice de fenetre EAZY_GEM  
             partir du handle GEM et rciproquement. Voici les prototypes;
             
             int WindHandToIndice( int w_h);  /* retourne l'indice EAZY_GEM */
             int IndiceToWindHand( int w_ind);/* retourne le handle GEM     */

int w_flag;  Flag d'usage interne  EAZY_GEM. Vous n'avez pas  vous occuper de 
             ce paramtre.

EVNT_I w_evnt_i;   Ici l'on trouve la structure de paramtrage vnementiel 
             associe  la fenetre. C'est cette structure qu'il faudra modifier 
             si l'on veut changer la rponse vnementielle pour cette fenetre. 
             Par exemple pour dfinir les rectangles MU_M1 et MU_M2. Cette 
             structure est fixe par dfaut  la cration de la fenetre.
             Normalement, vous ne devrez pas avoir  la modifier.
              
GRECT ExtGrectUse; Cette structure rectangulaire contient les dimensions 
             externes de la fenetre, qu'il faut utiliser pour la mettre en 
             LITLE_SIZE. (si elle est dj en FULL_SIZE plein cran et qu'il est 
             cliqu sur la case FULLER). Normalement vous n'avez pas  vous 
             occuper de tout a, car des fonctions spciales d'EAZY_GEM 
             s'occupent de tout ce mic-mac.
             
GRECT GemWorkGrect; Cette structure rectangulaire contient les dimensions 
             GEM interne (surface de travail GEM) de la fenetre. Elles sont
             mises  jour  chaque changement de taille, ou de position de
             la fenetre.
           
DLG_VAR DlgVar; Cette structure est capitale, car elle stocke et contient tous 
             les renseignements concernant les dialogues et ressources en 
             fenetre. Nous verrons plus loin en dtail les membres de cette 
             structure. 
              
char titre[256]; Ici l'on trouve la chaine de caractres du titre de la 
             fenetre.
             
void *UserPtr;  Ici vous pouvez placer une adresse, par exemple l'adresse d'un 
             bloc mmoire que vous avez rserv pour le fonctionnement de cette 
             fenetre, ou tout autre chose dpendant de vos besoins.
             
char  MemSup[256];  Ici une zone libre de 256 octets vous permet de placer des 
             valeurs, par exemple des paramtres lis  cette fenetre. A vous 
             d'organiser cette zone.
             
c) LA STRUCTURE DLG_VAR:
-----------------------       

         DEFINITION:
          ----------
   
Cette structure appartient et existe pour chaque fenetre en tant que membre de 
la structure WINDTAB. C'est elle qui relie le dialogue d'une ressource  la 
fenetre. Seuls les trois premiers membres sont  vraiment connaitre, et 
positionner sur les bonnes valeurs.
Le reste de la structure est initialis sur les bonnes valeurs aprs appel de la 
fonction:  Xform_construct();    et ne devraient normalement pas etre modifis 
par vous.
       
       Voici la definition de la structure DLG_VAR, telle que vous pouvez la 
trouver dans le fichier EAZY_GEM.H :  

typedef struct
 {int   type;         /* structure type ressource en fenetre          */
  void  *AdrRsc;      /* adresse ressource                            */
  int    NumTree;     /* numero arbre de cette ressource              */
  int    NbrTree;     /* nombre d'arbre de cette ressource            */
  OBJECT *tree;       /* adresse arbre de la resource de  fenetre     */
  int ObjEdit;        /* stocke numero objet en edition               */
  int PosCursX;       /* position du curseur dans le champ editable   */
  int CurState;       /* etat allume/1 ou eteint/0 du curseur         */
  int CurTim;         /* compteur de temps pour clignotage curseur    */
  int MoForm;         /* forme de la souris                           */
  int BlkDef;         /* bloc en mode edition/1  ou non edition/0     */  
  void *LstAdr;       /* adr d'une listbox si il y a en a une ouverte */
 }DLG_VAR;

        Description des membres de DLG_VAR:
         ---------------------------------- 

int   type;  Ce paramtre peut prendre deux valeurs: soit RSC_DIAL et alors les  
           dimensions de la fenetre se fixent sur celle du dialogue  
           reprsenter (sauf si dialogue MULTI_DIAL o c'est le dialogue qui 
           s'adapte  la fenetre).                   soit RSC_TOOL et alors les  
           dimensions du dialogue se fixent sur celle de la fenetre et le 
           dialogue est plac en haut de la fenetre en barre d'outils. (sauf si 
           dialogue MULTI_DIAL o c'est le dialogue qui s'adapte  la fenetre).

void  *AdrRsc Ce paramtre spcifie l'adresse de chargement de la ressource. Si 
           une fenetre ne comporte pas de dialogue, ce paramtre doit etre  
           zro. 
           
int    NumTree; Ici il est indiqu l'indice (base zero) de l'arbre devant etre 
           affich comme dialogue. (une ressource peut en effet comporter 
           plusieurs arbres de dialogues).

int    NbrTree; Ici il est indiqu le nombre d'arbres que comporte la ressource 
           charge en AdrRsc.
       
OBJECT *tree; L se trouve l'adresse du premier objet de l'arbre devant etre 
           affich .
           
int ObjEdit; Lorsqu'un ou plusieurs objets ditables sont prsents, ce paramtre 
          indique l'indice de celui qui possde le focus (curseur clignotant).
          Si il est gal  -1 c'est qu'il n'y a pas d'objets ditables.
          
int PosCursX; Caractre (base zro) devant lequel curseur ditable se trouve.

int CurState;  etat allume/1 ou eteint/0 du curseur clignotant.

int CurTim;    compteur de temps pour clignotage curseur.

int MoForm;    forme de la souris.     

int BlkDef;     bloc texte en mode edition/1  ou non edition/0 .                         
       
void *LstAdr;   adr d'une listbox si il y a en a une ouverte.

 
////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XIV  -- CREATION DES FENETRES EAZY_GEM /////////////////
////////////////////////////////////////////////////////////////////////////////


a) RAPPEL NOTION DE FENETRE et FONCTION DE FENETRE:
---------------------------------------------------

La notion de fenetre avec EAZY_GEM ne va pas sans la fonction qui est charge de 
grer cette fenetre comme nous l'avons vu plus haut.
EAZY_GEM considre une fenetre, plus par la fonction associe qui est charge de 
la grer, que par les lments chargs de la reprsenter.

Donc une fenetre est avant tout une fonction de fenetre,  laquelle EAZY_GEM 
fera constamment appel pour traiter l'vnementiel la concernant.


/*-------------------  MaFonctionFenetre -------------------------------*/ 
/* ACTION: Gestion du flux vnementiel associ  une fenetre           */ 
/*                                                                      */
/* PROTOTYPE:                                                           */
/*         CALLBACK MaFonctionFenetre (int w_ind, EVNT_O *Evnt)         */
/* ENTREE: int w_ind  indice de la fenetre pour laquelle la fonction    */ 
/*                    est appele (inutile si fonction par dfaut)      */
/*         EVNT_O *Evnt  pointe sur la structure de flux vnementiel   */
/*                       pour lequel il est demand de ragir.          */ 
/* RETOURNE: un int qui doit etre l'vnement transmis en entree avec   */
/*                  Si la fonction ne le retourne pas et retourne zro  */
/*                  alors l'vnement ne sera pas retransmis aux autres */
/*                  fonctions CALLBACK. Cette possibilit est utile     */
/*                  par exemple pour empcher un click souris de se     */
/*                  transmettre aux fenetres de dessous...              */ 
/*                  Pour le message WM_CONSTRUCT il est possible de     */
/*                  retourner deux valeurs: WM_STANBY ou WM_ABORT afin  */
/*                  de modifier le processus de creation de fenetre     */ 

Nous avons vus plus haut le principe de fonctionnement d'une telle fonction 
CALLBACK.
Avant toute ouverture de fenetre il faut donc prvoir et crire la fonction 
CALLBACK associe. Pour cela il vous suffit de copier la fonction d'un des 
exemples, et de l'adapter  vos besoins.


         

d) CREATION ET OUVERTURE DE FENETRE:
-----------------------------------

La cration d'une fenetre fait appel  une fonction spciale initialisant tous 
les paramtres lis  cette fenetre. C'est la fonction: CreateWindow(). Un appel 
 cette fonction, gnre le message WM_CONSTRUCT, et appelle la fonction de 
fenetre associe  la fenetre cre, afin que la fonction de fenetre puisse 
initialiser tout ce qui la concerne avant son ouverture.


                        
/* --------------------------- CreateWindow -----------------------------*/
/* PROTOTYPE:                                                            */
/* ----------                                                            */
/*  int  CreateWindow ( long w_attr,                                     */
/*                      int ident,                                       */
/*                      void *adr,                                       */               
/*                      CALLBACK (*w_proc)(int w_ind, EVNT_O *Evnt),     */
/*                      int x, int y, int w, int h,                      */
/*                      char *nom                                        */
/*                    );                                                 */
/* DESCRIPTION:                                                          */
/* ------------                                                          */
/*  long w_attr: attributs GEM classique d'une fenetre                   */
/*               trois attributs de plus:                                */
/*                         BORDER permet d'avoir un cadre epais en       */
/*                                  relief autour de la fenetre.         */
/*                         XMOVER permet d'avoir une poigne de deplace- */
/*                                ment sur le bord sup du cadre epais    */
/*                         XSIZER permet l'agrandissement de la fenetre  */
/*                                en cliquant sur le cadre epais         */
/*  int Ident:  nbr arbitraire(jamais nul) que vous devez donner. Cela   */
/*              peut servir  reperer tel ou tel type de fenetre dans    */
/*              votre programme. Exemple votre application comporte      */
/*              plusieurs fenetres dont une de menu  laquelle vous      */
/*              donnez int ident=2 lors de sa cration. Il est           */
/*              alors facile pour le programme de savoir si la fenetre   */
/*              menu est ouverte en faisant appel  la fonction          */
/*              int IdentToIndice(2); qui vous retourne l'indice de la   */
/*              fenetre (si elle n'existe pas l'indice est >= MAX_WIND ) */
/*              pensez  utiliser des type symboliques declars avec:    */
/*              #define FENETRE_TRUC 2  plutot qu'un nombre sans sens.   */
/*                                                                       */
/*  void *adr:  adresse pointant sur diverses choses dependant du type   */
/*              gestion que l'on prevoit pour la fenetre. Cette adresse  */
/*              permet par exemple de passer un pointeur sur une struct- */
/*              ture, avec laquelle elle doit travailler. Ce parametre   */
/*              est donc facultatif. La fonction: CreateWindow() place   */
/*              ce parametre dans Wintab[w_ind].UserPtr de la fenetre.   */
/*  CALLBACK (*w_proc)(int w_ind, EVNT_O *Evnt): L vous donnez le nom   */
/*              fonction qui sera charge de gerer tous les evenements   */
/*              de cette fenetre. Cette fonction sera appelee par la     */
/*              sur couche EAZY_GEM.                                     */
/* int x, int y, int w, int h,: coordonnees en pixels de la fenetre      */
/*              ces coordonnees doivent etre celles du contour exterieur */
/*              de la fenetre et non de la surface de travail            */
/*              si zero en entree alors les dimensions maxi possibles    */
/*              seront choisies.                                         */
/*              Ces dimensions peuvent etre modifiees avant ouverture de */
/*              la fenetre lors du traitement du message WM_CONSTRUCT    */
/*              au sein de la procedure de fenetre.                      */
/* char *nom:   titre de la fenetre                                      */
/*              de meme le titre de la fenetre peut etre modifie au sein */
/*              de la procedure de fenetre lors du traitement du message */
/*              WM_CONTRUCT.                                             */
/* RETOURNE: Le handle GEM de la fenetre si tout est OK.                 */
/*           -1 si Echec du constructeur de la fenetre                   */
/*           -2 si nbr fenetre superieur  MAX_WIND (maximum EAZY_GEM)   */
/*           -3 si l'AES n'a plus de fenetre  nous donner               */
   

////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XV  -- INTEGRATION D'UN DIALOGUE EN FENETRE ////////////
////////////////////////////////////////////////////////////////////////////////


Pour intgrer une ressource en fenetre il convient, de la charger et la reloger 
en mmoire  l'aide de la fonction:   RscFicLoad ()  ,puis d'intgrer  un des 
arbres de cette ressource,  la fenetre lors du message WM_CONSTRUCT avec la 
fonction:  Xform_construct().

Pour desinstaller un arbre de ressource d'une fenetre, il convient de le faire  
l'aide de la fonction: Xform_Destruct(), et ce avant changement d'arbre au 
niveau de la fenetre ou avant destruction de la fenetre ou avant dechargement 
de la ressource de la memoire (c'est imperatif pour liberer la memoire reservee 
lors de l'appel de la fonction Xform_construct()).

Pour decharger la memoire d'une ressource il convient de le faire   l'aide de 
la fonction: RscFicUnLoad (), il est imperatif de decharger toutes les 
ressources charges en mmoire avant de fermer et quitter un programme.

En resum: fonctions de chargement dechargement en memoire
                RscFicLoad () 
                RscFicUnLoad ()      
           fonctions d'installation et de desinstallation en fenetre
                Xform_construct () 
                Xform_Destruct ()     
                 
Il existe trois types de ressources en fenetre:

  - 1 - La fenetre qui affiche un dialogue simple: La fenetre est non 
        dimensionnable, et la fenetre encadre le dialogue.
        pour cela placez: dlg.type  = RSC_DIAL;
        
  - 2 - La fenetre qui affiche un dialogue barre d'outil: La fenetre peut etre 
        redimensionne, et de dimensions plus grandes que le dialogue, et le 
        dialogue s'affiche en haut de la fenetre, et est ajust  la largeur de 
        la fenetre.      
        pour cela placez: dlg.type  = TOOL_BAR;
  
  - 3 - La fenetre qui affiche un dialogue MULTI_DIAL: La fenetre peut etre 
        redimensionne, ou pas selon si les attributs XSIZER|BORDER ou SIZER 
        sont positinns. Elle peut comporter quatres dialogues, ou une 
        combinaison de ces quatres types de dialogues (fils de MULTI_DIAL):
            un  TOP_DIAL     en barre d'outils,
            un  RIGHT_DIAL   colle au bord droit de la fenetre,
            un  BOTTOM_DIAL  colle au bord inf de la fenetre,
            un  LEFT_DIAL    colle au bord gauche de la fenetre
        pour cela placez: dlg.type  = TOOL_BAR ou RSC_DIAL;

Lorsqu'une ressource doit etre lie et affiche par une fenetre, il est 
possible de le faire:
         
        A l'appel de la fonction de cration de la fenetre on ne passe pas de 
        structure renseignant sur la ressource et le numero d'arbre  intgrer 
        en fenetre:
        
        CreateWindow( CLOSER|FULLER|NAME|MOVER|BORDER|XMOVER|XSIZER,
                        FEN_A_MOI,  /* typage fenetre pour la retrouver      */
                        0L,         /* parametre optionnel                   */
                        MaFonctionFenetre,  /* donner adresse fonc. fenetre  */
                        20, 20, 100, 100, "Ma Fenetre"
                      );
                      
        et lors du traitement du message WM_CONSTRUCT dans la fonction associe 
         la fenetre, on renseigne la fenetre sur la ressource et l'arbre 
        qu'elle doit afficher par exemple de la faon suivante (en supposant que 
        w_ind pointe sur l'indice EAZY_GEM de la fenetre):              
        .
        .
        case WM_CONSTRUCT:
             /*...... on renseigne la structure de ressource attache .......*/
             /*       la fenetre w_ind, sur la ressource et l'arbre         */
             /*                  devant etre intgrs                        */
             Windtab[w_ind].DlgVar.AdrRsc  = AdrRsc ;  /* adresse chargement */
             Windtab[w_ind].DlgVar.type    = RSC_DIAL; /* prciser type      */  
             Windtab[w_ind].DlgVar.NumTree = 0;        /* numro de l'arbre  */
             
             /*........ appel de la fonction d'intgration ..................*/
             if (Xform_construct(w_ind, Evnt) == WM_ABORT return WM_ABORT; 
              
             /*........... centrer le tout sous la souris ..............*/
             AdjustWindCoordToScreen (w_ind, Evnt, (GRECT*)&Evnt->pipe[X_B]); 
             break;                               
        .
        .
        
   EN RESUME: Il est possible de rferencer la ressource  afficher soit lors de 
              l'appel  la fonction de cration de la fenetre, soit lors du 
              traitement du message WM_CONSTRUCT, dans la fonction associe  
              cette fenetre.
              
              De toutes faons il faut faire appel lors du message WM_CONSTRUCT, 
               la fonction: Xform_construct() qui intgre et lie vritablement 
              le dialogue  la fenetre.
              
              Les trois variables suivantes:
              Windtab[w_ind].DlgVar.AdrRsc  = AdrRsc ;  /* adresse chargement */
              Windtab[w_ind].DlgVar.type    = RSC_DIAL; /* prciser type      */  
              Windtab[w_ind].DlgVar.NumTree = 0;        /* numro de l'arbre  */
                                              doivent obligatoirement etre mises 
              sur les bonnes valeurs avant l'appel de la fonction:
                               Xform_construct ().
               
////////////////////////////////////////////////////////////////////////////////
/////////////////////-- XVI  -- GESTION D'UN DIALOGUE EN FENETRE ///////////////
////////////////////////////////////////////////////////////////////////////////

 Le plus simple pour comprendre est de prendre un exemple simple de fonction de 
 fenetre grant une ressource en fenetre.
 
CALLBACK MaFonctionFenetre(int w_ind, EVNT_O *Evnt)
{/*.............. les variables locales suivantes sont souvent ..........*/
 /*           utiles pour toutes les fonctions de fenetre EZGEM pour:    */
 int w_h;              /* handle de la fenetre de cette FonctionFenetre  */
 int wh_top;           /* handle de la fenetre en avant plan             */
 
 /*.................. INITIALISER LES VARIABLES ....................*/
 /*.................... recuperer handles ..........................*/    
 wind_get( 0, WF_TOP, &wh_top); /* celui de fenetre avant plan      */
 w_h = Windtab[w_ind].w_h;      /* celui de notre fenetre           */
 
           
 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/      
 /*...........................TOUCHE CLAVIER APPUYEE ...................*/
 /* Dans le cadre d'une ressource en fenetre j'ai cree une fonction qui */
 /* s'occupe de gerer tout ce qui a un rapport avec une touche clavier  */
 /* Notamment l'edition et saisie de texte dans les champs editables et */
 /* les raccourcis clavier.                                             */
 /* Pour une ressource en fenetre il est indispensable que l'evenement  */
 /* MU_KEYBD soit traite avant l'evenement  MU_BUTTON afin de permettre */
 /* un fonctionnement correct des raccourcis clavier. En effet le       */
 /* raccourci clavier d'un objet simule un clic souris sur l'objet.     */
 /* en renvoyant un evenement MU_BUTTON                                 */
 
 if (Evnt->evnt & MU_KEYBD && w_h==wh_top)
    {Xform_keybd(w_ind, Evnt);
    } /* endif MU_KEYBD  et fenetre au premier plan */
 
 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/   
 /*.......................... BOUTONS SOURIS ...........................*/ 
 /* Dans le cadre d'une ressource en fenetre j'ai cree une fonction qui */
 /* s'occupe de gerer tout ce qui a un rapport avec un appui sur un     */
 /* bouton de souris.                                                   */
 /* Notamment l'appui sur un bouton de la ressource, la selection du    */
 /* texte dans les champs editables, et le placement du curseur de      */
 /* texte dans les champs editables.                                    */
 /* Votre travail consiste  programmer les actions selon les objets    */
 /* Cliqus (EAZY_GEM ne peut pas le faire  votre place !!)            */ 
 if (Evnt->evnt & MU_BUTTON)
    {int ob_ret;
     OBJECT *object;            /* pointera le premier objet de l'arbre */ 
     object=Windtab[w_ind].DlgVar.tree;  /* le faire pointer dessus     */ 
     /*............ appel  la fonction de test ressource ..............*/  
     ob_ret = Xform_button(w_ind, Evnt);       
     if (ob_ret>-1)
        {Evnt->evnt &= ~MU_BUTTON;        /* bloquer message  MU_BUTTON */           
         /*............. si objet exit selectionne ...................*/
         object[ob_ret].ob_state &= ~SELECTED;
         Xobjc_draw(object, ob_ret, 1, &Windtab[w_ind].GemWorkGrect);
         /*............. action selon l'objet cliqu .................*/         
         switch (ob_ret)            
           {               
           }                               
        }  /* endif objet selectable cliqu  */            
    } /* endif MU_BUTTON  et fenetre au premier plan */
 
 if (Evnt->evnt & MU_M1)
    {
    }
 if (Evnt->evnt & MU_M2)
    {
    }
    
 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/   
 /*.......................... TIMER ..................................*/  
 /* Dans le cadre d'une ressource en fenetre la fonction: Xform_timer */
 /* s'occupe de tout ce que doit gerer le timer notamment le clignote */
 /* ment du curseur texte dans les champs editables                   */
 if (Evnt->evnt & MU_TIMER && w_h==wh_top)  
    {Xform_timer(w_ind);  
    }
    
 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/   
 /*.......................... MOUVEMENTS SOURIS ......................*/   
 /* Pour une ressource en fenetre la fonction: Xform_mu_move          */
 /* s'occupe de tout ce qui doit etre ger par un mouvement souris.   */      
 /* Notamment les formes de la souris lors du survol des differentes  */
 /* zones de la ressource.                                            */ 
 if (Evnt->evnt & MU_MOVE)   /*  (EZGEM evenement)   */
    {Xform_mu_move(w_ind, Evnt);
    }
          
 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/   
 /*.......................... MESSAGES GEM et AUTRES .................*/     
 if (Evnt->evnt & MU_MESAG)
    {switch (Evnt->pipe[MESG])
       {
        case WM_CONSTRUCT:      /*  (EZGEM message)   */
             /***********************************************************/
             /*.................... WM_CONSTRUCT (EZGEM message)........*/
             /* Ce message est transmis avant la creation et ouverture  */
             /* de la fenetre associee  notre procedure de fenetre.    */
             /* c'est  cet endroit que vous devez initialiser tout ce  */
             /* qui concerne votre fenetre: Memoire, chargement d'un    */
             /* fichier ressource, modification des dimensions fenetre  */
             /* avant ouverture, declaration des Bulles d'aide associees*/
             /*  cette fenetre, titre de la fenetre.....etc            */
             /* eventuellement si pas deja fait avant: ouverture d'une  */
             /* Station de travail VDI autre que celle d'EAZY_GEM.      */  
             /* EAZY_GEM vous laisse toute liberte pour faire ce que    */
             /* vous voulez:                                            */
             /* Vous pouvez tres bien charger votre fichier ressource  */    
             /* cet endroit ou avant dans l'application..               */
             /* Lors de ce message il est donn dans:                   */
             /*                  Evnt->pipe[X_B]                        */
             /*                  Evnt->pipe[Y_B]                        */
             /*                  Evnt->pipe[W_B]                        */
             /*                  Evnt->pipe[H_B]                        */
             /*                               les dim exterieures  maxi */
             /* possibles d'ouverture de la fenetre sur l'ecran.        */ 
             /* c'est par defaut ces dimensions qui sont choisies pour  */
             /* ouvrir une fenetre.Si on veut d'autres dimensions c'est */
             /* ces valeurs qu'il faudra modifier.                      */
             /*                                                         */
             /* REPONDRE AU MESSAGE WM_CONTRUCT:                        */
             /* Il est possible de repondre au message WM_CONSTRUCT     */
             /* de deux manieres equivalentes au point de vue resultat: */
             /* Soit en faisant  Evnt->evnt = WM_ABORT; (ou WM_STANDBY) */
             /* Soit en faisant  return WM_ABORT;       (ou WM_STANDBY) */                
             /*                                                         */
             /* Vous pouvez interrompre le processus de creation de la  */
             /* fenetre en retournant le message: WM_ABORT par exemple  */
             /* vous n'avez pas pu reserver toute la memoire souhaitable*/
             /* ou vous n'avez pas trouve un fichier indispensable      */
             /* ou pour toute autre raison liee a votre application.etc.*/
             /*                                                         */
             /* Vous pouvez empecher l'ouverture de la fenetre et donc  */
             /* permettre juste sa creation en retournant le message:   */   
             /* WM_STANDBY. Pour ouvrir et afficher la fenetre ulterieu-*/
             /* ment il faudra utiliser la fonction: OpenWindow         */
             /* Si vous ne retournez pas ce message la fenetre s'ouvre  */
             /* dans la foulee (cas le plus utile).                     */                           
             /*                                                         */                                       
             /*............... la fonction Xform_construct .............*/
             /* doit etre appele chaque fois qu'un arbre de ressource  */
             /* doit etre initialis et install dans une fenetre       */
             Windtab[w_ind].DlgVar.AdrRsc  = AdrRsc;
             Windtab[w_ind].DlgVar.type    = TOOL_BAR;
             Windtab[w_ind].DlgVar.NumTree = 0;
             if (Xform_construct(w_ind, Evnt) == WM_ABORT) return WM_ABORT;                          
             break;
             
        case WM_DESTRUCT:       /*  (EZGEM message)   */
             /**************************************************************/              
             /*........................ WM_DESTRUCT (EZGEM message)........*/
             /* Ce message est envoy a notre procedure de fenetre avant   */
             /* que le systeme ne la detruise. c'est  cet endroit qu'il   */
             /* convient de desinitialiser tout ce que l'on avait fait     */
             /* auparavant memoire, bulles d'aide, ressources....          */
             /*                                                            */
             /*............... la fonction Xform_Destruct .................*/
             /* doit etre appele chaque fois qu'un arbre de ressource     */
             /* doit etre desinstall d'une fenetre, soit avant changement */
             /* d'arbre au niveau de la fenetre soit avant dechargement    */
             /* definitif la ressource, au niveau de la memoire.           */
             Xform_Destruct(w_ind, Evnt);
             /*................. la fonction RscFicUnLoad .................*/
             /* doit etre appele chaque fois qu'une ressource doit etre   */
             /* dechargee et enlevee de la memoire.                        */
             RscFicUnLoad(Windtab[w_ind].DlgVar.AdrRsc);                                                                                                  
             break;
             
        case WM_TT_ON_OFF:      /*  (EZGEM message)   */
             /**************************************************************/
             /*...................... WM_TT_ON_OFF (EZGEM message).........*/
             /* Ce message est envoy  notre fenetre chaque fois qu'il est*/
             /* demand d'activer ou de desactiver l'affichage des bulles  */
             /* d'aide. Il suffit simplement d'appeler la fonction qui suit*/
             /* pour mettre  jour l'objet representant l'etat actif ou    */
             /* inactif de notre ressource (si il existe)                  */
             /* Cet Objet est un objet type BOXTEXT extended type 25 que   */ 
             /* vous devez placer sur votre formulaire. Il refletera l'etat*/
             /* actif ou inactif du systeme de bulle d'aide.               */
             SetBulleState(w_h, Windtab[w_ind].DlgVar.tree);   
             break;   
        
        case AID_REQUEST: 
             /**************************************************************/
             /*..................... AID_REQUEST (EZGEM message)...........*/
             /* Ce message est envoye a notre application chaque fois que  */
             /* DIDEROT nous demande une aide et une reference pour la     */
             /* fenetre au dessus de laquelle la souris se trouve.         */
             /* Ce message est structure comme suit:                       */
             /* En: Evnt->pipe[MESG] message AID_REQUEST (1502)            */
             /*     Evnt->pipe[APPL] ID de l'appli demandeuse(DIDEROT)     */              
             /*     Evnt->pipe[SUPL] on trouve  0                          */
             /*     Evnt->pipe[WHND] handle de la fenetre pour laquelle    */
             /*                      DIDEROT aimerait qu'on lui renvoie un */
             /*                      fichier d'aide et la reference  a     */ 
             /*                      afficher pour ce fichier.             */
             /* La reponse consiste a renvoyer a DIDEROT l'adresse d'une   */
             /* structure: DID_HELP remplie avec les parametres permettant */
             /* a DIDEROT d'afficher l'aide demandee.                      */
             /* La fonction EAZY_GEM: DiderotHelpReply() fait tout ce      */
             /* travail notre place.                                       */
              {                                                
               int ref;
               ref   = XYtoRef(Evnt->x,Evnt->y);	
               w_ind = IdentToIndice(W_EZ_03);
               DiderotHelpReply(w_ind,        /* indice de la fenetre pour */
                                              /* laquelle je fourni l'aide */
                                              /* "EXEMPLE.AID"             */ 
                               Evnt,          /* transmettre le flux       */
                                              /* evenementiel.             */
                              &VIEWHLP,       /* placer adresse structure  */
                                              /* d'aide type DID_HELP      */   
                              "EXEMPLE.AID",  /* nom du fichier d'aide.    */
                              ref,            /* placer la reference que   */
                                              /* veut visualiser de ce     */
                                              /* fichier d'aide.           */ 
                              400,            /* largeur de la fenetre.    */ 
                              500);           /* hauteur de la fenetre.    */ 
              }                
              break;

        case WM_TT_GET_TXT:     /*  (EZGEM message)   */
             /**************************************************************/              
             /*...................... WM_TT_GET_TXT .(EZGEM message).......*/
             /* Ce message est envoy a notre procedure de fenetre chaque  */
             /* fois que le systeme d'affichage d'une bulle d'aide desire  */
             /* qu'on lui fournisse un texte  afficher.                   */
             /* en  Evnt->pipe[X_G] se trouve le type de bulle demande:   */
             /*     SI egal  TT_UPSTOOL c'est une bulle d'aide sur un     */
             /*                          objet de ressource alors en:      */
             /*                          Evnt->pipe[Y_G]  on trouve le     */
             /*                          numro de cet objet.              */
             /* Ce texte peut etre affiche sur plusieurs lignes en mettant */
             /* comme separateur le signe | .                              */
             /* Exemple:                                                   */
             /* strcpy(sztt_txt,"Premiere ligne|deuxieme ligne|troisieme");*/
             /* Si vous placez une chaine vide "", la bulle d'aide ne sera */
             /* pas affichee.                                              */
             /*  Exemple: strcpy(sztt_txt,"");                             */ 
               
             {char *sztt_txt;                     /* crer  pointeur texte */   
              /*............. rcuperer adresse o l'on doit ..............*/
              /*              placer le texte de la bulle et               */
              /*              initialiser le pointeur texte                */
              sztt_txt  = (char*)     *(long*)(&Evnt->pipe[W_G]);  
              
              /*............ selon l'objet pour lequel la bulle............*/
              /*             demande un texte, placer celui-ci             */           
              if (Evnt->pipe[X_G]==TT_UPSTOOL)
                 {switch ( Evnt->pipe[Y_G])                          
                    {case 0:                         
                          strcpy(sztt_txt,"Objet Racine"); 
                          break; 
                     case 1:                         
                          strcpy(sztt_txt,"Objet N 1"); 
                          break;                                                                    
                     case 2:                           
                          strcpy(sztt_txt,"Objet N 2"); 
                          break;                                    
                     case 3:                              
                          strcpy(sztt_txt,"Objet N 3"); 
                          break;    
                     case 4:                              
                          strcpy(sztt_txt,"Objet N 4"); 
                          break;                                        
                     default:                                       
                          strcpy(sztt_txt,"");                       
                    }                                         
                }    
             }      
             break;
             
        case WM_WND_MENU:       /*  (EZGEM message)   */            
             /**************************************************************/              
             /*...................... WM_WND_MENU (EZ_GEM message).........*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* une entree de menu deroulant en fenetre est clique.       */  
             /* en Evnt->pipe[X_G] se trouve  numero de l'item selectionn */       
             /* comme dans les menu GEM classiques.                        */   
             /* en Evnt->pipe[Y_G] se trouve  numero de l'arbre de menu    */                                                         
             /* en *(long*)Evnt->pipe[W_G] adresse arbre menu, cela permet */
             /* de distinguer le menu en fenetre dans le cas de plusieurs  */
             /* menu dans la meme fenetre (c'est possible !!!!)            */               
             break;
             
        case WM_ONGLET_CHG:     /*  (EZGEM message)   */
             /**************************************************************/              
             /*................... WM_ONGLET_CHG .(EZGEM message)..........*/
             /* Ce message est envoy a notre procedure de fenetre chaque  */
             /* fois qu'il y a eu changement d'onglet, au niveau d'une     */
             /* ressource geree par notre fenetre. C'est lors de ce messa- */
             /* ge, qu'il convient d'initialiser le nouveau dialogue et de */
             /* recuperer les donnes de l'ancien. Ce message est envoy    */
             /* avant le dessin du nouveau dialogue.                       */
             /* Le message est compose comme suit:                         */
             /*  Evnt->pipe[MESG] = WM_ONGLET_CHG (message envoy)         */             
             /*  Evnt->pipe[APPL] = identificateur de l'application        */
             /*  Evnt->pipe[SUPL] = 0 (pas de surplus)                     */
             /*  Evnt->pipe[WHND] = handle fenetre contenant ressource     */  
             /*  Evnt->pipe[X_G]  = indice du dialogue qui va etre activ  */
             /*  Evnt->pipe[Y_G]  = indice du dialogue qui sera desactive  */    
             /*  *(long*)&Evnt->pipe[W_G] =  adr arbre ou sont les objets  */                                       
             break; 
                 
        case WM_EXEFUNC:        /*  (EZGEM message)   */
             /**************************************************************/              
             /*...................... WM_EXEFUNC .(EZGEM message)..........*/
             /* Ce message est envoy a notre procedure de fenetre chaque  */
             /* fois qu'il est demand d'executer une fonction referencee  */
             /* par un numero de fonction.                                 */
             /* Le message est compose comme suit:                         */
             /* SI  Evnt->pipe[WHND]= RSC_DIAL; le message provient d'une  */
             /*                             ressource.  ET ALORS           */                     
             /*     Evnt->pipe[X_G] = indice objet declenchant le message  */
             /*     Evnt->pipe[Y_G] = numero de la fonction referencee     */
             /*     *(long*)&Evnt->pipe[W_G] =  adr arbre ou est l'objet   */                                         
             break;        
                       
        case WM_PAINT:          /*  (EZGEM message)   */
             /**************************************************************/              
             /*........................ WM_PAINT (EZGEM message)...........*/
             /* Ce nouveau message est envoy a notre procedure de fenetre */
             /* lorsqu'il faut retracer quelque chose  l'ecran.           */
             /*                                                            */
             /* En: Evnt->pipe[X_G], Evnt->pipe[Y_G], Evnt->pipe[W_G], et  */
             /*     Evnt->pipe[W_G], se trouve le rectangle de clipping    */              
             /*                      qui est dej clipp par EAZY_GEM,     */
             /* En: Evnt->pipe[X_B], Evnt->pipe[Y_B], Evnt->pipe[W_B], et  */
             /*     Evnt->pipe[W_B], se trouve le rectangle de la surface  */    
             /*                      client qu'il est   votre charge de   */
             /*                      redessiner                            */
             /*....... effacer espace de travail ..........................*/   
             /* ICI JE TRACE LE RECTANGLE ESPACE DE TRAVAIL INTERIEUR AU   */
             /*             BORD EPAIS ET  LA RESSOURCE                   */
             Graphmode(MD_REPLACE);
             vsf_color( VDIhandle, 0 );           /* placer attributs de   */
             vsf_interior(VDIhandle,0);           /* traage fond blanc    */           
             GrectPbox((GRECT*)&Evnt->pipe[X_G]); /* tracer le fond blanc  */                                                                                                                                          
             break;  
             
        case WM_PAINTBOX:
             /**************************************************************/              
             /*........................ WM_PAINTBOX (EZGEM message)........*/
             /* Ce nouveau message est envoy a notre procedure de fenetre */
             /* lorsqu'il faut retracer la surface d'une boite de type     */
             /* PAINT_BOX (ob-type etendu PAINT_BOX (215).                 */             
             /*                                                            */
             /* En: Evnt->pipe[X_G], Evnt->pipe[Y_G], Evnt->pipe[W_G], et  */
             /*     Evnt->pipe[W_G], se trouve le rectangle de clipping    */              
             /*                      qui est dej clipp par EAZY_GEM,     */
             /* En: Evnt->pipe[X_B], Evnt->pipe[Y_B], Evnt->pipe[W_B], et  */
             /*     Evnt->pipe[W_B], se trouve le rectangle de la surface  */    
             /*                      client qu'il est   votre charge de   */
             /*                      redessiner                            */
             /* En: Evnt->pipe[12]   se trouve le numero de l'objet dont   */
             /*                      il faut retracer la surface.          */
                                            
        case MN_SELECTED:
             /**************************************************************/              
             /*...................... MN_SELECTED (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* une entree du menu deroulant GEM est clique.              */  
             /*......... recuperer adresse premier objet du menu ..........*/ 
             /* xrsrc_gaddr (R_TREE, 0, &object, AdrRscMenu);              */
             /* menu_tnormal( object, Evnt->pipe[3],1);                    */
             /* en Evnt->pipe[4] se trouve le numero de l'item selectionn */                                                                           
             break;
             
             
        case WM_REDRAW:             
             /**************************************************************/              
             /*........................ WM_REDRAW (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* il faut redessiner une partie de la fenetre (par exemple un*/
             /* accessoire qui la recouvrait vient de se fermer, il faut   */
             /* alors retracer la partie de notre fenetre que l'accessoire */
             /* recouvrait. Avant c'etait un veritable enfer, maintenant   */
             /* il vous faut juste appeler la routine: Lister_rectangles   */
             /* qui vous renvoie le message WM_PAINT                       */
             /* et vous n'avez plus  vous occuper de savoir comment faire */
             /* notamment pour traiter la liste des rectangles et leur     */
             /* intersection avec notre fenetre.                           */    
             Lister_rectangles(w_h,(GRECT*)&Evnt->pipe[X_G]);             
             break;
                                                            
       case WM_BOTTOM:
             /**************************************************************/              
             /*........................ WM_BOTTOM (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* on lui demande de se mettre au dernier plan. Il convient   */
             /* de le faire avec la fonction: wind_set(w_h, WF_BOTTOM );   */        
             wind_set(w_h, WF_BOTTOM );             
             break;
                               
       case WM_TOPPED:
             /**************************************************************/              
             /*........................ WM_TOPPED (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* on lui demande de se mettre en premier plan. Il convient   */
             /* de le faire avec la fonction: wind_set(w_h, WF_TOP );      */        
             wind_set(w_h, WF_TOP );             
             break;

        case WM_CLOSED:
             /**************************************************************/
             /*........................ WM_CLOSED (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre         */
             /* lorsqu'une demande de fermeture de la fenetre est demandee */
             /* si vous voulez detruire completement cette fenetre il faut */
             /* appeler imperativement la fonction: DestroyWindow()        */
             /* pour la reouvrir ensuite il vous faudra appeler la         */
             /* fonction:                           CreateWindow()         */
             /* sinon il vous faut faire un simple: CloseWindow()  et la   */
             /* reouvrir par:                       OpenWindow()           */
             /* sans etre oblige de tout reinitialiser                     */
             CloseWindow(w_ind);                                        
             /* DestroyWindow(w_h); */
             break;
             
        case WM_ALLICONIFY: 
             /**************************************************************/
             /*.................... WM_ALLICONIFY (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre         */
             /* lorsqu'une demande de d'iconification de toute             */
             /* l'appication est demande.                                 */ 
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */ 
             AllIconify(0L);
             break;
             
        case WM_ICONIFY:
             /**************************************************************/
             /*....................... WM_ICONIFY (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre         */
             /* lorsqu'une demande de d'iconification d'une fenetre est    */
             /* demande.                                                  */ 
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */ 
             IconifyWindow(w_ind, 0L);
             break;           
                                                      
        case WM_UNICONIFY:
             /**************************************************************/
             /*..................... WM_UNICONIFY (GEM message)............*/
             /* Ce message est envoy a notre procedure de fenetre         */
             /* lorsqu'une demande de desiconification d'une fenetre est   */
             /* demande.                                                  */ 
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */
             UnconifyWindow(w_ind, (GRECT*)&Evnt->pipe[X_G]);            
             break; 
        /*                               
        case WM_ARROWED:
             break;
        case WM_HSLID:
             break;
        case WM_VSLID:
             break;
        */     
        case WM_FULLED: 
             /**************************************************************/              
             /*....................... WM_FULLED (GEM message).............*/   
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* le bouton de pleine fenetre (FULLER) a t cliqu          */
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */             
             OnWm_fulled( w_ind, Evnt);  
             break;     
             
        case WM_SIZED:    
             /**************************************************************/              
             /*........................ WM_SIZED (GEM message).............*/   
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* on lui demande de mettre a jour ses dimensions apres une   */
             /* demande de changement de taille lors de l'appui sur une    */
             /* case de dimensionnement, ou lors d'une demande logicielle. */
             /* ou apres une modification des coordonnes de la fenetre     */
             /* les dimmensions externes de la fenetre sont recuperables   */
             /* la ou classiquement le GEM les place  dans:                */
             /*      Evnt->pipe[X_G],Evnt->pipe[Y_G],Evnt->pipe[W_G], et   */
             /*      Evnt->pipe[H_G]                                       */ 
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */                                           
             OnWm_sized(w_ind, Evnt);  
             break;
             
        case WM_MOVED:
             /**************************************************************/              
             /*........................ WM_MOVED (GEM message).............*/
             /* Ce message est envoy a notre procedure de fenetre lorsque */
             /* on lui demande de a jour ses dimensions apres une demande  */
             /* de changement de taille lors de l'appui sur une case de    */
             /* dimensionnement, ou lors d'une demande logicielle.         */
             /* ou apres une modification des coordonnes de la fenetre     */
             /* les dimmensions externes de la fenetre sont recuperables   */
             /* la ou classiquement le GEM les place  dans:                */
             /*      Evnt->pipe[X_G],Evnt->pipe[Y_G],Evnt->pipe[W_G], et   */
             /*      Evnt->pipe[H_G]                                       */ 
             /*      ou elles doivent etre selon EZ_GEM.                   */ 
             /* Dans EAZY_GEM la fonction suivante s'occupe de tout        */  
             OnWm_moved(w_ind, Evnt);
             break;
        /*     
        case WM_NEWTOP:
             break;
        case AC_OPEN:
             break;
        case AC_CLOSE:
             break;                                                                   
       */      
       }
    }      
 return Evnt->evnt;    /* retourner le flux evenementiel (modifie ou pas)    */
}         
  
////////////////////////////////////////////////////////////////////////////////
//////////-- XVII  -- UNE AIDE EN LIGNE POUR EAZY_GEM //////////////////////////
////////////////////////////////////////////////////////////////////////////////

Vos programmes faits avec EAZY_GEM peuvent beneficier du fabuleux DIDEROT  
mettant a votre disposition un systeme de gestion d'aides en lignes performant
et esthetique. (Le fabuleux viewer d'aide en ligne de DIDEROT est fait avec
EAZY_GEM et est dispo sur le BBS d'AFSF au 01 64 29 44 23).
Voici comment utiliser dans vos programme un appel  DIDEROT. La description
ci_dessous est valable meme pour les programme n'tant pas sous EAZY_GEM.

............................................................................
- a - Il suffit de declarer quelque part, en variable globale une structure de 
    type DID_HELP dont je rappelle (pour ceux qui n'utilisent pas EAZY_GEM),
    la definition ci dessous que l'on trouve dans le fichier EAZY_GEM.H, inclu
    avec tout programme sous EAZY_GEM.
    
/*                             DID_HELP                                */ 
/* definition de la structure permettant de communiquer avec l'aide    */
/* de DIDEROT. Les parametres de cette structure determinent, avec     */
/* quel fichier d'aide et quelle reference de ce fichier la fenetre de */
/* DIDEROT doit s'afficher.                                            */

 typedef struct
   {
    char Aid_file[256]; /*recevra le chemin complet du fichier d'aide */
                        /* d'aide que l'on veut associer a notre       */
                        /* programme.                                  */
    long Ref;           /*Numro de la reference que l'on veut voir   */
                        /* dans ce fichier.                            */
    int  x_win;         /*position X de la fenetre d'aide             */
    int  y_win;         /*position Y de la fenetre d'aide             */
    int  w_win;         /*largeur de la fenetre d'aide                */
    int  h_win;         /*hauteur de la fenetre d'aide                */
                        /* Si il est fourni -1 comme parametres, la    */
                        /* fenetre de DIDEROT s'ouvrira avec des       */
                        /* dimensions par defaut.                      */
                        /* Ce sont les dimensions exterieures de la    */
                        /* fenetre que ces parametres decrivent.       */                  
    int  w_h;           /*handle de la fenetre demandeuse, DIDEROT a  */
                        /* besoin de la connaitre pour la remettre au  */
                        /* dessus des autres(l'activer), apres s'etre  */
                        /* ouvert !!!. Ce n'est utile que lors des     */
                        /* AES < 3.99.                                 */
                        /* Si l'on fourni -1 pour w_h, la fenetre      */
                        /* demandeuse ne sera pas remise au TOP.       */                  
  }DID_HELP;

Pour memoire je rappelle aussi (pour ceux qui n'utilisent pas EAZY_GEM)
les valeurs AID_REQUEST, et AID_SEND dont on trouve les dfinitions 
suivantes dans le fichier EAZY_GEM.H  inclu avec tout programme sous 
EAZY_GEM.
    
                 #define AID_REQUEST      1502    
                 #define AID_SEND         1500    

Exemple: 
      .
      .
      DID_HELP VIEWHLP;  /* declaration d'une variable pour les Aides    */
      .                  /* cette declaration doit etre en var globale   */
      .                  /* ou static afin que l'accessoire puisse s'en  */
      .                  /* servir, en effet l'adresse de cette variable */
      .                  /* est transmise  DIDEROT. Si cette variable   */
      .                  /* est locale, DIDEROT se servira de l'adresse  */
      .                  /* transmise avec le message apres SORTIE de    */
      .                  /* votre fonction o la variable a t dclare */
      .                  /* donc APRES destruction des variables locales */
      .                  /* (restauration de la pile et rutilisation    */
      .                  /* probable de celle-ci par une autre fonction) */   
      .                  /* donc DIDEROT plantera.                       */              
      .
............................................................................      
- b -  Le message AID_REQUEST: lorsque la fenetre de DIDEROT est au premier
     plan, donc active, et que la touche HELP est appuyee, DIDEROT envoie
     a la fenetre au dessus de laquelle se trouve la souris, le message
     AID_REQUEST, afin que l'application a laquelle appartient cette 
     fenetre renvoie a DIDEROT une aide et reference a afficher.
     Pour repondre a ce message une application devra faire comme si 
     c'etait sa touche HELP qui a ete appuyee. (voir paragraphe ci_dessous). 

............................................................................      
- c - Pour faire afficher par DIDEROT une aide, comme par exemple lors de 
     l'appui de la touche HELP il faut envoyer a DIDEROT le message AID_SEND, 
     en placant dans le quatrime et cinquieme champ du pipe, l'adresse d'une 
     structure de type DID_HELP, correctement initialisee, afin que DIDEROT 
     puisse savoir ce quoi et comment il doit afficher l'aide souhaite.

Exemple valable pour n'importe quelle appli meme sans EAZY_GEM:      
      .
      .
      .         
int acc_id;                                       /* recevra l'id GEM  DIDEROT */
acc_id = appl_find("DIDEROT ");                   /* DIDEROT es tu la ???      */
if ( acc_id >= 0 )                                /* Si oui envoyer message    */
   {
    /*.............. initialiser structure d'aide .............................*/
    strcpy(VIEWHLP.Aid_file, "A:\FICHIER.AID");   /* path du fichier d'aide    */
    VIEWHLP.Ref    = 0;                           /* reference a visualiser    */
    VIEWHLP.x_win  = 40;                          /* position X fenetre d'aide */
    VIEWHLP.y_win  = 40;                          /* position Y fenetre d'aide */
    VIEWHLP.w_win  = 200;                         /* largeurfenetre d'aide     */
    VIEWHLP.h_win  = 300;                         /* hauteur fenetre d'aide    */
    VIEWHLP.w_h    = Windtab[w_ind].w_h;          /* handle fenetre demandeuse */
    
    /*.............. envoyer message vers DIDEROT .............................*/ 
    wind_update(BEG_UPDATE);            /* bloquer le GEM.                     */  
    msgbuf[MESG] = AID_SEND;            /* message reponse  pour DIDEROT.      */
    msgbuf[APPL] = Appl_id;             /* iddentificateur de l'application    */
    msgbuf[SUPL] = 0;                   /* message sans surplus                */
    *(long*)(&msgbuf[3])=(long)VIEWHLP; /* placer adresse structure VIEWHLP    */             
    appl_write(acc_id,16,msgbuf);       /* envoyer message  DIDEROT           */
    wind_update(END_UPDATE);            /* debloquer le GEM.                   */    
   }
      .
      .
      .

Dans le cadre d'EAZY_GEM j'ai ecrit une fonction qui permet de repondre et
automatise un peu tout ca. C'est la fonction: DiderotHelpReply() dont voici
le prototype:

/*---------------------- DiderotHelpReply -------------------------------*/
/* ACTION: repond au message AID_REQUEST envoy par DIDEROT lorsqu'il    */
/*         doit afficher une aide. Cette fonction rempli automatiquement */
/*         les membres de la structure DID_HELP *VIEWHLP: dont on fourni */
/*         en entree l'adresse. Le fichier d'aide est cherche dans les   */
/*         repertoires systemes de l'application.                        */
/*         Au premier affichage de la fenetre d'aide ses dimensions sont */
/*         automatiquement ajustees pour qu'elle s'affiche de facon a ne */
/*         pas recouvrir la fenetre demandeuse d'aide.                   */
/*                                                                       */ 
/* ENTREE: w_ind: indice EAZY_GEM de la fenetre correspondant au fichier */
/*                d'aide, specifie par la variable: char *fic_aide       */
/*                Si ce n'est pas la fenetre pour laquelle DIDEROT deman-*/
/*                de une aide, il ne se passera rien et la fonction      */
/*                retourne avec 0;                                       */   
/*         EVNT_O *Evnt: variable de flux evenementiel.                  */
/*         DID_HELP *VIEWHLP: pointeur sur la structure de retour, que   */
/*                            l'on va renvoyer a DIDEROT afin qu'il      */
/*                            afficher l'aide demandee.                  */ 
/*         char *fic_aide: nom du fichier d'aide. il sera cherch dans   */
/*                         les repertoires systemes de l'application.    */
/*         int ref: numero de la reference a afficher de ce fichier      */
/*                  d'aide.                                              */
/*         int w, h: largeur et hauteur que l'on veut pour l'affichage   */
/*                   de la fenetre d'aide.                               */
/* RETOUR:  1 tout est OK                                                */
/*          0 l'indice de fenetre fourni en entre n'est pas le bon.      */
/*         -1 l'application DIDEROT non presente.                        */
/*         -2 le fichier d'aide fourni en entre n'est pas trouve.        */

int DiderotHelpReply(int w_ind, EVNT_O *Evnt, 
                     DID_HELP *VIEWHLP, char *fic_aide, int ref, 
                     int w, int h);

Exemple ici je repond au message AID_REQUEST (exemple tire de EZ_03.C)
        du dossier DIDACTIC.     
        .
        .
        .
if (Evnt->evnt & MU_MESAG)
    {switch (Evnt->pipe[MESG])
       {/*****************************************************************************/
        /*......................... AID_REQUEST (EZGEM message)......................*/
        /* DIDEROT nous demande une aide et une reference pour la fenetre au dessus  */
        /* de laquelle la souris se trouve.                                          */
        /* Ce message est structure comme suit:                                      */
        /* En: Evnt->pipe[MESG] on trouve le message AID_REQUEST (1502)              */
        /*     Evnt->pipe[APPL] on trouve l'ID de l'appli demandeuse(DIDEROT ou nous)*/              
        /*     Evnt->pipe[SUPL] on trouve  0                                         */
        /*     Evnt->pipe[WHND] se trouve le handle de la fenetre pour laquelle      */
        /*                      DIDEROT aimerait qu'on lui renvoie un fichier d'aide */
        /*                      et la reference a afficher.                          */   
        /* La reponse consiste a renvoyer a DIDEROT l'adresse d'une structure:       */
        /* DID_HELP remplie avec les parametres permettant a DIDEROT d'afficher      */
        /* l'aide demandee.                                                          */
        /* La fonction EAZY_GEM: DiderotHelpReply() fait tout le travail a notre     */
        /*                                                                           */
        case AID_REQUEST: 
             {int ref;
              ref   = XYtoRef(Evnt->x,Evnt->y);	
              w_ind = IdentToIndice(W_EZ_03);
              DiderotHelpReply(w_ind,         /* indice de la fenetre pour laquelle  */
                                              /* je fourni l'aide "CHARVIEW.AID"     */ 
                              Evnt,           /* transmettre les evenements.         */
                              &VIEWHLP,       /* placer adresse variable d'aide.     */   
                              "CHARVIEW.AID", /* nom du fichier d'aide.              */
                              ref,            /* placer la reference.                */
                              400,            /* largeur de la fenetre.              */ 
                              500);           /* hauteur de la fenetre.              */ 
             }                
             break;
         .
         .
         .
    
............................................................................      
- d - ASTUCE lorsque la touche HELP est appuye dans mon application, 
      j'envoie a mon application le message AID_REQUEST, afin qu'elle 
      reagisse comme si  c'etait DIDEROT qui demande une aide. De cette facon
      je n'ai qu'un seul endroit dans mon programme ou je gere les aides, 
      c'est lors de la reception du message AID_REQUEST.
     
Exemple:
       .
       .
       .
    switch(scan)
             {/*.........0x62 code scan touche HELP ....................*/ 
              /* nous allons nous envoyer le message AID_REQUEST        */
              /* (comme si s'etait DIDEROT qui l'envoyait) de facon     */
              /* a declencher une reponse vers DIDEROT.                 */           
              case  0x62: 
                    SendWindMessage(Windtab[w_ind].w_h, AID_REQUEST, 0L);                        
                    break;
      .
      .
      .   



////////////////////////////////////////////////////////////////////////////////
//////////-- XVIII  -- FONCTIONS  ET VARIABLES D'EAZY GEM //////////////////////
////////////////////////////////////////////////////////////////////////////////

/*////////////////////////////////////////////////////////////////////////////*
/*                                                                            */
/*------- VARIABLES GLOBALES PUBLIQUES (liees au fichier EAZY_GEM.LIB)--------*/
/*         ces variables peuvent etre utilises par tous les fichiers         */
/*                                                                            */
/*////////////////////////////////////////////////////////////////////////////*/
/*.......... les deux variables suivantes doivent etre modifiees .............*/
/*           avant l'appel  la fonction: InitEazyGem() pour                  */
/*               que la modification soit prise en compte                     */
extern int MAX_TTIPS;   /* nbr maxi de structures TOOL_TIPS permises */
extern int MAX_WIND;    /* nbr maxi de fenetres de notre application */

extern char NomAppli[14]; /* contient apres initialisation le nom du programme */
extern int Appl_id;    /* variable globale publique identifiant l'application  */
                       /* que le gem nous attribue lorsque nous lui demandons  */
                       /* l'autorisation de demarrer. Cette variable est       */
                       /* retournee par la fonction InitEazyGem()              */ 
extern MACHINE_INFO MachineInfo; /* structure pour les info sur la machine   */
extern int AESversion;    /* version AES utilise          (ne pas modifier)  */
extern int VDIhandle;     /* handle que le systeme m'attribuera apres        */
                           /* ouverture de la station de travail graphique   */
extern int Ecran_l;        /* largeur en pixel de l'ecran (ne pas modifier)  */                     
extern int Ecran_h;        /* hauteur en pixel de l'ecran (ne pas modifier)  */  
extern int Nb_plan;        /* nbr de plans de l'ecran     (ne pas modifier) */
extern long Nb_color;      /* nbr de couleurs de l'ecran  (ne pas modifier) */
extern int EZGemRun; /* variable globale publique si zero le programme sort */
                /* de la boucle evenementielle                         */
                /* pour mettre fin au programme il faut la mettre a 0  */
                /* de n'importe quel endroit du programme              */
                
extern WINDTAB   *Windtab;     /* declaration des table de structures  */
                               /* de fenetre.                          */
extern int TTswitch;           /* si 0/pas de bulle si 1/bulle actives */                               
extern int TT_Time_ON;         /* delai avant apparition bulle         */
extern int TT_Time_OFF;        /* delai pour disparition bulle         */

extern int *MenTTBack;         /* pointe sur sauvegarde fond bulle d'aide  */                               
                               /* definition de la forme souris "I"        */
                               /* mise au debut des bulles d'aides         */                               
extern int NbFont;             /* nombre de fontes                         */
extern char *FontTab;     /* pointera sur tableau global des fontes        */
extern char *FontName;    /* pointera sur tableau des nom de fontes        */
extern long *FontID;      /* pointera sur tableau des ID de fontes         */
extern long Gdos;         /* contient: l'identificateur Gdos si ok         */
                          /*          -2 si Gdos pas charg                */
                          /*          '_FSM' si vectoriel possible         */


/*/////////////////////////////////////////////////////////////////////////////*
/*                                                                            */
/*------- FONCTIONS REDEFINIE (liees au fichier EAZY_GEM.LIB) ----------------*/
/*                                                                            */
/*////////////////////////////////////////////////////////////////////////////*/

int EZ_vst_font(int vh, int fnt);
#define vst_font(a,b)  EZ_vst_font((a),(b))

int EZ_vst_point( int vh, int point, int *c, int *d, int *e, int *f);
#define vst_point(a,b,c,d,e,f)   EZ_vst_point((a),(b),(c),(d),(e),(f))

int EZ_vst_rotation(int vh, int angle);
#define vst_rotation(a,b) EZ_vst_rotation((a),(b))

int EZ_vst_effect(int vh, int effect);
#define vst_effects(a,b)   EZ_vst_effect((a),(b))

int EZ_vst_color(int vh, int color);
#define vst_color(a,b)   EZ_vst_color((a),(b))

int EZwind_update(int mode);
#define wind_update(a)  EZwind_update((a))

int EZ_alert( int default_button, char *form_string );
#define form_alert(a,b)  EZ_alert((a),(b))

int EZ_menu_bar( OBJECT *tree, int show );
#define menu_bar(a,b)  EZ_menu_bar((a),(b))

/*/////////////////////////////////////////////////////////////////////////////*
/*                                                                            */
/*------- FONCTIONS PUBLIQUES (liees au fichier EAZY_GEM.LIB) ----------------*/
/*   ces fonctions peuvent etre utilises par tous les fichiers               */
/*                                                                            */
/*////////////////////////////////////////////////////////////////////////////*/

/*************************************************************************/
/*           F O N T I O N S   D 'I N I T I A L I S A T I O N  ( G E M ) */
/*************************************************************************/


/*--------------------------- InitEazyGem -----------------------------*/
/* ACTION: initialise sur des valeurs par defaut la structure WINDTAB  */
/*         et dclare l'application au gem                             */
/* elle declare notre programme  EAZY_GEM,                            */
/* Initialise l'application et son identificateur GEM: Appl_id,        */
/* Ouvre une station de travail VDI dont le handle est: VDIhandle,     */
/* Initialise le GDOS (si il existe), charge les polices de caracteres */
/*     Reserve et initialise la zone des donnees de fontes: FontTab,   */
/*     itialise la variable de nombre de fontes: NbFont,               */
/*     initialise le tableau d'identificateur de fontes: FontID[],     */
/*     initialise le tableau de nom des fontes: FontName,              */
/* Initialisation desvariables globales suivantes:                     */
/*                Appl_id  (identificateur GEM de l'application)       */
/*                VDIhandle (handle VDI de l'application)              */
/*                FontTab  (pointe sur zone memoire reservee pour les  */
/*                          variables lies aux fontes)                */
/*                FontID[] (tableau des identificateurs de fontes)     */
/*                FontName (zone des noms de fontes. Chaque nom de     */
/*                         fonte fait 36 caracteres y compris zero de  */
/*                         fin de chaine. EXP: Pour accder au nom de  */
/*                         la 12me fonte il faut faire, (le premier   */
/*                         lment commenant  zro):                 */
/*                         FontName + 11 * 36. L'adresse ainsi         */
/*                         calcule pointe sur le nom de la 12me      */
/*                         fonte charge.Ce nom est identique  celui  */
/*                         retourn par la fonction VDI: vqt_name      */ 
/*                         ouf !!)                                     */
/*                NbFont  (Nombre de fontes disponibles y compris la   */
/*                         fonte systme)                              */
/*                Ecran_l (largeur de l'ecran en pixels)               */
/*                Ecran_h (hauteur de l'ecran en pixels)               */    
/*                Nb_color(nombre de couleurs)                         */
/*                Nb_plan (nombre de plan de l'ecran)                  */
/*                NomAppli (pointe sur le nom du programme)            */
/*                AESversion (utile  tester pour certaines fonctions) */
/*                Screen_MFDB  (structure raster cran)                */
/*                MachineInfo  (structure renseignant sur la machine   */
/*                               et systme sur lequel l'on est)       */
/*                Gdos   contient: l'identificateur Gdos si ok         */
/*                                -2 si Gdos pas charg                */
/*                                '_FSM' si vectoriel possible         */
/* Initialisation de la structure WINDTAB sur zero et valeurs de defaut*/ 
/*                                                                     */ 
/* ENTREE:      char *nomappli   doit pointer sur le nom du programme  */ 
/* RETOUR:      un int  positif si reussite de l'operation, qui est    */ 
/*                         alors l'identificteur GEM de l'application  */
/*                      NEGATIF -2 alors station de travail VDI non     */
/*                                 ouverte il faut abandonner.          */
/*                      NEGATIF -1 alors tout est foutu il faut quitter */
/* PROTOTYPE:                                                          */ 
              int InitEazyGem(char *nomappli);


/*----------------------------- ExitEasyGem ---------------------------*/
/* ACTION: Libre la mmoire reserve par EAZY_GEM pour ses besoins    */ 
/*         internes, dcharge les polices de caractres, ferme la      */
/*         station VDI, libre l'application du GEM, et quitte.        */
/* ENTREE:    nant                                                    */
/* RETOUR:    sans intrt                                             */ 
/* PROTOTYPE:                                                          */
              int ExitEasyGem(void);

/*------------------------- BouclePrincipale  -------------------------*/
/* ACTION: Noyau d'EAZY_GEM cette fonction est celle qui gre          */
/*         l'vnementiel GEM le filtre, le redistribue aux diffrentes*/
/*         fonctions CALLBACK en les appelant                          */
/*         Pour mettre fin  cette boucle il faut mettre la variable   */
/*         globale: EZGemRun                                           */
/*                   0 (demande de confirmation avant sortie)         */
/*                   1 (sortie sans demande de confirmation)          */
/* ENTREE: CALLBACK (*MyEventProc)(int w_ind, void *adr) adresse de la */ 
/*                   fonction qui sera charge de grer l'vnmentiel  */ 
/*                   GEM par dfaut. Si cette valeur est NULL, alors   */ 
/*                   l'vnmentiel GEM ne pourra etre gr que par les */ 
/*                   fonctions CALLBACK  de fenetre                    */
/* RETOUR: nant                                                       */
/* PROTOTYPE:                                                          */

void BouclePrincipale(CALLBACK(*MyEventProc)(int w_ind,EVNT_O *Evnt));
              
/*************************************************************************/
/*           F O N T I O N S   D E   R E S S O U R C E S   ( G E M )     */
/*************************************************************************/

/* --------------------------- RscFicLoad ---------------------------- */
/* ACTION: charge un fichier ressource en memoire et l'adapte aux      */
/*         nouvelles specification d'EAZY_GEM.                         */
/*         La memoire est automatiquement reservee et la ressource est */
/*         relogee et convertie prete  l'emploi.                      */
/* ENTREE: char *path, char *name chemin et nom de la ressource        */
/*         int scale_flag = 1 SCALE affichage au standard GEM (normal) */
/*                        = 0 NO_SCALE affichage au standard EAZY_GEM  */      
/*                            (police moyenne taille 9)                */
/*         pour le menu GEM classique utilizez  SCALE ou 1             */
/*         pour un menu en fenetre ou une ressource en fenetre         */ 
/*              choisissez ce qui vous plait le plus.                  */           
/* RETOUR: adresse memoire o la ressource a t charge               */
/*         SI = 0 pas assez de memoire                                 */
/*            = 1 ce n'est pas un fichier de ressource                 */
/*            = 2 ouverture fichier impossible (fichier non trouv     */
/*                                              mauvais chemin ou nom) */
/*         il est fortement conseille de stocker cette adresse de      */
/*         chargement quelque part !!!                                 */
/* PROTOTYPE:                                                          */
          void *RscFicLoad(char *path, char *name, int scale_flag); 

/* ------------------------- RscFicUnLoad --------------------------------- */
/* ACTION: decharge la ressource et la memoire occupe par celle ci.        */
/*         il est obligatoire d'appeler cette fonction avant la fin du      */
/*         programme ou si l'on veut liberer et ejecter cette ressource     */         
/*         car l'on n'en a plus besoin. Il est evident que si l'on veut de  */
/*         nouveau utiliser cette ressource il faudra la recharger avec     */
/*         la fonction: RscFicLoad                                          */
/* ENTREE: void *adr_rsc adresse memoire o a t charge la ressource      */
/* SORTIE: void *adr_rsc est mise  zero                                    */        
/* PROTOTYPE:                                                               */
           void RscFicUnLoad(void *adr_rsc);                              

/*------------------------ LoadAppliRsc ----------------------------------*/
/* ACTION: charge la ressource dont le nom est donn en entree, dans les  */
/*         diffrents repertoires possibles de l'application.             */
/*         Soit celui de la chaine d'environnement lie  l'application,  */
/*         Soit dans un dossier portant le nom de l'application avec      */
/*              l'extension .RSC, situe dans meme repertoire que l'appli- */ 
/*              cation.                                                   */
/*         Soit dans un dossier portant le nom de l'application avec      */
/*              l'extension .SYS, situe dans meme repertoire que l'appli- */ 
/*              cation.                                                   */
/*         Soit au niveau du repertoire de l'application.                 */
/* ENTREE: char *nom_rsc: pointe sur nom du fichier ressource  charger   */
/*         int scale: NO_SCALE/0 echelle reduite.                         */
/*                       SCALE/1 echelle normale du GEM.                  */
/* SORTIE: adresse de chargement de la ressource.                         */

void *LoadAppliRsc(char *nom_rsc, int scale);

/*------------------------ xrsrc_gaddr -------------------------------------*/
/* ACTION: permet d'obtenir l'adresse des differents elements de la         */
/*         ressource. Cette fonction fonctionne comme  rsrc_gaddr du GEM    */
/*         avec comme parametre suplementaire l'adresse de la ressource     */
/* ENTREE: int type:     type d'element dont on veut l'adresse              */
/*                       (comme ceux du  rsrc_gaddr classique du GEM)       */        
/*         int index:    index de l'element dont on veut l'adresse          */
/*         int *adr_rsc: adresse de chargement de la ressource. C'est celle */
/*                       que l'on a obtenu avec la fonction: RscFicLoad     */ 
/* SORTIE: void *adr_ret: adresse de l'element recherch                    */
/* EXEMPLE: cet exemple indique comment obtenir l'adresse d'un arbre de     */
/*          ressource (dialogue, menu, etc..) Ici je desire avoir l'adresse */
/*          du premier objet du troisieme arbre (indexe  partie de zero)   */
/*          de la ressource chargee par: RscFicLoad  l'adresse: AdrRsc     */
/*          OBJECT *tree;   je declare un pointeur sur un objet             */
/*          xrsrc_gaddr (R_TREE, 2, &tree, AdrRsc);  j'appelle la fonction  */
/*          et apres cet appel, tree pointe sur le premier objet de la      */
/*                              ressource que je peux donc utiliser pour    */
/*                              affichage et autres  manipulations comme    */
/*                              dans le GEM traditionnel.                   */
/* PROTOTYPE:                                                               */
    int xrsrc_gaddr (int type, int index, void *adr_ret, int *adr_rsc);  

/*----------------------- SetBulleState ------------------------------*/
/* ACTION: cherche un indicateur d'tat de la bulle d'aide dans       */
/*         l'arbre de ressource point par OBJECT *object et le place */
/*         dans le bon etat d'activite et le redessine.               */
/* ENTREE: int w_h, handle GEM de la fenetre ou se trouve la ressource*/
/*         OBJECT *object, pointe sur l'arbre de ressource.           */    

void SetBulleState(int w_h, OBJECT *object);


/*------------------- FindFirstEditable -----------------------------*/   
/* ACTION: trouve le premier editable dans les fils d'un objet       */
/* ENTREE: OBJECT *object, pointe sur l'arbre dont on cherche le     */
/*                premier editable.                                  */
/*         int ind indice de l'objet pere dont il faut explorer la   */
/*                descendance.                                       */
/* RETOUR: indice du premier editable si trouv.                     */
/*         -1 si non trouv.                                         */

int FindFirstEditable(OBJECT *object, int ind);

/*------------------- FindNextEditable ------------------------------*/   
/* ACTION: trouve l'editable suivant un objet dans la descendance    */
/*         d'un objet.                                               */
/* ENTREE: OBJECT *object, pointe sur l'arbre dont on cherche        */
/*                l'editable.                                        */
/*         int ind, indice de l'objet pere dont il faut explorer la  */
/*                descendance.                                       */
/*         int ob_edit, indice de l'objet actuellement edit.        */
/* RETOUR: indice de  l'editable suivant si trouv.                  */
/*         -1 si non trouv.                                         */

int FindNextEditable(OBJECT *object, int ind, int ob_edit);

/*------------------- FindPreviousEditable --------------------------*/   
/* ACTION: trouve l'editable prcdant un objet dans la descendance  */
/*         d'un objet.                                               */
/* ENTREE: OBJECT *object, pointe sur l'arbre dont on cherche        */
/*                l'editable.                                        */
/*         int ind, indice de l'objet pere dont il faut explorer la  */
/*                descendance.                                       */
/*         int ob_edit, indice de l'objet actuellement edit.        */
/* RETOUR: indice de  l'editable precedent si trouv.                */
/*         -1 si non trouv.                                         */

int FindPreviousEditable(OBJECT *object, int ind, int ob_edit);

/*------------------- FindFirstObject -------------------------------*/
/* ACTION: donne l'indice du premier objet d'un arbre ressource      */
/*         par rapport  un objet quelconque passe en entree         */
/* ENTREE: OBJECT* object, pointe sur un objet quelconque            */               
/* RETOUR: indice de l'objet pere (forcement negatif)                */

int FindFirstObject(OBJECT *object);

/*--------------------------- ObjcGetTxt -----------------------------------*/
/* ACTION: permet d'obtenir l'adresse de la chaine texte d'un objet.        */
/*         Il est impratif de n'utiliser que cette fonction dans EAZY_GEM  */
/*         pour obtenir l'adresse de la chaine texte des objets.            */
/* ENTREE: OBJECT *adr, pointe sur l'arbre de l'objet.                      */
/*         int object, indice de l'objet.                                   */
/* RETOUR: un char* pointant sur la chaine de texte de cet objet.           */

char *ObjcGetTxt (OBJECT *adr, int object);

/*---------------------------- ObjcSetTxt ----------------------------------*/
/* ACTION : place la chaine string place en entr dans la zone texte       */
/*          de l'objet donn en entre. La chaine d'entree est tronque si  */
/*          elle depasse celle que l'objet peut admettre.                   */
/*          Il est impratif de n'utiliser que cette fonction dans EAZY_GEM */
/*          pour placer une chaine texte dans un objet .                    */
/* ENTREE: OBJECT *adr, pointe sur l'arbre de l'objet.                      */
/*         int object, indice de l'objet.                                   */
/*         char *string, pointe sur la chaine de caracteres  placer.       */

void ObjcSetTxt (OBJECT *adr, int object, char *string);

/*-----------------------  Wobjc_draw ------------------------------*/
/* ACTION: redessine l'objet place en entree, en tenant compte de   */
/*         la liste des rectangles.                                 */
/* ENTREE: int w_ind: indice EAZY_GEM de LA fenetre.                */
/*         OBJECT *object, adresse arbre auquel appartient l'objet. */
/*         int num_ob, numro de l'objet dans cet arbre.            */
/*         int niveau, profondeur de redessin dans la descendance   */
/*         GRECT *clipgrect, rectangle de clipping.                 */
/*                si il est non defini (==0), c'est le rectangle de */
/*                de l'objet qui est utilis.                       */

int Wobjc_draw(int w_ind, OBJECT *object, int num_ob, int niveau, GRECT *clip_grect);

/*-----------------------  Xobjc_draw ------------------------------*/
/* ACTION: redessine l'objet place en entree avec le rectangle de   */
/*         clipping                                                 */
/* ENTREE: OBJECT *object, adresse arbre auquel appartient l'objet. */
/*         int num_ob, numro de l'objet dans cet arbre.            */
/*         int niveau, profondeur de redessin dans la descendance   */
/*         GRECT *clipgrect, rectangle de clipping.                 */

void Xobjc_draw(OBJECT *object, int num_ob, int niveau, GRECT *clipgrect);

/*-------------------------------- PopupDo -------------------------------------*/
/* ACTION: affiche et controle un popup fait d'un objet quelconque contenant    */
/*         d'autres objets consideres comme des options.                        */
/* ENTREE: OBJECT *object:                                                      */
/*               adresse de l'arbre auquel appartient l'objet pere des options. */
/*         int ind:                                                             */
/*               indice dans cet arbre de l'objet pere des options .            */        
/*         int ob_sel:                                                          */
/*               indice dans cet arbre de l'objet option preselectionnee.       */
/*         int x,y:                                                             */
/*               coordonnes d'affichage du centre popup. Ce centre se recentre */
/*               sur l'option preselectionne                                   */
/* RETOUR: int: option selectionne si >0    click non valide sinon             */

int PopupDo(OBJECT *object, int ind, int ob_sel, int x, int y);

/*---------------------------- PopupListDo --------------------------------*/
/* ACTION: affiche un popup menu avec surveillance des rectangles de titre */
/*         -->> Si ces rectangles sont definis,                            */ 
/*                          (grecttitle_out !=0 et grecttitle_in != 0),    */
/*         lorsque la souris penetre dans la zone  grecttitle_out le popup */
/*         se referme et retourne le message POPUP_CHANGE (32000)          */
/*         -->> Si ces rectangles ne sont pas definis,                     */
/*                          (grecttitle_out ==0 et grecttitle_in == 0),    */
/*         le popup se referme soit si click en dehors, soit si click sur  */
/*         option valide (non disabled)                                    */
/*         Cette fonction est une sous fonction de la fonction de menu en  */
/*         fenetre, et peut etre utilise pour afficher un popup simple.   */
/*         c'est pourquoi son fonctionnement est particulier.              */
/* ENTREE: ............... 1) objet de reference graphique .............   */
/*         OBJECT *object: adresse arbre auquel appartient l'objet.        */
/*         int ob_ind: numro de l'objet dans cet arbre.                   */
/*               NOTE: l'objet designe par object[ob_ind] ne sert que pour */
/*                     indiquer les caractristiques graphiques du fond et */
/*                     du texte du popup. C'est en fait son TEDINFO qui    */
/*                     utilis pour dessiner le reste du menu.             */
/*                     Pour un popup simple, c'est l'objet pere des        */
/*                     options du menu. (par exemple).                     */ 
/*                     Cet objet pere peut etre: SOIT -> un type G_BOXTEXT */
/*                     (type BoxText sous Interface) type tendu doit      */
/*                     etre: 102.                                          */
/*                                               SOIT -> un type G_BOXTEXT */
/*                     (type BoxText sous Interface) type tendu doit      */
/*                     etre: 107. Pere d'un menu GEM en fenetre.           */
/*         ............... 2) objet de reference options ...............   */
/*         OBJECT *menu_tree: adresse arbre auquel appartient l'objet.     */  
/*         int ind_list: numro de l'objet dans cet arbre.                 */
/*               NOTE: l'objet designe par menu_tree[ind_list] doit        */
/*                     contenir comme objets fils les options de menu sous */
/*                     forme de string.                                    */
/*         int x,y;  coordonnees d'affichage du popup.                     */
/*         GRECT *grecttitle_out: rectangle de surveillance.               */
/*         GRECT *grecttitle_in: rectangle de surveillance.                */

int PopupListDo(OBJECT *object,     int ob_ind,  
                OBJECT *menu_tree,  int ind_list,
                int x, int y, 
                GRECT *grecttitle_out,
                GRECT *grecttitle_in);                                          
                
/*--------------------------- MakeEvntClicOnObjet ------------------------*/
/* ACTION: Modifie le flux evenementiel, represente par EVNT_O *Evnt, de  */
/*         maniere a silmuler le click sur un objet dont les coordonnees  */
/*         sont donnees en entree.                                        */
/* ENTREE: OBJECT *object, pointe sur le prem. objet de l'arbre d'objets  */
/*                         ou se trouve l'objet.                          */
/*         int ob_ind, indice de l'objet clique dans cet arbre.           */
/*         EVNT_O *Evnt, pointe sur la variable de flux evenementiel a    */
/*                       modifier.                                        */
/* SORTIE: EVNT_O *, pointe sur la variable de flux evenementiel modifiee */

EVNT_O *MakeEvntClicOnObjet(OBJECT *object, int ob_ind, EVNT_O *Evnt);

/*--------------------- GetFreeString ------------------------------------*/
/* ACTION: Retourne l'adresse du tableau de pointeurs de freestring, d'une*/
/*         ressource.                                                     */
/*         Il est ensuite possible d'acceder a chaque chaine de cette     */
/*         table par son indice. (utiliser pour les indices la table      */
/*                                symbolique .H que genere Interface.)    */                                          
/* ENTREE: void *adr_rsc, adresse ou a ete chargee la ressource dont on   */
/*                        cherche la table de FreeString.                 */
/* SORTIE: char **, pointe sur la table de pointeur de chaine.            */

char **GetFreeStringTab(void *adr_rsc);
                
/*************************************************************************/
/*           F O N T I O N S   D E   S O U R I S   ( G E M )             */
/*************************************************************************/ 
/* ----------------------------- Mouse_on ----------------------------- */
/* ACTION: cette fonction sert  afficher la souris. EAZY_GEM tient    */
/*         jour un flag de visibilit permettant d'utiliser cette       */
/*         fonction sans se procuper de l'tat anterieur de la souris. */
/*         Il est conseill de toujours utiliser cette fonction.        */ 

void Mouse_on( void );            

/* ----------------------------- Mouse_off ---------------------------- */
/* ACTION: cette fonction sert  effacer la souris. EAZY_GEM tient     */
/*         jour un flag de visibilit permettant d'utiliser cette       */
/*         fonction sans se procuper de l'tat anterieur de la souris. */
/*         Il est conseill de toujours utiliser cette fonction.        */ 

void Mouse_off( void );               

/*-------------------------- Mousek ------------------------------------*/
/* ACTION: cette fonction retourne l'etat du bouton de la souris.       */

int Mousek(void);

/*-------------------------- Mousex ------------------------------------*/
/* ACTION: cette fonction retourne la position X de la souris.          */

int Mousex(void);

/*----------------------- Mousey ---------------------------------------*/
/* ACTION: cette fonction retourne la position Y de la souris.          */

int Mousey(void);

/*--------------------------- SetMouseForm -----------------------------*/
/* ACTION: determine la forme de la souris.                             */
/*         Il est recommand d'utiliser cette fonction pour modifier la */
/*         forme de la souris avec EAZY_GEM                             */
/* ENTREE: long cursor, forme de la souris.                             */
/*                 Les formes 0  7 sont les formes GEM Classiques.     */
/*                 8   100 sont les formes EAZY_GEM                    */
/* RETOUR: mode effectivement mis en place                              */

int SetMouseForm(long cursor);

/*--------------------------- GetMouseForm -----------------------------*/
/* ACTION: retourne la forme actuelle de la souris.                     */
/* RETOUR: forme souris effectivement en place                          */

long GetMouseForm(void);
/*************************************************************************/
/* F O N T I O N S   D E   T E S T   I N T E R R O G A T I O N ( V D I ) */
/*************************************************************************/

/*-------------------------- IsMouseXYInGrect -----------------------------*/
/* ACTION: Teste si la souris est dans le rectangle GRECT *grect.          */
/* ENTREE: int x, int y, coordonnes x & y  de la souris                   */
/*         GRECT *grect pointe sur le rectangle  tester                   */
/* SORTIE: 1 si la souris est dans le rectangle 0/si en dehors.            */

int IsMouseXYInGrect(int x, int y, GRECT *grect);                     


/*-------------------------- IsMouseXYInVrect -----------------------------*/
/* ACTION: Teste si la souris est dans le rectangle VRECT *vrect.          */
/* ENTREE: int x, int y, coordonnes x & y  de la souris                   */
/*         VRECT *vrect pointe sur le rectangle  tester                   */
/* SORTIE: 1 si la souris est dans le rectangle 0/si en dehors.            */

int IsMouseXYInVrect(int x, int y, VRECT *vrect);

/*------------------------------ FntID_VDI_to_TabInd --------------------------*/
/* ACTION: retourne l'indice permettant de pointer sur le tableau de fontes   */
/*         partir de l'identificateur VDI de la fonte                          */
/* ENTREE: long Id_Vdi:  identificateur VDI de la fonte                        */
/* RETOUR: indice permettant de pointer sur le tableau de fonte                */       

int  FntID_VDI_to_TabInd(long Id_Vdi);

/*************************************************************************/
/*           F O N T I O N S   D E   T R A C E   ( V D I )               */
/*************************************************************************/
/*----------------------- Graphmode ---------------------------------*/
/* ACTION: Met en place un mode graphique VDI.                       */ 
/* ENTREE: int mode: mode graphique VDI qui peut prendre les valeurs */
/*            suivantes:  MD_REPLACE      1  Replace                 */
/*                        MD_TRANS        2  Transparent             */
/*                        MD_XOR          3  Xor                     */
/*                        MD_ERASE        4  Reverse Transparent     */

void Graphmode(int mode);

/*----------------------- Defline -----------------------------------*/
/* ACTION: Definie et positionne tous les attributs VDI de ligne     */
/* ENTREE: int type, type VDI de ligne                               */
/*         int width, epaisseur de la ligne.                         */
/*         int deb, type VDI du debut de ligne.                      */
/*         int fin, type VDI de fin de ligne.                        */
/*         int color, couleur de la ligne.                           */

void Defline(int type,int width,int deb,int fin,int color);

/*------------------------Deffill------------------------------------*/
/* ACTION: Positionne tous les attributs VDI de remplissage          */
/* ENTREE: int color, couleur de la ligne.                           */
/*         int interior, type VDI de remplissage.                    */
/*         int motif, type VDI de motif.                             */

void Deffill(int color,int interior,int motif);

/*------------------------ Deftext ----------------------------------*/
/* ACTION: Positionne tous les attributs VDI d'affichage de texte.   */
/*         si speedo est detecte alors les fonctions speedo seront   */
/*         utilisees.                                                */
/* ENTREE: int color, couleur du texte.                              */
/*         int effect, effet VDI du texte.                           */
/*         int angle, angle VDI (en 10me Degres) affichage texte.   */
/*         int point, taille en points du texte.                     */
/*         int font, indice VDI de la police de caracteres.          */

void Deftext(int color,int effect,int angle,int point,int font);

/*----------------------- VdiText --------------------------------------*/
/* ACTION: affiche un texte sur le peripherique de sortie  represente   */
/*         par VDIhandle. Si Speedo est detect alors les fonctions     */ 
/*         d'affichage speedo seront utilisees.                         */
/* ENTREE: int x, int y: coordonnes en pixels d'affichage de la chaine */
/*         texte.                                                       */
/*         char *string: pointeur sur la chaine de texte.               */

void VdiText(int x, int y, char *string);

/*------------------------ Box --------------------------------------*/
/* ACTION: dessine un rectangle non rempli (mode trait).             */
/* ENTREE: int *xyxy tableau de coordonnes VDI.                     */

void Box(int *xyxy);

/*------------------------ Box_p -------------------------------------*/
/* ACTION: dessine un rectangle non rempli (mode trait).              */
/*         Idem que Box mais coordonnes donnes spares, sous forme */
/*         de paramtres individuels et non de tableau de parametres. */            
/* ENTREE: int x0,int y0,int x1,int y1, Coordonnees VDI.              */

void Box_p(int x0,int y0,int x1,int y1);

/*------------------------ Pbox ---------------------------------------*/
/* ACTION: dessine un rectangle rempli avec le motif en vigueur.       */
/* ENTREE: int *xyxy tableau de coordonnes VDI.                       */

void Pbox(int *xyxy);

/*------------------------ Pbox_p -------------------------------------*/
/* ACTION: dessine un rectangle rempli avec le motif en vigueur.       */
/*         Idem que Pbox mais coordonnes donnes spares,sous forme  */
/*         de paramtres individuels et non de tableau de parametres.  */            
/* ENTREE: int x0,int y0,int x1,int y1, Coordonnees VDI.               */

void Pbox_p(int x0,int y0,int x1,int y1);

/*--------------------------- GrectBox ------------------------------*/
/* ACTION: dessine un rectangle non rempli (mode trait).             */
/* ENTREE: GRECT *grect, adresse du rectangle de Coordonnees GEM.    */

void GrectBox(GRECT *grect);

/*-------------------------- GrectPbox ------------------------------*/
/* ACTION: dessine un rectangle rempli avec le motif en vigueur.     */
/* ENTREE: GRECT *grect, adresse du rectangle de Coordonnees GEM.    */

void GrectPbox(GRECT *grect);

/*----------------------------- DrawCustomCadre ----------------------------*/
/* ACTION: dessine un cadre rectangulaire epais en relief ou fin grav.     */
/* ENTREE: VRECT *vrect, coordonnes VDI du rectangle.                      */
/*         int type, si 0/epais relief,   si 1/fin grav                    */

void DrawCustomCadre(VRECT *vrect, int type);

/*------------------------ DrawReliefCadre ---------------------------------*/
/* ACTION: dessine un cadre rectangulaire avec effet relief.                */
/* ENTREE: GRECT *grect: pointe sur le rectangle d'entree.                  */
/*         int flag_relief: Si zero le cadre sera dessine sans relief.      */
/*                          Si >0 le carde est en relief sortant.           */
/*                          Si <0 le cadre est en relief rentrant.          */
/*         int thickness: epaisseur du cadre.                               */
/* SORTIE: neant:                                                           */
/* PROTOTYPE:                                                               */
   
void DrawReliefCadre(GRECT *grect, int flag_relief, int cadreColor,int thick);

/*--------------------------- DrawEnjolivedBox ---------------------------*/
/* ACTION: Dessine une boite avec cadre semi_circulaire, ombre, et fond   */
/*         Jaune comme celle des bulles d'aide.                           */
/* ENTREE: GRECT *grect_in: coordonnes du rectangle de la boite.         */
/*         GRECT *grect_cli: adresse du rectangle dans lequel il sera     */
/*                          retourne la surface interne utile de la boite */
/* SORTIE: GRECT *grect_cli: contient le rectangle client. (rectangle     */
/*                           interieur au cadre semi-circulaire)          */
/* RETOUR: GRECT * pointe sur le rectangle: grect_cli                     */

GRECT *DrawEnjolivedGrectBox(GRECT *grect_in, GRECT *grect_cli, int ofs_ombre);


/*------------------------ Line_p -----------------------------------*/
/* ACTION: dessine une ligne avec les attributs de ligne en vigueur. */
/* ENTREE: int x0,int y0,int x1,int y1, Coordonnees VDI.             */

void Line_p(int x0,int y0, int x1, int y1);

/*-------------------------- ClipGrect -----------------------------------*/
/* ACTION: clippe le rectangle GEM, GRECT *grect donn en entre          */
/* ENTREE: GRECT *grect, pointe sur le rectangle GEM  clipper.           */

void ClipGrect(GRECT *grect);            


/*------------------------- Blk_size -----------------------------------*/
/* ACTION : calcule la taille memoire necessaire pour stocker le bloc   */
/*          ecran dont la hauteur et la largeur sont donnes en entree  */
/* ENTREE : l et h largeur et hauteur du bloc en nbr de pixels -1       */
/*          int nb_plan, nombre de plans de l'image.                    */
/* SORTIE : Long longueur calcule                                      */

unsigned long Blk_size(int l, int h, int nb_plan);

/*----------------------------- GetGRECT ---------------------------------*/
/* ACTION: sauve dans un buffer le fond de l'ecran du rectangle grect     */
/* ENTREE: GRECT *grect, pointe sur le rectangle GEM  sauver.            */
/* RETOUR: adresse de la zone memoire ou est sauve ce fond                */
/*         zero ou NULL si plus de memoire disponible                     */

int *GetGRECT(GRECT* grect);

/*----------------------------- Get --------------------------------------*/
/* ACTION: sauve dans un buffer, un bloc d'ecran rectangulaire (VDI)      */
/* ENTREE: int *xyxy, pointe sur les dimensions du rectangle  sauver.    */
/* RETOUR: adresse de la zone memoire ou est sauve le bloc graphique ou:  */
/*            Le 1er  int est la largeur du bloc en nbr de pixels-1       */
/*            le 2eme int est la hauteur du bloc en nbr de pixels-1       */
/*            le 3eme est le nbr de plans de l'image.                     */
/*            suivent les datas d'image.                                  */
/*         zero ou NULL si plus de memoire disponible                     */

int *Get(int *xyxy);

/*-------------------------- Put-----------------------------------------*/
/* ACTION: Place en x et y un bloc d'ecran precedemment sauv par Get.   */
/*         ce graphique doit obligatoirement etre avec les memes         */
/*         caracteristiques RASTER quel'ecran (meme nbr couleurs, plans  */
/*         et organisation memoire).                                     */
/* ENTREE: int x,int y:                                                  */
/*              coordonnes x et y (angle sup gauche) ou l'on            */
/*              desire placer le bloc graphique.                         */
/*         int *xyxy_buff:                                               */
/*              pointeur sur la zone memoire ou se trouve le bloc        */
/*              graphique. Le 1er  int est la largeur en nbr de pixels-1 */
/*                         le 2eme int est la hauteur en nbr de pixels-1 */
/*                         le 3eme est le nbr de plans de l'image.       */
/*                         suivent les datas d'image.                    */
/*         int mode:                                                     */
/*              mode de copie du bloc (voir doc VDI)                     */

void Put( int x,int y,int *blk_buff,int mode);

/*-------------------------Put_mono--------------------------------------*/
/* ACTION: Place en x et y un bloc d'ecran precedemment sauv par Get.   */
/*         ce graphique doit obligatoirement etre monochrome 1 plan.     */
/* ENTREE: int x,int y:                                                  */
/*              coordonnes x et y (angle sup gauche) ou l'on            */
/*              desire placer le bloc graphique.                         */
/*         int *xyxy_buff:                                               */
/*              pointeur sur la zone memoire ou se trouve le bloc        */
/*              graphique. Le 1er  int est la largeur en nbr de pixels-1 */
/*                         le 2eme int est la hauteur en nbr de pixels-1 */
/*                         le 3eme est le nbr de plans de l'image.       */
/*                         suivent les datas d'image.                    */
/*         int mode:                                                     */
/*              mode de copie du bloc (voir doc VDI)                     */

void Put_mono(int x,int y,int *xyxy_buff,int mode);

/*------------------------- Put_mono_color -------------------------------*/
/* ACTION: Place en x et y un bloc d'ecran precedemment sauv par Get.   */
/*         ce graphique doit obligatoirement etre monochrome 1 plan.     */
/* ENTREE: int x,int y:                                                  */
/*              coordonnes x et y (angle sup gauche) ou l'on            */
/*              desire placer le bloc graphique.                         */
/*         int *xyxy_buff:                                               */
/*              pointeur sur la zone memoire ou se trouve le bloc        */
/*              graphique. Le 1er  int est la largeur en nbr de pixels-1 */
/*                         le 2eme int est la hauteur en nbr de pixels-1 */
/*                         le 3eme est le nbr de plans de l'image.       */
/*                         suivent les datas d'image.                    */
/*         int mode:                                                     */
/*              mode de copie du bloc (voir doc VDI)                     */
/*         int *color:                                                   */
/*             pointe sur deux int, le 1er est la couleur avec laquelle  */
/*                                  les pixels  1 (mis) du bloc, seront */
/*                                  recopis sur l'ecran.                */ 
/*                                  le 2eme est la couleur avec laquelle */
/*                                  les pixels  0 (non mis) du bloc,    */
/*                                  seront recopis sur l'ecran.         */ 

void Put_mono_color(int x,int y,int *xyxy_buff,int mode, int *color);


/*-------------------------- Scroll_p---------------------------------------*/
/* ACTION: Cette fonction permet de faire scroller en vertical un rectangle */
/*         d'une certaine quantit.                                         */
/* ENTREE: int x0,int y0,int x1,int y1, coordonnes VDI du rectangle.       */
/*         int  delty, est la valeur dont doit scroller le rectangle xyxy   */
/*                   en entree: SI negative la partie haute xyxy descend.   */
/*                              SI positive la partie basse xyxy monte.     */

void Scroll_p(int x0,int y0,int x1,int y1,int delty);
 



/*************************************************************************/
/*         F O N T I O N S   D E    F E N E T R E S   ( G E M )          */
/*************************************************************************/

/* --------------------------- CreateWindow -----------------------------*/
/* DESCRIPTION:                                                          */
/* ------------                                                          */
/*      il est impratif de n'utiliser que cette fonction dans EAZY_GEM  */
/*       pour creer une fenetre.                                         */
/*  long w_attr: attributs GEM classique d'une fenetre                   */
/*               trois attributs de plus:                                */
/*                         BORDER permet d'avoir un cadre epais en       */
/*                                  relief autour de la fenetre.         */
/*                         XMOVER permet d'avoir une poigne de deplace- */
/*                                ment sur le bord sup du cadre epais    */
/*                         XSIZER permet l'agrandissement de la fenetre  */
/*                                en cliquant sur le cadre epais         */
/*  int Ident:  nbr arbitraire(jamais nul) que vous devez donner. Cela   */
/*              peut servir  reperer tel ou tel type de fenetre dans    */
/*              votre programme. Exemple votre application comporte      */
/*              plusieurs fenetres dont une de menu  laquelle vous      */
/*              donnez int ident=2 lors de sa cration. Il est           */
/*              alors facile pour le programme de savoir si la fenetre   */
/*              menu est ouverte en faisant appel  la fonction          */
/*              int IdentToIndice(2); qui vous retourne l'indice de la   */
/*              fenetre (si elle n'existe pas l'indice est >= MAX_WIND ) */
/*              pensez  utiliser des type symboliques declars avec:    */
/*              #define FENETRE_TRUC 2  plutot qu'un nombre sans sens.   */
/*                                                                       */
/*  void *adr:  adresse pointant sur diverses choses dependant du type   */
/*              gestion que l'on prevoit pour la fenetre. Cette adresse  */
/*              permet par exemple de passer un pointeur sur une struct- */
/*              ture, avec laquelle elle doit travailler. Ce parametre   */
/*              est donc facultatif. La fonction: CreateWindow() place   */
/*              ce parametre dans Wintab[w_ind].UserPtr de la fenetre.   */
/*                                                                       */                              
/*  CALLBACK (*w_proc)(int w_ind, EVNT_O *Evnt): L vous donnez le nom   */
/*              fonction qui sera charge de gerer tous les evenements   */
/*              de cette fenetre. Cette fonction sera appelee par la     */
/*              sur couche EAZY_GEM.                                     */
/* int x, int y, int w, int h,: coordonnees en pixels de la fenetre      */
/*              ces coordonnees doivent etre celles du contour exterieur */
/*              de la fenetre et non de la surface de travail            */
/*              si zero en entree alors les dimensions maxi possibles    */
/*              seront choisies.                                         */
/*              Ces dimensions peuvent etre modifiees avant ouverture de */
/*              la fenetre lors du traitement du message WM_CONSTRUCT    */
/*              au sein de la procedure de fenetre.                      */
/* char *nom:   titre de la fenetre                                      */
/*              de meme le titre de la fenetre peut etre modifie au sein */
/*              de la procedure de fenetre lors du traitement du message */
/*              WM_CONTRUCT.                                             */
/* RETOURNE: Le handle GEM de la fenetre si tout est OK.                 */
/*           -1 si Echec du constructeur de la fenetre                   */
/*           -2 si nbr fenetre superieur  MAX_WIND (maximum EAZY_GEM)   */
/*           -3 si l'AES n'a plus de fenetre  nous donner               */
/* PROTOTYPE:                                                            */
/*                                                                       */
  int  CreateWindow ( long w_attr,                                     
                      int ident,                                      
                      void *adr,                                                    
                      CALLBACK (*w_proc)(int w_ind, EVNT_O *Evnt),    
                      int x, int y, int w, int h,                      
                      char *nom                                        
                    );    
/*---------------------- CreateModalWindow -----------------------------*/
/* ACTION: cet appel est le meme que create window, a la difference     */
/*         qu'apres cet appel la main n'est rendue qu'apres fermeture   */
/*         de la fenetre. Lors de cet appel les autres fenetres, et le  */
/*         menu ne sont plus accessibles.                               */
                                                                 
int  CreateModalWindow ( long w_attr,                                     
                    int ident,                                         
                    void *adr,                                                        
                    CALLBACK (*w_proc)(int w_ind, EVNT_O *Evnt),      
                    int x, int y, int w, int h,                       
                    char *nom                                         
                  );
                  
/*-------------------------- DestroyWindow ---------------------------------*/
/* ACTION: dtruit une fenetre. Cette fonction gnre le message WM_DESTUCT */
/*         permettant  la fonction de fenetre de dsinitialiser ce qu'elle */
/*         avait ventuellement reserv (memoire, station de travail...)    */
/*         avant la destruction definitive de la fenetre GEM.               */
/*         Il est impratif de n'utiliser que cette fonction dans EAZY_GEM  */
/*         pour detruire une fenetre.                                       */
/* ENTREE: int w_h, handle GEM de la fenetre  detruire.                    */
  
void DestroyWindow(int w_h);

/*---------------------------- DestroyAllWindow ----------------------------*/
/* ACTION: dtruit toutes les fenetres de l'application. Cette fonction     */
/*         gnre pour chaque fenetre, le message WM_DESTUCT permettant     */
/*          la fonction de fenetre  de dsinitialiser ce qu'elle           */
/*         avait ventuellement reserv (memoire, station de travail...)    */
/*         avant la destruction definitive de la fenetre GEM.               */
/*         Il est impratif de n'utiliser que cette fonction dans EAZY_GEM  */
/*         pour detruire les fenetres.                                      */
/* ENTREE: neant                                                            */
  
void DestroyAllWindow(void);

/*-------------------------------- OpenWindow ------------------------------------*/
/* ACTION: ouvre une fenetre et note si elle est pas en FULL les coord.           */
/*         return 1 si FULL_SIZE return 0 si pas FULL_SIZE                        */
/*         Il est impratif de n'utiliser que cette fonction dans EAZY_GEM        */
/*         pour ouvrir une fenetre.                                               */
/* ENTREE: int w_ind:                                                             */
/*             indice EAZY_GEM de la fenetre (pointe sur tableau Windtab[w_ind]   */
/*             correspondant  cette fenetre.                                     */ 
/*         GRECT* grectb: coordonnees externes d'ouverture de la fenetre.         */
/* RETOUR: int: si 1/ouverture en full size  car coordonnes trop grandes.        */ 
/*                 0/ouverture selon coordonnes d'entre.                        */
                                 
int  OpenWindow(int w_ind, GRECT* grectb);

/*--------------------------- CloseWindow ---------------------------------*/
/* ACTION: ferme une fenetre EAZY_GEM. Il est absolument imperatif et      */
/*         indispensable d'utiliser cette fonction dans EAZY_GEM pour      */
/*         fermer une fenetre.                                             */
/* ENTREE: int w_ind, indice EAZY_GEM de cette fenetre.                    */
/* RETOUR: 0/si deja fermee    1/ si non deja fermee                       */

int  CloseWindow(int w_ind);

/*--------------------------- SetWindowSize ------------------------------*/
/* ACTION: redimensionne une fenetre EAZY_GEM et note si elle est pas en  */
/*         FULL les coord.                                                */
/*         Il est impratif d'utiliser cette fonction dans EAZY_GEM pour  */
/*         modifier les dimensions d'une fenetre.                         */
/* ENTREE: int w_ind, indice EAZY_GEM de cette fenetre.                   */
/*         GRECT* grectb dimensions exterieures souhaites de la fenetre. */             
/*         return 1 si FULL_SIZE return 0 si pas FULL_SIZE                */

int  SetWindowSize(int w_ind, GRECT* grectb);

/*-------------------------- IsWindOpen ----------------------------------*/
/* ACTION: teste si la fenetre EAZY_GEM est ouverte                       */
/* ENTREE: int ind, indice EAZY_GEM de cette fenetre.                     */
/* RETOUR: 0/si pas ouverte  1/si ouverte                                 */

int IsWindOpen(int ind);

/*--------------------------- IsWindFullSize -----------------------------*/
/* ACTION: teste si la fenetre EAZY_GEM est en plein ecran.               */
/* ENTREE: GRECT *grectb, dimensions exterieures de la fenetre.           */
/* RETOUR: 0/si pas plein ecran  1/si plein ecran                         */

int IsWindFullSize(GRECT *grectb);

/*--------------------------- IsWindExist --------------------------------*/
/* ACTION: teste si la fenetre EAZY_GEM existe.                           */
/* ENTREE: int ident, typage EAZY_GEM de cette fenetre (valeur donnee en  */
/*                    deuxime paramtre lors de CreateWindow() ).        */ 
/* RETOUR: -1/si existe pas  indice EAZY_GEM/si existe                    */

int IsWindExist(int ident);

/*--------------------------- IdentToIndice --------------------------------*/
/* ACTION: permet de retrouver l'indice EAZY_GEM d'une fenetre, dont le     */
/*         type: int ident, est donn en entre (celui que l'on met en      */
/*         deuxime paramtre de la fonction: CreateWindow() )              */
/* RETOUR: indice EAZY_GEM, permettant de pointer sur le tableau Windtab de */
/*         la fenetre correspondante. Cet indice doit etre < MAX_WIND sinon */
/*         la fenetre correspondant au type donn en entre n'existe pas.   */

int IdentToIndice(int ident);
            
/*--------------------------- WindHandToIndice -----------------------------*/
/* ACTION: permet de retrouver l'indice EAZY_GEM d'une fenetre, dont le     */
/*         handle GEM: int w_h, est donn en entre (celui retourn par  la */
/*         fonction: CreateWindow()  )                                      */
/* RETOUR: indice EAZY_GEM, permettant de pointer sur le tableau Windtab de */
/*         la fenetre correspondante. Cet indice doit etre < MAX_WIND sinon */
/*         la fenetre correspondant au type donn en entre n'existe pas.   */

int WindHandToIndice( int w_h);      

/*----------------------- GetGemWindWorkGRECT ----------------------------*/
/* ACTION: Retourne l'espace de travail GEM (interieur aux gadgets GEM de */
/*         la fenetre: Barre de titre, ascenseurs, cases etc ...          */
/* ENTREE: int hwnd, handle GEM de la fenetre.                            */
/* SORTIE: GRECT *grect, est initialis sur les valeurs de ce rectangle.  */

void GetGemWindWorkGRECT(int hwnd, GRECT *grect); 

/*----------------------- GetGemWindFullGRECT ----------------------------*/
/* ACTION: Retourne les coordonnes maxi exterieurs de la fenetre GEM     */
/* ENTREE: int hwnd, handle GEM de la fenetre.                            */
/* SORTIE: GRECT *grect, est initialis sur les valeurs de ce rectangle.  */

void GetGemWindFullGRECT(int hwnd,GRECT *grect);

/*----------------------- GetGemWindExtGRECT ------------------------------*/
/* ACTION: Retourne les coordonnes exterieurs actuelles de la fenetre GEM */
/* ENTREE: int hwnd, handle GEM de la fenetre.                             */
/* SORTIE: GRECT *grect, est initialis sur les valeurs de ce rectangle.   */

void GetGemWindExtGRECT(int hwnd,GRECT *grect);

/*------------------------------ GetClientGrect ----------------------------*/
/* ACTION: calcule l'espace de travail utilisateur laiss libre dans la     */
/*         fenetre, interieur au cadre epais et aux ressources de bords     */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre dont on recherche       */
/*                    l'espace client.                                      */
/*         GRECT *grect, adresse d'un rectangle devant recevoir les         */
/*                     coordonnes de l'espace client.                      */
/* SORTIE: GRECT *grect, est initialis sur l'espace de travail.            */
/* RETOUR: adresse du rectangle d'entree GRECT *grect initialise sur        */
/*               l'espace client, si il existe                              */
/*         zero sinon                                                       */

GRECT *GetClientGrect(int w_ind, GRECT *grect);

/*--------------------------- GemWindWorkToClientGrect ---------------------*/
/* ACTION: calcule l'espace de travail utilisateur laiss libre dans la     */
/*         fenetre, interieur au cadre epais et aux ressources de bords     */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre dont on recherche       */
/*                    l'espace client.                                      */
/*         GRECT *grect, rectangle de l'espace de travail GEM, qui sera     */
/*                     converti en coordonnes de l'espace client.          */
/* SORTIE: GRECT *grect, est initialis sur l'espace de travail client.     */
/* RETOUR: adresse du rectangle d'entree GRECT *grect initialise sur        */
/*               l'espace client, si il existe                              */
/*         zero sinon                                                       */

GRECT *GemWindWorkToClientGrect(int w_ind, GRECT *grect);

/*------------------------ WindEZWorkToGemBorder -----------------------*/ 
/* ACTION: calcule  partir de l'espace de travail interieur au cadre   */
/*         epais (si il existe) d'une fenetre EAZY_GEM, l'espace        */
/*         exterieur de la fenetre GEM.                                 */
/* ENTREE: long attr, attributs EAZY_GEM de la fenetre.                 */
/*         GRECT* grectw espace de travail interieur de la fenetre      */
/*                EAZY_GEM.                                             */
/* SORTIE: GRECT *grectb, est rempli avec les coordonnes externes GEM  */
/*                de la fenetre.                                        */

void WindEZWorkToGemBorder(long attr, GRECT* grectw, GRECT* grectb);


/*------------------------ WindGemBorderToEZWork -----------------------*/ 
/* ACTION: calcule  partir de l'espace de travail exterieur d'une      */
/*         fenetre GEM, l'espace interieur du fenetre EAZY_GEM          */
/*         (espace interieur au cadre epais si il existe)               */
/* ENTREE: long attr, attributs EAZY_GEM de la fenetre.                 */
/*         GRECT* grectb espace de travail exterieur de la fenetre      */
/*                GEM.                                                  */
/* SORTIE: GRECT *grectw, est rempli avec les coordonnes interieures   */
/*                de la fenetre EAZY_GEM.                               */

void WindGemBorderToEZWork(long attr,GRECT* grectb, GRECT* grectw);

/*------------------------- AdjustWindCoordToSrceen ------------------------------*/
/* ACTION: ajuste les coordonnes de la fenetre sous la souris, de faon  ce     */
/*         qu'elles ne dpassent pas de l'ecran et reajuste position ressource.   */
/* ENTREE: int w_ind:                                                             */
/*             indice EAZY_GEM de la fenetre (pointe sur tableau Windtab[w_ind]   */
/*             correspondant  cette fenetre.                                     */ 
/*         EVNT_O *Evnt: pointeur sur structure de flux evenementiel, d'ou l'on   */
/*             recupere les coordonnes de la souris.                             */
/*         GRECT *grect: pointeur sur un rectangle representant les coordonnes   */
/*             exterieures de la fenetre.                                         */
/* RETOUR: GRECT *: pointeur sur le rectangle d'entree modifie.                   */

GRECT *AdjustWindCoordToScreen (int w_ind, EVNT_O *Evnt, GRECT *grect);

/*----------------------------- UnconifyWindow -------------------------------*/
/* ACTION: desiconifie la fenetre iconifiee, si c'est une fenetre representant*/
/*         toute l'application, alors toutes les fenetres seront deployes.   */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre devant etre desiconifiee. */
/* RETOUR: toujours 1                                                         */

int UnconifyWindow(int w_ind);

/*------------------------------- IconifyWindow ------------------------------*/
/* ACTION: iconifie une fenetre ou l'application si touche CONTROL appuye.   */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre devant etre iconifiee.    */
/*         GRECT *grect, si pas egal  zero, alors les coordonnees fenetre    */
/*         icone seront celles donnes par ce rectangle et non celles         */
/*         automatiques que le GEM calcule.                                   */                                                     
/* RETOUR: toujours 1                                                         */

int IconifyWindow(int w_ind, GRECT *grect);

/*------------------------------- AllIconify ---------------------------------*/
/* ACTION: iconifie toute l'application.                                      */
/* ENTREE: GRECT *grect, si pas egal  zero, alors les coordonnees fenetre    */
/*         icone seront celles donnes par ce rectangle et non celles         */
/*         automatiques que le GEM calcule.                                   */                                                     
/* RETOUR: toujours 1                                                         */

int AllIconify(GRECT *grect);

/*------------------------------ Xform_keybd ---------------------------------*/
/* ACTION: gestion des actions clavier sur une ressource en fenetre           */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */
/* SORTIE: modification des divers champs editables                           */
/*         modification des elements de la structure DLG_VAR *dlg             */
/*         retourne -1 ou le Numero d'un objet default exit active RETURN     */   

int Xform_keybd(int w_ind, EVNT_O *Evnt);     

/*------------------------------ OnWm_moved ----------------------------------*/
/* ACTION: fonction executant tout ce qu'il est classique de faire pour       */
/*         le message WM_MOVED pour une fenetre avec ressource                */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */

int OnWm_moved( int w_ind, EVNT_O *Evnt);

/*------------------------------ OnWm_fulled ---------------------------------*/
/* ACTION: fonction executant tout ce qu'il est classique de faire pour       */
/*         le message WM_FULLED pour une fenetre avec ressource               */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */

int OnWm_fulled( int w_ind, EVNT_O *Evnt);

/*------------------------------ OnWm_sized ----------------------------------*/
/* ACTION: fonction executant tout ce qu'il est classique de faire pour       */
/*         le message WM_SIZED pour une fenetre avec ressource                */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */

int OnWm_sized( int w_ind, EVNT_O *Evnt); 

/*------------------------------ OnButtonBorder ------------------------------*/
/* ACTION: gestion des actions souris sur la bordure d'une fenetre            */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */
/* SORTIE: messages d'agrandissement et deplacements envoys                  */
/*         retourne 0 si pas souris sur bord                                  */   
/*                  1 si souris sur bord                                      */

int OnButtonBorder( int w_ind, EVNT_O *Evnt);  

/*------------------------------ Xform_button  -------------------------------*/
/* ACTION: gestion des actions souris sur une ressource en fenetre            */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */
/* SORTIE: modification des divers champs editables                           */
/*         modification des elements de la structure DLG_VAR *dlg             */
/*         retourne -1 ou le Numero d'un objet selectable cliqu              */   

int Xform_button( int w_ind, EVNT_O *Evnt);    

/*------------------------ Xform_moved -------------------------------*/
/* ACTION: reajuste les parametres de la ressource en fenetre apres   */
/*         un mouvement de fenetre                                    */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */
/*         GRECT *grect coordonnees interieures GEM de la fenetre contenant la*/
/*               ressource.                                                   */

void Xform_moved(int w_ind, EVNT_O *Evnt);

/*------------------------------ Xform_timer ---------------------------------*/
/* ACTION: gestion des actions timersur une ressource en fenetre              */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/* SORTIE: etat du curseur clignotant                                         */

int Xform_timer(int w_ind); 

/*------------------------------ Xform_mu_move -------------------------------*/
/* ACTION: gestion des actions des mouvements souris sur une ressource en     */
/*         fenetre.                                                           */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */
/*         EVNT_O *Evnt structure de flux evenementiel                        */
/* SORTIE: forme EAZY_GEM de la souris                                        */

int Xform_mu_move(int w_ind, EVNT_O *Evnt); 

/*---------------------- WindDialogConstruct ---------------------------*/
/* ACTION: integre un dialogue en fenetre.                              */
/* ENTREE: int w_ind: indice de notre fenetre pointe sur bonne          */
/*                    structure Windtab[wind]                           */
/*         void *adr_rsc: adresse de chargement de la ressource.        */
/*         int tree:      numero de l'arbre a integrer.                 */
/*         int type:      type d'arbre a integrer RSC_DIAL ou TOOL_BAR  */
/*         EVNT_O *Evnt: pointe sur structure de flux evenementiel      */
/* SORTIE: Evnt->evnt = WM_ABORT; si echec / inchang si tout est ok    */
/*         Evnt->pipe[X_B]  Evnt->pipe[H_B] initialise sur dimenssions */
/*                                         d'ouverture de la ressource  */

int WindDialogConstruct(int w_ind, void *adr_rsc, int tree, int type, 
                        EVNT_O *Evnt );
/*--------------------------- Xform_construct --------------------------*/
/* ACTION: installe un arbre de ressource dans une fenetre et l'adapte  */
/* ENTREE: int w_ind indice de notre fenetre pointe sur bonne structure */
/*                   Windtab[wind]                                      */
/*         EVNT_O *Evnt pointe sur structure de flux evenementiel       */
/* IMPORTANT:                                                           */
/*         Windtab[wind].DlgVar.AdrRsc doit deja etre initialise sur    */
/*         l'adresse de chargement de la ressource avant l'appel.       */
/*         Windtab[wind].DlgVar.type doit deja etre initialise sur      */
/*         le type de ressource avant l'appel.                          */
/*         Windtab[wind].DlgVar.NumTree doit deja etre initialise sur   */
/*         l'arbre  installer (une ressource peut comporter plusieurs  */
/*         arbres)                                                      */
/* SORTIE: les elements de DLG_VAR *dlg sont initialises sur la ressour.*/
/*         Evnt->evnt = WM_ABORT; si echec / inchang si tout est ok    */
/*         Evnt->pipe[X_B]  Evnt->pipe[H_B] initialise sur dimenssions */
/*                                         d'ouverture de la ressource  */

int Xform_construct(int w_ind, EVNT_O *Evnt);

/*--------------------------- Xform_Destruct ---------------------------*/
/* ACTION: efface tous les blocs memoires reserve par la ressource lors */
/*         de sa mise en fenetre                                        */
/* ENTREE: int w_ind indice de notre fenetre pointe sur bonne structure */
/*                   Windtab[wind]                                      */
/*         EVNT_O *Evnt pointe sur structure de flux evenementiel       */

int Xform_Destruct(int w_ind, EVNT_O *Evnt);

/*----------------------------- CloseListBox ---------------------------------*/
/* ACTION: Verifie si une LISTBOX est ouverte dans la fenetre                 */
/*         et si oui la ferme.                                                */
/* ENTREE: w_ind, indice EAZY_GEM de la fenetre conteneant le ressource.      */

void CloseListBox (int w_ind);

/*----------------------------- SetCursObEditOff------------------------------*/
/* ACTION: eteint le curseur texte des champs editables                       */
/*         Il est recommand d'utiliser cette fonction avan le redessin d'un  */
/*         editable par la fonction Xobjc_draw().                             */
/* ENTREE: DLG_VAR *dlg structure dialogue rattache  la fenetre contenant   */
/*         l'arbre de ressource dont on souhaite eteindre le curseur.         */

void SetCursObEditOff(DLG_VAR *dlg);

/* --------------------------- Lister_rectangles -------------------------- */
/* ACTION: Gestion de la liste des rectangles GEM. Cette fonction est      */
/*         utiliser en reponse au message GEM WM_REDRAW.                    */
/*         Tout le redessin d'une ressource en fenetre est pris en          */
/*         charge par cette fonction, qui gnre le message WM_PAINT si     */
/*         il est  votre charge de redessiner quelque chose.               */
/* Ce nouveau message est envoy a notre procedure de fenetre               */
/* lorsqu'il faut retracer quelque chose  l'ecran: la surface client.      */
/* La surface client est le rectangle interieur  la fenetre, au cadre      */
/* epais, et aux eventuelles ressources de bord. Cette surface peut tres    */
/* bien ne pas exister par exemple dans le cas d'une ressource occupant     */
/* toute la fenetre, et alors le message WM_PAINT n'est pas genere.         */                                               
/*                                                                          */
/* En: Evnt->pipe[X_G], Evnt->pipe[Y_G], Evnt->pipe[W_G], et                */
/*     Evnt->pipe[W_G], se trouve le rectangle de clipping                  */              
/*                      qui est dej clipp par EAZY_GEM,                   */
/* En: Evnt->pipe[X_B], Evnt->pipe[Y_B], Evnt->pipe[W_B], et                */
/*     Evnt->pipe[W_B], se trouve le rectangle de la surface                */    
/*                      client qu'il est   votre charge de                 */
/*                      redessiner                                          */
/* ENTRE : w_h handle  de la fenetre  redessiner                           */
/*         xyly pointeur sur la zone a redessiner                           */

void Lister_rectangles(int w_h, GRECT *xylh);




/*************************************************************************/
/*           F O N T I O N S   D E  M E S S A G E S   ( G E M )          */
/*************************************************************************/

/*----------------------------- Pause_EZ ----------------------------------*/
/* ACTION: permet d'introduire un delai de x dixiemes de secondes          */
/*         Cette fonction est une fonction GEM et ne doit pas etre utilisee*/
/*         dans les fonctions cdecl.                                       */
/* ENTREE: long t, delai en dixiemes de secondes.                          */

void Pause_EZ(long t);
 
/*--------------------------- Send_VA_START ---------------------------*/
/* ACTION envoie  l'application dont l'ID est appl_id, un message     */
/*        VA_START afin qu'elle charge le fichier ou se mette au       */
/*                 premier plan ou fasse un peu ce qu'elle veut        */
/* ENTREE: appl_id iddentificateur de l'application destinataire       */
/*         path chemin complet envoy  l'application                  */

void  Send_VA_START(int appl_id, char *path); 

/*--------------------------- SendMessage --------------------------*/
/* ACTION: Envoie un message simple sans paramtres                 */
/* ENTREE: int messg, message  envoyer                             */

void SendMessage(int messg);

/*--------------------------- SendGrectRedrawMessage ---------------*/
/* ACTION: ordonne  une fenetre de redessiner une portion de sa    */
/*         surface.                                                 */
/* ENTREE: int w_h, handle GEM de la fenetre cible.                 */
/*         GRECT *grect coordonnes du rectangle  redessiner.      */

void SendGrectRedrawMessage(int w_h, GRECT *grect);

/*--------------------------- SendWindRedraw -----------------------*/
/* ACTION: ordonne  une fenetre de se redessiner sur toute sa      */
/*         surface.                                                 */
/* ENTREE: int w_h, handle GEM de la fenetre  redessiner           */

void SendWindRedraw(int w_h);

/*--------------------------- SendExeFunc ------------------------------*/
/* ACTION: envoie a l'application de destination app_id, un message  */
/*         d'execution de fonction.                                  */
/* ENTREE: int app_id: identificateur GEM de l'application a qui le  */
/*                     message est destin.                          */
/*         int num_func: numero de fonction que l'on desire executer */
/*                       dans cette application .                    */
 
void SendExeFunc(int app_id, int num_func);

/*----------------------- SendObjectRedraw -------------------------*/      
/* ACTION: envoie un message de redessin sur la surface occupee par */
/*         un objet  a une fenetre                                  */
/* ENTREE: int w_h, handle GEM de la fenetre cible.                 */
/*         OBJECT *object, adresse arbre auquel appartient l'objet. */
/*         int num_ob, numro de l'objet dans cet arbre.            */

void SendObjectRedraw(int w_h, OBJECT *object, int num_ob);

/*-------------------------- SendWindMessage --------------------------*/ 
/* ACTION: permet d'envoyer  une fenetre un message quelconque avec   */
/*         4 parametres de dimensions (ou autre chose)                 */
/* ENTREE: int w_h, handle GEM de la fenetre cible.                    */
/*         int messg, message  envoyer                                */
/*         GRECT *grect 4 parametres sous forme de rectangle.          */
/*                SI grect est egal  zero le rectangle est ignor     */

void SendWindMessage(int w_h, int messg, GRECT *grect);

/*----------------------------ExeAllMessage---------------------------------*/
/* ACTION: permet d'executer tous les messages empils                      */
/*         afin d'etre sur que notre action puisse se faire apres tous les  */
/*         autres messages                                                  */

int ExeAllMessage( void );
 

/*************************************************************************/
/*           F O N T I O N S   D E   F I C H I E R S   ( G E M  )        */
/*************************************************************************/

/*---------------------------Fic_select----------------------------------*/
/* ACTION: appelle le selecteur d'objet et met  jour le chemin d'entree */
/*         et le nom de fichier, si le fichier est valide et confirmer.  */
/* ENTREE: char *path_in, path d'entree de la forme A:\PATH\             */
/*         char *nom_in, nom du fichier de la forme  NOM_FIC.EXT         */
/*         char *ext, extension                                          */
/*         char *mess message d'information  afficher.                  */
/* RETOUR:                                                               */
/* <- longueur du fichier si zero fichier vide                           */   
/*                        si -1L     mauvaise extension                  */  
/*                        si -2L;    option annuler cliquee              */
/*                        si -3L;    ce Fichier n'existe pas             */
/* <- path eventuellement modifie (si Len_fic>0)                         */
/* <- nom eventuellement modifie  (si Len_fic>0)                         */

long Fic_select (char *path_in, char *nom_in, char *ext, char *mess);

/*---------------------- GetPathAppli ----------------------------------*/
/*  ACTION: cherche le path de demarrage de l'application  partir de   */
/*          son nom, eventuellement retourne le nom du fichier avec     */
/*          lequel le programme est demarr                             */
/* ENTREE:  nom_appli = NOM_PRG.PRG nom du programme cherch            */
/* SORTIE:  path  chemin A:\UPSIS\ dans lequel se trouve le programme   */
/*          fic_auto si non NUL il sera retourne le nom du fichier      */
/*                   eventuellement depose sur le programme au depart   */          
/* RETOUR: 0 si pas de fichier associe au lancement du programme        */
/*         1 si fichier associe au demarrage                            */

int GetPathAppli(char *path, char *nom_appli, char *fic_auto);

/*--------------------------- FindFicSys --------------------------------*/
/* ACTION: cherche le fichier nom, d'abord au niveau du repertoire       */
/*         path, puis au niveau du repertoire path\nom_appli.SYS puis au */
/*         niveau du repertoire path\nom_appli.RSC                       */
/* ENTREE: path = "A:\PATH\" chemin ou doit commencer la recherche       */
/*         nom_appli = "NOMPRG.PRG" nom de l'application                 */
/*         nom       = "NOMFIC.FIC" nom du fichier  chercher            */
/* RETOUR: <0 si pas trouve  >=0 si trouve                               */
/*         path contient le chemin "A:\PATH\" de dcouverte              */

long FindFicSys(char *path, char *nom_appli, char *nom);  

/*************************************************************************/
/*           F O N T I O N S   D E   F I C H I E R S   ( G E M D O S  )  */
/*************************************************************************/

/*---------------------- PathNomToNomFic -------------------------------*/
/* ACTION: extrait le nom du fichier  partir du nom complet du path    */
/* ENTREE: path = A:\DOSSIER\NOM.FIC                                    */
/* SORTIE: nom  = NOM.FIC                                               */
/*         path = A:\DOSSIER\                                           */
/* RETOUR: adresse de nom                                               */              
                           
char *PathNomToNomFic(char *path, char *nom);

/*--------------------------- Enleve_ext -------------------------------*/
/* ACTION: enleve l'extension  nom de fichier passe en entree.          */
/* ENTREE: char *nom, pointe sur le nom du fichier.                     */
/* RETOUR: un char* pointant sur le nom modifie                         */

char *Enleve_ext(char *nom);

/*---------------------Epure_path---------------------------------------*/
/* ACTION:  enleve au path l'eventuel "*.EXT"                           */
/* ENTREE: char *path, chaine  traiter           A:\PATH\*.EXT         */
/* RETOUR: un char* pointant sur chaine traite   A:\PATH\              */

char *Epure_path(char *path);

/*----------------------Fic-exist ---------------------------------------*/
/* ACTION: retourne la longueur d'un fichier, ou -1L si n'existe pas     */
/*         avec message Alert si il n'existe pas                         */
/*         les paths d'entree ne sont pas modifis                       */
/* ENTREE: char *path_in, path d'entree de la forme A:\PATH\             */
/*         char *nom_in, nom du fichier de la forme  NOM_FIC.EXT         */
/* RETOUR: longueur du fichier si il existe                              */
/*        -1 si il n'existe pas                                          */

long Fic_exist(char *path, char *nom);

/*--------------------------- FicLen ------------------------------------*/
/* ACTION: retourne la longueur d'un fichier, ou -1L si n'existe pas     */
/*         avec message Alert si il n'existe pas                         */
/*         les paths d'entree ne sont pas modifis                       */
/* ENTREE: char *path_in, path d'entree de la forme A:\PATH\             */
/*         char *nom_in, nom du fichier de la forme  NOM_FIC.EXT         */
/* RETOUR: longueur du fichier si il existe                              */
/*        -1 si il n'existe pas                                          */

long FicLen(char *path, char *nom);

/*---------------------------Bload--------------------------------------*/
/* ACTION: Charge un fichier a l'adresse specifiee en entree.           */
/* ENTREE: char *path_in, path d'entree de la forme A:\PATH\            */
/*         char *nom_in, nom du fichier de la forme  NOM_FIC.EXT        */
/* SORTIE: adresse memoire situee apres le dernier octet charge.        */
/*         (si egale a l'adresse de chargement c'est qu'il il n'y a     */
/*          rien de charge donc erreur.)                                */

void  *Bload( char *path, char *name, void *adr_load);

/*------------------------- Bsave --------------------------------------*/
/* ACTION: Sauve dans un fichier dont le nom et le path sont specifies  */
/*         un bloc memoire situe  l'adresse adr_src et de longueur len */
/*         si le fichier existait auparavant, il est detruit.           */
/* ENTREE: char *path_in, path d'entree de la forme A:\PATH\            */
/*         char *nom_in, nom du fichier de la forme  NOM_FIC.EXT        */
/*         void *adr_src, adresse de la zone memoire a sauver.          */
/*         size_t len, longueur de memoire a sauver.                    */
/* SORTIE: long positif, tout est OK. (nbr d'octets lus)                */
/*         Negatif: -300 ce fichier existait deja et n'a pu etre efface */
/*                  -301 impossible d'ouvrir le fichier.                */
/*                  autres nbr. negatifs = GEMDOS ERROR                 */

long Bsave(char *path_in, char *nom_in, void *adr_src, size_t len);           
/*************************************************************************/
/*           F O N T I O N S   D E   T R A N S F O R M A T I O N         */
/*************************************************************************/      
            
/*-------------------- VRECT_to_GRECT ------------------------------------*/ 
/* ACTION: transforme un rectangle VDI en rectangle GEM                   */
/* ENTREE: VRECT *vrect, pointe sur le rectangle VDI.                     */
/*         GRECT *grect, pointe sur le rectangle GEM.                     */
/* SORTIE: GRECT *grect, est initialis sur les valeurs transformes.     */
/* RETOUR: un pointeur sur le rectangle GRECT *grect, de l'entree.        */

GRECT *VRECT_to_GRECT(VRECT *vrect, GRECT *grect);            
            
/*-------------------- GRECT_to_VRECT ------------------------------------*/ 
/* ACTION: transforme un rectangle GEM en rectangle VDI                   */
/* ENTREE: GRECT *grect, pointe sur le rectangle GEM.                     */
/*         VRECT *vrect, pointe sur le rectangle VDI.                     */
/* SORTIE: VRECT *vrect, est initialis sur les valeurs transformes.     */
/* RETOUR: un pointeur sur le rectangle VRECT *vrect, de l'entree.        */

VRECT *GRECT_to_VRECT(GRECT *grect,VRECT *vrect);            
                        
/*-----------------------AdjustXYGrectToScreen -----------------------------*/
/* ACTION: rajuste les coordones du rectangle GRECT de faon  ce qu'il */
/*         soit centr sur x et y et qu'il tienne dans l'ecran            */
/* ENTREE: int x,int y, coordonnes du centre souhait du rectangle.      */
/*         GRECT *grect, pointe sur le rectangle GEM recentrer.           */
/* SORTIE: GRECT *grect, est initialis sur les valeurs transformes.     */

void AdjustXYGrectToScreen (int x, int y, GRECT *grect);

/*---------------------------- AdjustGrectToGrect ------------------------*/
/* ACTION: ajuste les coordonnes du rectangle grect, de faon  ce qu'il */
/*         tienne dans le rectangle limit_grect.                          */
/* ENTREE: GRECT *limit_grect: rectangle dans lequel il faut faire tenir  */
/*                             le rectangle grect.                        */
/*         GRECT *grect: rectangle dont il faut eventuellement reajuster  */
/*                       la position.                                     */
/* RETOUR: GRECT * pointe sur le rectangle reajust.                      */

GRECT *AdjustGrectToGrect(GRECT *limit_grect, GRECT *grect);

/*----------------------- Rc_intersect ------------------------------------*/
/* ACTION: calcule l'intersection de deux rectangles entre eux et retourne */ 
/*         TRUE si il ya intersection et FALSE si pas d'intersection       */
/* ENTREE: r1 pointe sur premier rectangle.                                */
/*         r2 pointe sur deuxieme rectangle.                               */
/* RETOUR: retourne TRUE si intersection et FALSE si pas d'intersection    */
/*         r2 est modifie en rectangle intersectant resultant.             */

int Rc_intersect(GRECT *r1,GRECT *r2);			

/*---------------------------- NumSelToTrame --------------------------------*/
/* ENTREE:un nombre compris entre 0 et 39                                    */
/*        representant tous les types possibles de trames systemes atari     */
/*        selon la valeur passee dans le parametre sel le remplissage des    */
/*        objets sera le suivant:                                            */
/*        si zero pas de remplissage les objets sont de type ligne           */
/*        si 1  c'est la couleur du fond d'indice zero (blanc) (trame unie)  */
/*        si 2  c'est la couleur en cours qui remplit l'objet  (trame unie)  */
/*        si 3   26  c'est le premier groupe de trame GEM                   */
/*        si 27  38  c'est le deuxieme groupe de trame GEM                  */
/* SORTIE: int *type et int *trame sont positionnes sur les bonnes valeurs  */
/*         pour faire vsf_style (VDIhandle, type);    suivi de               */
/*                    vsf_interior(VDIhandle, trame); afin de positionner    */
/*                    les atributs de traage sur les bonnes valeurs         */ 

void NumSelToTrame(int sel, int *type, int *trame);

/*---------------------------- TrameToNumSel --------------------------------*/
/* ACTION: transforme deux nombres diffrents reprsentant, le type VDI de   */
/*         remplissage correspondant aux fonctions: vsf_interior  () et      */
/*                                                  vsf_style()              */
/*         en un indice de liste, permettant de pointer sur une LISTBOX de   */
/*         trames.                                                           */   
/* ENTREE: int type correspond  la fonction  vsf_interior() et peut prendre */
/*                  les valeurs suivantes FIS_HOLLOW/0  FIS_SOLID/1          */
/*                  FIS_PATERN/2 FIS_HATCH/3 FIS_USER/4                      */
/*         int trame correspond  la fonction  vsf_style()                   */
/* SORTIE: un nombre compris entre 0 et 40                                   */ 

int TrameToNumSel(int type, int trame);

/*------------------------------ ScanToAscii --------------------------*/
/* ACTION: retourne  partir du scan code et de l'tat des touches     */
/*         ALTERNATE, CONTROL, SHIFT le caractre ASCII.               */
/* ENTREE: int scan, scan code de la touche clavier.                   */
/*         int state, etat des touches ALTERNATE, CONTROL, SHIFT       */
/* RETOUR: un int, qui est le code ASCII de la touche clavier.         */

int ScanToAscii(int scan, int state);   

/*------------------------- StrTrimEnd ---------------------------------*/
/* ACTION: enleve les espaces de fin de chaine.                         */
/* ENTREE: char *str:                                                   */
/*             pointe sur la chaine de caracteres  traiter.            */
/* RETOUR: char*: un pointeur sur cette chaine traitee.                 */               

char *StrTrimEnd(char *str);

/*---------------------------- StrTrimDeb ------------------------------*/
/* ACTION: recherche le premier caractere non espace d'une chaine       */
/*         en partant de son debut.                                     */
/* ENTREE: char *str:                                                   */
/*             pointe sur la chaine de caracteres  traiter.            */
/* RETOUR: char*: un pointeur sur le premier caractere non espace de la */
/*             chaine.                                                  */

char *StrTrimDeb(char *pt);

/*************************************************************************/
/*           F O N T I O N S   D ' O B J E T S    E T E N D U S          */
/*************************************************************************/           
                     
/*------------------------------ ActiveOnglet --------------------------------*/
/* ACTION: active un des dialogues d'une boite  onglet                       */
/* ENTREE: int w_ind,  indice EAZY_GEM de la fenetre contenant le dialogue    */
/*         int ob_onglet, numero d'objet de la boite  onglets                */
/*         int next_dial, numero du dialogue d'onglet  activer               */
/* SORTIE: neant                                                              */
void ActiveOnglet(int w_ind, int ob_onglet, int next_dial);     

/*--------------------------- SetListCallBackFunc ----------------------------*/
/* ACTION: Cette  fonction  permet de modifier la fonction d'affichage  d'une */
/*         LIST_BOX, ou d'une SCROLLBOX.                                      */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/*         Dans le paramtre: void *func l'on  place l'adresse de la fonction */
/*                            devant afficher les cases de la LISTBOX. Cette  */
/*                            fonction doit bien sur etre ecrite par vous.    */
/* RETOUR: l'adresse de l'ancienne fonction de gestion.                       */                                                   
                         
void *SetListCallBackFunc ( OBJECT *tree, int   ind_ob, void *func ); 

/*--------------------------- SetScrollBoxParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLBOX.                                                       */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLBOX.                    */                                
/*         Dans le paramtre: int  LgnH  hauteur en pixels d'une ligne de     */
/*                             scrolling c'est de cette distance dont scrolle */
/*                             en vertical la boite.                          */
/*         Dans le paramtre: int  ClnW  largeur en pixels d'une colonne      */
/*                            scrolling  c'est de cette distance dont scrolle */
/*                            en horizontal la boite.                         */
/*         Dans le paramtre: int NbLgn nombre de lignes total (hauteur totale*/
/*                            du document / LgnH ).                           */
/*         Dans le paramtre: int NbCln nombre de colonnes total (largeur     */
/*                            totale du document / ClnW ).                    */     
/*         Dans le paramtre: int FstLgn indice de la ligne de scrolling     */
/*                            placer en haut e la boite  (offset d'affichage  */ 
/*                            vertical).                                      */
/*         Dans le paramtre: int FstCln indice de la colonne de scrolling   */
/*                            placer  droite de la boite  (offset d'affichage*/ 
/*                            horizontal).                                    */     
/*         Dans le paramtre: int LgnSlct indice de la ligne document         */
/*                            slectionne.                                   */
/*         Dans le paramtre: int ClnSlct indice de la colonne document       */
/*                            slectionne.                                   */
/*         Dans le paramtre: void *SclBoxParam  l'on  peut  placer  ce  que  */
/*                            l'on veut, une adresse de donnes, ou tout autre*/
/*                            chose. Ce  paramtre est transmis  la fonction */
/*                            d'affichage de la SCROLBOX.                     */
/*         Dans le paramtre: int Do, l'on  peut  placer une valeur qui       */
/*                            modifiera le comportement de la sroll_box lors  */
/*                            d'un affichages: si LST_DRAW elle sera dessinee */
/*                                             normalement.                   */
/*                                             si LST_NODRAW elle ne sera pas */
/*                                             redessinee.                    */                 
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         1 tout est Ok                                                      */     

int SetScrollBoxParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */
        int LgnH,          /* hauteur en pixels d'une ligne de scrolling      */
        int ClnW,          /* largeur en pixels d'une colonne scrolling       */
        int NbLgn,         /* Nombre total de lignes document                 */     
        int NbCln,         /* nombre total de colonnes document               */
        int FstLgn,        /* indice ligne document  afficher en 1er         */ 
        int FstCln,        /* indice colonne document  afficher  gauche     */
        int LgnSlct,       /* ligne selectionne ( mettre en surbrillance)   */ 
        int ClnSlct,       /* colonne selectionne ( mettre en surbrillance) */
        void *SclBoxParam, /* paramtre optionnel  type de pointeur          */    
        int Do             /* parametre d'action                              */
      );  
                 
/*--------------------------- GetScrollBoxParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLBOX.                                                       */
/*         Si vous fournissez la valeur 0, pour une adresse de parametre, le  */
/*         parametre correspondant ne sera pas retourn.                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int ind_ob l'on doit placer l'indice de l'objet */
/*                            correspondant  la SCROLBOX.                    */                                
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *LgnH on reoit la hauteur en pixels d'une  */
/*                            ligne de scrolling c'est de cette distance dont */
/*                            scrolle en vertical la boite.                   */
/*         Dans le paramtre: int *ClnW  on reoit la largeur en pixels d'une */
/*                            colonne scrolling  c'est de cette distance dont */
/*                            scrolle en horizontal la boite.                 */
/*         Dans le paramtre: int *NbLgn l'on reoit le nombre de lignes total*/
/*                            (hauteur totale du document / LgnH ).           */
/*         Dans le paramtre: int *NbCln on reoit le nombre de colonnes total*/
/*                            (largeur totale du document / ClnW ).           */     
/*         Dans le paramtre: int *FstLgn l'on reoit l'indice de la ligne de */
/*                            scrolling  placer en haut e la boite  (offset  */ 
/*                            d'affichage vertical).                          */
/*         Dans le paramtre: int *FstCln on reoit l'indice de la colonne de */
/*                            scrolling  placer  droite de la boite  (offset*/ 
/*                            d'affichage horizontal).                        */     
/*         Dans le paramtre: int *LgnSlct l'on reoit l'indice de la ligne   */
/*                            document slectionne.                          */
/*         Dans le paramtre: int *ClnSlct l'on reoit indice de la colonne   */
/*                            document slectionne.                          */
/*         Dans le paramtre: long *SclBoxParam l'on reoit le parametre      */
/*                            optionnel.                                      */
/*         Dans le paramtre: int *NbCase l'on reoit le nombre de lignes     */
/*                            affichables dans la scrollbox                   */
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         adresse de la structure TEDINFO de cet objet                       */     

TEDINFO *GetScrollBoxParam 
      ( 
        OBJECT *tree,       /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,         /* indice de l'objet dans l'arbre                  */
        int *LgnH,          /* hauteur en pixels d'une ligne de scrolling      */
        int *ClnW,          /* largeur en pixels d'une colonne scrolling       */
        int *NbLgn,         /* Nombre total de lignes document                 */     
        int *NbCln,         /* nombre total de colonnes document               */
        int *FstLgn,        /* indice ligne document  afficher en 1er         */ 
        int *FstCln,        /* indice colonne document  afficher  gauche     */
        int *LgnSlct,       /* ligne selectionne ( mettre en surbrillance)   */ 
        int *ClnSlct,       /* colonne selectionne ( mettre en surbrillance) */
        long *SclBoxParam,  /* paramtre optionnel  type de pointeur          */          
        int *NbCase         /* nbr de cases afichables                         */     
      );
 
/*---------------------------- DoScrollBoxSlide ------------------------------*/     
/* ACTION: Cette fonction permet de modifier faire scroller la SCROLBOX, d'une*/
/*         certaine quantit de lignes en horizontal ou vertical.             */
/*         Si vous fournissez une valeur ngative le sens est vers le haut et */
/*         et la droite.                                                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLBOX,                        */
/*         Dans le paramtre: int ind_ob l'on doit placer l'indice de l'objet */
/*                            correspondant  la SCROLBOX.                    */                                
/*         Dans le paramtre: int n_vert nbr de lignes verticales  scroller. */
/*         Dans le paramtre: int n_hori nbr de lignes horizontales  scroller*/
/*                            colonne scrolling  c'est de cette distance dont */
/*         Dans le paramtre: GRECT *clip_grect il doit etre donn            */
/*                            rectangle de clipping.                          */
/* RETOUR: 0 erreur (ce n'est pas une SCROLBOX)                               */
/*         1 tout est Ok                                                      */   

int DoScrollBoxSlide 
     ( 
      OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
      int ind_ob,        /* indice de l'objet dans l'arbre                  */
      int n_vert,        /* nombre de lignes  scroller                     */
      int n_hori,        /* nombre de colonnes  scroller                   */
      GRECT *clip_grect  /* rectangle de clipping                           */
     );

/*---------------------------- XYToScrollBoxItem -------------------------*/
/* ACTION: Retourne la ligne cliquee dans la SCROLLBOX.                   */
/* ENTREE: OBJECT *object, pointe sur le prem. objet de l'arbre d'objets  */
/*                         ou se trouve l'objet.                          */
/*         int ob_ind, indice de l'objet SCROLLBOX clique dans cet arbre.  */
/*         int x, int y, coordonnees X & Y de la souris                   */
/* SORTIE: int, ligne cliquee (option base 0) de la SCROLLBOX.            */

int XYToScrollBoxItem(OBJECT *object, int ob_ind, int x, int y);

/*------------------------------ VascPosAdjust ---------------------------------------------*/
/* ACTION: calcule la position de l'ascenseur vertical d'une SCROLLBAR  partir des donnes */
/*         d'un objet de type SCROLLBOX.                                                    */
/* ENTREE: OBJECT *object:                                                                  */
/*            pointe sur le premier objet (objet racine) de l'arbre ou sont contenus les    */
/*            autres objets.                                                                */
/*         int ob_scroll: numero ou indice de l'objet SCROLLBOX dans cet arbre.             */
/*         int ob_Vbar:   numero ou indice de l'objet SCROLLBAR dans cet arbre.             */
/*                        une SCROLLBAR est un objet contenant un objet fils ascenseur.     */
/* RETOUR: int: position y de l'ascenseur. (en relatif  la SCROLLBAR ob_Vbar).             */

int VascPosAdjust(OBJECT *object, int ob_scroll, int ob_Vbar);

/*------------------------------ VascHeightAdjust ------------------------------------------*/
/* ACTION: calcule la taille de l'ascenseur vertical d'une SCROLLBAR  partir des donnes   */
/*         d'un objet de type SCROLLBOX. La donne: scrollboxblk->FstLgn est si besoin      */
/*         ajuste de facon  etre coherente, ainsi que la position verticale ascenseur.    */
/* ENTREE: OBJECT *object:                                                                  */
/*            pointe sur le premier objet (objet racine) de l'arbre ou sont contenus les    */
/*            autres objets.                                                                */
/*         int ob_scroll: numero ou indice de l'objet SCROLLBOX dans cet arbre.             */
/*         int ob_Vbar:   numero ou indice de l'objet SCROLLBAR dans cet arbre.             */
/*                        une SCROLLBAR est un objet contenant un objet fils ascenseur.     */
/* RETOUR: int: position y de l'ascenseur. (en relatif  la SCROLLBAR ob_Vbar).             */

int VascHeightAdjust(OBJECT *object, int ob_scroll, int ob_Vbar);

/*------------------------ Scroll_window -------------------------------*/
/* ACTION: fait scroller le rectangle de fenetre specifie, et redessine */
/*         en faisant appel  la fonction de fenetre, la partie         */
/*         decouverte.                                                  */
/* ENTREE: int w_ind: indice EAZY_GEM de la fenetre dont il faut faire  */
/*                    sroller une partie.                               */
/*         GRECT *scrol_grect: coordonnes de la zone rectangulaire a   */
/*                             faire scroller.                          */
/*         int dir: egal  HORIZONTAL, VERTICAL (sens de scrolling).    */
/*         long delta: quantite  faire scroller si  <0 dans un sens,   */
/*                     si >0 dans l'autre.                              */ 

void Scroll_window (int w_ind, GRECT *scrol_grect, int dir, long delta);


/*---------------------------- SlidePosToDocPos ------------------------*/
/* ACTION: calcul de la nouvelle position document  partir de la       */
/*         position souris sur l'assenceur.                             */
/* ENTREE: OBJECT *object, int ob_Vbar objet de type SLIDEBAR c.a.d.    */
/*         barre de scroll avec en fils un assenceur (slide)            */
/*         unsigned long doc_total, taille totale du document.          */
/*         unsigned long doc_view, taille representable du document dans*/
/*                                 la fenetre de visualisation.         */
/*         unsigned long doc_pos, ofset d'affichage du document par     */
/*                                rapport a son debut.(en fait c'est le */
/*                                premier element affich).             */  
/*         int pos_mouse,         position de la souris.                */
/*         int scrolcoef,  coefficient de scrolling minimum.            */
/*         int mode, HORIZONTAL ou VERTICAL indique le type de barre de */
/*                   SLIDEBAR a laquelle l'on a affaire.                */
/* RETOUR: un long qui la nouvelle position document.                   */

long SlidePosToDocPos(OBJECT *object, int ob_Vbar,
                      unsigned long doc_total, 
                      unsigned long doc_view,
                      unsigned long doc_pos, 
                      int pos_mouse,
                      int scrolcoef,
                      int mode);
                      
/*---------------------------- SetSlideWidth ---------------------------*/
/* ACTION: calcul de la largeur d'un assenceur  partir des donnes du   */
/*         document.                                                    */
/* ENTREE: OBJECT *object, int ob_Vbar objet de type SLIDEBAR c.a.d.    */
/*         barre de scroll avec en fils un assenceur (slide)            */
/*         unsigned long doc_total, taille totale du document.          */
/*         unsigned long doc_view, taille representable du document dans*/
/*                                 la fenetre de visualisation.         */
/*         unsigned long doc_pos, ofset d'affichage du document par     */
/*                                rapport a son debut.(en fait c'est le */
/*                                premier element affich).             */  
/*         int min_slide,  taille minimum de l'assenceur.               */
/*         int mode, HORIZONTAL ou VERTICAL indique le type de barre de */
/*                   SLIDEBAR a laquelle l'on a affaire.                */
/* RETOUR: un long qui la nouvelle position document.                   */

long SetSlideWidth(OBJECT *object, int ob_Vbar, 
                  unsigned long doc_total, 
                  unsigned long doc_view, 
                  unsigned long doc_pos,
                  int min_slide,
                  int mode);
                                        
/*---------------------------- DocPosToSlidePos ------------------------*/
/* ACTION: calcul de la position d'un assenceur  partir des donnes du  */
/*         document.                                                    */
/* ENTREE: OBJECT *object, int ob_Vbar objet de type SLIDEBAR c.a.d.    */
/*         barre de scroll avec en fils un assenceur (slide)            */
/*         unsigned long doc_total, taille totale du document.          */
/*         unsigned long doc_view, taille representable du document dans*/
/*                                 la fenetre de visualisation.         */
/*         unsigned long doc_pos, ofset d'affichage du document par     */
/*                                rapport a son debut.(en fait c'est le */
/*                                premier element affich).             */  
/*         int mode, HORIZONTAL ou VERTICAL indique le type de barre de */
/*                   SLIDEBAR a laquelle l'on a affaire.                */
/* RETOUR: un int qui le nombre de pixels dont s'est deplace            */
/*         l'ascenseur                                                  */  
                     
int DocPosToSlidePos(OBJECT *object, int ob_Vbar,                     
                     unsigned long doc_total, 
                     unsigned long doc_view,
                     unsigned long doc_pos, 
                     int mode);

/*--------------------------- SetScrollTxtParam ------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la SCROLTEXT.                                                      */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLTEXT,                       */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLTEXT.                   */                                
/*         Dans le paramtre: int  Clr  l'on  place la couleur du texte.      */
/*         Dans le paramtre: int Pts   l'on  place la taille du texte.       */
/*         Dans le paramtre: int Fnt   l'on  place l ID de la fonte.         */
/* RETOUR: 0 erreur (ce n'est pas une SCROLTEXT)                              */
/*         1 tout est Ok                                                      */ 

int SetScrollTxtParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */                
        int Clr,           /* couleur du texte                                */ 
        int Pts,           /* taille en point du texte                        */
        int Fnt            /* Police de caractere                             */             
      );

/*--------------------------- GetScrollTxtParam ------------------------------*/     
/* ACTION: Cette fonction permet de recuperer les parametres de fonctionnement*/
/*         la SCROLTEXT.                                                      */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la SCROLTEXT,                       */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la SCROLTEXT.                   */                                
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *Clr   l'on  reoit la couleur du texte.    */
/*         Dans le paramtre: int *Pts   l'on  reoit la taille du texte.     */
/*         Dans le paramtre: int *Fnt   l'on  reoit l'ID VDI de la fonte.   */
/* RETOUR: 0 erreur (ce n'est pas une SCROLTEXT)                              */
/*         adresse de la structure SCROLL_TXT_PRM                             */     
/* RAPPEL:                                                                    */
/*     typedef struct                                                         */
/*        { int Type;          type de donnes  afficher                     */
/*          char *txt;         adresse du texte                               */
/*          char **PtLgnTab;   adr. du tableau de pointeurs de lignes texte   */        
/*          int Pts;           taille en points des caractres                */
/*          int Color;         couleur des caractres                         */
/*          long FontId;       ID VDI de la police a employer pour l'affichage*/
/*        } SCROLL_TXT_PRM;                                                   */

SCROLL_TXT_PRM *GetScrollTxtParam 
      ( 
        OBJECT *tree,      /* adresse de l'arbre ou se trouve la SCROLBOX     */
        int ind_ob,        /* indice de l'objet dans l'arbre                  */                
        int *Clr,           /* couleur du texte                               */ 
        int *Pts,           /* taille en point du texte                       */
        int *Fnt            /* Police de caractere                            */             
      );

/*--------------------------- SetListBoxParam --------------------------------*/     
/* ACTION: Cette fonction permet de modifier les parametres de fonctionnement */
/*         la LIST_BOX.                                                       */
/*         Si vous fournissez la valeur -2, pour une valeur de parametre, le  */
/*         parametre correspondant ne sera pas modifi.                       */
/* ENTREE: Dans le parametre: OBJECT *tree l'on  place l'adresse de l'arbre   */
/*                            ou se situe la LISTBOX,                         */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/*         Dans le paramtre: int   select l'on  place le numero de l'lment */
/*                            de la  liste    reprsenter devant etre affich*/
/*                            dans la case de slection (premier lment de la*/
/*                            LISTBOX).                                       */
/*         Dans le paramtre: int first, l'on place le numero de l'lment de */
/*                            la liste  reprsenter,devant etre affich dans */
/*                            la premire  case de liste (celle situe sousla */
/*                            case de slection, soit le deuxime  lment de */
/*                            la LISTBOX).                                    */
/*         Dans le paramtre: int nbcases l'on  place le nombre d'lments que*/
/*                            doit comporter la  LISTBOX, y compris la case de*/
/*                            slection.                                      */
/*         Dans le paramtre: int nb_item l'on place le nombre d'lments     */
/*                            de la liste  reprsenter.                      */
/*         Dans le paramtre: int h_lign l'on  place la hauteur d'une case de */
/*                            la  LISTBOX.                                    */
/*         Dans le paramtre: void *LstBoxParam l'on peut placer ce que l'on  */
/*                            veut, une adresse de donnes, ou tout autre     */
/*                            chose. Ce  paramtre est transmis  la fonction */
/*                            d'affichage de la LISTBOX.                      */
/* RETOUR: 0 erreur (ce n'est pas une LISTBOX)                                */
/*         1 tout est Ok                                                      */
                                               
int SetListBoxParam 
     ( OBJECT *tree,
       int   ind_ob,
       int select,
       int first,
       int nbcases,
       int nb_item,
       int h_lign,   
       void *LstBoxParam    
     );

/*------------------------GetSelectedListBoxItem------------------------------*/
/* ACTION: cette fonction permet d'obtenir l'indice (base 0) de l'element     */
/*         selectionne dans une LISTBOX, cet indice pointe donc sur une       */
/*         donnee de la liste.                                                */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/* RETOUR: indice (base 0) de l'element selectionne dans une LISTBOX, cet     */
/*         indice pointe donc sur une donnee de la liste. C'est cette donne  */
/*         qui doit etre affichee dans la boite de selection.                 */
                                                 
int GetSelectedListBoxItem(OBJECT *object, int ind);

/*--------------------------- GetListBoxParam --------------------------------*/     
/* ACTION: Cette  fonction  permet d'obtenir les parametres de fonctionnement */
/*         la LIST_BOX.                                                       */
/*         Si vous fournissez la valeur 0, pour une adresse de parametre, le  */
/*         parametre correspondant ne sera pas retourn.                      */
/* ENTREE: Dans le parametre:  OBJECT *tree l'on  place l'adresse de l'arbre  */
/*                             ou se situe la LISTBOX,                        */
/*         Dans le paramtre: int   ind_ob l'on  place l'indice  de l'objet   */
/*                            correspondant  la LIST_BOX.                    */
/* SORTIE:                                                                    */
/*         Dans le paramtre: int *select, l'on reoit le numero de l'lment */
/*                            de la  liste    reprsenter devant etre affich*/
/*                            dans la case de slection (premier lment de la*/
/*                            LISTBOX).                                       */
/*         Dans le paramtre: int *first, l'on  reoit le numero de l'lment */
/*                            de la liste  reprsenter,devant etre affich   */
/*                            dans la premire  case  de  liste (celle situe */
/*                            sous la case de slection, soit le deuxime     */
/*                            lment  de la LISTBOX).                        */
/*         Dans le paramtre: int *nbcases, l'on reoit le nombre d'lments  */
/*                            que doit comporter la  LISTBOX, y compris la    */
/*                            case de slection.                              */
/*         Dans le paramtre: int *nb_item, l'on reoit le nombre d'lments  */
/*                            de la liste  reprsenter.                      */
/*         Dans le paramtre: int *h_lign, l'on reoit la hauteur d'une case  */
/*                            la  LISTBOX.                                    */
/*         Dans le paramtre: long *LstBoxParam, l'on reoit le parametre     */
/*                            optionnel.                                      */
/* RETOUR: 0 erreur (ce n'est pas une LISTBOX)                                */
/*         1 tout est Ok                                                      */

int GetListBoxParam 
     ( OBJECT *tree,
       int   ind_ob,
       int *select,
       int *first,
       int *nbcases,
       int *nb_item,
       int *h_lign,   
       long *LstBoxParam    
     );

/*------------------------------ XYToListBoxItem -------------------------------*/
/* ACTION: si une listbox est ouverte dans la fenetre, il est recherche l'item  */
/*         pointe par la souris.                                                */
/* ENTREE: int w_ind: indice EAZY_GEM de la fenetre contenant la LISTBOX        */
/*         int x, int y: position de la souris.                                 */
/* RETOUR: int: si -1 pas d'item pointe, si >=0 item point dans liste.         */

int XYToListBoxItem( int w_ind, int x, int y);


/*---------------------- AdaptListBoxToWindHeight -----------------------*/
/* ACTION: adapte une LISTBOX de maniere a ce qu'elle occupe toute la    */
/*         la hauteur d'une fenetre dont les dimenssions exterieures     */
/*         donnees (ou pas) dans les limites fixees par maxcases.        */
/* ENTREE: int w_ind, indice EAZY_GEM de la fenetre ou se trouve la      */
/*                    LISTBOX.                                           */
/*         int ob_list, indice de l'objet LISTBOX dans l'arbre de        */
/*                      ressource de la fenetre.                         */
/*         int maxcases, Maximum de cases que l'on autorise.             */
/*         GRECT *ext_grect, rectangle exterieur de la fenetre.          */
/*                           Si 0 la fonction utilise le dernier que la  */
/*                                la fenetre a stocke dans sa structure  */
/*                                de fenetre: Windtab[w_ind].GemWorkGrect*/
/*                           Sinon c'est celui passe en entree qui est   */
/*                                 utilise.                              */

void AdaptListBoxToWindHeight(int w_ind, int ob_list, int maxcases, GRECT *ext_grect)
/*************************************************************************/
/*                   F O N T I O N S   D I V E R S E S                   */
/*************************************************************************/
/*---------------------- DiderotHelpReply -------------------------------*/
/* ACTION: repond au message AID_REQUEST envoy par DIDEROT lorsqu'il    */
/*         doit afficher une aide. Cette fonction rempli automatiquement */
/*         les membres de la structure DID_HELP *VIEWHLP: dont on fourni */
/*         en entree l'adresse. Le fichier d'aide est cherche dans les   */
/*         repertoires systemes de l'application.                        */
/*         Au premier affichage de la fenetre d'aide ses dimensions sont */
/*         automatiquement ajustees pour qu'elle s'affiche de facon a ne */
/*         pas recouvrir la fenetre demandeuse d'aide.                   */
/*                                                                       */ 
/* ENTREE: w_ind: indice EAZY_GEM de la fenetre correspondant au fichier */
/*                d'aide, specifie par la variable: char *fic_aide       */
/*                Si ce n'est pas la fenetre pour laquelle DIDEROT deman-*/
/*                de une aide, il ne se passera rien et la fonction      */
/*                retourne avec 0;                                       */   
/*         EVNT_O *Evnt: variable de flux evenementiel.                  */
/*         DID_HELP *VIEWHLP: pointeur sur la structure de retour, que   */
/*                            l'on va renvoyer a DIDEROT afin qu'il      */
/*                            afficher l'aide demandee.                  */ 
/*         char *fic_aide: nom du fichier d'aide. il sera cherch dans   */
/*                         les repertoires systemes de l'application.    */
/*         int ref: numero de la reference a afficher de ce fichier      */
/*                  d'aide.                                              */
/*         int w, h: largeur et hauteur que l'on veut pour l'affichage   */
/*                   de la fenetre d'aide.                               */
/* RETOUR:  1 tout est OK                                                */
/*          0 l'indice de fenetre fourni en entre n'est pas le bon.      */
/*         -1 l'application DIDEROT non presente.                        */
/*         -2 le fichier d'aide fourni en entre n'est pas trouve.        */

int DiderotHelpReply(int w_ind, EVNT_O *Evnt, 
                     DID_HELP *VIEWHLP, char *fic_aide, int ref, 
                     int w, int h);
                     
/*------------------------------ Vq_cookie -----------------------------*/
/* ACTION :retourne l'adresse d'un Cookie dont l'identificateur est     */
/*        passe en entree sinon Zero                                    */

COOKIE *Vq_cookie (long id);

/*----------------------- GetTxtNbLigne -------------------------*/
/*ACTION: compte le nombre de lignes d'un texte, afin de prevoir */
/*        la taille  du tableau de pointeurs                     */
/* ENTREE: char *txt: adresse du texte dont il faut compter les  */
/*                    lignes.                                    */
/* RETOUR: int: nombre de lignes du texte.                       */

int GetTxtNbLigne(char *txt);

/*----------------------- InitTxtLgnPtr -------------------------*/
/* ACTION:initialise un tableau de pointeurs de lignes sur les   */
/*        adresse de debut de lignes d'un texte                  */
/* ENTREE: char *txt: adresse du texte dont il faut initialiser  */
/*                    les pointeurs de lignes.                   */
/*         char **PtLgnTab: pointeur sur un tableau de pointeurs */
/*                    qui sera rempli par les adresses correctes */
/* RETOUR: toujours 1                                            */

int InitTxtLgnPtr(char *txt, char **PtLgnTab);

/*------------------ GetDragDropList --------------------------------------*/
/* ACTION: recupere une liste de chaines, separes par des zero de fin     */
/*         lors du message AP_DRAGDROP. (en general liste de fichiers)     */
/* ENTREE: EVNT_O *Evnt: pointeur sur le flux evenementiel. Permet  la    */
/*               fonction de se servir du pipe.                            */
/*         char *path: pointeur sur la chaine dans laquelle la liste sera  */
/*               recopie.                                                 */
/*         long len_path: longueur de la chaine d'entree, afin que la      */
/*               recopie ne deborde pas.                                   */
/* RETOUR: long: longueur de la chaine pouvant etre recupre. Si cette    */
/*              longueur est plus longue que len_path, c'est qu'il ya eu   */
/*              non recopie d'une partie de la chaine.                     */

long GetDragDropList(EVNT_O *Evnt, char *path, long len_path);

/*------------------------- ClipboardSave -------------------------------------*/
/* ACTION: sauve le buffer passe en entree dans le clipboard (presse papier)   */
/* ENTREE: char *txt: adresse du buffer texte  sauver.                        */
/*         int mode: O_WRONLY   ecriture seulement                             */
/*                   O_APPEND   ajout du texte  la suite de celui deja present*/                            
/*                   O_CREAT    recree et efface l'ancien texte.               */    

int ClipboardSave(char *txt, int mode);