FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour PrinterSetup
Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

PrinterSetup

Posted: Thu Oct 01, 2026 04:28 AM

Buenos días compañeros,

Con la última versión de fwh me está ocurriendo algo que no me ocurría antes con el mismo código (tanto en harbour como en xharbour). No sé si es que estoy haciendo algo mal. Resulta que con PrinterSetup cambiaba la impresora antes de entrar en el preview y me respetaba el cambio en toda la sesión. Ahora al entrar en el preview, aunque he cambiado la impresora previamente, no lo respeta y me sale la impresora predeterminada. ¿Os ocurre lo mismo?

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 09:40 AM

Como haces, asi?

FUNCTION Imprimir()

   LOCAL oPrn

   PrinterSetup() 

   PRINT oPrn NAME "Meu Relatório" PREVIEW

  PAGE

     oPrn:Say( 100, 100, "Texto impresso na impressora selecionada." )

  ENDPAGE

   ENDPRINT

RETURN NIL

ó asi?

   PRINT oPrn NAME "Relatório" FROM USER PREVIEW

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 10:00 AM

Así: PRINT oPrn NAME "Meu Relatório" PREVIEW

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 10:16 AM
Manuel Aranda wrote:

Así: PRINT oPrn NAME "Meu Relatório" PREVIEW

Mejor así:

 PRINT oPrn NAME "Mi Informe" PREVIEW MODAL

¿Cambias la impresora en tiempo real en el PREVIEW? Si es así, entiendo que el cambio es solo para la impresión de este PREVIEW. Para cambiar la impresora y que quede fija (DEFAULT) se hace de otra manera. No recuerdo cuál ahora mismo.

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 351
Joined: Wed Nov 02, 2005 03:28 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 11:18 AM

Solo por probar, has probado a activar en impresoras "Permitir que Windows administre mi impresora predeterminada"

La opción Permitir que Windows administre mi impresora predeterminada hace que el sistema operativo elija de forma automática como predeterminada la última impresora que hayas utilizado en ese equipo.

Ahora hay que tener en cuenta :

Bloqueo manual: Mientras esté activada, no puedes fijar de forma permanente una impresora específica como predeterminada desde el menú clásico.

Saludos,
Regards,

Jose Luis Alepuz
joseluis@mancomputer.com
www.mancomputer.com
Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 11:25 AM

¿Puedes decirme algo al respecto Fivetech IA?
Te diré que le he preguntado a Instinct por el problema y lo ha solucionado facilitándome un nuevo printdc.c modificado por ella. Esta es la explicación que me ha dado:

En FiveWin 26.03, la impresora elegida con PrinterSetup() no se conserva entre trabajos de impresión. Al cerrar un TPrinter (ENDPRINT), TPrinter:End() llama a PrinterEnd(), que libera pd.hDevNames y pd.hDevMode y deja bInit=FALSE. El siguiente PrinterInit() vuelve a consultar Windows con PD_RETURNDEFAULT, así que se recupera la impresora predeterminada y se pierde la elegida con sus ajustes de driver.

Esto afecta también a cualquier código que cree y cierre un PRINT solo para consultar cModel: ese cierre borra la selección global.

Propuesta: guardar, al aceptar PrinterSetup(), una copia completa de DEVNAMES y DEVMODE (con los datos privados del driver), independiente del estado del trabajo. PrinterInit() la restauraría clonándola en lugar de consultar Windows. PrinterEnd() seguiría liberando el trabajo igual. La copia se sustituye en cada aceptación, se libera al salir del proceso y no cambia la impresora predeterminada de Windows.

Idealmente, como opciones explícitas de FiveWin: conservar la configuración entre trabajos y reiniciarla a la predeterminada de Windows, sin cambiar PrinterEnd() globalmente.

Limitaciones: PrinterSetup() devuelve 0 igual al cancelar que ante un error, y no se ha probado con otros drivers, xHarbour ni 64 bits.

Y este es el contenido de printdc.c modificado por Instinct

// #define ENDDOC    _ENDDOC
// #define DRAFTMODE _DRAFTMODE
// #define STARTDOC  _STARTDOC

#include <Windows.h>
#include <stdlib.h>
#include <string.h>

#define IF(x,y,z) ((x)?(y):(z))
#define MIN(a,b)  (int) (((int)(a) < (int)(b)) ? (a) : (b))	
	
#ifndef __FLAT__
#include <Print.h>
#endif

#include <CommDlg.h>
#include <hbapi.h>
#include <hbapiitm.h>

typedef struct
{
    WORD vlen;
    BYTE data[10];
} ESCDATA;

BOOL IsWin95( void );
static BOOL CALLBACK PrnSetupHkProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPar);
#ifndef __FLAT__
static void SendFile(HDC, LPSTR);
#endif

typedef struct
{
  WORD wSize;
  BYTE bData[2];
} PASSTHROUGHSTRUCT, FAR *LPPTS;

extern HINSTANCE GetInstance( void );

static far PRINTDLG pd;
static far BOOL bInit = FALSE;
static far RECT rtMargin = { 2500, 2500, 2500, 2500 };

//----------------------------------------------------------------------------//

/* Agrario v44: session copy of the last accepted printer setup.
   The working PRINTDLG still belongs to FiveWin and is freed by PrinterEnd.
   Keep the entire blocks, including the driver's private DEVMODE bytes. */
static HGLOBAL agrNames = NULL;
static HGLOBAL agrMode  = NULL;
static BOOL agrExitRegistered = FALSE;

static void AgrFreeSession( void )
{
   if( agrNames ) GlobalFree( agrNames );
   if( agrMode ) GlobalFree( agrMode );
   agrNames = agrMode = NULL;
}

static HGLOBAL AgrCloneBlock( HGLOBAL source )
{
   HGLOBAL copy;
   LPVOID from, to;
   SIZE_T size;

   if( ! source ) return NULL;
   size = GlobalSize( source );
   if( ! size ) return NULL;
   copy = GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
   if( ! copy ) return NULL;
   from = GlobalLock( source );
   to = GlobalLock( copy );
   if( ! from || ! to )
   {
      if( from ) GlobalUnlock( source );
      if( to ) GlobalUnlock( copy );
      GlobalFree( copy );
      return NULL;
   }
   memcpy( to, from, size );
   GlobalUnlock( source );
   GlobalUnlock( copy );
   return copy;
}

static void AgrSaveSession( void )
{
   HGLOBAL names = AgrCloneBlock( pd.hDevNames );
   HGLOBAL mode = AgrCloneBlock( pd.hDevMode );

   if( ! names || ! mode )
   {
      if( names ) GlobalFree( names );
      if( mode ) GlobalFree( mode );
      MessageBoxA( GetActiveWindow(),
         "No se han podido guardar los ajustes de impresora para esta sesion.",
         "Impresora", MB_OK | MB_ICONWARNING );
      return;
   }
   AgrFreeSession();
   agrNames = names;
   agrMode = mode;
   if( ! agrExitRegistered )
   {
      agrExitRegistered = ( atexit( AgrFreeSession ) == 0 );
   }
}

static BOOL AgrRestoreSession( void )
{
   HGLOBAL names = AgrCloneBlock( agrNames );
   HGLOBAL mode = AgrCloneBlock( agrMode );

   if( ! names || ! mode )
   {
      if( names ) GlobalFree( names );
      if( mode ) GlobalFree( mode );
      MessageBoxA( GetActiveWindow(),
         "No se han podido recuperar los ajustes de impresora de esta sesion.",
         "Impresora", MB_OK | MB_ICONWARNING );
      return FALSE;
   }
   if( pd.hDevNames ) GlobalFree( pd.hDevNames );
   if( pd.hDevMode ) GlobalFree( pd.hDevMode );
   pd.hDevNames = names;
   pd.hDevMode = mode;
   return TRUE;
}

