小弟最近编的程序,出现了很怪的问题,在有的电脑上数据能正常接收,在有的电脑上(性能相对差一些)接收到的数字却是乱的,连字节数都不对,想了几天至今仍一筹莫展。求高手指教!代码大致如下:
//...串口初始化设置
  PostEvent:=CreateEvent(nil,True,True,nil);
  if PostEvent=null then
  begin
    MessageBox(0,'Create Event Error','Notice',MB_OK);
    Form1.StatusBar1.panels[0].Text := '串口打开失败';
    Exit;
  end;
  ReadOs.hEvent :=CreateEvent(nil,true,False,nil);
  if ReadOs.hEvent=null then
  begin
    MessageBox(0,'Create Event Error','Notice',MB_OK);
    CloseHandle(PostEvent);
    StatusBar1.panels[0].Text := '串口打开失败';
    Exit;
  end;
  CommHandle:= CreateFile(pchar('COM'+H),GENERIC_WRITE or GENERIC_READ,
           0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL,0);
  if CommHandle = INVALID_HANDLE_VALUE then
  begin
    CloseHandle(PostEvent);
    CloseHandle(ReadOs.hEvent);
    MessageBox(0,'串口打开失败','Notice',MB_OK);
    StatusBar1.panels[0].Text := '串口打开失败';
    Exit;
  end;
  form1.StatusBar1.panels[0].Text:= '已与端口COM'+H+' 连接!';
  CommTimeOut.ReadIntervalTimeout := MAXDWORD;
  CommTimeOut.ReadTotalTimeoutMultiplier := 0;
  CommTimeOut.ReadTotalTimeoutConstant := 0;
  Commtimeout.WriteTotalTimeoutMultiplier:=0;
  Commtimeout.WriteTotalTimeoutConstant:=0;
  SetCommTimeouts(CommHandle, CommTimeOut);
  SetupComm(CommHandle,4096,1024);
  GetCommState(CommHandle,DCB);
  DCB.BaudRate:=9600;
  DCB.ByteSize:=8;
  DCB.Parity:=NOPARITY;
  DCB.StopBits:=ONESTOPBIT;
  Connected:=SetCommState(CommHandle,DCB);
  if (not SetCommMask(CommHandle,EV_RXCHAR)) then
  begin
    MessageBox(0,'Set CommMask Error','Notice',MB_OK);
    Exit;
  end;
  ReadData;
end;procedure TForm1.ReadData;
var
com_thread:Thandle;
ThreadID:DWORD;
begin
  if not Connected then
  begin
    Form1.StatusBar1.panels[0].Text:='未打开串口';
    Exit;
  end;
  FillChar(ReadOs,sizeof(readOs),0);
  ReadOs.Offset:=0;
  ReadOs.OffsetHigh:=0;
  Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);
  if (Com_thread=0) then
    Application.messagebox('No Create Thread!',nil,mb_OK);
end;procedure CommWatch(Ptr:Pointer);stdcall;
var
dwEvtMask,dwTranser:Dword;
PostMsgFlag:Boolean;
overlapped:Toverlapped;
begin
  Receive:=True;
  FillChar(overlapped,SizeOf(overlapped),0);
  overlapped.hEvent:=CreateEvent(nil,True,False,nil);
  if overlapped.hEvent=null then
  begin
    MessageBox(0,'overlapped.Event Create Error','Notice',MB_OK);
    Exit;
  end;
  while(Receive) do
  begin
    dwEvtMask:=0;
    if not WaitCommEvent(CommHandle,dwEvtMask,@overlapped) then
    begin
      if ERROR_IO_PENDING=GetLastError then
        GetOverLappedResult(CommHandle,overlapped,dwTranser,True);
      end;
      if ((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
      begin
        WaitForSingleObject(Postevent,INFINITE);
        ResetEvent(PostEvent);
        PostMsgFlag:=PostMessage(Form1.Handle,WM_COMMNOTIFY,CommHandle,0);
        if (not PostMsgFlag) then
        begin
          MessageBox(0,'PostMessage Error','Notice',MB_OK);
          Exit;
        end;
      end;
    end;
    CloseHandle(overlapped.hEvent);
end;procedure TForm1.WMCOMMNOTIFY(var Message:TMessage);
var
CommState:ComStat;
dwNumberOfBytesRead:Dword;
ErrorFlag:Dword;
InputBuffer:Array[0..255] of Byte;
begin
  Sleep(50);
  if not ClearCommError(CommHandle,ErrorFlag,@CommState) then
  begin
    MessageBox(0,'ClearCommError','Notice',MB_OK);
    PurgeComm(CommHandle,Purge_Rxabort or Purge_Rxclear);
    Exit;
  end;
  if CommState.cbInQue>0 then
  begin
    Fillchar(InputBuffer,256,0);
    if (not ReadFile(CommHandle,InputBuffer,CommState.cbInQue,dwNumberOfBytesRead,@ReadOs)) then
    begin
      ErrorFlag:=GetLastError();
      if (ErrorFlag <> 0) and (ErrorFlag <> ERROR_IO_PENDING) then
      begin
        MessageBox(0,'ReadFile Error','Notice',MB_OK);
        Receive :=False;
        CloseHandle(ReadOs.hEvent);
        CloseHandle(PostEvent);
        CloseHandle(CommHandle);
        Exit;
      end
      else
      begin
        WaitForSingleObject(CommHandle,INFINITE);
        GetOverlappedResult(CommHandle,ReadOs,dwNumberOfBytesRead,False);
      end;
    end;
    if dwNumberOfBytesRead>0 then
    begin
      Statusbar1.Panels[1].Text:=format('已接收%d字节',CommState.cbInQue]);
      //..提取接收数据后用于处理显示部分代码
   end;
  end;
  SetEvent(PostEvent);
end;