AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Timer in einer Unit

Ein Thema von Popov · begonnen am 19. Mär 2015 · letzter Beitrag vom 23. Mär 2015
Antwort Antwort
Dejan Vu
(Gast)

n/a Beiträge
 
#1

AW: Timer in einer Unit

  Alt 22. Mär 2015, 12:22
Ich hatte die MSDN-Beschreibung so verstanden, aber -so im nachhinein- wäre das auch ziemlich blöd, wenn es nur 1x gefeuert würde.
So ist es halt nur wieder das übliche BlaBla.
Niveau ist das Denkmal des Verstandes.
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#2

AW: Timer in einer Unit

  Alt 22. Mär 2015, 12:45
Ich hab das mal übersetzt:

SetTimer
Code:
function SetTimer(Wnd: HWnd; IDEvent: Integer; Elapse: Word; TimerFunc: TFarProc): Word;
Die Funktion SetTimer erzeugt ein System-Timer-Ereignis. Ein Time-Out-Wert wird festgelegt. Immer wenn ein Time-Out eintritt, sendet das System eine WM_TIMER-Meldung an die installierte Anwendungswarteschlange, oder übergibt die Meldung an eine anwendungsdefinierte TimerProc-Callback-Funktion.

ParameterBeschreibung
WndLegt das Fenster fest, das dem Timer zugeordnet werden soll. Ist der Parameter TimerFunc nil, erhält die mit diesem Fenster verbundene Fenster-Prozedur die Meldungen WM_TIMER von dem Timer. Ist dieser Parameter Null, wird kein Fenster mit dem Timer verbunden.
IDEventLegt einen von Null verschiedenen Bezeichner für ein Timer-Ereignis fest. Ist der Parameter Wnd Null, wird dieser Parameter ignoriert.
ElapseBestimmt die abgelaufene Zeit zwischen Timer-Ereignissen in Millisekunden.
TimerFuncBestimmt die Adresse der Prozedurinstanz der Callback-Funktion, die die Meldungen WM_TIMER weitergibt. Ist dieser Parameter nil, werden die Meldungen WM_TIMER in der Anwendungswarteschlange plaziert, und das hwnd-Mitglied der Struktur TMSG enthält das durch den Parameter Wnd bestimmte Fenster-Handle. Weitere Informationen finden Sie in der Beschreibung der Callback-Funktion TimerProc

Rückgabewert
Der Rückgabewert legt den Integer-Bezeichner für das neue Timer-Ereignis fest, wenn der Parameter Wnd Null ist, und die Funktion erfolgreich ausgeführt wurde. Eine Anwendung übergibt diesen Wert an die Funktion KillTimer, um das Timer-Ereignis zu beseitigen. Der Rückgabewert ist ungleich Null, wenn der Parameter Wnd ein gültiges Fenster-Handle ist, und die Funktion erfolgreich ausgeführt wurde. Andernfalls ist der Rückgabewert Null.

Hinweis
Timer sind eine eingeschränkt verfügbare, globale Ressource. Aus diesem Grund ist es wichtig, daß eine Anwendung den durch die Funktion SetTimer zurückgegeben Wert überprüft, um sicherzustellen, daß ein Timer verfügbar ist.

Um eine Timer-Funktion zu installieren, muß TimerFunc eine Adresse der Prozedurinstanz einer Callback-Funktion bestimmen und die Funktion muß in der Moduldefinitionsdatei der Anwendung exportiert werden. Die Adresse sollte mit Hilfe der Funktion MakeProcInstance erzeugt werden.

Die Callback-Funktion muß die Pascal-Aufrufkonvention verwenden und als FAR deklariert werden.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Timer in einer Unit

  Alt 22. Mär 2015, 13:13
@Popov

Nein, so ist es nicht ganz:
  • Übergibst du ein Fenster-Handle, dann bist du für die Vergabe/Verwaltung der TimerID zuständig.
  • Übergibst du kein Fenster-Handle, dann bekommst du eine TimerID zugewiesen.
Also wir übergeben ein Handle und eine TimerID:
Delphi-Quellcode:
var
  LTimerID: UINT_PTR;
begin
  LTimerID := 1;
  LTimerID := SetTimer( AHandle, LTimerID, 1000, @TimerProc );
end;
Nach Aufruf von SetTimer ist LTimerID immer noch 1.

