2009-04-07 12 views
5

Sto utilizzando WPF e devo consentire agli utenti di impostare alcune opzioni relative alla stampa come proprietà stampante e stampante (ad esempio papertray, orizzontale/verticale, duplex, ecc.). Sono a conoscenza della classe PrintDialog per ottenere un oggetto PrintQueue e PrintTicket. Tuttavia, ho bisogno di creare una soluzione personalizzata e non posso mostrare PrintDialog. Sono riuscito a ottenere gli oggetti PrintQueue disponibili e consentire agli utenti di selezionare una stampante. Sto lottando con le proprietà della stampante. La mia domanda è: come posso mostrare la finestra di dialogo in cui un utente può impostare le proprietà della stampante per il PrintQueue selezionato (la finestra di dialogo che viene mostrata quando un utente fa clic sul pulsante Proprietà nel PrintDialog di WPF).Come posso richiamare la finestra di dialogo per impostare manualmente le opzioni della stampante?

+0

Vedere questa domanda: http://stackoverflow.com/questions/2437337/how-to-show-printer-properties-preferences-dialog-and -Salva I Cambiamenti –

risposta

4

Il seguente codice è stato trovato here (meno l'evento Window_Loaded). L'ho provato e sembra funzionare come un fascino. Ovviamente dovrai impostare il nome della stampante nell'oggetto PrinterSettings prima di visualizzare la finestra di dialogo.

Spero che questo funziona per voi:

[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

Se il target di compilazione x86 ed eseguire da una macchina x64, il codice da Pwninstein non funziona: in sede di assegnazione devModeData, DocumentPropreties avrà sempre esito negativo e restituisce un sizeNeeded di -1, con un codice LastError 13.

per risolvere il problema, assicurarsi che si target AnyCPU o semplicemente cambiare la chiamata a DocumentPropreties al seguente:

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

Utilizzando IntPtr.Zero invece di una vera e propria puntatore a una struttura DEVMODE sembra sbagliato, ma che prima chiamata a DocumentProperties non tentare di modificare la memoria in quella posizione. L'unico dato restituito dalla chiamata è la dimensione della memoria necessaria per memorizzare i dati della modalità dispositivo che rappresentano i parametri interni del driver di stampa.

Riferimento:

Problemi correlati