unit MainForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ToolWin, ComCtrls, Grids, HexGrid, Buttons, ExtCtrls, jpeg, Menus,
  ActnList, ImgList, Placemnt, MRUList, CommInt, StdCtrls, Mask, ToolEdit,
  ComboDigEdit, CRC, DevicesFrame;
const
    MainFormCaption = 'Alt-Prog: ';

    BaudR: array[TBaudRate] of String =
     ('110', '300', '600', '1200', '2400', '4800', '9600', '14400',
      '19200', '38400', '56000', '57600', '115200', '128000', '256000');
    lParity:array[TParity] of string = ('None', 'Odd', 'Even', 'Mark', 'Space');
    lStopbits:array[TStopbits] of string = ('1', '1.5', '2');
    lDatabits:array[TDatabits] of string = ('4', '5', '6', '7', '8');
    lFlowControl:array[TFlowControl] of string = ('None', 'CTS', 'DTR', 'Software', 'Default', 'AltProg (CTS,DTR)');



type
  TActionProc = procedure(Addr:Cardinal) of object;

  DFTypes = (dftHEX,dftBin);



type
  PDataBuf = ^TDataBuf;
  TDataBuf = record
    Count:Cardinal;
    data:array[0..MaxdataCount] of Byte;
  end;

  TfrmDeviceClass = class of TfrmDevice;

  TConstructorType = record
   name:string;               // Имя класса программируемых микросхем
