AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Komponente ableiten

Ein Thema von hansklok · begonnen am 30. Aug 2010 · letzter Beitrag vom 1. Jan 2011
Antwort Antwort
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#1

AW: Komponente ableiten

  Alt 30. Aug 2010, 21:11
OK, da haben wir doch schonmal was. Folgender Ansatz:

- Personen haben Referenzen auf Eltern und Partner, so entsteht der Stammbaum
- Eine Klasse TFamilyTree übernimmt die Darstellung. Der eigentliche Stammbaum ist aber das Objektgeflecht
- TFamilyTree hat ne Referenz auf die markierte Person
- TFamilyTree hat Operationen um den Stammbaum zu erweitern. AddFather() z.B. diese Methode ruft AddFather() der markierten Person auf. Die Person selbst weiß, wie sie einen Vater kriegt, nicht der Stammbaum! Die OOP sagt: "Do it myself!"
- TFamilyTree hat eine Referenz auf die Wurzel des Stammbaums. Das reicht, um am Ende alle freigeben zu können. Außerdem kannst du so wieder an den Anfang zurückspringen.
- Zusätzlich kannst du, wenn du willst, noch ne ObjectList mit allen Personen halten. Das macht das Freigeben später einfacher (OwnsObjects macht das für dich), dafür musst du aber die Liste pflegen. Dazu würdest du beispielsweise AddFather() einen Rückgabewert verpassen und den dann auswerten. Eigentlich brauchst du das aber nicht. Stattdessen kannst du am Ende rekursiv eine Liste aufstellen. Das ist einfacher. Du kannst auch versuchen direkt rekursiv freizugeben. Da solltest du aber aufpassen. Ansonsten kann es in gewissen Fällen (Inzest) zu Zugriffsverletzungen kommen.
- TFamilyTree hat ne Referenz auf den Probanden und ne Methode makeProband(TPerson), die die übergebene Person zum Probanden macht.
- TPerson muss TFamilyTree mitteilen können, wann es doppelgeklickt wurde, damit makeProband() aufgerufen wird. Da gibt jetzt mehrere Möglichkeiten:
a) Observer Pattern. Das ist die saubere Variante
b) ein zusätzliches public, aber nicht published Event (zusätzlich zu onDblClick) das den Doppelklick an das TFamilyTree-Objekt meldet. Noch einigermaßen saubere Lösung.
c) TPerson hat ne Referenz auf TFamilyTree und ruft selbst makeProband(Self) auf. Das ist nicht so schön, weil es die Kopplung erhöht.
- makeProband(), macht zuerst die bisher angezeigten Personen invisible, setzt dann die Referenz auf den neuen Probanden, setzt die Positionen der anzuzeigenden Probanden und macht diese Visible.

Weiteres:
- Du könntest überlegen, ob du getrennte Klassen für Darstellung und Logik machst. Also TPerson von TPersistent ableiten und TGraphicPerson von TGraphicControl ableiten und eine TPerson komponieren. Das wäre sauberer, ist aber etwas schwieriger. Mach das nur, wenn du sicher bist, dass du es verstehst.

Fragen:
- du schreibst was von Geschwistern. Wie hast du dir das vorgestellt?
- so richtig verstanden, warum du nur max. 15 Personen anzeigen willst, hab ich immer noch nicht.

mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#2

AW: Komponente ableiten

  Alt 30. Aug 2010, 21:33
Lieber Christian,

danke für die tollen Hinweise. Ich habe bereits daran gedacht, den Doppelklick der TPerson an den Stammbaum weiterzuleiten, leider habe ich überhaupt keine Idee, wie ich das anstellen soll.
Warum nur 15 Personen dargestellt werden sollen? Das hängt mit den 4 Generationen zusammen, die ich darstellen möchte:

1. Generation: Proband (1 Person in der Ansicht)
2. Generation: Vater, Mutter (2 Personen in der Ansicht)
3. Generation: Großväter, Großmütter (4 Personen in der Ansicht)
4. Generation: Urgroßväter, Urgroßmütter (8 Personen in der Ansicht)

