Seite 1 von 4

WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 10:43
von alDo
Hallöchen, sitz schon seit ein paar Tagen an dem Problem, dass WaitWindowEvent die Werte für nicht ausgelöste Events in meine Event-Variable speichert. Daraufhin verläuft der Programmablauf nicht wie geplant (Select usw.). Der Fehler lässt sich leider nicht in einen Testcode reproduzieren, sondern tritt nur in meinem Projekt auf :angry: Enable Explicit ist aktiviert also keine Rächtschraipfehler :freak:
Achtung der Code ist offensichtlich nicht ausführbar, da ich die serielle Schnittstelle benutze.
Folgend der Code zum Verständnis in dem ich die Variable verwende(manipuliere).
Eine Prozedur zum Auswählen des Comports (die Variable Event ist zwar Protected aber man kann ja nie wissen):

Code: Alles auswählen

Procedure.s selectComport()
  
  Protected Event, GadgetID, COMPORT$, EXIT, i
  
  If OpenWindow(#WINDOW_SELECT,#PB_Ignore,#PB_Ignore,230,60,"Select Comport",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ComboBoxGadget(#COMBO_BOX   , 10, 30,130, 20,#PB_ComboBox_UpperCase)
      ButtonGadget(#SELECTButton,150, 30, 70, 20,"Select")
        TextGadget(#SELECTText  , 10, 10,190, 20,"Select the available comport:",#PB_Text_Right)
  EndIf
  
  For i=2 To 100
    If ReadFile(0,"COM"+Str(i)+":")                ; try to read the comport i
      AddGadgetItem(#COMBO_BOX,-1,"COM"+Str(i))    ; add available COM to combobox
      CloseFile(0)                                 ; close comport
    EndIf
  Next
  
  SetGadgetState(#COMBO_BOX,0)
  
  Repeat
    Event = WaitWindowEvent()
    GadgetID = EventGadget()
    
    Select Event
      
      Case #PB_Event_Gadget
        
        If GadgetID = #COMBO_BOX
        
        ElseIf GadgetID = #SELECTButton
          COMPORT$ = GetGadgetText(#COMBO_BOX)
          CloseWindow(#WINDOW_SELECT)
          ProcedureReturn COMPORT$
          
        EndIf
      
      Case #PB_Event_CloseWindow
        EXIT = 1
      
    EndSelect
    
  Until EXIT
  
  End
  
EndProcedure
Diese Prozedur wird vor der Main Loop einmalig aufgerufen und läuft nie zeitgleich mit dieser.
Die Main-Loop:

Code: Alles auswählen

Define n, StartTime, Event, EventGadget, EXIT
StartTime = ElapsedMilliseconds()
Repeat                                                                       ; eventloop
  Event = WaitWindowEvent(10)
  EventGadget = EventGadget()
  
  Result = AvailableSerialPortInput(SerPort)
  Select Event
    
    Case #Null                                                               ; timeout
      SetGadgetText(#CAN_MESSAGERECBYTESString,Str(Result))                  ; number of received bytes
      If Result > 7                                                          ; filtering garbage
        receiveCANMessage()
      EndIf
      
    Case #PB_Event_Gadget
      handleButtons(EventGadget)
      
    Case #PB_Event_CloseWindow
      EXIT = 1
      
  EndSelect
  
Until EXIT
closeCAN(SendBuffer())
CloseSerialPort(SerPort)
DisableExplicit
End
Zur seriellen Schnittstelle: vor der Main Loop öffne ich nur die Schnittstelle (und erstelle das Fenster :roll: ) und während die Main Loop den Fehler erzeugt treffen keineDaten ein.
Der Debugger zeigt mir für die Konstante #PB_Event_Gadget den Wert 332C an und genau dieser Wert ist auch in meiner Event-Variablen enthalten obwohl ich keinen Button betätige oder auch nur die Maus bewege. Merkwürdigerweise wechselt die Variable Event alternierend zwischen den Werten 0(=#Null) und 332C(=#PB_Event_Gadget) nach jedem Schleifendurchlauf. Stehe für Rückfragen bereit und hoffe auf eine Lösung für dieses Problem.
Gruss alDo

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 11:55
von Kaeru Gaman
du benutzt sowohl in deiner Procedure als auch in deiner Main ein WaitWindowEvent.

Ausschließlich wenn die Proc als Thread aufgerufen wird, ist diese Vorhehensweise korrekt.
Andernfalls sind Proc und Main nicht gegeneinander gekapselt und benutzen die selbe Eventqueue.

Benutze also nur einmal WaitWindowEvent, nämlich in der Hauptschleife.
treffe dort eine Unterscheidung, in welchem Fenster das Event anliegt.
http://www.purebasic.fr/german/viewtopi ... 52&start=0

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 12:32
von alDo
Vielen Dank Kaeru :D

Wie kann ich es denn erreichen, dass ein Fenster so lange es geöffnet ist den Fokus behält bis es geschlossen wird oder alle Aktionen beendet sind?
Hintergrund: Mein kleines Auswahlfenster ploppt beim Programmstart auf und fordert den User auf einen Comport auszuwählen. Daraufhin wird die ausgewählte serielle Schnitstelle geöffnet und ein grosses Fenster öffnet sich auf dem ganz viele tolle Sachen geschehen :wink:
Mein Ziel wäre es nun das kleine Auswahlfenster sticky zu machen und so den Zugriff auf das Grosse zu unterbinden, so lange kein Comport ausgewählt wurde. Dies ist nötig, da ich ja die Fenster logischerweise vor der Eventloop erstellen muss.
Kennt jemand evt. ein Flag oder ähnliches dafür?

Gruss alDo

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:03
von Kiffi
@alDo:

PseudoCode

Code: Alles auswählen

KleinesFensterÖffnen

EventschleifeAnfang

 EventAbfragen

 If Event = FensterSchliessen
  If EventKommtVon = KleinesFenster
    KleinesFensterSchliessen
    GrossesFensterÖffnen
  Endif
 EndIf

EventschleifeEnde
Grüße ... Kiffi

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:04
von Kaeru Gaman
du bekommst ein Werzeugfenster modal, indem du es zum Child des Hauptfensters machst, und das Hauptfanster Deaktivierst.
also beim Child beim Öffnen die ParentID angeben: WindowID(#HauptFenster) und DisableWindow(#HauptFenster, 1),
und wenn du vom Child das Close-Event bekommst,
schließt du es CloseWindow(#WINDOW_SELECT) und aktivierst das Hauptfenster wieder DisableWindow(#HauptFenster, 0)
sämtliche Events beider Fenster handelst du in einer Hauptschleife ab.

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:08
von ts-soft
Kaeru Gaman hat geschrieben:du benutzt sowohl in deiner Procedure als auch in deiner Main ein WaitWindowEvent.

Ausschließlich wenn die Proc als Thread aufgerufen wird, ist diese Vorhehensweise korrekt.
Nein, WaitWindowEvent funktioniert nur im Erstellerthread des Fensters!

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:22
von Kaeru Gaman
ts-soft hat geschrieben:
Kaeru Gaman hat geschrieben:du benutzt sowohl in deiner Procedure als auch in deiner Main ein WaitWindowEvent.

Ausschließlich wenn die Proc als Thread aufgerufen wird, ist diese Vorhehensweise korrekt.
Nein, WaitWindowEvent funktioniert nur im Erstellerthread des Fensters!
korrekt, er erstellt ja auch das Zweitfenster innerhalb der Proc, wo er versucht nur dessen Events mit einem WaitWindowEvent zu empfangen...
als Thread wäre diese Vorgehensweise ja auch richtig.

... wobei mir grad durch den Kopf geht, dass es ja eigentlich trotzdem gehen müßte, wenn die
Eventschleife in der Proc korrekt aufgebaut ist, die Äußere wird in der Zeit ja nicht benutzt.

aber mangels Testbarkeit habe ich nunmal zuerst angesprochen was mit zuerst auffiel.
schon oft hat es geholfen, wenn man unklaren Code in sauberen verwandelt hat, etliche Fehler verschwinden dann schon.

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:23
von alDo
Also habe jetzt mein Code geändert und trotzdem gibt mir die Debug Ausgabe den Wert der Konstanten #PB_Event_Gadget an. Vielleicht hab ich noch etwas nicht beachtet.
Kleines Fenster:

Code: Alles auswählen

Procedure createSelectWindow()
  
  Protected i
  
  If OpenWindow(#WINDOW_SELECT,#PB_Ignore,#PB_Ignore,230,60,"Select Comport",#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_TitleBar|#PB_Window_ScreenCentered)
    ComboBoxGadget(#COMBO_BOX   , 10, 30,130, 20,#PB_ComboBox_UpperCase)
      ButtonGadget(#SELECTButton,150, 30, 70, 20,"Select")
        TextGadget(#SELECTText  , 10, 10,190, 20,"Select the available comport:",#PB_Text_Right)
    
    For i=2 To 100
      If ReadFile(0,"COM"+Str(i)+":")                ; try to read the comport i
        AddGadgetItem(#COMBO_BOX,-1,"COM"+Str(i))    ; add available COM to combobox
        CloseFile(0)                                 ; close comport
      EndIf
    Next
  
    SetGadgetState(#COMBO_BOX,0)
    
  EndIf
  
EndProcedure
Und die Main Loop:

Code: Alles auswählen

createSelectWindow()
StartTime = ElapsedMilliseconds()
Repeat                                                                       ; eventloop
  Event = WaitWindowEvent(10)
  EventWindow = EventWindow()
  EventGadget = EventGadget()
  Debug Event
  Select Event
    
    Case #Null                                                               ; timeout
      If WindowMain
        Result = AvailableSerialPortInput(SerPort)
        SetGadgetText(#CAN_MESSAGERECBYTESString,Str(Result))                  ; number of received bytes
        If Result > 7                                                          ; filtering garbage
          receiveCANMessage()
        EndIf
      EndIf
      
    Case #PB_Event_Gadget
      Select EventWindow
        
        Case #WINDOW_SELECT
          If EventGadget = #SELECTButton
            COMPORT$ = GetGadgetText(#COMBO_BOX)
            CloseWindow(#WINDOW_SELECT)
            initCAN(COMPORT$)
            createMainWindow()
            WindowMain = #True
          EndIf
          
        Case #WINDOW_MAIN
          handleButtons(EventGadget)
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      If EventWindow = #WINDOW_MAIN
        closeCAN(SendBuffer())
        CloseSerialPort(SerPort)
      EndIf
      EXIT = 1
      
  EndSelect
  
Until EXIT
DisableExplicit
End

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:28
von Kaeru Gaman
nuja... ist ja schwierig was zu sagen, schließlich sieht man nicht mal ob sich IDs überschneiden oder so.

was mir grundsätzlich ins Auge fällt:
beim erstellen deines Fensters in der Proc führst du 99 mal ein AddGadgetItem aus und dann noch ein SetGadgetState.
damit solltest du logischer Weise erst mal mindestens Hundert Events auf dem Gadget haben, die dann natürlich auch erst mal verarbeitet werden müssen.

warum packst du diese Aktion nicht auch ins TimeOut?

Re: WaitWindowEvent erhält nicht ausgelöste Events

Verfasst: 02.03.2010 13:41
von alDo
Welche IDs meinst du, die sich überschneiden könnten?

Wenn ich es so mache klappts auch nicht :(

Code: Alles auswählen

createSelectWindow()
WindowSelect = #True
StartTime = ElapsedMilliseconds()
Repeat                                                                       ; eventloop
  Event = WaitWindowEvent(10)
  EventWindow = EventWindow()
  EventGadget = EventGadget()
  Debug Event
  Select Event
    
    Case #Null                                                               ; timeout
      If WindowSelect
        For n=2 To 100
          If ReadFile(0,"COM"+Str(n)+":")                ; try to read the comport n
            AddGadgetItem(#COMBO_BOX,-1,"COM"+Str(n))    ; add available COM to combobox
            CloseFile(0)                                 ; close comport
          EndIf
        Next
        SetGadgetState(#COMBO_BOX,0)
      EndIf
      
      If WindowMain
        Result = AvailableSerialPortInput(SerPort)
        SetGadgetText(#CAN_MESSAGERECBYTESString,Str(Result))                  ; number of received bytes
        If Result > 7                                                          ; filtering garbage
          receiveCANMessage()
        EndIf
      EndIf
      
    Case #PB_Event_Gadget
      Select EventWindow
        
        Case #WINDOW_SELECT
          If EventGadget = #SELECTButton
            COMPORT$ = GetGadgetText(#COMBO_BOX)
            CloseWindow(#WINDOW_SELECT)
            initCAN(COMPORT$)
            createMainWindow()
            WindowSelect = #False
            WindowMain   = #True
          EndIf
          
        Case #WINDOW_MAIN
          handleButtons(EventGadget)
          
      EndSelect
      
    Case #PB_Event_CloseWindow
      If EventWindow = #WINDOW_MAIN
        closeCAN(SendBuffer())
        CloseSerialPort(SerPort)
      EndIf
      EXIT = 1
      
  EndSelect
  
Until EXIT
DisableExplicit
End