Techninis straipsnis

Dinaminis „HotPDF“ komponento kūrimas ir atlaisvinimas „C++Builder“ aplinkoje

Nuvilkti THotPDF į formą projektavimo metu yra gerai greitam prototipui, tačiau tai susieja komponentą su formos gyvavimo ciklu, o to retai norima gamybiniame kode. Ataskaitų generatorius, kuris paleidžiamas vieną kartą paspaudus mygtuką, paslaugos gija, kuri paketuoja naktinius eksportavimus, pagalbinė klasė, kuri apskritai neturi formos: kiekvienoje iš šių situacijų norite, kad komponentas egzistuotų tiksliai vienos PDF užduoties trukmę, o po to išnyktų. Tai reiškia paskirstymą vykdymo metu, ir tai pakeičia du dalykus, kuriuos verta suprasti prieš rašant pirmąją eilutę: kam priklauso objektas ir kaip atliekamas valymas, kai kažkas nepavyksta

Savininko semantika VCL

Kiekvienas VCL komponento konstruktorius priima Owner parametrą, kurio tipas yra TComponent*. Perdavus this (formą), naujas objektas užregistruojamas formos priklausančių komponentų sąraše, todėl, jei forma sunaikinama, kai komponentas vis dar gyvas, VCL jį atlaisvina automatiškai. Perdavus nullptr, reiškia, kad savininko nėra: prisiimate visą atsakomybę už rodyklę, ir niekas jos neišvalys už jus, jei išimtis išvynios krūvą prieš aiškų jūsų delete

Vienkartiniam eksportavimui, kuris užbaigiamas vienoje funkcijoje, tinka abu pasirinkimai, tačiau jie turi skirtingus gedimo režimus. Kai savininkas yra this, nuotėkis neįmanomas, kol forma galiausiai uždaroma; naudojant nullptr, rodyklė turi pasiekti __finally bloką. Praktiškai, nullptr kartu su __finally šablonu yra šiek tiek švaresnis trumpalaikiams objektams, nes padaro gyvavimo ribą matomą iš pirmo žvilgsnio ir išvengia formos kaupti priklausančius objektus, kurie turėjo būti laikini

Išimtims saugi struktūra

PDF generavimas gali nepavykti dėl priežasčių, kurios neturi nieko bendro su API: išvesties katalogas skirtas tik skaityti, trūksta šrifto failo, srautas ištuštinamas per anksti arba skambinančiojo pateikti duomenys pasiekia ilgio limitą. Nepriklausomai nuo priežasties, valymo kelias turi būti paleistas. Idiomatinis „C++Builder“ būdas tai garantuoti yra try/__finally:

#include <vcl.h>
#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* Pdf = new THotPDF(nullptr);
    try
    {
        Pdf->FileName = "output.pdf";
        Pdf->Compression = cmFlateDecode;
        Pdf->FontEmbedding = true;
        Pdf->BeginDoc();
        Pdf->CurrentPage->SetFont("Arial", TFontStyles(), 12);
        Pdf->CurrentPage->TextOut(72, 720, 0, L"Hello from C++Builder");
        Pdf->EndDoc();
    }
    __finally
    {
        delete Pdf;
    }
}

Verta atkreipti dėmesį į kelis dalykus šiame sąraše. Savininkas yra nullptr, todėl gyvavimo laikas tampa aiškus. Compression ir FontEmbedding nustatomi prieš BeginDoc: abi yra dokumento lygio parinktys, kurias „HotPDF“ pritaiko atidarydamas dokumentą, o vėlesnis jų priskyrimas neturi jokio poveikio. TextOut priima koordinates taškais, matuojamais nuo apatinio kairiojo puslapio kampo, Y didėjant į viršų; pora 72, 720 padeda tekstą netoli laiško formato puslapio viršutinio kairiojo kampo su vieno colio kairiąja parašte. delete Pdf blokas __finally dalyje vykdomas, nesvarbu, ar BeginDoc, piešimas, ar EndDoc sukėlė išimtį, ar ne

Venkite kviesti bet kokį metodą per Pdf po delete. Jei rodyklė saugoma nario kintamajame, iškart po ištrynimo nustatykite ją į nullptr, kad bet koks atsitiktinis vėlesnis prisijungimas sukeltų aiškią avariją, o ne tylų duomenų sugadinimą

Projekto konfigūracija

„C++Builder“ randa THotPDF naudodamas įtraukimo kelių, bibliotekų kelių ir pragma direktyvos derinį. Sugeneruota antraštė yra šalia HPDFDoc.pas „HotPDF“ šaltinio kataloge; pridėkite tą katalogą prie Project > Options > C++ Compiler > Include path. #pragma link "HPDFDoc" direktyva nurodo saistytojui įtraukti sukompiliuotą vienetą, neįtraukiant jo rankiniu būdu į projekto failą. Jei naudojate vykdymo laiko paketą vietoj statinio susiejimo, pirmiausia įdiekite „HotPDF“ projektavimo ir vykdymo laiko paketus; pragma vis tiek taikoma

Palikite vieneto pavadinimą HPDFDoc nepakeistą. „C++Builder“ išveda antraštės pavadinimą iš „Pascal“ vieneto pavadinimo, todėl failo pervardijimas arba kelio pseudonimo naudojimas pragmoje tyliai sugadina paiešką

Taikymo sritis ir daugiadokumentinės užduotys

Vienkartiniam eksportavimui, kurį suaktyvina vartotojo veiksmas, vietinis kintamasis, apribotas mygtuko apdorojimo tvarkykle, yra teisingas atsakymas: jis sukuriamas, naudojamas ir sunaikinamas viename iškvietimo rėmelyje, ir ketinimas yra akivaizdus bet kam, skaitančiam kodą vėliau. Projektavimo laiko alternatyva pateisinama, kai ta pati forma valdo nuolatinę darbo eigą, pavyzdžiui, spausdinimo peržiūros skydelį, kuris perkonstruoja dokumentą kaskart, kai vartotojas pakeičia nustatymą; tokiu atveju komponento išlaikymas aktyvaus ir pakartotinis BeginDoc/EndDoc kvietimas sukelia mažiau trikdžių nei nuolatinis krūvos objektų paskirstymas ir atlaisvinimas

Paketinėms užduotims, kurios nuosekliai sukuria daug dokumentų, vieno THotPDF susiejimas vienam dokumentui yra vertas paskirstymo išteklių. Būsena nepersiduoda tarp dokumentų, jei nėra objekto, kuris ją perduotų, ir tai yra viena klasė protarpiais pasitaikančių klaidų, kurių jums niekada neteks derinti. Paskirstykite, generuokite, ištrinkite, pakartokite

Viena savybė, kuri atsiranda keliose „HotPDF“ demonstracinėse versijose, yra AutoLaunch, atidaranti sugeneruotą failą sistemos PDF peržiūros programoje iškart po EndDoc. Tai naudinga rašant pirmąjį maketo juodraštį. Gamybinėje aplinkoje praleiskite tai: atidarykite išvesties kelią aiškiai, patikrinkite, ar failas egzistuoja ir jo dydis nėra nulinis, užregistruokite rezultatą ir leiskite kviečiančiajai darbo eigai nuspręsti, ar peržiūros programa yra aktuali. Paketinėje užduotyje AutoLaunch paleidžia vieną peržiūros programos langą kiekvienam dokumentui ir kai kuriose sistemose užblokuos procesą, laukiant, kol peržiūros programa bus uždaryta

Komponentas THotPDF ir visi čia parodyti piešimo iškvietimai yra „Delphi“ ir „C++Builder“ skirto „HotPDF“ komponento dalis