2009-04-07 100 views
5

我正在使用WPF,並且需要讓用戶設置一些打印相關選項,如打印機和打印機屬性(例如,papertray,風景/人像,雙面打印等)。我知道PrintDialog類來獲得PrintQueue和PrintTicket對象。不過,我需要創建I自定義解決方案,並且不能顯示PrintDialog。 我設法獲得可用的PrintQueue對象並讓用戶選擇打印機。我正在努力與打印機屬性。 我的問題是:如何顯示用戶可以在其中設置所選PrintQueue的打印機屬性的對話框(當用戶單擊WPF PrintDialog中的屬性按鈕時顯示的對話框)。如何調用對話框手動設置打印機選項?

+0

看到這個問題: http://stackoverflow.com/questions/2437337/how-to-show-printer-properties-preferences-dialog-and -保存更改 – 2010-04-26 07:01:30

回答

4

找到以下代碼here(減去Window_Loaded事件)。我測試了它,它似乎像魅力一樣工作。很明顯,您必須在顯示對話框之前在PrinterSettings對象中設置打印機名稱。

希望這對你的作品:

[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 Int32 DM_OUT_BUFFER = 14; 

public void OpenPrinterPropertiesDialog(PrinterSettings printerSettings, System.IntPtr pHandle) { 
    IntPtr hDevMode = printerSettings.GetHdevmode(); 
    IntPtr pDevMode = GlobalLock(hDevMode); 
    Int32 fMode = 0; 
    int sizeNeeded = DocumentProperties(pHandle, IntPtr.Zero, printerSettings.PrinterName, pDevMode, pDevMode, fMode); 
    IntPtr devModeData = Marshal.AllocHGlobal(sizeNeeded); 

    fMode = DM_OUT_BUFFER; 

    DocumentProperties(pHandle, IntPtr.Zero, printerSettings.PrinterName, devModeData, pDevMode, fMode); 
    GlobalUnlock(hDevMode); 
    printerSettings.SetHdevmode(devModeData); 
    printerSettings.DefaultPageSettings.SetHdevmode(devModeData); 
    GlobalFree(hDevMode); 
    Marshal.FreeHGlobal(devModeData); 
} 

private void Window_Loaded(object sender, RoutedEventArgs e) { 
    OpenPrinterPropertiesDialog(new PrinterSettings(), new WindowInteropHelper(this).Handle); 
} 
3

如果你的目標的x86彙編和X64的機器上運行,從Pwninstein代碼將無法正常工作:分配devModeData時,DocumentPropreties總是會失敗,並返回一個sizeNeeded的-1,具有LastError碼13

爲了解決這個問題,無論是確保您指定AnyCPU或者只是改變調用DocumentPropreties以下幾點:

int sizeNeeded = DocumentProperties(pHandle, 
            IntPtr.Zero, 
            printerSettings.PrinterName, 
            IntPtr.Zero, // This solves it 
            pDevMode, 
            fMode); 

使用IntPtr.Zero,而不是一個適當的指針DEVMODE結構看起來不對,但DocumentProperties是第一次調用不會嘗試在該位置修改內存。調用返回的唯一數據是存儲代表打印驅動程序內部參數的設備模式數據所需的內存大小。

參考: