📄 inffiles.~pas
字号:
var
P: PHashItem;
begin
P := Find(Key)^;
if P <> nil then
Result := P^.Value else
Result := -1;
end;
{ THashedStringList }
procedure THashedStringList.Changed;
begin
inherited;
FValueHashValid := False;
FNameHashValid := False;
end;
destructor THashedStringList.Destroy;
begin
FValueHash.Free;
FNameHash.Free;
inherited;
end;
function THashedStringList.IndexOf(const S: string): Integer;
begin
UpdateValueHash;
if not CaseSensitive then
Result := FValueHash.ValueOf(AnsiUpperCase(S))
else
Result := FValueHash.ValueOf(S);
end;
function THashedStringList.IndexOfName(const Name: string): Integer;
begin
UpdateNameHash;
if not CaseSensitive then
Result := FNameHash.ValueOf(AnsiUpperCase(Name))
else
Result := FNameHash.ValueOf(Name);
end;
procedure THashedStringList.UpdateNameHash;
var
I: Integer;
P: Integer;
Key: string;
begin
if FNameHashValid then Exit;
if FNameHash = nil then
FNameHash := TStringHash.Create
else
FNameHash.Clear;
for I := 0 to Count - 1 do
begin
Key := Get(I);
P := AnsiPos('=', Key);
if P <> 0 then
begin
if not CaseSensitive then
Key := AnsiUpperCase(Copy(Key, 1, P - 1))
else
Key := Copy(Key, 1, P - 1);
FNameHash.Add(Key, I);
end;
end;
FNameHashValid := True;
end;
procedure THashedStringList.UpdateValueHash;
var
I: Integer;
begin
if FValueHashValid then Exit;
if FValueHash = nil then
FValueHash := TStringHash.Create
else
FValueHash.Clear;
for I := 0 to Count - 1 do
if not CaseSensitive then
FValueHash.Add(AnsiUpperCase(Self[I]), I)
else
FValueHash.Add(Self[I], I);
FValueHashValid := True;
end;
{ TMemIniFile }
constructor TMemIniFile.Create(const FileName: string);
begin
inherited Create(FileName);
FSections := THashedStringList.Create;
{$IFDEF LINUX}
FSections.CaseSensitive := True;
{$ENDIF}
LoadValues;
end;
destructor TMemIniFile.Destroy;
begin
if FSections <> nil then Clear;
FSections.Free;
inherited;
end;
function TMemIniFile.AddSection(const Section: string): TStrings;
begin
Result := THashedStringList.Create;
try
THashedStringList(Result).CaseSensitive := CaseSensitive;
FSections.AddObject(Section, Result);
except
Result.Free;
raise;
end;
end;
procedure TMemIniFile.Clear;
var
I: Integer;
begin
for I := 0 to FSections.Count - 1 do
TObject(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;
function TMemIniFile.GetCaseSensitive: Boolean;
begin
Result := FSections.CaseSensitive;
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.SetCaseSensitive(Value: Boolean);
begin
FSections.CaseSensitive := Value;
end;
procedure TMemIniFile.SetStrings(List: TStrings);
var
I, J: Integer;
S: string;
Strings: TStrings;
begin
Clear;
Strings := nil;
for I := 0 to List.Count - 1 do
begin
S := Trim(List[I]);
if (S <> '') and (S[1] <> ';') then
if (S[1] = '[') and (S[Length(S)] = ']') then
begin
Delete(S, 1, 1);
SetLength(S, Length(S)-1);
Strings := AddSection(Trim(S));
end
else
if Strings <> nil then
begin
J := Pos('=', S);
if J > 0 then // remove spaces before and after '='
Strings.Add(Trim(Copy(S, 1, J-1)) + '=' + Trim(Copy(S, J+1, MaxInt)) )
else
Strings.Add(S);
end;
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;
{$IFDEF MSWINDOWS}
{ TIniFile }
destructor TIniFile.Destroy;
begin
UpdateFile; // flush changes to disk
inherited Destroy;
end;
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 EIniFileException.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
Strings.Clear;
for I := 0 to KeyList.Count - 1 do
Strings.Add(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 EIniFileException.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;
{$ENDIF}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -