Seite 1 von 3

StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 05:27
von BSP
Hallo.
Gibt es eine Möglichkeit zu erkennen,
ob ein StartDrawing - Block gerade offen ist?

Zum Hintergrund der Frage:
Ich lasse über ein "SetTimer_" eine kleine Grafik Uhr laufen.
Im Hauptprg laufen aber auch Grafikfunktionen ab.
Dabei kommt es gelegentlich in der Uhrprocedur zu konflikten
mit "StopDrawing muss erst aufgerufen werden".

Nun kann ich natürlich vor jeder Zeichenoperation die Uhr kurz ausschalten,
KillTimer_()
Oder ich setze eine Globale Var, die gesetzt und gelöscht wird.

Global op = 0
op = StartDrawing()
StopDrawing()
op = 0
In der Uhr dann "op" abfragen und g.G. abbrechen.

Schöner wäre es aber, wenn ich in der Uhrprocedure prüfen kann,
ob gerade ein "StartDrawing" offen ist.

Habt Ihr eine (einfache) Lösung?
Gruß: BSP

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 05:50
von STARGÅTE
Vorab:
Es wäre einfacher für dich, wenn du AddWindowTimer von PB nehmen würdest, und bei jedem Time-Event dann deine Uhr aktuallisierst.

Ansonsten, in der Hilfe steht:
StartDrawing() hat geschrieben:Wenn "Erstelle threadsicheres Executable" in den Compiler-Optionen aktiviert ist, dann hat jeder Thread seine eigene aktuelle Zeichenausgabe. Dies bedeutet, dass zwei Threads zur gleichen Zeit auf verschiedene Ausgaben zeichnen können.
Die beiden StartDrawings sollten eigentlich beide aufrufbar sein, außer SetTimer_ macht gar kein Thread auf.

Edit: PB-Timer:

Code: Alles auswählen

Enumeration
	#Window
	#Timer
	#Gadget
EndEnumeration

Procedure LineAR(X.i, Y.i, Radius.i, Angle.f, Color.i)
	LineXY(X, Y, X+Radius*Cos(Radian(Angle)), Y+Radius*Sin(Radian(Angle)), Color)
EndProcedure

