Question

I am trying to modify the System.Drawing.Printing.PrinterSettings object that I get from the System.Windows.Forms.PrintDialog after the dialog has been shown to the user. Although I am able to change property values on the PrinterSettings object, none of the changes that I make after the dialog has been shown is actually considered when printing a document.

Here is an example of what I mean:

//Show the printdialog and retreive the printersettings    
var printDialog = new PrintDialog();
if (printDialog.ShowDialog() != DialogResult.OK) 
            return;
var printerSettings = printDialog.PrinterSettings;

//Now modify the printersettings object
printerSettings.ToPage = 8;

Now use the printerSettings object for printing. I use the 3rd Party dll Aspose.Words for this, since I need to print Word, but this seems not to be the problem. It seems like that after the dialog has been shown all settings have already been commited to the Printer and changing the PrinterSettings achieves nothing. Any Ideas on how to get this to work?

EDIT: I have some workarounds for this. What I want here is to get an answer to these specific questions: Is it possible to change the PrinterSettings object after the dialog has been shown and are these changes considered in printing. If someone knows only one way of how this can work (you can decide on what API you want to use for printing, it does not matter as long as the PrinterSettings object is used), I would be very thankful.

Was it helpful?

Solution

Not sure why your question got a down vote, seemes pretty reasonable to me????

Anyhow, a few things I've noticed with PrintDialog (which may or may not answer your question).

First thing is that it is just a wrapper class for the windows com dialogue.

[DllImport("comdlg32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        public static extern bool PrintDlg([In, Out] NativeMethods.PRINTDLG lppd);

and second, and most important with reference to you question I guess: The PrintDialog class has this routine which is called after closing of the PrintDlg call

if (!UnsafeNativeMethods.PrintDlg(data))
                return false;

            IntSecurity.AllPrintingAndUnmanagedCode.Assert();
            try { 
                UpdatePrinterSettings(data.hDevMode, data.hDevNames, data.nCopies, data.Flags, settings, PageSettings); 
            }
            finally { 
                CodeAccessPermission.RevertAssert();
            }

. . .

// VSWhidbey 93449: Due to the nature of PRINTDLGEX vs PRINTDLG, separate but similar methods 
// are required for updating the settings from the structure utilized by the dialog.
// Take information from print dialog and put in PrinterSettings
private static void UpdatePrinterSettings(IntPtr hDevMode, IntPtr hDevNames, short copies, int flags, PrinterSettings settings, PageSettings pageSettings) {
        // Mode 
        settings.SetHdevmode(hDevMode);
        settings.SetHdevnames(hDevNames); 

        if (pageSettings!= null)
            pageSettings.SetHdevmode(hDevMode); 

        //Check for Copies == 1 since we might get the Right number of Copies from hdevMode.dmCopies...
        //this is Native PrintDialogs
        if (settings.Copies == 1) 
            settings.Copies = copies;

        settings.PrintRange = (PrintRange) (flags & printRangeMask); 
    }

There is also a rather interesting interplay here (bearing in mind you set PrinterSettings.ToPage):

public PrinterSettings PrinterSettings {
   get { 
        if (settings == null)
        {
            settings = new PrinterSettings(); 
        }
        return settings; 
    } 
    set {
        if (value != PrinterSettings) 
        {
            settings = value;
            **printDocument = null;**
        } 
    }
} 

and then

public PrintDocument Document {
            get { return printDocument;}
            set {
                printDocument = value; 
                **if (printDocument == null)
                    settings = new PrinterSettings();** 
                else 
                    settings = printDocument.PrinterSettings;
            } 
        }

Not a direct answer I know, but I think should point you in the right direction of why it is not working. Seems to me that during the dialogue's use, it can happily nullify the settings on changes as it will be recreated on completion, but when the Dialogue is complete, changing settings actually invalidates the document print settings until it is set again. It may be possible to do this manually, or it may be loch\ked by M$ in the usual internal/private way many internals are.

There is an option of course (not as nice I know) to just use the Win API diectly after the call - code could be hythed from the above dialgues to build your own wrapper if required.

Good luck.

OTHER TIPS

From Aspose documentation:

AsposeWordsPrintDocument awPrintDoc = new AsposeWordsPrintDocument(doc);
awPrintDoc.PrinterSettings = printDlg.PrinterSettings;

So it seems that you can pass yuor modified PrinterSettings object to the word document you are trying to print. Could you tell me if this works?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top