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 "Element '' hat kein übergeordnetes Fenster" (https://www.delphipraxis.net/86317-element-hat-kein-uebergeordnetes-fenster.html)

xZise 12. Feb 2007 15:42


"Element '' hat kein übergeordnetes Fenster"
 
Ich Bau meine Memo um und schreibe eine Komponente mit einer ListBox.
Problem ist nur, wenn ich dessen repräsetant (die Property) setze, und as "StringList"-Editor-Fenster schliesse, dann kommt die Meldung, dass Element '' kein übergeordnetes Fenster hat.

Ich bin auch ratlos, woran es liegen könnte...
Wenn ihr Code braucht, dann schicke ich ihn nach (bitte nur einzelene Segemente, wie "Destroy-funktion", "Header" o.ä.

yörsch 12. Feb 2007 15:48

Re: "Element '' hat kein übergeordnetes Fenster"
 
Hai, :hi: das Fenster müstest du im create als Referenz mit geben, und dann setzen! dann sollte es gehn...

xZise 12. Feb 2007 15:54

Re: "Element '' hat kein übergeordnetes Fenster"
 
Du meinst:

Delphi-Quellcode:
constructor Create(AOwner : TComponent)
???
Ist schon so... Die Listbox hat auch dessen Owner...

yörsch 12. Feb 2007 16:01

Re: "Element '' hat kein übergeordnetes Fenster"
 
Gib mal einen codeschnipsel vielleicht fällt mir auf :roll:

xZise 12. Feb 2007 16:06

Re: "Element '' hat kein übergeordnetes Fenster"
 
Die Create Methode:
Delphi-Quellcode:
constructor TCompletionMemo.Create(AOwner: TComponent);
begin
   inherited;
  completionBox := TListBox.Create(self);
  completionBox.Parent := AOwner as TWinControl;
  completionBox.Width := FCompletionSizeWidth;
  completionBox.Height := FCompletionSizeHeight;
  FCompletionList := TStringList.Create;
end;
Und ggf. wichtig:
Die Property der ListBox:
Delphi-Quellcode:
  published
    property CompletionList : TStringList read FCompletionList write FCompletionList;

DGL-luke 12. Feb 2007 16:09

Re: "Element '' hat kein übergeordnetes Fenster"
 
bitte ersma Parent zuweisen.

Sidorion 12. Feb 2007 16:14

Re: "Element '' hat kein übergeordnetes Fenster"
 
Die Strings von der ListBox werden wie die von der ComboBox vom BS verwaltet. Und das BS kann das erst, wenn die ListBox ein Handle hat. Du kannst mal schaun, ob 'completionBox.HandleNeeded' was hilft. Nen parent zuweisen hilft nicht. Der könnte ja auch noch 'unsichtbar' sein und kein Handle haben.
[edit]: das HandleNeeded nachdem Zuweisen eines Parent schreiben, weil ohne den ist das BS hilflos in Sachen Handle kreieren.

yörsch 12. Feb 2007 16:39

Re: "Element '' hat kein übergeordnetes Fenster"
 
Hmm??? Sidorion hat da leiderrecht...
wenn´s möglich ist das TStringList.Create vieleicht zu einem späteren Zeitpunkt ausführen??
also im onShow oder so...

xZise 12. Feb 2007 17:13

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von DGL-luke
bitte ersma Parent zuweisen.

Wovon? Wenn du das Memofeld meinst => inherited, wenn du die ListBox meinst => Create von dem Memofeld:
Delphi-Quellcode:
completionBox.Parent := AOwner as TWinControl;
Zitat:

Zitat von yörsch
Hmm??? Sidorion hat da leiderrecht...
wenn´s möglich ist das TStringList.Create vieleicht zu einem späteren Zeitpunkt ausführen??
also im onShow oder so...

Ich verstehe nicht, warum das so wichtig ist, weil die StringList nicht an der ListBox hängt. Nur wenn sie angezeigt wird (was sie nicht wird), wird die gebraucht.

xZise hat folgendes hinzugefügt:
Das funktioniert nicht:
Zitat:

---------------------------
Fehler
---------------------------
nil kann nicht zu TRichEditStrings zugewiesen werden.
---------------------------
OK Details >>
---------------------------




Zitat:

Zitat von Sidorion
Die Strings von der ListBox werden wie die von der ComboBox vom BS verwaltet. Und das BS kann das erst, wenn die ListBox ein Handle hat. Du kannst mal schaun, ob 'completionBox.HandleNeeded' was hilft. Nen parent zuweisen hilft nicht. Der könnte ja auch noch 'unsichtbar' sein und kein Handle haben.
[edit]: das HandleNeeded nachdem Zuweisen eines Parent schreiben, weil ohne den ist das BS hilflos in Sachen Handle kreieren.

Ich werde mal gucken...

PS: Ich bin noch in der IDE ... Nur damit ihr das nicht durcheinander bringt!

xZise hat folgendes hinzugefügt:
Das tut es auch nicht :/ Ich habe kein Plan, warum das nicht funktioniert...

Vielleichts hilft es ja:
Delphi-Quellcode:
  TKeyPress = procedure (Sender: TObject; var Key: Char) of object;
  TKeyDown = procedure (Sender: TObject; var Key: Word; Shift: TShiftState) of object;
  TSize = array [0..1] of Integer;

  TCompletionMemo = class(TMemo)
  private
    FCompletionList : TStrings;
    completionBox : TListBox;

    FMoveableCaret: Boolean;
    preSelect : string;

    caretPosition : Integer;
    FCompletionSizeWidth: Integer;
    FCompletionSizeHeight: Integer;

    procedure repositionating;
    procedure SetCompletionSizeHeight(const Value: Integer);
    procedure SetCompletionSizeWidth(const Value: Integer);
  protected
    procedure KeyDown(var Key: Word; Shift: TShiftState); override;
    procedure KeyPress(var Key: Char); override;
  public
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;
  published
    property CompletionList : TStrings read FCompletionList write FCompletionList;
    property CompletionSizeWidth : Integer read FCompletionSizeWidth write SetCompletionSizeWidth default 80;
    property CompletionSizeHeight : Integer read FCompletionSizeHeight write SetCompletionSizeHeight default 40;
    property MoveableCaret : Boolean read FMoveableCaret write FMoveableCaret;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TCompletionMemo]);
