我的程序分析之路

unit reader;      {这个是我标注的}
{疑问:
1.  curOrderNo curOperNo  orderLst  recDataLst 这些都是干什么的
}

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls, StdCtrls, SPComm;

type                         //定义类
  TfrmReader = class(TForm)
    pnlTitle: TPanel;
    comReader: TComm;
    Label6: TLabel;
    Panel1: TPanel;
    pgcReader: TPageControl;
    tbsConfig: TTabSheet;
    gbCommSet: TGroupBox;
    lblComName: TLabel;
    lblBaudRate: TLabel;
    lblParity: TLabel;
    lblByteSize: TLabel;
    lblStopBits: TLabel;
    cbComName: TComboBox;
    cbBaudRate: TComboBox;
    cbParity: TComboBox;
    cbByteSize: TComboBox;
    cbStopBits: TComboBox;
    btnChComm: TButton;
    btnTestReader: TButton;
    memComSet: TMemo;
    edStatus: TEdit;
    TabSheet1: TTabSheet;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label7: TLabel;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    ComboBox3: TComboBox;
    ComboBox4: TComboBox;
    ComboBox5: TComboBox;
    Button1: TButton;
    Button18: TButton;
    GroupBox16: TGroupBox;
    ComboBox20: TComboBox;
    tbsLowLevel: TTabSheet;
    gbLoweOper: TGroupBox;
    btnSeekCard: TButton;
    btnCollision: TButton;
    btnSelect: TButton;
    btnTerminate: TButton;
    gbLowRe: TGroupBox;
    memLowRe: TMemo;
    tbsPassDown: TTabSheet;
    gbPasswordDown: TGroupBox;
    lblPDSector0: TLabel;
    lblPDSector1: TLabel;
    lblPDSector2: TLabel;
    lblPDSector3: TLabel;
    lblPDSector4: TLabel;
    lblPDSector5: TLabel;
    lblPDSector6: TLabel;
    lblPDSector7: TLabel;
    lblPDSector8: TLabel;
    lblPDSector9: TLabel;
    lblPDSectorA: TLabel;
    lblPDSectorB: TLabel;
    lblPDSectorC: TLabel;
    lblPDSectorD: TLabel;
    lblPDSectorE: TLabel;
    lblPDSectorF: TLabel;
    edtSecPwd0: TEdit;
    edtSecPwd1: TEdit;
    edtSecPwd2: TEdit;
    edtSecPwd3: TEdit;
    edtSecPwd4: TEdit;
    edtSecPwd5: TEdit;
    edtSecPwd6: TEdit;
    edtSecPwd7: TEdit;
    edtSecPwd8: TEdit;
    edtSecPwd9: TEdit;
    edtSecPwd10: TEdit;
    edtSecPwd11: TEdit;
    edtSecPwd12: TEdit;
    edtSecPwd13: TEdit;
    edtSecPwd14: TEdit;
    edtSecPwd15: TEdit;
    rgSePwdOrg: TRadioGroup;
    btnPwdDwn: TButton;
    tbsDataOper: TTabSheet;
    gbRWSector: TGroupBox;
    lblBlock0: TLabel;
    lblBlock1: TLabel;
    lblBlock2: TLabel;
    lblBlock3: TLabel;
    edtBlock0: TEdit;
    edtBlock1: TEdit;
    edtBlock2: TEdit;
    edtBlock3: TEdit;
    gbRWSeSec: TGroupBox;
    cbRWSec: TComboBox;
    btnBlockRd: TButton;
    btnBlockWt: TButton;
    tbsBlockOper: TTabSheet;
    gbReOrWt: TGroupBox;
    lblCurValue: TLabel;
    lblOpeValue: TLabel;
    edtCurValue: TEdit;
    edtOpeValue: TEdit;
    gbBkSec: TGroupBox;
    cbBSecSe: TComboBox;
    gbBlokSe: TGroupBox;
    cbBSe: TComboBox;
    btnBlockInit: TButton;
    btnBlockRead: TButton;
    btnBlockAdd: TButton;
    btnBlockSub: TButton;
    tbsPassCh: TTabSheet;
    gbEntryPwd: TGroupBox;
    lblPwdA: TLabel;
    lblPwdB: TLabel;
    edtPwdA: TEdit;
    edtPwdB: TEdit;
    gbConBit: TGroupBox;
    lblConBit0: TLabel;
    lblConBit1: TLabel;
    lblConBit2: TLabel;
    lblConBit3: TLabel;
    edtConBit0: TEdit;
    edtConBit1: TEdit;
    edtConBit2: TEdit;
    edtConBit3: TEdit;
    gbChPwdSec: TGroupBox;
    cbChPwdSec: TComboBox;
    btnChPwd: TButton;
    btnChCon: TButton;
    tbsSeRe: TTabSheet;
    gbComSendRec: TGroupBox;
    lblExplain: TLabel;
    memComSeRe: TMemo;
    TabSheet2: TTabSheet;
    PageControl1: TPageControl;
    TabSheet3: TTabSheet;
    GroupBox2: TGroupBox;
    Label8: TLabel;
    Label9: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    ComboBox6: TComboBox;
    ComboBox7: TComboBox;
    ComboBox8: TComboBox;
    ComboBox9: TComboBox;
    ComboBox10: TComboBox;
    Button2: TButton;
    Button3: TButton;
    Memo1: TMemo;
    TabSheet4: TTabSheet;
    GroupBox3: TGroupBox;
    Label13: TLabel;
    Label14: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    Label18: TLabel;
    ComboBox11: TComboBox;
    ComboBox12: TComboBox;
    ComboBox13: TComboBox;
    ComboBox14: TComboBox;
    ComboBox15: TComboBox;
    Button4: TButton;
    TabSheet5: TTabSheet;
    GroupBox4: TGroupBox;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    GroupBox5: TGroupBox;
    Memo2: TMemo;
    TabSheet6: TTabSheet;
    GroupBox6: TGroupBox;
    Label19: TLabel;
    Label20: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    Label34: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    Edit9: TEdit;
    Edit10: TEdit;
    Edit11: TEdit;
    Edit12: TEdit;
    Edit13: TEdit;
    Edit14: TEdit;
    Edit15: TEdit;
    Edit16: TEdit;
    RadioGroup1: TRadioGroup;
    Button9: TButton;
    TabSheet7: TTabSheet;
    GroupBox7: TGroupBox;
    Label35: TLabel;
    Label36: TLabel;
    Label37: TLabel;
    Label38: TLabel;
    Label48: TLabel;
    Edit17: TEdit;
    Edit18: TEdit;
    Edit19: TEdit;
    Edit20: TEdit;
    Edit29: TEdit;
    Button10: TButton;
    Button11: TButton;
    GroupBox8: TGroupBox;
    ComboBox16: TComboBox;
    TabSheet8: TTabSheet;
    GroupBox9: TGroupBox;
    Label39: TLabel;
    Label40: TLabel;
    Edit21: TEdit;
    Edit22: TEdit;
    GroupBox10: TGroupBox;
    ComboBox17: TComboBox;
    GroupBox11: TGroupBox;
    ComboBox18: TComboBox;
    Button12: TButton;
    Button13: TButton;
    Button14: TButton;
    Button15: TButton;
    TabSheet9: TTabSheet;
    GroupBox12: TGroupBox;
    Label41: TLabel;
    Label42: TLabel;
    Edit23: TEdit;
    Edit24: TEdit;
    GroupBox13: TGroupBox;
    Label43: TLabel;
    Label44: TLabel;
    Label45: TLabel;
    Label46: TLabel;
    Edit25: TEdit;
    Edit26: TEdit;
    Edit27: TEdit;
    Edit28: TEdit;
    GroupBox14: TGroupBox;
    ComboBox19: TComboBox;
    Button16: TButton;
    Button17: TButton;
    TabSheet10: TTabSheet;
    GroupBox15: TGroupBox;
    Label47: TLabel;
    Memo3: TMemo;
    TabSheet11: TTabSheet;
    TabSheet12: TTabSheet;
    Memo4: TMemo;
    GroupBox17: TGroupBox;
    Label50: TLabel;
    ImageOff: TImage;
    ImageOn: TImage;
    Label49: TLabel;
    Label51: TLabel;
    Label52: TLabel;
    Label53: TLabel;
    Button19: TButton;
    Button20: TButton;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure comReaderReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    procedure btnTestReaderClick(Sender: TObject);
    procedure btnSeekCardClick(Sender: TObject);
    procedure btnCollisionClick(Sender: TObject);
    procedure btnSelectClick(Sender: TObject);
    procedure btnTerminateClick(Sender: TObject);
    procedure btnPwdDwnClick(Sender: TObject);
    procedure btnBlockRdClick(Sender: TObject);
    procedure btnBlockWtClick(Sender: TObject);
    procedure btnBlockInitClick(Sender: TObject);
    procedure cbRWSecChange(Sender: TObject);
    procedure btnBlockReadClick(Sender: TObject);
    procedure btnBlockAddClick(Sender: TObject);
    procedure btnBlockSubClick(Sender: TObject);
    procedure btnChPwdClick(Sender: TObject);
    procedure btnChCommClick(Sender: TObject);
    procedure memLowReDblClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure memComSetDblClick(Sender: TObject);
    procedure memComSeReDblClick(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure GroupBox7DblClick(Sender: TObject);
    procedure Edit17DblClick(Sender: TObject);
    procedure Edit18DblClick(Sender: TObject);
    procedure Edit19DblClick(Sender: TObject);
    procedure Edit20DblClick(Sender: TObject);
    procedure Edit29DblClick(Sender: TObject);
    procedure Memo4DblClick(Sender: TObject);
    procedure Button18Click(Sender: TObject);
    procedure cbBaudRateChange(Sender: TObject);
    procedure edtSecPwd0DblClick(Sender: TObject);
    procedure edtSecPwd1DblClick(Sender: TObject);
    procedure edtSecPwd2DblClick(Sender: TObject);
    procedure edtSecPwd3DblClick(Sender: TObject);
    procedure edtSecPwd4DblClick(Sender: TObject);
    procedure edtSecPwd5DblClick(Sender: TObject);
    procedure edtSecPwd6DblClick(Sender: TObject);
    procedure edtSecPwd7DblClick(Sender: TObject);
    procedure edtSecPwd8DblClick(Sender: TObject);
    procedure edtSecPwd9DblClick(Sender: TObject);
    procedure edtSecPwd10DblClick(Sender: TObject);
    procedure edtSecPwd11DblClick(Sender: TObject);
    procedure edtSecPwd12DblClick(Sender: TObject);
    procedure edtSecPwd13DblClick(Sender: TObject);
    procedure edtSecPwd14DblClick(Sender: TObject);
    procedure edtSecPwd15DblClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button19Click(Sender: TObject);
    procedure Button20Click(Sender: TObject);
 private
    { Private declarations }                 //定义私有成员
    function exchData(orderStr : string):string;
    procedure sendData();
    procedure checkOper();
    procedure ShowStatus;
    procedure EnumComPorts(Ports: TStrings);
  public
    { Public declarations }
  end;

var
    multflag : integer=0;
    frmReader : TfrmReader;          //生成TForm1类对象Form1
    curOrderNo : integer=0;         //当前操作命令号
    curOperNo : integer=0;          //当前操作码类型
    orderLst : Tstrings;       //发送的命令
    recDataLst : Tstrings;    //接收的数据
    buffer : array [0..2048] of byte;

implementation

{$R *.dfm}

//转换发送数据格式  也就是转化为二进制
function TfrmReader.exchData(orderStr : string):string;
var
    ii,jj : integer;
    TmpStr : string;
    reTmpStr : string;
begin
    if (length(orderStr)=0) then
    begin
        MessageBox(handle,'传入参数不能为空!','错误',MB_ICONERROR+MB_OK);
        result:='';     //无返回
        exit;
    end;
    if (length(orderStr) mod 2) <> 0 then      //mod求摸
    begin
        MessageBox(handle,'传入参数错误!','错误',MB_ICONERROR+MB_OK);
        result:='';
        exit;
    end;
    for ii:=1 to (length(orderStr) div 2) do
    begin
        tmpStr:=copy(orderStr,ii*2-1,2);
        jj:=strToint('$' + tmpStr);             //必须要添加上'$'
        reTmpStr:=reTmpStr+chr(jj);          //chr函数转化为ACSll代码 就是二进制代码 另外一种解释16进制字符串转换成字符串
    end;
    result:=reTmpStr; //返回
end;

//发送数据过程
procedure TfrmReader.sendData();
var
    orderStr : string;
begin
    if orderLst.Count > curOrderNo then        //curOrdeNo 当前操作命令号  这里不明白
    begin
        orderStr:=orderLst.Strings[curOrderNo];
        memComSeRe.Lines.Add('==>> '+orderStr);  //在《发送接收》栏窗口显示
        orderStr:=exchData(orderStr);     //转化格式
        comReader.WriteCommData(pchar(orderStr),length(orderStr));    //发送orderstr,用于发送一个字符串到写线程,发送成功返回true,发送失败返回false,
                                                                    //执行此函数将立即得到返回值,发送操作随后执行。函数有两个参数,其中
                                                                    //pdatatowrite是要发送的字符串,dwsizeofdatatowrite 是发送的长度。
        inc(curOrderNo);    //当前操作命令号自增
    end;
end;

//接收数据过程
procedure TfrmReader.comReaderReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
    ii,i : integer;
    recStr : string;
    tmpStr,tmpStr1 : string;
begin
    recStr:='';
    SetLength(tmpStr, BufferLength);//定义tmpstr的长度就是 BufferLength
    move(buffer^,pchar(tmpStr)^,BufferLength); //这里是一个固定的格式就跟copy一样的
    for ii:=1 to BufferLength do
    begin
        recStr:=recStr+intTohex(ord(tmpStr[ii]),2);   //字符串转换成16进制字符串
    end;                                            //以上这个是接收的固定格式
    memComSeRe.Lines.Add('<<== '+recStr); //《发送接收》栏窗口显示
    tmpStr1:= copy(recStr,3,2);   //从第三位拷贝,连续拷贝两个字符
    if   strtoint('$'+tmpStr1)= $0E then
      begin
        curOperNo:=16;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        Button18.Enabled :=true;     //<采集器设置>栏选择扇区号按钮使能
        recDataLst.Clear();
        Memo4.Lines.Add('              多卡采集启动!              ');
      end;

    recDataLst.Add(recStr);
    if curOrderNo < orderLst.Count then
        sendData()
    else begin
        checkOper();    //检查返回的数据并显示
        memComSeRe.Lines.Append('');     //和add一样的结果
    end;
end;

//检查返回的数据并显示
procedure tfrmReader.checkOper();
var
    i,ii,jj : integer;
    tmpStr,tmpStr1,tmpStr2,tmpStr3 : string;
begin
    case curOperNo of
        0 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        memComSet.Lines.Add('读卡器连结失败');
                        memComSet.Lines.Add('');
                        exit;
                    end;
                memComSet.Lines.Add('读卡器连结成功');
                memComSet.Lines.Add('');
            end;
        1 : begin
                memLowRe.Lines.Add('命令: 寻卡');
                if copy(recDataLst.Strings[0],3,2)<>'00' then //如果返回的命令字为00则说明讯卡失败
                    memLowRe.Lines.Add('结果: 寻卡失败')
                else
                begin
                    memLowRe.Lines.Add('结果: 寻卡成功');
                    if copy(recDataLst.Strings[0],5,2)='04' then    //这个请看RC500通信协议04表示的是Mifare one
                        memLowRe.Lines.Add('该卡片为Mifare one')
                    else
                        memLowRe.Lines.Add('该卡片为其它类型');
                end;
                memLowRe.Lines.Add('');   //空出来一行
            end;
        2 : begin
                memLowRe.Lines.Add('命令: 防冲突');
                if copy(recDataLst.Strings[0],3,2)<>'00' then      //下面的都是一样的只要命令字返回00则表示的是失败
                    memLowRe.Lines.Add('结果: 防冲突失败')
                else begin
                    memLowRe.Lines.Add('结果: 防冲突成功');
                    tmpStr:=recDataLst.Strings[0];
                    tmpStr:=copy(tmpStr,5,length(tmpStr)-4);
                    memLowRe.Lines.Add('序号: '+tmpStr);
                end;
                memLowRe.Lines.Add('');
            end;
        3 : begin
                memLowRe.Lines.Add('命令: 选择');
                if copy(recDataLst.Strings[0],3,2)<>'00' then
                    memLowRe.Lines.Add('结果: 选择失败')
                else
                    memLowRe.Lines.Add('结果: 选择成功');
                memLowRe.Lines.Add('');
            end;
        4 : begin
                memLowRe.Lines.Add('命令: 终止');
                if copy(recDataLst.Strings[0],3,2)<>'00' then
                    memLowRe.Lines.Add('结果: 终止失败')
                else
                    memLowRe.Lines.Add('结果: 终止成功');
                memLowRe.Lines.Add('');
            end;
        5 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then         //密码下载
                    begin
                        MessageBox(handle,'密码下载失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'密码下载成功','成功',MB_OK);
            end;
      6 : begin
                for i:=0 to 3 do
                begin
                    if copy(recDataLst.Strings[i+4],3,2)<>'00' then      //检测每个扇区的块三的密码是否存在
                    begin
                        gbRWSector.Caption:=cbRWSec.Text+'读取失败';// <数据读写模块> 选择扇区的扇区号并在这个栏的大标题框中提示出来
                        exit;
                    end;                                              {09 06 60 01 FF FF FF FF FF FF 这里面06是命令字60为PICC-AYTHENT1A
                                                                      (61为PICC-AYTHENT1B),01为扇区号,12个F为密码在这里可以设置32位 }
                end;
                edtBlock0.Text:=copy(recDataLst.Strings[4],5,32);   //前六位是密码位,总共可以设置32位的密码
                edtBlock1.Text:=copy(recDataLst.Strings[5],5,32);
                edtBlock2.Text:=copy(recDataLst.Strings[6],5,32);
                edtBlock3.Text:=copy(recDataLst.Strings[7],5,32);
                gbRWSector.Caption:=cbRWSec.Text+'读取成功';
            end;      
        7 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        gbRWSector.Caption:=cbRWSec.Text+'写入失败';
                        exit;
                    end;
                gbRWSector.Caption:=cbRWSec.Text+'写入成功';
            end;
        8 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        MessageBox(handle,'块值初始化失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'块值初始化成功','成功',MB_OK);
            end;
        9 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        MessageBox(handle,'块值读取失败','失败',MB_OK);
                        exit;
                    end;
                tmpStr1:=copy(recDataLst.Strings[4],5,8);
                tmpStr:='';
                for i:=3 downto 0 do
                  begin
                    tmpStr:=tmpStr + copy(tmpStr1,(i*2+1),2);
                  end;
                edtCurValue.Text:=tmpStr;
                MessageBox(handle,'块值读取成功','成功',MB_OK);
            end;
        10 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        MessageBox(handle,'块值加值失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'块值加值成功','成功',MB_OK);
            end;
        11 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        MessageBox(handle,'块值减值失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'块值减值成功','成功',MB_OK);
            end;
        12 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        MessageBox(handle,'密码修改失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'密码修改成功','成功',MB_OK);
            end;
        13 : begin
                 if copy(recDataLst.Strings[0],3,2)<>'00' then
                    begin
                        MessageBox(handle,'下位机波特率修改失败','失败',MB_OK);
                        exit;
                    end;
                MessageBox(handle,'下位机波特率修改成功,请把上位机波特率设置为和下位机一样!','成功',MB_OK);
            end;
        14 : begin
                for i:=0 to recDataLst.Count-1 do
                    if copy(recDataLst.Strings[i],3,2)<>'00' then
                    begin
                        GroupBox7.Caption:=ComBoBox16.Text+'写入失败';
                        exit;
                    end;
                GroupBox7.Caption:=ComBoBox16.Text+'写入成功';
            end;
        15 : begin
                for i:=0 to 3 do
                begin
                    if copy(recDataLst.Strings[i+4],3,2)<>'00' then
                    begin
                        GroupBox7.Caption:=ComBoBox16.Text+'读取失败';
                         Edit17.Text:='';
                         Edit18.Text:='';
                         Edit19.Text:='';
                         Edit20.Text:='';
                         Edit29.Text:='';
                        exit;
                    end;
                end;
                tmpStr3:='';
                tmpStr:=copy(recDataLst.Strings[4],5,32);
                tmpStr2:='';
                for ii:=1 to (length(tmpStr) div 2) do
                  begin
                    tmpStr1:=copy(tmpStr,ii*2-1,2);
                    tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                  end;
                tmpStr3:=tmpStr3+tmpStr2;
                tmpStr:=copy(recDataLst.Strings[5],5,32);
                tmpStr2:='';
                for ii:=1 to (length(tmpStr) div 2) do
                  begin
                    tmpStr1:=copy(tmpStr,ii*2-1,2);
                    tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                  end;
                tmpStr3:=tmpStr3+tmpStr2;
                tmpStr:=copy(recDataLst.Strings[6],5,32);
                tmpStr2:='';
                for ii:=1 to (length(tmpStr) div 2) do
                  begin
                    tmpStr1:=copy(tmpStr,ii*2-1,2);
                    tmpStr2:=tmpStr2+chr(strToint('$'+tmpStr1));
                  end;
                tmpStr3:=tmpStr3+tmpStr2;

                jj:=1;
                i:= integer(tmpStr3[jj]);
                Edit17.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('姓名: '+Edit17.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit18.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('性别: '+Edit18.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit19.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('职务: '+Edit19.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit20.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('学号: '+Edit20.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit29.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('学校: '+Edit29.Text+#13+#10);
                GroupBox7.Caption:=ComBoBox16.Text+'读取成功';

            end;
        16 : begin
                if  length(recDataLst.Strings[0])<=30 then
                     begin
                     recDataLst.Clear();
                     exit;
                     end;
                tmpStr := '';
                tmpStr2:=copy(recDataLst.Strings[0],5,32);
                tmpStr := tmpStr + tmpStr2;
                tmpStr2:=copy(recDataLst.Strings[0],41,32);
                tmpStr := tmpStr + tmpStr2;
                tmpStr2:=copy(recDataLst.Strings[0],77,32);
                tmpStr := tmpStr + tmpStr2;
                tmpStr3:='';
                for ii:=1 to (length(tmpStr) div 2) do
                  begin
                    tmpStr1:=copy(tmpStr,ii*2-1,2);
                    tmpStr3:=tmpStr3+chr(strToint('$'+tmpStr1));
                  end;

                jj:=1;
                i:= integer(tmpStr3[jj]);
                Edit17.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('姓名:'+Edit17.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit18.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('性别:'+Edit18.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit19.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('职务:'+Edit19.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit20.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('学号:'+Edit20.Text);

                jj:=jj+i+1;
                i:= integer(tmpStr3[jj]);
                Edit29.Text:=copy(tmpStr3,jj+1,i);
                Memo4.Lines.Add('学校:'+Edit29.Text+#13+#10);

                recDataLst.Clear();
            end;
        17 : begin
               if (copy(recDataLst.Strings[0],3,2)<>'00') then
                    MessageBox(handle,'更改扇区失败','失败',MB_OK)
                  else
                    MessageBox(handle,'更改扇区成功','成功',MB_OK);
               curOperNo:=16;                            
             end;

    end;
end;

//系统初始化
procedure TfrmReader.FormShow(Sender: TObject);
begin

    comReader.StopComm(); //关闭串口
    orderLst:=TStringList.Create;
    recDataLst:=tStringList.Create;

    btnChComm.Caption := '打开串口';
    cbComName.Enabled := true;   //串口号波特率校验位  数据位 停止位下拉列表使能
    cbBaudRate.Enabled := true;
    cbParity.Enabled := true;
    cbByteSize.Enabled := true;
    cbStopBits.Enabled := true;
    ImageOn.Visible   := false; //串口打开或关闭图片显示设置
    ImageOff.Visible  := true;

    Button18.Enabled :=false;    //选择扇区按钮不使能(采集器设置栏)
    Label50.Caption :='多卡采集模式';// (多卡采集演示栏)
    label7.Caption :='说明:'+chr(13)+'1、如果下位机的晶振是11.0592MHz,那么波特率不支持38400'
    +'和115200;如果下位机的晶振是22.1184MHz,那么将支持左边所有的波特率设置。'+chr(13)
    +'2、下位机采集系统的波特率设置只能是左边列出来的这几种,其他的暂不支持!'
    +chr(13)+'3、"设置下位机波特率"将会把修改过的波特率写入到EEPROM,请牢记已经更改了的波特率!';     //(采集器设置栏)
    label51.Caption :='注意:'+chr(13)+'0扇区0块是只读的,在写入数据的时候要把它清空,否则,无法写入数据!';//(数据读写栏)
    label52.Caption :='注意:'+chr(13)+'1、0扇区0块是只读的,无法进行初始化、加值和减值操作!'+chr(13)
    +'2、在加值、减值操作之前要先进行初始化操作!'+chr(13) + '3、输入的数值都是十六进制!';; //(块值操作栏)
    label53.Caption :='注意:'+chr(13)+'在修改密码前要先对相应的扇区进行数据读出操作!';  //(修改密码栏)
    //+chr(13)表示回车+chr(10)表示换行
    //ShowMessage('正在设置系统');
    edtOpeValue.Text:='12345678'; //(操作值(块值操作栏))
    ShowStatus;
end;
//释放系统资源
procedure TfrmReader.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    orderLst.Free();
    recDataLst.Free();
    comReader.StopComm();
end;

//扇区号变化
procedure TfrmReader.cbRWSecChange(Sender: TObject);   //扇区号发生变化的时候块值栏变为初始值   不用看
begin
    gbRWSector.Caption:=cbRWSec.Text;
    edtBlock0.Text:='';
    edtBlock1.Text:='';
    edtBlock2.Text:='';
    edtBlock3.Text:='';
end;

//测试读卡器.
procedure TfrmReader.btnTestReaderClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=0;      //  00成功10失败  //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('测试读卡器');
    orderLst.Add('020B0F');  //蜂鸣器启动表明测试读卡器按键被按下 以下都是一样的
    sendData();
end;
//寻卡
procedure TfrmReader.btnSeekCardClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=1;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('寻卡');
    orderLst.Add('020226'); //02为命令字,26为 卡系列号
    orderLst.Add('020B0F');
    sendData();
end;
//防冲突
procedure TfrmReader.btnCollisionClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=2;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('防冲突');
    orderLst.Add('0103'); //03为命令字
    orderLst.Add('020B0F');
    sendData();
end;
//选择卡
procedure TfrmReader.btnSelectClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=3;  //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('选择');
    orderLst.Add('0104');   //04为命令字即选择卡
    orderLst.Add('020B0F');
    sendData();
end;
//终止卡
procedure TfrmReader.btnTerminateClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=4;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('终止');
    orderLst.Add('0101');    //都是一样的   命令字  不得不佩服这个软件的编程者有很高的思维能力,写的程序一点都不乱
    orderLst.Add('020B0F');
    sendData();
end;
//密码下载
procedure TfrmReader.btnPwdDwnClick(Sender: TObject);
var
    i,j,allpwdflag : integer;
    nameStr,pwdStr,noStr,pwdOrg : string;
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=5;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    allpwdflag:=0;  //至少有一个密码不为空标志位
    memComSeRe.Lines.Add('密码下载');

    if rgSePwdOrg.ItemIndex=0 then
        pwdOrg:='60'          //60为IC卡密码的类型一个是密码A ,61为密码B
    else
        pwdOrg:='61';
    for i:=0 to ComponentCount-1 do
    begin
        if components[i] is TEdit then    //如果components[i]是TEdit类型的话就执行下面的语句
        begin
            nameStr:=components[i].Name;
            if copy(nameStr,1,9)='edtSecPwd' then
            begin
                noStr:=copy(nameStr,10,length(nameStr)-9);
                pwdStr:=(components[i] as TEdit).Text;
                 if pwdStr<>'' then
                 begin
                    allpwdflag:=1;
                    noStr:=intTohex(strToint(noStr),2);
                    if length(pwdStr)<12 then
                    begin
                        MessageBox(handle,PChar(noStr+' 扇区密码位数据错误'),'错误',MB_OK);
                        exit;
                    end;
                    for j:=1 to length(pwdStr) do
                        if  not (pwdStr[j] in ['0'..'9','A'..'F','a'..'f']) then   //如果超过十六进制的字符范围就警告
                        begin
                            MessageBox(handle,PChar(noStr+' 扇区密码含有非法数据'),'错误',MB_OK);
                            exit;
                        end;
                    orderLst.Add('0906'+pwdOrg+noStr+pwdStr);
                    //ShowMessage('0906'+pwdOrg+noStr+pwdStr);
                 end;
            end;
        end;
    end;
    if (allpwdflag=1) then
       begin
          orderLst.Add('020B0F');
          sendData();
       end
    else
       begin
       MessageBox(handle,'所有的密码都为空,请输入要下载的密码!','错误',MB_OK);
       //MessageBeep(10);
       end;
end;
//扇区内容读取
procedure TfrmReader.btnBlockRdClick(Sender: TObject);
var
    i : integer;
    curSectorNo : string;
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=6;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    curSectorNo:=intTohex(cbRWSec.ItemIndex,2);
    memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'扇区内容读取');
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+curSectorNO+intTohex(cbRWSec.ItemIndex*4,2));
    for i:=0 to 3 do
        orderLst.Add('0208'+intTohex(cbRWSec.ItemIndex*4+i,2));
    orderLst.Add('020B0F');
    sendData();
end;
//扇区数据写入
procedure TfrmReader.btnBlockWtClick(Sender: TObject);
var
    i : integer;
    blockCont : string;
    curSectorNo : string;
begin
    if (edtBlock0.Text<>'') or (edtBlock1.Text<>'') or (edtBlock2.Text<>'') then    //如果《数据读写》栏的块值0,12其中有一个不是空的
   else
        exit;
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=7;        //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    curSectorNo:=intTohex(cbRWSec.ItemIndex,2);
    //memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'扇区内容写入');
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+curSectorNO+intTohex(cbRWSec.ItemIndex*4,2));

    blockCont:=edtBlock0.Text;
    if blockCont<>'' then
    begin
        if length(blockCont)<>32 then
        begin
            MessageBox(Handle,'块0数据位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 32 do
            if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'块0数据含有非法内容!','错误',MB_OK);
                exit;
            end;
        orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4,2)+blockCont);
    end;

    blockCont:=edtBlock1.Text;
    if blockCont<>'' then
    begin
        if Length(blockCont)<>32 then
        begin
            MessageBox(Handle,'块1数据位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 32 do
            if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'块1数据含有非法内容!','错误',MB_OK);
                exit;
            end;
        orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4+1,2)+blockCont);
    end;


    blockCont:=edtBlock2.Text;
    if blockCont<>'' then
    begin
        if Length(blockCont)<>32 then
        begin
            MessageBox(Handle,'块2数据位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 32 do
            if not (blockCont[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'块2数据含有非法内容!','错误',MB_OK);
                exit;
        end;
        orderLst.Add('1209'+intTohex(cbRWSec.ItemIndex*4+2,2)+blockCont);
    end;

    orderLst.Add('020B0F');
    sendData();
end;
//块值初始化
procedure TfrmReader.btnBlockInitClick(Sender: TObject);
var
    blockNo,sectorNo,i,tmpInt : integer;
    blockValue,tmpStr,iniValue : string;
begin
    if ((cbBSecSe.ItemIndex*4+cbBse.ItemIndex)=0) then   //如果绝对块号是0
      begin
         MessageBox(handle,'0扇区0块是只读的,无法进行初始化操作!','错误',MB_OK);
         exit;
      end;
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=8;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    sectorNo:=cbBSecSe.ItemIndex;  //cbBSecSe扇区号
    blockNo:=cbBSe.ItemIndex;      //cbBSe块号
    memComSeRe.Lines.Add(intTostr(cbRWSec.ItemIndex)+'块值初始化');

    blockValue:=edtOpeValue.Text;  //操作值
    if blockValue='' then
    begin
        MessageBox(handle,'操作值不能为空!','错误',MB_OK);
        exit;
    end;
    if length(blockValue)<>8 then
    begin
        MessageBox(handle,'操作值位数错误!','错误',MB_OK);
        exit;
    end;
    for i:=1 to 8 do
        if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
        begin
            MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
            exit;
        end;

    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+intTohex(sectorNo,2)+intTohex(sectorNo*4,2));

    //ShowMessage(intTostr(sectorNo));
    tmpStr:='';
    for i:=3 downto 0 do
    begin
      tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
    end;
    blockValue:=tmpStr;
    //ShowMessage(blockValue);
    iniValue:='';
    //ABCD(4字节)+ABCD的反码(4字节)+ABCD(4字节)
    //+add(1字节)+add的反码(1字节)+add(1字节)+add的反码(1字节) 注:其中add是绝对扇区号
    for i:=0 to 3 do
    begin
        tmpStr:=copy(blockValue,(i*2+1),2);
        tmpInt:=255-strToint('$'+tmpStr);
        //ShowMessage(tmpStr);
        iniValue:=iniValue+intTohex(tmpInt,2);
    end;
    iniValue:=blockValue+iniValue+blockValue;

    tmpInt:=255-(sectorNo*4+blockNo);
    tmpStr:=intTohex(sectorNo*4+blockNo,2)+intTohex(tmpInt,2);
    iniValue:=iniValue+tmpStr+tmpStr;
     //ShowMessage(iniValue);
    orderLst.Add('1209'+intTohex(sectorNo*4+blockNo,2)+iniValue);
    orderLst.Add('020B0F');
    sendData();
end;
//块值读取
procedure TfrmReader.btnBlockReadClick(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=9;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值读取');
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
    orderLst.Add('0208'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
    orderLst.Add('020B0F');
    sendData();
end;
//块值加值
procedure TfrmReader.btnBlockAddClick(Sender: TObject);
var
    sectorNo,blockNo,i: integer;
    blockValue,tmpStr : string;
begin
    sectorNo:=cbBSecSe.ItemIndex*4+cbBse.ItemIndex;  //绝对块号
    if (sectorNo=0) then
      begin
         MessageBox(handle,'0扇区0块是只读的,无法进行加值操作!','错误',MB_OK);
         exit;
      end;  
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=10;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值加值');

    blockValue:=edtOpeValue.Text;
    if blockValue='' then
    begin
        MessageBox(handle,'操作值不能为空!','错误',MB_OK);
        exit;
    end;
    if length(blockValue)<>8 then
    begin
        MessageBox(handle,'操作值位数错误!','错误',MB_OK);
        exit;
    end;
    for i:=1 to 8 do
        if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
        begin
            MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
            exit;
        end;
     tmpStr:='';
    for i:=3 downto 0 do
    begin
      tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
    end;
    blockValue:=tmpStr;
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
    orderLst.Add('080AC1'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2)+blockValue+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
    orderLst.Add('020B0F');
    sendData();
end;
//块值减值
procedure TfrmReader.btnBlockSubClick(Sender: TObject);
var
    sectorNo,blockNo,i: integer;
    blockValue,tmpStr : string;
begin
    sectorNo:=cbBSecSe.ItemIndex*4+cbBse.ItemIndex;  //绝对块号
    if (sectorNo=0) then
      begin
         MessageBox(handle,'0扇区0块是只读的,无法进行减值操作!','错误',MB_OK);
         exit;
      end;
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=11;     //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add(intTostr(cbBse.ItemIndex+cbBSecSe.ItemIndex)+'块值减值');

    blockValue:=edtOpeValue.Text;
    if blockValue='' then
    begin
        MessageBox(handle,'操作值不能为空!','错误',MB_OK);
        exit;
    end;
    if length(blockValue)<>8 then
    begin
        MessageBox(handle,'操作值位数错误!','错误',MB_OK);
        exit;
    end;
    for i:=1 to 8 do
        if not (blockValue[i] in ['0'..'9','A'..'F','a'..'f']) then
        begin
            MessageBox(Handle,'操作数据含有非法内容!','错误',MB_OK);
            exit;
        end;
    tmpStr:='';
    for i:=3 downto 0 do
    begin
      tmpStr:=tmpStr + copy(blockValue,(i*2+1),2);
    end;
    blockValue:=tmpStr;

    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+intTohex(cbBSecSe.ItemIndex,2)+intTohex(cbBSecSe.ItemIndex*4,2));
    orderLst.Add('080AC0'+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2)+blockValue+intTohex(cbBSecSe.ItemIndex*4+cbBse.ItemIndex,2));
    orderLst.Add('020B0F');
    sendData();
end;
//扇区密码写入
procedure TfrmReader.btnChPwdClick(Sender: TObject);
var
    i : integer;
    pwdA,pwdB : string;
    curSectorNo,tmpStr : string;
begin
    if (edtPwdA.Text<>'') or (edtPwdB.Text<>'') then
    else
        exit;
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=12;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    curSectorNo:=intTohex(cbChPwdSec.ItemIndex,2);
    memComSeRe.Lines.Add(intTostr(cbChPwdSec.ItemIndex)+'扇区密码写入');
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+curSectorNo+intTohex(cbRWSec.ItemIndex*4,2));

    pwdA:=edtPwdA.Text;
    if pwdA<>'' then
    begin
        if Length(pwdA)<>12 then
        begin
            MessageBox(Handle,'密码A位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 12 do
            if not (pwdA[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'密码A含有非法内容!','错误',MB_OK);
                exit;
            end;
    end;

    pwdB:=edtPwdB.Text;
    if pwdB<>'' then
    begin
        if Length(pwdB)<>12 then
        begin
            MessageBox(Handle,'密码B位数错误!','错误',MB_OK);
            exit;
        end;
        for i:=1 to 12 do
            if not (pwdB[i] in ['0'..'9','A'..'F','a'..'f']) then
            begin
                MessageBox(Handle,'密码B含有非法内容!','错误',MB_OK);
                exit;
            end;
    end;
    if pwdB='' then
        for i:=1 to 12 do
        begin
            tmpStr:=copy(pwdA,i,1);
            tmpStr:=intTostr(15-strToint('$'+tmpStr));
            pwdB:=pwdB+tmpStr;
        end;

    orderLst.Add('1209'+intTohex(cbChPwdSec.ItemIndex*4+3,2)+pwdA+'ff078069'+pwdB);

    orderLst.Add('020B0F');
    sendData();

end;
//设置下位机的波特率。
procedure TfrmReader.Button1Click(Sender: TObject);
 var
   tempstr : string;
begin
    case ComboBox2.ItemIndex of
        0 : tempstr:='00';
        1 : tempstr:='01';
        2 : tempstr:='02';
        3 : tempstr:='03';
        4 : tempstr:='04';
        5 : tempstr:='05';
        6 : tempstr:='06';
        else tempstr:='00';
    end;
    if  ((tempstr='04') or (tempstr='06')) then
      begin
      MessageBox(Handle,'下位机暂不支持该波特率!','非法波特率',MB_OK);   {提示信息}
      exit;
      end;
    orderLst.Clear();     //定义的私有成员
    recDataLst.Clear();   //定义的私有成员
    curOrderNo:=0;         //当前操作命令号
    curOperNo:=13;          //当前操作码类型//这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    memComSeRe.Lines.Add('设置下位机的波特率');
    orderLst.Add('020D'+tempstr);
      //ShowMessage('020D'+tempstr);
    sendData();
end;

procedure TfrmReader.btnChCommClick(Sender: TObject);       //(上机参数设置)
var
     tmpStr : array[1..3] of string;
begin
      if btnChComm.Caption = '打开串口' then
         begin
           tmpStr[1]:=cbComName.Text;  //把端口名赋给数组 1
           comReader.CommName:=tmpStr[1]; //吧数组1的内容送给COM插件的相关属性
           tmpStr[2]:=cbBaudRate.Text;    //波特率赋给数组2
           comReader.BaudRate:=strToint(tmpStr[2]); //吧数组2的内容送给COM插件的相关属性
           comReader.Parity:=tParity(cbParity.ItemIndex); // 奇偶校验位
           //memComSet.Lines.Add('检验位: '+cbParity.Text);
           { Even-表示偶校验     None-表示无校验     Odd-表示奇校验
           Mark-表示校验位为1  Space-表示校验位为0   }
           comReader.ByteSize:=TByteSize(cbByteSize.ItemIndex);  //数据位
           comReader.StopBits:=TStopBits(cbStopBits.ItemIndex);  //停止位
           comReader.StartComm;  //打开串口

           btnChComm.Caption := '关闭串口';
           cbComName.Enabled := false;  {这些都变成不使能}
           cbBaudRate.Enabled := false;
           cbParity.Enabled := false;
           cbByteSize.Enabled := false;
           cbStopBits.Enabled := false;
           ImageOff.Visible  := false;
           ImageOn.Visible   := true;     //“关闭”图片显示

           MessageBeep(10);     //调用系统声音
           memComSet.Lines.Add('串口为: '+tmpStr[1]);     //一下的都是(上位机参数设置栏)的 显示模块
           memComSet.Lines.Add('波特率: '+tmpStr[2]);
           memComSet.Lines.Add('检验位: '+cbParity.Text);
           memComSet.Lines.Add('数据位: '+cbByteSize.Text);
           memComSet.Lines.Add('停止位: '+cbStopBits.Text);
           memComSet.Lines.Add('串口参数设置成功');
           memComSet.Lines.Add('');
         end
      else //if Button1.Caption = '关闭串口' then
         begin
          comReader.StopComm;// 关闭串口
          btnChComm.Caption := '打开串口';
          cbComName.Enabled := true;
          cbBaudRate.Enabled := true;
          cbParity.Enabled := true;
          cbByteSize.Enabled := true;
          cbStopBits.Enabled := true;
          ImageOn.Visible   := false;
          ImageOff.Visible  := true;
        end;
  ShowStatus; //把当前的状态显示到(上位机参数设置栏)上的lebal中
end;
//清空低级操作TMemo内容
procedure TfrmReader.memLowReDblClick(Sender: TObject);
begin
    memLowRe.Text:='';        //(低级操作栏)双击清空内容
end;
//清空波特率设置TMemo内容
procedure TfrmReader.memComSetDblClick(Sender: TObject);
begin
    memComSet.Text:='';       //(上位机参数设置栏)双击清空内容
end;
//清空发送和接收TMemo内容
procedure TfrmReader.memComSeReDblClick(Sender: TObject);
begin
    memComSeRe.Text:='';     //(发送接收栏)双击清空内容
end;
//图书信息写入电子标签
procedure TfrmReader.Button11Click(Sender: TObject);
var
    i ,totalcount: integer;
    blockCont ,tempstr: string;
    curSectorNo : string;
begin
     if (Edit17.Text<>'') then
        else
          begin
           MessageBox(Handle,'图书编号不能为空!','错误',MB_OK);
           exit;
           end;
        orderLst.Clear();
        recDataLst.Clear();
        curOrderNo:=0;
        curOperNo:=14;   //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
        curSectorNo:=intTohex(ComBoBox16.ItemIndex,2);
        //memComSeRe.Lines.Add(intTostr(ComBoBox16.ItemIndex)+'扇区内容写入');
        orderLst.Add('020252');
        orderLst.Add('0103');
        orderLst.Add('0104');
        orderLst.Add('040560'+curSectorNO+intTohex(ComBoBox16.ItemIndex*4,2));
     //Edit17.Text:='1234';
    //Edit18.Text:='789-5';
    //Edit19.Text:='C语言教程';
    //Edit20.Text:='谭浩强';
    //Edit29.Text:='高等教育出版社';

    tempstr:='';
    //totalcount:=6+length(Edit17.Text)+length(Edit18.Text)+length(Edit19.Text)+length(Edit20.Text)+length(Edit29.Text);
    //tempstr:=inttohex(totalcount,2);

    //ShowMessage(inttostr(totalcount));
   
    tempstr:=tempstr + inttohex(length(Edit17.Text),2);

    //ShowMessage(inttostr(length(tempstr)));
        for i:=1 to length(Edit17.Text) do
         tempstr :=tempstr + inttohex(integer(edit17.Text[i]),2);

    tempstr:=tempstr + inttohex(length(Edit18.Text),2);
        for i:=1 to length(Edit18.Text) do
         tempstr :=tempstr + inttohex(integer(edit18.Text[i]),2);

     tempstr:=tempstr + inttohex(length(Edit19.Text),2);
        for i:=1 to length(Edit19.Text) do
         tempstr :=tempstr + inttohex(integer(edit19.Text[i]),2);

     tempstr:=tempstr + inttohex(length(Edit20.Text),2);
        for i:=1 to length(Edit20.Text) do
         tempstr :=tempstr + inttohex(integer(edit20.Text[i]),2);

     tempstr:=tempstr + inttohex(length(Edit29.Text),2);
        for i:=1 to length(Edit29.Text) do
         tempstr :=tempstr + inttohex(integer(edit29.Text[i]),2);

       for i:= length(tempstr)+1 to 96 do
            tempstr := tempstr + '0';

       //ShowMessage(tempstr);
       //Memo4.Text :=tempstr;
        for i:=0 to 2 do
           begin
             blockCont:=copy(tempstr,i*32+1,32);
             orderLst.Add('1209'+intTohex(ComBoBox16.ItemIndex*4+i,2)+blockCont);
            end;
           orderLst.Add('020B0F');
           sendData();
end;

procedure TfrmReader.Button10Click(Sender: TObject);
var
    i : integer;
    curSectorNo : string;
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=15;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    curSectorNo:=intTohex(ComBoBox16.ItemIndex,2);
    memComSeRe.Lines.Add(intTostr(ComBoBox16.ItemIndex)+'扇区内容读取');
    orderLst.Add('020252');
    orderLst.Add('0103');
    orderLst.Add('0104');
    orderLst.Add('040560'+curSectorNO+intTohex(ComBoBox16.ItemIndex*4,2));
    for i:=0 to 2 do
        orderLst.Add('0208'+intTohex(ComBoBox16.ItemIndex*4+i,2));
    orderLst.Add('020B0F');
    sendData();
end;

procedure TfrmReader.GroupBox7DblClick(Sender: TObject);
begin
    Edit17.Text:='';
    Edit18.Text:='';
    Edit19.Text:='';
    Edit20.Text:='';
    Edit29.Text:='';
end;

procedure TfrmReader.Edit17DblClick(Sender: TObject);
begin
    Edit17.Text:='';
end;

procedure TfrmReader.Edit18DblClick(Sender: TObject);
begin
    Edit18.Text:='';
end;

procedure TfrmReader.Edit19DblClick(Sender: TObject);
begin
   Edit19.Text:='';
end;

procedure TfrmReader.Edit20DblClick(Sender: TObject);
begin
     Edit20.Text:='';
end;

procedure TfrmReader.Edit29DblClick(Sender: TObject);
begin
     Edit29.Text:='';
end;

procedure TfrmReader.Memo4DblClick(Sender: TObject);
begin
     Memo4.Text:='';
end;

procedure TfrmReader.Button18Click(Sender: TObject);
begin
    orderLst.Clear();
    recDataLst.Clear();
    curOrderNo:=0;
    curOperNo:=17;    //这个是为了使检测的时候是应该检测那个具体请看procedure tfrmReader.checkOper();这个函数
    //memComSeRe.Lines.Add('设置下位机的存储图书信息的扇区号');
    orderLst.Add('020F'+intTohex(ComboBox20.ItemIndex,2));  
    //orderLst.Add('020B0F');
    sendData();
end; 
//

procedure TfrmReader.ShowStatus;
begin
  if btnChComm.Caption = '关闭串口' then   {如果检测到打开串口按钮被打开则}
  begin
    edStatus.Text := Format('当前串口状态: %s已打开  波特率%s   校验位%s   数据位%s   停止位%s  ', [cbComName.Text,
      {cbComName.Text,}IntToStr(comReader.BaudRate), cbParity.Text,
      cbByteSize.Text, cbStopBits.Text]);   {Format()函数用来将字符串按指定的格式输出%[<参数位置>:][-][<所占宽度>][.<小数位数>]<类型>
                                              说明:若缺省[<参数位置>:],则从左到右依次分配各参数;"-"表示左对齐,若缺省则
                                              右对齐;<类型>为参数的类型     其中这里的 %后的S表示的是将结果转化为字符串型数据}
  end
  else
    edStatus.Text := ' 当前串口状态: '+cbComName.Text+'已关闭';
end;

 

procedure TfrmReader.cbBaudRateChange(Sender: TObject);  //波特率改变之后发生的状况
var
  BaudRate: Integer;
begin
  if cbBaudRate.Text = 'Custom' then
  begin
    cbBaudRate.Style := csDropDown; //csDropDown是由编辑框和列表框组合而成的组合框,列表框中的任一项都是高度相同的字符串
    cbBaudRate.SetFocus;    // 设置键盘焦点  (也就是键盘输入有效))
    btnChComm.Enabled := false; //“打开串口”按钮不使能
  end
  else
  begin
    if cbBaudRate.ItemIndex > 0 then
      cbBaudRate.Style := csDropDownList; // csDropDownList只有列表框而没有编辑框,任一项是高度一致的字符串
      //下面是自定义波特率的
    if TryStrToInt(cbBaudRate.Text, BaudRate) then   //TryStrToInt:返回字符串S转换成整数Value是否成功
    begin
      comReader.BaudRate := BaudRate;   //吧选择的串口信息传递到COMreader的信息当中
      btnChComm.Enabled := true;         //“打开串口”按钮使能
    end
    else
      btnChComm.Enabled := false;
  end;
end;

procedure TfrmReader.edtSecPwd0DblClick(Sender: TObject);
begin
     edtSecPwd0.Text :='';                                   //双击使它变为空
end;

procedure TfrmReader.edtSecPwd1DblClick(Sender: TObject);
begin
     edtSecPwd1.Text :='';
end;

procedure TfrmReader.edtSecPwd2DblClick(Sender: TObject);
begin
        edtSecPwd2.Text :='';
end;

procedure TfrmReader.edtSecPwd3DblClick(Sender: TObject);
begin
      edtSecPwd3.Text :='';
end;

procedure TfrmReader.edtSecPwd4DblClick(Sender: TObject);
begin
   edtSecPwd4.Text :='';
end;

procedure TfrmReader.edtSecPwd5DblClick(Sender: TObject);
begin
     edtSecPwd5.Text :='';
end;

procedure TfrmReader.edtSecPwd6DblClick(Sender: TObject);
begin
     edtSecPwd6.Text :='';
end;

procedure TfrmReader.edtSecPwd7DblClick(Sender: TObject);
begin
    edtSecPwd7.Text :='';
end;

procedure TfrmReader.edtSecPwd8DblClick(Sender: TObject);
begin
    edtSecPwd8.Text :='';
end;

procedure TfrmReader.edtSecPwd9DblClick(Sender: TObject);
begin
   edtSecPwd9.Text :='';
end;

procedure TfrmReader.edtSecPwd10DblClick(Sender: TObject);
begin
    edtSecPwd10.Text :='';
end;

procedure TfrmReader.edtSecPwd11DblClick(Sender: TObject);
begin
    edtSecPwd11.Text :='';
end;

procedure TfrmReader.edtSecPwd12DblClick(Sender: TObject);
begin
     edtSecPwd12.Text :='';
end;

procedure TfrmReader.edtSecPwd13DblClick(Sender: TObject);
begin
   edtSecPwd13.Text :='';
end;

procedure TfrmReader.edtSecPwd14DblClick(Sender: TObject);
begin
     edtSecPwd14.Text :='';
end;

procedure TfrmReader.edtSecPwd15DblClick(Sender: TObject);
begin
     edtSecPwd15.Text :='';
end;

procedure TfrmReader.FormCreate(Sender: TObject);
begin

  EnumComPorts(cbComName.Items);    //得到串口列表
  EnumComPorts(ComboBox1.Items);    //得到串口列表
  if (copy(cbComName.Items[1],1,2)<>'') then    //如果有得到空闲的串口的信息那么就显示获取的串口的第一位
      begin
        cbComName.ItemIndex := 1;
        ComboBox1.ItemIndex := 1;
      end
    else
       begin
         cbComName.ItemIndex:=0;
         ComboBox1.ItemIndex:=0;
         end;
  comReader.CommName := cbComName.Text;  //把得到的串口的值付给COMM控件的相关属性
  cbBaudRate.ItemIndex := 4;  //波特率下拉框的默认值为第四位
  comReader.BaudRate := StrToInt(cbBaudRate.Text);    //COMM控件的波特率设置
  cbParity.ItemIndex := 0;
  comReader.Parity := None;   {以下的都为默认值不用管}
  cbByteSize.ItemIndex := 3;
  comReader.ByteSize := _8;
  cbStopBits.ItemIndex := 0;
  comReader.StopBits := _1;
end;

//得到串口列表
procedure TfrmReader.EnumComPorts(Ports: TStrings);//枚举串口列表(不用管它是怎样实现的。。底层的)
var
  KeyHandle: HKEY;
  ErrCode, Index: Integer;
  ValueName, Data: string;
  ValueLen, DataLen, ValueType: DWORD;
  TmpPorts: TStringList;
begin
  ErrCode := RegOpenKeyEx(
    HKEY_LOCAL_MACHINE,
    'HARDWARE\DEVICEMAP\SERIALCOMM',
    0,
    KEY_READ,
    KeyHandle);

  if ErrCode <> ERROR_SUCCESS then
    Exit;  // raise EComPort.Create(CError_RegError, ErrCode);

  TmpPorts := TStringList.Create;
  try
    Index := 0;
    repeat
      ValueLen := 256;
      DataLen := 256;
      SetLength(ValueName, ValueLen);
      SetLength(Data, DataLen);
      ErrCode := RegEnumValue(
        KeyHandle,
        Index,
        PChar(ValueName),
        Cardinal(ValueLen),
        nil,
        @ValueType,
        PByte(PChar(Data)),
        @DataLen);

      if ErrCode = ERROR_SUCCESS then
      begin
        SetLength(Data, DataLen);
        TmpPorts.Add(Data);
        Inc(Index);
      end
      else
        if ErrCode <> ERROR_NO_MORE_ITEMS then
          exit; //raise EComPort.Create(CError_RegError, ErrCode);

    until (ErrCode <> ERROR_SUCCESS) ;

    TmpPorts.Sort;
    Ports.Assign(TmpPorts);
  finally
    RegCloseKey(KeyHandle);
    TmpPorts.Free;
  end;

end;        //到这里都是串口枚举函数

procedure TfrmReader.Button19Click(Sender: TObject);
begin
    edtSecPwd0.Text :='';
    edtSecPwd1.Text :='';
    edtSecPwd2.Text :='';
    edtSecPwd3.Text :='';
    edtSecPwd4.Text :='';
    edtSecPwd5.Text :='';
    edtSecPwd6.Text :='';
    edtSecPwd7.Text :='';
    edtSecPwd8.Text :='';
    edtSecPwd9.Text :='';
    edtSecPwd10.Text :='';
    edtSecPwd11.Text :='';
    edtSecPwd12.Text :='';
    edtSecPwd13.Text :='';
    edtSecPwd14.Text :='';
    edtSecPwd15.Text :='';
end;

procedure TfrmReader.Button20Click(Sender: TObject);
begin
    edtSecPwd0.Text :='FFFFFFFFFFFF';
    edtSecPwd1.Text :='FFFFFFFFFFFF';
    edtSecPwd2.Text :='FFFFFFFFFFFF';
    edtSecPwd3.Text :='FFFFFFFFFFFF';
    edtSecPwd4.Text :='FFFFFFFFFFFF';
    edtSecPwd5.Text :='FFFFFFFFFFFF';
    edtSecPwd6.Text :='FFFFFFFFFFFF';
    edtSecPwd7.Text :='FFFFFFFFFFFF';
    edtSecPwd8.Text :='FFFFFFFFFFFF';
    edtSecPwd9.Text :='FFFFFFFFFFFF';
    edtSecPwd10.Text :='FFFFFFFFFFFF';
    edtSecPwd11.Text :='FFFFFFFFFFFF';
    edtSecPwd12.Text :='FFFFFFFFFFFF';
    edtSecPwd13.Text :='FFFFFFFFFFFF';
    edtSecPwd14.Text :='FFFFFFFFFFFF';
    edtSecPwd15.Text :='FFFFFFFFFFFF';
end;
end.
posted @ 2012-07-28 01:01  编程小爬虫  阅读(126)  评论(0编辑  收藏  举报