几个月了,CSDN、DFW上都无人能解决,分全给了-----真牛人在哪里???(12分)

  • 主题发起人 主题发起人 terrace
  • 开始时间 开始时间
T

terrace

Unregistered / Unconfirmed
GUEST, unregistred user!
我的是Delphi5 + Win2000. 如何在程序中清空Win2000下的打印作业呢?如何在程序中快速清空Win2000下的打印作业呢?(请给具体细节代码,因为我试过了一些朋友给的函数名,并不能实现)。
能解决任何一个都OK,请高手出招!!!
 
老兄,不要这么说,
最好是自己动手!
 
首先要把自己的问题提清楚,让人看的明白。
 
kkyy朋友:
我已经试过SetJob、SetPrinter、ResetPrinter,好象都不行,你能给出SetJob函数的具体参数设置吗?有个例子最好,谢谢!!!
 
先问一下打印机是安装在本机吗?
如果不是,我估计你没有权限清空打印队列
 
只能取消未傳送到打印機的任務,已經傳送到打印機的任務是無法取消的(除非關掉打印機電源).你可以用個長文件試試.連win2000自己都沒有辦法清楚已經傳送出去的資料.
 
同上,
SetJob(hPrinter,JobId, //换成需要的,一次删除一个
0, nil, JOB_CONTROL_CANCEL)
 
lirenzhao朋友:
打印机是安装在本机的。
foresail朋友:
我只需要取消未傳送到打印機的任務。
kkyy朋友:
关键的问题是我并不清楚有多少个作业,也不知道各个作业的JobId,怎么样才能遍历这些作业呢(要是有方法一次就把所有作业都删除最好了)?
 
转贴一段, 希望能有帮助
unit mbPrinterStatus;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Printers, WinSpool;
const
imaxPrintJobs = 10000;
type
EPrintError = class(Exception);
TPrinterState = (psPAUSED, psERROR, psDELETING, psSPOOLING,
psPRINTING, psOFFLINE, psPAPEROUT, psPRINTED, psDELETED,
psBLOCKED_DEVQ, psUSER_INTERVENTION, psRESTART, psUNKNOWN, psOK);
TPrinterStates = set of TPrinterState;

TArrayJobInfo2 = array[0..iMaxPrintJobs] of TJobInfo2;
{ Dit component kan worden gebruikt om de status van een (remote) printer
op te vragen. Met SpoolerReady kan worden opgevraagd of de spooler
beschikbaar is. Als er tijdens de verdere controle iets mis gaan wordt een
EPrintError geraised. Kontroleer voor het printen altijd of de spooler
te benaderen is. }
TmbPrinterStatus = class(TComponent)
private
FDefaultPrinter: boolean;
FSpoolerErrorID: integer;
FSpoolerErrorStr: string;
FErrorStart: integer;
FstrPrinterName: string;
FhPrinter : THAndle;
FpPrinterInfo2 : ^TPrinterInfo2;
FpJobStorage : ^TArrayJobInfo2;
FNrOfJobs : DWORD;
FErrorStates: TPrinterStates;
function StorePrinterName: boolean;
function GetSpoolerReady: boolean;
function GetJobs: Boolean;
function GetJobStatus(Index: integer): TPrinterStates;
function GetStatusDesc(Index: integer): string;
function QueueStatus: DWORD;
procedure SetPrinterName(Value: string);
function GetJobCount: integer;
procedure SetDefaultPrinter(Value: boolean);
function GetJobInfo(Index: integer): TJobInfo2;
protected
public
{ Aantal jobs voor geselekteerde printer }
property JobCount: integer read GetJobCount;
{ Status voor een bepaalde job. Als Index buiten de range is wordt een
lege set gegeven
TPrinterState = (psPAUSED, psERROR, psDELETING, psSPOOLING,
psPRINTING, psOFFLINE, psPAPEROUT, psPRINTED, psDELETED,
psBLOCKED_DEVQ, psUSER_INTERVENTION, psRESTART,
psUNKNOWN, psOK)
TPrinterStates = set of TPrinterState }
property JobStatus[Index: Integer]: TPrinterStates read GetJobStatus;
{ Omschrijving van de status van een bepaalde job. Als meerdere statussen
gelden voor de job worden deze achter elkaar geplakt, gescheidendo
or
een spatie }
property StatusDesc[Index: Integer]: string read GetStatusDesc;
{ Geeft aan of de spooler klaar is. Er wordt gekeken naar de spoolerstatus
en of de jobs bereikbaar zijn. Als dit niet het geval is zal meestal het
betreffende station niet aan staan. Met SpoolerErrorStr en SpoolerErrorID
kan worden opgevraagd wat de fout is. }
property SpoolerReady: boolean read GetSpoolerReady;
{ Omschrijving van de laatst opgetreden fout }
property SpoolerErrorStr: string read FSpoolerErrorStr;
{ ID van de laatst opgetreden fout }
property SpoolerErrorID: integer read FSpoolerErrorID;
{ Geeft een jobinfo van een printjob. Het type TJobInfo2 is gedefinieerd in
de Delphi unit WinSpool.pas.
TJobInfo2W = record
JobId: DWORD;
pPrinterName: PWideChar;
pMachineName: PWideChar;
pUserName: PWideChar;
pDocument: PWideChar;
pNotifyName: PWideChar;
pDatatype: PWideChar;
pPrintProcessor: PWideChar;
pParameters: PWideChar;
pDriverName: PWideChar;
pDevMode: PDeviceModeW;
pStatus: PWideChar;
pSecurityDescriptor: PSECURITY_DESCRIPTOR;
Status: DWORD;
Priority: DWORD;
Position: DWORD;
StartTime: DWORD;
UntilTime: DWORD;
TotalPages: DWORD;
Size: DWORD;
Submitted: TSystemTime;
// Time the job was spooled
Time: DWORD;
// How many seconds the job has been printing
PagesPrinted: DWORD;
end;
TJobInfo2 = TJobInfo2A;
}
property JobInfo[Index: Integer]: TJobInfo2 read GetJobInfo;
constructor Create(AOwner: TComponent);
override;
destructor Destroy;
override;
function FirstJobInError: Integer;
function NextJobInError: Integer;
function FindJob(Title: string): Integer;
published
{ Printer waarop moet worden gekontroleerd, dit is de printernaam zoals deze
in My Computer/Printers staat. Als Printernaam leeg wordt gelaten wordt
DefaultPrinter op true gezet }
property PrinterName: string
read FstrPrinterName write SetPrinterName stored StorePrinterName;
{ Set van statussen die als fout worden gezien. FirstJobInError en
NextJobInError gebruiken deze property om te kijken of een job fout is
TPrinterState = (psPAUSED, psERROR, psDELETING, psSPOOLING,
psPRINTING, psOFFLINE, psPAPEROUT, psPRINTED, psDELETED,
psBLOCKED_DEVQ, psUSER_INTERVENTION, psRESTART,
psUNKNOWN, psOK)
TPrinterStates = set of TPrinterState }
property ErrorStates: TPrinterStates
read FErrorStates write FErrorStates default [psERROR, psOFFLINE];
{ Bepaalt of altijd de default printer wordt gebruikt of de printer zoals
deze in PrinterName is opgegeven. Als deze property aan wordt gezet wordt
de PrinterName meteen op de default printer gezet }
property DefaultPrinter: boolean
read FDefaultPrinter write SetDefaultPrinter default true;
end;

procedure Register;
implementation
procedure Register;
begin
RegisterComponents('MvB Systools', [TmbPrinterStatus]);
end;

{ Default errorstates worden gezet en printername wordt op default printer
gezet }
constructor TmbPrinterStatus.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FSpoolerErrorStr := '';
FpPrinterInfo2 := nil;
FpJobStorage := nil;
FErrorStates := [psERROR, psOFFLINE];
FDefaultPrinter := true;
SetPrinterName('');
end;

destructor TmbPrinterStatus.Destroy;
begin

if FpPrinterInfo2 <> nil then
dispose(FpPrinterInfo2);
if FpJobStorage <> nil then
dispose(FpJobStorage);
inherited Destroy;
end;

function TmbPrinterStatus.GetJobCount: integer;
begin
Result := -1;
if QueueStatus = 0 then
Result := FNrOfJobs;
end;

{ Vraagt de status van de queue op en vult FNrOfJobs }
function TmbPrinterStatus.QueueStatus: DWORD;
var
cbBuf : DWORD;
pcbBuf : pointer;
Needed : DWORD;
pcbNeeded : LPDWORD;
begin
pcbBuf := @cbBuf;
if not GetPrinter(FhPrinter,2,Nil,0,pcbBuf) then
if GetLastError <> ERROR_INSUFFICIENT_BUFFER then
begin
FSpoolerErrorStr := Name + ': GetPrinterQueueStatus Getprinter1 fout: ' +
IntToStr(GetLastError);
FSpoolerErrorID := GetLastError;
raise EPrintError.Create(FSpoolerErrorStr);
end;

