如何检测打印机的后台打印是正在打印或空闲着(200分)

  • 主题发起人 主题发起人 lop
  • 开始时间 开始时间
L

lop

Unregistered / Unconfirmed
GUEST, unregistred user!
本人正在做一个项目,其中有一段是一下子连续生成几百个报表打印,随着报表数目的
增加,最近发现后面的报表打不出来,不知是否打印缓冲数据太多的原故。现在想检测
打印机的后台打印状态,如果是空闲就送一个报表过去打印,这样就不会引起太多的打
印数据在后台排队。但不知用什么方法去检测打印机的后台是正在打印呢还是空闲呢,
有这样的一个API函数吗?
望高手指教。谢谢,谢谢!
 
看看吧。
var
pinfo: pPRINTERINFO2;
pprt,a: Cardinal;
b:PDWORD;
begin

b:=allocmem(256);
pinfo:=AllocMem(1000);
if OpenPrinter('HP DJ 200',pprt,nil) then

begin

a:=1000;
if getprinter(pprt,2,pinfo,a,b) then

showmessage(pinfo.pPrinterName+' ststus:'+inttostr(pinfo.Status));
ClosePrinter(pprt);
end;

freemem(b);
freemem(pinfo);
end;

PRINTER_INFO_2.Status :
Windows NT:
PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION
Windows 95:
PRINTER_STATUS_BUSY
PRINTER_STATUS_DOOR_OPEN
PRINTER_STATUS_ERROR
PRINTER_STATUS_INITIALIZING
PRINTER_STATUS_IO_ACTIVE
PRINTER_STATUS_MANUAL_FEED
PRINTER_STATUS_NO_TONER
PRINTER_STATUS_NOT_AVAILABLE
PRINTER_STATUS_OFFLINE
PRINTER_STATUS_OUT_OF_MEMORY
PRINTER_STATUS_OUTPUT_BIN_FULL
PRINTER_STATUS_PAGE_PUNT
PRINTER_STATUS_PAPER_JAM
PRINTER_STATUS_PAPER_OUT
PRINTER_STATUS_PAPER_PROBLEM
PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION
PRINTER_STATUS_PRINTING
PRINTER_STATUS_PROCESSING
PRINTER_STATUS_TONER_LOW
PRINTER_STATUS_UNAVAILABLE
PRINTER_STATUS_USER_INTERVENTION
PRINTER_STATUS_WAITING
PRINTER_STATUS_WARMING_UP
//////////////////////////////////////////////////////////////////
unit PrinterStatus;

interface
uses
Windows, Messages, WinProcs, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

// TPrinterstatus
// Komponente zum Abfragen des aktuellen Druckerportstatus
// Programmiert 2000 von K. Otto
// funktioniert unter Win 9x, jedoch nicht unter Win NT
// ---------------------------------
// Status: Freeware incl. Sourcecode
// ---------------------------------
// Diese Komponente beruht auf einem Beitrag von Robert Vivrette
// f黵 "The unofficial Newsletter of Delphi Users"
// http://www.undu.com/articles/990228a.html
type
TPrinterStatus = class(TComponent)
private
{ Private-Deklarationen }
fStatus : Byte;
fLPT : Integer;
Function GetTimeOut : Boolean;
Function GetIOError : Boolean;
Function GetPrinterSelected : Boolean;
Function GetOutOfPaper : Boolean;
Function GetAcknowledgement : Boolean;
Function GetPrinterBusy : Boolean;
protected
{ Protected-Deklarationen }
public
{ Public-Deklarationen }
Procedure CheckPrinterStatus;
// Liest den Druckerstatus der angegeben LPT-Schnittstelle
Constructor Create(AOwner : TComponent);
Override;
Property TimeOut : Boolean Read GetTimeOut;
Property IOError : Boolean Read GetIOError;
Property PrinterSelected : Boolean Read GetPrinterSelected;
Property OutOfPaper : Boolean Read GetOutOfPaper;
Property Acknowledgement : Boolean Read GetAcknowledgement;
Property Busy : Boolean Read GetPrinterBusy;
published
{ Published-Deklarationen }
Property LPT : Integer Read fLPT Write fLPT;
end;

procedure Register;

implementation
procedure Register;
begin

RegisterComponents('Eigene', [TPrinterStatus]);
end;

Function TPrinterStatus.GetTimeOut : Boolean;
begin

Result:=(fStatus and $01)=$01;
end;

Function TPrinterStatus.GetIOError : Boolean;
begin

Result:=(fStatus and $08)=$08;
end;

Function TPrinterStatus.GetPrinterSelected : Boolean;
begin

Result:=(fStatus and $10)=$10;
end;

Function TPrinterStatus.GetOutOfPaper : Boolean;
begin

Result:=(fStatus and $20)=$20;
end;