Jetzt ohne Handle:
Delphi-Quellcode:
var
  LTimerID: UINT_PTR;
begin
  LTimerID := 1;
  LTimerID := SetTimer( 0, LTimerID, 1000, @TimerProc );
end;
Nach dem Aufruf von SetTimer bekommen wir eine völlig andere TimerID zurück - es sei denn, es gibt schon einen Timer mit der TimerID 1, dann wird dieser auf das neue Intervall gesetzt. Wenn wir Pech haben funken wir einem anderen Timer dazwischen. Darum soll man hier zwingend 0 übergeben, wenn man einen neuen Timer anlegen will und keinen vorhandenen ändern.

Das steht auch alles so in der Doku.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#4

AW: Timer in einer Unit

  Alt 22. Mär 2015, 13:45
...oder mit Konstante:

Delphi-Quellcode:
//global
const IDC_TIMER = 4;
var wnd: HWND;
    hwndTimer : DWORD;

//in beliebigen Prozeduren
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
...
KillTimer(wnd, hwndTimer);
hwndTimer := 0;
...
function WndProc(wnd: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM):
  LRESULT; stdcall;
begin
case uMsg of
WM_TIMER:
      begin
 // tu was...
      end;   
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Timer in einer Unit

  Alt 22. Mär 2015, 14:23
@hathor

Vorausgesetzt dass wnd ungleich 0 ist, ist hwndTimer überflüssig, denn der wird immer den Wert 4 haben (oder 0 wenn die Erstellung des Timers fehlgeschlagen ist).
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#6

AW: Timer in einer Unit

  Alt 22. Mär 2015, 14:40
@Sir Rufo:

Das stimmt nicht:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
//hwndTimer - Werte bei mir:
//7187
//7186
//7185
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Timer in einer Unit

  Alt 22. Mär 2015, 14:50
@Sir Rufo:

Das stimmt nicht:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
hwndTimer := SetTimer(wnd,IDC_TIMER,1000,nil); // 1000 msec
Memo1.Lines.Add(INTTOSTR(hwndTimer));
//hwndTimer - Werte bei mir:
//7187
//7186
//7185
end;
Es wäre sehr schön, wenn du den Wert von wnd mal mit postest (und ob das auch ein gültiges Fenster-Handle ist, denn ansonsten ist das so wie ich es gesagt habe und in der Doku steht).

Ist das so schwer zu begreifen? Diese SetTimer-Funktion reagiert abhängig davon ob du ein Fenster-Handle übergibst oder nicht. Ohne Fenster-Handle bekommst du eine TimerID zugewiesen. Die übergebene TimerID sollte aber 0 (in Worten Null, Zero, Nada, nix, ...) sein, wenn du einen neuen Timer haben möchtest.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
BadenPower

Registriert seit: 17. Jun 2009
616 Beiträge
 
#8

AW: Timer in einer Unit

  Alt 22. Mär 2015, 14:52
Wenn Du SetTimer() mit einem Handle aufrufst, dann ist der Rückgabewert irgendein Wert. Diesen Wert solltest Du aber nicht für KillTimer() benutzen, sondern den, welchen Du im 2. Parameter angegeben hast.

Ist kein Handle bei SetTimer() angegeben, dann ist der Rückgabewert der Funktion gleich dem Wert, welchen Du für die KillTimer()-Funktion benötigst.
Programmieren ist die Kunst aus Nullen und Einsen etwas sinnvollen zu gestalten.
Der bessere Künstler ist allerdings der Anwender, denn dieser findet Fehler, welche sich der Programmierer nicht vorstellen konnte.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.948 Beiträge
 
Delphi 12 Athens
 
#9

AW: Timer in einer Unit

  Alt 22. Mär 2015, 14:55
Also mich wundert vor allem wieso die TimerProc hier in allen Posts nicht der Doku entspricht. Ich würde mal sagen die Beispiele sorgen alle für einen fehlerhaften Stack...
Denn die bekommt eigentlich noch Parameter und da das stdcall ist, muss die aufgerufene Prozedur auch die Parameter aufräumen (tut es aber nicht, weil sie nix davon weiß):
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Korrekt sieht die so aus:
Delphi-Quellcode:
procedure OnTimer(hwnd: HWND; uMsg: UINT; idEvent: UINT_PTR; dwTime: DWORD); stdcall;
begin
...
Und dann hat man auch die ID des Timers...
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:20 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