Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Amiga E - types d'outils et arguments
(Article écrit par Yann Armand et Pierre Girard et extrait d'Amiga News - janvier 1996)
|
|
Comme promis le mois dernier, voici la version améliorée de notre AppIcon. Il était dommage de devoir lancer notre AppIcon
depuis le Shell alors qu'il crée un objet Workbench. De plus, la méthode pour quitter était loin d'être satisfaisante.
Nous allons donc ce mois-ci voir comment gérer les types d'outils (tooltypes) d'une icône et créer une fenêtre de requête
de sortie afin de ne plus avoir à toucher le clavier. Néanmoins, pour les aficionados du Shell (ou un lancement dans la user-startup),
le programme traite aussi les arguments de la ligne de commande.
Détection du lancement
En premier lieu, nous devons déterminer comment notre AppIcon a été lancé. Trois cas peuvent apparaître :
- L'AppIcon est lancé du Shell avec des arguments.
- Il est lancé du Shell sans argument auquel cas il intercepte les types d'outil de son icône.
- Il est lancé du Workbench et lit les types d'outils de son icône.
Pour distinguer le type de lancement, nous utilisons la fonction ReadArgs('.../A',...). Le /A (argument obligatoire) indique à
la fonction de renvoyer une valeur non nulle si le lancement s'est effectué avec arguments (c'est le premier IF). Dans le cas
inverse (ELSEIF), si wbmessage (variable globale du E) est égal à NIL, l'AppIcon n'a pas été lancé depuis le Workbench.
C'est donc un lancement Shell sans argument. Dans tous les autres cas (ELSE), le lancement a forcément eu lieu depuis le Workbench.
L'article du nº84 vous a déjà donné toutes les clés de la fonction ReadArgs(),
encore faut-il l'avoir lu !
Récupération des types d'outils
Si l'AppIcon est lancé depuis le Shell sans argument, le problème est de trouver son icône. On récupère d'abord son nom avec
GetProgramName(). Mais cela ne suffit pas s'il y a un chemin (path) de 10 km dans la commande (par exemple
DH0:Dev/Amigae/sources/Avion/papillon .../AppIcon).
On doit donc récupérer le chemin complet en utilisant NameFromLock(). Mais là on n'est pas sorti de l'auberge car il faut lui
passer un verrou (lock) en argument, que GetProgramDir() se charge de lui attribuer. Le tout est stocké dans nomcomplet. Il
ne nous reste plus qu'à lire l'icône de notre programme avec la fonction GetDiskObject(nomcomplet), et à chercher les différents
types d'outils grâce à FindToolType(diskobj.tooltypes,'ToolType recherché').
Si l'AppIcon est lancé depuis le Workbench, c'est encore plus simple. La liste des arguments se trouve dans un tableau pointé
par wbmessage.arglist. Chaque entrée du tableau possède le nom et le verrou du fichier déposé sur l'AppIcon. Comme par défaut
le Workbench a son répertoire courant en SYS:, nous devons nous positionner dans le répertoire du programme appelé : c'est le
rôle de CurrentDir(). Pour la récupération des types d'outil, c'est tout pareil.
Gestion de l'AppIcon
C'est le même principe que le mois dernier avec un bonus. Si le programme appelé n'a pas d'icône, on lui affecte l'icône par
défaut WBTool.
Quant à la propreté de la sortie, on a fait un effort. Lors de la réception d'un message, si la arglist est vide (IF wb_args=0),
cela signifie que l'utilisateur a double-cliqué. On ouvre donc une fenêtre de requête booléen qui nous renvoie 1 si on a cliqué
sur le premier bouton (gauche) et 0 sur l'autre, ceci étant stocké dans la variable quit. L'astuce consiste alors à sortir de
la boucle si quit est égal à 1 grâce au EXIT quit.
Pour finir
Vous aurez remarqué que nous avons changé la structure du programme, passant des IF imbriqués aux HANDLE/Raise/EXCEPT, histoire
de vous y habituer. Nous nous en tiendrons là en ce qui concerne les AppIcons.
N'hésitez pas à nous soumettre vos idées d'articles en écrivant à la rédaction ou par courriel. Si vous vous intéressez vraiment
au E, la version 3.2a est désormais disponible en partagiciel. Atchao, bonsoir.
/* AppIcon : Ajoute une AppIcon aux programmes qui n'en possèdent pas*/
OPT OSVERSION=36
MODULE 'workbench/workbench'
MODULE 'workbench/startup'
MODULE 'dos/dos'
MODULE 'utility/tagitem'
MODULE 'wb','icon'
MODULE 'exec/ports'
MODULE 'exec/nodes'
DEF old_lock,quit
DEF myport,appicon,res : PTR TO mp
DEF diskobj : PTR TO diskobject
DEF appmsg : PTR TO appmessage
DEF wb_args : PTR TO wbarg
DEF wb : PTR TO wbstartup
DEF args : PTR TO wbarg
DEF rdargs,arguments[5] : ARRAY OF LONG
DEF commande[200] : STRING
DEF programme[200] : STRING
DEF iconname[100] : STRING
DEF path[100] : STRING
DEF nomcomplet[200] : STRING
DEF appname[20] : STRING
DEF result : PTR TO LONG
PROC main() HANDLE
IF (iconbase:=OpenLibrary('icon.library',37))=NIL THEN Raise(0)
IF rdargs:=ReadArgs('/M/A',arguments,NIL)
result:=arguments[0]
StrCopy(programme,result[0],ALL)
StrCopy(appname,result[1],ALL)
FreeArgs(rdargs)
ELSEIF wbmessage=NIL
GetProgramName(iconname,200)
NameFromLock(GetProgramDir(),path,200)
StrCopy(nomcomplet,path)
StrAdd(nomcomplet,'/')
StrAdd(nomcomplet,iconname,ALL)
diskobj:=GetDiskObject(nomcomplet)
programme:=FindToolType(diskobj.tooltypes,'PROG')
appname:=FindToolType(diskobj.tooltypes,'APPNAME')
ELSE
wb:=wbmessage
args:=wb.arglist
iconname:=args[0].name
old_lock:=CurrentDir(args[0].lock)
diskobj:=GetDiskObject(iconname)
programme:=FindToolType(diskobj.tooltypes,'PROG')
appname:=FindToolType(diskobj.tooltypes,'APPNAME')
CurrentDir(old_lock)
ENDIF
IF (workbenchbase:=OpenLibrary('workbench.library',37))=NIL THEN Raise(0)
IF (myport:=CreateMsgPort())=NIL THEN Raise(0)
IF diskobj:=GetDiskObject(programme)
ELSE
diskobj:=GetDefDiskObject(WBTOOL)
ENDIF
IF (appicon:=AddAppIconA(0,0,appname,myport,NIL,diskobj,[MTYPE_APPICON,TAG_DO
N
E]))=NIL THEN Raise(0)
quit:=0
WHILE quit=0
res:=WaitPort(myport)
IF (appmsg:=GetMsg(myport))=NIL THEN Raise(0)
wb_args:=appmsg.arglist
IF wb_args=0 THEN quit:=EasyRequestArgs(0,[20,0,0,'Que fait on ?','Quitter|Lancer'],0,0)
EXIT quit
old_lock:=CurrentDir(wb_args[0].lock)
StrCopy(commande,programme)
StrAdd(commande,' ')
StrAdd(commande,wb_args[0].name,ALL)
Execute(commande,NIL,stdout)
CurrentDir(old_lock)
ReplyMsg(appmsg)
WHILE appmsg:=GetMsg(myport) DO ReplyMsg(appmsg)
ENDWHILE
RemoveAppIcon(appicon)
DeleteMsgPort(myport)
CloseLibrary(workbenchbase)
CloseLibrary(iconbase)
FreeDiskObject(diskobj)
CleanUp(0)
EXCEPT
WriteF('Une erreur s''est produite')
IF appicon THEN RemoveAppIcon(appicon)
IF myport THEN DeleteMsgPort(myport)
IF workbenchbase THEN CloseLibrary(workbenchbase)
IF diskobj THEN FreeDiskObject(diskobj)
IF iconbase THEN CloseLibrary(iconbase)
CleanUp(0)
ENDPROC
|
|