PDA

Ver la Versión Completa : controlar el spooler de impresion


amilcarsuarez
24-03-2008, 07:39:36
estoy desarrollando un pequeño sistema para la escuela donde trabajo, consiste en evitar el desperdicio y el mal uso de las impresiones de las tareas de los alumnos en el centro de computo. La idea es que todo trabajo enviado a la impresora compartida (HP DeskJet 840C) sea pausado para asi saber de donde y de quien es el documento; Segun yo ya habia logrado mi proposito, pero despues de algunas pruebas note que despues del cuarto trabajo pausado , el quinto provoca un error ciclico y deja de funcionar mi aplicacion.Este es el código...espero sus consejos y ayudas.

unit monitor;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WinSpool, ExtCtrls, Grids, Menus, StdCtrls;

type
JOB_INFO_1_ARRAY = Array of JOB_INFO_1;
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Timer1: TTimer;
PopupMenu1: TPopupMenu;
Resumen: TMenuItem;
Pausa: TMenuItem;
Eliminar: TMenuItem;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure ResumenClick(Sender: TObject);
procedure PausaClick(Sender: TObject);
procedure EliminarClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure LiberarMemoria;

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

Function GetSpoolerJobs(sPrinterName : String) : JOB_INFO_1_ARRAY;
var
i : Integer;
hPrinter : THandle;
bResult : Boolean;
cbBuf : DWORD;
pcbNeeded : DWORD;
pcReturned : DWORD;
aJobs : Array[0..99] of JOB_INFO_1;
begin
cbBuf := 1000;

bResult := OpenPrinter(PChar(sPrinterName), hPrinter, Nil);
if NOT bResult then begin
ShowMessage('Error abriendo la impresora');
exit;
end;

bResult := EnumJobs(hPrinter,0,Length(aJobs),1,@aJobs,cbBuf,pcbNeeded,pcReturned);
if NOT bResult then begin
ShowMessage('Error llamando la informacion de los trabajos');
exit;
end;

ClosePrinter(hPrinter);

for i:=0 to pcReturned-1 do begin
if aJobs[i].pDocument <> Nil then begin
SetLength(Result, Length(Result)+1);
Result[Length(Result)-1] := aJobs[i];
end;
end;
end;

procedure TForm1.LiberarMemoria;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
i, ii : Integer;
aJobs : JOB_INFO_1_ARRAY;
hPrinterHandle : THandle;
begin
LiberarMemoria;
aJobs := GetSpoolerJobs('HP DeskJet 840C'); //aqui se pone la impresora
for i:=0 to Length(aJobs)-1 do begin
If aJobs[i].Status <> JOB_STATUS_PAUSED Then
Begin
OpenPrinter('HP DeskJet 840C', hPrinterHandle, Nil);
SetJob(hPrinterHandle,aJobs[i].JobId,1,@aJobs[i], JOB_CONTROL_PAUSE);
ClosePrinter(hPrinterHandle);
End;
end;
end;

procedure TForm1.ResumenClick(Sender: TObject);
var
bResult : Boolean;
hPrinterHandle : THandle;
sPrinterName : PChar;
aJobs : JOB_INFO_1_ARRAY;
i:integer;
begin
i:=StringGrid1.Row;
If StringGrid1.Cells[0,i]<>'' Then
Begin
i:=i-1;
sPrinterName := 'HP DeskJet 840C';

//Recupera todos los trabajos usando el “GetSpoolerJobs”
aJobs := GetSpoolerJobs(sPrinterName);

if Length(aJobs) = 0 then begin
ShowMessage('No hay trabajos en el spooler');
exit;
end;

//llama el printer handle
bResult := OpenPrinter(sPrinterName, hPrinterHandle, Nil);
if NOT bResult then begin
ShowMessage('Error llamando el printer handle');
exit;
end;

//esto RESUME el trabajo del spooler despues de haberlo pausado
SetJob(hPrinterHandle,aJobs[i].JobId,1,@aJobs[i], JOB_CONTROL_RESUME);
ClosePrinter(hPrinterHandle);

End
Else ShowMessage('No existe trabajo seleccionado...')
end;


procedure TForm1.PausaClick(Sender: TObject);
var
bResult : Boolean;
hPrinterHandle : THandle;
sPrinterName : PChar;
aJobs : JOB_INFO_1_ARRAY;
i:integer;
begin
i:=StringGrid1.Row;
If StringGrid1.Cells[0,i]<>'' Then
Begin
i:=i-1;
sPrinterName := 'HP DeskJet 840C';

