Seite 1 von 1

Hilfe bei CreateImage und DrawText

Verfasst: 04.04.2009 19:06
von ossy
Hallo Alle,

ich experimentiere mit PB 4.3.

Und ich komme mit CreateImage und DrawText nicht weiter.
Kann sich jemand mal meinen Code anschauen und mir erklären, warum
der Text nicht angezeigt wird.

Code: Alles auswählen



Declare StartWertesetzen()
Declare SchreibeDaten()
;*****************************************
;*           Programm: Uhr               *
;*      Programmautor: Wolfgang Drescher *
;*            Version: 1.0               *
;*              Datum: 02.04.2009        *
;*****************************************

Structure Uhr

hh.w
ii.w
ss.w

butimgbr.l
butimghh.l
windowbr.l 
windowhh.l 
infimgbr.l 
infimghh.l
backcolor.l
frontcolor.l
time$


EndStructure

Global wd.Uhr


LoadFont(0,"Arial",12)

StartWertesetzen()

titel$ = "  Uhr" 
OpenWindow(0, 0, 0, wd\windowbr, wd\windowhh, titel$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget )
  SetWindowColor(0, wd\backcolor)
 

  schreibedaten()

Repeat 

Delay(1)

 With wd.Uhr
 
 Delay(1) 
 
    EventID = WindowEvent() 

     SchreibeDaten() 
      
 EndWith  
     
Until EventID = #PB_Event_CloseWindow  ; Wenn das Schliessen Button gedrückt wird, Programm beenden. 

End   ; Programm ende 


Procedure StartWertesetzen() 

With wd.Uhr

\hh=0
\ii=0
\ss=0
\windowbr = 400 
\windowhh = 400 
\infimgbr = 300 
\infimghh = 300 
\butimgbr = 100
\butimghh = 100
\time$="00:00:00"
\backcolor= RGB(20,10,100)
\frontcolor = #Yellow


EndWith

EndProcedure

Procedure SchreibeDaten()

With wd.Uhr

CreateImage(0, \infimgbr, \infimghh)

