In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Modificar Formularios de Impresión utilizando la API de Windows

Foro público de Xailer en español
Responder
Avatar de Usuario
Shadax
Mensajes: 104
Registrado: Lun Mar 14, 2011 12:32 pm

Modificar Formularios de Impresión utilizando la API de Windows

Mensaje 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.
Avatar de Usuario
ignacio
Site Admin
Mensajes: 9452
Registrado: Lun Abr 06, 2015 8:00 pm
Ubicación: Madrid, Spain
Contactar:

Modificar Formularios de Impresión utilizando la API de Windows

Mensaje 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
Ignacio Ortiz de Zúñiga
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com
Avatar de Usuario
Shadax
Mensajes: 104
Registrado: Lun Mar 14, 2011 12:32 pm

Modificar Formularios de Impresión utilizando la API de Windows

Mensaje por Shadax »

No hay problema Ignacio, subid el código puesto que lo he posteado con ánimo de aportar cosas que puedan ser útiles.
joselalinf
Mensajes: 291
Registrado: Jue Ene 31, 2013 1:10 pm

Modificar Formularios de Impresión utilizando la API de Windows

Mensaje 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
Avatar de Usuario
Shadax
Mensajes: 104
Registrado: Lun Mar 14, 2011 12:32 pm

Modificar Formularios de Impresión utilizando la API de Windows

Mensaje 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.
Responder