还是关于检测打印机状态的问题,如何能判断打印机断开,缺纸,打印成功的问题(200分)

  • 主题发起人 主题发起人 apiao
  • 开始时间 开始时间
A

apiao

Unregistered / Unconfirmed
GUEST, unregistred user!
看了不少的贴子,但是都没有可用的答案
打印机是联在打印服务器的,EPSON针打。pc用的是2000。
打印失败时候windows能给出错误的对话框。如何在程序中截获?
以前的贴子有说用EPSON提供的函数来解决,这应该是个有效的办法,如何解决?
还有如何清空打印机内部缓存的问题,难道除了打印机断电重启就没有好办法了????
w
用汇编的方案似乎只对非NT的windows和直接接到并口的打印机有效
我用windows打印管理器监控用未连接的打印机打印的时候,也是半天才有反应,告诉我打印机未连接。
问题解决,分数另外追加,呵呵,我的分数多得很。每个环节解决都格外给分,
呵呵,将贴子提前也有分。
我就奇怪了,大富翁人才济济,这么实用的问题怎么就没有一个好答案。
 
我再提前
 
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 &amp;Status, ah;
end;

end;

Result := Status;
end;

参数时打印机端口,返回值如下:
01h - Timeout
08h - I/O Error
10h - Printer selected
20h - Out of paper
40h - Printer acknowledgement
80h - Printer not busy (0 if busy)
 
AbortPrinter 删除打印机缓冲文件
 
to andy263:
谢谢
1,我的打印机是接到打印机服务器的,并没有和并口相连。
2,我的系统是2000,用汇编直接访问端口允许吗?
3,我要清空的是打印机内部的缓存,不是打印队列。
 
用SmallPort调用
 
个人也遇到,但也未能完全解决,可参考方法:
一、用EPSON的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;
 
谢谢大家,继续讨论
。。。。。。。。
 
各位大虾们不要再用int17了,它只能在98SE以前版本的windows上用,2000以后的windows下int17会被操作系统禁止的。另外大家讨论一个相关问题:如果我的打印机是连接到计算机串口的,在2000/xp下如何查询打印机的状态?
 
这个问题又成了悬案
看来没有什么好的答案
用直接访问端口的方法肯定是性不同的
其实这个问题也真的和打印驱动程序相关的
例如HP和EPSON的效果是不同的
在憋几天看看
 
to 星月无痕:
串口你就别想了,我测试过,根本监测不到的
无论你接不接打印机,呵呵,都是打印成功的!
 
打印机的状态看来是很难取了,那么打印机的作业数量总可以吧,就像windows的打印管理器中看到的作业一样。他是怎么取到打印机的打印作业的。
 
取出打印作业数没问题,windows的打印管理器中所有的消息都能取出
 
偶也面临这个问题。。。
用API获取打印机状态都没用。
 
后退
顶部