Двойная буферизация формы - не всегда волшебный трюк c для решения всех ваших проблем с мерцанием. вам нужно понять, почему у вас это мерцание в первую очередь.
если вы часто используете объект холста непосредственно в процедуре рисования, то вы ничего не делаете.
В большинстве случаев Чтобы решить эту проблему и уменьшить мерцание, вам необходимо нарисовать растровое изображение памяти, затем, наконец, CopyRect
для объекта canvas.
Что-то вроде этого для вашего компонента (замените процедуру Paint
на эту code)
procedure TRotateImage.Paint;
var
SavedDC: Integer;
PaintBmp: TBitmap;
begin
PaintBmp := TBitmap.Create;
try
PaintBmp.SetSize(Width, Height);
if not RotatedBitmap.Empty then
begin
if RotatedBitmap.Transparent then
begin
PaintBmp.Canvas.StretchDraw(ImageRect, RotatedBitmap);
end
else
begin
SavedDC := SaveDC(PaintBmp.Canvas.Handle);
try
SelectClipRgn(PaintBmp.Canvas.Handle, ImageRgn);
IntersectClipRect(PaintBmp.Canvas.Handle, 0, 0, Width, Height);
PaintBmp.Canvas.StretchDraw(ImageRect, RotatedBitmap);
finally
RestoreDC(PaintBmp.Canvas.Handle, SavedDC);
end;
end;
end;
if csDesigning in ComponentState then
begin
PaintBmp.Canvas.Pen.Style := psDash;
PaintBmp.Canvas.Brush.Style := bsClear;
PaintBmp.Canvas.Rectangle(0, 0, Width, Height);
end;
Canvas.CopyRect(ClientRect, PaintBmp.Canvas, PaintBmp.Canvas.ClipRect);
finally
PaintBmp.Free;
end;
end;
, если это не решит проблему полностью, вы можете взглянуть на этот набор компонентов без мерцания и попытаться адаптировать вращающийся код на одном из его компонентов или наследовать его (Я не автор, и он претендует на функциональность без мерцания).
FreeEsVclComponents GitHub репозиторий
Редактировать: после отладки Я обнаружил много проблем с этим элементом управления, поэтому я решил go с моей рекомендацией.
Я создал для вас следующий элемент управления
* 10 23 *
Все, что я сделал, это унаследовал от TEsImage
и внес некоторые изменения в его работу. Из старого элемента управления я использовал приведенную ниже процедуру для преобразования вращения.
function CreateRotatedBitmap(Bitmap: TBitmap; const Angle: Extended; bgColor: TColor): TBitmap;
Как видно из рисунка выше, процедура вращения не идеальна. Я предлагаю вам поискать альтернативу.
Я также разветвил репозиторий FreeEsVclComponents и добавил TAttitudeControl
к блоку Es.Images
, так что у вас есть все, что нужно для установки элемента управления в вашей системе. Нажмите здесь
Наконец я протестировал это в Токио, и из файла readme репозитория оно должно работать на XE2 без проблем.
Edit2: Я изменил CreateRotatedBitmap
на лучший (на основе GDI +), вот результат:
Я уже перенес изменения в Github так что вы можете git код оттуда. Я также добавляю код здесь на случай, если Github выйдет из строя (очень маловероятно:))
uses
WinApi.Windows, WinApi.GDIPApi, WinApi.GDIPObj, Vcl.Graphics, System.Types;
function RotateImage(Source: TBitmap; Angle: Extended; AllowClip: Boolean): TBitmap;
var
OutHeight, OutWidth: Integer;
Graphics: TGPGraphics;
GdiPBitmap: TGPBitmap;
begin
if AllowClip then
begin
OutHeight := Source.Height;
OutWidth := Source.Width;
end
else
begin
if (Source.Height > Source.Width) then
begin
OutHeight := Source.Height + 5;
OutWidth := Source.Height + 5;
end
else
begin
OutHeight := Source.Width + 5;
OutWidth := Source.Width + 5;
end;
end;
Result := TBitmap.Create;
Result.SetSize(OutWidth, OutHeight);
GdiPBitmap := nil;
Graphics := TGPGraphics.Create(Result.Canvas.Handle);
try
Graphics.SetSmoothingMode(SmoothingModeDefault);
Graphics.SetPixelOffsetMode(PixelOffsetModeHalf);
Graphics.SetInterpolationMode(InterpolationModeLowQuality);
Graphics.TranslateTransform(OutWidth / 2, OutHeight / 2);
Graphics.RotateTransform(Angle);
Graphics.TranslateTransform(-OutWidth / 2, -OutHeight / 2);
GdiPBitmap := TGPBitmap.Create(Source.Handle, Source.Palette);
try
Graphics.DrawImage(GdiPBitmap, 0, 0);
finally
GdiPBitmap.Free;
end;
finally
Graphics.Free;
end;
end;