Search Results for

    Show / Hide Table of Contents

    Custom previewing (C++)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\Demo\Cpp\Modules\25.Printing and Exporting\20.CustomPreview and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​VCL-​demos/​tree/​master/​Cpp/​Modules/​25.​Printing and Exporting/​20.​Custom​Preview

    Overview

    FlexCel comes with a full featured viewer that you can use to display a preview of Excel files in your application, and without having any printer installed.

    Concepts

    • How to create a preview form that you can embed inside your application, including thumbnails, navigation, etc.

    • How to Export to PDF from a thread, allowing the user to cancel it.

    Files

    CustomPreview.cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <tchar.h>
    //---------------------------------------------------------------------------
    
    USEFORM("UCustomPreview.cpp", FCustomPreview);
    USEFORM("UPasswordDialog.cpp", PasswordDialog);
    //---------------------------------------------------------------------------
    int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
    {
        try
        {
            Application->Initialize();
            Application->MainFormOnTaskBar = true;
            Application->CreateForm(__classid(TFCustomPreview), &FCustomPreview);
            Application->Run();
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
        catch (...)
        {
            try
            {
                throw Exception("");
            }
            catch (Exception &exception)
            {
                Application->ShowException(&exception);
            }
        }
        return 0;
    }
    //---------------------------------------------------------------------------
    

    UCustomPreview.cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "UCustomPreview.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TFCustomPreview *FCustomPreview;
    //---------------------------------------------------------------------------
    __fastcall TFCustomPreview::TFCustomPreview(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::FormCreate(TObject *Sender)
    {
      Xls = new TXlsFile(1, false);
      Xls->Protection->OnPassword = GetPassword;
      ImgExport = new TFlexCelImgExport(Xls, false);
      ImgExport->AllVisibleSheets = false;
      MainPreview->Document = ImgExport;
      Thumbs->Document = ImgExport;
      RegisterForHDPI(this, DPIChanged);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::FormDestroy(TObject *Sender)
    {
      PrintingThread->Free();
      PdfThread->Free();
      ImgExport->Free();
      Xls->Free(); //after freeing the threads, so we don't free the xls object while they are working.
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::ActionCloseExecute(TObject *Sender)
    {
      Close();
    }
    //---------------------------------------------------------------------------
    
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older, this should be "TOnPasswordEventArgs * const e".
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
    void __fastcall TFCustomPreview::GetPassword(const TOnPasswordEventArgs* e)
    {
      TPasswordDialog* Pwd = new TPasswordDialog(NULL);
      try
      {
        Pwd->SetFileName(OpenDialog->FileName);
        if (Pwd->ShowModal() != mrOk) return;
    
        //We need this cast because the delphi object is a constant pointer, not a pointer to a constant.
        const_cast<TOnPasswordEventArgs*>(e)->Password = Pwd->Password();
      }
      __finally
      {
        Pwd->Free();
      }
    }
    #else
    //XE3 has fixed the bug, now we need to define the event correctly
    void __fastcall TFCustomPreview::GetPassword(TOnPasswordEventArgs* const e)
    {
      TPasswordDialog* Pwd = new TPasswordDialog(NULL);
      try
      {
        Pwd->SetFileName(OpenDialog->FileName);
        if (Pwd->ShowModal() != mrOk) return;
    
        e->Password = Pwd->Password();
      }
      __finally
      {
        Pwd->Free();
      }
    }
    #endif
    
    
    void __fastcall TFCustomPreview::ActionOpenExecute(TObject *Sender)
    {
      if (!(OpenDialog->Execute())) return;
      LoadFile(OpenDialog->FileName);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::LoadFile(String FileName)
    {
      PanelPdfOk->Visible = false;
      PanelPdfError->Visible = false;
      PanelPdf->Visible = false;
      PanelPrintingOk->Visible = false;
      PanelPrintingError->Visible = false;
      PanelPrinting->Visible = false;
    
    
      OpenDialog->FileName = FileName;
      lbSheets->Items->Clear();
    
      try
      {
        Xls->Open(FileName);
      }
      catch (Exception* ex)
      {
        EnableCommonActions(false);
        ActionPrint->Enabled = false;
        ActionPdf->Enabled = false;
        ActionZoom->Enabled = false;
        ActionAutofit->Enabled = false;
        ActionOpen->Enabled = true;
        PanelSelectPage->Visible = false;
        Xls->NewFile(1, TExcelFileFormat::v2019);
        Caption = "Custom Preview";
        ShowMessage("Error opening file: " + ex->Message);
        MainPreview->InvalidatePreview();
        return;
      }
    
      for (int i = 1; i <= Xls->SheetCount; i++)
      {
        lbSheets->Items->Add(Xls->GetSheetName(i));
      }
      lbSheets->ItemIndex = Xls->ActiveSheet - 1;
    
      EnableCommonActions(true);
      ActionPrint->Enabled = true;
      ActionPdf->Enabled = true;
      ActionZoom->Enabled = true;
      ActionAutofit->Enabled = true;
      Caption = "Custom Preview: " + OpenDialog->FileName;
      PanelSelectPage->Visible = true;
      ToolBarAutofit->Left = PanelSelectPage->Left + 10; //Make the panel appear to the left of the toolbar.
      MainPreview->InvalidatePreview();
    }
    
    
    void __fastcall TFCustomPreview::cbAllSheetsClick(TObject *Sender)
    {
      PanelSheets->Visible = !cbAllSheets->Checked;
      ImgExport->AllVisibleSheets = cbAllSheets->Checked;
      MainPreview->InvalidatePreview();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::lbSheetsClick(TObject *Sender)
    {
      if (lbSheets->Items->Count > Xls->SheetCount) return;
      Xls->ActiveSheet = lbSheets->ItemIndex + 1;
      MainPreview->InvalidatePreview();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::EnableCommonActions(bool Enable)
    {
      if (Enable) DisabledCount--; else DisabledCount++;
      if (DisabledCount < 0) DisabledCount = 0;
      if (Enable && DisabledCount > 0) return; //we would be both printing and exporting to pdf, if one finishes, the buttons shouldn't be enabled util the other finishes too.
    
    
      ActionOpen->Enabled = Enable;
      ActionGridLines->Enabled = Enable;
      ActionHeadings->Enabled = Enable;
      ActionRecalc->Enabled = Enable;
    }
    
    void __fastcall TFCustomPreview::PdfProgressFeedback(int Progress, String Msg)
    {
      PdfProgressBar->Position = Progress;
      lblPdfPage->Caption = Msg;
    }
    
    void __fastcall TFCustomPreview::PdfFinalFeedback(bool Ok, String Msg)
    {
      PanelPdf->Visible = false;
      if (!Ok)
      {
        PanelPdfError->Visible = true;
        lblPdfError->Caption = "Error exporting to PDF: " + Msg;
      }
      else
      {
        PanelPdfOk->Visible = true;
      }
    
      EnableCommonActions(true);
      ActionPdf->Enabled = true;
    }
    
    void __fastcall TFCustomPreview::ActionPdfExecute(TObject *Sender)
    {
      if (!(PdfSaveDialog->Execute())) return;
    
      PdfProgressBar->Position = 0;
      lblPdfPage->Caption = "Initializing";
      EnableCommonActions(false);
      ActionPdf->Enabled = false;
      btnPdfCancel->Enabled = true;
      btnPdfCancel->Caption = "Cancel";
    
      PanelPdfOk->Visible = false;
      PanelPdfError->Visible = false;
      PanelPdf->Visible = true;
    
      PdfThread->Free();
    
      PdfThread = new TPdfThread(
        Xls,
        PdfProgressFeedback,
        PdfFinalFeedback,
        PdfSaveDialog->FileName,
        cbAllSheets->Checked);
    
      PdfThread->Start();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::PrintProgressFeedback(int Progress, String Msg)
    {
      PrintProgressBar->Position = Progress;
      lblPrintPage->Caption = Msg;
    }
    
    void __fastcall TFCustomPreview::PrintFinalFeedback(bool Ok, String Msg)
    {
      PanelPrinting->Visible = false;
      if (!Ok)
      {
        PanelPrintingError->Visible = true;
        lblPrintingError->Caption = "Error printing: " + Msg;
      }
      else
      {
        PanelPrintingOk->Visible = true;
      }
    
      EnableCommonActions(true);
      ActionPrint->Enabled = true;
    }
    
    void __fastcall TFCustomPreview::ActionPrintExecute(TObject *Sender)
    {
      if (!(PrintDialog->Execute())) return;
    
      PrintProgressBar->Position = 0;
      lblPrintPage->Caption = "Initializing";
      EnableCommonActions(false);
      ActionPrint->Enabled = false;
    
      btnPrintCancel->Enabled = true;
      btnPrintCancel->Caption = "Cancel";
    
      PanelPrintingOk->Visible = false;
      PanelPrintingError->Visible = false;
      PanelPrinting->Visible = true;
    
      PrintingThread->Free();
      PrintingThread = new TPrintingThread(
        Xls,
        &PrintProgressFeedback,
        &PrintFinalFeedback,
        "",
        cbAllSheets->Checked);
    
      PrintingThread->Start();
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnOpenGeneratedFileClick(TObject *Sender)
    {
      ShellExecute(0, L"open", PdfSaveDialog->FileName.c_str(), L"", L"", SW_SHOWNORMAL);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPdfCancelClick(TObject *Sender)
    {
      if (PdfThread == NULL) //it shouldn't really happen
      {
        PanelPdf->Visible = false;
        return;
      }
      btnPdfCancel->Enabled = false;
      btnPdfCancel->Caption = "Canceling...";
      PdfThread->Terminate(); //FlexCel will check that we set terminated, and exit as fast as it can.
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPrintCancelClick(TObject *Sender)
    {
      if (PrintingThread == NULL) //it shouldn't really happen
      {
        PanelPrinting->Visible = false;
        return;
      }
      btnPrintCancel->Enabled = false;
      btnPrintCancel->Caption = "Canceling...";
      PrintingThread->Terminate(); //FlexCel will check that we set terminated, and exit as fast as it can.
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPdfErrorCloseClick(TObject *Sender)
    {
      PanelPdfError->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPrintingErrorCloseClick(TObject *Sender)
    {
      PanelPrintingError->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPrintOkCloseClick(TObject *Sender)
    {
      PanelPrintingOk->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btnPdfOkCloseClick(TObject *Sender)
    {
      PanelPdfOk->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::UpdatePages()
    {
      edPage->Text = IntToStr(MainPreview->StartPage);
      lblTotalPages->Caption = "of " + IntToStr(MainPreview->TotalPages);
    }
    
    void __fastcall TFCustomPreview::ChangePages()
    {
      int pn;
      if (TryStrToInt(Trim(edPage->Text), pn)) MainPreview->StartPage = pn;
    }
    
    void __fastcall TFCustomPreview::DPIChanged()
    {
      MainPreview->InvalidatePreview();
    }
    
    void __fastcall TFCustomPreview::MainPreviewStartPageChanged(TObject *Sender)
    {
      UpdatePages();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::edPageExit(TObject *Sender)
    {
      ChangePages();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::edPageKeyPress(TObject *Sender, System::WideChar &Key)
    
    {
      if (Key == (char)13)
      {
        ChangePages();
        Key = (char)0;
      }
      else if (Key == (char)27)
      {
        UpdatePages();
        Key = (char)0;
      }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::UpdateZoom()
    {
      ActionZoom->Caption = IntToStr((int)(MainPreview->Zoom * 100)) + "%";
      if (MainPreview->AutofitPreview == TAutofitPreview::None) UpdateAutofitText();
      ChangingZoom = true;
      __try
      {
        TrackBarZoom->Position = (int)(MainPreview->Zoom * 100);
      }
      __finally
      {
        ChangingZoom = false;
      }
    }
    void __fastcall TFCustomPreview::MainPreviewZoomChanged(TObject *Sender)
    {
       UpdateZoom();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::ActionZoomExecute(TObject *Sender)
    {
      System::Types::TPoint p;
      p.X = ToolButtonZoom->Left;
      p.Y = ToolButtonZoom->Top + ToolButtonZoom->Height;
      p = ToolButtonZoom->ClientToParent(p, FCustomPreview);
    
      PanelZoom->Left = p.X;
      PanelZoom->Top = p.Y;
      PanelZoom->Visible = true;
      ActiveControl = TrackBarZoom;
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btn25Click(TObject *Sender)
    {
      MainPreview->Zoom = 0.25;
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btn50Click(TObject *Sender)
    {
      MainPreview->Zoom = 0.50;
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btn75Click(TObject *Sender)
    {
      MainPreview->Zoom = 0.75;
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btn100Click(TObject *Sender)
    {
      MainPreview->Zoom = 1;
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::btn150Click(TObject *Sender)
    {
      MainPreview->Zoom = 1.5;
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::TrackBarZoomChange(TObject *Sender)
    {
      if (ChangingZoom) return; //avoid recursive calls.
      MainPreview->Zoom = TrackBarZoom->Position / 100.0;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::TrackBarZoomEnter(TObject *Sender)
    {
      PanelZoom->SetFocus();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::PanelZoomExit(TObject *Sender)
    {
      PanelZoom->Visible = false;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::UpdateAutofitText()
    {
      switch (MainPreview->AutofitPreview)
      {
        case TAutofitPreview::None: ActionAutofit->Caption = "No Autofit"; break;
        case TAutofitPreview::Width: ActionAutofit->Caption = "Fit to Width"; break;
        case TAutofitPreview::Height: ActionAutofit->Caption = "Fit to Height"; break;
        case TAutofitPreview::Full: ActionAutofit->Caption = "Fit to Page"; break;
      }
    }
    
    
    void __fastcall TFCustomPreview::ActionAutofitExecute(TObject *Sender)
    {
      if (!(dynamic_cast<TControl* >(Sender))) return;
    
      System::Types::TPoint PopPoint;
      PopPoint.X = ((TControl*)Sender)->Left;
      PopPoint.Y = ((TControl*)Sender)->Top + ((TControl*)Sender)->Height;
      PopPoint = ClientToScreen(PopPoint);
      AutofitMenu->Popup(PopPoint.X, PopPoint.Y);
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::NoAutofit1Click(TObject *Sender)
    {
      MainPreview->AutofitPreview = TAutofitPreview::None;
      UpdateAutofitText();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::FittoWidth1Click(TObject *Sender)
    {
      MainPreview->AutofitPreview = TAutofitPreview::Width;
      UpdateAutofitText();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::FittoHeight1Click(TObject *Sender)
    {
      MainPreview->AutofitPreview = TAutofitPreview::Height;
      UpdateAutofitText();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::FittoPage1Click(TObject *Sender)
    {
      MainPreview->AutofitPreview = TAutofitPreview::Full;
      UpdateAutofitText();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::ActionRecalcExecute(TObject *Sender)
    {
      Xls->Recalc();
      MainPreview->InvalidatePreview();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::ActionGridLinesExecute(TObject *Sender)
    {
      if (cbAllSheets->Checked)
      {
        int SaveActiveSheet = Xls->ActiveSheet;
        for (int i = 1; i <= Xls->SheetCount; i++)
        {
          Xls->ActiveSheet = i;
          Xls->PrintGridLines = ActionGridLines->Checked;
        }
        Xls->ActiveSheet = SaveActiveSheet;
      }
      else
      {
        Xls->PrintGridLines = ActionGridLines->Checked;
      }
      MainPreview->InvalidatePreview();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TFCustomPreview::ActionHeadingsExecute(TObject *Sender)
    {
      if (cbAllSheets->Checked)
      {
        int SaveActiveSheet = Xls->ActiveSheet;
        for (int i = 1; i <= Xls->SheetCount; i++)
        {
          Xls->ActiveSheet = i;
          Xls->PrintHeadings = ActionHeadings->Checked;
        }
        Xls->ActiveSheet = SaveActiveSheet;
      }
      else
      {
        Xls->PrintHeadings = ActionHeadings->Checked;
      }
      MainPreview->InvalidatePreview();
    }
    //---------------------------------------------------------------------------
    

    UPasswordDialog.cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "UPasswordDialog.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    
    //---------------------------------------------------------------------------
    __fastcall TPasswordDialog::TPasswordDialog(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    String __fastcall TPasswordDialog::Password()
    {
       return edPassword->Text;
    }
    
    void __fastcall TPasswordDialog::SetFileName(const String FileName)
    {
      lblFileName->Caption = ExtractFileName(FileName);
    }
    

    UPdfExporting.cpp

    //---------------------------------------------------------------------------
    
    #pragma hdrstop
    
    #include "UPdfExporting.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    
    __fastcall TPdfThread::TPdfThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets)
          : TProgressThread(aXls, aProgressFeedback, aFinalFeedback, aFileName, aAllSheets)
    {
    }
    
    
    void __fastcall TPdfThread::Execute()
    {
      TFlexCelPdfExport* pdf = new TFlexCelPdfExport(Xls, true);
      try
      {
        pdf->AfterGeneratePage = ShowProgress;
    
        if (AllSheets)
        {
          TFileStream* fs = new TFileStream(FileName, fmCreate);
          try
          {
            pdf->BeginExport(fs);
            pdf->PageLayout = TPageLayout::Outlines;
            pdf->ExportAllVisibleSheets(false, TPath::GetFileNameWithoutExtension(FileName));
            pdf->EndExport();
          }
          __finally
          {
            fs->Free();
          }
        }
        else
        {
          pdf->Export(FileName);
        }
      }
      __finally
      {
        pdf->Free();
      }
    }
    
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
    void __fastcall TPdfThread::ShowProgress(const TObject* sender, const TPageEventArgs* e)
    #else
    void __fastcall TPdfThread::ShowProgress(TObject* const sender, TPageEventArgs* const e)
    #endif
    {
      TFlexCelPdfExportProgress* Prog = ((TFlexCelPdfExport*)sender)->Progress;
      int Percent;
      if (Prog->TotalPage == 0) Percent = 100; else Percent = (int)(Prog->Page * 100.0 / Prog->TotalPage);
    
      ProgressFeedback_percent = Percent;
      ProgressFeedback_msg = String(L"Page ") + IntToStr(Prog->Page) + L" of " + IntToStr(Prog->TotalPage);
      Synchronize(&DoProgressFeedback);
    
    }
    

    UPrinting.cpp

    //---------------------------------------------------------------------------
    
    #pragma hdrstop
    
    #include "UPrinting.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    
    __fastcall TPrintingThread::TPrintingThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets)
          : TProgressThread(aXls, aProgressFeedback, aFinalFeedback, aFileName, aAllSheets)
    {
    }
    
    
    void __fastcall TPrintingThread::Execute()
    {
      TFlexCelPrintDocument* doc = new TFlexCelPrintDocument(Xls);
      try
      {
        doc->AfterGeneratePage = ShowProgress;
    
        if (AllSheets)
        {
            doc->BeginPrint();
            try
            {
              doc->PrintAllVisibleSheets(false);
            }
            __finally
            {
              doc->EndPrint();
            }
        }
        else
        {
          doc->Print();
        }
      }
      __finally
      {
        doc->Free();
      }
    }
    
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
    void __fastcall TPrintingThread::ShowProgress(const TObject* sender, const TPrintPageEventArgs* e)
    #else
    void __fastcall TPrintingThread::ShowProgress(TObject* const sender, TPrintPageEventArgs* const e)
    #endif
    {
      TFlexCelPrintingProgress* Prog = ((TFlexCelPrintDocument*)sender)->Progress;
      int Percent;
      if (Prog->TotalPage == 0) Percent = 100; else Percent = (int)(Prog->Page * 100.0 / Prog->TotalPage);
    
      ProgressFeedback_percent = Percent;
      ProgressFeedback_msg = String(L"Page ") + IntToStr(Prog->Page) + L" of " + IntToStr(Prog->TotalPage);
      Synchronize(&DoProgressFeedback);
    }
    

    UProgressThread.cpp

    //---------------------------------------------------------------------------
    
    #pragma hdrstop
    
    #include "UProgressThread.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    
    __fastcall TProgressThread::TProgressThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets): TThread(true)
    {
      FreeOnTerminate = false;
      Canceled = false;
      Xls = aXls;
      ProgressFeedback = aProgressFeedback;
      FinalFeedback = aFinalFeedback;
      FileName = aFileName;
      AllSheets = aAllSheets;
    
    }
    
    void __fastcall TProgressThread::TerminatedSet()
    {
      TThread::TerminatedSet();
      Canceled = true;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TProgressThread::DoTerminate()
    {
      TThread::DoTerminate();
      FinalFeedback_msg = "";
      FinalFeedback_ok = !Canceled;
      if (FatalException != NULL)
      {
        FinalFeedback_ok = false;
        if (dynamic_cast<Exception*>(FatalException))
        {
          FinalFeedback_msg = ((Exception*)FatalException)->Message;
        }
        else FinalFeedback_msg = "Unexpected error: " + FatalException->ClassName();
      }
    
      if (Canceled) FinalFeedback_msg = "Operation canceled by the user.";
    
    
      //DoTerminate runs in the thread context, not the main thread context as OnTerminate.
      Synchronize(&DoFinalFeedback);
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TProgressThread::DoFinalFeedback()
    {
        FinalFeedback(FinalFeedback_ok, FinalFeedback_msg);
    }
    
    void __fastcall TProgressThread::DoProgressFeedback()
    {
        ProgressFeedback(ProgressFeedback_percent, ProgressFeedback_msg);
    }
    

    UCustomPreview.h

    //---------------------------------------------------------------------------
    
    #ifndef UCustomPreviewH
    #define UCustomPreviewH
    //---------------------------------------------------------------------------
    #include <System.Classes.hpp>
    #include <Vcl.Controls.hpp>
    #include <Vcl.StdCtrls.hpp>
    #include <Vcl.Forms.hpp>
    #include <Vcl.ActnList.hpp>
    #include <Vcl.ComCtrls.hpp>
    #include <Vcl.Dialogs.hpp>
    #include <Vcl.ExtCtrls.hpp>
    #include <Vcl.ImgList.hpp>
    #include <Vcl.Menus.hpp>
    #include <Vcl.ToolWin.hpp>
    #include "FlexCel.Preview.hpp"
    #include "FlexCel.Render.hpp"
    #include "FlexCel.XlsAdapter.hpp"
    #include "FlexCel.VCLSupport.hpp"
    #include "FlexCel.Core.hpp"
    #include "UPdfExporting.h"
    #include "UPrinting.h"
    #include "UPasswordDialog.h"
    #include "UFlexCelHDPI.hpp"
    //---------------------------------------------------------------------------
    class TFCustomPreview : public TForm
    {
    __published: // IDE-managed Components
        TSplitter *Splitter1;
        TPanel *Panel1;
        TSplitter *Splitter2;
        TPanel *Panel3;
        TCheckBox *cbAllSheets;
        TPanel *Panel4;
        TPanel *Panel5;
        TPanel *Panel6;
        TFlexCelPreviewer *Thumbs;
        TPanel *PanelSheets;
        TListBox *lbSheets;
        TPanel *Panel2;
        TFlexCelPreviewer *MainPreview;
        TPanel *PanelPrinting;
        TLabel *lblProgressTask;
        TLabel *lblPrintPage;
        TProgressBar *PrintProgressBar;
        TButton *btnPrintCancel;
        TPanel *PanelPdf;
        TLabel *Label1;
        TLabel *lblPdfPage;
        TProgressBar *PdfProgressBar;
        TButton *btnPdfCancel;
        TPanel *PanelPdfError;
        TLabel *lblPdfError;
        TButton *btnPdfErrorClose;
        TPanel *PanelPrintingError;
        TLabel *lblPrintingError;
        TButton *btnPrintingErrorClose;
        TPanel *PanelPrintingOk;
        TLabel *Label2;
        TButton *btnPrintOkClose;
        TPanel *PanelPdfOk;
        TLabel *Label3;
        TButton *btnPdfOkClose;
        TButton *btnOpenGeneratedFile;
        TPanel *FlowPanel1;
        TToolBar *ToolBar2;
        TToolButton *ToolButton14;
        TToolButton *ToolButton15;
        TToolButton *ToolButton16;
        TToolButton *ToolButton17;
        TToolButton *ToolButton18;
        TPanel *PanelSelectPage;
        TLabel *Label4;
        TLabel *lblTotalPages;
        TEdit *edPage;
        TToolBar *ToolBar4;
        TToolButton *ToolButtonZoom;
        TToolButton *ToolButton27;
        TToolButton *ToolButton28;
        TToolButton *ToolButton29;
        TToolButton *ToolButton30;
        TToolButton *ToolButton31;
        TToolButton *ToolButton32;
        TPanel *PanelZoom;
        TTrackBar *TrackBarZoom;
        TButton *btn25;
        TButton *btn50;
        TButton *btn75;
        TButton *btn100;
        TButton *btn150;
        TPanel *PanelPrint;
        TButton *btnPrint;
        TActionList *Actions;
        TAction *ActionOpen;
        TAction *ActionAutofit;
        TAction *ActionRecalc;
        TAction *ActionHeadings;
        TAction *ActionPdf;
        TAction *ActionPrint;
        TAction *ActionGridLines;
        TAction *ActionClose;
        TAction *ActionZoom;
        TOpenDialog *OpenDialog;
        TImageList *ToolbarImages;
        TImageList *ToolbarImagesDisabled;
        TSaveDialog *PdfSaveDialog;
        TPrintDialog *PrintDialog;
        TPopupMenu *AutofitMenu;
        TMenuItem *NoAutofit1;
        TMenuItem *FittoWidth1;
        TMenuItem *FittoHeight1;
        TMenuItem *FittoPage1;
        TImageList *ToolbarImages_100Scale;
        TImageList *ToolbarImages_300Scale;
        TToolBar *ToolBarAutofit;
        TToolButton *ToolButton1;
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall ActionCloseExecute(TObject *Sender);
        void __fastcall ActionOpenExecute(TObject *Sender);
        void __fastcall cbAllSheetsClick(TObject *Sender);
        void __fastcall lbSheetsClick(TObject *Sender);
        void __fastcall ActionPdfExecute(TObject *Sender);
        void __fastcall ActionPrintExecute(TObject *Sender);
        void __fastcall btnOpenGeneratedFileClick(TObject *Sender);
        void __fastcall btnPdfCancelClick(TObject *Sender);
        void __fastcall btnPrintCancelClick(TObject *Sender);
        void __fastcall btnPdfErrorCloseClick(TObject *Sender);
        void __fastcall btnPrintingErrorCloseClick(TObject *Sender);
        void __fastcall btnPrintOkCloseClick(TObject *Sender);
        void __fastcall btnPdfOkCloseClick(TObject *Sender);
        void __fastcall MainPreviewStartPageChanged(TObject *Sender);
        void __fastcall edPageExit(TObject *Sender);
        void __fastcall edPageKeyPress(TObject *Sender, System::WideChar &Key);
        void __fastcall MainPreviewZoomChanged(TObject *Sender);
        void __fastcall ActionZoomExecute(TObject *Sender);
        void __fastcall btn25Click(TObject *Sender);
        void __fastcall btn50Click(TObject *Sender);
        void __fastcall btn75Click(TObject *Sender);
        void __fastcall btn100Click(TObject *Sender);
        void __fastcall btn150Click(TObject *Sender);
        void __fastcall TrackBarZoomChange(TObject *Sender);
        void __fastcall TrackBarZoomEnter(TObject *Sender);
        void __fastcall PanelZoomExit(TObject *Sender);
        void __fastcall ActionAutofitExecute(TObject *Sender);
        void __fastcall NoAutofit1Click(TObject *Sender);
        void __fastcall FittoWidth1Click(TObject *Sender);
        void __fastcall FittoHeight1Click(TObject *Sender);
        void __fastcall FittoPage1Click(TObject *Sender);
        void __fastcall ActionRecalcExecute(TObject *Sender);
        void __fastcall ActionGridLinesExecute(TObject *Sender);
        void __fastcall ActionHeadingsExecute(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
    private:  // User declarations
        TExcelFile *Xls;
        TFlexCelImgExport *ImgExport;
        TPrintingThread *PrintingThread;
        TPdfThread *PdfThread;
        int DisabledCount;
        bool ChangingZoom;
        void __fastcall EnableCommonActions(bool Enable);
        void __fastcall LoadFile(String FileName);
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older, this should be "TOnPasswordEventArgs * const e".
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
        void __fastcall GetPassword(const TOnPasswordEventArgs *e);
    #else
        void __fastcall GetPassword(TOnPasswordEventArgs* const e);
    #endif
    
        void __fastcall UpdateZoom();
        void __fastcall UpdateAutofitText();
        void __fastcall UpdatePages();
        void __fastcall ChangePages();
        void __fastcall DPIChanged();
        void __fastcall PdfFinalFeedback(bool Ok, String  Msg);
        void __fastcall PdfProgressFeedback(int Progress, String Msg);
        void __fastcall PrintFinalFeedback(bool Ok, String  Msg);
        void __fastcall PrintProgressFeedback(int Progress, String Msg);
    
    public:       // User declarations
        __fastcall TFCustomPreview(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TFCustomPreview *FCustomPreview;
    //---------------------------------------------------------------------------
    #endif
    

    UPasswordDialog.h

    //---------------------------------------------------------------------------
    
    #ifndef UPasswordDialogH
    #define UPasswordDialogH
    //---------------------------------------------------------------------------
    #include <System.Classes.hpp>
    #include <Vcl.Controls.hpp>
    #include <Vcl.StdCtrls.hpp>
    #include <Vcl.Forms.hpp>
    //---------------------------------------------------------------------------
    class TPasswordDialog : public TForm
    {
    __published: // IDE-managed Components
        TLabel *Label1;
        TLabel *lblFileName;
        TButton *Button1;
        TButton *Button2;
        TEdit *edPassword;
    private:  // User declarations
    public:       // User declarations
        __fastcall TPasswordDialog(TComponent* Owner);
    
        __fastcall String Password();
        __fastcall void SetFileName(const String FileName);
    
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TPasswordDialog *PasswordDialog;
    //---------------------------------------------------------------------------
    #endif
    

    UPdfExporting.h

    //---------------------------------------------------------------------------
    
    #ifndef UPdfExportingH
    #define UPdfExportingH
    //---------------------------------------------------------------------------
    
    #include <IOUtils.hpp>
    #include "UProgressThread.h"
    #include "FlexCel.Pdf.hpp"
    #include "FlexCel.Render.hpp"
    #include "FlexCel.Core.hpp"
    //---------------------------------------------------------------------------
    class TPdfThread: public TProgressThread
    {
      public:
        __fastcall TPdfThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets);
    
    
      virtual void __fastcall Execute();
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
    void __fastcall ShowProgress(const TObject* sender, const TPageEventArgs* e);
    #else
    void __fastcall ShowProgress(TObject* const sender, TPageEventArgs* const e);
    #endif
    };
    //---------------------------------------------------------------------------
    
    #endif
    

    UPrinting.h

    //---------------------------------------------------------------------------
    
    #ifndef UPrintingH
    #define UPrintingH
    //---------------------------------------------------------------------------
    #include "UProgressThread.h"
    #include "FlexCel.Render.hpp"
    //---------------------------------------------------------------------------
    class TPrintingThread: public TProgressThread
    {
      public:
        __fastcall TPrintingThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets);
    
    
      virtual void __fastcall Execute();
    #if (__BORLANDC__ < 0x0650) //XE2 or older
    //C++ builder header translations are wrong for XE2 or older
    //see http://qc.embarcadero.com/wc/qcmain.aspx?d=42782
    void __fastcall ShowProgress(const TObject* sender, const TPrintPageEventArgs* e);
    #else
    void __fastcall ShowProgress(TObject* const sender, TPrintPageEventArgs* const e);
    #endif
    };
    //---------------------------------------------------------------------------
    #endif
    

    UProgressThread.h

    //---------------------------------------------------------------------------
    
    #ifndef UProgressThreadH
    #define UProgressThreadH
    //---------------------------------------------------------------------------
    #include <System.Classes.hpp>
    #include "FlexCel.Core.hpp"
    
    typedef void __fastcall (__closure *TFeedbackMethod)(int Progress, String Msg);
    typedef void __fastcall (__closure *TFinalFeedbackMethod)(bool Ok, String Msg);
    
    //---------------------------------------------------------------------------
    class TProgressThread: public TThread
    {
      private:
        String FinalFeedback_msg;
        bool FinalFeedback_ok;
        void __fastcall DoFinalFeedback();
      protected:
        String ProgressFeedback_msg;
        bool ProgressFeedback_percent;
        void __fastcall DoProgressFeedback();
    
      protected:
        TFeedbackMethod ProgressFeedback;
        TFinalFeedbackMethod FinalFeedback;
        TExcelFile *Xls;
        String FileName;
        bool AllSheets;
        bool Canceled;
    
        virtual void __fastcall TerminatedSet();
        virtual void __fastcall DoTerminate();
    
      public:
        __fastcall TProgressThread(TExcelFile *aXls, TFeedbackMethod aProgressFeedback,
          TFinalFeedbackMethod aFinalFeedback, String aFileName, bool aAllSheets);
    
    };
    //---------------------------------------------------------------------------
    #endif
    
    In This Article
    Back to top FlexCel Studio for VCL and FireMonkey v7.24
    © 2002 - 2025 tmssoftware.com