das ergibt insgesamt 15 Personen. Sollte eine Person Geschwister haben, so werden diese erstmal nicht in der Ansicht dargestellt, es sei denn sie werden über eine Auswahlliste (z.B. TListBox) ausgewählt, dann sind sie der neue Proband des Stammbaums.

Ich hoffe das bringt etwas Licht ins dunkle.

Gruß

hansklok
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#3

AW: Komponente ableiten

  Alt 31. Aug 2010, 08:10
danke für die tollen Hinweise. Ich habe bereits daran gedacht, den Doppelklick der TPerson an den Stammbaum weiterzuleiten, leider habe ich überhaupt keine Idee, wie ich das anstellen soll.
Delphi-Quellcode:
// Pseudocode:
TPerson = class
private
  OnDblClickForFamilyTree: TNotifyEvent;
public
  property _OnDblClickForFamilyTree: TNotifyEvent read F_OnDblClickForFamilyTree write OnDblClickForFamilyTree;
  procedure DblClick; override;
end;

procedure TPerson.DblClick;
begin
  inherited;
  if Assigned(F_OnDblClickForFamilyTree) then
  begin
    F_OnDblClickForFamilyTree;
  end;
end;

TFamilyTree.Somewhere;
begin
  SomePerson._OnDblClickForFamilyTree := PersonDblClicked;
end;

procedure TFamilyTree.PersonDblClicked(Sender: TObject);
begin
  makeProband(Sender as TPerson);
end;
Das ist in etwa Lösung b)

Zitat:
Warum nur 15 Personen dargestellt werden sollen? Das hängt mit den 4 Generationen zusammen, die ich darstellen möchte: [...]
Ja, das ist klar. Aber warum nur 4 Generationen?

Zitat:
Sollte eine Person Geschwister haben, so werden diese erstmal nicht in der Ansicht dargestellt, es sei denn sie werden über eine Auswahlliste (z.B. TListBox) ausgewählt, dann sind sie der neue Proband des Stammbaums.
Wie siehts mit Halbgeschwistern und Stiefgeschwistern aus?

mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
hansklok

Registriert seit: 14. Apr 2004
Ort: Karlsruhe
318 Beiträge
 
Delphi 2010 Architect
 
#4

AW: Komponente ableiten

  Alt 31. Aug 2010, 13:08
So, ich stelle mal ein bisschen Source von der grafischen Ausgabe des Stammbaums rein. Vielleicht hilft das ja jmd. bei der Suche nach Lösungen weiter. Vielleicht ist mein Arbeitsansatz auch völlig falsch.

Gruße hansklok

Delphi-Quellcode:
type
  TPerson = class(TCustomControl)
    private
      fTag: Integer;
      fID: Integer; // Verweis auf die ID der Person, sie wird später aus TStammbaum.fGenealogie... zugewiesen
      fTyp: String;
      fVorname: String; // holt den Vornamen der Person auf Grundlage von fID später aus TStammbaum.fGenealogie...
      fNachname: String; // holt den Nachnamen der Person auf Grundlage von fID später aus TStammbaum.fGenealogie...

      fMarkiert: Boolean;
      fMouseOver: Boolean;

      procedure SetTyp(Bezeichnung: String);
    public
      constructor Create(AOwner: TComponent; Oben: Integer);

      procedure Paint; override;

      procedure Click;override;//(Sender: TObject); //overload;

      procedure MouseEnter; override;
      procedure MouseLeave; override;

      //property _OnDblClickForFamilyTree: TNotifyEvent read OnDblClickForFamilyTree write OnDblClickForFamilyTree;
      //procedure DblClick; override;

      property Tag: Integer read fTag write fTag;
      property ID: Integer read fID write fID;
      property Typ: String read fTyp write fTyp;
      property Markiert: Boolean read fMarkiert write fMarkiert;
      property Vorname: String read fVorname write fVorname;
      property Nachname: String read fNachname write fNachname;
    published
      property OnClick;
      property OnMouseEnter;
      property OnMouseLeave;
  end;

  TStammbaum = class(TCustomControl)
    private
      fGenealogie: TGenealogie; // hier werden die Daten zu den Personen geholt
      fPerson: TObjectList;
      fProband: Integer;
      fGeneration: Integer;
      fMarkiert: Integer;

      procedure SetPersonen(Person, Y: Integer);
      procedure Markieren(Plus: Boolean; Person: Integer);
    public
      constructor Create(AOwner: TComponent);

      procedure Paint; override;

      procedure Click; override;//(Sender: TObject); overload;
      procedure MouseEnter; override;

      procedure PersonenUpdate(Proband_ID: Integer);

      property Genealogie: TGenealogie read fGenealogie write fGenealogie;
      property Person: TObjectList read fPerson write fPerson;
      property Proband: Integer read fProband write fProband;
      property Generation: Integer read fGeneration write fGeneration;
      property Markiert: Integer read fMarkiert write fMarkiert;
    published
     // property OnClick;
      property OnEnter;
  end;

