Types: Objekte per Array erstellen + einzeln auslesen

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

KnorxThieus

Betreff: Types: Objekte per Array erstellen + einzeln auslesen

BeitragFr, Feb 07, 2014 17:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

da ich mich für eine Funktion noch näher mit Types beschäftigt habe, ist mir klar geworden, dass ich die Zusammenhänge und Kombinationsmöglichkeiten zwischen Types und Array nicht begreife.
Meines Verständnisses gibt es da
1. Field als Array: BlitzBasic: [AUSKLAPPEN]
Type T
Field f[2]
End Type

2. Objekte mit Array erstellen: BlitzBasic: [AUSKLAPPEN]
Type T
Field f
End Type

Dim o.T(3)

For a = 0 To 3
o.T(a) = New T
o(a)\f = a
Next

3. Gibt es noch etwas?

Aber mein Kernproblem liegt bei 2.: Kann ich [Blitzarrays] erstellen? Mein Problem liegt dabei, dass ich gerne 3 Objektreihen getrennt voneinander erstellen möchte, also etwa so: BlitzBasic: [AUSKLAPPEN]
Type T
Field f
End Type

o1.T = New T
o1\f = 42

o2.T = New T
o2\f = 1764

o3.T = New T
o3\f = 3111696

Das möchte ich per Array (ob Blitz- oder multidimensionales ist mir egal) zusammenfassen: BlitzBasic: [AUSKLAPPEN]
Type T
Field f
End Type

Dim o.T(3) ;ich weiß, ein Array beginnt eigentl. bei 0

o.T(1) = New T
o(1)\f = 42

o.T(2) = New T
o(2)\f = 1764

o.T(3) = New T
o(3)\f = 3111696

Aber wenn ich nun meine erste Typereihe durchgehen will, liefert mir BlitzBasic auch die benachbarten Einträge: BlitzBasic: [AUSKLAPPEN]
Type T
Field f
End Type

Dim o.T(3)

o.T(1) = New T
o(1)\f = 42

o.T(2) = New T
o(2)\f = 1764

o.T(3) = New T
o(3)\f = 3111696



For o.T(1) = Each T
DebugLog o(1)\f
Next

Stop

Konsolenausgabe: Code: [AUSKLAPPEN]
42
1764
3111696


Kann ich das irgendwie verhindern? Geht das per Blitzarray, das habe ich nicht hinbekommen? Geht es per quadratisches Array, wobei mir da ebenfalls unklar ist, wie sich dies bewerkstelligen ließe?

Gesucht hab ich schon im gefühlten halben Forum, das hier und das hier konnten mir aber nicht weiterhelfen.

Mit freundlichen Grüßen,
KnorxThieus
Version: BlitzPlus / Blitz+
 

Matthias

BeitragFr, Feb 07, 2014 18:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hay.

Jedes Type hat nur eine Liste und deshalb werden immer alle Einträge mit Each durch gegangen.

Vlt hilft dir diese Möglichkeit.

Code: [AUSKLAPPEN]



Dim Garage.TGarage(10)
Garage(0)=New TGarage
G.TGarage=Garage(0)
G\Autos[3]=New TAuto
G\Autos[3]\Name="VW"

G\Autos[4]=New TAuto
G\Autos[4]\Name="Viat"

Type TGarage
   Field Autos.TAuto[10]
   
End Type

Type TAuto
   Field Name$
End Type

For I=0 To 9
   If Garage(0)\Autos[I]<>Null Then
      DebugLog Garage(0)\Autos[I]\Name
   End If   
Next   


Mfg Matz Laughing

KnorxThieus

BeitragFr, Feb 07, 2014 18:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

vielen Dank für deine Antwort.
Allerdings ist mir nicht ganz die Vorgehensweise deines Codes klar.

Du erstellst einen Type TAuto mit dem Feld Name und einen Type TGarage mit dem Feld Autos.TAuto. Aber den Rest verstehe ich nicht: BlitzBasic: [AUSKLAPPEN]
Dim Garage.TGarage(10)
Garage(0)=New TGarage
G.TGarage=Garage(0)
G\Autos[3]=New TAuto
G\Autos[3]\Name="VW"

G\Autos[4]=New TAuto
G\Autos[4]\Name="Viat"

BlitzBasic: [AUSKLAPPEN]
For I=0 To 9
If Garage(0)\Autos[I]<>Null Then
DebugLog Garage(0)\Autos[I]\Name
End If
Next
Version: BlitzPlus / Blitz+
 

Matthias

