Michael Damatov
Michael Damatov

Reputation: 15633

Display printer-specific configuration dialog

Having a PrintTicket how to display the printer-specific configuration dialog?

Note: I don't mean the PrintDialog from the System.Windows.Controls namespace.

Upvotes: 1

Views: 855

Answers (2)

SomeCodeMonkey
SomeCodeMonkey

Reputation: 61

Since I am not trustworthy enough to edit the accepted answer, I'll post a second answer instead...

The accepted answer works fine for showing a native printer dialog and getting the changes from that dialog. However, it does not set the properties on the dialog correctly, beforehand.

In order to push settings into the native dialog, you have to change the signature of DocumentProperties as follows. The new signature does not use a ref parameter as input.

Here is the page that pointed me to this small but significant difference.

[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,
  IntPtr pDevModeInput,    //removed ref
  int fMode);

Upvotes: 3

Alexander Zwitbaum
Alexander Zwitbaum

Reputation: 4846

To show the PrinterSettings dialog use

[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) {
  var handle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
  var hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
  var pDevMode = GlobalLock(hDevMode);
  var sizeNeeded = DocumentProperties(handle, IntPtr.Zero, printerSettings.PrinterName, pDevMode, ref pDevMode, 0);
  var devModeData = Marshal.AllocHGlobal(sizeNeeded);
  DocumentProperties(handle, IntPtr.Zero, printerSettings.PrinterName, devModeData, ref pDevMode, 14);
  GlobalUnlock(hDevMode);
  printerSettings.SetHdevmode(devModeData);
  printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
  GlobalFree(hDevMode);
  Marshal.FreeHGlobal(devModeData);
}

// Show this dialog.
var printQueue = LocalPrintServer.GetDefaultPrintQueue();
var settings = new PrinterSettings { PrinterName = printQueue.FullName };
OpenPrinterPropertiesDialog(settings);

Upvotes: 2

Related Questions