if FpPrinterInfo2 <> nil then
dispose(FpPrinterInfo2);
GetMem(FpPrinterInfo2,cbBuf);
fillChar(FpPrinterInfo2^,cbBuf,0);
pcbNeeded := @Needed;
if not GetPrinter(FhPrinter,2,FpPrinterInfo2,cbBuf,pcbNee
ded) then
begin
FSpoolerErrorStr := Name + ': GetPrinterQueueStatus Getprinter2 fout: ' +
IntToStr(GetLastError);
FSpoolerErrorID := GetLastError;
raise EPrintError.Create(FSpoolerErrorStr);
end;

Result := FpPrinterInfo2^.status;
FNrOfJobs := FpPrinterInfo2^.cJobs;
end;

procedure TmbPrinterStatus.SetPrinterName(Value: string);
begin

{ ALs property niet verandert ook niets uitvoeren. Als een lege waarde wordt
meegegeven kan dit de initialisatie zijn, deze moet dus altijd worden
uitgevoerd }
if (Value <> FstrPrinterName) or (Value = '') then
begin
FErrorStart := -1;
{ Als de waarde op leeg wordt gezet wordt de default printer gezet. Deze
wordt (desgign-time) niet opgeslagen omdat ook run-time dan de default
printer moet worden geselekteerd }
if Trim(Value) = '' then
with Printerdo
begin
FDefaultPrinter := true;
Value := Printers[PrinterIndex];
end
else
FDefaultPrinter := false;
if not Openprinter(PChar(Value), FhPrinter, nil) then
begin
FSpoolerErrorStr := 'TPrtStat.Create Openprinter fout: ' +
IntToStr(GetLastError);
FSpoolerErrorID := GetLastError;
raise EPrintError.Create(FSpoolerErrorStr);
end;

FstrPrinterName := Value;
end;

end;

{ Als Defaultprinter aan staat moet de printernaam niet worden opgeslagen }
function TmbPrinterStatus.StorePrinterName: boolean;
begin
Result := not FDefaultPrinter;
end;

function TmbPrinterStatus.GetJobStatus(Index: integer): TPrinterStates;
var
Status: DWORD;
begin
result := [];
if (Index >= JobCount) or (Index < 0) then
Exit;
if not GetJobs then
Exit;
Status := FpJobStorage^[Index].status;
if Status = 0 then
Result := [psOK]
else
begin

if (JOB_STATUS_PAUSED and Status) = JOB_STATUS_PAUSED then
Result := Result + [psPAUSED];

if (JOB_STATUS_ERROR and Status) = JOB_STATUS_ERROR then
Result := Result + [psERROR];

if (JOB_STATUS_DELETING and Status) = JOB_STATUS_DELETING then
Result := Result + [psDELETING];

if (JOB_STATUS_SPOOLING and Status) = JOB_STATUS_SPOOLING then
Result := Result + [psSPOOLING];

if (JOB_STATUS_PRINTING and Status) = JOB_STATUS_PRINTING then
Result := Result + [psPRINTING];

if (JOB_STATUS_OFFLINE and Status) = JOB_STATUS_OFFLINE then
Result := Result + [psOFFLINE];

if (JOB_STATUS_PAPEROUT and Status) = JOB_STATUS_PAPEROUT then
Result := Result + [psPAPEROUT];

if (JOB_STATUS_PRINTED and Status) = JOB_STATUS_PRINTED then
Result := Result + [psPRINTED];

if (JOB_STATUS_DELETED and Status) = JOB_STATUS_DELETED then
Result := Result + [psDELETED];

if (JOB_STATUS_BLOCKED_DEVQ and Status) = JOB_STATUS_BLOCKED_DEVQ then
Result := Result + [psBLOCKED_DEVQ];

if (JOB_STATUS_USER_INTERVENTION and Status) = JOB_STATUS_USER_INTERVENTION then
Result := Result + [psUSER_INTERVENTION];
if Result = [] then
Result := [psUNKNOWN];
end;
end;

function TmbPrinterStatus.GetJobs: Boolean;
var
cbBuf : DWORD;
Needed : DWORD;
begin
GetJobs := false;
if JobCount >= 0 then
begin
if not EnumJobs(FhPrinter,0,FpPrinterInfo2^.cJobs,2,
FpJobStorage,0,cbBuf,Needed) then

if GetLastError <> ERROR_INSUFFICIENT_BUFFER then
begin
FSpoolerErrorStr := 'Fout bij bepalen JOB-buffer: ' +
IntToStr(GetLastError);
FSpoolerErrorID := GetLastError;

raise EPrintError.Create(FSpoolerErrorStr);
end;

