为什么在GetClipRgn的结果上调用GetRgnBox会返回一个与GetClipRect非常不同的矩形?

Mas*_*ler 1 windows delphi winapi

我有一个区域TCanvas有几个需要重新绘制的子区域,但其他点没有.由于不必要的绘画可能很昂贵,我试图只GetClipRgn在画布的手柄上使用并重新检查某些区域是否与区域重叠,从而重新绘制所需的内容.

不幸的是,现在画画以奇怪的方式失败了.所以我呼吁GetRgnBox该地区得到它的边界.从文档中,我希望这会产生与调用GetClipBoxcanvas的句柄完全相同的rect .(或者只是检索它ClipRect,以这种方式计算它.)但相反,这两个部分是奇怪的不同.

ClipRect属性(在GetClipBox版)给出(440, 231, 644, 427),这是我的期望.但呼吁GetRgnBox该地区收益率(0, 0, 204, 196),这是完全错误的.有谁知道这里发生了什么以及如何解决它?

Ser*_*yuz 7

我的假设是,你没有告诉过,你的Canvas有一个使用逻辑坐标系转换的设备上下文.例如,如果它是a的画布,就会发生这种情况TGraphicControl.因此,差异是逻辑坐标和设备坐标的差异.

您可以通过调用GetWindowOrgEx/ 轻松验证是否是这种情况GetViewportOrgEx.

你打电话GetRgnBox给检索的地区GetClipRgn.GetClipRgn检索使用设备坐标的区域.这在SelectClipRgn文档中提到,该GetClipRgn文档说明它检索的区域标识为:

GetClipRgn:

应用程序定义的剪切区域是由SelectClipRgn函数标识的剪切区域.

SelectClipRgn:

SelectClipRgn函数假定为一个区域的坐标在设备单元被指定.


另一方面,GetClipBox使用逻辑空间:

GetClipBox根据给定的设备上下文返回逻辑坐标.


一个非常简短的例子,展示了a的不同之处TPaintBox.将PaintBox放在具有一些偏移量的表单上(即不在(0,0)处).第一个FillRect调用填充了paintbox的表面.这是GetClipBox返回的矩形,它使用逻辑坐标.

第二个填充的矩形SelectClipRgn通过调用传递画布的剪切矩形来标识.此矩形不支持绘制框本身的位置,而是与其所在窗口的客户端原点对齐.GetClipRgn会检索这个地区.

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.Brush.Color := clWhite;
  PaintBox1.Canvas.FillRect(PaintBox1.Canvas.ClipRect);

  SelectClipRgn(PaintBox1.Canvas.Handle,
      CreateRectRgnIndirect(PaintBox1.Canvas.ClipRect));
  PaintBox1.Canvas.Brush.Color := clYellow;
  PaintBox1.Canvas.FillRect(PaintBox1.Canvas.ClipRect);
end;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述