BeitragFr, Feb 07, 2014 18:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Weil es jetzt sehr allgemein war.

Es kommt darauf an was du erreichen willst. Bitte erkläre es mir genauer.

Mit der For schleife werden alle Autos aus der Garage 0 durch gegangen und die die vorhanden sind werden mit dem Namen angezeigt.

Code: [AUSKLAPPEN]


DebugLog Garage(0)\Autos[3]\Name

KnorxThieus

BeitragFr, Feb 07, 2014 18:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich lade Daten für Styles in mein Programm (Schrift, Farbe etc.), dabei habe ich mehrere Styles und jeweils mehrere Zustände (es handelt sich um Links, MouseHover, MouseDown, nichts von alledem, Link aktiv...). Später habe ich dann Variablen style und zustand, daher ist es mir sehr wichtig, den einzelnen Typeeintrag direkt ansprechen zu können. Geht das jetzt nur mit verschachtelten Types oder auch anders?

MFG
Version: BlitzPlus / Blitz+
 

Matthias

BeitragFr, Feb 07, 2014 18:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Achso ok.

Vlt sowas.
Code: [AUSKLAPPEN]


Dim Styles.TStyles(10)
Type TStyles
   Field Schrift$,Farbe$
End Type   

Styles(0)=New TStyles
Styles(0)\Schrift="Arial"
Styles(0)\Farbe="Blau"

Styles(1)=New TStyles
Styles(1)\Schrift="OS"
Styles(1)\Farbe="Grün"

DebugLog Styles(1)\Schrift


DAK

BeitragSa, Feb 08, 2014 0:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Dein Fehler war das hier:

BlitzBasic: [AUSKLAPPEN]
For o.T(1) = Each T
DebugLog o(1)\f
Next

Dabei werden in einer Schleife alle existenten T durchlaufen (Each T) und eins nach dem anderen in o.T(1) reingestopft. Verwende die For ... = Each ... -Schleifen, wenn du jedes Element eines Types ein mal verwenden möchtest.

Verwende o.T(x), wenn du das T haben willst, was sich an x-ter Stelle im Array o.T befindet.
Gewinner der 6. und der 68. BlitzCodeCompo

KnorxThieus

BeitragSo, Feb 09, 2014 10:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@Matthias.
Danke, aber wenn ich jetzt zum nächsten Objekt der Reihe springe (also vom 1. Objekt der Reihe Style (0) zum 2. Objekt), komme ich beim 1. Objekt der Reihe Style (1) raus:
BlitzBasic: [AUSKLAPPEN]

Dim Styles.TStyles(10)
Type TStyles
Field Schrift$,Farbe$
End Type

Styles(0)=New TStyles
Styles(0)\Schrift="Arial"
Styles(0)\Farbe="Blau"

Styles(1)=New TStyles
Styles(1)\Schrift="OS"
Styles(1)\Farbe="Grün"

Styles.TStyles(0) = First TStyles
DebugLog Styles(0)\Farbe$
Styles.TStyles(0) = After Styles(0).TStyles
DebugLog Styles(0)\Farbe$

Stop

Eigentlich sollte ja beim zweiten DebugLog Styles(0) = null gelten und eine fehlermeldung entstehen!

Also anstatt
Code: [AUSKLAPPEN]
Objekt(0)   Objekt(1)   Objekt(2)
Objekt(0)   Objekt(1)   Objekt(2)
Objekt(0)   Objekt(1)   Objekt(2)
...      ...      ...

(nach oben / unten mit After / Before, nach links und rechts gar nicht)
gilt:
Code: [AUSKLAPPEN]
Objekt(0)
Objekt(0)
Objekt(0)
...
Objekt(1)
Objekt(1)
Objekt(1)
...
Objekt(2)
Objekt(2)
Objekt(2)

(am ende der reihe objekt(0) geht es gleich mit objekt(1) weiter!)

Und ich versuche, Modell 1 hinzukriegen.
Ist das so verständlich? Embarassed

Deine verschachtelten Types schienen mir schon ein Ansatz, bloß sehe ich nicht ganz, wie ich das umsetzen soll... ich versuche es gleich noch mal...

@DAK: (ich hab dich erst jetzt gesehen, tut mir leid)
Ich verstehe schon, aber wie lässt sich jetzt das o1.T, o2.T, o3.T als Array o.T(1) einzeln abfragen (siehe Modell 1)?


EDIT:
Ich habe mir Matthias' Garagencode nochmal intensiv angeschaut und was probiert:
BlitzBasic: [AUSKLAPPEN]
Type Style	;hier trage ich meine einzelnen Einstellungswerte ein
Field font$
Field clr
End Type