//   ID:integer;                // Идентификатор класса в программаторе
   ClassName:TfrmDeviceClass; // Класс формы
  end;

  TfrmMain = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Open1: TMenuItem;
    Save1: TMenuItem;
    Settings1: TMenuItem;
    ActionList: TActionList;
    OpenFile: TAction;
    SaveFile: TAction;
    Exit: TAction;
    Edit: TAction;
    Exit2: TMenuItem;
    N1: TMenuItem;
    ImageList1: TImageList;
    SaveDialog: TSaveDialog;
    OpenDialog: TOpenDialog;
    GridSettings: TAction;
    Gridsettings1: TMenuItem;
    ToolBar1: TToolBar;
    tbEdit: TToolButton;
    tbBIN: TToolButton;
    tbHEX: TToolButton;
    tbDEC: TToolButton;
    StatusBar: TStatusBar;
    FormStorage1: TFormStorage;
    ToolButton2: TToolButton;
    tbASCII: TToolButton;
    tb8: TToolButton;
    tb16: TToolButton;
    ToolButton1: TToolButton;
    MRUManager: TMRUManager;
    CommPort: TComm;
    CommPortSettings: TAction;
    Commportsettings1: TMenuItem;
    mnDevices: TMenuItem;
    Panel1: TPanel;
    Splitter1: TSplitter;
    PageControl: TPageControl;
    tsEditing: TTabSheet;
    Panel2: TPanel;
    Label1: TLabel;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    SpeedButton6: TSpeedButton;
    SpeedButton7: TSpeedButton;
    SpeedButton8: TSpeedButton;
    rgRange: TRadioGroup;
    GroupBox1: TGroupBox;
    Label2: TLabel;
    Label3: TLabel;
    DeviceClose: TAction;
    Deviceclose1: TMenuItem;
    edConstant: TComboDigEdit;
    edBegin: TComboDigEdit;
    edEnd: TComboDigEdit;
    GroupBox2: TGroupBox;
    sbCalculateCRC: TSpeedButton;
    edCount: TComboDigEdit;
    Label4: TLabel;
    GotoAddr: TAction;
    About1: TMenuItem;
    About: TAction;
    sbUpdateGridRange: TSpeedButton;
    cbCRC: TComboBox;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    CodeGrid: THexGrid;
    TabSheet2: TTabSheet;
    EEPROMGrid: THexGrid;
    UpdateToolBar: TAction;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    Search: TAction;
    PopupMenu1: TPopupMenu;
    Goto1: TMenuItem;
    Gridsettings2: TMenuItem;
    Search1: TMenuItem;
    ToolButton3: TToolButton;
    DoGoToAddr: TAction;
    DoSearch: TAction;
    DoSearchNext: TAction;
    edCRC: TEdit;
    CRC1: TCRC;
    Label5: TLabel;
    Label6: TLabel;
    tshDevice: TTabSheet;
    DeviceOpen: TAction;
    actPerfomanceTest: TAction;
    PerfomanceCounterTest1: TMenuItem;
    procedure EditExecute(Sender: TObject);
    procedure OpenFileExecute(Sender: TObject);
    procedure SaveFileExecute(Sender: TObject);
    procedure GridSettingsExecute(Sender: TObject);
    procedure tbBINClick(Sender: TObject);
    procedure tbHEXClick(Sender: TObject);
    procedure tbDECClick(Sender: TObject);
    procedure tbASCIIClick(Sender: TObject);
    procedure tb8Click(Sender: TObject);
    procedure tb16Click(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure SaveAsExecute(Sender: TObject);
    procedure MRUManagerClick(Sender: TObject; const RecentName,
      Caption: String; UserData: Integer);
    procedure FormCreate(Sender: TObject);
    procedure ExitExecute(Sender: TObject);
    procedure CommPortSettingsExecute(Sender: TObject);
    procedure FormStorage1RestorePlacement(Sender: TObject);
    procedure ClickEditAction(Sender: TObject);
    procedure sbUpdateGridRangeClick(Sender: TObject);
    procedure DeviceCloseExecute(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure edExit(Sender: TObject);
    procedure edKeyPress(Sender: TObject; var Key: Char);
    procedure GotoAddrExecute(Sender: TObject);
    procedure AboutExecute(Sender: TObject);
    procedure TabSheet2Show(Sender: TObject);
    procedure TabSheet1Show(Sender: TObject);
    procedure UpdateToolBarExecute(Sender: TObject);
    procedure SearchExecute(Sender: TObject);
    procedure DoGoToAddrExecute(Sender: TObject);
    procedure Searching(StrtIndex:Integer);
    procedure DoSearchExecute(Sender: TObject);
    procedure DoSearchNextExecute(Sender: TObject);
    procedure sbCalculateCRCClick(Sender: TObject);
    procedure DeviceOpenExecute(Sender: TObject);
    procedure actPerfomanceTestExecute(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    FWorkFileName:String;
    FSaveRequire:boolean;
    FActionProg: TActionProc;
    Constant:word;
    procedure SaveWorkFile;
    Procedure OpenWorkFile(FName:String;dft:DFTypes);

    procedure ActionFill(Addr:Cardinal);
    procedure ActionAnd(Addr:Cardinal);
    procedure ActionOr(Addr:Cardinal);
    procedure ActionXor(Addr:Cardinal);
    procedure ActionAdd(Addr:Cardinal);
    procedure ActionSub(Addr:Cardinal);
    procedure ActionMul(Addr:Cardinal);
    procedure ActionDiv(Addr:Cardinal);

    procedure DoActionAll;
    procedure DoActionSelection;
    procedure DoActionRange;

    { Private declarations }
  public
    FGotoForm:TForm;
    FSearchForm:TForm;
    FDeviceForm:TForm;
    FEditingForm:TForm;
    HexGrid: THexGrid;      //текущая активная сетка данных
    LoFirstOrder:boolean;   // Указатель на порядок расположения байт в слове в файле
    procedure UpdateStatusBar;
    procedure UpdateEdits;
  end;

var
  frmMain: TfrmMain;
  ConstructorsList:array of TConstructorType;


implementation

uses GridSettings, RUtilites, PortSettings, SendThread,
     About,  GoToForm, SearchForm, CreateMenu, PerfomanceTest;

{$R *.DFM}

procedure TfrmMain.FormCreate(Sender: TObject);
var i:integer;


begin
  Caption:=MainFormCaption+ 'New';
  HexGrid:=CodeGrid;
  LoFirstOrder:=false;
  for i:=0 to High(StandartCRCModels) do
    cbCRC.Items.Add(StandartCRCModels[i].name);

  BuildDevMenu;
  CalibrConst:=DelayCalibrating; // Вычислить калибровочную константу
end;

procedure TfrmMain.DeviceOpenExecute(Sender: TObject);
begin
  PageControl.ActivePage:=tshDevice;
  DeviceCloseExecute(nil);
  StartConstructor(TMenuItem(Sender).Name);
  FormStorage1.WriteString('DefaultDevice',TMenuItem(Sender).Name);
end;

procedure TfrmMain.DeviceCloseExecute(Sender: TObject);
var i:integer;
begin
  for  i:=0 to tshDevice.ControlCount-1 do
  begin
    tshDevice.Controls[i].Free;
  end;
end;

procedure TfrmMain.FormStorage1RestorePlacement(Sender: TObject);
begin
  UpdateToolBarExecute(Self);
  UpdateStatusBar;
  UpdateEdits;
end;


procedure TfrmMain.TabSheet2Show(Sender: TObject);
begin
  HexGrid:=EEPROMGrid;
  UpdateStatusBar;
  UpdateEdits;
  UpdateToolBarExecute(Self);
end;

procedure TfrmMain.TabSheet1Show(Sender: TObject);
begin
  HexGrid:=CodeGrid;
  UpdateStatusBar;
  UpdateEdits;
  UpdateToolBarExecute(Self);
end;


procedure TfrmMain.EditExecute(Sender: TObject);
begin
  if goEditing in HexGrid.Options  then
  begin
    HexGrid.Options:=HexGrid.Options-[goAlwaysShowEditor]-[goEditing];
 //   Edit1.Caption:='Edit enable';
  end
  else
  begin
    HexGrid.Options:=HexGrid.Options+[goAlwaysShowEditor]+[goEditing];
 //   Edit1.Caption:='Edit disable';
  end;
  HexGrid.Invalidate;
end;


procedure TfrmMain.GridSettingsExecute(Sender: TObject);
begin
  with TfrmGridsettings.Create(Self) do
  begin
    InitForm(HexGrid);
    Showmodal;
    Free;
  end;
end;

procedure TfrmMain.tbBINClick(Sender: TObject);
begin
  HexGrid.ViewMode:=vmBIN;
end;

procedure TfrmMain.tbHEXClick(Sender: TObject);
begin
  HexGrid.ViewMode:=vmHEX;
end;

procedure TfrmMain.tbDECClick(Sender: TObject);
begin
  HexGrid.ViewMode:=vmDEC;
end;

procedure TfrmMain.tbASCIIClick(Sender: TObject);
begin
  HexGrid.ViewMode:=vmASCII;
end;

procedure TfrmMain.tb8Click(Sender: TObject);
begin
  HexGrid.DataSize:=dsByte
end;

procedure TfrmMain.tb16Click(Sender: TObject);
begin
  HexGrid.DataSize:=dsWord
end;

procedure TfrmMain.ToolButton1Click(Sender: TObject);
var w:Longint;
begin
  w:=HexGrid.ColWidths[0];
  HexGrid.DefaultColWidth:= Trunc((HexGrid.ClientWidth-w-10)/HexGrid.GridColCount);
  HexGrid.ColWidths[0]:=w
end;







Procedure TfrmMain.OpenWorkFile(FName:String;dft:DFTypes);
begin
 case  dft of
  dftBin: LoadBinFile(FName,HexGrid);
  dftHEX: LoadHexFile(FName,HexGrid,LoFirstOrder);
 end;

 MRUManager.Add(FName,Integer(dft));
 FWorkFileName:=FName;
 FSaveRequire:=false;
 Caption:=MainFormCaption+ FWorkFileName;
 HexGrid.Invalidate;
 UpdateStatusBar;
 UpdateEdits;
end;


procedure TfrmMain.OpenFileExecute(Sender: TObject);
begin
  if OpenDialog.Execute then
    case  OpenDialog.FilterIndex of
     1: OpenWorkFile(OpenDialog.FileName,dftBIN);
     2: OpenWorkFile(OpenDialog.FileName,dftHEX);
    end;
end;

procedure TfrmMain.SaveWorkFile;
begin
  if SaveDialog.Execute then
  begin
    if  LowerCase(ExtractFileExt(saveDialog.FileName))='.hex' then
      SaveHexFile(SaveDialog.FileName,HexGrid)
    else
      SaveBinFile(SaveDialog.FileName,HexGrid);
    MRUManager.Add(SaveDialog.FileName,0);
    FWorkFileName:=SaveDialog.FileName;
    FSaveRequire:=false;
    Caption:=MainFormCaption+ FWorkFileName;
  end;
  UpdateStatusBar;
end;

procedure TfrmMain.SaveFileExecute(Sender: TObject);
begin
  saveDialog.FileName:=FWorkFileName;
  SaveWorkFile;
end;

procedure TfrmMain.SaveAsExecute(Sender: TObject);
begin
  saveDialog.FileName:='';
  SaveWorkFile;
end;

procedure TfrmMain.MRUManagerClick(Sender: TObject; const RecentName,
  Caption: String; UserData: Integer);
begin
  OpenWorkFile(RecentName,DFTypes(UserData));
end;

procedure TfrmMain.GotoAddrExecute(Sender: TObject);
begin
   if FGoToForm=Nil then
     FGoToForm:=TfrmGoTo.Create(Self);
   TfrmGoTo(FGoToForm).bbGoto.OnClick:=DoGoToAddrExecute;
   FGoToForm.Show;

end;

procedure TfrmMain.DoGoToAddrExecute(Sender: TObject);
var adr:Integer;
    col,row:integer;
begin
  adr:=TfrmGoTo(FGoToForm).edGotoAddr.Value;
  if (adr<Integer(HexGrid.BegAddr)) or
      (adr>Integer(HexGrid.BegAddr+Cardinal(HexGrid.DataCount)-1))  then
  begin
    MessageDlg('Address out of range',mtWarning,[mbAbort],0);
    Abort
  end;
  col:=((adr-LongInt(hexgrid.BegAddr)) mod hexgrid.GridColCount)+1;
  row:=((adr-LongInt(hexgrid.BegAddr)) div hexgrid.GridColCount)+1;
  HexGrid.col:=Col;
  HexGrid.Row:=row;
end;

procedure TfrmMain.SearchExecute(Sender: TObject);
begin
  if FSearchForm=Nil then
    FSearchForm:=TfrmSearch.Create(Self);
  TfrmSearch(FSearchForm).bbFind.OnClick:=DoSearchExecute;
  TfrmSearch(FSearchForm).bbFindNext.OnClick:=DoSearchNextExecute;
  FSearchForm.Show;
end;

procedure TfrmMain.Searching(StrtIndex:Integer);
var vl:Word;
    i:Integer;
    col,row:integer;
    Searched:boolean;
begin
  Searched:=false;
  if HexGrid.DataSize=dsByte then
  begin
    vl:=Byte(TfrmSearch(FSearchForm).edValue.Value);
    if StrtIndex<>0 then StrtIndex:=StrtIndex+1 ;
    for i:=StrtIndex to HexGrid.DataCount-1 do
    begin
      if HexGrid.AData[i]=vl then
      begin
        col:=(i mod hexgrid.GridColCount)+1;
        row:=(i div hexgrid.GridColCount)+1;
        HexGrid.col:=col;
        HexGrid.row:=row;
        Searched:=true;
        Break;
      end
    end;
    if Not Searched then
      MessageDlg('Value not found!',mtWarning,[mbOk],0);
  end
  else
  begin
    vl:=Word(TfrmSearch(FSearchForm).edValue.Value);
    if StrtIndex<>0 then StrtIndex:=(StrtIndex div 2)+1;
    for i:=StrtIndex to (HexGrid.DataCount div 2)-1 do
    begin
      if (HexGrid.AData[i*2]*256+HexGrid.AData[i*2+1])=vl then
      begin
        col:=(i mod hexgrid.GridColCount)+1;
        row:=(i div hexgrid.GridColCount)+1;
        HexGrid.col:=col;
        HexGrid.row:=row;
        Searched:=true;
        Break;
      end
    end;
    if Not Searched then
      MessageDlg('Value not found!',mtWarning,[mbOk],0);
  end;
end;

procedure TfrmMain.DoSearchExecute(Sender: TObject);
begin
  Searching(0)
end;

procedure TfrmMain.DoSearchNextExecute(Sender: TObject);
begin
  Searching(HexGrid.GetDataIndex(HexGrid.Col,HexGrid.Row))
end;

procedure TfrmMain.AboutExecute(Sender: TObject);
begin
  with TfrmAbout.Create(Self) do
  begin
    Showmodal;
    Free;
  end;
end;

procedure TfrmMain.ExitExecute(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TfrmMain.CommPortSettingsExecute(Sender: TObject);
begin
  with  TfrmPortSettings.CreatePortSettings(Self,CommPort) do
  begin
    try
      ShowModal;
    finally
      Free;
      UpdateStatusBar;
    end;
  end;
end;


procedure TfrmMain.UpdateStatusBar;
var str:string;
begin
  with StatusBar do
  begin
    str:=CommPort.DeviceName;
    str:=str+'/'+BaudR[CommPort.BaudRate];
    str:=str+'/'+lParity[CommPort.Parity];
    str:=str+'/'+lStopBits[CommPort.StopBits];
    str:=str+'/'+lDataBits[CommPort.DataBits];
    str:=str+'  Flow control: '+lFlowControl[CommPort.Flowcontrol];
    if CommPort.Enabled then
      str:=str+'. Port open'
    else
      str:=str+'. Port close';
    panels[1].text:=str;

    str:='Size: '+IntToStr(HexGrid.DataCount)+' bytes';
    panels[0].text:=str;
  end;
end;

procedure TfrmMain.UpdateEdits;
begin
  edBegin.value:=HexGrid.BegAddr;
  if HexGrid.DataSize=dsWord then
    edEnd.value:=(HexGrid.DataCount div 2)-1
  else
    edEnd.value:=HexGrid.DataCount-1;
  edExit(edEnd);
  if (FDeviceForm<>Nil) and (HexGrid.name='CodeGrid')  then
  begin
//    TfrmDevice(FDeviceForm).edBufFrom.Value:=HexGrid.BegAddr;
//    TfrmDevice(FDeviceForm).edChipFrom.Value:=0;
    if HexGrid.DataSize=dsWord then
//      TfrmDevice(FDeviceForm).edChipTo.value:=(HexGrid.DataCount div 2)-1
    else
//      TfrmDevice(FDeviceForm).edChipTo.value:=HexGrid.DataCount-1
  end;
end;

procedure TfrmMain.UpdateToolBarExecute(Sender: TObject);
begin
  case HexGrid.DataSize of
  dsByte: tb8.Down:=true;
  dsWord: tb16.Down:=true;
  end;
  case HexGrid.ViewMode of
  vmHEX: tbHex.Down:=true;
  vmBIN: tbBIN.Down:=true;
  vmDEC: tbDEC.Down:=true;
  vmASCII: tbASCII.Down:=true;
  end;
  if HexGrid.EditorMode then
    tbEdit.Down:=true
  else
    tbEdit.Down:=false;
end;


procedure TfrmMain.ActionFill(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=Byte(Constant);
end;


procedure TfrmMain.ActionAnd(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) and Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=HexGrid.AData[Addr] and Byte(Constant);
end;

procedure TfrmMain.ActionOr(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) or Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=HexGrid.AData[Addr] or Byte(Constant);
end;

procedure TfrmMain.ActionXor(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) xor Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=HexGrid.AData[Addr] xor Byte(Constant);
end;

procedure TfrmMain.ActionSub(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) - Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=Byte(HexGrid.AData[Addr]-Byte(Constant));
end;

procedure TfrmMain.ActionAdd(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) + Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=Byte(HexGrid.AData[Addr]+Byte(Constant));
end;

procedure TfrmMain.ActionMul(Addr:Cardinal);
var F:integer;
begin
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) * Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=Byte(HexGrid.AData[Addr]*Byte(Constant));
end;

procedure TfrmMain.ActionDiv(Addr:Cardinal);
var F:Integer;
begin
  if Byte(Constant)<>0 then
    if HexGrid.DataSize=dsWord then
    begin
      F:=((HexGrid.AData[Addr] shl 8) or HexGrid.AData[Addr+1]) div Constant;
      HexGrid.AData[Addr]:=Hi(F);
      HexGrid.AData[Addr+1]:=Lo(F);
    end
    else
      HexGrid.AData[Addr]:=Byte(HexGrid.AData[Addr]div Byte(Constant));
end;

procedure TfrmMain.DoActionAll;
var i:cardinal;
begin
  for i:=0 to HexGrid.Datacount-1 do
    if HexGrid.DataSize=dsWord then
      FActionProg(i*2)
    else
      FActionProg(i);
  HexGrid.Invalidate;
end;

procedure TfrmMain.DoActionSelection;
var i,j:cardinal;
begin
  for j:=HexGrid.Selection.Top to HexGrid.Selection.Bottom do
    for i:=HexGrid.Selection.Left to HexGrid.Selection.Right do
      FActionProg(HexGrid.GetDataIndex(i,j));
  HexGrid.Invalidate;
end;

procedure TfrmMain.DoActionRange;
var begaddr,endaddr,i:cardinal;
begin
  begaddr:=edBegin.Value;
  endaddr:=edEnd.Value;
  for i:=begaddr to endaddr do
    if HexGrid.DataSize=dsWord then
      FActionProg(i*2)
    else
      FActionProg(i);
  HexGrid.Invalidate;
end;

procedure TfrmMain.ClickEditAction(Sender: TObject);
begin
  constant:=edConstant.Value;
  case TSpeedButton(Sender).Tag of
  1:FActionProg:=ActionFill;
  2:FActionProg:=ActionAnd;
  3:FActionProg:=ActionOr;
  4:FActionProg:=ActionXor;
  5:FActionProg:=ActionSub;
  6:FActionProg:=ActionAdd;
  7:FActionProg:=ActionMul;
  8:FActionProg:=ActionDiv;
  else
    Abort;
  end;

  case rgRange.ItemIndex of
  0:DoActionAll;
  1:DoActionSelection;
  2:DoActionRange;
  end;
end;

procedure TfrmMain.sbUpdateGridRangeClick(Sender: TObject);
var BegAddr,EndAddr:Longint;
begin
  BegAddr:=edBegin.Value;
  EndAddr:=edEnd.Value;
  HexGrid.DataCount:=EndAddr-BegAddr+1;
  HexGrid.BegAddr:=Cardinal(BegAddr);
  UpdateStatusBar;
end;

procedure TfrmMain.edExit(Sender: TObject);
var edName:string ;
begin
  edName:=TComboDigEdit(Sender).Name;
  if (edName='edBegin') or (edName='edEnd') then
  begin
    If edBegin.value>edEnd.value then
    begin
      MessageDlg('Value Begin > End !',mtError, [mbOk], 0);
      TWinControl(Sender).SetFocus;
    end
    else
    begin
      if edCount.Value<>(edEnd.value-edBegin.value+1) then
        edCount.Value:=edEnd.value-edBegin.value+1;
    end
  end;
  if edName='edCount' then
  begin
    If ((edBegin.Value+edCount.Value-1)>edEnd.MaxValue)
        or (edCount.Value<1) then
    begin
      MessageDlg('Value out of range!',mtError, [mbOk], 0);
      TWinControl(Sender).SetFocus;
    end
    else
    begin
      if edEnd.Value<>(edBegin.value+edCount.value-1) then
        edEnd.Value:=edBegin.value+edCount.value-1;
    end
  end;
end;

procedure TfrmMain.edKeyPress(Sender: TObject; var Key: Char);
begin
  if Key=Chr($0d) then edExit(Sender);
end;





procedure TfrmMain.FormDestroy(Sender: TObject);
begin
  DeviceCloseExecute(Sender);
end;









procedure TfrmMain.sbCalculateCRCClick(Sender: TObject);
var i,j:integer;
    index:integer;
begin
  if cbCRC.Text='' then Abort;
  CRC1.CRC:=StandartCRCModels[cbCRC.Items.IndexOF(cbCRC.Text)];
  CRC1.Cm_Ini;
  case rgRange.ItemIndex of
  0:  CRC1.Cm_Blk(@PDataBuf(HexGrid.DataBufer).data[0],HexGrid.DataCount);

  1:begin   // selection
     for j:=HexGrid.Selection.Top to HexGrid.Selection.Bottom do
       for i:=HexGrid.Selection.Left to HexGrid.Selection.Right do
       begin
         index:=HexGrid.GetDataIndex(i,j);
         if HexGrid.DataSize=dsWord then
         begin
           CRC1.Cm_Nxt(HexGrid.Adata[index]);
           CRC1.Cm_Nxt(HexGrid.Adata[index+1]);
         end
         else
           CRC1.Cm_Nxt(HexGrid.Adata[index]);
       end
    end;
  2:begin   //range
      for i:=edBegin.Value to edEnd.Value do
      begin
        if HexGrid.DataSize=dsWord then
        begin
          CRC1.Cm_Nxt(HexGrid.Adata[i*2]);
          CRC1.Cm_Nxt(HexGrid.Adata[i*2+1]);
        end
        else
          CRC1.Cm_Nxt(HexGrid.Adata[i]);
      end;
    end;
  end;


  edCRC.Text:=Format('%.'+IntToStr(CRC1.CRC.width div 4)+'x',[CRC1.Cm_CRC]);
end;


procedure TfrmMain.actPerfomanceTestExecute(Sender: TObject);
begin
  with  TfrmPerfomanceTest.Create(Self) do
  begin
    try
      ShowModal;
    finally
      Free;
    end;
  end;

end;



procedure TfrmMain.FormShow(Sender: TObject);
var str:string;
    mnItem:TMenuItem;

  function FindMenuItem(mnItem:TMenuItem;str:string):TMenuItem;
  var i:integer;
  label end_;
  begin
    result:=nil;
    if mnItem.name=str then
    begin
      Result:=mnItem;
      goto end_;
    end;
    for i:=0 to mnItem.count-1 do
    begin
      Result:=FindMenuItem(mnItem.Items[i],str);
      if Result<>nil then
        goto end_;
    end;
  end_:
  end;

begin
 // Востановить форму последнего использовавшегося чипа
  str:= FormStorage1.ReadString('DefaultDevice','');
  if str<>'' then
  begin
     mnItem:=FindMenuItem(mnDevices,str);
     if mnItem<>nil then mnItem.Click;
  end;


end;

initialization

  ConstructorsList:=nil;

end.
