如何在Delphi Athens中使用Skia Canvas创建设计时组件?
解决Delphi Athens中Skia组件设计时AccessViolation问题
核心原因
设计时IDE环境不会自动执行运行时的初始化逻辑,比如ALGlobalUseSkia := True这类Skia全局配置代码,导致组件在设计时渲染时因Skia未完成初始化触发AV错误。
具体实现方案
1. 在组件单元的初始化/终结块处理设计时判断
在自定义组件单元的initialization和finalization块中,判断当前是否处于设计时环境,执行对应的Skia初始化:
unit YourCustomSkiaComponent; interface uses System.Classes, Vcl.Controls, Skia, Skia.Vcl; type TYourCustomSkiaComponent = class(TGraphicControl) protected procedure Paint; override; end; implementation uses DesignIntf; // 引入设计时相关单元 procedure TYourCustomSkiaComponent.Paint; var LCanvas: ISkCanvas; begin inherited; // Skia Canvas渲染逻辑示例 LCanvas := TSkPaintBoxHelper.CreateSkCanvas(Canvas, ClientRect); try LCanvas.DrawRect(TRectF.Create(ClientRect), TSkPaint.Create(ColorToSkColor(clRed))); finally LCanvas := nil; end; end; initialization // 判断是否处于设计时环境 if Assigned(Designer) then begin if not ALGlobalUseSkia then ALGlobalUseSkia := True; // 确保Skia底层库加载完成 TSkLibrary.Load; end; finalization // 设计时环境下可选择性重置全局设置(按需) if Assigned(Designer) then begin // ALGlobalUseSkia := False; end; end.
2. 在组件构造函数或Loaded事件中补充初始化
如果单元初始化块的时机不合适,可在组件内部的构造函数或Loaded事件中处理:
constructor TYourCustomSkiaComponent.Create(AOwner: TComponent); begin inherited; if (csDesigning in ComponentState) then begin if not ALGlobalUseSkia then ALGlobalUseSkia := True; TSkLibrary.Load; end; end;
3. IDE兼容性配置
- 确保Skia相关的设计时包(如
Skia.Design)已添加到组件包的requires列表并正确安装到IDE - 设计时预览尽量简化渲染逻辑,避免执行复杂业务代码,仅保留占位或基础图形绘制
关键注意事项
ALGlobalUseSkia是全局变量,设置后会影响整个IDE环境,终结时可按需重置,避免干扰其他组件TSkLibrary.Load必须在所有Skia相关操作前执行,否则会因底层库未加载触发AV
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