//Recupera todos los trabajos usando el “GetSpoolerJobs”
aJobs := GetSpoolerJobs(sPrinterName);

if Length(aJobs) = 0 then begin
ShowMessage('No hay trabajos en el spooler');
exit;
end;

//llama el printer handle
bResult := OpenPrinter(sPrinterName, hPrinterHandle, Nil);
if NOT bResult then begin
ShowMessage('Error llamando el printer handle');
exit;
end;

//esto PAUSA el trabajo del spooler despues de haberlo pausado
SetJob(hPrinterHandle,aJobs[i].JobId,1,@aJobs[i], JOB_CONTROL_PAUSE);
ClosePrinter(hPrinterHandle);
End
Else ShowMessage('No existe trabajo seleccionado...')
end;

procedure TForm1.EliminarClick(Sender: TObject);
var
bResult : Boolean;
hPrinterHandle : THandle;
sPrinterName : PChar;
aJobs : JOB_INFO_1_ARRAY;
i:integer;
begin
i:=StringGrid1.Row;
If StringGrid1.Cells[0,i]<>'' Then
Begin
i:=i-1;
sPrinterName := 'HP DeskJet 840C';

//Recupera todos los trabajos usando el “GetSpoolerJobs”
aJobs := GetSpoolerJobs(sPrinterName);

if Length(aJobs) = 0 then begin
ShowMessage('No hay trabajos en el spooler');
exit;
end;

//llama el printer handle
bResult := OpenPrinter(sPrinterName, hPrinterHandle, Nil);
if NOT bResult then begin
ShowMessage('Error llamando el printer handle');
exit;
end;

//esto ELIMINA el trabajo del spooler despues de haberlo pausado
SetJob(hPrinterHandle,aJobs[i].JobId,1,@aJobs[i], JOB_CONTROL_CANCEL);
ClosePrinter(hPrinterHandle);
End
Else ShowMessage('No existe trabajo seleccionado...')

end;
procedure TForm1.Button1Click(Sender: TObject);
var
i, ii : Integer;
aJobs : JOB_INFO_1_ARRAY;
hPrinterHandle : THandle;
begin
for i:=0 to StringGrid1.ColCount-1 do
for ii:=0 to StringGrid1.RowCount-1 do StringGrid1.Cells[i,ii] := '';

StringGrid1.Cells[0,0] := 'Nombre Impresora';
StringGrid1.Cells[1,0] := 'PC';
StringGrid1.Cells[2,0] := 'Usuario';
StringGrid1.Cells[3,0] := 'Nombre del Docto.';
StringGrid1.Cells[4,0] := 'Tipo del Docto';
StringGrid1.Cells[5,0] := 'Estatus';
StringGrid1.Cells[6,0] := 'Descripcion del status';

aJobs := GetSpoolerJobs('HP DeskJet 840C'); //aqui se pone la impresora

for i:=0 to Length(aJobs)-1 do begin
StringGrid1.Cells[0,i+1] := aJobs[i].pPrinterName;
StringGrid1.Cells[1,i+1] := aJobs[i].pMachineName;
StringGrid1.Cells[2,i+1] := aJobs[i].pUserName;
StringGrid1.Cells[3,i+1] := aJobs[i].pDocument;
StringGrid1.Cells[4,i+1] := aJobs[i].pDatatype;
StringGrid1.Cells[5,i+1] := IntToStr(aJobs[i].Status);

case aJobs[i].Status of
JOB_STATUS_PAUSED: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_PAUSED';
JOB_STATUS_ERROR: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_ERROR';
JOB_STATUS_DELETING: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_DELETING';
JOB_STATUS_SPOOLING: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_SPOOLING';
JOB_STATUS_PRINTING: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_PRINTING';
JOB_STATUS_OFFLINE: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_OFFLINE';
JOB_STATUS_PAPEROUT: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_PAPEROUT';
JOB_STATUS_PRINTED: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_PRINTED';
JOB_STATUS_DELETED: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_DELETED';
JOB_STATUS_BLOCKED_DEVQ: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_BLOCKED_DEVQ';
JOB_STATUS_USER_INTERVENTION: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_USER_INTERVENTION';
JOB_STATUS_RESTART: StringGrid1.Cells[6,i+1] := 'JOB_STATUS_RESTART';
JOB_POSITION_UNSPECIFIED: StringGrid1.Cells[6,i+1] := 'JOB_POSITION_UNSPECIFIED';

else StringGrid1.Cells[6,i+1] := 'Estatus desconocido...';
end;
end;

StringGrid1.Refresh;
end;

end.