
Resetear el objeto Printer
#1
Escrito 04 noviembre 2013 - 12:30
Me encuentro con un problema con las impresoras en Windows 7 - Windows 8.
Sospecho que las impresoras del sistema cambian durante la sesión de Windows (cambian de orden o bien se activan/desactivan impresoras tipo Fax, OneNote, XPS Document Writer, ...). El caso es que cuando desde mi aplicación intento enviar un trabajo a una impresora determinada, muchas veces sale por otra.
Esto es debido a que el objeto de Delphi Printer solo se inicializa al iniciar la aplicación, de forma que ese objeto no se actualiza con los cambios en las impresoras que ocurran durante la sesión de Windows. Por eso cuando intento imprimir en la impresora n-ésima que tengo definida en Printers, el documento sale por otra impresora (parece ser que la impresora n-ésima del sistema ya no corresponde a la impresora n-ésima en el objeto Printers).
¿ Conocéis alguna forma de resetear sobre la marcha el objeto Printers para que refleje el estado actual de las impresoras Windows, y no el que había al iniciar la aplicación ?.
Esa aplicación la tengo en Delphi 6.
Gracias.
#2
Escrito 04 noviembre 2013 - 12:52
El método getprinters obtiene las impresoras y tal vez pueda servirte para redefinir a que impresora quieres enviar el trabajo.
Procedure TfrmMonitor.GetPrinters; Var Needed, i: Cardinal; begin If not enumprinters(PRINTER_ENUM_LOCAL, nil, 5, nil, 0, Needed, NumPrinters) then ppi5 := GetMemory(Needed); if assigned(ppi5) then enumprinters(PRINTER_ENUM_LOCAL, nil, 5, ppi5, Needed, Needed, NumPrinters); SetLength(APrinterInfo, NumPrinters); For i := 0 To NumPrinters - 1 Do begin APrinterInfo[i].Name := ppi5.pPrinterName; APrinterInfo[i].Pos := i; Inc(ppi5); if Length(ppi5.pPrinterName) > 0 then ListView1.Items.Add.Caption := ppi5.pPrinterName; End; ListView1.Columns.Items[0].Width := 300; End;
#3
Escrito 05 noviembre 2013 - 10:15
El objeto Printer, definido en la unit Printers, tiene la propiedad Printers de tipo TStrings. Como buen TStrings, tiene el método IndexOf que podría servirte para localizar la impresora por nombre en lugar de por índice (que entiendo es tu problema).
Un abrazo Marc ;-)
#4
Escrito 05 noviembre 2013 - 01:14
Hola
El objeto Printer, definido en la unit Printers, tiene la propiedad Printers de tipo TStrings. Como buen TStrings, tiene el método IndexOf que podría servirte para localizar la impresora por nombre en lugar de por índice (que entiendo es tu problema).
Un abrazo Marc ;-)
Hola Xavi,
El problema es que las impresoras especificadas en Printers parece ser que no reflejan la realidad de un momento dado sino que reflejan como estaban las impresoras al iniciar la aplicación Delphi (y en Windows 7 y Windows 8 aparentemente las impresoras disponibles en el sistema a veces varían a lo largo de la sesión Windows, imagino que debido a impresoras como la Fax, OneNote, etc. ...).
Una abraçada.
#5
Escrito 05 noviembre 2013 - 01:17
se me ocurre que podría servirte el código que publiqué en mi blog sobre un monitor de impresiones.
El método getprinters obtiene las impresoras y tal vez pueda servirte para redefinir a que impresora quieres enviar el trabajo.
delphi
Procedure TfrmMonitor.GetPrinters; Var Needed, i: Cardinal; begin If not enumprinters(PRINTER_ENUM_LOCAL, nil, 5, nil, 0, Needed, NumPrinters) then ppi5 := GetMemory(Needed); if assigned(ppi5) then enumprinters(PRINTER_ENUM_LOCAL, nil, 5, ppi5, Needed, Needed, NumPrinters); SetLength(APrinterInfo, NumPrinters); For i := 0 To NumPrinters - 1 Do begin APrinterInfo[i].Name := ppi5.pPrinterName; APrinterInfo[i].Pos := i; Inc(ppi5); if Length(ppi5.pPrinterName) > 0 then ListView1.Items.Add.Caption := ppi5.pPrinterName; End; ListView1.Columns.Items[0].Width := 300; End;
#6
Escrito 06 noviembre 2013 - 02:38
Has probado con Printer.Refresh;??
#7
Escrito 10 noviembre 2013 - 12:30
Bones
Has probado con Printer.Refresh;??
Hola xiquet.
Sí, lo probé, no funciona, aunque no recuerdo exactamente si el método no está disponible o bien simplemente no hace nada.
#8
Escrito 10 noviembre 2013 - 12:43
Existir, existe, y funcionar, funciona. He hecho en D6 la siguiente prueba: formulario con un botón y un memo. El botón simplemente hace un Printer.Refresh y actualiza el memo con la lista de impresoras. Ejecuto el programa y le doy al botón y me muestra las impresoras del sistema; añado una nueva impresora y vuelvo a pulsar el botón mostrando en el memo la nueva lista de impresoras con la impresora que acabo de añadir.
Haz la prueba a ver :-)
Una abraçada nen!!
#9
Escrito 11 noviembre 2013 - 10:14
Bones Mar
Existir, existe, y funcionar, funciona. He hecho en D6 la siguiente prueba: formulario con un botón y un memo. El botón simplemente hace un Printer.Refresh y actualiza el memo con la lista de impresoras. Ejecuto el programa y le doy al botón y me muestra las impresoras del sistema; añado una nueva impresora y vuelvo a pulsar el botón mostrando en el memo la nueva lista de impresoras con la impresora que acabo de añadir.
Haz la prueba a ver :-)
Una abraçada nen!!
Wow, tienes toda la razón, he hecho esa prueba y menuda sorpresa me he llevado.

Entonces mi problema tiene otro motivo y todo este tiempo he mirado el sitio equivocado.
Moltes gràcies, nen.