#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 стал слишком сложным в своей реализации, особенно с тех пор, как были введены темы, что делает его поведение очень глючным и непредсказуемым ИМХО.