Nach Resize wird nichts mehr aufs canvas gezeichnet [gelöst]

Rund um die LCL und andere Komponenten
Antworten
Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Nach Resize wird nichts mehr aufs canvas gezeichnet [gelöst]

Beitrag von corpsman »

Servus,

ich habe hier mal wieder etwas, das mich wahnsinnig macht.

Verwendet wird : fpc 2.7.1, Lazarus Revision 42538, Win7 (64-Bit)

Der Fehler lässt sich wie folgt reproduzieren
1. Programm Starten
2. Fenster Maximieren
3. Checkbox Klicken

Soll : ein Roter Strich von links oben nach Rechts unten
Ist : ein Roter Strich aber nur links oben

Witzigerweise , werden die Schritte 2 und 3 vertauscht funktioniert es (leider mache ich in 99% aller Fälle die Reihenfolge 2,3).

Wenn ich mache
Programm Starten, Maximieren, maximieren rückgängig, maximieren, checkbox klicken
Dann ists wie es soll, generell scheint es ab dem 2. Resize zu gehen..

Kann mir einer von euch weiter helfen / das ganze Reproduzieren ?

Hier noch der Relevante Code aus Unit1:

Code: Alles auswählen

 
Var
  Form1: TForm1;
  bm: Tbitmap = Nil;
 
Implementation
 
{$R *.lfm}
 
{ TForm1 }
 
Procedure TForm1.FormCreate(Sender: TObject);
Begin
  bm := Tbitmap.create();
End;
 
Procedure TForm1.FormResize(Sender: TObject);
Begin
  PaintBox1Resize(Nil);
End;
 
Procedure TForm1.PaintBox1Paint(Sender: TObject);
Begin
  If assigned(bm) Then Begin
    bm.canvas.Pen.Color := clblack;
    bm.canvas.Brush.Color := clwhite;
    bm.Canvas.Rectangle(0, 0, bm.Width, bm.Height);
    If CheckBox1.Checked Then Begin
      bm.Canvas.Pen.Color := clred;
      bm.Canvas.Line(0, 0, bm.Width, bm.Height);
    End;
    PaintBox1.Canvas.Draw(0, 0, bm);
  End;
End;
 
Procedure TForm1.PaintBox1Resize(Sender: TObject);
Begin
  If assigned(bm) Then Begin
    bm.Width := PaintBox1.Width;
    bm.Height := PaintBox1.Height;
  End;
  //PaintBox1.Invalidate;
  form1.Invalidate;
  PaintBox1.Refresh;
  //PaintBox1.Repaint;
  //PaintBox1.AdjustSize; // Sonst passt die Größe evtl. nicht.
  //PaintBox1.Invalidate;
  //PaintBox1.AdjustSize; // Sonst passt die Größe evtl. nicht.
  PaintBox1.OnPaint(Nil); // PaintBox1.Refresh;
  application.ProcessMessages;
 
End;
 
Procedure TForm1.FormCloseQuery(Sender: TObject; Var CanClose: boolean);
Begin
  bm.free;
  bm := Nil;
End;
 
Procedure TForm1.CheckBox1Change(Sender: TObject);
Begin
  PaintBox1.OnPaint(Nil); //  PaintBox1.Refresh;
End;
 
End.
 
 
Dateianhänge
Problem.zip
Komplettes Projekt zum Testen
(2.4 KiB) 58-mal heruntergeladen
Zuletzt geändert von corpsman am Mo 22. Sep 2014, 07:52, insgesamt 1-mal geändert.
--
Just try it

Patito
Beiträge: 203
Registriert: Di 22. Sep 2009, 13:08
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von Patito »

Also das Application.ProcessMessages ist doch nur gut um alle Events so richtig durcheinander zu bringen. Lass das erst mal weg.

Mir reicht in solchen Fällen meistens ein einzelnes Repaint() einer Komponente.

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

*g*

