在WM_PAINT处理程序中查找被InvalidateRgn无效的区域

问题描述 投票:0回答:1

我的任务是创建一个带有背景刻度和指针的指示器。当指针移动时,我想在其先前位置重新绘制背景的一部分,然后绘制一个新的指针。

指针形状定义为我从中创建了GDI +区域的多边形。

所以我有2个区域对象:旧的和新的。

每隔50毫秒,我会调用以下例程:

procedure TForm1._timerTick(Sender: TObject);
var
  g: TGPGraphics;
  mx: TGPMatrix;
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
    InvalidateRgn(Handle, _oldRegion.GetHRGN(g), False); //Restore background
    InvalidateRgn(Handle, _newRegion.GetHRGN(g), False); //Draw new region
  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
1个回答
0
投票

WM_PAINT处理程序内部,您可以使用以下任何一种:

两种方法都将为您提供一个需要绘制HDC的剪切区域。您在该裁剪区域之外所做的任何绘图都将被丢弃。因此,您可以将此作为一种优化,以免浪费精力绘画任何将被丢弃的东西。

© www.soinside.com 2019 - 2024. All rights reserved.