Конференция "Основная" » ciacomport [D7, Win2k, WinXP]
 
  • Максим (09.04.08 12:06) [0]
    Здравствуйте.
    При работе с компонентом ciacomport под Дельфи 7 столкнулся вот с какими проблемами:
    - При компиляции на различных платформах Windows (2000/2003/XP различных сборок и сервиспаков) компонент ведет себя по разному.
    - вторая проблема, наверняка тоже связана с первой. При работе с термопринтером (com-порт) одна и та же функция печати в одной программе ведет себя не совсем так как хочется.

    Сначало о первом.
    Работал на XP Professional писал проект с использованием этого компонента. После переустановки Windows на XP Home, оборудование на отрез отказалось работать в той же самой сборке компонентов. прищлось вносить небольшие изменения, чтобы привести все в чувство. Зато она хорошо закомпилировалась на Win2003 и прекрасно все заработало.

    Теперь о второй проблеме.
    Фукция печати чека работает не по закону всемирного программирования ))). У меня есть главная форма и форма, на которой лежит сам компонент CiaComPort. На этой же форме расположена функция печати. При вызове функции из главной формы этой функции вроде все работает верно (по крайней мере как и хочется). А вот при вызове этой же самой функции из второй формы печать идет, но не заканчивается. Она прерывается напечатав только часть данных и останавлиается. Правда есть одна особенность - после печати, я закрываю форму. Но я проверил - порт даже после закрытия формы остается открытым (ранее выяснил, что при закрытии порта он останавливает процесс печати).

    Вот так выглядит моя функция печати до модификации
    procedure TDataM.PrintChek(s:string);
    var s1: String;
       sc:PChar;
    begin
     try
       CiaComPort1.Open:=False;
       CiaComPort1.Parity:=ptNone;
       CiaComPort1.Baudrate:=19200;
       CiaComPort1.Open:=True;

       sc:=PChar(s+#$0A);
       s1:=sc;
       CharToOem(sc,PChar(s1));

       CiaComPort1.SendStr(#$1B#$4D#$00); //размер шрифта.
       CiaComPort1.SendStr(s1+#$A#$D#$A#$D#$A#$D#$A#$D#$A#$D);
       CiaComPort1.SendStr(#$1D#$49#$01);
       CiaComPort1.SendStr(#$1B#$69);
     except
       CiaComPort1.Open:=False;
     end;
    end;

    А вот так после:
    procedure TDataM.PrintChek(s:string);
    var s1: String;
       sc:PChar;
    begin
     try
       CiaComPort1.Baudrate:=19200;
       CiaComPort1.Open:=False;
       CiaComPort1.Open:=True;
       CiaComPort1.Accessible;

       sc:=PChar(s+#$0A);
       s1:=sc;
       AnsiToOem(sc,PChar(s1));

       //CiaComPort1.SendStr(#$1B+'t'+#$09); //Windows Character.
       CiaComPort1.PurgeTx;
       CiaComPort1.SendStr(#$1B+'t'+#$07); //DOS Character.
       CiaComPort1.ProcessMessages;
       sleep(10);

       CiaComPort1.PurgeTx;
       CiaComPort1.SendStr(#$1B#$4D#$00); //размер шрифта.
       CiaComPort1.ProcessMessages;
       sleep(10);
       CiaComPort1.PurgeTx;
       CiaComPort1.SendStr(s1+#$A#$D#$A#$D#$A#$D#$A#$D#$A#$D);
       CiaComPort1.ProcessMessages;

       sleep(100);

       CiaComPort1.PurgeTx;
       CiaComPort1.SendStr(#$1D#$49#$01);
       CiaComPort1.ProcessMessages;
       sleep(100);

       CiaComPort1.PurgeTx;
       CiaComPort1.SendStr(#$1B#$69); // Отрезка чека
       CiaComPort1.ProcessMessages;
       sleep(100);

       log('print chek','Ok');
     except
      on e:Exception do
      begin
       log('print chek','ERROR:'+e.Message);
       CiaComPort1.Open:=False;
      end;
     end;
    end;

    p.s.: компонент версии 1.15. Принтер CITIZEN CBM1000 Serial.
    Хотя тип устройства значения не имеет, т.к. они все перестали работать.

    Заранее благодарю.
  • Сергей М. © (09.04.08 12:32) [1]

    > Фукция печати чека работает не по закону всемирного программирования


    Эт точно)
    По закону всемирного программирования конструкция try..except используется, мягко говоря, иначе)
  • Максим (09.04.08 12:56) [2]
    Мягко говоря он в Экскепт не попатает.
    А что с конструкцией!?
    try
     ...
    except
     on e:Exception do
     begin
      log('EXCEPT','ERROR:'+e.Message);
     end;
    end;
    Что в ней не так!?
  • Максим (09.04.08 13:00) [3]
    Вырезка из справки:
    try
    ...
    except
     on E: Exception do ErrorDialog(E.Message, E.HelpContext);
    end;
    Не вижу ничего некорректного.
  • Сергей М. © (09.04.08 13:02) [4]
    try
     .. настройка порта
     .. открытие порта
     try
       .. работа с открытым портом
     finally
       .. закрытие порта    
     end;
    except
     .. обработка и/или протоколирование исключений
    end;
  • Максим (09.04.08 13:12) [5]
    Собственно - проблема то не в этом. Хотя за совет спасибо.

    Я порт по окончанию работы не закрываю, т.к. Если закрыть, то он прерывает отправку и перестает печатать. Он работает в синхронном режиме. А как избавится от этой зависимости я не знаю не нашел.
    Хотя там есть такая процедура:
    CiaComPort1.CloseDelayed;
    не могу понять что это и как оно работает.
  • Сергей М. © (09.04.08 13:15) [6]

    > Он работает в синхронном режиме


    Судя по


    > порт по окончанию работы не закрываю, т.к. Если закрыть,
    >  то он прерывает отправку и перестает печатать


    как раз строго наоборот - в асинхронном.
  • Максим (09.04.08 13:24) [7]
    функция WriteFile возвращает True или False. Она показывает завершена ли отправка данных или нет.

    т.е. пока он там отправляет (фоном) я могу что то еще отправить. Это и есть Асинхронный!?
  • Сергей М. © (09.04.08 13:27) [8]

    > функция WriteFile возвращает True или False


    Ты о какой функции ? WinAPI'шной ?
  • Максим (09.04.08 13:32) [9]
    наткнулся вот на эту статью.
    http://www.delphimaster.ru/articles/comport2/index.html
    с мсходничком. Попробую покапаться и реализовать без компонента.
    Однако все равно замечу, что на разных платформах виндовс они почему то по разному работают. Видимо разные библеотеки.
  • Сергей М. © (09.04.08 13:36) [10]
    Ты не ответил на вопрос ..
  • Максим (09.04.08 13:37) [11]
    WinAPI
  • Сергей М. © (09.04.08 13:41) [12]
    А как ееиспользование связано с приведенным тобой кодом ?
    Не вижу там никаких WriteFile ..
  • Максим (09.04.08 13:47) [13]
    Эта функция вызывается компонентом:

    procedure TCiaComPort.SendStr(const Tx: string);
    begin
      Send(Pointer(Tx), Length(Tx));
    end;

    function TCiaComPort.Send(Buffer: Pointer; Len: integer): cardinal;
    var
      TxLen: cardinal;
    begin
      Result := 0;
      if not FOpen then
         raise ECiaComPort.Create('Port not open');

      if (Len <= 0) or not Assigned(Buffer) then
         Exit;

      if FSending or (FTxBuf.Count > 0) then begin
         Result := Len;
         FTxBuf.Write(Buffer, Len);
         Exit;
      end;

      TxLen := Min(Len, FTxBuffer);
      InternalSend(Buffer, TxLen);
      FSending   := True;
      FSendCount := TxLen;

      FTxBuf.Write(PChar(Buffer) + TxLen, cardinal(Len) - TxLen);
      Result := Len;
      // hier
    end;

    function TCiaComPort.InternalSend(Buffer: Pointer; Len: integer): cardinal;
    begin
      FillChar(OverLapTx, SizeOf(TOverLapped), 0);
      WriteFile(FCommThread.ComHandle, Buffer^, Len, Result, @OverLapTx);
    end;
  • Сергей М. © (09.04.08 13:50) [14]

    > Эта функция вызывается компонентом


    Теперь понятно.
    Такой компонент можно смело выбросить в корзину.

    Но если ответ на вопрос о режиме работы все же интересует, ищи в исходниках фрагмент , где вызывается CreateFile() - по ее параметрам как раз и определишь режим.
  • Максим (09.04.08 13:56) [15]
    Спасибо! )))
    Компонент реально нестабилен в работе, несмотря на все его преимущества.
    На него его и влияет работа системы, т.е. если ситема слабенькая, то задержки между отправляемыми и получаемыми данными различны и порой доходит до того, что я получаю данные кусками или наоборот 2-3 ответа от порта склеиваются в один, что усложняет процесс обработки.
  • Максим (09.04.08 14:33) [16]
    А что Вы можете посоветовать для работы с потром, помимо того что реализовать работу с портом самостоятельно. По идее тот пример в статье белее-менее актуален и прост в использовании, но как там написано "в реальности необходимо обработать все возможные ошибки", а унего больше половины вырезано.
  • Kolan © (09.04.08 14:37) [17]
    Конечно лучьше самому сделать, но можно взять AsyncPro раз самому не написать.
  • Сергей М. © (09.04.08 14:39) [18]

    > можно взять AsyncPro раз самому не написать


    Можно, если самому сложно.
  • Максим (09.04.08 14:49) [19]
    Аха. Помницца попадалась мне такая штучка, универсальная, которая много чего усеет, но поэксперементировать тогда не было возможности. Еще раз Спасибо!
 
Конференция "Основная" » ciacomport [D7, Win2k, WinXP]
Есть новые Нет новых   [134487   +52][b:0][p:0.001]