Solved

Printer WaitForSingleObject problems

Posted on 1997-04-11
11
661 Views
Last Modified: 2013-12-03
The code below is SUPPOSED to wait until the print spooler has a job submitted to it. Unfortunately, it always returns IMMEDIATELY from the WaitForSingleObject without waiting for a job! All above this point doesn't error (have stripped out error checking!
/////////////////////////////////////////////////
DWORD needed, returned;
HANDLE printer = 0;
BOOL didit;
PRINTER_INFO_1 printers[255];
PRINTER_DEFAULTS pdefaults;
DWORD event;
HANDLE changenotify;

EnumPrinters((DWORD)PRINTER_ENUM_NAME,(LPTSTR)"Windows 95 Local Print Provider",
            (DWORD)1,(LPBYTE)printers,sizeof(PRINTER_INFO_1)*255,
            &needed,&returned);
pdefaults.pDatatype = NULL;
pdefaults.pDevMode = NULL;
pdefaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
OpenPrinter(printers[0].pName,(LPHANDLE)&printer,(LPPRINTER_DEFAULTS)&pdefaults);
// Now let's see if we can wait for a job!
changenotify = FindFirstPrinterChangeNotification(printer,PRINTER_CHANGE_ALL,0,NULL);
event = WaitForSingleObject(changenotify,INFINITE);
MessageBox("Wait Completed","Wait");
if(event==WAIT_FAILED)
{
      char buff[50];
/////////////////////////////////////////////////////////////////////////////////////
      wsprintf(buff,"failed...%d",GetLastError()); // **HERE IS WHERE IT ALWAYS FAILS!! ** With the informative error code 6!!!
////////////////////////////////////////////////////////////////////////////////////
      MessageBox(buff);
}
else if(event == PRINTER_CHANGE_JOB)
{
      MessageBox("Yippee Printer change job signalled\n","Mwuhahaha");
}
else
{
      sprintf(buff,"Hmmm....wait returned %d",event);
      EditBox->SetText(buff);
}
0
Comment
Question by:nmsltd
  • 7
  • 3
11 Comments
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334542
What is error code (returned by GetLastError) printed in follow statement?

