ButtonGadget reagiert nicht sofort auf Mausklick

Anfängerfragen zum Programmieren mit PureBasic.
Peter aus der Nordheide
Beiträge: 34
Registriert: 18.05.2005 14:59

ButtonGadget reagiert nicht sofort auf Mausklick

Beitrag von Peter aus der Nordheide »

Hallo zusammen,

ich habe ein kleines Problemchen.

In einer Procedur wird eine 12-fach geschachtelte FOR-NEXT Schleife abgearbeitet.
Je nach Grenzwerte dauert das auch schon mal 30 Minuten.

Um die Events abzuarbeiten, hatte ich zuerst ein
While WindowEvent() : Wend
in die innerste FOR - NEXT Schleife eingebaut, die immer durchlaufen wird.
Soweit, so gut.

Nun möchte ich gern während der Abarbeitung der 12 geschachtelten FOR - NEXT Schleifen eine Abbruchbedingung einfügen, die Schleife verlassen, und zum Ende der Procedur gehen.

Dies soll durch Anklicken eines Button oder des Schließknopfes möglich sein.

Dazu habe ich die WHILE / WEND Schleife wie folgt erweitert :

Code: Alles auswählen

               

   While WindowEvent()  
                 
        Select = WaitWindowEvent()
              
            Case #PB_EventCloseWindow
                        
                 EventID = #PB_Event_CloseWindow
                        
                 Abbruch = Abbruch + 1
                        
                 FreeGadget(95)
                        
                 Break 13
             
            Case #PB_Event_Gadget
                  
                  EventID=EventGadgetID() 
                        
                  If EventID = 95
                        
                  Abbruch = Abbruch + 1
                        
                  FreeGadget(95)
                        
                  EndIf
                                                                                             
                  Break 13

        EndSelect
                  
   Wend

Zur Info : ButtonGadget(95, 830, 510, 145, 50, "Programm abbrechen ?")


Das Problem ist nun, daß der Klick auf den Button oder des Schließknopfes nicht immer sofort erkannt wird.

Manchmal erst beim 3-4.Mal !

Eine mögliche und sicher auch elegantere Lösung mit einem eigenständigen Thread möchte ich als PureBasic - Erstklässler naturgemäß noch nicht gehen.

Gibt es auch eine funktionierende Lösung "Zu Fuß" ?

Ich habe hier im Anfängerforum hoch und runtergeblättert, und auch schon ähnliche Fragestellungen gesehen.

Aber irgendwie haben die nicht so richtig gepaßt, oder ich habe es nicht richtig geschnallt.

Diesmal bitte nicht ein Hinweis zum Selbsterarbeiten, sondern ausnahmsweise einen kompletten Codeschnipsel.

Für Eure Hilfe schon mal herzlichen Dank.

Gruß Peter
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

Die Event-Schleife darf nicht in umgebenden Schleifen verschachtelt werden. Kenne ja Dein Problem nicht, kann Dir deshalb keine Code Posten.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Das liegt daran, dass du mehrere WaitWindowEvent (EDIT: ok, 1 waitwindowevent und ein windowevent, aber auch diese beiden zusammen sind eines zuviel) hast. Bei den Windowmessages ist es so, die werden alle auf einen Stapel gepackt und bei WaitWindowevent werden sie rausgezogen und ausgewertet, immer ein Event. Wenn du nun 2 mal hintereinander die Events herausziehst aber nur eines davon per Select auswertest, fällt eines unter den Tisch. ALso mach am Besten ein "event.l = waitwindowevent()" und arbeite dann mit der Variablen weiter. Es darf auf jeden Fall nur ein waitwindowevent pro Schleifendurchlauf sein. ;)
Peter aus der Nordheide
Beiträge: 34
Registriert: 18.05.2005 14:59

Beitrag von Peter aus der Nordheide »

Hallo zusammen,

habe jetzt wieder ein paar Stunden damit "vergeigt" und habe nun "scheinbar" eine funktionierende Lösung gefunden.

Code: Alles auswählen


 ; While WindowEvent()             ; soll ja nicht doppelt sein
                 
 Select = WindowEvent()           ; nicht WaitWindowEvent()
              
     Case #PB_EventCloseWindow
                        
          EventID = #PB_Event_CloseWindow
                        
          Abbruch = Abbruch + 1
                        
          FreeGadget(95)
                        
          Break 12                       ; 1 weniger weil while-wend wegfällt
             
     Case #PB_Event_Gadget
                  
          EventID=EventGadgetID() 
                        
          If EventID = 95
                        
          Abbruch = Abbruch + 1
                        
          FreeGadget(95)

          Break 12                       ; 1 weniger weil while-wend wegfällt
                        
          EndIf

 EndSelect
                  
 ;  Wend
              
Die Frage, die sich mir jetzt stellt, ist,
ob denn die anderen Ereignisse jetzt mit diesem Konstrukt abgearbeitet werden ?
Soweit wie ich das bis jetzt testen konnte, scheint das der Fall zu sein ?!

@Sunny

