Recent

Author Topic: Override TPanel.OnPaint - but Children no longer show?  (Read 3725 times)

Ozz_Nixon

  • Full Member
  • ***
  • Posts: 127
  • ~ email: nixon.ozz@aol.com or ozznixon@gmail.com
    • http://www.modernpascal.com/
Override TPanel.OnPaint - but Children no longer show?
« on: November 11, 2023, 05:05:42 am »
I have successfully modified TPanel's OnPaint to give me a gradient background.


However, the children (a TLabel and a TImage) no longer render. I am assuming that I am supposed to crawl the Components[index] and call Paint or Invalidate? Or is it because I do not have inherited OnPaint; in my onPaint code?  :-[


I am simply calling the GradientFill(Rect,StartColor,EndColor,Vert);


** PART TWO of this question - is it possible to treat the Fill like a roundRect?
---
Want to kick the tires to a Free Pascal like script engine? http://www.ModernPascal.com/

Handoko

  • Hero Member
  • *****
  • Posts: 5485
  • My goal: build my own game engine using Lazarus
Re: Override TPanel.OnPaint - but Children no longer show?
« Reply #1 on: November 11, 2023, 07:50:52 am »
For your information, OnPaint event and Paint method are 2 different things. Because you mentioned OnPaint several times, so I tested it on my Lazarus 2.2.6 Ubuntu, it worked.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Image1: TImage;
  16.     Label1: TLabel;
  17.     Panel1: TPanel;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     procedure NewPanelPaint(Sender: TObject);
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormCreate(Sender: TObject);
  35. begin
  36.   Label1.Caption := 'Test custom OnPaint';
  37.   Panel1.OnPaint := @NewPanelPaint;
  38. end;
  39.  
  40. procedure TForm1.NewPanelPaint(Sender: TObject);
  41. begin
  42.   Panel1.Canvas.GradientFill(Panel1.ClientRect, clWhite, clYellow, gdVertical);
  43. end;
  44.  
  45. end.

For gradient round rectangle, you can try:
https://forum.lazarus.freepascal.org/index.php/topic,32677.msg210848.html#msg210848
« Last Edit: November 11, 2023, 08:38:22 am by Handoko »

lainz

  • Hero Member
  • *****
  • Posts: 4735
  • Web, Desktop & Android developer
    • https://lainz.github.io/
Re: Override TPanel.OnPaint - but Children no longer show?
« Reply #2 on: November 11, 2023, 11:05:19 am »
I have successfully modified TPanel's OnPaint to give me a gradient background.


However, the children (a TLabel and a TImage) no longer render. I am assuming that I am supposed to crawl the Components[index] and call Paint or Invalidate? Or is it because I do not have inherited OnPaint; in my onPaint code?  :-[


I am simply calling the GradientFill(Rect,StartColor,EndColor,Vert);


** PART TWO of this question - is it possible to treat the Fill like a roundRect?

You need to call inherited.

For your information, OnPaint event and Paint method are 2 different things. Because you mentioned OnPaint several times, so I tested it on my Lazarus 2.2.6 Ubuntu, it worked.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Image1: TImage;
  16.     Label1: TLabel;
  17.     Panel1: TPanel;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     procedure NewPanelPaint(Sender: TObject);
  21.   public
  22.  
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. { TForm1 }
  33.  
  34. procedure TForm1.FormCreate(Sender: TObject);
  35. begin
  36.   Label1.Caption := 'Test custom OnPaint';
  37.   Panel1.OnPaint := @NewPanelPaint;
  38. end;
  39.  
  40. procedure TForm1.NewPanelPaint(Sender: TObject);
  41. begin
  42.   Panel1.Canvas.GradientFill(Panel1.ClientRect, clWhite, clYellow, gdVertical);
  43. end;
  44.  
  45. end.

For gradient round rectangle, you can try:
https://forum.lazarus.freepascal.org/index.php/topic,32677.msg210848.html#msg210848

The author of this topic is talking about overriding not using the event.

wp

  • Hero Member
  • *****
  • Posts: 13195
Re: Override TPanel.OnPaint - but Children no longer show?
« Reply #3 on: November 11, 2023, 01:41:29 pm »
** PART TWO of this question - is it possible to treat the Fill like a roundRect?

Use a clip region:

Code: Pascal  [Select][+][-]
  1. uses
  2.   LCLIntf, LCLType;
  3.  
  4. procedure TForm1.Panel1Paint(Sender: TObject);
  5. var
  6.   Rgn: HRgn;
  7. begin
  8.   Rgn := CreateRoundRectRgn(0, 0, Panel1.Width, Panel1.Height, 30, 30);
  9.   try
  10.     SelectClipRgn(Panel1.Canvas.Handle, Rgn);
  11.     Panel1.Canvas.GradientFill(Rect(0, 0, Panel1.Width, Panel1.Height), clBlue, clSkyBlue, gdVertical);
  12.     SelectClipRgn(Panel1.Canvas.Handle, 0);
  13.   finally
  14.     DeleteObject(Rgn);
  15.   end;
  16. end;

 

TinyPortal © 2005-2018