AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Die Delphi-IDE Wann sind objecte auf der IDE fertig initialisert?
Thema durchsuchen
Ansicht
Themen-Optionen

Wann sind objecte auf der IDE fertig initialisert?

Ein Thema von DrUArn · begonnen am 27. Feb 2018 · letzter Beitrag vom 28. Feb 2018
Antwort Antwort
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 11:44
Hi Himitsu,

danke für's mitdenken.

"Wenn du im Code (z.B. Button-Click) auf den Property/Setter zugreifst, dann ist es True?"

-> dann ist das FALSE, und man kann über SetShowpts(const Value: tshowOpts_UA) hier den SubRichEd ein und ausschalten.

Nur bei der Initialisierung, nach TSimpTestRich_UA.Create(AOwner:TComponent);overrid e;,wenn danach automatisch eine Eigenschaft nach der anderen über die Setter eingelesen wird, ist dort (csloading in ComponentState) TRUE.

Aber dein Hinweis ist schon richtig: Erst wenn alles gelesen ist, sollte man den Rest initialisieren.

Delphi-Quellcode:
protected
  { protected declarations }
procedure Loaded;override;// nun wieder versteckt

...

procedure TSimpTestRich_UA.Loaded;
begin
  inherited;
  setReadyForTmp(FReadyForTmp);//die anderen Komponenten initialisieren
  SetShowpts(FShowOpts);
end;
... so ich den unbedingt die Setter so nutzen will - die Warnung habe ich schon verstanden.

Finde ich aber praktisch: Man kann über FShowOpts:tShowOpts_UA; und dessen Setter die Kompenenten ein und ausschalten.
Diese Komponenten bekomme ich sogar in der IDE und im Objekt-Inspektor zu sehen, wenn ich die entsprechende Option anklicke (ShowOpts:=[ShowSubRichEd_UA, ...] oder setReadyForTmp:=true) an der Stelle, wohin ich sie in ihrem Create hinrechne.
Komponenten mit Feld kann ich sogar im Objekt-Inspektor editieren (z.B. Left, Top), die Änderungen werden aber nicht übernommen - logisch - läuft ja über Create.

Und man kann viel Unfug mit solchen Settern anrichten: Habe zum Test im Objekt-Inspektor in die Eigenschaft "SubRichEd" einen auch auf dem Desktop liegend TrichEdit eingebunden - das geht auch, und man kann diesen Richedit auch nutzen, aber wehe, man löscht in der IDE diesen Richedit mal schnell weg - dann kann man das Programm nicht mehr compilieren noch den SubRichEd vom Desktop nehmen, noch das Delphi mit speichern beenden. Mußte dann händisch aus der *.dfm die störenden Objekte (SubrichEd und Richedit) entfernen,
um wieder normal starten zu können.

"Entweder Self.Name niemals für SubKomponenten verwenden, oder diese Namen immer mit synchronisieren"
und hier war ich der irrigen Ansicht, daß, wenn ich mehrere TSimpTestRich_UA's auf den Desktop lege, es zu Namensdopplungen kommen kann - ist aber nicht so, da das nur beim Owner nicht passieren darf, Parent(hier tForm) ist das egal.

"oder diese Namen immer mit synchronisieren" heißt ? self.Name unbedingt selbst festlegen?


Grüße Uwe

