Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Impresión
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo Hace 5 Días
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Ubicación: Toledo - España
Posts: 1.430
Poder: 21
Angel.Matilla Va por buen camino
Automatizar el uso de Bullzip PDF Printer

Tengo instalado este programa para cuando necesito imprimir en formato PDF y me gustaría que en un programa que estoy desarrollando si selecciono como destino esta impresora se automatizara el proceso sin necesidad de mostrar cuadros de diálogo y demás. Lo malo es que el único código aparentemente completo que he encontrado está en VBA y no tengo ni idea de como funciona. ¿Alguno puede ayudarme con la traducción?
Cita:
Sub ImprimirAut()
Dim objPrinterSettings As Object
Set objPrinterSettings = CreateObject("Bullzip.PDFPrinterSettings")

' Configurar la ruta y nombre del archivo
objPrinterSettings.SetValue "Output", "C:\MisDocumentos\ArchivoAutomatico.pdf"

' Desactivar todas las ventanas emergentes
objPrinterSettings.SetValue "ShowSaveAs", "never"
objPrinterSettings.SetValue "ShowProgress", "no"
objPrinterSettings.SetValue "ShowProgressFinished", "no"
objPrinterSettings.SetValue "ShowPDF", "no" ' No abrir el PDF al terminar
objPrinterSettings.SetValue "ConfirmOverwrite", "no"

' Guardar la configuración (escribe el archivo runonce.ini automáticamente)
objPrinterSettings.WriteSettings True

' Enviar a imprimir desde tu aplicación asegurándote de usar Bullzip
' Ejemplo en Excel:
' ActiveSheet.PrintOut ActivePrinter:="Bullzip PDF Printer"
End Sub
Porque también lo he encontrado en C++, pero me parece que falta algo.
Código:
#include <windows.h>
#include <iostream>
#include <comdef.h>

// Reemplaza esta ruta por la localización real de tu archivo de configuración de Bullzip si fuese necesario.
// Sin embargo, instanciarlo por su ProgID ("Bullzip.PDFPrinterSettings") suele ser suficiente.