bei meinem Beispiel hilft das, in der richtigen Anwendung klappts leider nicht :(
--
Just try it

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von theo »

Warum so complicirt? Bei mir geht das einfach so wie unten, habe ich was verpasst?

Code: Alles auswählen

 
Procedure TForm1.PaintBox1Paint(Sender: TObject);
Begin
  If assigned(bm) Then Begin
    bm.Width := PaintBox1.Width;
    bm.Height := PaintBox1.Height;
    bm.canvas.Pen.Color := clblack;
    bm.canvas.Brush.Color := clwhite;
    bm.Canvas.Rectangle(0, 0, bm.Width, bm.Height);
    If CheckBox1.Checked Then Begin
      bm.Canvas.Pen.Color := clred;
      bm.Canvas.Line(0, 0, bm.Width, bm.Height);
    End;
    PaintBox1.Canvas.Draw(0, 0, bm);
  End;
End;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
    bm := Tbitmap.create();
end;
 
procedure TForm1.CheckBox1Change(Sender: TObject);
begin
  PaintBox1.Invalidate;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  bm.free;
end;     

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

Hallo Theo,

Deine Lösung funktioniert bei meinem Beispiel, in der eigentlichen Anwendung leider nicht.
Es fällt auf, wenn ich das so mache "Flackert" das Fenster (ich hab hier ne Auflösung von 3840*1080).


Kannst du mit meinem Beispielprogramm den Fehler Reproduzieren ?
--
Just try it

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von theo »

corpsman hat geschrieben:Deine Lösung funktioniert bei meinem Beispiel, in der eigentlichen Anwendung leider nicht.
Es fällt auf, wenn ich das so mache "Flackert" das Fenster (ich hab hier ne Auflösung von 3840*1080).

Ist das Flackern dein ganzes Problem?

corpsman hat geschrieben:Kannst du mit meinem Beispielprogramm den Fehler Reproduzieren ?

Habe ich nicht probiert und werde ich auch nicht, da ich deinen Code nicht kapiere.
Das ist doch, mit Verlaub, Käse:

Code: Alles auswählen

form1.Invalidate;
PaintBox1.Refresh;
PaintBox1.OnPaint(Nil); // PaintBox1.Refresh;
application.ProcessMessages;

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

Das ist doch, mit Verlaub, Käse:


Das Stimmt. Da ich nicht verstanden hatte warum der Fehler auftritt, habe ich alle Routinen hingeschrieben, welche mir zum Thema Neu Zeichnen Eingefallen sind. Der Fehler bleibt, auch wenn man es "Richtig" macht und nur eine der vielen Varianten steht.

Wenn du das ding runterlädst und auf deinem Rechner Testet und der Fehler ist weg (das hoffe ich), dann liegt es an meinem System / Lazarus Version und ich würde eine neuere Probieren. Unter Linux ist der Fehler übrigens nicht.
--
Just try it

Antrepolit
Beiträge: 340
Registriert: Di 12. Sep 2006, 08:57
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von Antrepolit »

Bei einer Auflösung von 3840*1080 hast du doch bestimmt zwei Monitore? Da wundert es eigentlich nicht, dass schon mal was flackert. Da könntest du Double-Buffering einsetzen. Windows CGI-Grafik ist nicht das schnellste in der Hinsicht.
Grüße, Antrepolit

care only if your os is really burning

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von theo »

Ich bin auf Linux, aber du hast die Frage noch nicht beantwortet: Ist nur das Flackern das Problem bei meiner Variante?

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

sry theo, das flackern kam dazu.

wie geschrieben, bei meinem "Demo" lösten bisher alle Vorschläge das Problem. Lediglich bei deiner Variante flackerte es dann.

Ich habe 2 * 21 Zoll Monitore leider keine 3 ;(. Mit dem Flackern könnte ich auch leben. Mein Problem ist viel mehr, das "nicht" zeichnen können.
Dieses Nicht zeichnen können geht auch reproduzierbar nach 2 mal Anwendung Größe ändern weg.
=>
Wenn das ein Bug in meinem Code ist, wieso ist es dann Plattformabhängig und nur bis zum zweiten Resize ?

Ich will das erst als Bug Reporten wenn ein anderer Windows User das bestätigen kann. Alle meine anderen Rechner sind ja zum Glück Linux, mir fehlt da also leider die weitere Testmöglichkeit...
--
Just try it

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von Michl »

Wenn ich den ganzen unnötigen Code rausschmeiße, funktioniert das bei mir problemlos:

Code: Alles auswählen

Procedure TForm1.FormCreate(Sender: TObject);
Begin
  bm := Tbitmap.create();
End;
 
Procedure TForm1.FormResize(Sender: TObject);
Begin
//  PaintBox1Resize(Nil);
End;
 
Procedure TForm1.PaintBox1Paint(Sender: TObject);
Begin
  If assigned(bm) Then Begin
    bm.canvas.Pen.Color := clblack;
    bm.canvas.Brush.Color := clwhite;
    bm.Canvas.Rectangle(0, 0, bm.Width, bm.Height);
    If CheckBox1.Checked Then Begin
      bm.Canvas.Pen.Color := clred;
      bm.Canvas.Line(0, 0, bm.Width, bm.Height);
    End;
    PaintBox1.Canvas.Draw(0, 0, bm);
  End;
End;
 
Procedure TForm1.PaintBox1Resize(Sender: TObject);
Begin
  If assigned(bm) Then Begin
    bm.Width := PaintBox1.Width;
    bm.Height := PaintBox1.Height;
  End;
  //PaintBox1.Invalidate;
  //form1.Invalidate;
  //PaintBox1.Refresh;
  //PaintBox1.Repaint;
  //PaintBox1.AdjustSize; // Sonst passt die Größe evtl. nicht.
  //PaintBox1.Invalidate;
  //PaintBox1.AdjustSize; // Sonst passt die Größe evtl. nicht.
  //PaintBox1.OnPaint(Nil); // PaintBox1.Refresh;
  //application.ProcessMessages;
end;
 
Procedure TForm1.FormCloseQuery(Sender: TObject; Var CanClose: boolean);
Begin
  bm.free;
  bm := Nil;
End;
 
Procedure TForm1.CheckBox1Change(Sender: TObject);
Begin
  PaintBox1.OnPaint(Nil); //  PaintBox1.Refresh;
End;       

Getetstet unter Win7:
Lazarus 1.2.4 FPC 2.6.4
Lazarus 1.3 r46148M FPC 2.7.1

PS: Ja, wenn ich das Projekt von Dir unverändert starte, werden Width und Height von der ursprünnglichen Paintbox genommen, daher wird der Strich nicht über die gesamte Fenstergröße gezeichnet. Das ist aber auch nicht weiter verwunderlich, wenn Du während des Ereignisses OnResize "Invalidate"+"ProcessMessages" aufrufst.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

Danke michl für den Test, in meiner Anwendung mache ich das auch im Mouse Move (da ist die Linie dann an einer seite fest und die andere ist am cursor) man kann dann deutlich sehen, dass die "alten" dimensionen aktualisiert werden, bewege ich den cursor aus diesem Bereich ist der Teil außerhalb nicht mehr sichtbar.

Deinen code kann ich erst am mo wieder testen, erst dann sitze ich wieder vor einem windows rechner..
--
Just try it

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Nach Resize wird nichts mehr aufs canvas gezeichnet

Beitrag von corpsman »

Juhe, ich habs endlich gefunden.

Es lag an

PaintBox1.ClientRect

das habe ich zum Rendern genutzt. Wenn ich das Ersetze zu :

rect(0, 0, bm.width, bm.height)

Was ja beides identlisch sein sollte, dann gehts *g*.
--
Just try it

Antworten