Obligement - L'Amiga au maximum

Vendredi 06 juin 2025 - 12:54  

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 : Amiga C Manual - Les fenêtres
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)


Note : traduction par Serge Hammouche.

2. Les fenêtres

2.1 Introduction

Les fenêtres (windows) sont des boîtes rectangulaires qui peuvent être aussi grandes que l'écran ou ne faire qu'un pixel de large. Elles peuvent être redimensionnées, déplacées sur l'écran, passer devant ou derrière d'autres fenêtres, et ainsi de suite. Tout est géré par Intuition, et votre programme n'a pas à s'en occuper si vous ne le voulez pas.

Le but des fenêtres est de rendre la communication entre l'utilisateur et l'ordinateur aussi facile que possible. Les fenêtres fournissent à l'utilisateur un affichage structuré facile à comprendre. Elles permettent aussi à l'utilisateur d'interagir avec les programmes grâce à des symboles graphiques (les gadgets) qui peuvent être liés aux fenêtres (voir le chapitre 4 - Les gadgets pour plus d'informations sur les gadgets).

Les fenêtres fonctionnent en étroite relation avec les écrans, dans la mesure où la résolution de l'écran, etc. influent sur le dessin des fenêtres. Le déplacement d'un écran entraîne aussi celui de toutes les fenêtres qui lui sont liées.

2.2 Les fenêtres spéciales

Les fenêtres normales sont des boîtes rectangulaires avec une bordure autour. Cependant, il existe des types de fenêtre spéciaux.

2.2.1 Les fenêtres d'arrière-plan (backdrop windows)

Les fenêtres d'arrière-plan seront toujours derrière toutes les autres fenêtres. Ceci vous permet d'avoir une fenêtre à l'arrière-plan, et elle y restera, même si l'utilisateur se sert des gadgets de profondeur.

Les fenêtres d'arrière-plan diffèrent des autres fenêtres car :
  • Elles s'ouvrent toujours derrière toutes les autres, y compris les autres fenêtres d'arrière-plan déjà ouvertes.
  • Le gadget de fermeture est le seul gadget système que vous pouvez lier à une fenêtre d'arrière-plan (vous pouvez bien sûr y lier vos propres gadgets normalement).
  • Elle sera toujours derrière n'importe quelle autre fenêtre.
La fenêtre d'arrière-plan est très pratique quand vous voulez avoir un dessin à l'arrière-plan (par exemple votre affichage principal), avec des outils, etc. sur la fenêtre. Ceci permet à l'utilisateur de déplacer vos outils comme il/elle veut sans craindre de passer les fenêtres derrière l'affichage principal.

