Seite 1 von 3

ButtonGadget reagiert nicht sofort auf Mausklick

Verfasst: 12.07.2005 23:09
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

Verfasst: 12.07.2005 23:20
von ts-soft
Die Event-Schleife darf nicht in umgebenden Schleifen verschachtelt werden. Kenne ja Dein Problem nicht, kann Dir deshalb keine Code Posten.

Verfasst: 12.07.2005 23:21
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. ;)

Verfasst: 13.07.2005 18:42
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

Verfasst: 13.07.2005 19:03
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:

Verfasst: 13.07.2005 21:15
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

Verfasst: 13.07.2005 21:23
von bluejoke
Das EndSelect noch genauso weit einrücken wie das Select, danach gefällts mir prima!

Delay(1) - nachgefragt

Verfasst: 13.07.2005 22:34
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

Re: Delay(1) - nachgefragt

Verfasst: 13.07.2005 23:15
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

Verfasst: 13.07.2005 23:36
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).