Hello all,
I'm using a component TComPort for communication with external hardware. The
component contains a thread object which calls events, triggered by the
status of the comport. This is also the only reason why this thread is
needed. This is what happens:
1) In TComport.Open a file handle is created that makes reading from and
writing to the comport possible.
2) Furthermore, the thread object is created. In the thread object a
stopevent is created that makes exiting the execute procedure possible.
3) Application is closed, TComPort.Close is executed. ComThread is Freed, so
StopEvent is set and execute wil be terminated.
4) Then, in TComport.Close, ComHandle is closed. This statement creates an
exception $0E every now and then, with the familiar blue screen. Why does
this happen? Only when I set the priority to tpTimeCritical or when I don't
create the thread object, I don't get a blue screen.
What could be the reason for this?
Thanks in advance for the help!
Roy
***** TComPort object ******
procedure TComPort.Open;
begin
ComHandle := CreateFile(PChar(ComString), GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
ComThread := TComThread.Create;
end;
procedure TComPort.Close;
begin
ComThread.Free;
if ComHandle <> INVALID_HANDLE_VALUE then
CloseHandle(ComHandle);
end;
***** TComThread object *****
procedure TComThread.Execute;
var
EventHandles: Array[0..1] of THandle;
Overlapped: TOverlapped;
dwSignaled, BytesTrans: DWORD;
begin
FillChar(Overlapped, SizeOf(Overlapped), 0);
Overlapped.hEvent := CreateEvent(nil, True, True, nil);
EventHandles[0] := StopEvent;
EventHandles[1] := Overlapped.hEvent;
repeat
WaitCommEvent(Owner.ComHandle, Mask, @Overlapped);
dwSignaled := WaitForMultipleObjects(2, @EventHandles, False, INFINITE);
case dwSignaled of
WAIT_OBJECT_0:
Break;
WAIT_OBJECT_0 + 1:
if GetOverlappedResult(Owner.ComHandle, Overlapped,
BytesTrans, False) then Synchronize(DoEvents);
else Break;
end;
until False;
Owner.PurgeIn;
Owner.PurgeOut;
CloseHandle(Overlapped.hEvent);
CloseHandle(StopEvent);
end;
constructor TComThread.Create(AOwner: TComPort);
begin
inherited Create(True);
StopEvent := CreateEvent(nil, True, False, nil);
Owner := AOwner;
Priority := tpTimeCritical;
Resume;
end;
destructor TComThread.Destroy;
begin
SetEvent(StopEvent);
inherited Destroy;
end;