if FpJobStorage <> nil then
dispose(FpJobStorage);
GetMem(FpJobStorage,cbBuf);
fillChar(FpJobStorage^,cbBuf,0);
if not EnumJobs(FhPrinter,0,FpPrinterInfo2^.cJobs,2,FpJobStorage,
cbBuf,Needed,cbBuf) then
begin
FSpoolerErrorStr := 'Fout bij EnumJobs: ' + IntToStr(GetLastError);
FSpoolerErrorID := GetLastError;
raise EPrintError.Create(FSpoolerErrorStr);
end;

GetJobs := true;
end;

end;

function TmbPrinterStatus.GetStatusDesc(Index: Integer): string;
var
Status: TPrinterStates;
begin
Status := GetJobStatus(Index);
Result := '';
if (psPAUSED in Status) then
Result := Result + ' PAUSED';
if (psERROR in Status) then
Result := Result + ' ERROR';
if (psDELETING in Status) then
Result := Result + ' DELETING';
if (psSPOOLING in Status) then
Result := Result + ' SPOOLING';
if (psPRINTING in Status) then
Result := Result + ' PRINTING';
if (psOFFLINE in Status) then
Result := Result + ' OFFLINE';
if (psPAPEROUT in Status) then
Result := Result + ' PAPEROUT';
if (psPRINTED in Status) then
Result := Result + ' PRINTED';
if (psDELETED in Status) then
Result := Result + ' DELETED';
if (psBLOCKED_DEVQ in Status) then
Result := Result + ' BLOCKED';
if (psUSER_INTERVENTION in Status) then
Result := Result + ' USERINTERVENTION';
end;

{ Geeft de index van de eerste job die in error staat. Gebruik deze functie om
te kijken of er fouten zijn, zolang deze -1 retoureerd zijn er geen fouten.
Als deze functie een jobnummer geeft met een fout kan met NextJobInError
worden opgevraagd of er nog meer jobs met fouten zijn. De property
ErrorStates bepaalt welke statussen als 'fout' worden gezien }
function TmbPrinterStatus.FirstJobInError: Integer;
begin
FErrorStart := 0;
Result := NextJobInError;
end;

{ Als FirstJobInError een jobnummer geeft met een fout kan met NextJobInError
worden opgevraagd of er nog meer jobs met fouten zijn. De property
ErrorStates bepaalt welke statussen als 'fout' worden gezien }
function TmbPrinterStatus.NextJobInError: Integer;
var
i: Integer;
begin

if FErrorStart = -1 then
raise Exception.Create(
Name + ': FirstJobInError not executed before NextJobInError');

Result := -1;
for i := FErrorStart to JobCount - 1do
if (GetJobStatus(i) * ErrorStates) <> [] then
begin
Result := i;
Break;
end;

if Result = -1 then
FErrorStart := JobCount+1
else
FErrorStart := Result + 1;
end;

function TmbPrinterStatus.GetSpoolerReady: boolean;
begin
FSpoolerErrorStr := '';
try
Result := (QueueStatus = 0) and (GetJobs);
except
on e: EPrintErrordo
Result := false;
on e: Exceptiondo
raise
end;
end;

procedure TmbPrinterStatus.SetDefaultPrinter(Value: boolean);
begin
if Value <> FDefaultPrinter then
begin
FDefaultPrinter := Value;
if FDefaultPrinter then
SetPrinterName('');

end;

end;

function TmbPrinterStatus.GetJobInfo(Index: integer): TJobInfo2;
begin
if (Index < 0) or (Index >= JobCount) then
Exit;

Result := FpJobStorage^[Index];
end;

{ Zoekt naar een job aan de hand van zijn title (pDocument) De index van de job
in de queue wordt geretourneerd, als de job niet is gevonden wordt -1
geretourneerd. Deze routine kan worden gebruikt om te kijken of eendo
cument
daadwerkelijk in de queue is opgenomen.
with Printerdo
begin
Title := 'Testje';
<--------Altijd voor begin
Doc
begin
Doc;
Canvas.TextOut(0, 0, 'TestPrint');
EndDoc;
if mbPrinterStatus.FindJob(Title) = -1 then
ShowMessage('OOPS!!');
end;
}
function TmbPrinterStatus.FindJob(Title: string): Integer;
var
i: Integer;
begin
Result := -1;
if GetJobs then
for i := 0 to JobCount - 1do
if (JobInfo.pDocument <> '') and (JobInfo.pDocument = Title) then
begin
Result := i;
Break;
end;
end;

end.
 
顶。。。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
867
DelphiTeacher的专栏
D
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
836
DelphiTeacher的专栏
D
后退
顶部