Dessiner dans une fenêtre d'arrière-plan plutôt que sur l'écran lui-même est très courant car il est alors impossible de dessiner au mauvais moment. Si un menu (Voir le chapitre 5 - Les menus pour plus d'informations) est affiché, les routines de dessin attendront automatiquement, et ne détruiront donc pas le menu, ce qui serait arrivé si vous aviez dessiné directement sur l'écran.

2.2.2 Les fenêtres sans bordures (borderless windows)

Les fenêtres sans bordures sont des fenêtres normales sauf que (surprise, surprise) elle n'ont pas de bordures. Il est très courant de combiner une fenêtres sans bordures et une fenêtre d'arrière-plan, pour recouvrir un écran.

Il peut être gênant pour l'utilisateur qu'une fenêtres sans bordures ne recouvre pas entièrement l'écran, car il/elle ne peut alors plus savoir ou les bordures de la fenêtre sont. Il est donc généralement préférable d'avoir des fenêtres sans bordures de la taille de l'écran.

2.2.3 Les fenêtres Gimmezerozero (Gimmezerozero windows)

Une fenêtre Gimmezerozero est une fenêtre normale, sauf qu'elle est constituée de deux zones : une fenêtre Outer et une fenêtre Inner. La fenêtre Outer est utilisée pour afficher les bordures, les gadgets système, etc., tandis que la fenêtre Inner n'est utilisée que par vous.

Si vous dessinez dans une fenêtre normale, vou devez commencer quelques pixels en retrait (11, 1) pour ne pas dessiner dans les bordures, etc. Par contre, si vous dessinez dans une fenêtre Gimmezerozero, vous n'avez pas à faire de corrections. Le coin supérieur gauche de votre fenêtre Inner est toujours à la position (0,0).

Les fenêtres Gimmezerozero sont donc très pratiques si vous voulez faire beaucoup de dessins sans avoir à vous soucier des bordures. L'inconvénient est qu'elles consomment beaucoup plus de mémoire et de temps qu'une fenêtre normale.

2.2.4 Les fenêtres SuperBitmap (SuperBitMap windows)

Si vous utilisez une fenêtre SuperBitMap, vous allouez vous-même la mémoire pour l'affichage de la fenêtre au lieu de laisser Intuition s'en charger. L'avantage est que vous pouvez définir une zone de dessin plus grande que la fenêtre. Vous pouvez alors faire défiler la zone de dessin dans la fenêtre. Un bon exemple vous en est fourni par les programmes de démonstrations joints à votre disquette Workbench quand vous avez acheté votre ordinateur.

Il est généralement préférable de combiner une fenêtre SuperBitMap à une fenêtre Gimmezerozero. Les bordures, etc., ne seront alors pas dessinées dans votre SuperBitMap, mais dans la fenêtre Outer. Ceci vous permet de faire ce que vous voulez dans la fenêtre Inner sans affecter les bordures, etc.

2.3 Les gadgets système (system gadgets)

Les gadgets système permettent à l'utilisateur de déplacer la fenêtre, la redimensioner, la passer derrière les autres fenêtres, etc., sans même que votre programme ne le sache. Les gadgets système sont contrôlés par Intuition, et sont toujours identiques. Il vous suffit de dire à Intuition quels gadgets vous voulez, et il fait le reste pour vous.

Les cinq gadgets système sont placés comme suit :


   1       2       3  4  
  [*][***********][*][*]  
  |                    |  
  |      fenêtre       |  
  |                    |  
  |                    |  
  |__________________[*]  
                      5  


1 : gadget de fermeture (close gadget). Cliquez pour fermer la fenêtre. C'est le seul gadget système auquel votre programme doit répondre. Il indiquera à votre programme que l'utilisateur a cliqué sur le gadget de fermeture, mais vous devez fermer la fenêtre vous-même en appelant la fonction CloseWindow().

2 : barre de déplacement (drag gadget). Une pression du bouton gauche de la souris quand le pointeur est dessus permet de déplacer la fenêtre tant que le bouton n'est pas relaché. Si votre fenêtre a un intitulé, il sera affiché par-dessus le gadget mais ne s'y mélangera pas.

3 : cellule de mise en arrière (depth-arrangement gadget back). Cliquer sur ce gadget passe la fentre derrière toutes les autres fenêtres.

4 : cellule de mise en avant (depth-arrangement gadget up). Cliquer sur ce gadget passe la fentre devant toutes les autres fenêtres.

5 : cellule de redimensionnement (size gadget). Une pression du bouton gauche de la souris quand le pointeur est dessus permet changer la taille de la fenêtre tant que le bouton n'est pas relaché.

2.4 Le rafraîchissement des fenêtres

Comme les fenêtres peuvent être déplacées sur l'écran, il est très courant qu'elles se chevauchent. Si l'utilisateur éloigne la fenêtre du dessus, celle du dessous doit être rafraîchie.

Il y a deux méthodes pour rafraîchir une fenêtre :
  • Le rafraîchissement simplte (simple refresh). Intuition vous indique simplement qu'il faut la rafraîchir, et votre programme doit tout redessiner lui-même.
  • Le rafraîchissement intelligent (smart refresh). Intuition sauvegarde les parties cachées, et les remet automatiquement en place. Consomme plus de mémoire que le rafraîchissment simple, mais rafraîchit l'affichage beaucoup plus vite.
Si vous avez une fenêtre SuperBitMap, vou avez alloué la mémoire pour l'affichage vous-même, et votre fenêtre ne sera donc pas detruite par les autres fenêtres.

Si vous changez la taille d'une fenêtre à rafraîchissement simple, ou qu'elle est dévoillée après avoir été masquée, Intuition vous indiquera que vous devez la rafraîchir. Une fenêtre à rafraîchissement intelligent ne vous demandera de la rafraîchir que si vous l'avez agrandie.

Le message IDCMP "REFRESHWINDOW" vous indique qu'il faut rafraîchir la fenêtre (voir le chapitre 8 - IDCMP pour plus d'informations sur les drapeaux IDCMP).

Attention : si votre programme reçoit un message REFRESHWINDOW, vous devez appeler les fonctions BeginRefresh() - EndRefresh() :
  • BeginRefresh() redessine aussi vite que possible. Seules les parties endommagées de la fenêtre seront rafraîchies.
  • EndRefresh() indique à Intuition que vous avez fini de redessiner.
Si vous recevez un message REFRESHWINDOW et que vous ne voulez pas redessiner l'affichage, vous devez quand même appelez les deux fonctions. Ceci mettra de l'ordre dans le système et réorganisera la Layer.library.

2.5 Initialiser une fenêtre

Avant d'ouvrir une fenêtre, vous devez initialiser une structure NewWindow qui ressemble à ceci :

struct NewWindow
{
  SHORT LeftEdge, TopEdge;
  SHORT Width, Height;
  UBYTE DetailPen, BlockPen;
  ULONG IDCMPFlags;
  ULONG Flags;
  struct Gadget *FirstGadget;
  struct Image *CheckMark;
  UBYTE *Title;
  struct Screen *Screen;
  struct BitMap *BitMap;
  SHORT MinWidth, MinHeight;
  SHORT MaxWidth, MaxHeight;
  USHORT Type;
};
  • LeftEdge (bord gauche) : position initiale en x de la fenêtre.
  • TopEdge (bord supérieur) : position initiale en y de la fenêtre.
  • Width (largeur) : largeur initiale de la fenêtre. Si la fenêtre est liée à un écran haute résolution, elle peut aller de 1 à 640. Sinon (écran basse résolution) elle peut aller de 1 à 320.
  • Height (hauteur) : hauteur initiale de la fenêtre. Elle peut aller de 1 à la hauteur de l'écran.
  • DetailPen (crayon à détail) : le registre couleur utilisé pour afficher le texte.
  • BlockPen (crayon à bloc) : le registre couleur utilisé pour les remplissages de blocs, etc.
  • IDCMPFlags (drapeaux IDCMP) : voir le chapitre 8 - IDCMP pour la liste et les explications de ces drapeaux.
  • FirstGadget (premier gadget) : un pointeur sur le premier fadget de votre liste, ou NULL si vous n'avez pas de gadget personnel lié à la fenêtre (voir le chapitre 4 - Les gadgets pour plus d'informations sur les gadgets).
  • CheckMark (coche) : un pointeur sur une structure Image (voir le chapitre 3 - Les graphismes pour plus d'informations sur les structures Image) qui sera utilisée pour les éléments des menus sélectionnés (voir le chapitre 7 - Les menus pour plus d'informations sur les menus). Si aucun pointeur n'est donné (NULL), Intuition utilisera la coche par défaut.
  • Title (intitulé) : un pointeur sur une chaîne terminée par NULL qui sera utilisée comme intitulé de la fenêtre. La chaîne sera placée dans la barre d'intitulé, en haut de la fenêtre.
  • Screen (écran) : un pointeur sur votre écran personnalisé, ou NULL si la fenêtre doit être liée à l'écran Workbench. Si la fenêtre est liée à l'écran Workbench, mettez la variable Type à WBENCHSCREEN, sinon mettez la à CUSTOMSCREEN.
  • BitMap : si vous utilisez une fenêtre SuperBitMap, vous devez fournir à Intuition un pointeur sur la structure BitMap que vous avez initialisée, NULL sinon. Pensez à activer le drapeau SUPER_BITMAP, et je vous conseille aussi de prendre une fenêtre Gimmezerozero.
  • Flags (drapeaux) : si vous voulez des gadgets système, une fenêtre spéciale (sans bordures, d'arrière-plan, etc.), activez les drapeaux nécessaires :

      Gadgets système :

    • WINDOWCLOSE : ajoute le gadget de fermeture dans le coin supérieur gauche de votre fenêtre. Rappelez-vous que c'est le seul gadget système auquel votre programme doit répondre. Intuition vous informera simplement que l'utilisateur veut fermer la fenêtre, mais vous devez le faire vous-même en appelant la fonction CloseWindow().
    • WINDOWDRAG : transforme la barre d'intitulé en un gadget qui permet à l'utilisateur de déplacer la fenêtre.
    • WINDOWDEPTH : si vous voulez que l'utilisateur puisse passer la fenêtre devant ou derrière toutes les autres fenêtres, activez ce drapeau. Les gadgets (de mise en avant/en arrière) seront placés dans le coin supérieur droit de la fenêtre.
    • WINDOWSIZING : permet à l'utilisateur de redimensioner la fenêtre comme il le souhaite (vous pouvez spécifier les tailles maximale et minimale de la fenêtre grâce aux variables MinWidth/MinHeight/MaxWidth/MaxHeight). La cellule de redimensionnement sera placée dans la bordure de droite par défaut (SIZEBRIGHT), mais peut aussi être placée dans la bordure inférieure (activez le drapeau SIZEBOTTOM) si vous voulez que la fenêtre soit affichée avec la largeur maximale.

      Fenêtres spéciales :

    • BACKDROP : activez ce drapeau si vous voulez une fenêtre d'arrière-plan.
    • BORDERLESS : activez ce drapeau si vous voulez une fenêtre sans bordures.
    • GIMMEZEROZERO : activez ce drapeau si vous voulez une fenêtre Gimmezerozero.
    • SUPER_BITMAP : activez ce drapeau si vous voulez une fenêtre SuperBitMap. Si vous utilisez un bitmap que vous avez alloué vous-même, vous devez aussi initialisez la variable BitMap pour qu'elle pointe sur votre structure BitMap. Explication plus loin dans ce chapitre.

      Drapeaux de rafraîchissement. Si vous n'utilisez pas une fenêtre SuperBitMap, vous devez activer l'un de ces drapeaux :

    • SIMPLE_REFRESH : votre programme doit redessiner l'affichage lui-même.
    • SMART_REFRESH : Intuition redessinera automatiquement l'affichage si nécessaire. Il n'y a que quand l'utilisateur agrandit la fenêtre que vous devez vous-même redessiner l'affichage.

      Autres drapeaux :

    • REPORTMOUSE : activez ce drapeau si vous voulez recevoir les mouvements du pointeur en terme de coordonnées x,y (voir le chapitre 8 - IDCMP pour plus d'informations).
    • NOCAREREFRESH : activez ce drapeau si vous ne voulez pas recevoir de message vous demandant de redessiner votre fenêtre.
    • RMBTRAP : activez ce drapeau si vous ne voulez pas que l'utilisateur ait accès aux menus tant que la fenêtre est active. Si vous voulez utilisez le bouton droit de la souris pour autre chose que les menus, vous devez activer ce drapeau (voir le chapitre 8 - IDCMP pour plus d'informations).
    • ACTIVATE : activez ce drapeau si vous voulez que la fenêtre soit activée à son ouverture. L'utilisateur pourra bien sûr activer d'autres fenêtres après s'il le désire. Cliquer dans une fenêtre l'activera, et toutes les entrées se feront dans la nouvelle fenêtre active. Toutes les autres fenêtres seront désactivées, et leur barres d'intitulé passeront en mode fantôme (ghosted).
Si vous avez demandé le gadget système WINDOWSIZING, vous devez fixer les tailles minimale/maximale de votre fenêtre, sinon vous pouvez ignorer ces variables. Si une variable est fixée à zéro, la taille initiale (Width/Height) sera utilisée comme taille maximale/minimale :
  • MinWidth : largeur minimale de la fenêtre.
  • MinHeight : hauteur minimale de la fenêtre.
  • MaxWidth : largeur maximale de la fenêtre.
  • MaxHeight : hauteur maximale de la fenêtre.
  • Type : si votre fenêtre doit être liée à l'écran Workbench, mettez WBENCHSCREEN, sinon mettez CUSTOMSCREEN. Si vous activez le drapeau CUSTOMSCREEN, vous devez mettre dans la variable Screen un pointeur sur votre écran personnalisé préalablement ouvert.
Il est courant de déclarer et d'initialiser la structure NewWindow selon ses besoins, en ignorant (NULL) le pointeur Screen. Vous ouvrez alors votre écran personnalisé, et immédiatement après vous initialisez le pointeur Screen avec le pointeur retourné par la fonction OpenScreen() (voir l'exemple 2 pour plus d'informations).

2.6 Ouvrir une fenêtre

La procédure d'ouverture d'une fenêtre est très proche de l'ouverture d'un écran personnalisé. L'idée est que vous déclarez une structure NewWindow (similaire à NewScreen) et l'initialisez selon vos besoins. Il vous suffit dès lors d'appeler la fonction OpenWindow() (similaire à OpenScreen()) avec votre structure NewWindow, et la fonction retourne un pointeur sur votre structure Window. Vous n'aurez alors plus besoin de la structure NewWindow (si vous ne voulez plus ouvrir de fenêtre utilisant la même structure bien sûr).

Appelez la fonction OpenWindow() comme suit :

my_window = OpenWindow( &my_new_window );

...où my_window a été déclaré comme :

struct Window *my_window;

...et my_new_window a été déclaré comme :

struct NewWindow *my_new_window;

...et initialisée selon vos besoins.

OpenWindow() retournera un pointeur sur votre structure Window. Si elle n'a pas pu ouvrir la fenêtre (par exemple par manque de mémoire), elle retournera NULL. Pensez donc à vérifier ce qu'a retourné OpenWindow() :

if( my_window == NULL )
{
  /* Panique ! Impossible d'ouvrir la fenêtre */
}

2.7 La structure Window

Quand vous aurez ouvert la fenêtre, vous recevrez un pointeur (my_window) sur une structure Window :

struct Window
{
    struct Window *NextWindow;    /* Pointeur sur la prochaine fenêtre.*/
    SHORT LeftEdge, TopEdge;      /* Position de la fenêtre.           */
    SHORT Width, Height;          /* Taille de la fenêtre.             */
    SHORT MouseY, MouseX;         /* Position du pointeur par rapport  */
                                  /* au coin supérieur gauche de la    */
                                  /* fenêtre.                          */
    SHORT MinWidth, MinHeight;    /* Taille minimale/maximale de la    */
    USHORT MaxWidth, MaxHeight;   /* fenêtre.                          */

    ULONG Flags;                  /* Les drapeaux de la fenêtre.       */

    struct Menu *MenuStrip;       /* Pointeur sur le premier menu de   */
                                  /* la fenêtre.                       */

    UBYTE *Title;                 /* L'intitulé de la fenêtre.         */

    struct Requester *FirstRequest;
    struct Requester *DMRequest;
    SHORT ReqCount;

    struct Screen *WScreen;       /* Un pointeur sur l'écran auquel la */
                                  /* fenêtre est liée.                 */
    struct RastPort *RPort;       /* Le RastPort de la fenêtre.        */

    BYTE BorderLeft, BorderTop, BorderRight, BorderBottom;

    struct RastPort *BorderRPort; /* Pointeur sur le RastPort de la    */
                                  /* fenêtre Outer s'il s'agit d'une   */
                                  /* fenêtre Gimmezerozero.            */

    struct Gadget *FirstGadget;
    struct Window *Parent, *Descendant;

    USHORT *Pointer;              /* Données pour le Pointeur.         */
    BYTE PtrHeight;               /* Hauteur du pointeur.              */
    BYTE PtrWidth;                /* Largeur du pointeur.              */
    BYTE XOffset, YOffset;        /* point actif du pointeur.          */

    ULONG IDCMPFlags;             /* Les drapeaux IDCMP.               */

    struct MsgPort *UserPort, *WindowPort;
    struct IntuiMessage *MessageKey;

    UBYTE DetailPen, BlockPen;
    struct Image *CheckMark;

    UBYTE *ScreenTitle;           /* L'intitulé de l'écran auquel la   */
                                  /* fenêtre est liée.                 */

    /* A n'utiliser que si vous avez ouvert une Gimmezerozero Window:  */
    SHORT GZZMouseX; /* Position de la souris par rapport à l'Inner    */
    SHORT GZZMouseY; /* Window.                                        */
    SHORT GZZWidth;  /* Taille de la fenetre Inner.                    */
    SHORT GZZHeight;

    UBYTE *ExtData;
    BYTE *UserData;
    struct Layer *WLayer;
    struct TextFont *IFont;
};

2.8 Ouvrir une fenêtre SuperBitMap

La différence entre l'ouverture d'une fenêtre normale et celle d'une fenêtre SuperBitMap est qu'Intuition alloue automatiquement de la mémoire pour l'affichage d'un fenêtre normale, tandis qu'une fenêtre SuperBitMap doit allouer sa mémoire elle-même. Néanmoins, c'est en fait moins dur qu'il n'y paraît. Vous n'avez qu'à suivre ces étapes :
  • 1. Déclarer et initialiser une structure NewWindow selon vos besoins. (prendre Flags = SUPER_BITMAP, et BitMap=NULL)

       struct NewWindow my_new_window={ .... };
    

  • 2. Déclarer une structure BitMap :

       struct BitMap my_bitmap;
    

  • 3. Initialiser votre propre BitMap en appelant la fonction :

       InitBitMap( &my_bitmap, Depth, Width, Height );
    

    • &my_bitmap : un pointeur sur la structure my_bitmap.
    • Depth : nombre de plans de bits à utiliser.
    • Width : la largeur du BitMap.
    • Height : la hauteur du BitMap.

  • 4. Allouer de la mémoire pour l'affichage du BitMap :

       for( loop=0; loop < Depth; loop++)
         if( (my_bitmap.Planes[loop] = AllocRaster( Width,
           Height )) == NULL )
         {
           /* Panique !  Pas assez de mémoire */
         }
    

  • 5. Après avoir alloué la mémoire d'affichage, il est préférable d'effacer les plans de bits :

       for( loop=0; loop < Depth; loop++)
         BltClear(my_bitmap.Planes[loop], RASSIZE(Width, Height), 0);
    

  • 6. S'assurer que le pointeur BitMap de NewWindow pointe bien sur votre structure BitMap :

         my_new_window.BitMap=&my_bitmap;
    

  • 7. Enfin, ouvrir la fenêtre :

       my_window = OpenWindow( &my_new_window );
    

  • 8. Ne pas oublier de fermer la fenêtre, et de libérer la mémoire d'affichage :

       CloseWindow( my_window );
    
       for( loop=0; loop < Depth; loop++)
        if( my_bitmap.Planes[loop] )
          FreeRaster( my_bitmap.Planes[loop], Width, Height );
    
2.9 Faire son propre pointeur personnalisé (custom pointer)

Chaque fenêtre peut avoir son propre pointeur. Quand la fenêtre devient active, le pointeur change d'apparence. Ceci aide l'utilisateur à savoir quelle fenêtre est active, et peut aussi renseigner l'utilisateur sur ce qu'est en train de faire l'ordinateur. Par exemple, un traitement de texte peut avoir un pointeur en forme de crayon, et quand l'ordinateur est occupé, le pointeur peut se changer en un petit symbole "Zzz".

Si votre fenêtre utilise un pointeur personnalisé (custom), vous devez :
  • Allouer et initialiser une structure de données Sprite.
  • Utiliser la fonction SetPointer() pour changer le pointeur de la fenêtre.
Quand vous faites une nouvelle image pour votre pointeur, vous devez d'abord prévoir à quoi il ressemblera. Le pointeur est en fait un sprite (Voir le chapitre 10 - Les sprites pour plus d'informations sur les sprites), il peut donc avoir jusqu'à 16 pixels de large, et être aussi haut que vous le souhaitez. Vous pouvez utiliser trois couleurs plus la transparence (comme le pointeur est un sprite (no. 0), il peut passer d'un écran à un autre ayant une résolution différente sans problèmes d'affichage).

