如何使用sdk函数 得知打印机中的一个任务已经完成 (打印机设置为不记录已打印完作业)
请高人帮忙 问题点数:50、回复次数:9Top
1 楼whxhqq(^_^)回复于 2005-08-01 18:17:44 得分 0
没人会吗???高人来啊 !!!!!Top
2 楼bobob(静思)回复于 2005-08-01 19:12:33 得分 0
BOOL IsPrinterPrinted(HANDLE hPrinter)
{
JOB_INFO_2 *pJobs;
int cJobs, i;
DWORD dwPrinterStatus;
if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
return FALSE;
for (i=0; i < cJobs; i++)
{//在这里是枚举了所有jobid,特定的job
if (pJobs[i].Status & (JOB_STATUS_PRINTED))
{
return TRUE;
}
}
return FALSE;
}
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 information. */
if (!GetPrinter(hPrinter,
2,
(unsigned char *)(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 = nReturned;
*pStatus = pPrinterInfo->Status;
*ppJobInfo = pJobStorage;
free(pPrinterInfo);
return TRUE;
}Top
3 楼bobob(静思)回复于 2005-08-01 19:13:48 得分 0
不好意思,注释还没有写完
特定的job应该能拿到吧?Top
4 楼whxhqq(^_^)回复于 2005-08-01 19:57:59 得分 0
bobob(静思--潜心研究PDF) 你好 谢谢你给我回复 ,但是我说的问题没有那么简单,我在问题中注明打印机设置成不保存已完成的任务,也就是说,已经打印完的作业的信息是取不到的,所以使用enumjobs函数得到的作业中并没有printed状态的作业.如果可能,请你帮我再想一下,谢谢啦!
我有一种方法,是设置一个timer,隔断时间取一次打印队列的信息,然后比较两次采样的第一个作业,如果两个作业不同,表明之前采样时的作业已经完成,但是这种方法有缺陷,如果用户可以把打印机状态设置为暂停,再把第一个作业取消,我就无法判断它究竟是打印完了,还是被用户取消了.Top
5 楼whxhqq(^_^)回复于 2005-08-01 20:42:45 得分 0
up 希望有高人帮我解决 ,着急啊!!!工作任务Top
6 楼whxhqq(^_^)回复于 2005-08-01 21:38:37 得分 0
高人 帮忙啊Top
7 楼bobob(静思)回复于 2005-08-02 08:54:16 得分 0
不好意思,昨天早早就回去了,今天继续
其实enumjobs这个函数本身就是列举打印列表里面的任务,打印完的是拿不到的
至于是否取消或暂停,状态都可以拿到,看看winspool.h中的如下定义:
#define JOB_STATUS_PAUSED 0x00000001
#define JOB_STATUS_ERROR 0x00000002
#define JOB_STATUS_DELETING 0x00000004
#define JOB_STATUS_SPOOLING 0x00000008
#define JOB_STATUS_PRINTING 0x00000010
#define JOB_STATUS_OFFLINE 0x00000020
#define JOB_STATUS_PAPEROUT 0x00000040
#define JOB_STATUS_PRINTED 0x00000080
#define JOB_STATUS_DELETED 0x00000100
#define JOB_STATUS_BLOCKED_DEVQ 0x00000200
#define JOB_STATUS_USER_INTERVENTION 0x00000400
#define JOB_STATUS_RESTART 0x00000800
既然你可以比较两次采样时的第一个作业,那你为什么不能比较所有的呢?Top
8 楼whxhqq(^_^)回复于 2005-08-02 10:47:17 得分 0
bobob 你好 我之前的程序试过,如果一个作业被取消,那么它的信息也就没有了,也就是说使用enumjobs获取的作业中没有JOB_STATUS_DELETED状态的,对于JOB_STATUS_DELETING 这个状态的作业,删除的时间太短,估计也没法取到,我觉得可能这种方法就不能很好的实现我所要的功能,还有一种方法, FindFirstPrinterChangeNotification 检测打印机的状态变化 ,你有研究吗??? PRINTER_CHANGE_WRITE_JOB 这个事件究竟怎样才会被触发,msdn中说的不太清楚,不知你是否知道 ,还请多多帮忙啊 !!!Top
9 楼whxhqq(^_^)回复于 2005-08-02 15:41:36 得分 0
up一下Top




