Obligement - L'Amiga au maximum

Dimanche 26 septembre 2021 - 14:13  

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


Twitter

Suivez-nous sur Twitter




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

 · Sites de téléchargements
 · Associations
 · Pages Personnelles
 · Matériel
 · Réparateurs
 · Revendeurs
 · Presse et médias
 · Programmation
 · Logiciels
 · Jeux
 · Scène démo
 · Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : Amiga C Manual - IDCMP
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)


Note : traduction par Serge Hammouche.

8. IDCMP

8.1 Introduction

Dans les quatre derniers chapitres, nous avons parlé d'IDCMP mais nous n'avons jamais expliqué en quoi cela consiste. Dans ce chapitre nous vous donnerons plus d'informations. IDCMP signifie "Intuition Direct Communications Message Ports", c'est la manière la plus utilisée pour recevoir des messages d'Intuition et la seule pour communiquer avec elle.

8.2 Les ports IDCMP

Quand quelque chose se passe dans l'Amiga (une disquette est insérée, un gadget sélectionné, etc.), un message est automatiquement créé. Intuition examine les messages et vérifie si cela intéresse votre programme (chaque fenêtre a une liste de drapeaux IDCMP qui disent à Intuition ce qui intéresse cette fenêtre). Si le programme est intéressé par le message, il recevra un message spécial (IntuiMessage) qui contient des informations intéressantes sur le message.

---------------------------   Messages créés dans l'Amiga.
| DISKINSERTED   MENUPICK |   Par exemple, une disquette est insérée,
|    CLOSEWINDOW          |   un menu est activé, une fenêtre
|  NEWSIZE    GADGETDOWN  |   est fermée, etc.
---------------------------
    |   |   |   |   |
    V   V   V   V   V
      -------------           Intuition examine chaque message
      | INTUITION |           et vérifie si cela intéresse un
      -------------           programme.
     /            \
DISKINSERTED   GADGETDOWN     Si le programme A est intéressé
    |              |          par les messages DISKINSERTED,
    V              V          Intuition l'enverra au programme A.
------------- -------------   Si le programme B est intéressé
| PROGRAM A | | PROGRAM B |   par les messages GADGETDOWN, B
------------- -------------   recevra un message chaque fois
                              qu'un gadget est sélectionné dans
                              la fenêtre de B.

                              Tous les messages qui n'intéressent
                              aucun programme seront rejetés.

Intuition commencera toujours par examiner la fenêtre active et beaucoup de messages seront probablement "avalés". Si le programme B est actif et si Intuition a trouvé un message GADGETDOWN, ce message sera passé au programme B, les autres programmes n'en connaitront pas l'existence.

