procedure IniCOM;
var i:integer;
begin
{инициализация СОМ — номер в строке stcom}
hCOM:=CreateFile(Pchar(stcom),
GENERIC_READ+GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
st:=stcom+'не найден';
Application.MessageBox(Pchar(st),'Error',MB_OK);
exit;
st:=stcom+' занят или заданы неверные параметры';
Application.MessageBox(Pchar(st),'Error',MB_OK);
exit;
GetCommTimeouts(hCom,comtime); {устанавливаем задержки:}
comtime.WriteTotalTimeoutMultiplier:=1;
comtime.WriteTotalTimeoutConstant:=10;
comtime.ReadlntervalTimeout:=10;
comtime.ReadTotalTimeoutMultiplier:=1;
comtime.ReadTotalTimeoutConstant:=2 000; {ждем чтения 2 с}
SetCommTimeouts(hCom,comtime);
ab[1]:=ord('A'); {будем посылать инициализацию модема}
ab[2]:=ord('T');
ab[3]:=13 ;{CR}
ab[4]:=10 ;{LF}
WriteFile(hCOM,ab,4,xn,nil);
st:=»;
st:=stcom+' занят модемом';
Application.MessageBox(Pchar(st),'Error',MB_OK);
CloseHandle(hCOM); hCOM:=0;
Forml.Label7.Caption:='COM?';
exit;
Form1.Labe17.Caption:=s tcom+' 9600 1;
end;
Сначала текст тут мало отличается от того, что описано во всех стандартных рекомендациях по программированию порта. Единственный момент, который несколько выходит за рамки стандарта: мы не устанавливаем поля структуры DCВ напрямую, а используем функцию BuildCommDCB. Я это делаю отчасти потому, что структура DCB в Delphi транслируется из API не полностью (сравните ее описание в Windows.pas и в Win32.hip), и хотя для данного случая, разумеется, все нужные поля имеются, но функция BuildCommDCB все равно удобнее.
После стандартных установок мы сразу выполняем два действия, о которых упоминают далеко не всегда. Во-первых, мы устанавливаем все возможные задержки (timeout) для разных вариантов приема и передачи. В параметрах, которые заканчиваются на «Multiplier» можно для простоты всегда ставить «1» (если больше, то процедуры чтения/записи будут отслеживать еще и скорость поступления байтов, что нам не требуется). А остальные из этих параметров делают следующее: если задержка посылки через порт больше, чем writeTotaiTimeoutConstant (в миллисекундах), то будет прервана передача, а при задержке между поступающими байтами больше, чем ReadIntervaiTimeout, и при задержке всей процедуры чтения (в данном случае — самый главный параметр) больше, чем ReadTotalTimeoutConstant, будет прерван прием. Последний параметр мы установили равным двум секундам. При выборе этих параметров следует иметь в виду, что один байт при скорости 9600 передается/принимается примерно за 1 мс. Если эти параметры вообще не устанавливать (оставить их в значении «0», как по умолчанию), то при отсутствии принимаемых байтов процедура чтения через ReadFile просто зациклится и «повесит» всю программу.