我监测的打印份数和张数为什么不正确(急!!) ( 积分: 200 )

  • 主题发起人 主题发起人 shownl
  • 开始时间 开始时间
S

shownl

Unregistered / Unconfirmed
GUEST, unregistred user!
我在win2000做一个打印监控的程序,但是在监控打印份数和张数时有时候正确有时候不正确总是少,不知道什么原因,小弟很着急,看有没有高高手解决这个问题???
麻烦各位看看!!!
我使用的源码如下:
procedure Tfrm_Main.MonitorFunc(APrinterName: string);
var
sTemp,sErrPos : string;
jobs : array [1..2000] of JOB_INFO_2;
//保留打印作业详细信息
size : DWORD;
jobs1 : array of JOB_INFO_2;
//动态数组用于对大于size的任务进行操作
pcbNeeded,dObject : DWORD;
//所有打印字节数
actNeed :integer;
pcReturned : DWORD;
//打印任务数
buf : Pchar;
//指向打印机或机器名
ret1:Bool ;
//获得打印机句柄返回值
ret:Bool ;
//获得打印机任务返回值
bMonitor:boolean;
//监控标志
len: integer ;
j : integer;
pPntDef:PRINTER_DEFAULTS ;
chgObject :THANDLE;
pdwChange :DWORD;
fcnreturn :BOOL;
hPrinter : THandle ;
//打印机句柄
ppPrinterNotifyInfo :PPrinterNotifyInfo;
pPrinterNotifyOptions:PRINTER_NOTIFY_OPTIONS;
mntSite :TMonitorSite_Struct;
//监控现场结构
prnDetail : TPrintDetail_Struct;//打印明细结构
StdInfo : TStudentInfo_Struct;//学生信息结构
srtPrinter : TPrinters_Struct;//打印机设置结构
cTemp :do
uble;
begin
size := 2000*sizeof(JOB_INFO_2);
jobs1 := nil;
pcbNeeded := 0;
pcReturned := 0;
pPntDef.DesiredAccess := PRINTER_ALL_ACCESS;
buf:= StrAlloc(255*SizeOf(Char));
GetMem(ppPrinterNotifyInfo,SizeOf(TPrinterNotifyInfo));
len:=Length(APrinterName);
StrPLCopy(buf,Pchar(APrinterName),len);//................字符串到字符的转换,
ret1:= OpenPrinter(buf,hPrinter,@pPntDef);//................获得打印机句柄
if(not ret1) then
begin
MessageDlg('获取打印机句柄异常!',mtError,[mbOK],0);
exit;
end;
srtPrinter := dm_MonitorDM.GetPrinterStruct(APrinterName);
bMonitor := true;
chgObject := FindFirstPrinterChangeNotification(hPrinter,PRINTER_CHANGE_JOB, 0, @pPrinterNotifyOptions);// PRINTER_CHANGE_ALL
while bMonitordo
begin
do
bject:=WaitForSingleObject(chgObject, WAIT_TIMEOUT);
if(dObject = WAIT_TIMEOUT) then
begin
Application.ProcessMessages;
continue;
end;
fcnreturn := FindNextPrinterChangeNotification(chgObject, pdwChange, Pointer(@pPrinterNotifyOptions), Pointer(ppPrinterNotifyInfo));
if (fcnreturn) then
begin
if (pdwChange and PRINTER_CHANGE_ADD_JOB)>0 then
begin
ret:= EnumJobs(hPrinter, 0, 127, 2,nil, 0,pcbNeeded,pcReturned);
//必要的一步,先取出打印机里任务的字节数,然后决定jobs1变量大小。//--------------------------①
if (ret and (pcbNeeded>size)) then
//.................重定义Jobs1, 根据pcbNeeded决定使用哪个变量
begin
actNeed:=pcbNeeded;
GetMem(jobs1, actNeed*sizeof(JOB_INFO_2));
ret:= EnumJobs(hPrinter, 0, 127, 2,@jobs1, actNeed, pcbNeeded, pcReturned);
end else
ret:= EnumJobs(hPrinter,0,127, 2,@jobs,size, pcbNeeded, pcReturned);//-----------------------------③
if(not ret)then
begin
MessageDlg('打印服务器监控异常!',mtError,[mbOK],0);
end;
if(pcbNeeded<size) and (pcbNeeded>0)then
begin
for j:=1to pcReturneddo
begin
try
sTemp := String(jobs[j].pMachineName);
mntSite.sComputerID := dm_MonitorDM.GetPrintComputerName(Copy(sTemp,3,Length(sTemp)-2));
//计算机名称
StdInfo := dm_MonitorDM.GetStudentInfo(mntSite.sComputerID);
mntSite.iJobID := jobs[j].JobId;
//任务ID
mntSite.sStudentNo := StdInfo.sStudentNo;
//学号
mntSite.sName := StdInfo.sName;
//姓名
mntSite.dtPrintTime := Now;
//打印时间
mntSite.sDocName := copy(String(jobs[j].pDocument),1,49);
//打印文档名称
mntSite.sPaperType := Trim(srtPrinter.sPaperType);
//打印纸张类型
mntSite.iCopys := jobs[j].pDevMode.dmCopies;
//打印份数
mntSite.sPrinterName := String(jobs[j].pPrinterName);
//打印机名称
if (mntSite.iCopys>1)then
begin
mntSite.iTotalPages := jobs[j].TotalPages * mntSite.iCopys;
//打印页数
mntSite.iPagePrinted := jobs[j].PagesPrinted * mntSite.iCopys;
end else
begin
mntSite.iPagePrinted := jobs[j].PagesPrinted;
mntSite.iTotalPages := jobs[j].TotalPages;
end;
end;
 
