Obligement - L'Amiga au maximum

Vendredi 23 mai 2025 - 14:11  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

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


Trucs et astuces

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


Glossaire

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


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : icon.library
(Article écrit par Iliak et extrait de GuruMed.net - décembre 2002)


Le Workbench est le bureau de l'Amiga. Celui-ci permet de représenter simplement et graphiquement les disques, les répertoires et les fichiers. Dans cet article, nous allons aborder deux bibliothèques, la workbench.library et l'icon.library du Workbench 3.5. La première permet aux applications de communiquer avec le Workbench, tandis que la deuxième permet aux applications d'afficher des icônes sur le bureau.

Dans un premier temps, nous allons étudier l'icon.library afin d'afficher des icônes, puis nous nous intéresserons à la workbench.library.

1. Présentation de l'icon.library

Afin d'afficher des icônes, le Workbench a besoin d'un fichier se terminant par un ".info" et portant le même nom que le fichier à afficher. Ainsi, pour afficher le fichier "toto", il faut avoir son fichier icône nommé "toto.info" dans le même répertoire. Par défaut, le système fourni quatre types d'icônes :
  • Disque : un disque dur ou une disquette.
  • Répertoire : par exemple Sys:Devs/.
  • Projet : un fichier de données.
  • Objet : un exécutable.
Pour créer des icônes, vous devez utiliser le logiciel IconEdit fourni avec le système, ou la créer vous-même au sein de votre programme. Vous devez absolument respecter la liste ci-dessus, sinon vous aurez des problèmes pour faire marcher votre application si vous désirez la lancer depuis le Workbench. Il existe un cas particulier pour nommer les icônes : les disques. Dans tous les cas, l'icône pour un disque se nomme "disk.info", a le type "disk" et se situe à la racine du disque (disquette ou disque dur). En plus du fait de fournir une interface graphique, l'icon.library est un pilier central entre votre application et le Workbench. En effet, vous pouvez stocker des informations à l'intérieur des icônes, comme la taille de la pile, des arguments, la priorité, etc.

1.1 Structure

Tout d'abord, voici à quoi ressemble la structure DiskObject (voir "include:workbench/workbench.h" dans les RKM ou sur l'Amiga Developer CD 2.1) :

struct DiskObject
{
   UWORD         do_Magic;
   UWORD         do_Version;
   struct Gadget      do_Gadget;
   UBYTE         do_Type;
   char         *do_DefaultTool;
   char         **do_ToolTypes;
   LONG         do_CurrentX;
   LONG         do_CurrentY;
   struct DrawerData   *do_DrawerData;
   char         *do_ToolWindow;
   LONG         do_StackSize;
};
  • do_Magic : numéro qui permet à la bibliothèque de savoir à coup sûr que c'est une icône. Cette valeur est WB_DISKMAGIC.
  • do_Version : permet de savoir et garder la compatibilité de l'icône.
  • do_Gadget : structure Gadget qui contient les images de l'icône (voir paragraphe "1.2 Les gadgets").
  • do_Type : type de l'icône :
    • WBDISK : icône d'un disque.
    • WBDRAWER : icône d'un répertoire.
    • WBTOOL : icône d'un exécutable.
    • WBPROJECT : icône d'un fichier de données.
    • WBGARBAGE : icône d'une poubelle.
    • WBKICK : icône d'une disquette de démarrage (Kickstart).
    • WBAPPICON : icône d'une AppIcon (voir paragraphe "2.1 AppIcon").
  • do_DefaultTool : utilisable seulement sur les icônes de type projet et disque. Chemin indiquant l'action par défaut à effectuer lorsque l'on double-clique sur l'icône pour un projet. Pour un disque, l'action par défaut est "Sys:System/diskCopy".
  • do_ToolTypes : permet de passer des chaînes de caractères au programme. Ni l'icon.library, ni le Workbench ne regarde ces chaînes. Elles servent juste à passer des arguments au programme via l'icône (voir chapitre "1.3 Les types d'outils").
  • do_CurrentX, do_CurrentY : position de l'icône dans la fenêtre. Au cas où l'icône ne dispose pas de position prédéfinie, elle a comme valeur "NO_ICON_POSITION".
  • do_DrawerData : si l'icône est du type WBDISK, WBDRAWER ou WBGARBAGE, alors ce champ est valide. Il indique au Workbench comment ouvrir le répertoire et aussi sauvegarder vos préférences. Cette structure à la forme suivante :

    struct DrawerData
    {
       struct   NewWindow   dd_NewWindow; // voir le fichier d'inclusion intuition/intuition.h
       LONG         dd_CurrentX;  // Position X
       LONG         dd_CurrentY;  // Position Y
    };
    

  • do_ToolWindow : ne pas utiliser, pour un usage futur.
  • do_StackSize : taille de la pile du programme en octets. Si cette valeur est absente, une pile de 4 ko sera attribuée au programme.
