編輯:我的錯!我預料,實際上只有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