unit ConfigOptions; interface uses SysUtils, Classes, Contnrs, TypInfo, Graphics, Controls, Forms, StdCtrls, ExtCtrls, Buttons; type TOptionControl = class; TOptionList = class(TObject) private FItems: TObjectList; function GetCount: Integer; function GetItem(Index: Integer): TOptionControl; public constructor Create; destructor Destroy; override; function Add(AOption: TOptionControl): TOptionControl; property Count: Integer read GetCount; property Items[Index: Integer]: TOptionControl read GetItem; default; end; TOptionControl = class(TObject) public function CreateControl: TControl; virtual; abstract; end; TOptionSpacer = class(TOptionControl) public function CreateControl: TControl; override; end; TOptionFrame = class(TOptionControl) private FFrame: TFrame; public constructor Create(AFrame: TFrame); function CreateControl: TControl; override; end; TOption = class(TOptionControl) private FPropName: string; FInstance: TObject; FInfo: PPropInfo; FCaption: string; FHint: string; function GetAsFloat: Double; function GetAsInteger: Integer; function GetAsString: string; procedure SetAsFloat(const Value: Double); procedure SetAsInteger(const Value: Integer); procedure SetAsString(const Value: string); function GetAsBoolean: Boolean; procedure SetAsBoolean(const Value: Boolean); public constructor Create(AInstance: TObject; const APropName, ACaption, AHint: string); property AsString: string read GetAsString write SetAsString; property AsInteger: Integer read GetAsInteger write SetAsInteger; property AsFloat: Double read GetAsFloat write SetAsFloat; property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; property Instance: TObject read FInstance; property PropName: string read FPropName; property Caption: string read FCaption; property Hint: string read FHint; end; TOptionCheckBox = class(TOption) private procedure EvClick(Sender: TObject); public function CreateControl: TControl; override; end; { TOptionGroup = class(TOptionControl) end; TOptionRadioButton = class(TOption) end; TOptionEdit = class(TOption) end;} TOptionDirectoryEdit = class(TOption) public function CreateControl: TControl; override; end; { TOptionDropDown = class(TOption) end; TOptionDropDownList = class(TOptionDropDown) end; TOptionButton = class(TOption) end; TOptionCheckListBox = class(TOption) end;} EOptionError = class(Exception); implementation uses InstallerConsts, FrmeDirectoryEdit; procedure InvalidOption(const PropName: string); begin raise EOptionError.CreateFmt(RsInvalidOptionProperty, [PropName]); end; { TOptionList } constructor TOptionList.Create; begin inherited Create; FItems := TObjectList.Create; end; destructor TOptionList.Destroy; begin FItems.Free; inherited Destroy; end; function TOptionList.GetCount: Integer; begin Result := FItems.Count; end; function TOptionList.GetItem(Index: Integer): TOptionControl; begin Result := TOptionControl(FItems[Index]); end; function TOptionList.Add(AOption: TOptionControl): TOptionControl; begin FItems.Add(AOption); Result := AOption; end; { TOption } constructor TOption.Create(AInstance: TObject; const APropName, ACaption, AHint: string); begin inherited Create; FInstance := AInstance; FPropName := APropName; FInfo := GetPropInfo(Instance, PropName); if not Assigned(FInfo) then InvalidOption(PropName); FCaption := ACaption; FHint := AHint; end; function TOption.GetAsInteger: Integer; begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: Result := GetOrdProp(Instance, FInfo); tkString, tkLString: Result := StrToInt(GetStrProp(Instance, FInfo)); tkFloat: Result := Trunc(GetFloatProp(Instance, FInfo)); tkWString: Result := StrToInt(GetWideStrProp(Instance, FInfo)); else InvalidOption(PropName); Result := 0; end; end; procedure TOption.SetAsInteger(const Value: Integer); begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: SetOrdProp(Instance, FInfo, Value); tkString, tkLString: SetStrProp(Instance, FInfo, IntToStr(Value)); tkFloat: SetFloatProp(Instance, FInfo, Value); tkWString: SetWideStrProp(Instance, FInfo, IntToStr(Value)); else InvalidOption(PropName); end; end; function TOption.GetAsFloat: Double; begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: Result := GetOrdProp(Instance, FInfo); tkString, tkLString: Result := StrToFloat(GetStrProp(Instance, FInfo)); tkFloat: Result := GetFloatProp(Instance, FInfo); tkWString: Result := StrToFloat(GetWideStrProp(Instance, FInfo)); else InvalidOption(PropName); Result := 0; end; end; procedure TOption.SetAsFloat(const Value: Double); begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: SetOrdProp(Instance, FInfo, Trunc(Value)); tkString, tkLString: SetStrProp(Instance, FInfo, FloatToStr(Value)); tkFloat: SetFloatProp(Instance, FInfo, Value); tkWString: SetWideStrProp(Instance, FInfo, FloatToStr(Value)); else InvalidOption(PropName); end; end; function TOption.GetAsString: string; begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: Result := IntToStr(GetOrdProp(Instance, FInfo)); tkString, tkLString: Result := GetStrProp(Instance, FInfo); tkFloat: Result := FloatToStr(GetFloatProp(Instance, FInfo)); tkWString: Result := GetWideStrProp(Instance, FInfo); else InvalidOption(PropName); Result := ''; end; end; procedure TOption.SetAsString(const Value: string); begin case FInfo.PropType^.Kind of tkInteger, tkChar, tkEnumeration, tkWChar: SetOrdProp(Instance, FInfo, StrToInt(Value)); tkString, tkLString: SetStrProp(Instance, FInfo, Value); tkFloat: SetFloatProp(Instance, FInfo, StrToFloat(Value)); tkWString: SetWideStrProp(Instance, FInfo, Value); else InvalidOption(PropName); end; end; function TOption.GetAsBoolean: Boolean; begin Result := Boolean(AsInteger); end; procedure TOption.SetAsBoolean(const Value: Boolean); begin AsInteger := Integer(Value); end; { TOptionSpacer } function TOptionSpacer.CreateControl: TControl; begin Result := TPanel.Create(nil); with TPanel(Result) do begin Height := 20; Caption := ''; BevelInner := bvNone; BevelOuter := bvNone; end; end; { TOptionFrame } constructor TOptionFrame.Create(AFrame: TFrame); begin inherited Create; FFrame := AFrame; end; function TOptionFrame.CreateControl: TControl; begin Result := FFrame; end; { TOptionDirectoryEdit } function TOptionDirectoryEdit.CreateControl: TControl; var Frame: TFrameDirectoryEdit; begin Frame := TFrameDirectoryEdit.Create(nil); Frame.Option := Self; Result := Frame; end; { TOptionCheckBox } function TOptionCheckBox.CreateControl: TControl; var cbx: TCheckBox; begin cbx := TCheckBox.Create(nil); cbx.Caption := Caption; cbx.Hint := Hint; cbx.ShowHint := Hint <> ''; cbx.OnClick := EvClick; cbx.Checked := AsBoolean; Result := cbx; end; procedure TOptionCheckBox.EvClick(Sender: TObject); begin AsBoolean := (Sender as TCheckBox).Checked; end; end.