implementation

constructor TPerson.Create(AOwner: TComponent; Oben: Integer);
begin
  inherited Create(AOwner);
  Self.fID:= -1; // keine Person verknüpft
  Self.Top:= Oben;
  Self.Left:= 30;
  Self.Height:= 24; // 24 = einzeilig (nur Name), 36 = zweizeilig Textausgabe (Name & Geburts- & Todesdatum)
  Self.Width:= 200;
end;

procedure TPerson.SetTyp(Bezeichnung: String);
begin
  Self.fTyp:= Bezeichnung;
  Self.Hint:= Bezeichnung;
end;

procedure TPerson.Paint;
begin
  case Self.fMarkiert of
    True: begin
             Self.Canvas.Font.Color:= clWhite;
             Self.Canvas.GradientFill(Self.ClientRect, $00D5BCAD, $0091522B, gdVertical);
           end;
    False: begin
             Self.Canvas.Font.Color:= clBlack;
             case Self.fMouseOver of
               True: Self.Canvas.GradientFill(Self.ClientRect, $00F6F2EE, $00D9C2B5, gdVertical);
               False: Self.Canvas.GradientFill(Self.ClientRect, $00FAF8F6, $00E8DED6, gdVertical);
             end;
           end;
  end;

  Self.Canvas.TextRect(Self.ClientRect, 6, 5, IntToStr(Self.fTag) + ' ' + Self.fTyp); // hier soll später der Name der Person ausgegeben werden
  Self.Canvas.Pen.Color:= $00A09070;
  Self.Canvas.Brush.Style:= bsClear;
  Self.Canvas.Rectangle(Self.ClientRect);
end;

procedure TPerson.MouseEnter;
begin
  Self.fMouseOver:= True;
  Self.Repaint;
end;

procedure TPerson.MouseLeave;
begin
 Self.fMouseOver:= False;
 Self.Repaint;
end;

procedure TPerson.Click;
begin
  inherited;
  Self.fMarkiert:= not Self.fMarkiert;
  Self.Repaint;
end;

constructor TStammbaum.Create(AOwner: TComponent);
var
  i: Byte;
  Pers: TPerson;
begin
  inherited Create(AOwner);
  fGeneration:= 4; // Darstellung von 4 Generationen
  fPerson:= TObjectList.Create;
  for i:= 0 to 14 do
    begin
      // Positionierung ist nicht angepasst, muss noch gemacht werden
      case i of
        0: Pers:= TPerson.Create(AOwner, 0); // Proband
        1: Pers:= TPerson.Create(AOwner, 170); // Vater
        2: Pers:= TPerson.Create(AOwner, -170); // Mutter
        3..6: Pers:= TPerson.Create(AOwner, 300); // Großeltern
        7..14: Pers:= TPerson.Create(AOwner, 540); // Urgroßeltern
      end;
      Pers.Parent:= Self;
      Pers.Tag:= i;
     { if i = 0 then Pers.Top:= 10 else
        Pers.Top:= TPerson(Person.Items[i-1]).Top + TPerson(Person.Items[i-1]).Height + 5;}

      case i of
        0: Pers.SetTyp('Proband');
        1: Pers.SetTyp('Vater');
        2: Pers.SetTyp('Mutter');
        3,5: Pers.SetTyp('Großvater');
        4,6: Pers.SetTyp('Großmutter');
        7,9,11,13: Pers.SetTyp('Urgroßvater');
        8,10,12,14: Pers.SetTyp('Urgroßmutter');
      end;
      Person.Add(Pers);
    end;

  Self.Width:= 750;
  Self.Height:= 600;

  fGenealogie:= TGenealogie.Create;
