Seite 1 von 1

Gezeichnete Kreise und Linien verschwinden

Verfasst: 25.11.2007 18:42
von steelbasic
Hallo,

diese Frage ist bestimmt schon hier beantwortet worden, habe sie aber nicht gefunden bzw. die Antwort nicht verstanden.

In einem Programm verschwinden eingezeichnete Linien usw nach dem Aktivieren des Bildschirmschoners oder dem Verschieben des Fensters.

Beispiel:

Code: Alles auswählen

Width=200
  Height=150 
  If OpenWindow(0, 0, 0, Width, Height, "Circles", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If StartDrawing(WindowOutput(0))
      x = Width/2
      y = Height/2
      For Radius = Height/2 To 10 Step -10
        Circle(x, y, radius ,RGB(Random(255),Random(255),Random(255)))
      Next
      StopDrawing() ; Dies ist nach Abschluss der Zeichenoperationen immer nötig!!! Vergessen Sie dies nie!
    EndIf
    
    Repeat : Event = WaitWindowEvent() : Until  Event = #PB_Event_CloseWindow
  EndIf
Hilfe wäre nett, meine Frau beschwert sich schon seit einem Jahr über diese Fehlfunktion und nun habe ich ein 2. ähnliches Projekt :oops:

Verfasst: 25.11.2007 18:48
von #NULL
bei jedem refresh wird der fenster inhalt zerstört, dann musst du neu zeichnen:

Code: Alles auswählen

Width=200
  Height=150
  If OpenWindow(0, 0, 0, Width, Height, "Circles", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_Repaint
        If StartDrawing(WindowOutput(0))
          x = Width/2
          y = Height/2
          For Radius = Height/2 To 10 Step -10
            Circle(x, y, radius ,RGB(Random(255),Random(255),Random(255)))
          Next
          StopDrawing() ; Dies ist nach Abschluss der Zeichenoperationen immer nötig!!! Vergessen Sie dies nie!
        EndIf
      EndIf
    Until Event = #PB_Event_CloseWindow
  EndIf 
besser als auf das fenster zu zeichnen ist aber 1x auf ein imagegadget zu zeichnen und den refresh dem os zu überlassen

Verfasst: 25.11.2007 19:05
von steelbasic
aha schon besser :D

Aber wie geht das mit dem ImageGadget. Meine Programmoberfläche habe ich mit PureForm erstellt. Muss ich hier schon ein "leeres" (was ist leer ?) Image angeben?

Ich oute mich ungern als faul oder zu blöd :oops: aber die Probleme liegen bei mir glaube ich tiefer! Im Abstand von einigen Monaten lese ich immer die Hilfe durch.... und komme nicht weiter.

Wie erstelle ich ein Image auf dem ich während der Programmausführung zeichnen kann?

Verfasst: 25.11.2007 19:19
von roherter
Schau dir mal CreateImage() unter der Befehls-Kategorie Image an.

Verfasst: 25.11.2007 19:26
von #NULL
geht z.b. so:

Code: Alles auswählen

Width=200
Height=150

CreateImage(0,200,150)

OpenWindow(0, 0, 0, Width, Height, "Circles", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
  ImageGadget(0,0,0,0,0,ImageID(0))
Repeat
  Event = WaitWindowEvent(10)
  If Not Random(10)
    StartDrawing(ImageOutput(0))
      x = Width/2
      y = Height/2
      For Radius = Height/2 To 10 Step -10
        Circle(x, y, radius ,RGB(Random(255),Random(255),Random(255)))
      Next
    StopDrawing()
    SetGadgetState(0,ImageID(0)) ; <- wichtig: gadget aktualisieren !
  EndIf
Until Event = #PB_Event_CloseWindow

Verfasst: 25.11.2007 22:17
von Ligatur
Ich sehe keinen Vorteil in den hier so oft genannten Rat, ein Imagegadget zu verwenden statt PB_Event_Repaint zu benutzen, zumal es nicht das OS ist welches dann für das Neuzeichnen zuständig ist sondern das Imagegadget - Steuerelement welches es dann übernimmt, das Image neuzuzeichnen wenn der Inhalt zerstört wurde.
Außerdem kostet es zusätzlichen Speicherplatz und flexibilität, wenn ständig bei jeder Änderung ein Image neugezeichnet und anschließend neu zugewiesen werden muß. Eine Ausnahme ist es höchstens, wenn der Zeichenvorgang extrem komplex ist und sehr viel Zeit in Anspruch nehmen würde. Dieser Fall tritt aber nur extrem selten ein. Und selbst in diesen Fall kann man in ein Image zeichnen und bei Auftreten von #PB_Event_Repaint das Image in das Fenster hineinzeichnen. Etwas anderes macht das Imagegadget letztlich auch nicht, nur das nicht direkt in das Fenster gemalt wird sondern in ein Childfenster.

Verfasst: 25.11.2007 22:55
von steelbasic
Vielen Dank! Ich habe nun zwei Lösungsansätze und hoffe, dass keine weiteren Fragen hierzu aufkommen :|

Image als Fensterhintergrund...

Verfasst: 26.11.2007 11:50
von Nalfein
Die Idee mit dem Imagegadget hatte ich auch schon mal. Funktioniert auch solange man keine anderen Gadgets verwendet.
Wenn das Image den Hintergrund des Fensters darstellt und ich noch andere Gadgets (davor) erstelle, sieht es zwar immer noch toll aus, aber leider kann ich die Gadgets im Vordergrund nicht mehr anklicken!
Für die Lösung wäre interessant, ob man eine "Reihenfolge" der Gadgets angeben kann, so daß das Image immer als letztes Events erhält und keine von z.B. einem Butten davor abfängt...

Bei der Methode mit dem Neu-Zeichnen tauchte folgendes Problem auf:
Beim Event #pb_event_Activate_window lasse ich den Hintergrund neu zeichnen. Danach sind aber die Gadgets übermalt! Der Versuch mit Hidegadget(x,0) alle aktuell zu sehenden Gadgets nochmal zu refreshen (bei .NET gibt's da die Befehle refresh() oder invalidate() - eigentlich suche ich eine Entsprechnung dafür...) funktioniert nur, wenn ich sie vorher auch verstecke.
DADURCH wiederum fühlen sich auch andere Gadgets (die versteckt sind und es auch bleiben sollen) angesprochen und ich habe da einen "Schatten" aller Gadgets, die theoretisch da sind, aber die nicht gezeigt werden sollen, in der Window Hintergrundfarbe auf dem selbstgezeichneten Hintergrund (ist Farbverlauf; egal wie die Window Hintergrundfarbe ist - einen einfarbigen Löschbereich sieht man!).

Ich glaube ich habe jetzt alle Reihenfolgen mit Event -> Gadgets verstecken -> Schirm neu malen -> sichtbare wieder anzeigen durch, aber keines funktioniert (in allen Fällen...).... :cry:
Die aktuelle Reihenfolge funktionert perfekt, wenn man das Fenster kurzzeitig wechselt, aber direkt nach dem Verstecken sind da immer diese Löschbereiche, mit denen er versteckte Gadgets übermalt, und das OBWOHL der Hide-Befehl VOR dem Malen des Hintergrundes steht!

Verfasst: 26.11.2007 18:40
von Ligatur
Gadgets neuzeichnen geht mit InvalidateRect_(GadgetID(#Nr), 0, #True).