Un joli pointeur "flèche" (16 pixels de large, 16 lignes de haut) peut avoir cet aspect :

0000000200000000      0: Transparent
0000002200000000      1: Rouge
0000023200000000      2: Noir
0000231200000000      3: Blanc
0002311200000000
0023111222222200
0231111133333320
2311111111111132
0211111111111112
0021111222221112
0002111200023112
0000211200023112
0000021200023112
0000002200023112
0000000200023112
0000000000022222

Vous devez maintenant le transformer en données Sprite. Chaque ligne du pointeur sera transformée en deux mots de données. Le premier mot représente le premier plan de bits, et le deuxième mot le deuxième plan de bits. Le principe est que pour la couleur 0 les deux plans de bits doivent être à 0, pour la couleur 1 le plan de bit 0 doit être à 1 et le plan de bits 1 à 0 et ainsi de suite :

Couleur  Plan de bits 1   Plan de bits 0              Car
--------------------------------------------------------------------
   0           0                 0            00 Binaire = 0 Décimal
   1           0                 1            01 Binaire = 1 Décimal
   2           1                 0            10 Binaire = 2 Décimal
   3           1                 1            11 Binaire = 3 Décimal

Les données du pointeur ressembleront donc à ceci :

 Plan de bits 0         Plan de bits 1

