/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\   RSC_INFO.C    \\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/* Ce module est le source C du MODULE: EZ_INFO.O                      */
/*                                                                     */
/* Le fichier projet associ‚ est:          EZ_03.PRJ                   */
/* dans lequel nous pouvons voir que ce Programme comporte deux        */
/* modules:                                                            */
/*                                     EZ_03.C  gerant la fenetre      */
/*    principale. La compilation de ce module donne EZ_03.O            */
/*                                                                     */
/*                                     EZ_INFO.C gerant la fenetre     */
/*    d'information.  La compilation de ce module donne EZ_INFO.O      */
/*                                                                     */
/* Lors de la phase de linkage ces deux modules seront li‚s pour       */
/* former le programme final CHARVIEW.APP                              */ 
/*                                                                     */
/* le source C ci-dessous est est celui du module: EZ_INFO.O           */
/* Gestion d'une boite d'information (SCROLLBOX) affichant un petit    */
/* texte d'information sur le mode d'emploi du programme.              */

/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\ I N C L U D E S \\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*--------------------- INCLUDES DES AUTRES MODULES DU PROGRAMME -------*/
#include <EAZY_GEM.H>  /* inclure les definitions des fonctions que le  */
                       /* que le module EAZY_GEM.LIB met … votre et     */
                       /* notre disposition                             */ 
                       /* et inclure les definitions des variables      */
                       /* globales  d'EAZY_GEM                          */
                       /* Je rappelle que le fichier EAZY_GEM.H et le   */
                       /* fichier EAZY_GEM.LIB doivent se trouver dans  */
                       /* les repertoires INCLUDE (pour le .H) et LIB   */
                       /* (pour le .LIB) de votre Pure C.               */ 
/* C'est … cause de cette ligne que vous avez le droit d'utiliser les   */
/* fonctions d'EAZY_GEM.                                                */                       
/* La lecture de ce fichier peut vous renseigner sur tout un tas de     */
/* choses. Il est toujours instructif de regarder les fichiers .H       */

/*--------------------- INCLURE LES DEFINITIONS SYMBOLIQUES ------------*/
/*                      que l'‚diteur de ressource g‚nŠre               */
/*                      lors de la cr‚ation de la ressource             */
#include "CHARVIEW.RSC\CHARINFO.H"    
                      /* l'inclusion des d‚finitions symboliques permet */
                      /* d'utiliser des symboles literaux plus parlants */
                      /* qu'un nombre, pour les numero d'objets.        */
                      /* Il est ‚vident qu'il est imp‚ratif de nommer   */
                      /* les objets dans votre editeur de ressources    */
                      /* pour que le fichier.H correspondant soit       */
                      /* interessant.                                   */
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\ D E F I N E S  \\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/ 
/*                         TYPAGE DES FENETRES                          */ 
/*----------------------------------------------------------------------*/ 
/* Dans EAZY_GEM, chaque fenetre doit avoir un num‚ro unique. Celui-ci  */
/* permet par la suite d'interroger EAZY_GEM pour savoir si la fenetre  */
/* correspondant … ce numero existe, ou est ouverte, ou etc....         */
/* Par exemple j'‚cris un programme comportant deux dialogues: un pour  */
/* parametrer les couleurs, et un autre affichant un choix de trames    */
/* couleurs. Chacun de ses dialogues ‚tant dans une fenetre diff‚rente, */
/* lorsque je modifie les couleurs avec le premier dialogue, il faut    */
/* repercuter la modification de couleur, sur tous les autre dialogues  */
/* concern‚s afin de les mettre … jour. Pour cela il me faut savoir si  */
/* ils existent, et sont ouverts, et auquel cas les mettre … jour, et   */
/* envoyer un message leur demandant de reafficher les ‚l‚ments         */
/* concern‚s par la modification du premier dialogue.                   */
/* On peut appeler ‡a g‚rer les multi-d‚pendances inter-dialogue.       */

/* Plutot que de manipuler un nombre abstrait qui ne me dit rien  je    */
/* pr‚fŠre d‚finir un symbole plus parlant, que j'utiliserai par la     */
/* suite dans le programme … la place du nombre, d'ou les lignes:       */
/* #define ci_dessous. (ici deux lignes car deux fenetres)              */      
 
#define W_EZ_03       1     /* (identificateur ou type) de la Fenetre   */
                            /* on peut choisir n'importe quel nombre    */
                            /* entre 1 et 32000 (‡'est assez non ?)     */
                            /* Il est imp‚ratif que deux fenetres n'    */
                            /* aient pas le meme nombre.                */
#define W_RINFO       2     /* ID Fenetre information traitee dans le   */
                            /* module EZ_INFO.C                         */
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\ V A R I A B L E S    G L O B A L E S \\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/* yen a pas pour ce module !!!                                         */
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\/ P R O T O T Y P E S  F O N C T I O N S \\\\\\\\\\\\\\\*/
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

/*................ FONCTIONS CALLBACK DE FENETRES ......................*/
/* Dans EAZY_GEM, … chaque fenetre est associ‚e une fonction CALLBACK.  */
/* CALLBACK veut dire mot … mot: appel arriŠre, 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 g‚rer la fenetre que vous d‚sirez ouvrir, et que   */
/* c'est EAZY_GEM, qui RAPELLERA votre fonction selon les diff‚rentes   */
/* actions et ‚v‚nements la concernant. L'int‚rˆt 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 pr‚voir, en rappelant votre fonction.                     */
/* Cette fa‡on 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'‚vŠnementiel GEM classique est transmis …   */
/* la fonction CALLBACK de Fenetre, plus d'autres messages sp‚cifiques  */
/* … EAZY_GEM, que nous verons petit … petit dans les exemples.         */
/* En r‚ponse aux messages et ‚vŠnements 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'acc‚s aux fonctions ‚tendues de gestion de ressource en fenetre et */
/* autres aspect pointus d'EAZY_GEM ne se fait bien ‚videment qu'au     */
/* travers des fonctions pr‚vues pour cela.                             */
/*                                                                      */
/* Ces principes de programmation peuvent apparaitre difficiles pour    */
/* ceux qui n'y sont pas habitu‚s, mais apr‚s un effort d'adaptation    */
/* minime, l'on regrette de ne pas l'avoir fait avant, tellement la     */
/* programmation sous GEM semble ensuite facile !!!.                    */ 

/* ICI je d‚clare le nom et le prototype de la fonction de fenetre qui  */
/* traitera tout ce qui concerne la fenetre que l'on va ouvrir.         */

