Deuxième étape
Dans l'article précédent, on a introduit l'exploitation des ressources AmigaOS et on a apprécié combien la
lisibilité du langage Amiga-E rend cette gestion plus claire et plus sûre.
Dans cet article on utilise ces notions de base pour expliquer comment paramétrer le logiciel.
Car tout logiciel réaliste comprend une logique complexe de paramétrage et de personnalisation.
Enfin cet article présente de nouvelles notions qui préparent le prochain article, c'est-à-dire la
programmation des interfaces graphiques et de l'interactivité proprement dite.
Les arguments Shell
Les paramètres DOS sont interprétés par la fonction ReadArgs() de la dos.library,
on fournit un tableau de LONGs à ReadArgs(), et en retour ReadArgs() y stocke toutes les
valeurs de paramètres DOS.
Bien entendu, il faut appeler FreeArgs() quand on a terminé.
Cet exemple simple affiche le MESSAGE fourni comme argument shell :
OPT OSVERSION=37
ENUM ERR_OK,ERR_ARGS
DEF myargs:PTR TO LONG,rdargs
PROC main() HANDLE
myargs:=[0]
rdargs:=ReadArgs('MESSAGE/A',myargs,NIL)
IF rdargs=NIL THEN Raise(ERR_ARGS)
PrintF('\s\n',myargs[0])
EXCEPT DO
SELECT exception
CASE ERR_ARGS
PrintF('Bad Args!\n')
ENDSELECT
IF rdargs THEN FreeArgs(rdargs)
ENDPROC
|
Pour plus d'information sur ReadArgs() et les paramètres DOS, voir les Autodocs.
Les arguments Workbench
Les types d'outil (tooltypes) sont vraiment pratiques, et même plus pratiques que les paramètres DOS car
ils sont persistants. Donc les types d'outil sont utiles même si on démarre du Shell. Ils fournissent les
paramètres de base que l'utilisateur Shell pourra affiner par des paramètres DOS.
Voici comment faire pour lire les types d'outil :
1. Ouvrir la icon.library.
Puis si on démarre du Shell :
2. Obtenir le chemin d'accès du programme, via GetProgramName() de la dos.library.
Ou si on démarre du Workbench :
2a. Obtenir le chemin du répertoire wbmessage.arglist.lock, via NameFromLock() de la dos.library.
2b. Ajouter le nom du programme wbmessage.arglist.name, via AddPart() de la dos.library.
Continuer :
3. Charger l'objet icône du programme via GetDiskObject() de la icon.library.
4. Lire les types d'outil via FindToolType() de la icon.library, les types d'outil inexistants retournent NIL.
5. Une fois terminé, libérer l'objet icône via FreeDiskObject().
Le code suivant illustre l'ensemble du processus, il lit le type d'outil MESSAGE
dans le fichier .info du programme, et l'affiche dans le Shell ou sur le Workbench :
OPT OSVERSION=37
MODULE 'reqtools','icon'
MODULE 'workbench/startup','workbench/workbench'
ENUM ERR_OK,ERR_NOREQTOOLS,ERR_NOICON,ERR_NOINFO,ERR_NOMESSAGE
DEF prog[80]:STRING
DEF wbmsg:PTR TO wbstartup
DEF diskobj:PTR TO diskobject
PROC main() HANDLE
DEF rcode,msg
reqtoolsbase:=OpenLibrary('reqtools.library',37)
IF reqtoolsbase=NIL THEN Raise(ERR_NOREQTOOLS)
iconbase:=OpenLibrary('icon.library',37)
IF iconbase=NIL THEN Raise(ERR_NOICON)
IF wbmessage
wbmsg:=wbmessage
NameFromLock(wbmsg.arglist.lock,prog,80)
AddPart(prog,wbmsg.arglist.name,80)
ELSE
GetProgramName(prog,80)
ENDIF
IF (diskobj:=GetDiskObject(prog))=NIL THEN Raise(ERR_NOINFO)
msg:=FindToolType(diskobj.tooltypes,'MESSAGE')
IF msg=NIL THEN Raise(ERR_NOMESSAGE)
display(msg)
EXCEPT DO
rcode:=10
SELECT exception
CASE ERR_NOREQTOOLS
PrintF('Could not open reqtools.library v37+ !\n')
CASE ERR_NOICON
display('Could not open icon.library v37+ !')
CASE ERR_NOINFO
display('Could not open .info file!')
CASE ERR_NOMESSAGE
display('Could not find MESSAGE tooltype!')
DEFAULT
rcode:=0
ENDSELECT
IF diskobj THEN FreeDiskObject(diskobj)
IF iconbase THEN CloseLibrary(iconbase)
IF reqtoolsbase THEN CloseLibrary(reqtoolsbase)
ENDPROC rcode
PROC display(msg)
IF wbmessage
RtEZRequestA(msg,'Ok',0,0,0)
ELSE
PrintF('\s\n',msg)
ENDIF
ENDPROC
|
Le "versionnement"
Une chaîne de version de programme est identique à n'importe quelle autre chaîne de version :
OPT OSVERSION=37
PROC main()
PrintF('Hello World!\n')
ENDPROC
CHAR '$VER: HelloWorld 1.0 (04.05.2004) Copyright © Damien Guichard'
|
La commande C:Version permet d'afficher cette information de version.
Si vous ne l'avez pas déjà, préférez plutôt VersionWB
de Håkan Parting.
La localisation
C'est le domaine de la locale.library.
Localiser un programme n'est vraiment pas compliqué.
Un catalogue contient toutes les chaînes du programme.
Il est ouvert par OpenCatalogA() et fermé par CloseCatalog().
Entre-temps toutes les chaînes sont lues via GetCatalogStr().
Utilisez EasyCatalog pour produire le catalogue.
Et voici comment localiser un HelloWorld :
OPT OSVERSION=37
MODULE 'locale'
ENUM ERR_OK,ERR_NOLOCALE
ENUM CAT_HELLO
DEF cat
PROC main() HANDLE
localebase:=OpenLibrary('locale.library',38)
IF localebase=NIL THEN Raise(ERR_NOLOCALE)
cat:=OpenCatalogA(NIL,'hello.catalog',NIL)
PrintF(GetCatalogStr(cat,CAT_HELLO,'Hello World!\n'))
EXCEPT DO
SELECT exception
CASE ERR_NOLOCALE
PrintF('Could not open locale.library v38+ !\n')
ENDSELECT
IF cat THEN CloseCatalog(cat)
IF localebase THEN CloseLibrary(localebase)
ENDPROC
|
Ce programme pourrait écrire "Bonjour le monde!\n" avec le catalogue approprié et "français" comme langue sélectionnée.
À noter qu'il n'y a pas besoin de quitter si OpenCatalogA échoue.
Dans ce cas le programme utilise simplement les chaînes internes.
Note importante : si "english" est le langage sélectionné alors OpenCatalogA n'ouvrira PAS de catalogue, et ce même
si un catalogue "english" est présent. Dans ce cas OpenCatalogA renvoie toujours NIL, c'est pourquoi il faut sélectionner
"français" pour tester la localisation.
Les signaux de tâche
Les applications à interface graphique sont dirigées par les événements,
elles sont en repos en attente d'un signal qui les réactive. Une tâche en repos ne consomme aucune puissance
processeur. Vous pouvez mettre votre programme en repos en appelant Wait() avec les événements dont vous voulez
être averti.
Par exemple ce programme est en repos jusqu'à réception d'un "Break" émis en appuyant sur le bouton "Break"
de PriMan v2.0 :
OPT OSVERSION=37
CONST SIGNAL_BREAK=$1000
PROC main()
PrintF('sleeping... (use PriMan v2.0 to continue)\n')
Wait(SIGNAL_BREAK)
PrintF('running...\n')
ENDPROC
|
Téléchargez PriMan v2.0 ici : aminet/util/moni/Priman20.lha.
Plus tard nous verrons comment Wait() peut attendre d'autres événements comme les événements de fenêtre.
Les listes d'attributs (tag lists)
Les listes d'attributs sont un moyen très flexible pour passer des paramètres aux fonctions AmigaOS. Une liste d'attributs
est simplement un tableau de LONGs qui a toujours la forme suivante :
[TAG1,info1,TAG2,info2,...,0]
|
Une étiquette en majuscules indique quel attribut est renseigné par le LONG "info" suivant.
Le "info" est la valeur de l'attribut.
Le type liste d'attributs est natif en Amiga-E.
Notez que les listes d'attributs sont allouées statiquement.
Pour des listes d'attributs allouées dynamiquement il faut utiliser NEW :
NEW [TAG1,info1,TAG2,info2,...,0]
|
Parmi de nombreuses autres librairies, Intuition et Gadtools font un usage intensif des listes d'attributs.
Pour plus d'information sur les listes d'attributs, voir les Includes et les Autodocs de la utility.library.
Les listes Exec
De nombreux éléments de l'AmigaOS, comme par exemple les écrans, sont reliés
entre eux par les listes Exec.
Alors qu'une liste d'attributs ressemble fort à un tableau statique, une
liste Exec est dynamique comme une liste chaînée, on peut y insérer ou y
retirer des éléments.
Les fonctions de base pour ce faire sont AddHead(), AddTail(),
RemHead(), RemTail(), Insert() et Remove() de la librairie exec.
Cette fonction alloue une liste Exec vide :
MODULE 'exec/nodes','exec/lists'
PROC newlist()
DEF list:PTR TO mlh
list:=NewR(SIZEOF mlh)
list.head:=list+4
list.tailpred:=list
ENDPROC list
|
Et celle-ci retourne un nouveau noeud de liste portant le nom spécifié :
PROC newnode(name)
ENDPROC NEW [0,0,0,0,name]:ln
|
Pour plus d'information sur les listes Exec, voir les Autodocs de la
exec.library ainsi que les Includes exec/nodes.h et exec/lists.h.
Pour aller plus loin
La documentation indispensable c'est les Autodocs de Commodore, et c'est encore mieux dans le format AmigaGuide :
aminet/dev/misc/AmigaOS_guides.lha.
Les non moins indispensables AmigaOS Includes : www.amiga.com/3.9/download/NDK3.9.lha.
Le compilateur EC v3.3a de Wouter van Oortmerssen (version complète) :
www.aminet.net/dev/e/amigae33a.lha et aminet/dev/e/ec33a.lha.
Le compilateur ECX de Leif Salomonsson (version démo) : home.swipnet.se/blubbe/ECX.
L'Amiga-E mailing list : www.freelists.org/list/positron.
|
|