Gezeichnete Kreise und Linien verschwinden

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
steelbasic
Beiträge: 63
Registriert: 02.09.2004 19:41
Wohnort: Niedersachsen

Gezeichnete Kreise und Linien verschwinden

Beitrag 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:
Viele Grüße
Hein Blöd
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag 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
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
steelbasic
Beiträge: 63
Registriert: 02.09.2004 19:41
Wohnort: Niedersachsen

Beitrag 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?
Viele Grüße
Hein Blöd
Benutzeravatar
roherter
Beiträge: 1407
Registriert: 10.04.2005 18:58
Kontaktdaten:

Beitrag von roherter »

Schau dir mal CreateImage() unter der Befehls-Kategorie Image an.
Purebasic 5.0 32bit und 64 bit

I'm back from hell
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag 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
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag 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.
Benutzeravatar
steelbasic
Beiträge: 63
Registriert: 02.09.2004 19:41
Wohnort: Niedersachsen

Beitrag von steelbasic »

Vielen Dank! Ich habe nun zwei Lösungsansätze und hoffe, dass keine weiteren Fragen hierzu aufkommen :|
Viele Grüße
Hein Blöd
Benutzeravatar
Nalfein
Beiträge: 29
Registriert: 22.08.2005 13:14

Image als Fensterhintergrund...

Beitrag 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!
If OSVersion() <> #PB_OS_Windows_ME : End : EndIf !!!
Benutzeravatar
Ligatur
Beiträge: 196
Registriert: 09.07.2006 00:41

Beitrag von Ligatur »

Gadgets neuzeichnen geht mit InvalidateRect_(GadgetID(#Nr), 0, #True).
Antworten