修改特定于打印机的配置对话框的属性

我们已经构建了一个自定义打印对话框,其中包含一个用于显示打印机特定对话框 我读了Shurup的 这个答案 ,它帮助我实现了这个目标。 ( 编辑:但它包含错误,如我的回答中所述)

但是,我们将其与存储的设置结合使用。 当我们用PrinterSettings调用方法时,它们会被忽略。 无论提供的设置对象如何,本机对话框都会显示其默认设置。

编辑:删除了我的失败代码。

感谢这个页面,我找到了一个有效的解决方案 我链接的另一个stackoverflow答案中的代码包含一个小而重要的错误:对DocumentProperties的外部调用将输入DEVMODE参数定义为ref参数。 工作解决方案不使用ref! 这可能看起来微不足道,但实际上(至少在我的Win32 XP环境中)它导致打印机对话框忽略输入!

此代码从PrinterSettings获取设置,相应地设置打印机对话框并随后更新PrinterSettings(您可以忽略从WPF获取窗口句柄的调用):

 [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, int fMode); [DllImport("kernel32.dll")] static extern IntPtr GlobalLock(IntPtr hMem); [DllImport("kernel32.dll")] static extern bool GlobalUnlock(IntPtr hMem); private void OpenPrinterPropertiesDialog(PrinterSettings printerSettings) { Window parentWindow = Window.GetWindow(this); if (parentWindow == null) { return; } IntPtr hDevMode = IntPtr.Zero; IntPtr devModeData = IntPtr.Zero; try { IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(parentWindow).Handle; //get DEVMODE from settings hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings); IntPtr pDevMode = GlobalLock(hDevMode); //get needed size and allocate memory int sizeNeeded = DocumentProperties(hwnd, IntPtr.Zero, printerSettings.PrinterName, IntPtr.Zero, pDevMode, 0); devModeData = Marshal.AllocHGlobal(sizeNeeded); //show the native dialog DocumentProperties(hwnd, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, 14); GlobalUnlock(hDevMode); //get settings and page settings from changed DEVMODE printerSettings.SetHdevmode(devModeData); printerSettings.DefaultPageSettings.SetHdevmode(devModeData); } finally { if (hDevMode != IntPtr.Zero) { Marshal.FreeHGlobal(hDevMode); } if (devModeData != IntPtr.Zero) { Marshal.FreeHGlobal(devModeData); } } }