如何撤消IntersectClipRect的效果?

时间:2013-09-03 15:31:55

标签: windows delphi gdi clipping

给出以下代码片段:

procedure TPicture.PaintLine(_Canvas: TCanvas; _Left, _Top, _Right, _Bottom: Integer);
begin
  IntersectClipRect(_Canvas.Handle, _Left, _Top, _Right, _Bottom);
  try
    _Canvas.MoveTo(_Left - 10, _Top - 10);
    _Canvas.LineTo(_Right + 10, _Bottom + 10);
    // (This is an example only, the actual drawing is much more complex.)
  finally
    SelectClipRgn(_Canvas.Handle, 0); // This does too much
  end;
end;

我想撤消对IntersectClipRect调用所产生的剪辑,以便先前激活的剪辑再次变为活动状态。在上面的代码中,这是由SelectClipRgn(...,0)完成的,它完全关闭了裁剪。这种方法很有效,但之后没有裁剪活动,所以在上面之后执行的一些绘图将绘制到不应该绘制的区域。

那么,只撤消IntersectClipRect效果的正确方法是什么?

编辑:在理解了Sertac的评论之后删除了不必要的CreateRectRgn和DeleteObject代码,以使其他人可以在以后偶然发现这个问题时更具可读性。

2 个答案:

答案 0 :(得分:6)

你可以saverestore DC的状态:

var
  //  RGN: HRGN;
  SavedDC: Integer;
begin
//  RGN := CreateRectRgn(_Left, _Top, _Right, _Bottom);
  SavedDC := SaveDC(_Canvas.Handle);
  try
    IntersectClipRect(_Canvas.Handle, _Left, _Top, _Right, _Bottom);
    _Canvas.MoveTo(_Left - 10, _Top - 10);
    _Canvas.LineTo(_Right + 10, _Bottom + 10);
    // (This is an example only, the actual drawing is much more complex.)
  finally
    RestoreDC(_Canvas.Handle, SavedDC);
  end;
  ...

答案 1 :(得分:3)

IIRC,首先使用GetClipRgn存储当前剪辑区域,并在完成后再次SelectClipRgn存储的区域。

查看您的代码,再次SelectClipRgn RGN就足够了,因为:

  

IntersectClipRect函数从当前剪切区域和指定矩形的交点创建剪切区域。