int main() {
    // 1. Inicializar el entorno COM de Windows
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr)) {
        std::cerr << "Error al inicializar COM." << std::endl;
        return 1;
    }

    try {
        // 2. Obtener el CLSID a partir del ProgID de Bullzip
        CLSID clsid;
        hr = CLSIDFromProgID(L"Bullzip.PDFPrinterSettings", &clsid);
        if (FAILED(hr)) {
            throw std::runtime_error("No se encontró el componente COM de Bullzip. ¿Está instalado?");
        }

        // 3. Crear la instancia del objeto de configuración
        IDispatch* pBullzipSettings = nullptr;
        hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pBullzipSettings);
        if (FAILED(hr)) {
            throw std::runtime_error("No se pudo crear la instancia de Bullzip Settings.");
        }

        // Helper Lambda para invocar métodos (SetValue, WriteSettings) mediante IDispatch
        auto invokeMethod = [](IDispatch* obj, OLECHAR* name, VARIANT* args, int argCount) -> _variant_t {
            DISPID dispid;
            HRESULT hr = obj->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid);
            if (FAILED(hr)) return _variant_t();

            DISPPARAMS params = { args, NULL, (UINT)argCount, 0 };
            _variant_t result;
            hr = obj->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, NULL);
            return result;
        };

        // 4. Configurar los parámetros de impresión automática
        // Nota: Los argumentos en Invoke se pasan en orden inverso (derecha a izquierda)
        
        // Parámetro: Output -> Ruta donde se guardará el PDF
        VARIANT argsOutput[2];
        argsOutput[1].vt = VT_BSTR; argsOutput[1].bstrVal = SysAllocString(L"Output");
        argsOutput[0].vt = VT_BSTR; argsOutput[0].bstrVal = SysAllocString(L"C:\\destino\\mi_documento.pdf");
        invokeMethod(pBullzipSettings, L"SetValue", argsOutput, 2);
        SysFreeString(argsOutput[1].bstrVal); SysFreeString(argsOutput[0].bstrVal);

        // Parámetro: ShowPDF -> "no" (Evita que se abra el lector de PDF tras crear el archivo)
        VARIANT argsShow[2];
        argsShow[1].vt = VT_BSTR; argsShow[1].bstrVal = SysAllocString(L"ShowPDF");
        argsShow[0].vt = VT_BSTR; argsShow[0].bstrVal = SysAllocString(L"no");
        invokeMethod(pBullzipSettings, L"SetValue", argsShow, 2);
        SysFreeString(argsShow[1].bstrVal); SysFreeString(argsShow[0].bstrVal);

        // Parámetro: ShowSettings -> "never" (Oculta por completo la interfaz gráfica de Bullzip)
        VARIANT argsShowSettings[2];
        argsShowSettings[1].vt = VT_BSTR; argsShowSettings[1].bstrVal = SysAllocString(L"ShowSettings");
        argsShowSettings[0].vt = VT_BSTR; argsShowSettings[0].bstrVal = SysAllocString(L"never");
        invokeMethod(pBullzipSettings, L"SetValue", argsShowSettings, 2);
        SysFreeString(argsShowSettings[1].bstrVal); SysFreeString(argsShowSettings[0].bstrVal);

        // Parámetro: ConfirmOverwrite -> "no" (Sobrescribe de forma automática si el archivo ya existe)
        VARIANT argsOverwrite[2];
        argsOverwrite[1].vt = VT_BSTR; argsOverwrite[1].bstrVal = SysAllocString(L"ConfirmOverwrite");
        argsOverwrite[0].vt = VT_BSTR; argsOverwrite[0].bstrVal = SysAllocString(L"no");
        invokeMethod(pBullzipSettings, L"SetValue", argsOverwrite, 2);
        SysFreeString(argsOverwrite[1].bstrVal); SysFreeString(argsOverwrite[0].bstrVal);

        // 5. Confirmar y escribir la configuración en el archivo temporal 'runonce.ini'
        // El método WriteSettings acepta un booleano (true para escribir la configuración de inmediato)
        VARIANT argsWrite[1];
        argsWrite[0].vt = VT_BOOL; argsWrite[0].boolVal = VARIANT_TRUE;
        invokeMethod(pBullzipSettings, L"WriteSettings", argsWrite, 1);

        // 6. Liberar el objeto COM de configuración
        pBullzipSettings->Release();

        // 7. Lanzar la impresión real del documento usando la API de Windows
        // Esto envía el archivo a la cola de Bullzip, la cual procesará el runonce.ini que acabamos de crear.
        std::cout << "Configuración inyectada. Enviando archivo a 'Bullzip PDF Printer'..." << std::endl;
        
        // Ejemplo para mandar a imprimir un archivo de texto existente silenciosamente:
        ShellExecute(NULL, L"printto", L"C:\\origen\\documento.txt", L"\"Bullzip PDF Printer\"", NULL, SW_HIDE);

    } catch (const std::exception& e) {
        std::cerr << "Excepción: " << e.what() << std::endl;
    }

    // Cerrar el entorno COM
    CoUninitialize();
    return 0;
}
Hay por ahí un par de funciones (CoInitialize y CoUninitialize) que no han incluído en el código.
Responder Con Cita
  #2  
Antiguo Hace 5 Días
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.714
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Pregunto, ¿tiene que ser ese programa?
Hay otros que puedes usar y funcionan perfectamente.
E incluso creo recordar que el propio windows ya permite instalar una impresora pdf directamente.
Responder Con Cita
  #3  
Antiguo Hace 4 Días
emailx45 emailx45 is offline
Miembro
 
Registrado: abr 2025
Posts: 27
Poder: 0
emailx45 Va por buen camino
Thumbs up

Try this: (CONSOLE for tests... )

Código Delphi [-]
program ConverterBullzipCom;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Variants,
  Winapi.Windows,
  Winapi.ShellAPI,
  System.Win.ComObj,
  Winapi.Ole2;

procedure ExecutarAutomacaoBullzip;
var
  LBullzipSettings: OleVariant;
  LPrinterName    : string;
  LArquivoOrigem  : string;
  LRetorno        : NativeInt;
