在引用了代码项目,msdn论坛,堆栈溢出等不同的论坛和文章之后,建议使用以下代码段打开打印机属性对话框并保存修改后的更改,但仅打开属性对话框,但更改对打印机属性所做的设置不会保存。我正在从WPF应用程序中调用以下方法。有人可以看看吗,让我知道是否遗漏了任何东西?
/// Open the printer preferences prompt.
/// </summary>
/// <param name="printerSettings">settings of the printer to be used</param>
/// <returns>
public void OpenPrinterPropertiesDialog(PrinterSettings printerSettings)
{
IntPtr hDevMode = IntPtr.Zero;
IntPtr pDevMode = IntPtr.Zero;
IntPtr devModeData = IntPtr.Zero;
try
{
PRINTER_DEFAULTS pd = default(PRINTER_DEFAULTS);
IntPtr hPrinter = default(IntPtr);
int nRet = 0;
pd.DesiredAccess = PRINTER_ACCESS_USE;
// Open the printer by name
nRet = OpenPrinter(printerSettings.PrinterName, out hPrinter, ref pd);
// Get devmode handle from printer settings
hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
// Lock the devmode
pDevMode = GlobalLock(hDevMode);
//Fetch the size needed to allocate memory
int sizeNeeded = DocumentProperties(IntPtr.Zero, hPrinter, printerSettings.PrinterName, IntPtr.Zero, pDevMode, 0);
devModeData = Marshal.AllocHGlobal(sizeNeeded);
// Show the native printer preferences dialog
DocumentProperties(IntPtr.Zero, hPrinter, printerSettings.PrinterName, devModeData, pDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
// UnLock the devmode
GlobalUnlock(hDevMode);
// Close Printer
ClosePrinter(hPrinter);
// Get settings and page settings from changed DEVMODE
printerSettings.SetHdevmode(devModeData);
printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
// Free memory
GlobalFree(hDevMode);
}
finally
{
if (hDevMode != IntPtr.Zero)
{
Marshal.FreeHGlobal(hDevMode);
}
if (pDevMode != IntPtr.Zero)
{
Marshal.FreeHGlobal(devModeData);
}
if (devModeData != IntPtr.Zero)
{
Marshal.FreeHGlobal(devModeData);
}
}
}
// Win32 API Declaration
[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 = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
[MarshalAs(UnmanagedType.LPStr)] string pDeviceName,
IntPtr pDevModeOutput, IntPtr pDevModeInput, int fMode);
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, ref PRINTER_DEFAULTS pDefault);