Function TPrinterStatus.GetAcknowledgement : Boolean;
begin

Result:=(fStatus and $40)=$40;
end;

Function TPrinterStatus.GetPrinterBusy : Boolean;
begin

Result:=not ((fStatus and $80)=$80);
end;

Procedure TPrinterStatus.CheckPrinterStatus;
Var
Status : Byte;
CheckLPT : Word;
begin

Status:=0;
If (fLPT>=1) and (fLPT<=3) then

begin

CheckLPT:=fLPT-1;
asm
mov dx,CheckLPT;
mov al,0;
mov ah,2;
int 17h;
mov &amp;Status, ah;
end;

end;

fStatus:=Status;
end;

Constructor TPrinterStatus.Create(AOwner : TComponent);
begin

Inherited Create(AOwner);
fLPT:=1;
fStatus:=0;
end;

end.

//////////////////////////////////////////////////////
用法:
if not PrinterStatus1.PrinterReady(0) then
//0 = current printerport
ShowMessage(PrinterStatus1.StatusMsg) else
{print print print} ;

unit PrinterStatus;

interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
TPrinterStatus = class(TComponent)
private
{ Private declarations }
FPort : Word;
FStatusStr : string;
protected
{ Protected declarations }
public
{ Public declarations }
function PrinterReady(LPT: Word): boolean;
published
{ Published declarations }
property StatusMsg: string read FStatusStr;
end;

procedure Register;

implementation
uses Printers;

procedure Register;
begin

RegisterComponents('Win95', [TPrinterStatus]);
end;

const
PrnReady = $90;
OffLine = $00;
OffLine2 = $10;
{NEW LINE}
PaperOut = $20;
PaperOut2 = $30;
{NEW LINE}
HookedButOff = $80;
{NEW LINE}
NoConnect = $B0;
{MODIFIED LINE}
{NOCONNECT = $30 FOR SOME COMPUTERS BY STU}
function TPrinterStatus.PrinterReady(LPT: Word): boolean;
var
ErrorCode, C : BYTE;
code, x : integer;
s : string;

function GetPrinterStatus (LPT: Word): Byte;
{Pass 1 in LPT for LPT1}
begin

asm
mov ah,2
mov dx,LPT
dec dx
int $17
mov @Result,ah
end;

end;
{GetPrinterStatus}

begin

result := false;
//assume not
FPort := LPT;
if FPort = 0 then
begin
{if no port specified then
try to set port to current
printer port}
{printer name}
s := Printer.Printers[Printer.PrinterIndex];
if Pos('FPort',s) <> 0 then
begin

s := Copy(s, Pos('FPort',s) +3, 1);
Val(s,x,code);
if code <> 0 then
FPort := 1 else
FPort := x;
end else
FPort := 1;
{default to LPT1}
end;

{valid LPT is 1..4}
if (FPort > 4) or (FPort < 1) then
begin

raise ERangeError.CreateFmt(
'LPT%d is not within the valid range of %d..%d',
[FPort, 1, 4]);
exit;
end;


ErrorCode := GetPrinterStatus(FPort);

ErrorCode := ErrorCode and $B0;
{NEW LINE}
C := ERRORCODE shl 6;
{ALWAYS MEANS NOTHING CONNECTED}
if C > 0 then
ERRORCODE := $B0;
{ELEMINATES NO LPT3 AND NOTHING CONNECTED}
case ErrorCode of
PrnReady : begin
FStatusStr := 'Printer Ready';
result := true;
end;

NoConnect : FStatusStr := 'Printer not connected';
Offline,OffLine2 : FStatusStr := 'Printer off line';
{Modified}
PaperOut,PaperOut2 : FStatusStr := 'Printer out of paper';
{Modified}
HookedButOff : FStatusStr := 'Printer connected but turned off';
{New}
else

FStatusStr := 'Printer error code: ' + IntToStr(ErrorCode);
end;

end;


end.

 
太复杂了,俺看不懂,可以说简单一点或具体说一下它的用法吗?
我只要知道脱机打印是否空闲就行了。谢谢大侠!谢谢大侠!
分数俺有的是,如果要的话可以再给,别客气。谢谢了!
 
var
pinfo: pPRINTERINFO2;
pprt,a: Cardinal;
b:PDWORD;
begin
b:=allocmem(256);
pinfo:=AllocMem(1000);
if OpenPrinter('HP DJ 200',pprt,nil) then
//'HP DJ 200'为打印机类型
begin
a:=1000;
if getprinter(pprt,2,pinfo,a,b) then

showmessage(pinfo.pPrinterName+' ststus:'+inttostr(pinfo.Status));
ClosePrinter(pprt);
end;

freemem(b);
freemem(pinfo);
end;
 
