WaitCommEvent failing

I have the following code segents in my app:

  ovlap: OVERLAPPED;

  ...

  ovlap.hEvent := CreateEvent(nil,true,false,PChar('VPW'));

  ...

  SetCommMask(fd,EV_DSR);

  ...

  fd := CreateFile(PChar(Name),GENERIC_READ+GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL+FILE_FLAG_OVERLAPPED,0);
  if ( fd=INVALID_HANDLE_VALUE ) then
    Raise EVpw.CreateFmt('Can''t open %s. %s',[Name,WinMsg(GetLastError)]);

  ...

  if ( not WaitCommEvent(fd,flag,@ovlap) ) then
  begin
    err := GetLastError;
    if ( err<>ERROR_IO_PENDING ) then
      Raise EVpw.CreateFmt('WaitCommEvent(~DSR) failed for %s. %s',[Name,WinMsg(err)]);
    state := WaitForSingleObject(ovlap.hEvent,10);

  ...

  The call to WaitCommEvent returns FALSE and
  err is set to 87="The parameter is incorrect".

Can anyone tell me why and how to fix it?
LVL 6
zebadaAsked:
Who is Participating?
 
intheConnect With a Mentor Commented:
hi zebada,
here is the example,i founbd it a while back when i wanted some port stuff without using components.
hope it is useful for you ;-)
Regards Barry



type
TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    bContinue   :  boolean;
    hcomm       :  THandle;
    CommTimeouts   : TCommTimeouts;
    overlappedRead : TOverlapped;
    overlappedWait : TOverlapped;
    dwEventMask    : DWord;
    inputbuffer    : array [0..2047] of byte;
    function CheckForCharacters:boolean;
    procedure SetupSerial;
  public
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
  dwDummy   : dword;
  bWait          : boolean;
  bStartWait   : boolean;
begin
  SetupSerial;
  bContinue:=true;
  bStartWait:=true;
  bwait:=false;
  while bContinue do // Now continue looping every Second
   begin
    if bStartWait then
     begin
       bStartWait:=false;
       bWait:=WaitCommEvent(hcomm,dwEventMask,@overlappedWait);
     end;
    if not bWait then
     begin
     // showmessage(syserrormessage(getlasterror));
        If WAIT_OBJECT_0 = WaitForSingleObject(overlappedWait.hEvent,1000) then
            if GetOverlappedResult(hComm,overlappedWait,dwdummy,false) then
              if ((dwEventMask and EV_RxChar)=EV_RxChar) then
               begin
                 // Character(s) arrived- now do a readfile operation
                 CheckForCharacters;
                 bStartWait:=true;
               end;
     end else
          begin
            if GetOverlappedResult(hComm,overlappedWait,dwdummy,false) then
              if ((dwEventMask and EV_RxChar)=EV_RxChar) then
               begin
                 // Character(s) already there- now do a readfile operation
                 CheckForCharacters;
                 bStartWait:=true;
               end;
          end;
      application.processmessages;
   end; // while bContinue
  //Close the commport
  CloseHandle (hComm );
  CloseHandle (overlappedWait.hEvent);
  CloseHandle (overlappedRead.hEvent);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 bContinue:=false;
end;



procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  bContinue:=false;
end;

procedure TForm1.SetupSerial;
var dcb            :  TDCB;
begin
  Fillchar(overlappedread,SizeOf(overlappedread),0);
  Fillchar(overlappedwait,SizeOf(overlappedwait),0);
  // Create manual-reset events in nonsignaled state
  overlappedread.hevent:=CreateEvent(nil,True,True,nil);
  overlappedwait.hevent:=CreateEvent(nil,True,True,nil);
  hComm := CreateFile( PChar('COM1'),
                                     GENERIC_READ+GENERIC_WRITE,
                                     0, {no Filesharing}
                                    nil, {security always 0}
                                   OPEN_EXISTING,
                                   FILE_FLAG_OVERLAPPED, 0);
  GetCommState( hComm, dcb );
  dcb.Flags:=1 + DTR_Control_Enable shl 4 +
                 RTS_CONTROL_HANDSHAKE shl 12; // Handshake Protocol
  dcb.Baudrate:=CBR_9600;
  dcb.ByteSize:=8;        // 8 Databits
  dcb.Parity:=NOPARITY;   // No Parity
  dcb.StopBits:=ONESTOPBIT;
  SetCommState(hcomm,dcb);
  GetCommTimeouts( hComm, commtimeouts );
  commtimeouts.ReadIntervalTimeout:= 20;
  commtimeouts.ReadTotalTimeoutMultiplier:=0;
  commtimeouts.ReadTotalTimeoutConstant:= 250;
  SetCommTimeOuts(hcomm,commtimeouts);
  GetCommMask(hcomm,dwEventMask);
  dwEventMask:=dwEventMask or EV_RXCHAR;
  SetCommMask(hcomm,dwEventMask);
  SetupComm(hcomm,2048,2048);
end;

function TForm1.CheckForCharacters: boolean;
var
  dwDummy : DWord;
  dwBytesRead: DWord;
  s:string;
begin
 ReadFile(hcomm,inputbuffer,sizeof(inputbuffer),dwDummy,@overlappedRead);
 if GetOverlappedResult(hComm,overlappedRead,dwBytesRead,true) then
  begin
   setLength(s,dwBytesRead);
   move(inputbuffer,s[1],dwBytesRead);
   memo1.text:=memo1.text+s;
   result:=true;
  end else result:=false;

end;
0
 
intheCommented:
hi,
i cant see why your getting that error but if you want i have an example of waiting for an event on the comport using WaitComEvent(),WaitForSingleObject etc..
0
 
zebadaAuthor Commented:
Hi inthe,

An example would be great.

I have found that I don't get the error on the first few times. Only after I have called WaitCommEvent maybe three or four times. If I put a SetCommMask before WaitCommEvent then I don't get any errors - because SetCommMask will clear any pending waits. I think it might be something to do with the fact that I might be trying to wait on an event that I am already waiting on, if you know what I mean.
0
 
zebadaAuthor Commented:
Thanks Barry,

By looking at the code I figured out where I was going wrong.

Thanks.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.