Delphi est un tout nouvel outil de développement de programmation WINDOWS fourni par Borland. Parce qu'il utilise le langage Pascal orienté objet (pascal orienté objet) flexible et réutilisable et dispose d'un puissant moteur de base de données (BDE), d'un code rapide, le compilateur fournit également de nombreux excellents. composants. Il est favorisé par la majorité des programmeurs. Il se démarque parmi de nombreux langages de programmation (tels que VB, PowerBuilder, Powerpoint, etc.).
L'un des avantages de DELPHI par rapport aux autres langages de programmation (tels que VB4.0) est que les messages peuvent être personnalisés dans DELPHI et traités directement. Ceci est pour ceux qui souhaitent écrire leurs propres composants (Component), ou qui souhaitent intercepter et filtrer les messages. C'est essentiel pour les utilisateurs, car l'écriture de composants nécessite généralement le traitement des messages correspondants. Ce qui suit est une introduction au mécanisme de traitement des messages dans Delphi.
1. Remise des messages dans DELPHI VCL
Chaque composant VCL (Visual Component Library) (tel que Tbutton, Tedit, etc.) dans Delphi possède un mécanisme de traitement de message inhérent. Le point fondamental est que la classe de composant reçoit certains messages et les envoie à la méthode de traitement appropriée, le cas échéant. Aucune méthode de traitement spécifique, le handle de traitement des messages par défaut est appelé. Parmi eux, mainwndPRoc est une méthode statique définie dans la classe Twincontrol et ne peut pas être surchargée (Override). Il ne traite pas le message directement, mais laisse le traitement à la méthode wndproc et fournit un module de gestion des exceptions pour la méthode wndproc. La méthode Mainwndproc est déclarée comme suit :
procédure MainWndProc(var Message : TMessage);
Wndproc est une méthode virtuelle définie dans la classe Tcontrol, qui appelle la méthode dispatch pour distribuer les messages. La méthode wndproc est déclarée comme suit :
procédure WndProc(var Message : TMessage); virtuel ;
La méthode de répartition est définie dans la classe racine Tobject et est déclarée comme suit :
procédure Tobject.dispatch(var Message); Le paramètre de message passé à dispatch doit être un type d'enregistrement, et le premier point d'entrée dans cet enregistrement doit être un champ de type cardinal (champ), qui contient le message du message à distribuer. . Par exemple:
taper
Tmessage=enregistrement
Message : cardinal ;
wparam : Mot ;
lparam:entier long;
résultat : entier long ;
fin;
La méthode Dispatch appellera la méthode handle de la classe de dernière génération du composant qui gère ce message en fonction du numéro de message. S'il n'y a pas de gestionnaire correspondant à ce message dans ce composant et sa classe ancêtre, la méthode Dispatch appellera le Defaulthandler. méthode. La méthode Defaulthandler est La méthode virtuelle définie dans Tobject est déclarée comme suit :
procédure Defaulthandler(var Message);virtuel;
La méthode Defaulthandler de la classe Tobject implémente uniquement un simple retour sans aucun traitement du message. Nous pouvons implémenter le traitement par défaut du message dans la sous-classe en surchargeant cette méthode virtuelle pour les composants de la VCL, sa méthode Defaulthandler démarrera les fenêtres. Fonction API Defwindowproc pour traiter le message.
2. Poignée de traitement des messages dans DELPHI
Dans DELPHI, les utilisateurs peuvent personnaliser les messages et les handles de traitement des messages. La définition des handles de traitement des messages repose sur les principes suivants :
La méthode handle de traitement des messages doit être une procédure et ne peut transmettre qu'un seul paramètre de variable de type Tmessage.
La déclaration de méthode doit être suivie d'une commande de message, suivie d'un label de message (constante entière) compris entre 0 et 32767.
La méthode du gestionnaire de messages n'a pas besoin d'utiliser la commande override pour indiquer explicitement le remplacement d'un gestionnaire de messages de l'ancêtre. De plus, elle est généralement déclarée dans la zone protégée ou privée du composant.
Dans le handle de traitement du message, l'utilisateur traite généralement le message en premier, et utilise enfin la commande héritée pour appeler le handle de traitement correspondant à ce message dans la classe ancêtre (dans certains cas, cela peut être l'inverse car le handle de traitement de). ce message dans la classe ancêtre peut être Le nom et le type de paramètre ne sont pas clairs, et l'appel de la commande héritée peut éviter ce problème. De même, s'il n'y a pas de gestionnaire correspondant à ce message dans la classe ancêtre, hérité appellera automatiquement la méthode Defaulthandler. (Bien sûr, si vous souhaitez bloquer ce message, Il n'est pas nécessaire d'utiliser la commande héritée).
La méthode du gestionnaire de messages est déclarée comme suit :
procédure Mymsgmethod(var message:Tmessage); message Msgtype;
De même, les utilisateurs peuvent également définir leurs propres messages. Les messages définis par l'utilisateur doivent commencer par WM_USER.
Des exemples de messages personnalisés et de handles de traitement de messages sont les suivants :
const mon_paint=Wm_user+1;
taper
Tmypaint=enregistrement
msgstr:cardinal;
msize:mot;
mcolor: entier long;
msgresult: entier long ;
fin;
taper
Tmycontrol=class(TCustomControl)
protégé
changement de procédure (var message:Tmypaint); message my_paint;
.....
fin;
...
procédure Tmycontrol.change(var message:Tmypaint);
commencer
size:=message.msize; {Définir l'attribut de taille Tmybutton}
color:=message.mcolor; {Définir l'attribut de couleur Tmybutton}
{faire autre chose}
hérité ; {Remis à Tcustomcontrol}
fin;
3. Filtrer les messages
Le filtrage des messages est également appelé piège à messages. Dans certaines circonstances, les utilisateurs peuvent avoir besoin de bloquer certains messages ou d'intercepter certains messages à des fins de traitement. D'après l'introduction ci-dessus, nous pouvons voir qu'il existe généralement trois façons de filtrer les messages : (1). Surcharger la méthode virtuelle wndproc héritée par le composant (2). Surcharger la méthode virtuelle Defhandler héritée du composant, où les messages sont traités. La méthode la plus couramment utilisée est la méthode (2), qui a été présentée dans la section précédente. La méthode (1) est similaire à la méthode (3). Nous ne présentons ici que brièvement la méthode (1).
Le processus général de surcharge de la méthode virtuelle wndproc est le suivant :
procédure Tmyobject.wndproc(var message:Tmessage);
commencer
{... Déterminez si ce message doit être traité..}
wndproc hérité (message);
{Les messages non traités sont gérés par la méthode wndproc parent}
fin;
On peut en déduire que l'avantage du traitement des messages dans la méthode wndproc est qu'elle peut filtrer toute la plage des messages sans avoir à spécifier un handle de traitement pour chaque message. En fait, il est utilisé dans le composant Tcontrol pour filtrer et. traiter tous les messages de la souris (de WM_mousefirst à WM_mouselast, comme indiqué dans le code suivant). Il peut également être utilisé pour empêcher l'envoi de certains messages au gestionnaire.
procédure TControl.WndProc(var Message : TMessage);
commencer
si (Message.Msg>=WM_MOUSEFIRST) et
(Message.Msg <= WM_MOUSELAST)
alors
si vous faites glisser, alors {Gérer l'événement de glisser}
DragMouseMsg(TWMMouse(Message))
autre
... {gérer les autres messages de la souris}
fin;
Expédition (Message);
{Sinon, envoyez le message normalement}
fin;
L'exemple suivant est un exemple simple de composant personnalisé :
La classe Tmyedit est une nouvelle classe dérivée de la classe Tedit. Sa caractéristique est qu'elle ne peut pas obtenir le focus pendant le fonctionnement et ne peut pas être saisie par le clavier (un peu similaire au composant Tlabel. Nous pouvons filtrer les messages WM_setfocus et WM_mousemove dans son contenu). Méthode wndproc et exécution Pour répondre aux exigences ci-dessus, le programme source est le suivant :
unité monédition ;
interface
utilise
Windows, messages, SysUtils, classes, graphiques,
Contrôles, formulaires, boîtes de dialogue,
StdCtrl ;
taper
Tmyedit = classe (TEdit)
privé
{Déclarations privées}
protégé
{ Déclarations protégées }
{ autres champs et méthodes}
procédure wndproc(var message:Tmessage);override;
publique
{Déclarations publiques}
publié
{ Déclarations publiées }
fin;
registre de procédure ;
mise en œuvre
registre de procédure ;
commencer
RegisterComponents('Échantillons', [Tmyedit]);
fin;
procédure Tmyedit.wndproc(var message:tmessage);
commencer
si message.msg=wm_mousemove alors
commencer
curseur:=crarrow;
{Définissez le curseur sur crarrow au lieu du curseur crBeam par défaut}
sortie;
fin;
si message.msg=wm_SetFocus alors quittez ;
{Protégez le message WM_setfocus et empêchez le contrôle Tmyedit d'obtenir le focus d'entrée}
wndproc hérité (message);
{D'autres messages sont transmis au wndproc parent pour traitement}
fin;
fin.
Vous pouvez ajouter Tmyedit à la palette de composants pour tester ses performances.
Comme le montre l'introduction ci-dessus, ce n'est qu'en comprenant le mécanisme de traitement des messages dans Delphi VCL, en maîtrisant les méthodes et le timing de traitement de divers messages (en utilisant divers outils si nécessaire, tels que winsight32, spy, etc.), et en combinant les caractéristiques du langage POO, nous pouvons compiler des composants de haute qualité. Bien entendu, cela nécessite que les lecteurs explorent et accumulent constamment de l’expérience dans la pratique.