Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   "inherited" in Windows-Messages? (https://www.delphipraxis.net/97807-inherited-windows-messages.html)

pstruh 16. Aug 2007 16:03


"inherited" in Windows-Messages?
 
Hm, ich bin verwirrt :spin2: und möchte das gern einmal geklärt haben. Die Verwendung einer Windows-Message könnte z.B. wie nachstehend aussehen (nicht von mir)...

Delphi-Quellcode:
procedure TForm1.WMNCHitTest(var Message: TWMNCHitTest);
begin
  inherited;
  if Message.Result = htClient then
    Message.Result := htCaption;
end;
Warum steht vor dem individuellen Code das "inherited"? Was wird denn hier "geerbt oder vererbt"? Ich finde solche Codeschnipsel auch zuhauf ohne jedes "inherited". Auch kann ich keinen Unterscheid im Programmverhalten feststellen, egal ob mit oder ohne "inherited". Ist "inherited" nun immer/manchmal oder nie erforderlich :pale:
Gruß aus Hamburg :hi:

mkinzler 16. Aug 2007 16:09

Re: "inherited" in Windows-Messages?
 
es wird zuerst der Code der entsprechenden Methode der Superklasse aufgerufen.

pstruh 16. Aug 2007 16:13

Re: "inherited" in Windows-Messages?
 
Ok, also die Superklasse wird aufgerufen - bedeutet das nun, dass dieser Aufruf immer notwendig ist?

mkinzler 16. Aug 2007 16:15

Re: "inherited" in Windows-Messages?
 
Es kommt darauf an. wenn dein Code zusätzlich ausgeführt werden soll: ja; wenn er anstatt des geerbten Codes ausgeführt werden soll: nicht.
Beim Konstruktor z.B. würde ich es auf Jedenfall machen

Vjay 16. Aug 2007 16:16

Re: "inherited" in Windows-Messages?
 
Nein, nur wenn du ihr die Bearbeitung ermöglichen möchtest.

pstruh 16. Aug 2007 16:19

Re: "inherited" in Windows-Messages?
 
Ok, dann bin ich jetzt schlauer! Danke :hello:

Kedariodakon 16. Aug 2007 16:22

Re: "inherited" in Windows-Messages?
 
Eben es kommt immer drauf an, was du damit bewirken willst. Du reichst mit Inherited einfach nur zur geerbten Klasse weiter...

Die Hilfe hilft da auch :zwinker:

Zitat:

Das reservierte Wort inherited ist für die Polymorphie von großer Bedeutung. Es kann in Methodenimplementierungen (mit oder ohne nachfolgendem Bezeichner) angegeben werden.

Folgt auf inherited der Name eines Elements, entspricht dies einem normalen Methodenaufruf bzw. einer Referenz auf eine Eigenschaft oder ein Feld. Der einzige Unterschied besteht darin, dass die Suche nach dem referenzierten Element bei dem direkten Vorfahren der Klasse beginnt, zu der die Methode gehört. Wenn Sie beispielsweise

inherited Create(...);

in der Definition einer Methode angeben, wird die geerbte Methode Create aufgerufen.

Die Anweisung inherited ohne Bezeichner verweist auf die geerbte Methode mit demselben Namen wie die aufrufende Methode. Handelt es sich bei der aufrufenden Methode um eine Botschaftsbehandlung, verweist diese auf die geerbte Botschaftsbehandlung für dieselbe Botschaft. In diesem Fall übernimmt inherited keine expliziten Parameter, sondern der geerbten Methode werden einfach die Parameter der aufrufenden Methode übergeben. So wird beispielsweise:

inherited;

häufig in der Implementierung von Konstruktoren verwendet. Der geerbte Konstruktor wird also mit den Parametern aufgerufen, die an die abgeleitete Klasse übergeben wurden.

pstruh 16. Aug 2007 16:27

Re: "inherited" in Windows-Messages?
 
Ah, ja, ich bin seit 25 Jahren Hobby-Programmierer und habe immer noch Schwierigkeiten mit der Objektorientierung :( - diesen Hilfetext (genau den) hatte ich mir auch angesehen. Aber nun zu meinem Ehrenrettungs-Versuch: Ich hatte mir gedacht, dass die Nutzung von Windows-Messages etwas anders ist. So im Sinne von "eingeschleiftem Code", also das quasi automatisch alles "vor und hinterher" sowieso aufgerufen wird und "mein Code" einfach "dazwischengeschoben wird". Hm, ist das verständlich, was ich da gedacht hatte?

oki 16. Aug 2007 16:31

Re: "inherited" in Windows-Messages?
 
Verstädlich schon, aber eben falsch. Du fängst ja keine Botschaft ab und reichst sie weiter, sondern überschreibst die implementierte Methode der Klasse die die Botschaft verarbeitet. Damit ist das nichts anderes wie jede andere virtuelle Methode (zumindest was das inherited betrifft).

Gruß oki

Khabarakh 16. Aug 2007 16:46

Re: "inherited" in Windows-Messages?
 
Kann schon sein, dass ich mit der VCL langsam nicht mehr so vertraut bin, aber als ich das letzte Mal einen Blick in forms.pas geworfen habe, waren dort alle Botschaftsmethoden statisch :zwinker: (was sich ja auch mit dem zitierten OH-Text deckt).

SirThornberry 16. Aug 2007 17:34

Re: "inherited" in Windows-Messages?
 
hier wird die botschaftsbehandlung nicht im herkömlichen Sinne überschrieben. Es wird ein Messagehandler "registriert" an den eben bei eintreffen der Message diese geschickt wird. Will man die Message jetzt in den originalen Messagehandler bringen (die Nachrichtenschleife oder andere registrierte Messagehandler von Klassen von denen man geerbt hat) ist eben das inherited notwendig.

jbg 16. Aug 2007 17:40

Re: "inherited" in Windows-Messages?
 
Zitat:

Zitat von Khabarakh
waren dort alle Botschaftsmethoden statisch

Die waren noch nie statisch. WndProc war schon immer virtual und alle "message WM_XXX" sind dynamische Methoden (eintrag in der DMT [Dynamic Method Table])

pstruh 16. Aug 2007 18:13

Re: "inherited" in Windows-Messages?
 
Hallo zusammen, nun nicht mehr aus dem Büro, sondern von zu Haus! Bin erstaunt, welche interessanten Antworten auf meine, aus professioneller Sicht wohl recht naive, Frage hervorgebracht hat. Ich bedanke mich noch einmal bei allen Beteiligten - ist echt ein sehr aktives und hilfreiches Forum... :cheers:

SirThornberry 16. Aug 2007 18:22

Re: "inherited" in Windows-Messages?
 
um geanz genau zu erfahren was passiert bei dem aufruf von inherited in einem Messagehandler, schalte einfach mal die Debug-DCUs ein und steppe mit F7 hinein.
Du wirst einen Unterschied feststellen bei "abfangen" einer Nachricht welche bereits abgefangen wurde, von der klasse von der du erbst, und einer Nachricht die direkt an die DefWindowProc von Windows durchgeleitet wird.

negaH 16. Aug 2007 20:04

Re: "inherited" in Windows-Messages?
 
Zitat:

Botschaftsmethoden statisch
Falsch. Botschaftsmethoden sind schon imemr dynamische Methoden gewesen. Also auch keine virtuelle Methoden !!
Dynamische Methoden zeichnen sich dadurch aus das der Methode eine eindeutige Slot-ID zugeordnet wird. Das ist meistens ein Word der ein Index in die DMT -> Dynamic Method Table der Klasse ist. Virtuelle Methoden sind in der VMT der Klasse gespeichert. Der Unterschied besteht im Speicherverbrauch dieser Tabellen. Die DMT ist wesentlich kompakter benötigt aber einen echt rießigen Calling-Overhead beim Aufrufen einer solchen Methode. Dynmisch statt Virtuell bezieht sich nämlich auf die Art und Weise wie man eine Dynamische Methode aufruft und benutzt. Man hat ja erstmal nur eine Slot-ID und ein Objekt. Nun muß eine Aufrufprocedure innerhalb der DMT dieser Objektklasse nach einem Eintrag mit der Slort-ID der Methode suchen. Findet sich in dieser Klasse keine Dynamische Methode mit dieser ID so wird mit der Vorfahrklasse das gleiche gemacht. Man sucht also ausgehend von der aktuellen Klasse des Objecte alle DMTs aller Vorfahrklassen so lange durch bis man die Slot-ID gefunden hat. Dort wird dann auch der Zeiger in das Codesegement an der die reale Methode steht gespeichert. Eine Klasse als Struktur erbt also ganz unterschiedlich bezogen auf die DMT und VMT. Die VMT einer neuen Klasse ist eine komplette Kopie der Vorfahrklasse plus alle virtuallen Methoden die in der neuen Klasse deklariert wurden. Logisch da nur so eine 1 zu 1 Beziehung der Virtuellen Methoden in der komplette Klassenhirarchie ermöglicht wird. An der gleichen Position in der VMT steht immer die gleiche virtuelle Methode der kompletten Hierarchie, sonst könnte man garnicht eine Methode überschreiben. Die DMT einer neuen Klasse enthält dagegen nur die Einträge an dynamischen Methoden die in dieser Klasse implementiert wurden. Wurde eine dynamische Methode der Vorfahrklasse überschrieben so wird auch in der DMT der neuen klasse ein Eintrag mit der entsprechenden Slot-ID stehen, ansonsten fehlt dieser Eintrag. Die VMT wiederum kopiert alle virtuellen Methoden für jede Klasse egal ob die aktuelle Klasse sie überschreibt oder nicht. Das kostet Speicherplatz.

Und in meinen Worten steckt noch was, ich sagte DMT -> Methoden die implementiert wurden und VMT -> Methoden die deklariert wurden. Der Unterschied besteht nämlich darin das bei dynamischen Methoden exakt 2^16 Stück möglich wären und das das schon in der Klasse TObjekt festgelegt ist. Man kann also mit dynamischen Methoden Funktionaliät festlegen ohne wissen zu müssen wann, wo und ob die reale Implementierung einer dynamischen Methode real erfolgt. Dazu muß man aber in der Basisklasse keine Platzhaltermethode wie bei virtuellen Methoden vorsehen, also selbst die Implementation der Basisfunktionaliät kann bei dynamischen Methoden entfallen. Das einzigste was notwendig ist ist

1.) ein einheitliches Parameterinterface, bei Botschaftsmethoden eben die Einigung auf (var Msg: TMessage);
2.) die Bedeutung der Slot-IDs als Konstanten, eben wm_Paint = $xxxx.

