Penampil PDF di Delphi bermuara pada dua komponen dan pengkabelan di antaranya. TPdf memiliki dokumen: ia membuka file, mendekripsinya, dan menjawab pertanyaan tentang jumlah halaman dan metadata. TPdfView adalah kontrol visual yang mengecat halaman di layar dan menangani pengguliran, zoom, dan halaman yang sedang dilihat pengguna. PDFium Component membungkus mesin render yang sama yang dikirim di dalam Chrome, sehingga glyph, anti-aliasing, dan warna yang Anda dapatkan di kanvas cocok dengan yang sudah dilihat pengguna Anda di browser mereka. Pekerkerjaannya bukan pada rendering. Itu ada pada menghubungkan objek dokumen ke view, memuat tanpa crash pada file yang rusak atau dilindungi kata sandi, dan memberi pengguna segelintir kontrol yang membuat penampil terasa selesai: mengganti halaman, mengubah zoom, dan menyesuaikan halaman ke jendela
Ini menelusuri perakitan itu dalam urutan yang benar-benar Anda bangun. Semua di sini merender satu halaman pada satu waktu, yang diinginkan sebagian besar alur kerja dokumen. Jika Anda butuh halaman ditumpuk dalam satu kolom yang digulir terus-menerus, itu adalah keputusan tata letak yang berbeda dan bukan jalur di sini
Mengkabel TPdf ke TPdfView
Jatuhkan TPdf dan TPdfView di form, lalu beri tahu view dokumen mana yang akan ditampilkan. Penugasan tunggal itu adalah seluruh tautan antara dokumen non-visual dan kontrol yang mengecatnya
procedure TFormMain.FormCreate(Sender: TObject);
begin
// Pdf dan PdfView dijatuhkan saat desain.
PdfView.Pdf := Pdf; // view mengecat apa pun yang disimpan dokumen ini
PdfView.FitMode := pfmFitWidth; // mulai pengguna pada zoom yang masuk akal
end;
Sebelum salah satu dari ini berjalan, pustaka native PDFium harus ada di mesin. PDFium Component memanggil ke pdfium32.dll atau pdfium64.dll tergantung platform target Anda, dan dokumen tersebut menolak dibuka jika DLL tidak ditemukan. Kirim DLL yang cocok di samping executable Anda, atau letakkan di tempat pemuat sistem akan menemukannya. Build V8-enabled hanya ada untuk PDF yang membawa JavaScript yang ingin Anda jalankan, yang tidak dilakukan penampil polos, jadi jangkau DLL standar kecuali Anda punya alasan konkret untuk tidak melakukannya
Memuat dokumen tanpa mempercayai input
Instingnya adalah membungkus pemuatan dalam try/except dan memperlakukan pengecualian yang dilemparkan sebagai kegagalan. Insting itu salah di sini, dan salah menghasilkan penampil yang terlihat baik-baik saja sampai seseorang memberinya file rusak. Menyetel Active := True tidak melempar pada kegagalan muat. PDFium Component menangkap kesalahan internal dan membiarkan Active duduk di False, jadi satu-satunya cara jujur untuk mengetahui apakah dokumen terbuka adalah membaca properti kembali setelah Anda menyetelnya
procedure TFormMain.OpenDocument(const FileName: string);
begin
Pdf.FileName := FileName;
Pdf.Active := True; // tidak pernah melempar; kegagalan membiarkan Active = False
if not Pdf.Active then
begin
ShowMessage('Could not open ' + FileName);
Exit;
end;
PdfView.PageNumber := 1; // view melacak halaman saat ini miliknya sendiri
UpdatePageLabel;
end;
Dua hal patut diperhatikan. Yang pertama adalah PageNumber ada di kedua objek dan keduanya independen. Pdf.PageNumber adalah gagasan dokumen tentang halaman saat ini; PdfView.PageNumber adalah halaman yang sebenarnya ditampilkan kontrol, dan itulah yang Anda setel untuk menggerakkan pengguna melalui file. Menyetel satu tidak menggerakkan yang lain, jadi penampil selalu menggerakkan properti view. Yang kedua adalah pengindeksan berbasis-1: halaman berjalan dari 1 ke Pdf.PageCount, bukan dari 0, yang menjebak siapa pun yang terbiasa dengan array berbasis-nol
Menangani file terenkripsi
Dokumen terenkripsi terlipat ke dalam jalur muat yang sama. Jika kata sandi terbuka disetel sebelum aktivasi, dokumen didekripsi saat dibuka; jika salah atau hilang, Active tetap False persis seperti untuk file rusak. Jadi pemulihannya adalah meminta kata sandi dan mencoba aktivasi lagi
procedure TFormMain.OpenWithPassword(const FileName: string);
var
Password: string;
begin
Pdf.FileName := FileName;
Pdf.Active := True;
if not Pdf.Active then
begin
if InputQuery('Password required', 'Password:', Password) then
begin
Pdf.Password := Password; // harus disetel sebelum Active := True
Pdf.Active := True;
end;
if not Pdf.Active then
begin
ShowMessage('Unable to open the document.');
Exit;
end;
end;
PdfView.PageNumber := 1;
end;
Karena kegagalan diam untuk kata sandi buruk dan file rusak, Anda tidak bisa membedakan keduanya dari Active saja. Dalam praktik itu dapat diterima untuk penampil: pengguna baik menyediakan kata sandi yang benar atau belajar file tidak akan terbuka, dan pesan terbaca sama baiknya
Berhalaman melalui dokumen
Dengan dokumen terbuka, navigasi adalah aritmetika pada PdfView.PageNumber yang dibatasi oleh Pdf.PageCount. Satu-satunya pekerjaan nyata adalah penjepitan, sehingga tombol tidak pernah mendorong halaman keluar dari rentang dan tombol pertama dan terakhir tetap dinonaktifkan di ujung file
procedure TFormMain.GoToPage(NewPage: Integer);
begin
if not Pdf.Active then
Exit;
if NewPage < 1 then
NewPage := 1
else if NewPage > Pdf.PageCount then
NewPage := Pdf.PageCount;
PdfView.PageNumber := NewPage;
UpdatePageLabel;
end;
// keempat tombol navigasi menyederhanakan menjadi satu panggilan masing-masing
procedure TFormMain.FirstClick(Sender: TObject); begin GoToPage(1); end;
procedure TFormMain.PrevClick(Sender: TObject); begin GoToPage(PdfView.PageNumber - 1); end;
procedure TFormMain.NextClick(Sender: TObject); begin GoToPage(PdfView.PageNumber + 1); end;
procedure TFormMain.LastClick(Sender: TObject); begin GoToPage(Pdf.PageCount); end;
Kotak teks "go to page N" adalah panggilan GoToPage yang sama yang diberi makan dari integer yang diurai, dan penjepit mencakup kasus di mana pengguna mengetik 9999 ke dalam file sepuluh-halaman. Jaga UpdatePageLabel sebagai tempat tunggal yang menulis "Page 3 of 12" agar pembacaan tidak pernah menyimpang dari apa yang ditampilkan view
Zoom: persentase eksplisit dan mode fit
Zoom pada TPdfView tiba dalam dua rasa yang berinteraksi, dan memahami interaksi adalah perbedaan antara kontrol zoom yang berperilaku baik dan yang melawan pengguna. Rute langsung adalah properti Zoom, persentase di mana 100 berarti ukuran aktual. Rute lain adalah FitMode, yang memberi tahu view untuk menghitung zoom untuk Anda dan terus menghitungnya saat jendela diubah ukurannya
// pembesaran tetap
PdfView.Zoom := 100; // ukuran aktual
PdfView.Zoom := 50; // setengah
PdfView.Zoom := 200; // dua kali
// biarkan view menyesuaikan halaman ke jendela, dan jaga ukurannya saat resize
PdfView.FitMode := pfmFitWidth; // lebar halaman memenuhi kontrol
PdfView.FitMode := pfmFitPage; // seluruh halaman terlihat
PdfView.FitMode := pfmActualSize; // 1:1 dengan titik-titik dokumen
Inilah bagian yang menjebak orang. Menetapkan Zoom secara langsung mereset FitMode ke pfmNone. Itu adalah perilaku yang benar, bukan bug: saat pengguna memilih 150% yang persis, view tidak bisa lagi juga menghormati "fit to width," karena dua permintaan bertentangan. Konsekuensinya untuk UI Anda adalah tombol zoom-in dan tombol fit-to-page adalah status yang saling eksklusif, dan toolbar harus membuat mode aktif terlihat. Saat pengguna mengklik fit-to-page, setel FitMode; saat mereka mengklik zoom numerik, setel Zoom dan biarkan membersihkan mode fit sendiri
Jika Anda lebih suka menghitung nilai fit sendiri, mungkin untuk menyemai slider zoom dengan persentase fit saat ini, pembantu per-halaman memberi Anda angka tanpa mengubah mode. PageWidthZoom[N], PageZoom[N], dan ActualSizeZoom[N] mengembalikan persentase yang akan menyesuaikan halaman N ke lebar, menyesuaikannya utuh, atau merendernya pada ukuran aktual
// bibit penunjuk zoom dari nilai fit-to-width halaman saat ini
var
FitPercent: Double;
begin
FitPercent := PdfView.PageWidthZoom[PdfView.PageNumber];
ZoomEdit.Text := Format('%.0f%%', [FitPercent]);
end;
Apa yang benar-benar dibutuhkan penampil yang selesai
Penampil di atas adalah beberapa lusin baris, dan sudah melakukan pekerjaan yang dibutuhkan alur kerja dokumen: membuka file, bertahan dari yang buruk, menampilkan halaman, berpindah antar halaman, dan mengubah pembesaran dengan tangan atau dengan fit. PDFium melakukan bagian yang sulit secara diam-diam. Font yang tersemat terselesaikan, anotasi dan kolom formulir mengecat di tempat dokumen menempatkannya, dan halaman yang Anda lihat cocok dengan yang akan dilihat pengguna Chrome, karena ini mesin yang sama menggambar keduanya
Dari basis ini tambahan adalah inkremental bukan struktural. Pemilihan dan pencarian teks dibaca dari lapisan teks yang sama yang sudah dibangun PDFium; metadata seperti Pdf.Title dan Pdf.Author adalah satu baca properti jauhnya; rotasi dan skala abu-abu adalah opsi render yang Anda lewatkan saat menggambar halaman ke bitmap. Tidak satu pun dari itu mengubah tulang punggung yang Anda miliki di sini, yaitu objek dokumen, view, dan alur muat-lalu-navigasi yang menghubungkannya. Dapatkan tulang punggung itu dengan benar dan sisanya adalah dekorasi
Komponen TPdf dan TPdfView yang digunakan di sepanjang adalah bagian dari PDFium Component untuk Delphi dan C++Builder, yang membawa referensi penampil lengkap pada halaman produknya