Solved

Hooking System Print Messages

Posted on 1998-07-10
3
390 Views
Last Modified: 2013-11-19
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.
0
Comment
Question by:jstolan
  • 2
3 Comments
 
LVL 8

Accepted Solution

by:
trestan earned 200 total points
ID: 1319012
Use Win32 function "OpenPrinter" to retrieve a handle identifying the specified printer or print server.
Use "EnumPrinters" function to enumerate available printers, print servers, domains, or print providers.
The "GetPrinter" function retrieves information about a specified printer. The "PRINTER_INFO_2" structure specifies detailed printer information. But the status information is held differentely between NT and 95. In Windows 95, it can be the following values:

PRINTER_STATUS_BUSY
PRINTER_STATUS_DOOR_OPEN
PRINTER_STATUS_ERROR
PRINTER_STATUS_INITIALIZING
PRINTER_STATUS_IO_ACTIVE
PRINTER_STATUS_MANUAL_FEED
PRINTER_STATUS_NO_TONER
PRINTER_STATUS_NOT_AVAILABLE
PRINTER_STATUS_OFFLINE
PRINTER_STATUS_OUT_OF_MEMORY
PRINTER_STATUS_OUTPUT_BIN_FULL
PRINTER_STATUS_PAGE_PUNT
PRINTER_STATUS_PAPER_JAM
PRINTER_STATUS_PAPER_OUT
PRINTER_STATUS_PAPER_PROBLEM
PRINTER_STATUS_PAUSED
PRINTER_STATUS_PENDING_DELETION
PRINTER_STATUS_PRINTING
PRINTER_STATUS_PROCESSING
PRINTER_STATUS_TONER_LOW
PRINTER_STATUS_UNAVAILABLE
PRINTER_STATUS_USER_INTERVENTION
PRINTER_STATUS_WAITING
PRINTER_STATUS_WARMING_UP

You can make your function according to the value.
In Windows NT, the status value is specified in PRINTER_INFO_6 structure. But in VS5, this structure is only used by "SetPrinter". I did not try it, but I think the status can be obtained when set the command parameter to be zero.
I think the implimentation with these API functions would not be difficult. It would be my pleasure to debug your codes if you met any problem in compiling the program.
Good luck.



0
 
LVL 8

Expert Comment

by:trestan
ID: 1319013
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);            
      }      
}
0
 
LVL 2

Author Comment

by:jstolan
ID: 1319014
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
0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

777 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