mlzhou:
很感谢你的帮助。问题是运行这程序,不管是有打印或没有打印,得到的
pinfo.Status值总是为0,我试着用word在打印一篇东西,同时运行这程序,得
到的pinfo.status也是为0,不知是什么原因。望能指教。
 
还有人对这问题有兴趣吗?帮帮忙吧。
 
这应是一个很普遍的问题吧,怎么没人有兴趣呢?
 
写多文字给你点提示
T P r i n t e r 类的一个对象,该对象在P r i n t e r s 单元中定义。可以把P r i n t e r 全局函数看作一个全局变
量,并利用这个全局变量来与打印机进行打印操作。
利用P r i n t e r 来实现打印的一般过程如下:
1) 调用B e g i n D o c 过程向打印机发送一个打印作业(此时还没有在打印机上开始打印)。
2) 通过一个Te x t 变量或调用C a n v a s 对象方法建立打印输出。
3) 调用E n d D o c 过程结束当前的打印作业,该打印作业开始在打印机上打印。
4) 如果出现问题,调用A b o r t 过程取消当前打印的作业。
下面是T P r i n t e r 类的几个常用属性:
&amp;#8226;
Aborted 判断是否中止打印作业。
&amp;#8226;
Canvas 画布属性。
&amp;#8226;
Capabilities 当前打印机驱动设备的设置信息。
&amp;#8226;
Copies 打印的份数。
&amp;#8226;
Fonts 字体属性。
&amp;#8226;
Handle 打印机句柄。
&amp;#8226;
Orientation 纸张的方向:横向或纵向。
&amp;#8226;
PageHeight 纸张的高度。
&amp;#8226;
PageNumber 当前打印的页数。
&amp;#8226;
PageWidth 纸张的宽度。
&amp;#8226;
PrinterIndex 打印机属性中当前打印机的索引值。
&amp;#8226;
Printers 系统中安装的所有打印机。
&amp;#8226;
Printing 标识是否正在进行一个打印作业。
&amp;#8226;
Title 打印管理器中显示的打印作业的名称。
下面是T P r i n t e r 类的几个常用函数:
&amp;#8226;
Abort 中止正在打印的打印作业。
&amp;#8226;
begin
Doc 向打印机发送一个打印作业。
&amp;#8226;
EndDoc 结束当前的打印作业并关闭文本文件变量。
&amp;#8226;
NewPage 开始新的一页并增加P a g e N u m b e r 属性。
&amp;#8226;
Refresh 更新字体和打印机的属性。
通常,在打印前要进行打印预览。在打印预览的时候,往往要将打印的结果在屏幕上显示
出来。这时,就要注意屏幕的分辨率和打印机的分辨率的差别了。读取屏幕信息可以通过全局
变量S c r e e n 来实现,S c r e e n 为T S c r e e n 类的一个实例,在创建工程的时候就自动创建了,并在程
序开始运行时读取了屏幕的一些设置信息。
看到了么?可以搞定你的问题了吧
 
楼上的先生,你所说的应该是程序的打印控制,我所说的是windows系统的后台打印,
即是说我们把打印数据输出后,windows的任务栏上显示的那台打印机。我现在想知道
那台打印机是在打印还是空闲着。
 
楼上说的就有嘛,printer.Printing标识是否正在进行打印作业。
 
老兄tprinter控件那里找
 
to chlxy:
Tprinter是Delphi有的,你在uses中加入printer就可以了。
 
打印大量报表,为了不让他们全部生成到缓冲区,我的做法是手工修改打印机的属性
有个属性,关于后台打印的,你修改为,直接输出到端口,这样的话,就没了后台打印
打印机接收多少数据,你的程序就发出多少,没有缓冲,不会出现“打印机”文件夹出现
后台打印文档的情况,还有个好处是,假如你的程序是有进度条显示打印进度的,这种直接
输出到端口,不使用后台打印的情况下,那进度条如实反映了打印的进度
 
这倒也是一个方法,但应有一个方法检测到后台打印的情况吧?
 
这么大的活,提高打印机的配置就行了,不要所有的问题都让软件扛
 
看一看printers.pas中关于如何对winspl32.pas调用就知道了。所有的功能都在winspl32.pas中写得清清楚楚。
 
最后化了30元人民币买了本书,终于把问题搞掂了.只是有一个缺陷,就是在某些厂家提供
的驱动程序上还是不能检测到,如我现在用的Epson MJ-1500K,在Win98下用Epson提供的
驱动程序就不行,但用Windows本身带的驱动程序一般没有问题.
谢谢各位大侠的参与,现发分!
 
我也遇到相同的问题:pinfo.Status值总是为0,得不到打印机的状态。该怎么办呢?
 
lop,
pinfo.Status值总是为0,得不到打印机的状态,这个问题你后来是怎么解决的?能告我吗?
我很急。单位里急着要。或者你告诉我那本书上查得到也行。
谢谢!!!
 
后退
顶部