![]() |
Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Hallo Leute,
mein Problem ist zweifellos schon zig-fach gelöst. Doch wo genau? Ich brauche nichts als einen Wecker für 10 Minuten. 1) Es gibt einen "Startknopf", um den Countdown zu beginnen, dessen Methode hier drunter steht. 2) Und es gibt einen "Abbruch-Button", zu dem es noch gar keine Methode gibt.
Delphi-Quellcode:
Meine erste Frage ist die Funttion des Countdowns:
// Ausführungsprogramm des Countdowns
procedure TForm_KalenderMain.Panel_CountdownClick(Sender: TObject); Var Startzeit: TTime; begin Startzeit:=DateTimePicker_Alarm; .... * hier soll irgendwie abgefragt werden, ob seit der Startzeit bereits 10 Minuten vergangen sind. * Panel_Alarm.Color:=clGreen; end; Wie löse ich den Countdown am Elegantesten? Mit Sleep? Oder indem ich jede Sekunde die Zeit neu abfrage? Oder indem ich ....? Das kann wohl jeder lösen. Irgendwie. Der Profi hingegen weiß, wie es zu lösen geht, ohne sinnlos Ressourcen zu blockieren, indem ich ständig die Zeit prüfe. Wofür ich hier danke. Dann wird es trickreicher: Es soll noch eine Button geben, der erlaubt, den Alarm abzubrechen. Dieser Button wird in ein Click-Event führen. Doch - was dann? Ich könnte natürlich die Starzeit als globale Variable führen und sie einfach hochsetzen. Das sieht aber richtig hässlich aus vom Stil her. Ich könnte eine globale Boolean Variable einführen, die den Alarm hält oder nicht. Allerdings müsste ich die neben der Zeit ständig abfrgen und das nur alle 1 Sekunden. Was eine hässliche Verzögerung darstellt. Ich könnte ein Handle schreiben und gleich ins System greifen. Das sieht mir aber noch hässlicher aus. Hat hier jemand 2 ELEGANTE Lösungen? Mit bestem Dank im Voraus. Nicole |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Nimm einen
![]() |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Danke für den Tipp!
Der Timer ist jetzt Teil meines Projekts und startet jetzt. mit Timer1.Intervall:=...; Timer1.Enabeled:=true; So weit so fein. Wie bringe ich ihn dazu, am Ende einen Sound abzuspielen (bzw. piep piep zu machen) und das Panel rot zu färben? Mit anderen Worten: Ich bräuchte ein OnEndTimer-Event. Das dürfte es auch geben, doch eine Vorlage zu haben, wie ich es schreibe, wäre toll. Die Schnipsel auf Stackoverflow usw. sind mir nicht so leicht verständlich bzw. recht unübersichtlich. |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Zitat:
|
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Der Timer hat ein OnTimer-Event.
Dort schaltest Du als erstes den Timer aus:
Delphi-Quellcode:
und dann machst Du in dem Ereignis, was immer Du willst.
Timer1.Enabled := false;
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin timer1.Enabled := false; Panel1.Color := clRed; // ... weiter, wie in jedem beliebigen andern OnClick- oder On...-Ereignis auch. end; |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Zitat:
![]() ![]() Zitat:
Addiere MMSystem zu den Uses.. Führe diese Funktion aus.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin timer1.Enabled := false; PlaySound('SOUND1', hInstance, SND_RESOURCE or SND_ASYNC); Panel1.Color := clRed; end; Davon ab würde ich gar keinen Timer nehmen sondern einen Thread dafür verwenden.
Delphi-Quellcode:
var
EndAlarm : BOOL;
Delphi-Quellcode:
procedure Alarm(Delay: Integer); stdcall;
var //... begin //... Repeat //... Was auch immer du für die Zeit Berechnung benötigst. // Wenn Bedingung erfüllt. if (bla = bla) then begin EndAlarm := True; PlaySound('SOUND1', hInstance, SND_RESOURCE or SND_ASYNC); Panel1.Color := clRed; end; Sleep(Delay); Until (EndAlarm = True); // globale variable EndAlarm Definieren und über Button auf True setzen. Oder darauf warten bis Bedingung erfüllt end;
Delphi-Quellcode:
Aufruf!
function StartAlarm(Delay: Integer): Integer;
var Return: Integer; hThread, dwThreadId: DWORD; begin Return := LB_ERR; hThread := CreateThread(nil, 0, @Alarm, Pointer(Delay), 0, dwThreadId); if (hThread <> 0) then begin Return := LB_OKAY; Sleep(100); end; CloseHandle(hThread); Result := Return; end;
Delphi-Quellcode:
if (StartAlarm(60) = LB_OKAY) then
// bla, bla |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Den Sound kann man Async abspielen, somit hat der Hauptthread garnichts zu tun und ein Thread ist garnicht nötig.
Fazit: Die eleganzeste Lösung ist ein Timer. |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Zitat:
Abfrage der Zeiten und..und..und Fazit: Daher ist die eleganteste Lösung diese mit der Sie am besten zurecht kommt Code bedingt. Ich Render zum Beispiel noch einige Bilder innerhalb des Thread deshalb habe ich ihn umgeschrieben und hier angeboten. Glaube es oder nicht der hat genug zu tun. (In meiner Anwendung)
Delphi-Quellcode:
Wie gesagt kann nicht riechen was ihr da so vorschwebt!
procedure Animate(Delay: Integer); stdcall;
var Brush: HBrush; StepX: Integer; DesktopDC: HDC; lpSize: TSize; graphics: LONG_PTR; rc: TRect; rw: TRect; bf: BLENDFUNCTION; lp, ptSrc: TPoint; // label DoLoop; begin GetWindowRect(gP.Handle, rc); lpSize.cx := rc.right - rc.left; lpSize.cy := rc.bottom - rc.top; SetRect(rc, 0, 0, lpSize.cx, lpSize.cy); if (gP.img = 0) then exit; bf.BlendOp := AC_SRC_OVER; bf.BlendFlags := 0; bf.AlphaFormat := AC_SRC_ALPHA; bf.SourceConstantAlpha := 255; // DoLoop: Repeat if (gP.bitmap = 0) then begin DesktopDC := GetDC(0); gP.DC := CreateCompatibleDC(DesktopDC); gP.bitmap := CreateDIBSection32(gP.DC, lpSize.cx, lpSize.cy); SelectObject(gP.DC, gP.bitmap); ReleaseDC(0, DesktopDC); end; if (gP.bitmap <> 0) then begin GetWindowRect(gP.Handle, rw); StepX := 1; lp.y := rw.top; if (rw.right > GetSystemMetrics(0)) and (HideIt = 0) then begin lp.x := rw.left - StepX; end else if (Sound = 0) then begin Sound := -1; inc(PlayThis); if (PlayThis = 2) then PlaySound('SOUND2', gP.instance, SND_RESOURCE or SND_ASYNC) else if (PlayThis < 2) then PlaySound('SOUND1', gP.instance, SND_RESOURCE or SND_ASYNC); end; if (PlayThis > 2) then Playthis := 3; if (HideIt = 3) then begin if rw.left < GetSystemMetrics(0) - 25 then lp.x := rw.left + StepX else begin HideIt := 0; Sound := 0; end end; Brush := CreateSolidBrush(0); SelectObject(gP.DC, Brush); FillRect(gP.DC, rc, Brush); DeleteObject(Brush); if (GDIP_CreateFromHDC(gP.DC, graphics) = OK) then begin inc(gP.frametouse); if (gP.frametouse > gP.framecount) then begin gP.frametouse := 1; if rw.right < GetSystemMetrics(0) + 1 then inc(HideIt); end; if (gP.img <> 0) then GDIP_DrawImageRectRectI(graphics, gP.img, 0, 0, lpSize.cx, lpSize.cy, lpSize.cx * gP.frametouse - lpSize.cx, 0, lpSize.cx, lpSize.cy, 2, nil, nil, nil); GDIP_DeleteGraphics(graphics); end; UpdateLayeredWindow(gP.Handle, 0, @lp, @lpSize, gP.DC, @ptSrc, 0, @bf, ULW_ALPHA); Sleep(Delay); end; Until (EndAnimate = True); // Goto DoLOOP; end; Aber eine allgemeine Aussage was richtig ist oder falsch muß sie selbst entscheiden. So hat Sie auf jedenfalls einen anderen Ansatz. |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Ich würde auf jeden Fall empfehlen das mit TDateTime zu machen, und zum Beispiel die Differenz (Now - StartDatum) als Trigger zu nehmen, oder auf eine Ablaufzeit FEndTime zu vergleichen.
Delphi-Quellcode:
Diese Abfrage dann regelmäßig mit DoTick triggern lassen, wie unten beschrieben, über Timer, Thread oder sonstwas.type TMyForm = class FStartTime : TDateTime; end; procedure TMyForm.Start; begin FStartTime := Now; end; procedure TMyForm.OnTick; begin if MilliSecondsBetween(Now, FStartTime) > 10000 then // if Now >= FEndTime then //<== Alternativ begin Alarm; end; end; Der Vorteil ist das der Wecker dann immer beliebig genau ist nach der Systemzeit, egal wie genau der Timer ist. Dem Timer traue ich da über große Zeiträume eher weniger zu, der könnte auch mal irgendwo hängen bleiben, aber als zyklischer "Ticker" ist der super.. |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Danke für die Antworten!
Ich werde sie alle durchforsten und wohl ganz viel davon einbauen. Die vielen Codeschnipsel sind enorm nützlich. Wer hier eines Tages nachliest, der soll auch noch dieses Link zum Thema finden: ![]() |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Zitat:
;-) Sherlock |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Ich retriggere den Timer eigentlich fast immer in seiner OnTimer Routine.
So kann man den auch schön definiert abschalten und aufräumen lassen.
Delphi-Quellcode:
So kann das was im OnTimer gemacht werden soll in Ruhe arbeiten, ohne Gefahr dass ein OnTimer ein zweites Mal reintriggert.
procedure TForm1.Timer1Timer(Sender: TObject);
begin Timer1.Enabled := False; DoTick; if FTimerIsRunning then begin Timer1.Enabled := True; end else begin CleanupAfterStop; end; end; Insbesondere bei schnellen Ticks hilft das, damit es nicht aus dem Tritt gerät wenn DoTick mal 100ms und mal 500ms dauern kann. Das geht natürlich auf insgesamt Kosten der Timergenauigkeit, aber die ist für mich sowieso meistens nicht relevant, deshalb das TDateTime um die wirkliche Zeit zu bekommen. Wenn ich hochpräzise Timer brauche dann nehme ich sowieso was Anderes. |
AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
huch, wie konnte das passieren? Ich kopierte das Link.
Um es für alle Zeiten "sicher" zu machen, das ist es, was dort zu finden ist:
Delphi-Quellcode:
Und dieser Mann machte mich ganz nervös, weil er so langsam sprach, doch danch hatte ich es wirklich verstanden:
ActiveControl (Delphi)
Description Place a TTimer object on the form and enter Timer1Timer in the OnTimer event. Place other controls on the form and change the active control at run time. The following event handler responds to timer events by moving the active control one pixel to the right every 100 milliseconds. Code procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Interval := 100; if ActiveControl <> nil then ActiveControl.Left := ActiveControl.Left + 1; end; Uses Vcl.Forms.TCustomForm.ActiveControl ( fr | de | ja ) Vcl.ExtCtrls.TTimer.OnTimer ( fr | de | ja ) Vcl.ExtCtrls.TTimer.Interval ( fr | de | ja ) Vcl.Controls.TControl.Left ( fr | de | ja ) ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 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