if(event==WAIT_FAILED) { wsprintf(buff,"failed...%d",GetLastError());
0
 

Author Comment

by:nmsltd
ID: 1334543
Edited text of question
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334544
Error code 6 mean 'Invalid handle'
Did you check changenotyfy variable after calling FindFirstPrinterChangeNotification() to make sure it is not equal INVALID_HANDLE_VALUE? If so, invoke GetLastError() immediately after this call and check error code.

Also, is OpenPrinter() return TRUE?
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334545
I'm not sure you can set these values to NULL:
  pdefaults.pDatatype = NULL;
  pdefaults.pDevMode = NULL;

May be, better try this:
OpenPrinter(printers[0].pName,(LPHANDLE)&printer,NULL);




0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334546
If it works, please let me know to turn comments into answer.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 2

Expert Comment

by:amartin030297
ID: 1334547
also make sure your linking to the multi-threaded libraries, because by default (msvc 4.x and 5.x) they are single-threaded..

0
 

Author Comment

by:nmsltd
ID: 1334548
In response to above comments:
Yes I do check for INVALID_HANDLE_VALUE (it's ok).
OpenPrinter does indeed return TRUE.

According to the Borland C++ V5 helpdoc on open printer:
".....or obtain a handle to a print server to call WaitForPrinterChange. To do so, it should call OpenPrinter with pPrinterName set to the name of the server and should specify a server access mask value such as SERVER_ALL_ACCESS. The pDatatype and pDevMode members of the PRINTER_DEFAULTS data structure should be set to NULL. The handle returned by such a call may be passed to the ClosePrinter or WaitForPrinterChange function.

So (allegedly) you can set these values to NULL.

I am linking multithreading libraries.

I have tried OpenPrinter(printers[0].pName,(LPHANDLE)&printer,NULL);
Still doesn't work! :(

My only thoughts on the matter reading the above snippet from the helpdoc is that it says "print server". Is there a difference between a printer returned from EnumPrinters and a print server, or a print provider? I have found no real explanation of the terminology in any documentation (oh for a decent book on windows printer programming - are there any???)
Hope this clarifies the problem!
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334549
http://www.microsoft.com/win32dev/guidelns/apidiffs.htm DECLARES:

Printer change notification

Printer change notification print spooler functions are not supported on Windows 95 nor on Windows 95 OSR 2. The following functions are not supported:

FindClosePrinterChangeNotification

FindFirstPrinterChangeNotification

FindNextPrinterChangeNotification

WaitForPrinterChange
0
 
LVL 15

Accepted Solution

by:
NickRepin earned 100 total points
ID: 1334550
You cannot use FindFirstPrinterChange... in Windows95 (see comments above). This function just does nothing and returns 0 (not INVALID_HANDLE_VALUE!!!).

That is output of my little test program (code see below):

*** EnumPrinters() 1 0 Needed:396 Returned: 5
pDesc: HP LaserJet 4P,HP LaserJet 4P,
pName: HP LaserJet 4P
pComment:
*** OpenPrinter() 1 0 Handle:0x005105a8
*** ChangeNotify() 1 78 Handle:0x00000000
*** WaitForSingleObject() 0 6 Handle:ffffffff


//**************************************
// Here is test program
//**************************************

#include <iostream.h>
#include <windows.h>

// Compile as BCC32 -WM <filename>
void main(int argc,char* argv[])
{
   if(argc<2) return;

   BOOL r;
   DWORD needed, returned;
   PRINTER_INFO_1 printers[255];
   cout<<"*** EnumPrinters() ";
   r=EnumPrinters(PRINTER_ENUM_NAME,argv[1],1,LPBYTE(&printers[0]),sizeof(printers),
      &needed,&returned);
   cout<<r<<' '<<GetLastError()<<" Needed:"<<needed<<" Returned: "<<returned<<endl;
   if(!r) return;
   cout<<"pDesc: "<<printers[0].pDescription<<endl<<"pName: "<<printers[0].pName<<endl<<
      "pComment: "<<printers[0].pComment<<endl;

   HANDLE printer = 0;
   PRINTER_DEFAULTS pdefaults;
   pdefaults.pDatatype = NULL;
   pdefaults.pDevMode = NULL;
   pdefaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
   cout<<"*** OpenPrinter() ";
   r=OpenPrinter(printers[0].pName,&printer,&pdefaults);
   cout<<r<<' '<<GetLastError()<<" Handle:"<<hex<<printer<<endl;
   if(!r) return;

   cout<<"*** ChangeNotify() ";
   HANDLE changenotify=FindFirstPrinterChangeNotification(printer,PRINTER_CHANGE_ALL,0,NULL);
   cout<<(changenotify!=INVALID_HANDLE_VALUE)<<' '<<GetLastError()<<" Handle:"<<hex<<
      changenotify<<endl;
   if(changenotify==INVALID_HANDLE_VALUE) return;

   cout<<"*** WaitForSingleObject() ";
   DWORD event=WaitForSingleObject(changenotify,INFINITE);
   cout<<(event!=WAIT_FAILED)<<' '<<GetLastError()<<" Handle:"<<hex<<event<<endl;
   if(event==WAIT_FAILED) return;

   cout<<"Wait success: "<<event<<endl;
}
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334551
FindFirstPrinterChangeNotification() works fine for NT, but not for Windows95!
0
 

Author Comment

by:nmsltd
ID: 1334552
100% Correct! I discovered this myself at 1:30 this afternoon!
Great minds think alike, eh Nick?! Now all I have to figure out is how I'm going to implement FindFirstPrinterChangeNotification on win95 & the project's home and dry :)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now