AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht
Thema durchsuchen
Ansicht
Themen-Optionen

Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

Ein Thema von NicoleWagner · begonnen am 24. Mai 2022 · letzter Beitrag vom 26. Mai 2022
Antwort Antwort
Seite 1 von 2  1 2      
NicoleWagner

Registriert seit: 6. Jul 2010
167 Beiträge
 
Delphi XE3 Professional
 
#1

Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 14:59
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:
// 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;
Meine erste Frage ist die Funttion des Countdowns:
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
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.763 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 15:01
Nimm einen TTimer, setze die Zeit wie Du sie möchtest, dann reagiere auf OnTimer. Ausserdem kannst Du TTimer auch aktivieren und Deaktivieren. Der Rest ist trivial.
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
NicoleWagner

Registriert seit: 6. Jul 2010
167 Beiträge
 
Delphi XE3 Professional
 
#3

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 17:23
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.
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 17:54
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.
Den gibt's doch, wie Sherlock in seiner Antwort angab: OnTimer.
Peter Below
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.419 Beiträge
 
Delphi 7 Professional
 
#5

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 18:00
Der Timer hat ein OnTimer-Event.

Dort schaltest Du als erstes den Timer aus: Timer1.Enabled := false; und dann machst Du in dem Ereignis, was immer Du willst.
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;
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#6

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 18:02
Zitat:
Den gibt's doch, wie Sherlock in seiner Antwort angab: OnTimer.
Genau!
Example

Zitat:
Wie bringe ich ihn dazu, am Ende einen Sound abzuspielen.
Addiere eine Wave-Datei zur Ressource.
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:
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;
Aufruf!

Delphi-Quellcode:
if (StartAlarm(60) = LB_OKAY) then
          // bla, bla

Geändert von venice2 (25. Mai 2022 um 10:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.152 Beiträge
 
Delphi 12 Athens
 
#7

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 18:50
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#8

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 18:56
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.
Du weist doch gar nicht was alles noch innerhalb des Threads behandelt werden soll.
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:
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;
Wie gesagt kann nicht riechen was ihr da so vorschwebt!
Aber eine allgemeine Aussage was richtig ist oder falsch muß sie selbst entscheiden.
So hat Sie auf jedenfalls einen anderen Ansatz.

Geändert von venice2 (24. Mai 2022 um 19:06 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
3.908 Beiträge
 
Delphi 12 Athens
 
#9

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 24. Mai 2022, 19:44
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:

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;
Diese Abfrage dann regelmäßig mit DoTick triggern lassen, wie unten beschrieben, über Timer, Thread oder sonstwas.
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..

Geändert von Rollo62 (24. Mai 2022 um 19:47 Uhr)
  Mit Zitat antworten Zitat
NicoleWagner

Registriert seit: 6. Jul 2010
167 Beiträge
 
Delphi XE3 Professional
 
#10

AW: Wecker - ELEGANTE Lösung mit Abbruch via Button gesucht

  Alt 25. Mai 2022, 09:31
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:
https://docwiki.embarcadero.com/Code...ontrol_(Delphi)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 09:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz