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 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 :
- Ouvrir un port IDCMP.
- Attendre des messages.
- Collecter les messages.
- Les examiner.
- 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.
|