Dva odprta dokumenta hrati, ista številka strani, vsak v svoji drsni plošči: to je jedro primerjalnega pregledovalnika. PDFium Component to omogoča prek preprostega objektnega modela, kjer je TPdf lastnik datoteke, TPdfView pa lastnik prikaza. En dokument, en TPdf, en TPdfView. Če želite tri plošče, imate tri pare. Težki deli niso klici API, temveč aritmetika postavitve ob spreminjanju velikosti okna in logika sinhronizacije strani, ko se odločate, kateri pogled naj sledi kateremu
Postavitev obrazca
Obrazec VCL vsebuje tri vsebnike TScrollBox drug ob drugem, vsak z vgrajenim TPdfView in poravnan na alClient, tako da zapolni polje. Med polji sta nameščeni dve komponenti TSplitter, tako da lahko uporabnik med delovanjem prilagaja širine stolpcev. Orodna vrstica nad ploščami vsebuje gumbe za odpiranje, kontrole za zoom in preklop med pogledom dveh ali treh plošč
Način s tremi pogledi je logična vrednost (boolean), ki jo obrazec spremlja interno. Ko se preklopi, ponovno izračunate širine ter prikažete ali skrijete tretji stolpec. Najpreprostejši pristop je, da počistite vse lastnosti Align, skrijete splitterje in nato nastavite absolutne položaje:
procedure TFormMain.UpdateLayout;
var
TotalWidth: Integer;
begin
TotalWidth := ClientWidth;
if ThreeViewMode then
begin
ScrollBox3.Visible := True;
ScrollBox1.Left := 0;
ScrollBox1.Width := TotalWidth div 3;
ScrollBox2.Left := ScrollBox1.Width;
ScrollBox2.Width := TotalWidth div 3;
ScrollBox3.Left := ScrollBox2.Left + ScrollBox2.Width;
ScrollBox3.Width := TotalWidth - ScrollBox3.Left;
// Apply the same (ClientHeight - toolbar height) to all three Height values
end
else
begin
ScrollBox3.Visible := False;
ScrollBox1.Left := 0;
ScrollBox1.Width := TotalWidth div 2;
ScrollBox2.Left := ScrollBox1.Width;
ScrollBox2.Width := TotalWidth - ScrollBox2.Left;
end;
end;
Nastavitev Align := alNone na vseh treh poljih pred celoštevilsko aritmetiko prepreči, da bi se mehanizem omejitev VCL boril z vašimi dodelitvami. Po določitvi položaja obnovite vidnost splitterjev, če želite omogočiti spreminjanje velikosti z vlečenjem v načinu dveh pogledov
Višina vsakega drsnega polja je enaka višini območja stranke (client area) minus višina orodne vrstice. Ker je orodna vrstica zasidrana na vrhu z alTop, ClientHeight - PanelButtons.Height vam poda uporaben navpični prostor. To dodelite vsem trem poljem znotraj istega klica UpdateLayout, da se izognete utripanju postavitve zaradi začasnih razlik v višini
Odpiranje dokumenta
Vsak par plošč potrebuje svojo proceduro za odpiranje. Vzorec je kratek: deaktivirajte komponento, nastavite ime datoteke, poskusite aktivirati in ulovite EPdfError, če datoteka zahteva geslo. Upoštevajte, da TPdfView.Active nadzoruje upodabljanje, medtem ko TPdf.Active dejansko odpre datoteko; ti dve lastnosti sta neodvisni. Nastavitev PdfView.Active := True, ko povezane TPdf še ni aktivna, je neškodljiva, vendar ne prikaže ničesar
procedure TFormMain.OpenPdfFile(PdfComponent: TPdf;
PdfViewComponent: TPdfView);
var
Password: string;
begin
if not OpenDialog.Execute then
Exit;
PdfComponent.Active := False;
PdfComponent.FileName := OpenDialog.FileName;
PdfComponent.Password := '';
try
PdfComponent.Active := True;
except
on E: EPdfError do
begin
if InputQuery('Password', 'Enter document password:', Password) then
begin
PdfComponent.Password := Password;
PdfComponent.Active := True;
end
else
raise;
end;
end;
if PdfComponent.Active then
begin
PdfViewComponent.PageNumber := 1;
SetActivePdfView(PdfViewComponent);
end;
end;
Po dodelitvi vedno preverite PdfComponent.Active; poškodovana datoteka ali napačno geslo povzroči, da nalaganje tiho spodleti, ne da bi se sprožila izjema v privzeti poti. Eksplicitna nastavitev PdfViewComponent.PageNumber := 1 po uspešnem odpiranju prepreči ohranitev stare številke strani iz prejšnjega dokumenta
Zgoraj navedena koda za obravnavo gesel sproži izjema pri kateri koli napaki, ki ni znano sporočilo o geslu. To je namerno: želite, da se poškodovane ali nepodprte datoteke takoj pokažejo, namesto da bi se tiho skrile kot prazna plošča. Uporabnik, ki ne vidi ničesar, ne ve, ali se je datoteka naložila in je prazna, ali pa jo je komponenta zavrnila. Sprožitev izjeme ohranja napako vidno
Sledenje aktivni plošči
Ko uporabnik klikne znotraj plošče, ta postane aktivna. Obrazec spremlja zasebno polje FActivePdfView: TPdfView. Vizualna povratna informacija je sprememba barve obrobe na vsebujočem TScrollBox: nastavite jo na clHighlight za aktivno polje in clWindow za ostala. To povežite z vsakim dogodkom TPdfView.OnClick in s proceduro za odpiranje, da fokus sledi pravkar odprtemu dokumentu
Nekatere operacije veljajo za vse vidne plošče in ne le za aktivno. A boolean FAllViewsMode na obrazcu krmili to vejo. Ko je True, se spremembe povečave in navigacija po straneh prenesejo na vsako ploščo z aktivnim dokumentom:
procedure TFormMain.ApplyZoomToAll(NewZoom: Double);
begin
if PdfView1.Active then PdfView1.Zoom := NewZoom;
if PdfView2.Active then PdfView2.Zoom := NewZoom;
if ThreeViewMode and PdfView3.Active then PdfView3.Zoom := NewZoom;
end;
Sinhronizirana navigacija po straneh
Sinhronizirana navigacija je neobvezna, vendar uporabna pri delovnih tokovih pregledovanja različic dokumentov, kjer obe datoteki pokrivata enak obseg strani. Logika sodi v dogodkovni predstavitveni program, ki se sproži po tem, ko uporabnik navigira po enem pogledu. Ko izvorni pogled spremeni svojo vrednost PageNumber, predstavitveni program to številko prenese na ostale poglede, z eno varovalko: ciljni pogled mora imeti vsaj toliko strani, sicer se korak preskoči
Lastnosti PageNumber na TPdfView in na TPdf sta neodvisni. TPdf.PageNumber spremlja, katero stran komponenta dokumenta šteje za trenutno; TPdfView.PageNumber pa spremlja, kaj je prikazano na zaslonu. Za namene navigacije potrebujete lastnost pogleda, ne dokumenta
Potrditveno polje, označeno na primer s "Sinhroniziraj strani", daje uporabniku nadzor. Ko je odznačeno, vsaka plošča navigira neodvisno, predstavitveni program pa se takoj zaključi. Ta neodvisnost je pomembna za primere, ko imata dokumenta različno število strani ali ko želi uporabnik najti ustrezen odstavek v prevodu, ki se začne na drugi strani. Prisilna sinhronizacija bi orodje naredila manj uporabno kot preprosta namestitev dveh oken
Ena stvar, na katero morate biti pozorni: programsko nastavljanje PdfView.PageNumber znotraj sinhronizacijskega predstavitvenega programa bo samo po sebi sprožilo dogodek spremembe na tem pogledu. Zaščitite se pred neskončno rekurzijo z logično zastavico, ki jo nastavite pred dodelitvijo in počistite takoj po njej. Zastavica je nastavljena na ravni obrazca in ne na ravni pogleda, saj vsi trije pogledi souporabljajo isti predstavitveni program
Zoom na ploščo
Vsak TPdfView vsebuje svojo lastnost Zoom (tipa Double), kjer 1.0 predstavlja 100 %. Njena nastavitev povozi kateri koli aktivni FitMode. Za gumb "prilagodi širini" na aktivni plošči preberite zoom iz PdfView.PageWidthZoom[PdfView.PageNumber] in ga dodelite. Za prilagoditev strani uporabite PageZoom[PageNumber]. Obe sta lastnosti polja z indeksom strani od 1 naprej, zato se pred dostopom zaščitite pred številko strani nič
Ko izvozite trenutno stran v sliko, preberite rotacijo iz pogleda, vendar pokličite RenderPage na komponenti TPdf, ne na pogledu. Bitna oblika metode TPdf.RenderPage sprejme eksplicitne dimenzije slikovnih pik ter vrednost TRotation in nabor TRenderOptions. Varianta funkcije vrne TBitmap v lasti klicatelja, ki ga morate po shranjevanju sami sprostiti:
procedure TFormMain.SaveActiveViewAsImage;
var
Pdf: TPdf;
Bmp: TBitmap;
Jpeg: TJpegImage;
begin
if not Assigned(FActivePdfView) or not FActivePdfView.Active then
Exit;
Pdf := FActivePdfView.Pdf;
Pdf.PageNumber := FActivePdfView.PageNumber;
Bmp := Pdf.RenderPage(
0, 0,
Round(Pdf.PageWidth * 2),
Round(Pdf.PageHeight * 2),
FActivePdfView.Rotation, [], clWhite);
try
if SavePictureDialog.Execute then
begin
Jpeg := TJpegImage.Create;
try
Jpeg.Assign(Bmp);
Jpeg.CompressionQuality := 90;
Jpeg.SaveToFile(SavePictureDialog.FileName);
finally
Jpeg.Free;
end;
end;
finally
Bmp.Free;
end;
end;
Množitelj 2x za širino in višino zagotavlja ostrejši izpis za dokumente z drobnim besedilom. Konstrukcija try/finally okoli sprostitve bitne slike ni neobvezna; preklic TSaveDialog še vedno doseže blok finally, vi pa želite bitno sliko sprostiti ne glede na uporabnikovo dejanje
Zahteve za DLL
PDFium Component obdaja izvorno knjižnico pdfium. 32-bitni gostiteljski proces potrebuje pdfium32.dll, 64-bitni gostitelj pa pdfium64.dll. Različice z mehanizmom JavaScript V8 dodajo pripono v8 in tehtajo približno 23 do 27 MB v primerjavi s 5 do 6 MB za standardne gradnje. Za primerjalni pregledovalnik, ki onemogoči izpolnjevanje obrazcev (Pdf.FormFill := False), zadošča standardna različica brez mehanizma V8, ko želite ohraniti manjšo velikost distribucije
DLL postavite v isti imenik kot izvršljivo datoteko ali v kateri koli imenik v sistemski poti PATH. Komponenta ga naloži na zahtevo ob aktivaciji prvega TPdf, zato se manjkajoči DLL pokaže takrat in ne ob zagonu aplikacije. Če pošiljate namestitveni program, je najbolj zanesljiv pristop kopiranje DLL v mapo aplikacije med namestitvijo, namesto zanašanja na sistemski imenik, ki ga administrator lahko pozneje počisti
Gradnje z mehanizmom V8 so koristne predvsem takrat, ko morate sodelovati z dejanji JavaScript v PDF-ju, na primer za sprožitev kalkulacijskih polj ali predstavitvenih programov za oddajo. Pasivni primerjalni pregledovalnik nima razloga za izvajanje JavaScripta; nastavitev Pdf.FormFill := False pred Active := True v celoti preskoči okolje za izpolnjevanje obrazcev, kar pomeni, da se mehanizem JS ne inicializira niti ob uporabi standardne gradnje. To je pravilen privzeti način za bralni pregledovalnik, ne glede na to, katero različico DLL pošiljate
Za več podrobnosti o komponenti PDFium Component in njenem celotnem API-ju obiščite produktno stran Delphi PDFium Component