So kann das nicht funktionieren. Ich weiß nicht, was du alles vorhast. Aber wenn die Ini-Datei IniF immer global im Projekt existieren muss, darfst du die Datei im Ini-Editor nicht erneut von Platte einlesen, sondern du musst dir die Strings des zu bearbeitenden Schlüssels aus IniF holen. TIniDatei hat dafür die Methode ReadSectionValues (im Unterschied zu ReadSection bleiben dabei die Name=Wert Paare erhalten). Das Einlesen der Ini-Strings im FormShow von TFrmIniEdit wird damit zu
Code: Alles auswählen
procedure TFrmIniEdit.FormShow(Sender: TObject);
begin
IniF.ReadSectionValues('RISIKO', ValEdIni.Strings);
end;
Da hier nur eine Section übertragen wird, würde ich dir empfehlen noch eine Listbox in den IniEditor aufzunehmen, in dessen Items du per IniF.ReadSections die Abschnittsbezeichnungen einliest (das sind die Zeilen mit eckigen Klammern). Durch Klick auf einem Listboxeintrag kannst du dann wie oben die Section-Werte in den ValueListEditor übertragen. Aber nicht vergessen, vorher den bisherigen Abschnitt zu sichern - wie das geht, kommt gleich. Alternativ kannst du auch alle Sections in den ValuelistEditor einlesen, wobei der Schlüsselname ohne Wert in der rechten Spalte auftauchen sollte. Etwa so (ist in meinen Augen sehr unübersichtlich. Besser wäre ein StringGrid mit einer zusätzlichen Spalte für den Schlüsselnamen, oder noch besser ein VirtualTreeView, um die nicht interessierenden Abschnitte zuklappen zu können):
Code: Alles auswählen
procedure TFrmIniEdit.FormShow(Sender: TObject);
var
L: TStringList;
sections: TStringList;
i, j: Integer;
begin
L := TStringList.Create;
sections := TStringList.Create;
try
IniF.ReadSections(sections);
for i:=0 to sections.Count-1 do begin
if sections[i] = '' then
Continue;
ValEdIni.Strings.Add(sections[i] + '=');
IniF.ReadSectionValues(sections[i], L);
for j := 0 to L.count-1 do
ValEdIni.Strings.Add(L[j]);
end;
finally
L.Free;
sections.Free;
end;
end;
Die SaveINI-Methode muss die Werte aus dem ValueListEditor in IniF übertragen. Leider gibt es dafür keine kompakte Methode a la ReadSectionValues, sondern man muss die Stringpaare einzeln in IniF zurückschreiben. Aber das ist nicht der Rede wert:
Code: Alles auswählen
procedure TFrmIniEdit.SaveINI;
var
i: Integer;
begin
IniF.EraseSection('RISIKO');
for i:=0 to ValEdIni.Strings.Count-1 do
IniF.WriteString('RISIKO', ValEdIni.Strings.Names[i], ValEdIni.Strings.ValueFromIndex[i]);
IniF.UpdateFile;
end;
Falls du das mit der Listbox machst, musst du natürlich statt "RISIKO" den in der Listbox ausgewählten Schlüsselnamen verwenden.
MakeIniFile hat auch ein Problem, Du willst hier eine neue Ini-Datei auf der Platte anlegen. Dazu löschst du die alte und versuchst per IniF := TIniFile.Create(...) eine neue zu erzeugen. Aber das erzeugt keine Datei, sondern eine neue Instanz der Klasse TIniFile! Die alte (die in FormCreate erzeugt wurde) existiert übrigens weiterhin, nachdem du den Pointer auf die Instanz überschrieben hast, kannst du auf die alte Instanz nicht mehr zugreifen und sie inbesondere nicht mehr freigeben, so dass du ein Speicherleck erzeugt hast. Andererseits die Instanz zu zerstören, ist auch nicht ohne, da hier der Inhalt von IniF auf die Platte geschrieben und beim Create wieder eingelesen wird. Wie geht's richtig? Ich würde die Instanz beibehalten und im Speicher aufräumen durch Aufruf von IniF.EraseSection(...):
Code: Alles auswählen
procedure TFrmIniEdit.MakeIniFile;
// INI-Datei erstellen
var
L: TStringList;
i: Integer;
begin
L := TStringList.Create;
try
IniF.ReadSections(L);
for i:=0 to L.Count-1 do IniF.EraseSection(L[i]);
finally
L.Free;
end;
try
IniF.WriteString('RISIKO','Multiple WK-Fx','2');
....
Daneben habe ich noch einige Probleme gesehen. Aber der Post ist eh schon so lang...