falls das obere Konstrukt zweifelhaft sein sollte, würde ich Dich bitten, daß Du mal Deinen Vorschlag hier einstellst, oder vielleicht auf jeden Fall ? :roll:

@Thomas

Das Ganze soll eine Permutation k aus n werden. In der Hauptschleife werden k und n eingegeben und dann entsprechend k die jeweiligeProcedur aufgerufen, hier k=12.
Hier wird dann die eigentliche Permutation erstellt und in einer Datei gespeichert.
Diesen "Prozess" möchte ich ggf. unterbrechen, um zur Hauptschleife zurückzukehren.

Gruß Peter
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Beitrag von ts-soft »

damit das Fenster immer neugezeichnet wird und die CPU-Auslastung runtergeht, könntest Du noch ein Default in der Selectabfrage einbauen:

Code: Alles auswählen

 ; While WindowEvent()             ; soll ja nicht doppelt sein
                 
 Select = WindowEvent()           ; nicht WaitWindowEvent()
  
  Case #PB_EventCloseWindow
    
    EventID = #PB_Event_CloseWindow
    
    Abbruch = Abbruch + 1
    
    FreeGadget(95)
    
    Break 12                       ; 1 weniger weil while-wend wegfällt
    
  Case #PB_Event_Gadget
    
    EventID=EventGadgetID()
    
    If EventID = 95
      
      Abbruch = Abbruch + 1
      
      FreeGadget(95)
      
      Break 12                       ; 1 weniger weil while-wend wegfällt
      
    EndIf
  Default
    Delay(1)
EndSelect
                 
 ;  Wend 
so das Windoofs Luft krieg, wenn nichts passiert :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Peter aus der Nordheide
Beiträge: 34
Registriert: 18.05.2005 14:59

Beitrag von Peter aus der Nordheide »

Hallo Thomas,

ja, an so etwas habe ich auch schon gedacht.

Denn während der Testerei bin ich selbst mit dem Klammeraffengriff nur mit Verzögerung dazwischengekommen.

Ist die Lösung so ok, oder gibt es eine Bessere ?

Gruß Peter
Benutzeravatar
bluejoke
Beiträge: 1244
Registriert: 08.09.2004 16:33
Kontaktdaten:

Beitrag von bluejoke »

Das EndSelect noch genauso weit einrücken wie das Select, danach gefällts mir prima!
Ich bin Ausländer - fast überall
Windows XP Pro SP2 - PB 4.00
Peter aus der Nordheide
Beiträge: 34
Registriert: 18.05.2005 14:59

Delay(1) - nachgefragt

Beitrag von Peter aus der Nordheide »

Hallo Thomas,

habe das mit Delay(1) ausprobiert, Ergebnis :

Bei der Permutation 12 aus 17 mit 6.188 Reihen brauche ich

ohne Delay 0:00 Min. und mit Delay 1:38 Min.

Jetzt wage ich kaum, mir auszurechnen, wie lange es bei 6 aus 49 mit den bekannten 14 Mio. Reihen braucht.

Kein Problem : Delay(1/1000) ---> war ein Satz mit X

Übrigens kein Fehlerhinweis durch den Compiler ??

Also, gibt es noch eine andere Möglichkeit mit kürzerer Verzögerung ?

Gruß Peter
Benutzeravatar
Batze
Beiträge: 1492
Registriert: 03.06.2005 21:58
Wohnort: Berlin
Kontaktdaten:

Re: Delay(1) - nachgefragt

Beitrag von Batze »

Peter aus der Nordheide hat geschrieben: Kein Problem : Delay(1/1000) ---> war ein Satz mit X

Übrigens kein Fehlerhinweis durch den Compiler ??
Natürlich sagt der Compiler nichts, da 1/1000 für den gleich 0 ist. :wink:

Für eine andere Verzögerung einfach eine Variable machen und dann

Code: Alles auswählen

Wait.l = 0
repeat
Wait + 1
if Wait = 1000
 delay(1)
 Wait = 0
endif

until windowevent()=#PB_Event_CloseWindow
Hier sind meine Codes (aber die Seite geht gerade nicht):
http://www.basicpure.de.vu
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

wieso nimmst du windowevent und nicht waitwindowevent? Windowevent nimmt man, wenn man einen Prozess abzuarbeiten hat, auch wenn keine Windowevents anstehen. Also es wird eben nicht auf ein Event gewartet sondern immer wieder durchlaufen. Ist vielleicht bei deinem Programm unnötig, weiß ja nicht was du genau machst. Aber ein waitwindowevent ist in den meisten Programmen sinnvoller, da dann beim Nichts-Tun des Users dort in der Schleife gewartet wird ohne Systemauslastung. Und erst wenn es Messages abzuarbeiten gibt, geht's weiter.
Wenn du allerdings DInge im Programm hast, welche in gewissen Zyklen ablaufen müssen, unabhängig von Usereingaben oder Messages, wirst du wohl ein windowevent nehmen müssen und damit dann ein Delay in Kauf nehmen. (Oder hohe Systemauslastung, wobei ich lieber das Delay nehmen würde).
Antworten