Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Parameter in Event übergeben (https://www.delphipraxis.net/176458-parameter-event-uebergeben.html)

cltom 6. Sep 2013 09:22

Delphi-Version: XE2

Parameter in Event übergeben
 
Hallo,

wenig aussagekräftiger Titel, es ist aber auch eine recht allgemeine Frage. Ich hab eine einfache Zeichenprozedur. Dieser will ich eine Objektliste übergeben, also etwa:

Delphi-Quellcode:
procedure myclass.DrawObjects(myobjects : TObjectList<ObjectType>);
var
  i : integer;
begin
  for i := 0 to myobjects.count -1 do
    begin
     ...
    end;
end;
Nun soll die Zeichenprozedur ja im OnPaint-Event der PaintBox aufgerufen werden.

Delphi-Quellcode:
procedure myclass.OnPaint (Sender : TObject);
begin
  DrawObjects(...);
end;
Nun hat aber das event ja nur den Sender als Argument. Ich kann ihr also nicht die Objektliste übergeben, damit dann die OnPaint-Prozedur die Objektliste weiter an die Paint-Prozedur übergibt. Alternativ kann ich dann ja nur die Objektliste in der Klasse generell verfügbar machen und sie nur einemal übergeben. Lässt sich das auch eleganter machen?

danke und gruß
tom

Uwe Raabe 6. Sep 2013 09:27

AW: Parameter in Event übergeben
 
Auf den Aufruf der Paint-Routine hast du keinen Einfluss. Weder darauf, wann sie aufgerufen wird und wie. Innerhalb der Paint-Routine muss die zu zeichnende Objektliste (sinnvollerweise in der Klasse) verfügbar sein. Der Inhalt der Liste oder die aktuelle Instanz kann natürlich variieren.

Ich würde ein Feld in der Klasse anlegen, das von der Paint-Routine genutzt wird. Du kannst dann ja an anderer STelle diesem Feld die passende Liste zuweisen.

mkinzler 6. Sep 2013 09:35

AW: Parameter in Event übergeben
 
Oder die Referenz in den .Tag scheiben, wenn du die Klasse nicht verändern willst/kannst.

cltom 6. Sep 2013 10:36

AW: Parameter in Event übergeben
 
Danke. Gut, ich kann natürlich die Objektliste in der ganzen Klasse verfügbar machen, ich dachte halt, es wäre eleganter, ich könnte sie nur als Parameter übergeben.

Aber danke!

mkinzler 6. Sep 2013 10:45

AW: Parameter in Event übergeben
 
Ich würde diese nicht der Klasse, sondern pro Instanz bereitstellen; entweder als Eigenschaft oder halt im Tag

cltom 6. Sep 2013 12:16

AW: Parameter in Event übergeben
 
Danke. Aber auch wenn ich theoretisch weiss, was der Unterschied zwischen Klasse und Instanz ist, wie sähe das praktisch aus?

Ich hab jetzt eine Klasse "TDesigner", von der ich im Hauptform eine Instanz erzeuge. In der Klasse hab ich die Objektliste drin als public und natürlich auch die Draw und OnPaint. Also:

Delphi-Quellcode:
type
  TDesigner = Class(TObject)

    private
      Graphics : IGPGraphics;
      ABrush: IGPBrush;
      APen: IGPPen;
      AFont : IGPFont;

    public
      Destination_PB : TPaintBox;
      MyObjects : TObjectList<TDesignerObject>;
      procedure Initialize;
      procedure Draw;
      procedure AddObject(objecttype : TDesignerObjectType; x,y,d : integer);
      procedure Dest_PaintMe (Sender : TObject);
  end;

stahli 6. Sep 2013 12:34

AW: Parameter in Event übergeben
 
Du meintest schon das richtige.

Die Liste wird Bestandteil Deines Objektes (also Deiner Klasseninstanz).

Es gibt auch die Möglichkeit, Klassenvariablen zu verwenden (z.B.
Delphi-Quellcode:
class var GlobalList: TList;
).
Dann würden alle Klasseninstanzen auf die selbe Liste zugreifen können. Sie müsste dann ggf. in einem Klassenconstruktor erzeugt und in einem Klassendestructor aufgelöst werden.

Du willst ja aber offenbar eine Liste in jeder Klasseninstanz.


Nur mal noch zwei kleine Anmerkungen:
Üblich ist als Präfix für private Felder ein F (ich nutze inzwischen meist ein kleines f). Natürlich ist das nicht zwingend, hilft aber möglichen Dritten, Deinen Quelltext besser lesen zu können.
Die Objektliste könntest Du als Nur-Lesen-Property definieren (wenn sie direkt vom Objekt verwaltet wird) oder als Property mit Getter und Setter. Dann könntest Du im Setter erkennen, wenn eine neue Liste zugewiesen wird und gleich ein Neuzeichnen veranlassen.
Delphi-Quellcode:
type
   TDesigner = Class(TObject)
 
    private
       Graphics : IGPGraphics;
       fBrush: IGPBrush;
       fPen: IGPPen;
       fFont : IGPFont;
       fMyObjects : TObjectList<TDesignerObject>; // privat
 
    public
       Destination_PB : TPaintBox;
       procedure Initialize;
       procedure Draw;
       procedure AddObject(objecttype : TDesignerObjectType; x,y,d : integer);
       procedure Dest_PaintMe (Sender : TObject);
       property MyObjects : TObjectList<TDesignerObject> read fMyObjects {write set_MyObjects}; // öffentlich
   end;

cltom 6. Sep 2013 12:49

AW: Parameter in Event übergeben
 
ok, danke Euch!

Ja, klar gewollt ist natürlich, dass jede Instanz ihre Liste hat. Im Mainform erzeuge ich dann eine Instanz des Designers und der führt dann seine Liste an Objekten mit. Ja, mein "in der ganzen Klasse verfügbar machen" war also natürlich falsch und irreführend.

Präfix "f" lässt sich machen, klar, danke für den Hinweis. Und auch der Ansatz mti der Objektliste macht Sinn. Im aktuellen Entwurf hat nur die Instanz selbst mit der Liste zu schaffen. Von aussen wird ein neues Objekt nur durch die prozedur "AddObject" (später dann "RemoveObject", "MoveObject", etc.) verwaltet. Direkt will ich da von der mainform nicht reinpfuschen.

Das bringt mich allerdings gleich zu einer anderen Design-Frage. Wenn ich das so handhabe, wie beschrieben, dann kennt nur dieses Objekt die Objektliste (und zwar hier zum Zeichnen). Wenn ich jetzt die Objektliste für andere Zwecke haben möchte (etwa zum speichern oder für Berechnungen), dann müsste ich im Grunde neue Objekte erschaffen, die wiederum die Objekte in ihren Listen haben und mit den Daten ihre Funktionen durchführen. Die Redunanz hier wäre überschaubar, weil die Daten zur Zeichnung und die Daten zur Berechnung recht unterschiedlich sind (die Zeichnung ist ein einfaches Symbol, für die Berechnung kommt natürlich viel mehr dazu). Aber dennoch: man müsste für jedes neue Ding, das ich hinzufüge, ein Objekt in allen unterschiedlichen Objektlisten der einzelnen Objekte anlegen.

Alternativ könnte man in einer eigenen Überklasse eine Objektliste halten (die alle notwendigen Daten enthält) und diese (oder Teile davon) an diverse Objekte übergeben, je nachdem, was damit passieren soll. Gibt es dazu Empfehlungen?

stahli 6. Sep 2013 13:19

AW: Parameter in Event übergeben
 
Eine Nachfrage zum Verständnis:

Du wirst also auf keinen Fall Controls (wie Panels o.ä.) irgendwo platzieren, sondern direkt auf einem Canvas selbst zeichnen?

Deine letzte Überlegung ist (wenn ich sie richtig interpretiere) auf jeden Fall sinnvoll.
Es macht auf jeden Fall Sinn, die Daten komplett an einer zentralen Stelle zu verwalten und diese bei Bedarf in der GUI darzustellen.
Ich habe jetzt noch nicht verstanden, warum Du mehrere Deiner Designer mit Objektlisten benötigst.

Du könntest z.B. Deine Daten in einer Art Manager verwalten, die dort berechnen und speichern bzw. laden und dem Manager einen Designer zuweisen auf dem er die Daten darstellen kann.

Grundsätzlich solltest Du Daten und Darstellung im Quelltext konsequent trennen und sich nur über eine Schnittstelle gegenseitig bekannt machen.
Das wird die Wartbarkeit Deines Projektes deutlich erhöhen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:10 Uhr.

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