home *** CD-ROM | disk | FTP | other *** search
-
- {*******************************************************}
- { }
- { Borland Delphi Visual Component Library }
- { }
- { Copyright (c) 1995,99 Inprise Corporation }
- { }
- {*******************************************************}
-
- unit IniFiles;
-
- {$R-,T-,H+,X+}
-
- interface
-
- uses Windows, SysUtils, Classes;
-
- type
- TCustomIniFile = class(TObject)
- private
- FFileName: string;
- public
- constructor Create(const FileName: string);
- function SectionExists(const Section: string): Boolean;
- function ReadString(const Section, Ident, Default: string): string; virtual; abstract;
- procedure WriteString(const Section, Ident, Value: String); virtual; abstract;
- function ReadInteger(const Section, Ident: string; Default: Longint): Longint; virtual;
- procedure WriteInteger(const Section, Ident: string; Value: Longint); virtual;
- function ReadBool(const Section, Ident: string; Default: Boolean): Boolean; virtual;
- procedure WriteBool(const Section, Ident: string; Value: Boolean); virtual;
- function ReadDate(const Section, Name: string; Default: TDateTime): TDateTime; virtual;
- function ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime; virtual;
- function ReadFloat(const Section, Name: string; Default: Double): Double; virtual;
- function ReadTime(const Section, Name: string; Default: TDateTime): TDateTime; virtual;
- procedure WriteDate(const Section, Name: string; Value: TDateTime); virtual;
- procedure WriteDateTime(const Section, Name: string; Value: TDateTime); virtual;
- procedure WriteFloat(const Section, Name: string; Value: Double); virtual;
- procedure WriteTime(const Section, Name: string; Value: TDateTime); virtual;
- procedure ReadSection(const Section: string; Strings: TStrings); virtual; abstract;
- procedure ReadSections(Strings: TStrings); virtual; abstract;
- procedure ReadSectionValues(const Section: string; Strings: TStrings); virtual; abstract;
- procedure EraseSection(const Section: string); virtual; abstract;
- procedure DeleteKey(const Section, Ident: String); virtual; abstract;
- procedure UpdateFile; virtual; abstract;
- function ValueExists(const Section, Ident: string): Boolean;
- property FileName: string read FFileName;
- end;
-
- { TIniFile - Encapsulates the Windows INI file interface
- (Get/SetPrivateProfileXXX functions) }
-
- TIniFile = class(TCustomIniFile)
- public
- function ReadString(const Section, Ident, Default: string): string; override;
- procedure WriteString(const Section, Ident, Value: String); override;
- procedure ReadSection(const Section: string; Strings: TStrings); override;
- procedure ReadSections(Strings: TStrings); override;
- procedure ReadSectionValues(const Section: string; Strings: TStrings); override;
- procedure EraseSection(const Section: string); override;
- procedure DeleteKey(const Section, Ident: String); override;
- procedure UpdateFile; override;
- end;
-
- { TMemIniFile - loads and entire ini file into memory and allows all
- operations to be performed on the memory image. The image can then
- be written out to the disk file }
-
- TMemIniFile = class(TCustomIniFile)
- private
- FSections: TStringList;
- function AddSection(const Section: string): TStrings;
- procedure LoadValues;
- public
- constructor Create(const FileName: string);
- destructor Destroy; override;
- procedure Clear;
- procedure DeleteKey(const Section, Ident: String); override;
- procedure EraseSection(const Section: string); override;
- procedure GetStrings(List: TStrings);
- procedure ReadSection(const Section: string; Strings: TStrings); override;
- procedure ReadSections(Strings: TStrings); override;
- procedure ReadSectionValues(const Section: string; Strings: TStrings); override;
- function ReadString(const Section, Ident, Default: string): string; override;
- procedure Rename(const FileName: string; Reload: Boolean);
- procedure SetStrings(List: TStrings);
- procedure UpdateFile; override;
- procedure WriteString(const Section, Ident, Value: String); override;
- end;
-
- implementation
-
- uses Consts;
-
- { TCustomIniFile }
-
- constructor TCustomIniFile.Create(const FileName: string);
- begin
- FFileName := FileName;
- end;
-
- function TCustomIniFile.SectionExists(const Section: string): Boolean;
- var
- S: TStrings;
- begin
- S := TStringList.Create;
- try
- ReadSection(Section, S);
- Result := S.Count > 0;
- finally
- S.Free;
- end;
- end;
-
- function TCustomIniFile.ReadInteger(const Section, Ident: string;
- Default: Longint): Longint;
- var
- IntStr: string;
- begin
- IntStr := ReadString(Section, Ident, '');
- if (Length(IntStr) > 2) and (IntStr[1] = '0') and
- ((IntStr[2] = 'X') or (IntStr[2] = 'x')) then
- IntStr := '$' + Copy(IntStr, 3, Maxint);
- Result := StrToIntDef(IntStr, Default);
- end;
-
- procedure TCustomIniFile.WriteInteger(const Section, Ident: string; Value: Longint);
- begin
- WriteString(Section, Ident, IntToStr(Value));
- end;
-
- function TCustomIniFile.ReadBool(const Section, Ident: string;
- Default: Boolean): Boolean;
- begin
- Result := ReadInteger(Section, Ident, Ord(Default)) <> 0;
- end;
-
- function TCustomIniFile.ReadDate(const Section, Name: string; Default: TDateTime): TDateTime;
- var
- DateStr: string;
- begin
- DateStr := ReadString(Section, Name, '');
- Result := Default;
- if DateStr <> '' then
- try
- Result := StrToDate(DateStr);
- except
- on EConvertError do
- else raise;
- end;
- end;
-
- function TCustomIniFile.ReadDateTime(const Section, Name: string; Default: TDateTime): TDateTime;
- var
- DateStr: string;
- begin
- DateStr := ReadString(Section, Name, '');
- Result := Default;
- if DateStr <> '' then
- try
- Result := StrToDateTime(DateStr);
- except
- on EConvertError do
- else raise;
- end;
- end;
-
- function TCustomIniFile.ReadFloat(const Section, Name: string; Default: Double): Double;
- var
- FloatStr: string;
- begin
- FloatStr := ReadString(Section, Name, '');
- Result := Default;
- if FloatStr <> '' then
- try
- Result := StrToFloat(FloatStr);
- except
- on EConvertError do
- else raise;
- end;
- end;
-
- function TCustomIniFile.ReadTime(const Section, Name: string; Default: TDateTime): TDateTime;
- var
- TimeStr: string;
- begin
- TimeStr := ReadString(Section, Name, '');
- Result := Default;
- if TimeStr <> '' then
- try
- Result := StrToTime(TimeStr);
- except
- on EConvertError do
- else raise;
- end;
- end;
-
- procedure TCustomIniFile.WriteDate(const Section, Name: string; Value: TDateTime);
- begin
- WriteString(Section, Name, DateToStr(Value));
- end;
-
- procedure TCustomIniFile.WriteDateTime(const Section, Name: string; Value: TDateTime);
- begin
- WriteString(Section, Name, DateTimeToStr(Value));
- end;
-
- procedure TCustomIniFile.WriteFloat(const Section, Name: string; Value: Double);
- begin
- WriteString(Section, Name, FloatToStr(Value));
- end;
-
- procedure TCustomIniFile.WriteTime(const Section, Name: string; Value: TDateTime);
- begin
- WriteString(Section, Name, TimeToStr(Value));
- end;
-
- procedure TCustomIniFile.WriteBool(const Section, Ident: string; Value: Boolean);
- const
- Values: array[Boolean] of string = ('0', '1');
- begin
- WriteString(Section, Ident, Values[Value]);
- end;
-
- function TCustomIniFile.ValueExists(const Section, Ident: string): Boolean;
- var
- S: TStrings;
- begin
- S := TStringList.Create;
- try
- ReadSection(Section, S);
- Result := S.IndexOf(Ident) > -1;
- finally
- S.Free;
- end;
- end;
-
- { TIniFile }
-
- function TIniFile.ReadString(const Section, Ident, Default: string): string;
- var
- Buffer: array[0..2047] of Char;
- begin
- SetString(Result, Buffer, GetPrivateProfileString(PChar(Section),
- PChar(Ident), PChar(Default), Buffer, SizeOf(Buffer), PChar(FFileName)));
- end;
-
- procedure TIniFile.WriteString(const Section, Ident, Value: string);
- begin
- if not WritePrivateProfileString(PChar(Section), PChar(Ident),
- PChar(Value), PChar(FFileName)) then
- raise Exception.CreateResFmt(@SIniFileWriteError, [FileName]);
- end;
-
- procedure TIniFile.ReadSections(Strings: TStrings);
- const
- BufSize = 16384;
- var
- Buffer, P: PChar;
- begin
- GetMem(Buffer, BufSize);
- try
- Strings.BeginUpdate;
- try
- Strings.Clear;
- if GetPrivateProfileString(nil, nil, nil, Buffer, BufSize,
- PChar(FFileName)) <> 0 then
- begin
- P := Buffer;
- while P^ <> #0 do
- begin
- Strings.Add(P);
- Inc(P, StrLen(P) + 1);
- end;
- end;
- finally
- Strings.EndUpdate;
- end;
- finally
- FreeMem(Buffer, BufSize);
- end;
- end;
-
- procedure TIniFile.ReadSection(const Section: string; Strings: TStrings);
- const
- BufSize = 16384;
- var
- Buffer, P: PChar;
- begin
- GetMem(Buffer, BufSize);
- try
- Strings.BeginUpdate;
- try
- Strings.Clear;
- if GetPrivateProfileString(PChar(Section), nil, nil, Buffer, BufSize,
- PChar(FFileName)) <> 0 then
- begin
- P := Buffer;
- while P^ <> #0 do
- begin
- Strings.Add(P);
- Inc(P, StrLen(P) + 1);
- end;
- end;
- finally
- Strings.EndUpdate;
- end;
- finally
- FreeMem(Buffer, BufSize);
- end;
- end;
-
- procedure TIniFile.ReadSectionValues(const Section: string; Strings: TStrings);
- var
- KeyList: TStringList;
- I: Integer;
- begin
- KeyList := TStringList.Create;
- try
- ReadSection(Section, KeyList);
- Strings.BeginUpdate;
- try
- for I := 0 to KeyList.Count - 1 do
- Strings.Values[KeyList[I]] := ReadString(Section, KeyList[I], '');
- finally
- Strings.EndUpdate;
- end;
- finally
- KeyList.Free;
- end;
- end;
-
- procedure TIniFile.EraseSection(const Section: string);
- begin
- if not WritePrivateProfileString(PChar(Section), nil, nil,
- PChar(FFileName)) then
- raise Exception.CreateResFmt(@SIniFileWriteError, [FileName]);
- end;
-
- procedure TIniFile.DeleteKey(const Section, Ident: String);
- begin
- WritePrivateProfileString(PChar(Section), PChar(Ident), nil,
- PChar(FFileName));
- end;
-
- procedure TIniFile.UpdateFile;
- begin
- WritePrivateProfileString(nil, nil, nil, PChar(FFileName));
- end;
-
- { TMemIniFile }
-
- constructor TMemIniFile.Create(const FileName: string);
- begin
- inherited Create(FileName);
- FSections := TStringList.Create;
- LoadValues;
- end;
-
- destructor TMemIniFile.Destroy;
- begin
- if FSections <> nil then Clear;
- FSections.Free;
- inherited;
- end;
-
- function TMemIniFile.AddSection(const Section: string): TStrings;
- begin
- Result := TStringList.Create;
- try
- FSections.AddObject(Section, Result);
- except
- Result.Free;
- end;
- end;
-
- procedure TMemIniFile.Clear;
- var
- I: Integer;
- begin
- for I := 0 to FSections.Count - 1 do
- TStrings(FSections.Objects[I]).Free;
- FSections.Clear;
- end;
-
- procedure TMemIniFile.DeleteKey(const Section, Ident: String);
- var
- I, J: Integer;
- Strings: TStrings;
- begin
- I := FSections.IndexOf(Section);
- if I >= 0 then
- begin
- Strings := TStrings(FSections.Objects[I]);
- J := Strings.IndexOfName(Ident);
- if J >= 0 then Strings.Delete(J);
- end;
- end;
-
- procedure TMemIniFile.EraseSection(const Section: string);
- var
- I: Integer;
- begin
- I := FSections.IndexOf(Section);
- if I >= 0 then
- begin
- TStrings(FSections.Objects[I]).Free;
- FSections.Delete(I);
- end;
- end;
-
- procedure TMemIniFile.GetStrings(List: TStrings);
- var
- I, J: Integer;
- Strings: TStrings;
- begin
- List.BeginUpdate;
- try
- for I := 0 to FSections.Count - 1 do
- begin
- List.Add('[' + FSections[I] + ']');
- Strings := TStrings(FSections.Objects[I]);
- for J := 0 to Strings.Count - 1 do List.Add(Strings[J]);
- List.Add('');
- end;
- finally
- List.EndUpdate;
- end;
- end;
-
- procedure TMemIniFile.LoadValues;
- var
- List: TStringList;
- begin
- if (FileName <> '') and FileExists(FileName) then
- begin
- List := TStringList.Create;
- try
- List.LoadFromFile(FileName);
- SetStrings(List);
- finally
- List.Free;
- end;
- end else Clear;
- end;
-
- procedure TMemIniFile.ReadSection(const Section: string;
- Strings: TStrings);
- var
- I, J: Integer;
- SectionStrings: TStrings;
- begin
- Strings.BeginUpdate;
- try
- Strings.Clear;
- I := FSections.IndexOf(Section);
- if I >= 0 then
- begin
- SectionStrings := TStrings(FSections.Objects[I]);
- for J := 0 to SectionStrings.Count - 1 do
- Strings.Add(SectionStrings.Names[J]);
- end;
- finally
- Strings.EndUpdate;
- end;
- end;
-
- procedure TMemIniFile.ReadSections(Strings: TStrings);
- begin
- Strings.Assign(FSections);
- end;
-
- procedure TMemIniFile.ReadSectionValues(const Section: string;
- Strings: TStrings);
- var
- I: Integer;
- begin
- Strings.BeginUpdate;
- try
- Strings.Clear;
- I := FSections.IndexOf(Section);
- if I >= 0 then Strings.Assign(TStrings(FSections.Objects[I]));
- finally
- Strings.EndUpdate;
- end;
- end;
-
- function TMemIniFile.ReadString(const Section, Ident,
- Default: string): string;
- var
- I: Integer;
- Strings: TStrings;
- begin
- I := FSections.IndexOf(Section);
- if I >= 0 then
- begin
- Strings := TStrings(FSections.Objects[I]);
- I := Strings.IndexOfName(Ident);
- if I >= 0 then
- begin
- Result := Copy(Strings[I], Length(Ident) + 2, Maxint);
- Exit;
- end;
- end;
- Result := Default;
- end;
-
- procedure TMemIniFile.Rename(const FileName: string; Reload: Boolean);
- begin
- FFileName := FileName;
- if Reload then LoadValues;
- end;
-
- procedure TMemIniFile.SetStrings(List: TStrings);
- var
- I: Integer;
- S: string;
- Strings: TStrings;
- begin
- Clear;
- Strings := nil;
- for I := 0 to List.Count - 1 do
- begin
- S := List[I];
- if (S <> '') and (S[1] <> ';') then
- if (S[1] = '[') and (S[Length(S)] = ']') then
- Strings := AddSection(Copy(S, 2, Length(S) - 2))
- else
- if Strings <> nil then Strings.Add(S);
- end;
- end;
-
- procedure TMemIniFile.UpdateFile;
- var
- List: TStringList;
- begin
- List := TStringList.Create;
- try
- GetStrings(List);
- List.SaveToFile(FFileName);
- finally
- List.Free;
- end;
- end;
-
- procedure TMemIniFile.WriteString(const Section, Ident, Value: String);
- var
- I: Integer;
- S: string;
- Strings: TStrings;
- begin
- I := FSections.IndexOf(Section);
- if I >= 0 then
- Strings := TStrings(FSections.Objects[I]) else
- Strings := AddSection(Section);
- S := Ident + '=' + Value;
- I := Strings.IndexOfName(Ident);
- if I >= 0 then Strings[I] := S else Strings.Add(S);
- end;
-
- end.
-