Librairie Workbench
Un article de GuruMed.
Par Iliak
La workbench.library fournis aux dévellopeurs 3 moyens de communication suplémentaires sous le workbench :
- les AppIcons : Icone spéciale qui renvois un signal lorsqu'une autre icone est lachée dessus. Le workbench donne le nom et le répertoire de l'icone lachée dans l'AppIcon.
- les AppMenus : Sous menu spécial qui se rajoute dans le menu "Outils" du Workbench. Celui-ci en retour nous indique dès que le menu a été selectionné.
- les AppWindows : Fenêtre qui a la particularité de permettre d'ici déplacer une icone dedans. Ainsi on est informé dès qu'une icone est déposée dans cette fenêtre. En retour le workbench donne le nom et le répertoire de l'icone lachée dans l'AppWindow.
Ces 3 fonctions permettent d'étendre les possibilités de communication avec l'interface graphique du Workbench. En retour de chaqu'unes d'elles, le Workbench renvoit un pointeur vers une structure WBArg :
struct WBArg{
BPTR wa_Lock; /* Lock sur le répertoire */
BYTE *wa_Name; /* Nom de l'icone */
};
Nous allons d'ailleurs aborder ces 3 facettes grâce à des exemples.
AppIcon
Dans cet exemple, nous allons mettre en place une AppIcon. Note icone aura l'apparence d'un disque et dès que nous lacherons une icone dessus, nous afficherons des informations.
#include <exec/types.h>
#include <workbench/workbench.h> /* Les structures DiskObject et AppIcon */
#include <workbench/startup.h> /* Les structures WBStartup et WBArg */
#include <exec/libraries.h>
struct Library *IconBase;
struct Library *WBBase;
int main(int argc, char **argv)
{
struct DiskObject *dskobj;
struct MsgPort *mport;
struct AppIcon *appicon;
struct AppMessage *appmsg;
ULONG x;
if(IconBase = OpenLibrary("icon.library",37))
{
if (WBBase=OpenLibrary("workbench.library",37))
{
/* On obtient l'image d'une icone par défaut (ici un disque) */
dskobj=GetDefDiskObject(WBDISK);
if(dskobj!=0)
{
/* TOUJOURS NULL pour une AppIcon ! */
dskobj->do_Type=NULL;
/* Création du port de communication pour que le WorkBench puisse nous répondre */
mport=CreateMsgPort();
if(mport)
{
/* On mets l'icone sur le WorkBench */
appicon=AddAppIconA(0,0,"AppIcon",mport,NULL,dskobj,NULL);
if(appicon)
{
/* On attends un message de la part du WorkBench */
WaitPort(mport);
/* ATTENTION, il peut y avoir plusieurs messages ! */
while(appmsg=GetMsg(mport))
{
if(appmsg->am_NumArgs==0)
/* Si NumArgs est nul, alors on a double clicke sur l'AppIcon */
printf("Double click sur l'icone !\n");
else if(appmsg->am_NumArgs>0)
{
/* Si NumArgs est >0 alors l'AppIcon a été activé avec */
/* une ou plusieurs autre(s) icones */
printf("Il y a %ld icones lachées sur l'AppIcon\n", appmsg->am_NumArgs);
for(x=0;x<appmsg->am_NumArgs;x++)
printf("Icone #%ld, nom='%s'\n",x+1,appmsg->am_ArgList[x].wa_Name);
}
/* On réponds au message */
ReplyMsg(appmsg);
}
RemoveAppIcon(appicon);
}
DeleteMsgPort(mport);
}
FreeDiskObject(dskobj);
}
CloseLibrary(WBBase);
}
CloseLibrary(IconBase);
}
return(0);
}
AppMenu
Dans cet exemple, nous allons rajouter un menu appellé "Cli" dans le menu "Outils" du WorkBench. Dès que celui-ci sera sélectionné, nous ouvrir une fenêtre Cli et nous quiterons notre programe. Pour ouvrir la fenêtre Cli, nous utiliserons la commande SystemTags(). Celle-ci fera l'objet d'une étude prochainement.
#include <exec/types.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <exec/libraries.h>
#include <dos/dostags.h>
#include <stdio.h>
struct Library *WBBase;
int main(int argc, char **argv)
{
struct MsgPort *msgport;
struct AppMenuItem *appitem;
struct AppMessage *appmsg;
LONG result, x;
BPTR file;
if (WBBase = OpenLibrary("workbench.library",37))
{
/* On crée notre port ce communication */
if(msgport = CreateMsgPort())
{
/* On ajoute notre AppMenu aux menus du WorkBench */
appitem=AddAppMenuItemA(NULL, /* Notre numéro ID */
(ULONG)"c:NewShell", /* Notre commande */
"Cli", /* Le texte à afficher */
msgport, /* Notre port de communication */
,NULL); /* Pas de paramètres */
if(appitem)
{
WaitPort(msgport);
appmsg=(struct AppMessage *)GetMsg(msgport)
printf("AppMenuItem sélectionné avec %ld icones\n",appmsg->am_NumArgs);
for(x=0;x<appmsg->am_NumArgs;x++)
printf("Icone #%ld nom : '%s'\n",x+1,appmsg->am_ArgList[x].wa_Name);
/* On ouvre une fenêtre pour tout message à afficher */
if( file=Open("CON:0/40/640/150/Fenêtre de sorite/auto/close/wait",MODE_OLDFILE))
{
result=SystemTags((UBYTE *)appmsg->am_UserData,SYS_Input,file,
SYS_Output,NULL,
SYS_Asynch,TRUE,
TAG_DONE);
/* La commande a échoué */
if(result == -1) Close(file);
}
ReplyMsg((struct Message *)appmsg);
RemoveAppMenuItem(appitem);
}
/* On efface tous les messages potentiellement restant dans la file d'attente */
while(appmsg=(struct AppMessage *)GetMsg(msgport))
ReplyMsg((struct Message *)appmsg);
DeleteMsgPort(msgport);
}
CloseLibrary(WBBase);
}
return(0);
}
AppWindow
Cet exemple montre comment créer une AppWindow. Il suffit de lâcher une ou plusieurs icones dans cette fenêtre pour récuperer leur nom.
#include <exec/types.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <exec/libraries.h>
#include <stdio.h>
struct Library *IntuitionBase;
struct Library *WBBase;
int main(int argc, char **argv)
{
struct MsgPort *msgport;
struct Window *win;
struct AppWindow *appwin;
struct IntuiMessage *imsg;
struct AppMessage *appmsg;
struct WBArg *WBarg;
ULONG winsig,
appwinsig,
signals,
id=1,
userdata = 0;
BOOL done=FALSE;
int i;
if (IntuitionBase = OpenLibrary("intuition.library", 37))
{
if (WBBase = OpenLibrary("workbench.library", 37))
{
if (msgport = CreateMsgPort())
{
if (win = OpenWindowTags(NULL,
WA_Width, 200, /* Largeur */
WA_Height, 50, /* Hauteur */
WA_IDCMP, CLOSEWINDOW, /* Messages que l'on désire recevoir */
WA_Flags, WINDOWCLOSE | WINDOWDRAG, /* Les gadgets de la fenêtre */
WA_Title, "AppWindow", /* Nom de la fenêtre */
TAG_DONE))
{
if (appwin = AddAppWindow(id, userdata, win, msgport, NULL))
{
winsig = 1 << win->UserPort->mp_SigBit;
appwinsig = 1 << msgport->mp_SigBit;
while (!done)
{
/* On attentds des signaux IDCMP ou de l'AppWindow */
signals = Wait( winsig | appwinsig );
if(signals & winsig) /* Message IDCMP*/
{
while (imsg=GetMsg(win->UserPort))
{
if (imsg->Class = CLOSEWINDOW) done=TRUE;
ReplyMsg(imsg);
}
}
if(signals & appwinsig) /* AppMessage */
{
while (appmsg =GetMsg(msgport))
{
printf("AppMessage : Type = %ld, ID = %ld, Arguments=%ld\n",
appmsg->am_Type, /* Type de message */
appmsg->am_ID, /* Numéro du message */
appmsg->am_NumArgs /* Arguments */
);
WBarg = appmsg->am_ArgList;
for (i=0; i<appmsg->am_NumArgs; i++)
{
printf("arg(%ld): Name='%s', Lock=%lx\n",
i, /* numéro */
WBarg->wa_Name, /* Nom de l'icone */
WBarg->wa_Lock /* Lock sur le répertoire */
);
WBarg++;
}
ReplyMsg(appmsg);
}
}
}
RemoveAppWindow(appwin);
}
CloseWindow(win);
}
/* On efface tous les messages en attente */
while(appmsg = (struct AppMessage *)GetMsg(msgport))
{
ReplyMsg((struct Message *)appmsg);
}
DeleteMsgPort(msgport);
}
CloseLibrary(WorkbenchBase);
}
CloseLibrary(IntuitionBase);
}
return(0);
}