0000 0000 0000 0000    0000 0001 0000 0000
0000 0000 0000 0000    0000 0011 0000 0000
0000 0010 0000 0000    0000 0111 0000 0000
0000 0110 0000 0000    0000 1101 0000 0000
0000 1110 0000 0000    0001 1001 0000 0000
0001 1110 0000 0000    0011 0001 1111 1100
0011 1111 1111 1100    0111 0000 1111 1110
0111 1111 1111 1110    1100 0000 0000 0011
0011 1111 1111 1110    0100 0000 0000 0001
0001 1110 0000 1110    0010 0001 1111 0001
0000 1110 0000 1110    0001 0001 0001 1001
0000 0110 0000 1110    0000 1001 0001 1001
0000 0010 0000 1110    0000 0101 0001 1001
0000 0000 0000 1110    0000 0011 0001 1001
0000 0000 0000 1110    0000 0001 0001 1001
0000 0000 0000 0000    0000 0000 0001 1111

La dernière étape est la traduction des nombres binaires en hexadécimal. Regroupez les nombres binaires par quatre et transformez-les en hexadécimal :

0000 =  0          0100 =  4          1000 =  8          1100 =  C
0001 =  1          0101 =  5          1001 =  9          1101 =  D
0010 =  2          0110 =  6          1010 =  A          1110 =  E
0011 =  3          0111 =  7          1011 =  B          1111 =  F

