SetTimer_(0,0,4000,@Hidewin())

Anfängerfragen zum Programmieren mit PureBasic.
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

SetTimer_(0,0,4000,@Hidewin())

Beitrag von HemSA »

Hallole Ihr,
kann mich jemand aufklären was es mit dem Befehl und Syntaks (das ist jetzt bestimmt falsch geschrieben :( )von "SetTimer_(0,0,4000,@Hidewin())":

Code: Alles auswählen

Repeat
bla
bla
..
SetTimer_(0,0,4000,@Hidewin()) 
..
bla
bla
Until
wirklich auf sich hat?
und was es mit Verbindung von

Code: Alles auswählen

Procedur Hidewind()
Static zeit
If ElapsedMilliseconds()>zeit
zeit=ElapsedMilliseconds()+10000
bla
bla
EndProcedure
zu beachten gibt. Ich habe bei einer Anwendungs das Gefühl, dass der "Timer" ab und zu auser Tritt kommt und nicht immer die 4 sek. ( 4000 Millisekunden) abwartet.

Mehr Fragen dazu werde ich dann vielleicht noch später dazu stellen.

Vielen Dank schon mal für den Anfang.
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
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 »

Der API Timer ist für Anwendungen meist ausreichend

Code: Alles auswählen

Procedure Alle4Sekunden()
  Beep_(1000, 100)
EndProcedure

If OpenWindow(0, #PB_Ignore, 0, 640, 480, "TimerTest")
  SetTimer_(WindowID(0), 0, 4000, @Alle4Sekunden())
  
  ; bla
  While WaitWindowEvent() <> 16 : Wend
  
  KillTimer_(WindowID(0), 0)
EndIf
Erzeugt jetzt alle 4 Sekunden einen Beep
Für grössere Genauigeit hier gucken: http://www.purebasic.fr/german/viewtopic.php?t=9938
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
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

Danke ts-soft für die Antwort,
aber was ich noch nicht verstehe ist:

- WindowID(0) ==> ist die Fensternummer? Ich habe hier nur "0"
- was hat es mit der 2. "0" auf sich?

- die 4000 ==> ist wohl die "Zeit" in Millisekunden
-@Alle4Sekunden ==> ist wohl der Name der Procedure die aufgerufen wird

- der Befehl "SetTimer bla bla" wird ja bei dir auch nur 1 mal aufgerufen wie bei meinem Programm. Danach geht es ja bei dir immer in der "While - Wend"-Schleife bis 16 hin und her. Wie läuft das programmässig ab, das die Procedure immer alle 4000 ms wieder aufgerufen wird?

Danke schon mal im Vorraus ( die Genauikkeit ist für mich locker ausreichend )
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
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 »

HemSA hat geschrieben: - WindowID(0) ==> ist die Fensternummer? Ich habe hier nur "0"
- was hat es mit der 2. "0" auf sich?
Du kannst mehrere IDs vergeben, das hab ich aber ausser acht gelassen, dann muß auch die TimerProcedur erweitert werden, so ähnlich wie in dem Code zur HighresTimer!
HemSA hat geschrieben: - die 4000 ==> ist wohl die "Zeit" in Millisekunden
-@Alle4Sekunden ==> ist wohl der Name der Procedure die aufgerufen wird
genau, sind Millisekunden, die Genauigkeit ist aber in Wirklichkeit geringer, bei WinNT ca. 10 ms, bei Win9x ca 57 ms.
HemSA hat geschrieben: - der Befehl "SetTimer bla bla" wird ja bei dir auch nur 1 mal aufgerufen wie bei meinem Programm. Danach geht es ja bei dir immer in der "While - Wend"-Schleife bis 16 hin und her. Wie läuft das programmässig ab, das die Procedure immer alle 4000 ms wieder aufgerufen wird?

Danke schon mal im Vorraus ( die Genauikkeit ist für mich locker ausreichend )
Das aufrufen der Timerprocedure übernimmt Windows. Das Programm wird dadurch so gut wie nicht mehr beinträchtigt.
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
KeyPusher
Beiträge: 52
Registriert: 04.10.2006 10:56

Beitrag von KeyPusher »

der befehel 'SetTimer_' kommt aus der WinAPI. wenn du ein wenig englisch kannst, kann ich dir nur die beschreibung zu SetTimer empfehlen. übrings heisst der befehl eigentlich 'SetTimer', also ohne das '_'. aber da es sich um WinAPI handelt, wird dem befehl im PB ein '_' angehängen. so spart man sich das extra einbinden von libs oder dll's. das erledigt in dem moment pb für uns.
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

- WindowID(0) ==> ist die Fensternummer? Wenn ich also nur 1 Fenster habe dann kann ich statt: WindowID(0) einfach: "0 oder 1 oder ..." schreiben?

- was hat es mit der 2. "0" auf sich?

- das heisst dann, Windows ruft dann nach dem einmaligem Aufruf vom Programm die Prozedure xxxxx automatisch alle 4000 ms auf? Ohne jeweils wieder vom Programm aufgerufen zu werden?

Ich poste hier mal meinen Code ( den ich ohne Edel wohl nicht hätte ):

Code: Alles auswählen

   
  Procedure hauptfenster() 
    If OpenWindow(0,400,300,330,220,"İtalyanca - Release 1.1",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar ) 
    EndIf 
    
    If LoadFont(1, "Arial", 10) 
        SetGadgetFont(#PB_Default, FontID(1)) 
    EndIf
    
    
    If  LoadImage(0, "I.bmp")    
        LoadImage(1, "Tr.bmp") 
    EndIf 
    
    
    
    If CreateGadgetList(WindowID(0)) 
      TextGadget(0, 10,10, 230, 30, "Giuseppe, bana İtalyanca öğrettiğin") 
      TextGadget(1, 10,40,200, 30, "için çok teşekkür ederim.") 
      ImageGadget(2, 250,10,10, 10,ImageID(0))
      TextGadget(3, 250,70, 350, 30, "Saygılar") 
      TextGadget(4, 250,100, 350, 30, "Michael") 
      TextGadget(5, 10,130, 220, 30, "Şu anda programın kelime hazinesi: ") 
      TextGadget(6, 250,130, 150, 30, "") 
      ButtonGadget(7, 35, 170, 250, 30, "Program başlamak için tıklayın") 
    EndIf 
    
    If ReadFile(1,"Wortschatz.dat") 
        laengel.l= Lof(1) 

        zeilenanzahlw.w=laengel.l/162 
        zeilenanzahls.s= StrU((zeilenanzahlw.w), #Word) 
        SetGadgetText(6,zeilenanzahls.s) 
       CloseFile(1) 
     EndIf 
    
    
    
    
    If OpenWindow(1,50,100,250,130,"Hatırlatma pencere",#PB_Window_Invisible) 
      
      
      If LoadFont(1, "Arial", 15) 
        SetGadgetFont(#PB_Default, FontID(1)) 
      EndIf 
      
            
      
      If CreateGadgetList(WindowID(1)) 
        ImageGadget(8, 10,10,10, 10,ImageID(0))                      
        TextGadget(9, 90, 20, 150, 50, "")                            
        ImageGadget(10, 10,70,10, 10,ImageID(1))    
        TextGadget(11, 90,80, 150, 50, "") 
         
      EndIf 
      
    EndIf 
    
  EndProcedure    
  
  hauptfenster() 
  
  
  Procedure Hidewin() 
    Static zeit 
    
    If ElapsedMilliseconds() > zeit 
      zeit = ElapsedMilliseconds() + 180111
      
      If ReadFile(1,"Wortschatz.dat") 
        laengel.l= Lof(1) 
        ;Debug laengel.l
        zeilenanzahlw.w=laengel.l/162 
        zeilenanzahls.s= StrU((zeilenanzahlw.w), #Word) 
        
        zufallszeilennummerw.w= Random(zeilenanzahlw.w-1) 
        
        FileSeek(1,zufallszeilennummerw.w*162)                                        
        
        wert1s.s= StrU((zufallszeilennummerw.w+1), #Word)            
        wert2s.s=ReadString(1) 
        italienischs.s=Left(wert2s.s,40) 
        tuerkischs.s=Mid(wert2s.s,41, 40) 
        deutschs.s=Mid(wert2s.s,81, 40)
        englischs.s=Mid(wert2s.s,121, 40)
        
        SetGadgetText(9,italienischs.s)    
        SetGadgetText(11,tuerkischs.s) 
       
        Debug "Zeile: "+wert1s.s+"     Italienisch:    "+italienischs.s+"     Türkisch:    "+tuerkischs.s+"     Deutsch:    "+deutschs.s+"     Englisch:    "+englischs.s
     
        
        CloseFile(1) 
        
      EndIf 
      
      ;HideWindow(1,0) 
      SetWindowState(1, #PB_Window_Normal)
      StickyWindow(1,1)
    Else 
      ;HideWindow(1,1)
      SetWindowState(1, #PB_Window_Minimize)
    EndIf 
    
  EndProcedure 
  
  Repeat      
    
    EventID = WaitWindowEvent() 
    
    If EventID = #PB_Event_CloseWindow 
      Quit = 1 
    EndIf 
    
    If EventID = #PB_Event_Gadget    
      If EventGadget()=7
         SetTimer_(0,0,4000,@Hidewin())
         SetWindowState(0, #PB_Window_Minimize) 
      EndIf 
      
       
    EndIf 
    
  Until quit=1 
  
  
  End 
  
Nun ist mir und meinen Mitschülern aufgefallen, dass es mit der "Anzeigezeit" von 4 Sekunden ( 4000 ms ) nicht immer hinhaut. Manchmal verschwindet das Fenster schon nach vielleicht 2 Sekunden, jedenfalls in einer kürzeren Zeit - und natürlich nur manchmal.
Ich habe dann versucht es mit einer "krummen" Zahl ( 180111) zu lösen, um vielleicht einem gemeinsamen Vielfachen entgegenzuwirken - jedoch ohne Unterschied.Das Verhalten kam mir jedenfalls nicht logisch vor, deshalb meine Frage am Anfang was es mit dem Befehl SETTIMER... mit all seinen Komponenten so auf sich hat.

KeyPusher - vielen Dank,
da verstehe ich nicht viel - wird wohl viel "C" verlangt. Kommt mir dann noch komplizierter vor mit den ganzen Ausdrücken (UINT_PTR SetTimer( HWND hWnd,
UINT_PTR nIDEvent,
UINT uElapse,
TIMERPROC lpTimerFunc
).

Die "..." mache ich zum Abheben vom übrigen Text.

Es kommt der Befehl:"KillTimer " vor - ist der nötig?
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
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 »

>> WindowID(0) ==> ist die Fensternummer?
ja
>> Manchmal verschwindet das Fenster schon nach vielleicht 2 Sekunden
Das Interval ist 4 Sekunden, nicht die Dauer.
>> Es kommt der Befehl:"KillTimer " vor - ist der nötig?
Der Timer muß doch beendet werden, sonst kostet es unnütz performance.
Wenn die WindowID korrekt übergeben wurde, wird Windows den evtl. auch alleine einstellen, weil der Ansprechpartner ja fehlt :mrgreen:

Korrekt sähe die TimerProcedure in etwa so aus:

Code: Alles auswählen

Procedure Alle4Sekunden(hWnd.l, uMsg, IDEvent, dwTime)

  Select IDEvent
    Case 0 ; die zweite 0 ;)
      Beep_(1000, 100)
    Case 1
      ; andere ID, mache bla
  EndSelect
EndProcedure
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
HemSA
Beiträge: 221
Registriert: 16.10.2005 13:59
Wohnort: Manisa / Türkei
Kontaktdaten:

Beitrag von HemSA »

Hallo ts-soft,
>> Manchmal verschwindet das Fenster schon nach vielleicht 2 Sekunden
Das Interval ist 4 Sekunden, nicht die Dauer.
Das war bezogen auf mein Programm, da wird ja ein Fenster 4 Sekunden lang angezeigt, um danach sich wieder für ca. 3 Minuten sich zu minimieren ( 180111 Millisekunden ). Danach taucht es wieder auf für 4 Sekunden.
Das was mich eben stutzig macht ist, das sich das Fenster ab und zu auch schon nach einer kürzeren Zeit ( unterschiedlich - ca. 2 Sekunden - 1 Sekunde ) sich minimiert - aber eben nicht immer - ein Schönheitsfehler, den ich zu verstehen versuche.

So jetzt gehe ich aber ins Bett - und danke nochmals
PB 4.02 (wegen Disphelper), 5.72 (Windows) (x64)
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

HemSA hat geschrieben: Nun ist mir und meinen Mitschülern aufgefallen, dass es mit der "Anzeigezeit" von 4 Sekunden ( 4000 ms ) nicht immer hinhaut. Manchmal verschwindet das Fenster schon nach vielleicht 2 Sekunden, jedenfalls in einer kürzeren Zeit - und natürlich nur manchmal.
Ich habe gerade das gleiche Problem gehabt. Dabei ist mir bei der näheren Analyse aufgefallen, daß Windows selbst auch Timer-Routinen einrichtet, z.B. wenn man den Cursor über eine Schaltfläche hält, die eine Popup-Meldung hervorruft. Deshalb ist es dringend notwendig, eine eigene Timer-ID anzugeben und nicht 0 wie in ts-softs Beispiel. Außerdem sollte man eine höhere ID benutzen, auf keinen Fall 1, 2, 3 oder 4, weil die von Windows unter Umständen selbst genutzt werden. In meinem Beispiel habe ich 123 benutzt:

Code: Alles auswählen

#TimerID = 123

If OpenWindow(1, 0, 0, 100, 45, "Timer-Test", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
  If CreateGadgetList(WindowID(1))
    ButtonGadget(1, 25, 10, 50, 20, "Demo")
    GadgetToolTip(1, "Jetzt werden fremde Timer-Ereignisse generiert...")

    SetTimer_(WindowID(1), #TimerID, 4000, 0) 

    InactivitySeconds = ElapsedMilliseconds() / 1000

    Repeat
      WindowEventID = WaitWindowEvent()

      If WindowEventID = #WM_TIMER
        If EventwParam() = #TimerID
          Debug Str(ElapsedMilliseconds()/1000 - InactivitySeconds) + " Sekunden sind seit dem letzten Timer-Ereignis vergangen..."
          InactivitySeconds = ElapsedMilliseconds() / 1000
        EndIf
      EndIf
    Until WindowEventID = #PB_Event_CloseWindow

    KillTimer_(WindowID(1), #TimerID)
  EndIf
EndIf
Wenn man #TimerID = 123 setzt, wird absolut zuverlässig eine Debug-Meldung alle 4 Sekunden ausgegeben. Aber man kann ja auch einmal ausprobieren, was passiert, wenn #TimerID = 1 ist und man etwas mit dem Maus-Cursor über der "Demo"-Schaltfläche wackelt... :wink:
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Shardik hat geschrieben:Ich habe gerade das gleiche Problem gehabt. Dabei ist mir bei der näheren Analyse aufgefallen, daß Windows selbst auch Timer-Routinen einrichtet, z.B. wenn man den Cursor über eine Schaltfläche hält, die eine Popup-Meldung hervorruft. Deshalb ist es dringend notwendig, eine eigene Timer-ID anzugeben und nicht 0 wie in ts-softs Beispiel. Außerdem sollte man eine höhere ID benutzen, auf keinen Fall 1, 2, 3 oder 4, weil die von Windows unter Umständen selbst genutzt werden. In meinem Beispiel habe ich 123 benutzt:
Wo hast du denn das her ? Die ID wird nur in Verbindung mit (d)einem
Fenster genutzt. Da kann man sehr wohl 1 oder 2 schreiben.
Zuletzt geändert von edel am 22.11.2006 11:03, insgesamt 1-mal geändert.
Antworten