AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Combobox aus *.ini laden

Ein Thema von volvox · begonnen am 4. Mär 2013 · letzter Beitrag vom 4. Mär 2013
Antwort Antwort
volvox

Registriert seit: 17. Jan 2006
8 Beiträge
 
Delphi 7 Professional
 
#1

Combobox aus *.ini laden

  Alt 4. Mär 2013, 19:25
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:
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;
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.

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 if cbbOE.items[i]='then cbbOE.Items[i].Delete; ging natürlich nicht.

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!
  Mit Zitat antworten Zitat
zeras

Registriert seit: 11. Mär 2007
Ort: Saalkreis
1.643 Beiträge
 
Delphi 12 Athens
 
#2

AW: Combobox aus *.ini laden

  Alt 4. Mär 2013, 19:30
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.
Matthias
Es ist nie falsch das Richtige zu tun!
- Mark Twain
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#3

AW: Combobox aus *.ini laden

  Alt 4. Mär 2013, 19:41
Ich hab mal sowas in der Art als Tipp in DF gepostet. Vielleicht bringt es was:

http://www.entwickler-ecke.de/topic_...n_21553,0.html
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.746 Beiträge
 
Delphi 2007 Professional
 
#4

AW: Combobox aus *.ini laden

  Alt 4. Mär 2013, 19:42
Ich würde mir mal Delphi-Referenz durchsuchenTIniFile.ReadSection und/oder Delphi-Referenz durchsuchenTIniFile.ReadSectionValues anschauen.
Uli Gerhardt
  Mit Zitat antworten Zitat
volvox

Registriert seit: 17. Jan 2006
8 Beiträge
 
Delphi 7 Professional
 
#5

AW: Combobox aus *.ini laden

  Alt 4. Mär 2013, 19:47
Ja, "Add" und "Clear". Ich merke, dass ich lange nicht mit Delphi gearbeitet habe. Der Post von Popov sieht auch gut aus. Danke
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Combobox aus *.ini laden

  Alt 4. Mär 2013, 20:10
Weil ich es gerade hier so fertig herumliegen habe:

Eine Unit mit der man alle published Properties (rw) einer beliebigen Instanz, eine TCollection und TStrings in eine ini-Datei schreiben und wieder auslesen kann.

Die Handhabung ist recht einfach:
Delphi-Quellcode:
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;
Eine TStringList würde dann wie folgt gespeichert werden
Code:
[MyObject\Strings]
0=Zeile1
1=Zeile2
2=Zeile3
BTW: Man könnte damit auch die komplette ComboBox abspeichern ... aber dann kommt halt alles andere auch mit

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.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 4. Mär 2013 um 20:44 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:44 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz