为什么我的MSComm控件的OnComm事件会不断的重复执行啊,导致接收的数据为空,报“variant array index out of bounds”的错误,我的MSComm控件的参数是这样的:procedure TForm1.FormCreate(Sender: TObject);
begin
  MSComm1.CommPort := 1;
  MSComm1.DTREnable := false;   //确定在通信时是否使(DTR)线有效
  MSComm1.RTSEnable := false;   //
  MSComm1.EOFEnable := false;   //
  MSComm1.Handshaking := comNone;//握手协议
  MSComm1.NullDiscard := false;  MSComm1.InBufferSize := 1024;
  MSComm1.OutBufferSize := 1024;
  MSComm1.InputLen := 0;        //设置并返回Input属性从缓冲区中每次读取的字
  MSComm1.RThreshold := 5;      //设置或返回输入缓冲区中存放接收字符的最小数
  MSComm1.SThreshold := 0;      //输出
  MSComm1.InputMode := comInputModeBinary;//设置或返回 Input 属性取回的数据的类型为16进制
  MSComm1.Settings := '9600,n,8,1'      //BCD码
end;OnComm事件是这样的:procedure TForm1.MSComm1Comm(Sender: TObject);
var
  codesize : Integer;
begin
  codesize := MSComm1.InBufferCount;
  data := varArrayCreate([0,codesize-1],varByte);
  case MSComm1.CommEvent of
    comEvCD,comEvCTS,comEvDSR,comEvSend,comEvRing,comEvReceive:
     begin
       buffer := MSComm1.Input;
       data := buffer;
       MSComm1.InBufferCount := 0;
       if (data[0] = $AA) and (data[1] = $3) and (data[2] = $A2) and (data[3] = $0) and (data[4] = $25) then
       begin
         Send_Succ := true;
         if length(MemoShow.Text) = 7 then
         begin
           MemoShow.Text := '';
         end;
         if IntToStr(CommandCode) = '$A' then
         begin
           MemoShow.Text := '*';
         end
         else if IntToStr(CommandCode) = '$B' then
         begin
           MemoShow.Text := '#';
         end
         else
         begin
           MemoShow.Text := MemoShow.Text + IntToStr(CommandCode);
         end;
       end
       else if (data[0] = $AA) and (data[1] = $3) and (data[2] = $A1) then
       begin
         FCS := 0;
         buf[0] := StrToInt('$AA');
         buf[1] := StrToInt('$3');
         buf[2] := StrToInt('$A2');
         buf[3] := StrToInt('$0');
         buf[4] := StrToInt('$25');
         MSComm1.InBufferCount := 0;
         sBuf := buf;
         MSComm1.Output := sBuf;         State := data[3];
         case State of
           0:
           begin
             lbShow.Caption := '住户呼叫中心机.....';
           end;
           1:
           begin
             lbShow.Caption := '住户通话中.....';
           end;
           2:
           begin
             lbShow.Caption := '网络呼叫中.....';
           end;
           3:
           begin
             lbShow.Caption := '网络通话中.....';
           end;
           4:
           begin
             lbShow.Caption := '网络监视中....按*键退出!';
           end;
           5:
           begin
             lbShow.Caption := '无此住户';
           end;
           6:
           begin
             lbShow.Caption := '网络忙';
           end;
           7:
           begin
             lbShow.Caption := '网络空闲';
           end;
         end;
       end
       else
       begin
         Send_Succ := False;
       end;
     end;
  end;
end;

解决方案 »

  1.   

    就是当执行到OnComm事件的过程时,第一遍下来是正常的,执行到最后一个end;时,又跳到最前面的begin开始执行,由于这时缓存中的数据为空,随意导致报“variant  array  index  out  of  bounds”的错误
      

  2.   

    如果你没有收到数据,此时codesize为0,那么
    data := varArrayCreate([0,codesize-1],varByte);-------->>>>>>>>>>.
    data := varArrayCreate([0,-1],varByte);是会出错的。
    把这句放到里面。
      case MSComm1.CommEvent of
        comEvCD,comEvCTS,comEvDSR,comEvSend,comEvRing,comEvReceive:
         begin
           data := varArrayCreate([0,codesize-1],varByte);
           buffer := MSComm1.Input;
      

  3.   

    还是不行啊,虽然放进去了,但是仍然报那个错误,是在这个地方报错的“if (data[0] = $AA) and (data[1] = $3) and (data[2] = $A2) and (data[3] = $0) and (data[4] = $25) then
    ”,就是这个data的数据为空的
      

  4.   

    老兄啊,你不判断datasize就使用data是很不安全的啊。其实,在函数入口处判断就可以了,判断
    if datasize<*** then
        exit;
    就是,如果datasize小于完整的数据长度,就是错误的数据,此时就不能进行下面的处理的。
      

  5.   

    不懂噎,我这里有datasize吗?能否说清楚点啊,多谢!!!
      

  6.   

    错了,是codesize。你要判断数据的准确性,才能进行下一步的处理。
      

  7.   

    为什么MSComm1.InBufferCount为0,还会发生OnComm事件啊,偶我新人,不大懂噎,请指教!!!
      

  8.   

    当有新字符到达,或端口状态改变,或发生错误时,MSComm控件都将解发OnComm事件,而应用程序在捕获该事件后,通过检查MSComm控件的CommEvent属性可以获知所发生的事件或错误,从而采取相应的操作。