[英]Cannot get the correct printer status
I am using Delphi 10.3 to create a program that prints labels with barcodes.我正在使用 Delphi 10.3 创建一个打印带有条形码的标签的程序。 I do not want the printer to queue multiple jobs instead i want to start printing the next job after the previous is finished and receive ready status from the printer.我不希望打印机将多个作业排队,而是我想在前一个作业完成后开始打印下一个作业并从打印机接收就绪状态。 The status of the printer is always ready, even if it is offline!打印机的状态始终处于就绪状态,即使它处于脱机状态!
I use this functions to get the status of the printer:我使用这个函数来获取打印机的状态:
function TPrintQRForm.GetCurrentPrinterHandle() : THandle;
var
Device, Driver, Port : Array[0..255] of Char;
hDeviceMode : THandle;
begin
Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
if not Winspool.OpenPrinter(@Device, Result, nil) then
begin
RaiseLastOSError();
end;
end;
function TPrintQRForm.GetCurrentPrinterInformation() : TPrinterInfo;
var
hPrinter : THandle;
pInfo : PPrinterInfo2;
bytesNeeded : DWORD;
begin
hPrinter := GetCurrentPrinterHandle();
try
Winspool.GetPrinter(hPrinter, 2, Nil, 0, @bytesNeeded);
pInfo := AllocMem(bytesNeeded);
try
Winspool.GetPrinter(hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded);
Result.ServerName := pInfo^.pServerName;
Result.PrinterName := pInfo^.pPrinterName;
Result.ShareName := pInfo^.pShareName;
Result.PortName := pInfo^.pPortName;
Result.DriverName := pInfo^.pDriverName;
Result.Comment := pInfo^.pComment;
Result.Location := pInfo^.pLocation;
Result.DeviceMode := pInfo^.pDevMode;
Result.SepFile := pInfo^.pSepFile;
Result.PrintProcessor := pInfo^.pPrintProcessor;
Result.DataType := pInfo^.pDatatype;
Result.Parameters := pInfo^.pParameters;
Result.SecurityDescriptor := pInfo^.pSecurityDescriptor;
Result.Attributes := pInfo^.Attributes;
Result.DefaultPriority := pInfo^.DefaultPriority;
Result.StartTime := pInfo^.StartTime;
Result.UntilTime := pInfo^.UntilTime;
Result.Status := pInfo^.Status;
Result.Jobs := pInfo^.cJobs;
Result.AveragePPM := pInfo^.AveragePPM;
finally
FreeMem(pInfo);
end;
finally
ClosePrinter(hPrinter);
end;
end;
And then on a certain event i check for printer status using this code:然后在某个事件中,我使用以下代码检查打印机状态:
PrinterInfo := GetCurrentPrinterInformation();
while PrinterInfo.Status <> 0 do
begin
if PrinterInfo.Status = PRINTER_STATUS_PRINTING then
begin
// Get information about the selected printer
PrinterInfo := GetCurrentPrinterInformation();
// Process messages from the OS and do not freeze the UI
Application.ProcessMessages;
Continue;
end;
Case PrinterInfo.Status of
PRINTER_STATUS_PAUSED : ShowMessage('The printer is paused.');
PRINTER_STATUS_ERROR : ShowMessage('The printer is in an error state.');
PRINTER_STATUS_PENDING_DELETION : ShowMessage('The printer is being deleted.');
PRINTER_STATUS_PAPER_JAM : ShowMessage('Paper is jammed in the printer.');
PRINTER_STATUS_PAPER_OUT : ShowMessage('The printer is out of paper.');
PRINTER_STATUS_MANUAL_FEED : ShowMessage('The printer is in a manual feed state.');
PRINTER_STATUS_PAPER_PROBLEM : ShowMessage('The printer has a paper problem.');
PRINTER_STATUS_OFFLINE : ShowMessage('The printer is offline.');
PRINTER_STATUS_IO_ACTIVE : ShowMessage('The printer is in an active input/output state.');
PRINTER_STATUS_BUSY : ShowMessage('The printer is busy.');
PRINTER_STATUS_OUTPUT_BIN_FULL : ShowMessage('The printer''s output bin is full.');
PRINTER_STATUS_NOT_AVAILABLE : ShowMessage('The printer is not available for printing.');
PRINTER_STATUS_WAITING : ShowMessage('The printer is waiting.');
PRINTER_STATUS_PROCESSING : ShowMessage('The printer is processing a print job.');
PRINTER_STATUS_INITIALIZING : ShowMessage('The printer is initializing.');
PRINTER_STATUS_WARMING_UP : ShowMessage('The printer is warming up.');
PRINTER_STATUS_TONER_LOW : ShowMessage('The printer is low on toner.');
PRINTER_STATUS_NO_TONER : ShowMessage('The printer is out of toner.');
PRINTER_STATUS_PAGE_PUNT : ShowMessage('The printer cannot print the current page.');
PRINTER_STATUS_USER_INTERVENTION : ShowMessage('The printer has an error that requires the user to do something.');
PRINTER_STATUS_OUT_OF_MEMORY : ShowMessage('The printer has run out of memory.');
PRINTER_STATUS_DOOR_OPEN : ShowMessage('The printer door is open.');
PRINTER_STATUS_POWER_SAVE : ShowMessage('The printer is in power save mode.');
else
ShowMessage('The error is unknown');
end;
Exit;
end;
After this code i start the printing process and everything is in a loop for all the copies i need to print.在此代码之后,我开始打印过程,并且对于我需要打印的所有副本,一切都在循环中。
I am using a TSC-TPP 2410M printer and it never gives printing status although it queues the jobs.我使用的是 TSC-TPP 2410M 打印机,尽管它对作业进行排队,但它从不提供打印状态。 So the code never goes inside the while because i am always getting 0 printer status.所以代码永远不会进入,因为我总是得到 0 打印机状态。
Is there any way to disable the queue or to make the app wait for the printer to stop printing and then execute the next print job?有什么方法可以禁用队列或让应用程序等待打印机停止打印然后执行下一个打印作业? Any thoughts?有什么想法吗?
EDIT: After some suggestions from @BlurrySterk i discovered that the printer emits PRINTER_STATUS_PRINTING when the number of jobs in the queue get to 10. After printing all of them it gets ready again.编辑:在@BlurrySterk 提出一些建议后,我发现当队列中的作业数量达到 10 时,打印机会发出 PRINTER_STATUS_PRINTING。在打印完所有作业后,它会再次准备好。
It seems that there are limits to the WinAPI, as mentioned in the comments.如评论中所述,WinAPI 似乎存在限制。
Because the previous printer is dead now, we bought a TSC ME240.因为以前的打印机现在已经死了,我们买了一台 TSC ME240。 There is a programming manual for TSPL/2 commands in this link .此链接中有 TSPL/2 命令的编程手册。
To solve the problem i connected the printer to the network and send TSPL/2 commands through a tcp socket.为了解决这个问题,我将打印机连接到网络并通过 tcp 套接字发送 TSPL/2 命令。
I needed this code to get the status我需要这段代码来获取状态
// Create TCP Client
TCPClient := TIdTCPClient.Create();
// Connect to server
TCPClient.Host := PrinterIP;
TCPClient.Port := PrinterPort;
TCPClient.Connect();
// Set status string
StatusString := #27 + '!?';
// Send command
TCPClient.Socket.WriteLn(StatusString);
// Check status
PrinterStatus := TCPClient.Socket.ReadByte;
The printer is responding and the job is done.打印机正在响应并且作业已完成。 Thanks for all the effort guys/girls.感谢所有努力的男孩/女孩。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.