end;

{ TCompletionMemo }

constructor TCompletionMemo.Create(AOwner: TComponent);
begin
   inherited;
  completionBox := TListBox.Create(self);
  completionBox.Parent := AOwner as TWinControl;
  completionBox.Width := FCompletionSizeWidth;
  completionBox.Height := FCompletionSizeHeight;
  completionBox.HandleNeeded;
  FCompletionList := TStringList.Create;
end;

destructor TCompletionMemo.Destroy;
begin
  FreeAndNil(completionBox);
  FreeAndNil(FCompletionList);
  inherited;
end;

procedure TCompletionMemo.KeyDown(var Key: Word;
  Shift: TShiftState);
begin
  {...}
  inherited;
end;

procedure TCompletionMemo.KeyPress(var Key: Char);
var
   i : Integer;
begin
  {...}
  inherited;
end;

procedure TCompletionMemo.repositionating;
var
   CaretPos : TPoint;
begin
  CaretPos := GetCaretPos;
  CaretPos := ClientToParent(CaretPos);

  with completionBox do
  begin
    Left := CaretPos.X + 3;
    Top := CaretPos.Y - Font.Height + 3;
  end;
end;

procedure TCompletionMemo.SetCompletionSizeHeight(const Value: Integer);
begin
  FCompletionSizeHeight := Value;
  completionBox.Height := Value;
end;

procedure TCompletionMemo.SetCompletionSizeWidth(const Value: Integer);
begin
  FCompletionSizeWidth := Value;
   completionBox.Width := Value;
end;

end.

xZise 14. Feb 2007 14:16

Re: "Element '' hat kein übergeordnetes Fenster"
 
