65.9K
CodeProject is changing. Read more.
Home

How to Show a Popup Window for Printer Properties

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.20/5 (8 votes)

Jun 8, 2006

CPOL

1 min read

viewsIcon

77228

downloadIcon

1615

This article introduces a method to show a popup window for printer properties.

Sample Image - PrinterPropertiesWindow.jpg

Introduction

Generally, we use the System.Windows.Forms.PrintDialog class for a printer popup widow and we click the "Properties" button in the printer popup window in order to show a printer properties popup window. But we are occasionally asked to show a printer properties popup window directly.

See the following source code...

Add namespaces

Add the namespaces System.Drawing.Printing and System.Runtime.InteropServices.

using System.Drawing.Printing;
using System.Runtime.InteropServices;

DLL Interop Code

We use a DLL and driver file for the printer properties popup window (winspool.Drv, kernel32.dll). Paste the following code in your class (Form or user control or custom class):

[DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesW", SetLastError = true,
            ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
            [MarshalAs(UnmanagedType.LPWStr)] string pDeviceName,
            IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);

[DllImport("kernel32.dll")]
static extern IntPtr GlobalLock(IntPtr hMem);

[DllImport("kernel32.dll")]
static extern bool GlobalUnlock(IntPtr hMem);

[DllImport("kernel32.dll")]
static extern bool GlobalFree(IntPtr hMem);

private void OpenPrinterPropertiesDialog(PrinterSettings printerSettings)
{
    IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
    IntPtr pDevMode = GlobalLock(hDevMode);
    int sizeNeeded = DocumentProperties(this.Handle, IntPtr.Zero, 
                        printerSettings.PrinterName, pDevMode, ref pDevMode, 0);
    IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded);
    DocumentProperties(this.Handle, IntPtr.Zero, 
            printerSettings.PrinterName, devModeData, ref pDevMode, 14);
    GlobalUnlock(hDevMode);
    printerSettings.SetHdevmode(devModeData);
    printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
    GlobalFree(hDevMode);
    Marshal.FreeHGlobal(devModeData);
}

Using the OpenPrinterPropertiesDialog Method

A instance of PrinterSettings has your default printer's setting values. If you want to assign another printer's setting values to an instance of PrinterSettings, then remove the following code's comment symbol:

//ps.PrinterName = System.Drawing.Printing.PrinterSettings.InstalledPrinters[1];

"System.Drawing.Printing.PrinterSettings.InstalledPrinters" is a collection of printer names. If you put a printer name to the PrinterName property of a PrinterSettings instance, you'll have that printer's setting values.

Finally, you should write a try ... catch block because the above code line may cause errors.

You can write the following code in your button control's event handler:

private void button1_Click(object sender, System.EventArgs e)
{
    try
    {
        PrinterSettings ps = new PrinterSettings();
        // ps.PrinterName = System.Drawing.Printing.PrinterSettings.InstalledPrinters[1];
        OpenPrinterPropertiesDialog(ps);
   }
   catch(Exception ex)
   {
       MessageBox.Show("Printer settings are incorrect.", "ERROR", 
                       MessageBoxButtons.OK,MessageBoxIcon.Error);
   }  
}

Thank you very much.

Be happy!