4

给定以下代码片段:

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 代码,以使以后可能偶然发现的其他人更容易理解这个问题。

4

2 回答 2

7

您可以保存恢复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;
  ...
于 2013-09-03T16:06:10.460 回答
3

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

SelectClipRgn查看您的代码,这对您来说应该足够RGN了,因为:

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

于 2013-09-03T15:37:13.520 回答