.net 显示打印机特定配置对话框

.net 显示打印机特定配置对话框,.net,wpf,printing,.net,Wpf,Printing,拥有PrintTicket如何显示打印机特定配置对话框 注意:我不是指System.Windows.Controls命名空间中的PrintDialog。要显示PrinterSettings对话框,请使用 [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesW", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.St

拥有
PrintTicket
如何显示打印机特定配置对话框


注意:我不是指
System.Windows.Controls
命名空间中的
PrintDialog

要显示PrinterSettings对话框,请使用

[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);

要显示PrinterSettings对话框,请使用

[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);

由于我不够可信,无法编辑已接受的答案,因此我将发布第二个答案

接受的答案可以很好地显示本机打印机对话框并从该对话框中获取更改。但是,它没有事先正确设置对话框的属性

为了将设置推送到本机对话框中,必须按如下所示更改DocumentProperties的签名。新签名不使用ref参数作为输入

这让我想到了这个微小但却意义重大的区别

[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);

由于我不够可信,无法编辑已接受的答案,因此我将发布第二个答案

接受的答案可以很好地显示本机打印机对话框并从该对话框中获取更改。但是,它没有事先正确设置对话框的属性

为了将设置推送到本机对话框中,必须按如下所示更改DocumentProperties的签名。新签名不使用ref参数作为输入

这让我想到了这个微小但却意义重大的区别

[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);