Vienu metu atidaryti du dokumentai, tas pats puslapio numeris, kiekvienas savo slenkamame skydelyje: tai yra palyginimo peržiūros programos pagrindas. „PDFium Component“ tai užtikrina naudodamas paprastą objektų modelį, kuriame TPdf priklauso failas, o TPdfView – ekranas. Vienas dokumentas, vienas TPdf, vienas TPdfView. Norite trijų skydelių – turite tris poras. Sunkiausia dalis nėra API iškvietimai; tai yra maketo aritmetika, kai keičiasi lango dydis, ir puslapių sinchronizavimo logika, kai nusprendžiate, kuris rodinys kurį turėtų sekti
Formos maketas
VCL formoje greta vienas kito yra trys TScrollBox konteineriai, kurių kiekviename yra TPdfView ir kurie sulygiuoti pagal alClient, kad užpildytų laukelį. Tarp laukelių yra du TSplitter komponentai, kad naudotojas galėtų reguliuoti stulpelių plotį vykdymo metu. Virš skydelių esančioje įrankių juostoje yra atidarymo mygtukai, mastelio keitimo valdikliai ir dviejų / trijų rodinių perjungiklis
Trijų rodinių režimas yra loginė reikšmė (boolean), kurią forma seka viduje. Kai ji perjungiama, perskaičiuojate pločius ir parodote arba paslepiate trečiąjį stulpelį. Paprasčiausias būdas yra išvalyti visas Align savybes, paslėpti skirstytuvus ir nustatyti absoliučias pozicijas:
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;
// Pritaikykite tą pačią (ClientHeight - įrankių juostos aukštis) reikšmę visoms trims Height reikšmėms
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;
Nustatę Align := alNone visiems trims laukeliams prieš atliekant sveikųjų skaičių aritmetiką, išvengsite VCL apribojimų variklio prieštaravimų jūsų priskyrimams. Po pozicionavimo atkurkite skirstytuvų matomumą, jei norite, kad dviejų rodinių režimu būtų galima keisti dydį vilkimo būdu
Kiekvieno slinkties laukelio aukštis yra kliento sritis minus įrankių juostos skydelio aukštis. Kadangi įrankių juosta yra priglausta viršuje naudojant alTop, ClientHeight - PanelButtons.Height suteikia jums naudingą vertikalią erdvę. Priskirkite tai visiems trims laukeliams tame pačiame UpdateLayout iškvietime, kad niekada nebūtų kadro, kai vienas laukelis yra aukštesnis už kitus ir sukelia maketo mirgėjimą
Dokumento atidarymas
Kiekvienai skydelių porai reikia atskiros atidarymo procedūros. Šablonas yra trumpas: išjunkite komponentą, nustatykite failo pavadinimą, įjunkite, tada patikrinkite Active; jei jis liko False, paprašykite slaptažodžio ir bandykite dar kartą. Atkreipkite dėmesį, kad TPdfView.Active valdo atvaizdavimą, tačiau TPdf.Active iš tikrųjų atidaro failą; jie yra nepriklausomi. Nustačius PdfView.Active := True, kai su juo susietas TPdf dar nėra aktyvus, yra nekenksminga, bet nieko nerodo
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;
// Įkėlimo klaidos yra tylios: Active lieka False, o ne iškeliama išimtis.
if not PdfComponent.Active then
begin
// Greičiausiai slaptažodžiu apsaugotas failas; suteikite naudotojui vieną bandymą pakartoti.
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;
Visada patikrinkite PdfComponent.Active po priskyrimo; dėl sugadinto failo ar neteisingo slaptažodžio įkėlimas nepavyksta tyliai, nesukeliant išimties numatytajame kelyje. Aiškus PdfViewComponent.PageNumber := 1 nustatymas po sėkmingo atidarymo leidžia išvengti pasenusio puslapio numerio iš ankstesnio dokumento
Pranešimų dialogo langas pabaigoje yra tyčinis: norite, kad sugadinti ar nepalaikomi failai iškiltų iš karto, o ne būtų praryti kaip tylus tuščias skydelis. Naudotojas, kuris nieko nemato, neįsivaizduoja, ar failas buvo įkeltas ir yra tiesiog tuščias, ar komponentas jį atmetė. Pranešus apie gedimą, klaida lieka matoma
Aktyvaus skydelio sekimas
Kai naudotojas spusteli skydelio viduje, tas skydelis tampa aktyvus. Forma stebi privačių FActivePdfView: TPdfView lauką. Vizualinis grįžtamasis ryšys yra rėmelio spalvos pasikeitimas turinčiame TScrollBox: nustatykite jį į clHighlight aktyviajam ir clWindow kitiems. Susiekite tai su kiekvienu TPdfView.OnClick ir su atidarymo procedūra, kad fokusavimas sektų dokumentą, kurį ką tik atidarėte
Kai kurios operacijos taikomos visiems matomiems skydeliams, o ne tik aktyviajam. Loginė reikšmė FAllViewsMode formoje valdo šią šaką. Kai ji yra teisinga (true), mastelio keitimai ir puslapių naršymas išsiskirsto į kiekvieną skydelį, turintį aktyvų dokumentą:
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;
Sinchronizuotas puslapių naršymas
Sinchronizuotas naršymas yra neprivalomas, bet naudingas dokumentų peržiūros darbo eigose, kai abu failai apima tą patį puslapių diapazoną. Logika priklauso įvykių apdorojimo programai, kuri suveikia naudotojui naršant viename rodinyje. Kai šaltinio rodinys pakeičia savo PageNumber, apdorojimo programa perduoda tą numerį kitiems rodiniams su viena apsauga: tikslinis rodinys turi turėti bent tiek puslapių, kitaip jis praleidžiamas
PageNumber TPdfView ir TPdf komponentuose yra nepriklausomi. TPdf.PageNumber seka, kurį puslapį dokumento komponentas laiko dabartiniu; TPdfView.PageNumber seka, kas rodoma ekrane. Naršymo tikslais jums reikia rodinio savybės, o ne dokumento savybės
Žymimasis langelis, pažymėtas kažkuo panašiu į „Sinchronizuoti puslapius“, suteikia naudotojui valdymą. Kai jis atžymėtas, kiekvienas skydelis naršomas atskirai ir apdorojimo programa nedelsiant išeina. Šis nepriklausomumas yra svarbus naudojimo atvejais, kai du dokumentai turi skirtingą puslapių skaičių, arba kai naudotojas nori rasti atitinkamą ištrauką vertime, kuris prasideda kitame puslapyje. Nuolatinis sinchronizavimo priverstinis taikymas padarytų įrankį sunkiau naudojamą nei paprastas dviejų langų darbalaukio išdėstymas
Vienas dalykas, į kurį reikia atkreipti dėmesį: programinis PdfView.PageNumber nustatymas sinchronizavimo apdorojimo programos viduje savaime sukels to rodinio pakeitimo įvykį. Apsisaugokite nuo begalinės rekursijos naudodami loginę vėliavėlę, kurią nustatote prieš priskyrimą ir išvalote iškart po jo. Vėliavėlė yra skirta formai, o ne rodiniui, nes visi trys rodiniai dalijasi ta pačia apdorojimo programa
Kiekvieno skydelio mastelio keitimas
Kiekvienas TPdfView turi savo Zoom savybę – Double procentais, kur Zoom := 100 reiškia tikrąjį dydį (100 %). Ją nustačius, nepaisoma jokio aktyvaus FitMode. Mygtukui „pritaikyti prie pločio“ aktyviame skydelyje nuskaitykite pritaikymo mastelį iš PdfView.PageWidthZoom[PdfView.PageNumber] ir jį priskirkite. Norėdami pritaikyti prie puslapio, naudokite PageZoom[PageNumber]. Abi yra masyvo savybės, indeksuojamos pagal nuo 1 prasidedantį puslapio numerį, todėl prieš pasiekdami jas, apsisaugokite nuo nulinio puslapio numerio
Kai eksportuojate dabartinį puslapį į vaizdą, nuskaitykite pasukimą iš rodinio, bet iškvieskite RenderPage TPdf komponente, o ne rodinyje. Taškinės grafikos (bitmap) TPdf.RenderPage forma priima aiškius pikselių matmenis, plius TRotation reikšmę ir TRenderOptions rinkinį. Funkcijos variantas grąžina iškvietėjui priklausantį TBitmap, kurį atlaisvinate patys po išsaugojimo:
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;
2 kartų daugiklis pločiui ir aukščiui suteikia ryškesnį išvesties rezultatą dokumentams su smulkiu tekstu. try/finally blokas aplink taškinės grafikos atlaisvinimą nėra neprivalomas; TSaveDialog atšaukimas vis tiek pasiekia finally bloką, o jūs norite, kad taškinė grafika būtų atlaisvinta neatsižvelgiant į tai, ką padarė naudotojas
DLL reikalavimai
„PDFium Component“ apgaubia natūralią (native) „pdfium“ biblioteką. 32 bitų prieglobos (host) procesui reikia pdfium32.dll; 64 bitų prieglobai reikia pdfium64.dll. Variantai su V8 „JavaScript“ varikliu prideda v8 priesagą ir sveria maždaug 23-27 MB, palyginti su 5-6 MB standartinėmis versijomis. Palyginimo peržiūros programai, kuri išjungia formų pildymą (Pdf.FormFill := False), pakanka standartinės ne V8 versijos ir tai išlaiko mažesnį platinimo paketą
Įdėkite DLL į tą patį katalogą kaip ir vykdomasis failas arba į bet kurį katalogą, esantį sistemos PATH. Komponentas įkelia jį pagal pareikalavimą, kai aktyvuojamas pirmasis TPdf, todėl trūkstamas DLL iškyla tuo momentu, o ne paleidžiant programą. Jei tiekiate diegimo programą, patikimiausias būdas yra diegimo metu nukopijuoti DLL į programos aplanką, o ne pasikliauti sistemos katalogu, kurį administratorius vėliau gali išvalyti
V8 versijos pirmiausia naudingos, kai reikia sąveikauti su PDF „JavaScript“ veiksmais, pavyzdžiui, paleisti skaičiavimo laukus arba pateikti tvarkykles. Pasyviai palyginimo peržiūros programai nėra jokios priežasties vykdyti „JavaScript“; nustačius Pdf.FormFill := False prieš Active := True, visiškai praleidžiama formų pildymo aplinka, o tai taip pat reiškia, kad joks JS variklis nėra inicijuojamas net ir naudojant standartinę versiją. Tai yra teisinga numatytoji reikšmė tik skaitymo peržiūros programai, neatsižvelgiant į tai, kurį DLL variantą tiekiate
Norėdami gauti daugiau informacijos apie „PDFium Component“ ir visą jo API, apsilankykite Delphi PDFium Component produkto puslapyje