Certains messages sont importants pour tous les programmes, DISKINSERTED par exemple et seront communiqués à toutes les fenêtres intéressées (si le champ IDCMP d'une fenêtre contient le drapeau DISKINSERTED, cette fenêtre est intéressée par ce message).

8.3 Comment recevoir les messages IDCMP

Si vous voulez recevoir des messages d'Intuition vous devez :
  1. Ouvrir un port IDCMP.
  2. Attendre des messages.
  3. Collecter les messages.
  4. Les examiner.
  5. Répondre (dire à Intuition que vous avez lu le message).
8.3.1 Ouvrir un port IDCMP

Le port IDCMP peut être automatiquement attribué par Intuition quand vous ouvrez une fenêtre. Il suffit de spécifier dans le champ IDCMP de la structure NewWindow quels messages vous voulez recevoir d'Intuition et le reste sera fait pour vous. Par exemple, si vous ouvrez une fenêtre avec le champ IDCMP contenant le drapeau GADGETDOWN, un port vous sera attribué et votre programme recevra un message chaque fois qu'un gadget a été sélectionné.

Si vous avez déjà ouvert une fenêtre, vous pouvez ensuite changer les ports IDCMP en appelant la fonction ModifyIDCMP().

8.3.2 Attendre des messages

Une fois qu'un port IDCMP a été ouvert, votre programme devra attendre qu'un (ou plusieurs) message arrive. Il y a deux façons d'attendre des messages :
  • De façon passive. Votre programme est arrêté et ne se réveillera qu'à l'arrivée du message. Ceci augmentera la vitesse des autres applications puisque le processeur ne s'occupe pas de votre programme tant qu'il "dort". Utilisez la fonction Wait().

  • La façon active. Votre programme essaie de collecter un message, s'il n'en trouve pas, il recommence. Ceci est nécessaire si vous voulez que votre programme reste actif et ne s'arrête pas pour attendre l'arrivée d'un message.
8.3.3 Collecter des messages

Quand vous collectez un message, vous devez utiliser la fonction GetMsg(). Celle-ci renverra un pointeur à une structure IntuiMessage qui contient toutes les informations intéressantes sur le message ou NULL s'il n'a pu collecter de message.

8.3.4 Examiner le message

Une fois le message collecté vous pouvez examiner la structure IntuiMessage. Elle ressemble à ceci :

struct IntuiMessage
{
  struct Message ExecMessage;
  ULONG Class;
  USHORT Code;
  USHORT Qualifier;
  APTR IAddress;
  SHORT MouseX, MouseY;
  ULONG Seconds, Micros;
  struct Window *IDCMPWindow;
  struct IntuiMessage *SpecialLink;
};
  • ExecMessage : utilisé par Exec, ne pas y toucher.
  • Class : contient le drapeau IDCMP.
  • Code : contient certaines valeurs spéciales relatives au drapeau IDCMP (Class). Par exemple, si vous recevez un message MENUVERIFY vous pouvez examiner le champ Code pour voir si c'est le menu de votre programme (Code == MENUHOT) ou le menu d'un autre programme (Code == MENUWAITING) qui sera affiché. Si vous recevez un message RAWKEY ou VANILLAKEY le champ Code contiendra le code clé.
  • Qualifier : si votre programme reçoit des messages RAWKEY (keycodes non traduits), ce champ contiendra des informations qui déterminent si les touches "Shift" ou "Ctrl" ont été pressées ou pas (une copie du ie_Qualifier).
  • IAddress : pointeur sur l'objet qui a créé le message. Par exemple, si vous recevez un message GADGETDOWN, ce champ contiendra un pointeur sur le gadget qui a été sélectionné.
  • MouseX : position en X du pointeur par rapport au coin supérieur gauche de votre fenêtre.
  • MouseY : position en Y du pointeur par rapport au coin supérieur gauche de votre fenêtre.
  • Seconds : copie des secondes de l'horloge du système.
  • Micros : copie des microsecondes de l'horloge du système.
  • IDCMPWindow : pointeur sur la fenêtre qui a envoyé ce message.
  • SpecialLink : utilisé par Exec et Intuition alors n'y touchez pas.
La meilleure façon d'examiner cette structure est de copier toutes les valeurs importantes et de répondre aussi vite que possible (Intuition sera ralenti si vous tardez à répondre). Vous pouvez alors, après avoir répondu, vérifier les valeurs copiées. Attention : ne pas utiliser la structure IntuiMessage une fois que vous avez répondu.

8.3.5 Reply

Une fois que votre programme a lu tout ce qui l'intéresse, il doit répondre à Intuition par la fonction ReplyMsg(). Cela signale à Intuition que vous avez fini de lire le message.

Important : après avoir répondu, vous ne pouvez pas examiner ou changer la structure IntuiMessage. Un autre programme ou Intuition peut l'utiliser !

8.3.6 Exemple

Voici un exemple de la façon dont votre programme doit collecter et exécuter les messages IDCMP (façon passive) :

/* 1. Attendre qu'un message arrive */
Wait( 1 << my_window->UserPort->mp_SigBit );

/* my_Window est un pointeur sur une fenêtre */
/* Ne vous occupez pas des formules bizarres */

/* 2. Essayer de collecter un message */
my_message = GetMsg( my_window->UserPort );

/* Pouvons-nous collecter un message ? (si message == NULL */
/* nous n'avons pas collecté de message)                   */
if( my_message )
{
  /* OUI ! Nous avons réussi à collecter un message. */

  /* 3. Nous devons maintenant examiner la structure          */
  /*    IntuiMessage et sauver toutes les valeurs importantes.*/
  /*    (Si nous sauvons l'information nous pouvons répondre  */
  /*    dès que possible et ensuite examiner les valeurs)     */
  class   = my_message->Class;
  code    = my_message->Code;
  address = my_message->IAddress;

  /* 4. Nous devons répondre puisque nous avons fini de lire  */
  /*    la structure IntuiMessage (votre programme doit       */
  /*    répondre le plus vite possible)                       */
  ReplyMsg( my_message );

  /* 5. Nous pouvons maintenant regarder en quoi consistait  */
  /*    le message : (nous avons répondu, donc nous ne       */
  /*    pouvons plus examiner la structure IntuiMessage,     */
  /*    mais nous pouvons vérifier les variables : class,    */
  /*    code and address) 
  switch( class )
  {
    case GADGETDOWN: /* Un gadget a été pressé.               */
    case GADGETUP:   /* Un gadget a été relâché.              */
    case MENUPICK:   /* Un élément du menu a été sélectionné. */
    /* ainsi de suite...                                      */
  }
}

