Teknik makale

PDFium: form-field navigation and viewer validation

Delphi ve C++Builder uygulamalarına PDFium VCL Component iş akışlarını, Lazarus/FPC projelerine PDFium LCL Component iş akışlarını; görüntüleme, render, formlar, yazdırma, preflight raporları ve standart odaklı doğrulama için kaynak kodlu bileşenlerle ekleyin.

Bu yazı developers building PDF data-entry viewers where users need to complete forms accurately için hazırlanmıştır. form-field navigation and viewer validation konusunu tek bir bileşen çağrısı olarak değil, üretim düzeyinde belge mühendisliği olarak ele alır.

Pratik risk şudur: users can tab through a form and still submit incorrect or invisible data if field focus, required-state display, export values, and calculated fields are not coordinated. Bu nedenle akışın yazılı sözleşmeye, gözlemlenebilir tanılara ve gerçekçi regresyon dosyalarına ihtiyacı vardır.

Mimari kararlar

Make field navigation a first-class viewer feature. tab order, required-field markers, and skip rules for hidden or read-only fields / value conversion for checkboxes, radio groups, combo boxes, and date fields

  • tab order, required-field markers, and skip rules for hidden or read-only fields
  • value conversion for checkboxes, radio groups, combo boxes, and date fields
  • calculation timing and whether scripts are supported, ignored, or blocked
  • how invalid fields are highlighted, listed, and returned to the user

Uygulama akışı

Build a form index before user interaction. Aşağıdaki sıra, iş akışını Delphi ve C++Builder ekipleri için incelenebilir tutar.

  1. scan fields and widgets into a navigation index when the document opens
  2. connect keyboard traversal, mouse selection, and side-panel selection to the same index
  3. validate current values before page changes, save, export, or submission
  4. show field-specific messages that reference the document location and rule
  5. record validation outcomes for support when users report submission failures

Doğrulama kanıtı

Validation signals users and support can understand. Bu alanları çıktı veya destek kaydıyla birlikte saklayın.

  • field name, type, page, widget bounds, required flag, and current export value
  • navigation order and skipped field reasons
  • validation rule, failing value, message shown to the user, and time of check
  • calculated-field dependencies and whether scripts were allowed

A field is not only a rectangle

A viewer-side form workflow needs field identity, widget geometry, page location, validation messages, current value, export value, and focus behavior. That model should drive both UI navigation and diagnostics.

Review questions before release

Before this reaches production, the team should be able to answer these questions without reading source code.

  • Who owns tab order, required-field markers, and skip rules for hidden or read-only fields?
  • What evidence proves field name, type, page, widget bounds, required flag, and current export value?
  • What happens when radio button groups often share one field name across several widgets?
  • Which regression file covers record validation outcomes for support when users report submission failures?

Mühendislik inceleme notları: form-field navigation and viewer validation

Özelliğin bir demoyu aşıp sürüm, destek ve müşteri eskalasyonu sırasında savunulabilir olduğunu doğrulamak için bu inceleme notlarını kullanın.

  • Karar: tab order, required-field markers, and skip rules for hidden or read-only fields. Uygulama baskı noktası: connect keyboard traversal, mouse selection, and side-panel selection to the same index. Kabul kanıtı: validation rule, failing value, message shown to the user, and time of check. Regresyon tetikleyicisi: calculated values can become stale when editing jumps across pages
  • Karar: value conversion for checkboxes, radio groups, combo boxes, and date fields. Uygulama baskı noktası: validate current values before page changes, save, export, or submission. Kabul kanıtı: calculated-field dependencies and whether scripts were allowed. Regresyon tetikleyicisi: radio button groups often share one field name across several widgets

Sınır durumları

  • radio button groups often share one field name across several widgets
  • required fields hidden by logic still need a policy decision
  • date and number formatting should match the document, not only the OS locale
  • calculated values can become stale when editing jumps across pages

Delphi / C++Builder notes

PDFium Component should sit behind a small service boundary that receives files, streams, profiles, and credentials, then returns output paths, warnings, metrics, and validation status. Important terms include form field, tab order, widget, export value, validation, calculated field.

Delphi kod örneği

Aşağıdaki Delphi taslağı bu konu için pratik bir servis sınırını gösterir. Politika kontrollerini, günlüklemeyi ve doğrulamayı dar ürün çağrısı bölümünün dışında tutarak akışı test edilebilir bırakın.

procedure TFormHost.BuildFieldNavigation(const FileName: string);
begin
  PdfView.LoadFromFile(FileName);
  FFields := ExtractInteractiveFields(PdfView);
  FFields.SortByPageAndBounds;
  ValidateRequiredFieldNames(FFields);
  FocusFirstEditableField;
end;

Üretim kontrol listesi

  • İş akışını boş bir dosyada, normal bir müşteri dosyasında ve en kötü durum dosyasında çalıştırın
  • Oluşturulan PDF'yi hedef görüntüleyici, doğrulayıcı, yazıcı veya aşağı akış uygulamasıyla açın
  • Ürün sürümünü, profil sürümünü, giriş karmasını, çıktı yolunu, geçen süreyi ve uyarı sayısını kaydedin
  • Parolaları, sertifikaları, geçici dosyaları ve müşteri verilerini açık saklama kuralları altında tutun
  • Bir müşteri dosyası yeni bir uç durum ortaya çıkardığında regresyon belgeleri ekleyin

Ürün belgeleri

PDFium Component

Ek kod örnekleri

procedure TFormViewer.HandleTabKey(Shift: TShiftState);
begin
  if ssShift in Shift then
    PdfView.FocusPreviousFormField
  else
    PdfView.FocusNextFormField;
  UpdateFieldStatus;  // e.g. "Field 4 of 17: InvoiceDate"
end;
procedure TFormViewer.FillAndSave(const Values: array of WString;
  const OutputPath: string);
var
  i: Integer;
begin
  for i := 0 to Pdf.FormFieldCount - 1 do
    Pdf.FormField[i] := Values[i];   // writes /V only

  // Rebuild the /AP appearance streams; without this the form
  // looks blank in Acrobat until each field is clicked
  Pdf.GenerateFormAppearances;

  Pdf.SaveAs(OutputPath);
end;