unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,
  ExtCtrls, IniFiles, FormComp, DateUtils, Forms, ComCtrls, StdCtrls, JPEG;

type
  TPerem = record
    Name:string;
    Offset:byte;
  end;

  tBuffer = record
    Offset:byte;
    BufferLength:byte;
  end;

  TLog = class(timage)
    Procedure add(hvalue:byte;value:real);
  private
    PeremsCout:byte;
    Perems:array of TPerem;
    Max,Min:integer;
    Name:string;
  end;

  TPribor = record
    Name:string;
    Vid:byte;
    Formula:string;
    Size,SSize:word;
    X,Y,SX,SY:word;
    Max,Min:integer;
    PinNum:word;
    NumLen:word;
    StartCone:smallint;
    EndCone:smallint;
    Horiz:boolean;
    Revers:boolean;
    ShkalaColor:tcolor;
    StrelkaColor:tcolor;
    TextColor:tcolor;
    Trevoga:boolean;
    TrevogaLow:boolean;
    TrevogaPoz:real;
    TrevSwich:boolean;
    TrevSwichedCol:tcolor;
    Trev:boolean;
    nach,kon,rl:real;
    OffBit:tbitmap;
    OnBit:tbitmap;
  end;

  TClock = record
    Size,SSize:word;
    X,Y,SX,SY:word;
    Color:tcolor;
    Visible:boolean;
  end;

  TAllData = record
    BuffersCout:byte;
    Buffers:array of TBuffer;
    LogCout:byte;
    LogsFormuls: array of Tformula;
    Logs:array of TLog;
    PriborCout:byte;
    PriborFormuls: array of Tformula;
    Pribors:array of TPribor;
    LogValues:array of real;
    PribValues:array of real;
    Clock:TClock;
  end;

  TForm1 = class(TForm)
    Timer1: TTimer;
    ScrollBox1: TScrollBox;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    Button1: TButton;
    Image1: TImage;
    ScrollBox2: TScrollBox;
    procedure Recording;
    procedure DrawPribBack;
    procedure DrawPrib;
    procedure FormCreate(Sender: TObject);
    procedure LogPrint(var Msg: TMessage); message WM_User+1000;
    procedure FormDblClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure ScrollBox1MouseWheel(Sender: TObject; Shift: TShiftState;
      WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure TabSheet2Resize(Sender: TObject);
  private
    Data: TAllData;
    Buffer: array [0..$6F] of byte;
    DoRec: boolean;
    Rec: string;
    PribBackMap:tbitmap;
    PribTempMap:tbitmap;
    { Private declarations }
  public
    { Public declarations }
  end;

  TCommThread = class(TThread)
  private
    PortSt: PAnsiChar;
    COMport: dword;
    BufCout, N, NBufferLength,NBufferOffset:byte;
    BufRd: array [0..50] of byte;
    overlapped : TOverlapped;
    PreambSize:byte;
    Procedure AssBuff;
    Procedure WriteToPort;
  protected
    Procedure Execute; override;
  end;


var
  Form1: TForm1;
  CommThread: TCommThread;

implementation

{$R *.dfm}


procedure TForm1.DrawPribBack;
var i,j,tx,ty:integer; val,px,py:real; s:string; jpg:TJpegImage; FileBit,TempBit,MaskBit:tbitmap;
begin
   Image1.Picture.Bitmap.Width:=Image1.Width;
   Image1.Picture.Bitmap.Height:=Image1.Height;
   PribTempMap.Width:=Image1.Width;
   PribTempMap.Height:=Image1.Height;
   PribBackMap.Free;
   PribBackMap:=TBitMap.Create;
   PribBackMap.Canvas.Font.Name:='Arial';
   PribBackMap.Canvas.Brush.Color:=Form1.ScrollBox1.Color;
   PribBackMap.Width:=Image1.Width;
   PribBackMap.Height:=Image1.Height;
   PribBackMap.Canvas.Brush.Style:=bsClear;
   if FileExists('.\back.jpg') then begin
     Jpg:=TJpegImage.Create;
     Jpg.LoadFromFile('.\back.jpg');
     PribBackMap.Canvas.StretchDraw(rect(0,0,Image1.Width,Image1.Height),Jpg);
     Jpg.Free;
    end;
with Data do with PribBackMap.Canvas do
 for i:=0 to PriborCout-1 do
  with Pribors[i] do begin
    SSize:=round(Image1.Width/400*Size);
    SX:=round(Image1.Width/400*X);
    SY:=round(Image1.Width/400*Y);
    Font.Height:=round(SSize*0.2);
    Font.Color:=TextColor;
    Pen.Width:=round(SSize*0.013);
    Pen.Color:=ShkalaColor;
    ty:=TextHeight('0');
    case Vid of
      0: begin
        nach:=-pi / 180 * StartCone;
        kon:=-pi / 180 * EndCone;
        rl:=(kon-nach)/(max-min)*(TrevogaPoz-min)+nach;
        if nach>kon then
          Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(nach)*100),SY+SSize+round(sin(nach)*100),SX+SSize+round(cos(kon)*100),SY+SSize+round(sin(kon)*100))
        else
          Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(kon)*100),SY+SSize+round(sin(kon)*100),SX+SSize+round(cos(nach)*100),SY+SSize+round(sin(nach)*100));

        for j:=0 to PinNum do begin
          val:=(kon-nach)/PinNum*j+nach;
          px:=cos(val)*SSize;
          py:=sin(val)*SSize;
          MoveTo(SX+SSize+round(px),SY+SSize+round(py));
          LineTo(SX+SSize+round(px*0.9),SY+SSize+round(py*0.9));
          s:=copy(floattostr((max-min)/PinNum*j+min),0,NumLen);
          tx:=TextWidth(s);
          TextOut(SX+SSize+round(px*0.75)-tx div 2,SY+SSize+round(py*0.75)-ty div 2,s);
          if j>0 then begin
            val:=(kon-nach)/PinNum*(j-0.5)+nach;
            px:=cos(val)*SSize;
            py:=sin(val)*SSize;
            MoveTo(SX+SSize+round(px),SY+SSize+round(py));
            LineTo(SX+SSize+round(px*0.95),SY+SSize+round(py*0.95));
           end;
         end;
        Ellipse(SX+SSize-SSize div 10,SY+SSize-SSize div 10,SX+SSize+SSize div 10,SY+SSize+SSize div 10);
        s:=Name;
        tx:=TextWidth(s) div 2;
        TextOut(SX+SSize-tx,SY+SSize-ty-SSize div 10,s);

        Pen.Width:=round(SSize * 0.03);
        Pen.Color:=$0000FF;
        if Trevoga then
          if not TrevogaLow then
            if nach<kon then
              Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(kon)*100),SY+SSize+round(sin(kon)*100),SX+SSize+round(cos(rl)*100),SY+SSize+round(sin(rl)*100))
            else
              Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(rl)*100),SY+SSize+round(sin(rl)*100),SX+SSize+round(cos(kon)*100),SY+SSize+round(sin(kon)*100))
          else
            if nach>kon then
              Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(nach)*100),SY+SSize+round(sin(nach)*100),SX+SSize+round(cos(rl)*100),SY+SSize+round(sin(rl)*100))
            else
              Arc(SX,SY,SX+SSize*2+1,SY+SSize*2+1,SX+SSize+round(cos(rl)*100),SY+SSize+round(sin(rl)*100),SX+SSize+round(cos(nach)*100),SY+SSize+round(sin(nach)*100))
       end;

      1: begin
        s:=Name;
        TextOut(SX,SY,s);
        if not revers then begin
          nach:= SSize*2-ty*0.5;
          kon:= ty*2.5;
         end else begin
          kon:= SSize*2-ty*0.5;
          nach:= ty*2.5;
         end;
        MoveTo(SX+round(SSize*0.13),SY+round(nach));
        LineTo(SX+round(SSize*0.13),SY+round(kon));
        for j:=0 to PinNum do begin
          val:=(kon-nach)/PinNum*j+nach;
          MoveTo(SX+round(SSize*0.13),SY+round(val));
          LineTo(SX+round(SSize*0.20),SY+round(val));
          s:=copy(floattostr((max-min)/PinNum*j+min),0,NumLen);
          TextOut(SX+round(SSize*0.23),SY+round(val)-ty div 2,s);
          if j<PinNum then begin
            val:=(kon-nach)/PinNum*(j+0.5)+nach;
            MoveTo(SX+round(SSize*0.13),SY+round(val));
            LineTo(SX+round(SSize*0.17),SY+round(val));
           end;
         end;
        Pen.Width:=round(SSize * 0.03);
        Pen.Color:=$0000FF;
        if Trevoga then
          if not TrevogaLow then begin
            MoveTo(SX+round(SSize*0.13),SY+round(rl));
            LineTo(SX+round(SSize*0.13),SY+round(kon));
           end else begin
            MoveTo(SX+round(SSize*0.13),SY+round(rl));
            LineTo(SX+round(SSize*0.13),SY+round(nach));
           end;

       end;

      2: begin
        s:=Name;
        TextOut(SX,SY,s);
       end;

      4: begin
        if FileExists('.\icons\'+name+'.bmp') then begin
          FileBit:=TBitMap.Create;
          FileBit.LoadFromFile('.\icons\'+name+'.bmp');
          TempBit:=TBitMap.Create;
          MaskBit:=TBitMap.Create;
          TempBit.Height:=round(FileBit.Height/FileBit.Width*SSize*0.3);
          TempBit.Width:=round(SSize*0.3);
          MaskBit.Width:=TempBit.Width;
          MaskBit.Height:=TempBit.Height;
          OnBit:=TBitMap.Create;
          OffBit:=TBitMap.Create;
          OnBit.Width:=TempBit.Width;
          OnBit.Height:=TempBit.Height;
          OffBit.Width:=TempBit.Width;
          OffBit.Height:=TempBit.Height;
          TempBit.Canvas.StretchDraw(rect(0,0,TempBit.Width,TempBit.Height),FileBit);
          MaskBit.Canvas.StretchDraw(rect(0,0,TempBit.Width,TempBit.Height),FileBit);
          MaskBit.Mask(0);
          bitblt(OnBit.Canvas.Handle,0,0,TempBit.Width,TempBit.Height,PribBackMap.Canvas.Handle,SX,SY,srccopy);
          bitblt(OffBit.Canvas.Handle,0,0,TempBit.Width,TempBit.Height,PribBackMap.Canvas.Handle,SX,SY,srccopy);
          bitblt(OnBit.Canvas.Handle,0,0,TempBit.Width,TempBit.Height,MaskBit.Canvas.Handle,0,0,srcand);
          bitblt(OnBit.Canvas.Handle,0,0,TempBit.Width,TempBit.Height,TempBit.Canvas.Handle,0,0,srcpaint);
          bitblt(OffBit.Canvas.Handle,0,0,TempBit.Width,TempBit.Height,MaskBit.Canvas.Handle,0,0,srcand);
          FileBit.Free;
          TempBit.Free;
          MaskBit.Free;
         end else vid:=3;
       end;
     end;
   end;
  Data.Clock.SSize:=round(Image1.Width/400*Data.Clock.Size);
  Data.Clock.SX:=round(Image1.Width/400*Data.Clock.X);
  Data.Clock.SY:=round(Image1.Width/400*Data.Clock.Y);
end;

procedure TForm1.DrawPrib;
var i,tx,ty:integer; val:real; s:string;
begin
bitblt(PribTempMap.Canvas.Handle,0,0,Image1.Width,Image1.Height,PribBackMap.Canvas.Handle,0,0,srccopy);
with Data do with PribTempMap.Canvas do
 for i:=0 to PriborCout-1 do
  with Pribors[i] do begin
    Font.Height:=round(SSize*0.20);
    Font.Color:=TextColor;
    Pen.Color:=StrelkaColor;
    Pen.Width:=round(SSize * 0.04);
    s:=floattostrf(PribValues[i],fffixed,7,2);
    val:=(kon-nach)/(max-min)*(PribValues[i]-min)+nach;
    if PribValues[i]>max then val:=kon;
    if PribValues[i]<min then val:=nach;
    case Vid of
      0: begin
        tx:=TextWidth(s) div 2;
        TextOut(SX+SSize-tx,SY+SSize+SSize div 10,s);
        MoveTo(SX+SSize+round(cos(val+pi)*SSize*0.2),SY+SSize+round(sin(val+pi)*SSize*0.2));
        LineTo(SX+SSize+round(cos(val)*SSize*0.9),SY+SSize+round(sin(val)*SSize*0.9));
       end;

      1: begin
        ty:=TextHeight(s);
        TextOut(SX,SY+ty,s);
        MoveTo(SX,SY+round(val-SSize*0.03));
        LineTo(SX+round(SSize*0.13),SY+round(val));
        LineTo(SX,SY+round(val+SSize*0.03));
       end;
      2: begin
        ty:=TextHeight(s);
        if Trev then
          Font.Color:=$0000ff;
        TextOut(SX,SY+ty,s);
       end;
      3: begin
        if Trev then
          Font.Color:=$0000ff;
        s:=Name;
        TextOut(SX,SY,s);
       end;
      4: begin
        if Trev then
          bitblt(PribTempMap.Canvas.Handle,SX,SY,OnBit.Width,OnBit.Height,OnBit.Canvas.Handle,0,0,srccopy)
        else
          bitblt(PribTempMap.Canvas.Handle,SX,SY,OffBit.Width,OffBit.Height,OffBit.Canvas.Handle,0,0,srccopy)
       end;
   end;
 end;

if Data.Clock.Visible then begin
  PribTempMap.Canvas.Font.Color:=Data.Clock.Color;
  PribTempMap.Canvas.Font.Size:=round(Data.Clock.SSize*0.13);
  PribTempMap.Canvas.TextOut(Data.Clock.SX,Data.Clock.SY,timetostr(time));
 end;
bitblt(Image1.Canvas.Handle,0,0,Image1.Width,Image1.Height,PribTempMap.Canvas.Handle,0,0,srccopy);
Image1.Refresh;
end;


Procedure TLog.Add(hvalue:byte; value:real);
var center,Size:integer; s:string;
begin
center:=Height-round(Height/(max-min)*(-min));
Picture.Bitmap.Width:=Width;
Picture.Bitmap.Height:=Height;
Picture.Bitmap.Canvas.Draw(-1,0,Picture.Bitmap);
picture.Bitmap.Canvas.MoveTo(Width-1,0);
Picture.Bitmap.Canvas.FillRect(Bounds(Width-1,0,1,Height));
Picture.Bitmap.Canvas.MoveTo(Width-1,center);
Picture.Bitmap.Canvas.LineTo(Width-1,center-round(Height/(max-min)*value));
Picture.Bitmap.Canvas.FillRect(Bounds(Width-1,0,1,1));
Size:=Picture.Bitmap.Canvas.Font.Height;
Picture.Bitmap.Canvas.FillRect(Bounds(0,0,size*4,size*3));
Picture.Bitmap.Canvas.TextOut(0,0,Name);
s:=floattostrf(value,fffixed,5,2);
Picture.Bitmap.Canvas.TextOut(Size*4-Canvas.TextWidth(s),Size,s);
s:=inttostr(hvalue);
Picture.Bitmap.Canvas.TextOut(Size*3-Canvas.TextWidth(s),Size*2,s);
end;

Procedure TCommThread.Execute;
var
  temp:dword;
  comstat : TComStat;
  dcb: TDCB;
Begin
  N:=0;

  COMport:= CreateFile(PortSt,GENERIC_READ or GENERIC_WRITE, 0, NiL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
  dcb.DCBlength:= sizeof(DCB);
  GetCommState(COMport, dcb);
  dcb.BaudRate:= CBR_9600;
  dcb.ByteSize := 8;
  dcb.Parity := 0;
  dcb.StopBits := 0;
  SetCommState(COMport, dcb);
  SetCommMask(COMport,EV_RXCHAR);
  SetupComm(COMport,255,255);
  overlapped.hEvent:= CreateEvent(NiL, true, true, '');

  Repeat
    WaitCommEvent(COMport, temp, @overlapped);               	//ожидать события приёма байта (это и есть перекрываемая операция)
    WaitForSingleObject(overlapped.hEvent, INFINITE);
    if terminated then break;
    ClearCommError(COMport, temp, @comstat);
    if comstat.cbInQue >= NBufferLength+PreambSize+3  then
      begin
        sleep(0);
        ReadFile(COMport, BufRd, comstat.cbInQue, temp, @overlapped);
        Synchronize(AssBuff);
        WriteToPort;
      end;
  Until Terminated;
End;

Procedure TCommThread.AssBuff;
begin
  move(BufRd[PreambSize+2],form1.Buffer[NBufferOffset],NBufferLength);
  if N >=BufCout-1 then
    begin
      PostMessage(Form1.Handle,WM_User+1000,0,0);
      N:=0;
    end else Inc(N);
  NBufferOffset:= form1.Data.Buffers[N].Offset;
  NBufferLength:= form1.Data.Buffers[N].BufferLength;
  Form1.Timer1.Enabled:=false;
  Form1.Timer1.Enabled:=true;
end;

Procedure TCommThread.WriteToPort;
var
  temp:dword;
  BufWd: array [0..4] of byte;
begin
        PurgeComm(COMport, PURGE_RXCLEAR);
        BufWd[0]:=$20;
        BufWd[1]:=$05;
        BufWd[2]:=NBufferOffset;
        BufWd[3]:=NBufferLength;
        BufWd[4]:=-(bufwd[0]+bufwd[1]+bufwd[2]+bufwd[3]);
        WriteFile(COMport, BufWd, 5, temp, @overlapped);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
begin
  CommThread.WriteToPort;
{  for i:=0 to high(buffer) do
    buffer[i]:=random(255);//TrackBar1.Position;
  PostMessage(Form1.Handle,WM_User+1000,0,0); }
end;

procedure TForm1.LogPrint(var Msg: TMessage);
var
  i,j,b:byte; r:real; t:single;
begin
          t:=time;
          if DoRec then
            begin
              rec:=rec+chr(hourof(t));
              rec:=rec+chr(minuteof(t));
              rec:=rec+chr(secondof(t));
              rec:=rec+chr(round(millisecondof(t)/5));
              for j:=0 to $6F do
                rec:=rec+chr(Buffer[j]);
              TabSheet1.Highlighted:= not TabSheet1.Highlighted;
            end;

  for i:=0 to Data.LogCout-1 do
    begin
      for j:=0 to Data.Logs[i].PeremsCout-1 do
        Data.LogsFormuls[i].DS[j]:=Buffer[Data.Logs[i].perems[j].offset];
      r:=Data.LogsFormuls[i].proc;
      Data.LogValues[i]:=r;
      b:=Buffer[Data.Logs[i].perems[high(Data.Logs[i].perems)].offset];
      Data.Logs[i].Add(b,r);
    end;
if PageControl1.TabIndex = 1 then begin
  ScrollBox2.Color:=ScrollBox1.Color;
  for i:=0 to Data.PriborCout-1 do
    begin
      for j:=0 to Data.LogCout-1 do
        Data.PriborFormuls[i].DS[j]:=Data.LogValues[j];
      Data.PribValues[i]:=Data.PriborFormuls[i].proc;
      Data.Pribors[i].Trev:=false;
      if (Data.Pribors[i].Trevoga) and ((Data.PribValues[i]>Data.Pribors[i].TrevogaPoz)<>Data.Pribors[i].TrevogaLow) then begin
         if Data.Pribors[i].TrevSwich then
          ScrollBox2.Color:=Data.Pribors[i].TrevSwichedCol;
         Data.Pribors[i].Trev:=true;
        end;
    end;
  DrawPrib;
 end;
end;

procedure TForm1.FormDblClick(Sender: TObject);
begin
  Recording;
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if key='r' then Recording;
end;

procedure TForm1.Recording;
var
  l:textfile;
begin
if dorec then
  begin
    AssignFile(l,extractfilepath(Application.ExeName)+'logs\'+datetostr(now)+'-'+inttostr(hourof(now))+inttostr(minuteof(now))+inttostr(secondof(now))+'.xlg');
    Rewrite(l);
    write(l,rec);
    CloseFile(l);
    DoRec:=false;
    rec:='';
    TabSheet1.Highlighted:=false;
    TabSheet1.Caption:='Графики';
  end else
  begin
    TabSheet1.Caption:='ЗАПИСЬ ЛОГА';
    rec:='';
    DoRec:=true;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  IniFile: TIniFile;
  i,j: byte;
  PeremList,PeremListPr: TStringList;
begin
  IniFile:= TIniFile.Create(ExtractFilePath(Application.ExeName)+'set.ini');

  if IniFile.ReadBool('настройки','на_весь_экран',false) then
    begin
      Form1.FormStyle:=fsStayOnTop;
      Form1.WindowState:=wsMaximized;
      Form1.BorderStyle:=bsNone;
    end;
  Form1.ScrollBox1.Color:= IniFile.ReadInteger('настройки','цвет_фона',clBtnFace);
  Form1.ScrollBox2.Color:= Form1.ScrollBox1.Color;
  Timer1.Interval:=IniFile.ReadInteger('настройки','таймаут_отв',1000);

  Data.BuffersCout:= IniFile.ReadInteger('настройки','кол-во_областей',1);
  SetLength(Data.Buffers, Data.BuffersCout);
  for j:=0 to Data.BuffersCout-1 do
    begin
      Data.Buffers[j].Offset:= IniFile.ReadInteger('области','смещение_'+inttostr(j),$00);
      Data.Buffers[j].BufferLength:= IniFile.ReadInteger('области','размер_'+inttostr(j),$01);
    end;

  PeremList:= TStringList.Create;
  PeremListPr:= TStringList.Create;

  Data.LogCout:= IniFile.ReadInteger('настройки','кол-во_логов',1);
  SetLength(Data.Logs, Data.LogCout);
  SetLength(Data.LogsFormuls, Data.LogCout);
  for i:=0 to Data.LogCout-1 do
    begin
     Data.Logs[i]:= TLog.Create(self);
     Data.Logs[i].PeremsCout:= IniFile.ReadInteger('логер_'+inttostr(i),'кол-во_перем',1);
     SetLength(Data.Logs[i].Perems, Data.Logs[i].PeremsCout);
     PeremList.Clear;
     if Data.Logs[i].PeremsCout>0 then
     for j:=0 to Data.Logs[i].PeremsCout-1 do
       begin
         Data.Logs[i].Perems[j].Name:= IniFile.ReadString('логер_'+inttostr(i),'переменная_'+inttostr(j),'p'+inttostr(j));
         Data.Logs[i].Perems[j].Offset:= IniFile.Readinteger('логер_'+inttostr(i),'отступ_пер_'+inttostr(j),$ff);
         PeremList.Add(Data.Logs[i].Perems[j].Name);
       end;
     CodeBuild(Data.LogsFormuls[i],IniFile.ReadString('логер_'+inttostr(i),'формула','0'),PeremList);
     Data.Logs[i].Parent:= Form1.ScrollBox1;
     Data.Logs[i].Height:= IniFile.ReadInteger('логер_'+inttostr(i),'высота',150);
     Data.Logs[i].Align:= AlTop;
     Data.Logs[i].Enabled:= false;
     Data.Logs[i].Name:=IniFile.ReadString('логер_'+inttostr(i),'название','датчик'+inttostr(i));
     Data.Logs[i].Max:= IniFile.ReadInteger('логер_'+inttostr(i),'макс_знач',100);
     Data.Logs[i].Min:= IniFile.ReadInteger('логер_'+inttostr(i),'мин_знач',0);
     Data.Logs[i].Picture.Bitmap.Canvas.Pen.Color:= IniFile.ReadInteger('логер_'+inttostr(i),'цвет',$ff0000);
     Data.Logs[i].Picture.Bitmap.Canvas.Brush.Color:= IniFile.ReadInteger('настройки','цвет_фона',clBtnFace);
     Data.Logs[i].Picture.Bitmap.Canvas.Font.Color:= IniFile.ReadInteger('настройки','цвет_шрифта',clred);
     Data.Logs[i].Picture.Bitmap.Canvas.Font.Height:= IniFile.ReadInteger('настройки','размер_шрифта',10);
     Data.Logs[i].Picture.Bitmap.Canvas.Font.Style:=[fsBold];
     Data.Logs[i].Picture.Bitmap.Canvas.Font.Name:='Arial';
     Data.Logs[i].add(0,0);
     PeremListPr.Add(IniFile.ReadString('логер_'+inttostr(i),'Имя_перем',''));
    end;
  PeremList.Free;


  Data.PriborCout:= IniFile.ReadInteger('настройки','кол-во_приборов',1);
  SetLength(Data.Pribors, Data.PriborCout);
  SetLength(Data.PriborFormuls, Data.PriborCout);
  for i:=0 to Data.PriborCout-1 do
    begin
      Data.Pribors[i].Name:=IniFile.ReadString('Прибор_'+inttostr(i),'Название','NoName');
      Data.Pribors[i].Vid:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Вид',0);
      Data.Pribors[i].Formula:=IniFile.ReadString('Прибор_'+inttostr(i),'Формула','');
      CodeBuild(Data.PriborFormuls[i],Data.Pribors[i].Formula,PeremListPr);
      Data.Pribors[i].Size:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Размер',50);
      Data.Pribors[i].X:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Х',50);
      Data.Pribors[i].Y:=IniFile.ReadInteger('Прибор_'+inttostr(i),'У',50);
      Data.Pribors[i].Max:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Максимум',50);
      Data.Pribors[i].Min:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Минимум',0);
      Data.Pribors[i].PinNum:=IniFile.ReadInteger('Прибор_'+inttostr(i),'ГрадацияШк',50);
      Data.Pribors[i].NumLen:=IniFile.ReadInteger('Прибор_'+inttostr(i),'Кол-воЦиврШк',50);
      Data.Pribors[i].StartCone:=IniFile.ReadInteger('Прибор_'+inttostr(i),'НачУгол',50);
      Data.Pribors[i].EndCone:=IniFile.ReadInteger('Прибор_'+inttostr(i),'КонУгол',50);
      Data.Pribors[i].Horiz:=IniFile.ReadBool('Прибор_'+inttostr(i),'Горизонтальный',false);
      Data.Pribors[i].Revers:=IniFile.ReadBool('Прибор_'+inttostr(i),'Реверс',false);
      Data.Pribors[i].ShkalaColor:=IniFile.ReadInteger('Прибор_'+inttostr(i),'ЦветШк',50);
      Data.Pribors[i].StrelkaColor:=IniFile.ReadInteger('Прибор_'+inttostr(i),'ЦветСтр',50);
      Data.Pribors[i].TextColor:=IniFile.ReadInteger('Прибор_'+inttostr(i),'ЦветТекст',50);
      Data.Pribors[i].Trevoga:=IniFile.ReadBool('Прибор_'+inttostr(i),'Тревога',false);
      Data.Pribors[i].TrevogaLow:=IniFile.ReadBool('Прибор_'+inttostr(i),'ТревогаНиже',false);
      Data.Pribors[i].TrevogaPoz:=IniFile.ReadFloat('Прибор_'+inttostr(i),'ТревогаУровень',10);
      Data.Pribors[i].TrevSwich:=IniFile.ReadBool('Прибор_'+inttostr(i),'ТревогаМенятьЦвет',false);
      Data.Pribors[i].TrevSwichedCol:=IniFile.ReadInteger('Прибор_'+inttostr(i),'ТревогаЦвет',50);
   end;

   SetLength(Data.LogValues, Data.LogCout);
   SetLength(Data.PribValues, Data.PriborCout);

   PeremListPr.Free;
   DoRec:= false;
   PribBackMap:=TBitMap.Create;
   PribTempMap:=TBitMap.Create;
   PribTempMap.Canvas.Font.Name:='Arial';
   PribTempMap.Canvas.Brush.Style:=bsClear;
   Data.Clock.Size:=IniFile.ReadInteger('Часы','Размер',50);
   Data.Clock.X:=IniFile.ReadInteger('Часы','Х',50);
   Data.Clock.Y:=IniFile.ReadInteger('Часы','У',50);
   Data.Clock.Color:=IniFile.ReadInteger('Часы','Цвет',50);
   Data.Clock.Visible:=IniFile.ReadBool('Часы','Отображать',false);
   TabSheet2Resize(self);

  for i:=0 to $6f do
    buffer[i]:=0;

  CommThread:=TCommThread.Create(true);
  CommThread.BufCout:=Data.BuffersCout;
  CommThread.NBufferLength:=Data.Buffers[0].BufferLength;
  CommThread.PortSt:=PChar(IniFile.ReadString('настройки','порт','com1'));
  if IniFile.ReadBool('настройки','преамбула',true) then CommThread.PreambSize:=5 else CommThread.PreambSize:=0;
  CommThread.Resume;
  IniFile.Free;
  sleep(10);
  CommThread.WriteToPort;
end;


procedure TForm1.ScrollBox1MouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
if PageControl1.TabIndex = 0 then
  ScrollBox1.VertScrollBar.Position:=ScrollBox1.VertScrollBar.Position-WheelDelta div 5
else
  ScrollBox2.VertScrollBar.Position:=ScrollBox2.VertScrollBar.Position-WheelDelta div 5;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form1.Close;
end;

procedure TForm1.TabSheet2Resize(Sender: TObject);
begin
Image1.Left:=20;
Image1.Top:=20;
Image1.Width:=ScrollBox2.ClientWidth-40;
Image1.Height:=Image1.Width div 4 * 3;
Image1.Width:=ScrollBox2.ClientWidth-40;
Image1.Height:=Image1.Width div 4 * 3;
DrawPribBack;
bitblt(Image1.Canvas.Handle,0,0,Image1.Width,Image1.Height,PribBackMap.Canvas.Handle,0,0,srccopy);
end;

end.