begin
  // 1. Inicializa COM (Delphi ya gestiona CoInitialize implícitamente al instanciar OleVariant,
  // pero podemos asegurarlo llamándolo si es necesario).
  CoInitialize( nil );
  try
    try
      // 2. Crea la instancia del objeto COM de Bullzip a partir del ProgID
      LBullzipSettings := CreateOleObject( 'Bullzip.PDFPrinterSettings' );

      // 3. Configura los parámetros de impresión automática utilizando el método SetValue
      // Nota: En Delphi con OleVariant, la llamada a métodos con parámetros es directa.
      LBullzipSettings.SetValue( 'Output', 'C:\destino\mi_documento.pdf' );
      LBullzipSettings.SetValue( 'ShowPDF', 'no' );
      LBullzipSettings.SetValue( 'ShowSettings', 'never' );
      LBullzipSettings.SetValue( 'ConfirmOverwrite', 'no' );

      // 4. Guarda la configuración en el archivo 'runonce.ini' (equivalente a WriteSettings(true))
      LBullzipSettings.WriteSettings( True );

      // 5. Libera la referencia COM (asignando Unassigned)
      LBullzipSettings := Unassigned;

      Writeln( 'Configuração inyectada. Enviando arquivo para "Bullzip PDF Printer"...' );

      // 6. Define la impresora de destino y el archivo de origen
      LPrinterName   := 'Bullzip PDF Printer';
      LArquivoOrigem := 'C:\origen\documento.txt';

      // 7. Envía el archivo a la impresora usando ShellExecute con el verbo 'printto'
      LRetorno := ShellExecute( 0, 'printto', PChar( LArquivoOrigem ), PChar( LPrinterName ), nil, SW_HIDE );

      if LRetorno > 32 then
        Writeln( '¡Comando de impresión enviado con éxito!' )
      else
        Writeln( 'Error al enviar a imprimir. Código: ', LRetorno );

    except
      on E: Exception do
      begin
        Writeln( 'Excepción capturada: ', E.Message );
      end;
    end;
  finally
    CoUninitialize( );
  end;
end;

begin
  ExecutarAutomacaoBullzip;
  Writeln( 'Presiona ENTER para salir...' );
  Readln;

end.

Última edición por emailx45 fecha: Hace 4 Días a las 22:57:44.
Responder Con Cita
  #4  
Antiguo Hace 4 Días
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Ubicación: Toledo - España
Posts: 1.430
Poder: 21
Angel.Matilla Va por buen camino
Cita:
Empezado por Casimiro Noteví Ver Mensaje
Pregunto, ¿tiene que ser ese programa?
Hay otros que puedes usar y funcionan perfectamente.
E incluso creo recordar que el propio windows ya permite instalar una impresora pdf directamente.
No, puede ser cualquiera pero es el que llevo años utilizando y siempre me ha dado buen resultado.
Cita:
Empezado por emailx45 Ver Mensaje
Try this: (CONSOLE for tests... )
Muchas gracias por el esfuerzo, pero no era trasladarlo a Delphi. Eso se me olvidó ponerlo: era para C++.
Responder Con Cita
  #5  
Antiguo Hace 4 Días
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.714
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Prueba el pdfcreator, está en nuestro ftp:
https://terawiki.clubdelphi.com/Delp...PdfCreator.zip
Eso crea una impresora virtual a donde puedes enviar todo lo que quieras imprimir a formato pdf.
La versión última de ese componente me temo que lo ha comprado una empresa y ahora e de pago, pero esa versión que está en nuestro ftp es la anterior que era gratis.
Y funciona perfectamente.
Responder Con Cita
  #6  
Antiguo Hace 4 Días
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.714
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Y si necesitas código C++ para lo que te ha pasado en Delphi emailx45, pásaselo a cualquier IA y le indicas que te lo convierta al lenguaje que quieras.
Responder Con Cita
  #7  
