Kaksi asiakirjaa auki yhtä aikaa, sama sivunumero, kumpikin omassa vieritettävässä paneelissaan: se on vertailukatseluohjelman ydin. PDFium Component tarjoaa tämän suoraviivaisella objektimallilla, jossa TPdf omistaa tiedoston ja TPdfView omistaa näytön. Yksi asiakirja, yksi TPdf, yksi TPdfView. Haluat kolme paneelia, sinulla on kolme paria. Vaikeat osat eivät ole API-kutsut; ne ovat asettelu-aritmetiikkaa, kun ikkunan koko muuttuu, ja sivusynkronoinnin logiikka, kun päätät, minkä näkymän tulisi seurata mitäkin
Lomakkeen asettelu
VCL-lomake sisältää kolme TScrollBox-säilöä vierekkäin, kussakin sisällä TPdfView kohdistettuna arvoon alClient, jotta se täyttää laatikon. Kaksi TSplitter-komponenttia sijaitsee laatikoiden välissä, jotta käyttäjä voi säätää sarakeleveyksiä suoritusaikana. Paneelien yläpuolella oleva työkalurivi sisältää avauspainikkeet, zoomaussäätimet sekä kaksi-/kolminäkymä-kytkimen
Kolminäkymätila on totuusarvo, jota lomake seuraa sisäisesti. Kun se kytketään, lasket leveydet uudelleen ja näytät tai piilotat kolmannen sarakkeen. Yksinkertaisin tapa on tyhjentää kaikki Align-ominaisuudet, piilottaa jakajat ja asettaa sitten absoluuttiset sijainnit:
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;
// Sovella samaa (ClientHeight - työkalurivin korkeus) kaikkiin kolmeen Height-arvoon
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;
Määrityksen Align := alNone tekeminen kaikkiin kolmeen laatikkoon ennen kokonaislukuaritmetiikkaa estää VCL:n rajoitemoottoria taistelemasta määrityksiäsi vastaan. Palauta jakajien näkyvyys sijoittelun jälkeen, jos haluat vetämällä tapahtuvaa koon muuttamista kaksinäkymätilassa
Kunkin vierityslaatikon korkeus on asiakasalue miinus työkalurivipaneelin korkeus. Koska työkalurivi on telakoitu ylös arvolla alTop, ClientHeight - PanelButtons.Height antaa sinulle käyttökelpoisen pystysuoran tilan. Määritä tämä kaikille kolmelle laatikolle saman UpdateLayout-kutsun sisällä, jotta ei koskaan ole ruutua, jossa yksi laatikko on pidempi kuin muut ja aiheuttaa asettelun välkynnän
Asiakirjan avaaminen
Jokainen paneelipari tarvitsee oman avausmenettelynsä. Kuvio on lyhyt: deaktivoi komponentti, aseta tiedostonimi, aktivoi, ja tarkista sitten Active; jos se pysyi tilassa False, kysy salasanaa ja yritä uudelleen. Huomaa, että TPdfView.Active ohjaa hahmontamista, mutta TPdf.Active on se, mikä oikeasti avaa tiedoston; ne ovat itsenäisiä. Määrityksen PdfView.Active := True tekeminen silloin, kun siihen linkitetty TPdf ei ole vielä aktiivinen, on vaaratonta, mutta ei näytä mitään
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 := '';
PdfComponent.Active := True;
// Latauksen epäonnistumiset ovat hiljaisia: Active pysyy False-tilassa poikkeuksen sijaan.
if not PdfComponent.Active then
begin
// Todennäköisesti salasanasuojattu tiedosto; anna käyttäjälle yksi uusi yritys.
if InputQuery('Password', 'Enter document password:', Password) then
begin
PdfComponent.Password := Password;
PdfComponent.Active := True;
end;
end;
if not PdfComponent.Active then
begin
ShowMessage('Could not open ' + OpenDialog.FileName +
' (damaged file or wrong password)');
Exit;
end;
PdfViewComponent.PageNumber := 1;
SetActivePdfView(PdfViewComponent);
end;
Tarkista aina PdfComponent.Active määrityksen jälkeen; vioittunut tiedosto tai väärä salasana saa latauksen epäonnistumaan hiljaisesti nostamatta poikkeusta oletuspolulla. Määrityksen PdfViewComponent.PageNumber := 1 tekeminen eksplisiittisesti onnistuneen avaamisen jälkeen välttää vanhentuneen sivunumeron jäämisen edellisestä asiakirjasta
Lopussa oleva viesti-valintaikkuna on tarkoituksellinen: haluat, että vioittuneet tai tukemattomat tiedostot tulevat pintaan välittömästi sen sijaan, että ne nieltäisiin hiljaisena tyhjänä paneelina. Käyttäjällä, joka ei näe mitään, ei ole aavistustakaan siitä, latautuiko tiedosto ja onko se yksinkertaisesti tyhjä, vai hylkäsikö komponentti sen. Epäonnistumisesta raportoiminen pitää virheen näkyvänä
Aktiivisen paneelin seuranta
Kun käyttäjä napsauttaa paneelin sisällä, tuosta paneelista tulee aktiivinen. Lomake seuraa yksityistä FActivePdfView: TPdfView -kenttää. Visuaalinen palaute on reunaviivan värin muutos sisältävässä TScrollBox-laatikossa: aseta se arvoon clHighlight aktiiviselle ja clWindow muille. Kytke tämä jokaiseen TPdfView.OnClick-tapahtumaan ja avausmenettelyyn, jotta kohdistus seuraa juuri avaamaasi asiakirjaa
Jotkin toiminnot koskevat kaikkia näkyviä paneeleja pelkän aktiivisen sijaan. Totuusarvo FAllViewsMode lomakkeessa ohjaa tuota haaraa. Kun se on tosi, zoomausmuutokset ja sivunavigointi leviävät jokaiseen paneeliin, jossa on aktiivinen asiakirja:
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;
Synkronoitu sivunavigointi
Synkronoitu navigointi on valinnainen, mutta hyödyllinen asiakirjojen versiotyönkuluille, joissa molemmat tiedostot kattavat saman sivualueen. Logiikka kuuluu tapahtumankäsittelijään, joka laukeaa sen jälkeen, kun käyttäjä navigoi yhtä näkymää. Kun lähdenäkymä muuttaa PageNumber-arvoaan, käsittelijä välittää tuon numeron muihin näkymiin, yhden suojan varassa: kohdenäkymässä on oltava vähintään yhtä monta sivua, muuten se ohitetaan
PageNumber-ominaisuudet luokissa TPdfView ja TPdf ovat itsenäisiä. TPdf.PageNumber seuraa, mitä sivua asiakirjakomponentti pitää nykyisenä; TPdfView.PageNumber seuraa, mitä näytöllä näytetään. Navigointitarkoituksiin haluat näkymän ominaisuuden, et asiakirjan ominaisuutta
Valintaruutu, jonka nimi on esimerkiksi "Synkronoi sivut", antaa käyttäjälle hallinnan. Kun sen valinta poistetaan, kukin paneeli navigoi itsenäisesti ja käsittelijä poistuu välittömästi. Tuo itsenäisyys on tärkeää käyttötapauksille, joissa kahdessa asiakirjassa on eri sivumäärät, tai joissa käyttäjä haluaa löytää vastaavan kohdan käännöksestä, joka alkaa eri sivulta. Synkronoinnin pakottaminen aina tekisi työkalusta vaikeamman käyttää kuin yksinkertainen kaksi-ikkunainen työpöytäjärjestely
Yksi asia, jota kannattaa varoa: PdfView.PageNumber-ominaisuuden asettaminen ohjelmallisesti synkronointikäsittelijän sisällä laukaisee itsessään muutostapahtuman kyseisessä näkymässä. Suojaudu ääretöntä rekursiota vastaan totuusarvoisella lipulla, jonka asetat ennen määritystä ja tyhjennät heti sen jälkeen. Lippu on lomakekohtainen, ei näkymäkohtainen, koska kaikki kolme näkymää jakavat saman käsittelijän
Zoomaus paneelia kohti
Jokainen TPdfView kantaa oman Zoom-ominaisuutensa, Double-arvon prosentteina, jossa Zoom := 100 tarkoittaa todellista kokoa (100 %). Sen asettaminen kumoaa minkä tahansa aktiivisen FitMode-tilan. Fit-to-width-painikkeelle aktiivisessa paneelissa lue fit-zoomaus ominaisuudesta PdfView.PageWidthZoom[PdfView.PageNumber] ja määritä se. Fit-to-page-toiminnolle käytä PageZoom[PageNumber]-ominaisuutta. Molemmat ovat taulukko-ominaisuuksia, jotka on indeksoitu 1-pohjaisella sivunumerolla, joten suojaudu nollasivunumeroa vastaan ennen niiden käyttämistä
Kun viet nykyisen sivun kuvaksi, lue kierto näkymästä, mutta kutsu RenderPage-metodia TPdf-komponentilla, ei näkymällä. TPdf.RenderPage-metodin bittikarttamuoto ottaa eksplisiittiset pikselimitat sekä TRotation-arvon ja TRenderOptions-joukon. Funktion variantti palauttaa kutsujan omistaman TBitmap-objektin, jonka vapautat itse tallentamisen jälkeen:
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;
2x-kerroin leveydessä ja korkeudessa antaa terävämmän tulosteen asiakirjoille, joissa on hienoa tekstiä. try/finally-lohko bittikartan vapauttamisen ympärillä ei ole valinnainen; TSaveDialog-peruutus osuu silti finally-lohkoon, ja haluat, että bittikartta vapautetaan riippumatta siitä, mitä käyttäjä teki
DLL-vaatimukset
PDFium Component kietoo natiivin pdfium-kirjaston. 32-bittinen isäntäprosessi tarvitsee pdfium32.dll-kirjaston; 64-bittinen isäntä tarvitsee pdfium64.dll-kirjaston. Variantit, joissa on V8 JavaScript -moottori, lisäävät v8-liitteen ja painavat karkeasti 23-27 Mt verrattuna 5-6 Mt:n standardiversioihin. Vertailukatseluohjelmalle, joka poistaa lomakkeiden täytön käytöstä (Pdf.FormFill := False), standardi ei-V8-koontiversio riittää ja pitää jakelun pienempänä
Sijoita DLL samaan hakemistoon kuin suoritettava tiedosto, tai mihin tahansa hakemistoon järjestelmän PATH-muuttujassa. Komponentti lataa sen tarpeen mukaan, kun ensimmäinen TPdf aktivoidaan, joten puuttuva DLL nousee pintaan vasta siinä vaiheessa sovelluksen käynnistyksen sijaan. Jos toimitat asennusohjelman, luotettavin tapa on kopioida DLL sovelluskansioon asennuksen aikana sen sijaan, että luottaisit järjestelmähakemistoon, jonka järjestelmänvalvoja saattaa myöhemmin siivota
V8-koontiversiot ovat ensisijaisesti hyödyllisiä, kun sinun on oltava vuorovaikutuksessa PDF:n JavaScript-toimintojen kanssa, esimerkiksi laskentakenttien liipaisemiseksi tai lähetyskäsittelijöiden käynnistämiseksi. Passiivisella vertailukatseluohjelmalla ei ole mitään syytä suorittaa JavaScriptiä; määrityksen Pdf.FormFill := False tekeminen ennen Active := True -kutsua ohittaa lomakkeen täyttöympäristön kokonaan, mikä tarkoittaa myös, ettei JS-moottoria alusteta, vaikka käytettäisiin standardiversiota. Se on oikea oletus vain luku -katseluohjelmalle riippumatta siitä, minkä DLL-variantin toimitat
Lisätietoja PDFium Component -komponentista ja sen täydestä API:sta löydät Delphi PDFium Component -tuotesivulta