Die Frage ist leider immernoch nicht beantwortet :(
Wäre nett, wenn mich mal jemand aufklären könnte... Immerhin gibt es ja auch andere Controls, welche TStrings als Property verwenden...

DGL-luke 14. Feb 2007 14:41

Re: "Element '' hat kein übergeordnetes Fenster"
 
Wir hatten die Diskussion vor kurzem doch erst :roll:

Aber für dich noch mal, so weit ichs in Erinnerung habe: Änderung an den TStrings wird sofort an die WinAPI weitergegeben, die das umzusetzen versucht. Geht aber nicht ohne bereits angezeigtes Parentwindow.

xZise 14. Feb 2007 14:56

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von DGL-luke
Wir hatten die Diskussion vor kurzem doch erst :roll:

Link?

Und übrigens habe ich kA, was das verbockt. Aber ich nehme eben an das es die TStrings Property ist, da der Fehler meist dann kommt, wenn ich diesen Wert ändere.

Nils_13 14. Feb 2007 15:01

Re: "Element '' hat kein übergeordnetes Fenster"
 
Das verbockt nichts. Probier rum und denk ab und zu logisch, du hast den Debugger und ich bin um ehrlich zu sein (:mrgreen:) einfach zu faul es einzubauen. Diesen Fehler hatte ich schon oft und irgendwie hab ich es immer hinbekommen. Einfach mal nachdenken....

IngoD7 14. Feb 2007 15:58

Re: "Element '' hat kein übergeordnetes Fenster"
 
Täusche ich mich oder wird hier tatsächlich immer hübsch abwechselnd mal von der Listbox und mal von der Stringliste geredet?
Delphi-Quellcode:
  private
    FCompletionList : TStrings;
    completionBox : TListBox;
Ich weiß überhaupt nicht, welches Problem genau mit welchem Feld von TCompletionMemo genau wann genau auftritt. :roll:

xZise 14. Feb 2007 16:16

Re: "Element '' hat kein übergeordnetes Fenster"
 
So... Jetzt kompiliert er immerhin... Wahrscheinlich, weil ich bei TCustomMemo gesehen habe, dass das Setzen der Variable nicht einfach "FCompletionList" ist, sondern in eine Funktion ausgelagert werden muss...

@ Ingo: Ich hatte vorher keine Anhnung, warum und was etc. Ich kannte nur diese Fehlermeldung.
Allerdings habe ich jetzt das Problem, dass keine ListBox angezeigt wird... Und (siehe oben) die Daten (Breite, Höhe, Owner und Parent) setze ich ja...

Nagut... Es funktioniert doch nicht ganz so:
Zitat:

---------------------------
Fehler
---------------------------
nil kann nicht zu TRichEditStrings zugewiesen werden.
---------------------------
OK Details >>
---------------------------
Kommt, wenn ich diesen Dialog anzeigen will um die strings zu setzen...

IngoD7 14. Feb 2007 17:42

Re: "Element '' hat kein übergeordnetes Fenster"
 
Nimm's mir nicht übel, aber das meiste muss man sich immer erst mühsam zusammenreimen, ehe man ungefähr weiß, wo es bei dir brennt ... :|

Dass es irgendwie so (siehen nachfolgend) heißen muss, hattest du schon herausbekommen, oder?

Delphi-Quellcode:
protected
  procedure SetCompletionList(Value: TStrings);
published
  property CompletionList : TStrings read FCompletionList write SetCompletionList;
Wie sieht denn jetzt deine Methode SetCompletionList genau aus?

xZise 14. Feb 2007 18:02

Re: "Element '' hat kein übergeordnetes Fenster"
 
Ja... War mir bekannt (stand ja so in CustomMemo)... Habe es auch schon geändert.
Die Funktion:
Delphi-Quellcode:
FCompletionList.Assign(Value);
Was mich irretiert, das die Items der Meo keine TStrings, sondern TMemoStrings sind... Und aauch scheint es irgendwie bei fast jeder Komponente so zu sein, dass sie statt TStrings TXXXXStrings nehmen (o.ä.)...

Mal geraten: Hängt es damit zusammen?


Zitat:

Zitat von IngoD7
Nimm's mir nicht übel, aber das meiste muss man sich immer erst mühsam zusammenreimen, ehe man ungefähr weiß, wo es bei dir brennt ... :|

Das Hauptproblem ist ja, dass es in der IDE passiert :| Und da hilft debugen nichts...
Was mich auch irretiert ist, dass die Listbox nicht erscheint, obwohl die Funktion aufgerufen wird :|

SirThornberry 14. Feb 2007 18:26

Re: "Element '' hat kein übergeordnetes Fenster"
 
das ist das was die ganze zeit versucht wird dir zusagen :-D TStrings ist eine abstrakte Basisklasse. Die ganzen Elemente wie Listboxen, Memos etc. haben eine davon abgeleitete Klasse welche das lesen und schreiben von Einträgen direkt auf die WinApi abbilden. Wenn aber zu dem Zeitpunkt das Control noch nicht angelegt ist (kein Handle angefordert etc.) kann nichts auf die WinApi abgebildet werden.

Noch was aus meiner persönlichen Sicht:
Sowas gehört sich nicht:
Delphi-Quellcode:
constructor TComponentNachfahre(AOwner: TComponent);
begin
  [...]
  MemberVar := AOwner as TWinControl;
  [...]
der Owner von TComponent hat nichts mit dem Parent oder anderen Visuellen Dingen zu tun geschweige dem mit Handles. Du kannst/solltest/darfst nie davon ausgehen das überhaupt ein Owner übergeben wird. Wenn Komponenten dynamisch erzeugt werden ist der Owner oftmals nil weil er nicht benötigt wird -> denn Dinge die man selbst anlegt/instanziert räumt man auch selbst wieder auf und ist somit nicht auf den Owner angewiesen der teilweise in der Objecthierarchy auch nicht vorhanden ist die man sich im Konzept überlegt hat.

xZise 14. Feb 2007 22:20

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von SirThornberry
Wenn aber zu dem Zeitpunkt das Control noch nicht angelegt ist (kein Handle angefordert etc.) kann nichts auf die WinApi abgebildet werden.

Und das heißt?
Soll ich also Beispielsweise die Items von der Listbox nehmen (ich komme net auch den namen)?
Problem: "TListBoxStrings" ist sozusagen "privat", also für mich nicht zugänglich....

Zitat:

Zitat von SirThornberry
Noch was aus meiner persönlichen Sicht:
Sowas gehört sich nicht:
Delphi-Quellcode:
constructor TComponentNachfahre(AOwner: TComponent);
begin
  [...]
  MemberVar := AOwner as TWinControl;
  [...]

Ich weiß, nur muss ich doch (höchstwahrscheinlich?) meiner Listbox ein Parent zuweisen. Jedenfalls müsste ich das wenn ich sie dynamisch in meiner Anwendung erstelle. Aufgrund dessen wollte ich der Listbox ein Parent zuweisen.
Das Problem ist aber, dass ich jetzt nicht genau weis was als Parent genommen wird.
Gibt es vielleicht bessere Vorschläge?

IngoD7 14. Feb 2007 22:31

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von SirThornberry
Wenn Komponenten dynamisch erzeugt werden ist der Owner oftmals nil weil er nicht benötigt wird -> denn Dinge die man selbst anlegt/instanziert räumt man auch selbst wieder auf und ist somit nicht auf den Owner angewiesen der teilweise in der Objecthierarchy auch nicht vorhanden ist die man sich im Konzept überlegt hat.

Ergänzung:
Wenn es sich aber - so wie hier - um eine visuelle Komponente handelt, spricht doch nichts dagegen, den Owner vorzusehen. Dazu passend spricht auch nichts dagegen, der zur Laufzeit erzeugten visuellen Komponente als Owner das Form zu übergeben, auf dem die Komponente angezeigt wird. Hat auch den Vorteil, dass sie in der Eigenschaft Components des Form eingetragen wird, was oftmals nützlich ist.

Zudem sagt die Hilfe folgendes:
Zitat:

"Der Eigentümer ist für das Laden und Speichern der published-Eigenschaften seiner untergeordneten Komponenten verantwortlich."
Ich weiß zwar gerade nicht so wirklich, was das bedeutet, aber es klingt nicht unwichtig.

Ich sehe daher nicht viele Gründe, einen Owner nicht vorzusehen. Möchte man keinen übergeben bei Txxx.Create(aOwner), so übergibt man eben NIL.

Und da z.B. fangen die Probleme dann an, wenn man - so wie speziell hier geschehen - den Owner pauschal auch zum Parent erklären möchte. Denn das kann (trotz oder gerade wegen Typecast auf TWinControl) schön schiefgehen, wenn eben der Owner kein TWinControl ist.

Ich denke, SirThornberry meint das auch so; ich wollte es nur noch mal etwas verdeutlichen. :-)