Type StyleData ;hier erstelle ich die "Style-Sets" für Hover, MouseDown, etc....
Field s.Style[3] ;siehe Type Style
End Type

Dim st.StyleData(10) ;ich plane 10 Style-Sets



st.StyleData(0) = New StyleData ;erstelle SS 1

st(0)\s.Style[0] = New Style ;erste Situation: kein Mauskontakt
st(0)\s[0]\font$ = "Calibri"
st(0)\s[0]\clr = $0000FF

st(0)\s.Style[1] = New Style ;2. S; Maus drüber
st(0)\s[1]\font$ = "Calibri"
st(0)\s[1]\clr = $3030FF

st(0)\s.Style[2] = New Style ;3. S: Maus runtergedrückt
st(0)\s[2]\font$ = "Calibri"
st(0)\s[2]\clr = $FF0000

st(0)\s.Style[3] = New Style ;4. S.: schon besuchter Link
st(0)\s[3]\font$ = "Calibri"
st(0)\s[3]\clr = $0070DF


st.StyleData(1) = New StyleData ;2. SS

st(1)\s.Style[0] = New Style ;...
st(1)\s[0]\font$ = "Arial"
st(1)\s[0]\clr = $0000A0

st(1)\s.Style[1] = New Style
st(1)\s[1]\font$ = "Arial"
st(1)\s[1]\clr = $3030AA

st(1)\s.Style[2] = New Style
st(1)\s[2]\font$ = "Arial"
st(1)\s[2]\clr = $FF0050

st(1)\s.Style[3] = New Style
st(1)\s[3]\font$ = "Arial"
st(1)\s[3]\clr = $0000A0




;ANWENDUNG

ss = 1 ;geg.: Style Set Nummer 1
s = 2 ;Situation 2

RuntimeError "Schrift: " + st(ss)\s[s]\font$ + " Farbe: $" + Hex$(st(ss)\s[s]\clr)

Ist das nur zufällig richtig, oder hab ich das Prinzip verstanden?

Die Typelisten sähen dann so aus:
Code: [AUSKLAPPEN]
st(0)\s.Style[0]   st(1)\s.Style[0]
(st(0)\s.Style[0]   (st(1)\s.Style[0] ;(*)
...)         ...)
st(0)\s.Style[1]   st(1)\s.Style[1]
(st(0)\s.Style[1]   (st(1)\s.Style[1]
...)         ...)
st(0)\s.Style[2]   st(1)\s.Style[2]
...         ...


(*)   ich könnte rein theoretisch weitere hiervon erstellen, aber beim Auslesen wäre das dann s[1] etc...., oder?

Stimmt das?

Midimaster

BeitragSo, Feb 09, 2014 11:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich verstehe nicht ganz das Durcheinander, dass hier herscht.

Wenn man ein Array aud Objekten machen will, sollte man sie anschließend auch als Array ansprechen:

Code: [AUSKLAPPEN]

Dim Styles.TStyles(10)

Type TStyles
   Field Schrift$,Farbe$
End Type   

Styles(0)=New TStyles
Styles(0)\Schrift="Arial"
Styles(0)\Farbe="Blau"

Styles(1)=New TStyles
Styles(1)\Schrift="OS"
Styles(1)\Farbe="Grün"

Max%=1
For i%=0 To Max
    DebugLog i + " " + Styles(i)\Farbe + " " + Styles(i)\Schrift
Next


Die Variante "Each" könnnte höchstens zufällig die richtige Reihenfolge enthalten. Garantiert ist das nicht!
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

KnorxThieus

BeitragSo, Feb 09, 2014 11:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Stimmt, ich könnte das Ganze auch so anstellen:
BlitzBasic: [AUSKLAPPEN]
Type T
Field f
End Type

Dim o.T(10, 2)

o.T(0, 0) = New T
o(0, 0)\f = 42

o.T(0, 1) = New T
o(0, 1)\f = 4242

o.T(0, 2) = New T
o(0, 2)\f = 424242

o.T(1, 0) = New T
o(1, 0)\f = 24

o.T(1, 1) = New T
o(1, 1)\f = 2424

o.T(1, 2) = New T
o(1, 2)\f = 242424

;...

RuntimeError o(1, 1)\f

Hauptsache ist ja, dass es sich eindeutig ansprechen lässt... und das klappt ja jetzt hier, bei Midimaster und meinem Editcode?
Ich hatte bloß nicht zu Beginn begriffen, was Midimaster soeben sagte...