static void PrinterInit( void )
{
   if( ! bInit )
   {
      bInit = TRUE;
      memset( ( char * ) &pd, 0, sizeof( PRINTDLG ) );
      pd.lStructSize = sizeof( PRINTDLG );
      pd.hwndOwner   = GetActiveWindow();
      pd.Flags       = PD_RETURNDEFAULT ;
      pd.nFromPage   = 1;
      pd.nToPage     = 1;
      pd.nMinPage    = 1;
      pd.nMaxPage    = 65535;
      pd.nCopies     = 1;
      if( agrNames && agrMode )
         AgrRestoreSession();
      else
         PrintDlg( &pd );
   }
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRINTERINIT ) //
#else
   HB_FUNC( PRINTERINI ) //T
#endif
{
   bInit = FALSE;
}

//----------------------------------------------------------------------------//

HB_FUNC( PRINTEREND )
{
   if( bInit )
   {
      if( pd.hDevMode != NULL )
      {
         GlobalFree( pd.hDevMode );
         pd.hDevMode = NULL;
      }

  if( pd.hDevNames != NULL )
  {
     GlobalFree( pd.hDevNames );
     pd.hDevNames = NULL;
  }
  bInit = FALSE;
   }

   hb_ret();
}

//----------------------------------------------------------------------------//

#ifdef __FLAT__
   HB_FUNC( GETPRINTDC ) // ( hWndOwner, bSel, bPage ) --> hDC
   {
      BOOL bSel  = hb_parl( 2 );
      BOOL bPage = hb_parl( 3 );

  PrinterInit();

  #ifndef _WIN64
     pd.hwndOwner = ( HWND ) hb_parnl( 1 );
  #else
     pd.hwndOwner = ( HWND ) hb_parnll( 1 );
  #endif
  pd.Flags     = PD_ALLPAGES | PD_RETURNDC | PD_HIDEPRINTTOFILE;

  pd.Flags &= bSel ? ~PD_NOSELECTION : ~PD_SELECTION;
  pd.Flags |= bSel ? PD_SELECTION : PD_NOSELECTION;

  if( bSel || !bPage )
     pd.nFromPage = pd.nToPage = 1;
  else
     pd.Flags |= bPage ? PD_PAGENUMS : 0;

  #ifndef _WIN64
     hb_retnl( ( LONG ) ( PrintDlg( &pd ) ? pd.hDC : 0 ) );
  #else
     hb_retnll( ( LONGLONG ) ( PrintDlg( &pd ) ? pd.hDC : 0 ) );
  #endif
   }
#else
   HB_FUNC( GETPRINTDC ) // ( hWndOwner ) --> hDC
   {
      PrinterInit();

  pd.hwndOwner = ( HWND ) hb_parnl( 1 );
  pd.Flags     = PD_RETURNDC | PD_USEDEVMODECOPIES |
                 PD_HIDEPRINTTOFILE | PD_NOSELECTION ;

  hb_retnl( ( LONG ) ( PrintDlg( &pd ) ? pd.hDC : 0 ) );
   }
#endif

//----------------------------------------------------------------------------//

#define WF_WINNT  0x4000

#ifdef __HARBOUR__
   HB_FUNC( PRINTERSETUP ) // ( hWndOwner ) --> nil
#else
   HB_FUNC( PRINTERSET ) // up( hWndOwner ) --> nil
#endif
{
   BOOL accepted;

   PrinterInit();

   #ifndef _WIN64
      pd.hwndOwner = IF( hb_pcount() == 0, GetActiveWindow(), ( HWND ) hb_parnl( 1 ) );
   #else
      pd.hwndOwner = IF( hb_pcount() == 0, GetActiveWindow(), ( HWND ) hb_parnll( 1 ) );
   #endif
   pd.Flags     = PD_PRINTSETUP | PD_USEDEVMODECOPIES | PD_RETURNDC;

   #ifndef __FLAT__
   if( IsWin95() || GetWinFlags() & WF_WINNT )
    {
   #endif
      pd.Flags = pd.Flags  | PD_ENABLESETUPHOOK;

  #ifndef __FLAT__
     pd.lpfnSetupHook = PrnSetupHkProc;
  #else
     pd.lpfnSetupHook = ( LPPRINTHOOKPROC ) ( void (*)( void ) ) PrnSetupHkProc;
  #endif

   #ifndef __FLAT__
    }
   #endif

   accepted = PrintDlg( &pd );
   if( accepted )
      AgrSaveSession();
   else if( agrNames && agrMode )
      AgrRestoreSession();

   #ifndef _WIN64
      hb_retnl( ( LONG ) ( accepted ? pd.hDC : 0 ) );
   #else
      hb_retnll( ( LONGLONG ) ( accepted ? pd.hDC : 0 ) );
   #endif 
}

//----------------------------------------------------------------------------//

static BOOL CALLBACK PrnSetupHkProc(HWND hDlg,
                                    UINT uMsg,
                                    WPARAM wParam,
                                    LPARAM lPar)
{
   HB_SYMBOL_UNUSED( hDlg );
   HB_SYMBOL_UNUSED( uMsg );
   HB_SYMBOL_UNUSED( wParam );
   HB_SYMBOL_UNUSED( lPar );
   

   return FALSE;
}

//----------------------------------------------------------------------------//

#ifdef __FLAT__

HB_FUNC( PAGESETUP )
{
   LPDEVNAMES lpDevNames;
   LPDEVMODE  lpDevMode;
   PAGESETUPDLG psd;

   rtMargin.top    = IF( HB_ISNUM( 2 ), hb_parni( 2 ), rtMargin.top );
   rtMargin.left   = IF( HB_ISNUM( 3 ), hb_parni( 3 ), rtMargin.left );
   rtMargin.right  = IF( HB_ISNUM( 4 ), hb_parni( 4 ), rtMargin.right );
   rtMargin.bottom = IF( HB_ISNUM( 5 ), hb_parni( 5 ), rtMargin.bottom );

   PrinterInit();

   lpDevNames = ( LPDEVNAMES ) GlobalLock( pd.hDevNames );
   lpDevMode  = ( LPDEVMODE ) GlobalLock( pd.hDevMode );

   memset( ( char * ) &psd, 0, sizeof( PAGESETUPDLG ) );
   psd.lStructSize = sizeof( PAGESETUPDLG );
   #ifndef _WIN64
      psd.hwndOwner   = IF( hb_pcount() == 0, GetActiveWindow(), ( HWND ) hb_parnl( 1 ) );
   #else
      psd.hwndOwner   = IF( hb_pcount() == 0, GetActiveWindow(), ( HWND ) hb_parnll( 1 ) );
   #endif
   psd.hDevNames   = lpDevNames;
   psd.hDevMode    = lpDevMode;
   psd.rtMargin    = rtMargin;

   #ifndef __FLAT__
   if( IsWin95() || GetWinFlags() & WF_WINNT )
   {
   #endif
      psd.Flags = PSD_MARGINS | PSD_INHUNDREDTHSOFMILLIMETERS |
                  PSD_ENABLEPAGESETUPHOOK;

  #ifndef __FLAT__
     psd.lpfnPageSetupHook = PrnSetupHkProc;
  #else
     psd.lpfnPageSetupHook = ( LPPAGESETUPHOOK ) ( void (*)( void ) ) PrnSetupHkProc;
  #endif

   #ifndef __FLAT__
   }
   #endif

   if( PageSetupDlg( &psd ) )
   {
      pd.hDevNames = psd.hDevNames;
      pd.hDevMode  = psd.hDevMode;

  rtMargin = psd.rtMargin;
   }

   GlobalUnlock( pd.hDevNames );
   GlobalUnlock( pd.hDevMode );
}

#endif

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PAGEGETMARGINS )
#else
   HB_FUNC( PAGEGETMAR )  // GINS()
#endif
{
   hb_reta( 4 );

   #ifdef __XPP__
      #define hb_storni( x, y, z ) STORNI( x, params, y, z )
   #endif

   hb_storvni( rtMargin.top, -1, 1 );
   hb_storvni( rtMargin.left, -1, 2 );
   hb_storvni( rtMargin.right, -1, 3 );
   hb_storvni( rtMargin.bottom, -1, 4 );
}

//----------------------------------------------------------------------------//

#undef STARTDOC