Nun inherited kann man aufrufen vor oder nach der eigenen Implementierung oder auch garnicht. Das hängt einfach von der Zielsetzung ab.
Wird inherited in einer virtuellen Methode aufgerufen dann ist das wenig Code. Man schaut in der VMT der Vorfahrklasse am exakt gleichen Index wie die akteulle Methode nach und lädt von dort den Zeiger auf die Vorfahrmethode und ruft sie per CALL auf (Parameter nicht vergessen). Bei dynamischen Methoden ist das bischen aufwendiger kann ja die Vorfahrklasse garkeine Implementierung zur aktuellen Slot-ID besitzen. Man muß also auch wieder mit einer speziellen Suchfunktion erstmal die DMTs der Vorfahrklassen durchsuchen.

Die Slot-ID ist die Zahl die man bei dynamischen Methoden hinter deren Deklaration vergeben muß oder kann ;) Botschaftmethoden sind dynamische Methoden mit dem Unterschied das man diese Slot-ID per "message wm_Paint" o.ä vorgibt.

Übrigens Botschaftmethoden sind nicht begrenzt auf Windows-Controls sondern funktionieren mit allen Klassen abgleitet von TObject. Das macht zb. Sinn für Datenobjekte zb. Nodes und Node-Bäume die Daten hierarisch verwalten und denoch auf Eingaben der Maus, des Keyboards oder sich selber zeichnen sollen. Auch Broadcasting Botschaften lassen sich so auf Datenobjekte anwenden, einfach indem man seine eigene Message Methoden in diese Datenobjekte implementiert.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:02 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz