Link to home
Create AccountLog in
Visual C++.NET

Visual C++.NET

--

Questions

--

Followers

Top Experts

Avatar of Caroline_Perkins
Caroline_Perkins

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,
                                    devMode);
            if(PaperNames==NULL) ErrorMessage("Error: need more memory for paper names");

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

            PaperSizes = new POINT[PaperSizeCount];
            DeviceCapabilities(PrinterName, port, DC_PAPERSIZE, (char*)PaperSizes,
                                    devMode);
            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) + "\")");
                        break;
                  }
                  p++;
            }
            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?

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


SOLUTION
Avatar of lakshman_celakshman_ce

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Avatar of Caroline_PerkinsCaroline_Perkins

ASKER

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.

ASKER CERTIFIED SOLUTION
Avatar of DanRollinsDanRollins🇺🇸

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.

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.

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.

Visual C++.NET

Visual C++.NET

--

Questions

--

Followers

Top Experts

Microsoft Visual C++ (often abbreviated as MSVC or VC++) is an integrated development environment (IDE) product from Microsoft for the C, C++, and C++/CLI programming languages. It features tools for developing and debugging C++ code, especially code written for the Microsoft Windows API, the DirectX API, and the Microsoft .NET Framework. Many applications require redistributable Visual C++ packages to function correctly and are often installed independently of applications, allowing multiple applications to make use of the package while only having to install it once