Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Wird Komponente aus DFM geladen? (https://www.delphipraxis.net/158039-wird-komponente-aus-dfm-geladen.html)

himitsu 3. Feb 2011 10:11

Wird Komponente aus DFM geladen?
 
Morschn :hi: ,

ob eine Komponente "gerade" aus der DFM geladen wird, soll man ja "angeblich" über Delphi-Referenz durchsuchenTComponent.ComponentState rausbekommen, siehe csLoading und csReading.

Warum gibt es das aber noch nicht im Constructor?
OK, das kann ich mir schon fast denken, also wie kann man dieses dort dennoch mitbekommen?

Grund: Am Ende des Constructor, bzw. in AfterConstruction wird eine Aktion gestartet, welche aber erst anlaufen soll, wenn das Laden fertig ist, falls es über die DFM geschieht.
Dafür stellt die VCL ja Delphi-Referenz durchsuchenTComponent.Loaded bereit, wo ich das machen könnte, also würde ich das Starten nun dahin verschieben.

> Problem gelöst?

Leider nicht, denn die Aktion soll ja auch anlaufen, wenn die Komponente manuell/dynamisch erzeugt wird.
In diesem Fall wird Loaded aber nicht aufgerufen und ich müßte dennoch im Constructor/AfterConstruction starten ... nur leider bekomm ich da nicht mit, ob die Komponente manuell/dynamisch oder über die VCL erstellt wurde, da ComponentState dort immer leer ist. :cry:

Bummi 3. Feb 2011 10:56

AW: Wird Komponente aus DFM geladen?
 
Ich habe gerade mal alle denkbaren Methoden überladen und eine Message ausgeben lassen, ich habe nichts sinnvolles gefunden was nach Loaded ausgeführt wird.

Memnarch 3. Feb 2011 11:50

AW: Wird Komponente aus DFM geladen?
 
Nur mal ne Vermutung:
Wenn du eine Form zur laufzeit erstellst, und sie bereits vorher einmal erstellt wurde, bezweifle ich, dass er wieder auf die File zugreift. Schätze eher, dass er die DFM direkt beim programmstart initialisiert oder nur einmal ab dem zeitpunkt wo sie benötigt wird.(bei ersterem wäre auch beim erstmaligen dynamischen erstellen kein 'Loaded' fällig)



Aber nur seeeehr wage gvermutungen, weil ich da keine ahnung habe^^"

MFG
Memnarch

Deep-Sea 3. Feb 2011 12:36

AW: Wird Komponente aus DFM geladen?
 
Delphi-Quellcode:
If csLoading in Owner.ComponentState then ... ;

Das könnte im Create helfen :-D

himitsu 3. Feb 2011 12:43

AW: Wird Komponente aus DFM geladen?
 
@Deep-Sea: Das ist ja mein Problem ... dieses Flag vurde von der VCL einfach vergessen. :wall:
siehe "im Programm von VCL aus DFM laden"

Ach ja, Delphi XE ... wo anders hab ich's noch nicht probiert.

Es handelt sich um eine Serverkomponente mit Autostartfunktion und dieses Autostart macht mir grad Sorgen ... also wann ich den Server Starte, wenn Autostart=true, da dieses standardmäßig auf True steht.



Hab mal schnell eine Demo erstellt.
Code:
in Formdesigner einbinden:

TMyTestComponent.Create(459394672) [csDesigning]
TMyTestComponent.AfterConstruction(459394672) [csDesigning]

in Formdesigner laden/anzeigen:

TMyTestComponent.Create(459394192) [csDesigning]
TMyTestComponent.AfterConstruction(459394192) [csDesigning]
TMyTestComponent.SetText(459394192) = "abcdef" [csLoading,csReading,csDesigning]
* TMyTestComponent.Loaded(459394192) [csDesigning]

im Programm von VCL aus DFM laden

Debug-Ausgabe: TMyTestComponent.Create(18795632) []
Debug-Ausgabe: TMyTestComponent.AfterConstruction(18795632) []
Debug-Ausgabe: TMyTestComponent.SetText(18795632) = "abcdef" [csLoading,csReading]
* Debug-Ausgabe: TMyTestComponent.Loaded(18795632) []

dynamisch erzeugen (Button1)

Debug-Ausgabe: TMyTestComponent.Create(18796112) []
Debug-Ausgabe: TMyTestComponent.AfterConstruction(18796112) []
* fehlt
Debug-Ausgabe: TMyTestComponent.SetText(18796112) = "123456" []
Das * zeigt, wo ich spätestens meine Aktion ausführen möchte.
fehlt: hätte es ja gerne in Create/AfterConstruction gemacht, aber da gibt es ja kein csLoading, woran ich mich orientieren kann, ob jetzt oder erst in Loaded.

Delphi-Quellcode:
procedure TForm3.Button1Click(Sender: TObject);
var
  C: TMyTestComponent;
begin
  C := TMyTestComponent.Create(Self);
  C.Text := '123456';
end;
Delphi-Quellcode:
unit MyTestComponent;

interface

uses
  Windows, SysUtils, Classes, Controls, ExtCtrls, Dialogs, TypInfo;

type
  TMyTestComponent = class(TPaintBox)
  private
    { Private-Deklarationen }
    FText: String;
    function Conv(C: TComponentState): String;
    procedure SetText(Value: String);
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    constructor Create(AOwner: TComponent); override;
    procedure AfterConstruction; override;
    procedure Loaded; override;
  published
    { Published-Deklarationen }
    property Text: String read FText write SetText;
  end;

procedure Register;

implementation

function TMyTestComponent.Conv(C: TComponentState): String;
begin
  Result := SetToString(PTypeInfo(TypeInfo(TComponentState)), Word(C), True)
end;

procedure TMyTestComponent.SetText(Value: String);
begin
  OutputDebugString(PChar(Format('TMyTestComponent.SetText(%d) = "%s" %s',
    [Integer(Self), Value, Conv(ComponentState)])));
  MessageBox(0, PChar(Format('TMyTestComponent.SetText(%d) = "%s" %s',
    [Integer(Self), Value, Conv(ComponentState)])), nil, 0);
end;

constructor TMyTestComponent.Create(AOwner: TComponent);
begin
  inherited;
  FText := 'abcdef';
  OutputDebugString(PChar(Format('TMyTestComponent.Create(%d) %s',
    [Integer(Self), Conv(ComponentState)])));
  MessageBox(0, PChar(Format('TMyTestComponent.Create(%d) %s',
    [Integer(Self), Conv(ComponentState)])), nil, 0);
end;

procedure TMyTestComponent.AfterConstruction;
begin
  inherited;
  OutputDebugString(PChar(Format('TMyTestComponent.AfterConstruction(%d) %s',
    [Integer(Self), Conv(ComponentState)])));
  MessageBox(0, PChar(Format('TMyTestComponent.AfterConstruction(%d) %s',
    [Integer(Self), Conv(ComponentState)])), nil, 0);
end;

procedure TMyTestComponent.Loaded;
begin
  inherited;
  OutputDebugString(PChar(Format('TMyTestComponent.Loaded(%d) %s',
    [Integer(Self), Conv(ComponentState)])));
  MessageBox(0, PChar(Format('TMyTestComponent.Loaded(%d) %s',
    [Integer(Self), Conv(ComponentState)])), nil, 0);
end;

procedure Register;
begin
  RegisterComponents('himitsu', [TMyTestComponent]);
end;

end.

Deep-Sea 3. Feb 2011 12:47

AW: Wird Komponente aus DFM geladen?
 
Also ich hab es vorher getestet: Bei mir geht es. Aber vlt. verstehe ich nur nicht ganz, was du willst.
Aber zum Hinweis: In dem Beispiel prüfe ich auf OWNER.ComponentState, und nicht auf den eigenen.

Bummi 3. Feb 2011 13:11

AW: Wird Komponente aus DFM geladen?
 
und eine Q&D, Loaded aufrufen wenn Du es zur Laufzeit erzeugst....:oops:

himitsu 3. Feb 2011 13:17

AW: Wird Komponente aus DFM geladen?
 
Ah, das Owner hab ich übersehn.

Hmm, stimmt, da steht es drin ... nur eben nicht im Eigenen.
Wobei das ja mit csDesigning klappt und es überall richtig drinsteht ... nur eben nicht beim cdLoading kommt es erst so spät.

@Bummi: Sowas vergißt man ja schnell mal. :oops:


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz