[gelöst] onClick nur einmal..
[gelöst] onClick nur einmal..
Ich habe eine grafik mit onClick procedure.
ich will das während die procedure durchläuft
kein weiterer onclick möglich ist.
scheint unmöglich....
erster versuch: die grafik am anfang der procedure auf enabled:=false, am ende wieder auf true..
geht nicht. also dachte ich ok, nehm ich den code der durchlaufen werden soll aus der onclick procedure
raus und in eine eigene. geht auch nicht.
zweiter versuch: ich lege nach dem onclick eine andere grafik drüber und lösche sie nach dem durchlaufen wieder, auch nix.
dritter versuch: die grafik auf ein panel, bei onclick das panel disabled, danach wieder enabled, nix..
vierter versuch: onclick auf nil, nach dem durchlauf wieder auf die @procedure... auch nix..
wie mche ich es nun richtig?
ich will das während die procedure durchläuft
kein weiterer onclick möglich ist.
scheint unmöglich....
erster versuch: die grafik am anfang der procedure auf enabled:=false, am ende wieder auf true..
geht nicht. also dachte ich ok, nehm ich den code der durchlaufen werden soll aus der onclick procedure
raus und in eine eigene. geht auch nicht.
zweiter versuch: ich lege nach dem onclick eine andere grafik drüber und lösche sie nach dem durchlaufen wieder, auch nix.
dritter versuch: die grafik auf ein panel, bei onclick das panel disabled, danach wieder enabled, nix..
vierter versuch: onclick auf nil, nach dem durchlauf wieder auf die @procedure... auch nix..
wie mche ich es nun richtig?
Zuletzt geändert von atroesch am Fr 24. Okt 2025, 20:28, insgesamt 1-mal geändert.
Re: onClick nur einmal..
Wie testest du das?
Bei mir geht das so problemlos:
Linux, GTK2
Bei mir geht das so problemlos:
Code: Alles auswählen
procedure TForm1.Image1Click(Sender: TObject);
begin
Image1.OnClick:=nil;
Sleep(2000);
Memo1.Lines.Add(TimeToStr(Now));
Application.ProcessMessages;
Image1.OnClick:=@Image1Click;
end; Re: onClick nur einmal..
Application.ProcessMessages;
Danke...
- Zvoni
- Beiträge: 468
- Registriert: Fr 5. Jul 2024, 08:26
- OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
- CPU-Target: 64Bit
- Wohnort: BW
Re: [gelöst] onClick nur einmal..
Sofern das keine Multithread-Anwendung, müsste der Code in OnClick doch die Message-Queue der GUI blockieren, oder?
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
- af0815
- Lazarusforum e. V.
- Beiträge: 6984
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: [gelöst] onClick nur einmal..
Meiner Erfahrung nach -> Nein, nicht unbedingt. Ist auch vom BS abhängig.Zvoni hat geschrieben: Mo 27. Okt 2025, 08:58 Sofern das keine Multithread-Anwendung, müsste der Code in OnClick doch die Message-Queue der GUI blockieren, oder?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: [gelöst] onClick nur einmal..
Das OS-GUI und deine App sind ja heute unterschiedliche Threads.Zvoni hat geschrieben: Mo 27. Okt 2025, 08:58 Sofern das keine Multithread-Anwendung, müsste der Code in OnClick doch die Message-Queue der GUI blockieren, oder?
Weil es eben eine Queue ist, sammelt das OS die Nachrichten an deine Anwendung, welche diese dann bei Gelegenheit abholt.
Mit Application.ProcessMessages leerst du Quasi die Queue.
Bin nicht sicher, ob das so technisch korrekt beschrieben ist, aber so erkläre ich mir das.
Klar scheint, dass ohne Application.ProcessMessages du die Mehrfach-Clicks nachgereicht bekommst.
- Zvoni
- Beiträge: 468
- Registriert: Fr 5. Jul 2024, 08:26
- OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
- CPU-Target: 64Bit
- Wohnort: BW
Re: [gelöst] onClick nur einmal..
Da hab ich mich vielleicht falsch ausgedrückt:theo hat geschrieben: Mo 27. Okt 2025, 12:01Das OS-GUI und deine App sind ja heute unterschiedliche Threads.Zvoni hat geschrieben: Mo 27. Okt 2025, 08:58 Sofern das keine Multithread-Anwendung, müsste der Code in OnClick doch die Message-Queue der GUI blockieren, oder?
Weil es eben eine Queue ist, sammelt das OS die Nachrichten an deine Anwendung, welche diese dann bei Gelegenheit abholt.
Mit Application.ProcessMessages leerst du Quasi die Queue.
Bin nicht sicher, ob das so technisch korrekt beschrieben ist, aber so erkläre ich mir das.
Klar ist, dass ohne Application.ProcessMessages du die Mehrfach-Clicks nachgereicht bekommst.
"müsste der Code in OnClick doch die Message-Queue des Formulars blockieren, oder?"
Mir gings eher um das ursprüngliche Problem, so wie ich OP verstanden habe:
Er clickt auf sein Bild, und will verhindern, dass WÄHREND seine OnClick-Prozedur läuft, nochmal geclickt werden kann (and er damit einen Reentrance bekommt).
Das würde nur passieren, wenn er denn tatsächlich die Messages in der Queue abholt innerhalb seiner OnClick.
Oder will er generell verhindern, dass wenn der User mehrfach auf das Bild clickt, dass der Code dann im Nachhinein nochmal ausgeführt wird?
Weil das ist für mich die einzige Erklärung für deinen Ansatz mit dem Nil-en des Event-Handlers, aber innerhalb des Codes dann die Queue leer zu machen
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.
- af0815
- Lazarusforum e. V.
- Beiträge: 6984
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: [gelöst] onClick nur einmal..
Bei Windows ist der Queuce Scheduler angehalten mehrfache gleiche Paint Einträge zusammenzufassen und als einen Auszuliefern.theo hat geschrieben: Mo 27. Okt 2025, 12:01...Zvoni hat geschrieben: Mo 27. Okt 2025, 08:58 Sofern das keine Multithread-Anwendung, müsste der Code in OnClick doch die Message-Queue der GUI blockieren, oder?
Klar ist, dass ohne Application.ProcessMessages du die Mehrfach-Clicks nachgereicht bekommst.
https://learn.microsoft.com/de-de/windo ... age-queues sieh Nachrichten in der Warteschlange.
Zitat:
Das heisst im Umkehrschluss, das es doppelte OnClick (und andere) geben kann. Ich gehe daher schon öfters her und mache mir ein Sperrbit. Ist das gesetzt, steige ich sofort aus der Routine aus. Das Bit über try/finally natürlich absichern.Die WM_PAINT Nachricht, die WM_TIMER Nachricht und die WM_QUIT Nachricht werden jedoch in der Warteschlange beibehalten und nur dann an die Fensterprozedur weitergeleitet, wenn die Warteschlange keine anderen Nachrichten enthält. Darüber hinaus werden mehrere WM_PAINT Nachrichten für dasselbe Fenster in einer einzelnen WM_PAINT Nachricht kombiniert, wodurch alle ungültigen Teile des Clientbereichs in einem einzelnen Bereich konsolidiert werden. Durch das Kombinieren WM_PAINT Nachrichten wird die Anzahl der Wiederholungen reduziert, mit denen ein Fenster den Inhalt des Clientbereichs neu zeichnen muss.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
Re: [gelöst] onClick nur einmal..
So habe ich das verstanden. Jedenfalls scheint er mit der Lösung zufrieden zu sein, was die Frage eigentlich beantwortet.Zvoni hat geschrieben: Mo 27. Okt 2025, 12:30 Oder will er generell verhindern, dass wenn der User mehrfach auf das Bild clickt, dass der Code dann im Nachhinein nochmal ausgeführt wird?
Re: [gelöst] onClick nur einmal..
Ja genau das war das Problem.Oder will er generell verhindern, dass wenn der User mehrfach auf das Bild clickt, dass der Code dann im Nachhinein nochmal ausgeführt wird?
Ist aber mit der Antwort von Theo und Application.ProcessMessages; gelöst.
Danke nochmal...
-
Mathias
- Beiträge: 7086
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: [gelöst] onClick nur einmal..
Ich hätte dies ein wenig anders gelöst.
Einfach den EventHandle sicheren und dieser nachher wieder zurück geben.
Einfach den EventHandle sicheren und dieser nachher wieder zurück geben.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
oldhandle: TNotifyEvent;
begin
oldhandle := Button1.OnClick;
Button1.OnClick := nil;
Sleep(2000); // Mache irgend etwas
Application.ProcessMessages;
Button1.OnClick := oldhandle;
end; Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: [gelöst] onClick nur einmal..
es ging um dieses Spiel:
viewtopic.php?t=17406
wenn man auf den Würfelbecher geklickt hat,
konnte man den nochmal anklicken bevor der Wurf beendet war.
viewtopic.php?t=17406
wenn man auf den Würfelbecher geklickt hat,
konnte man den nochmal anklicken bevor der Wurf beendet war.
Re: [gelöst] onClick nur einmal..
Das würde ich mit einer Statusvariablen, z.B. "WuerfelnAktiv", lösen. Durch diese wird der Klick auf den Würfelbecher gesperrt und erst dann wieder freigegeben, wenn die eigentliche Würfel-Prozedur ausgeführt ist und die Statusvariable wieder zurückgesetzt hat.wenn man auf den Würfelbecher geklickt hat,
konnte man den nochmal anklicken bevor der Wurf beendet war.
Ungetestet:
Code: Alles auswählen
type
TForm1 = class(TForm)
procedure WuerfelBecherClick(Sender: TObject);
private
WuerfelnAktiv: Boolean;
procedure Wuerfeln;
end;
procedure TForm1.WuerfelBecherClick(Sender:TObject);
begin
if not WuerfelnAktiv then
begin
WuerfelnAktiv := true;
Wuerfeln;
end;
end;
procedure TForm1.Wuerfeln;
begin
if WuerfelnAktiv then exit;
// Hier Code für das Würfeln
WuerfelnAktiv := false;
end;