-
Здравствуйте.
При работе с компонентом 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.
Хотя тип устройства значения не имеет, т.к. они все перестали работать.
Заранее благодарю.
-
> Фукция печати чека работает не по закону всемирного программирования
Эт точно)
По закону всемирного программирования конструкция try..except используется, мягко говоря, иначе)
-
Мягко говоря он в Экскепт не попатает.
А что с конструкцией!?
try
...
except
on e:Exception do
begin
log('EXCEPT','ERROR:'+e.Message);
end;
end;
Что в ней не так!?
-
Вырезка из справки:
try
...
except
on E: Exception do ErrorDialog(E.Message, E.HelpContext);
end;
Не вижу ничего некорректного.
-
try
.. настройка порта
.. открытие порта
try
.. работа с открытым портом
finally
.. закрытие порта
end;
except
.. обработка и/или протоколирование исключений
end;
-
Собственно - проблема то не в этом. Хотя за совет спасибо.
Я порт по окончанию работы не закрываю, т.к. Если закрыть, то он прерывает отправку и перестает печатать. Он работает в синхронном режиме. А как избавится от этой зависимости я не знаю не нашел.
Хотя там есть такая процедура:
CiaComPort1.CloseDelayed;
не могу понять что это и как оно работает.
-
> Он работает в синхронном режиме
Судя по
> порт по окончанию работы не закрываю, т.к. Если закрыть,
> то он прерывает отправку и перестает печатать
как раз строго наоборот - в асинхронном.
-
функция WriteFile возвращает True или False. Она показывает завершена ли отправка данных или нет.
т.е. пока он там отправляет (фоном) я могу что то еще отправить. Это и есть Асинхронный!?
-
> функция WriteFile возвращает True или False
Ты о какой функции ? WinAPI'шной ?
-
-
Ты не ответил на вопрос ..
-
WinAPI
-
А как ееиспользование связано с приведенным тобой кодом ?
Не вижу там никаких WriteFile ..
-
Эта функция вызывается компонентом:
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;
-
> Эта функция вызывается компонентом
Теперь понятно.
Такой компонент можно смело выбросить в корзину.
Но если ответ на вопрос о режиме работы все же интересует, ищи в исходниках фрагмент , где вызывается CreateFile() - по ее параметрам как раз и определишь режим.
-
Спасибо! )))
Компонент реально нестабилен в работе, несмотря на все его преимущества.
На него его и влияет работа системы, т.е. если ситема слабенькая, то задержки между отправляемыми и получаемыми данными различны и порой доходит до того, что я получаю данные кусками или наоборот 2-3 ответа от порта склеиваются в один, что усложняет процесс обработки.
-
А что Вы можете посоветовать для работы с потром, помимо того что реализовать работу с портом самостоятельно. По идее тот пример в статье белее-менее актуален и прост в использовании, но как там написано "в реальности необходимо обработать все возможные ошибки", а унего больше половины вырезано.
-
Конечно лучьше самому сделать, но можно взять AsyncPro раз самому не написать.
-
> можно взять AsyncPro раз самому не написать
Можно, если самому сложно.
-
Аха. Помницца попадалась мне такая штучка, универсальная, которая много чего усеет, но поэксперементировать тогда не было возможности. Еще раз Спасибо!