CALLBACK WindProcInfo(int w_ind, EVNT_O *Evnt);
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
/*               € A   C O M M E N C E   I C I   !!!!                   */
/*              Definition des fonctions de ce module                   */
/*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

/*------------------------------ WindProcInfo ---------------------------*/
/* Affiche la boite d'information du programme                           */        
CALLBACK WindProcInfo(int w_ind, EVNT_O *Evnt)
{int w_h;              /* handle de la fenetre de cette Wind_proc_xxx    */
 int wh_top;           /* handle de la fenetre en avant plan             */
 DLG_VAR *dlg;       /* structure attachee … chaque ressource en fenetre */
 
 /*.................. INITIALISER LES VARIABLES ....................*/
 dlg = &Windtab[w_ind].DlgVar;
  
 /*.................... 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           */
 
 if (Evnt->evnt & MU_KEYBD && w_h==wh_top)
    {int i;
     char scan;  
     OBJECT *object; 
     GRECT grect;          /* rectangle surface de travail                   */
 
     grect = Windtab[w_ind].GemWorkGrect;  
     object=dlg->tree;
     scan=(char)(Evnt->key>>8); 
     switch(scan)
       {case  80:     /* down */
        case  72:     /* up   */          
          if (Evnt->ksp & (K_RSHIFT|K_LSHIFT))  
             {GetScrollBoxParam(object,LIS_INFO_SCROLL,0L,0L,0L,0L,0L,0L,0L,0L,0L,&i);
              if (scan!=80) i=-i;
              DoScrollBoxSlide (object, LIS_INFO_SCROLL,i,0,&grect);
              object[LIS_INFO_ASC].ob_y = VascPosAdjust(object, LIS_INFO_SCROLL, LIS_INFO_BAR, LIS_INFO_ASC); 
              Xobjc_draw(object, LIS_INFO_BAR, 1, &grect);                                     
             }    
          else if (dlg->LstAdr  == 0)
             {if (scan==80) i= 1;
              else          i=-1;
              DoScrollBoxSlide (object, LIS_INFO_SCROLL,i,0,&grect);
              object[LIS_INFO_ASC].ob_y = VascPosAdjust(object, LIS_INFO_SCROLL, LIS_INFO_BAR, LIS_INFO_ASC); 
              Xobjc_draw(object, LIS_INFO_BAR, 1, &grect);                                     
             }          
          break;
        case 71:     /* clr home  */
          if (Evnt->ksp & (K_RSHIFT|K_LSHIFT))
             {int nblt,    /* nbr de lignes total document                 */
                  nb_l;    /* nbr de lignes affichables par la scroll box  */
              GetScrollBoxParam (object, LIS_INFO_SCROLL,0L,0L,&nblt,0L,0L,0L,0L,0L,0L,&nb_l); 
              SetScrollBoxParam (object, LIS_INFO_SCROLL,-2,-2,-2,-2,nblt-nb_l,-2,-2,-2,(void*)-2L,-2);  
             } 
          else
             {SetScrollBoxParam (object, LIS_INFO_SCROLL,-2,-2,-2,-2,0,-2,-2,-2,(void*)-2L,-2); 
             }
          object[LIS_INFO_ASC].ob_y = VascPosAdjust(object, LIS_INFO_SCROLL, LIS_INFO_BAR, LIS_INFO_ASC); 
          Xobjc_draw(object, LIS_INFO_BAR, 1, &grect);  
          Xobjc_draw(object, LIS_INFO_SCROLL, 1, &grect);                                   
          break;             
       } /*end switch scan  */                        
    }
    
 if (Evnt->evnt & MU_BUTTON )
    {int ob_ret;
     ob_ret = Xform_button(w_ind, Evnt);  
     if (ob_ret == LIS_INFO_SCROLL)
        {Evnt->evnt &= ~MU_BUTTON;   /* empecher propagation message  MU_BUTTON */
         /*............. si objet exit selectionne ...................*/
         dlg->tree[ob_ret&0x7FFF].ob_state &= ~SELECTED; 
         SendWindMessage(w_h, WM_CLOSED, 0L);        
        }     
    } /* endif MU_BUTTON  et fenetre au premier plan */

 if (Evnt->evnt & MU_TIMER && w_h==wh_top)  
    {Xform_timer(w_ind, Evnt);    
    }
 if (Evnt->evnt & MU_MOVE)   
    {Xform_mu_move(w_ind, Evnt);
    }      
 if (Evnt->evnt & MU_MESAG)
    {switch (Evnt->pipe[MESG])
       {case WM_CONSTRUCT:
             dlg->AdrRsc = LoadAppliRsc( "CHARINFO.RSC", NO_SCALE);  
             if ( dlg->AdrRsc )                                                              
                {dlg->type     = RSC_DIAL;   /* type de structure passee en entree */ 
                 dlg->NumTree  = 0;
                 Xform_construct(w_ind, Evnt);                    
                 /*........... placer le tout sous la souris ..............*/
                 AdjustWindCoordToScreen (w_ind, Evnt, (GRECT*)&Evnt->pipe[X_B]); 
                }                  
             else
                {return WM_ABORT;
                }                
             break;
                                         
        case WM_DESTRUCT:       /*  (EZGEM message)   */
             Xform_Destruct(w_ind, Evnt);    
             RscFicUnLoad(dlg->AdrRsc);                
             break;            
        case WM_TT_ON_OFF:      /*  (EZGEM message)   */
             SetBulleState(w_h, dlg->tree);
             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.                   */
             /* 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,"");                             */
             /*                                                            */             
             
             if (Evnt->pipe[X_G]==TT_UPSTOOL)
                {/*........... recuperer l'adresse ou l'on doit ...........*/
                 /*            copier le texte de la bulle                 */
                 char *sztt_txt  = (char*) *(long*)(&Evnt->pipe[W_G]); 
                 /*........... selon l'objet survol‚ placer ...............*/
                 /*                 le texte adequat                       */
                 switch ( Evnt->pipe[Y_G])                            
                   {case LIS_INFO_SCROLL:                           
                         strcpy(sztt_txt,"Cliquez ici pour fermer|cette fenetre.");   
                         break;                                                   
                    default:                                       
                         strcpy(sztt_txt,"");                       
                   }                                                                            
                }
             break;                                    
        case WM_REDRAW:               
             Lister_rectangles(w_h,(GRECT*)&Evnt->pipe[X_G]);                          
             break;    
        case WM_BOTTOM:
             wind_set(w_h, WF_BOTTOM );             
             break;                               
        case WM_TOPPED:
             wind_set(w_h, WF_TOP );             
             break;
        case WM_CLOSED:
             DestroyWindow(w_h);
             break;
        case WM_ALLICONIFY:    
             AllIconify(0L);
             break;     
        case WM_ICONIFY:
             IconifyWindow(w_ind, 0L);
             break;                                                    
        case WM_UNICONIFY:
             UnconifyWindow(w_ind);            
             break;                                        
        case WM_SIZED:    
        case WM_MOVED:
             Xform_moved(w_ind, Evnt);                                     
             break;                                                                                     
       }
    }      
 return Evnt->evnt;    /* retourner le flux evenementiel (modifie ou pas)    */
}

