Entwickler-Ecke

Sonstiges (Delphi) - Auf Aktionen des Users reagieren


s00sh1 - Do 03.01.08 23:51
Titel: Auf Aktionen des Users reagieren
Hallo an alle,

habe seit langem wieder mit Delphi angefangen und habe direkt das erste Problem.
Ich möchte während einer repeat-schleife auf einen Befehl vom Benutzer zugreifen können.
D.h. während die schleife läuft, was sie zwangsläufig endlos tun wird, möchte ich prüfen, ob der Benutzer z.B. auf einen Button klickt.
Wenn dies der Fall ist, dann soll das Programm die Schleife beenden. (Hierzu habe ich schon eine Lösung im Hinterkopf aber für kreative Ideen oder Anregungen bin ich IMMER offen)

Mein Hauptproblem liegt also darin, das ich nicht weiß wie man Aktionen oder Eingaben eines Benutzers abfragt, während das Programm läuft.

Vielen Dank im voraus.


Narses - Do 03.01.08 23:57

Moin und :welcome: im Forum!

user profile icons00sh1 hat folgendes geschrieben:
D.h. während die schleife läuft, was sie zwangsläufig endlos tun wird, möchte ich prüfen, ob der Benutzer z.B. auf einen Button klickt.
Wenn dies der Fall ist, dann soll das Programm die Schleife beenden. (Hierzu habe ich schon eine Lösung im Hinterkopf aber für kreative Ideen oder Anregungen bin ich IMMER offen)
Das ist möglicherweise nicht der "richtige" Programmierstil für eine ereignisgesteuerte Anwendung (was eine Formularanwendung unter Delphi üblicherweise ist). :? Schau mal hier [http://www.delphi-library.de/topic_auf+Ereignisse+in+FormAnwendungen+warten+AppState+T1_67969.html], das sollte den richtigen Weg weisen. ;)

user profile icons00sh1 hat folgendes geschrieben:
Ich möchte während einer repeat-schleife auf einen Befehl vom Benutzer zugreifen können.
Grundsätzlich kann man sowas mit Application.ProcessMessages; innerhalb der Schleife lösen; wie aber schon oben gesagt: das scheint mir nicht der geeignete Weg zu sein... :nixweiss:

cu
Narses


oldmax - Fr 04.01.08 06:51

Hi
Grundsätzlich gebe ich Narses recht, das Schleifen, ob Repeat oder While nicht durch Useraktion, sondern durch Vergleiche aus dem Programm beendet werden sollten. Trotzdem kann ich mir vorstellen, das aus irgendwelchen Gründen diese Abbruchbedingung nicht mehr gegeben ist und dann um die Endlosschleife zu beenden, ein "Reset"-Button Rettungsanker werden soll. Dafür gibt es die Ereignisbehandlung. Du findest im Objektinspektor aller Elemente die Ereignisproceduren und durch doppelclick auf die entsprechende Spalte (onClick, onChange, onExit etc. ) generierst du den Procedurkopf. Nun brauchst du nur noch deinen Code einzufügen.
z.B. Abbruch einer Repeat-Schleife

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Bedingung:=False;  // globale boolsche variable
Repeat
  ....
  ....
  if x=y then Bedingung :=true; // globale Boolsche variable
until Bedingung;


und nun die Useraktion

Delphi-Quelltext
1:
2:
3:
4:
Procedure TMyForm.MyResetButtonClick(Sender: Tobject);
Begin
  Bedingung:=true; // Abbruchbedingung für die Repeatschleife setzen
end;

Nun ja, nicht sehr elegant und sehr anfällig....
Man beachte die globale Deklaration von "Bedingung". Dadurch ist überall im Programm möglich, diese Variable zu beinflussen und dann gibt's stundenlange Fehlersuche. Aber so kann man sich aus einer Endlosschleife retten. Besser ist jedoch immer, innerhalb der Schleife dafür zu sorgen, das diese nicht endlos läuft.
Gruß oldmax


oldmax - Fr 04.01.08 07:04

Hi,
ich nochmal mit einer kleinen Ergänzung
Bsp. für eine "Endlosschleife"

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
x:=0// können beliebige Werte sein, 
y:=1//aber diese Besetzung garantiert eine Endlosschleife...
Bedingung :=False;
Repeat
  Inc(x); // x=1
  Dec(y); // y=0
  if x=y then Bedingung:=true; // wird nie passieren
  if y<x then // damit kein Overflow eintritt
  begin
    x:=1;
    y:=0;
  end;
until Bedingung; //und schon sind wir endlos

Ist ein vereinfachtes Beispiel, wie der Code innerhalb einer Schleife die Abbruchbedingung außer Kraft setzen kann. Das zu erkennen und natürlich diese Konstellation abzufangen ist die Kunst des Programmierers.
Gruß oldmax


s00sh1 - Fr 04.01.08 14:26

@ oldmax:
so in etwa habe ich mir das auch gedacht. nur das das bei mir nicht klappt, könnte evtl an dem timer liegen der mit eingebaut ist.



die grundidee für mein programm ist irgendein hintergrundprogramm, das mit einem timer irgendeine action ausführt (z.B. einen radio-button wechsel) damit mein vitsa x64 net so oft abstürzt! wobei damit nicht garantiert ist ob das auch funktioniert ;)

das eine abbruchbedingung durch ein ereignis in der jeweiligen schleife eleganter ist, war mir vorher klar (ich danke trotzdem für den tipp!!!!). mir geht es nur darum, das man überhaupt irgendein laufendes ereignis durch einen button-click abbrechen kann.

danke für die bisherigen anregungen!
das forum hier ist echt toll und schnell ^^

gruß


platzwart - Fr 04.01.08 14:37

hi,

du könntest auch Deine durchlaufende Prozedur in einen eigenen Thread auslagern. Dann brauchst du keine globale Variable und könntest durch Benutzerinteraktion den Thread anhalten, neustarten oder beenden, halte ich für das dynamischste...


s00sh1 - Mi 09.01.08 23:06

Ich danke euch allen für eure Hilfe.
Bin hier super ins Forum reingekommen.

Hab mein Problem mit Hilfe von Application.ProcessMessages; gelöst. Super Tipp und ein riesiges DANKE an Narses!
Genau das war es was ich mehr oder weniger gesucht hatte.

Danke @ all.

Gruß s00sh1