Cet exemple est bien beau mais que ce passe-t-il si deux messages arrivent en même temps ? Eh bien le premier message sera traité normalement mais le second message ne sera jamais traité.

Après avoir attendu un message, nous devons en fait nous préparer à traiter de nombreux messages. Nous devons donc utiliser une boucle "while" et rester dans la boucle tant que nous pouvons collecter des messages avec succès. Une fois que nous ne pouvons plus en collecter, nous devons remettre notre tâche au repos. Voici une version modifiée et améliorée :

/* 1. Attendre un message: */
Wait( 1 << my_window->UserPort->mp_SigBit );

/* Tant que nous pouvons collecter des messages, nous restons */
/* dans la boucle while : */
while( my_message = GetMsg( my_window->UserPort ) )
{
  /* La suite ne change pas... */

  /* 3. Nous devons maintenant examiner la structure IntuiMessage, */
  /*    et sauver les valeurs importantes (si nous sauvons les     */
  /*    informations nous pouvons répondre le plus rapidement      */
  /*    possible et ensuite examiner ces valeurs)                  */
  class   = my_message->Class;
  code    = my_message->Code;
  address = my_message->IAddress;

  /* 4. Nous devons maintenant répondre puisque nous avons fini de */
  /*    lire la structure IntuiMesage (votre programme doit        */
  /*    toujours répondre le plus vite possible)                   */
  ReplyMsg( my_message );

  /* 5. Nous pouvons maintenant examiner de plus près en quoi      */
  /*    consistait le message (nous avons répondu donc nous ne     */
  /*    pouvons pas examiner la structure IntuiMessage mais nous   */
  /*    pouvons bien sûr vérifier les variables : class, code et   */
  /*    address)                                                   */
  switch( class )
  {
    case GADGETDOWN: /* Un gadget a été pressé.              */
    case GADGETUP:   /* Un gadget a été relâché.             */
    case MENUPICK:   /* Un élément du menu a été sélectionné */
    /* Et ainsi de suite...                                  */
  }
}

8.4 Drapeaux IDCMP