Antiguo Hace 4 Días
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Ubicación: Toledo - España
Posts: 1.430
Poder: 21
Angel.Matilla Va por buen camino
Cita:
Empezado por Casimiro Noteví Ver Mensaje
Prueba el pdfcreator, está en nuestro ftp:
https://terawiki.clubdelphi.com/Delp...PdfCreator.zip
Eso crea una impresora virtual a donde puedes enviar todo lo que quieras imprimir a formato pdf.
La versión última de ese componente me temo que lo ha comprado una empresa y ahora e de pago, pero esa versión que está en nuestro ftp es la anterior que era gratis.
Y funciona perfectamente.
Gracias por ambas sugerencias. Lo probaré,
Responder Con Cita
  #8  
Antiguo Hace 4 Días
emailx45 emailx45 is offline
Miembro
 
Registrado: abr 2025
Posts: 27
Poder: 0
emailx45 Va por buen camino
Red face

Cita:
Empezado por Angel.Matilla Ver Mensaje
Gracias por ambas sugerencias. Lo probaré,
Lamentablemente, no domino CBuilder / C++.
Por lo tanto, creo que un ejemplo en Delphi sería de ayuda.

Como nunca he utilizado BullZIP, no he probado el código que muestras en el ejemplo. Sin embargo, he notado que algo no funciona como se esperaba en la línea "LRetorno := ...", ya que no obtengo un valor de retorno de 32 o superior. Por consiguiente, sería necesario analizar la versión actual de BullZIP y consultar el sitio web del desarrollador para verificar qué es lo que realmente se espera en la configuración...

Otra forma más sencilla sería tener la aplicación instalada en su sistema y utilizar el menú de Delphi para obtener la API traducida de la DLL de BullZip; de este modo, los comandos resultarían más nativos para su uso en Delphi.
Consulte el menú Component -> Importar Component (DLL); incluso sería posible crear un componente de Delphi si le interesa estudiar las llamadas a esta DLL.

Última edición por emailx45 fecha: Hace 4 Días a las 16:41:46.
Responder Con Cita
  #9  
Antiguo Hace 4 Días
emailx45 emailx45 is offline
Miembro
 
Registrado: abr 2025
Posts: 27
Poder: 0
emailx45 Va por buen camino
Thumbs up

