Форум: "WinAPI";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
ВнизКосяк с принтером, а точнее с определением его статуса Найти похожие ветки
← →
ChainikDenis © (2006-05-16 22:02) [0]Коллеги, беда!
Коротко:
Чековый принтер на COM2. Типа печатает чеки с номерками клиентов. Задача - определить когда кончается бумага и соответсвенно не печатать.
Засада в том что Винда не обращает внимание на то что в принтере нет бумаги или то что он вообще не подключен. Просто отправляет в COM2 массив байт и считает что на том конце все нормально. Отправку массива определаяю визуально - у меня светодиодики на RxD и TxD сидят.
Принтер достаточно умный и по RS232 может сообщить о своем состоянии все что нужно, НО драйвер принтера занял порт в монопольном режиме и этот порт теперь недоступен!
Хрен бы с ним, сделал так:
var PrnHandle: THandle;
var PrnInfo: TPRINTERINFO2;
var pcbNeeded: DWord;
var PrinterName: string;
PrinterName := "TPTCM60 Dispenser";
if OpenPrinter(PChar(PrinterName), PrnHandle, nil) then
begin
GetPrinter(PrnHandle, 2 , @PrnInfo, 0, @pcbNeeded); // Получаем размер
SetLastError(0); // Собственно толку от нее ни какого
if GetPrinter(PrnHandle, 2 , @PrnInfo, pcbNeeded, @pcbNeeded) then
Form1.StatusBar1.Panels[3].Text := IntToStr(PrnInfo.Status) // Выводим статус
else
Form1.StatusBar1.Panels[3].Text := "Статус не известен...";
ClosePrinter(PrnHandle);
end
else Form1.StatusBar1.Panels[3].Text := "Принтер не доступен";
Но данная конструкция всегда выводит 0 - вне зависимости от состояния принтера, даже если он ваще отключен...
Кстати, если этот кусок втыкаю в обработчик кнопки, то все нормально, а если в обработчик таймера который срабатывает каждые 250 мс, то на этой строке: if GetPrinter(PrnHandle, 2 , @PrnInfo, pcbNeeded, @pcbNeeded) then... в первом же вызове Acces Vialation вылезает... С чего бы это...
Волнует другой вопрос. Для этого принтера есть StatusMonitor - программулина, которая собственно этот статус и показывает. Причем при ее запуске видно что она где-то раз в секунду посылает запрос в COM2 и соответсвенно оттуда ответ получает.. Я б и сам послал_принял, да доступа к порту нет...
Млин..
Что делать-то? Как определить состояние принтера, или как получить доступ к порту?
P.S. Перевел принтер и соответсвенно драйвер принтера на hardware control - стало лучше, но не то. Просто если нет бумаги, то задание висит в очереди печати пока принтер не включишь (или не вставишь бумагу)...
← →
ChainikDenis © (2006-05-16 22:31) [1]
> бумаги, то задание висит в очереди печати пока принтер не
> включишь (или не вставишь бумагу)...
Фиг там - потихоничку "печатается". Примернт по 3 кб в минуту от задания в очереди печати куда-то печатаются. Так что минит через 10 вроде как и напечатал чек... На выключенный принтер...
← →
GanibalLector © (2006-05-17 00:27) [2]2 ChainikDenis
>Для этого принтера есть StatusMonitor - программулина, которая собственно этот статус и показывает. Причем при ее запуске видно что она где-то раз в секунду посылает запрос в COM2 и соответсвенно оттуда ответ получает
Как так? Программулина имеет доступ к порту, а ты нет. Чудеса какие-то.
В конце концов,запусти PortMon и посмотри что творится.
З.Ы. Как вариант,не использовать тот драйвер,а самому взять брозды правления, написав СОМ-сервер.
← →
ChainikDenis © (2006-05-17 00:41) [3]PortMon от SysInternals? Так этож из другой песни...Я про RS232 расказываю. А для того что б понять что порт занять достаточно попытаться его открыть в Терминал Эмуляторе. Но я для надежности еще и класическим CreateFile проверял - занят нафик.
← →
ChainikDenis © (2006-05-17 00:48) [4]Все, млин совсем хана...
Вот это:
procedure TForm1.Button1Click(Sender: TObject);
var PrnHandle: THandle;
var PrnInfo: TPRINTERINFO2;
var pcbNeeded: longword;
var PrinterName : string;
begin
PrinterName := "TPTCM60 Dispenser";
if OpenPrinter(PChar(PrinterName), PrnHandle, nil) then
begin
GetPrinter(PrnHandle, 2 , nil, 0, @pcbNeeded);
if GetPrinter(PrnHandle, 2 , @PrnInfo, pcbNeeded, @pcbNeeded) then
Form1.Label1.Caption := IntToStr(PrnInfo.Status)
else
Form1.Label1.Caption := Статус не известен...";
// ClosePrinter(PrnHandle);
end
else Form1.Label1.Caption := "Принтер не доступен!";
end;
нихрена не работает,
А если этот кусок вставить в обработчик от IdUDPServer1UDPRead то все работает. Похоже при втором вызове GetPrinter куда-то теряется содержимое PrnHandle ...
Хана мне. Спать пойду..
Поможите кто чем можете. ...
← →
Германн © (2006-05-17 03:59) [5]1. Устройство подключено к Com-порту
2. Спецификация команд известна.
Удалить это устройство, то бишь принтер, из системы. Порт освободится. Работать с принтером как с COM-портом.
← →
ChainikDenis © (2006-05-17 12:03) [6]Порочный путь.
В графическом режиме ручками печатать достаточтно геморойно. Понятно когда собственный контроллер заставляешь печатать, а тут винда с гигабайтами памяти, мышками и клавиатурами.
Отказ от попытки решения теоретически решаемой задачи - путь слабых.
Нашел пока только один способ - GetPrinter выдает количество задач стоящих в очереди на печать. Зная примерное время печати чека можно сделать вывод о работе/неработе принтера.
Отправляем на печать и засекаем время. Если по окончании опеределенного периода задача еще висит в очереди - значит принтер не работает.
Теперь бы понять почему вышепреведенный код нормально работает только в обработчкие IdUDPServer1UDPRead, а в паралельном потоке и в таймере не работает...
← →
tesseract © (2006-05-17 12:10) [7]
> Порочный путь.
да как раз наоборот.
погеммороишься с рендерингом пару дней, зато потом лафа.
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.035 c