end;

procedure TStammbaum.SetPersonen(Person, Y: Integer);
begin
  case Person of
    1: TPerson(Self.Person.Items[Person]).Left:= 176;
    2: TPerson(Self.Person.Items[Person]).Left:= 176;
    3: TPerson(Self.Person.Items[Person]).Left:= 176;
    4: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-3]).Left + Trunc(TPerson(Self.Person.Items[Person-3]).Width / 2) + 20;
    5: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-3]).Left + Trunc(TPerson(Self.Person.Items[Person-3]).Width / 2) + 20;
    6: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-4]).Left + Trunc(TPerson(Self.Person.Items[Person-4]).Width / 2) + 20;

    7: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-1]).Left + Trunc(TPerson(Self.Person.Items[Person-1]).Width) + 20;
    8: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-2]).Left + Trunc(TPerson(Self.Person.Items[Person-2]).Width) + 20;

    9: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-4]).Left + Trunc(TPerson(Self.Person.Items[Person-4]).Width) + 20;
    10: TPerson(Self.Person.Items[Person]).Left:= TPerson(Self.Person.Items[Person-5]).Left + Trunc(TPerson(Self.Person.Items[Person-5]).Width) + 20;

  end;
end;

procedure TStammbaum.Paint;
begin
  Self.Canvas.Pen.Color:= $00A09070;
  Self.Canvas.Brush.Style:= bsClear;
  Self.Canvas.Rectangle(Self.ClientRect);

  TPerson(Self.Person.Items[0]).Top:= Trunc((Self.Height - TPerson(Self.Person.Items[0]).Height) / 2); { Proband }
  SetPersonen(1, 110); { Vater }
  SetPersonen(2, 110); { Mutter }

  SetPersonen(3, 170); { Vater des Vaters }
  SetPersonen(4, -50); { Mutter des Vaters }
  SetPersonen(5, 50); { Vater der Mutter }
  SetPersonen(6, 170); { Mutter der Mutter }

  SetPersonen(7, 200); { Vater des Vaters }
  SetPersonen(8, -160); { Mutter des Vaters }

  SetPersonen(9, -160); { Vater des Vaters }
  SetPersonen(10, 200); { Mutter des Vaters }
end;

procedure TStammbaum.Click;//(Sender: TObject);
var
  i: Integer;
begin
  //TPerson(Self.Person.Items[1])._OnDblClickForFamilyTree:= PersonDblClicked;
  Self.Repaint;
end;

procedure TStammbaum.MouseEnter;
begin
  Self.SetFocus;
end;

procedure TStammbaum.Markieren(Plus: Boolean; Person: Integer);
begin
  case Plus of
    True: begin
             TPerson(Self.Person.Items[Self.fMarkiert]).fMarkiert:= False;
             TPerson(Self.Person.Items[Self.fMarkiert+Person]).fMarkiert:= True;
             Self.fMarkiert:= Self.fMarkiert+Person;
           end;
    False: begin
             TPerson(Self.Person.Items[Self.fMarkiert]).fMarkiert:= False;
             TPerson(Self.Person.Items[Self.fMarkiert-Person]).fMarkiert:= True;
             Self.fMarkiert:= Self.fMarkiert-Person;
           end;
  end;
  Self.Repaint;
end;