Otra forma sería utilizar únicamente la DLL de GhostScript (y nada más) para enviar el archivo PDF directamente a la impresión; de este modo, no dependerías de ninguna impresora virtual instalada. Solo necesitarías la DLL de GhostScript (la versión 10.0.8, por ejemplo, ya está disponible en el sitio https://ghostscript.com/releases/gsdnld.html).

Con esto, accederías directamente a la API de GhostScript sin necesidad de instalar ninguna aplicación; bastaría con copiar la DLL para tu uso particular.

Delphi puede cargar la DLL mediante la función "LoadLibrary" y obtener los métodos necesarios a través de "GetProcAddress()"; ambos forman parte de la unidad "WinApi.Windows".

Se trataría de muy pocas líneas de código, unas 100 aproximadamente (ya que tendrías que definir los parámetros, la forma de acceso, las variables, el manejo de errores, etc.), todo ello bastante sencillo.
Aquí tienes un esquema básico para que te hagas una idea de lo fácil que resultaría:



Código Delphi [-]
function ProcessarPdfComGhostscript( const AArquivoOrigem, AArquivoDestino: string; const AGSDllPath: string ): Boolean;

implementation

type
  TGsApiNewInstance    = function( var pinstance: Pointer; caller_handle: Pointer )     : Integer; stdcall;
  TGsApiInitWithArgs   = function( instance: Pointer; argc: Integer; argv: PPAnsiChar ): Integer; stdcall;
  TGsApiExit           = function( instance: Pointer )                                         : Integer; stdcall;
  TGsApiDeleteInstance = procedure( instance: Pointer ); stdcall;

function ProcessarPdfComGhostscript( const AArquivoOrigem, AArquivoDestino: string; const AGSDllPath: string ): Boolean;
var
  LHandle               : HMODULE;
  LGSAPI_New_Instance   : TGsApiNewInstance;
  LGSAPI_Init_with_Args : TGsApiInitWithArgs;
  LGSAPI_Exit           : TGsApiExit;
  LGSAPI_Delete_Instance: TGsApiDeleteInstance;

  LInstance: Pointer;
  LArgs    : array [ 0 .. 5 ] of PAnsiChar;
  LResult  : Integer;

  LProgram: AnsiString;
  LBatch  : AnsiString;
  LNoPause: AnsiString;
  LDevice : AnsiString;
  LOutput : AnsiString;
  LInput  : AnsiString;
begin
  Result := False;
  ...
 try
    @LGSAPI_New_Instance    := GetProcAddress( LHandle, 'gsapi_new_instance' );
    @LGSAPI_Init_with_Args  := GetProcAddress( LHandle, 'gsapi_init_with_args' );
    @LGSAPI_Exit            := GetProcAddress( LHandle, 'gsapi_exit' );
    @LGSAPI_Delete_Instance := GetProcAddress( LHandle, 'gsapi_delete_instance' );
    ..
    if LGSAPI_New_Instance( LInstance, nil ) < 0 then ... // error
      // message ... exit;
    else
    ...
      ...
    LProgram := AnsiString( 'gs' );
      LBatch   := AnsiString( '-dBATCH' );
      LNoPause := AnsiString( '-dNOPAUSE' );
      LDevice  := AnsiString( '-sDEVICE=pdfwrite' );
      LOutput  := AnsiString( '-sOutputFile=' + AArquivoDestino );
      LInput   := AnsiString( AArquivoOrigem );
    ...
    LArgs[ 0 ] := PAnsiChar( LProgram );
      LArgs[ 1 ] := PAnsiChar( LBatch );
      LArgs[ 2 ] := PAnsiChar( LNoPause );
      LArgs[ 3 ] := PAnsiChar( LDevice );
      LArgs[ 4 ] := PAnsiChar( LOutput );
      LArgs[ 5 ] := PAnsiChar( LInput );

      // Executa o processamento do PDF
      LResult := LGSAPI_Init_with_Args( LInstance, 6, @LArgs[ 0 ] );
     ...
      if LResult >= 0 then
      begin
        Result := True;
        // Abre o arquivo resultante no visualizador padrão do Windows
        ShellExecute( 0, 'open', PChar( AArquivoDestino ), nil, nil, SW_NORMAL );
      end  else
      begin
        ///
      end;
      //
     LGSAPI_Exit( LInstance );  // 
    finally
      LGSAPI_Delete_Instance( LInstance );
    end;

  finally
    FreeLibrary( LHandle );
  end;

Código Delphi [-]
uses
  UImprimirGhostscript;

procedure TForm2.btnGhostScriptPrintingClick( Sender: TObject );
var
  LCaminhoDLL      : string;
  LOrigem, LDestino: string;
begin
  randomize;
  //
  (*
Podrías colocar solo el archivo DLL (gsdll32.dll) en cualquier carpeta de tu preferencia; 
¡no necesitarías todos los archivos de la instalación de GhostScript!
*)
  // Ajuste o caminho da DLL conforme a sua instalação do Ghostscript (ex: pasta bin)
  LCaminhoDLL := 'E:\RADProjectsD13\_Temp\Nova pasta (13)\GhostScript\gsdll32.dll';
  LOrigem     := 'E:\DelphiTela.pdf';
  LDestino    := Format( 'E:\%s%.8d.pdf', [ 'NewPDF_', random( word.MaxValue ) ] );

  if ProcessarPdfComGhostscript( LOrigem, LDestino, LCaminhoDLL ) then
    Memo1.Lines.Add( TimeToStr( now ) + ', ' + LOrigem + ', was sent to the printer.' + slinebreak + LDestino );
end;


Aquí estoy usando Chrome como mi aplicación predeterminada para abrir archivos PDF.


Última edición por emailx45 fecha: Hace 4 Días a las 19:01:22.
Responder Con Cita
  #10  
Antiguo Hace 4 Días
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Ubicación: Toledo - España
Posts: 1.430
Poder: 21
Angel.Matilla Va por buen camino
Cita:
Empezado por emailx45 Ver Mensaje
Otra forma sería utilizar únicamente la DLL de GhostScript
Gracias por tu respuesta. La leeré con atención, aunque no sé que versión de está instalada con BullZip.
Responder Con Cita
  #11  
Antiguo Hace 3 Días
emailx45 emailx45 is offline
Miembro
 
Registrado: abr 2025
Posts: 27
Poder: 0
emailx45 Va por buen camino
Esto debería redirigir la salida a una impresora física instalada y utilizada por defecto en el sistema.

Código Delphi [-]
 var
        LPrinterName: string := 'HP LaserJet Pro M404'; // 'Microsoft Printer PDF'
        //
      LProgram := AnsiString( 'gs' );                         // ghostscript program
      LBatch   := AnsiString( '-dBATCH' );                    // -d
      LNoPause := AnsiString( '-dNOPAUSE' );                  // -d
      LDevice  := AnsiString( '-sDEVICE=mswinprn' );          // '-sDEVICE=pdfwrite' );              // -s
      LOutPut  := AnsiString( '-s%printer%' + LPrinterName ); // '-sOutputFile=' + APDFFileOutput ); // -s
      LInPut   := AnsiString( APDFFileInput );                // -s
..
Responder Con Cita
  #12  
Antiguo Hace 9 Horas
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Ubicación: Toledo - España
Posts: 1.430
Poder: 21
Angel.Matilla Va por buen camino
Después de unos cuantos días peleando, y con ayuda de internet, conseguí un código que funciona. Son estas cuatro funciones:
1.Establece la configuración de Bullzip
Código:
HRESULT BullzipSetValue(IDispatch *Objeto, const wchar_t *Parametro, const wchar_t *Valor)
{
     VARIANT argumentos[2];

     VariantInit(&argumentos[0]);
     VariantInit(&argumentos[1]);

     // Los argumentos se pasan en orden inverso.
     argumentos[1].vt      = VT_BSTR;
     argumentos[1].bstrVal = SysAllocString(Parametro);

     argumentos[0].vt      = VT_BSTR;
     argumentos[0].bstrVal = SysAllocString(Valor);

     HRESULT hr = InvocarMetodo(Objeto, L"SetValue", argumentos, 2);

     VariantClear(&argumentos[0]);
     VariantClear(&argumentos[1]);

     return hr;
}
//-----------------------------------------------------------------
2. Escribe la configuración de Bullzip.
Código:
HRESULT BullzipWriteSettings(IDispatch *Objeto)
{
     VARIANT argumento;

     VariantInit(&argumento);

     argumento.vt      = VT_BOOL;
     argumento.boolVal = VARIANT_TRUE;

     HRESULT hr = InvocarMetodo(Objeto, L"WriteSettings", &argumento, 1);
     VariantClear(&argumento);
     return hr;
}
//-----------------------------------------------------------------
3. Función auxiliar para ejecutar métodos COM mediante IDispatch
Código:
HRESULT InvocarMetodo(IDispatch *Objeto, const wchar_t *Nombre, VARIANT *Argumentos, int NumeroArgumentos)
{
     DISPID dispid;
     LPOLESTR nombre = (LPOLESTR)Nombre;

     HRESULT hr = Objeto->GetIDsOfNames(IID_NULL, &nombre, 1, LOCALE_USER_DEFAULT, &dispid);
     if (FAILED(hr))
          return hr;

     DISPPARAMS parametros;
     parametros.rgvarg = Argumentos;
     parametros.rgdispidNamedArgs = NULL;
     parametros.cArgs = NumeroArgumentos;
     parametros.cNamedArgs = 0;

     VARIANT resultado;
     VariantInit(&resultado);

     hr = Objeto->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &parametros, &resultado, NULL, NULL);
     VariantClear(&resultado);
     return hr;
}
//---------------------------------------------------------------------------
4. Genera el PDF
Código:
bool GenerarPDF(TQuickRep *Reporte, AnsiString &FicheroDestino, int ImpPdf)
{
     CLSID clsid;
     IDispatch *pBullzipSettings = NULL;
     
     try
     {
          // Inicializar COM.
          HRESULT hr = CoInitialize(NULL);

          if (FAILED(hr))
               throw Exception("Error al inicializar COM.");

          // Obtener CLSID de Bullzip.
          hr = CLSIDFromProgID( L"Bullzip.PDFPrinterSettings", &clsid);

          if (FAILED(hr))
               throw Exception("No se encuentra Bullzip PDF Printer Settings.");

          // Crear objeto COM.
          hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void**)&pBullzipSettings);

          if (FAILED(hr))
               throw Exception("No se pudo crear el objeto COM de Bullzip.");

          // Convertir la ruta a formato Unicode.
          WideString rutaPDF = ExtractFilePath(Application->ExeName) + "Impresos\\" + FicheroDestino;

          // Configurar destino del PDF.
          hr = BullzipSetValue(pBullzipSettings, L"Output", rutaPDF.c_bstr());

          if (FAILED(hr))
               throw Exception("Error configurando Output.");

          // No abrir el lector PDF.
          hr = BullzipSetValue(pBullzipSettings, L"ShowPDF", L"no");

          if (FAILED(hr))
               throw Exception("Error configurando ShowPDF.");

          // Ocultar la ventana de configuración.
          hr = BullzipSetValue(pBullzipSettings, L"ShowSettings", L"never");

          if (FAILED(hr))
               throw Exception("Error configurando ShowSettings.");

          // Sobrescribir automáticamente.
          hr = BullzipSetValue(pBullzipSettings, L"ConfirmOverwrite", L"no");

          if (FAILED(hr))
               throw Exception("Error configurando ConfirmOverwrite.");

          // Guardar configuración para la siguiente impresión.
          hr = BullzipWriteSettings(pBullzipSettings);

          if (FAILED(hr))
               throw Exception("Error escribiendo configuración Bullzip.");

          // Liberar objeto COM antes de imprimir.
          pBullzipSettings->Release();
          pBullzipSettings = NULL;


          // Seleccionar Bullzip como impresora.
          int impresoraAnterior = Printer()->PrinterIndex;

          Printer()->PrinterIndex = ImpPdf;

          try
          {
               // Imprimir directamente el QuickReport.
               Reporte->Print();
          }
          __finally
          {
               Printer()->PrinterIndex = impresoraAnterior;
          }

          CoUninitialize();
          return true;
     }
     catch (Exception &e)
     {
          if (pBullzipSettings != NULL)
               pBullzipSettings->Release();

          CoUninitialize();
          ShowMessage(AnsiString("Error generando PDF: ") + e.Message);
             return false;
     }
}
//---------------------------------------------------------------------------
Y se usa así:
Código:
if (Printer()->Printers->Strings[Form1->Tag] == "Bullzip PDF Printer")
{
     AnsiString cAux = Now().FormatString("'L'ddhhnnss'.pdf'");
     if (!GenerarPDF(Form1->QuickRep1, cAux, Form1->Tag))
          Mensaje(1, "No se ha generado el fichero " + cAux, "Volver");
}
En el Tag del formualrio guardo la impresora seleccionada, lo que hago a través de otro formulario diferente. Al llamar a la función para generar el PDF paso tres parámetros:
  1. El QuickReport que quiero imprimir
  2. El nombre del fichero de destino. Puede pasarse con o sin dirección de la carpeta de destino. Yo paso sólo el nombre porque los guardo siempre en la misma carpeta.
  3. El valor de la impresora
Y funciona
Imágenes Adjuntas
Tipo de Archivo: pdf Disco_03100121.pdf (270,8 KB, 0 visitas)

Última edición por Angel.Matilla fecha: Hace 9 Horas a las 11:03:19.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Automatizar web login amadis Internet 2 13-08-2010 15:15:42
automatizar instalación de mysql Aprendiendo MySQL 3 10-02-2010 17:19:58
Automatizar OpenOffice. Critter Servers 2 31-07-2007 20:41:24
Automatizar BACKUPS y RESTORES AMINOA2R Firebird e Interbase 12 20-10-2005 17:11:16
Automatizar Login JoseQ Internet 0 30-03-2005 13:35:50


La franja horaria es GMT +2. Ahora son las 20:54:47.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi