How to show printer properties/preferences dialog and save changes?

后端 未结 4 621
日久生厌
日久生厌 2020-12-09 00:23

EDIT: My fault! I expected the changes to be written back to the default printer settings when in fact only the local instance of the PrinterSettings are changed. -

4条回答
  •  攒了一身酷
    2020-12-09 00:37

    Even though the answer ended up working its way into the question, I think the following provides a better answer to the original question,

    (1) Because it clearly does not modify the passed-in PrinterSettings if the user cancels.

    (2) Because it returns a DialogResult, which the caller will likely be interested in.

    [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);
    [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);
    
    private const int DM_PROMPT = 4;
    private const int DM_OUT_BUFFER = 2;
    private const int DM_IN_BUFFER = 8;
    
    private DialogResult EditPrinterSettings(PrinterSettings printerSettings)
    {
        DialogResult myReturnValue = DialogResult.Cancel;
        IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
        IntPtr pDevMode = GlobalLock(hDevMode);
        int sizeNeeded = DocumentProperties(this.Handle, IntPtr.Zero, printerSettings.PrinterName, pDevMode, pDevMode, 0);
        IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded);
        long userChoice = DocumentProperties(this.Handle, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
        long IDOK = (long)DialogResult.OK;
        if (userChoice == IDOK)
        {
            myReturnValue = DialogResult.OK;
            printerSettings.SetHdevmode(devModeData);
            printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
        }
        GlobalUnlock(hDevMode);
        GlobalFree(hDevMode);
        Marshal.FreeHGlobal(devModeData);
        return myReturnValue;
    }
    

提交回复
热议问题