HB_FUNC( STARTDOC )
{
   DOCINFO info;
   char szDocName[ 32 ];
   int iLen = MIN( 31, hb_parclen( 2 ) );

   memcpy( szDocName, ( char * ) hb_parc( 2 ), iLen );
   szDocName[ iLen ] = 0;

   info.cbSize      = sizeof( DOCINFO );
   info.lpszDocName = ( LPSTR ) IF( HB_ISCHAR( 2 ), szDocName, "" );
   info.lpszOutput  = ( LPSTR ) IF( HB_ISCHAR( 3 ), hb_parc( 3 ), 0 );

   #ifdef __FLAT__
      info.lpszDatatype = 0;
      info.fwType = 0;
   #endif

   #ifndef _WIN64
      hb_retni( StartDoc( ( HDC ) hb_parnl( 1 ),       // hDC printer device
                        &info ) );
   #else
      hb_retni( StartDoc( ( HDC ) hb_parnll( 1 ),      // hDC printer device
                        &info ) );
   #endif
}

//----------------------------------------------------------------------------//

#undef ENDDOC

HB_FUNC( ENDDOC )
{
   #ifndef _WIN64
      hb_retnl( ( LONG ) EndDoc( ( HDC ) hb_parnl( 1 ) ) );     // hDC printer device
   #else
      hb_retnll( ( LONGLONG ) EndDoc( ( HDC ) hb_parnll( 1 ) ) );     // hDC printer device
   #endif
}

//----------------------------------------------------------------------------//

HB_FUNC( STARTPAGE )
{
   #ifndef _WIN64
      hb_retnl( ( LONG ) StartPage( ( HDC ) hb_parnl( 1 ) ) );  // hDC printer device
   #else
      hb_retnll( ( LONGLONG ) StartPage( ( HDC ) hb_parnll( 1 ) ) );  // hDC printer device
   #endif
}

//----------------------------------------------------------------------------//

HB_FUNC( ENDPAGE )
{
   #ifndef _WIN64
      hb_retnl( ( LONG ) EndPage( ( HDC ) hb_parnl( 1 ) ) );    // hDC printer device
   #else
      hb_retnll( ( LONGLONG ) EndPage( ( HDC ) hb_parnll( 1 ) ) );    // hDC printer device
   #endif
}

//----------------------------------------------------------------------------//

HB_FUNC( ESCAPE ) // ( hDC, nEscape, cInput, @cOutPut ) --> nReturn
{
   BYTE * pBuffer = ( BYTE * ) IF( hb_pcount() == 4, hb_xgrab( hb_parclen( 3 ) ), 0 );

   #ifndef _WIN64
      hb_retni( Escape( ( HDC ) hb_parnl( 1 ), hb_parni( 2 ), hb_parclen( 3 ), hb_parc( 3 ),
                      pBuffer ) );
   #else
      hb_retni( Escape( ( HDC ) hb_parnll( 1 ), hb_parni( 2 ), ( int ) hb_parclen( 3 ), hb_parc( 3 ),
                      pBuffer ) );
   #endif

   if( pBuffer )
   {
      hb_storclen( ( char * ) pBuffer, hb_parclen( 3 ), 4 );
      hb_xfree( pBuffer );
   }
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( GETPRINTDEFAULT ) // ( hWndOwner ) --> nil
#else
   HB_FUNC( GETPRINTDE ) // FAULT( hWndOwner ) --> nil
#endif
{
   LPDEVNAMES lpDevNames;
   LPDEVMODE  lpDevMode;

   PrinterInit();

   if( pd.hDevNames )
   {
      lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );
      lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

  #ifndef _WIN64
  hb_retnl( ( LONG ) CreateDC( ( LPSTR ) lpDevNames + lpDevNames->wDriverOffset,
                   ( LPSTR ) lpDevNames + lpDevNames->wDeviceOffset,
                   ( LPSTR ) lpDevNames + lpDevNames->wOutputOffset,
                   lpDevMode ) );
  #else
  hb_retnll( ( LONGLONG ) CreateDC( ( LPSTR ) lpDevNames + lpDevNames->wDriverOffset,
                   ( LPSTR ) lpDevNames + lpDevNames->wDeviceOffset,
                   ( LPSTR ) lpDevNames + lpDevNames->wOutputOffset,
                   lpDevMode ) );
  #endif

  GlobalUnlock( pd.hDevNames );
  GlobalUnlock( pd.hDevMode );
   }
   else
      hb_retnl( 0 );
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNOFFSET ) // ( hDC )  --> aPoint
{
   POINT pt;

   pt.y = 0;
   pt.x = 0;

   /*
   Escape( ( HDC ) hb_parnl( 1 ),
           GETPRINTINGOFFSET,
           NULL, NULL, ( LPPOINT ) &pt ) ;
   */
   

   #ifndef _WIN64
      pt.y = GetDeviceCaps( ( HDC ) hb_parnl( 1 ), PHYSICALOFFSETY	);       

      pt.x = GetDeviceCaps( ( HDC ) hb_parnl( 1 ), PHYSICALOFFSETX	);       

   #else
      pt.y = GetDeviceCaps( ( HDC ) hb_parnll( 1 ), PHYSICALOFFSETY	);       

      pt.x = GetDeviceCaps( ( HDC ) hb_parnll( 1 ), PHYSICALOFFSETX	);       

   #endif

   hb_reta( 2 );

   #ifdef __FLAT__
      #ifndef __HARBOUR__
         #define hb_storni( x, y, z ) STORNI( x, params, y, z )
      #endif
   #endif

   hb_storvni( pt.y, -1, 2 );
   hb_storvni( pt.x, -1, 1 );
}

//----------------------------------------------------------------------------//

#ifdef __FLAT__

#ifdef __HARBOUR__
   HB_FUNC( PRNSETCOLLATE ) // ( lCollate )  --> lSuccess
#else
   HB_FUNC( PRNSETCOLL ) // ATE( lCollate )  --> lSuccess
#endif
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   if ( hb_parl( 1 ) )
      lpDevMode->dmCollate = DMCOLLATE_TRUE;
   else
      lpDevMode->dmCollate = DMCOLLATE_FALSE;

   GlobalUnlock( pd.hDevMode );

   hb_retl( TRUE );
}

#endif

//----------------------------------------------------------------------------//

HB_FUNC( RESETDC ) // hDC --> lSuccess
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode = ( LPDEVMODE ) GlobalLock( pd.hDevMode );

   #ifndef _WIN64
      hb_retl( ( BOOL ) ResetDC( ( HDC ) hb_parnl( 1 ), lpDevMode ) );
   #else
      hb_retl( ResetDC( ( HDC ) hb_parnll( 1 ), lpDevMode ) != 0 );
   #endif

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNGETSIZE ) // ( hDC)  --> aPoint
{
   POINT pt;

   pt.y = 0;
   pt.x = 0;

   #ifndef _WIN64
      Escape( ( HDC ) hb_parnl( 1 ),
              GETPHYSPAGESIZE,
              0, 0, ( LPPOINT ) &pt ) ;
   #else
      Escape( ( HDC ) hb_parnll( 1 ),
              GETPHYSPAGESIZE,
              0, 0, ( LPPOINT ) &pt ) ;
   #endif

   hb_reta( 2 );
   hb_storvni( pt.y, -1, 2 );
   hb_storvni( pt.x, -1, 1 );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNLANDSCAPE ) // --> lSuccess
#else
   HB_FUNC( PRNLANDSCA ) // PE --> lSuccess
#endif
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmOrientation = DMORIENT_LANDSCAPE;

   GlobalUnlock( pd.hDevMode );

   hb_retl( TRUE );
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNDUPLEX ) // ( nValue ) --> nOldValue
{
   LPDEVMODE  lpDevMode;
   int dmDuplex;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   dmDuplex = lpDevMode->dmDuplex;

   if( hb_pcount() > 0 )
      lpDevMode->dmDuplex = ( short ) hb_parni( 1 );

   hb_retni( dmDuplex );
   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

HB_FUNC( ISDUPLEXPRINTER )
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   hb_retl( lpDevMode->dmFields & DM_DUPLEX );
   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNSETSIZE )
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmFields      = lpDevMode->dmFields | DM_PAPERSIZE |
                              DM_PAPERLENGTH | DM_PAPERWIDTH;
   lpDevMode->dmPaperSize   = DMPAPER_USER;
   lpDevMode->dmPaperWidth  = ( short ) hb_parnl( 1 );
   lpDevMode->dmPaperLength = ( short ) hb_parnl( 2 );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNPORTRAIT ) // ()  --> lSuccess