Ich denke, dann nehme ich die Variante mit st(ss)\s[s]\value.

MFG
Version: BlitzPlus / Blitz+

DAK

BeitragSo, Feb 09, 2014 12:48
Antworten mit Zitat
Benutzer-Profile anzeigen
OK, noch mal von Anfang. Es gib zwei verschiedene Arten Objekte eines Types anzusprechen. Per Variable oder per Liste.

Gegeben folgender Type:
BlitzBasic: [AUSKLAPPEN]
Type TTest
Field a
EndType


Per Variable:
BlitzBasic: [AUSKLAPPEN]
o1.TTest = New TTest
o1\a = 1
o2.TTest = New TTest
o2\a = 2
Print(o1\a) ;gibt 1 aus
Print(o2\a) ;gibt 2 aus
o1 = o2 ;o1 wird o2 zugewiesen, sie zeigen jetzt beide auf das gleiche Objekt
Print(o1\a) ;gibt jetzt 1 aus
o1\a = 5
Print(o2\a) ;gibt 5 aus, da o1 und o2 auf das gleiche Objekt zeigen

Eine Variable behält also ihren Wert solange bis sie überschrieben wird. Anders als z.B. bei normalen Zahlenwerten wird der Wert nicht in der Variable selbst gespeichert sondern die Variable beinhaltet eine Referenz auf ein Objekt. Haben zwei Variablen den gleichen Zahlenwert, dann sind sie von einander unabhängig. Verändert man den Wert der einen Variable ändert das an der Anderen nichts.
Bei Type-Variablen ist das anders. Zeigen zwei Variablen auf das gleiche Objekt und man ändert den Wer eines Feldes des Objekts, dann wird das Feld bei beiden Variablen geändert sein, da beide Variablen auf das gleiche Feld zeigen.

Per Liste:
BlitzBasic: [AUSKLAPPEN]
For x.TTest = Each TTest
;hier wird x nacheinander mit jedem exisitierenden TTest befüllt
Next
x.TTest = First TTest ;x beinhaltet jetzt das zuerst erstellte (=älteste) TTest
x.TTest = After x.TTest ;x beinhaltet jetzt das zweite erstellte TTest
x.TTest = After x.TTest ;x beinhaltet jetzt das dritte erstellte TTest
x.TTest = Last TTest ;x beinhaltet jetzt das zuletzt erstellte (=neueste) TTest


Das Array ist ein Sonderfall vom Zugriff per Variable. Ein Array ist ein Satz von einer fixen Anzahl Variablen, die sich per Index-Zahl ansprechen lassen. Du musst also nicht die Befehle First, After, Last oder Each verwenden um an die Objekte zu kommen. Im Gegenteil, dadurch, dass du sie kombinierst machst du eigentlich alles kaputt.
Um noch mal dein Beispiel von vorhin aufzugreifen:

BlitzBasic: [AUSKLAPPEN]
Dim Styles.TStyles(10) 
Type TStyles
Field Schrift$,Farbe$
End Type

Styles(0)=New TStyles ;Styles(0) hat jetzt das erste erstelle Objekt, nennen wir es o1
Styles(0)\Schrift="Arial"
Styles(0)\Farbe="Blau"

Styles(1)=New TStyles ;Styles(1) = o2
Styles(1)\Schrift="OS"
Styles(1)\Farbe="Grün"

Styles.TStyles(0) = First TStyles ;Styles(0) wird jetzt wieder o1 neu zugewiesen
DebugLog Styles(0)\Farbe$
Styles.TStyles(0) = After Styles(0).TStyles ;Styles(0) wird jetzt o2 (also das Objekt nach 01) zugewiesen
DebugLog Styles(0)\Farbe$


Wie du siehst ist es nur Zufall, dass du das richtige Ergebnis bekommst. Wenn du beim Erstellen der Objekte z.B. zuerst Styles(1) und dann erst Styles(0) einen Wert zuweist, dann wird die Ausgabe genau falsch herum sein.

Richtig wäre folgendes:
BlitzBasic: [AUSKLAPPEN]

DebugLog Styles(0)\Farbe$ ;Styles(0) hat ja schon von der Zeile Styles(0) = new TTest an o1 drinnen
DebugLog Styles(1)\Farbe$ ;Styles(1) hat auch schon o2 drinnen
Gewinner der 6. und der 68. BlitzCodeCompo

KnorxThieus