1.2 Les gadgets

Afin de garder l'image de l'icône, le Workbench utilise une structure Gadget. Étant donné que tous les champs de cette structure ne sont pas utilisés, ils sont laissés à 0 et ne doivent pas être modifiés. Voici la liste des champs utilisés :
  • Width : largeur de la zone réactive de l'icône.
  • Height : hauteur de la zone réactive de l'icône.
  • Flags : doit absolument être du type "GADIMAGE". Trois méthodes de surbrillance existent :
    • GADHCOMP : complète l'image de l'icône.
    • GADHIMAGE : utilise une autre image.
    • GADGBACKFILL : similaire à "GADHCOMP" mais évite "l'anneau" autour de l'image.
  • Activation : soit "RELVERIFY" ou "GADGIMMEDIAT".
  • Type : doit être "BOOLGADGET".
  • GadgetRender : pointeur vers l'image complémentaire.
1.3 Les types d'outils

Nous avons dit que l'on pouvait utiliser l'icône afin de passer des arguments à notre programme. Cela se fait par l'intermédiaire du champ "do_ToolTypes". Pour modifier ce champ, vous devez sélectionner l'icône et, dans le menu du Workbench, cliquer sur "Information". Vous obtiendrez la liste des types d'outils ("ToolTypes"). Du point de vue programmation, les types d'outils sont une série de pointeurs vers des chaînes de 128 caractères au maximum. De plus, vous ne devez utiliser que des caractères imprimables (fortement conseillé) et la casse est sensible, ainsi "Toto" est différent de "TOTO".

Le format standard des types d'outils est "=[|...]". Bien évidement, des valeurs réservées existent :
  • DONOTWAIT=n : le Workbench n'attend pas un message de retour de la part de la tâche.
  • STARTPRI=n : définit l'ordre de lancement dans le répertoire WBStartup.
  • TOOLPRI=n : définit la priorité de la tâche sous Exec.
Afin de lire les types d'outils, le système fournit "FindToolType()" qui permet de récupérer la valeur d'un type d'outils et "MatchToolValue()" qui permet de savoir si un type d'outils a une certaine valeur.

Exemple d'utilisation des types d'outils : cette procédure va lire tous les types d'outils d'une icône. Comme argument, elle prend le message que le Workbench vous envoie au démarrage.

void showToolTypes(struct WBArg *wbarg)
{
   struct   DiskObject *dobj;
   char   **toolarray;
   char   *s;
   BOOL   success = FALSE;
    printf("Lock=0x%lx, Nom=%s\n", wbarg->wa_Lock, wbarg->wa_Name);

   if((*wbarg->wa_Name) && (dobj=GetDiskObject(wbarg->wa_Name)))
   {
      printf("We have read the DiskObject (icon) for this arg\n");
      toolarray = (char **)dobj->do_ToolTypes;

      if(s=(char *)FindToolType(toolarray,"FILETYPE"))
      {
         fprintf(conwin,"    Found tooltype FILETYPE with value %s\n",s);
      }
      if(s=(char *)FindToolType(toolarray,"FLAGS"))
      {
         fprintf(conwin,"    Found tooltype FLAGS with value %s\n",s);
         if(MatchToolValue(s,"BOLD"))
            fprintf(conwin,"      BOLD flag requested\n");
         if(MatchToolValue(s,"ITALICS"))
            fprintf(conwin,"      ITALICS flag requested\n");
         }
      /* Free the diskobject we got */
      FreeDiskObject(dobj);
      success = TRUE;
   }
   else if(!(*wbarg->wa_Name)){
      fprintf(conwin,"  Must be a disk or drawer icon\n");
   }
   else
   {
      fprintf(conwin,"  Can't find any DiskObject (icon) for this WBArg\n");
   }
}

