Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Objektereignisse bearbeiten (https://www.delphipraxis.net/41184-objektereignisse-bearbeiten.html)

engel 27. Feb 2005 16:09


Objektereignisse bearbeiten
 
Männer! (Oder gibt's hier auch Frauen?)

Wahrscheinlich eine Anfängerfrage:

Ich habe ein grafisches Objekt gebaut, mit dem ich vom Hauptprogramm aus kommunizieren kann (wie üblich über properties mittels read und write-Methoden).
Wenn mein Objekt jetzt aber darüberhinaus ein Ereignis auslöst, weil es z.B. einen Button hat, auf den geklickt werden kann, wie kann mein Hauptprogramm davon sofort erfahren?:

Das Objekt könnte einfach das Ereignis behandeln, indem es eine Prozedur des Hauptprogramms aufruft - das widerspricht aber dem objektorientierten Prinzip, denn der Zugriff auf's Objekt sollte ja ausschließlich über properties erfolgen, oder?

Wie macht man's richtig?

Matthias :roll:

sniper_w 27. Feb 2005 16:14

Re: Objektereignisse bearbeiten
 
Ereignisse (Events) sind Propertys (Eigenschaften) selbst.

engel 27. Feb 2005 17:21

Re: Objektereignisse bearbeiten
 
Du meinst, sowohl Eigenschaften als auch Ereignisse können properties sein? Schon klar, aber ein kleines Beispiel würde mir helfen:
Wie sieht 1. die Deklaration der Ereignisbehandlungsroutine im Objekt aus, und wie 2. die Deklaration der Ereignisbehandlungsroutine im Hauptprogramm, die auf das Ereignis reagiert, welches vom Objekt ausgelöst + ans Hauptprogramm weitergeleitet wurde?
Oder stelle ich mir den Ablauf falsch vor?

Matthias

jfheins 27. Feb 2005 17:26

Re: Objektereignisse bearbeiten
 
Ich glaube schon. eigendlich alles, was du schreibst, ist in ereignisbehandlungsroutinen (events) z.B. von dem Formulr.

In deinem Objekt kannst du nun ein´gene events definieren, indem du einen zeiger auf eine procedure erstellst, und dann eine property von diesem typ erstellst. dann ist das automatisch ein event.

xineohp 27. Feb 2005 17:40

Re: Objektereignisse bearbeiten
 
moin,

Delphi-Quellcode:
tMyClass = class
private
  FOnIrgendwas: tNotifyEvent;
  procedure IrgendeineMethode;
public
  property OnIrgendwas: tNotifyEvent read FOnIrgendwas write OnIrgendwas;
end;

implementation

procedure tMyClass.IrgendeineMethode;
begin
  {...}
  If Assigned(FOnIregndwas) then
    FOnIrgendwas(self)
  {...}
end;
Ich hoffe das hilft.

engel 27. Feb 2005 20:39

Re: Objektereignisse bearbeiten
 
...ich ahne jetzt zumindest, wie's geht, danke!

sniper_w 27. Feb 2005 20:43

Re: Objektereignisse bearbeiten
 
Delphi-Quellcode:
procedure tMyClass.IrgendeineMethode;
begin
  {...}
  If Assigned(FOnIregndwas) then
    [b]OnIrgendwas(self)[/b]
     // eher FOnIregndwas(Self);
  {...}
end;
Oder ?

xineohp 28. Feb 2005 14:06

Re: Objektereignisse bearbeiten
 
korrekt, war ein Tipfehler, sorry :oops: ist geändert

engel 2. Mär 2005 12:25

Re: Objektereignisse bearbeiten
 
...na dann aber auch:

If Assigned(FOnIrgendwas) then ...

oder? (wohl auch Tippfehler)

Was ich nicht verstehe: ich habe Beispiele gefunden, wo beide Parameter gleich sind, also z.B.

read OnIrgendwas write OnIrgendwas

Was steckt dahinter? Eigentlich brauche ich doch nur read, wenn das Ereignis im Objekt stattfindet + Richtung Hauptprogramm geschickt wird, oder??

Boombuler 2. Mär 2005 13:02

Re: Objektereignisse bearbeiten
 
Hi

ich hoffe mal ich schreib jetzt nix falsches:
du brauchst auch ein write um der Property eine Methode zuzuweisen die aufgerufen werden soll...
würde zB der Mensch der TButton(ich will jetzt nix höhren von TButton is abgeleitet von...) geschrieben hat beim OnClick nur Read und nich Write implementiert haben, so könntest du mit dem Button relativ wenig anfangen weil du ihm nich sagen kannst (write) was zu tun ist wenn der Button gedrückt wird...


Greetz
Boombuler

shmia 2. Mär 2005 13:25

Re: Objektereignisse bearbeiten
 
Es ist sinnvoll, sich an den Standard (bezüglich der Namensgebung) der VCL zu halten.

Hier erst mal die Vorlage:
Delphi-Quellcode:
TMyClass = class(TPersistent)
private
  FOnChange: TNotifyEvent;
protected
  procedure DoChange;dynamic;
public
  property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;

procedure TMyClass.DoChange;
begin
   if Assigned(FOnChange) then
      FOnChange(self);
end;
Das Property für das Event greift üblicherweise direkt auf die Eventvariable zu; Set- oder Getfunktionen werden nicht gebraucht.
Soll heissen: hinter read und write steht eine Variable, keine Methode.

Das Event soll nicht direkt aufgerufen werden, sondern wird indirekt über die Do-Procedure aufgerufen.
Die Do-Procedure ist die einzige Stelle in der ganzen Klasse, an der auf die Eventvariable FOnChange zugegriffen wird!!

Jetzt kommt der Trick:
Die Procedure DoChange ist virtuell.
Damit kann man in abgeleiteten Klassen den Zeitpunkt, wann der Event aufgerufen wird verändern.
In 95% aller Fälle wird man die Procedure DoChange nicht überschreiben wollen; das Standardverhalten reicht meisten aus.
Deshalb ist die Procedure mit dem Schlüsselwort dynamic versehen; dies spart Speicherplatz.

engel 13. Mär 2005 18:04

Re: Objektereignisse bearbeiten
 
danke, das versteh' ich! Aber wie schreibe ich jetzt die entsprechende Ereignisbehandlungsroutine für das Objektproperty "OnChange" in der Haupt-Unit (habe für's Objekt eine extra Unit)? Wie verbinde ich dieses Property OnChange jetzt mit meinem Ereignis-Bearbeitungs-Prozedurnamen in der Haupt-Unit (was ich sonst ja komfortabel im Objektinspektorfenster machen kann)?

Z.B.: ich habe in meinem Objekt 2 Buttons erzeugt, bei Klick darauf soll dieses o.g. OnChange ausgelöst + in der Hauptunit bearbeitet werden.
1. Wie mache ich das?
2. Wie werte ich dann aus, welcher von beiden geklickt wurde? :|

hanselmansel 22. Jul 2005 14:59

Re: Objektereignisse bearbeiten
 
Auch wenn das Thema schon drei Monate alt ist, möchte ich dennoch hier posten, denn meine Frage passt thematisch gut in diesen Thread.

Ich arbeite noch an meiner Komponente TWechselButton und versuche nun, die Events hinzubekommen. Dazu habe ich hier in der DP diesen Thread gefunden, und auch versucht meine Events nach diesem Schema hier zu programmieren.
Leider tut sich überhauptnichts. :( Wenn ich in einem fertigen Test-Programm auf meine Komponente klicke, wird weder die Aktion ausgeführt, die ich zur Entwicklungszeit in die Ereignisbehandlungsroutine "OnMouseDown" geschreiben habe, noch die automatische Wertzuweisung, die ich versucht habe in die Komponente zu implementieren.

Aber vieleicht sollte ich das an ein wenig Code deutlich machen:
Delphi-Quellcode:
type
  Wechselbutton = class(TCustomControl)
  private
    FOnMouseDown   :TNotifyEvent;

  protected  
    Procedure DoChange; dynamic;

  public  
  published  
    Property OnMouseDown: TNotifyEvent read FOnMouseDown write FOnMouseDown;
  end;

implementation

Procedure Wechselbutton.DoChange;
begin
if Assigned(FOnMouseDown) then
  Begin
  FOnMouseDown(self);
  b_MouseDown := True;  //Bei jedem OnMouseDown soll b_MouseDown auf TRUE gesetzt werden!
  End;
end;
Mein Ziel ist nun folgendes: Wenn auf die Komponente geklickt wird, soll OnMouseDown die Variable "b_MouseDown" auf True gesetzt, und die Komponente neu gezeichnet werden. OnMouseUp soll es dann umgekehrt gemacht werden.
An beiden Methoden soll der Entwickler aber nicht mehr dran rumfummeln müssen (muss er bei TButton ja auch nicht), das heisst, die Methoden sollten in der Komponente aufgerufen werden.

Zusätzlich soll der Entwickler, natürlich wie gewohnt über den Objektinspektor, Ereignisse meiner Komponente behandeln können.

Ich denke mal, in der Prozedur DoChange steckt irgendwo der Wurm drin. :gruebel: Könnt ihr mir sagen, wo? :stupid:

MfG,

hanselmansel


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:49 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