La maggior parte degli esempi HotPDF inserisce un componente in un form a design time. È comodo per le demo, ma il codice di produzione a volte deve creare il componente PDF solo per una specifica operazione di esportazione. La creazione dinamica è utile in moduli di servizio, helper di report, job batch e form in cui il componente non deve vivere per tutta la durata del form.
Il modello di base in C++Builder consiste nell’allocare un’istanza THotPDF, configurare il file di output e le opzioni del documento, generare il PDF e rilasciare il componente al termine dell’operazione. L’esempio seguente mostra il flusso minimo dentro un handler di pulsante.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include #pragma hdrstop #include "Unit1.h" #pragma package(smart_init) #pragma link "HPDFDoc" #pragma resource "*.dfm" TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } void __fastcall TForm1::Button1Click(TObject *Sender) { THotPDF* HotPDF1 = new THotPDF(this); HotPDF1->FileName = "HelloWorld.pdf"; HotPDF1->AutoLaunch = true; HotPDF1->BeginDoc(false); HotPDF1->CurrentPage->PrintText( 10, 10, 0, "Hello World!" ); HotPDF1->EndDoc(); HotPDF1->Free(); } |
Ownership e pulizia
Il costruttore riceve this come owner, quindi il form può pulire il componente se rimane vivo. In questo breve esempio l’oggetto viene anche liberato esplicitamente dopo EndDoc. Nel codice reale, mantieni il percorso di cleanup sicuro rispetto alle eccezioni: se la generazione PDF può fallire, racchiudi il lavoro in un blocco try/__finally o usa un piccolo helper RAII in modo che Free() venga comunque eseguito.
Non chiamare metodi sul componente dopo Free() ed evita di memorizzare il puntatore in un ambito più ampio, a meno che un’altra parte del form possieda davvero il ciclo di vita del componente. Una variabile locale è di solito la scelta più semplice per esportazioni PDF una tantum.
Note di configurazione del progetto
Il progetto deve poter trovare header, librerie e package design/runtime di HotPDF. Aggiungi la directory include di HotPDF al percorso include C++ e la directory delle librerie al percorso di ricerca del linker. Se il progetto collega HPDFDoc, mantieni invariati i nomi di package e unità così C++Builder può risolvere gli header generati.
Prima della distribuzione
- Usa un percorso di output assoluto o validato quando generi file fuori da una cartella demo.
- Chiama
BeginDoceEndDocin coppie bilanciate. - Apri il PDF generato in almeno un viewer esterno, non solo con
AutoLaunch. - Registra gli errori di generazione così il supporto può distinguere problemi di percorso, permessi, font e rendering PDF.
Struttura sicura rispetto alle eccezioni
L’esempio mantiene il codice compatto, ma una vera routine di esportazione deve gestire le eccezioni tra allocazione e cleanup. La generazione PDF può fallire perché la cartella di output è in sola lettura, un font non può essere risolto, uno stream viene chiuso troppo presto o i dati utente contengono un valore inatteso. Il percorso di cleanup non deve dipendere dal successo di ogni chiamata di disegno.
Un approccio pratico è creare il componente subito prima dell’esportazione e poi rilasciarlo in un blocco di cleanup garantito. Così la vita del componente resta legata a un solo job PDF. Se l’applicazione genera molti documenti in sequenza, questo schema riduce anche la possibilità che lo stato di un documento passi al successivo.
Componenti a design time e a runtime
Un componente a design time è più semplice quando un form possiede un flusso di esportazione prevedibile. Un componente a runtime è migliore quando l’applicazione richiede più esportatori temporanei, sceglie le impostazioni dinamicamente o esegue codice di esportazione da una classe helper invece che da un form. Le chiamate API sono le stesse; cambia solo chi possiede l’oggetto e quanto a lungo vive.
Per codice in stile server o batch, evita di affidarti a AutoLaunch. Genera il file, verifica che esista, registra il percorso di output e lascia che il workflow chiamante decida se aprire un viewer.