AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

VCL Elemente in geblocktem Ereignishandler disablen

Ein Thema von Viktorii · begonnen am 21. Aug 2012 · letzter Beitrag vom 21. Aug 2012
Antwort Antwort
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#1

VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 08:47
Moin.

Wie im Titel schon geschrieben möchte ich VCL Elemente (vier Buttons) in einer Ereignishandler eines Buttons disablen.

Dieser Ereignishandler ist für eine gewisse Zeit geblockt und während dieser Zeit sollen die Buttons disabled sein. Da beim Blocken ja keine Window Messages verarbeitet werden können, habe ich es mit repaint, refresh und processmessages probiert. Alles ohne Erfolg:

Delphi-Quellcode:
procedure TForm2.Button2Click(Sender: TObject);
begin
  button1.Enabled := false;
  button1.Refresh;
  button1.Repaint;
  button2.Enabled := false;
  button2.Refresh;
  button2.Repaint;
  button3.Enabled := false;
  button3.Refresh;
  button3.Repaint;
  button4.Enabled := false;
  button4.Refresh;
  button4.Repaint;

  Form2.Refresh;
  Form2.Repaint;

  Application.ProcessMessages;

  sleep(5000);

  button1.Enabled := true;
  button2.Enabled := true;
  button3.Enabled := true;
  button4.Enabled := true;
end;
Es wird nur der geklickte Button disabled. Alle anderen Buttons werde erst nach den fünf Sekunden disabled und sofort wieder enabled.

Wie muss ich es richtig machen?
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#2

AW: VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 08:51
Vielleicht solltest du nicht Sleep verwenden, sondern z.B. einen Timer. Der blockiert den MainThread nicht und du hättest das, was du willst.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#3

AW: VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 08:58
Man kann mit der VCL nicht so umgehen, als ob jeder Aufruf einer Methode einen unmittelbaren Effekt hätte. Insbesondere die Methoden/Eigenschaften zur Veränderung des Aussehens (Enable, Visible, Caption etc.) sollten eher nach dem Motto: "Bitte ausführen, wenn die Anwendung mal wieder Zeit hat" gehandhabt werden.

So ein Formular wartet ja eigentlich immer, das der Anwender irgendwo raufklickt oder sonstwas anstellt. Und nur in der Zeit werden die o.g. Anforderungen an Layoutänderungen abgearbeitet.

Man kann z.T. mit 'Update', 'Repaint' usw. das Neuzeichnen forcen, aber so richtig schick ist das nicht, da das Formular dann zwar u.U. statisch neu gezeichnet wird, aber nur einmalig.

Du willst bei einem Buttonklick eine Aktion starten und solange diese Aktion läuft, soll der Button nicht klickbar sein? Aber das Fenster soll man ja noch verschieben dürfen, oder?

Verwende einen Thread. Im OnClick des Start-Buttons startest Du dem Thread und disablest den Button. Dem Thread sagst Du, das er bei Beendigung (OnTerminate) den Button wieder enablen soll.

Dann musst Du nur im OnClose-Ereignis des Formulars eine ggfs. aktive Instanz des Threads terminieren.
  Mit Zitat antworten Zitat
Viktorii

Registriert seit: 19. Jul 2007
358 Beiträge
 
#4

AW: VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 09:10
Das ganze ist für kleines Tool eine Quick and Dirty Lösung. Das sleep ist hier nur ein Platzhalter. Eigentlich wird eine Funktion aufgerufen die für eine gewisse Zeit blockiert...

Habe für das Tool eigentlich keine Lust mit mehreren Threads zu hantieren. Mit ist klar, dass das Fenster für die Zeit nicht verschiebbar bzw. für Benutzereingaben nicht empfänglich ist. Es soll durch das disablen nur eine optisches Feedback gegeben werden, dass das Tool beschäftigt ist.

Man kann mit der VCL nicht so umgehen, als ob jeder Aufruf einer Methode einen unmittelbaren Effekt hätte. Insbesondere die Methoden/Eigenschaften zur Veränderung des Aussehens (Enable, Visible, Caption etc.) sollten eher nach dem Motto: "Bitte ausführen, wenn die Anwendung mal wieder Zeit hat" gehandhabt werden.
Ich dachte genau dafür ist processmessage da. Man sagt: "Nimm dir jetzt Zeit um alles abzuarbeiten was angefordert ist und mache erst dann weiter" (in diesem Fall das disablen). Also lässt die VCL solch eine Lösung nicht zu?
  Mit Zitat antworten Zitat
Furtbichler
(Gast)

n/a Beiträge
 
#5

AW: VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 09:35
Also bei mir funktioniert es, allerdings ohne das ganze Repaint/Refresh-Gedöns.

Im Zweifelsfall rufst Du in deiner Schleife immer mal wieder Application.Processmessages auf.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

AW: VCL Elemente in geblocktem Ereignishandler disablen

  Alt 21. Aug 2012, 10:56
SO sollte das aussehen:
Delphi-Quellcode:
procedure TForm2.EnableButtons(en:Boolean);
begin
  button1.Enabled := en;
  button2.Enabled := en;
  button3.Enabled := en;
  button4.Enabled := en;
end;

procedure TForm2.MachDieArbeit;
var
  i : Integer;
begin
  for i:= 1 to ANZAHL_HAARE_IM_WASCHBECKEN do
  begin
    // der "Trick" ist, immer mal wieder Application.ProcessMessages aufzurufen
    // um die GUI upzudaten und auf Messages zu reagieren
    // Macht man dies aber zu oft, dann verlängert sich die Gesamtzeit
    // mit der Modulo-Abfrage kann man die Anzahl der Aufrufe entsprechend reduzieren
    // es kommt halt immer auf den konkreten Fall an
    if (i mod 10) = 0 then
      Application.ProcessMessages;
    
    Sleep(20); // Platzhalter für blockierenden Code
  end;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
  EnableButtons(False);
  try
    MachDieArbeit;
  finally
    EnableButtons(True);
  end;
end;
Andreas

Geändert von shmia (21. Aug 2012 um 11:06 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 15:15 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