Le résultat aura cette allure :

Zéro     Un
-------------
0000    0100
0000    0300
0200    0700
0600    0d00
0E00    1900
1E00    31FC
3FFC    60FE
7FFE    c003
3FFE    4001
1E0E    21F1
0E0E    1119
060E    0919
020E    0519
000E    0319
000E    0119
0000    001F

Comme l'Amiga doit aussi stocker la position du pointeur, sa taille, etc., vous devez aussi déclarer deux mots vides au début des données du sprite et deux autres à la fin. Ces mots seront initialisés et mis à jour par Intuition, vous n'avez donc pas à vous en occuper.

Voici donc la déclaration et l'initialisation des données d'un beau sprite flèche pour un pointeur (un nombre hexadécimal tel 3FFE s'écrit 0x3FFE en C) :

UWORD chip my_sprite_data[36]=
{
 0x0000, 0x0000, /* Utilisés seulement par Intuition. */

 0x0000, 0x0100,
 0x0000, 0x0300,
 0x0200, 0x0700,
 0x0600, 0x0D00,
 0x0E00, 0x1900,
 0x1E00, 0x31FC,
 0x3FFC, 0x60FE,
 0x7FFE, 0xC003,
 0x3FFE, 0x4001,
 0x1E0E, 0x21F1,
 0x0E0E, 0x1119,
 0x060E, 0x0919,
 0x020E, 0x0519,
 0x000E, 0x0319,
 0x000E, 0x0119,
 0x0000, 0x001F,

 0x0000, 0x0000  /* Utilisés seulement par Intuition. */
};

Ce n'est donc pas si compliqué quand on y est habitué, mais pour vous faciliter un peu la tâche, j'ai écrit des utilitaires qui vous aideront à transformer les graphismes en données de sprite (voir le répertoire Tool pour plus d'informations).

La dernière étape est l'appel de la fonction SetPointer() qui doit se faire comme suit :

SetPointer( my_window, my_sprite_data, 16, 16, 0, -7);
  • my_window : pointeur sur la fenêtre.
  • my_sprite_data : pointeur sur les données du sprite.
  • 16 : hauteur.
  • 16 : largeur (inférieure ou égale à 16 !).
  • 0 : XOffset, côté gauche (position du point actif).
  • -7 : YOffset, à 7 lignes du haut (position du point actif).
Le point actif (hot spot) est le pixel qui sert de point sensible au pointeur. Sur le pointeur par défaut, il est en haut à gauche, mais sur notre pointeur personnalisé, il doit être sur le coté gauche (0), à mi-hauteur (-7).

Pour restorer le pointeur par défaut, il suffit d'appeler la fonction ClearPointer() :

ClearPointer( my_window );

Comme vous aller utiliser des données graphiques, il est important de les placer en mémoire Chip. La mémoire Chip est constituée des 512 premiers ko de mémoire, et les routines graphiques de l'Amiga exigent que les données des sprites, comme toutes les autres données graphiques soient y soient placées. La raison en est que si le processeur de l'Amiga peut adresser les 9 premiers Mo de mémoire, le Blitter (un coprocesseur graphique) lui, n'a accès qu'aux 512 premiers ko).

Il y a un nouveau jeu de circuits ECS pour les Amiga 500 et 2000 qui permet au Blitter, etc., d'accéder au premier Mo, mais sur Amiga OCS, les données doivent être placées dans la mémoire située entre $00000 to $7FFFF.

Si vous utilisez le compilateur Lattice C V5.0 ou plus, c'est très simple. Vous n'avez qu'à mettre le mot "chip" devant les données. Par exemple :

UWORD chip graphics_data[]={ ... };

Sur le compilateur Lattice C V4.0, vous pouvez compiler les sources avec le commitateur "-acdb" qui chargera tout dans la mémoire Chip. Par exemple :

lc -acdb -Lm my_program.c

Ce qui lance lc1 puis lc2, et lie le code avec la bibliothèque mathématique standard. Tout est chargé en mémoire Chip.

Si vous n'avez pas l'un de ces compilateurs C, vous verrez probablement comment faire dans le manuel. Attention ! Si vous n'indiquez pas au compilateur de toujours mettre les données graphiques dans la mémoire Chip, vous allez finir avec d'horribles bogues. Ça pourra parfois marcher si vous n'avez pas d'extension de mémoire, mais ça plantera probablement sur un Amiga avec extension.

2.10 Les fonctions

Voici des fonctions qui sont souvent utilisées avec les fenêtres.

OpenWindow()

Cette fonction ouvre une fenêtre avec les caractéristiques définies dans la structure NewWindow. Elle retourne un pointeur sur la structure Window.

Si vous voulez utiliser l'écran du Workbench, et qu'il a été fermé, il est automatiquement réouvert. Par contre, si vous liez la fenêtre à un écran personnalisé, vous devez l'ouvrir vous-même avant d'appeler la fonction OpenWindow().
  • Synopsis : my_window = OpenWindow( my_new_window );
  • my_window : (struct Window *). Pointeur sur la structure Window ou NULL si la fenêtre n'a pas pu être ouverte.
  • my_new_window : (struct NewWindow *). Pointeur sur la structure NewWindow qui a été initialisée selon vos besoins.
CloseWindow()

Cette fonction ferme une fenêtre que vous avez precédemment ouvert. Rappelez-vous que vous devez fermer toutes les fenêtres liées à un écran avant de pouvoir fermer cet écran, et que toutes les fenêtres ouvertes doivent être fermées avant la fin de vos programmes.
  • Synopsis : CloseWindow( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
MoveWindow()

Cette fonction déplace une fenêtre. Elle a le même effet qu'un déplacement par l'utilisateur avec la barre de déplacement.
  • Synopsis : MoveWindow( my_window, delta_x, delta_y );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • delta_x : (long). Déplacement horizontal.
  • delta_y : (long). Déplacement vertical.
SizeWindow()

Cette fonction modifie la taille de la fenêtre à volonté. Elle a le même effet qu'un redimensionnement par l'utilisateur avec le gadget de redimensionnement.
  • Synopsis : SizeWindow( my_window, delta_x, delta_y );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • delta_x : (long). Nombre de pixels dont la taille horizontale de la fenêtre doit varier.
  • delta_y : (long). Nombre de pixels dont la taille verticale de la fenêtre doit varier.
WindowToFront()

Cette fonction place la fenêtre devant toutes les autres fenêtres.
  • Synopsis : WindowToFront( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
WindowToBack()

Cette fonction place la fenêtre derrière toutes les autres fenêtres.
  • Synopsis : WindowToBack( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
SetWindowTitles()

Cette fonction vous permet de changer le nom d'une fenêtre après qu'elle ait été ouverte.
  • Synopsis : SetWindowTitles( my_window, window_t, screen_t );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • window_t : (char *). Pointeur sur une chaîne terminée par NULL qui va va devenir le nom de la fenêtre, ou 0 (efface la barre de nom) ou encore -1 (garde l'ancien nom).
  • screen_t : (char *). Pointeur sur une chaîne terminée par NULL qui va devenir le nom de l'écran de la fenêtre, ou 0 (efface la barre de nom) ou encore -1 (garde l'ancien nom).
WindowLimits()

Cette fonction change la taille limite maximale/minimale de la fenêtre. Toute valeur fixée à 0 reste inchangée.
  • Synopsis : WindowLimits( my_window, min_w, min_h, max_w, max_h );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • min_w : (long). Largeur minimale de la fenêtre.
  • min_h : (long). Hauteur minimale de la fenêtre.
  • max_w : (long). Largeur maximale de la fenêtre.
  • max_h : (long). Hauteur maximale de la fenêtre.
SetPointer()

Cette fonction vous permet de changer le pointeur d'une fenêtre.
  • Synopsis : Setpointeur( my_window, data, height, width, x, y );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • data : (short *). Pointeur sur les données du sprite.
  • width : (long). La largeur du pointeur. Inférieure ou égale à 16.
  • height : (long). La hauteur du pointeur. Peut être quelconque.
  • x : (long). La position en x du point actif.
  • y : (long). La position en y du point actif.
ClearPointer()

Supprime le pointeur personnalisé (custom), et le remplace par le pointeur par défaut d'Intuition.
  • Synopsis : ClearPointer( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
ReportMouse()

Vous pouvez appeler cette fonction que vous voulez la fenêtre commence/arrête de vous signaler la position de la souris (voir le chapitre 8 - IDCMP pour plus d'informations sur ReportMouse).
  • Synopsis : ReportMouse( my_window, boolean );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
  • boolean : (long) mettez à "TRUE" si vous voulez que la fenêtre commence à signaler la position de la souris, sinon mettez à "FALSE", et la fenêtre arrêtera de signaler la position de la souris.
BeginRefresh()

Cette fonction accélère le rafraîchissement des fenêtres. Vous devez appeler cette fonction avant de commencer à rafraîchir la fenêtre, et seules les parties nécessaires seront redessinées.
  • Synopsis : BeginRefresh( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
EndRefresh()

Cette fonction indique à Intuition que vous avez fini vos rafraîchissements. Attention ! Si vous recevez un message REFRESHWINDOW, vous devez appeler les fonctions BeginRefresh() et EndRefresh(), même si vous ne voulez rien redessiner.
  • Synopsis : EndRefresh( my_window );
  • my_window : (struct Window *). Pointeur sur la structure Window qui a auparavant été initialisée par un appel d'OpenWindow().
2.11 Exemples

Nous avons vu les différents types de fenêtres, comment y lier des gadgets système, la marche à suivre pour personnaliser votre pointeur et plus encore. Il est à présent temps de regarder quelques exemples (dans le répertoire "Amiga_C_Manual/2.Fenetres").

Exemple 1

Ce programme ouvre une fenêtre normale qui est liée à l'écran Workbench. Il l'affiche pendant 30 secondes, et la ferme.

Exemple 2

Ce prgramme ouvre un écran personnalisé haute résolution en 16 couleurs et une fenêtre normale qui lui est liée. Il l'affiche pendant 30 secondes, puis ferme l'écran personnalisé et la fenêtre.

Exemple 3

Ce programme ouvre une fenêtre normale qui est liée à l'écran Workbench. La fenêtre utilise tous les gadgets système, et s'active automatiquement. Il l'affiche pendant 30 secondes, et la ferme. Pensez que le gadget de fermeture ne ferme pas la fenêtre elle-même, il vous informe seulement que l'utilisateur veut la fermer. Mais dans cet exemple, nous ne nous occupons pas de ce qu'il veut.

Exemple 4

Ce programme ouvre deux fenêtres normales qui sont liées à l'écran Workbench. Les fenêtres utilisent tous les gadgets système. Il les affiche pendant 30 secondes, puis les ferme.

Exemple 5

Ce programme ouvre une fenêtre sans bordures qui est liée à l'écran Workbench. Il l'affiche pendant 30 secondes, puis le programme prend fin.

Exemple 6

Comme l'exemple 5 sauf que la fenêtre utilise aussi tous les gadgets système.

Exemple 7

Ce programme ouvre trois fenêtres, deux sont normales et la troisième est une fenêtre d'arrière-plan. Les fenêtres utilisent tous les gadgets systeme sauf la fenêtre d'arrière-plan, qui ne peut utiliser que le gadget de fermeture. Après 30 secondes, le programme prend fin (essayez de passer la fenêtre 1 ou 2 derrière la fenêtre d'arrière-plan).

Exemple 8

Ce programme ouvre une fenêtre SuperBitMap qui est liée à l'écran Workbench. Comme c'est une fenêtre SuperBitMap, nous en faisont aussi une fenêtre Gimmezerozero. La fenêtre utilise tous les gadgets système, et des boites sont dessinées. Il l'affiche pendant 30 secondes, puis la ferme (rétrécissez la fenêtre, puis agrandissez-la, et vous constaterez que les lignes sont toujours là !).

Exemple 9

Ce programme ouvre une fenêtre normale à laquelle sont liés tous les gadgets système. Si vous activez la fenêtre, le pointeur se transforme en une "jolie" flèche.

Exemple 10

Ce programme ouvre deux fenêtres normales auxquelles sont liés tous les gadgets système. Si la première fenêtre est activée, le pointeur se transforme en un symbole "Zzz", si la deuxième fenêtre est activée, le pointeur ressemblera à un pistolet.


[Retour en haut] / [Retour aux articles] [Chapitre précédent : les écrans] / [Chapitre suivant : les graphismes]