我在win2000做一个打印监控的程序,但是在监控打印份数和张数时有时候正确有时候不正确总是少,不知道什么原因,小弟很着急,看有没有高高手解决这个问题???
麻烦各位看看!!!
我使用的源码如下:
procedure Tfrm_Main.MonitorFunc(APrinterName: string);
var
sTemp,sErrPos : string;
jobs : array [1..2000] of JOB_INFO_2;
//保留打印作业详细信息
size : DWORD;
jobs1 : array of JOB_INFO_2;
//动态数组用于对大于size的任务进行操作
pcbNeeded,dObject : DWORD;
//所有打印字节数
actNeed :integer;
pcReturned : DWORD;
//打印任务数
buf : Pchar;
//指向打印机或机器名
ret1:Bool ;
//获得打印机句柄返回值
ret:Bool ;
//获得打印机任务返回值
bMonitor:boolean;
//监控标志
len: integer ;
j : integer;
pPntDef:PRINTER_DEFAULTS ;
chgObject :THANDLE;
pdwChange :DWORD;
fcnreturn :BOOL;
hPrinter : THandle ;
//打印机句柄
ppPrinterNotifyInfo :PPrinterNotifyInfo;
pPrinterNotifyOptions:PRINTER_NOTIFY_OPTIONS;
mntSite :TMonitorSite_Struct;
//监控现场结构
prnDetail : TPrintDetail_Struct;//打印明细结构
StdInfo : TStudentInfo_Struct;//学生信息结构
srtPrinter : TPrinters_Struct;//打印机设置结构
cTemp :do
uble;
begin
size := 2000*sizeof(JOB_INFO_2);
jobs1 := nil;
pcbNeeded := 0;
pcReturned := 0;
pPntDef.DesiredAccess := PRINTER_ALL_ACCESS;
buf:= StrAlloc(255*SizeOf(Char));
GetMem(ppPrinterNotifyInfo,SizeOf(TPrinterNotifyInfo));
len:=Length(APrinterName);
StrPLCopy(buf,Pchar(APrinterName),len);//................字符串到字符的转换,
ret1:= OpenPrinter(buf,hPrinter,@pPntDef);//................获得打印机句柄
if(not ret1) then
begin
MessageDlg('获取打印机句柄异常!',mtError,[mbOK],0);
exit;
end;
srtPrinter := dm_MonitorDM.GetPrinterStruct(APrinterName);
bMonitor := true;
chgObject := FindFirstPrinterChangeNotification(hPrinter,PRINTER_CHANGE_JOB, 0, @pPrinterNotifyOptions);// PRINTER_CHANGE_ALL
while bMonitordo
begin
do
bject:=WaitForSingleObject(chgObject, WAIT_TIMEOUT);
if(dObject = WAIT_TIMEOUT) then
begin
Application.ProcessMessages;
continue;
end;
fcnreturn := FindNextPrinterChangeNotification(chgObject, pdwChange, Pointer(@pPrinterNotifyOptions), Pointer(ppPrinterNotifyInfo));
if (fcnreturn) then
begin
if (pdwChange and PRINTER_CHANGE_ADD_JOB)>0 then
begin
ret:= EnumJobs(hPrinter, 0, 127, 2,nil, 0,pcbNeeded,pcReturned);
//必要的一步,先取出打印机里任务的字节数,然后决定jobs1变量大小。//--------------------------①
if (ret and (pcbNeeded>size)) then
//.................重定义Jobs1, 根据pcbNeeded决定使用哪个变量
begin
actNeed:=pcbNeeded;
GetMem(jobs1, actNeed*sizeof(JOB_INFO_2));
ret:= EnumJobs(hPrinter, 0, 127, 2,@jobs1, actNeed, pcbNeeded, pcReturned);
end else
ret:= EnumJobs(hPrinter,0,127, 2,@jobs,size, pcbNeeded, pcReturned);//-----------------------------③
if(not ret)then
begin
MessageDlg('打印服务器监控异常!',mtError,[mbOK],0);
end;
if(pcbNeeded<size) and (pcbNeeded>0)then
begin
for j:=1to pcReturneddo
begin
try
sTemp := String(jobs[j].pMachineName);
mntSite.sComputerID := dm_MonitorDM.GetPrintComputerName(Copy(sTemp,3,Length(sTemp)-2));
//计算机名称
StdInfo := dm_MonitorDM.GetStudentInfo(mntSite.sComputerID);
mntSite.iJobID := jobs[j].JobId;
//任务ID
mntSite.sStudentNo := StdInfo.sStudentNo;
//学号
mntSite.sName := StdInfo.sName;
//姓名
mntSite.dtPrintTime := Now;
//打印时间
mntSite.sDocName := copy(String(jobs[j].pDocument),1,49);
//打印文档名称
mntSite.sPaperType := Trim(srtPrinter.sPaperType);
//打印纸张类型
mntSite.iCopys := jobs[j].pDevMode.dmCopies;
//打印份数
mntSite.sPrinterName := String(jobs[j].pPrinterName);
//打印机名称
if (mntSite.iCopys>1)then
begin
mntSite.iTotalPages := jobs[j].TotalPages * mntSite.iCopys;
//打印页数
mntSite.iPagePrinted := jobs[j].PagesPrinted * mntSite.iCopys;
end else
begin
mntSite.iPagePrinted := jobs[j].PagesPrinted;
mntSite.iTotalPages := jobs[j].TotalPages;
end;
end;
 
Procedure TFormX.WMSpoolerstatus( Var msg: TWMSpoolerStatus );
begin

label1.caption:= Format('Spooler status code: %d',
[ msg.JobStatus ]);
label2.caption:= Format('Jobs left: %d', [msg.JobsLeft]);

end;

******************************************************************************************
type
TForm1 = class(TForm)
Label1: TLabel;
private
{ Private declarations }
procedure WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
message WM_SPOOLERSTATUS;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.WM_SpoolerStatus(var Msg : TWMSPOOLERSTATUS);
begin

Lable1.Caption := IntToStr(msg.JobsLeft)+' Jobs currenly in spooler';
msg.Result := 0;
end;


************************************************************************************
uses Printers, WinSpool;

function PrinterStatusText(Status: Integer): String;
begin

case Status of
0: Result := 'Waiting';
JOB_STATUS_PAUSED: Result := 'Paused';
JOB_STATUS_ERROR: Result := 'Error';
JOB_STATUS_DELETING: Result := 'Deleting';
JOB_STATUS_SPOOLING: Result := 'Spooling';
JOB_STATUS_PRINTING: Result := 'Printing';
JOB_STATUS_OFFLINE: Result := 'Offline';
JOB_STATUS_PAPEROUT: Result := 'Paper Out';
JOB_STATUS_PRINTED: Result := 'Printed';
JOB_STATUS_DELETED: Result := 'Deleted';
JOB_STATUS_BLOCKED_DEVQ: Result := 'Blocked';
JOB_STATUS_USER_INTERVENTION: Result := 'User Intervention';
JOB_STATUS_RESTART: Result := 'Restart';
else
Result := 'Status ' + IntToStr(Status);
end;

end;

procedure GetJobs(PrinterName: String;
JobList: TStrings);
const
InfoLevel = 1;
FirstJob = 0;
LastJob = 19;
var
Jobs: array [FirstJob..LastJob] of TJobInfo1;
PrinterHandle, BytesNeeded, I, NumJobs: Integer;
begin

if OpenPrinter(PChar(PrinterName),PrinterHandle,nil) then
begin

if
EnumJobs(PrinterHandle,FirstJob,LastJob+1,InfoLevel,@Jobs,SizeOf(Jobs),BytesNeed
ed,NumJobs) then
begin

JobList.Clear;
for I := 0 to NumJobs-1do

with Jobsdo

JobList.Add(Format('%s
(%s)',[StrPas(pDocument),PrinterStatusText(Status)]));
end;

ClosePrinter(PrinterHandle);
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin

GetJobs('HP Laserjet 4P',Memo1.Lines);
end;
 
win 2000 xiabian
 
没有高手回答么?
 
页数就是不太准确的,我写的程序也是如此。
不过,90%得到的数据是正确的。老兄呢?
 
会不会与空页有关
 
后退
顶部