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 E - petit utilitaire
(Article écrit par Pierre Girard et extrait d'Amiga News - janvier 1998)
|
|
Après l'article théorique du mois de novembre, nous allons passer à du concret en programmant
un petit utilitaire. Celui-ci aura pour fonction de fermer une fenêtre, quelle qu'elle soit, mais en particulier une fenêtre
Workbench.
Le but du jeu est bien sûr d'éviter le plus possible de se fatiguer en évitant de cliquer sur le gadget de fermeture de cette
fenêtre (et en plus, c'est plus rapide !). Bien sûr, l'intérêt en programmation pure est relativement restreint. Cependant,
ce petit programme va nous permettre de mettre le nez dans les structures intéressantes de l'Amiga.
Préambule
Avez-vous déjà essayé de fermer une fenêtre du Workbench en utilisant par exemple moniteur temps réel ? Si votre réponse est oui,
vous avez sans doute constaté que votre adoré Amiga plante lamentablement. Si votre réponse est non, relisez la phrase précédente.
Mais pourquoi tant de haine ? Parce qu'on ne peut pas fermer impunément une fenêtre du système qui communique avec la tâche qui
lui est associée (surtout qu'ici c'est le Workbench) ou attend des ordres de votre part (redimensionnement, fermeture...).
La solution
En fait, il en existe deux. On peut chercher l'adresse de la fenêtre et faire un CloseWindow(). Cependant, cette méthode oblige
le programmeur à faire beaucoup d'initialisations et surtout de veiller à ce que le système reste stable. Pour cela, il faut
notamment vider le port de message de la fenêtre, s'assurer qu'aucun menu n'est attaché, etc.
Cette méthode a comme inconvénient de plus faire partie de la bidouille que de la programmation système. Nous en utiliserons
donc une autre qui consiste à envoyer un message à la fenêtre en lui signifiant qu'il est temps qu'elle se ferme. Le système
fait alors comme si on avait réellement cliqué sur le gadget de fermeture et se charge lui-même des travaux ingrats.
Ferme_Fenetre
Nous allons maintenant étudier le petit programme de ce mois-ci que nous nommerons CloseWBWindow. Les déclarations concernent
la création d'un port de message afin de communiquer avec celui de la fenêtre, et la définition d'un message Intuition. La
première chose à faire est de déterminer quelle fenêtre est ouverte et de récupérer son adresse. Cela est d'une facilité
déconcertante. Allons fouiller dans la structure intuitionbase (dont l'adresse est automatiquement stockée en E dans
"intuitionbase"). L'adresse de la fenêtre active se trouve dans le champ activewindow. Profitons-en pour initialiser winuserport
avec l'adresse du port utilisateur de cette fenêtre.
Ensuite, nous créons un port de message personnel afin de pouvoir communiquer avec notre cible.
On ferme
Bon, bon. Tout est prêt pour fermer notre fenêtre. Il suffit maintenant de préparer un message Intuition (intuimessage) avant
de l'envoyer. Dans la procédure closewin(thiswindow), nous commençons par allouer la mémoire nécessaire à un intuimessage.
Ensuite, nous définissons dans l'ordre : le port de message de réponse (replymsgport qui est notre port personnel), la longueur
du message à envoyer, et la classe du message (en fait, l'action associée au message qui est ici IDCMP_CLOSEWINDOW). Et hop,
on envoie le tout grâce à un petit PutMsg(portmessage).
Il ne reste plus qu'à s'assurer que tout s'est bien passé en vérifiant qu'il y a bien un message de retour, et comme on ne
veut pas prendre le risque qu'il y ait plusieurs réponses (krash assuré), on met le tout dans une boucle. Reste à mettre un
peu d'ordre afin de libérer toute la mémoire (et éviter tout plantage).
Critique
Comme je ne suis pas parfait (loin de là) et que je viens de relire entièrement ce programme (je sais, c'est un peu tard, vu
que c'est la fin de l'article), je vais faire mon autocritique. Il eut été plus subtil d'éviter les variables globales et de
faire une procédure closewin() avec des arguments, dans le style closewin(win,sendport,replyport). L'avantage est évident :
c'est que cette routine pourrait être utilisable dans n'importe quel programme. C'est une sorte de programmation orientée objet.
Les seules choses fixes sont les arguments et on peut retoucher n'importe quoi dans le programme tant que l'on conserve ces
trois arguments en entrée. Je vous laisse méditer là-dessus et je commence ma conclusion.
Idée initiale
Quand j'ai commencé ce programme (qui est ridiculement court, je vous l'accorde), j'avais dans l'idée de faire un utilitaire
pour fermer toutes les fenêtres "parent" d'un coup. J'ai malheureusement découvert que cela avait déjà été fait, comme toutes
les bonnes idées que j'ai, en général ;)). À propos, pour utiliser ce programme en l'état, il n'y a qu'une seule solution :
l'assigner à une touche grâce à un utilitaire. En effet, il tente de fermer la fenêtre active, alors inutile d'essayer du
Shell. Joyeux Noël à tous.
PS : Amiga E 3.3 est arrivé sur Aminet !
|