![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как завершить второй поток, работая с СОМ портом. [D7, WinXP]
MadGhost © (2005-11-28 10:09:00)Приветствую уважаемые мастера.
Встал следующий вопрос:
Необходимо данные с СОМ порта отсылать на несколько компьютеров, я использовал не компонент а использовать WinAPI функции, второй поток запустил в котором хочу принимать данные.
До конца не добрался, но когда закрываю программу выдает ошибку.
function TForm1.OpenCommPort:boolean;
begin
hPort := CreateFile('COM1', GENERIC_READ or GENERIC_WRITE, 0, nil,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if hPort = INVALID_HANDLE_VALUE then raise Exception.Create('Error opening port');
if not GetCommState(hPort, Dcb) then
raise Exception.Create('Error setting port state');
Dcb.BaudRate := CBR_9600;
Dcb.Parity := NOPARITY;
Dcb.ByteSize := 8;
Dcb.StopBits := ONESTOPBIT;
if not SetCommState(hPort, Dcb) then raise Exception.Create('Error setting port state');
if not PurgeComm(hPort, PURGE_TXCLEAR or PURGE_RXCLEAR) then
raise Exception.Create('Error purging port');
//ïðîãðàììà äîëæíà îæèäàòü ñîáûòèÿ î ïðèåìå îäíîãî èëè íåñêîëüêèõ
//áàéò èç ÑÎÌ ïîðòà..
if not SetCommMask(hPort, EV_RXCHAR) then raise Exception.Create('Error seting port mask');
result := true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
CommThread1: TCommThread;
begin
OpenCommPort;
StopThread.hEvent := CreateEvent(nil, true, false, nil);
CommThread1.Create(false);
h := CommThread1.Handle;
end;
вот, во втором потоке
procedure TCommThread.Execute;
var
ComStat: TComStat;
dwMask, dwError, dwRes: DWORD;
OverRead: array [0..1] of TOverlapped;
Buf: array [0..$FF] of byte;
dwRead: DWORD;
begin
{ Place thread code here }
OverRead[0].hEvent := CreateEvent(nil, True, True, nil);
OverRead[1].hEvent := StopThread.hEvent;
FreeOnTerminate := true;
while not Terminated do
begin
if not WaitCommEvent(hPort, dwMask, @OverRead) then
begin
if GetLastError = ERROR_IO_PENDING then
begin
dwRes := WaitForMultipleObjects(2, @OverRead, FALSE, 500);
case dwRes of
WAIT_OBJECT_0:
end;
end
else
raise Exception.Create('Error waiting port event');
end;
if not ClearCommError(hPort, dwError, @ComStat) then
raise Exception.Create('Error clearing port');
dwRead := ComStat.cbInQue;
if dwRead > 0 then
begin
if not ReadFile(hPort, Buf, dwRead, dwRead, @OverRead) then
raise Exception.Create('Error reading port');
end;
end;
end;
1.вот таким образом вопрос, как корректно в этом случае завершить второй поток?
2.Как WriteBytes: array of Byte; переделать в String и обратно?
Заранее спасибо. Нужно очень скоро.
MadGhost (2005-11-28 12:22:00) [21]Leonid Troyanovsky © (28.11.05 10:42) [1]
1. Да, надо отменить как то операцию чтения из порта, и завершить корректно поток.
2. Поточнее можно, если можно?
заранее благодарен
Leonid Troyanovsky (2005-11-28 10:42:00) [22]
> MadGhost © (28.11.05 10:09)
> 1.вот таким образом вопрос, как корректно в этом случае
> завершить второй поток?
> 2.Как WriteBytes: array of Byte; переделать в String и обратно?
1. CancelIO ?
2. SetString, Move
--
Regards, LVT.