AGB  ·  Datenschutz  ·  Impressum  







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

Schleifenabbruch durch Esc Taste...

Ein Thema von Codix32 · begonnen am 1. Nov 2014 · letzter Beitrag vom 9. Nov 2014
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#1

Schleifenabbruch durch Esc Taste...

  Alt 1. Nov 2014, 19:43
Delphi-Version: 2005
Hallo,

in der CodeLib auf Delphi Praxis gibt es die Beschreibung eines Schleifenabbruchs per Tastaturdruck
mit Messagedialog Abfrage:

http://www.delphipraxis.net/98300-sc...erbrechen.html
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
   ResetEscPressed;
   for i := 0 to 10000000 do
   begin
     Caption := inttostr(i);
     if EscPressed('Schleife abbrechen ?') then Break;
   end;
end;
Beim Tastendruck wird das Hochzählen der Variablen i sofort gestoppt, aber der Messagedialog in der Funktion EscPressed wird erst 7 - 12 Sekunden später angezeigt.

Kann man da irgendwie was machen, dass der Dialog nahezu zeitgleich angezeigt wird?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Schleifenabbruch durch Esc Taste...

  Alt 1. Nov 2014, 20:28
wird erst 7 - 12 Sekunden später angezeigt.
Entweder du machst was falsch, oder du hast den Code nicht ganz verstanden.

Kann man da irgendwie was machen, dass der Dialog nahezu zeitgleich angezeigt wird?
Ja, du drückst sofort ESC und somit kommt der Dialog auch sofort.

Und nicht die ESC-Taste zu lange drücken.


-> Wenn Taste gedrückt, dann zeige den Dialog an und frag nach, ob wirklich abgebrochen werden soll.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 1. Nov 2014 um 20:30 Uhr)
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#3

AW: Schleifenabbruch durch Esc Taste...

  Alt 1. Nov 2014, 21:49
wird erst 7 - 12 Sekunden später angezeigt.
Entweder du machst was falsch, oder du hast den Code nicht ganz verstanden.

Kann man da irgendwie was machen, dass der Dialog nahezu zeitgleich angezeigt wird?
Ja, du drückst sofort ESC und somit kommt der Dialog auch sofort.

Und nicht die ESC-Taste zu lange drücken.


-> Wenn Taste gedrückt, dann zeige den Dialog an und frag nach, ob wirklich abgebrochen werden soll.
Was könnte da falsch sein?
Delphi-Quellcode:

Unit1

procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
  ResetEscPressed;
   for i := 0 to 10000000 do
    begin
     Caption := inttostr(i);
     if EscPressed('Schleife abbrechen ?') then break;
    end;
end;
...
...
...
unit Tastendruck;

interface

uses
  Windows, Dialogs, Controls;


function EscPressed(const Msg:string):Boolean;
procedure ResetEscPressed;

implementation


function EscPressed(const Msg:string):Boolean;
begin
   // Aus der WinAPI-Doku zu GetAsyncKeyState:
   // if the function succeeds, the return value specifies whether the key was pressed
   // since the last call to GetAsyncKeyState, and whether the key is currently up or down.
   // If the most significant bit is set, the key is down, and if the least significant bit is set,
   // the key was pressed after the previous call to GetAsyncKeyState.
   // The return value is zero if a window in another thread or process currently has the keyboard focus
   Result := ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0) or
     ((GetAsyncKeyState(VK_PAUSE) and $8001) <> 0);
   if Result then
   begin
      Result := (MessageDlg(Msg, mtConfirmation, [mbYes,mbNo], 0) = mrYes);
   end;
end;

// muss vor dem Benutzen von EscPressed() aufgerufen werden
procedure ResetEscPressed;
begin
   GetAsyncKeyState(VK_ESCAPE);
   GetAsyncKeyState(VK_PAUSE);
end;
Also ich drücke den Button, die Schleife wird ausgeführt und im Form1.Caption wird das Hochzählen der Schleife angezeigt. Wenn ich jetzt ESC drücke, hört das Hochzählen sofort auf, aber der 'Schleife abbrechen' Dialog wird erst nach weiteren ~7 Sekunden angezeigt. Merkwürdig... Liegt es an Windows 7 64bit?
Während der 7 Sekunden geht am Rechner nichts anderes mehr.
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#4

AW: Schleifenabbruch durch Esc Taste...

  Alt 1. Nov 2014, 22:39
Wenn man sowieso IMMER abbrechen will, kann man sich den Dialog sparen.

Delphi-Quellcode:
function EscPressed(const Msg:string):Boolean;
begin
   Result := ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0) or
     ((GetAsyncKeyState(VK_PAUSE) and $8001) <> 0);
   if Result then Result := TRUE;
end;
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#5

AW: Schleifenabbruch durch Esc Taste...

  Alt 1. Nov 2014, 22:54
Wenn man sowieso IMMER abbrechen will, kann man sich den Dialog sparen.