xZise 14. Feb 2007 22:34

Re: "Element '' hat kein übergeordnetes Fenster"
 
Okay... Wegen dem Parent habe ich gerade einen Einfall gehabt:
Ich überschreibe einfach die "Parent"-Property der Memo, und setze immer wenn das Memoparent gesetzt wird, auch gleichzeitig den Listboxparent.


Allerdings komme ich nicht mit dem TStrings weiter....

IngoD7 14. Feb 2007 22:42

Re: "Element '' hat kein übergeordnetes Fenster"
 
Nochmal eben zu dem Parent:

Zitat:

Zitat von xZise
Ich weiß, nur muss ich doch (höchstwahrscheinlich?) meiner Listbox ein Parent zuweisen. Jedenfalls müsste ich das wenn ich sie dynamisch in meiner Anwendung erstelle. Aufgrund dessen wollte ich der Listbox ein Parent zuweisen.
Das Problem ist aber, dass ich jetzt nicht genau weis was als Parent genommen wird.
Gibt es vielleicht bessere Vorschläge?

Wo soll denn die Listbox angezeigt werden? Auf dem TCompletionMemo? Dann ist das CompletionMemo auch der Parent der Listbox. Also so:

Delphi-Quellcode:
constructor TCompletionMemo.Create(AOwner: TComponent);
begin
   inherited;
  completionBox := TListBox.Create(self);
  completionBox.Parent := self;  //<=============== guckst du
  completionBox.Width := FCompletionSizeWidth;
  completionBox.Height := FCompletionSizeHeight;
  completionBox.HandleNeeded;
  FCompletionList := TStringList.Create;