procedure TStammbaum.PersonenUpdate(Proband_ID: Integer);
begin
  if Proband_ID > -1 then
    begin
      { Proband }
      if Proband_ID > -1 then begin
        Proband:= Proband_ID;
        TPerson(Person.Items[0]).ID:= Proband_ID;
        TPerson(Person.Items[0]).Vorname:= TINDI(Genealogie.INDI.Items[TPerson(Person.Items[0]).ID]).GIVN end else
        Exit;
      { Vater }
      if TINDI(Person.Items[0]).FATH >= 0 then begin
        TPerson(Person.Items[1]).ID:= TINDI(Person.Items[0]).FATH;
        TPerson(Person.Items[1]).Vorname:= TINDI(Genealogie.INDI.Items[TPerson(Person.Items[1]).ID]).GIVN; end else begin
        TPerson(Person.Items[1]).Vorname:= '(Vater)';
        end;
      { Mutter }
      if TINDI(Person.Items[0]).MOTH > -1 then
        TPerson(Person.Items[2]).ID:= TINDI(Person.Items[0]).MOTH else
        Exit;
      { Großvater I - Vater des Vaters }
      if TINDI(Person.Items[1]).FATH > -1 then
        TPerson(Person.Items[3]).ID:= TINDI(Person.Items[1]).FATH else
        Exit;
      { Großmutter I - Mutter des Vaters }
      if TINDI(Person.Items[1]).MOTH > -1 then
        TPerson(Person.Items[4]).ID:= TINDI(Person.Items[1]).MOTH else
        Exit;
      { Großvater II - Vater der Mutter }
      if TINDI(Person.Items[2]).FATH > -1 then
        TPerson(Person.Items[5]).ID:= TINDI(Person.Items[2]).FATH else
        Exit;
      { Großmutter II - Mutter der Mutter }
      if TINDI(Person.Items[2]).MOTH > -1 then
        TPerson(Person.Items[6]).ID:= TINDI(Person.Items[2]).MOTH else
        Exit;
    end;
end;

end.

Geändert von hansklok (31. Aug 2010 um 13:25 Uhr)
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#5

AW: Komponente ableiten

  Alt 31. Aug 2010, 13:52
Achtung nicht erschrecken. Wenn ich ein Programm auseinander nehme, sieht das immer so aus.

TPerson:

Delphi-Quellcode:
      fTag: Integer;
      fTyp: String;
Welchen Sinn haben diese Felder? Kommt mir merkwürdig vor.

      fMarkiert: Boolean; OK, ich sehe unten, du verzweigst entsprechend beim Zeichnen. OK.

      fMouseOver: Boolean; dito.

procedure SetTyp(Bezeichnung: String); string-Parameter sollten const sein.

constructor Create(AOwner: TComponent; Oben: Integer); Der zusätzliche Parameter Oben kommt mir komisch vor. Damit rechnet man nicht. Mach den weg.

//property _OnDblClickForFamilyTree: [...] Warum hast du das auskommentiert?

Delphi-Quellcode:
property Tag: Integer read fTag write fTag;
property Typ: String read fTyp write fTyp;
s.o.

Außerdem fehlen TPerson Referenzen auf die Eltern, etc.


TStammbaum:

      fGenealogie: TGenealogie; // hier werden die Daten zu den Personen geholt Zeig mal die Klasse. Zumindest der Bezeichner sieht verbeserungswürdig aus.

      fPerson: TObjectList; Zumindest der Bezeichner ist falsch. Wenn es nur eine Person ist, kann es keien ObjectList sein. Wie aber oben erwähnt, brauchst du keine ObjectList. Zumindest hier nicht.

      fProband: Integer; Nein, nicht Integer. TPerson. Also eine Referenz auf das konkrete Objekt.

      fGeneration: Integer; Was bedeutet dieses Feld?

      fMarkiert: Integer; Auch hier eine Referenz, keine ID.

procedure SetPersonen(Person, Y: Integer); Parameter sind unverständlich.

procedure PersonenUpdate(Proband_ID: Integer); Prozedurnamen sind Verben. wenn dann sollte es heißen UpdatePersonen und nicht anders herum. Aber auch dann passt der Name nicht. Denn die Prozedur soll ja den Probanden setzen. Also makeProband() wie in vorherigem Post genannt. Außerdem gilt natürlich auch hier: Vergiss die IDs. Wenn du IDs fürs dateiformat brauchst o.ä. dann lass sie drin. Nimm die aber nur zum Speichern und laden. Ansonsten solltest du mit Referenzen arbeiten.

