Per Canvas erstellte Elemente nach Form minimieren weg

Für Fragen von Einsteigern und Programmieranfängern...
DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von DL3AD »

Hallo,

ich habe folgenden Effekt.
Auf dem Form sind einige Elemente mit Canvas erstellt worden, wie z.B. Linien und Grafiken aus einer Piclist.
Wenn ich die Form minimiere in die Taskleiste und wieder aufrufe dann sind die mit Canvas erstelleten Elemente verschwunden :shock:
Getestet unter Win7 64
Was ist da faul ?

Gruß
Frank

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von Mathias »

Zeichnest du die Linien im OnPaint-Ereignis ?

Ansonsten ist dies normal, das die Linien verschwinden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von DL3AD »

ich mache dass so

Code: Alles auswählen

ImgLstM.Draw(PanMatrix.Canvas, 50,300,1);
 

und so

Code: Alles auswählen

Img_Earth.Canvas.LineTo(DxDot.Left+3,DxDot.Top+(MyDot.Width div 2));
 


Wie kann man es den verhindern dass die nicht verschwinden ?

Gruß Frank

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von siro »

Hallo Frank,
wichtig ist WO (wann) Du das zeichnest, wie Mathias schon schrieb.

Wenn Du das zum Beispiel nur zeichnest wenn eine Taste gedrückt wird,
dann funktioniert das, aber eben nur zu diesem Zeitpunkt.
"ALLE" Zeichenfunktionen sollten generell innerhalb des Ereignisses "OnPaint"
gezeichnet werden. Wenn Du nämlich dein Fenster runterklappst und dann wieder herstellst, muss ja alles neu gezeichnet werden
und das passiert immer in der OnPaint Funktion

Wenn Du zum Beispiel ein TImage auf dem Formular hast, dann musst Du
bei Ereignisse von TImage auch OnPaint doppelt klicken und dort zeichen.
Also da muss dein Code hin

Wenn Du irgendwann möchtest, daß alles neu gezeichnet wird, weil sich was geändert hat
rufst Du "Invalidate" auf. Damit sagt man der Anwendung, dass alles neu gezeichnet werden muss.
Dies löst dann ein erneutes OnPaint aus.

Hab ich aber anfangs auch nicht kapiert, hat "etwas" gedauert....

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von DL3AD »

Hallo siro,

bei mir wird z.B gezeichnet wenn ein OnCange Ereigniss eines Edit Feldes kommt - d.h. ich muss über ein OnPaint des Form das OnCange des Editfeldes noch mal erzeugen ? :?:

Gruß Frank

wp_xyz
Beiträge: 4888
Registriert: Fr 8. Apr 2011, 09:01

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von wp_xyz »

Nein. OnPaint ist die Anleitung für das Control, sich selbst zu zeichnen - egal wann immer das erforderlich ist. In OnChange veranlasst du durch den Aufruf von Invalidate, dass das Control vom Betriebssystem die Aufforderung erhält, sich neu zu zeichnen.

Du schreibst also deinen Draw-Code, der bisher fälschlicherweise in OnChange steht, in OnPaint. Und in OnChange steht nur Invalidate für das Control.

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von DL3AD »

... habe mir ein Beispiel gemacht - funktioniert
hmm dann muss ich ja Datenbankzugriffe und Berechnungen usw.von der Zeichnerei entkoppeln sonst möhrt er ja ständig in der DB umher - schei...e :mrgreen:

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von Mathias »

Hab ich aber anfangs auch nicht kapiert, hat "etwas" gedauert....

Ganz am Anfang hatte ich dieses Problem auch, das kommt davon, wen man früher für DOS programmierte.

Nein. OnPaint ist die Anleitung für das Control, sich selbst zu zeichnen

Im Grunde, wird für jede Komponente, ein OnPaint-Ereignis aufrufen, aber bei den fertigen Komponenten muss zum Glück sich nicht um dies kümmern. :wink:

Mache doch mal einen Versuch, zeichne ein Rechteck mit OnClick im Form, drücke dann der Button, dann wird das Rechteck gezeichnet, minimierst du das Fenster und öffnet es wieder, ist das Rechteck weg. Zeichnes du aber das Rechteck in OnPaint, wird es immer wieder erscheinen

Interessanter Versuch, mit diesem Code wirst du gut sehen, wen das OS ein OnPaint-Ereignis aufruft.

Code: Alles auswählen

procedure TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Brush.Color := Random($FFFFFF);
  Canvas.Rectangle(10, 10, 200, 200);
end;
.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von siro »

Hallo Frank,

Ich hab Dir mal ein Beispiel zum Verständnis gemacht.
Frank1.zip
(126.79 KiB) 75-mal heruntergeladen


Ein Editfeld auf einem Formular.
Bei jeder Änderung wird ein Wert um eins hochgezählt und in der Titelleiste des Formulars angezeigt.
Dazu wird auch jedesmal eine rote horizontale Line immer jeweils ein Pixel weiter unten gezeichnet.
Also bei jeder Änderung in deinem Textfeld wird auch eine weitere Line gezeichnet,
das sollte man auch sofort sehen.

