【问题标题】:How do i undo the effect of IntersectClipRect?如何撤消 IntersectClipRect 的效果?
【发布时间】:2013-09-06 21:56:50
【问题描述】:

给定以下代码sn-p:

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

【问题讨论】:

  • 不相关,但只是一个建议... 下划线 _ 前缀通常用于全局变量(与任何对象无关),而前缀 A 通常建议用于方法参数;或者根本没有前缀。如果您按照现在的方式进行操作,没有什么坏处,只是建议您遵循更多的标准做法。至少你添加了一个前缀来明确区分这些,尽管我建议使用 A 而不是 _ 以更符合编码实践。
  • 我发布了一个答案,考虑到您实际上并没有以任何方式使用您在“尝试”之前创建的区域 - 直到“最终”。你对问题的演示是否正确?还是问题中的代码应该不同?
  • @Jerry Dodge:我不打算讨论编码风格。根据我的经验,这不会导致任何结果。
  • @Sertac Akyuz:根据 MSDN 文档,IntersectClipRect 必须传递一个现有的 HRGN。
  • @dumm - 再次阅读文档。如您所见,您没有将任何区域传递给它。

标签: windows delphi gdi clipping


【解决方案1】:

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

看你的代码,SelectClipRgnyour RGN 应该就够了,因为:

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

【讨论】:

  • 我不确定我是否理解您想通过第二段告诉我的内容,但使用 GetClipRgn 和 SelectClipRgn 就可以了。
  • IntersectClipRect 将创建一个新区域。您的RGN 中的区域应该仍然未修改并且可以重新选择。话又说回来,我没有仔细看:您从不在代码中使用该区域。
【解决方案2】:

您可以save 和restore 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;
  ...

【讨论】:

  • 嗯,这实际上可能是更好的解决方案,因为除了剪切区域之外,我的实际代码还保存和恢复字体、笔和画笔。
  • 根据您的代码,SaveDC 可能确实是更好的方法。
猜你喜欢
  • 2019-06-10
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 2014-04-12
  • 2012-07-10
  • 1970-01-01
  • 2021-01-19
相关资源
最近更新 更多