V1s1ter
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору DmitryKz В библиотеке EhLib есть TPropStorageEh. В библиотеке DevExpress есть TPropertiesStore. Ну и я когдато на заре писал? удобно, чем, что: - легко расширяется - не требует подробных указаний, что именно сохранять. Код: unit VIniValue; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TIniOption = (ioFormCoordinate, ioGridWidth, ioEditValue); TSetIniOptions = set of TIniOption; TVIniValue = class(TComponent) private FormOnCreate : TNotifyEvent; FormOnDestroy: TNotifyEvent; FIniFileName: String; FAutomatic: Boolean; FIniOptions: TSetIniOptions; procedure NewFormOnCreate(Sender : TObject); procedure NewFormOnDestroy(Sender : TObject); procedure SetIniFileName(const Value: String); protected procedure Loaded; override; public constructor Create(AOwner: TComponent); override; procedure Load; procedure Save; published property Automatic: Boolean read FAutomatic write FAutomatic default True; property IniFileName: String read FIniFileName write SetIniFileName; property IniOptions: TSetIniOptions read FIniOptions write FIniOptions; end; procedure Register; implementation uses TypInfo, IniFiles, VVCLUtl, VStrUtl; procedure Register; begin RegisterComponents('Victory Common', [TVIniValue]); end; { TVIniValue } constructor TVIniValue.Create(AOwner: TComponent); begin inherited Create(AOwner); FAutomatic := True; end; procedure TVIniValue.Loaded; function EqualAddr(Addr1, Addr2: TNotifyEvent): Boolean; begin Result := CompareMem(@TMethod(Addr1), @TMethod(Addr2), 8); end; begin inherited Loaded; if not (csDesigning in ComponentState) then begin if FIniFileName = '' then FIniFileName := Name; FIniFileName := ExtractFilePath(ParamStr(0)) + FIniFileName; if FAutomatic and (Owner is TForm) and not EqualAddr((Owner as TForm).OnCreate, NewFormOnCreate) then begin FormOnCreate := (Owner as TForm).OnCreate; (Owner as TForm).OnCreate := NewFormOnCreate; FormOnDestroy := (Owner as TForm).OnDestroy; (Owner as TForm).OnDestroy := NewFormOnDestroy; end; end; end; procedure TVIniValue.NewFormOnCreate(Sender: TObject); begin if Assigned(FormOnCreate) then FormOnCreate(Self); if FAutomatic then Load; end; procedure TVIniValue.NewFormOnDestroy(Sender: TObject); begin if FAutomatic then Save; if Assigned(FormOnDestroy) then FormOnDestroy(Self); end; procedure TVIniValue.Load; var IniFile: TIniFile; Prop : PPropInfo; i,j,V: Integer; s: String; begin IniFile := TIniFile.Create(IniFileName); try if ioFormCoordinate in IniOptions then begin V := IniFile.ReadInteger(Owner.Name, 'FormTop', -1); if V <> -1 then TForm(Owner).Top := V; V := IniFile.ReadInteger(Owner.Name, 'FormLeft', -1); if V <> -1 then TForm(Owner).Left := V; V := IniFile.ReadInteger(Owner.Name, 'FormHeight', -1); if V <> -1 then TForm(Owner).Height := V; V := IniFile.ReadInteger(Owner.Name, 'FormWidth', -1); if V <> -1 then TForm(Owner).Width := V; V := IniFile.ReadInteger(Owner.Name, 'WindowState', -1); if (TForm(Owner).FormStyle <> fsMDIChild) and (V <> -1) and TWinControl(Owner).Showing then TForm(Owner).WindowState := TWindowState(V); end; for i := 0 to Owner.ComponentCount -1 do begin if ioEditValue in IniOptions then begin Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Text'); if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then begin s := GetStrProp(Owner.Components[i], Prop); SetStrProp(Owner.Components[i], Prop, IniFile.ReadString(Owner.Name,Owner.Components[i].Name,s)); end; Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Value'); if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then begin s := GetStrProp(Owner.Components[i], Prop); SetStrProp(Owner.Components[i], Prop, IniFile.ReadString(Owner.Name,Owner.Components[i].Name,s)); end; if (Prop <> nil) and (Prop^.PropType^.Kind = tkInteger) then begin j := GetOrdProp(Owner.Components[i], Prop); SetOrdProp(Owner.Components[i], Prop, IniFile.ReadInteger(Owner.Name,Owner.Components[i].Name,j)); end; Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Checked'); if (Prop <> nil) then begin j := GetOrdProp(Owner.Components[i], Prop); SetOrdProp(Owner.Components[i], Prop, Ord(IniFile.ReadBool(Owner.Name,Owner.Components[i].Name,Boolean(j)))); end; end; end; finally IniFile.Free; end; end; procedure TVIniValue.Save; var IniFile: TIniFile; Prop : PPropInfo; i: Integer; WS: TWindowState; begin IniFile := TIniFile.Create(IniFileName); try if ioFormCoordinate in IniOptions then begin WS := TForm(Owner).WindowState; if TForm(Owner).WindowState <> wsNormal then TForm(Owner).WindowState := wsNormal; IniFile.WriteInteger(Owner.Name, 'FormTop', TForm(Owner).Top); IniFile.WriteInteger(Owner.Name, 'FormLeft', TForm(Owner).Left); IniFile.WriteInteger(Owner.Name, 'FormHeight', TForm(Owner).Height); IniFile.WriteInteger(Owner.Name, 'FormWidth', TForm(Owner).Width); IniFile.WriteInteger(Owner.Name, 'WindowState', Integer(WS)); TForm(Owner).WindowState := WS; end; for i := 0 to Owner.ComponentCount -1 do begin if ioEditValue in IniOptions then begin Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Text'); if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then IniFile.WriteString(Owner.Name,Owner.Components[i].Name,GetStrProp(Owner.Components[i], Prop)); Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Value'); if (Prop <> nil) and (Prop^.PropType^.Kind in [tkString,tkLString,tkWString]) then IniFile.WriteString(Owner.Name,Owner.Components[i].Name,GetStrProp(Owner.Components[i], Prop)); if (Prop <> nil) and (Prop^.PropType^.Kind = tkInteger) then IniFile.WriteInteger(Owner.Name,Owner.Components[i].Name,GetOrdProp(Owner.Components[i], Prop)); Prop := GetPropInfo(Owner.Components[i].ClassInfo, 'Checked'); if (Prop <> nil) then IniFile.WriteBool(Owner.Name,Owner.Components[i].Name,Boolean(GetOrdProp(Owner.Components[i], Prop))); end; end; finally IniFile.Free; end; end; procedure TVIniValue.SetIniFileName(const Value: String); var S: String; begin FIniFileName := Value; S := Copy(FIniFileName, Length(FIniFileName)-4, 4); S := AnsiLowerCase(S); if S <> '.ini' then FIniFileName := FIniFileName+'.ini'; end; end. | |