From: Pankaj on
hi all,

I am trying to monitor the printer queue by using the Win32 Apis
FindFirstPrinterChangeNotification and
FindNextPrinterChangeNotification.
But, I am not getting two information....one is the no. of pages
printed and the job completion indication.
For the first one I am setting the JOB_NOTIFY_FIELD_PAGES_PRINTED and
for the second one JOB_NOTIFY_FIELD_STATUS is being used, in the
required member of the PRINTER_NOTIFY_OPTIONS_TYPE structure.

In the case of no. of pages printed, i get correct values, if the
document is more than 1 page, but always get 0 when the document is
having a single page. why is this so?
And as regard the second thing the JOB_STATUS_PRINTED is never
received. My code is as below:


void StartNotifications(void)
{
HANDLE hPrinter = NULL;
PRINTER_NOTIFY_OPTIONS * p_NotifyOptions = NULL;
PRINTER_NOTIFY_OPTIONS_TYPE arr_NotifyOptionsType[2];
PWORD pJobFields, pPrinterFields;
HANDLE hwndNotify = NULL;
DWORD dwChanged = 0;

PRINTER_NOTIFY_INFO * p_OutPut = NULL;

if(OpenPrinter(_T("\\\\NECHCLSTDC\\HP LaserJet 4345 mfp PCL 5e"),
&hPrinter, NULL))
{
pJobFields = (PWORD)malloc(5 * sizeof(WORD));
pJobFields[0] = JOB_NOTIFY_FIELD_USER_NAME;
pJobFields[1] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
pJobFields[2] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
pJobFields[3] = JOB_NOTIFY_FIELD_STATUS;
pJobFields[4] = JOB_NOTIFY_FIELD_STATUS_STRING;

arr_NotifyOptionsType[0].Type = JOB_NOTIFY_TYPE ;
arr_NotifyOptionsType[0].pFields = pJobFields;
arr_NotifyOptionsType[0].Count = 5;

pPrinterFields = (PWORD)malloc(2 * sizeof(WORD));
pPrinterFields[0] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
pPrinterFields[1] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;

arr_NotifyOptionsType[1].Type = PRINTER_NOTIFY_TYPE ;
arr_NotifyOptionsType[1].pFields = pPrinterFields;
arr_NotifyOptionsType[1].Count = 2;



p_NotifyOptions = new PRINTER_NOTIFY_OPTIONS;

p_NotifyOptions->Count = 2;
p_NotifyOptions->Version = 2;
p_NotifyOptions->pTypes = arr_NotifyOptionsType;
p_NotifyOptions->Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;

if((hwndNotify = FindFirstPrinterChangeNotification(hPrinter, 0, 0,
p_NotifyOptions)) != INVALID_HANDLE_VALUE)
{
while(hwndNotify != INVALID_HANDLE_VALUE)
{
if(WaitForSingleObject(hwndNotify, 0) == WAIT_OBJECT_0)
{

FindNextPrinterChangeNotification(hwndNotify, &dwChanged,
(LPVOID)p_NotifyOptions, (LPVOID*)&p_OutPut);
for (int i=0;i<p_OutPut->Count;i++)
{
if(p_OutPut->aData[i].Type == JOB_NOTIFY_TYPE)
{
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_USER_NAME)
{
MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
,_T("Status"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED)
{
TCHAR buff[25];
_stprintf(buff,_T("PP = %d Job ID
%ld"),p_OutPut->aData[i].NotifyData.adwData[0], p_OutPut->aData[i].Id);

MessageBox(NULL,buff ,_T("Status"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS)
{
if(p_OutPut->aData[i].NotifyData.adwData[0] & JOB_STATUS_PRINTED)
MessageBox(NULL,_T("Job Done") ,_T("Status"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS_STRING)
{
MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
,_T("Status"),MB_OK);
}
}
}
}
}
}
else
{
DWORD dwError = GetLastError();
dwError += 0;
}
}
else
{
DWORD dwError = GetLastError();
dwError += 0;
}
}



It will be great if some one help me out with this...

Thanks
Pankaj

From: Pankaj on
hi all....

can some one help me out with the problem stated below.

Thanks
Pankaj
Pankaj wrote:
> hi all,
>
> I am trying to monitor the printer queue by using the Win32 Apis
> FindFirstPrinterChangeNotification and
> FindNextPrinterChangeNotification.
> But, I am not getting two information....one is the no. of pages
> printed and the job completion indication.
> For the first one I am setting the JOB_NOTIFY_FIELD_PAGES_PRINTED and
> for the second one JOB_NOTIFY_FIELD_STATUS is being used, in the
> required member of the PRINTER_NOTIFY_OPTIONS_TYPE structure.
>
> In the case of no. of pages printed, i get correct values, if the
> document is more than 1 page, but always get 0 when the document is
> having a single page. why is this so?
> And as regard the second thing the JOB_STATUS_PRINTED is never
> received. My code is as below:
>
>
> void StartNotifications(void)
> {
> HANDLE hPrinter = NULL;
> PRINTER_NOTIFY_OPTIONS * p_NotifyOptions = NULL;
> PRINTER_NOTIFY_OPTIONS_TYPE arr_NotifyOptionsType[2];
> PWORD pJobFields, pPrinterFields;
> HANDLE hwndNotify = NULL;
> DWORD dwChanged = 0;
>
> PRINTER_NOTIFY_INFO * p_OutPut = NULL;
>
> if(OpenPrinter(_T("\\\\NECHCLSTDC\\HP LaserJet 4345 mfp PCL 5e"),
> &hPrinter, NULL))
> {
> pJobFields = (PWORD)malloc(5 * sizeof(WORD));
> pJobFields[0] = JOB_NOTIFY_FIELD_USER_NAME;
> pJobFields[1] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
> pJobFields[2] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
> pJobFields[3] = JOB_NOTIFY_FIELD_STATUS;
> pJobFields[4] = JOB_NOTIFY_FIELD_STATUS_STRING;
>
> arr_NotifyOptionsType[0].Type = JOB_NOTIFY_TYPE ;
> arr_NotifyOptionsType[0].pFields = pJobFields;
> arr_NotifyOptionsType[0].Count = 5;
>
> pPrinterFields = (PWORD)malloc(2 * sizeof(WORD));
> pPrinterFields[0] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
> pPrinterFields[1] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
>
> arr_NotifyOptionsType[1].Type = PRINTER_NOTIFY_TYPE ;
> arr_NotifyOptionsType[1].pFields = pPrinterFields;
> arr_NotifyOptionsType[1].Count = 2;
>
>
>
> p_NotifyOptions = new PRINTER_NOTIFY_OPTIONS;
>
> p_NotifyOptions->Count = 2;
> p_NotifyOptions->Version = 2;
> p_NotifyOptions->pTypes = arr_NotifyOptionsType;
> p_NotifyOptions->Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
>
> if((hwndNotify = FindFirstPrinterChangeNotification(hPrinter, 0, 0,
> p_NotifyOptions)) != INVALID_HANDLE_VALUE)
> {
> while(hwndNotify != INVALID_HANDLE_VALUE)
> {
> if(WaitForSingleObject(hwndNotify, 0) == WAIT_OBJECT_0)
> {
>
> FindNextPrinterChangeNotification(hwndNotify, &dwChanged,
> (LPVOID)p_NotifyOptions, (LPVOID*)&p_OutPut);
> for (int i=0;i<p_OutPut->Count;i++)
> {
> if(p_OutPut->aData[i].Type == JOB_NOTIFY_TYPE)
> {
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_USER_NAME)
> {
> MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED)
> {
> TCHAR buff[25];
> _stprintf(buff,_T("PP = %d Job ID
> %ld"),p_OutPut->aData[i].NotifyData.adwData[0], p_OutPut->aData[i].Id);
>
> MessageBox(NULL,buff ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS)
> {
> if(p_OutPut->aData[i].NotifyData.adwData[0] & JOB_STATUS_PRINTED)
> MessageBox(NULL,_T("Job Done") ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS_STRING)
> {
> MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> ,_T("Status"),MB_OK);
> }
> }
> }
> }
> }
> }
> else
> {
> DWORD dwError = GetLastError();
> dwError += 0;
> }
> }
> else
> {
> DWORD dwError = GetLastError();
> dwError += 0;
> }
> }
>
>
>
> It will be great if some one help me out with this...
>
> Thanks
> Pankaj

From: Sten Westerback (MVP SDK) on
"Pankaj" <pnkjadlakha(a)gmail.com> wrote in message
news:1165236408.717688.83540(a)16g2000cwy.googlegroups.com...
> hi all,
>
> I am trying to monitor the printer queue by using the Win32 Apis
> FindFirstPrinterChangeNotification and
> FindNextPrinterChangeNotification.
> But, I am not getting two information....one is the no. of pages
> printed and the job completion indication.
> For the first one I am setting the JOB_NOTIFY_FIELD_PAGES_PRINTED and
> for the second one JOB_NOTIFY_FIELD_STATUS is being used, in the
> required member of the PRINTER_NOTIFY_OPTIONS_TYPE structure.
>
> In the case of no. of pages printed, i get correct values, if the
> document is more than 1 page, but always get 0 when the document is
> having a single page. why is this so?
> And as regard the second thing the JOB_STATUS_PRINTED is never
> received. My code is as below:
>
>
> void StartNotifications(void)
> {
> HANDLE hPrinter = NULL;
> PRINTER_NOTIFY_OPTIONS * p_NotifyOptions = NULL;
> PRINTER_NOTIFY_OPTIONS_TYPE arr_NotifyOptionsType[2];
> PWORD pJobFields, pPrinterFields;
> HANDLE hwndNotify = NULL;
> DWORD dwChanged = 0;
>
> PRINTER_NOTIFY_INFO * p_OutPut = NULL;
>
> if(OpenPrinter(_T("\\\\NECHCLSTDC\\HP LaserJet 4345 mfp PCL 5e"),
> &hPrinter, NULL))
> {
> pJobFields = (PWORD)malloc(5 * sizeof(WORD));
> pJobFields[0] = JOB_NOTIFY_FIELD_USER_NAME;
> pJobFields[1] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
> pJobFields[2] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
> pJobFields[3] = JOB_NOTIFY_FIELD_STATUS;
> pJobFields[4] = JOB_NOTIFY_FIELD_STATUS_STRING;
>
> arr_NotifyOptionsType[0].Type = JOB_NOTIFY_TYPE ;
> arr_NotifyOptionsType[0].pFields = pJobFields;
> arr_NotifyOptionsType[0].Count = 5;
>
> pPrinterFields = (PWORD)malloc(2 * sizeof(WORD));
> pPrinterFields[0] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
> pPrinterFields[1] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
>
> arr_NotifyOptionsType[1].Type = PRINTER_NOTIFY_TYPE ;
> arr_NotifyOptionsType[1].pFields = pPrinterFields;
> arr_NotifyOptionsType[1].Count = 2;
>
>
>
> p_NotifyOptions = new PRINTER_NOTIFY_OPTIONS;
>
> p_NotifyOptions->Count = 2;
> p_NotifyOptions->Version = 2;
> p_NotifyOptions->pTypes = arr_NotifyOptionsType;
> p_NotifyOptions->Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
>
> if((hwndNotify = FindFirstPrinterChangeNotification(hPrinter, 0, 0,
> p_NotifyOptions)) != INVALID_HANDLE_VALUE)
> {
> while(hwndNotify != INVALID_HANDLE_VALUE)
> {
> if(WaitForSingleObject(hwndNotify, 0) == WAIT_OBJECT_0)
> {
>
> FindNextPrinterChangeNotification(hwndNotify, &dwChanged,
> (LPVOID)p_NotifyOptions, (LPVOID*)&p_OutPut);
> for (int i=0;i<p_OutPut->Count;i++)
> {
> if(p_OutPut->aData[i].Type == JOB_NOTIFY_TYPE)
> {
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_USER_NAME)
> {
> MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED)
> {
> TCHAR buff[25];
> _stprintf(buff,_T("PP = %d Job ID
> %ld"),p_OutPut->aData[i].NotifyData.adwData[0], p_OutPut->aData[i].Id);
>
> MessageBox(NULL,buff ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS)
> {
> if(p_OutPut->aData[i].NotifyData.adwData[0] & JOB_STATUS_PRINTED)
> MessageBox(NULL,_T("Job Done") ,_T("Status"),MB_OK);
> }
> if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS_STRING)
> {
> MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> ,_T("Status"),MB_OK);
> }
> }
> }
> }
> }
> }
> else
> {
> DWORD dwError = GetLastError();
> dwError += 0;
> }
> }
> else
> {
> DWORD dwError = GetLastError();
> dwError += 0;
> }
> }


A quick look trought it doesn't reveal any real problems. But i can imagine
that your busy loop, due to WaitFor... (0), can cause a slow computer to
miss some notifications.
You should also not call a HANDLE hwndSomething - just hSomething will do.
A print job with "always 0 pages" sounds easy enough to handle to me - just
replace 0 with 1. :)
I'll look into it in more detail with more time.
If you are in a hurry i suggest a good way to fix problems -- record the
whole routine.

- Sten


From: Pankaj on
Thanks Sten, for your reply...

I modified the code as below:


void StartNotifications(void)
{
HANDLE hPrinter = NULL;
PRINTER_NOTIFY_OPTIONS * p_NotifyOptions = NULL;
PRINTER_NOTIFY_OPTIONS_TYPE arr_NotifyOptionsType[2];
PWORD pPrinterFields;
WORD arrJobFields[100];
HANDLE hwndNotify = NULL;
DWORD dwChanged = 0;
int i;
FILE * pFile;
TCHAR * pBuf;
DWORD * adwData;
TCHAR arrBuf[50];
pFile = _tfopen(_T("C:\\PrinterNotifications.txt"), _T("a+"));
if(pFile)
{
MessageBox(NULL, _T("Opened"), _T("File Status"), MB_OK);
}

PRINTER_NOTIFY_INFO * p_OutPut = NULL;

if(OpenPrinter(_T("\\\\NECHCLSTDC\\HP LaserJet 4345 mfp PCL 5e"),
&hPrinter, NULL))
{
i=0;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PRINTER_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_MACHINE_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PORT_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_USER_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_NOTIFY_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_DATATYPE;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PRINT_PROCESSOR;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PARAMETERS;
arrJobFields[i++] = JOB_NOTIFY_FIELD_DRIVER_NAME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_STATUS_STRING;
arrJobFields[i++] = JOB_NOTIFY_FIELD_DOCUMENT;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PRIORITY;
arrJobFields[i++] = JOB_NOTIFY_FIELD_POSITION;
arrJobFields[i++] = JOB_NOTIFY_FIELD_START_TIME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_UNTIL_TIME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_TIME;
arrJobFields[i++] = JOB_NOTIFY_FIELD_TOTAL_PAGES;
arrJobFields[i++] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
arrJobFields[i++] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
arrJobFields[i++] = JOB_NOTIFY_FIELD_BYTES_PRINTED;


arr_NotifyOptionsType[0].Type = JOB_NOTIFY_TYPE ;
arr_NotifyOptionsType[0].pFields = arrJobFields;
arr_NotifyOptionsType[0].Count = 20;

pPrinterFields = (PWORD)malloc(2 * sizeof(WORD));
pPrinterFields[0] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
pPrinterFields[1] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;

arr_NotifyOptionsType[1].Type = PRINTER_NOTIFY_TYPE ;
arr_NotifyOptionsType[1].pFields = pPrinterFields;
arr_NotifyOptionsType[1].Count = 2;



p_NotifyOptions = new PRINTER_NOTIFY_OPTIONS;

p_NotifyOptions->Count = 2;
p_NotifyOptions->Version = 2;
p_NotifyOptions->pTypes = arr_NotifyOptionsType;
p_NotifyOptions->Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;

if((hwndNotify = FindFirstPrinterChangeNotification(hPrinter,
PRINTER_CHANGE_ALL, 0, p_NotifyOptions)) != INVALID_HANDLE_VALUE)
{
while(hwndNotify != INVALID_HANDLE_VALUE)
{
if(WaitForSingleObject(hwndNotify, INFINITE) == WAIT_OBJECT_0)
{

FindNextPrinterChangeNotification(hwndNotify, &dwChanged,
(LPVOID)p_NotifyOptions, (LPVOID*)&p_OutPut);
for (int i=0;(i<p_OutPut->Count) && ;i++)
{
pBuf = (TCHAR*)(p_OutPut->aData[i].NotifyData.Data.pBuf);
adwData = p_OutPut->aData[i].NotifyData.adwData;
switch(p_OutPut->aData[i].Type)
{
case JOB_NOTIFY_TYPE:
{
//printf("\tジョブ通知(no.%d, id:%d)...", i,
p_OutPut->aData[i].Id);
switch(p_OutPut->aData[i].Field)
{
case JOB_NOTIFY_FIELD_PRINTER_NAME:
_fputts(_T("Printer Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_MACHINE_NAME:
_fputts(_T("machine Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_PORT_NAME:
_fputts(_T("Port Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_USER_NAME:
_fputts(_T("User Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_NOTIFY_NAME:
_fputts(_T("Notify Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_DATATYPE:
_fputts(_T("Data Type "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_PRINT_PROCESSOR:
_fputts(_T("Print Processor "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_PARAMETERS:
_fputts(_T("Parameters"), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_DRIVER_NAME:
_fputts(_T("Driver Name "), pFile);
_fputts(pBuf, pFile);
_fputtc(_T('\n'), pFile);
break;
case JOB_NOTIFY_FIELD_DEVMODE:
// DEVMODE
break;
case JOB_NOTIFY_FIELD_STATUS:
//printf("ジョブの状態(flag):");
if(adwData[0] & JOB_STATUS_PAUSED)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Paused"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_ERROR)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Error"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_DELETING)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Deleting"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_SPOOLING)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Spooling"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_PRINTING)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Printing"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_OFFLINE)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Offline"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_PAPEROUT)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("PaperOut"), pFile);
_fputtc(_T('\n'), pFile);
}

if(adwData[0] & JOB_STATUS_PRINTED)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Printed"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_DELETED)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Deleted"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_BLOCKED_DEVQ)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Blocked DevQ"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_USER_INTERVENTION)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("User Intervention"), pFile);
_fputtc(_T('\n'), pFile);
}
if(adwData[0] & JOB_STATUS_RESTART)
{
_fputts(_T("Status = "), pFile);
_fputts( _T("Restart"), pFile);
_fputtc(_T('\n'), pFile);
}
break;
case JOB_NOTIFY_FIELD_STATUS_STRING:
{
_fputts(_T("Status String= "), pFile);
_fputts( pBuf, pFile);
_fputtc(_T('\n'), pFile);
}
break;
case JOB_NOTIFY_FIELD_DOCUMENT:
{
_fputts(_T("Document = "), pFile);
_fputts( pBuf, pFile);
_fputtc(_T('\n'), pFile);
}
break;
/*case JOB_NOTIFY_FIELD_PRIORITY:
printf("優先度:%d\n", adwData[0]);
break;
case JOB_NOTIFY_FIELD_POSITION:
printf("順番:%d\n", adwData[0]);
break;*/
case JOB_NOTIFY_FIELD_SUBMITTED:
//SYSTEMTIME
break;
case JOB_NOTIFY_FIELD_START_TIME:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Start Time: %d:%d\n"), adwData[0]/60,
adwData[0]%60);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_UNTIL_TIME:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Until Time: %d:%d\n"), adwData[0]/60,
adwData[0]%60);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_TIME:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Field Time: %d: %d\n"), adwData[0]/60,
adwData[0]%60);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_TOTAL_PAGES:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Total Pages: %d\n"), adwData[0]);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_PAGES_PRINTED:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Pages Printed: %d\n"), adwData[0]);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_TOTAL_BYTES:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Total Bytes: %d\n"), adwData[0]);
_fputts(arrBuf, pFile);
break;
case JOB_NOTIFY_FIELD_BYTES_PRINTED:
memset(arrBuf, _T('\0'), 50);
_stprintf(arrBuf,_T("Bytes Printed: %d\n"), adwData[0]);
_fputts(arrBuf, pFile);
break;
}
break;
}
case PRINTER_NOTIFY_TYPE:
{
}
break;
}
/*if(p_OutPut->aData[i].Type == JOB_NOTIFY_TYPE)
{
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_USER_NAME)
{
MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
,_T("User Name"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED)
{
TCHAR buff[25];
_stprintf(buff,_T("PP = %d Job ID
%ld"),p_OutPut->aData[i].NotifyData.adwData[0], p_OutPut->aData[i].Id);

MessageBox(NULL,buff ,_T("Pages Printed"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS)
{
if(p_OutPut->aData[i].NotifyData.adwData[0] &
JOB_STATUS_PRINTED)
MessageBox(NULL,_T("Job Done") ,_T("Status"),MB_OK);
if(p_OutPut->aData[i].NotifyData.adwData[0] &
JOB_STATUS_PRINTING)
MessageBox(NULL,_T("Printing Started") ,_T("Status"),MB_OK);
}
if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS_STRING)
{
MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
,_T("Status"),MB_OK);
}
}*/
}
}
}
}
else
{
DWORD dwError = GetLastError();
dwError += 0;
}
}
else
{
DWORD dwError = GetLastError();
dwError += 0;
}
}



I dumped the notification data in a file, and had the following
observations:

1. I never received any Status notification for any type of Print job,
i.e be it in EMF format or RAW format. In case of Status String, the
notification was there, but the pBuf was empty.

2. In case of print job with EMF data type, the Total Pages and Printed
pages data was received correctly. Same case for Total Byres and
Printed Bytes.

3. In case of print job with RAW format, Total pages was received with
correct values, but Printed Pages was always recieved with the value 0.
Total Bytes was OK, but at the end of the print job, the Total Bytes
and Printed Bytes were different, the latter being lesser then former.
So, it doesn't help in determining that whether a print job is finished
or not.




Sten Westerback (MVP SDK) wrote:
> "Pankaj" <pnkjadlakha(a)gmail.com> wrote in message
> news:1165236408.717688.83540(a)16g2000cwy.googlegroups.com...
> > hi all,
> >
> > I am trying to monitor the printer queue by using the Win32 Apis
> > FindFirstPrinterChangeNotification and
> > FindNextPrinterChangeNotification.
> > But, I am not getting two information....one is the no. of pages
> > printed and the job completion indication.
> > For the first one I am setting the JOB_NOTIFY_FIELD_PAGES_PRINTED and
> > for the second one JOB_NOTIFY_FIELD_STATUS is being used, in the
> > required member of the PRINTER_NOTIFY_OPTIONS_TYPE structure.
> >
> > In the case of no. of pages printed, i get correct values, if the
> > document is more than 1 page, but always get 0 when the document is
> > having a single page. why is this so?
> > And as regard the second thing the JOB_STATUS_PRINTED is never
> > received. My code is as below:
> >
> >
> > void StartNotifications(void)
> > {
> > HANDLE hPrinter = NULL;
> > PRINTER_NOTIFY_OPTIONS * p_NotifyOptions = NULL;
> > PRINTER_NOTIFY_OPTIONS_TYPE arr_NotifyOptionsType[2];
> > PWORD pJobFields, pPrinterFields;
> > HANDLE hwndNotify = NULL;
> > DWORD dwChanged = 0;
> >
> > PRINTER_NOTIFY_INFO * p_OutPut = NULL;
> >
> > if(OpenPrinter(_T("\\\\NECHCLSTDC\\HP LaserJet 4345 mfp PCL 5e"),
> > &hPrinter, NULL))
> > {
> > pJobFields = (PWORD)malloc(5 * sizeof(WORD));
> > pJobFields[0] = JOB_NOTIFY_FIELD_USER_NAME;
> > pJobFields[1] = JOB_NOTIFY_FIELD_PAGES_PRINTED;
> > pJobFields[2] = JOB_NOTIFY_FIELD_TOTAL_BYTES;
> > pJobFields[3] = JOB_NOTIFY_FIELD_STATUS;
> > pJobFields[4] = JOB_NOTIFY_FIELD_STATUS_STRING;
> >
> > arr_NotifyOptionsType[0].Type = JOB_NOTIFY_TYPE ;
> > arr_NotifyOptionsType[0].pFields = pJobFields;
> > arr_NotifyOptionsType[0].Count = 5;
> >
> > pPrinterFields = (PWORD)malloc(2 * sizeof(WORD));
> > pPrinterFields[0] = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
> > pPrinterFields[1] = PRINTER_NOTIFY_FIELD_AVERAGE_PPM;
> >
> > arr_NotifyOptionsType[1].Type = PRINTER_NOTIFY_TYPE ;
> > arr_NotifyOptionsType[1].pFields = pPrinterFields;
> > arr_NotifyOptionsType[1].Count = 2;
> >
> >
> >
> > p_NotifyOptions = new PRINTER_NOTIFY_OPTIONS;
> >
> > p_NotifyOptions->Count = 2;
> > p_NotifyOptions->Version = 2;
> > p_NotifyOptions->pTypes = arr_NotifyOptionsType;
> > p_NotifyOptions->Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
> >
> > if((hwndNotify = FindFirstPrinterChangeNotification(hPrinter, 0, 0,
> > p_NotifyOptions)) != INVALID_HANDLE_VALUE)
> > {
> > while(hwndNotify != INVALID_HANDLE_VALUE)
> > {
> > if(WaitForSingleObject(hwndNotify, 0) == WAIT_OBJECT_0)
> > {
> >
> > FindNextPrinterChangeNotification(hwndNotify, &dwChanged,
> > (LPVOID)p_NotifyOptions, (LPVOID*)&p_OutPut);
> > for (int i=0;i<p_OutPut->Count;i++)
> > {
> > if(p_OutPut->aData[i].Type == JOB_NOTIFY_TYPE)
> > {
> > if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_USER_NAME)
> > {
> > MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> > ,_T("Status"),MB_OK);
> > }
> > if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED)
> > {
> > TCHAR buff[25];
> > _stprintf(buff,_T("PP = %d Job ID
> > %ld"),p_OutPut->aData[i].NotifyData.adwData[0], p_OutPut->aData[i].Id);
> >
> > MessageBox(NULL,buff ,_T("Status"),MB_OK);
> > }
> > if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS)
> > {
> > if(p_OutPut->aData[i].NotifyData.adwData[0] & JOB_STATUS_PRINTED)
> > MessageBox(NULL,_T("Job Done") ,_T("Status"),MB_OK);
> > }
> > if(p_OutPut->aData[i].Field == JOB_NOTIFY_FIELD_STATUS_STRING)
> > {
> > MessageBox(NULL,(LPTSTR)(p_OutPut->aData[i].NotifyData.Data.pBuf)
> > ,_T("Status"),MB_OK);
> > }
> > }
> > }
> > }
> > }
> > }
> > else
> > {
> > DWORD dwError = GetLastError();
> > dwError += 0;
> > }
> > }
> > else
> > {
> > DWORD dwError = GetLastError();
> > dwError += 0;
> > }
> > }
>
>
> A quick look trought it doesn't reveal any real problems. But i can imagine
> that your busy loop, due to WaitFor... (0), can cause a slow computer to
> miss some notifications.
> You should also not call a HANDLE hwndSomething - just hSomething will do.
> A print job with "always 0 pages" sounds easy enough to handle to me - just
> replace 0 with 1. :)
> I'll look into it in more detail with more time.
> If you are in a hurry i suggest a good way to fix problems -- record the
> whole routine.
>
> - Sten