Nachdem Du einige Linien siehst, nimmst Du mal das Fenster und schiebst es bis zur Hälfte links oder
rechts aus dem Bildschirm und dann wieder zurück in die Mitte.

Nun wirst Du feststellen, dass der Bereich, welcher ausserhalb des Bildschirms war,
auch nicht mehr richtig restauriert wird. Die Linien sind abgeschnitten.

Wenn Du dann das Formular komplett runterklappst und wieder hochklappst, dann sind alle roten Linien verloren.

Wenn Du nun wieder im Editfeld etwas änderst werden wieder Linien dort gezeichent wo es vorher aufgehört hatte.
Die Linien sind also NUR momentan sichtbar, sollte irgen etwas den Bildinhalt verdecken, ist der Inhalt
unwiederruflich verloren. Du kannst auch mal nen anderes Fenster drüber schieben, das wirkt dann wie ein Radiergummi
auf dein roten Linien.

Es fehlt also ein Mechanismus, der deinen Bildinhalt wieder herstellt und genau dafür ist die OnPaint Funktion zuständig.

Im Prinzip passiert genau das vermutlich bei deinem Programm.

Soweit der erste Teil: der zweite folgt gleich:
Siro
Zuletzt geändert von siro am Mo 3. Jul 2017, 22:55, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von Mathias »

In deiner Zip, ist die lpi-Datei nur 0 Byte gross.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von Mathias »

Nachdem Du einige Linien siehst, nimmst Du mal das Fenster und schiebst es bis zur Hälfte links oder
rechts aus dem Bildschirm und dann wieder zurück in die Mitte.

Nun wirst Du feststellen, dass der Bereich, welcher ausserhalb des Bildschirms war,
auch nicht mehr richtig restauriert wird. Die Linien sind abgeschnitten.

Du kannst auch mal nen anderes Fenster drüber schieben, das wirkt dann wie ein Radiergummi
auf dein roten Linien.

Da sieht man gut, das nicht alle OS/Treiber die Fenster gleich verwaltet, bei Mint, werden die Linien nicht zerstört.
So wie es scheint puffert Linux den Fenster-Inhalt und bei Windows gehen die Zeichen-Funktionen direkt auf den Bildschirm.

Anders sieht es aus, wen man die Grösse des Fensters ändert.

Aber dies hat eigentlich nichts zur Sache, OnPaint sollte man auf jeden Fall verwenden.
Zuletzt geändert von Mathias am Mo 3. Jul 2017, 22:58, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von siro »

Dank Dir Mathias, hab ich grad korrigiert.

und hier der zweite Teil für Frank:
Frank2.zip
(127.03 KiB) 67-mal heruntergeladen


Ich hoffe, ich konnte es etwas "verdeutlichen"

Siro
Zuletzt geändert von siro am Mo 3. Jul 2017, 23:52, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Mathias
Beiträge: 6193
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von Mathias »

und hier der zweite Teil für Frank:

unit1.pas nicht gefunden.
Du hast komische Verknüpfungen im Projekt-Inspektor.

Noch ein kleiner Schönheitsfehler.

Code: Alles auswählen

Form1.canvas.Line(0,i,Form1.width,i)

In so einem Fall sollte man ClientWidth verwenden.
Das Vorangestellte Form1 kann man sich auch sparen.
Wen es bei dir wegen der Übersichtlichkeit geht, würde ich wenigstens Self verwenden.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von siro »

Du hast recht, da gehört natürlich ClientWidth und nicht Width rein.

Die Angabe von Form.canvas kann ich natürlich weglassen, ich habe es hier bewusst so geschrieben, damit eindeutig ist welcher canvas gemeint ist.
Wenn Frank z.B ein Image oder PaintBox auf dem Formular hat, muss er entsprechend PaintBox1.canvas .... benutzen.
Das war bei mir auch OFT ein Fehler, dass ich nur canvas. geschrieben habe und meine Zeichenobjekte dann nicht da gelandet sind wo sie solten.
Deshalb hier etwas ausführlicher.

So, nachdem mein Festplatte anscheinend irgendwelche Probleme zeigt, hoffe ich jetzt klappt es mit der neuen Zipdatei.
ich wünsch euch einen schönen Abend,
Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

DL3AD
Beiträge: 478
Registriert: Fr 13. Sep 2013, 12:07
OS, Lazarus, FPC: Debian Bullseye (L 2.2.0)
CPU-Target: 64Bit
Wohnort: Rügen

Re: Per Canvas erstellte Elemente nach Form minimieren weg

Beitrag von DL3AD »

Hallo siro,

vielen Dank für deine Bemühungen - habe den Sachverhalt nun vollumfänglich begriffen :mrgreen:
Habe auch schon die ersten Änderungen erfolgreich in meinem Projekt vorgenommen.

Gruß
Frank

Antworten