Página 1 de 1

Modificar Formularios de Impresión utilizando la API de Windows

Publicado: Jue Feb 21, 2013 7:18 pm
por Shadax
Buenas tardes a todos.
Hoy me he puesto a echarle mano a la API de Windows para ver si finalmente era posible obtener, crear, modificar... Tipos de papel existentes en el Servidor de impresión de un equipo.
Y bueno, si es posible!
Para poder modificar los tipos de papel que encontramos aquí­:


Me las he apañado así­:
XAILER

********************************************************************************
* Descripción : Configura el tipo de papel indicado en la impresora deseada.
* Parámetros : cImpresora, cTipoPapel, nAncho, nAlto
* Autor : Joan Ramón Tur
* Fecha : 18/04/2011
********************************************************************************
FUNCTION lConfigurarImpresora( cImpresora, cTipoPapel, nAncho, nAlto )
//------------------------------------------------------------------------------
LOCAL lResultado
LOCAL cResultado
DEFAULT cImpresora TO "Nombre_Dispositivo"
DEFAULT cTipoPapel TO "A4"
DEFAULT nAncho TO 210000
DEFAULT nAlto TO 297000
cResultado := CONFIGURARPAPELIMPRESORA( cImpresora, cTipoPapel, nAncho, nAlto )
IF cResultado != "OK"
lResultado := .F.
ELSE
lResultado := .T.
ENDIF
RETURN lResultado

C

#pragma BEGINDUMP
#include "Windows.h"
#include "wininet.h"
#include "Xailer.h"
HB_FUNC_STATIC( CONFIGURARPAPELIMPRESORA )
{
/* ESTA ESTRUCTURA ES NECESARIA PARA LA OBTENCIí“N DEL TIPO DE FORMULARIO */
typedef struct _FORM_INFO_1 {
DWORD Flags;
LPTSTR pName;
SIZEL Size;
RECTL ImageableArea;
} FORM_INFO_1, *PFORM_INFO_1;
/* HANDLE QUE ME DEVOLVERí OPENPRINTER */
HANDLE p_hPrinter;
/* ESTRUCTURA TIPO FORM_INFO_1 QUE CONTENDRí LAS CARACTERíSTICAS DEL FORM */
FORM_INFO_1* pForm;
/* TAMAí‘O DE BUFFER NECESARIO PARA LA OBTENCIí“N DEL FORM */
DWORD dwBytesNeeded;
/* APERTURA DE LA IMPRESORA QUE NOS INTERESA PARA OBTENCIí“N DEL FORM */
if (OpenPrinter(hb_parc(1), &p_hPrinter, NULL))
{
/* TENGO EL HANDLE DE LA IMPRESORA Y YA PUEDO OBTENER SUS FORMS.
PRIMERO OBTENGO EL TAMAí‘O DEL BUFFER REQUERIDO */
GetForm(p_hPrinter, hb_parc(2), 1, NULL, NULL, &dwBytesNeeded);
pForm = (FORM_INFO_1 *)GlobalAlloc(GPTR, dwBytesNeeded);
/* AHORA QUE TENGO EL TAMAí‘O DE BUFFER NECESARIO, OBTENGO EL FORM */
if (GetForm(p_hPrinter, hb_parc(2), 1, (LPBYTE)pForm, dwBytesNeeded, &dwBytesNeeded))
{
/* ESTABLEZCO ANCHO Y ALTO DEL PAPEL */
pForm->Size.cx = hb_parnl(3);
pForm->Size.cy = hb_parnl(4);
/* PODRíA CONFIGURAR LOS MíRGENES PERO
LO DEJO COMENTADO PORQUE NO ME INTERESA */
// pForm->ImageableArea.Top = hb_parnl(/*PARíMETRO*/);
// pForm->ImageableArea.Bottom = hb_parnl(/*PARíMETRO*/);
// pForm->ImageableArea.Left = hb_parnl(/*PARíMETRO*/);
// pForm->ImageableArea.Right = hb_parnl(/*PARíMETRO*/);
if (!SetForm(p_hPrinter, pForm->pName, 1, (LPBYTE)pForm))
{
GlobalFree(pForm);
hb_retc( "No pudieron configurarse las dimensiones del ticket." );
}
GlobalFree(pForm);
hb_retc("OK");
}
GlobalFree(pForm);
hb_retc( "No pudo localizarse el tipo de papel especificado." );
}
else
{
hb_retc( "No pudo localizarse la impresora." );
}
}
#pragma ENDDUMP

El retorno que hago desde C es una cadena, pero bien podrí­a devolver un lógico simplemente. Le he metido cadena para saber por dónde puede fallar el proceso.
Espero que os sirva de utilidad para poder gestionaros vuestros propios tipos de papel. Creo que puede estar bastante interesante.

Modificar Formularios de Impresión utilizando la API de Windows

Publicado: Vie Feb 22, 2013 12:10 pm
por ignacio
Hola,
Las propiedades nPaperLength, nPaperWidth y PaperSizeType utilizan los mecanismos estándar que establece el API de Windows para cambiar dicho valores. Dichas operaciones consisten básicamente en establecer valores en estructuras internas (pDevMode) que luego se utilizan cuando se ejecuta cualquier trabajo de impresión. Por lo tanto no es posible a priori saber si la operación ha podido realizarse con éxito.
Por el contrario, la función SetForm() que estás utilizando si permite saber si la operación ha podido realizarse con éxito por tratarse de una función sí­ncrona que se conecta con la impresora, pero tiene el inconveniente de que puede tardar un tiempo importante en responder, sobre todo si la impresora no es local.
Por lo que veo, incluso en determinados casos es la única forma de poder establecer dichos valores.
Te animo a que subas dicho código al área de descargas o nos des tu permiso para subirlo en tu nombre. Estoy convencido que puede ser útil a mucha gente.
Un saludo

Modificar Formularios de Impresión utilizando la API de Windows

Publicado: Vie Feb 22, 2013 12:21 pm
por Shadax
No hay problema Ignacio, subid el código puesto que lo he posteado con ánimo de aportar cosas que puedan ser útiles.

Modificar Formularios de Impresión utilizando la API de Windows

Publicado: Vie Feb 22, 2013 2:05 pm
por joselalinf
Joan Ramón,
a primera vista ese código te va a cascar la aplicación y probablemente el
sistema operativo.
Asegúrate de liberar la memoria que reservas con GloballAlloc() con
GlobalFree(). O mejor aún, cámbialas por hb_xgrab()/hb_xfree() que
penalizan menos el rendimiento.
Saludos,
José Lalí­n

Modificar Formularios de Impresión utilizando la API de Windows

Publicado: Vie Feb 22, 2013 4:27 pm
por Shadax
Bueno, eso es cierto. Es algo que debo tener en cuenta y se me ha pasado, pero ya libero memoria en el código que tengo. Corregid ese detalle y colgadlo si lo véis útil. Gracias por la observación José.
Por cierto ¿tanto penaliza el Alloc frente a hb_xgrab? Ahora me ha saltado la curiosidad...
****
EDIT
****
- He editado el código para meterle los <GlobalFree(pForm);> que no puse cuando posteé el ejemplo.