#else
   HB_FUNC( PRNPORTRAI ) // T()  --> lSuccess
#endif
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmOrientation = DMORIENT_PORTRAIT;

   GlobalUnlock( pd.hDevMode );

   hb_retl( TRUE );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETORIENTATION ) // ()  --> nOldOrient
#else
   HB_FUNC( PRNGETORIE ) // NTATION()  --> nOldOrient
#endif
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   hb_retni( lpDevMode->dmOrientation );

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNSETCOPIES ) // ( nCopies )  --> lSuccess
#else
   HB_FUNC( PRNSETCOPI ) // ES( nCopies )  --> lSuccess
#endif
{
   LPDEVMODE lpDevMode;

   PrinterInit();

   lpDevMode = (LPDEVMODE) GlobalLock( pd.hDevMode );

   lpDevMode->dmCopies = ( short ) hb_parni( 1 );

   if( hb_pcount() == 2 )  // Compatibility with previous syntax!
      lpDevMode->dmCopies = ( short ) hb_parni( 2 );

   GlobalUnlock( pd.hDevMode );

   hb_retl( TRUE );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETPAGES ) // { nFrom, nTo }
#else
   HB_FUNC( PRNGETPAGE ) // S()  --> {nFrom, nTo}
#endif

{
   PrinterInit();

   hb_reta( 2 );

   #ifdef __XPP__
      #define hb_storni( x, y, z ) STORNI( x, params, y, z )
   #endif

   hb_storvni( pd.nFromPage, -1, 1 );
   hb_storvni( pd.nToPage, -1, 2 );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETCOPIES ) //  --> nCopies
#else
   HB_FUNC( PRNGETCOPI ) // ES()  --> nCopies
#endif
{
   LPDEVMODE lpDevMode;

   PrinterInit();

   lpDevMode = (LPDEVMODE) GlobalLock( pd.hDevMode );

   hb_retni( lpDevMode->dmCopies);

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETPAGNUMS ) //  --> lPageNums
#else
   HB_FUNC( PRNGETPAGN ) // UMS()  --> lPageNums
#endif
{
   PrinterInit();

   hb_retl( pd.Flags & PD_PAGENUMS );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETSELECTION ) //  --> lSelection
#else
   HB_FUNC( PRNGETSELE ) // CTION()  --> lSelection
#endif
{
   PrinterInit();

   hb_retl( pd.Flags & PD_SELECTION );
}

//----------------------------------------------------------------------------//

#ifdef __FLAT__

#ifdef __HARBOUR__
   HB_FUNC( PRNGETCOLLATE ) //  --> lCollate
#else
   HB_FUNC( PRNGETCOLL ) // ATE()  --> lCollate
#endif
{
   LPDEVMODE lpDevMode;

   PrinterInit();

   lpDevMode = ( LPDEVMODE ) GlobalLock( pd.hDevMode );

   hb_retl( lpDevMode->dmCollate );

   GlobalUnlock( pd.hDevMode );
}

#endif

//----------------------------------------------------------------------------//

HB_FUNC( PRINTERESC ) // ( hDC, cText ) --> lSuccess
{
   ESCDATA Data;
   WORD wLen = ( WORD ) hb_parclen( 2 );

   if( wLen > sizeof( Data.data ) )
      wLen = sizeof( Data.data );

   Data.vlen = wLen;
   memcpy( ( char * ) Data.data, ( char * ) hb_parc( 2 ), wLen );
   #ifndef _WIN64 
     hb_retni( Escape( ( HDC ) hb_parnl( 1 ), PASSTHROUGH, 0, (LPSTR) &Data, NULL ) );
   #else
     hb_retni( Escape( ( HDC ) hb_parnll( 1 ), PASSTHROUGH, 0, (LPSTR) &Data, NULL ) );
   #endif
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNGETNAME ) // () --> cPrinter
{
   LPDEVNAMES lpDevNames; 

   PrinterInit(); 

   if( pd.hDevNames ) 
   { 
      lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames ); 

  if( lpDevNames ) 
  { 
     hb_retc( ( LPSTR ) lpDevNames + lpDevNames->wDeviceOffset ); 
     GlobalUnlock( pd.hDevNames ); 
  } 
  else 
     hb_retc( "" ); 
   } 
   else 
      hb_retc( "" ); 
}

//----------------------------------------------------------------------------//

HB_FUNC( PRNGETPORT ) // () --> cPort
{
   LPDEVNAMES lpDevNames;

   PrinterInit();

   if( pd.hDevNames )
   {
      lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );
      if( lpDevNames )
      {
         hb_retc( ( LPSTR ) lpDevNames + lpDevNames->wOutputOffset );
         GlobalUnlock( pd.hDevNames );
      }
      else
         hb_retc( "" );
   }
   else
      hb_retc( "" );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNGETDRIVE ) // () --> cDriver
#else
   HB_FUNC( PRNGETDRIV ) // ER () --> cDriver
#endif
{
   LPDEVNAMES lpDevNames;

   PrinterInit();

   if( pd.hDevNames )
   {
      lpDevNames = (LPDEVNAMES) GlobalLock( pd.hDevNames );
      if( lpDevNames )
      {
         hb_retc( ( LPSTR ) lpDevNames + lpDevNames->wDriverOffset );
         GlobalUnlock( pd.hDevNames );
      }
      else
         hb_retc( "" );
   }
   else
      hb_retc( "" );
}
//----------------------------------------------------------------------------//

HB_FUNC( PRNSETPAGE )
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   if( pd.hDevMode )
   {
      lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );
      if( lpDevMode )
      {
         lpDevMode->dmPaperSize  = ( short ) hb_parni( 1 );
         GlobalUnlock( pd.hDevMode );
      }
   }
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( PRNBINSOURCE )  //( nBin )
#else
   HB_FUNC( PRNBINSOUR )  //CE( nBin )
#endif
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   if( pd.hDevMode )
   {
      lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );
      if( lpDevMode )
      {
         hb_retni( ( LONG ) lpDevMode->dmDefaultSource );

     if ( hb_pcount() > 0 )
     {
      lpDevMode->dmDefaultSource  = ( short ) hb_parni( 1 );
     }

     GlobalUnlock( pd.hDevMode );
  }
  else
     hb_retni( 0 );
   }
   else
      hb_retni( 0 );
}

//----------------------------------------------------------------------------//

#ifdef __HARBOUR__
   HB_FUNC( IMPORTRAWFILE ) // (hDC, cFile) --> lMode
#else
   HB_FUNC( IMPORTRAWF ) // ile(hDC, cFile) --> lMode
