Листинг 18.4

procedure IniCOM;

var i, err: integer;

begin

    FlagCOM:=False;

    Form1.Label7.Caption:='COM?';

{инициализация COM — номер в строке stcom}

    Form1.AfComPort1.Close; {закрываем старый COM, если был}

    val(stcom[length(stcom)],i,err); {извлекаем номер порта}

    if err=0 then Form1.AfComPort1.ComNumber:=i else exit;

                               {здесь требуется число, а не строка}

     Form1.AfComPortl.BaudRate:=br9600; {скорость 9600}

     try

         Form1.AfComPortl.Open  ;{пробуем открыть}

     except

       if not Form1.AfComPort1.Active then {если не открылся}

       begin

           st:=stcom+' does not be present or occupied.';

           Application.MessageBox(Pchar(st),'Error',MB_OK);

           exit {выход из процедуры — неудача}

       end;

   end;

   ab[1]:=ord('A'); {будем посылать инициализацию модема}

   ab[2]:=ord('Т');

   ab[3]:=13;  {CR}

   ab[4]:=10;  {LF}

   for i:=1 to 4 do Form1.AfComPort1.WriteData(ab[i],1);

   {ответ не сразу:}

   Form1.Timer1.Enabled:=True;

   tall:=0;

   while tall<1 do application.ProcessMessages; {пауза в 1 с}

   Form1.Timer1.Enabled:=False;

   st:=Form1.AfComPort1.ReadString; {ответ модема 10 знаков}

   if pos(1 OK',st)<>0 then {модем}

begin

         st:=stcom+' занят модемом';

         Application.MessageBox(Pchar(st),'Error',MB_OK);

         exit;

   end else {все нормально, COM открыт}

   begin

   Form1.Label7.Caption:=stcom+' 96001;

   FlagCOM:=True;

   end;

end;

Как видим, процедура создания порта много понятнее, чем в случае прямого обращения к API — все через привычную установку свойств компонента. FlagCOM играет у нас роль индикатора, доступен порт или нет. Если он остался при значении False, то процедуру следует повторить с другим значением в строке stcom (каковую мы задаем с помощью ComboBox, см. далее). При определении модема применен хитрый способ задания паузы — вместо обычного оператора Sleep, который тормозит программу, мы использовали таймер. Чтобы это сработало, надо в обработчике события OnTimer: все время увеличивать переменную tall. Полностью процедура по таймеру приводится далее, т. к. tall нам понадобится не только для этого.

Как только мы обратились к процедуре AfComPort1.open, у нас немедленно будет создан параллельный поток и весь прием пойдет через него. Поэтому, чтобы при определении модема принятые байты не обрабатывались, нужно не забыть добавить в процедуру приема выход по условию FiagCOM=Faise.

Для создания этой процедуры обычным способом — через инспектор объектов — создадим обработчик события AfComPort1DataRecived[17] (листинг 18.5).

Листинг 18.5

procedure TForm1.AfComPort1DataRecived(Sender:TObject; Count:Integer);

{чтение очередного байта по сообщению wmCOMPORT}

var i: integer;

begin

    if FlagCOM=False then exit; {если модем еще не опрошен}

    if count<>0 then {если что-то принято}

    begin

        AfComPort1.ReadData(ab,count); {читаем буфер в массив}

        хn:=xn+count; {число принятых байт}

        tall:=0; {обнуляем время}

     end;

end;

На самом деле условие count<>0 не требуется, оно введено просто ради порядка (иначе бы процедура просто не была бы вызвана). По выходу из процедуры в переменной хn будет накапливаться количество принятых байтов. Осталось только дописать остальные процедуры (листинг 18.6).

Перейти на страницу:

Поиск

Похожие книги