Fermer Gérer les messages Windows

GERER LES MESSAGES WINDOWS

Dernière mise à jour : 29/01/00

Pourquoi les messages ?

Les messages sont directement liés au phénomène de programmation événementielle :

Pour certaines actions, Windows génère un message. Il peut alors être récupéré par le programme qui peut ainsi réagir à cet événement.

Par exemple : vous appuyez sur le bouton gauche de la souris et un message WM_LBUTTONDOWN est automatiquement envoyé par Windows. Votre application peut être avertie de cette action de plusieurs façons.

Notamment par les événements OnMouseDown qui sont déclenchés automatiquement lorsque ce message est intercepté par votre application.

La programmation événementielle est donc un subtil mélange de génération de messages et réactions face à ces messages.

 

Principe de fonctionnement

A toute action possible sous Windows est associé un message. Ce message possède une "constante de message" qui permet de l'identifier. D'autres paramètres sont également associés au message qui permettent par exemple de récupérer la position de la souris au moment d'un click.

Structure générale d'un message tel que défini dans l'API Windows :

TMSG = record
  hwnd :HWnd; {fenêtre destinataire}
  message:word;{constante du message permet d'identifier le message}
  wParam:word; {paramètre codé sur un mot}
  lParam : LongInt; {paramètre codé sur un entier long}
  time : Longint; {heure de la création du message}
  pt:TPoint; {position de la souris en coordonnées écran à la création du message}
end;

Que se passe-t-il lors de l'émission d'un message ?

  • Un événement survient (cliquer sur un bouton de la souris, appuyer sur une touche..)

  • Cet événement est traduit par Windows sous forme d'un message de type TMSG. Windows génère un ou PLUSIEURS messages selon les cas. Par exemple dans le cas de l'appui sur une touche, Windows envoie des WM_KEYDOWN et un WM_KEYUP quand on relâche la touche (touche non système).

  • La plupart des messages sont alors placés dans la file d'attente des messages de l'application. Certains messages sont envoyés par Windows directement à WndProc par exemple WM_WINDOWPOSCHANGED (et en général tous les messages qui affectent l'état ou l'aspect d'une fenêtre). Dans une application multithread il y a une file par thread (si celui-ci gère une interface utilisateur). La file d'attente est de type FIFO (premier entré/premier sorti).

  • L'application scrute en permanence cette file d'attente et agit en fonction du message qu'elle peut capter de différentes manières. Ayant capté le message de type TMSG, elle a accès à tous les paramètres et donc aux renseignements la concernant.

 

Concrètement : la réception des messages sous Delphi

Le message transite par les différentes routines suivantes:

(On notera que le paramètre Message est de type TMessage. En effet, Delphi utilise un type simplifié en remplacement du type TMSG).

  1. L'application reçoit le message puis le transmet à la routine associée à la fenêtre du destinataire; {s'il est défini, déclenchement de l'événement Application.OnMessage. A ce stade, tous les messages de l'application qui ont étés envoyés dans la file d'attente sont concernés. Les messages envoyés par SendMessage ne passent pas par la file d'attente et ne déclenche donc pas Application.OnMessage}Pour plus de détails et un exemple d'utilisation de Application.OnMessage

  2. MainWinWndProc(var Message:TMessage); {routine associée à la fenêtre du destinataire. Pas de traitement spécifique, redirige le message vers WinProc. A ce stade, seuls transitent les messages concernant la fenêtre destinataire}

  3. WindProc(var Message:TMessage) ; virtual; {peut être surchargé pour créer des actions spécifiques en fonction du message et peut intercepter le message c'est à dire en arrêter la diffusion}Pour plus de détails et un exemple d'utilisation de WindProc

  4. Dispatch(var Message : TMessage); {chargée d'appeler le bon gestionnaire traitant ce message précis}

  5. Procédure de message liée à l'événement {à ce stade, on est dans une procédure correspondant au message lui même et non à tous les messages}Pour plus de détails et un exemple d'utilisation

  6. Gestionnaire d'événement. {par exemple OnKeyDown}

 

Description du Type TMessage :

type 
  TMessage = record
    Msg: Cardinal;
    case Integer of
    0: (
      WParam: Longint;
      LParam: Longint;
      Result: Longint);
    1: (
      WParamLo: Word;
      WParamHi: Word;
      LParamLo: Word;
      LParamHi: Word;
      ResultLo: Word;
      ResultHi: Word);
  end;

Delphi propose également des types d'enregistrements qui permettent de récupérer directement sans transtypages les paramètres des messages. Vous trouverez ces types dans le source de l'unité message (message.pas) (pour ceux qui l'ont !)

Voir Utilisation des types d'enregistrements permettant de récupérer directement les paramètres des messages.

 

retour au sommaire