Modify properties for printer-specific configuration dialog

♀尐吖头ヾ 提交于 2019-12-09 19:41:51

问题


We have build a custom print dialog that has a button for showing the printer specific dialog. I read this answer by Shurup, and it helped me to achieve this. (Edit: But it contains an error, as explained in my answer)

However, we use this in combination with stored settings. When we call the method with our PrinterSettings they get ignored. The native dialog shows its default settings, regardless of the provided settings object.

EDIT: Removed my fail-code.


回答1:


Thanks to this page I found a working solution! The code in the other stackoverflow answer that I linked, contained a small but significant error: The external call to DocumentProperties had the input DEVMODE parameter defined as ref parameter. The working solution doesn't use ref! This may seem insignificant, but actually (at least in my Win32 XP environment) it caused the printer dialog to ignore the input!

This code takes the settings from the PrinterSettings, sets the printer dialog accordingly and updates the PrinterSettings afterwards (you may ignore the calls to get a window handle from 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);
        }
    }
}


来源:https://stackoverflow.com/questions/5408995/modify-properties-for-printer-specific-configuration-dialog

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!