|
|||||||||||||||||||||||||||||||||||||||||||||
|
Commodore a fait l'expérience avec le système d'exploitation 1.3 que chaque programmeur voulait s'accaparer les touches du clavier pour leur application. Le problème est que l'Amiga étant une machine multitâche, elle n'a qu'un clavier et le système 1.3 n'était pas encore assez bien pensé pour régler ce problème. Un ingénieur du système a donc pensé à établir un sous-système qui s'occuperait de gérer quelle touche va à quelle application et tout cela restant configurable par l'usager et non les applications. Ils ont appellé cela les commodités car la plupart des programmes qui utilisent des touches spéciales sont des programmes qui corrigent ou améliorent le système déjà en place. Ce que nous allons écrire, c'est un programme qui permet de changer d'écran sans utiliser les touches Amiga-Gauche + M. Notre programme ne fonctionnera que sous le système 2.1 et plus car les commodités n'étaient pas encore installées sous le système 2.04. Je ne copierai pas les codes de l'application dans cette article, mais vous remarquerez que tous les sources et documents étaient dans l'archive d'Amiga Québec. Donc je n'expliquerai que les parties concernant les commodités de ce petit programme. Interaction avec les types d'outils Chaque commodités doit réagir à des types d'outils (tooltypes) portant le même nom. Ainsi, l'utilisateur voulant configurer ses commodités n'aura pas à apprendre des types d'outils différents pour chacun de ces petits programmes. Voici donc les noms des types d'outils auxquels notre programme devra tenir compte : CX_PRIORITY Ce type d'outils indique au système quelle commodité démarrer en premier. Admettons que vous avez sept commodités et que l'ordre dans lequel ces commodités doivent être démarrées est important. La commodité 3 plante lorsqu'elle est partie après la commodité 1. Alors, nous mettrons une priorité plus élevée à la commodité 3. Nous pouvons choisir une valeur comprise entre -128 et 127 pour ce type d'outils. Par défaut, si on ne met rien, elle sera mise à zéro. CX_POPUP Ce type d'outils permet, si l'application possède une fenêtre de configuration, de dire au système de montrer ou non cette fenêtre. Si vous avez des commodités qui ouvrent toujours leur fenêtre et que vous ne voulez pas que cela se produise, il suffit de mettre la valeur "NO" à ce type d'outils. L'autre valeur possible est "YES". CX_POPKEY Ce type d'outils permet, si la fenêtre de configuration n'est pas ouverte, de décider quelle(s) touche(s) permettra de l'ouvrir. Ainsi, nous pouvons faire en sorte que la touche F1 ouvre la fenêtre de configuration de Virus Checker simplement en ajoutant le type d'outils "CX_POPKEY=f1". HOTKEY Ce type d'outils contient la touche qui active notre programme. Il contient les mêmes choses que CX_POPKEY à l'exception qu'il n'ouvre pas nécessairement une fenêtre. Exemple : "HOTKEY=shift f5". Notre commodité ne tiendra pas compte des types d'outils CX_POPUP et CX_POPKEY car notre programme ne contient pas de fenêtre de configuration. Par défaut, CX_PRIORITY sera égale à zéro et HOTKEY égal à f10. Lecture des types d'outils Comment notre programme fait pour lire les types d'outils ? C'est assez simple car Commodore nous fournit les outils nécessaires à cet ouvrage. Ils sont dans les bibliothèques icon.library et commodities.library.
"ArgArrayInit()" nécessite un double pointeur sur des bytes. Il arrange une table et efface les types d'outils non valides. ArgString() va aller nous chercher le type d'outils demandé, dans ce cas "HOTKEY" et va nous donner la chaîne qu'il y a dans ce type d'outils. Si le type d'outils n'existe pas, nous recevrons la chaîne "f10". Ensuite, ArgInt() fonctionne comme ArgString() sauf qu'il traite des nombres, il en fait même la conversion et la validation pour nous. S'il ne trouve pas le type d'outils "CX_PRIORITY", il nous retournera la valeur 0. "ArgArrayDone()", lui, libère la mémoire utilisée par "ArgArrayInit()" et à cause de cela, il ne faut pas appeler cette fonction avant la fin du programme. Broker Maintenant que nous possédons la valeur des types d'outils qui nous serons utiles, nous pouvons demander une place comme commodité. Pour ce faire, nous devons installer un "Broker". Un Broker, c'est un client. Nous devenons un client des entrées. En d'autres mots, nous serons mis au courant lorsque l'usager exécutera n'importe quelles entrées, souris, clavier, lecteur de disquette, etc. Mais pour accélérer les choses, nous allons nous décrire au sous-système des commodités. Pour ce faire, nous devons créer une structure "NewBroker". Cette structure se définie comme suit :
"nb_Version" contient une version du Broker, elle est déjà définie par le système et nous mettrons la constante "NB_VERSION". "nb_Name", lui, contient un pointeur sur une chaîne de caractère indiquant le nom de cette nouvelle commodité. Nous lui donnerons le nom de "ScreenMenu". Ensuite "nb_Title" est le titre de cette commodité. La différence entre "nb_Name" et "nb_Title" est minime. Lorsque vous allez dans le programme Exchange, vous voyez les noms des commodités et lorsque vous en sélectionnez une, vous avez de l'information qui apparaît à droite et c'est là que le titre apparaît. "nb_Descr" est la description que l'usager verra dans Exchange. Nous indiquons "Popup a list of screen", ainsi il aura un résumé des fonctions du programme. "nb_Unique" contient des valeurs qui activent ou désactivent des possibilités d'une commodité. Les valeurs possibles pour ce champ sont "NBU_DUPLICATE", "NBU_UNIQUE" et "NBU_NOTIFY". Admettons que nous ne voulons pas qu'il soit possible de mettre deux instances de notre programme en mémoire. Nous mettrons la valeur "NBU_UNIQUE". Si nous voulons seulement être averti pour pouvoir agir, c'est la valeur "NBU_NOTIFY" qui sera mise. Et si on se fiche qu'il y ait plusieurs fois le même programme en mémoire, nous mettrons "NBU_DUPLICATE". Dans notre cas, on se servira de ce système pour permettre à l'usager de quitter le programme en le lançant une deuxième fois. Alors nous allons mettre "NBU_UNIQUE|NBU_NOTIFY". "nb_Flags" est un peu la même chose que "nb_Unique" excepté qu'il n'a pas encore été développé et il n'y a pas encore d'options. Peut-être que le système 3.0 ou 4.0 nous en donnera. "nb_Pri" est la priorité que l'usager a mise à "CX_PRIORITY". "nb_Port" est l'endroit où nous recevrons des messages nous indiquant ce qu'il s'est passé avec notre programme, il a peut-être été lancé deux fois, ou nous avons reçu notre "HOTKEY". "nb_ReservedChannel" est réservé au système des commodités et il ne faut pas y toucher. CxBroker Lorsque le tout est fait, nous devons créer un objet CxBroker. Cela ce fait avec la fonction "CxBroker()" et nous devons passer l'adresse de notre structure NewBroker et l'adresse d'une variable qui contiendra l'erreur s'il y a. Les erreurs possibles sont :
Attachement du Filter avec Broker Maintenant, il faut attacher notre Filter après notre Broker, sinon le système ne saura pas qu'il y a un Filter pour notre Broker. C'est la fonction "AttachCxObj()" qui s'en charge. On lui dit l'adresse de notre Broker et l'adresse de l'objet à y attacher après, dans ce cas c'est notre Filter. Parce que certaines commodités n'envoient pas nécessairement un message au programme qui l'a conçue lorsqu'elles reçoivent leur HOTKEY, il nous faut créer un objet "Sender" qui s'occupera de le faire. La fonction "CxSender()" nous permet de créer un tel objet. Les paramètres sont le MsgPort créé pour recevoir les messages et l'ID qui y sera envoyé. On attache cet objet à notre Broker avec la fonction "AttachCxObj()". Nous n'avons pas encore terminé. Lorsque l'usager va taper la touche décrite dans HOTKEY, il nous est possible de faire en sorte que l'entrée existe encore. Admettons que nous ne voulions que lire et avertir toutes les fois que l'usager appuie sur le bouton gauche de la souris, nous ne voudrions tout de même pas que l'effet du bouton soit annulé. Alors, nous devons dire au système qu'il peut réutiliser l'entrée pour d'autres programmes. Pour cela, il nous faut un autre objet, Translate. Ce nouvel objet dans notre cas devra indiquer que la touche pressée ne doit pas continuer pour d'autres programmes, car ce n'est pas utile. Avec la fonction "CxTranslate()" nous allons indiquer qu'il ne faut rien retourner, c'est-à-dire que la touche pressée sera annulée. Donc, aucun paramètre ne sera donné, un NULL sera mis. Nous attachons ce dernier objet avec "AttachCxObj()" et nous pouvons maintenant activer notre commodité. Pour l'activer, nous utiliserons la fonction "ActivateCxObj()" avec comme paramètre l'adresse de notre Broker avec tous les objets que nous lui avons attachés. Lorsque tout est actif, nous pouvons recevoir des CxMessage. Il y a deux types de message qui nous intéressent. CXM_IEVENT Si nous recevons ce type de message, c'est que nous avons reçu une entrée. Aussi, nous avons installé un objet Filter et donc il aura placé l'ID que nous lui avons passé au bon endroit dans le CxMessage. Nous vérifions cet ID et si c'est le même nous ouvrons notre fenêtre avec la liste des écrans. CXM_COMMAND Nous avons reçu un message venant du programme Exchange. Le type de message sera :
Il est certain que vous aimeriez avoir encore plus de détail, alors je vous recommande l'ouvrage "Amiga ROM Kernel Reference Manual: Libraries" car les informations y sont toutes et bien complètes. Sinon, vous pouvez toujours aller voir les sources de ScreenMenu, vous êtes encouragé à le modifier, l'améliorer et en faire un nouveau programme, tant que mon nom est affiché clairement comme étant l'initiateur de votre nouveau programme, et que j'en ai une copie 100% fonctionnel gratuitement.
|