Menu bzw Event Fragen - Zeitproblem

Anfängerfragen zum Programmieren mit PureBasic.
willib
Beiträge: 8
Registriert: 29.12.2008 21:21
Wohnort: Bielefeld

Beitrag von willib »

Hi TS-Soft
Leider ist es derzeit bei mir so :oops:
Sollte man dann wenn Netzwerk und / oder Runprogramm mit #PB_Program_Open|#PB_Program_Read aufgerufen hat, das mit der Timertechnik wie im Beispiel machen ?
Es gibt bestimmt noch mehr, was der WaitWindowEvent() nicht abfängt und was mir jetzt auf die Schelle nicht einfällt...

Gruß Willi
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

du kannst trotzdem WaitWindowEvent mit einem Timer benutzen, Delay ist echt nich gut an der stelle.

Code: Alles auswählen

    Repeat
      Event = WaitWindowEvent(200)
      Debug ElapsedMilliseconds()
    Until Event = #PB_Event_CloseWindow 
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
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 »

Alles, was ein waitwindowevent() nicht durchbricht, z.B. Netzwerkevents,
prüfste in der Timerprocedur und behandelste dann dort, bzw. verzweigst in
neue Proceduren.

Kannst für verschiedene Probleme auch unterschiedliche Timer verwenden,
mußte nur mal im Forum ein bißchen suchen, oder API-Hilfe durchlesen,
wonach Du suchen mußt, haste ja jetzt.
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
mk-soft
Beiträge: 3845
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Mit Thread funktioniert das auch einwandfrei und man kann z.B. auf Netzwerk viel schneller reagieren. Man muss das nur einmal sauber aufbauen.

[Edit]
Habe das Beisspiel mal mit eine Datenstrukture erweitert.
Somit kann mann mit Command (*myData\cmd) den Thread aus den Menu steuern. Das Menu schreibt ein Befehltnummer und der Thread setzt diesen dann wieder auf Null.

Mal eine komplette Basis mit Thread.

Code: Alles auswählen

; Thread Example

Structure udtData
  cmd.l
  value1.l
  value2.l
  ; etc
EndStructure

Declare myThread(*myData.udtData)

;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
  #Menu_Cmd_1
  #Menu_Cmd_2
  #Menu_Cmd_3
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  #List
EndEnumeration

; ***************************************************************************************

