【发布时间】:2020-02-18 19:59:23
【问题描述】:
我的任务是创建带有背景刻度和指针的指标。当指针移动时,我想在之前的位置重新绘制一部分背景,然后绘制一个新的指针。
指针形状被定义为一个多边形,我从中创建了一个 GDI+ 区域。
所以我有 2 个区域对象:旧的和新的。
我每 50 毫秒调用一次以下例程:
procedure TForm1._timerTick(Sender: TObject);
var
g: TGPGraphics;
mx: TGPMatrix;
hr: HRGN;
begin
if _newRegion <> nil then _newRegion.Free();
if _oldRegion <> nil then _oldRegion.Free();
_newRegion := _baseRegion.Clone();
_oldRegion := _baseRegion.Clone();
mx := TGPMatrix.Create();
try
mx.RotateAt(_angle, MakePoint(250.0, 120.0));
_oldRegion.Transform(mx);
mx.Reset();
Inc(_angle);
if _angle >= 360 then _angle := 0;
mx.RotateAt(_angle, MakePoint(250.0, 120.0));
_newRegion.Transform(mx);
finally
mx.Free();
end;
g := TGPGraphics.Create(Canvas.Handle);
try
hr := _oldRegion.GetHRGN(g);
try
InvalidateRgn(Handle, hr, False); //Restore background
finally
DeleteObject(hr);
end;
hr := _newRegion.GetHRGN(g);
try
InvalidateRgn(Handle, hr, False); //Draw new region
finally
DeleteObject(hr);
end;
finally
g.Free();
end;
end;
如您所见,我没有比调用InvalidateRgn 两次更好的主意:一次用于后台恢复,一次用于指针绘制。
WM_PAINT 处理程序如下所示:
procedure TForm1.Paint();
var
g: TGPGraphics;
mx: TGPMatrix;
brs: TGPSolidBrush;
begin
inherited;
g := TGPGraphics.Create(Canvas.Handle);
mx := TGPMatrix.Create();
brs := TGPSolidBrush.Create(MakeColor(255, 255, 0));
try
if _fullDraw then begin
_fullDraw := False;
end
else begin
g.IntersectClip(_oldRegion);
end;
g.DrawImage(_img, 0, 0);
if _newRegion <> nil then begin
g.ResetClip();
g.FillRegion(brs, _newRegion);
end;
finally
brs.Free();
mx.Free();
g.Free();
end;
end;
它总是做两个操作:恢复背景和绘制指针。
如果我执行两次InvalidateRgn,那么 Paint 也会被调用两次,导致四个操作而不是两个。
有什么方法可以在 Windows 级别的 Paint 方法中找出哪个区域正在失效?
【问题讨论】:
标签: windows gdi+ delphi-10-seattle invalidation