{------------------------------------------------------------------------------} { Unit Name: IniPara Purpose : General purpose parameter f.ex base class for Modbus-parameters Author : Vesa Lappalainen Date : 30.12.1996 Changes: 31.12.1996 + puuttuvia osia 28.03.1997 + translation to file .ktr to speed up reading 23.08.1997 + WriteValueNoSave + try-except to SaveValue -function 08.02.2003 + Lisätty FCName TParamValue:lle. Systeemi perustuu yksinomaan indeksoituihin parametreihin kuten n001..n0xx. Jos perittävä systeemi tarvitseekin kommunikoinnissa muuta nimeä, se voidaan määritellä tällä = cn initiedostossa. Oletuksena CName=Name. 13.09.2003 + noread : boolean to WriteFunction TParamValue is a paramter that can read the behavior from two inifiles: 1) The way to display the param and ranges 2) The current value for the param When inherited it can be made to read some physical device, like from Modbus register. TParamList keeps a list of TParamValue. The list can display itself in a form that can be edited. ToDo : One example hierarcy ===================== 0-n TParamValue -----<> TParamList IniPara.pas | ^ | 1 | ------------ | |----TKParamList | | ^ | TComponent | | ^ | ---<>TParams KParams.pas | ^ ------------ | | YasParamValue TYasParams KYasPar.pas * | TModBus --- } {------------------------------------------------------------------------------} unit IniPara; interface {$define TRANS } uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,inifiles, ExtCtrls, kComp, KParam, Grids, kdouble, erotaind, ComCtrls, kbar, savepos, kinicomp, ksplitter; const Param_OK_String = 'Write OK!'; type PComponent = ^TComponent; type NameString = String[10]; type {----------------------------------------------------------------------------} TParamValue = class(TObject) private FName : NameString; { Parametrin 'nimi', käyt .ini-tiedostossa } FCName : NameString; { Kommunikointi nimi ks. sepustus ylhäällä } FExpl : String; { Parametrin selitys } FValue : Double; { Parametrin todellinen arvo } FFactory : Double; { Tehdasasetus } FMult : Double; { Kerroin, käyt/mult kun muutetaan intiksi } FDes : integer; { Parametrin desimaalien lukumäärä } FIni : string; { Paramterin ini-tiedosto } FSec : string; { Ini-tiedoston section } FIndex : integer; { parametrin sisäinen indeksi, esim. rek.nro } FTyp : char; { paramterin tyyppi } FTyps : string[10]; { tyyppijono } FNoIni: boolean; { kirjoitetaanko ini-tiedostoon } FRO : boolean; public LastError : string; function ToStrs(strs:TStringList):TStringList; procedure FromStrs(strs:TStringList); function GetInt: integer; virtual; procedure SetInt(i: integer); virtual; function GetStr: string; virtual; procedure SetStr(const s: string); virtual; function WriteValueNoSave(d: double;noread:boolean=false): string; function WriteValue(d: double): string; virtual; function WriteBitNoSave(i:integer; b:boolean; noread:boolean=false) : string; function WriteBit(i:integer; b:boolean) : string; function WriteBitMask(i, v, maskand,maskor: integer) : string; procedure SetBitMask(i, v, maskand,maskor: integer); procedure SetBit(i:integer; b:boolean); virtual; function GetBit(i:integer):boolean; virtual; function ReadBit(i:integer):boolean; function WriteFunction(d: double;noread:boolean=false): string; virtual; function ReadFunction: string; virtual; function SaveValueToIni: string; virtual; function RefreshValue: string; virtual; function IsFactoryValue: boolean; virtual; function IsFactory(d: double): boolean; virtual; procedure ParseType(const s:string); procedure StoreEEPROM; virtual; procedure StoreRAM; virtual; published property Name : NameString read FName write FName; property CName : NameString read FCName write FCName; property Expl : String read FExpl; property Value : double read FValue write FValue; property AsString : string read GetStr write SetStr; property Factory : double read FFactory write FFactory; property Mult : double read FMult write FMult; property Des : integer read FDes write FDes; property AsInteger : integer read GetInt write SetInt; property Ini : string read FIni write FIni; property Sec : string read FSec write FSec; property Ind : integer Read FIndex write FIndex; public end; type {----------------------------------------------------------------------------} TParamList = class(TStringList) private FModel:string; protected Owner : TComponent; public ValueIniName: String; TypeTraName:string; ValueSection:String; TypeIniName: String; constructor Create(AOwner: TComponent); function ReadTranslation(var IniV:TIniFile):boolean; virtual; function ReadParams(typeini,valueini,valsec: string):string; virtual; function Value(i: integer): Double; virtual; function Name(i: integer): string; virtual; function PValue(i: integer): TParamValue; virtual; function WriteValue(i: integer; d: double): string; virtual; function WriteBit(i,b:integer;v:boolean):string; virtual; procedure SetBit(i,b:integer;v:boolean); virtual; function GetBit(i,b:integer):boolean; virtual; function RefreshValue(i: integer): string; virtual; function RefreshAll: string; virtual; function SaveAll: string; virtual; function WriteAll: string; virtual; function AsString(i: integer): string; virtual; function IsFactoryValue(i:integer): boolean; virtual; function NewParam(const name:string):TParamValue; virtual; function GetValue(const name:string):double; virtual; function GetIndex(const name:string):integer; virtual; function FindParam(const name:string): TParamValue; virtual; procedure StoreEEPROM; virtual; procedure StoreRAM; virtual; published property Model : String read FModel write FModel; end; type TFormParams = class(TForm) PanelE: TPanel; NotebookType: TNotebook; ListBoxList: TListBox; LabelParam: TLabel; PanelW: TPanel; TimerChange: TTimer; PanelESelected: TPanel; LabelSelected: TLabel; PanelEHeader: TPanel; LabelHeader: TLabel; PanelEControls: TPanel; LabelUnit: TLabel; LabelRange: TLabel; kParamValue: TkParam; GParams: TStringGrid; PanelButtons: TPanel; ButtonRefresh: TButton; ButtonSaveAll: TButton; ButtonWrite: TButton; ButtonDone: TButton; LabelFactory: TLabel; PanelN: TPanel; LabelError: TLabel; EditName: TEdit; ButtonWriteAll: TButton; ButtonDefault: TButton; Label1: TLabel; Label2: TLabel; ListBoxBit: TListBox; ButtonRead: TButton; CheckBoxAutoRead: TkCheckBox; TimerAutoRead: TTimer; ButtonNot: TButton; kTrackBarValue: TkTrackBar; LabelMax: TLabel; LabelMin: TLabel; SavePos1: TSavePos; kSplitter1: TkSplitter; procedure FormCreate(Sender: TObject); procedure ListBoxListClick(Sender: TObject); procedure TimerChangeTimer(Sender: TObject); procedure GParamsClick(Sender: TObject); procedure ShowParam(row:integer); virtual; procedure ButtonDoneClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure kParamValueClick(Sender: TObject); procedure CheckWriteButton; procedure ButtonWriteClick(Sender: TObject); procedure ButtonRefreshClick(Sender: TObject); procedure ButtonSaveAllClick(Sender: TObject); procedure EditNameChange(Sender: TObject); procedure ButtonDefaultClick(Sender: TObject); procedure ButtonWriteAllClick(Sender: TObject); procedure ButtonReadClick(Sender: TObject); procedure TimerAutoReadTimer(Sender: TObject); procedure CheckBoxAutoReadClick(Sender: TObject); procedure ListBoxBitDblClick(Sender: TObject); procedure ButtonNotClick(Sender: TObject); procedure SetTBPos; function GetTBPos:double; procedure kTrackBarValueChange(Sender: TObject); procedure PanelWResize(Sender: TObject); private { Private declarations } pcomp : PComponent; pvalue : TParamValue; list : TParamList; origvalue : double; curvalue : double; factoryvalue : double; TBMult : double; function HeaderStr(row:Integer):String; virtual; procedure ReadRow; public { Public declarations } constructor Create3(AOwner:TComponent; ipcomp:PComponent; l:TParamList); function FindIndex(row:integer): integer; virtual; function FindIndexRow: integer; virtual; procedure RefreshGrid(row:integer); virtual; procedure RefreshGridRow; virtual; end; implementation uses KString,Math; {$R *.DFM} Const TypeSection = 'Params'; constructor TFormParams.Create3(AOwner:TComponent; ipcomp:PComponent; l:TParamList); begin pcomp := ipcomp; list := l; inherited Create(AOwner); end; procedure TFormParams.FormCreate(Sender: TObject); var Ini:TIniFile; n,i:integer; s:string; section:string; begin TBMult := 1; Ini := TIniFile.Create(list.TypeIniName); Caption := list.Model; GParams.DefaultRowHeight := -GParams.Font.Height+3; GParams.RowCount := list.Count+1; // One for fixed header row (0) GParams.Cells[0,0] := 'Name'; GParams.Cells[1,0] := 'Parameter'; GParams.Cells[2,0] := 'Value'; // GParams.Cells[3,0] := 'Factory'; GParams.Cells[4,0] := 'Ini section'; n := 0; for i:=0 to list.Count-1 do begin section := list.name(i); // section := list.PValue(i).CName; s := list.PValue(i).Expl; if ( s = '' ) then continue; n := n + 1; GParams.Cells[0,n] := list.PValue(i).CName; GParams.Cells[1,n] := s; GParams.Cells[4,n] := section; RefreshGrid(n); end; Ini.Free; ShowParam(1); end; procedure HandleCtrls(var s:string); var p:integer; begin while ( true ) do begin p := pos('\t',s); if ( p = 0 ) then break; s[p] := Chr(9); Delete(s,p+1,1); while ( s[p+1] = ' ' ) do Delete(s,p+1,1); end; end; function ListStrToInt(const s:string; c:char):integer; var st:string; p:integer; begin p := pos(c,s); st := copy(s,1,p-1); Result := StrToInt(st); end; procedure TFormParams.ListBoxListClick(Sender: TObject); var s:string; begin s := ListBoxList.Items[ListBoxList.ItemIndex]; LabelSelected.Caption := s; curvalue := ListStrToInt(s,'='); CheckWriteButton; end; function TFormParams.HeaderStr(row:integer):String; begin Result := GParams.Cells[0,Row] + ': ' + GParams.Cells[1,Row]; end; procedure ReadListItems(Ini:TIniFile; lb:TListBox; const section,r:string; mark:integer); label NextItem; var i,p:integer; e: Erota_tyyppi; olditem,psec,pitem,pval : string; begin olditem := ''; i := erota_eka(e,PChar(r),0,20); while ( i >= 0 ) do begin psec := IntToStr(i); pval:=psec; pitem := Ini.ReadString(section,psec,olditem); if ( pitem = '' ) then goto NextItem; if ( pitem[1] = '(' ) then begin p := Pos(')',pitem); if ( p = 0 ) then goto NextItem; pval:=Copy(pitem,2,p-2); Delete(pitem,1,p+1); end; if ( pitem[1] = '[' ) then begin // muoto 0=[n035]2-24 p := Pos(']',pitem); if ( p = 0 ) then goto NextItem; ReadListItems(Ini,lb,Copy(pitem,2,p-2),Copy(pitem,p+1,100),mark); goto NextItem; end; // tavallinen arvo olditem := pitem; HandleCtrls(pitem); if ( StrToInt(pval) = mark ) then pval := pval+'='; lb.Items.Add(pval+'='+pitem); NextItem: i := erota_seuraava(e); end; end; var stBool:array [0..1,0..31] of string[20]; function ChangeBitSt(const st:string;i,value:integer) : string; var p:integer; begin Result := st; if ( i < 0 ) or ( 32 <= i ) then exit; value := ( value shr i ) and 1; p := pos(#9,st); if ( p = 0 ) then exit; delete(Result,p+1,100); Result := Result + stBool[value][i]; end; procedure FindBS(var s,b:string; i,value:integer); var p1,p2,mask : integer; b0,b1,answ :string; begin mask := 1; mask := mask SHL i; mask := mask AND value; p1 := Pos('|',s); answ := copy(s,p1+1,100); Delete(s,p1,100); p2 := Pos('|',answ); b0 := Copy(answ,1,p2-1); b1 := Copy(answ,p2+1,100); if ( 0 <= i ) and ( i < 32 ) then begin stBool[0][i] := b0; stBool[1][i] := b1; end; if ( mask = 0 ) then b := b0 else b := b1; end; procedure ReadBitItems(Ini:TIniFile; lb:TListBox; const section,r:string; value:integer); label NextItem; var i,p:integer; e: Erota_tyyppi; olditem,psec,pitem,bitst : string; begin olditem := ''; i := erota_eka(e,PChar(r),0,20); while ( i >= 0 ) do begin psec := IntToStr(i); pitem := Ini.ReadString(section,psec,olditem); if ( pitem = '' ) then goto NextItem; if ( pitem[1] = '[' ) then begin // muoto 0=[n035]2-24 p := Pos(']',pitem); if ( p = 0 ) then goto NextItem; ReadBitItems(Ini,lb,Copy(pitem,2,p-2),Copy(pitem,p+1,100),value); goto NextItem; end; // tavallinen arvo olditem := pitem; FindBS(pitem,bitst,i,value); lb.Items.Add(psec+'='+pitem+#9+bitst); NextItem: i := erota_seuraava(e); end; end; function FindInt(lb:TListBox; value:Integer):integer; var i:integer; begin for i:=0 to lb.Items.count do if ListStrToInt(lb.Items[i],'=') = value then begin Result := i; Exit; end; Result := 0; end; procedure TFormParams.SetTBPos; var d,r1,r2: double; begin r1 := kParamValue.MinValue; r2 := kParamValue.MaxValue; d := r2 - r1; if ( d <= 0 ) then exit; // kTrackBarValue.Position := round(1000-(kParamValue.Value-r1)*1000/d); kTrackBarValue.Position := -Round(kParamValue.Value * TBMult); end; function TFormParams.GetTBPos:double; //var d,r1,r2: double; begin // r1 := kParamValue.MinValue; // r2 := kParamValue.MaxValue; // d := r2 - r1; // Result := (1000-kTrackBarValue.Position)*d/1000 + r1; Result := -kTrackBarValue.Position / TBMult; kParamValue.Value := Result; curvalue := Result; CheckWriteButton; end; procedure TFormParams.ShowParam(row:integer); var r,section:string; Ini:TIniFile; index:integer; sel : integer; r1,r2:double; oldf : TNotifyEvent; // pvalue : TParamValue; begin index := FindIndex(row); if ( index < 0 ) then exit; LabelParam.Caption := HeaderStr(row); pvalue := list.PValue(index); section := list.Name(index); Ini := TIniFile.Create(list.TypeIniName); LabelHeader.Caption := Ini.ReadString(section,'h',''); origvalue := pvalue.value; curvalue := origvalue; factoryvalue := pvalue.factory; CheckWriteButton; case pvalue.FTyp of 'L','l' : begin NoteBookType.PageIndex := 0; ListBoxList.Items.Clear; r := Ini.ReadString(section,'r','0,1'); ReadListItems(Ini,ListBoxList,section,r,Round(factoryvalue)); sel:=FindInt(ListBoxList,pvalue.AsInteger); ListBoxList.ItemIndex := sel; ListBoxListClick(self); end; 'D','d','E','e' : begin NoteBookType.PageIndex := 1; kParamValue.Hint := HeaderStr(row); LabelUnit.Caption := Ini.ReadString(section,'u',''); r := Ini.ReadString(section,'r',''); LabelRange.Caption := 'Range: ' + r + ' ' + LabelUnit.Caption; LabelFactory.Caption := ' Factory: '+ DoubleToIniStr(pvalue.Factory,pvalue.Des) + ' ' + LabelUnit.Caption; GetDoubleRangeLimit(r,r1,r2,0,100); kParamValue.MinValue := r1; kParamValue.MaxValue := r2; kParamValue.Desim := pvalue.des; kParamValue.Value := pvalue.value; TBMult := IntPower(10,kParamValue.Desim); if ( TBMult < 1 ) then TBMult := 1; oldf := kTrackBarValue.OnChange; kTrackBarValue.OnChange := nil; // Quick hack to prevent crash. TTrackBar can not have large limits. if ( Abs(R2-R1)<10000 ) then begin kTrackBarValue.Visible:=true; LabelMin.Visible:=true; LabelMax.Visible:=true; kTrackBarValue.Max := -Round(r1*TBMult); kTrackBarValue.Min := -Round(r2*TBMult); with kTrackBarValue do if ( Max-Min > 0 ) then begin Linesize := Round(IntPower(10,Trunc(Log10((Max-Min)/100))+1)); PageSize := Round(IntPower(10,Trunc(Log10((Max-Min)/10))+1)); end; LabelMin.Caption := DoubleToStr(r1,1); LabelMax.Caption := DoubleToStr(r2,1); SetTBPos; kTrackBarValue.OnChange := oldf; end else begin kTrackBarValue.Visible:=false; LabelMin.Visible:=false; LabelMax.Visible:=false; end; end; 'B','b' : begin NoteBookType.PageIndex := 2; ListBoxBit.Items.Clear; r := Ini.ReadString(section,'r','0,1'); ReadBitItems(Ini,ListBoxBit,section,r,pvalue.AsInteger); end; end; Ini.Free; end; {------------------------------------------------------------------------------} function TFormParams.FindIndex(row:integer): integer; begin Result := list.Indexof(GParams.Cells[4,row]); end; {------------------------------------------------------------------------------} function TFormParams.FindIndexRow: integer; begin Result := list.Indexof(GParams.Cells[4,GParams.row]); end; {------------------------------------------------------------------------------} procedure TFormParams.RefreshGrid(row:integer); var pvalue:TParamValue; s:string; begin pvalue := list.PValue(FindIndex(row)); if ( pvalue = nil ) then exit; // GParams.Cells[0,row] := pvalue.Name; GParams.Cells[2,row] := pvalue.AsString; s := ''; if ( not pvalue.IsFactoryValue ) then s := '<='; GParams.Cells[3,row] := s; end; {------------------------------------------------------------------------------} procedure TFormParams.RefreshGridRow; begin RefreshGrid(GParams.Row); end; procedure TFormParams.TimerChangeTimer(Sender: TObject); begin TimerChange.Enabled := False; ShowParam(GParams.Row); end; procedure TFormParams.GParamsClick(Sender: TObject); begin LabelParam.Caption := HeaderStr(GParams.Row); TimerChange.Enabled := False; TimerChange.Enabled := True; end; procedure TFormParams.ButtonDoneClick(Sender: TObject); begin Close; end; procedure TFormParams.FormClose(Sender: TObject; var Action: TCloseAction); begin if ( pcomp <> NIL ) then pcomp^ := NIL; Release; end; {------------------------------------------------------------------------------} constructor TParamList.Create(AOwner: TComponent); begin inherited Create; Owner := AOwner; end; {------------------------------------------------------------------------------} function TParamList.NewParam(const name:string):TParamValue; begin Result := TParamValue.Create; end; {------------------------------------------------------------------------------} function TParamList.GetIndex(const name:string):integer; begin Result := IndexOf(name); end; {------------------------------------------------------------------------------} function TParamList.FindParam(const name:string): TParamValue; var i:integer; begin i := GetIndex(name); Result := NIL; if ( i >= 0 ) then Result := PValue(i); end; {------------------------------------------------------------------------------} function TParamList.GetValue(const name:string):double; var i:integer; begin i := IndexOf(name); Result := 0; if ( i < 0 ) then exit; Result := Value(i); end; function TParamList.ReadTranslation(var IniV:TIniFile):boolean; var TraStrs,TraStr : TStringList; value : TParamValue; i:integer; at,ai:integer; begin Result := False; TraStrs := NIL; TraStr := NIL; if ( not FileExists(TypeTraName) ) then exit; ai := FileAge(TypeIniName); at := FileAge(TypeTraName); if ( at <= ai ) then exit; try try TraStrs := TStringList.Create; TraStr := TStringList.Create; TraStrs.LoadFromFile(TypeTraName); for i:=0 to TraStrs.Count-1 do begin TraStr.CommaText := TraStrs.Strings[i]; value := NewParam(TraStr.Strings[0]); value.FromStrs(TraStr); value.Value := IniReadDouble(IniV,ValueSection,value.name,value.Factory); value.Ini := ValueIniName; value.Sec := ValueSection; AddObject(value.name,value); end; Result := Not Result; // Hämäystä, = true, koska muuten kääntäjä valittaa except exit; end finally if ( TraStr <> NIL ) then TraStr.Free; if ( TraStrs <> NIL ) then TraStrs.Free; end; end; {------------------------------------------------------------------------------} { Ini-tiedoston muoto on: [Params] Model=Yaskawa VS-616PC5/P5 name0=n range0=1-29 fill0=000 len0=3 base0=$100 ; => n001-n029 [n001] n=... Also following is valid format: [Params] Model=Yaskawa VS-616PC5/P5 [name0] name=n range=1-29 fill=000 len=3 base=$100 } function TParamList.ReadParams(typeini,valueini,valsec: string):string; var Ini,IniV:TIniFile; len,i:integer; ptype,fill,r,name,sname,nname:string; value : TParamValue; e: Erota_tyyppi; maxlen,nr,base:integer; nrs:string[10]; {$ifdef TRANS } TraStrs,TraStr : TStringList; {$endif} procedure ReadOneName(const TypeSection,nrs:string); label NextParam; begin r := Ini.ReadString(TypeSection,'Range'+nrs,''); if ( r = '' ) then exit; fill := Ini.ReadString(TypeSection,'fill'+nrs,''); maxlen := Ini.ReadInteger(TypeSection,'len'+nrs,50); Base := Ini.ReadInteger(TypeSection,'base'+nrs,0); i := erota_eka(e,PChar(r),0,20); while ( true ) do begin { testi ei heti jotta ilman rajoja tulee yksi n } nname := ''; if ( i>=0 ) then begin nname := fill+IntToStr(i); len := Length(nname); nname := Copy(nname,max(1,len-maxlen+1),maxlen); end; name := sname+nname; ptype := Ini.ReadString(name,'t',''); if ( ptype <= ' ' ) then goto NextParam; value := NewParam(name); if ( value = NIL ) then goto NextParam; value.Name := name; value.CName := Ini.ReadString(name,'cn',name); value.FExpl := Ini.ReadString(name,'n',''); value.FTyps := ptype; value.ParseType(ptype); value.Factory := IniReadDouble(Ini,name,'f',0); if not value.FNoIni then value.Value := IniReadDouble(IniV,ValueSection,name,value.Factory); value.Mult := IniReadDouble(Ini,name,'m',1.0); value.Ind := Ini.ReadInteger(name,'i',max(base + i,0)); value.Des := Ini.ReadInteger(name,'des',CountDes(value.Mult)); value.Ini := ValueIniName; value.Sec := ValueSection; AddObject(name,value); {$ifdef TRANS } value.ToStrs(TraStr); TraStrs.Add(TraStr.CommaText); {$endif} NextParam: if ( i < 0 ) then break; i := erota_seuraava(e); if ( i < 0 ) then break; end; // while (true) end; begin Result := ''; TypeIniName := typeini; TypeTraName := ChangeExtension(typeini,'.ktr'); ValueIniName := valueini; ValueSection := valsec; Ini := TIniFile.Create(TypeIniName); IniV := TIniFile.Create(ValueIniName); Model := Ini.ReadString(TypeSection,'Model','Params'); {$ifdef TRANS } if ( ReadTranslation(IniV) ) then begin IniV.free; Ini.Free; exit; end; TraStrs := TStringList.Create; TraStr := TStringList.Create; {$endif} for nr := 0 to 10000 do begin // Huijausylärajana, seur. break lopettaa nrs := IntToStr(nr); sname := Ini.ReadString(TypeSection,'name'+nrs,''); if ( sname = '' ) then break; ReadOneName(TypeSection,nrs); end; for nr := 0 to 10000 do begin // Huijausylärajana, seur. break lopettaa nrs := IntToStr(nr); sname := Ini.ReadString('name'+nrs,'name',''); if ( sname = '' ) then break; ReadOneName('name'+nrs,''); end; {$ifdef TRANS } TraStr.Free; TraStrs.SaveToFile(TypeTraName); TraStrs.Free; {$endif} IniV.Free; Ini.Free; end; {------------------------------------------------------------------------------} function TParamList.Value(i: integer): Double; begin Result := 0; if ( i < 0 ) or ( i >= Count ) then exit; Result := (Objects[i] as TParamValue).Value; end; {------------------------------------------------------------------------------} function TParamList.Name(i: integer): string; begin Result := ''; if ( i < 0 ) or ( i >= Count ) then exit; Result := Strings[i]; end; {------------------------------------------------------------------------------} function TParamList.PValue(i: integer): TParamValue; begin Result := NIL; if ( i < 0 ) or ( i >= Count ) then exit; Result := (Objects[i] as TParamValue); end; {------------------------------------------------------------------------------} procedure TParamValue.ParseType(const s:string); begin FTyp := s[1]; FRO := Pos('R',s) > 1; FNoIni := ( Pos('O',s) > 1 ) or FRO; end; {------------------------------------------------------------------------------} function TParamValue.ToStrs(strs:TStringList) : TStringList; begin with strs do begin Clear; Add(FName); Add(FCName); Add(FTyps); Add(FExpl); // Add(DoubleToStr(FValue,FDes); Add(IntToStr(FDes)); Add(DoubleToIniStr(FFactory,FDes)); Add(DoubleToIniStr(FMult,3)); Add(IntToStr(FIndex)); end; Result := strs; end; {------------------------------------------------------------------------------} procedure TParamValue.FromStrs(strs:TStringList); var index:integer; begin with strs do begin index:=0; FName := Strings[index]; index:=index+1; FCName := Strings[index]; index:=index+1; FTyps := Strings[index]; ParseType(Strings[index]); index:=index+1; FExpl := Strings[index]; index:=index+1; FDes := Trunc(IniStrToDouble(Strings[index],0)); index:=index+1; FFactory := IniStrToDouble(Strings[index],0); index:=index+1; FMult := IniStrToDouble(Strings[index],0); index:=index+1; FIndex := Trunc(IniStrToDouble(Strings[index],0)); //index:=index+1; end; end; {------------------------------------------------------------------------------} function TParamValue.GetInt: integer; var w : smallint; begin if ( mult = 0 ) then mult := 1; Result := trunc(value/mult+0.5); if ( FTyp = 'E' ) or ( FTyp = 'e' ) then begin w := Result; // if ( Result < 0 ) then w := ( ( not ( w and $ffff ) ) + 1 ); Result := w; end; end; {------------------------------------------------------------------------------} procedure TParamValue.SetInt(i: integer); var w : smallint; begin if ( mult = 0 ) then mult := 1; if ( FTyp = 'E' ) or ( FTyp = 'e' ) then begin w := i; i := w; end; value := i * mult; end; {------------------------------------------------------------------------------} function TParamValue.GetStr: string; begin Result := DoubleToStr(value,des); end; {------------------------------------------------------------------------------} procedure TParamValue.SetStr(const s: string); begin value := StrToDoubleDef(s,value); end; {------------------------------------------------------------------------------} procedure TFormParams.CheckWriteButton; begin ButtonWrite.Enabled := origvalue <> curvalue; ButtonDefault.Enabled := factoryvalue <> origvalue; ButtonRead.Visible := pvalue.FNoIni; ButtonDefault.Visible := NOT ButtonRead.Visible; ButtonWrite.Visible := NOT ButtonRead.Visible; if ( NOT pvalue.FRO ) and ( ButtonWrite.Enabled ) then ButtonWrite.Visible := true; ButtonNot.Visible := not pvalue.FRO; kTrackBarValue.Enabled := not pvalue.FRO; CheckBoxAutoRead.Visible := not ButtonWrite.Visible; if ( Not TimerAutoRead.Enabled ) and CheckBoxAutoRead.Visible and CheckBoxAutoRead.Checked then TimerAutoRead.Enabled := true; end; procedure TFormParams.ButtonRefreshClick(Sender: TObject); var i:integer; begin LabelError.Caption := list.RefreshAll; for i:=1 to GParams.RowCount do RefreshGrid(i); ShowParam(GParams.Row); end; procedure TFormParams.ButtonSaveAllClick(Sender: TObject); begin LabelError.Caption := list.SaveAll; end; procedure TFormParams.kParamValueClick(Sender: TObject); begin if ( PValue.FRO ) then exit; kParamValue.Ask; curvalue := kParamValue.value; SetTBPos; CheckWriteButton; end; procedure TFormParams.ButtonWriteClick(Sender: TObject); var index:integer; begin index := FindIndexRow; if ( index < 0 ) then exit; LabelError.Caption := list.WriteValue(index,curvalue); RefreshGridRow; ShowParam(GParams.Row); end; procedure TFormParams.ButtonDefaultClick(Sender: TObject); begin curvalue := factoryvalue; ButtonWriteClick(self); end; procedure TFormParams.ButtonWriteAllClick(Sender: TObject); begin LabelError.Caption := list.WriteAll end; procedure TFormParams.EditNameChange(Sender: TObject); var n,i:integer; s:string; start,stop : integer; begin s := UpperCase(EditName.Text); start := GParams.Row; stop := GParams.RowCount-1; if ( UpperCase(GParams.Cells[4,start]) > s ) then begin stop := start; start := 1; end; n := 1; for i := start to stop do begin n := i; if ( UpperCase(GParams.Cells[4,i]) >= s ) then begin break; end; end; GParams.Row := max(n,1); end; {------------------------------------------------------------------------------} procedure TFormParams.ReadRow; var old : double; begin old := curvalue; // pvalue.value; pvalue.RefreshValue; if ( pvalue.value = old ) then exit; RefreshGridRow; ShowParam(GParams.Row); end; {------------------------------------------------------------------------------} procedure TFormParams.ButtonReadClick(Sender: TObject); begin ReadRow; end; {------------------------------------------------------------------------------} function TParamList.RefreshValue(i: integer): string; var value : TParamValue; begin Result := ''; value := PValue(i); if ( value = NIL ) then exit; result := value.RefreshValue; end; {------------------------------------------------------------------------------} function TParamList.WriteValue(i: integer; d: double): string; var value : TParamValue; begin Result := ''; value := PValue(i); if ( value = NIL ) then exit; Result := value.WriteValue(d); end; {------------------------------------------------------------------------------} function TParamList.WriteBit(i,b:integer;v:boolean):string; var value : TParamValue; begin Result := ''; value := PValue(i); if ( value = NIL ) then exit; Result := value.WriteBit(b,v); end; {------------------------------------------------------------------------------} procedure TParamList.SetBit(i,b:integer;v:boolean); var value : TParamValue; begin value := PValue(i); if ( value = NIL ) then exit; value.SetBit(b,v); end; {------------------------------------------------------------------------------} function TParamList.GetBit(i,b:integer):boolean; var value : TParamValue; begin Result := false; value := PValue(i); if ( value = NIL ) then exit; Result := value.GetBit(b); end; {------------------------------------------------------------------------------} function TParamValue.SaveValueToIni: string; var IniV:TIniFile; s:string; begin Result := ''; if ( FNoIni ) then exit; IniV := TIniFile.Create(Ini); try if ( value = Factory ) then begin s := IniV.ReadString(Sec,Name,''); if ( s<>'' ) then IniV.WriteString(Sec,Name,''); end else IniV.WriteString(Sec,Name,AsString); except Result := 'Can''t write to ini-file:' + ' ' + Ini; end; IniV.Free; end; {------------------------------------------------------------------------------} function TParamValue.IsFactory(d: double): boolean; begin Result := Factory = d; end; {------------------------------------------------------------------------------} function TParamValue.IsFactoryValue: boolean; begin Result := IsFactory(Value); end; {------------------------------------------------------------------------------} function TParamValue.WriteValueNoSave(d: double; noread : boolean): string; begin Result := ''; if ( FRO ) then exit; Result := WriteFunction(d,noread); if ( Result <> '' ) then exit; Result := Param_OK_String; end; {------------------------------------------------------------------------------} function TParamValue.WriteValue(d: double): string; begin Result := WriteValueNoSave(d); if ( Result <> Param_OK_String ) then exit; Result := SaveValueToIni; if ( Result <> '' ) then exit; Result := Param_OK_String; end; {------------------------------------------------------------------------------} function TParamValue.WriteBitNoSave(i:integer; b:boolean; noread:boolean) : string; var masko,maska,bits : integer; begin maska := (not 0) xor (1 shl i); masko := 1 shl i; if ( not b ) then masko := 0; bits := Round(Value); bits := ( bits and maska ) or masko; Result := WriteValueNoSave(bits,noread); end; {------------------------------------------------------------------------------} function TParamValue.WriteBit(i:integer; b:boolean) : string; var masko,maska,bits : integer; begin maska := (not 0) xor (1 shl i); masko := 1 shl i; if ( not b ) then masko := 0; bits := Round(Value); bits := ( bits and maska ) or masko; Result := WriteValue(bits); end; function TParamValue.WriteBitMask(i, v, maskand,maskor: integer) : string; var masko,maska,bits : integer; begin maska := (not 0) xor (maskand shl i); maskand := maskand and v; masko := (maskand shl i) or maskor; bits := Round(Value); bits := ( bits and maska ) or masko; Result := WriteValue(bits); end; {------------------------------------------------------------------------------} procedure TParamValue.SetBit(i:integer; b:boolean); var masko,maska,bits : integer; begin maska := (not 0) xor (1 shl i); masko := 1 shl i; if ( not b ) then masko := 0; bits := Round(Value); bits := ( bits and maska ) or masko; Value := bits; end; procedure TParamValue.SetBitMask(i:integer; v,maskand,maskor:integer); // Onko oikein??? var masko,maska,bits : integer; begin maska := (not 0) xor (maskand shl i); maskand := maskand and v; masko := (maskand shl i) or maskor; bits := Round(Value); bits := ( bits and maska ) or masko; Value := bits; end; {------------------------------------------------------------------------------} function TParamValue.GetBit(i:integer):boolean; var maska : integer; begin Result := false; maska := 1 shl i; if ( Round(Value) and maska ) <> 0 then Result := true; end; {------------------------------------------------------------------------------} function TParamValue.ReadBit(i:integer):boolean; begin LastError := RefreshValue; Result := GetBit(i); end; {------------------------------------------------------------------------------} function TParamValue.RefreshValue: string; begin Result := ReadFunction; LastError := Result; end; {------------------------------------------------------------------------------} { Write value to the fysical device if one exist and chage value to d } { if success } { Return error message as text. } function TParamValue.WriteFunction(d: double;noread:boolean): string; begin value := d; Result := ''; end; {------------------------------------------------------------------------------} { Read value from fysical device and change te value if success } { Return error message as text. } function TParamValue.ReadFunction: string; begin Result := ''; end; {------------------------------------------------------------------------------} function TParamList.RefreshAll: string; var i:integer; err : string; begin Result := ''; for i:=0 to Count-1 do begin err := PValue(i).RefreshValue; if ( err <> '' ) then Result := err; end; if ( Result = '' ) then Result := 'Read ok'; end; {------------------------------------------------------------------------------} function TParamList.SaveAll: string; var i:integer; err : string; begin Result := ''; for i:=0 to Count-1 do begin err := PValue(i).SaveValueToIni; if ( err <> '' ) then Result := err; end; end; {------------------------------------------------------------------------------} function TParamList.WriteAll: string; var i:integer; err : string; begin Result := ''; for i:=0 to Count-1 do begin err := PValue(i).WriteValue(PValue(i).Value); if ( err <> '' ) then Result := err; end; end; {------------------------------------------------------------------------------} function TParamList.AsString(i: integer): string; begin result := PValue(i).AsString; end; {------------------------------------------------------------------------------} function TParamList.IsFactoryValue(i:integer): boolean; begin Result := Pvalue(i).IsFactoryValue; end; procedure TFormParams.TimerAutoReadTimer(Sender: TObject); begin if CheckBoxAutoRead.Visible and CheckBoxAutoRead.Checked then ReadRow else TimerAutoRead.Enabled := false; end; procedure TFormParams.CheckBoxAutoReadClick(Sender: TObject); begin TimerAutoRead.Enabled := CheckBoxAutoRead.Checked; end; procedure TFormParams.ListBoxBitDblClick(Sender: TObject); var ind,bit:integer; s:string; begin If PValue.FRO then exit; ind := ListBoxBit.ItemIndex; if ( ind < 0 ) then exit; s := ListBoxBit.Items[ind]; bit := ListStrToInt(s,'='); // pvalue.SetBit(bit,not pvalue.GetBit(bit)); // curvalue := pvalue.AsInteger; curvalue := round(curvalue) xor (1 shl bit); ListBoxBit.Items[ind] := ChangeBitSt(s,bit,round(curvalue)); ListBoxBit.ItemIndex := ind; CheckWriteButton; end; procedure TFormParams.ButtonNotClick(Sender: TObject); begin ListBoxBitDblClick(Sender); end; procedure TFormParams.kTrackBarValueChange(Sender: TObject); begin GetTBPos; end; procedure TParamList.StoreEEPROM; begin // end; procedure TParamList.StoreRAM; begin // end; procedure TParamValue.StoreEEPROM; begin // end; procedure TParamValue.StoreRAM; begin // end; procedure TFormParams.PanelWResize(Sender: TObject); var WDesc:integer; begin GParams.ColWidths[4]:=0; WDesc:=GParams.ClientWidth - GParams.ColWidths[0]- GParams.ColWidths[2]- GParams.ColWidths[3]- 3; GParams.ColWidths[1]:=WDesc; end; end.