Following my last question, I have fallen into another problem.
The Full Context: I’m writing a small component to wrap two TscGPGlyphButton into TscPanel (both custom components from AlmediaDev, inheriting from TCustomControl
and TComponent
). All three elements appear in Design Time the exact way they should, but in runtime only the panel renders. I’ve read from other sources that it could be due:
- DFM Corruption, but I created another form from the beginning and it had the same problem.
- No Parenting, If I remove parenting it also won’t show on Design Time, but my problem seems to happen only in Runtime.
- Not set as
SubComponent
, which I think is the case only because once I addSetSubComponent
(right after the instance creation as the docs tells to), the code goes from not showing to displaying:
Exception EReadError in module IUD.exe at OOOBEADC.
Error reading ImprovedFluentTopBar1.CloseButton.Left:
Property CloseButton.Left does not exist.
Which is obviously not True, the property exist in its ancestors and is visible in the Object Inspector. For this case I have already inferred that it seems to happen during Form components creation, so my guess is that it’s trying to access the .Left
property before it even exists, but I don’t know why. Also this theory was reinforced by the fact that the error becomes
Exception EReadError in module IUD.exe at OOOBEADC.
Error reading ImprovedFluentTopBar1.MinimizeButton.Left:
Property MinimizeButton.Left does not exist.
if I change the order the properties are declared in the component class.
TL;DR My first state was: Panel renders, buttons doesn’t render. Added SetSubComponent to ComponentSetup (and after moved it directly into the constructor as the code shows) and now it raises a EReadError
. I don’t know what is happening.
The full code for the Component.
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, scControls, scGPControls, scStyledForm, Constants.UI;
type
TImprovedFluentTopBar = class(TscPanel)
private
FCloseButton: TscGPGlyphButton;
FMinimizeButton: TscGPGlyphButton;
procedure SetupComponent;
protected
procedure Resize; override;
public
constructor Create(AOwner: TComponent); override;
published
property CloseButton: TscGPGlyphButton read FCloseButton;
property MinimizeButton: TscGPGlyphButton read FMinimizeButton;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Improved UI Design', [TImprovedFluentTopBar]);
end;
{ TImprovedFluentPanel }
constructor TImprovedFluentTopBar.Create(AOwner: TComponent);
begin
inherited;
SetupComponent;
if (AOwner <> nil) and (csDesigning in AOwner.ComponentState) then // Pesquisar sobre isso aqui
begin
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
{$IFNDEF DEBUG}
raise Exception.Create('TImprovedFluentTopBar is already on the form.');
{$ENDIF}
end
else if TForm(AOwner).Components[I] is TscStyledForm then
begin
Found := True;
end;
end;
if not Found then
begin
{$IFNDEF DEBUG}
//raise Exception.Create('TscStyledForm not found in current TForm'); // TO-DO Remove || fix: Raises exception everytime it loads the form designer (prob loaded b4 TscStyledForm?)
{$ENDIF}
end;
end;
end;
procedure TImprovedFluentTopBar.Resize;
begin
inherited;
end;
procedure TImprovedFluentTopBar.SetupComponent;
begin
FMinimizeButton := TscGPGlyphButton.Create(Self);
FMinimizeButton.SetSubComponent(True);
FCloseButton := TscGPGlyphButton.Create(Self);
FCloseButton.SetSubComponent(True);
Self.Caption := '';
Self.DragForm := True;
Self.Align := alTop;
Self.Height := 28;
FMinimizeButton.Name := 'MinButton';
FCloseButton.Name := 'ClsButton';
FMinimizeButton.Parent := Self;
FMinimizeButton.Align := alRight;
FMinimizeButton.Left := 10;
FCloseButton.Parent := Self;
FCloseButton.Align := alRight;
FCloseButton.Left := 10;
FCloseButton.CanFocused := False;
FCloseButton.GlyphOptions.Kind := scgpbgkClose;
FCloseButton.GlyphOptions.Thickness := 1;
FCloseButton.GlyphOptions.DisabledColor := clWhite;
FCloseButton.GlyphOptions.FocusedColor := cl_CLOSE_BUTTON;
FCloseButton.GlyphOptions.HotColor := cl_CLOSE_BUTTON;
FCloseButton.GlyphOptions.NormalColor := clWhite;
FCloseButton.GlyphOptions.PressedColor := cl_CLOSE_BUTTON_PRESSED;
FCloseButton.GlyphOptions.DisabledColorAlpha := 30;
FCloseButton.GlyphOptions.FocusedColorAlpha := 255;
FCloseButton.GlyphOptions.HotColorAlpha := 255;
FCloseButton.GlyphOptions.NormalColorAlpha := 255;
FCloseButton.GlyphOptions.PressedColorAlpha := 255;
FCloseButton.Visible := True;
end;
end.