BeitragSo, Feb 09, 2014 13:24
Antworten mit Zitat
Benutzer-Profile anzeigen
OK, vielen Dank nochmals, dann habe ich es jetzt wohl verstanden.
Liste und Einzelobjekt waren mir ja schon klar, bloß das Array nicht.

Ist mein EDIT-Code nun also richtig?

MFG
Version: BlitzPlus / Blitz+

DAK

BeitragSo, Feb 09, 2014 13:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Öh, ja, sollte passen.
Gewinner der 6. und der 68. BlitzCodeCompo

Xeres

Moderator

BeitragSo, Feb 09, 2014 13:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich glaube, die Verwirrung hier rührt weniger von Types selbst her, vielmehr ist nicht ganz klar, was für eine Datenstruktur du versuchst auf zu bauen.
Du hast n Styles mit m Untertypen - also beliebig viele zu beliebig vielen? Dann verstehe ich nicht, wozu die ganzen Arrays gut sein sollen. Hier wäre erst mal ein Diagramm angebracht, dass das Problem beschreibt: Welche Objekte wie zu anderen stehen.
Vorschnelle Versuche etwas optimieren zu wollen, bringen meistens nichts.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

KnorxThieus

BeitragSo, Feb 09, 2014 13:56
Antworten mit Zitat
Benutzer-Profile anzeigen
@DAK: Ok, danke!
@Xeres: Ich habe in jenem Edit-Post auch schon versucht, die Lage darzustellen:
Code: [AUSKLAPPEN]
st(0)\s.Style[0]   st(1)\s.Style[0]
(st(0)\s.Style[0]   (st(1)\s.Style[0] ;(*)
...)         ...)
st(0)\s.Style[1]   st(1)\s.Style[1]
(st(0)\s.Style[1]   (st(1)\s.Style[1]
...)         ...)
st(0)\s.Style[2]   st(1)\s.Style[2]
...         ...


(*)   ich könnte rein theoretisch weitere hiervon erstellen, aber beim Auslesen wäre das dann s[1] etc...., oder?

Stimmt das?

Mir ist bloß nicht ganz klar (nein, ich habe es ausprobiert:) mir war nicht ganz klar, was passiert, wenn ich zweimal Styles(1)=New TStyles aufrufe: Letzter Aufruf überschreibt vorherigen. Dann ist mir jetzt eigentlich alles klar, bloß aus meinem "Diagramm" muss ich die Fußnote und die Punkte streichen.

MFG
Version: BlitzPlus / Blitz+

Xeres

Moderator

BeitragSo, Feb 09, 2014 14:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich kann dir nicht sagen ob das "stimmt" denn ich kann beim besten Willen nicht erkennen, was du darstellen willst.
Ein UML Diagramm könnte helfen.

Wenn du zwei mal "Styles(1)=New TStyles" ausführst, enthält Styles(1) das zu letzt erzeugte Objekt - das ist richtig. Allerdings existiert das zu erst erstelle Objekt weiter in der Globalen Typeliste bist du es mit Delete löschst.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

KnorxThieus

BeitragSo, Feb 09, 2014 15:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie ich oben schrieb:
nach oben / unten mit After / Before, nach links und rechts gar nicht

Xeres hat Folgendes geschrieben:
Wenn du zwei mal "Styles(1)=New TStyles" ausführst, enthält Styles(1) das zu letzt erzeugte Objekt - das ist richtig. Allerdings existiert das zu erst erstelle Objekt weiter in der Globalen Typeliste bist du es mit Delete löschst.

Und wie spreche ich das erste Styles(1) an? per For-each?
Version: BlitzPlus / Blitz+

Xeres

Moderator

BeitragSo, Feb 09, 2014 15:42
Antworten mit Zitat
Benutzer-Profile anzeigen
For...Each ist die einzige Möglichkeit dieses Style Objekt wieder zu erreichen, wenn die Referenz aus dem Array entfernt bzw. überschrieben wurde.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

KnorxThieus

BeitragSo, Feb 09, 2014 16:02
Antworten mit Zitat
Benutzer-Profile anzeigen
OK, also gewissermaßen wurde die Adresse gelöscht.
?
Version: BlitzPlus / Blitz+

Xeres

Moderator

BeitragSo, Feb 09, 2014 16:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja.
Alle Type-Variablen enthalten immer nur eine Referenz auf ein Objekt. Mit For..Each werden einer Variable der Reihe nach die Referenzen aus der Internen, Globalen Liste des Types zugewiesen. Auf diese Liste kann man auch mit First/Last usw. zugreifen. Wichtig ist, dass Objekte nie verschwinden wenn man sie nicht explizit mit Delete löscht.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group