مقالة تقنية

إنشاء عارض PDF متعدد الصفحات مع التمرير المستمر في دلفي

· برمجة PDF

هذا البرنامج التعليمي يستكشف عرض متعدد الصفحات ، وهو نموذج يوسع عارض PDF الأساسي بقدرات التمرير المستمر. هذا الوضع مشابه لكيفية عرض برامج قراءة PDF الحديثة مثل Adobe Acrobat للمستندات، مما يسمح للمستخدمين بالتمرير بسلاسة عبر جميع الصفحات.

نظرة عامة

يوضح نموذج عرض متعدد الصفحات أوضاع العرض المتقدمة في PDFium VCL، بما في ذلك التمرير المستمر لصفحة واحدة والتمرير المستمر لصفحتين (وضع الكتاب). هذه الميزات ضرورية لإنشاء تجربة قراءة PDF احترافية.

أوضاع العرض

يدعم PDFium VCL أوضاع عرض متعددة من خلال الخاصية: DisplayMode التمرير المستمر

1
2
3
4
5
6
7
8
9
10
11
12
13
14
type
  TPdfDisplayMode = (
    dmSingleContinuous,  // Single page with continuous vertical scrolling
    dmDoubleContinuous   // Two pages side-by-side (book layout)
  );
 
// Switch between display modes
procedure TFormMain.ComboBoxDisplayModeChange(Sender: TObject);
begin
  case ComboBoxDisplayMode.ItemIndex of
    0: PdfView.DisplayMode := dmSingleContinuous;
    1: PdfView.DisplayMode := dmDoubleContinuous;
  end;
end;

الميزات الرئيسية

  • التمرير المستمر. التمرير عبر جميع الصفحات دون الحاجة إلى التنقل صفحة بصفحة.
  • وضع الشاشة المزدوجة. عرض صفحتين جنبًا إلى جنب مثل كتاب مادي.
  • تحديد النص عبر الصفحات. تحديد ونسخ النص الذي يمتد عبر صفحات متعددة.
  • التنقل باستخدام الإشارات المرجعية. الانتقال الفوري إلى الأقسام المرجعية.
  • البحث مع التمييز. – ابحث عن النص وقم بتمييزه في المستند.
  • التنقل باستخدام لوحة المفاتيح. – دعم مفاتيح الأسهم، ومفاتيح Page Up/Down، ومفاتيح Home/End.
  • أداء مُحسّن. – يعرض فقط الصفحات المرئية لتحقيق تجربة تصفح سلسة.

متطلبات ملف PDFium DLL.

قبل تشغيل أي تطبيق PDFium VCL، يجب تثبيت ملفات PDFium DLL. تقع ملفات DLL في: DLLs مجلد:

  • pdfium32.dll / pdfium64.dll – إصدارات قياسية لمعظم التطبيقات.
  • pdfium32v8.dll / pdfium64v8.dll – الإصدارات الموسعة مع محرك JavaScript V8.

التثبيت: تشغيل PDFiumVCL\DLLs\CopyDlls.bat بصلاحيات المسؤول لنسخ ملفات DLL إلى مجلدات نظام Windows. في نظام Windows 64 بت، يتم وضع ملفات DLL‏ 32 بت في SysWOW64 ويتم وضع ملفات DLL‏ 64 بت في System32.

إعداد المكون.

يوضح العرض التوضيحي نظام تحديد نص متطور:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
procedure TFormMain.PdfViewMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  CharIndex: Integer;
begin
  if Button = mbLeft then
  begin
    // Get character index at click position
    CharIndex := GetPreciseCharacterIndex(X, Y);
    
    if CharIndex >= 0 then
    begin
      SelectionMode := True;
      Selecting := True;
      SelectionStart := CharIndex;
      SelectionEnd := CharIndex;
    end;
  end;
end;
 
procedure TFormMain.PdfViewMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
var
  CharIndex: Integer;
begin
  if Selecting then
  begin
    CharIndex := GetPreciseCharacterIndex(X, Y);
    if CharIndex >= 0 then
    begin
      SelectionEnd := CharIndex;
      PdfView.Invalidate; // Redraw to show selection
    end;
  end;
end;

اكتشاف فهرس الأحرف.

لتحقيق تحديد نص دقيق، يستخدم العرض التوضيحي نطاقًا يعتمد على مستوى التكبير لاكتشاف الأحرف:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function TFormMain.GetPreciseCharacterIndex(X, Y: Integer): Integer;
var
  BaseTolerance: Single;
  ZoomFactor: Single;
  AdjustedTolerance: Single;
  CharIndex: Integer;
begin
  Result := -1;
  
  if not PdfView.Active then
    Exit;
    
  // Calculate dynamic tolerance based on zoom level
  ZoomFactor := PdfView.Zoom;
  BaseTolerance := 5.0;
  
  // Adjust tolerance inversely to zoom
  AdjustedTolerance := BaseTolerance / ZoomFactor;
  
  // Get character at position with tolerance
  CharIndex := PdfView.CharacterIndexAtPos(X, Y,
    AdjustedTolerance, AdjustedTolerance);
    
  Result := CharIndex;
end;

تسليط الضوء على النص المحدد.

يسلط العرض التوضيحي الضوء على التحديدات في. OnPaint الحدث:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
procedure TFormMain.PdfViewPaint(Sender: TObject);
var
  I, StartIdx, EndIdx: Integer;
  Rect: TPdfRectangle;
  R: TRect;
