Wie das Neuzeichnen des Canvasgadgets unterbinden?
Wie das Neuzeichnen des Canvasgadgets unterbinden?
Hallo,
mein Problem scheint auf den ersten Blick hier schon einmal behandelt worden zu sein, aber eine Lösung habe ich dort leider nicht gefunden.
Ich programmiere ein Customgadget unter Verwendung des Canvas Gadgets.
Das Erscheinungsbild des Gadgets (81 Sudoku-Felder mit Zahlen) wird mit mehr oder weniger vielen Zeichenoperationen erstellt. Nun wird das Canvasgadget aber leider nach jeder Zeichenoperation neu auf dem Window gezeichnet. Das Gadget besteht aus 9 x 9 Feldern, die aus programmtechnischen Gründen nacheinander mit jeweils einem StartDrawing / Stopdrawing Block gezeichnet werden (es gibt halt eine Prozedur die ein einzelnes Feld zeichnet und die wird 81 mal aufgerufen).
Leider sieht man den Aufbau des Gadgets bzw. der Grafik schon recht deutlich, da das Canvasgadget sich immer wieder aktualisiert. Besser wäre es, wenn ich erstmal alles fertig zeichnen könnte und sich dann das Gadget einmal auf dem Window neuzeichnet.
Gibt's da eine Möglichkeit bei der ich kein Callback für das ganze Fenster erstellen muss, um die Canvas-repaints zu unterdrücken? Es soll ein universell einsetzbares Customgadget werden, daher möchte ich kein Callback auf das Fenster setzen, auf dem sich das Gadget später befinden wird. Das wäre meiner Meinung nach dann kein transparentes Verhalten.
Man kann das mit HideGadget() erreichen, aber dann ist das Gadget in der Zeit des Neuzeichnens komplett verschwunden. Das kommt auch nicht in Frage, da das Gadget später auch "während des Betriebs" z.B. mit neuen Zahlenreihen befüllt werden kann.
mein Problem scheint auf den ersten Blick hier schon einmal behandelt worden zu sein, aber eine Lösung habe ich dort leider nicht gefunden.
Ich programmiere ein Customgadget unter Verwendung des Canvas Gadgets.
Das Erscheinungsbild des Gadgets (81 Sudoku-Felder mit Zahlen) wird mit mehr oder weniger vielen Zeichenoperationen erstellt. Nun wird das Canvasgadget aber leider nach jeder Zeichenoperation neu auf dem Window gezeichnet. Das Gadget besteht aus 9 x 9 Feldern, die aus programmtechnischen Gründen nacheinander mit jeweils einem StartDrawing / Stopdrawing Block gezeichnet werden (es gibt halt eine Prozedur die ein einzelnes Feld zeichnet und die wird 81 mal aufgerufen).
Leider sieht man den Aufbau des Gadgets bzw. der Grafik schon recht deutlich, da das Canvasgadget sich immer wieder aktualisiert. Besser wäre es, wenn ich erstmal alles fertig zeichnen könnte und sich dann das Gadget einmal auf dem Window neuzeichnet.
Gibt's da eine Möglichkeit bei der ich kein Callback für das ganze Fenster erstellen muss, um die Canvas-repaints zu unterdrücken? Es soll ein universell einsetzbares Customgadget werden, daher möchte ich kein Callback auf das Fenster setzen, auf dem sich das Gadget später befinden wird. Das wäre meiner Meinung nach dann kein transparentes Verhalten.
Man kann das mit HideGadget() erreichen, aber dann ist das Gadget in der Zeit des Neuzeichnens komplett verschwunden. Das kommt auch nicht in Frage, da das Gadget später auch "während des Betriebs" z.B. mit neuen Zahlenreihen befüllt werden kann.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Weil ich die Zeichenoperationen als einzelne, unabhängige Prozeduren realisiert habe, die auch einzeln aufrufbar sind. DrawGrid(), DrawCell(), DrawDebugNumbers()... die haben alle Ihre einzelnen Start/Stop Aufrufe.STARGÅTE hat geschrieben:Du könntest zB erst mal auf einem eigene Image zeichnen und dann mit einem Mal DrawImage() auf dem Canvas ausführen.
Allerdings ist mir auch nicht ganz klar, wieso du mehrere Start/Stop brauchst.
Wenn ich das ganze Gadget zeichne, dann sind das zwei verschachtelte For Schleifen (1-9) in denen DrawCell(x,y) usw. aufgerufen wird.
Aber ich sehe schon, dass ich das dann wohl doch so umbauen sollte, dass die Prozeduren sowohl mit ihrem eigenen StartDrawing-Block als auch mit einem externen StartDrawing-Block außerhalb der Prozedur umgehen können.
Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Falls es so etwas wie ein RepaintOff(#Gadget, 1/0) nicht gibt, dann schreib ich meine Zeichenprozeduren nochmal um.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Das CanvasGadget bietet ja sogar SetGadgetAttribute(#Gadget, #PB_Canvas_Image, ImageID(...)).
Und das halte ich für "ungegurkt"
Und das halte ich für "ungegurkt"
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Wenn ich das recht verstanden habe hast du sowas gemacht ? :
Wobei sowas sinnvoller wäre :
Meinst du das ? Wenn nicht hab ich völliges missverständnis meinerseits
Ansonsten muss man auch nicht das komplette Canvas neuzeichnen, wenn sich nur ein Teil davon ändert.
Man braucht "nur" den Teil neu zeichnen, der sich auch tatsächlich ändert...
Code: Alles auswählen
Procedure DrawCell()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
Procedure DrawCellHere()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
Procedure DrawCellThere()
StartDrawing(Canvasou.....
Box(....
StopDrawing()
EndProcedure
; ----
Procedure NeuZEichnen()
DrawCell()
DrawCellHere()
DrawCellThere()
EndProcedure
Code: Alles auswählen
Procedure DrawCell()
Box(....
EndProcedure
Procedure DrawCellHere()
Box(....
EndProcedure
Procedure DrawCellThere()
Box(....
EndProcedure
; ----
Procedure NeuZEichnen()
StartDrawing(Canv....
DrawCell()
DrawCellHere()
DrawCellThere()
StopDrawing()
EndProcedure
Ansonsten muss man auch nicht das komplette Canvas neuzeichnen, wenn sich nur ein Teil davon ändert.
Man braucht "nur" den Teil neu zeichnen, der sich auch tatsächlich ändert...
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Das ist kein gegurke, das ist ganz normales Double Buffering wie es jedes Spiel verwendet um eben solche Effekte zu verhindern.Kurzer hat geschrieben: Das mit dem Image hatte ich auch schon überlegt. Die Idee fühlte sich aber "gegurkt" an.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke!
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Vielleicht (Windows only):
Eventuell danach ein
Code: Alles auswählen
SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#False,0)
...
...
...
SendMessage_(GadgetID(#Canvas),#WM_SETREDRAW,#True,0)
Code: Alles auswählen
RedrawWindow_(WindowID(#Window),#Null,#Null,#RDW_INVALIDATE|#RDW_UPDATENOW|#RDW_ERASE)
Re: Wie das Neuzeichnen des Canvasgadgets unterbinden?
Danke für Eure Hinweise.
Das mit dem "gegurkt" klang vermutlich dramatischer, als ich es eigentlich gemeint hatte. Sorry.
Ich wollte die Image-Idee damit nicht schlechtreden, nur kam es mir nicht richtig vor, weil das Canvasgadget lt. PB-Hilfe von sich aus schon double buffered gezeichnet wird. Das Problem ist einzig, dass ich nicht bedachte habe, dass das double buffering mit Startdrawing eingeleitet und mit StopDrawing beendet wird. Ich werde meine Routinen dahingehend anpassen und dann funktioniert vermutlich alles genau im Sinne des Erfinders.
@Bisonte: Ja, so in etwa ist das richtig, wie Du es aufgezeigt hast. Zusätzlich nutze ich DrawCell(x,y) aber auch noch einzeln, um die Zelle unter der Maus hervorzuheben. Daher muss das auch einzeln funktionieren.
Ich werde die Startdrawing/StopDrawing-Befehle jetzt außerhalb der Zeichnungsprozeduren platzieren.
@Thorium & Stargate: Wie gesagt, das war ein Verständnisproblem. Double buffering ist mir geläufig, ich hab's im Fall des Canvasgadgets halt nur nicht korrekt angewendet (mehrfache Start-/StopDrawings). Die Nutzung eines extenen Images löst die Problematik mit den mehrfachen Start-/StopDrawings, erhöht aber den Verwaltungsaufwand für das Gadegt, da man das flipping koordinieren muss.
Ich brauchte halt nur einen Wink, um in die richtige Richtung zu denken. Ist hiermit erfolgreich geschehen.
Besten Dank.
Das mit dem "gegurkt" klang vermutlich dramatischer, als ich es eigentlich gemeint hatte. Sorry.
Ich wollte die Image-Idee damit nicht schlechtreden, nur kam es mir nicht richtig vor, weil das Canvasgadget lt. PB-Hilfe von sich aus schon double buffered gezeichnet wird. Das Problem ist einzig, dass ich nicht bedachte habe, dass das double buffering mit Startdrawing eingeleitet und mit StopDrawing beendet wird. Ich werde meine Routinen dahingehend anpassen und dann funktioniert vermutlich alles genau im Sinne des Erfinders.
@Bisonte: Ja, so in etwa ist das richtig, wie Du es aufgezeigt hast. Zusätzlich nutze ich DrawCell(x,y) aber auch noch einzeln, um die Zelle unter der Maus hervorzuheben. Daher muss das auch einzeln funktionieren.
Ich werde die Startdrawing/StopDrawing-Befehle jetzt außerhalb der Zeichnungsprozeduren platzieren.
@Thorium & Stargate: Wie gesagt, das war ein Verständnisproblem. Double buffering ist mir geläufig, ich hab's im Fall des Canvasgadgets halt nur nicht korrekt angewendet (mehrfache Start-/StopDrawings). Die Nutzung eines extenen Images löst die Problematik mit den mehrfachen Start-/StopDrawings, erhöht aber den Verwaltungsaufwand für das Gadegt, da man das flipping koordinieren muss.
Ich brauchte halt nur einen Wink, um in die richtige Richtung zu denken. Ist hiermit erfolgreich geschehen.
Besten Dank.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.