home *** CD-ROM | disk | FTP | other *** search
/ Delphi 4 Bible / Delphi_4_Bible_Tom_Swan_IDG_Books_1998.iso / source / Inidata / INIDATA.PAS
Pascal/Delphi Source File  |  1998-02-17  |  7KB  |  270 lines

  1. (*
  2. Demonstrates how to use ini files to save/restore object properties
  3. Copyright (C) 1995, 1998 by Danny Thorpe; All rights reserved.
  4.   Used with permission of the author.
  5. Revised 2/12/1998 by Tom Swan;
  6.   See // comments for original code and new additions
  7. To use:
  8.   1. Add Inidata.Pas to your project
  9.   2. Insert Inidata in a unit's uses directive
  10.   3. Register classes and properties with RegisterINIDataProp
  11.   4. Call this module's SaveData... and LoadData... procedures
  12. *)
  13.  
  14. unit Inidata;
  15.  
  16. interface
  17.  
  18. uses SysUtils, Classes, INIFiles;
  19.  
  20. type
  21.   EINIDataProp = class(Exception);
  22.  
  23. procedure SaveDataToINIFile(Instance: TComponent; const Filename: String);
  24. procedure SaveDataToINI(Instance: TComponent; INI: TINIFile);
  25. procedure SaveDataToStrings(Instance: TComponent; Items: TStrings);
  26.  
  27. procedure LoadDataFromINIFile(Instance: TComponent; const Filename: String);
  28. procedure LoadDataFromINI(Instance: TComponent; INI: TINIFile);
  29. procedure LoadDataFromStrings(Instance: TComponent; Items: TStrings);
  30.  
  31. procedure RegisterINIDataProp(const ClassName, PropName: String);
  32.  
  33. implementation
  34.  
  35. uses TypInfo;
  36.  
  37. const
  38.   INIDataProps: TStringList = nil;
  39.  
  40. procedure RegisterINIDataProp(const ClassName, PropName: String);
  41. var
  42.   X: Integer;
  43. begin
  44.   if INIDataProps = nil then INIDataProps := TStringList.Create;
  45.   for X := 0 to INIDataProps.Count - 1 do
  46.     if CompareText(ClassName, INIDataProps[x]) = 0 then
  47.       raise EINIDataProp.Create(Format('Can''t register %s.%s - %s.%s is already registered',
  48.           [ClassName, PropName, ClassName, PString(INIDataProps.Objects[x])^]));
  49.   INIDataProps.AddObject(ClassName, TObject(NewStr(PropName)));
  50. end;
  51.  
  52. function FindINIDataProp(Instance: TComponent; var PropInfo: PPropInfo): Boolean;
  53. var
  54.   X: Integer;
  55. begin
  56.   Result := False;
  57.   if INIDataProps = nil then Exit;
  58.   for X := 0 to INIDataProps.Count - 1 do
  59.     if CompareText(Instance.ClassName, INIDataProps[x]) = 0 then
  60.     begin
  61.       PropInfo := GetPropInfo(Instance.ClassInfo, PString(INIDataProps.Objects[X])^);
  62.       Result := (PropInfo <> nil) and IsStoredProp(Instance, PropInfo);
  63.       Exit;
  64.     end;
  65. end;
  66.  
  67. type
  68.   TDataFiler = class
  69.     function ReadStr(const Key, Default: String):String; virtual; abstract;
  70.     procedure WriteStr(const Key, Value: String); virtual; abstract;
  71.     function ReadInt(const Key: String; Default: Longint): Longint;
  72.     procedure WriteInt(const Key: String; Value: Longint);
  73.     procedure LoadData(Instance: TComponent);
  74.     procedure SaveData(Instance: TComponent);
  75.   end;
  76.  
  77.   TDataINIFiler = class(TDataFiler)
  78.     FINIFile: TINIFile;
  79.     FSection: String[64];
  80.     constructor Create(INIFile: TINIFile; const Section: String);
  81.     function ReadStr(const Key, Default: String):String; override;
  82.     procedure WriteStr(const Key, Value: String); override;
  83.   end;
  84.  
  85.   TDataStringFiler = class(TDataFiler)
  86.     FStrings: TStrings;
  87.     constructor Create(SList: TStrings);
  88.     function ReadStr(const Key, Default: String):String; override;
  89.     procedure WriteStr(const Key, Value: String); override;
  90.   end;
  91.  
  92. function TDataFiler.ReadInt(const Key: String; Default: Longint): Longint;
  93. begin
  94.   Result := StrToInt(ReadStr(Key, IntToStr(Default)));
  95. end;
  96.  
  97. procedure TDataFiler.WriteInt(const Key: String; Value: Longint);
  98. begin
  99.   WriteStr(Key, IntToStr(Value));
  100. end;
  101.  
  102. procedure TDataFiler.LoadData(Instance: TComponent);
  103. var
  104.   P : TComponent;
  105.   X: Integer;
  106.   PropInfo: PPropInfo;
  107. begin
  108.   for X := 0 to Instance.ComponentCount - 1 do
  109.   begin
  110.     P := Instance.Components[X];
  111.     if (Length(P.Name) > 0) and FindINIDataProp(P, PropInfo) then
  112.       case PropInfo^.PropType^.Kind of
  113. // added following two types
  114.         tkLString, tkWString,
  115.         tkString: SetStrProp(P, PropInfo, ReadStr(P.Name, GetStrProp(P,PropInfo)));
  116.         tkInteger: SetOrdProp(P, PropInfo, ReadInt(P.Name, GetOrdProp(P,PropInfo)));
  117.         tkEnumeration: SetOrdProp(P, PropInfo,
  118. //          GetEnumValue(PropInfo^.PropType,
  119.           GetEnumValue(PropInfo.PropType^,
  120. //          ReadStr(P.Name, GetEnumName(PropInfo^.PropType,
  121.           ReadStr(P.Name, GetEnumName(PropInfo.PropType^,
  122. //          GetOrdProp(P,PropInfo))^)));
  123.           GetOrdProp(P,PropInfo)))));
  124.       end;
  125.   end;
  126. end;
  127.  
  128. procedure TDataFiler.SaveData(Instance: TComponent);
  129. var
  130.   X: Integer;
  131.   P: TComponent;
  132.   PropInfo: PPropInfo;
  133. begin
  134.   for X := 0 to Instance.ComponentCount-1 do
  135.   begin
  136.     P := Instance.Components[x];
  137.     if (Length(P.Name) > 0) and FindINIDataProp(P, PropInfo) then
  138.       case PropInfo^.PropType^.Kind of
  139. // added following two types
  140.         tkLString, tkWString,
  141.         tkString: WriteStr(P.Name, GetStrProp(P,PropInfo));
  142.         tkInteger: WriteInt(P.Name, GetOrdProp(P,PropInfo));
  143.         tkEnumeration: WriteStr(P.Name,
  144. //          GetEnumName(PropInfo^.PropType,
  145.           GetEnumName(PropInfo.PropType^,
  146. //          GetOrdProp(P,PropInfo))^);
  147.           GetOrdProp(P,PropInfo)));
  148.       end;
  149.   end;
  150. end;
  151.  
  152. constructor TDataINIFiler.Create(INIFile: TINIFile; const Section: String);
  153. begin
  154.   FINIFile := INIFile;
  155.   FSection := Section;
  156. end;
  157.  
  158. function TDataINIFiler.ReadStr(const Key, Default: String): String;
  159. begin
  160.   Result := FINIFile.ReadString(FSection, Key, Default);
  161. end;
  162.  
  163. procedure TDataINIFiler.WriteStr(const Key, Value: String);
  164. begin
  165.   FINIFile.WriteString(FSection, Key, Value);
  166. end;
  167.  
  168. constructor TDataStringFiler.Create(SList: TStrings);
  169. begin
  170.   FStrings := SList;
  171. end;
  172.  
  173. function TDataStringFiler.ReadStr(const Key, Default: String): String;
  174. var
  175.   X: Integer;
  176.   P: Integer;
  177. begin
  178.   for X := 0 to FStrings.Count-1 do
  179.   begin
  180.     Result := FStrings[x];
  181.     P := Pos('=',Result);
  182.     if (P <> 0) and (CompareText(Copy(Result, 1, P - 1), Key) = 0) then
  183.     begin
  184.       Result := Copy(Result,P+1,255);
  185.       Exit;
  186.     end;
  187.   end;
  188.   Result := Default;
  189. end;
  190.  
  191. procedure TDataStringFiler.WriteStr(const Key, Value: String);
  192. begin
  193.   FStrings.Values[Key] := Value;
  194. end;
  195.  
  196. procedure SaveDataToINIFile(Instance: TComponent; const FileName: String);
  197. var
  198.   INI: TINIFile;
  199. begin
  200.   INI := TINIFile.Create(Filename);
  201.   try
  202.     SaveDataToINI(Instance, INI);
  203.   finally
  204.     INI.Free;
  205.   end;
  206. end;
  207.  
  208. procedure SaveDataToINI(Instance: TComponent; INI: TINIFile);
  209. var
  210.   Filer: TDataFiler;
  211. begin
  212.   Filer := TDataINIFiler.Create(INI, Instance.Classname);
  213.   try
  214.     Filer.SaveData(Instance);
  215.   finally
  216.     Filer.Free;
  217.   end;
  218. end;
  219.  
  220. procedure SaveDataToStrings(Instance: TComponent; Items: TStrings);
  221. var
  222.   Filer: TDataFiler;
  223. begin
  224.   Filer := TDataStringFiler.Create(Items);
  225.   try
  226.     Filer.SaveData(Instance);
  227.   finally
  228.     Filer.Free;
  229.   end;
  230. end;
  231.  
  232. procedure LoadDataFromINIFile(Instance: TComponent; const Filename: String);
  233. var
  234.   INI: TINIFile;
  235. begin
  236.   INI := TINIFile.Create(Filename);
  237.   try
  238.     LoadDataFromINI(Instance, INI);
  239.   finally
  240.     INI.Free;
  241.   end;
  242. end;
  243.  
  244. procedure LoadDataFromINI(Instance: TComponent; INI: TINIFile);
  245. var
  246.   Filer: TDataFiler;
  247. begin
  248.   Filer := TDataINIFiler.Create(INI, Instance.ClassName);
  249.   try
  250.     Filer.LoadData(Instance);
  251.   finally
  252.     Filer.Free;
  253.   end;
  254. end;
  255.  
  256. procedure LoadDataFromStrings(Instance: TComponent; Items: TStrings);
  257. var
  258.   Filer: TDataFiler;
  259. begin
  260.   Filer := TDataStringFiler.Create(Items);
  261.   try
  262.     Filer.LoadData(Instance);
  263.   finally
  264.     Filer.Free;
  265.   end;
  266. end;
  267.  
  268.  
  269. end.
  270.