Brauche hilfe bei Schleife mit OnKeyDown und sleep

Rund um die LCL und andere Komponenten
Antworten
Tanketorion
Beiträge: 25
Registriert: Mo 7. Apr 2014, 20:55

Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Tanketorion »

Hi Leute

Ich möchte ein Metronom erstellen, welches auf Tastendruck einer bestimmten Taste ein oder aus geschaltet werden kann.
Mein Problem damit ist das abschalten.

Code: Alles auswählen

procedure TMetronom.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Ass:=1;
  if key=VK_Down then Ass:=0;     
  if Ass=1 then
  repeat
  PlaySound('Pfad', 0, SND_FILENAME or SND_ASYNC);
  sleep(300);
  if key=VK_Down then Ass:=0;
  until Ass=0;
end;       
 
Das Metronom startet bei jeder Taste außer VK_Down so wie es auch soll, nur wenn ich in dieser schleife VK_Down drücke läuft das Metronom einfach weiter.

Wie kann ich das Problem beheben??
Zuletzt geändert von Lori am Do 4. Sep 2014, 16:59, insgesamt 1-mal geändert.
Grund: Highlighter

Benutzeravatar
theo
Beiträge: 10865
Registriert: Mo 11. Sep 2006, 19:01

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von theo »

Baue Application.Processmessages in die Schleife ein.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Scotty »

Benutze einen TTimer, setze das Intervall auf den gewünschten Wert und toggle Enabled in OnKeyDown. Und im OnTimer-Event spielst du den Ton einfach asynchron ab.

Tanketorion
Beiträge: 25
Registriert: Mo 7. Apr 2014, 20:55

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Tanketorion »

:shock: :oops: oooookkkk???

Erst mal danke für eure schnelle Hilfe, aber ich bin noch nicht so erfahren in Lazarus das ich weis wie ich eure Tipps umsetzen kann.
Könnte mir das jemand kurz beschreiben??

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Michl »

theo hat geschrieben:Baue Application.Processmessages in die Schleife ein.
würde bei Dir so aussehen:

Code: Alles auswählen

procedure TMetronom.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Ass:=1;
  if key=VK_Down then Ass:=0;     
  if Ass=1 then
  repeat
  PlaySound('Pfad', 0, SND_FILENAME or SND_ASYNC);
  sleep(300);
  if key=VK_Down then Ass:=0;
  Application.ProcessMessages;   //z.B. hier
  until Ass=0;
end; 
Generell würde ich Scottys Vorschlag bevorzugen:
- TTimer auf das Formular ablegen, das Intervall des Timers auf 300 stellen (im Objektinspektor)
- Im Ereignis OnTimer den Sound abspielen:

Code: Alles auswählen

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  PlaySound('Pfad', 0, SND_FILENAME or SND_ASYNC);
end; 
- Im Ereignis OnKeyDown deines Formulars den Timer an-/ausstellen:

Code: Alles auswählen

procedure TForm1.FormKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if key=VK_Down then
    Timer1.Enabled:=False
  else
    Timer1.Enabled:=True;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Tanketorion
Beiträge: 25
Registriert: Mo 7. Apr 2014, 20:55

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Tanketorion »

Ok Vielen dank für eure schnelle hilfe :)

nur jetzt stehe ich vor einem weiteren Problem.
Das Metronom soll 2 verschiedene Töne abgeben, doch es kommt immer nur einer :(

das habe ich dazu geschrieben

Code: Alles auswählen

uses mmsystem;

Code: Alles auswählen

procedure TMetronom.Timer1Timer(Sender: TObject);
begin
  if Timer1.Tag=0 then
    begin
      PlaySound('Pfad1', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=1
    end;
  if timer1.tag=1 then
    begin
      PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=2
    end;
  if timer1.tag=2 then
    begin
      PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=3
    end;
   if timer1.tag=3 then
      begin
        PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
        timer1.tag:=0
      end;
end;   

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von baumina »

Wenn ich den Code so lese, müsste er sogar alle 4 Töne pro Timerevent, wenn timer.tag=0 ist, auf einmal abspielen, denn pro Timerevent erhöhst du den tag um eins und spielst den nächsten Sound ab. Da fehlt jeweils ein Exit oder du machst es über einen case.
.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Michl »

Na dann überleg mal, was passiert:

Code: Alles auswählen

procedure TMetronom.Timer1Timer(Sender: TObject);
begin
   if Timer1.Tag=0 then      //0 ist bestimmt der vorgegebene Wert (im Objektinspektor)
     begin                   //begin wird aufgerufen
       PlaySound('Pfad1', 0, SND_FILENAME or SND_ASYNC);
       timer1.tag:=1         //Timer1.Tag wird auf 1 gestellt
     end;
   if timer1.tag=1 then      //jetzt steht Timer1.Tag schon auf 1
     begin                   //jetzt wird sofort dieser Abschnitt ausgeführt
       PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
...
Da PlaySound immer nur einen Ton wiedergeben kann, wird immer nur der erste Ton zu hören sein. Ein "else" vor dem zweiten "if" wäre möglicherweise nicht schlecht oder schau Dir mal "case" an!

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

Tanketorion
Beiträge: 25
Registriert: Mo 7. Apr 2014, 20:55

Re: Brauche hilfe bei Schleife mit OnKeyDown und sleep

Beitrag von Tanketorion »

Nochmals vielen Dank :)

Ich habe das beides mal versucht mit "else" und "case".
Dabei bin ich dann auf einen vlt schon zu leichten Lösungsweg gestoßen :lol:

Code: Alles auswählen

procedure TMetronom.Timer1Timer(Sender: TObject);
begin
  if Timer1.Tag=0 then
    begin
      PlaySound('Pfad1', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=1;
      Exit;
    end;
  if timer1.tag=1 then
    begin
      PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=2;
      Exit;
    end;
  if timer1.tag=2 then
    begin
      PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
      timer1.tag:=3;
      Exit;
    end;
   if timer1.tag=3 then
      begin
        PlaySound('Pfad2', 0, SND_FILENAME or SND_ASYNC);
        timer1.tag:=0;
        Exit;
      end;
end; 

Antworten