我正在编写 AlmediaDev 的 TscPanel 和 GlyphIcons 的一个小包装,以创建类似于 TLabeledEdit 的行为。在设计时添加组件后,我想检查 3 个条件:
csDesigning in ComponentState
)TscStyledForm
已经在该表单上并且激活了阴影属性。我的问题源于这样一个事实:我的 ComponentState 似乎是空的,这让我思考谁管理、添加或删除该属性的标志。由于它是从 TComponent 一直继承的,所以我不相信它是由第三方管理的。
作为一个附带问题,我是否能够从表单访问其他组件并在设计时更改它们的属性?就像我的第三个条件一样,如果它没有激活,我不能自己激活它吗?
提前致谢。
编辑 1 添加了我用来检索 ComponentState 的代码
constructor TImprovedFluentTopBar.Create(AOwner: TComponent);
begin
ShowMessage('Creating');
if (csDesigning in ComponentState) then // Pesquisar sobre isso aqui
begin
ShowMessage('Checking');
if not (AOwner is TForm) then
begin
raise Exception.Create('Owner must be a TForm.');
end;
var Found: Boolean := False;
for var I:Integer := 0 to TForm(AOwner).ComponentCount - 1 do // Cast de AOwner para TForm. Acessa a componentCount do TForm.
begin
if TForm(AOwner).Components[I] is TImprovedFluentTopBar then
begin
raise Exception.Create('TImprovedFluentTopBar is already on the form.');
end
else if TForm(AOwner).Components[I] is TscStyledForm then
begin
Found := True;
end;
end;
if not Found then
begin
raise Exception.Create('TscStyleControls not found in current TForm');
end;
end else begin
ShowMessage(ComponentStateAsString(ComponentState));
end;
inherited Create(AOwner);
Self.Caption := '';
Self.DragForm := True;
FCloseButton := TscGPGlyphButton.Create(Self);
FCloseButton.Align := alRight;
FCloseButton.SetBounds(20, 60, 20, 20);
FMinimizeButton := TscGPGlyphButton.Create(Self);
FMinimizeButton.Align := alRight;
FMinimizeButton.SetBounds(20, 20, 20, 20);
end;
和 ComponentStateAsString:
function ComponentStateAsString(ACS: TComponentState): String;
begin
Result := 'States: ';
if (csAncestor in ACS) then
begin
Result := Result + 'csAncestor ';
end;
if (csDesigning in ACS) then
begin
Result := Result + 'csDesigning ';
end;
if (csDestroying in ACS) then
begin
Result := Result + 'csDestroying ';
end;
if (csFixups in ACS) then
begin
Result := Result + 'csFixups ';
end;
if (csFreeNotification in ACS) then
begin
Result := Result + 'csFreeNotification ';
end;
if (csInline in ACS) then
begin
Result := Result + 'csInline ';
end;
if (csLoading in ACS) then
begin
Result := Result + 'csLoading ';
end;
if (csReading in ACS) then
begin
Result := Result + 'csReading ';
end;
if (csWriting in ACS) then
begin
Result := Result + 'csWriting ';
end;
if (csDesignInstance in ACS) then
begin
Result := Result + 'csDesignInstance ';
end;
end;
我的问题源于这样一个事实:我的 ComponentState 似乎是空的,这让我思考谁管理、添加或删除该属性的标志。
csDesigning
标志通过 ComponentState
方法添加到组件的 TComponent.SetDesigning()
属性或从中删除,当您的组件添加到已具有 TComponent.InsertComponent()
的 Owner
组件时,csDesigning
会调用该方法。旗帜。如果 inherited
参数不是 InsertComponent()
,则组件的 AOwner
构造函数会调用 nil
。
constructor TComponent.Create(AOwner: TComponent);
begin
...
if AOwner <> nil then AOwner.InsertComponent(Self);
end;
procedure TComponent.InsertComponent(const AComponent: TComponent);
var
...
begin
...
if csDesigning in ComponentState then
AComponent.SetDesigning(True);
...
end;
procedure TComponent.SetDesigning(Value, SetChildren: Boolean);
var
I: Integer;
begin
if Value then
Include(FComponentState, csDesigning) else
Exclude(FComponentState, csDesigning);
if SetChildren then
for I := 0 to ComponentCount - 1 do Components[I].SetDesigning(Value);
end;
因此,组件的构造函数应该在读取
inherited
属性之前调用 ComponentState
构造函数 BEFORE。但是,您正在调用
inherited
AFTER 阅读 ComponentState
,这就是为什么您还没有看到分配的 csDesigning
标志:
constructor TImprovedFluentTopBar.Create(AOwner: TComponent);
begin
inherited Create(AOwner); // <-- DO THIS FIRST!
ShowMessage('Creating');
...
//inherited Create(AOwner); // <-- NOT HERE!
...
end;
如果您不想早点调用
inherited
,那么您必须检查 csDesigning
属性中的 AOwner.ComponentState
标志:
constructor TImprovedFluentTopBar.Create(AOwner: TComponent);
begin
ShowMessage('Creating');
if (AOwner <> nil) and (csDesigning in AOwner.ComponentState) then
begin
...
end;
inherited Create(AOwner);
...
end;