end;

xZise 15. Feb 2007 11:46

Re: "Element '' hat kein übergeordnetes Fenster"
 
Nein ;) Es soll auf dem Memoparent sein (deswegen werde ich auch die parent-property überschreiben...)!

Aber das ist nicht das Problem. Es liegt jetzt eher bei denen:
  • Keine Vernüftige Desgintime zuweisung der möglichen Einträge ((F)CompletionList)
  • Die Listbox wird nicht angezigt (ggf. ist das behoben, wenn ich die property überschreibe)

IngoD7 15. Feb 2007 12:24

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von xZise
Es soll auf dem Memoparent sein (deswegen werde ich auch die parent-property überschreiben...)!
Aber das ist nicht das Problem. Es liegt jetzt eher bei denen:
  • Keine Vernüftige Desgintime zuweisung der möglichen Einträge ((F)CompletionList)
  • Die Listbox wird nicht angezigt (ggf. ist das behoben, wenn ich die property überschreibe)

Mir fehlt in diesen Dingen die Erfahrung.

Aber mir fällt dazu das TLabeledEdit ein. Das ist ein Editfeld mit nebenstehendem Label.
Du möchtest ein Memo mit nebenstehender Listbox.

Schaue doch mal, wie das Label in das TLabeledEdit kommt und zur Designzeit angezeigt wird. Dort tauchen Proceduren wie SetSubComponent auf.

Vielleicht erkennst du notwendige Gemeinsamkeiten.

xZise 15. Feb 2007 15:01

Re: "Element '' hat kein übergeordnetes Fenster"
 
Zitat:

Zitat von IngoD7
Aber mir fällt dazu das TLabeledEdit ein.

Ich möchte die Listbox aber nicht als eine solche Komponente darstellen ;) Die Listbos soll nur von der Komponente verwaltet werden ;)

IngoD7 15. Feb 2007 15:12

Re: "Element '' hat kein übergeordnetes Fenster"
 
Was ist kaputt?????? :shock:

Von welcher Listbox, die nicht angezeigt wird, hast du denn die ganze Zeit gesprochen?

Erzählst du nicht die ganze Zeit davon, dass du dich in der IDE - also zur Entwurfszeit - befindest und die Box da aber nicht sehen kannst? Das ist aber nun auf einmal gar nicht schlimm, weil du sie ja nur zur Laufzeit anzeigen willst?


Ich geb's auf.


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

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