views:

347

answers:

5

I am writing a program using Delphi 2006 and storing data in XML files and a Firebird database. I create reports using either FastReports, Excel or QuickPDF. I allow my users to package several reports together and be directed to a destination of their choice, whether it is a PDF file, a printer, the screen, or email.

I want my users to be able to configure their printer choices for the reports they send to printers. To do this, I will use the printer dialog to choose a printer and set the properties of that printer. I want to be able to capture those properties and store them so that when they run their package of reports, they will all go to the correct printer using the configurations they have chosen.

I know different printers have different configuration possibilities. For example, one that I use will allow me to choose to print booklet style so you can produce a 5 1/2 X 8 1/2 booklet from a report. It's possible that a user might choose an option like that when they are configuring a report in their package and expect that report to print in that manner. There are probably lots of possibilities that I am not aware of but would like to allow if that is possible. I just don't know how to capture that configuration from the printer dialog, store it in a database and then use that information to configure the printer when it's time to print the report.

How can I translate the information stored in the printer dialog into something I can store (even in a blob) in a database and then use that information to configure the printer?

Thank you for your help.

A: 

I know this should be possible with GetPrinterDataEx, but I could not find information about people having this used.

--jeroen

Jeroen Pluimers
+2  A: 

AFAIK, that isn't possible. The printer setup dialog is standard, but quite often is replaced (or modified) to include additional printer specific setup information (eg., the booklet information you mentioned). Since there's no way for anyone other than the printer driver publisher to know what's there, there's no way to reliably get the information in a generic fashion.

The GetPrinterDataEx() API function Jeroen mentioned won't work, either, as it requires you to know ahead of time the name of the registry key that was used to store information via the SetPrinterDataEx() procedure, and that may or may not have been used by the printer driver. If it was used, you'd have to manually look at the registry to see where the driver publisher decided to store the info; I'd suspect that varies between printer manufacturers as well.

FOLLOWUP: I just ran a quick check and I'm pretty sure the above is correct. If I use the Printer Setup dialog from a Delphi app to access printer settings (for example, the duplex setting before running a report), no changes are written to the registry. However, if I go into the Control Panel Printer applet and change settings there, the registry is updated. This seems to confirm that per-report setting selections made on the fly by the user would be hard to save, as they're probably not accessible anywhere except to the printer driver. Permanent type settings (those made in the control panel applet) are made by the user and the user opts to make them permanent on a system-wide basis, and therefore they're saved to the registry. This seems to preclude saving those types of options on a per-report basis, at least from the printer setup dialog changes.

Ken White
Thanks, Ken. I guess I can stop struggling with this.
I believe, from what I have read, that I can query the printer dialog for some specific properties like whether to print in duplex or what bin to use and so on, store those in my own structure and set up the printer at print time to match those properties. Does that match your understanding?
I think you can do this. Comment with code from my app that does it posted.
mj2008
A: 

The documentation for the Windows API PRINTDLGEX Structure might contain some hints. In particular I think the hDevMode handle gives you the bits that are specific to a printer driver, even though they're undocumented. I don't know how you would use this information from Delphi.

Mark Ransom
+1  A: 

This is all possible, but for a specific printer on a specific computer. Basically, you ask the printer driver for its custom config data, and store that exactly as is. You can then pass it back later to print with.

Check out the following Windows API functions. If you want C code for this, ask in a comment. Actually, I'll copy a chunk here of the code I use, sorry it isn't translated to Delphi! This is from real working code though, hard fought over. Hopefully it will give you some clues.

bGood = OpenPrinter(pcDeviceName, &hPrinter, NULL);
int sBuffSize = DocumentProperties(hDlg, hPrinter, pcDeviceName, NULL, NULL, 0);
PDEVMODE pxDevMode = (PDEVMODE)malloc(sBuffSize);
gl_memset(pxDevMode, '\0', sBuffSize);
pxDevMode->dmSize = sBuffSize;
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_PROMPT | DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, NULL, DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_PROMPT | DM_COPY);
DocumentProperties(hDlg, hPrinter, pcDeviceName, pxDevMode, pxDevMode, DM_UPDATE | DM_MODIFY);
ClosePrinter(hPrinter);
mj2008
Sorry. I was out of town for a couple of days.OK. I feel like I might have been a little hasty in accepting no for an answer. What you are saying is what I was hoping to hear. I will keep working on this. Thanks for the code. It looks like I should be able to make some workable Delphi code out of it. If I get anywhere, I will post it back here.Jack
A: 

It appears that a similar question was answered with information that may solve my problem for me. Thanks for your responses.