property Genealogie: TGenealogie read fGenealogie write fGenealogie; Sicher, dass das Public sein muss?

Delphi-Quellcode:
property Person: TObjectList read fPerson write
property Proband: Integer read fProband write fProband;
property Generation: Integer read fGeneration write fGeneration;
property Markiert: Integer read fMarkiert write fMarkiert;
- properties können auch readonly sein. Manchmal ist das von Vorteil. Hier könnte man sowas überlegen. Insbesonder bei Person... äh... Personen

Delphi-Quellcode:
procedure TPerson.SetTyp(Bezeichnung: String);
begin
  Self.fTyp:= Bezeichnung;
  Self.Hint:= Bezeichnung;
end;
Das überschreibt den Hint. Das ist so nicht ersichtlich. Wenn, dann solltest du zusätzlich die Möglichkeit bieten, das über ne Property abzustellen. Besser den Hint von außen setzen, wenn nötig. Wie der Hint aussehen soll ist nicht Sache von TPerson.

  case Self.fMarkiert of Bei Boolean-Werten lohnt sich case eigentlich nicht wirklich. if ist da lesbarer

Delphi-Quellcode:
      case i of
        0: Pers:= TPerson.Create(AOwner, 0); // Proband
        1: Pers:= TPerson.Create(AOwner, 170); // Vater
        2: Pers:= TPerson.Create(AOwner, -170); // Mutter
        3..6: Pers:= TPerson.Create(AOwner, 300); // Großeltern
        7..14: Pers:= TPerson.Create(AOwner, 540); // Urgroßeltern
      end;
Hm... da gibts jetzt mehrere Sachen zu sagen.
- case ist in wirklich objektorientierten programmen selten. Wenn du es doch brauchst, solltest du zumindest mal überlegen, ob es notwendig ist.
- So langsam beginne ich zu verstehen, wie du das meinst. TPerson ist nicht wirklich eine Person, sondern nur die Grafische Darstellung und die Daten sind irgendwie in TGenealogie? Zeig unbedingt mal TGenealogie her.
- Du hast immer noch nicht erklärt, warum du die Beschränkung auf 4Generationen bzw. 15 Personen hast. Warum willst du niemals mehr anzeigen?


Delphi-Quellcode:
procedure TStammbaum.SetPersonen(Person, Y: Integer);
begin
  case Person of
Und was, wenn Person 11 ist? Oder 22? Diese Prozedur ist ziemlich kaputt. Sie sollte viel generischer sein.

  Self.Canvas.Pen.Color:= $00A09070; Für sowas solltest du Konstanten einführen.

Delphi-Quellcode:
procedure TStammbaum.Click;//(Sender: TObject);
var
  i: Integer;
begin
  //TPerson(Self.Person.Items[1])._OnDblClickForFamilyTree:= PersonDblClicked;
Da gehört das ja auch nicht rein. Das muss beim Erzeugen zugewiesen werden.

Delphi-Quellcode:
procedure TStammbaum.Markieren(Plus: Boolean; Person: Integer);
begin
  case Plus of
- plus ist unverständlich
- zudem ist es eine Hybridkopplung. Sollte man vermeiden.

TINDI(Person.Items[0]) Hier castest du TPerson-Objekte auf TINDI. Das ist merkwürdig und problematisch. Sei überhaupt vorsichtig mit casts. Vermeide sie wos nur geht.

Exit; exit ist nicht gut. Vermeide es. exit kann man für so genannte Wächter verwenden. Also ganz am Anfang einer Methode. Aonsten solletst du exit vermeiden,w eil es ein Programm tendenziell unleserlich macht.

=========================================
Langer Rede kurzer Sinn: Ich denke wir sollten nochmal Schritt für Schritt von vorne anfangen. Dann kriegen wir auch etwas Sauberes hin. Das wird ein bisschen Arbeit, aber du solltest dadurch einiges lernen (und ich auch). Lies trotzdem mal meine Kommentare oben und versuche, sie zu verstehen.

Zeig erstmal TGenealogie und TINDI. Dann bau ich dir mal ein Grundgerüst.


mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:36 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