Learn how to a build a cloud-first strategyRegister Now


Logging Paper Size of printed jobs (DeviceCapabilities and DEVMODE.dmPaperSize)

Posted on 2006-04-18
Medium Priority
Last Modified: 2010-08-05
I have written a program that uses FindNextPrinterChangeNotification to monitor changes in print jobs on a printer and log the information to a database. I am having a problem, however, that sometimes the paper size is reported as 8"x11" when the printed document is actually much larger.

I check the dmPaperWidth and dmPaperLength values of the DEVMODE (provided through JOB_NOTIFY_FIELD_DEVMODE in the PRINTER_NOTIFY_INFO_DATA structure) but often times these values are not used and dmPaperSize is set instead.

In these cases I use the following code to request the Paper Size dimensions (based on the dmPaperSize value) from the printer driver usiing DeviceCapabilites. It works in most cases, but occasionally the DEVMODE reports PaperSize as "1" and DeviceCapabilities says that this means 8"x11" even though this is not the correct size.

        // find out how many paper names there are
      PaperSizeCount = DeviceCapabilities(PrinterName, port, DC_PAPERNAMES, NULL, devMode);
      if(PaperSizeCount < 0) {
            ErrorMessage((string)"Error: DeviceCapabilities failed: " + ToString(GetLastError()));

      // make sure we have atleast one paper name
      else if (PaperSizeCount > 0) {

            PaperNames = new char[PaperSizeCount*64];
            DeviceCapabilities(PrinterName, port, DC_PAPERNAMES, PaperNames,
            if(PaperNames==NULL) ErrorMessage("Error: need more memory for paper names");

            PaperIds = new WORD[PaperSizeCount];
            DeviceCapabilities(PrinterName, port, DC_PAPERS, (char*)PaperIds,
            if(PaperIds==NULL) ErrorMessage("Error: need more memory for paper ids");

            PaperSizes = new POINT[PaperSizeCount];
            DeviceCapabilities(PrinterName, port, DC_PAPERSIZE, (char*)PaperSizes,
            if(PaperSizes==NULL) ErrorMessage("Error: need more memory for paper sizes");

            ErrorMessage("Notice: Found " + ToString(PaperSizeCount) + " PaperSize Defintions for " + PrinterName);
            // pointer to loop through PaperIds
            WORD* p = PaperIds;

            for (long i = 0; i < PaperSizeCount; i++) {
                  if(*p==devMode->dmPaperSize) {
                        memcpy(&ret, &PaperSizes[i], sizeof(POINT));
                        char temp[65];
                        memcpy(temp, &PaperNames[i*64], 64);
                        temp[64] = '\0';
                        ErrorMessage((std::string)"Notice: Found matching Paper Size Definition for " + ToString(devMode->dmPaperSize) + " on " + PrinterName + " : " + temp + " ("  + ToString(ret.x) + "\" x " + ToString(ret.y) + "\")");
            if(i==PaperSizeCount) ErrorMessage("Warning: No match for for Paper Size Code: " + ToString(devMode->dmPaperSize));

      } else {
            ErrorMessage((std::string)"Warning: No Paper Size Codes found for " + PrinterName);

The cases where the paper size is reported incorrectly seems to happen intermittently an unpredictably. I know the problem is happening on our KIP 8000 print driver and our HP 1055 driver because these are large format plotters. It is possible that other printer drivers are also reporting the wrong size, but I have not confirmed this yet.

It seems to me like the problem is in the software that is printing selecting dmPaperSize 1 when it prints yet actually printing a larger document. The drivers seem to accept this without complaint. Is there a better way to obtain the dimensions of the document being printed? Does anyone have any ideas about how I could improve my code to get the correct values in these cases?
Question by:Caroline_Perkins
  • 2
LVL 15

Assisted Solution

lakshman_ce earned 400 total points
ID: 16546346
Did you try passing PRINTER_NOTIFY_OPTIONS_REFRESH as the third parameter to FindNextPrinterChangeNotification method

BOOL FindNextPrinterChangeNotification(
  HANDLE hChange,                // change notification
  PDWORD pdwChange,              // condition that changed
  LPVOID pPrinterNotifyOptions,  // refresh option
  LPVOID *ppPrinterNotifyInfo    // printer information


Author Comment

ID: 16548584
I do pass PRINTER_NOTIFY_OPTIONS_REFRESH for the third parameter, but only if PRINTER_NOTIFY_INFO_DISCARDED is set in the returned notify options. Are you suggesting that I pass this flag everytime I call the function regardless of if PRINTER_NOTIFY_INFO_DISCARDED is set? It doesn't seem to me like this would make any difference... but I can try it if you have reason to think it will solve the problem.
LVL 49

Accepted Solution

DanRollins earned 1600 total points
ID: 16704604
This may be related to the driver.  When you bring up the pritner settings, does it allow entry of a custom paper size?

One thing you are not looking at is the currently-paper bin in use.  the driver might be using that value to flag "special handling" (that's a shot in the dark... but in general, I think you may need to look at every piece of available info and try to find a pattern).

As to the" intermittentnance" (is that word? lol) of the problem .. is it possible that only certain application programs cause the problem?  For instance, maybe AutoCad handles it one way and Notepad handles it another way.

Another long shot...
    DMPAPER_USER                256
is 0x100 which might look like 1 if one is not paying attention...

Also, check the value of
It contains bit flags that indicate which of the other fields in the structure apply.  Look in the file WINGDI.H for the definitions (eg, DM_PAPERWIDTH, etc).

-- Dan

Author Comment

ID: 16938645
I never did find a good solution to this particular problem. It seems to be a problem specific to large format plotter devices. I have had some communication with the someone at KIP and they are being pretty helpful. So maybe they will be able to correct it with a new version of their driver/software. Thanks to both of you for your suggestions.

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

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

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Screencast - Getting to Know the Pipeline

810 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