views:

39

answers:

1

For our application, we need to be able to print output at a specific location on a page. For example, we need to be able to print some text at exactly (1.00", 1.00") relative to the top left corner of the page. The problem lies in the fact that all coordinates in the various GDI calls are not relative to the upper left corner of the display, but are rather relative to a device dependent offset, which one obtains with code like:

int cx = ::GetDeviceCaps(hDC, PHYSICALOFFSETX);
int cy = ::GetDeviceCaps(hDC, PHYSICALOFFSETY);

These, of course, are in device units, so you convert them to logical units as desired. And then, you may adjust your coordinates in other API calls to get the output exactly where you need it.

This works like a charm when running under Windows directly. However, when using Terminal Services to print to a redirected printer on Windows Server 2008, the DeviceCaps functions no longer report correct information, at least for a large number of different printers. Device offsets are reported as 0, and when querying the printable region on a page, incorrect information is returned (the APIs overstate the amount of available real estate). Worse, it appears that either MS or the printer driver vendor is aware of the issue, because when the print job spools to your local machine (so that it can then spool to your local printer), all of the output is shifted by some compensating amount; an amount that appears to be a hack as it is nowhere close to the correct value reported by GetDeviceCaps when querying printer capabilities locally.

So, the result is that printed output gets shifted off the page ...

Has anyone else seen issues of this sort? Am I crazy to want precise control over printed output? Certainly, in order to paginate correctly, one needs an accurate value for the amount of available printable space, no? Any help or pointers would be appreciated.