打印任务的检测(200分)

  • 主题发起人 主题发起人 yth
  • 开始时间 开始时间
Y

yth

Unregistered / Unconfirmed
GUEST, unregistred user!
如何编程检测打印任务完成情况,在打印任务完成后通知我的程序进行处理,
如发提示音等,查MSDN得知可编打印机监视程序(估计类似剪贴板监视:】),
可惜E文欠佳,看得云里雾里,那位高手帮帮忙,希望有较详细的例子。
 
怎么无人回答,估计问题太偏,网上这方面资料极少,没有查到有此功能的软件,
不过MSDN中有这方面的介绍,应该能编出来,呼唤高手。
 
有回答吗?没有明天分分,会来抢分。前20位
 
MSDN中有一篇“How To Get the Status of a Printer and a Print Job ”文章有例程,其作用是得到当前打印任务队列以及任务状态,你只要循环检测测队列中的各任务,然后判断(pJobStorage.Status == JOB_STATUS_PRINTED)是否打印完成,接下来就处理自己的事情就是了。注意怎样使用API函数EnumJobs得到JOB_INFO_2结构以及怎样使用API函数GetPrinter得到PRINTER_INFO_2结构。
以下是MSDN例程:
BOOL GetJobs(HANDLE hPrinter, /* handle to the printer */
JOB_INFO_2 **ppJobInfo, /* pointer to be filled */
int *pcJobs, /* count of jobs filled */
DWORD *pStatus) /* print Queue status */
{
DWORD cByteNeeded,
nReturned,
cByteUsed;
JOB_INFO_2 *pJobStorage = NULL;
PRINTER_INFO_2 *pPrinterInfo = NULL;
/* Get the buffer size needed */
if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return FALSE;
}
pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
if (!(pPrinterInfo))
/* failure to allocate memory */
return FALSE;
/* get the printer info */
if (!GetPrinter(hPrinter,
2,
(LPSTR)pPrinterInfo,
cByteNeeded,
&cByteUsed))
{
/* failure to access the printer */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}
/* Get job storage space */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
NULL,
0,
(LPDWORD)&cByteNeeded,
(LPDWORD)&nReturned))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}
}
pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
if (!pJobStorage)
{
/* failure to allocate Job storage space */
free(pPrinterInfo);
pPrinterInfo = NULL;
return FALSE;
}
ZeroMemory(pJobStorage, cByteNeeded);
/* get the list of jobs */
if (!EnumJobs(hPrinter,
0,
pPrinterInfo->cJobs,
2,
(LPBYTE)pJobStorage,
cByteNeeded,
(LPDWORD)&cByteUsed,
(LPDWORD)&nReturned))
{
free(pPrinterInfo);
free(pJobStorage);
pJobStorage = NULL;
pPrinterInfo = NULL;
return FALSE;
}
/*
* Return the information
*/
*pcJobs = pPrinterInfo->cJobs;
*pStatus = pPrinterInfo->Status;
*ppJobInfo = pJobStorage;
free(pPrinterInfo);
return TRUE;
}

 
查了一下,应该用 OpenPrinter,FindFirstPrinterChangeNotification,
WaitForSingleObject,FindNextPrinterChangeNotification 和
ClosePrinterChangeNotification 这几个函数。
 
procedure Tform1.GetJobs(PrinterName: String);
const
InfoLevel = 1;
FirstJob = 0;
LastJob = 19;
var
//Jobs: array [FirstJob..LastJob] of TJobInfo1;
//PrinterHandle:Cardinal;
BytesNeeded, NumJobs: Cardinal;
I:integer;
jobid:Cardinal;
cur_row:integer;
rows:olevariant;
begin
if OpenPrinter(PChar(PrinterName),PrinterHandle,nil) then
begin
if EnumJobs(PrinterHandle,FirstJob,LastJob+1,InfoLevel,@Jobs,SizeOf(Jobs),BytesNeeded,NumJobs) then
begin
if NumJobs>0 then
begin
rows:=VarArrayCreate([0,10, 0, 0], varVariant);
for I := 0 to NumJobs-1do
begin
with Jobsdo
begin
cur_row:=VarArrayHighBound(rows, 2);
rows[0, cur_row]:=JobId;
rows[1, cur_row]:=StrPas(pPrinterName);
rows[2, cur_row]:=StrPas(pMachineName);
rows[3, cur_row]:=StrPas(pUserName);
rows[4, cur_row]:=StrPas(pDatatype);
rows[5, cur_row]:=StrPas(pDocument);
rows[6, cur_row]:=StrPas(pStatus);
rows[7, cur_row]:=Priority;
rows[8, cur_row]:=Position;
rows[9, cur_row]:=TotalPages;
rows[10, cur_row]:=PagesPrinted;
end;
VarArrayRedim(rows, cur_row + 1);
setJob(DevM,Jobid,0,@Jobs,JOB_CONTROL_PAUSE);
end;
lv.Items.Clear;
ListViewAddRows(rows,lv);
//ClosePrinter(PrinterHandle);
end;
end;
end;

end;
 
多人接受答案了。
 
后退
顶部