2009-04-07 12 views
5

Estoy usando WPF y necesito que los usuarios configuren algunas opciones relacionadas con la impresión, como las propiedades de la impresora y la impresora (por ejemplo, papertray, paisaje/retrato, dúplex, etc.). Conozco la clase PrintDialog para obtener un objeto PrintQueue y PrintTicket. Sin embargo, necesito crear una solución personalizada y no puedo mostrar PrintDialog. Logro obtener los objetos PrintQueue disponibles y dejar que los usuarios seleccionen una impresora. Estoy luchando con las propiedades de la impresora. Mi pregunta es: ¿cómo puedo mostrar el cuadro de diálogo en el que un usuario puede establecer las propiedades de la impresora para la PrintQueue seleccionada (el diálogo que se muestra cuando un usuario hace clic en el botón Propiedades en WPF PrintDialog).¿Cómo puedo invocar el diálogo para configurar las opciones de la impresora manualmente?

+0

Ver esta pregunta: http://stackoverflow.com/questions/2437337/how-to-show-printer-properties-preferences-dialog-and -guardar cambios –

Respuesta

4

Se encontró el siguiente código here (menos el evento Window_Loaded). Lo probé y parece funcionar como un encanto. Obviamente, deberá configurar el nombre de la impresora en el objeto PrinterSettings antes de mostrar el cuadro de diálogo.

Espero que esto funcione para usted:

[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

Si se dirige a la compilación x 86 y se ejecuta desde una máquina de 64 bits, el código de Pwninstein no va a funcionar: en la asignación de devModeData, DocumentPropreties siempre se producirá un error y devuelve un sizeNeeded de -1, con un código de LastError 13.

para resolver el problema, asegúrese de que usted apunta Cualquier CPU o simplemente cambiar la llamada a DocumentPropreties a lo siguiente:

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

Usando IntPtr.Zero en lugar de un puntero adecuado a una estructura DEVMODE se ve mal, pero esa primera llamada a DocumentProperties no intente modificar la memoria en esa posición. La única información devuelta por la llamada es el tamaño de memoria necesario para almacenar los datos del modo del dispositivo que representan los parámetros internos del controlador de impresión.

Referencia:

Cuestiones relacionadas