WinSkinIni.pas
上传用户:xjwsee
上传日期:2008-08-02
资源大小:796k
文件大小:14k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit WinSkinIni;
  2. {$B-}
  3. interface
  4. uses Classes,winconvert;
  5. type
  6. { TQuickIni class }
  7.   TQuickIni = class(TObject)
  8.   private
  9.     FAuto : boolean;
  10.     FFileName: String;
  11.     FIniFile : TStrings;
  12.     function GetName(const Line: String): String;
  13.     function GetValue(const Line, Name: String): String;
  14.     function GetSectionIndex(const Section: String): Integer;
  15.     function IsSection(const Line: String): Boolean;
  16.     procedure SetFileName(Value: string);
  17.     procedure SetIniFile(Value: TStrings);
  18.   protected
  19.     FSections: TStrings;
  20.     procedure Compress(source,dest:TStream);
  21.     procedure Decompress(source,Dest:TStream);
  22.   public
  23.     constructor Create;
  24.     destructor Destroy; override;
  25.     procedure LoadFromFile(aname:string);
  26.     procedure SaveToFile(aname:string);
  27.     procedure LoadFromStream(Stream: TStream);
  28.     procedure SaveToStream(Stream:Tstream);
  29.     procedure LoadFromZip(aname:string);
  30.     procedure SavetoZip(aname:string);
  31.     procedure DeleteKey(const Section, Ident: String);
  32.     procedure EraseSection(const Section: String);
  33.     function ReadBool(const Section, Ident: String; Default: Boolean): Boolean;
  34.     function ReadInteger(const Section, Ident: String; Default: Longint): Longint;
  35.     procedure ReadSection(const Section: AnsiString; Strings: TStrings);
  36.     procedure ReadSections(Strings: TStrings);
  37.     procedure ReadSectionValues(const Section: String; Strings: TStrings);
  38.     function ReadString(const Section, Ident: AnsiString; Default: AnsiString): AnsiString;
  39.     procedure RebuildSections;
  40.     procedure WriteBool(const Section, Ident: String; Value: Boolean);
  41.     procedure WriteInteger(const Section, Ident: String; Value: Longint);
  42.     procedure WriteString(const Section, Ident: String; Value: String);
  43.     property FileName: String read FFileName write SetFileName;
  44.     property AutoSaveLoad: boolean read FAuto write FAuto;
  45.     property IniFile: TStrings read FIniFile write SetIniFile;
  46.     procedure Clear;
  47.   end;
  48. implementation
  49. uses SysUtils;
  50. const
  51.   SStringsUnassignedError = 'The parameter Strings is unassigned!';
  52.   StartBracket = '[';
  53.   EndBracket   = ']';
  54.   Separator    = '=';
  55. { TQuickIni }
  56. constructor TQuickIni.Create;
  57. begin
  58.   FAuto := False;
  59.   FIniFile := TStringList.Create;
  60.   FSections := TStringList.Create;
  61. //  if FileExists(FileName) then
  62. //    LoadFromFile;
  63. end;
  64. destructor TQuickIni.Destroy;
  65. begin
  66.   FSections.Free;
  67.   FIniFile.Free;
  68. //  Finalize(FFileName);
  69. end;
  70. function TQuickIni.GetName(const Line: String): String;
  71. var
  72.   I: Integer;
  73. begin
  74.   I := Pos(Separator, Line);
  75.   if I <> 0 then
  76.     Result := Trim(Copy(Line, 1, I-1))
  77.   else
  78.     Result := EmptyStr;
  79.   result:=lowercase(result);
  80. end;
  81. function TQuickIni.GetValue(const Line, Name: String): String;
  82. var
  83.   I: Integer;
  84. begin
  85.   Result := EmptyStr;
  86.   if (Line <> EmptyStr) and (Name <> EmptyStr) then
  87.   begin
  88.     I := Pos(Separator, Line);
  89.     if (Name = GetName(Line)) and (I <> 0) then
  90.       Result := Trim(System.Copy(Line, I+1, Maxint));
  91.   end;
  92. end;
  93. function TQuickIni.IsSection(const Line: String): Boolean;
  94. var
  95.   S: String;
  96. begin
  97.   Result := False;
  98.   if Line <> EmptyStr then
  99.   begin
  100.     S := Trim(Line);
  101.     if (S[1] = StartBracket) and (S[System.Length(S)] = EndBracket) then
  102.       Result := True;
  103.   end;
  104. end;
  105. function TQuickIni.GetSectionIndex(const Section: String): Integer;
  106. begin
  107.   Result := FSections.IndexOf(StartBracket + Section + EndBracket);
  108.   if Result >= 0 then
  109.     Result := Integer(FSections.Objects[Result])
  110.   else
  111.     Result := -1;  
  112. end;
  113. procedure TQuickIni.Decompress(source,Dest:TStream);
  114. var
  115.    LZH: TLZH;
  116.    Size, Bytes: Longint;
  117. begin
  118.     // Decompress in memory blob.
  119.     LZH := TLZH.Create;
  120.     try
  121.        LZH.StreamIn:= source;
  122.        LZH.StreamOut:=dest;
  123.        LZH.StreamIn.Position := 0;
  124.        LZH.StreamOut.Position := 0;
  125.        // Uncompressed file size
  126.        LZH.StreamIn.Read(size, sizeof(Longint));
  127.        Bytes := Size;
  128.        // Decompress rest of stream.
  129.        LZH.LZHUnpack(Bytes, LZH.GetBlockStream, LZH.PutBlockStream);
  130.     finally
  131.        LZH.Free;
  132.     end;
  133. end;
  134. procedure TQuickIni.compress(source,dest:TStream);
  135. var
  136.    LZH: TLZH;
  137.    Size, Bytes: Longint;
  138. begin
  139.     // Decompress in memory blob.
  140.     LZH := TLZH.Create;
  141.     try
  142.         LZH.StreamIn := Source;
  143.         LZH.StreamOut := dest;
  144.         LZH.StreamIn.Position := 0;
  145.         LZH.StreamOut.Position := 0;
  146.         //write uncompressed size
  147.         Size := LZH.StreamIn.Size;
  148.         LZH.StreamOut.Write(Size, sizeof(Longint));
  149.         // Compress stream.
  150.         LZH.LZHPack(Bytes, LZH.GetBlockStream, LZH.PutBlockStream);
  151.     finally
  152.        LZH.Free;
  153.     end;
  154. end;
  155. procedure TQuickIni.LoadFromZip(aname:string);
  156. var
  157.   r,r2: TMemoryStream;
  158. begin
  159.     r:=Tmemorystream.create;
  160.     r2:=Tmemorystream.create;
  161.     try
  162.        r2.loadfromfile(aname);
  163.        Decompress(r2,r);
  164.        r.Seek(0,soFromBeginning);
  165.        loadfromstream(r);
  166.     finally
  167.        r.free;
  168.        r2.free;
  169.     end;
  170. end;
  171. procedure TQuickIni.SavetoZip(aname:string);
  172. var
  173.   m,m2: TMemoryStream;
  174. begin
  175.    m:=Tmemorystream.create;
  176.    m2:=Tmemorystream.create;
  177.    try
  178.      savetostream(m);
  179.      compress(m,m2);
  180.      m2.savetofile(aname);
  181.    finally
  182.      m.free;
  183.      m2.free;
  184.    end;
  185. end;
  186. procedure TQuickIni.LoadFromFile(aname:string);
  187. var
  188.   Stream: TStream;
  189.   Ptr, Start: PChar;
  190.   StmStr,Str: string;
  191.   Size : integer;
  192.   I : integer;
  193. begin
  194.   Stream := TFileStream.Create(aname, fmOpenRead or fmShareDenyWrite);
  195.   LoadFromStream(Stream);
  196.   Stream.Free;
  197. end;
  198. procedure TQuickIni.LoadFromStream(Stream: TStream);
  199. var
  200.   Ptr, Start: PAnsiChar;
  201.   StmStr,Str: Ansistring;
  202.   Size : integer;
  203.   I : integer;
  204. begin
  205.   if not assigned(Stream) then exit;
  206.   FIniFile.BeginUpdate;
  207.   FSections.BeginUpdate;
  208.   try
  209.     Size := Stream.Size - Stream.Position;
  210.     SetString(StmStr, nil, Size);
  211.     Stream.Read(Pointer(StmStr)^, Size);
  212.     FIniFile.Clear;
  213.     FSections.Clear;
  214.     Ptr := Pointer(StmStr);
  215.     I := 0;
  216.     if Ptr <> nil then
  217.       while Ptr^ <> #0 do
  218.       begin
  219.         Start := Ptr;
  220.         while not (Ptr^ in [#0, #10, #13]) do
  221.           Inc(Ptr);
  222.         SetString(Str, Start, Ptr - Start);
  223.         Str := Trim(Str);
  224.         if (Str <> '') and (Str[1] <> ';') then
  225.         begin
  226.           FIniFile.Add(Str);
  227.           if (Str[1] = '[') and (Str[Length(Str)] = ']') then
  228.           begin
  229.             FSections.AddObject(Trim(Str),TObject(I));
  230.           end;
  231.           inc(I);
  232.         end;
  233.         if Ptr^ = #13 then Inc(Ptr);
  234.         if Ptr^ = #10 then Inc(Ptr);
  235.       end;
  236.   finally
  237.     FSections.EndUpdate;
  238.     FIniFile.EndUpdate;
  239.   end;
  240. end;
  241. procedure TQuickIni.SaveToFile(aname:string);
  242. begin
  243. //  if AutoSaveLoad then
  244.     FIniFile.SaveToFile(aname);
  245. end;
  246. procedure TQuickIni.SaveToStream(Stream:Tstream);
  247. begin
  248. //  if AutoSaveLoad then
  249.     if assigned(stream) then
  250.     FIniFile.SaveTostream(stream);
  251. end;
  252. { Read all Names of one Section }
  253. procedure TQuickIni.ReadSection(const Section: AnsiString; Strings: TStrings);
  254. var
  255.   I: Integer;
  256.   N: String;
  257. begin
  258.   Assert(Assigned(Strings), SStringsUnassignedError);
  259.   Strings.BeginUpdate;
  260.   try
  261.     Strings.Clear;
  262.     if FIniFile.Count > 0 then
  263.     begin
  264.       I := GetSectionIndex(Section);
  265.       if I <> -1 then
  266.       begin
  267.         Inc(I);
  268.         while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
  269.         begin
  270.           N := GetName(FIniFile[I]);
  271.           if N <> EmptyStr then Strings.Add(N);
  272.           Inc(I);
  273.         end;
  274.       end;
  275.     end;
  276.   finally
  277.     Strings.EndUpdate;
  278.   end;
  279. end;
  280. { Read all Sections of the Ini-File }
  281. procedure TQuickIni.ReadSections(Strings: TStrings);
  282. var
  283.   I: Integer;
  284.   Section: String;
  285. begin
  286.   Assert(Assigned(Strings), SStringsUnassignedError);
  287.   Strings.Assign(FSections);
  288.   I := 0;
  289.   while I < Strings.Count do
  290.   begin
  291.     Strings.Objects[I] := Nil;
  292.     Section := Trim(Strings.Strings[I]);
  293.     System.Delete(Section, 1, 1);
  294.     System.Delete(Section, System.Length(Section), 1);
  295.     Strings.Strings[I] := Trim(Section);
  296.     Inc(I);
  297.   end;
  298. end;
  299. { Reads a String-Value of Ident in one Section.
  300.   The result is Default if
  301.   o Section doesn't exists
  302.   o Ident doesn't exists
  303.   o Ident doesn't have any assigned value }
  304. function TQuickIni.ReadString(const Section, Ident: AnsiString; Default: AnsiString): AnsiString;
  305. var
  306.   I: Integer;
  307.   V,s: AnsiString;
  308. begin
  309.   Result := Default;
  310.   s:=lowercase(ident);
  311.   if FIniFile.Count > 0 then
  312.   begin
  313.     I := GetSectionIndex(Section);
  314.     if I <> -1 then
  315.     begin
  316.       Inc(I);
  317.       while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
  318.       begin
  319.         if GetName(FIniFile[I]) = s then
  320.         begin
  321.           V := GetValue(FIniFile[I], s);
  322.           if V <> EmptyStr then
  323.             Result := V;
  324.           break;
  325.         end;
  326.         Inc(I);
  327.       end;
  328.     end;
  329.   end;
  330. end;
  331. { Reads an Integer-Value of Ident in one Section }
  332. function TQuickIni.ReadInteger(const Section, Ident: String; Default: Longint): Longint;
  333. var
  334.   IntStr: ansistring;
  335. begin
  336.   IntStr := ReadString(Section, Ident, '');
  337.   // convert a Hex-Value
  338.   if (Length(IntStr) > 2) and (IntStr[1] = '0') and ((IntStr[2] = 'X') or (IntStr[2] = 'x')) then
  339.     IntStr := '$' + System.Copy(IntStr, 3, Maxint);
  340.   Result := StrToIntDef(IntStr, Default);
  341. end;
  342. { Reads a Bool-Value of Ident in one Section }
  343. function TQuickIni.ReadBool(const Section, Ident: String; Default: Boolean): Boolean;
  344. begin
  345.   Result := ReadInteger(Section, Ident, Ord(Default)) <> 0;
  346. end;
  347. { Reads all Names + Values of one Section }
  348. procedure TQuickIni.ReadSectionValues(const Section: String; Strings: TStrings);
  349. var
  350.   I: Integer;
  351. begin
  352.   Assert(Assigned(Strings), SStringsUnassignedError);
  353.   Strings.BeginUpdate;
  354.   try
  355.     Strings.Clear;
  356.     if FIniFile.Count > 0 then
  357.     begin
  358.       I := GetSectionIndex(Section);
  359.       if I <> -1 then
  360.       begin
  361.         Inc(I);
  362.         while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
  363.         begin
  364.           if (FIniFile[I] <> '') then
  365.             Strings.Add(FIniFile[I]);
  366.           Inc(I);
  367.         end;
  368.       end;
  369.     end;
  370.   finally
  371.     Strings.EndUpdate;
  372.   end;
  373. end;
  374. { Writes a String-Value for Ident in one Section.
  375.   Note: If Section and/or Ident don't exist, they will be placed in the Ini-File }
  376. procedure TQuickIni.WriteString(const Section, Ident: String; Value: String);
  377. var
  378.   I: Integer;
  379.   Q : integer;
  380.   s:string;
  381. begin
  382.   I := GetSectionIndex(Section);
  383.   s:=lowercase(ident);
  384.   // Section exists
  385.   if I >= 0 then
  386.   begin
  387.     Inc(I);
  388.     while (I < FIniFile.Count) and not IsSection(FIniFile[I])
  389.       and (GetName(FIniFile[I]) <> s) do
  390.     begin
  391.       Inc(I);
  392.     end;
  393.     // End of File or Ident doesn't exists in the Section
  394.     if (I >= FIniFile.Count) then
  395.     begin
  396.       if Ident <> EmptyStr then
  397.       begin
  398.         FIniFile.Add(Ident + Separator + Value);
  399.       end
  400.     end
  401.     else if (I < FIniFile.Count) and IsSection(FIniFile[I]) then
  402.     begin
  403.       if Ident <> EmptyStr then
  404.       begin
  405.         FIniFile.Insert(I,Ident + Separator + Value);
  406.         Inc(I);
  407.         Q := FSections.IndexOf(FIniFile[I]);
  408.         FSections.Objects[Q] := TObject(I+1);
  409.       end
  410.     end
  411.     // Ident does exists in the section
  412.     else if Ident <> EmptyStr then
  413.     begin
  414.       FIniFile[I] := Ident + Separator + Value;
  415.     end;
  416.   end
  417.   // Section doesn't exists, so add new [Section] with Ident=Value
  418.   else
  419.   begin
  420.     I := FIniFile.Add(StartBracket + Section + EndBracket);
  421.     FSections.AddObject(StartBracket + Section + EndBracket,TObject(I));
  422.     if Ident <> EmptyStr then
  423.     begin
  424.       FIniFile.Add(Ident + Separator + Value);
  425.     end;
  426.   end;
  427. //  SaveToFile;
  428. end;
  429. { Writes an Integer-Value for Ident in one Section }
  430. procedure TQuickIni.WriteInteger(const Section, Ident: String; Value: Longint);
  431. begin
  432.   WriteString(Section, Ident, IntToStr(Value));
  433. end;
  434. { Writes a Bool-Value for Ident in one Section }
  435. procedure TQuickIni.WriteBool(const Section, Ident: String; Value: Boolean);
  436. const
  437.   Values: array[Boolean] of string = ('0', '1');
  438. begin
  439.   WriteString(Section, Ident, Values[Value]);
  440. end;
  441. { Deletes the Value of Ident in one Section.
  442.   Note: Only if Section and Ident exist, the Value of Ident will be set to NULL }
  443. procedure TQuickIni.DeleteKey(const Section, Ident: String);
  444. var
  445.   I: Integer;
  446. begin
  447.   I := GetSectionIndex(Section);
  448.   if I <> -1 then
  449.   begin
  450.     Inc(I);
  451.     while (I < FIniFile.Count) and not IsSection(FIniFile[I]) and
  452.       (GetName(FIniFile[I]) <> Ident) do Inc(I);
  453.     // Ident does exists  
  454.     if not (I >= FIniFile.Count) and not IsSection(FIniFile[I]) then
  455.     begin
  456.       FIniFile.Delete(I);
  457. //      SaveToFile;
  458.     end;  
  459.   end;
  460. end;
  461. procedure TQuickIni.EraseSection(const Section: String);
  462. var
  463.   I: Integer;
  464. begin
  465.   I := GetSectionIndex(Section);
  466.   if I <> -1 then
  467.   begin
  468.     // Delete Section-Header
  469.     FIniFile.Delete(I);
  470.     // Delete Section-Items
  471.     while (I < FIniFile.Count) and not IsSection(FIniFile[I]) do
  472.       FIniFile.Delete(I);
  473.     if I > 0 then FIniFile.Insert(I, EmptyStr);  
  474. //    SaveToFile;
  475.   end;
  476. end;
  477. procedure TQuickIni.SetFileName(Value: string);
  478. begin
  479.   if Value <> FFileName then
  480.   begin
  481.     FFileName := Value;
  482. //    if FileExists(Value) and FAuto then
  483. //      LoadFromFile;
  484.   end;
  485. end;
  486. procedure TQuickIni.SetIniFile(Value: TStrings);
  487. begin
  488.   FIniFile.Assign(Value);
  489.   RebuildSections;
  490. end;
  491. procedure TQuickIni.RebuildSections;
  492. Var
  493.   I : integer;
  494.   Count : integer;
  495. begin
  496.   FSections.Clear;
  497.   I := 0;
  498.   Count := FIniFile.Count;
  499.   while I < Count do
  500.   begin
  501.     if (FIniFile[I] <> '') and (FIniFile[I][1] = '[') and (FIniFile[I][Length(FIniFile[I])] = ']') then
  502.     begin
  503.       if assigned(FSections) then
  504.         FSections.AddObject(Trim(FIniFile[I]),TObject(I));
  505.     end;
  506.     inc(I);
  507.   end;
  508. end;
  509. procedure TQuickIni.Clear;
  510. begin
  511.   FIniFile.Clear;
  512.   FSections.Clear;
  513. end;
  514. end.