Моя задача - создать индикатор с фоновой шкалой и указателем. Когда указатель перемещается, я хотел бы перерисовать часть фона на прежнем месте, а затем нарисовать новый указатель.
Форма указателя определяется как многоугольник, из которого я создал область 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, какая область признана недействительной?