Проблема с мерцанием меток на панели формы Delphi-2009

#delphi #label #panel #delphi-2009 #flicker

#delphi #метка #панель #delphi-2009 #мерцание

Вопрос:

У меня есть простое приложение с панелью, содержащей 2 метки (например. A amp; B) и кнопка C, созданные Delphi 2009. Метка A будет отображать положение курсора при перемещении мыши внутри области панели. Метка B просто отображает статический текст (заголовок не изменится во время запуска приложения)

Если я перемещу мышь внутри панели, метка A будет мерцать.

Когда я включаю «Двойной буфер» формы, мерцание теряется. Кнопка C продемонстрирует, чтобы включить / отключить свойство «Двойной буфер»

Я хотел бы задать вопрос «Почему метка на панели мерцает? В чем основная причина? Как мы можем полностью решить эту проблему?

Вот мой код:

 unit DemoFlicker;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  System.StrUtils,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;


type
  TForm1 = class(TForm)
    pnlCtr: TPanel;
    btnDoubleBuffer: TButton;
    lblName: TLabel;
    lblNumber: TLabel;
    procedure btnDoubleBufferClick(Sender: TObject);
    procedure pnlCtrMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    FDoubleBuffer: Boolean;
  public
    { Public declarations }
  end;

 
var
  Form1: TForm1;

 
implementation

{$R *.dfm}

procedure TForm1.btnDoubleBufferClick(Sender: TObject);
begin
     FDoubleBuffer := not FDoubleBuffer;
     Self.DoubleBuffered := FDoubleBuffer;

     if FDoubleBuffer then
     begin
         btnDoubleBuffer.Caption := 'Not Apply Double Buffer';
     end
     else
     begin
         btnDoubleBuffer.Caption := 'Apply Double Buffer';
     end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    FDoubleBuffer := False;
    Self.DoubleBuffered := False;
end;

procedure TForm1.pnlCtrMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
    mousePos: string;
begin
    mousePos := Format('(X=%d, Y=%d)', [Mouse.CursorPos.X, Mouse.CursorPos.Y]);
    lblNumber.Caption := mousePos  ;
end;

end.
  

Ответ №1:

Мерцание возникает из-за того, как выполняется рисование. Без двойного буфера отрисовывается фон (окрашивается), а затем отрисовывается надпись. Итак, на данный момент вы видите только фон, а затем вы увидели надпись над фоном. Если вы повторите обновление, оно начнет мерцать.

При использовании «двойного буфера» рисование выполняется в невидимом буфере, а затем, когда рисование завершено, буфер отображается на экране. Таким образом, вы видите только полное изображение сразу и без мерцания.

Чтобы решить проблему, используйте двойную буферизацию, поскольку вы нашли ее самостоятельно.

Вы также можете создать новый компонент, который сам рисует все в своей процедуре рисования.

Комментарии:

1. Спасибо за ваш быстрый ответ. Итак, основная причина кроется в механизме рисования, как вы объяснили выше. Но у меня все еще есть путаница, то есть, если я больше не использую панель, я имею в виду поместить 2 метки (A amp; B) непосредственно в форму и не использовать двойной буфер -> Мерцания нет. Я не знаю, почему между двумя случаями возникают разные явления. Пожалуйста, ответьте мне (извините, я новичок в Delphi)

2. Я не думаю, что это все, что можно сказать по этому вопросу. Вполне возможно иметь отрисовку без мерцания без двойной буферизации. И желательно тоже.

3. @NamVu TForm (фактически TCustomForm) и TPanel (фактически TCustomPanel) имеют совершенно разные процедуры рисования.

Ответ №2:

У меня была такая же проблема, Delphi 10.4

Настройка заключающей TPanel таким образом —

 DoubleBuffered = True

ParentBackground = False
  

кажется, это исправлено.
VCL стал слишком сложным в своей реализации, особенно с тех пор, как были введены темы, что делает его поведение очень глючным и непредсказуемым ИМХО.