2. La workbench.library

La workbench.library fournit aux développeurs trois moyens de communication supplémentaires sous le Workbench :
  • Les AppIcons : icône spéciale qui renvoie un signal lorsqu'une autre icône est lâchée dessus. Le Workbench donne le nom et le répertoire de l'icône lâché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é sélectionné.
  • Les AppWindows : fenêtre qui a la particularité de permettre d'y déposer une icône dedans. Ainsi, on est informé dès qu'une icône est déposée dans cette fenêtre. En retour, le Workbench donne le nom et le répertoire de l'icône lâchée dans l'AppWindow.
Ces trois fonctions permettent d'étendre les possibilités de communication avec l'interface graphique du Workbench. En retour de chacunes d'elles, le Workbench renvoie un pointeur vers une structure "WBArg" :

struct WBArg{
BPTR   wa_Lock;   /* Verrou sur le répertoire */
BYTE   *wa_Name;   /* Nom de l'icône */
};

Nous allons d'ailleurs aborder ces trois facettes grâce à des exemples.

2.1 AppIcon

Dans cet exemple, nous allons mettre en place une AppIcon. Notre icône aura l'apparence d'un disque et dès que nous lâcherons une icône 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 icône 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 met l'icône sur le Workbench */
               appicon=AddAppIconA(0,0,"AppIcon",mport,NULL,dskobj,NULL);
               if(appicon)
               {
                  /* On attend 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-cliqué sur l'AppIcon */
                        printf("Double-clic sur l'icône !\n");

                     else if(appmsg->am_NumArgs>0)
                     {
                        /* Si NumArgs est >0 alors l'AppIcon a été activée avec */
                        /* une ou plusieurs autre(s) icônes */
                        printf("Il y a %ld icônes lâchées sur l'AppIcon\n", appmsg->am_NumArgs);
                        for(x=0;xam_NumArgs;x++)
                           printf("Icône #%ld, nom='%s'\n",x+1,appmsg->am_ArgList[x].wa_Name);
                     }
                     /* On répond au message */
                     ReplyMsg(appmsg);
                  }
                  RemoveAppIcon(appicon);
               }
               DeleteMsgPort(mport);
            }
            FreeDiskObject(dskobj);
         }
         CloseLibrary(WBBase);
      }
      CloseLibrary(IconBase);
   }

   return(0);
}

2.2 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é, cela ouvrira une fenêtre CLI et nous quitterons notre programe. Pour ouvrir la fenêtre CLI, nous utiliserons la commande "SystemTags()".

#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 de 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 icônes\n",appmsg->am_NumArgs);
            for(x=0;xam_NumArgs;x++)
               printf("Icône #%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 restants dans la file d'attente */
         while(appmsg=(struct AppMessage *)GetMsg(msgport))
            ReplyMsg((struct Message *)appmsg);

         DeleteMsgPort(msgport);
      }
      CloseLibrary(WBBase);
   }

   return(0);
}

2.3 AppWindow

Cet exemple montre comment créer une AppWindow. Il suffit de lâcher une ou plusieurs icônes 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 attend 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; iam_NumArgs; i++)
                           {
                              printf("arg(%ld): Name='%s', Lock=%lx\n",
                              i,      /* numéro */
                              WBarg->wa_Name,   /* Nom de l'icône */
                              WBarg->wa_Lock   /* Verrou 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);
}



[Retour en haut] / [Retour aux articles]