![]() |
Combobox aus *.ini laden
Hallo zusammen,
ich möchte gerne den Inhalt einer Combobox in einer INI-Datei speichern und wieder laden. Im Gegensatz zu den meisten anderen Themen hier im Forum, möchte ich alle Werte der Combobox speichern und laden. Da der Nutzer den Inhalt der Combobox nach Bedarf ändern kann, weiß ich nie wie viele Items in derCombobox sind. So schreibe ich in die Ini. Das klappt auch.
Delphi-Quellcode:
for i:=0 to (cbbOE.items.count -1) do // Inhalt der Combobox in Ini schreiben
begin with TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini')) do begin WriteString('Organisationseinheit', IntToStr(i), cbbOE.items[i]); Free; end; end; Beim Lesen der Ini und Beschreiben der Combobox habe ich jetzt das Problem, dass ich nicht weiß wie viele Items die Combobox haben wird. Wenn ich die Combobox standardmaäßg leer lasse, und einfach mit der Ini beschreibe, kommt eine Fehlermeldung, sinngemäß 'Maximale Anzahl an Items überschritten' und das Programm stürzt ab. Meine Momentane, nicht sehr elegante Lösung sieht so aus:
Delphi-Quellcode:
Ich erzeuge mit also 100 freie Item-Plätze und beschreibe diese dann mit der Ini. Da ich aber in der Regel nur 10-30 Plätze benötige, habe ich jede Menge leere Felder in der Combobox.
for i:=0 to 99 do //
begin with TIniFile.Create(ChangeFileExt(Application.ExeName, '.ini')) do begin cbbOE.items[i]:=ReadString('Organisationseinheit', IntToStr(i),''); Free; end; end; Wie kann ich das eleganter lösen. Notfalls hatte ich mit überlegt über die for schleife nach leeren Feldern zu suchen und diese dann wieder zu löschen. Gefällt mir nicht und hat programmiertechnisch nicht geklappt. Sowas wie
Delphi-Quellcode:
ging natürlich nicht.
if cbbOE.items[i]='' then cbbOE.Items[i].Delete;
Jetzt nochmal die Frage: Wie kann ich die Combo beschreiben ohne die maximale Anzahl der Items zu überschreiten und ohne leere Felder zu haben? Danke im Vorraus! |
AW: Combobox aus *.ini laden
Beim Laden prüfst du, ob es den Eintrag in der INI gibt. Wenn nicht, dann brauchst du auch die Combobox nicht füllen. Eintragen der Einträge in der Box dann über Items.Add und vorher mit Items.Clear den Inhalt erst mal löschen. Nicht über den Index eintragen, da du ja selber gemerkt hast, dass du dann eine Exception bekommst.
|
AW: Combobox aus *.ini laden
Ich hab mal sowas in der Art als Tipp in DF gepostet. Vielleicht bringt es was:
![]() |
AW: Combobox aus *.ini laden
|
AW: Combobox aus *.ini laden
Ja, "Add" und "Clear". Ich merke, dass ich lange nicht mit Delphi gearbeitet habe. Der Post von Popov sieht auch gut aus. Danke
|
AW: Combobox aus *.ini laden
Weil ich es gerade hier so fertig herumliegen habe:
Eine Unit mit der man alle
Delphi-Quellcode:
Properties (rw) einer beliebigen Instanz, eine TCollection und TStrings in eine ini-Datei schreiben und wieder auslesen kann.
published
Die Handhabung ist recht einfach:
Delphi-Quellcode:
Eine TStringList würde dann wie folgt gespeichert werden
var
MyObj : TMyObject; MyIni : TIniFile; begin ... // Instanzen von MyIni und MyObj müssen natürlich vorhanden sein // schreiben StoreObj( MyObj, MyIni, 'MyObject' ); // lesen LoadObj( MyObj, MyIni, 'MyObject' ); end;
Code:
BTW: Man könnte damit auch die komplette ComboBox abspeichern ... aber dann kommt halt alles andere auch mit ;)
[MyObject\Strings]
0=Zeile1 1=Zeile2 2=Zeile3
Delphi-Quellcode:
unit IniObjStore;
interface uses Classes, IniFiles; procedure StoreObj( const Instance : TObject; const Ini : TCustomIniFile; const Section : string ); procedure LoadObj( const Instance : TObject; const Ini : TCustomIniFile; const Section : string ); implementation uses SysUtils, TypInfo; const C_Sec_Delim = '\'; procedure StoreObj( const Instance : TObject; const Ini : TCustomIniFile; const Section : string ); procedure EraseSection; var LSubSections : TStrings; LIdx : Integer; begin LSubSections := TStringList.Create; try Ini.ReadSubSections( Section, LSubSections, True ); for LIdx := 0 to Pred( LSubSections.Count ) do Ini.EraseSection( Section + C_Sec_Delim + LSubSections[LIdx] ); finally LSubSections.Free; end; Ini.EraseSection( Section ); end; var LPropName, LPropValue : string; LPropInfo : PPropInfo; LPropCount : Integer; LPropList : PPropList; LPropType : PPTypeInfo; LIdx : Integer; LObj : TObject; LItem : TCollectionItem; begin EraseSection; if not Assigned( Instance ) then Exit; // TCollection-Handling if Instance is TCollection then for LItem in ( Instance as TCollection ) do // recursive call StoreObj( LItem, Ini, Section + C_Sec_Delim + IntToStr( LItem.Index ) ); if Instance is TStrings then with ( Instance as TStrings ) do for LIdx := 0 to Pred( Count ) do Ini.WriteString( Section + C_Sec_Delim + 'Strings', IntToStr( LIdx ), Strings[LIdx] ); // examine all published properties LPropCount := GetPropList( PTypeInfo( Instance.ClassInfo ), LPropList ); if LPropCount > 0 then try for LIdx := 0 to Pred( LPropCount ) do begin LPropInfo := LPropList^[LIdx]; LPropType := LPropInfo^.PropType; if LPropType^.Kind = tkMethod then Continue; // WriteOnly-Property if ( LPropInfo.GetProc = nil ) then Continue; LPropName := string( LPropInfo.Name ); case LPropType^.Kind of tkClass : begin LObj := GetObjectProp( Instance, LPropName ); // recursive call StoreObj( LObj, Ini, Section + C_Sec_Delim + LPropName ); end; tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkWChar, tkLString, tkWString, tkInt64, tkUString : begin // ReadOnly-Property if ( LPropInfo.SetProc = nil ) then Continue; LPropValue := GetPropValue( Instance, LPropName ); Ini.WriteString( Section, LPropName, LPropValue ); end; end; end; finally FreeMem( LPropList ); end; end; procedure LoadObj( const Instance : TObject; const Ini : TCustomIniFile; const Section : string ); var LPropName, LPropValue : string; LPropInfo : PPropInfo; LPropCount : Integer; LPropList : PPropList; LPropType : PPTypeInfo; LIdx : Integer; LObj : TObject; begin if not Assigned( Instance ) then Exit; // TCollection-Handling if Instance is TCollection then with Instance as TCollection do begin Clear; LIdx := 0; while Ini.SectionExists( Section + C_Sec_Delim + IntToStr( LIdx ) ) do begin // recursive call LoadObj( Add, Ini, Section + C_Sec_Delim + IntToStr( LIdx ) ); Inc( LIdx ); end; end; if Instance is TStrings then with Instance as TStrings do begin BeginUpdate; try Clear; LIdx := 0; while Ini.ValueExists( Section + C_Sec_Delim + 'Strings', IntToStr( LIdx ) ) do begin Add( Ini.ReadString( Section + C_Sec_Delim + 'Strings', IntToStr( LIdx ) ) ); Inc( LIdx ); end; finally EndUpdate; end; end; // examine all published properties LPropCount := GetPropList( PTypeInfo( Instance.ClassInfo ), LPropList ); if LPropCount > 0 then try for LIdx := 0 to Pred( LPropCount ) do begin LPropInfo := LPropList^[LIdx]; LPropType := LPropInfo^.PropType; if LPropType^.Kind = tkMethod then Continue; LPropName := string( LPropInfo.Name ); case LPropType^.Kind of tkClass : begin LObj := GetObjectProp( Instance, LPropName ); // recursive call LoadObj( LObj, Ini, Section + C_Sec_Delim + LPropName ); end; tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkWChar, tkLString, tkWString, tkInt64, tkUString : begin // ReadOnly-Property if LPropInfo.SetProc = nil then Continue; LPropValue := GetPropValue( Instance, LPropName ); LPropValue := Ini.ReadString( Section, LPropName, LPropValue ); SetPropValue( Instance, LPropName, LPropValue ); end; end; end; finally FreeMem( LPropList ); end; end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:53 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