Благодаря этой странице Я нашел рабочее решение!Код в другом ответе 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);
}
}
}