Geändert von DrUArn (28. Feb 2018 um 11:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.381 Beiträge
 
Delphi 12 Athens
 
#2

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 11:58
Und man kann viel Unfug mit solchen Settern anrichten: ...
Man muß es nur richtig machen.

Delphi-Quellcode:
type
  TMyClass = class(TComponent)
  private
    FInstance: TComponent;
    procedure SetInstance(Value: TComponent);
  protected
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  published
    property Instance: TComponent read FInstance write SetInstance;
  end;

procedure TMyClass.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if Operation = opRemove then begin
    if FInstance = AComponent then
      FInstance := nil;
  end;
end;

procedure TMyClass.SetInstance(Value: TComponent);
begin
  //if Assigned(FInstance) then begin
  // FInstance.RemoveFreeNotification(Self);
  FInstance := Value;
  if Assigned(FInstance) then begin
    FInstance.FreeNotification(Self);
end;
FreeNotification hat keine Referenzzählung.
Weitere Property und auch Onwer oder Parent registrieren das ebenfalls, also einfach garnicht deregistrieren. (macht die TComponent von selber, wenn Einer von Beiden freigegeben wird)
Also kann man deregistrieren, aber nur wenn man die volle Kontrolle über alle Referenzen besitzt, oder wenn man definitiv nur die eintige Referenz sein kann. (nur interne Instanzen, auf die es von Extern keinen Zugriff gibt)

FInstance.FreeNotification(Self); und Self.FreeNotification(FInstance); ist das Gleiche ... die registrieren sich gegenseitig.



Unter ARC könnte man auch Weak-Referenzen nutzen, wo das ARC diese global registriert und auf NIL setzt, wenn jemand die Instanz freigibt.
var [weak] Instance: TComponent;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (28. Feb 2018 um 12:08 Uhr)
  Mit Zitat antworten Zitat
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 12:41
Hallo Himitsu,

das ist mir als Laien-Delphianer dann doch zu hoch.
Bin schon stolz darauf, ein trichedit gezwungen zu haben, mir Cell-Bereiche, die ich definiert habe, anzuzeigen und in diesen Bereichen wie in einer Tabellen-Celle editieren zu können.

By the way: im Zusammenhang mit meinem Beispielprojekt oben gibt es noch ein Problem mit einem modalen Fenster (darf das etwas löschen, was nicht in dessen Owner-Liste steht).
Sollte ich dazu einen neuen Thread aufmachen oder kann ich hier weiter machen?
Es gibt hier im Forum ja strenge Regeln ... .

Grüße Uwe
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.381 Beiträge
 
Delphi 12 Athens
 
#4

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 12:54
Ist eigentlich recht einfach, siehe kurzes Beispielcode.

Du hast eine Referenz zu einer externen oder fremden Komponente, welche jemand löschen könnte.
Nun sagst du dieser Komponente via FreeNotification "Gib mir Bescheid, wenn du verschwindest".
Das macht diese Kompnente dann im Notification-Event, wo du die Verbindung zwischen den Komponenten trennen kannst, also z.B. deine Variable auf NIL setzt.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
DrUArn

Registriert seit: 20. Mär 2003
130 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 13:14
Hallo Himitsu,

der Absturz ist mir auf der IDE passiert, nicht bei laufendem Programm. Ich schaue mir deinen Code noch an, aber dazu brauche ich wohl länger.

Ich versuch's mal mit dem Showmodal-Fenster:
(die mich interessierende Stelle habe ich weiter unten nochmal editiert)

Delphi-Quellcode:
procedure TSimpTestRich_UA.ShowOptsEditor;
//mal bitte nicht den Sinn dieser Routine hinterfragen - normalerweise steckt sie in
//einer Komponente, die nach außen mit Window-Messages kommuniziert

//mit dem Editor kann mann die Oben Beschriebenen Komoponenten (SubRichEd,...) laden und wieder löschen

var i,l,t,checkwidth:integer;
    tb:tbutton;
    tf:tform;
begin
  {das Modalfenster}
  tf:=tform.create(application);
  tf.name:='DockEinstellungen';
  tf.Caption:='DockEinstellungen von '+ owner.name;
  tf.AutoSize:=true;
  tf.formstyle:=fsstayontop;

 {die Checkbox-Box}
 if not assigned(groupbox) //beim ersten Aufruf kann sie nicht assigned sein
   then groupbox:=tgroupbox.create(owner);//Owner ist TSimpTestRich_UA
 groupbox.parent:=tf;//der Anzeige-Ort für die Groupbox ist das modale Fenster
 groupbox.name:='do_Groupbox';

l:=10; t:=20; checkwidth:=0;
{checkboxes zuordnen}
for I := integer(Low(tShowopt_UA)) to integer(High(tShowopt_UA)) do
begin
  with tcheckbox.create(groupbox) do
  begin
  parent:=groupbox;
  left:=l;top:=t;
  caption:=DockOptsCaps_UA[tShowopt_UA(i)];
  name:=DockOptsCaps_UA[tShowopt_UA(i)];
    if checkwidth<height + length(caption)* groupbox.font.size then
          checkwidth:=length(caption)* groupbox.font.size; //größte Breite mitrechnen

  checked:= tShowopt_UA(i) in Showopts;
  tag:=integer(tShowopt_UA(i));
  inc(t,height);
  OnClick:=onCheckboxclick; //was soll bei Clicken passieren
  end;
end;

inc(t,20);
{eine Extra-Checkbox, um zu bestimmen, ob die Eigenschaft sofort gesetzt werden soll - True=Ja}
  with tcheckbox.create(groupbox) do
  begin
  parent:=groupbox;
  left:=l;top:=t;
  checked:=false;
  caption:='sofort anwenden';
  name:='sofort_anwenden';
  end;
inc(t,20);

{noch die obligaten Schließen-Knöpfe}
with tbutton.create(tf) do
begin
parent:=tf;
top:=t;left:=groupbox.left;
name:='DockOptsButton_OK';
Caption:='OK/Schliessen';
ModalResult:=mrOk;
end;

with tbutton.create(tf) do
begin
parent:=tf;
top:=t;left:=groupbox.left+Width;
name:='ShowOptsButton_Abbrechen';
Caption:='Abbrechen';
ModalResult:= mrCancel;
t:=t+Height;
end;



for i := 0 to groupbox.controlcount-1 do
  groupbox.Controls[i].Width:=checkwidth; // alle Cjeckckboxen haben die gleich max. Breite -vielleicht nicht nötig

  groupbox.width:=checkwidth;//Groupbox auch die größte Breite
  groupbox.Height:=t+10;

  groupbox.name:='Andockoptionen';

{Erscheinungsort errechenen - geht aber nicht}
  tf.left:=left;
  tf.top:=top;


if tf.showmodal=mrok then
  onCheckboxclick(self);//normalerweise rufen die Checkboxen oncheckboxclick auf, hier vereinbarungsgemäß setzen dort ohne Prüfung sofortsetzen

tf.free;

{??lebt die Groupbox noch oder ist sie weg??
wenn ja, wie so - DER owner ist doch TSimpTestRich_UA?
}


if assigned(groupbox)
then
begin
  try
  groupbox.free; //ergibt Fehler
  except
  lines.add('groupbox scheint assigned, aber ist nicht löschbar');
  groupbox:=nil;
  end;
end;

// wenn ich GrouBox nicht nil setze und das Fenster neu aufrufe, gibts auch einen Fehler
//lesen von 000000 und das programm ist kaputt


end;

Wichtig für mich zum Verstehen ist nur dieser Teil:

Delphi-Quellcode:
// ....

if tf.showmodal=mrok then
  onCheckboxclick(self);//normalerweise rufen die Checkboxen oncheckboxclick auf, hier vereinbarungsgemäß setzen dort ohne Prüfung sofortsetzen

tf.free;

{??lebt die Groupbox noch oder ist sie weg??
wenn ja, wie so - DER owner ist doch TSimpTestRich_UA?
}


if assigned(groupbox)
then
begin
  try
  groupbox.free; //ergibt Fehler
  except
  lines.add('groupbox scheint assigned, aber ist nicht löschbar');
  groupbox:=nil;
  end;
end;

// wenn ich GrouBox nicht nil setze und das Fenster neu aufrufe, gibts auch einen Fehler
//lesen von 000000 und das programm ist kaputt

// ....
Es fühlt sich so an , als ob beim Schließen dieses modalen Fensters TF ein Object (hier GroupBox) gelöscht wird, obwohl es dem Shomodal-Fenster TF nicht gehört, also nicht in der Owner-Liste steht.


Und auf dem Desktop auftauchen tut dieses Fenster wo es will
{Erscheinungsort errechenen - geht aber nicht}
tf.left:=left;
tf.top:=top;


Grüße Uwe
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.381 Beiträge
 
Delphi 12 Athens
 
#6

AW: Wann sind objecte auf der IDE fertig initialisert?

  Alt 28. Feb 2018, 13:21
Der gezeigte Notification-Code ist vor allem für den Form-Designer gut, aber er geht überall. (Runtime im Programm, IDE oder sonstwo)

Tipp: Du hast doch ein DesignTime-Package mit deiner Komponente.
Da nun statt deiner Anwendung die IDE angeben, also im Menü > Tools > Startparameter
> Host-Anwendung: C:\Program Files (x86)\Embarcadero\RAD Studio\8.0\bin\bds.exe
> eventuell noch die Parameter: -np -pDelphi

Und nun kanns du deine Komponente in der IDE debuggen, innerhalb einer zweiten IDE-Instanz.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:39 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