La mise en oeuvre facile des Fentres de dialogue non 
modales.	par  Jacques  Delavoix .

	Comme ce titre l'indique, ces routines, dont je viens de terminer la mise au point, ont t tudies 
pour permettre une mise en oeuvre trs faile des formulaires en fentres non bloquants, encore 
appels "fentres de dialogue non modales", avec une architecture similaire (mais pas identique)  celle 
employe lors de la mise en oeuvre de formulaires bloquants par "form_do()".
	Il tait galement important d'viter une dispersion et un mlange du code et aussi d'obtenir une 
bonne structuration de celui_ ci; le code grant le fonctionnement des fentres de dialogue est ici ind-
pendant du code de gestion des fentres principales. Cette structuration offre en outre l'avantage de 
faciliter la mise en oeuvre, la mise au point et le dboggage des programmes.

	Il est important de noter que les routines fournies ici donnent une base pour la programmation 
des fentres de dialogue, mais que ce code peut tre modifi pour tre adapt aux besoins propres de 
chaque programmeur. On pourra d'ailleurs s'en rendre compte lorsque je fournirai, durant l'automne 
1995, un accessoire utilisant une version spcialise de "WINDFORM".

	Quatre routines sont  la disposition des programmeurs pour la gestion de ces fentres :
	- init_var() pour l'initialisation de chaque fentre.
	- open_dialog() pour ouvrir une fentre de dialogue.
	- close_dialog() pour la refermer.
	- windform_do() pour grer le dialogue actuellement actif, le coeur du dispositif, quivalent en 
gestion non bloquante  la fonction form_do().

Pour la suite des explications, le terme de "routine utilisateur", servira  dsigner les fonctions ayant une 
action particulire dans votre programme et qui vont utiliser les fentres de dialogue; par exemple une 
fonction de Recherche et Remplacement ou tout simplement une routine affichant la traditionnelle boi-
te d'Informations du programme (baptise "informe()" dans le programme d'exemple fourni).

Le principe de fonctionnement :

	Nous allons donc justement voir ce qui se passe dans le cas de la boite "Informations" :
Regardez tout d'abord dans la fonction "main()", aprs l'appel  evnt_multi(), on commence, dans un 
premier temps, par dcoder les options de menu et appeler notre routine utilisateur "informe()". Vous 
remarquerez que l'on transmet un paramtre baptis "OPEN_DIAL"  cette routine. Ce paramtre, 
comme son nom le laisse supposer, indique  cette routine que l'on demande l'ouverture du dialogue. 
Cette routine va donc ouvrir la fentre d'"Informations" puis va retourner dans la boucle d'attente des 
vnements.
	Mais maintenant nous avons un problme ! car il faut bien que nous y retournions dans cette routi-
ne pour pouvoir grer le dialogue et effectuer les actions voulues en fonction du choix fait par l'utilisa-
teur dans la fentre de dialogue ! Et bien c'est l le principe fondamental du concept expos ici : aprs 
le dcodage des options du menu, nous allons effectuer un aiguillage en fonction du Handle de fentre 
renvoy par la fonction "evnt_multi()" et appeler de nouveau notre routine "informe()", mais cette fois 
en lui transmettant la variable des flags d'vnements en paramtre. Etant donn que le paramtre 
"OPEN_DIAL" emprunte le mme chemin, sa valeur a t fixe suffisamment haute pour ne pas interf-
rer avec les flags d'vnements. 
	Avant de faire ceci il nous reste quand mme un petit problme  rgler, en effet, le handle de 
fentre renvoy dans le mot 3 du buffer de message n'est valable que pour les vnements "Message"... 
Et bien peu inporte car nous allons, au pralable, affecter un handle de fentre aux vnements qui 
nous intressent et qui en sont dpourvus :
	- Pour "MU_KEYBD" nous demandons le handle de la fentre qui se trouve au premier plan.
	- Pour "MU_BUTTON" nous demandons, par "wind_find()", le handle de la fentre qui se trouve 
sous la souris, de faon  pouvoir aiguiller, le cas chant, vers un traitement des objets prsents sur le 
bureau du programme (non employ dans l'exemple fourni).

Les Variables :
	Pour pouvoir faire fonctionner nos fentres de dialogue, nous allons avoir besoin d'un certain 
nombre de variables : L'adresse du formulaire, le Handle de la fentre et ses coordonnes ainsi que 
deux variables ncssaires  la gestion des champs de texte ditables. Ces variables, qui sont personnel-
les  chaque fentre, ont t regroupes dans une structure de type "WINDFORM_VAR". L'adresse de 
la structure concerne sera transmise par notre routine utilisateur aux fonctions de gestion du dialogue 
(voir le fichier "WINDFORM.H"). Il faudra donc prvoir une structure "WINDFORM_VAR" pour cha-
que fentre de dialogue que l'on compte utiliser.

La Routine "Utilisateur" :
	Pour que le fonctionnement soit possible notre routine doit tre conue selon un shmas particu-
lier, d'une manire similaire  ce que l'on ferait pour une gestion bloquante par "form_do()", et dont 
voici le principe :

Routine utilisateur (vnements)
	Si vnements == OPEN_DIAL
		/* Initialisations ventuelles (champs ditables et/ou radio_buttons) */
		Alors Ouverture du dialogue
	sinon Choix = Gestion du dialogue
		Si Choix diffrent de Zro	/* si Choix == 0 le dialogue n'est pas termin. */
			Alors Fermeture possible du dialogue
			Si Choix == CLOSE_DIAL  /* La case de fermeture a t clique. */
						Choix = ANNULER   /* C'est  vous de le dcider ! */
			fin Si
			Si Choix diffrent de ANNULER
				Alors action demande
			fin Si
		fin Si
	fin Si
Retour

Voyons donc ce qui se passe dans le cas de la procdure "color_window()":
	Si cette routine reoit le paramtre "OPEN_DIAL", aprs avoir vrifi que la fentre n'est pas 
dj ouverte, nous initialisons l'unique champ de texte ditable prsent dans cette Boite, (notez que 
dans la boite "Client" les champs de texte ne sont initialiss que lors du dmarrage du programme, (c'est 
suivant ce que vous voulez faire) puis nous appellons la procdure d'ouverture.
	Sinon le paramtre reu est un vnement, et nous appellons la fonction de gestion du dialogue 
"windform_do()"; au retour de cette fonction, nous commenons par tester si le dialogue est termin, 
dans ce cas la valeur renvoye (rcupre dans la variable "choix") est diffrente de zro, et le reste du 
traitement est identique  celui que l'on aurait eu dans le cas d'une gestion par "form_do()", except la 
prise en compte de la valeur "CLOSE_DIAL" indiquant un Clic sur la case de fermeture de la fentre, 
normalement considre comme quivalente  "ANNULER", comme c'est le cas dans l'exemple fourni, 
mais vous pouvez bien entendu en dcider autrement.
	Observez attentivement les routines "informe()", "fiche_client()"  et "color_window()" dans le pro-
gramme et comparez les avec le modle que je viens de dcrire.

NOTE : Remarquez le bouton "noir" dans cette boite qui a t dclar "DISABLED".

Les quatre routines principales :
	Ces quatre routines reoivent toutes l'adresse de la structure WINDFORM_VAR concerne en 
premier paramtre. Leurs prototypes se trouvent dans le fichier "WINDFORM.H" ainsi que les diffren-
tes dfinitions utilises par les routines "WINDFORM".

La routine d'initialisation :

	Cette routine doit tre appele durant la phase d'initialisation du programme pour chaque fentre 
de dialogue. Le deuxime paramtre est l'index du formulaire dans le fichier ressource, donn par le 
fichier header associ (.H). Les deux paramtres "inf_x" et "inf_y" sont prvus pour tre utiliss en con-
jonction avec la lecture d'un fichier ".INF" o pourront tre sauvegardes les coordonnes initiales X et 
Y de chaque fentre (sauvegarde des prfrences). Si ces deux paramtres sont  zro, la fentre sera 
centre  l'cran.
	Voir la procdure "init_prog()" dans le programme.

La routine d'ouverture :
	Cette routine assure l'ouverture de la fentre de dialogue. Les deux autres paramtres  passer 
sont un pointeur sur le titre de la fentre et l'index de l'objet texte ditable o doit apparaitre le cu-
seurd'dition (ou '0' sinon).

La routine de fermeture :
	Fermeture de la fentre de dialogue concerne.

La routine de gestion du dialogue :
	Voici enfin cette fameuse routine ! Le deuxime paramtre est constitu des flags d'vnement 
retransmis par la routine utilisateur appelante. La valeur retourne est soit :

	- Zro : Le dialogue n'est pas termin.
	- CLOSE_DIAL  : Valeur -1, la case de fermeture de la fentre a t clique.
	- Une valeur Positive : Dans ce cas l'utilisateur a actionn un bouton de sortie et cette valeur en 
reprsente l'index.

La Mise en Oeuvre :
	Elle doit tre faite de la faon suivante, en vous inspirant du programme d'exemple fourni :

	1, Dclarez une structure WINDFORM_VAR pour chaque fentre de dialogue que vous dsirez 
mettre dans votre programme, et en lui donnant un nom explicite.

	2, Si ce n'est dj fait, structurez le traitement des vnements effectu aussitt aprs le retour de 
l'appel evnt_multi(), en traitant d'abord les options de Menu, puis en affectant un Handle de fentre 
aux vnements voulus et en effectuant ensuite des aiguillages sur vos procdures "utilisateur" en fonc-
tion de ce Handle. Je laisse  votre initiative le traitement d'autres vnements comme par exemple les 
vnements MU_TIMER; d'ailleurs en ce qui conerne l'vnement TIMER, je me permet de vous in-
citer  la prudence : N'utiliser cet vnement que si vous en avez rellement besoin, par exemple pour la 
sauvegarde automatique du document actif toute les n secondes.

	3, Lors de l'initialisation du programme, effectuez un appel  init_var() pour chaque fentre de 
dialogue, en passant en paramtres : L'adresse de la structure concerne, l'Indice du formulaire concer-
n et ventuellement les coordonnes X et Y de dpart (pouvant provenir de la lecture d'un fichier 
INF).

	4,  Concevez vos fonctions "utilisateurs" conformment  ce qui a t dcrit plus haut.

Les Formulaires :

	Ils seront dits de la mme faon que pour une mise en oeuvre classique avec des radio_buttons, 
champs de texte ditables, icnes couleurs, boutons de sortie et un bouton par dfaut ventuel. Libre  
vous de mettre en oeuvre les menus POP_UP du FALCON , les USERDEFS et autres...
	Notez que l'paisseur du cadre du formulaire doit tre au moins gal  2 pour les boites en 3D, il 
est galement possible de lui donner une paisseur de 3 si l'on veut que ce cadre soit visible dans la fe-
ntre.

Les extensions :

	WINDFORM_DO permet des commandes tendues, tout d'abord pour les champs ditables avec 
le positionnement du curseur en dbut ou en fin de champ par les touches "Control" + les touches  cur-
seur gauche et droite, sauter un mot par la touche "Shift" + ces mme touches curseur et positionner le 
curseur sur une lettre avec la souris.
Les Raccourcis clavier :

	Ils sont traits pour les Boutons dont l'OB_TYPE tendu comporte la valeur 18 et la lettre concer-
ne doit tre prcde du symbole "[" standard. Dans ces conditions le dessin et le comportement de ces 
boutons est tout  fait conforme aux boutons du GEM par le truchement de la routine USERDEF four-
nie ici, avec l'affichage du raccourci par un soulignement. Les flags 3D du nouveau TOS sont galement 
pris en compte (ob_flags 9 et ob_flags 10), seul l'tat SHADOWED n'est pas trait par la routine (faute 
d'avoir eu le temps de m'en occuper). J'ai cependant dot cette routine d'une possibilit supplmentai-
re, accessible en donnant la valeur 22 au lieu de 18 pour l'OB_TYPE tendu, et qui affiche alors un 
"mini bouton" (dcrit un peu plus bas).

Les valeurs utilises :

	Afficher des raccourcis clavier dans des boutons transforms en USERDEFS est une chose, en 
assurer la dtection dans la routine de gestion en est une autre. On pourrait penser qu'il suffit de dtec-
ter la valeur 18 pour dcider que le bouton puisse comporter un raccourci clavier, mais on se retrouve 
alors limit  un seul type de bouton; rajouter des tests sur d'autres valeurs est tout aussi limitatif, et de 
plus il faudrait encore dcider quelle seraient les valeurs  employer.
	J'ai donc opt pour le systme suivant : La valeur 18, prconise par INTERFACE pour les rac-
courcis clavier, positionne le bit Numro 1 de OB_TYPE tendu (valeur 2), la dtection des raccourcis 
clavier se fera donc en testant si ce bit est  1, ce qui nous laisse une belle brochette de valeurs pour les 
routines de boutons avec raccourcis que nous pourrons implmenter.

Les "mini boutons" :

	Cette possibilit est accessible en donnant une valeur de 22  l'OB_TYPE tendu au lieu de 18, on 
a alors accs  un bouton GEM de taille rduite et dont le texte est affich avec la plus petite fonte sys-
tme (fonte des Icnes de hauteur 4). Il sera par contre utile, dans ce cas, de rduire la largeur du bou-
ton lors de l'dition du ressource.

Les routines USERDEFS :

	-set_user() : Cette routine parcours le formulaire  la recherche des objets  transformer en 
USERDEFS et appelle, dans ce cas, la routine set_objc() qui ralise cette transformation, en lui trans-
mettant l'adresse de l'objet et l'adresse de la routine de dessin  utiliser (under_button() ).
	Une particularit du TOS 4.02 fait que les flags 3D ne sont pas directement utilisables; ils sont 
donc automatiquement dplacs dans ob_flags 11 et ob_flags 12 si ncssaire.
Ces flags sont dfinis au dbut du fichier WINDFORM.C par USR_INDICATOR et USR_ACTIVA-
TOR.

Les Accessoires :

	Le fichier ACC_FORM.C est un squelette pour la programmation d'un accessoire utilisant les rou-
tines WINDFORM. L'utilisation d'une allocation dynamique de mmoire tant dconseille dans le cas 
d'un accessoire, il suffit alors de rserver un tableau de structures USERBLK dont le nombre d'l-
ments sera au moins gal au nombre de boutons contenu dans le Ressource. La fonction set_objc() doit 
dans ce cas tre modifie en consquence, une variable globale sera alors utilise, comme compteur, 
pour indexer ce tableau d'USERBLKs et incrmnte aprs chaque transformation en USERDEF.

Annexe :

	Le fichier "USAGE" est destin  l'utilisateur de votre programme et est prvu pour tre incorpor 
dans le Manuel de celui_ci.

Les dfauts :

	Malgrs une tude approfondie, je n'ai pu viter un phnomne de non_rapparition du curseur  
d'dition dans certains cas, assez rares il est vrai. Si cela se produit, il suffit d'activer une autre fentre 
puis de ractiver la fentre de dialogue en cliquant dessus (ceci peut se produire si une fentre  t 
dplace sur notre fentre de dialogue puis redplace compltement en dehors de celle_ci, puis 
ferme, autant dire qu'il faut presque le faire exprs).

Le Programme d'exemple :

	Ce programme est founi sous la forme de  plusieurs fichiers source :
	- WINDFORM.C : Contient les routines de gestion du dialogue ainsi que rc_intersect() et 	stdkey(). Ce fichier est  prvu pour tre incorpor directement dans un projet logiciel.
	 ATTENTION : Ce fichier utilise des variables externes dfinies dans le programme principal et il 
vous faudra mettre les noms des variables concernes en concordance.

	- WINFDEMO.C : Le programme d'exemple proprement dit.
	ATTENTION : Vrifier dans votre fichier AES.H si la structure utilise par votre version de PURE 
C se nomme _GemParBlk; Si elle se nomme _VDIParBlk , alors mettez en service la ligne de 
redfinition situe au dbut du fichier WINDFORM.H.

	- WINDFORM.H contient les prototypes des fonctions et les dclarations utilises pour la gestion 
des dialogues.

	- ACC_FORM.C : Squelette d'un accessoire utilisant les routines WINDFORM.

A bientt, Jacques Delavoix.