网上有C#版的打印监控,可以监控到打印内容。如果只是监控打印队列,下面这段好像也可以:{$IFDEF DEBUGGING}var dbgwnd: THandle = INVALID_HANDLE_VALUE;
debugstr: string = '';procedure DebugOut(s: string;
pcs: PRTLCriticalSection = nil);
begin
if pcs <> nil then
begin
EnterCriticalSection(pcs^);
s := '[*] ' + s;
end;
if IsWindow(dbgwnd) then
begin
debugstr := debugstr + s + #13#10;
SendMessage(dbgwnd, WM_SETTEXT, 0, Integer(@debugstr[1]));
Sendmessage(dbgwnd, WM_VSCROLL, SB_BOTTOM, 0);
end;
OutPutDebugString(@s[1]);
if pcs <> nil then
LeaveCriticalSection(pcs^);
end;
{$ENDIF DEBUGGING}type PMyThreadData = ^TMyThreadData;
TMyThreadData = record ThreadID: Cardinal;
ThreadHandle: THandle;
Threadruns: BOOL;
countbuffers: Integer;
critsect: PRTLCriticalSection;
self: PMyThreadData;
cbPrintername, cbFilename: Integer;
Printername, Filename: PChar;
end;
var // initialised variables ... needed JobFields: array[0..7] of WORD = ( JOB_NOTIFY_FIELD_PRINTER_NAME, JOB_NOTIFY_FIELD_MACHINE_NAME, JOB_NOTIFY_FIELD_STATUS, // Status bits JOB_NOTIFY_FIELD_DOCUMENT, //do
cument Name JOB_NOTIFY_FIELD_USER_NAME, // Name ofdo
cuments owner JOB_NOTIFY_FIELD_TOTAL_PAGES, // Total pages in the job JOB_NOTIFY_FIELD_PAGES_PRINTED, // # of pages of the job that have printed JOB_NOTIFY_FIELD_SUBMITTED // The time and date job was submitted );
PrinterFields: array[0..4] of WORD = ( PRINTER_NOTIFY_FIELD_STATUS, // Status bits of printer queue PRINTER_NOTIFY_FIELD_CJOBS, // # of jobs in printer queue PRINTER_NOTIFY_FIELD_PRINTER_NAME, // Name of the printer queue PRINTER_NOTIFY_FIELD_SERVER_NAME, // Name of the server when the queue is remote PRINTER_NOTIFY_FIELD_SHARE_NAME // The queue's sharename );
Notifications: array[0..1] of PRINTER_NOTIFY_OPTIONS_TYPE = ( ( wType: JOB_NOTIFY_TYPE;
Reserved0: 0;
Reserved1: 0;
Reserved2: 0;
Count: sizeof(JobFields) div sizeof(JobFields[0]);
pFields: @JobFields[0];
), ( wType: PRINTER_NOTIFY_TYPE;
Reserved0: 0;
Reserved1: 0;
Reserved2: 0;
Count: sizeof(PrinterFields) div sizeof(PrinterFields[0]);
pFields: @PrinterFields[0];
) );
NotificationOptions: PRINTER_NOTIFY_OPTIONS = ( Version: 2;
Flags: PRINTER_NOTIFY_OPTIONS_REFRESH;
Count: 2;
pTypes: @Notifications[0];
);function PrinterNotify_Threadfunc(X: POINTER): DWORD;
stdcall;{0 = success1 = open printer error2 = notification handle invalid3 = Findnext.....() failed}var _ThreadBuffer: PMyThreadData;
pNotification: PPRINTERNOTIFYINFO;
p: pointer;
change, hNotify, hPrinter: cardinal;
i: integer;
OldFlags: Cardinal;{$IFDEF DEBUGGING} pFILETIME: FILETIME;
intdebugstr: string;{$ENDIF DEBUGGING}label _cleanup;
{ Everything that happens in this thread, happens in the WHILE loop. Everything else
is initialisation or finalisation. }begin
result := 0;
_ThreadBuffer := X;
if Openprinter(_ThreadBuffer^.Printername, hPrinter, nil) then
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('Openprinter() called successfully for "%s" [hPrinter = %8.8X]', [_ThreadBuffer^.Printername, pointer(hPrinter)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} change := PRINTER_CHANGE_ALL;
hNotify := FindFirstPrinterChangeNotification(hPrinter, change, 0, @NotificationOptions);
if hNotify = INVALID_HANDLE_VALUE then
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + 'Invalid notification handle returned! (hNotify = INVALID_HANDLE_VALUE)', _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} result := 2;
exit;
end;
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('Starting notification loop [%s].', [_ThreadBuffer^.Printername]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} while hNotify <> INVALID_HANDLE_VALUEdo
begin
if WaitForSingleObject(hNotify, INFINITE) = WAIT_OBJECT_0 then
begin
{$IFDEF DEBUGGING} DebugOut('', _ThreadBuffer^.critsect);
DebugOut('[T] ' + frmt('----->>> Got notification event [%s]', [_ThreadBuffer^.Printername]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} if not FindNextPrinterChangeNotification(hNotify, change, @NotificationOptions, p) then
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + 'No next notification handle: FindNextPrinterChangeNotification() = FALSE', _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} result := 3;
goto _cleanup;
end;
pNotification := p;
if assigned(pNotification) then
if (pNotification.Flags and PRINTER_NOTIFY_INFO_DISCARDED) <> 0 then
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + 'Trying to get get notification again due to too small buffer (PRINTER_NOTIFY_INFO_DISCARDED).', _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} Oldflags := NotificationOptions.Flags;
NotificationOptions.Flags := PRINTER_NOTIFY_OPTIONS_REFRESH;
FreePrinterNotifyInfo(p);
FindNextPrinterChangeNotification(hNotify, change, @NotificationOptions, p);
NotificationOptions.Flags := OldFlags;
end;
{$IFDEF DEBUGGING} intdebugstr := '';{$ENDIF DEBUGGING} for i := 0 to pNotification.Count - 1do
begin
case pNotification.aData
.wType of // get the right field from buffer ... JOB_NOTIFY_TYPE: case pNotification.aData.field of JOB_NOTIFY_FIELD_STATUS: begin
{$IFDEF DEBUGGING} intdebugstr := '';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_BLOCKED_DEVQ) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_BLOCKED_DEVQ ' else
intdebugstr := ' JOB_STATUS_BLOCKED_DEVQ ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_DELETED) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_DELETED ' else
intdebugstr := ' JOB_STATUS_DELETED ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_DELETING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_DELETING ' else
intdebugstr := intdebugstr + ' JOB_STATUS_DELETING ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_ERROR) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_ERROR ' else
intdebugstr := ' JOB_STATUS_ERROR ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_OFFLINE) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_OFFLINE ' else
intdebugstr := ' JOB_STATUS_OFFLINE ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_PAPEROUT) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_PAPEROUT ' else
intdebugstr := ' JOB_STATUS_PAPEROUT ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_PAUSED) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_PAUSED ' else
intdebugstr := ' JOB_STATUS_PAUSED ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_PRINTED) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_PRINTED ' else
intdebugstr := ' JOB_STATUS_PRINTED ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_PRINTING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_PRINTING ' else
intdebugstr := ' JOB_STATUS_PRINTING ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_RESTART) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_RESTART ' else
intdebugstr := ' JOB_STATUS_RESTART ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_SPOOLING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_SPOOLING ' else
intdebugstr := ' JOB_STATUS_SPOOLING ';
if (pNotification.aData.NotifyData.adwData[0] and JOB_STATUS_USER_INTERVENTION) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| JOB_STATUS_USER_INTERVENTION ' else
intdebugstr := ' JOB_STATUS_USER_INTERVENTION ';
intdebugstr := 'JOB_NOTIFY_FIELD_STATUS = (' + intdebugstr + ')';
DebugOut('[T] ' + intdebugstr, _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PRINTER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PRINTER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_MACHINE_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_MACHINE_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_DOCUMENT: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_DOCUMENT: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_USER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_USER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PAGES_PRINTED: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PAGES_PRINTED: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_TOTAL_PAGES: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_TOTAL_PAGES: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_SUBMITTED: begin
// try to set the date/time of notification if not SystemTimeToFileTime(SYSTEMTIME(pNotification.aData.NotifyData.Data.pbuf^), pFILETIME) then
begin
// set illegal date if conversion to filetime did not succeed pFILETIME.dwLowDateTime := $0F0F;
pFILETIME.dwHighDateTime := $F0F0;
end;
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_SUBMITTED: SYSTEMTIME(NotifyData.Data.pbuf^) = %8.8X%8.8X', [Pointer(pFILETIME.dwHighDateTime), Pointer(pFILETIME.dwLowDateTime)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PORT_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PORT_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_NOTIFY_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_NOTIFY_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_DATATYPE: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_DATATYPE: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PRINT_PROCESSOR: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PRINT_PROCESSOR: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PARAMETERS: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PARAMETERS: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_DRIVER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_DRIVER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_DEVMODE: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_DEVMODE: (too complex)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_STATUS_STRING: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_STATUS_STRING: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pBuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_PRIORITY: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_PRIORITY: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_POSITION: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_POSITION: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_START_TIME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_START_TIME: %2.2d:%2.2d', [pointer(pNotification.aData.NotifyData.adwData[0] div 60), pointer(pNotification.aData.NotifyData.adwData[0] mod 60)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_UNTIL_TIME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_UNTIL_TIME: %2.2d:%2.2d', [pointer(pNotification.aData.NotifyData.adwData[0] div 60), pointer(pNotification.aData.NotifyData.adwData[0] mod 60)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_TIME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_TIME: NotifyData.adwData[0] = %d sec', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_TOTAL_BYTES: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_TOTAL_BYTES: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
JOB_NOTIFY_FIELD_BYTES_PRINTED: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('JOB_NOTIFY_FIELD_BYTES_PRINTED: NotifyData.adwData[0] = %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
else
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('UNKNOWN job notification.', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
end;
PRINTER_NOTIFY_TYPE: case pNotification.aData.field of PRINTER_NOTIFY_FIELD_STATUS: begin
{$IFDEF DEBUGGING} intdebugstr := '';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PAUSED) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PAUSED ' else
intdebugstr := ' PRINTER_STATUS_PAUSED ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_ERROR) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_ERROR ' else
intdebugstr := ' PRINTER_STATUS_ERROR ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PENDING_DELETION) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PENDING_DELETION ' else
intdebugstr := ' PRINTER_STATUS_PENDING_DELETION ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PAPER_JAM) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PAPER_JAM ' else
intdebugstr := ' PRINTER_STATUS_PAPER_JAM ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PAPER_OUT) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PAPER_OUT ' else
intdebugstr := ' PRINTER_STATUS_PAPER_OUT ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_MANUAL_FEED) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_MANUAL_FEED ' else
intdebugstr := ' PRINTER_STATUS_MANUAL_FEED ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PAPER_PROBLEM) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PAPER_PROBLEM ' else
intdebugstr := ' PRINTER_STATUS_PAPER_PROBLEM ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_OFFLINE) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_OFFLINE ' else
intdebugstr := ' PRINTER_STATUS_OFFLINE ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_IO_ACTIVE) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_IO_ACTIVE ' else
intdebugstr := ' PRINTER_STATUS_IO_ACTIVE ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_BUSY) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_BUSY ' else
intdebugstr := ' PRINTER_STATUS_BUSY ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PRINTING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PRINTING ' else
intdebugstr := ' PRINTER_STATUS_PRINTING ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_OUTPUT_BIN_FULL) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_OUTPUT_BIN_FULL ' else
intdebugstr := ' PRINTER_STATUS_OUTPUT_BIN_FULL ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_NOT_AVAILABLE) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_NOT_AVAILABLE ' else
intdebugstr := ' PRINTER_STATUS_NOT_AVAILABLE ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_WAITING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_WAITING ' else
intdebugstr := ' PRINTER_STATUS_WAITING ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PROCESSING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PROCESSING ' else
intdebugstr := ' PRINTER_STATUS_PROCESSING ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_INITIALIZING) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_INITIALIZING ' else
intdebugstr := ' PRINTER_STATUS_INITIALIZING ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_WARMING_UP) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_WARMING_UP ' else
intdebugstr := ' PRINTER_STATUS_WARMING_UP ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_TONER_LOW) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_TONER_LOW ' else
intdebugstr := ' PRINTER_STATUS_TONER_LOW ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_NO_TONER) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_NO_TONER ' else
intdebugstr := ' PRINTER_STATUS_NO_TONER ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_PAGE_PUNT) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_PAGE_PUNT ' else
intdebugstr := ' PRINTER_STATUS_PAGE_PUNT ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_USER_INTERVENTION) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_USER_INTERVENTION ' else
intdebugstr := ' PRINTER_STATUS_USER_INTERVENTION ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_OUT_OF_MEMORY) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_OUT_OF_MEMORY ' else
intdebugstr := ' PRINTER_STATUS_OUT_OF_MEMORY ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_DOOR_OPEN) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_DOOR_OPEN ' else
intdebugstr := ' PRINTER_STATUS_DOOR_OPEN ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_SERVER_UNKNOWN) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_SERVER_UNKNOWN ' else
intdebugstr := ' PRINTER_STATUS_SERVER_UNKNOWN ';
if (pNotification.aData.NotifyData.adwData[0] and PRINTER_STATUS_POWER_SAVE) <> 0 then
if intdebugstr <> '' then
intdebugstr := intdebugstr + '| PRINTER_STATUS_POWER_SAVE ' else
intdebugstr := ' PRINTER_STATUS_POWER_SAVE ';
intdebugstr := 'PRINTER_NOTIFY_FIELD_STATUS = (' + intdebugstr + ')';
DebugOut('[T] ' + intdebugstr, _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_SERVER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_SERVER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PRINTER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PRINTER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_SHARE_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_SHARE_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PORT_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PORT_NAME: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_DRIVER_NAME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_DRIVER_NAME: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_COMMENT: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_COMMENT: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_LOCATION: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_LOCATION: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_DEVMODE: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_DEVMODE: (too complex)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_SEPFILE: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_SEPFILE: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PARAMETERS: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PARAMETERS: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_DATATYPE: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_DATATYPE: NotifyData.Data.pbuf = "%s"', [pNotification.aData.NotifyData.Data.pbuf]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR: (too complex)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_ATTRIBUTES: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_ATTRIBUTES: %8.8X', [pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PRIORITY: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PRIORITY: %8.8X', [pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY: %8.8X', [pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_START_TIME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_START_TIME: %2.2d:%2.2d', [pointer(pNotification.aData.NotifyData.adwData[0] div 60), pointer(pNotification.aData.NotifyData.adwData[0] mod 60)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_UNTIL_TIME: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_UNTIL_TIME: %2.2d:%2.2d', [pointer(pNotification.aData.NotifyData.adwData[0] div 60), pointer(pNotification.aData.NotifyData.adwData[0] mod 60)]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_STATUS_STRING: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_STATUS_STRING: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_CJOBS: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_CJOBS: %d', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_AVERAGE_PPM: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_AVERAGE_PPM: %d per minute', [Pointer(pNotification.aData.NotifyData.adwData[0])]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_TOTAL_PAGES: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_TOTAL_PAGES: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_PAGES_PRINTED: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_PAGES_PRINTED: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_TOTAL_BYTES: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_TOTAL_BYTES: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
PRINTER_NOTIFY_FIELD_BYTES_PRINTED: begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('PRINTER_NOTIFY_FIELD_BYTES_PRINTED: (not supported)', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
else
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('UNKNOWN printer notification.', []), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} end;
end;
end;
end;
// flush to file at this point ... _cleanup: FreePrinterNotifyInfo(p);
end;
end;
FindClosePrinterChangeNotification(hNotify);
end else
begin
{$IFDEF DEBUGGING} DebugOut('[T] ' + frmt('Openprinter() failed for "%s"', [_Threadbuffer^.Printername]), _ThreadBuffer^.critsect);{$ENDIF DEBUGGING} result := 1;
end;
_Threadbuffer^.Threadruns := false;
// set this thread to stoppedend;
var ThreadBuffer: PMyThreadData;
cs: TRTLCriticalSection;function InitnotificationThreads: boolean;var ppi4, ppi4_: PPrinterInfo4;
i, needed, returned: Cardinal;
_ThreadBuffer: PMyThreadData;
tempstring: string;
begin
result := false;{$IFDEF DEBUGGING} DebugOut('--------------------------------------------------------------------');
DebugOut('Starting initialisation.');
DebugOut('Initialising critical section ...');{$ENDIF DEBUGGING} InitializeCriticalSection(cs);{$IFDEF DEBUGGING} DebugOut('Getting needed buffer size for printer information (PRINTER_INFO_4).');{$ENDIF DEBUGGING} if not enumprinters(PRINTER_ENUM_LOCAL, nil, 4, nil, 0, needed, returned) then
try{$IFDEF DEBUGGING} DebugOut(frmt('Required size is: %d Bytes', [pointer(needed)]));{$ENDIF DEBUGGING} ppi4 := GetMemory(needed);
if assigned(ppi4) then
if EnumPrinters(PRINTER_ENUM_LOCAL, nil, 4, ppi4, needed, needed, returned) then
{$IFDEF DEBUGGING} DebugOut('Enumerated the printers successfully!'){$ENDIF DEBUGGING} else
{$IFDEF DEBUGGING} begin
DebugOut(frmt('Something went wrong during enumeration of the Printers (GetLastError: %X)', [Pointer(GetLastError)]));{$ENDIF DEBUGGING} exit;{$IFDEF DEBUGGING} end;
{$ENDIF DEBUGGING} ppi4_ := ppi4;
// get the required amount of memory for the ThreadBuffer ThreadBuffer := GetMemory(sizeof(TMyThreadData) * returned);{$IFDEF DEBUGGING} if assigned(ThreadBuffer) then
DebugOut(frmt('Got required amount of memory for ThreadBuffer. (%d Bytes)', [pointer(sizeof(TMyThreadData) * returned)])) else
DebugOut('Failed to get required amount of memory for ThreadBuffer.');
DebugOut('');
// empty line DebugOut('Copying the following names:');{$ENDIF DEBUGGING} if assigned(ThreadBuffer) then
ZeroMemory(ThreadBuffer, sizeof(TMyThreadData) * returned) else
exit;
_Threadbuffer := Threadbuffer;
for i := 0 to returned - 1do
try // get needed size for the printer name _ThreadBuffer^.cbPrintername := lstrlen(ppi4_^.pPrinterName) + 1;
// get the required amount of memory _ThreadBuffer^.Printername := GetMemory(_ThreadBuffer^.cbPrintername);
// fill it with zeroes ZeroMemory(_ThreadBuffer^.Printername, _ThreadBuffer^.cbPrintername);
// copy the name into our buffer lstrcpyn(_ThreadBuffer^.Printername, ppi4_^.pPrinterName, _ThreadBuffer^.cbPrintername);
// set number of overall buffers of PMyThreadData in ThreadBuffer _ThreadBuffer^.countbuffers := returned;
_ThreadBuffer^.self := _ThreadBuffer;{$IFDEF DEBUGGING} DebugOut(frmt('%2.2d. %s', [pointer(i + 1), _ThreadBuffer^.Printername]));{$ENDIF DEBUGGING} // step through the buffer inc(ppi4_);
inc(_ThreadBuffer);
except{$IFDEF DEBUGGING} DebugOut('An exception occured while reading PRINTER_INFO_4 into ThreadBuffer. Catched.'){$ENDIF DEBUGGING} end;
FreeMemory(ppi4);
_Threadbuffer := Threadbuffer;
if assigned(Threadbuffer) then
begin
for i := 0 to _ThreadBuffer^.countbuffers - 1do
begin
SetString(Tempstring, _Threadbuffer^.Printername, lstrlen(_Threadbuffer^.Printername));
while pos(#32, Tempstring) > 0do
// exchange whitespaces with underbars Tempstring[pos(#32, Tempstring)] := '_';
Tempstring := Tempstring + '.prtmon3';
// setting ThreadBuffer variables _Threadbuffer^.cbFilename := length(Tempstring) + 1;
_Threadbuffer^.Filename := GetMemory(_Threadbuffer^.cbFilename);
if Assigned(_Threadbuffer^.Filename) then
begin
ZeroMemory(_Threadbuffer^.Filename, _Threadbuffer^.cbFilename);
lstrcpyn(_Threadbuffer^.Filename, @TempString[1], _Threadbuffer^.cbFilename);{$IFDEF DEBUGGING} DebugOut(frmt('Output will be written to: "%s"', [_Threadbuffer^.Filename]));{$ENDIF DEBUGGING} end;
_ThreadBuffer^.critsect := @cs;
_Threadbuffer^.Threadruns := false;
_Threadbuffer^.ThreadHandle := INVALID_HANDLE_VALUE;
// starting thread _Threadbuffer^.ThreadHandle := CreateThread(nil, 0, @PrinterNotify_Threadfunc, _Threadbuffer^.self, 0, _Threadbuffer^.ThreadID);
// checking if thread runs if _Threadbuffer^.ThreadHandle <> INVALID_HANDLE_VALUE then
_Threadbuffer^.Threadruns := true;{$IFDEF DEBUGGING} if _Threadbuffer^.Threadruns then
DebugOut(frmt('Started thread successfully [%s]' + #13#10 + '-> Threadhandle = %8.8X', [_Threadbuffer^.printername, pointer(_Threadbuffer^.ThreadHandle)])) else
DebugOut(frmt('Thread could not be started [%s]' + #13#10 + '-> GetLastError = %d', [_Threadbuffer^.printername, pointer(GetLastError)]));{$ENDIF DEBUGGING} inc(_ThreadBuffer);
end;
result := true;
end;
except{$IFDEF DEBUGGING} DebugOut(frmt('Handled some exception %d', [pointer(IOResult)]));{$ENDIF DEBUGGING} end;
{$IFDEF DEBUGGING} DebugOut('Finished initialisation.');
DebugOut('--------------------------------------------------------------------');
DebugOut('');{$ENDIF DEBUGGING}end;
{$WARNINGS OFF}function FInitnotificationThreads: boolean;var _ThreadBuffer: PMyThreadData;
i: integer;
exitcode: Cardinal;
begin
result := false;{$IFDEF DEBUGGING} DebugOut('--------------------------------------------------------------------');
DebugOut('Starting finalisation.');{$ENDIF DEBUGGING} _ThreadBuffer := ThreadBuffer;
try for i := 0 to _ThreadBuffer^.countbuffers - 1do
begin
if TerminateThread(_ThreadBuffer^.ThreadHandle, exitcode) then
// say success if last buffer was freed result := _ThreadBuffer^.countbuffers - 1 = i{$IFDEF DEBUGGING} else
DebugOut(frmt('Could not terminate thread number %d [ThreadID = %8.8X]', [pointer(i + 1), pointer(_ThreadBuffer^.ThreadID)]));{$ENDIF DEBUGGING} end;
finally try FreeMemory(ThreadBuffer);
except;
end;
end;
// delete critical section ... make sure before, all the threads are terminated DeleteCriticalSection(cs);
// finalisation of this stuff{$IFDEF DEBUGGING} DebugOut('Finished finalisation.');
DebugOut('--------------------------------------------------------------------');{$ENDIF DEBUGGING}end;
{$WARNINGS ON}