为什么在GetClipRgn的结果上调用GetRgnBox会返回与GetClipRect截然不同的rect? [英] Why does calling GetRgnBox on the result of GetClipRgn return a very different rect than GetClipRect?
问题描述
我在 TCanvas
上有一个区域,其中有几个子区域需要重新粉刷,而其他地方则不需要。由于不必要的绘画可能会很昂贵,因此我尝试仅通过使用 GetClipRgn
在画布的手柄上和检查某些矩形是否与该区域重叠。
I've got an area on a TCanvas
that has several sub-areas that need to be repainted, but other points that don't. Since unnecessary painting can be expensive, I'm trying to only repaint what's needed by using GetClipRgn
on the canvas's handle and checking if certain rects overlap the region.
不幸的是,现在绘图以奇怪的方式失败了。所以我叫 GetRgnBox
以获取其边界矩形。从文档中,我希望它产生与调用 GetClipBox
在画布的手柄上。 (或者只是检索它的 ClipRect
,它是用这种方法计算的。)但是,这两个矩形却截然不同。
Unfortunately, now drawing is failing in bizarre ways. So I called GetRgnBox
on the region to get its bounding rect. From the documentation, I would expect this to yield exactly the same rect as calling GetClipBox
on the canvas's handle. (Or simply retrieving its ClipRect
, which calculates it that way.) But instead, the two rects are bizarrely different.
ClipRect
属性( GetClipBox
版本)给出(440、231、644 427)
,这正是我所期望的。但是在该区域上调用 GetRgnBox
会产生(0,0,204,196)
,这是完全错误的。有没有人知道这里发生了什么以及如何解决?
The ClipRect
property (the GetClipBox
version) gives (440, 231, 644, 427)
, which is what I expect. But calling GetRgnBox
on the region yields (0, 0, 204, 196)
, which is completely wrong. Does anyone have any idea what's going on here and how to fix it?
推荐答案
我的假设是,你没有告诉我,是您的Canvas具有使用逻辑坐标系转换的设备上下文。例如,如果这是 TGraphicControl
的画布,则可能会发生这种情况。因此,区别就是逻辑坐标和设备坐标的区别。
My assumption, what you have not told, is your Canvas has a device context that use a logical coordinate system transformation. This can happen, for instance, if it's the canvas of a TGraphicControl
. Hence, the difference is one that of logical coordinates and device coordinates.
您可以通过调用 GetWindowOrgEx $来轻松验证是否是这种情况。 c $ c> /
GetViewportOrgEx
。
You can easily verify if this is the case by calling GetWindowOrgEx
/GetViewportOrgEx
.
您调用 GetRgnBox
在由 GetClipRgn
检索的区域上。 GetClipRgn
检索使用设备坐标的区域。 SelectClipRgn
的文档中提到了此问题, GetClipRgn
的文档指出,它检索到的区域标识为:
You call GetRgnBox
on a region retrieved by GetClipRgn
. GetClipRgn
retrieves a region that use device coordinates. This is mentioned in SelectClipRgn
's documentation, which GetClipRgn
's documentation states that the region it retrieves is identified with:
应用程序定义的裁剪region是由 SelectClipRgn 函数标识的
的裁剪区域。
An application-defined clipping region is a clipping region identified by the SelectClipRgn function.
SelectClipRgn 函数假定在设备中指定了区域
的坐标
The SelectClipRgn function assumes that the coordinates for a region are specified in device units.
另一方面, GetClipBox
使用逻辑空间:
On the other hand, GetClipBox
uses logical space:
GetClipBox 返回基于给定设备
上下文的逻辑坐标。
GetClipBox returns logical coordinates based on the given device context.
一个非常简短的示例说明了 TPaintBox
的区别。将PaintBox放在具有一定偏移量的窗体上(即不在(0,0)处)。第一个 FillRect
调用填充了绘画盒的表面。这是 GetClipBox
返回的矩形,它使用逻辑坐标。
A very short example that demonstrates the difference on a TPaintBox
. Put a PaintBox on a form with some offset (i.e. not at (0, 0)). The first FillRect
call fills the paintbox's surface. This is the rectangle that GetClipBox
returns, which use logical coordinates.
第二个填充的矩形通过调用来标识到 SelectClipRgn
传递画布的剪切矩形。此矩形不支持绘画框本身的位置,而是与放置其的窗口的客户端原点对齐。 GetClipRgn
会检索此区域。
The second filled rectangle is identified with a call to SelectClipRgn
passing the canvas's clipping rectangle. This rectangle does not honor the position of the paintbox itself, but aligned to the client origin of the window it's placed on. GetClipRgn
would retrieve this region.
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;
这篇关于为什么在GetClipRgn的结果上调用GetRgnBox会返回与GetClipRect截然不同的rect?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!