Delphi ist ein brandneues WINDOWS-Programmierentwicklungstool von Borland. Da es die flexible und wiederverwendbare objektorientierte Pascal-Sprache (objektorientiertes Pascal) verwendet und über eine leistungsstarke Datenbank-Engine (BDE) verfügt, bietet der Compiler auch viele hervorragende Funktionen Komponenten werden von den meisten Programmierern bevorzugt (wie VB, PowerBuilder, Powerpoint usw.).
Einer der Vorteile von DELPHI gegenüber anderen Programmiersprachen (wie VB4.0) besteht darin, dass Nachrichten in DELPHI angepasst und direkt verarbeitet werden können. Dies ist für diejenigen geeignet, die ihre eigenen Komponenten (Component) schreiben möchten. , oder die Nachrichten abfangen und filtern möchten. Da das Schreiben von Komponenten im Allgemeinen die Verarbeitung entsprechender Nachrichten erfordert.
1. Nachrichtenübermittlung in DELPHI VCL
Jede VCL-Komponente (Visual Component Library) (wie Tbutton, Tedit usw.) verfügt über einen inhärenten Nachrichtenverarbeitungsmechanismus. Der grundlegende Punkt besteht darin, dass die Komponentenklasse bestimmte Nachrichten empfängt und sie an die entsprechende Verarbeitungsmethode sendet Es gibt keine spezifische Verarbeitungsmethode, das Standard-Nachrichtenverarbeitungshandle wird aufgerufen. Unter diesen ist mainwndPRoc eine statische Methode, die in der Twincontrol-Klasse definiert ist und nicht überladen werden kann (Override). Es verarbeitet die Nachricht nicht direkt, sondern überlässt sie der wndproc-Methode zur Verarbeitung und stellt ein Ausnahmebehandlungsmodul für die wndproc-Methode bereit. Die Mainwndproc-Methode wird wie folgt deklariert:
procedure MainWndProc(var Message: TMessage);
Wndproc ist eine in der Tcontrol-Klasse definierte virtuelle Methode, die die Dispatch-Methode zum Verteilen von Nachrichten aufruft. Die wndproc-Methode wird wie folgt deklariert:
procedure WndProc(var Message: TMessage virtual);
Die Dispatch-Methode ist in der Tobject-Stammklasse definiert und wird wie folgt deklariert:
procedure Tobject.dispatch(var Message); Der an den Versand übergebene Nachrichtenparameter muss ein Datensatztyp sein, und der erste Einstiegspunkt in diesem Datensatz muss ein Kardinaltypfeld (Feld) sein, das die zu verteilende Nachrichtennummer enthält . Zum Beispiel:
Typ
Tmessage=Datensatz
Nachricht:Kardinal;
wparam:Wort;
lparam:longint;
Ergebnis:longint;
Ende;
Die Dispatch-Methode ruft die Handle-Methode der Klasse der letzten Generation der Komponente auf, die diese Nachricht basierend auf der Nachrichtennummer verarbeitet. Wenn es in dieser Komponente und ihrer Vorgängerklasse keinen Handler gibt, der dieser Nachricht entspricht, ruft die Dispatch-Methode den Defaulthandler auf Die Defaulthandler-Methode ist Die in Tobject definierte virtuelle Methode wird wie folgt deklariert:
procedure Defaulthandler(var Message);virtual;
Die Defaulthandler-Methode in der Tobject-Klasse implementiert nur eine einfache Rückgabe ohne jegliche Verarbeitung der Nachricht. Wir können die Standardverarbeitung der Nachricht in der Unterklasse implementieren, indem wir diese virtuelle Methode überladen. Für Komponenten in der VCL startet ihre Defaulthandler-Methode die Fenster API-Funktion Defwindowproc zum Verarbeiten der Nachricht.
2. Nachrichtenverarbeitungs-Handle in DELPHI
In DELPHI können Benutzer Nachrichten und Nachrichtenverarbeitungs-Handles anpassen. Die Definition von Nachrichtenverarbeitungs-Handles folgt den folgenden Prinzipien:
Die Handle-Methode für die Nachrichtenverarbeitung muss eine Prozedur sein und kann nur einen variablen Parameter vom Typ Tmessage übergeben.
Auf die Methodendeklaration muss ein Nachrichtenbefehl folgen, gefolgt von einer Nachrichtenbezeichnung (Ganzzahlkonstante) zwischen 0 und 32767.
Die Message-Handler-Methode muss den Override-Befehl nicht verwenden, um das Überschreiben eines Message-Handlers des Vorfahren explizit anzugeben. Darüber hinaus wird sie im Allgemeinen im geschützten oder privaten Bereich der Komponente deklariert.
Im Nachrichtenverarbeitungshandle verarbeitet der Benutzer im Allgemeinen zuerst die Nachricht und ruft schließlich mit dem geerbten Befehl das dieser Nachricht entsprechende Verarbeitungshandle in der Vorfahrenklasse auf (in einigen Fällen kann dies der Fall sein). Diese Nachricht in der Vorfahrenklasse lautet möglicherweise nicht. Der Name und der Parametertyp sind unklar. Durch Aufrufen des Befehls „inherited“ kann dieses Problem vermieden werden. Wenn in der Vorfahrenklasse kein Handler vorhanden ist, der dieser Nachricht entspricht, ruft „inherited“ automatisch die Defaulthandler-Methode auf. (Wenn Sie diese Nachricht natürlich blockieren möchten, Es ist nicht erforderlich, den geerbten Befehl zu verwenden.
Die Message-Handler-Methode wird wie folgt deklariert:
procedure Mymsgmethod(var message:Tmessage); message Msgtype;
Ebenso können Benutzer auch ihre eigenen Nachrichten definieren. Benutzerdefinierte Nachrichten sollten mit WM_USER beginnen.
Beispiele für benutzerdefinierte Nachrichten und Nachrichtenverarbeitungshandles sind wie folgt:
const my_paint=Wm_user+1;
Typ
Tmypaint=record
msgstr:cardinal;
msize:word;
mcolor:longint;
msgresult:longint;
Ende;
Typ
Tmycontrol=class(TCustomControl)
geschützt
procedure change(var message:Tmypaint); message my_paint;
.....
Ende;
...
procedure Tmycontrol.change(var message:Tmypaint);
beginnen
size:=message.msize; {Tmybutton-Größenattribut festlegen}
color:=message.mcolor; {Tmybutton-Farbattribut festlegen}
{etwas anderes tun}
geerbt; {Übergeben an Tcustomcontrol}
Ende;
3. Nachrichten filtern
Das Filtern von Nachrichten wird auch als Nachrichtenfalle bezeichnet. Unter bestimmten Umständen müssen Benutzer möglicherweise bestimmte Nachrichten blockieren oder bestimmte Nachrichten zur Verarbeitung abfangen. Aus der obigen Einführung können wir ersehen, dass es im Allgemeinen drei Möglichkeiten gibt, Nachrichten zu filtern: (1). Überladen Sie die von der Komponente geerbte virtuelle Methode (2). Überladen Sie die von der Komponente geerbte virtuelle Methode Defhandler, in der Nachrichten verarbeitet werden. Die am häufigsten verwendete Methode ist Methode (2), die im vorherigen Abschnitt vorgestellt wurde. Methode (1) ähnelt Methode (3).
Der allgemeine Prozess zum Überladen der virtuellen Methode wndproc ist wie folgt:
procedure Tmyobject.wndproc(var message:Tmessage);
beginnen
{... Bestimmen Sie, ob diese Nachricht verarbeitet werden soll.}
geerbt wndproc(message);
{Unverarbeitete Nachrichten werden von der übergeordneten Methode wndproc verarbeitet}
Ende;
Daraus ist ersichtlich, dass der Vorteil der Nachrichtenverarbeitung in der wndproc-Methode darin besteht, dass sie den gesamten Nachrichtenbereich filtern kann, ohne dass für jede Nachricht ein Verarbeitungshandle angegeben werden muss. Tatsächlich wird sie in der Tcontrol-Komponente zum Filtern verwendet Verarbeiten Sie alle Mausnachrichten (von WM_mousefirst bis WM_mouselast, wie im folgenden Code gezeigt). Es kann auch verwendet werden, um zu verhindern, dass bestimmte Nachrichten an den Handler gesendet werden.
procedure TControl.WndProc(var Message: TMessage);
beginnen
if (Message.Msg>=WM_MOUSEFIRST) und
(Message.Msg <= WM_MOUSELAST)
Dann
wenn Ziehen, dann {Drag-Ereignis behandeln}
DragMouseMsg(TWMMouse(Nachricht))
anders
... {andere Mausnachrichten verarbeiten}
Ende;
Versand (Nachricht);
{Ansonsten senden Sie die Nachricht normal}
Ende;
Das folgende Beispiel ist ein einfaches Beispiel für eine benutzerdefinierte Komponente:
Die Tmyedit-Klasse ist eine neue Klasse, die von der Tedit-Klasse abgeleitet ist. Ihr Merkmal ist, dass sie während des Betriebs keinen Fokus erhalten kann und nicht über die Tastatur eingegeben werden kann (ähnlich wie die Tlabel-Komponente). Wir können die WM_setfocus- und WM_mousemove-Nachrichten in ihr herausfiltern wndproc-Methode und ausführen Um die oben genannten Anforderungen zu erfüllen, lautet das Quellprogramm wie folgt:
Einheit myedit;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen, Grafiken,
Steuerelemente, Formulare, Dialoge,
StdCtrls;
Typ
Tmyedit = Klasse(TEdit)
Privat
{Private Erklärungen}
geschützt
{Geschützte Erklärungen}
{andere Felder und Methoden}
procedure wndproc(var message:Tmessage);override;
öffentlich
{Öffentliche Erklärungen}
veröffentlicht
{ Veröffentlichte Erklärungen }
Ende;
Verfahren Registrieren;
Durchführung
Verfahren Registrieren;
beginnen
RegisterComponents('Samples', [Tmyedit]);
Ende;
procedure Tmyedit.wndproc(var message:tmessage);
beginnen
Wenn message.msg=wm_mousemove dann
beginnen
Cursor:=carrow;
{Setzen Sie den Cursor auf crarrow statt auf den standardmäßigen crBeam-Cursor}
Ausfahrt;
Ende;
Wenn message.msg=wm_SetFocus, dann beenden;
{WM_setfocus-Nachricht abschirmen und verhindern, dass das Tmyedit-Steuerelement den Eingabefokus erhält}
geerbt wndproc(message);
{Andere Nachrichten werden zur Verarbeitung an den übergeordneten wndproc übergeben}
Ende;
Ende.
Sie können Tmyedit zur Komponentenpalette hinzufügen, um seine Leistung zu testen.
Wie aus der obigen Einführung hervorgeht, ist es nur möglich, den Nachrichtenverarbeitungsmechanismus in Delphi VCL zu verstehen, die Methoden und das Timing der Verarbeitung verschiedener Nachrichten zu beherrschen (ggf. unter Verwendung verschiedener Tools wie Winsight32, Spy usw.) und die Eigenschaften zu kombinieren Mit der OOP-Sprache können wir hochwertige Komponenten kompilieren. Dies erfordert natürlich, dass der Leser ständig Erfahrungen in der Praxis erforscht und sammelt.