Изменить свойства для диалогового окна конфигурации принтера - PullRequest
2 голосов
/ 23 марта 2011

Мы создали пользовательский диалог печати, в котором есть кнопка для отображения конкретного диалогового окна принтера. Я прочитал этот ответ Shurup , и это помогло мне достичь этого. ( Редактировать: Но он содержит ошибку, как объяснено в моем ответе)

Однако мы используем это в сочетании с сохраненными настройками. Когда мы вызываем метод с нашим PrinterSettings, они игнорируются. Собственное диалоговое окно показывает настройки по умолчанию независимо от предоставленного объекта настроек.

РЕДАКТИРОВАТЬ: Удален мой код ошибки.

1 Ответ

1 голос
/ 25 марта 2011

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