Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Делфи _ Получить статус принтера

Автор: Jill 7.08.2006 20:57

Нашла неплохой код:

function TestPrinterStatus(LPTPort: Word): Byte;  
var
Status: byte;
CheckLPT: word;
begin
Status := 0;
if (LPTPort >= 1) and (LPTPort <= 3) then
begin
CheckLPT := LPTPort - 1;
asm
mov dx, CheckLPT;
mov al, 0;
mov ah, 2;
int 17h;
mov &Status, ah;
end;
end;
Result := Status;
end;

Но под NT он не работает!!! Просто из паскаля - все ок, а вот из делфи - ни в какую!!! Кто сталкивался с подобной проблемой? Что делать?

Автор: hiv 9.08.2006 15:05

Этот код неписан специально для DOS, а под win32 нужно использовать WIN32 API. Открыть файл или порт для винды все равно функция OPEN. Если какая-то программа этот порт открыла, то другая не сможет получить туда доступ. Посмотри в Delphi есть компонент TPrinter - может там найдешь то, что тебе нужно.

Автор: Jill 9.08.2006 19:19

С помощью TPrinter можно получить свойства, имя принтера, сервера, вывести очередь печати est. Но я не нашла статуса (готов/не готов). Это задача из разряда невыполнимых? sad.gif

Автор: volvo 9.08.2006 20:00

Цитата(Jill @ 9.08.2006 15:19)
Это задача из разряда невыполнимых?
Почему же сразу "невыполнимых?" Просто не совсем с помощью TPrinter...

Смотри в сторону EnumPrinters, получай с его помощью список всех принтеров в системе (информация будет записываться в массив переменных типа TPrinterInfo2), и для принтера, у которого pPrinterName совпадает с нужным тебе смотри, чему равно поле Status этой самой структуры TPrinterInfo2 ...

Чуть позже, если будет время, приведу пример кода, как это можно сделать...

Автор: volvo 10.08.2006 1:19

Хм... Не все так просто в Датском Королевстве... blink.gif

Единственное, что у меня пока получилось - это просмотреть очередь печати принтера, и только если она непустая, Status возвращается правильно... Может, кому-нибудь пригодится:

Function GetCurrentPrinterHandle: THandle;
Const
Defaults: TPrinterDefaults = (
pDatatype : nil;
pDevMode : nil;
DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
Var
Device, Driver, Port : array[0..255] of char;
hDeviceMode: THandle;
Begin { GetCurrentPrinterHandle }
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
If not OpenPrinter(@Device, Result, @Defaults) Then
RaiseLastWin32Error;
End; { GetCurrentPrinterHandle }

Function SafePChar( p: PChar ): PChar;
const error: PChar = 'Nil';
begin
if not assigned( p ) then
result := error
else
result := p;
end;

Const
amount = 25;
stv: array[1 .. amount] of integer = (
PRINTER_STATUS_PAUSED,
PRINTER_STATUS_ERROR,
PRINTER_STATUS_PENDING_DELETION,
PRINTER_STATUS_PAPER_JAM,
PRINTER_STATUS_PAPER_OUT,
PRINTER_STATUS_MANUAL_FEED,
PRINTER_STATUS_PAPER_PROBLEM,
PRINTER_STATUS_OFFLINE,
PRINTER_STATUS_IO_ACTIVE,
PRINTER_STATUS_BUSY,
PRINTER_STATUS_PRINTING,
PRINTER_STATUS_OUTPUT_BIN_FULL,
PRINTER_STATUS_NOT_AVAILABLE,
PRINTER_STATUS_WAITING,
PRINTER_STATUS_PROCESSING,
PRINTER_STATUS_INITIALIZING,
PRINTER_STATUS_WARMING_UP,
PRINTER_STATUS_TONER_LOW,
PRINTER_STATUS_NO_TONER,
PRINTER_STATUS_PAGE_PUNT,
PRINTER_STATUS_USER_INTERVENTION,
PRINTER_STATUS_OUT_OF_MEMORY,
PRINTER_STATUS_DOOR_OPEN,
PRINTER_STATUS_SERVER_UNKNOWN,
PRINTER_STATUS_POWER_SAVE
);
sts: array[1 .. amount] of string = (
'PRINTER_STATUS_PAUSED',
'PRINTER_STATUS_ERROR',
'PRINTER_STATUS_PENDING_DELETION',
'PRINTER_STATUS_PAPER_JAM',
'PRINTER_STATUS_PAPER_OUT',
'PRINTER_STATUS_MANUAL_FEED',
'PRINTER_STATUS_PAPER_PROBLEM',
'PRINTER_STATUS_OFFLINE',
'PRINTER_STATUS_IO_ACTIVE',
'PRINTER_STATUS_BUSY',
'PRINTER_STATUS_PRINTING',
'PRINTER_STATUS_OUTPUT_BIN_FULL',
'PRINTER_STATUS_NOT_AVAILABLE',
'PRINTER_STATUS_WAITING',
'PRINTER_STATUS_PROCESSING',
'PRINTER_STATUS_INITIALIZING',
'PRINTER_STATUS_WARMING_UP',
'PRINTER_STATUS_TONER_LOW',
'PRINTER_STATUS_NO_TONER',
'PRINTER_STATUS_PAGE_PUNT',
'PRINTER_STATUS_USER_INTERVENTION',
'PRINTER_STATUS_OUT_OF_MEMORY',
'PRINTER_STATUS_DOOR_OPEN',
'PRINTER_STATUS_SERVER_UNKNOWN',
'PRINTER_STATUS_POWER_SAVE'
);

procedure TForm1.Button1Click(Sender: TObject);
type
TJobs = Array [0..1000] of JOB_INFO_1;
PJobs = ^TJobs;
var
hPrinter : THandle;
bytesNeeded, numJobs, i, j: Cardinal;
pJ: PJobs;
begin
hPrinter:= GetCurrentPrinterHandle;
try
EnumJobs(hPrinter, 0, 1000, 1, Nil, 0, bytesNeeded, numJobs);
pJ := AllocMem(bytesNeeded);
If not EnumJobs(hPrinter, 0, 1000, 1, pJ, bytesNeeded,
bytesNeeded, numJobs)
Then
RaiseLastWin32Error;

memo1.clear;
if numJobs = 0 Then
memo1.lines.add('No jobs in queue')

else
For i:= 0 to Pred(numJobs) Do begin
memo1.lines.add( Format(
'Job %s, Status (%d): %s',
[SafePChar(pJ^[i].pDocument), pJ^[i].Status,
SafePChar(pJ^[i].pStatus)]
)
);

for j := 1 to amount do
if pJ^[i].Status and stv[j] = stv[j] then
memo1.Lines.Add(' ' + sts[j]);
end;
finally
ClosePrinter( hPrinter );
end;
end;