在Create / AfterConstruction代码中,我有两个独立的需求来检测是否正在从流中创建对象。
在第一种情况下,我有一个被引用的现有对象,因此它被实现为一个组件,以允许使用用户将该组件放在表单或数据模块上。并且需要在程序的不同运行中对于该对象示例保持唯一。在内部,Uuid保存在我们自己的类中,但我们在IDE中向用户提供了一个UuidString属性。我需要知道是否在首次创建时分配Uuid并注册组件,或者等到Loaded例程(如果不是从流中读取,则永远不会调用该例程)。
在第二种情况下,我有一组组件,为应用程序提供一个'OnReady'事件。一旦对象完全初始化(可能是异步的),事件就被调用。如果对象正在被流处理,那么我可以覆盖Loaded方法来进行额外的配置,但如果它没有被流处理,Loaded将永远不会被调用,我应该在AfterConstruction中开始额外的工作。
查看文档时,我认为我可以使用:
if( not (csLoading in Self.ComponentState) ) then
...
或者,若要特别在设计工具中拦截新建立的对象:
if( (csDesigning in Self.ComponentState) And
not (csLoading in Self.ComponentState) ) then
...
然而,在查看代码(我不是一个真正的 Delphi 程序员的背景)后,我看到csLoading只在Create / AfterConstruction执行 * 之后 * 才设置。
在Create / AfterConstruction执行过程中,我是否可以判断是否将调用Loaded?
我已经意识到,通过流创建的 * 所有 * 组件都将具有Owner<>nil
,但预计在运行时创建的组件通常也将具有Owner<>nil
。
我此刻唯一的想法是看看店主是不是装着这样的东西:
if( (Self.Owner<>nil) And (not (csLoading in Self.Owner.ComponentState)) ) then
...
这是正确的方法吗?或者有没有更好的“ Delphi 方法”来做?
2条答案
按热度按时间xuo3flqw1#
假设您的属性名为
UUIDString
,后面有一个字段FUUIDString
,那么这种方法应该可以实现:如果
UUIDString
在流阅读期间被加载,它将包含存储的值。否则Loaded内部的寄存器调用将生成一个新的值。xxe27gdn2#
你离解决方案很近了。你只需要重写正确的程序。
我使用“CreateWnd”的原因如下:
1.我需要初始化需要父级(面板)准备好句柄的图像,所以这个程序是正确的地方。
1.当建立ComponentState(使用csDesigning和/或csLoading)时,会呼叫它。
1.此时,任何已发布的属性都可用(已从DFM流入)。
1.它只被调用一次。
我正在使用的组件是一个“Picture- Button”,它是由一个TCustomPanel组成的,上面有一个TSpeedButton,面板上最多有4个图像。所以我想在面板上放置初始(默认)图像,这需要确定组件是何时第一次创建的(放在窗体上)。请参阅下面的一些代码〉〉