Delphi 如何访问TCanvas.ClipRect?
我正在尝试将一些代码从Delphi移植到Firemonkey(XE6) 我遇到了一个函数的问题,该函数将引用调用方提供的TCanvas。画布可以来自TPaintBox、TPanel、TForm或TBitmap。该函数读取TCanvas.ClipRect属性,以避免在其外部进行cpu密集型绘图。(cliprect表示TForm、TPaintBox等的无效区域) 不幸的是,TCanvas ClipRect属性似乎不再存在。有人知道我如何访问Firemonkey中的TCanvas.ClipRect吗?我确实注意到TPaintBox和TPanel现在有一个ClipRect属性,所以我可以使用它们,但TForm和TBitmap没有Delphi 如何访问TCanvas.ClipRect?,delphi,firemonkey,Delphi,Firemonkey,我正在尝试将一些代码从Delphi移植到Firemonkey(XE6) 我遇到了一个函数的问题,该函数将引用调用方提供的TCanvas。画布可以来自TPaintBox、TPanel、TForm或TBitmap。该函数读取TCanvas.ClipRect属性,以避免在其外部进行cpu密集型绘图。(cliprect表示TForm、TPaintBox等的无效区域) 不幸的是,TCanvas ClipRect属性似乎不再存在。有人知道我如何访问Firemonkey中的TCanvas.ClipRect吗?
请注意,我不是试图在画布中创建或更改cliprect,而是试图读取它。DoBeginScene有一个cliprect参数。但似乎没有一种方法能够真正检索到这个值。除此之外,画布上可能还有其他剪辑 为了获得剪辑矩形,需要画布的dc或cgcontext。您可以使用RTTI获得它。以下是OSX的一个示例:
function TCanvasCHelper.GetCGContext: CGContextRef;
var
Context: TRttiContext;
Field: TRttiField;
begin
// needs about 1ms
Field := Context.GetType(TCanvasQuartz).GetField('FContext'); // get private field using RTTI
Assert(Field <> nil);
Result := PPointer(Field.GetValue(Self).GetReferenceToRawData)^;
end;
函数tcanvacshelper.GetCGContext:CGContextRef;
变量
语境:语境;
字段:TRttiField;
开始
//大约需要1毫秒
字段:=Context.GetType(TCanvasQuartz.GetField('FContext');//使用RTTI获取私有字段
断言(字段nil);
结果:=PPointer(Field.GetValue(Self.GetReferenceToRawData)^;
结束;
不幸的是,为此使用RTTI可能没有要求的那么快。最后,我不得不创建一个FMX.Canvas.*类的副本来公开CGContext或DC。如果你想用FMX没有实现的画布做更高级的事情,你无论如何都需要这个
当您拥有CGContext或DC时,如果画布支持,您可以使用操作系统的功能,如CGContextGetClipboondingBox或GetClipBox来检索剪贴画。您可以使用
TControl
的Scene
属性。它有一个要绘制的剪辑矩形列表。使用GetUpdateRectScont
和GetUpdateRectScont
读取它们
例如,此代码读取需要重新绘制的矩形:
lStr := '';
for i := 0 to MyControl.Scene.GetUpdateRectsCount-1 do
with MyControl.Scene.GetUpdateRect(i) do
lStr := lStr + Format('(%g,%g,%g,%g)', [Left,Top,Right,Bottom]);
你可能问错了问题。这两个框架非常不同。您应该询问如何在新框架中解决问题。没有
TCanvas.ClipRect
,您可以通过检查FMX.Graphics.pas
源代码看到这一点FMX.Graphics.TCanvas
是一个抽象类,这意味着您无法实际创建它;您可以创建它的子代来实现该功能,并可以添加其他功能FMX.Forms.TCustomForm.addupdates
使用tcavasmanager.DefaultCanvas.GetCanvasStyle中的tcavasstyle.SupportClipRects查看当前画布是否支持ClipRects,这表明并非所有的tcavas
子体都支持ClipRects。如果后代不支持它,您就得不到它。@Ken您可以进一步说,如果后代不支持它,您也不需要它。:)@Ken非常感谢您确认TCanvas.ClipRect已不存在。@David Hefferman您可以在我的问题中看到,通过使用TPaintBox和TPanel ClipRect,我已经在新框架中找到了解决方案。我只是想知道是否有一种方法仍然可以从画布上获得它,这是一种更优雅的解决方案。对于TForm和TBitmap的情况,我必须解决。非常感谢,但我认为这将非常缓慢。我只是将TPaintBox.ClipRect或TPanel.ClipRect从包含画布的对象传递到函数。