Du bringst hier etwas durcheinander:
(1) Wenn du Zusatzinformation per TStrings.ValueFromIndex auslesen willst, muss die Information vorher via TStrings.Add('Name=Wert') in die Liste geschrieben worden sein. Das Argument des Add-Aufrufs ist aber gerade der Text, der auf dem Tab-Reiter steht, also "Name=Wert" - das willst du sicher nicht.
(2) Du schreibst die Zusatzinformation per TStrings.AddObject('name', Zusatzinfo_als_TObject) in die StringListe. Das wäre normalerweise OK, wenn die Zusatzinformation über TStrings.Objects[index] ausgelesen werden würde. Aber hier funktioniert auch das nicht, weil das eingehängte Objekt bereits intern verwendet wird. Um das zu sehen, klicke ein TabControl aufs Formular, füge im Designmodus ein paar Tabs hinzu und schreibe folgenden OnChange-Event-Handler:
Code: Alles auswählen
procedure TForm1.TabControl1Change(Sender: TObject);
var
tabObj: TObject;
begin
tabObj := TabControl1.Tabs.Objects[TabControl1.TabIndex];
if tabObj = nil then
ShowMessage('NIL')
else
ShowMessage(tabObj.Classname + / ' + TWinControl(tabObj).Caption);
end;
Bei jedem Klick wird "TabSheet/<Name des Tabs>" ausgegeben, obwohl eigentlich bewusst gar kein TTabSheet als Objekt an die Tabs gehängt worden ist. Meiner Meinung nach ist TTabControl hier sehr schlecht programmiert, weil Einhängen von Zusatzinformationen unterbunden wird.
Wenn du einen zusätzlichen Integer zu jedem Tab speichern möchtest, fallen mir folgende Möglichkeiten ein:
(1) ein separates Array (oder TList oder TIntegerList, o.ä) außerhalb des TTabControl anlegen und dort den Integer speichern. Du musst natürlich dafür sorgen, dass die Tab-Liste und die Integer-Liste synchron bleiben.
(2) Eine andere, sehr hackermäßige Variante geht davon aus, dass alle GUI-Elemente bei einem String, der ein #0 enthält, die folgenden Zeichen nicht mehr anzeigen. Daher könntest du die Zusatzinformation einfach nach einer #0 mit in die Tab-Beschriftung packen:
Code: Alles auswählen
while not Qu.Eof do
begin
tc.Tabs.Add(
Qu.FieldByName('VAL').Value + #0 + IntToStr(Qu.FieldByName('COL')).AsInteger));
...
Später beim Auslesen:
Code: Alles auswählen
procedure TfrmSolutions.tcChange(Sender: TObject);
var
s, info: String;
p: Integer;
begin
s := tc.Tabs[tc.TabIndex];
p := pos(#0, s);
if p > 0 then begin
info := copy(s, p+1, MaxInt);
s := copy(s, 1, p-1);
end else
info := '';
ShowMessage(s + LineEnding + 'ZusatzInfo: ' + info);
end;
Ich bin nicht sicher, ob sich alle Widgetsets so verhalten wie das von mir verwendete Windows. Und wie alle Hackerlösungen kann das irgendwann nicht mehr funktionieren.
(3) Die richtige Stelle, einen Integer einem Objekt mitzugeben, wäre die Allzweck-Eigenschaft "Tag". Nur: vordergründig erzeugt TTabControl keine separaten Objekte für die Tabs. Aber wie wir oben gesehen haben, ist das nicht richtig. Es wird für jeden Tab ein TTabsheet erzeugt und in den Objects[] der Tab-Strings abgelegt. Damit kommt man auf diese
Weise an das "Tag" zum Schreiben
Code: Alles auswählen
var
tabsheet: TTabSheet;
i: Integer;
...
while not Qu.Eof do
begin
i := tc.Tabs.Add(Qu.FieldByName('VAL').Value);
tabsheet := TTabSheet(tc.Tabs.Objects[i]);
tabsheet.Tag := Qu.FieldByName('COL')).AsInteger);
...
und so zum Auslesen
Code: Alles auswählen
var
tabsheet: TTabsheet;
begin
tabsheet := TTabSheet(tc.Tabs.Objects[tc.TabIndex])
ShowMessage(IntToStr(tabsheet.Tag));
Auch das gefällt mir nicht, weil das TTabControl offenbar sehr schlampig programmiert ist und sich irgendwann sicher jemand der Komponente annehmen wird - als Folge ist nicht garantiert, dass es weiterhin ein verstecktes TabSheet geben wird.
Also? Ich würde Variante 1 nehmen.