可用CREATEFILE以PRN为文件名生成一个文件,检测返回值,若成功则打印机可用,否则显示打印机故障。生成关于PRN的文件句柄后,可象普通文件一样向文件写入内容,比如WRITE,写完后关闭文件。 //从并行端口读取打印机状态 function GetPrinterStatus:byte; asm MOV DX,$379; IN AL,DX; end; //获取打印机是否出错 function CheckPrinter:boolean; var temp:byte; begin temp:=GetPrinterStatus; Result:=not ( ((temp and $80)=0) //打印机忙 or ((temp and $20)<>0) //打印机缺纸 or ((temp and $10)=0) //打印机未联机 or ((temp and $08)=0) ); //打印机出错; end;
在unix,linux 下好控制,但在windows中好象有问题
我想这么多款...,总有一款适合你:)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 &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.
可是它能够打开打印机,监测出的打印任务数量始终为0,为什么?
我的机器是win2k,a01是98unit UGetPrinterJob;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Printers,winspool;type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
LPHandle:THandle;
LPStrBuf:Array[0..256] of Char;
NoJobs:Word;
s:LongWord;
Job_Info:array[0..10] of JOB_INFO_1;
cbNeeded:Cardinal;
cReturned:Cardinal;
ret:LongBool;
I:Integer;begin
LPStrBuf:='\\A01\hp';
if (OpenPrinter(LPStrBuf,LPHandle,nil)=false) then
begin
MessageBox(Form1.Handle,'打开打印机失败。','信息',MB_OK);
Exit;
end; s:=Sizeof(Job_Info);
cbNeeded:=0;
cReturned:=0;
NoJobs:=0;
ret:=EnumJobs(LPHandle,
0,
NoJobs,
1,
@Job_Info,
s,
cbNeeded,
cReturned);
Memo1.Lines.Add('共有打印任务:'+IntToStr(cReturned)+'个');
for I:=0 to cReturned-1 do
Memo1.Lines.Add('第'+IntToStr(I+1)+'个打印任务有'
+IntToStr(Job_Info[I].TotalPages)+'页');end;end.
http://expert.csdn.net/Expert/topic/1390/1390575.xml?temp=4.131716E-02
可用CREATEFILE以PRN为文件名生成一个文件,检测返回值,若成功则打印机可用,否则显示打印机故障。生成关于PRN的文件句柄后,可象普通文件一样向文件写入内容,比如WRITE,写完后关闭文件。
//从并行端口读取打印机状态
function GetPrinterStatus:byte;
asm
MOV DX,$379;
IN AL,DX;
end;
//获取打印机是否出错
function CheckPrinter:boolean;
var
temp:byte;
begin
temp:=GetPrinterStatus;
Result:=not ( ((temp and $80)=0) //打印机忙
or ((temp and $20)<>0) //打印机缺纸
or ((temp and $10)=0) //打印机未联机
or ((temp and $08)=0) ); //打印机出错;
end;
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 &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.
那,有没有知道:Windows怎么做的?
就像Windows的打印机管理那样可
暂停,取消打印,重新打印