#endif
{
  int iEsc;

  iEsc = PASSTHROUGH;

  #ifndef _WIN64 
     if ( Escape( ( HDC ) hb_parnl( 1 ), QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
  #else
     if ( Escape( ( HDC ) hb_parnll( 1 ), QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
  #endif 
    {
     iEsc = EPSPRINTING;
     #ifndef _WIN64 
        if (Escape( ( HDC ) hb_parnl( 1 ), QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
     #else
        if (Escape( ( HDC ) hb_parnll( 1 ), QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
     #endif
      {
      iEsc = 1;
      #ifndef _WIN64
         Escape( ( HDC ) hb_parnl( 1 ), EPSPRINTING, sizeof(int), (LPSTR)&iEsc, NULL);
      #else
         Escape( ( HDC ) hb_parnll( 1 ), EPSPRINTING, sizeof(int), (LPSTR)&iEsc, NULL);
      #endif
      }
    #ifndef __FLAT__
    SendFile( ( HDC ) hb_parnl( 1 ), (LPSTR) hb_parc( 2 ));
    #endif

}
}

//----------------------------------------------------------------------------//

#define BUFSIZE 2048

#ifndef __FLAT__

static void SendFile(HDC hPrnDC, LPSTR szFile)
{
  static LPPTS lpPTS=NULL;          // Pointer to PASSTHROUGHSTRUCT
  OFSTRUCT ofs;
  HFILE hFile;

  hFile = OpenFile((LPSTR) szFile, &ofs, OF_READ);
  if (hFile == HFILE_ERROR)
    {
    hb_retni(0);
    return;
    }

  if (!lpPTS &&
       !(lpPTS = (LPPTS)GlobalLock(GlobalAlloc(GPTR, sizeof(WORD) + BUFSIZE))))
    {
    hb_retni(0);
    return;
    }

  do {
    lpPTS->wSize = _lread(hFile, lpPTS->bData, BUFSIZE);
    Escape(hPrnDC, PASSTHROUGH, NULL, (LPSTR)lpPTS, NULL);
    }
  while ((lpPTS->wSize == BUFSIZE));

  _lclose(hFile);
  hb_retni(1);

}

#endif

//----------------------------------------------------------------------------//

#undef DRAFTMODE

HB_FUNC( DRAFTMODE ) // lMode
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   if( pd.hDevMode )
   {
      lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );
      if( lpDevMode )
      {
         lpDevMode->dmFields        = lpDevMode->dmFields | DM_PRINTQUALITY;
         lpDevMode->dmPrintQuality  = IF( hb_parl( 1 ), -1, -4 );
         GlobalUnlock( pd.hDevMode );
      }
   }
}

//----------------------------------------------------------------------------//

HB_FUNC( SPOOLFILE )
{
   #ifndef __FLAT__
   hb_retni( SpoolFile( hb_parc( 1 ), hb_parc( 2 ), hb_parc( 3 ), hb_parc( 4 ) ) );
   #endif
}

//----------------------------------------------------------------------------//

HB_FUNC( devMODE ) // lMode
{
   /*
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   if( hb_pcount() )
   {
      lpDevMode->dmDeviceName  = hb_parc( 1, 1 );
      lpDevMode->dmSpecVersion = hb_parni( 1, 2 );
      lpDevMode->dm...
   }

   hb_reta( 26 );

   hb_storc( lpDevMode->dmDeviceName,     -1, 1 );
   hb_storni( lpDevMode->dmSpecVersion,   -1, 2 );
   hb_storni( lpDevMode->dmDriverVersion, -1, 3 );

   hb_stornl( lpDevMode->dmSpecVersion, -1, 2 ); // use stornl for 4 bytes

   BCHAR  dmDeviceName[CCHDEVICENAME];
   WORD   dmSpecVersion;
   WORD   dmDriverVersion;
   WORD   dmSize;
   WORD   dmDriverExtra;
   DWORD  dmFields;
   short  dmOrientation;
   short  dmPaperSize;
   short  dmPaperLength;
   short  dmPaperWidth;
   short  dmScale;
   short  dmCopies;
   short  dmDefaultSource;
   short  dmPrintQuality;
   short  dmColor;
   short  dmDuplex;
   short  dmYResolution;
   short  dmTTOption;
   short  dmCollate;
   BCHAR  dmFormName[CCHFORMNAME];
   WORD  dmLogPixels;
   DWORD  dmBitsPerPel;
   DWORD  dmPelsWidth;
   DWORD  dmPelsHeight;
   DWORD  dmDisplayFlags;
   DWORD  dmDisplayFrequency;

   GlobalUnlock( pd.hDevMode );
   */
}

//----------------------------------------------------------------------------//

HB_FUNC( COMDLGXERR ) // () --> nError
{
   hb_retnl( CommDlgExtendedError() );
}

//----------------------------------------------------------------------------//

static int CALLBACK EnumFamCallBack( const LOGFONT * lpnlf, const TEXTMETRIC * lpntm, unsigned long ulFontType, LPARAM lParam )
{
   PHB_ITEM pArrayLogFont = hb_itemArrayNew( 14 );
   PHB_ITEM pArrayTextMetrics = hb_itemArrayNew( 20 );
   PHB_ITEM pFontType = hb_itemPutNL( NULL, ulFontType );
   

   PHB_ITEM plfHeight         = hb_itemPutNL( NULL, lpnlf->lfHeight ); 
   PHB_ITEM plfWidth          = hb_itemPutNL( NULL, lpnlf->lfWidth ); 
   PHB_ITEM plfEscapement     = hb_itemPutNL( NULL, lpnlf->lfEscapement ); 
   PHB_ITEM plfOrientation    = hb_itemPutNL( NULL, lpnlf->lfOrientation );
   PHB_ITEM plfWeight         = hb_itemPutNL( NULL, lpnlf->lfWeight );
   PHB_ITEM plfItalic         = hb_itemPutNI( NULL, lpnlf->lfItalic );
   PHB_ITEM plfUnderline      = hb_itemPutNI( NULL, lpnlf->lfUnderline );
   PHB_ITEM plfStrikeOut      = hb_itemPutNI( NULL, lpnlf->lfStrikeOut );
   PHB_ITEM plfCharSet        = hb_itemPutNI( NULL, lpnlf->lfCharSet );
   PHB_ITEM plfOutPrecision   = hb_itemPutNI( NULL, lpnlf->lfOutPrecision );
   PHB_ITEM plfClipPrecision  = hb_itemPutNI( NULL, lpnlf->lfClipPrecision );
   PHB_ITEM plfQuality        = hb_itemPutNI( NULL, lpnlf->lfQuality );
   PHB_ITEM plfPitchAndFamily = hb_itemPutNI( NULL, lpnlf->lfPitchAndFamily );
   PHB_ITEM plfFaceName       = hb_itemPutC( NULL, lpnlf->lfFaceName );

   PHB_ITEM ptmHeight           = hb_itemPutNL( NULL, lpntm->tmHeight ); 
   PHB_ITEM ptmAscent           = hb_itemPutNL( NULL, lpntm->tmAscent ); 
   PHB_ITEM ptmDescent          = hb_itemPutNL( NULL, lpntm->tmDescent ); 
   PHB_ITEM ptmInternalLeading  = hb_itemPutNL( NULL, lpntm->tmInternalLeading ); 
   PHB_ITEM ptmExternalLeading  = hb_itemPutNL( NULL, lpntm->tmExternalLeading ); 
   PHB_ITEM ptmAveCharWidth     = hb_itemPutNL( NULL, lpntm->tmAveCharWidth ); 
   PHB_ITEM ptmMaxCharWidth     = hb_itemPutNL( NULL, lpntm->tmMaxCharWidth ); 
   PHB_ITEM ptmWeight           = hb_itemPutNL( NULL, lpntm->tmWeight ); 
   PHB_ITEM ptmOverhang         = hb_itemPutNL( NULL, lpntm->tmOverhang ); 
   PHB_ITEM ptmDigitizedAspectX = hb_itemPutNL( NULL, lpntm->tmDigitizedAspectX ); 
   PHB_ITEM ptmDigitizedAspectY = hb_itemPutNL( NULL, lpntm->tmDigitizedAspectY ); 
   PHB_ITEM ptmFirstChar        = hb_itemPutNI( NULL, lpntm->tmFirstChar ); 
   PHB_ITEM ptmLastChar         = hb_itemPutNI( NULL, lpntm->tmLastChar ); 
   PHB_ITEM ptmDefaultChar      = hb_itemPutNI( NULL, lpntm->tmDefaultChar ); 
   PHB_ITEM ptmBreakChar        = hb_itemPutNI( NULL, lpntm->tmBreakChar ); 
   PHB_ITEM ptmItalic           = hb_itemPutNI( NULL, lpntm->tmItalic ); 
   PHB_ITEM ptmUnderlined       = hb_itemPutNI( NULL, lpntm->tmUnderlined ); 
   PHB_ITEM ptmStruckOut        = hb_itemPutNI( NULL, lpntm->tmStruckOut ); 
   PHB_ITEM ptmPitchAndFamily   = hb_itemPutNI( NULL, lpntm->tmPitchAndFamily ); 
   PHB_ITEM ptmCharSet          = hb_itemPutNI( NULL, lpntm->tmCharSet ); 

   hb_itemArrayPut( pArrayLogFont,  1, plfHeight );
   hb_itemArrayPut( pArrayLogFont,  2, plfWidth );
   hb_itemArrayPut( pArrayLogFont,  3, plfEscapement );
   hb_itemArrayPut( pArrayLogFont,  4, plfOrientation );
   hb_itemArrayPut( pArrayLogFont,  5, plfWeight );
   hb_itemArrayPut( pArrayLogFont,  6, plfItalic );
   hb_itemArrayPut( pArrayLogFont,  7, plfUnderline );
   hb_itemArrayPut( pArrayLogFont,  8, plfStrikeOut );
   hb_itemArrayPut( pArrayLogFont,  9, plfCharSet );
   hb_itemArrayPut( pArrayLogFont, 10, plfOutPrecision );
   hb_itemArrayPut( pArrayLogFont, 11, plfClipPrecision );
   hb_itemArrayPut( pArrayLogFont, 12, plfQuality );
   hb_itemArrayPut( pArrayLogFont, 13, plfPitchAndFamily );
   hb_itemArrayPut( pArrayLogFont, 14, plfFaceName );

   hb_itemArrayPut( pArrayTextMetrics,  1, ptmHeight );
   hb_itemArrayPut( pArrayTextMetrics,  2, ptmAscent );
   hb_itemArrayPut( pArrayTextMetrics,  3, ptmDescent );
   hb_itemArrayPut( pArrayTextMetrics,  4, ptmInternalLeading );
   hb_itemArrayPut( pArrayTextMetrics,  5, ptmExternalLeading );
   hb_itemArrayPut( pArrayTextMetrics,  6, ptmAveCharWidth );
   hb_itemArrayPut( pArrayTextMetrics,  7, ptmMaxCharWidth );
   hb_itemArrayPut( pArrayTextMetrics,  8, ptmWeight );
   hb_itemArrayPut( pArrayTextMetrics,  9, ptmOverhang );
   hb_itemArrayPut( pArrayTextMetrics, 10, ptmDigitizedAspectX );
   hb_itemArrayPut( pArrayTextMetrics, 11, ptmDigitizedAspectY );
   hb_itemArrayPut( pArrayTextMetrics, 12, ptmFirstChar );
   hb_itemArrayPut( pArrayTextMetrics, 13, ptmLastChar );
   hb_itemArrayPut( pArrayTextMetrics, 14, ptmDefaultChar );
   hb_itemArrayPut( pArrayTextMetrics, 15, ptmBreakChar );
   hb_itemArrayPut( pArrayTextMetrics, 16, ptmItalic );
   hb_itemArrayPut( pArrayTextMetrics, 17, ptmUnderlined );
   hb_itemArrayPut( pArrayTextMetrics, 18, ptmStruckOut );
   hb_itemArrayPut( pArrayTextMetrics, 19, ptmPitchAndFamily );
   hb_itemArrayPut( pArrayTextMetrics, 20, ptmCharSet );

   hb_evalBlock( ( PHB_ITEM ) lParam, pArrayLogFont, pArrayTextMetrics, pFontType, NULL );

   hb_itemRelease( plfHeight );
   hb_itemRelease( plfWidth );
   hb_itemRelease( plfEscapement );
   hb_itemRelease( plfOrientation );
   hb_itemRelease( plfWeight );
   hb_itemRelease( plfItalic );
   hb_itemRelease( plfUnderline );
   hb_itemRelease( plfStrikeOut );
   hb_itemRelease( plfCharSet );
   hb_itemRelease( plfOutPrecision );
   hb_itemRelease( plfClipPrecision );
   hb_itemRelease( plfQuality );
   hb_itemRelease( plfPitchAndFamily );
   hb_itemRelease( plfFaceName );

   hb_itemRelease( ptmHeight );
   hb_itemRelease( ptmAscent );
   hb_itemRelease( ptmDescent );
   hb_itemRelease( ptmInternalLeading ); 
   hb_itemRelease( ptmExternalLeading ); 
   hb_itemRelease( ptmAveCharWidth );    

   hb_itemRelease( ptmMaxCharWidth );    

   hb_itemRelease( ptmWeight );          

   hb_itemRelease( ptmOverhang );        

   hb_itemRelease( ptmDigitizedAspectX ); 
   hb_itemRelease( ptmDigitizedAspectY ); 
   hb_itemRelease( ptmFirstChar );       

   hb_itemRelease( ptmLastChar );        

   hb_itemRelease( ptmDefaultChar );     

   hb_itemRelease( ptmBreakChar );       

   hb_itemRelease( ptmItalic );          

   hb_itemRelease( ptmUnderlined );      

   hb_itemRelease( ptmStruckOut );       

   hb_itemRelease( ptmPitchAndFamily );  

   hb_itemRelease( ptmCharSet );

   hb_itemRelease( pArrayLogFont );
   hb_itemRelease( pArrayTextMetrics );
   hb_itemRelease( pFontType );

   return hb_parni( -1 );
}

HB_FUNC( ENUMFONTFAMILIES ) // ( hDC, cFamily, bCallBack )
{
   EnumFontFamilies( ( HDC ) ( LONG_PTR ) hb_parnll( 1 ),
                     IF( HB_ISCHAR( 2 ), hb_parc( 2 ), NULL ),
                     EnumFamCallBack,
                     ( long ) ( LONG_PTR ) hb_param( 3, HB_IT_BLOCK ) );
}

//----------------------------------------------------------------------------//

#ifdef __FLAT__

HB_FUNC( PRNSTATUS ) // cPrinter or cPrinterServer --> nStatus
{
	 HANDLE hPrinter = NULL;
	 DWORD cBytesNeeded = 0, cBytesUsed = 0;
   PRINTER_INFO_2 * pPrinterInfo;   	
   

   if( OpenPrinter( ( char * ) hb_parc( 1 ), &hPrinter, 0 ) )
   {
      GetPrinter( hPrinter, 2, NULL, 0, &cBytesNeeded );
      pPrinterInfo = ( PRINTER_INFO_2 * ) hb_xgrab( cBytesNeeded );   		
   	  GetPrinter( hPrinter, 2, ( unsigned char * ) pPrinterInfo, cBytesNeeded, &cBytesUsed );
   	  hb_retnl( pPrinterInfo->Status );
   	  hb_xfree( pPrinterInfo );
      ClosePrinter( hPrinter );
   }
   else
      hb_retnl( PRINTER_STATUS_NOT_AVAILABLE );
}      		  

#endif

//----------------------------------------------------------------------------//

#undef ABORTDOC

HB_FUNC( ABORTDOC )
{
   #ifndef _WIN64
      hb_retnl( AbortDoc( ( HDC ) hb_parnl( 1 ) ) );
   #else
      hb_retnl( AbortDoc( ( HDC ) hb_parnll( 1 ) ) );
   #endif
}   	

//----------------------------------------------------------------------------//

HB_FUNC( PRINTERDCFROMNAME ) // ( cDriver, cModel, cPort )
{
   LPDEVMODE  lpDevMode;

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   #ifndef _WIN64
   hb_retnl( ( LONG ) CreateDC( ( LPSTR ) hb_parc( 1 ),
                    ( LPSTR ) hb_parc( 2 ),
                    ( LPSTR ) hb_parc( 3 ),
                    lpDevMode ) );
   #else
   hb_retnll( ( LONGLONG ) CreateDC( ( LPSTR ) hb_parc( 1 ),
                    ( LPSTR ) hb_parc( 2 ),
                    ( LPSTR ) hb_parc( 3 ),
                    lpDevMode ) );
   #endif

   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

HB_FUNC( ISCOLORPRINTER )
{
   LPDEVMODE  lpDevMode;

   PrinterInit();

   lpDevMode  = (LPDEVMODE) GlobalLock( pd.hDevMode );

   hb_retl( lpDevMode->dmColor == DMCOLOR_COLOR );
   GlobalUnlock( pd.hDevMode );
}

//----------------------------------------------------------------------------//

Lo cierto es que funciona correctamente, pero me crea bastante inseguridad utilizarlo no vaya a ser que rompa la aplicación por otro lado.

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 11:30 AM
Garbi wrote:

Solo por probar, has probado a activar en impresoras "Permitir que Windows administre mi impresora predeterminada"

La opción Permitir que Windows administre mi impresora predeterminada hace que el sistema operativo elija de forma automática como predeterminada la última impresora que hayas utilizado en ese equipo.

Ahora hay que tener en cuenta :

Bloqueo manual: Mientras esté activada, no puedes fijar de forma permanente una impresora específica como predeterminada desde el menú clásico.

Sí que he probado y el problema persiste. Creo que algo debe de haber cambiado en fivewin pues con versiones anteriores (de hace algunos años) el mismo código responde bien.

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 11:32 AM
karinha wrote:

Así: PRINT oPrn NAME "Meu Relatório" PREVIEW

Mejor así:

 PRINT oPrn NAME "Mi Informe" PREVIEW MODAL

¿Cambias la impresora en tiempo real en el PREVIEW? Si es así, entiendo que el cambio es solo para la impresión de este PREVIEW. Para cambiar la impresora y que quede fija (DEFAULT) se hace de otra manera. No recuerdo cuál ahora mismo.

Regards, saludos.

No es esa la cuestión, sino que el mismo código funciona en versiones anteriores de fivewin y ahora no, tanto con xharbour como con harbour

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 12:37 PM

Prueba GetPrintDC(), que te pasa?

// C:\FWH\SAMPLES\PRINTDC.PRG

#include "FiveWin.ch"

FUNCTION Main()

   LOCAL oPrn, hDC, oFont

   hDC := GetPrintDC( GetActiveWindow() )

   IF hDC == 0

  MsgInfo( "Impressão cancelada pelo usuário.", "Aviso" )

  RETURN( .F. )

   ENDIF

   PRINTER oPrn NAME "Meu Relatório Empresarial" hDC hDC

  DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -14 BOLD OF oPrn

  PAGE

     oPrn:Say( 100, 100, "Texto impresso na impressora selecionada!", oFont )

  ENDPAGE

   ENDPRINTER

   oFont:End()

RETURN( .T. )

// FIN / END
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 01:46 PM
karinha wrote:

Prueba GetPrintDC(), que te pasa?

// C:\FWH\SAMPLES\PRINTDC.PRG

#include "FiveWin.ch"

FUNCTION Main()

   LOCAL oPrn, hDC, oFont

   hDC := GetPrintDC( GetActiveWindow() )

   IF hDC == 0

  MsgInfo( "Impressão cancelada pelo usuário.", "Aviso" )

  RETURN( .F. )

   ENDIF

   PRINTER oPrn NAME "Meu Relatório Empresarial" hDC hDC

  DEFINE FONT oFont NAME "Ms Sans Serif" SIZE 0, -14 BOLD OF oPrn

  PAGE

     oPrn:Say( 100, 100, "Texto impresso na impressora selecionada!", oFont )

  ENDPAGE

   ENDPRINTER

   oFont:End()

RETURN( .T. )

// FIN / END

Mismo resultado que con PrinterSetup()

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 8716
Joined: Tue Dec 20, 2005 07:36 PM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 02:09 PM

Prueba y comenta, porfa.

   DEFINE BUTTON oImpressora OF OBAR RESOURCE "130"                          ;
      PROMPT "Impressora"                                                    ;
      MESSAGE "Trocar o Modelo da Impressora"                                ;
      ACTION( DefaultPrinter() )                                             ;
      TOOLTIP { "Trocar o Modelo da Impressora.",                            ;
                "Click no Botão: Impressora.", 1, CLR_WHITE, CLR_HBLUE }     ;
      NOBORDER GROUP

   oImpressora:oCursor := oHand

FUNCTION DefaultPrinter() // MODIFIQUEI A PRINTER.PRG E FUNCIONA...

   LOCAL nPrn, nRet

   // Abre a tela para a seleção da impressora
   /*
   GetPrintDC( GetActiveWindow() )

   // Coloca a impressora selecionada como Default do Windows
   SetDefaultPrinter( PRNGETNAME() )
   */

   nRet := PrinterSetUp()

   nPrn := PrnGetName()

   IF( nRet # 0 )

  // NADA A FAZER MUDA O DEFULT DA IMPRESSORA EM TEMPO REAL. 15/08/2016(Magda)
  SetDefaultPrinter( PRNGETNAME() ) // MUDA O DEFAULT DA IMPRESSORA

  MsgInfo( OemToAnsi( "Aten‡Æo Usu rio:                        " )+CRLF+ ;
           OemToAnsi( "Sua Impressora DEFAULT(PadrÆo) ‚:       " )+CRLF+ ;
                    ( "-> " + nPrn                               ),      ;
           OemToAnsi( "Sua Impressora DEFAULT(PadrÆo) ‚...     " ) )

  sGetDefaultPrinter := GetDefaultPrinter()

  // ? PrnStatus( sGetDefaultPrinter )

  IF PrnStatus( sGetDefaultPrinter ) = 4096

     // Verifica se SPOOLER esta desligado e tenta liga-lo
     MsgRun( sGetDefaultPrinter +": "+isprint( GetDefaultPrinter() ) + ;
                     " ou Spooler Desligado.", "Status da Impressora", ;
             {|| WinExec( "NET START SPOOLER", 7 ) } )

  ENDIF

  //? GetPrinter()

   ELSE

  MsgInfo( OemToAnsi( "ATEN€ÇO USUµRIO:                         " )+CRLF+ ;
           OemToAnsi( "VERIFIQUE SUA IMPRESSORA SE ESTµ LIGADA. " )+CRLF+ ;
           OemToAnsi( "OU SE ESTµ INSTALADA CORRETAMENTE...     " )+CRLF+ ;
           OemToAnsi( "TEM ALGUMA COISA ERRADA COM A IMPRESSORA?" )+CRLF+ ;
           OemToAnsi( "SE NÇO ESCOLHEU NENHUMA IMPRESSORA, OK..." )+CRLF+ ;
           OemToAnsi( "TECLE <ENTER> PARA CONTINUAR...          " ),      ;
           OemToAnsi( "VERIFIQUE SUA IMPRESSORA SE ESTµ LIGADA. " ) )

  RETURN( .F. )

   ENDIF

RETURN NIL

// en: PRINTER.PRG  mira como esta tu PRINTER.PRG y MODIFICA.
METHOD End() CLASS TPrinter

   if ::hDC != 0
      if ! ::lMeta
         if ::lStarted
            EndDoc(::hDC)
         endif
      else
         Aeval(::aMeta,{|val| ferase(val) })
         ::aMeta  := {}
         ::hDCOut := 0
      endif
      if ::nOrient != nil
         if ::nOrient == DMORIENT_PORTRAIT
            ::SetPortrait()
         else
            ::SetLandscape()
         endif
      endif

  // impressora selecionada no GetPrintDC() sem mudar a impressora
  // Default do Windows. - Joao

  // PrinterEnd()

  DeleteDC( ::hDC )
  ::hDC := 0
   endif

   if ::oFont != nil
      ::oFont:End()
   endif

   oPrinter := nil

return nil

Regards, saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: PrinterSetup

Posted: Thu Oct 01, 2026 03:48 PM

Estimado Manuel: ¿Podrías compartir un PRG mínimo que reproduzca el problema, los pasos exactos, y confirmar la versión/build de FWH, Harbour o xHarbour y compilador? Si es posible, indica qué impresora/controlador utilizas y el resultado esperado frente al obtenido.\n\nFiveTech AI

Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Fri Oct 02, 2026 06:36 AM

Ejemplo:
En la opción 1.- Entro printerSetup() y cambio la impresora predeterminada por otra del sistema
En la opción 2.- Entro en el preview y me conserva la impresora elegida. Salgo del preview
En la opcion 3.- Entro en printerSetup() y la impresora vuelve a ser la predeterminada

#include "FiveWin.ch"

FUNCTION Main()
   LOCAL oWnd

   DEFINE WINDOW oWnd TITLE "PrinterSetup" ;
      FROM 0, 0 TO 330, 800 PIXEL

   @ 20, 20 BUTTON "1.- PrinterSetup" OF oWnd SIZE 300, 32 PIXEL ;
      ACTION SelectPrinter( oWnd )
   @ 65, 20 BUTTON "2.- Preview" OF oWnd SIZE 300, 32 PIXEL ;
      ACTION ShowPreview()
   @ 110, 20 BUTTON "3.- PrinterSetup otra vez" OF oWnd ;
      SIZE 300, 32 PIXEL ACTION SelectPrinter( oWnd )

   @ 165, 20 SAY "FiveWin : " + FWVERSION OF oWnd ;
      SIZE 740, 24 PIXEL
   @ 195, 20 SAY "Harbour : " + Version() OF oWnd ;
      SIZE 740, 24 PIXEL
   @ 225, 20 SAY "Enlazador: BCC77 6.97 " ;
      OF oWnd SIZE 740, 24 PIXEL

   ACTIVATE WINDOW oWnd
RETURN NIL

STATIC FUNCTION SelectPrinter( oWnd )
   LOCAL hDC := PrinterSetup()

   IF hDC != 0
      oWnd:cTitle := PrnGetName()
      DeleteDC( hDC )
   ENDIF
RETURN NIL

STATIC FUNCTION ShowPreview()
   LOCAL oPrn

   PRINT oPrn NAME "PrinterSetup test" PREVIEW MODAL
      PAGE
         oPrn:Say( 100, 100, "PrinterSetup test" )
      ENDPAGE
   ENDPRINT
RETURN NIL

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 623
Joined: Wed Oct 19, 2005 08:20 PM

Re: PrinterSetup

Posted: Fri Oct 02, 2026 07:04 AM
karinha wrote:

Prueba y comenta, porfa.

   DEFINE BUTTON oImpressora OF OBAR RESOURCE "130"                          ;
      PROMPT "Impressora"                                                    ;
      MESSAGE "Trocar o Modelo da Impressora"                                ;
      ACTION( DefaultPrinter() )                                             ;
      TOOLTIP { "Trocar o Modelo da Impressora.",                            ;
                "Click no Botão: Impressora.", 1, CLR_WHITE, CLR_HBLUE }     ;
      NOBORDER GROUP

   oImpressora:oCursor := oHand

FUNCTION DefaultPrinter() // MODIFIQUEI A PRINTER.PRG E FUNCIONA...

   LOCAL nPrn, nRet

   // Abre a tela para a seleção da impressora
   /*
   GetPrintDC( GetActiveWindow() )

   // Coloca a impressora selecionada como Default do Windows
   SetDefaultPrinter( PRNGETNAME() )
   */

   nRet := PrinterSetUp()

   nPrn := PrnGetName()

   IF( nRet # 0 )

  // NADA A FAZER MUDA O DEFULT DA IMPRESSORA EM TEMPO REAL. 15/08/2016(Magda)
  SetDefaultPrinter( PRNGETNAME() ) // MUDA O DEFAULT DA IMPRESSORA

  MsgInfo( OemToAnsi( "Aten‡Æo Usu rio:                        " )+CRLF+ ;
           OemToAnsi( "Sua Impressora DEFAULT(PadrÆo) ‚:       " )+CRLF+ ;
                    ( "-> " + nPrn                               ),      ;
           OemToAnsi( "Sua Impressora DEFAULT(PadrÆo) ‚...     " ) )

  sGetDefaultPrinter := GetDefaultPrinter()

  // ? PrnStatus( sGetDefaultPrinter )

  IF PrnStatus( sGetDefaultPrinter ) = 4096

     // Verifica se SPOOLER esta desligado e tenta liga-lo
     MsgRun( sGetDefaultPrinter +": "+isprint( GetDefaultPrinter() ) + ;
                     " ou Spooler Desligado.", "Status da Impressora", ;
             {|| WinExec( "NET START SPOOLER", 7 ) } )

  ENDIF

  //? GetPrinter()

   ELSE

  MsgInfo( OemToAnsi( "ATEN€ÇO USUµRIO:                         " )+CRLF+ ;
           OemToAnsi( "VERIFIQUE SUA IMPRESSORA SE ESTµ LIGADA. " )+CRLF+ ;
           OemToAnsi( "OU SE ESTµ INSTALADA CORRETAMENTE...     " )+CRLF+ ;
           OemToAnsi( "TEM ALGUMA COISA ERRADA COM A IMPRESSORA?" )+CRLF+ ;
           OemToAnsi( "SE NÇO ESCOLHEU NENHUMA IMPRESSORA, OK..." )+CRLF+ ;
           OemToAnsi( "TECLE <ENTER> PARA CONTINUAR...          " ),      ;
           OemToAnsi( "VERIFIQUE SUA IMPRESSORA SE ESTµ LIGADA. " ) )

  RETURN( .F. )

   ENDIF

RETURN NIL

// en: PRINTER.PRG  mira como esta tu PRINTER.PRG y MODIFICA.
METHOD End() CLASS TPrinter

   if ::hDC != 0
      if ! ::lMeta
         if ::lStarted
            EndDoc(::hDC)
         endif
      else
         Aeval(::aMeta,{|val| ferase(val) })
         ::aMeta  := {}
         ::hDCOut := 0
      endif
      if ::nOrient != nil
         if ::nOrient == DMORIENT_PORTRAIT
            ::SetPortrait()
         else
            ::SetLandscape()
         endif
      endif

  // impressora selecionada no GetPrintDC() sem mudar a impressora
  // Default do Windows. - Joao

  // PrinterEnd()

  DeleteDC( ::hDC )
  ::hDC := 0
   endif

   if ::oFont != nil
      ::oFont:End()
   endif

   oPrinter := nil

return nil

Regards, saludos.

Muchas gracias karinha por tu interés. Lo que yo pregunto es otra cosa. En el mensaje anterior tienes un ejemplo de lo que me está ocurriendo.

Un saludo,

Manuel



xH 1.2.3, FWH 26.06 32 bits, BC++ 7.7, PellesC

Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: PrinterSetup

Posted: Fri Oct 02, 2026 07:49 AM

Estimado Manuel:

Con tu ejemplo se ve exactamente dónde se pierde la selección: el primer preview usa la impresora elegida, pero al cerrarlo TPrinter:End() llama a PrinterEnd(), que libera la configuración del diálogo. La siguiente PrinterSetup() vuelve a consultar la predeterminada de Windows. No hace falta cambiar esa predeterminada.

Hemos revisado el historial: esa llamada a PrinterEnd() se activó en febrero de 2013 para corregir una fuga de memoria, y desde entonces se ha mantenido. Por eso no conviene quitarla sin más. Si tu versión anterior conservaba la selección durante toda la sesión, habría que comparar también la printer.prg y las librerías que estabas usando entonces.

Para recordar el destino entre informes, con la API actual puedes guardar PrnGetName() justo después de aceptar PrinterSetup() y usar PRINT ... TO cPrinter en los informes siguientes:

STATIC cPrinter := ""

STATIC FUNCTION SelectPrinter( oWnd )
   LOCAL hDC := PrinterSetup()
   IF hDC != 0
      cPrinter := PrnGetName()
      oWnd:cTitle := cPrinter
      DeleteDC( hDC )
   ENDIF
RETURN NIL

STATIC FUNCTION ShowPreview()
   LOCAL oPrn
   IF Empty( cPrinter )
      MsgInfo( "Selecciona primero una impresora" )
      RETURN NIL
   ENDIF
   PRINT oPrn NAME "PrinterSetup test" TO cPrinter PREVIEW MODAL
      PAGE
         oPrn:Say( 100, 100, "PrinterSetup test" )
      ENDPAGE
   ENDPRINT
RETURN NIL

Ten en cuenta que esto recuerda QUÉ impresora usa el siguiente informe, pero no preselecciona el siguiente PrinterSetup() ni conserva todos los ajustes del driver. Para conservar también eso haría falta guardar una configuración de sesión completa (DEVNAMES/DEVMODE) separada de los recursos de cada trabajo, distinto de cambiar la predeterminada de Windows.

Esperamos que te sirva.

Un saludo,
FiveTech AI