Autor Beitrag
catweasel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Mo 17.11.03 21:04 
Hi,

Zunächst vorneweg:

Eine ähnliche Frage hat es hier schonmal im VCL Forum gegeben. Ich finde aber hier ist sie auch gut aufgehoben. (Bitte lieber Moderator, hau mich nich :wink: )

Bei dem anderen Post mit dieser Frage trat das Problem zur Designzeit auf. Bei mir tritt es zur Laufzeit auf :-(

Ich habe folgendes Problem:

Ich erstelle eine Combobox auf einem Panel, nicht zur Designzeit, sondern zur Laufzeit:
Das sieht in etwa so aus :

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
unit Superchart;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TSuperchart = class(twincontrol)
private
  heimtore : integer;
  gasttore : integer;
  anzeige : TPanel;
  heimdisplay : TCombobox;
  gastdisplay : TCombobox;
  heimtordisplay : TEdit;
  gasttordisplay : TEdit;
  abpfiff : TButton;
  spiellabel : TLabel;
  heimlabel : TLabel;
  gastlabel : TLabel;
  heimtorlabel : TLabel;
  gasttorlabel : TLabel;
  procedure setlabel(labeltext :string);
  function getlabel : string;
  procedure abpfiffklick(Sender : TObject);
  procedure heimtordisplayklick(Sender : TObject);
  procedure gasttordisplayklick(Sender : TObject);

protected
  { Protected declarations }

public
  constructor Create(Owner: TComponent; xalign, yalign : integer);
  destructor Destroy; override;
  procedure setfarbe(farbe :TColor);
  function wersieger : string;
  function torvorsprung : integer;

published
  property spielname: string read getlabel write Setlabel;
end;


... (einiges irrelevantes weggekürzt)

constructor TSuperchart.Create(Owner: TComponent; xalign, yalign : integer);
var
topalign_head : integer;
topalign_display : integer;
begin
  inherited create(Owner);
topalign_head := 20;
topalign_display := 5;
heimtore := 0;
gasttore := 0;

  left := xalign;
  top := yalign;
  height := 75;
  width := 630;

anzeige := TPanel.Create(Self);
with anzeige do begin
  Parent := self;
  height := self.height -15;
  width := self.Width;
  Top := 15;
end;

heimdisplay := TCombobox.Create(self);
with heimdisplay do begin
  Parent := anzeige;
  Width := 180;
  left := 5;
  Top := topalign_head;
end;

gastdisplay := TCombobox.Create(self);
with gastdisplay do begin
  Parent := anzeige;
  Width := 180;
  left := 225;
  Top := topalign_head;
end;

heimdisplay.Text := 'Testmannschaft';
//  heimdisplay.Items.LoadFromFile(extractfilepath(paramstr(0))+'mannschaften.txt');
end;

Es soll also beim erzeugen des Objekts der Inhalt der Textdatei in die Comboboxen geladen werden...

aber jeder Aufruf einer Methode der Combobox wie z.b.
ausblenden Delphi-Quelltext
1:
//  heimdisplay.Items.LoadFromFile(extractfilepath(paramstr(0))+'mannschaften.txt');					

oder
ausblenden Delphi-Quelltext
1:
heimdisplay.items.add('Mannschaftsname');					

führt zu der Fehlermeldung:
Zitat:
Control " has no parent window.

Obwohl doch Anzeige als Parent festgelegt wurde. :(

Aus den Postsa zu dem Thema bin ich nicht schlau geworden.
Holf mir mal bitte einer.....

Catweasel

Moderiert von user profile iconTino: Delphi- & Quote-Tags hinzugefügt.

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
barfuesser
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 324



BeitragVerfasst: Di 18.11.03 17:47 
Kann es sein, daß Dein SuperChart kein ParentWindow hat?

barfuesser
Mossi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 99
Erhaltene Danke: 2

Win XP, Linux
D7 Enterprise, K3 Prof
BeitragVerfasst: Di 18.11.03 20:44 
Ich hab jetzt zwar gerade kein Delphi zur Hand aber versuch mal folgendes:

ausblenden Quelltext
1:
heimdisplay := TCombobox.Create(anzeige);					


Bin mir zwar jetzt nicht hundertprozentig sicher, ob es so klappt, aber wenn ich mich recht erinnere, hab ich es auch so gemacht (siehe oben genanntes Problem)

EDIT: Zusätzlich aber auch noch die Parenteigenschaft setzen
Tendl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117



BeitragVerfasst: Fr 23.01.04 15:03 
Ich kämpfe momentan mit dem gleichen Problem, habe aber sicher einen Parent definiert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  ComboBox1 := TComboBox.create(self);
  ComboBox1.top := 10;
  ComboBox1.left := 80;
  ComboBox1.parent := self;
  combobox1.Items.Add('Diashow');
  combobox1.Items.Add('Unerase');
  combobox1.Items.Add('Move');
  combobox1.Items.Add('Copy');
  combobox1.Items.Add('Save');
  combobox1.Items.Add('Undo');
  //combobox1.ItemIndex:=0;
  //combobox1.Text:=combobox1.Items[0];


Die Fehlermeldung kommt nach den ersten Items.Add. Wenn ich auf die Items.Adds verzichte funktioniert es soweit (mit fehlender Textliste).

Wie war den Eure Lösung?

Thomas
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Fr 23.01.04 16:14 
Das Problem ist wahrscheinlich, dass dein SuperChart zu dem Zeitpunkt zu dem du die Controls erzeugst selbst noch keinen Parent hat...

@Tendl: wo steht dieser Code? Also wann erzeugst du die Combobox? Was ist Self für ein Objekt?

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
Tendl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117



BeitragVerfasst: Fr 23.01.04 17:04 
Hallo Motzi,

der Code steht in einer abgeleiteten Klasse von TCustomPanel

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
  TButton_Setup = class(TCustomPanel)
  private
    Label1: TLabel;
    ComboBox1: TComboBox;
  protected
  published
  public
    constructor create(AOwner: TComponent); override;
  end;

.....


constructor TButton_Setup.create(AOwner: TComponent);
begin
  inherited create(AOwner);
  align := alClient;

  Label1 := TLabel.create(self);
  with label1 do
  begin
    top := 10;
    left := 20;
    height:=20;
    caption := 'Action:';
    parent := self;
  end;

  ComboBox1 := TComboBox.create(self);
  ComboBox1.top := 10;
  ComboBox1.left := 80;
  ComboBox1.parent := self;
  combobox1.Items.Add('Diashow');
  combobox1.Items.Add('Unerase');
  combobox1.Items.Add('Move');
  combobox1.Items.Add('Copy');
  combobox1.Items.Add('Save');
  combobox1.Items.Add('Undo');
end;



Das Instanz von TButton_Setup liegt seinereits auf eine Tabsheet auf einem Panel auf einem Formular;

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
  TPanelbar_Setup = class(TCustomForm)
  private
  protected
  public
//...
    Panel2: TPanel;
    PageControl1: TPageControl;
    TabSheets: array[1..10of TTabSheet;
    TButton_Setups: array[1..10of TButton_Setup;
    constructor create(AOwner: TComponent); override;
  published
  end;

.....

constructor TPanelbar_Setup.create(AOwner: TComponent);
var i: integer;
begin
  inherited createnew(AOwner);
  caption := 'Setup Workarea';
  self.Height := 300;
  self.Width := 600;
  self.Top := 200;
  self.Left := 200;

//....

  Panel2 := TPanel.Create(Self);
  Panel2.Name := 'Panel2';
  Panel2.Parent := self;
  Panel2.Align := alBottom;
  Panel2.Height := 200;
  //Panel2.TabOrder := 1;
  panel2.Caption := 'Panel2';
  //panel2.Color := clred;

  PageControl1 := TPageControl.Create(Panel2);
  PageControl1.Parent := panel2;
  PageControl1.Name := 'PageControl1';
  PageControl1.Align := alClient;


//exit;
  for i := 1 to 10 do
  begin
    TabSheets[i] := TTabSheet.Create(PageControl1);
    TabSheets[i].Parent := PageControl1;
    TabSheets[i].PageControl := PageControl1;
    TabSheets[i].Caption := 'Button ' + inttostr(i);
    TabSheets[i].Name := 'TabSheet' + inttostr(i);
    TButton_Setups[i] := TButton_setup.create(self);
    TButton_Setups[i].Parent := TabSheets[i];
  end;

end;


Die Instanz von TPanelbar_Setup wird ebenfalls zur Laufzeit erzeugt mit

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TSpecThumbWorkArea.BtnClick1(Sender: TObject);
var setup: TPanelbar_Setup;
begin
  setup := TPanelbar_Setup.create(setup);
  setup.ShowModal;
  setup.Free;
end;




Wie beschrieben klappt alles, wenn ich die Items.Add() weglasse.
Der Fehler kommt erst, wenn ich versuche die Items beim Create vorzubelegen.

Sorry, für den vielen Code, aber so werden die Zusammenhänge klarer.

Wenn Du Zeit und Lust hast, dann schau bitte mal rein.

Danke Thomas
Tendl
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 117



BeitragVerfasst: Mo 26.01.04 13:53 
Das Problem ist gelöst:

In der Routine befinden sich die Zeilen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
constructor TPanelbar_Setup.create(AOwner: TComponent); 
var i: integer; 
begin 
  inherited createnew(AOwner); 
//....

  for i := 1 to 10 do 
  begin 
    //....
    TButton_Setups[i] := TButton_setup.create(self); 
    TButton_Setups[i].Parent := TabSheets[i]; 
  end
;

Die vorletzte Zeile weist den Parent zu, d.h. im TButton_setup.create wird dies nicht getan. Damit ergeben sich die genannten Probleme, nicht nur bei Comboboxen sondern z.B auch bei Radiogroups.

Die Korrektur lautet:
ausblenden Delphi-Quelltext
1:
    TButton_Setups[i] := TButton_setup.create(TabSheets[i]);					


Und im Create von TButton_setup:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
constructor TButton_Setup.create(AOwner: TComponent);
var itemlist:TStringlist;
begin
  inherited create(AOwner);
  parent:=TWINControl(AOwner);
 /....
end;


Mir ist das Problem damit klar, ich hoffe anderen auch
Thomas
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Mo 26.01.04 14:34 
ja, dieses Problem lässt sich so tatsächlich lösen. Aber da gibts noch ein paar andere Klippen...

hab das mit dem Control " has no parent window mal ein bischen unter die Lupe genommen....

Es sieht für mich folgendermassen aus:
Klingt vielleicht ein bischen Konfus, aber so stellt sich das durch rumprobieren für mich dar...:


These: Ein Objekt existiert erst wirklich dann wenn der Constructor wirklich und endgültig abgeschlossen ist....
weil : keine Methode die NUR als Methode implementiert ist funktioniert..... Man kann keine Listboxen füllen, nicht auf den Canvas einer Paintbox malen, etc....
Nur was als Property deklariert ist (width, top, etc.....) lässt sich im Constructor verwenden. (Als Ausnahme konnte ich nur die LoadFromFile() funktion von TImage finden).

@Tendel

auch wenn man die Parent Zuweisung NICHT vergessen hat, kann einem diese Meldung begegnen.....

Das wäre auch möglich...

Verlagere deinen Code mit den items.Add() einfach in eine eigene Funktion die du im Hauptprogramm direkt nach dem create() ausführen lässt....

combo1 := TComboBox.create(self);
combo1.fuellen;

dann funktioniert es.....

Das Unschöne dabei ist: Dadurch das man "extra nur deswegen" eine Prozedur oder Funktion öffentlich machen muss :-(
Nach meiner Auffassung von OOP wäre es am elegantesten wenn nichts ausser "Übergaberoutinen" öffentlich sind.....

Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 26.01.04 16:21 
@catweasel: Methoden die erst nach Abarbeitung des Constructors ausgeführt werden sollen kann man auch anders lösen...

TObject führt nämlich eine virtuelle Methode namens "AfterConstruction" ein, die immer automatisch sofort nach dem Constructor aufgerufen wird (zB löst die TForm das OnCreate-Event in ihrer überschriebenen Version dieser Methode aus).

Aber die Meldung "Control xxx has no parent window" kann einem auch durchaus außerhalb des Constructors begegnen...!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
catweasel Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 487
Erhaltene Danke: 1

Win 7 64bit
Delphi 7 Second Sedition V7.2
BeitragVerfasst: Mo 26.01.04 19:12 
Zitat:
Aber die Meldung "Control xxx has no parent window" kann einem auch durchaus außerhalb des Constructors begegnen...!


Ja, das kann sie.. Da aber, im Falle des Auftauchens während der Abarbeitung eines Constructors deuten die " zwei Einfachen Anführungszeichen auf einen leeren Komponentennamen hin......
Eigentlich sollte der aber bereis existieren, oder?

es ist ja eben nicht ...control 'xxx' has no... , sondern control " has no...

Catweasel

_________________
Pommes werden schneller fertig wenn man sie vor dem Frittieren einige Minuten in siedendes Fett legt.
Motzi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2931

XP Prof, Vista Business
D6, D2k5-D2k7 je Prof
BeitragVerfasst: Mo 26.01.04 21:22 
Ja, richtig... das '' deutet auf einen leeren Komponentennamen hin, aber wo sollte zum Zeitpunkt der Ausführung des Constructors denn bereits ein Name existieren? Bei zur Laufzeit erstellten Komponenten bist schließlich du dafür verantwortlich ihnen einen Namen zu verpassen (sofern es überhaupt notwendig ist - man kann den Namen auch einfach leer lassen).

Du darfst an dieser Stelle halt nicht Klassenname (zb TButton) und Komponentenname (zb Button1) verwechseln...!

_________________
gringo pussy cats - eef i see you i will pull your tail out by eets roots!
XelaRellum
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Mi 15.03.06 13:02 
Titel: Überschreiben von "SetParent" hat bei mir gut funktioniert.
Ich hatte eben ein ganz ähnliches Problem: ich hatte ein eigenes Control erzeugt, dass auf einem Tabsheet wiederum eine TComboBox anlegt und der dann auch gleich ein paare Werte zuweist. Bei mir liess sich das Problem (ohne Änderungen an anderen Programmteilen) entfernen, indem ich "SetParent" überschrieben habe und dort dann die ComboBox Werte hinzugefügt habe. Dies nur zur Info