3

In one of my windows application, I am in need of a module where we want to detect the coverage of the page being printed.

Right now, I am using Print Queue Watch library for detecting the printing job events.

But is there a way to detect how much part of the page being printed.?

Thanks in advance.

Vishal Suthar
  • 17,013
  • 3
  • 59
  • 105
  • 2
    I don't think this is possible if your printer doesn't send this data. Maybe you should see if there is an API given by the manufacturer of your printer. – Atlasmaybe Sep 13 '13 at 08:41
  • This makes little sense. If you want to measure toner cartridge consumption then there are ways to get that out of the printer itself. It greatly depends on the make and model. – Hans Passant Sep 23 '13 at 17:52
  • The documents are converted to raw data and sent to the printer via the driver and that process is shown as a window like printing document 1,2,3 etc.. So after handing over to the printer, it is the printer's job to calculate rest.. So its not possible unless an acknowledgment is received from the printer.. – Abdul Saleem Sep 25 '13 at 20:53

2 Answers2

2

Since you progammed your application in C# using WinForms, I assume you used a PrintDocument and your printing takes place in a PrintPage event using PrintPageEventArgs.Graphics.

If this is the case, it should be possible to refractor the code which prints into a seperate method, which takes a an instance of Graphics as parameter (and probably additional parameters, like page size and so on).

Then, you could create a (white) Bitmap object with sufficient size (and the same aspect ratio as your paper), and supply it to the method described above. Then, you can go and count the pixels which have been colored and thus, caculate the percentage of the page which the printer would have printed on.

Keep in mind that you probably have to respect the margin around the printing area and different paper sizes for your calculation.

If the refractoring of the code prooves to heavy, you could create a wrapper for the Graphics object, which "duplicates" all draw calls to a Bitmap while printing, and then continue with counting the pixels.

(This answer assumes you want to monitor your application, not other applications on the system)

Emiswelt
  • 3,909
  • 1
  • 38
  • 56
2

I know one way to do that. You need to create a Print Processor. The print processor is a driver that can change or read data before it is sent to the Print Monitor (This is the driver that emit things in proprietary format to the printer port).

See here a global view of the printing architecture http://technet.microsoft.com/en-us/library/cc976755.aspx. Here is a description of what a Printer Processor does: https://serverfault.com/questions/304536/what-is-the-reason-for-choosing-a-different-print-processor.

How to change the print processor by using PowerShell: http://blogs.technet.com/b/chad/archive/2012/10/31/tip-52-mixing-the-old-and-new-setting-a-printer-s-print-processor-using-powershell-wmi-and-setprinter-exe.aspx

And here is a sample on how to do it (i.e., to create a print processor): http://code.msdn.microsoft.com/windowshardware/Genprint-4a71134f.

To make it work you will need to redirect GdiPlayPageEMF to a bitmap on memory, then you can count its pixels before it is send to the handle of the printer. You can search about GdiPlayPageEMF on Google, there will be interesting results on how to do this kind of thing.

Also, there are a lot of good info about printing here http://www.undocprint.org/winspool/spool_files#reading_job_data.

I hope this helps.

Community
  • 1
  • 1
Luiz Felipe
  • 1,123
  • 8
  • 14
  • Not possible. However you monitor, the data is sent to the printer as bulk, not byte by byte. – Abdul Saleem Sep 25 '13 at 20:58
  • I think Luiz Felipe's solution is possible. You don't need to send the data byte by byte, but you will have to interpret the data sent to the processor (an EMF file in the best case). – Emiswelt Sep 26 '13 at 18:17