Чтение должно происходить в не в основном потоке программы, а в специально созданном для этого. Тогда зависания окна программы не будет. Что бы поток не грузил проц на 100% нужно его приостанавливать, а пробуждать по приходу байта в порт. делается примерно так:
Код:
procedure TRdThread.Execute;
Var
ComStat:TComStat; //состояние порта
Errs:Cardinal;
RdOvr:TOverlapped; //параметры асинхронной операции чтения
begin
FillChar(RdOvr,SizeOf(TOverlapped),0);// инициализируем структуру TOverlapped
RdOvr.hEvent:=CreateEvent(nil, //параметры защиты, если nil, то беруться от родительского процесса
true, //режим управления событием
false,//начальное состояние false - несигнальное состояние (занят)
nil //имя обекта nil - нет имени
);
SetCommMask( //задаем события, которые будут отслеживаться портом
Port, //дескриптор порта
//EV_RXCHAR //маска событий EV_RXCHAR-принят байт
EV_RXFLAG //маска событий EV_RXCHAR-принят байт
);
while not Terminated do begin
WaitCommEvent( // инициируем ожидание
Port, //дескриптор порта
mask, //маска событий
@RdOvr //указатель на WrOvr
);
WaitForSingleObject(RdOvr.hEvent,INFINITE); //ждем
GetOverlappedResult(Port,RdOvr,nRead,false); //после этого в переменной mask будет маска того события которое произошло
ClearCommError(Port,Errs,@ComStat); //считываем состояние порта
nToRead:=ComStat.cbInQue; //считываем число байт для чтения из структуры
GetMem(RcBuf,nToRead);
if not ReadFile(Port,RcBuf^,nToRead,nRead,@RdOvr) //считываем данные
then Synchronize(UpdateMainFormlabel5) //Если данные не считались выводим сообщение об ошибке
else Synchronize(UpdateMainForm); //Если данные считались выводим их на форму
FreeMem(RcBuf); //Освободим буфер
end;
end;
С помощью CreateEvent сначала создаем объект "событие", потом настраиваем COM порт (функция SetCommMask) так что бы при определенных событиях (например прием байта) изменялось состояние объекта "событие", созданного функцией CreateEvent. Потом "связываем" нужный порт с нужным объектом "событием" с помощью функции WaitCommEvent, затем останавливаем поток(WaitForSingleObject), который проснется автоматически как только изменится сотояние "события", а оно меняется при появлении данных.
Вот как то так.