![]() |
Delphi-Version: 7
TNotifyEvent mit zusätzlichen Parametern ?
Guten Abend DP,
ich bin immernoch dabei eine Art 'Tron' zu programmieren und bin erneut an meine Grenzen gestoßen :? In dem Project soll jedes Fahrzeug (Bike) einen Timer bekommen mit dem es sich bewegt. (Jeder einen eigenen, damit sie sich unterschiedlich schnell bewegen können) Nun kreiere ich meine Timer dynamisch und weise ihnen das .OnTimer Event zu. Allerdings möchte ich, dass die procedur sich unterschiedlich verhällt, je nach dem welcher Timer das Event ausgelöst hat. Doch nun stellt sich mir das Problem, dass ich einem TNotifyEvent keine Parameter übergeben kann und somit nicht feststellen kann wer es ausgelöst hat :| ![]() Deklaration:
Delphi-Quellcode:
Erstellung der Timer:
Timer: Array of TTimer;
Tasten: TQueue; Bike: Array of TBike;
Delphi-Quellcode:
onTimer:
for i:=0 to Pred(pTimerAnzahl) do begin
SetLength(Timer, Succ(i)); Timer[i] := TTimer.Create(nil); Timer[i].Interval := 10; Timer[i].OnTimer := onTimer(Timer[i], i); Timer[i].Enabled := True; end;
Delphi-Quellcode:
procedure TSpielfeld.onTimer(Sender: TObject);
begin if Sender = Timer[0] then if Tasten.Count > 0 then case Word(Tasten.Pop) of 70: Bike[0].dreheLinks; 74: Bike[0].dreheRechts; end; (Sender as TTimer).Enabled := False; bewegeBikes(Sender);//stellt nach Bewegung (Sender as TTimer).Enabled := True . . end; |
AW: TNotifyEvent mit zusätzlichen Parametern ?
Also beim NotifyEvent wird doch der Auslöser mitgegeben -> Sender
|
AW: TNotifyEvent mit zusätzlichen Parametern ?
Das Konzept der vielen Timer ist sicher sehr ungünstig, aber weil es Spass macht auch mal etwas um die Ecke zu programmieren .... bitte nicht so umsetzen.
Du brauchst nur einen Timer in dem die Zustände aller Fahrzeuge abzufragen un zu ändern .... also just 4 fun:
Delphi-Quellcode:
unit Unit3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TBike=Class; TTimer=Class(ExtCtrls.TTimer) Private FMyBike:TBike; public Property Bike:TBike read FMyBike; End; TBike=Class (TObject) private FTimer:TTimer; FName: String; public Constructor Create(const aName:String;aEvent:TNotifyEvent);overload; Destructor Destroy;override; Property Timer:TTimer read FTimer; Property Name:String Read FName; end; TForm3 = class(TForm) Button1: TButton; Timer1: TTimer; Memo1: TMemo; ListBox1: TListBox; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.Button1Click(Sender: TObject); var i:Integer; begin for I := 1 to 10 do Listbox1.Items.AddObject(Format('Bike %d',[i]),TBike.Create(Format('Bike %d',[i]),Timer1Timer)); end; { TBike } constructor TBike.Create(const aName:String;aEvent: TNotifyEvent); begin inherited Create; FTimer := TTimer.Create(nil); FTimer.OnTimer := aEvent; FTimer.Interval := 50; FTimer.FMyBike := self; FName := aName; end; destructor TBike.Destroy; begin FTimer.Free; end; procedure TForm3.FormDestroy(Sender: TObject); var i:Integer; begin for I := Listbox1.Items.Count-1 downto 0 do Listbox1.Items.Objects[i].Free; Listbox1.Items.Clear; end; procedure TForm3.Timer1Timer(Sender: TObject); begin if Sender is TTimer then if Assigned(TTimer(Sender).Bike) then Memo1.Lines.Add(TTimer(Sender).Bike.Name); end; end. |
AW: TNotifyEvent mit zusätzlichen Parametern ?
Danke für die schnellen Antworten bis jetzt.
@Sir Rufo: Dachte ich zunächst auch, doch als ich im Debuger geguckt habe wo es denn hapert, zeigte er mir an: Sender() also das Sender keinen Wert hat :shock: Müsste ich das on Timer Event dann nich auch anders zuweisen
Delphi-Quellcode:
?
Timer[i].OnTimer := onTimer(Sender); // das Sender
@Bummi: so in der Art habe ich es zur Zeit (mit einem einzigen Timer) doch Sinn und zweck der vershiedenen Timer sollte sein, dass diese auch unterschiedliche Intervalle haben (mit denen die Bewegung unterschiedlic oft ausgeführt wird und sich das Bike somit unterschiedlich schnell bewegt) |
AW: TNotifyEvent mit zusätzlichen Parametern ?
Speicher zu der Position der "Bikes" auch ihre Geschwindigkeit (und Richtung). Dann nimm weiterhin nur einen Timer, aber bewege jedes Bike immer nur um seine eigene Geschwindigkeit in seine eigene Richtung weiter (Geschwindigkeit und Richtung lassen sich i.A. zusammen als ein einziger Vektor darstellen). Das wäre, abgesehen davon, dass Timer hier im Grunde schon eher fragwürdig sind, schon näher an best-practice. (Und es macht auch wirklich Sinn ;))
|
AW: TNotifyEvent mit zusätzlichen Parametern ?
Zitat:
Da ist zu 99.9999999% genau die Timer-Instanz drin, die das Event aufruft. Falls du es nicht glaubst:
Delphi-Quellcode:
Witzig ist, wenn das nicht so ist, wieso sollte das denn hier (in deinem Code) funktionieren?
procedure TSpielfeld.onTimer(Sender: TObject);
begin (Sender as TTimer).Enabled := False; ShowMessage( Sender.ClassName ); // --> TTimer (Sender as TTimer).Enabled := True; end; Zitat:
|
AW: TNotifyEvent mit zusätzlichen Parametern ?
TNotifyEvent hat nunmal nur einen zwei Parameter und daran kann man nichts ändern.
Sender = der Sender (ein Timer) Self = Empfänger (deine Form) Nja, wie schon erwähnt, hast du einmal den Sender, und im Sender (TComponent) gibt es noch das Property Tag, welches der Programmierer nach Belieben nutzen kann. Bezüglich der Arrays, würde ich dir eher zu Listen raten (vorallem die TObjectList). Und was die Anzahl der Timer angeht, wurde auch schon alles gesagt. |
AW: TNotifyEvent mit zusätzlichen Parametern ?
Zitat:
Aber wieso findet du (oder ihr :-D) dass Timer fragwürdig sind ? Wie kann man soetwas sonst realisieren ? :o glaube Vektoren werde ich mir demnächst mal in Delphi anschauen müssen :oops: @Sir Rufo:
Delphi-Quellcode:
ich hatte das Problem, dass der Timer eine Berechnung gestartet hat, doch obwohl er noch nicht fertig mit rechnen war hat der nächste Timer schon losgelegt. Das kam dann zu recht fiesen Fehlern. Ich müsste mal testen ob es immernoch Fehler produziert :roll:
procedure TSpielfeld.onTimer(Sender: TObject);
begin if Sender = Timer[0] // <-- ja wenn da nichts in Sender ist ... (Sender as TTimer).Enabled := False; // <-- ??? bewegeBikes(Sender);//stellt nach Bewegung (Sender as TTimer).Enabled := True // <-- ??? end; @himitsu: Wo liegt denn der Vorteil von TObjectList's gegenüber Arrays ? Habe es bisher immer mit Array gemacht :oops: |
AW: TNotifyEvent mit zusätzlichen Parametern ?
Ich bezog mich darauf, dass du behauptest, in Sender würde nichts enthalten sein (hast du ja mit dem Debugger geprüft) und trotzdem benutzt du den Wert von Sender.
Das wollte ich nur damit aufzeigen, dass in Sender die Timer Instanz enthalten ist |
AW: TNotifyEvent mit zusätzlichen Parametern ?
viele Timer gegen einen Timer
Du hast nur einen Raum (Thread, in dem eine Person (Timer) gleichzeitig arbeiten kann. Man kann nun viele Personen (Timer) etwas nacheinander machen lassen oder manläßt eine Person (Timer) alles nacheinander machen. Vom Zeitaufwand wird nichts gewonnen, wenn Mehrere arbeiten, aber der Verwaltungsaufwand wird größer. - alle Personen (Timer) müssen irgenwo wohnen (Speicher und Resourcen) - und diese Personen wechseln sich ständig unkontrolierbar ab (extrem schwer zu debugggen, vorallem wenn Mal irgendwas nicht funktioniert) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:18 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