Delphi-Quellcode:
function EscPressed(const Msg:string):Boolean;
begin
   Result := ((GetAsyncKeyState(VK_ESCAPE) and $8001) <> 0) or
     ((GetAsyncKeyState(VK_PAUSE) and $8001) <> 0);
   if Result then Result := TRUE;
end;
Das Stimmt. Aber jetzt habe ich das Problem, dass nach dem Klick auf Escape die Schleife zwar gebreakt wird, aber wenn ich versuche, das Formular zu schliesen, dauert das gut 7 Sekunden. Das Programm scheint einzufrieren.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Schleifenabbruch durch Esc Taste...

  Alt 2. Nov 2014, 00:03
Klingt so, als wenn im Hintergrund die Schleife noch laufen und das Formular blockieren würde. Entweder man ruft in der Schleife Application.ProcessMessages auf oder man lagert das alles in einen Thread au.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#7

AW: Schleifenabbruch durch Esc Taste...

  Alt 2. Nov 2014, 21:24
Klingt so, als wenn im Hintergrund die Schleife noch laufen und das Formular blockieren würde. Entweder man ruft in der Schleife Application.ProcessMessages auf oder man lagert das alles in einen Thread au.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
  ResetEscPressed;
   for i := 0 to 10000000 do
    begin
     Application.ProcessMessages;
     Caption := inttostr(i);
     if EscPressed('Schleife abbrechen ?') then break;
    end; //For
    Label1.Caption:= 'stop';
end; //proc
Application.ProcessMessages bringt keine Änderung.

Beim Klick auf ESC zeigt das Label sofort 'Stop' an, die Schleife wird also sofort verlassen.
Es muss einen anderen Grund geben. Gibt es eine andere Möglichkeit als GetAsyncKeyState?
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#8

AW: Schleifenabbruch durch Esc Taste...

  Alt 2. Nov 2014, 21:58
Keine Ahnung, was bei dir los ist, aber bei mir funktioniert dein Code. Ich würde in jedem Fall in die Schleife ein Sleep einbauen, damit andere Threads und Prozesse Zeit bekommen und dein Thread nicht die CPU voll auslastet. Ein Sleep(1); reicht da schon aus. Warum überhaupt eine for-Schleife mit einem hohen Zahlenwert als Abbruchbedingung statt einer while- oder repeat-until-Schleife?

MfG Dalai
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#9

AW: Schleifenabbruch durch Esc Taste...

  Alt 5. Nov 2014, 23:15
Keine Ahnung, was bei dir los ist, aber bei mir funktioniert dein Code. Ich würde in jedem Fall in die Schleife ein Sleep einbauen, damit andere Threads und Prozesse Zeit bekommen und dein Thread nicht die CPU voll auslastet. Ein Sleep(1); reicht da schon aus. Warum überhaupt eine for-Schleife mit einem hohen Zahlenwert als Abbruchbedingung statt einer while- oder repeat-until-Schleife?

MfG Dalai
Vielen lieben Dank Dalai,

das Sleep(1) sorgt tatsächlich dafür, dass ich nach dem Klick auf ESC das Formular schließen kann.

Ich habe das Sleep einfach mal so eingefügt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   i : Integer;
begin
  ResetEscPressed;
   for i := 0 to 10000000 do
    begin
     Application.ProcessMessages;
     Caption := inttostr(i);
     Sleep(1); //<- Sleep in der Schleife
     if EscPressed('Schleife abbrechen ?') then break;
    end; //For
    Label1.Caption:= 'stop';
    Application.ProcessMessages;
    Button1.Enabled:=false;
end; //proc
Was ich gern verstehen würde, warum das so funktioniert, denn:

Denn auch ohne Sleep zeigt das Label1 sofort 'Stop' an,wenn ich ESC drücke, das heißt doch, dass die Schleife auch verlassen ist. Warum brauche ich jetzt das Sleep um das Form schließen zu können? Was passiert da noch im Hintergrund? Und ich wäre jetzt nicht darauf gekommen da ein Sleep einzubauen.
Und warum nun eine 4Kern CPU von einer Form.exe total eingenommen wird, wenn da
ein GetAsyncKeyState(VK_ESCAPE) in einer Schleife drin ist, verstehe ich ebenfalls nicht.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#10

AW: Schleifenabbruch durch Esc Taste...

  Alt 6. Nov 2014, 00:21
Ganz einfach: das Sleep erlaubt, anderen Prozessen und Threads zu arbeiten. Ohne das Sleep geht die Schleife so schnell durch, wie es dein Prozessor erlaubt - und "blockiert" damit auch den Thread, der sich um die GUI kümmert. Übrigens wird nur ein Kern ausgelastet, nicht mehr - ist ja nur ein Thread und ein Thread kann gleichzeitig nur auf einem Kern laufen.

MfG Dalai
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 5  1 23     Letzte »    


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 21:36 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