PDA

Ver la Versión Completa : ¿Cómo conocer las capacidades de las impresoras?


ElDuc
06-06-2014, 12:26:44
Hola a todos,

Estoy parado y si trabajo, necesito ocupar mi tiempo para escapar de la locura.

Como hobby, programo en Delphi desde la versión 2 que compré en El Corte Inglés (disquetes).

Como reto me he propuesto hacer un generador de informes que pueda utilizar en mis programas, soy consciente que existen multitud de estos generadores y que el propio Delphi (20120) trae el Rave Reports.

Pero lo que yo deseo es enfrentarme a un reto que me tenga ocupado y distraído, tengo 57 años y me temo que soy de los que ya no volverán a trabaja.

Perdonad esta pequeña introducción, la he hecho para que los colegas que lean mis preguntas, puedan entender lo que busco y que ya sé que estoy intentando inventar la rueda, pero ahora mismo es lo que me hace ilusión.

Vamos!, el problema es que el diseño lo realizas en una pantalla con unos ppp determinados, en mi caso 96 (Scrren.PixelsPerInch), pero luego imprimirás en una impresora que también tiene su resolución, puede imprimir hasta DIN A4, DIN A3, etc., además las impresoras suelen tener unos márgenes mínimos en los que no imprimen.

¿Alguien puede orientarme cómo averiguar todas estas cosas desde mi programa Delphi?

Muchas gracias.

engranaje
06-06-2014, 14:59:47
Te dejo aqui un procedimiento que puedes probar e igual te sirve de pista para seguir:

procedure MuestraInfoImpresora;

var
Log : TstringList;
i:integer;
LeftWaste,
TopWaste,
TotalPageWidth,
TotalPageHeight,
PageWidth,
PageHeight: integer;

strDatosImpresora:string;

begin
Log := tstringlist.create;
try
if printer.printers.count>0 then
begin

Log.add('printers.count > 0');

try
LeftWaste:=round(GetDeviceCaps(Printer.Handle,PHYSICALOFFSETX));
Log.add('LeftWaste = ' + inttostr(LeftWaste));
except
Log.add('Error asignando LeftWaste');
end;

try
TopWaste:=round(GetDeviceCaps(Printer.Handle,PHYSICALOFFSETX));
Log.add('TopWaste = ' + inttostr(TopWaste));
except
Log.add('Error asignando TopWaste');
end;

try
TotalPageWidth:=round(GetDeviceCaps(Printer.Handle,PHYSICALWIDTH));
Log.add('TotalPageWidth = ' + inttostr(TotalPageWidth));
except
Log.add('Error asignando TotalPageWidth');
end;

try
TotalPageHeight:=round(GetDeviceCaps(Printer.Handle,PHYSICALHEIGHT));
Log.add('TotalPageHeight = ' + inttostr(TotalPageHeight));
except
Log.add('Error asignando TotalPageHeight');
end;

try
PageWidth:=round(GetDeviceCaps(Printer.Handle,HorzRes)/
GetDeviceCaps(printer.Handle,LogPixelsX)*Screen.PixelsPerInch);
Log.add('PageWidth = ' + inttostr(PageWidth));
except
Log.add('Error asignando PageWidth');
end;

try
PageHeight:=round(GetDeviceCaps(Printer.Handle,VertRes)/
GetDeviceCaps(printer.Handle,LogPixelsY)*Screen.PixelsPerInch);
Log.add('PageHeight = ' + inttostr(PageHeight));
except
Log.add('Error asignando PageHeight');
end;

end
else
begin
Log.add('printers.count <= 0');
end;

for i := 0 to Log.count-1 do
begin
strDatosImpresora := strDatosimpresora + #13 + Log.strings[i];
end;

MessageDlg(strDatosImpresora, mtInformation,[mbOk], 0);
finally

end;
end;

Hay que añadir al uses printers;

