Link to home
Start Free TrialLog in
Avatar of jstolan
jstolan

asked on

Hooking System Print Messages

I would like to handle all printer error messages myself, rather than letting the Windows Print Manager handle them.  It would be ideal if the method would work with both NT and 95, but it would be acceptable if there was a separate method for both.

In other words, when the system would normally display a message like "Printer out of paper" or "Printer not found", it would instead call my function.  My function would add some extra functionality, and then maybe call the default message handler.

Is there a way to do this without writing a print driver?  Example code wold be appreciated.
ASKER CERTIFIED SOLUTION
Avatar of trestan
trestan
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi, I complied a small console program to get the printer status. You can check online help for the difference between 95 and NT. You need permission to set printer status otherwise the setprinter function will fail. You can put your functions under cases matching different status.

#include <afx.h>
#include <winspool.h>
#include <iostream.h>
void main ()
{
      LPTSTR pPrinterName = "\\\\CBS-NT\\FujitsuGrad";
      HANDLE hPrinter;
      PRINTER_INFO_2 * pPrinterInfo;

      //Get the handle of the specified printer.
      if (!OpenPrinter(pPrinterName, &hPrinter, NULL))
            cout<<"error open printer\n";
      
      //Get the buffer size to store information.
      DWORD nSize, cbNeeded;

      if (!GetPrinter(hPrinter, 2, NULL, 0, &nSize))
      {
            if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            {
                  ClosePrinter(hPrinter);
                  cout<<"getptrinter failed.\n";
                  exit(1);
            }
      }
      
      //Allocate memory.
      pPrinterInfo = (PRINTER_INFO_2 *) GlobalAlloc(GMEM_MOVEABLE |GMEM_ZEROINIT, nSize);
      cout<<"buffer size needed: "<<nSize<<"\n";
      if (!pPrinterInfo)
      {
            cout<<"error allocate bytes from the heap.\n";
            exit(1);
      }

      //Get printer status.
      if (!GetPrinter(hPrinter, 2, (LPBYTE) pPrinterInfo, nSize, &cbNeeded))
      {
            cout<<"error get printer: not enough memory.";
            exit(1);
      }

      cout<<pPrinterName<<":"<<"\n"<<"Actual buffer size: "<<cbNeeded<<"\n";
      switch (pPrinterInfo->Status)
      {
      case PRINTER_STATUS_PAUSED:
            {
                  cout<<"PRINTER_STATUS_PAUSED "<<pPrinterInfo->Status<<"\n";
                  break;
            }
            
      case PRINTER_STATUS_PENDING_DELETION:
            {
                  cout<<"PRINTER_STATUS_PENDING_DELETION "<<pPrinterInfo->Status<<"\n";
                  break;
            }
      default:
            cout <<"No listed status\n";
      }

      //Set printer to Pause status.
      if(!SetPrinter(hPrinter, 0, NULL, PRINTER_CONTROL_PAUSE))
      {
            cout<<"setprinter failed.\n";
            exit(1);            
      }      
}
Avatar of jstolan
jstolan

ASKER

Trestan

Thanks for your excellent help.  I'm not going to get a chance to try this as I'll be on vacation this week.  I'm sure you've saved me a ton of work though.

jstolan