//仅供 ccdos 专用<br>//2004-11-28<br>// hfghfghfg <br><br>unit PrinterEvent;<br><br>interface<br>uses SysUtils, Messages, Windows, Classes, WinSpool, dateUtils, ExtCtrls;<br>const<br> PrinterInfoLevel = 2;<br> JobInfoLevel = 2;<br> RefreshInterval: Integer = 10;<br> WM_THREADERROR = WM_USER + 1;<br> WM_PRINTED = WM_USER + 2;<br> WM_JobEvent = WM_USER + 3;<br><br><br>type<br><br> PJobRecord = ^TJobRecord;<br> TJobRecord = record<br> ComputerName: string;<br> UserName: string;<br> PrinterName: string;<br> DocName: string;<br> SUBMITTED_datetime: TDateTime;<br> id: integer;<br> PageCount: Integer<br> end;<br> TJobEvent = procedure(Sender: TObject; JobRecord: TJobRecord) of object;<br><br><br><br> TPrinterNTThread = class(TThread)<br> private<br> FPrnHandle: THandle;<br> FPrnName: string;<br> FNotify: THandle;<br> FOptions: TPrinterNotifyOptions;<br> FOptionsType: TPrinterNotifyOptionsType;<br><br> FJobEvent: TJobEvent;<br><br> protected<br> procedure SetPrnName(V: string);<br> procedure DoJobEvent(J: TJobRecord);<br> public<br> FNowJobRecord: TJobRecord;<br> constructor Create(V: string); virtual;<br> destructor Destroy; override;<br> procedure ForDoJobEvent;<br> procedure Execute; override;<br> property PrnName: string read FPrnName;<br> property onThreadJobEvent: TJobEvent read FJobEvent write FJobEvent;<br> end;<br><br><br><br><br><br><br> TPrinterEvent = class(TComponent)<br> private<br> FOnJobEvent: TJobEvent;<br> FTimer: TTimer;<br> FWaiteEventThread_List: array of TPrinterNTThread;<br> procedure ThreadJobEvent(Sender: TObject; JobRecord: TJobRecord);<br> protected<br> { Protected declarations }<br> public<br> constructor Create(AOwner: TComponent); override;<br> destructor Destroy; override;<br> procedure UpdatePrinters;<br> procedure onThreadTerminate(sender: TObject);<br> procedure OnTimer(sender: TObject);<br> published<br> { Published declarations }<br><br> property OnJobEvent: TJobEvent read FOnJobEvent write FOnJobEvent;<br> end;<br><br><br>implementation<br><br>procedure Register;<br>begin<br> RegisterComponents('Samples', [TPrinterEvent]);<br>end;<br>const<br> AFields: array[0..6] of Word<br> = (JOB_NOTIFY_FIELD_SUBMITTED, JOB_NOTIFY_FIELD_MACHINE_NAME, JOB_NOTIFY_FIELD_START_TIME, JOB_NOTIFY_FIELD_DOCUMENT, JOB_NOTIFY_FIELD_USER_NAME, JOB_NOTIFY_FIELD_TOTAL_PAGES, JOB_NOTIFY_FIELD_PAGES_PRINTED);<br><br><br><br>{ TPrinterNTThread }<br><br>constructor TPrinterNTThread.Create(V: string);<br>begin<br> SetPrnName(V);<br> inherited Create(True);<br> FreeOnTerminate := true;<br>end;<br><br>destructor TPrinterNTThread.Destroy;<br>begin<br> inherited;<br>end;<br><br>procedure TPrinterNTThread.DoJobEvent(J: TJobRecord);<br>begin<br> if assigned(FJobEvent) then<br> begin<br> FNowJobRecord := j;<br> Synchronize(ForDoJobEvent);<br> end;<br>end;<br><br>procedure TPrinterNTThread.ForDoJobEvent;<br>begin<br> FJobEvent(self, FNowJobRecord);<br>end;<br><br>procedure TPrinterNTThread.Execute;<br>type<br> PInfoDatas = ^TInfoDatas;<br> TInfoDatas = array[0..31] of TPrinterNotifyInfoData;<br>var<br> i: integer;<br> AChange: Cardinal;<br><br> AInfo: Pointer;<br> P: PInfoDatas;<br> pc: pchar;<br> strTemp: string;<br> jobRec: TJobRecord;<br> sys_time: _SystemTime;<br> ZI: TTimeZoneInformation;<br>begin<br><br> AInfo := nil;<br> while (FPrnHandle > 0) and (FNotify > 0) and (not Terminated) do<br> begin<br><br> if WaitForSingleObject(FNotify, INFINITE) = WAIT_OBJECT_0 then<br> begin<br> FreePrinterNotifyInfo(AInfo);<br> if not FindNextPrinterChangeNotification(FNotify, AChange, @FOptions, AInfo) then<br> begin<br>// SendError;<br> Continue;<br> end;<br><br><br> with PPrinterNotifyInfo(AInfo)^ do<br> begin<br><br><br> P := @aData;<br> for i := 0 to count - 1 do<br> begin<br> if p.wType = PRINTER_NOTIFY_TYPE then<br> begin<br> case p.Field of<br><br> PRINTER_NOTIFY_FIELD_SERVER_NAME: ;<br> PRINTER_NOTIFY_FIELD_PRINTER_NAME: ;<br> PRINTER_NOTIFY_FIELD_SHARE_NAME: ;<br> PRINTER_NOTIFY_FIELD_PORT_NAME: ;<br> PRINTER_NOTIFY_FIELD_DRIVER_NAME: ;<br> PRINTER_NOTIFY_FIELD_COMMENT: ;<br> PRINTER_NOTIFY_FIELD_LOCATION: ;<br> PRINTER_NOTIFY_FIELD_DEVMODE: ;<br> PRINTER_NOTIFY_FIELD_SEPFILE: ;<br> PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR: ;<br> PRINTER_NOTIFY_FIELD_PARAMETERS: ;<br> PRINTER_NOTIFY_FIELD_DATATYPE: ;<br> PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR: ;<br> PRINTER_NOTIFY_FIELD_ATTRIBUTES: ;<br> PRINTER_NOTIFY_FIELD_PRIORITY: ;<br> PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY: ;<br> PRINTER_NOTIFY_FIELD_START_TIME: ;<br> PRINTER_NOTIFY_FIELD_UNTIL_TIME: ;<br> PRINTER_NOTIFY_FIELD_STATUS: ;<br> PRINTER_NOTIFY_FIELD_STATUS_STRING: ;<br> PRINTER_NOTIFY_FIELD_CJOBS: ;<br> PRINTER_NOTIFY_FIELD_AVERAGE_PPM: ;<br> PRINTER_NOTIFY_FIELD_TOTAL_PAGES: ;<br> PRINTER_NOTIFY_FIELD_PAGES_PRINTED: ;<br> PRINTER_NOTIFY_FIELD_TOTAL_BYTES: ;<br> PRINTER_NOTIFY_FIELD_BYTES_PRINTED: ;<br> end;<br><br> end<br> else<br> if p.wType = JOB_NOTIFY_TYPE then<br> begin<br><br> if i = 0 then<br> begin<br><br> jobRec.id := p.Id;<br> jobRec.SUBMITTED_datetime := now;<br> jobRec.PrinterName := PrnName;<br> jobRec.PageCount := 0;<br> jobRec.id := p.Id;<br> end<br> else<br> if (jobRec.id <> p.Id) then<br> begin<br> DoJobEvent(jobRec);<br> jobRec.id := p.Id;<br> jobRec.SUBMITTED_datetime := now;<br> jobRec.PrinterName := PrnName;<br> jobRec.PageCount := 0;<br> jobRec.id := p.Id;<br> end;<br><br> case p.Field of<br> JOB_NOTIFY_FIELD_PRINTER_NAME: ;<br> JOB_NOTIFY_FIELD_MACHINE_NAME:<br> begin<br><br> SetLength(strTemp, p.NotifyData.Data.cbBuf);<br> Move(pchar(p.NotifyData.Data.pBuf)[0], strTemp[1], length(strTemp));<br> jobRec.ComputerName := pchar(strTemp);<br> strTemp := '';<br> end;<br> JOB_NOTIFY_FIELD_PORT_NAME: ;<br> JOB_NOTIFY_FIELD_USER_NAME:<br> begin<br><br> SetLength(strTemp, p.NotifyData.Data.cbBuf);<br> Move(pchar(p.NotifyData.Data.pBuf)[0], strTemp[1], length(strTemp));<br> jobRec.UserName := pchar(strTemp);<br> strTemp := '';<br> end;<br> JOB_NOTIFY_FIELD_NOTIFY_NAME: ;<br> JOB_NOTIFY_FIELD_DATATYPE: ;<br> JOB_NOTIFY_FIELD_PRINT_PROCESSOR: ;<br> JOB_NOTIFY_FIELD_PARAMETERS: ;<br> JOB_NOTIFY_FIELD_DRIVER_NAME: ;<br> JOB_NOTIFY_FIELD_DEVMODE: ;<br> JOB_NOTIFY_FIELD_STATUS: ;<br> JOB_NOTIFY_FIELD_STATUS_STRING: ;<br> JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR: ;<br> JOB_NOTIFY_FIELD_DOCUMENT:<br> begin<br> SetLength(strTemp, p.NotifyData.Data.cbBuf);<br> Move(pchar(p.NotifyData.Data.pBuf)[0], strTemp[1], length(strTemp));<br> jobRec.DocName := StrPas(pchar(strTemp));<br> strTemp := '';<br> end;<br> JOB_NOTIFY_FIELD_PRIORITY: ;<br> JOB_NOTIFY_FIELD_POSITION: ;<br> JOB_NOTIFY_FIELD_SUBMITTED:<br> begin<br><br> Move(p.NotifyData.Data.pBuf^, sys_time, Sizeof(sys_time));<br> jobRec.SUBMITTED_datetime := SystemTimeToDateTime(sys_time);<br> GetTimeZoneInformation(zi);