Timer zur Laufzeit erstellen & OnTimeEvent?

Ein Hallo an alle DelphiKönner,

Ich habe mir einer kleine unit geschrieben, in der ich einen Timer1 auf einer beliebigen Form erzeugen kann

----- CUT ---------------------------
unit MeineUnit;

interface

uses …

procedure MakeMeATimer(FormName: TForm);

var MeinTimer: TTimer;

implementation

procedure MakeMeATimer(FormName: TForm);
begin
MeinTimer:= TTimer.Create(FormName);
MeinTimer.Intervall:=1000;
MeinTimer.Enable:=True;
end;

end.
----- CUT ---------------------------

Nun binde ich meine Unit in mein Hauptprogramm ein und rufe die Prozedur mit MakeMeATimer(Form1); auf. Nun müsste ich doch einen laufenden Timer mit dem Namen MeinTimer auf der Form1 erstellt haben. Aber wie kann ich nun das OnTime Event in meinem Hauptprogramm oder wo auch immer abfangen und eine Prozedur ausführen? Kann mir jemand bei diesem Problem ein paar Hilfestellung geben?

Danke schon mal
Thomas

Hallo Thomas,

> unit MeineUnit;  
>   
> interface  
>   
> uses ...

PROCEDURE MakeMeATimer (FormName: TForm; TickEvent: TNotifyEvent);


> var MeinTimer: TTimer;  
>   
> implementation

procedure MakeMeATimer(FormName: TForm; TickEvent: TNotifyEvent);


> begin  
> MeinTimer:= TTimer.Create(FormName);  
> MeinTimer.Intervall:=1000;  
> MeinTimer.Enable:=True;

 MeinTimer.OnTimer := TickEvent


> end;


procedure FreeTimer; // Sollte nicht fehlen!
begin
 MeinTimer.Free
end;



> end.

Nun binde ich meine Unit in mein Hauptprogramm ein und rufe
die Prozedur mit MakeMeATimer(Form1); auf. Nun müsste
ich doch einen laufenden Timer mit dem Namen MeinTimer auf der
Form1 erstellt haben.

Ja, sobald die Prozedur aufgerufen wird, wird der Timer creatiert und initialisiert und fängt an zu ticken. Sein „Owner“ ist dabei das der Prozedur übergebene Formular („FormName“), in Deinem Fall also Form1. Übrigens legt der Timer selbst gar keinen Wert darauf, einen Owner zu haben; somit kannst Du durchaus auch einen „ownerlosen“ erzeugen:

procedure MakeMeATimer(TickEvent: TNotifyEvent);


> begin  
> MeinTimer:= TTimer.Create(NIL);  
> MeinTimer.Intervall:=1000;  
> MeinTimer.Enable:=True;

 MeinTimer.OnTimer := TickEvent


> end;

Aber wie kann ich nun das OnTime
Event in meinem Hauptprogramm oder wo auch immer abfangen und
eine Prozedur ausführen?

Siehe Code. Daß die „OnTimer“-Ereignisbehandlungsprozedur vom Typ „TNotifyEvent“ ist, ersiehst Du z. B. aus der Online-Hilfe zu „TTimer“. Das „TickEvent“ muß zwingend denselben Typ haben.

Mit freundlichem Gruß
Martin

Danke für die schnelle Antwort

es funktioniert irgendwie, aber mache ich das so richtig?
Die Prozedur von Dir habe ich übernommen und in meine Unit gepackt, dann in meinem Hauptprogramm eine neue Variable eingefügt TickEvent: TNotifyEvent und eine neue Prozedur geschrieben

procedure TickEvent(Sender. TObject);
begin
beep;
end;

Starten tue ich das ganze mal zum Testen in FormCreate mit MakeMeATimer(From1, TickEvent);
nun macht mein Rechner jede Sekunde beep :o) aber ist das richtig so wie ich das gemacht habe?

Gruß und vielen Danke
Thomas

Hi again,

es funktioniert irgendwie, aber mache ich das so richtig?

strenggenommen darf es so eigentlich noch gar nicht funktionieren (Erklärung weiter unten)…

Die Prozedur von Dir habe ich übernommen und in meine Unit
gepackt,

OK

dann in meinem Hauptprogramm eine neue Variable
eingefügt TickEvent: TNotifyEvent

Achtung: Das ist überflüssig! Eine solche Prozedurvariable wird nicht benötigt! Also weg damit!

und eine neue Prozedur geschrieben

procedure TickEvent(Sender. TObject);
begin
beep;
end;

Eine neue Prozedur mußt Du schreiben, aber es muß unbedingt eine Methode von „Form1“ sein, also procedure TForm1. TickEvent(Sender. TObject). Ist das bei Dir der Fall? Diese Prozedur muß dann natürlich noch in der Formulardeklaration eingetragen werden (am zweckmäßigsten wahrscheinlich im PRIVATE-Teil).

Bei dem Versuch, eine gewöhnliche Prozedur an „MakeMeATimer“ zu übergeben, würdest Du eine Fehlermeldung erhalten („inkompatible Typen“), weil „TNotify“ deklariert ist als „PROCEDURE (Sender: TObject) OF OBJECT“, nicht als „PROCEDURE (Sender: TObject)“.

Starten tue ich das ganze mal zum Testen in FormCreate mit
MakeMeATimer(From1, TickEvent);
nun macht mein Rechner jede Sekunde beep :o)

Mhh, „Beep“ ist nicht ganz unkritisch. „Beep“ ist eine VCL-Prozedur (definiert in Unit SysUtils), die ihrerseits die Windows-Funktion „MessageBeep“ aufruft. Die Sounds, die „MessageBeep“ letztendlich abspielt, hängen von der Einstellung in Systemsteuerung/Audioschemata ab. Wenn dort nun „Kein Sound“ gewählt ist (wie bei mir z. B.), hat Beep keine Wirkung. Daher könnte es sein, daß der Test eines mit Beep „überwachten“ Programms auf Rechner A erfolgreich ist, auf Rechner B aber fehlschlägt, und die Ursache dafür nicht im Programm liegt. Der, der dann im Code nach dem Fehler sucht, hat ein hübsches Problem.

Eine Alternative wäre z. B. die Zeile „Caption := IntToStr(Random(1000000))“. Die „Caption“ ist dabei die Titelzeile des Fensters. Das ist eine praktisch 100%ig sichere Überwachungsmöglichkeit.

Mit freundlichem Gruß
Martin

hallo,

ich verstehe den aufwand nicht ganz.
warum nimmst du nicht die komponente ttimer, plazierst sie (unsichtbar) auf deinem formular und setzt enabled auf false. wenn du sie im programm benötigst, dann setzt du sie auf enabled ist true.
mehr als einen timer braucht man in den seltensten fällen.
zum beepen verwendete ich write(^G); ich weiss nicht, ob das noch funktioniert.

ciao chris

Der Timer war nur ein „bloedes“ Beispiel,

ich habe eine andere Komponete erstellen muessen mit der man das Telefonbuch von Windows manipulieren oder sich eine Onlineverbindung starten kann, ohne die Windowsdialoge. Diese sendet auch Ihre Events aber ich wusste nie wie man solche Events abfangen kann. Und der Grund warum ich das alles zur Laufzeit erstellen will ist, um mein Programm ein bisschen Modular zu halten, falls ich die Funktionen oder Prozeduren in anderen Programmen brauche.

Deswegen der ganze Aufwand.

Aber trotzdem DANKE fuer den Tip

DANKE DANKE,

jetzt klappt es so wie ich es wollte.

vielen Danke nochmal

Thomas