Printed MetaFile drops lines when screen resolution is < 1280x1024
Posted on 2003-03-21
We are creating a TMetaFileCanvas and stretchdrawing an EMF onto it and then adding some custom text. Once completed, that metafile is stretchdrawn onto a printer's canvas and printed. These are our Forms. One form we have contains a table of information on it.
Using our original source, the grid lines (lines between the cells of the table) would not print when the Server was running a resolution at or below 1024x768. These lines would print when the resolution was 1280x1024. We traced this down to the creation of the TMetaFileCanvas. It was being created with a reference device of 0 (HWndDesktop). So, it was using a Device Context with the resolution of the screen to create the canvas. Our theory is that the resolution of that canvas was only 96dpi at 1024x768 and therefore the grid lines, that perhaps were finer than that, were being being optimized out.
We fixed this by using the default printer's device context to create the metafile canvas. This consistently allows the forms to print accurately. Obviously, the DPI of the printer was higher than that of the screen.
This would work fine on a standard application. HOWEVER, we've made things difficult by tossing a Server and a thin client into the archetecture. The TMetafileCanvas is being created on the Server which hosts the engine that dynamically builds and routes our forms. The completed metafile is sent to the client along with routing information. The client opens the appropriate device (a winprinter in this case) and plays the information out to it. So, the problem is that the printers are on the clients and not the server. We cannot get the correct Device Context for the destiation printer. In fact, we are not guaranteed to even have a printer on the server which is supposed to be a closed box unit. We've come up with a working solution that uses a printer DC if there is a non-generic printer on the server. If not falls back to the screen's DC if there is not. And we can dictate that upgrading to the next version of our software involves installing a dummy printer onto the server but... this cannot be the right way to do this. There has to be a better way.
We've played with using SetMapMode, SetWindowExtEx and SetViewPortExtEx but frankly we are not familiar enough with them and were just take shots in the dark. We do not know if we would have to apply these calls on Server side, client side or both. Our test concentrated on the client side fo things and applying the extents to the metafile canvas. Before and after we applied the sets, the Get*Extex calls always returned (1,1). This didn't make sense to us.
This all boils down to two questions:
1. Can we create the MetaFileCanvas passing a reference device of 0 (HWndDesktop) and then change the resolution/DPI of the canvas?
2. Is there an alternative we have not thought of yet?
Additional Info -
We are using Delphi but can translate examples from any language.
We are using CreateWithComments to create the TMetaFileCanvas.
We are "StretchDrawing" the EMF to the MFCanvas and then to the printer canvas. In Delphi, the StretchDraw call is filtered through a wrapper which in the end I believe boils down to a PlayEnhMetafile call - I have not completely traced this through and I could be wrong but the comments in the wrapper state that it "plays" the metafile. Can anyone confirm or deny this?
This one is tough but fun. I'd add more points but this is my first posting here. So, you get all the points I've got. You'll probably see me more often now that I'm an official "Expert" <g>.