1

TPanelからコントロールを継承し、Paintイベントハンドラーで、グラデーションを使用してクライアントrect全体を描画しました。これは、ユーザーがサイズを変更するまでは完全に正常に機能します。パネルのサイズを変更すると、パネルコンポーネントのちらつきが大きくなります。

このちらつきを回避するにはどうすればよいですか。MS Office 2007でグラデーションが見られましたが、クライアント領域のサイズを変更してもちらつきはありません。これについて教えてください。

期待してくれてありがとう

4

2 に答える 2

3

この質問をご覧ください。TPaintBoxの右端のちらつきをなくす方法(たとえば、サイズ変更時)

ちらつきを回避するためのオプションとTPanelのオプションの概要。

編集:Windows7のDelphiXEバージョンで簡単なテストを行いました。

このコードではちらつきを再現できません。継承されたペイントは削除され、ペイントルーチンは非常に高速になります。

それでもちらつきが見られる場合は、Simonからの提案を実装できますが、コンポーネント自体の存続期間中、作成されたビットマップを保持することをお勧めします。

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.
于 2011-08-25T20:03:48.417 に答える
0

ちらつきを減らす方法は、グラデーションを一時的なビットマップに描画し、ビットマップのコンテンツ全体をパネルに描画することです。このメソッドは、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;
于 2011-08-26T00:32:41.780 に答える