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

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?
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

Caroline_PerkinsAuthor Commented:
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.
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Caroline_PerkinsAuthor Commented:
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.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual C++.NET

From novice to tech pro — start learning today.