De flesta HotPDF-exempel placerar en komponent på ett formulär vid design time. Det är praktiskt för demos, men produktionskod behöver ibland skapa PDF-komponenten bara för en viss export. Dynamisk skapning är användbar i servicemoduler, rapporthjälpare, batchjobb och formulär där komponenten inte ska leva under hela formulärets livstid.
Det grundläggande C++Builder-mönstret är att allokera en THotPDF-instans, konfigurera utdatafilen och dokumentalternativen, generera PDF-filen och frigöra komponenten när arbetet är klart. Exemplet nedan visar det minsta arbetsflödet i en button handler.
|
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(); } |
Ägarskap och cleanup
Konstruktorn får this som owner, så formuläret kan städa upp komponenten om den fortfarande finns kvar. I detta korta exempel frigörs objektet också uttryckligen efter EndDoc. I verklig kod ska cleanup-vägen vara exception-safe: om PDF-generering kan misslyckas, lägg arbetet i ett try/__finally-block eller använd en liten RAII-hjälpare så att Free() ändå körs.
Anropa inga metoder på komponenten efter Free(), och undvik att lagra pekaren i ett bredare scope om inte en annan del av formuläret verkligen äger komponentens livscykel. En lokal variabel är oftast det enklaste valet för engångsexporter till PDF.
Projektinställningar
Projektet måste kunna hitta HotPDF-headers, bibliotek och design/runtime packages. Lägg till HotPDF include-katalogen i C++ include-sökvägen och bibliotekskatalogen i länkarens sökväg. Om projektet länkar HPDFDoc, behåll package- och enhetsnamn oförändrade så att C++Builder kan hitta de genererade header-filerna.
Före leverans
- Använd en absolut eller validerad utdatasökväg när filer genereras utanför en demomapp.
- Anropa
BeginDocochEndDoci balanserade par. - Öppna den genererade PDF-filen i minst en extern viewer, inte bara med
AutoLaunch. - Logga genereringsfel så att support kan skilja på sökvägs-, behörighets-, font- och PDF-renderingsproblem.
Exception-safe struktur
Exemplet håller koden kompakt, men en riktig exportrutin bör hantera undantag mellan allokering och cleanup. PDF-generering kan misslyckas för att utdatamappen är skrivskyddad, en font inte kan hittas, en stream stängs för tidigt eller användardata innehåller ett oväntat värde. Cleanup-vägen ska inte bero på att varje ritningsanrop lyckas.
En praktisk metod är att skapa komponenten omedelbart före exporten och sedan frigöra den i ett garanterat cleanup-block. Det binder komponentens livstid till ett PDF-jobb. Om applikationen genererar många dokument i följd minskar detta mönster också risken att tillstånd från ett dokument läcker in i nästa.
Design-time jämfört med runtime-komponenter
En design-time-komponent är enklare när ett formulär äger ett förutsägbart exportflöde. En runtime-komponent är bättre när applikationen behöver flera tillfälliga exportörer, väljer inställningar dynamiskt eller kör exportkod från en hjälparklass i stället för från ett formulär. API-anropen är samma; skillnaden är bara vem som äger objektet och hur länge det lever.
För serverliknande eller batchkod, undvik att förlita dig på AutoLaunch. Generera filen, kontrollera att den finns, registrera utdatasökvägen och låt det anropande arbetsflödet avgöra om en viewer ska öppnas.