StartDrawing(ImageOutput(0)) 

  Box(0, 0, \butimgbr, \butimghh, #Red) 
  
  Circle(10,10,150,#Green)
  
  FrontColor(#Yellow) 
  DrawingMode(#PB_2DDrawing_Transparent) 
   
 \time$=FormatDate("%hh:%ii:%ss", Date())  ; zeigt die aktuelle Zeit mittels dem 00:00:00 Format 
  
 
   
  DrawText( 10,20, \time$) 
  
  Delay(10)
  
  Debug \time$
  
    
  StopDrawing()
  
  
  
  EndWith
  
  EndProcedure 
  

Besten dank im vorraus.

Wolfgang

Verfasst: 04.04.2009 19:11
von STARGÅTE
weil das Image nicht angezeigt wird.

Du brauchst ein
ImageGadget(1, 0, 0, 0, 0,ImageID(0))
nach dem erste schreibedaten()
nach Openwindow

und in der Schleife ein
SetGadgetState(1,ImageID(0))
nach dem schreibedaten()

also so:

Code: Alles auswählen

Declare StartWertesetzen() 
Declare SchreibeDaten() 
;***************************************** 
;*           Programm: Uhr               * 
;*      Programmautor: Wolfgang Drescher * 
;*            Version: 1.0               * 
;*              Datum: 02.04.2009        * 
;***************************************** 

Structure Uhr 

hh.w 
ii.w 
ss.w 

butimgbr.l 
butimghh.l 
windowbr.l 
windowhh.l 
infimgbr.l 
infimghh.l 
backcolor.l 
frontcolor.l 
time$ 


EndStructure 

Global wd.Uhr 


LoadFont(0,"Arial",12) 

StartWertesetzen() 

titel$ = "  Uhr" 
OpenWindow(0, 0, 0, wd\windowbr, wd\windowhh, titel$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget ) 
  SetWindowColor(0, wd\backcolor) 
  

  schreibedaten() 

  ImageGadget(1, 0, 0, 0, 0,ImageID(0))

Repeat 

Delay(1) 

 With wd.Uhr 
  
 Delay(1) 
  
    EventID = WindowEvent() 

     SchreibeDaten() 
     SetGadgetState(1,ImageID(0))
      
 EndWith  
      
Until EventID = #PB_Event_CloseWindow  ; Wenn das Schliessen Button gedrückt wird, Programm beenden. 

End   ; Programm ende 


Procedure StartWertesetzen() 

With wd.Uhr 

\hh=0 
\ii=0 
\ss=0 
\windowbr = 400 
\windowhh = 400 
\infimgbr = 300 
\infimghh = 300 
\butimgbr = 100 
\butimghh = 100 
\time$="00:00:00" 
\backcolor= RGB(20,10,100) 
\frontcolor = #Yellow 


EndWith 

EndProcedure 

Procedure SchreibeDaten() 

With wd.Uhr 

CreateImage(0, \infimgbr, \infimghh) 

StartDrawing(ImageOutput(0)) 

  Box(0, 0, \butimgbr, \butimghh, #Red) 
  
  Circle(10,10,150,#Green) 
  
  FrontColor(#Yellow) 
  DrawingMode(#PB_2DDrawing_Transparent) 
    
 \time$=FormatDate("%hh:%ii:%ss", Date())  ; zeigt die aktuelle Zeit mittels dem 00:00:00 Format 
  
  
    
  DrawText( 10,20, \time$) 
  
  Delay(10) 
  
  Debug \time$ 
  
    
  StopDrawing() 
  
  
  
  EndWith 
  
  EndProcedure 

ob das dein gewünschtes ergebnis ist weiß ich nicht ^^

Verfasst: 04.04.2009 19:22
von Kaeru Gaman
also, ich würde davon abraten, in der Procedure das Image zu erzeugen und das Delay reinzupacken.

außerdem wäre es sinnvoll, ein timeout beim windowevent einzusetzen,
und das darstellen noch richtig timergesteuert zu implementieren...


hier ne Demo für ein timergesteuertes Image:
http://www.purebasic.fr/german/viewtopic.php?t=19394

Habe ich verstanden.

Verfasst: 04.04.2009 19:50
von ossy
Hallo STARGÅTE,

Du hast mir sehr geholfen. :allright:
Vielen Dank.





Hallo Kaeru Gaman,

diese Timeouts waren nur verzweiflungstaten.


Gruß Wolfgang

Verfasst: 04.04.2009 20:17
von Kaeru Gaman
grundsätzlich ist es aber sinnvoll, mit einem timeout im waitwindowevent zu arbeiten,
solange du nicht grundsätzlich einen timer-callback verwenden willst.

eine eventschleife mit WindowEvent() durchlaufen zu lassen, am end noch ganz ohne Delay(), ist sehr sehr schlechter Stil!

da bietet sich schon an, das ähnlich wie in meinem Beispiel zu lösen,
oder aber gleich mit Timer-Callback.

Verfasst: 05.04.2009 22:14
von ossy
Hallo Kaeru Gaman,

habe mir mal dein Programm angesehen.
Das sieht für mich aus wie ein "interrupt".

Aus anderen Programmen kann man immer was lernen.

Danke für Deine Hilfe.

Gruß Wolfgang

Verfasst: 05.04.2009 22:48
von Kaeru Gaman
nunja... eigentlich weniger.
der Timeout begrenzt nur die Wartezeit fürs WaitWindowEvent,
und wenn kein Event anliegt, also ein Timeout aufgetreten ist,
macht man update-sachen.
in diesem Fall checke ich sogar die vergangene zeit nochmal gegen,
und agiere nur, wenn mehr als 50ms um sind.
es ist also ähnlich, als wenn man direkt nen timer mit ElapsedMilliseconds vergleicht,
nur eben hier die CPU-Nutzung runtergeschraubt durch den Timeout und Event=#Null...



mit einem "Interrupt" könnte man schon eher einen Callback vergleichen:

Code: Alles auswählen

Procedure WndProc(hWnd, uMsg, wParam, lParam)
  If uMsg = #WM_TIMER
    Debug "Schon wieder 2 Sekunden um"
  EndIf
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(0, 0, 0, 200, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  SetWindowCallback(@WndProc())
  SetTimer_(WindowID(0), 0, 2000, 0)
  While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
EndIf : End
hier wird eine Procedure eingesetzt, die bei irgendeinem Event angesprungen wird (wie ein Interrupt)
dann wird der Windows-eigene Timer eingestellt, alle 2 sec. ein Event zu senden.
in der Callback-Procedure wird gecheckt, was für ein event ihn ausgelöst hat,
und wenn das #WM_TIMER ist, wird reagiert.