Nous avons utilisé plusieurs drapeaux IDCMP dans le dernier chapitre, tels que GADGETDOWN, MENUPICK, REQVERIFY, etc., mais voici la liste de tous les drapeaux.
D'abord les trois drapeaux qui sont en étroite relation avec les gadgets :
  • GADGETDOWN : Votre programme recevra ce message si un gadget a été sélectionné (notez que le gadget doit avoir le drapeau GADGIMMEDIATE réglé sur son champ d'activation. Sinon, aucun message GADGETDOWN ne sera créé).
  • GADGETUP : votre programme recevra ce message si un gadget a été relâché (notez que le gadget doit avoir le drapeau RELVERIFY réglé sur son champ d'activation. Sinon, aucun message GADGETUP ne sera créé).
  • CLOSEWINDOW : votre programme recevra ce message si l'utilisateur choisit le gadget Close Window (gadget système). Attention, la fenêtre ne sera pas automatiquement fermée. C'est à votre programme de décider s'il veut la fermer.
Voici les trois drapeaux IDCMP qui sont étroitement liés aux requêtes :
  • REQSET : votre programme recevra ce message si une requête a été ouverte dans votre fenêtre. Ceci est une bonne façon de détecter si une requête double-menu a été activée dans votre fenêtre (vous recevrez un message à la fois pour une requête double-menu et une requête normale).
  • REQCLEAR : ce message signifie qu'une requête a été effacée de votre fenêtre. Vous ne recevrez ce message que lorsque toutes les requêtes auront été effacées de votre fenêtre.
  • REQVERIFY : votre programme recevra ce message si une requête va être activée. Cependant, la requête sera d'abord affichée après que vous ayez répondu, cela vous permettra de terminer autre chose avant l'activation de la requête. Votre programme ne recevra ce message que lorsque la première requête aura été ouverte dans la fenêtre. Intuition supposera alors que vous avez cessé toute sortie vers cette fenêtre.
Voici les deux drapeaux IDCMP étroitement liés aux menus :
  • MENUPICK : votre programme recevra ce message si l'utilisateur a appuyé sur le bouton droit de la souris (notez que ceci ne veut pas forcément dire qu'un élément a été sélectionné). Le champ Code du message contiendra le numéro du menu. Si aucun élément n'a été sélectionné, Code vaudra MENUNULL. Utilisez les macros décrites au chapitre 7 - Menus pour vérifier quel menu/élément/sous-élément a été sélectionné.
  • MENUVERIFY : votre programme recevra ce message si un menu va être activé. Le menu sera cependant d'abord affiché après votre réponse, vous permettant d'achever quelque chose avant l'ouverture du menu.

    Vérifiez si le champ Code du message vaut MENUHOT, ce qui veut dire que votre menu va être affiché, ou MENUWAITING, qui veut dire que la barre de menu d'une autre fenêtre sera affichée. Vous pouvez même annuler toute l'opération menu si vous le désirez, en mettant le champ Code sur MENUCANCEL avant votre réponse.
Voici les trois drapeaux IDCMP qui sont étroitement liés à la souris :
  • MOUSEBUTTONS : votre programme recevra ce message si n'importe quel des boutons de la souris a été enfoncé ou relâché. Examiner le champ Code du message pour voir s'il vaut :
    • SELECTDOWN : le bouton gauche de la souris a été enfoncé.
    • SELECTUP : le bouton gauche de la souris a été relâché.
    • MENUDOWN : le bouton droit de la souris a été enfoncé.
    • MENUUP : le bouton droit de la souris a été relâché.

      Important : si l'utilisateur enfonce le bouton gauche de la souris pendant que le pointeur est quelque part sur une boîte de sélection d'un gadget, votre programme ne recevra aucun message. Rappelez-vous que si l'utilisateur enfonce le bouton droit de la souris une barre de menu est affichée et votre programme ne recevra pas de message MENUDOWN. Vous devez mettre le drapeau RMBTRAP dans la structure NewWindow afin de recevoir tout évènement en provenance du bouton droit de la souris (aucun menu ne peut alors être utilisé pour cette fenêtre).

  • MOUSEMOVE : votre programme recevra ce message si la souris a été déplacée. Notez que votre fenêtre devra avoir le drapeau REPORTMOUSE dans le champ correspondant de la structure NewWindow ; ou alors un gadget de la fenêtre devra avoir le drapeau FOLLOWMOUSE dans le champ correspondant de sa structure (attendez-vous à recevoir de nombreux messages !).
  • DELTAMOVE : identique à MOUSEMOVE à part que les mouvements seront rapportés sous forme de différences entre deux mouvements consécutifs ("mouvements delta") au lieu de coordonnées absolues. Notez que votre programme continuera de recevoir des mouvements delta même si le pointeur a atteint le bord de l'affichage (attendez-vous à recevoir de nombreux messages !).
Voici les cinq drapeaux IDCMP qui sont étroitement liés aux fenêtres :
  • NEWSIZE : votre programme recevra ce message si l'utilisateur a redimensionné la fenêtre. Vérifiez les champs de hauteur et de largeur de la structure Window de votre fenêtre pour connaître les nouvelles dimensions.
  • SIZEVERIFY : votre programme recevra ce message si l'utilisateur essaie de redimensionner la fenêtre. Cependant, Intuition changera d'abord les dimensions quand votre programme aura répondu, ce qui vous permet de finir ce que vous avez en cours avant que la fenêtre ne change de dimension.
  • REFRESHWINDOW : votre programme recevra ce message si la fenêtre doit être redessinée. Ceci ne s'applique qu'aux fenêtres SIMPLE_REFRESH et SMART_REFRESH. Souvenez-vous que si vous recevez un événement REFRESHWINDOW vous devez appeler les fonctions BeginRefresh() et EndRefresh() même si vous ne redessinez rien.
  • ACTIVEWINDOW : votre programme recevra ce message si votre fenêtre est activée.
  • INACTIVEWINDOW : votre programme recevra ce message si votre fenêtre est désactivée.
Les autres drapeaux IDCMP :
  • RAWKEY : votre programme recevra ce message chaque fois que l'utilisateur enfonce une touche. Le champ Code du message contiendra les codes clés bruts ("raw keycodes") (voir annexe C) et le champ Qualifier du message contiendra le qualificateur (Shift, Ctrl, etc.).
  • VANILLAKEY : votre programme recevra ce message chaque fois que l'utilisateur enfoncera une touche. Le champ Code du message contiendra le caractère ASCII (voir annexe D).
  • DISKINSERTED : votre programme recevra ce message si une disquette est insérée. Tous les programmes intéressés le sauront.
  • DISKREMOVED : votre programme recevra ce message si une disquette est retirée. Tous les programmes intéressés le sauront.
  • NEWPREFS : si les préférences système sont modifiées (par l'utilisateur ou par un programme), votre programme recevra un message NEWPREFS. Appeler la fonction GetPrefs() pour avoir les nouvelles préférences système (voir le chapitre 9 - Divers pour plus d'informations sur les préférences).
  • INTUITICKS : votre programme recevra ce message dix fois par seconde (environ). Cependant, si vous n'avez pas répondu au premier message INTUITICKS, le prochain message ne sera pas envoyé.
  • WBENCHMESSAGE : si le Workbench est ouvert ou fermé par un programme (en appelant les fonctions OpenWorkbench()/CloseWorkbench()), votre programme recevra un message WBENCHMESSAGE. Le champ Code du message vaudra WBENCHOPEN si le Workbench était ouvert ou WBCLOSE s'il était fermé.
8.5 Fonctions

GetMsg()

Cette fonction essaie d'obtenir un message d'un "message port".
  • Synopsis : my_message = GetMsg( my_message_port );
  • my_message : (struct Message *). Pointeur sur une structure Message, dans le cas présent un pointeur sur une structure IntuiMessage ou NULL si aucun message n'a été collecté.
  • my_message_port : (struct MsgPort *). Pointeur sur un MsgPort. Si vous avez ouvert une fenêtre, vous pouvez trouver le port du message de votre fenêtre dans la structure Window (my_window->UserPort).
ReplyMsg()

Cette fonction dit à Intuition que vous avez fini de lire le message. Souvenez-vous que vous ne pouvez plus examiner ou modifier la structure IntuiMessage une fois que vous avez répondu.
  • Synopsis : ReplyMsg( my_message );
  • my_message : (struct Message *). Pointeur sur une structure Message, dans le cas présent, un pointeur vers une structure IntuiMessage.
ModifyIDCMP()

Cette fonction change les champs IDCMP de la structure Window.
  • Synopsis : ModifyIDCMP( my_window, IDCMPFlags );
  • my_window : (struct Window *). Pointeur sur une fenêtre déjà ouverte.
  • IDCMPFlags : (long). Aucun ou plus de drapeaux IDCMP.
Si vous appelez cette fonction sans que les drapeaux IDCMP soient en place, les ports IDCMP de la fenêtre seront fermés. Par contre, si vous appelez cette fonction avec au moins un drapeau en place, un port vous sera ouvert, si nécessaire.

8.6 Exemples

Voir les exemples dans le chapitre 4 - Gadgets, chapitre 5 - Requêtes, chapitre 6 - Alertes et chapitre 7 - Menus. Ils vous expliqueront comment se servir des drapeaux IDCMP suivants : GADGETDOWN, GADGETUP, CLOSEWINDOW, REQSET, REQCLEAR, REQVERIFY, MENUPICK et MENUVERIFY.

Voici des exemples (dans le répertoire "Amiga_C_Manual/8.IDCMP") avec des IDCMP :

Exemple 1

Ce programme explique comment se servir du drapeau IDCMP MOUSEBUTTONS.

Exemple 2

Ce programme explique comment se servir du drapeau IDCMP MOUSEMOVE.

Exemple 3

Ce programme explique comment se servir des drapeaux IDCMP suivants : NEWSIZE, ACTIVEWINDOW et INACTIVEWINDOW.

Exemple 4

Ce programme explique comment se servir du drapeau IDCMP SIZEVERIFY.

Exemple 5

Ce programme explique comment se servir du drapeau IDCMP RAWKEY.

Exemple 6

Ce programme explique comment se servir du drapeau IDCMP VANILLAKEY.

Exemple 7

Ce programme explique comment se servir des drapeaux IDCMP suivants : DISKINSERTED et DISKREMOVED.

Exemple 8

Ce programme explique comment se servir du drapeau IDCMP INTUITICKS.

Exemple 9

Ce programme explique comment se servir du drapeau IDCMP REFRESHWINDOW et comment redessiner d'une façon optimale la fenêtre.


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