unit MI1201AGM_Roll_Form; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids, StdCtrls, ExtCtrls, CheckLst, xStringGrig, MI1201AGM_Emulator_Notificator, MI1201AGM_Emulator_XForm, MI1201AGM_Roll_Emulator; type tGridCol=( gcName, gcValue, gcNewValue, gcComment ); tGridRow=( grName, grCounter, grFlags, grAutoTuning ); tPortCol=( pcName, pcValueRead, pcValueWrite, pcComment ); const cIFmt='%d.'; cIHFmt='%d. (%0:xh)'; cIfmtLen=Length(cIFmt); cGridRowNames:array[tGridRow] of string=( 'Параметр', 'Счетчик импульсов', 'Флаги', 'Автоподстройка' ); cGridColNames:array[tGridCol] of string=( '', 'Значение', 'Новое значение', 'Комментарий' ); cPortColNames:array[tPortCol] of string=( '', 'Чтение', 'Запись', 'Комментарий' ); type TFRoll = class(TFormX) pBottom: TPanel; gbPorts: TGroupBox; sgPorts: TStringGrid; gbFlags: TGroupBox; clFlags: TCheckListBox; gbParameters: TGroupBox; sgParameters: TStringGrid; sp: TSplitter; gbError: TGroupBox; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure clFlagsClickCheck(Sender: TObject); private { Private declarations } procedure ProcessGridRowInt(Row:integer; Value:integer); procedure ProcessGridRowIntFmt(Row:integer; Value:integer; aFormat:string); procedure ProcessCounter; procedure ProcessOperational; procedure ProcessFlags; procedure ProcessAutotuning; procedure ProcessAll; procedure ProcessPortIO; procedure SetFlags; procedure FillParametersHeaders; procedure FillParametersData; procedure FillPortsHeaders; function GetEditableParameters(ACol, ARow: Longint):tEditAllowFlags; protected function Notify(Sender:TObject; var Event:tEvent):boolean; override; public { Public declarations } end; var FRoll: TFRoll; implementation uses MI1201AGM_PortIO_Emulator, MI1201AGM_Controller_Emulator, MI1201AGM_Emulator_FormMain; {$R *.DFM} function FillPort(AGrid:tStringGrid; PortNum:word; PortOperation:tPortOperation; PortValue:byte):boolean; var i:integer; sptr:PChar; slen:cardinal; c:word; const cCols:array[tPortOperation] of byte=(Ord(pcValueRead),Ord(pcValueWrite)); begin Result:=AGrid.RowCount>PortNum; if Result then with AGrid.Rows[PortNum] do begin c:=cCols[PortOperation]; slen:=Length(Strings[c]); if slen=0 then begin Strings[c]:=Format(cIHFmt, [High(PortValue)]); slen:=Length(Strings[c]); end; sptr:=@Strings[c][1]; i:=FormatBuf(sptr^, slen, cIHFmt, Length(cIHFmt), [PortValue, PortValue]); Dec(slen,i); if slen>0 then FillMemory(Pointer(Cardinal(sptr)+i),slen,Ord(' ')); end; end; procedure TFRoll.ProcessPortIO; var p:word; pn:integer; pv:byte; po:tPortOperation; begin if ControllerOK then begin p:=tRoll(Controller).LastPort; pv:=tRoll(Controller).LastPortValue; po:=tRoll(Controller).LastPortOperation; pn:=tRoll(Controller).PortNumber[p]; if pn>=0 then begin FillPort(sgPorts, Succ(pn), po, pv); end; end; end; function TFRoll.Notify(Sender:TObject; var Event:tEvent):boolean; begin Result:=SenderValid(Sender); if not Result then Exit; if TryLockDef then begin if Inherited Notify(Sender,Event) then // событие обработано else if Event.Base.SubID<0 then begin // ошибка end else if Event.Base.ID=evController then begin case tBaseEvent(Event.Base.SubID) of evCustom: begin case tRollEvent(Event.Base.CustomID) of evRollNothing,evRollLastEvent:; evRollSetAutotuning: begin ProcessAutotuning; end; evRollOperational: begin ProcessOperational; end; evRollFlags: begin ProcessFlags; end; evRollStartCount: begin end; evRollStopCount: begin ProcessCounter; end; else begin Result:=FALSE; end; end; end; evPortRead, evPortWrite: begin ProcessPortIO; end; else begin Result:=FALSE; end; end; end; end else begin Result:=FALSE; end; Unlock; end; procedure TFRoll.FormCreate(Sender: TObject); begin Lock; FMain.AssignProperties(Self); RegistryReadForm; if Assigned(Mi1201AGM) then begin Controller:=Mi1201AGM.Roll; Mi1201AGM.Roll.NotifyEvent:=Self.Notify; end; if RegistryOpenForRead then begin try // sgPorts.Height:=Registry.ReadIntegerDef('sgPorts.Height',sgPorts.Height); except end; try // cbHistoryOn.Checked:=Registry.ReadBoolDef(cbHistoryOn.Name,cbHistoryOn.Checked); // prHistoryOn:=cbHistoryOn.Checked; except end; try // HistoryBufferLengthSet(Registry.ReadIntegerDef('HistoryBufLength',Length(prHistoryBuffer))); except end; Registry.CloseKey; end; // eHLen.Text:=IntToStr(Length(prHistoryBuffer)); // prHistoryOn:=cbHistoryOn.Checked; // PortFillHeader(sgPorts); // ExcludeMask:=[0]; // RegistryReadGridColsWidth(sgPorts); // cbUseDirectIO.Checked:=(efUseDirectIO in MI1201AGM.Flags); // cbDirectIoReturn.Checked:=(efReturnDirectIO in MI1201AGM.Flags); FillParametersHeaders; FillPortsHeaders; ProcessAll; RegistryReadGridColsWidth(sgPorts); RegistryReadGridColsWidth(sgParameters); sgParameters.OnEditQuery:=GetEditableParameters; Unlock; end; procedure TFRoll.FormDestroy(Sender: TObject); begin Lock; inherited; if ControllerOK then begin tRoll(Controller).NotifyEvent:=NIL; end; RegistryWriteForm; if RegistryOpenForWrite then begin try // Registry.WriteInteger('sgPorts.Height',sgPorts.Height); except end; try // Registry.WriteBool(cbHistoryOn.Name,prHistoryOn); except end; try // Registry.WriteInteger('HistoryBufLength',Length(prHistoryBuffer)); except end; Registry.CloseKey; end; RegistryWriteGridColsWidth(sgPorts); RegistryWriteGridColsWidth(sgparameters); end; procedure TFRoll.ProcessCounter; begin If ControllerOK then begin ProcessGridRowInt(Ord(grCounter), tRoll(Controller).Counter); sgParameters.Invalidate; end; end; procedure TFRoll.ProcessOperational; begin end; procedure TFRoll.ProcessGridRowInt(Row:integer; Value:integer); var i:integer; sptr:PChar; slen:cardinal; begin with sgParameters.Rows[Row] do begin if Length(Strings[Ord(gcName)])=0 then Strings[Ord(gcName)]:=cGridRowNames[tGridRow(Row)]; slen:=Length(Strings[Ord(gcValue)]); if slen=0 then begin Strings[Ord(gcValue)]:=Format(cIFmt, [High(Value)]); slen:=Length(Strings[Ord(gcValue)]); end; sptr:=@Strings[Ord(gcValue)][1]; i:=FormatBuf(sptr^, slen, cIFmt, Length(cIFmt), [Value]); Dec(slen,i); if slen>0 then FillMemory(Pointer(Cardinal(sptr)+i),slen,Ord(' ')); end; sgParameters.Invalidate; end; procedure TFRoll.ProcessGridRowIntFmt(Row:integer; Value:integer; aFormat:string); var i:integer; sptr:PChar; slen:cardinal; begin with sgParameters.Rows[Row] do begin if Length(Strings[Ord(gcName)])=0 then Strings[Ord(gcName)]:=cGridRowNames[tGridRow(Row)]; slen:=Length(Strings[Ord(gcValue)]); if slen=0 then begin Strings[Ord(gcValue)]:=Format(aFormat, [High(Value)]); slen:=Length(Strings[Ord(gcValue)]); end; sptr:=@Strings[Ord(gcValue)][1]; i:=FormatBuf(sptr^, slen, aFormat, Length(aFormat), [Value]); Dec(slen,i); if slen>0 then FillMemory(Pointer(Cardinal(sptr)+i),slen,Ord(' ')); end; sgParameters.Invalidate; end; procedure TFRoll.ProcessAutotuning; var at:boolean; begin if ControllerOK then begin at:=tRoll(Controller).AutoTuning; ProcessGridRowInt(Ord(grAutoTuning), Byte(at)); end else begin clFlags.Enabled:=FALSE; end; end; procedure TFRoll.ProcessFlags; var flags:byte; i:byte; begin if ControllerOK then begin clFlags.Enabled:=TRUE; flags:=tRoll(Controller).Flags; for i:=0 to 7 do begin clFlags.Checked[i]:=((1 shl i) and flags)<>0; end; ProcessGridRowInt(Ord(grFlags), flags); end else begin clFlags.Enabled:=FALSE; end; end; procedure TFRoll.SetFlags; var i:integer; flags:byte; begin if ControllerOK then begin flags:=0; for i:=0 to 7 do begin if clFlags.Checked[i] then flags:=flags or ((1 shl i)); end; tRoll(Controller).Flags:=flags; end else begin clFlags.Enabled:=FALSE; end; end; procedure TFRoll.ProcessAll; begin ProcessCounter; ProcessOperational; ProcessFlags; ProcessAutotuning; end; procedure TFRoll.FillParametersHeaders; var c:tGridCol; r:tGridRow; i:integer; begin sgParameters.ColCount:=Succ(Ord(High(c))); for c:=Low(c)to High(c) do begin sgParameters.Cols[Ord(c)].Strings[0]:=cGridColNames[c]; end; FillParametersData; end; procedure TFRoll.FillParametersData; var i,c:integer; begin if ControllerOK then begin c:=tRoll(Controller).ParametersCount; if sgParameters.RowCount