Мерцание в градиентной панели - PullRequest
1 голос
/ 25 августа 2011

Я унаследовал элемент управления от TPanel, и в обработчике событий Paint я нарисовал весь прямоугольник клиента, используя градиент. Это прекрасно работает, пока пользователь не изменит размер. При изменении размера панели компонент панели слишком сильно мигает.

Как я могу избежать этого мерцания. Я видел градиенты в MS Office 2007, даже если мы изменим размер клиентской области, мерцания не будет. Пожалуйста, просветите меня об этом.

Спасибо в ожидании

Ответы [ 2 ]

2 голосов
/ 26 августа 2011

Вы можете посмотреть на этот вопрос Как устранить мерцание на правом краю TPaintBox (например, при изменении размера)

Хороший обзор вариантов, чтобы избежать мерцания, а также дляTPanel.

Редактировать: я провел быстрый тест в своей версии Delphi XE для Windows 7.

С этим кодом я не могу воспроизвести никакого мерцания.Унаследованный объект Paint удаляется, а процедура Paint выполняется довольно быстро.

Если вы все еще видите мерцание, предложение от Саймона может быть реализовано, но лучше сохранить созданное растровое изображение на время жизни самого компонента.

unit MainForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TGradientPanel = class(TPanel)
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  end;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    sPanel : TGradientPanel;
  public
    { Public declarations }
 end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

Uses Math;

 procedure GradVertical(Canvas:TCanvas; Rect:TRect; FromColor, ToColor:TColor) ;
 var
   Y:integer;
   dr,dg,db:Extended;
   C1,C2:TColor;
   r1,r2,g1,g2,b1,b2:Byte;
   R,G,B:Byte;
   cnt:Integer;
 begin
    C1 := FromColor;
    R1 := GetRValue(C1) ;
    G1 := GetGValue(C1) ;
    B1 := GetBValue(C1) ;

    C2 := ToColor;
    R2 := GetRValue(C2) ;
    G2 := GetGValue(C2) ;
    B2 := GetBValue(C2) ;

    dr := (R2-R1) / Rect.Bottom-Rect.Top;
    dg := (G2-G1) / Rect.Bottom-Rect.Top;
    db := (B2-B1) / Rect.Bottom-Rect.Top;

    cnt := 0;
    for Y := Rect.Top to Rect.Bottom-1 do
    begin
       R := R1+Ceil(dr*cnt) ;
       G := G1+Ceil(dg*cnt) ;
       B := B1+Ceil(db*cnt) ;

       Canvas.Pen.Color := RGB(R,G,B) ;
       Canvas.MoveTo(Rect.Left,Y) ;
       Canvas.LineTo(Rect.Right,Y) ;
       Inc(cnt) ;
    end;
 end;


constructor TGradientPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Self.ParentBackground := FALSE;
end;

procedure TGradientPanel.Paint;
var
  rect : TRect;
begin
  //inherited;  // Avoid any inherited paint actions as they may clear the panel background
  rect := GetClientRect;
  GradVertical( Self.Canvas, rect, clBlue, clRed);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  sPanel := TGradientPanel.Create( Self);
  sPanel.Parent := Self;
  sPanel.Top := 10;
  sPanel.Left := 10;
  sPanel.Width := 300;
  sPanel.Height := 300;
  sPanel.Anchors := [akLeft,akRight,akTop,akBottom];
  sPanel.Enabled := TRUE;
  sPanel.Visible := TRUE;
end;

end.
0 голосов
/ 26 августа 2011

Способ уменьшить мерцание - нарисовать градиент во временном растровом изображении, чтобы нарисовать все содержимое растрового изображения на панели.Этот метод предполагает, что у вас есть метод OnPaint и холст для рисования на вашей унаследованной панели.

Так что-то вроде этого (не проверено)

var bmp : Tbitmap;

procedure AfterConstruction;
begin
  bmp := TBitmap.Create;
end;

procedure Destroy()
begin
  if Assigned(bmp) then FreeandNil(bmp);
end;

//redraw you bmp gradient
procedure Panel1.OnResize();
begin
  if Assigned(bmp) then //ensure the bmp s created in your constructor
  begin
  try
    bmp.SetBounds(Panel1.Clientrect); //ensure the bmp is the same size as the panel
    //draw your gradient on the bmp
    Panel1.OnPaint();//repaint the tpanel

  finally
    bmp.Free;
  end;
end;

//paint to the panel
procedure Panel1.OnPaint()
begin
  Panel1.Canvas.Draw(0,0,bmp); //use the OnPaint method to draw to the canvas
end;
  end;
end;
...