Entwickler-Ecke

Sonstiges (Delphi) - Interaktivität disable?


delphijanka - Fr 05.02.10 12:27
Titel: Interaktivität disable?
Hej Forum! Kann sein, dass meine nächste Frage bereits gestellt wurde, allerdings habe ich Probleme diese mit Stichworten zu formulieren, um entsprechende Beiträge finden zu können. Hier kommt sie:

Angenommen, ich habe ein Programm, welches zwei Buttons hat. Beide rufen diesselbe Funktion, welche viele Global-Variablen nutzt (Werte hineinschreiben etc). Wenn ich auf Button1 klicke, der Prozess noch nicht zu Ende ist, und dann auf Button2 klicke, dann gibs ein Problem: die Werte der Global-Variablen werden vom Prozess2 überschrieben und somit dem Prozess1 nutzlos gemacht (es soll die Annahme gemacht werden, dass beide Prozesse tatsächlich zwei verschiedene Prozesse, also in zwei verschiedenen Threads laufen).

Schritt 1:
Ich setze ein globales Flag, und solange der erste Prozess noch arbeitet, kann kein anderer Prozess starten. Das Drücken von Button2 würde keinen Prozess starten.
Hier kommt ein Schönheitspoint: Der Benutzer soll sehen, dass er keinen anderen Prozess starten kann, solange der erste arbeitet.

Schritt2:
Ich setzen beide Buttons auf enabled=false. Sobald der erste Prozess zu Ende ist, tue ich bei beiden Buttons enabled=true.

Das Problem ist aber, wenn ich 100 Buttons habe. Würden sie sogar in verschiedenen Fenstern liegen, die dynamisch erzeugt werden, müsste ich auf alle Fenster oder Buttons die Referenz extra abspeichern, um auf sie zugreifen zu können. Dies ist natürlich zu umständlich.

Fragen an Forum:

1) Ist es möglich, die Interaktivität des ganzen Programms irgendwie zu deaktivieren, solange ein Prozess in Ausführung ist?

2) Angenommen, ich habe doch keine Nutzung von zwei Threads, sondern einfachen Funktions-Aufruf. Würde Delphi einen neuen Prozess auf Button2-Click starten, oder würde es warten, bis die Ausführung von Button1 zu Ende ist? (Hier könnte ich natürlich nach paar Testversuchen die Frage selber beantworten, möchte aber das Risiko nicht eingehen, ob sich der Sachverhalt nur aus Zufall oder anderen Gründen so oder so ereignete, daher brauche ich eine sichere Antwort)

Danke für Ihre Mühe!


Gausi - Fr 05.02.10 12:35

Das mit den "globalen Flags" lässt sich vermutlich besser über CriticalSections lösen. Für das Deaktivieren der Buttons habe ich bisher auch noch keine wirklich schöne Lösung gefunden.

Zu deiner zweiten Frage unten (eigentlich gilt ja: Eine Frage pro Thread, aber imho gehört das hier doch irgendwie zusammen):
Solange du kein Application.ProcessMessages oder ähnliches in den Prozeduren verwendest, wird der zweite Buttonklick erst dann ausgeführt, wenn der erste komplett abgearbeitet ist. Hast du sowas aber drin, damit die Form weiter "reagiert", dann sollte man damit sehr aufpassen. ;-)


Niko S. - Fr 05.02.10 12:43

Könntest du nicht, wenn du eh die Buttons dynamisch erzeugst, einfach die Buttons die die selbe Prozedur ausführen Taggen, damit du dann später beim enabled/Disble bloß ne schleife ablaufen brauchst um alle zu enablen/disablen.
Das würde diesen aufwand mit "enabled := false" auf eine schleife reduzieren.


delphijanka - Fr 05.02.10 12:59

Nico hat folgendes geschrieben:
Könntest du nicht, wenn du eh die Buttons dynamisch erzeugst, einfach die Buttons die die selbe Prozedur ausführen Taggen, damit du dann später beim enabled/Disble bloß ne schleife ablaufen brauchst um alle zu enablen/disablen.
Das würde diesen aufwand mit "enabled := false" auf eine schleife reduzieren.

Eigentlich erzeuge ich nicht die Buttons, sondern die Fenster, die die Buttons beinhalten. Bei jedem Fenster-Erzeugnis Referenzen auf die Buttons extra abspeichern finde ich keine schöne Lösung. Ich vermute mal, es gibt einen eleganteren Weg.


Niko S. - Fr 05.02.10 13:11

Naja wenn du das so willst, musst du so oder so die Buttons platzieren, d.h. die werden eh irgendwo abgespeichert.
Ob du die jetzt im Quelltext als zur Laufzeit erzeugte Objecte hast, oder als designte Objekte in der Form datei drin, spielt finde ich keine Rolle.
Somit kannst du alle Buttons in einer Array Speichern & hast das Problem mit dem Enablen/Disablen gelöst, und das noch recht übersichtlich.

(Außer ich versteh nicht, was du vor hast)


Flamefire - Fr 05.02.10 13:29

ok du erzeugst die fenster. speicherst du die schon in einem array?
wenn nein, tu es!

Dann kannst du einfach über die fenster auf die buttons zugreifen und die deaktivieren.
vl sogar in einer extra funktion:

Delphi-Quelltext
1:
2:
3:
procedure disableButton(form:TForm) begin
form.bt1.enabled:=false//...
end


dann eifnach über das array iterieren und die funktion aufrufen.


ALF - Fr 05.02.10 13:37

So ein ähnliches Thema wurde vor kurzem sehr heiss Diskutiert!

Ich bin bei solchen Themen, immer der Meinung das Ergebniss ist das Ziel, nicht der Button, der ja nur der Auslöser ist für das eigentliche, Porcedure aufrufen, Variablen setzten, Funktione aufrufen usw. ist.

Solange also kein Ergebnis vorhanden ist (Variable gesetzt, ergebnis der Funktion usw), sollte lieber darauf geprüft werden, bevor der nächste Button aktiviert wird.
Spätestens z.B., wenn ButtonX, Button7 und Button12 aktivieren soll, wenn das Ergebinss vorhanden ist, wird es kompliziert, warum ich einmal auf Tags reagiere und dann plötzlich auf ein Ergebnis reagieren muss.

und das bei evtl 100 Buttons, kann es sehr unübersichlich werden!

Alles andere hatt user profile iconGausi ja schon erwähnt!
Gruss ALf