Casimiro Notevi
06-06-2014, 15:09:22
Hola a todos, Estoy parado y si trabajo, necesito ocupar mi tiempo para escapar de la locura.
Vaya, pues sí, es mejor hacer cosas, buscarse entretenimientos.
Por cierto, creo recordar que eres de Madrid, ahí puedes tener oportunidad de encontrar ofertas para programadores senior delphi.
Hazte una lista de cosas para hacer :)
Ah, se me olvidaba, Report Manager (http://reportman.sourceforge.net/indexes.html) es libre y lo mismo puedes fijarte en su código para hacer el tuyo y para ver cómo hace distintas cosas, etc.

Neftali [Germán.Estévez]
06-06-2014, 15:40:29
Es posible que puedes obtener mucha de esa información utilizando WMI.
En concreto la clase Win32_Printer (http://msdn.microsoft.com/en-us/library/aa394363(v=vs.85).aspx) te da bastante información.

class Win32_Printer : CIM_Printer
{
uint32 Attributes;
uint16 Availability;
string AvailableJobSheets[];
uint32 AveragePagesPerMinute;
uint16 Capabilities[];
string CapabilityDescriptions[];
string Caption;
string CharSetsSupported[];
string Comment;
uint32 ConfigManagerErrorCode;
boolean ConfigManagerUserConfig;
string CreationClassName;
uint16 CurrentCapabilities[];
string CurrentCharSet;
uint16 CurrentLanguage;
string CurrentMimeType;
string CurrentNaturalLanguage;
string CurrentPaperType;
boolean Default;
uint16 DefaultCapabilities[];
uint32 DefaultCopies;
uint16 DefaultLanguage;
string DefaultMimeType;
uint32 DefaultNumberUp;
string DefaultPaperType;
uint32 DefaultPriority;
string Description;
uint16 DetectedErrorState;
string DeviceID;
boolean Direct;
boolean DoCompleteFirst;
string DriverName;
boolean EnableBIDI;
boolean EnableDevQueryPrint;
boolean ErrorCleared;
string ErrorDescription;
string ErrorInformation[];
uint16 ExtendedDetectedErrorState;
uint16 ExtendedPrinterStatus;
boolean Hidden;
uint32 HorizontalResolution;
datetime InstallDate;
uint32 JobCountSinceLastReset;
boolean KeepPrintedJobs;
uint16 LanguagesSupported[];
uint32 LastErrorCode;
boolean Local;
string Location;
uint16 MarkingTechnology;
uint32 MaxCopies;
uint32 MaxNumberUp;
uint32 MaxSizeSupported;
string MimeTypesSupported[];
string Name;
string NaturalLanguagesSupported[];
boolean Network;
uint16 PaperSizesSupported[];
string PaperTypesAvailable[];
string Parameters;
string PNPDeviceID;
string PortName;
uint16 PowerManagementCapabilities[];
boolean PowerManagementSupported;
string PrinterPaperNames[];
uint32 PrinterState;
uint16 PrinterStatus;
string PrintJobDataType;
string PrintProcessor;
uint32 Priority;
boolean Published;
boolean Queued;
boolean RawOnly;
string SeparatorFile;
string ServerName;
boolean Shared;
string ShareName;
boolean SpoolEnabled;
datetime StartTime;
string Status;
uint16 StatusInfo;
string SystemCreationClassName;
string SystemName;
datetime TimeOfLastReset;
datetime UntilTime;
uint32 VerticalResolution;
boolean WorkOffline;
};



Si buscas en el FTP o en los mensajes antiguos, verás que hay ejemplos (yo mismo he colgado varios) de cómo utilizar WMI. Te pueden servir para hacer algunas pruebas, ya que son fácilmente adaptable a esta clase.

Si te cuadra y no quieres hacerlo manualmene el paquete GLibWMI (http://sourceforge.net/projects/glibwmi/), ya lleva implementado un componente para esta clase.

ElDuc
06-06-2014, 16:19:13
Muchas gracias a todos, voy a trabajar con vuestras propuestas y ya os iré diciendo.

Si al final queda algo positivo, os lo digo y lo cuelgo en el club.

Gracias por vuestros ánimos y ayuda.

newtron
06-06-2014, 18:34:35
Hola.

No sé si imaginas en el "jardín" que te estás metiendo. Te lo comento porque ese desarrollo puede costar meses de trabajo, incluso años. Tendrás que hacer un programa para diseñar visualmente los reportes teniendo en cuenta de que puedes querer hacer grupos con sus cabeceras y pies, títulos, piés de página, insertar imágenes, incluir campos de distintas tablas, etc. y luego una función o procedimiento que al llamarlo convierta todo eso en un informe.

Te lo comento porque nosotros usamos uno propio y sé lo complicado que puede resultar, eso si, para entretenerte es un desarrollo estupendo. :D

Como te han comentado Report Manager es libre y puedes ver cómo funciona pero si quieres algo más "casero" te puedo enviar lo que nosotros tenemos desarrollado por si te sirve de guía.

Saludos

ElDuc
06-06-2014, 18:53:26
Gracias [newtron],

Como se trata de ocupar la mente seguiré con el empeño, consciente de que seguramente no haré más que perder el tiempo, pero de eso se trata ¿no?

No obstante si veo que me atranco mucho, cosa muy posible, igual te acepto lo que me propones.

Gracias otra vez.

mamcx
06-06-2014, 19:17:23
Una alternativa muy interesante para hacer esto: Usar HTML + JS & exportar a PDF. Eso es lo que estoy haciendo para generar facturas para mi app en iOS (iOS no tiene ningun generador de reportes como en windows).

La ventaja? El diseño de los reportes es totalmente libre de restricciones. El problema es que no hay control muy directo, asi que si es para impresoras de punto no funciona.

newtron
07-06-2014, 09:07:15
Nosotros lo que hacemos es que el programa "diseñador" genera un fichero .txt de los de toda la vida con cada uno de los campos y características del informe, en principio los datos generales del mismo como longitud del papel, número de copias, parámetros, tabla o tablas, paneles, etc. y luego vamos detallando uno por uno cada uno de los campos con sus características como fuente, tamaño, campo y tabla y esas cosas.

Cuando se quiere lanzar el informe llamamos a una función con el nombre del fichero .txt y lo genera.
Se puede lanzar directamente a la impresora o a pantalla con opciones de exportar a distintos formatos.