编辑:我的错!我预料,实际上只有PrinterSettings的本地实例发生更改时,才会将更改写回默认的打印机设置。 - 下面的代码似乎按预期工作如何显示打印机属性/首选项对话框并保存更改?
我想显示给定打印机的自定义打印机属性。我需要这个作为我试图编写的自定义PrintDialog的一部分。
我可以在网上找到的大多数例子都显示对话框,但用户可能做出的任何更改都会丢失,这使得它无用。
实施例: http://www.codeproject.com/KB/system/PrinterPropertiesWindow.aspx
(关于网页上面:我试图改变代码由BartJoy的建议(在页面上),但没有解决问题)
我还试图将样品和在pinvoke.net页面上的建议,但它仍然不能正常工作:
http://www.pinvoke.net/default.aspx/winspool.documentproperties
从上面的网站,我认为这个问题可能只有在64位Windows中的nd /或打印机名称是否长于32个字符。
我不知道我应该尝试接下来...我欣赏任何建议和意见!
编辑:这是我曾尝试:
[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("winspool.drv")]
private static extern int OpenPrinter(string pPrinterName, out IntPtr hPrinter, IntPtr pDefault);
[DllImport("winspool.drv")]
private static extern int ClosePrinter(IntPtr phPrinter);
[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);
private const int DM_PROMPT = 4;
private const int DM_OUT_BUFFER = 2;
private const int DM_IN_BUFFER = 8;
private void OpenPrinterPropertiesDialog()
{
var printerSettings = new System.Drawing.Printing.PrinterSettings();
var printerName = printerSettings.PrinterName;
IntPtr handle;
OpenPrinter(printerName, out handle, IntPtr.Zero);
IntPtr hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
IntPtr pDevMode = GlobalLock(hDevMode);
int sizeNeeded = DocumentProperties(this.Handle, handle, printerName, pDevMode, pDevMode, 0);
IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded);
DocumentProperties(this.Handle, handle, printerName, devModeData, pDevMode, DM_IN_BUFFER | DM_PROMPT | DM_OUT_BUFFER);
ClosePrinter(handle);
GlobalUnlock(hDevMode);
printerSettings.SetHdevmode(devModeData);
printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
GlobalFree(hDevMode);
Marshal.FreeHGlobal(devModeData);
}
我曾尝试使用OpenPrinter和ClosePrinter方法并传递devModeData在第二调用的输出参数,因为我觉得很奇怪,原来pinvoke.net的代码没有这样做。 (但我承认,我不知道我在做什么 - 这只是试错)。
下面是从PInvoke的网站原代码:
private void OpenPrinterPropertiesDialog(PrinterSettings printerSettings)
{
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);
DocumentProperties(this.Handle, IntPtr.Zero, printerSettings.PrinterName, IntPtr.Zero, pDevMode, 14);
GlobalUnlock(hDevMode);
printerSettings.SetHdevmode(devModeData);
printerSettings.DefaultPageSettings.SetHdevmode(devModeData);
GlobalFree(hDevMode);
Marshal.FreeHGlobal(devModeData);
}
而你怎么样设法得到chages救回来?此代码确实会更改printerSettings,但这些更改不会保存为默认打印机设置:( – Ando 2010-05-11 07:24:07