unit SpoolerStatusThreat;
interface
uses Classes, Windows, Messages, SysUtils, Graphics, StdCtrls, Forms;
type
TSpoolerMonitor =
class(TThread)
private
FMsg:
string;
FForm: TForm;
protected
procedure Execute;
override;
procedure SpoolerStatus;
public
constructor Create(Suspend: boolean);
overload;
constructor Create(Suspend: boolean; Dispatch2Target: TForm);
overload;
public
procedure exitThread;
end;
var
SpoolerMonitor: TSpoolerMonitor;
const
WM_PRINTJOB_ADDED = WM_USER + 1000;
implementation
uses WinSpool, Printers;
type
TPrinterDevice =
class
Driver:
string;
Device:
string;
Port:
string;
end;
Var
pi2: PRINTER_INFO_2;
pno: PRINTER_NOTIFY_OPTIONS;
pinfo: PPrinterNotifyInfo;
pn:
array[0..1]
of PRINTER_NOTIFY_OPTIONS_TYPE;
pnf:
array[0..100]
of WORD;
jnf:
array[0..100]
of WORD;
function GetCurrentPrinterName:
String;
begin
Result := TPrinterDevice(Printer.Printers.Objects[Printer.PrinterIndex]).Device;
end;
procedure TSpoolerMonitor.SpoolerStatus;
var
hResult: THandle;
Result: LongBool;
hPrinter: cardinal;
pdwChange: DWORD;
ok: boolean;
AppTerminated: Boolean;
aMsg: TMsg;
begin
pdwChange := 0;
pi2.pPrinterName := PWideChar(GetCurrentPrinterName);
if OpenPrinter(pi2.pPrinterName, hPrinter, 0)
then
hResult := FindFirstPrinterChangeNotification(hPrinter, PRINTER_CHANGE_JOB, 0, @pno);
ok:= hResult <> INVALID_HANDLE_VALUE;
if ok
then
while not terminated
do
begin
AppTerminated := false;
repeat
sleep(10);
// Pause von 10 Millisekunden neu eingefügt
PeekMessage(aMsg, 0, 0, 0, PM_REMOVE);
AppTerminated := (aMsg.
message = WM_QUIT);
until AppTerminated
or (WaitForSingleObject(hResult, 500) = WAIT_OBJECT_0);
if AppTerminated
then exit;
ok := false;
pno.Flags := 0;
Result := FindNextPrinterChangeNotification(hResult, pdwChange, @pno, pointer(pinfo));
if ord(Result) <> 0
then
begin
if (pdwChange
and PRINTER_CHANGE_ADD_JOB) > 0
then
PostMessage(fForm.Handle, WM_PRINTJOB_ADDED, 0, 0);
end;
end;
end;
constructor TSpoolerMonitor.Create(Suspend: boolean);
begin
inherited Create(Suspend);
FreeOnTerminate := True;
end;
constructor TSpoolerMonitor.Create(Suspend: boolean; Dispatch2Target: TForm);
begin
inherited Create(Suspend);
FreeOnTerminate := True;
FForm := Dispatch2Target;
end;
procedure TSpoolerMonitor.Execute;
var
aMsg: TMsg;
begin
inherited;
SpoolerStatus;
end;
procedure TSpoolerMonitor.exitThread;
begin
PostThreadMessage(Self.ThreadID, WM_QUIT, 0, 0);
if Suspended
then Resume;
end;
initialization
pno.Version := 2;
pno.Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
pno.Count := 200;
pno.pTypes := @pn;
pn[0].wType := PRINTER_NOTIFY_TYPE;
pn[0].Count := 8;
pn[0].pFields := @pnf;
pn[1].wType := JOB_NOTIFY_TYPE;
pn[1].Count := 24;
pn[1].pFields := @jnf;
pnf[0] := PRINTER_NOTIFY_FIELD_STATUS;
pnf[1] := PRINTER_NOTIFY_FIELD_CJOBS;
pnf[2] := PRINTER_NOTIFY_FIELD_ATTRIBUTES;
pnf[3] := PRINTER_NOTIFY_FIELD_COMMENT;
pnf[4] := PRINTER_NOTIFY_FIELD_DEVMODE;
pnf[5] := PRINTER_NOTIFY_FIELD_LOCATION;
pnf[6] := PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR;
pnf[7] := PRINTER_NOTIFY_FIELD_SEPFILE;
jnf[0] := JOB_NOTIFY_FIELD_DOCUMENT;
jnf[1] := JOB_NOTIFY_FIELD_STATUS;
jnf[2] := JOB_NOTIFY_FIELD_MACHINE_NAME;
jnf[3] := JOB_NOTIFY_FIELD_PORT_NAME;
jnf[4] := JOB_NOTIFY_FIELD_USER_NAME;
jnf[5] := JOB_NOTIFY_FIELD_NOTIFY_NAME;
jnf[6] := JOB_NOTIFY_FIELD_DATATYPE;
jnf[7] := JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
jnf[8] := JOB_NOTIFY_FIELD_PARAMETERS;
jnf[9] := JOB_NOTIFY_FIELD_DRIVER_NAME;
jnf[10] := JOB_NOTIFY_FIELD_DEVMODE;
jnf[11] := JOB_NOTIFY_FIELD_STATUS_STRING;
jnf[12] := JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR;
jnf[13] := JOB_NOTIFY_FIELD_PRINTER_NAME;
jnf[14] := JOB_NOTIFY_FIELD_PRIORITY;
jnf[15] := JOB_NOTIFY_FIELD_POSITION;
jnf[16] := JOB_NOTIFY_FIELD_SUBMITTED;
jnf[17] := JOB_NOTIFY_FIELD_START_TIME;
jnf[18] := JOB_NOTIFY_FIELD_UNTIL_TIME;
jnf[19] := JOB_NOTIFY_FIELD_TIME;
jnf[20] := JOB_NOTIFY_FIELD_TOTAL_PAGES;
jnf[21] := JOB_NOTIFY_FIELD_PAGES_PRINTED;
jnf[22] := JOB_NOTIFY_FIELD_TOTAL_BYTES;
jnf[23] := JOB_NOTIFY_FIELD_BYTES_PRINTED;
end.