OpenWindow(#Window, 0, 0, 300, 300, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
	AddWindowTimer(#Window, #Timer, 20)
	CanvasGadget(#Gadget, 0, 0, 300, 300)
	
Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
		Case #PB_Event_Timer
			Select EventTimer()
				Case #Timer
					StartDrawing(CanvasOutput(#Gadget))
						Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
						LineAR(200, 150, 50, 360*ElapsedMilliseconds()/1000, 0)
						LineAR(150, 150, 140, 360*Second(Date())/60-90, 0)
						LineAR(150, 150, 120, 360*(Minute(Date())+Second(Date())/60)/60-90, 0)
						LineAR(150, 150, 90, 360*(Hour(Date())+Minute(Date())/60)/12-90, 0)
					StopDrawing()
			EndSelect
		Case #PB_Event_Gadget
			Select EventGadget()
			EndSelect
			
	EndSelect
	
ForEver

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 07:12
von BSP
Hallo STARGÅTE.
Mit AddWindowTimer hatte ich das ursprünglich auch mal gemacht.
Aber das läuft nur im aktuellem Fenster.
Auch dann, wenn ich im WaitWindowEvent() einen Wert eingebe.
WaitWindowEvent(10)
Habe ich einen Dialog offen, steht die Uhr erst einmal.
(Es sei denn, ich baue die Eventabfrage auch im DialogFenster ein).

Ein threadsicheres Executable erzeugt bei mir einen Linkerfehler. Oder so.
Und ich wollte mich nun nicht auch deswegen wieder stundenlang durch Forum wuseln,
um das Problem zu lösen.

Um an meinen derzeitigen Aufgaben zu arbeiten statt lange zu suchen habe ich nun erst einmal wieder meine "TextUhr" eingesetzt.
Obwohl mir die nicht so gut gefällt,
da das Textgadget beim aktuallisieren mit SetGadgetText immer so blöde blinkt.

Schade.
Ich hatte gehofft, es gibt über die WinApi eine schnelle & einfache Lösung.

Aber trotzdem vielen Dank für Deinen Hilfeversuch.
Gruß: Bernd (BSP)

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 07:31
von Danilo
BSP hat geschrieben:Ein threadsicheres Executable erzeugt bei mir einen Linkerfehler. Oder so.
Das sollte nicht sein. Kannst Du mal ein kleines Beispiel dazu machen, wie Du die
zwei StartDrawings benutzt und was für ein Linkerfehler dann kommt?

Ohne Threadsicher mußt Du wohl selbst sicherstellen das nur ein StartDrawing/StopDrawing
auf einmal läuft, z.B. über einen Mutex.

Code: Alles auswählen

Global drawingMutex = CreateMutex()


LockMutex(drawingMutex)
    If StartDrawing( ... )
        ; ...
        StopDrawing()
    EndIf
UnlockMutex(drawingMutex)

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 08:00
von BSP
Hallo Danilo.
Nein, den Fehler kann ich z.Z nicht reproduzieren.
Scheinbar will mein Prg etwas haben, was ich ihm nicht biete.
(Schlecht, wenn man zu wenig Englisch kann).
Andere Prg's laufen.

Hier die Fehlermeldung:
POLink: error: Unresolved external symbol ‘_PB_StringBasePosition’.
POLink: fatal error: 1 unresolved external(s)

Das mit den MUTEX werd ich mal ausprobieren.

Gruß & Dank: Bernd

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 08:40
von BSP
Nachtrag:
Habe das mit dem Mutex mal ausprobiert, bringt aber nichts.
Nun gut.
Dann setze ich also vor jeden StartDrawing einen KillTimer_,
nach jeden StopDrawing schalte ich den Timer wieder an.
Dann sollte es dieses Problem nicht mehr geben.
Obwohl; Eventuell doch, weil es ja sein kann, das mein Prg gerade zeichnen will wenn die Uhr gerade aktualisiert.
Dann versichte ich besser auf diesen Timer und setze die Uhr direkt in die Eventschleife mit WaitWindowEvent(10) .
Mal sehen. Kommt hier ja nicht so genau drauf an. Smile.

Gruß: Bernd

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 10:26
von DarkDragon
BSP hat geschrieben:Hallo.
Gibt es eine Möglichkeit zu erkennen,
ob ein StartDrawing - Block gerade offen ist?
Evtl. liefert OutputWidth/OutputHeight/OutputDepth einen Anhaltspunkt ob ein StartDrawing Block gerade offen ist.

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 10:59
von ts-soft
BSP hat geschrieben: Hier die Fehlermeldung:
POLink: error: Unresolved external symbol ‘_PB_StringBasePosition’.
POLink: fatal error: 1 unresolved external(s)
Threadsichere Version der UserLib verwenden, richtiges SubSystem
"UserLibThreadSafe" wählen bei Tailbited UserLibs!

Re: StartDrawing ohne StopDrawing erkennen

Verfasst: 04.03.2012 17:47
von BSP
Hallo.
Habs jetzt erst mal so gelöst:
Globale var erstellt, von StartDrawing setzen lassen,
nach StopDrawing wieder auf null,
die Uhr nur laufen lassen, wenn var = 0

Code: Alles auswählen

Global sd

Procedure Uhr()
  If sd : ProcedureReturn 0 : EndIf
  ;
EndProcedure

Procedure Zeichne()
  sd = StartDrawing(...)
    ;
  StopDrawing()
  sd = 0
EndProcedure

SetTimer_(.....)

; - Hauptschleife
Repeat
  ;
Until ende
Ob ich damit glücklich bin, weiss ich noch nicht.
Aber erst mal scheints zu laufen.
Aber ich plane sowieso gerade die Neustrukturierung meines Prgs,
da werde ich dann mal sehen, wie ich das dann löse.
Schade. Gibt es denn keine SystemVar o.ä., die erkennt, ob gerade ZeichenOps laufen?
Das System müsste das doch auch manchmal wissen wollen; Oder?

@ts-soft.
Ach herje, wieder was neues, mit dem ich mich erst einmal auseinander setzen muss.
Na ja. Erstmal läufts so.
Ich merke mir aber Deinen Hinweis und werde mich später damit auseinander setzen.

Gruß & Dank an alle Helfer.
Bernd

StartDrawing ohne StopDrawing erkennen [Bla]

Verfasst: 05.03.2012 12:44
von funkheld
Eigentlich kein Problem vom Purebasic-hersteller.
Dieses Startdrawing/Stopdrawing verhindert ja eigentlich ein sogenanntes Flackern.

Dieses könnte der Purebasic-hersteller einfach so Programmieren das die Grafik immer darstellbar ist mit oder ohne Startdrawing, so das dem User die Freiheit bleibt wie er die Grafik zum Zeitpunkt der Herstellung sehen möchte.

Mal sehen , wann das kommt.

Gruss