Procedure UpdateWindow()

  Protected x,y,dx,dy
  Protected mn,st,tb
  
  x = 0
  y = 0
  mn = MenuHeight()
  st = StatusBarHeight(#StatusBar)
  ;tb = ToolBarHeight(#ToolBar)
  dx = WindowWidth(#Window)
  dy = WindowHeight(#Window) - mn - st - tb
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

Procedure WriteLog(Info.s)
  Protected temp.s
  temp = FormatDate("%YYYY.%MM.%DD %HH:%II:%SS - ", Date()) + Info
  AddGadgetItem(#List, -1, temp)
  If CountGadgetItems(#List) > 500
    RemoveGadgetItem(#List, 0)
  EndIf
  
  SendMessage_(GadgetID(#List), #LB_SETTOPINDEX, CountGadgetItems(#List) -1, 0)
  
EndProcedure

;- Globale Variablen
Global exit = 0
Global hThread
Global tmax
Global myData.udtData

;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
  ; Menu
  If CreateMenu(#Menu, WindowID(#Window))
    MenuTitle("&Datei")
      MenuItem(#Menu_Cmd_1, "Command 1")
      MenuItem(#Menu_Cmd_2, "Command 2")
      MenuItem(#Menu_Cmd_3, "Command 3")
      MenuBar()
      MenuItem(#Menu_Exit, "Be&enden")
  EndIf
  ; Statusbar
  CreateStatusBar(#Statusbar, WindowID(#Window))
  ; Gadgets
  If #True ; CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
  
  ;- Thread Starten
  hThread = CreateThread(@myThread(), @myData)
  
  ;-- Hauptschleife
  Repeat
    event   = WaitWindowEvent()
    Select event
      Case #PB_Event_Menu
        menu = EventMenu()
        Select menu
          Case #Menu_Exit
            Exit = 1
            
          Case #Menu_Cmd_1
            myData\cmd = 1
            
          Case #Menu_Cmd_2
            myData\cmd = 2
            
          Case #Menu_Cmd_3
            myData\cmd = 3
            
        EndSelect
      Case #PB_Event_Gadget
        gadget = EventGadget()
        type = EventType()
            
      Case #PB_Event_CloseWindow
        Exit = 1
      Case #PB_Event_Repaint
        window = EventWindow()
        
      Case #PB_Event_SizeWindow
        window = EventWindow()
        UpdateWindow()
        
      Case #PB_Event_MoveWindow
        window = EventWindow()
        
      Case #PB_Event_ActivateWindow
        window = EventWindow()
        
      Case #PB_Event_SysTray
        
    EndSelect
    
  Until Exit
EndIf

; Warten auf Thread Ende, wenn Thread nach 5 Sekunden nicht beendet denn Thread Killen
While IsThread(hThread)
  While WindowEvent() : Wend
  tmax + 1
  Delay(100)
  If tmax > 50
    KillThread(hThread)
    Break
  EndIf
Wend

End

; ***************************************************************************************

Procedure myThread(*myData.udtData) ; <- Ein Paremeter muss immer angegeben werden

  ; Start
  WriteLog("Start")
  
  ; Schleife
  Repeat
    Select *myData\cmd
      Case 1
        WriteLog("Command 1")
        *myData\cmd = 0
      
      Case 2
        WriteLog("Command 2")
        *myData\cmd = 0
      
      Case 3
        WriteLog("Command 3")
        *myData\cmd = 0
      
      Default
        Delay(500)
        WriteLog("Running...")
      
    EndSelect
  Until exit
  
  ; Abschluss
  WriteLog("Fertig.")
  
EndProcedure

; ***************************************************************************************
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
willib
Beiträge: 8
Registriert: 29.12.2008 21:21
Wohnort: Bielefeld

Beitrag von willib »

Hi ts soft und mk soft, hi all.
Erstmal vielen Dank besonders für die tollen Beispiele.
Das mit den Thread muß ich erstmal verdauen, das wird ein Weile dauern. :wink:
Das Timercallback Beispiel hat mein "Problem" gelöst und ich kann nun wieder mit waitwindowsevent() arbeiten, echt super. !!!
Da mein Code durcheinandergekommen ist, habe ich ein macheschön Programm entworfen. ( Zeilenausrichten , tabs , leere löschen )
Vielleicht kann das der Eine oder Andere auch gebrauchen , ist aber ohne Gewähr, der Quellcode wird nicht verändert am Ende sollte 0 rauskommen sonst mist !!. ;-).

Code: Alles auswählen

StandardFile$ = "C:\"   
Pattern$ = "PureBasic (*.pb)|*.pb|"
Pattern = 0  
File$ = OpenFileRequester("Bitte Datei zum Laden auswählen", "", Pattern$, Pattern)
If File$
  plus.s = UCase("Macro Structure If For Repeat Select Procedure while procedure.s ")
  minus.s = UCase("EndMacro EndStructure EndIf Next Until EndSelect EndProcedure wend ")
  plmi.s = "ELSE CASE "
  Ergebnis = CopyFile(File$, File$+".bak")
  Ergebnis = ReadFile(1, file$+".bak")
  Ergebnis = OpenFile(2, file$+".txt")
  nr = 0
  line=0
  While Eof(1) = 0 And nr<100       
    st.s = ReadString(1)     
    st2.s=""
    For ghj=1 To Len(st)
      ze.s=Mid(st,ghj,1)
      If Asc(ze)>31 
        st2=st2+ze
      Else
        st2=st2+" "
      EndIf
    Next ghj
    st=st2
    line = line +1
    up.s = UCase(st)
    pl = 0
    mi = 0
    pm = 0
    remz = 0
    If Trim(st) =""  ;
      ; Debug "Leer "+st
      remz =1
    EndIf
    If remz = 0
      For g= 1 To CountString(plus," ")
        sn.s= StringField(plus,g," ")
        For h=1 To CountString(up," ")+1
          snsn.s= StringField(up,h," ")
          If Left(snsn,1)=";" : h=1000 : EndIf
          If snsn = sn
            pl=1 
            Debug Str(line)+" "+Str(nr)+" + "+LSet(" ",nr)+"."+LTrim(st)
          EndIf
        Next h
      Next g
      For g= 1 To CountString(minus," ")
        sn= StringField(minus,g," ")
        For h=1 To CountString(up," ")+1
          snsn.s= StringField(up,h," ")
          If Left(snsn,1)=";" : h=1000  : EndIf
          If snsn = sn
            mi=1 
            Debug Str(line)+" "+Str(nr)+" - "+LSet(" ",nr-2)+"."+LTrim(st)
          EndIf
        Next h
      Next g
      For g= 1 To CountString(plmi," ")
        sn= StringField(plmi,g," ")
        For h=1 To CountString(up," ")+1
          snsn.s= StringField(up,h," ")
          If Left(snsn,1)=";" : h=1000 : EndIf
          If snsn = sn
            Debug Str(line)+" "+Str(nr)+" * "+LSet(" ",nr-2)+"."+LTrim(st)
            pm=1 
          EndIf
        Next h 
      Next g
    EndIf
    If mi=1 Or pm= 1 
      nr=nr -2
      If pl=1 
        nr=nr +2
        pl=0
        pm=0 
      EndIf
    EndIf
    If remz=0 
      WriteStringN(2,LSet(" ",nr)+LTrim(st))
    EndIf
    If pl=1 Or pm= 1
      nr=nr +2
    EndIf
  Wend
  CloseFile(1)       
  CloseFile(2)
EndIf
Debug "Ergebnis = " Str(line)+" "+Str(nr)
Sorry für meine Faulheit bei ein paar Zeilen... UCASE H=1000 ;-)
Sicherlich kann man einiges noch Verbessern...

Viele Grüße und einen "guten Rutsch" ins neue Jahr.

Willi
Christian H
Beiträge: 134
Registriert: 18.10.2005 10:22
Wohnort: Welschbillig

Beitrag von Christian H »

mk-soft hat geschrieben:

Code: Alles auswählen

  ; Gadgets
  If #True ; CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
Da hat sich ein kleiner Fehler eingeschlichen.

Code: Alles auswählen

  ; Gadgets
  If #True ;
    CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
Gruß u. Guten Rutsch
Christian
Andesdaf
Moderator
Beiträge: 2671
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

Christian H hat geschrieben:
mk-soft hat geschrieben:

Code: Alles auswählen

  ; Gadgets
  If #True ; CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
Da hat sich ein kleiner Fehler eingeschlichen.

Code: Alles auswählen

  ; Gadgets
  If #True ;
    CreateGadgetList(WindowID(#Window))
    ListViewGadget(#List, 0,0,0,0)
  EndIf
Gruß u. Guten Rutsch
Christian
Ab PB 4.3 baraucht man kein CreateGadgetList() unbedingt mehr.
Win11 x64 | PB 6.20
willib
Beiträge: 8
Registriert: 29.12.2008 21:21
Wohnort: Bielefeld

Beitrag von willib »

hi all
bei mir auch, die letzte Zeile muß
Debug "Ergebnis = "+ Str(line)+" "+Str(nr)
sein.

Gruß Willi
Christian H
Beiträge: 134
Registriert: 18.10.2005 10:22
Wohnort: Welschbillig

Beitrag von Christian H »

Andesdaf hat geschrieben:Ab PB 4.3 baraucht man kein CreateGadgetList() unbedingt mehr.
Ahh!
Gut zu wissen. Ich hab' noch 4.2 hier und werde dieses Jahr auch nicht mehr auf 4.3 updaten. :-)

Gruß
Christian
Andesdaf
Moderator
Beiträge: 2671
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Beitrag von Andesdaf »

> Gut zu wissen. Ich hab' noch 4.2 hier und werde dieses Jahr auch nicht mehr auf 4.3 updaten.
Naja, das aktuelle jahr geht nur noch 6 ein halb Stunden, das macht ja nicht
so nen großen Unterschied :wink:
Win11 x64 | PB 6.20
Antworten