如题,

解决方案 »

  1.   


    unit MainUnit;interfaceuses
      Windows, SysUtils, Forms, SPComm, Messages;type
      TDllComm = class(TComm)
      private
        procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
          BufferLength: Word);
      end;const
      ERR_SC_SUCCESS = 0;
      ERR_SC_NOTACTIVE = 1;
      ERR_SC_BUSY = 2;
      ERR_SC_TIMEOUT = 3;var
      IsActive: Boolean = False;
      IsBusy: Boolean = False;
      Received: Boolean;  RcvBuf: PChar;
      BufLen: PInteger;
      Comm: TDllComm;
      ReadTimeout: DWord;type
      TReceiveProc = function (RcvBuffer: PChar; Len: Integer): Integer;function OpenComm(Com: DWord; Bandrate: DWord): Boolean; stdcall;
    procedure CloseComm(); stdcall;
    function SendCommCmd(Command: PChar; RcvBuffer: PChar; var Len: Integer): Integer; stdcall;
    procedure SetCommTimeout(Timeout: DWord); stdcall;function SendData(Data: PChar; Len: Integer): Integer;
    procedure SetReceiveProc(OnReceive: TReceiveProc); stdcall;implementationvar
      ReceiveProc: TReceiveProc;procedure TDllComm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    begin
      if IsBusy then
      begin
        CopyMemory(RcvBuf, Buffer, BufferLength);
        BufLen^ := BufferLength;
        Received := True;
      end;  if Assigned(ReceiveProc) then
        ReceiveProc(Buffer, BufferLength);
    end;function OpenComm(Com: DWord; Bandrate: DWord): Boolean; stdcall;
    begin
      if IsActive then CloseComm();  ReadTimeout := 30000;
      Comm := TDllComm.Create(nil);
      Comm.CommName := 'COM' + IntToStr(Com);
      Comm.OnReceiveData := Comm.Comm1ReceiveData;
      Comm.BaudRate := Bandrate;
      Comm.Inx_XonXoffFlow := False;
      Comm.Outx_XonXoffFlow := False;
      try
        Comm.StartComm;
        Sleep(200);
        IsActive := True;
      except
        IsActive := False;
      end;
      Result := IsActive;
    end;procedure CloseComm(); stdcall;
    begin
      if not IsActive then Exit;  Comm.StopComm;
      IsActive := False;
      Comm.Free;
    end;function SendCommCmd(Command: PChar; RcvBuffer: PChar; var Len: Integer): Integer; stdcall;
    var
      i: DWord;
    begin
      if not IsActive then
      begin
        Result := ERR_SC_NOTACTIVE;
        Exit;
      end;
      if IsBusy then
      begin
        Result := ERR_SC_BUSY;
        Exit;
      end;  IsBusy := True;
      try
        Received := False;
        RcvBuf := RcvBuffer;
        BufLen := @Len;    Comm.WriteCommData(Command, Len);
        i := GetTickCount();
        while (not Received) and IsActive do
        begin
          if GetTickCount() - i >= ReadTimeout then
          begin
            Result := ERR_SC_TIMEOUT;
            Exit;
          end;
          Application.ProcessMessages;
        end;
        if not IsActive then
        begin
          Result := ERR_SC_NOTACTIVE;
          Exit;
        end;    Result := ERR_SC_SUCCESS;  finally
        IsBusy := False;
      end;
    end;procedure SetCommTimeout(Timeout: DWord); stdcall;
    begin
      ReadTimeout := Timeout;
    end;function SendData(Data: PChar; Len: Integer): Integer;
    begin
      if not IsActive then
      begin
        Result := ERR_SC_NOTACTIVE;
        Exit;
      end;
      if IsBusy then
      begin
        Result := ERR_SC_BUSY;
        Exit;
      end;  IsBusy := True;
      try
        Comm.WriteCommData(Data, Len);
        Result := ERR_SC_SUCCESS;
      finally
        IsBusy := False;
      end;
    end;procedure SetReceiveProc(OnReceive: TReceiveProc);
    begin
      ReceiveProc := OnReceive;
    end;end.