begin
  if (SelectionStart >= 0) and (SelectionEnd >= 0) then
  begin
    StartIdx := Min(SelectionStart, SelectionEnd);
    EndIdx := Max(SelectionStart, SelectionEnd);
    
    // Draw highlight for each character in selection
    for I := StartIdx to EndIdx do
    begin
      Rect := PdfView.CharacterRectangle[I];
      
      // Convert PDF coordinates to screen coordinates
      if PdfView.PageToDevice(
        Rect.Left, Rect.Top,
        PdfView.Left, PdfView.Top,
        PdfView.Width, PdfView.Height,
        PdfView.Rotation, R.Left, R.Top) then
      begin
        // Draw highlight rectangle
        PdfView.Canvas.Brush.Color := clHighlight;
        PdfView.Canvas.Brush.Style := bsSolid;
        PdfView.Canvas.FillRect(R);
      end;
    end;
  end;
end;

نسخ النص المحدد إلى الحافظة.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
procedure TFormMain.MenuItemCopyClick(Sender: TObject);
var
  StartIdx, EndIdx: Integer;
  SelectedText: string;
begin
  if (SelectionStart >= 0) and (SelectionEnd >= 0) then
  begin
    StartIdx := Min(SelectionStart, SelectionEnd);
    EndIdx := Max(SelectionStart, SelectionEnd);
    
    // Set page number for text extraction
    Pdf.PageNumber := PdfView.PageNumber;
    
    // Extract text from selection range
    SelectedText := Pdf.Text(StartIdx, EndIdx - StartIdx + 1);
    
    // Copy to clipboard
    Clipboard.AsText := SelectedText;
  end;
end;

وظيفة البحث.

تنفيذ البحث النصي مع التمييز:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
procedure TFormMain.SpeedButtonSearchClick(Sender: TObject);
var
  SearchText: string;
  FoundIndex: Integer;
begin
  SearchText := EditSearch.Text;
  
  if SearchText = '' then
    Exit;
    
  // Find first occurrence
  FoundIndex := Pdf.FindFirst(SearchText, [], 0, True);
  
  if FoundIndex >= 0 then
  begin
    SearchStart := FoundIndex;
    SearchEnd := FoundIndex + Length(SearchText) - 1;
    PdfView.Invalidate; // Redraw to show highlight
  end
  else
    ShowMessage('Text not found');
end;

حدث تغيير الصفحة.

معالجة تغييرات الصفحة لتحديث عناصر واجهة المستخدم:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TFormMain.PdfViewPageChanged(Sender: TObject);
begin
  if PdfView.Active then
  begin
    // Update page indicator
    SpeedButtonPageNumber.Caption :=
      IntToStr(PdfView.PageNumber) + ' of ' + IntToStr(PdfView.PageCount);
    
    // Update navigation button states
    SpeedButtonFirstPage.Enabled := PdfView.PageNumber > 1;
    SpeedButtonPreviousPage.Enabled := PdfView.PageNumber > 1;
    SpeedButtonNextPage.Enabled := PdfView.PageNumber < PdfView.PageCount;
    SpeedButtonLastPage.Enabled := PdfView.PageNumber < PdfView.PageCount;
    
    // Update bookmark tree selection
    if not DisableBookmarks then
      UpdateBookmarkSelection(PdfView.PageNumber);
  end;
end;

التنقل باستخدام لوحة المفاتيح.

العرض التوضيحي يتعامل مع اختصارات لوحة المفاتيح للتنقل:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
procedure TFormMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_ESCAPE:
      begin
        // Exit selection mode on Escape
        if SelectionMode then
        begin
          SelectionMode := False;
          SelectionStart := -1;
          SelectionEnd := -1;
          PdfView.Invalidate;
        end;
        Key := 0;
      end;
      
    VK_PRIOR, VK_UP, VK_LEFT:
      begin
        if SpeedButtonPreviousPage.Enabled then
          SpeedButtonPreviousPage.Click;
        Key := 0;
      end;
      
    VK_NEXT, VK_DOWN, VK_RIGHT:
      begin
        if SpeedButtonNextPage.Enabled then
          SpeedButtonNextPage.Click;
        Key := 0;
      end;
      
    VK_HOME:
      begin
        if SpeedButtonFirstPage.Enabled then
          SpeedButtonFirstPage.Click;
        Key := 0;
      end;
      
    VK_END:
      begin
        if SpeedButtonLastPage.Enabled then
          SpeedButtonLastPage.Click;
        Key := 0;
      end;
  end;
end;

التنقل بين الصفحات المزدوجة

عند استخدام وضع الصفحات المزدوجة، قم بالتنقل صفحتين في كل مرة:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TFormMain.SpeedButtonNextPageClick(Sender: TObject);
begin
  if PdfView.DisplayMode = dmSingleContinuous then
    PdfView.PageNumber := PdfView.PageNumber + 1
  else
    PdfView.PageNumber := PdfView.PageNumber + 2;
end;
 
procedure TFormMain.SpeedButtonPreviousPageClick(Sender: TObject);
begin
  if PdfView.DisplayMode = dmSingleContinuous then
    PdfView.PageNumber := PdfView.PageNumber - 1
  else
    PdfView.PageNumber := PdfView.PageNumber - 2;
end;

الخلاصة.

العرض التوضيحي "Multi-Page Viewer" يوضح كيفية إنشاء قارئ PDF كامل الميزات مع التمرير المستمر، واختيار النص، ووظائف البحث. هذه هي الميزات التي يتوقعها المستخدمون من تطبيقات عرض PDF الحديثة.

PDFium VCL تتعامل مع عمليات العرض المعقدة واستخراج النصوص، بينما تركز أنت على واجهة المستخدم والميزات الخاصة بالتطبيق. والنتيجة هي تجربة عرض PDF سلسة وسريعة الاستجابة تنافس برامج قراءة PDF التجارية.

احصل على مكون PDFium VCL. على loslab.com وابدأ في بناء تطبيقات PDF احترافية باستخدام Delphi اليوم.