home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedZip.Cab / F112561_MainMn.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  30.7 KB  |  918 lines

  1. /*******************************************************************************
  2.  File:        MainMn.cpp
  3.  Description: Zip Manager sample application using The Xceed Zip Compression
  4.               Library 4
  5.  Copyright (c) 1995-1999 Xceed Software Inc.
  6. *******************************************************************************/
  7.  
  8. #include <vcl\vcl.h>
  9. #include <string.h>
  10. #pragma hdrstop
  11.  
  12. #include "MainMn.h"
  13. #include "Tools.h"
  14.  
  15. #pragma link "XceedZipLib_TLB"
  16. #pragma resource "*.dfm"
  17.  
  18. TMainFormFm *MainFormFm = 0;
  19.  
  20. //
  21. // Private declarations
  22. //
  23. int MinWidth;
  24. long TotalSize;
  25. long TotalZipSize;
  26. long FilesLbBytes;
  27. bool Testing;
  28.  
  29. //
  30. // Constructor
  31. //
  32. __fastcall TMainFormFm::TMainFormFm(TComponent* Owner)
  33.     : TForm(Owner)
  34. {
  35. }
  36.  
  37. //
  38. // Destructor
  39. //
  40. void __fastcall TMainFormFm::FormCreate(TObject *Sender)
  41. {
  42.   Application->OnHint = StatusBarShowHint;
  43.   MinWidth = Width;
  44.   Caption = "Untitled - Xceed Zip Demo";
  45.   Application->Title = Caption;
  46. }
  47.  
  48. //
  49. // StatusBarShowHint:
  50. //  Update status bar state.
  51. //
  52. void __fastcall TMainFormFm::StatusBarShowHint(TObject *Sender)
  53. {
  54.   StatusLb->Visible = (Application->Hint.Length()==0);
  55.   HintLb->Visible = (Application->Hint.Length()!=0);
  56.   HintLb->Caption = Application->Hint;
  57. }
  58.  
  59. //
  60. // The EnableInterface procedure is used to 'shut down' parts of the graphical
  61. // interface of this demo while the TXceedZip component is working. It turns off
  62. // menus, changes the cursor to an hourglass, etc. It can also be called to turn
  63. // everything back on.
  64. //
  65. void TMainFormFm::EnableInterface(bool Enable)
  66. {
  67.   static int DisableCount = 0;
  68.   bool ControlsEnable = false;
  69.  
  70.   if (Enable)
  71.   {
  72.     // Keep track of multiple disables/enables, and enable interface only when
  73.     // there are as many 'enables' as there were 'disables'.
  74.     DisableCount--;
  75.     if (DisableCount <= 0)
  76.     {
  77.       DisableCount = 0;
  78.       ControlsEnable = true;
  79.     }
  80.   }
  81.   else
  82.   {
  83.     DisableCount++;
  84.   }
  85.  
  86.   FileMn->Enabled = ControlsEnable;
  87.   EditMn->Enabled = ControlsEnable;
  88.   OptionsMn->Enabled = ControlsEnable;
  89.   HelpMn->Enabled = ControlsEnable;
  90.   FilesLb->Enabled = ControlsEnable;
  91.  
  92.   // Do not allow abort when not using a temp file, it can corrupt the archive.
  93.   AbortSb->Enabled = (!ControlsEnable) && (MainXz->UseTempFile == True);
  94.  
  95.   if (ControlsEnable)
  96.     Cursor = crDefault;
  97.   else
  98.     Cursor = crHourGlass;
  99.  
  100.   if (Enable)
  101.   {
  102.     ProgressBar1->Position = 0;
  103.     StatusLb->Caption = AnsiString(FilesLb->Items->Count) + " Entries, " +
  104.                                   FloatToStrF(TotalSize, ffNumber, 10, 0) + " Bytes, " +
  105.                                   FloatToStrF(TotalZipSize, ffNumber, 10, 0) + " Bytes.";
  106.   }
  107.  
  108.   HintLb->Caption = "";
  109.  
  110.   // The HintLb and StatusLb labels are one on top of the other.
  111.   HintLb->Visible = ControlsEnable;
  112.   StatusLb->Visible = !ControlsEnable;
  113. }
  114.  
  115. //
  116. // The LoadFileList procedure asks the TXceedZipProxy component for a list of files
  117. // contained in the current archive. It calls the List method and expects to
  118. // receive all the information via the OnListing event. See the MainXzListing
  119. // procedure to see how the information is placed into the demo's main listbox.
  120. //
  121. void TMainFormFm::LoadFileList()
  122. {
  123.   xcdError Err;
  124.  
  125.   long TotalFiles;
  126.   long CompressedBytes;
  127.   long UnCompressedBytes;
  128.   short CompressionRatio;
  129.   short IsZipFileSpanned;
  130.  
  131.   TotalSize = 0;
  132.   TotalZipSize = 0;
  133.   FilesLb->Items->Clear();
  134.   FilesLbBytes = 0;
  135.  
  136.   Err = MainXz->GetZipFileInformation(&TotalFiles,&CompressedBytes,&UnCompressedBytes,&CompressionRatio,&IsZipFileSpanned);
  137.   ProgressBar1->Max = TProgressRange(TotalFiles);
  138.  
  139.   if (TotalFiles > 100)
  140.   {
  141.     StatusLb->Caption = "Reading " + AnsiString(TotalFiles) + " items...";
  142.   }
  143.  
  144.   FilesLb->Items->BeginUpdate();
  145.   MainXz->FilesToProcess = "";
  146.   Err = MainXz->ListZipContents();
  147.  
  148.   if (Err != xerNothingToDo)
  149.   {
  150.     HandleError(Err, "reading archive contents", MainXz);
  151.   }
  152.  
  153.   FilesLb->Items->EndUpdate(); //**-** this line produce bug
  154.  
  155.   ProgressBar1->Position = 0;
  156.   ProgressBar1->Max = TProgressRange(100); // reset to usual maximum
  157. }
  158.  
  159. //
  160. // The FileMnClick procedure makes sure that the proper items are enabled in the
  161. // File menu.
  162. //
  163. void __fastcall TMainFormFm::FileMnClick(TObject *Sender)
  164. {
  165.   bool ZipFileNameEmpty;
  166.   ZipFileNameEmpty = (MainXz->ZipFilename.Length() == 0);
  167.  
  168.   FileCloseMn->Enabled = (!ZipFileNameEmpty);
  169.   FileFixMn->Enabled = (ZipFileNameEmpty) && (!MainXz->SpanMultipleDisks);
  170.   FileDeleteMn->Enabled = (ZipFileNameEmpty);
  171.   FileTestMn->Enabled = (ZipFileNameEmpty);
  172. }
  173.  
  174. //
  175. // The FileNewMnClick procedure creates a new archive file, but the archive file
  176. // is not really created until files are added to it first.
  177. //
  178. void __fastcall TMainFormFm::FileNewMnClick(TObject *Sender)
  179. {
  180.   NewZipDg->FileName = "";
  181.   EnableInterface(false);
  182.   if (NewZipDg->Execute())
  183.   {
  184.     if (FileExists(NewZipDg->FileName))
  185.     {
  186.       DeleteFile(NewZipDg->FileName.c_str());
  187.     }
  188.  
  189.     // Inform the TXceedZip component of the zip file name to use.
  190.     MainXz->ZipFilename = NewZipDg->FileName;
  191.     Caption = ExtractFileName(MainXz->ZipFilename) + " - XceedZip Demo";
  192.     Application->Title = Caption;
  193.     FilesLb->Clear();
  194.     FilesLbBytes = 0;
  195.     TotalSize = 0;
  196.     TotalZipSize = 0;
  197.     StatusLb->Caption = "";
  198.   }
  199.   EnableInterface(true);
  200. }
  201.  
  202. //
  203. // The FileOpenMnClick procedure opens an already existing archive, and calls
  204. // LoadFileList to list the archive's contents into the demo's main listbox.
  205. //
  206. void __fastcall TMainFormFm::FileOpenMnClick(TObject *Sender)
  207. {
  208.   OpenZipDg->Title = "Open Archive";
  209.   OpenZipDg->FileName = "";
  210.   EnableInterface(false);
  211.   if (OpenZipDg->Execute())
  212.   {
  213.     // Inform the TXceedZip component of the zip file name to use. }
  214.     MainXz->ZipFilename = OpenZipDg->FileName;
  215.     Caption = MainXz->ZipFilename + " - XceedZip Demo";
  216.     Application->Title = Caption;
  217.     // Call procedure that will list the contents of the archive into the
  218.     // demo's main listbox.
  219.     LoadFileList();
  220.   }
  221.   EnableInterface(True);
  222. }
  223.  
  224. //
  225. // The FileCloseMnClick procedure closes an archive. It does not really close the
  226. // archive because the archive is already closed when not being used. It only
  227. // clears the main listbox, the ZipFileName property of the TXceedZip component,
  228. // and the application title is reset.
  229. //
  230. void __fastcall TMainFormFm::FileCloseMnClick(TObject *Sender)
  231. {
  232.   MainXz->ZipFilename = "";
  233.   Caption = "Untitled - XceedZip Demo";
  234.   Application->Title = Caption;
  235.   FilesLb->Clear();
  236.   FilesLbBytes = 0;
  237.   StatusLb->Caption = "";
  238. }
  239.  
  240. void __fastcall TMainFormFm::FileExitMnClick(TObject *Sender)
  241. {
  242.     Close();
  243. }
  244.  
  245. //
  246. // The FileDeleteMnClick procedure prompts the user for an archive file to
  247. // delete, then deletes it.
  248. //
  249. void __fastcall TMainFormFm::FileDeleteMnClick(TObject *Sender)
  250. {
  251.   OpenZipDg->Title = "Delete Archive";
  252.   OpenZipDg->FileName = "";
  253.   EnableInterface(false);
  254.  
  255.   if ((OpenZipDg->Execute()))
  256.   {
  257.     AnsiString Msg("Are you sure you want to delete file \r\n '" + OpenZipDg->FileName + "' ?");
  258.       if (Application->MessageBox(Msg.c_str(), "Confirmation", MB_YESNO + MB_ICONQUESTION) == IDYES)
  259.     {
  260.       DeleteFile(OpenZipDg->FileName.c_str());
  261.     }
  262.   }
  263.   EnableInterface(true);
  264. }
  265.  
  266. //
  267. // The FileTestMnClick procedure tells the TXceedZip component to test the
  268. // contents of an archive file selected by the user. A dialog box is opened for
  269. // the user to select the archive file. Note: The Test method is used, but is not
  270. // passed a list of files to process. Without a list of files to process, the
  271. // TXceedZip component will test all the files in the archive. You can pass a
  272. // list of files to test in the same way that files are passed to the Extract
  273. // method in the EditExtractMnClick procedure in this demo. This way, you can
  274. // test specific files.
  275. //
  276. void __fastcall TMainFormFm::FileTestMnClick(TObject *Sender)
  277. {
  278.   xcdError Err;
  279.  
  280.   OpenZipDg->Title = "Test Archive";
  281.   OpenZipDg->FileName = "";
  282.   EnableInterface(false);
  283.   // Open a dialog box to ask for the archive filename.
  284.   if (OpenZipDg->Execute())
  285.   {
  286.     // Inform the TXceedZip component of the filename.
  287.     MainXz->ZipFilename = OpenZipDg->FileName;
  288.  
  289.     // Since it may take long before getting an OnTesting event so we can
  290.     // display 'Testing file...' we will display 'Testing archive...' until then.
  291.     StatusLb->Caption = "Testing archive " + MainXz->ZipFilename;
  292.  
  293.     // used so that skipping messages are different
  294.     Testing = true;
  295.  
  296.     // Execute the Test method. Put return value in Err.
  297.     Err = MainXz->TestZipFile(true);
  298.     Testing = false;
  299.  
  300.     // Since we are testing an archive file, XcdSuccess means that all the
  301.     // files in the archive have passed the test.
  302.     if (Err == xerSuccess)
  303.     {
  304.       Application->MessageBox("All files in the archive are OK.", "Confirmation", MB_OK + MB_ICONQUESTION);
  305.     }
  306.     else
  307.     {
  308.       if (Err == xerFilesSkipped)
  309.       {
  310.         // We can permit ourselves to say 'Some files were skipped', without
  311.         // specifying which ones, because the OnSkippingFile event will have
  312.         // already informed us about each file being skipped.
  313.         Application->MessageBox("All files tested in the archive are OK.\r\n (Some files were skipped)", "Information", MB_OK + MB_ICONINFORMATION);
  314.       }
  315.       else
  316.       {
  317.         // Regular error handler.
  318.         HandleError(Err, "testing", MainXz);
  319.       }
  320.       MainXz->ZipFilename = "";
  321.     }
  322.     EnableInterface(true);
  323.   }
  324. }
  325.  
  326. //
  327. // The EditMnClick procedure makes sure that the proper menu items in the Edit
  328. // menu are enabled. For example, when we are in Multidisk mode, the Update,
  329. // Delete and UpdateZIPDate commands cannot be used.
  330. //
  331. void __fastcall TMainFormFm::EditMnClick(TObject *Sender)
  332. {
  333.   EditAddMn->Enabled = (MainXz->ZipFilename.Length() != 0) && ((MainXz->SpanMultipleDisks == xdsNever) || (FilesLb->Items->Count == 0));
  334.   EditDeleteMn->Enabled = (FilesLb->SelCount > 0) && (!MainXz->SpanMultipleDisks);
  335.   EditExtractMn->Enabled = (FilesLb->SelCount > 0);
  336.   EditUpdateMn->Enabled = (MainXz->ZipFilename.Length() != 0) && (!MainXz->SpanMultipleDisks);
  337.   EditSelectAllMn->Enabled = (FilesLb->Items->Count > 0);
  338. }
  339.  
  340. //
  341. // The EditAddMnClick procedure adds files to the currently opened archive file.
  342. // A dialog box is opened to allow the user to select the files to be added to
  343. // the archive. Files selected in the demo's main listbox are not considered.
  344. //
  345. void __fastcall TMainFormFm::EditAddMnClick(TObject *Sender)
  346. {
  347.   AddFilesDg->FileName = "";
  348.   EnableInterface(false);
  349.   // Allow user to select files to add with a dialog box.
  350.   if (AddFilesDg->Execute())
  351.   {
  352.     // Add all the files selected from the dialog box to the TXceedZip
  353.     // component's list of files to process.
  354.     MainXz->FilesToProcess = AddFilesDg->Files->Text;
  355.     StatusLb->Caption = "Adding selected files.";
  356.     // Add the files, handle return code.
  357.     if (HandleError(MainXz->Zip(), "adding", MainXz) != 2)
  358.     {
  359.       // If in Multidisk mode, tell user the add was completed (so that
  360.       // the user may understand that any further disk swapping is only
  361.       // to read the contents of the archive.
  362.       if (MainXz->SpanMultipleDisks)
  363.       {
  364.         Application->MessageBox("Add operation completed.  To test the archive, "
  365.                                 "you must close it first, then select the test "
  366.                                 "option from the file menu.", "Information", MB_OK + MB_ICONINFORMATION);
  367.  
  368.         // Update the demo's main listbox to reflect the new additions.
  369.         LoadFileList();
  370.       }
  371.     }
  372.   }
  373.   EnableInterface(true);
  374. }
  375.  
  376. //
  377. // The EditDeleteMnClick procedure takes the selected files in the demo's listbox
  378. // and instructs the TXceedZip component to delete these files from the currently
  379. // opened archive.
  380. //
  381. void __fastcall TMainFormFm::EditDeleteMnClick(TObject *Sender)
  382. {
  383.   EnableInterface(false);
  384.   // Add all the files that are selected in the demo's main listbox to the
  385.   // TXceedZip component's list of files to process. Since the main listbox
  386.   // contains a list of files already in the currently opened archive, only files
  387.   // in the archive can be selected to delete.
  388.   AssignFromLb(FilesLb, MainXz);
  389.   StatusLb->Caption = "Deleting selected files.";
  390.   // Delete the files, handle return code
  391.   HandleError(MainXz->RemoveFiles(), "deleting", MainXz);
  392.   // Update the demo's main listbox to reflect the current contents of the
  393.   // currently opened archive file.
  394.   LoadFileList();
  395.   EnableInterface(true);
  396. }
  397.  
  398. //
  399. // The EditExtractMnClick procedure takes the selected files in the demo's
  400. // listbox and instructs the TXceedZipProxy component to extract these files into the
  401. // user selected destination. A dialog box is opened to let the user select the
  402. // destination directory.
  403. //
  404. void __fastcall TMainFormFm::EditExtractMnClick(TObject *Sender)
  405. {
  406.   char Dir[260];
  407.  
  408.   GetCurrentDirectory(260, Dir);
  409.   if (FilesLb->SelCount > 0)
  410.   {
  411.     // Ask the user where to extract the files.
  412.     if (SelectDirectory (Dir, Handle))
  413.     {
  414.       EnableInterface(false);
  415.       // Add all the files that are selected in the demo's main listbox to the
  416.       // TXceedZip component's list of files to process. Since the main listbox
  417.       // contains a list of files already in the currently opened archive, only
  418.       // files in the archive can be selected to extract.
  419.       AssignFromLb(FilesLb, MainXz);
  420.       // Tell TXceedZip component where the user wants to extract the files.
  421.       MainXz->UnzipToFolder = Dir;
  422.       StatusLb->Caption = "Extracting selected files.";
  423.       //Extract the files, handle return code.
  424.       HandleError(MainXz->Unzip(), "extracting", MainXz);
  425.       // No need to update the main listbox here - contents have not changed.
  426.       EnableInterface(true);
  427.     }
  428.   }
  429. }
  430.  
  431. //
  432. // The EditUpdateMnClick procedure updates files in the currently opened archive
  433. // file. A dialog box is opened to allow the user to select files to be updated
  434. // in the archive. Update means that only files newer than those already in the
  435. // archive file will be added or replaced into the archive.
  436. //
  437. void __fastcall TMainFormFm::EditUpdateMnClick(TObject *Sender)
  438. {
  439.   AddFilesDg->FileName = "";
  440.   EnableInterface(false);
  441.   // Allow user to select files to update with a dialog box.
  442.   if (AddFilesDg->Execute())
  443.   {
  444.     // Add all the files selected from the dialog box to the TXceedZip
  445.     // component's list of files to process.
  446.     MainXz->FilesToProcess = AddFilesDg->Files->Text;
  447.     StatusLb->Caption = "Updating files.";
  448.     // Update the files, handle error
  449.     if (HandleError(MainXz->Zip(), "updating", MainXz))
  450.     {
  451.       // Update the demo's main listbox to reflect the new additions.
  452.       LoadFileList();
  453.     }
  454.   }
  455.   EnableInterface(true);
  456. }
  457.  
  458. //
  459. // The EditSelectAllMnClick procedure selects all the items in the demo's main
  460. // listbox.
  461. //
  462. void __fastcall TMainFormFm::EditSelectAllMnClick(TObject *Sender)
  463. {
  464.    SendMessage(FilesLb->Handle, LB_SELITEMRANGE, 1, (long) FilesLb->Items->Count - 1);
  465. }
  466.  
  467. void __fastcall TMainFormFm::OptionsMnClick(TObject *Sender)
  468. {
  469.   OptionsUseTempFileMn->Checked = MainXz->UseTempFile && (!MainXz->SpanMultipleDisks);
  470.   OptionsUseTempFileMn->Enabled = !MainXz->SpanMultipleDisks;
  471.   MultidiskmodeMn->Checked = MainXz->SpanMultipleDisks;
  472.   NoCompression->Checked = (MainXz->CompressionLevel == 0);
  473.   Fastestcompression->Checked = (MainXz->CompressionLevel == 1);
  474.   Normalcompression->Checked = (MainXz->CompressionLevel == 6);
  475.   Bestcompression->Checked = (MainXz->CompressionLevel == 9);
  476. }
  477.  
  478. //
  479. // The OptionsUseTempFileMnClick procedure informs the TXceedZip component
  480. // whether or not to use a temporary file when adding files.
  481. //
  482. void __fastcall TMainFormFm::OptionsUseTempFileMnClick(TObject *Sender)
  483. {
  484.   MainXz->UseTempFile = !MainXz->UseTempFile;
  485.   OptionsUseTempFileMn->Checked = MainXz->UseTempFile;
  486. }
  487.  
  488. void __fastcall TMainFormFm::MultidiskmodeMnClick(TObject *Sender)
  489. {
  490.   MainXz->SpanMultipleDisks = !MainXz->SpanMultipleDisks;
  491.   MultidiskmodeMn->Checked = !MainXz->SpanMultipleDisks;
  492. }
  493.  
  494. //
  495. // The HelpAboutMnClick option opens an about box for this demo.
  496. //
  497. void __fastcall TMainFormFm::HelpAboutMnClick(TObject *Sender)
  498. {
  499.   Application->MessageBox("Zip Manager sample application for C++Builder 3\r\n"
  500.                           "Using The Xceed Zip Compression Library 4\n\r"
  501.                           "Copyright ⌐ 1995-1999 Xceed Software Inc., all rights reserved.\n\r\n\r",
  502.                                     "Information", MB_OK | MB_ICONINFORMATION);
  503. }
  504.  
  505. //
  506. // The AbortSbClick procedure prompts the user (with a message box), if they want
  507. // to stop the current operation. This procedure is called when the user clicks
  508. // on the little stop sign in the bottom right corner of the demo's main form.
  509. //
  510. void __fastcall TMainFormFm::AbortSbClick(TObject *Sender)
  511. {
  512.   if (Application->MessageBox("Are you sure you want to abort the current process?",
  513.                               "Confirmation", MB_YESNO + MB_ICONWARNING) == IDYES)
  514.   {
  515.     MainXz->Abort = true;
  516.   }
  517. }
  518.  
  519. //
  520. // The FilesLbDrawItem procedure draws the items contained in the demo's main
  521. // listbox using the proper format. For example, the filename and path are
  522. // separated into the 1st and 7th column when being displayed. Column widths
  523. // are set according to the FilesHd header control which can be resized by
  524. // the user at runtime.
  525. //
  526. void __fastcall TMainFormFm::FilesLbDrawItem(TWinControl *Control, int Index, TRect &Rect,    TOwnerDrawState State)
  527. {
  528.     TRect R(Rect);
  529.   AnsiString FileName, ItemStr, Str;
  530.   TListBox *Ctrl = dynamic_cast<TListBox *> (Control);
  531.  
  532.     if  ((State.Contains(odGrayed)) || (State.Contains(odDisabled)))
  533.   {
  534.     Ctrl->Canvas->Font->Color = clGrayText;
  535.   }
  536.  
  537.   ItemStr = Ctrl->Items->Strings[Index];
  538.   int I = 1;
  539.  
  540.     R.Right = R.Left + FilesHd->Sections->Items[0]->Width;
  541.   ParseTab(ItemStr, I, FileName);
  542.   Ctrl->Canvas->TextRect(R, R.Left + 2, R.Top, ExtractFileName(FileName));
  543.  
  544.   R.Left = R.Right;
  545.     R.Right = R.Left + FilesHd->Sections->Items[1]->Width;
  546.   ParseTab(ItemStr, I, Str );
  547.   Ctrl->Canvas->TextRect(R, R.Left + (R.Right - R.Left) - Ctrl->Canvas->TextWidth(Str) - 2, R.Top, Str);
  548.  
  549.   R.Left = R.Right;
  550.     R.Right = R.Left + FilesHd->Sections->Items[2]->Width;
  551.   ParseTab(ItemStr, I, Str);
  552.   Ctrl->Canvas->TextRect(R, R.Left + (R.Right - R.Left) - Ctrl->Canvas->TextWidth(Str) - 2, R.Top, Str);
  553.  
  554.   R.Left = R.Right;
  555.     R.Right = R.Left + FilesHd->Sections->Items[3]->Width;
  556.   ParseTab(ItemStr, I, Str);
  557.   Ctrl->Canvas->TextRect(R, R.Left + (R.Right - R.Left) - Ctrl->Canvas->TextWidth(Str) - 2, R.Top, Str);
  558.  
  559.   R.Left = R.Right;
  560.     R.Right = R.Left + FilesHd->Sections->Items[4]->Width;
  561.     ParseTab(ItemStr, I, Str);
  562.   Ctrl->Canvas->TextRect(R, R.Left + (R.Right - R.Left) - Ctrl->Canvas->TextWidth(Str) - 2, R.Top, Str);
  563.  
  564.   R.Left = R.Right;
  565.     R.Right = R.Left + FilesHd->Sections->Items[5]->Width;
  566.   ParseTab(ItemStr, I, Str);
  567.   Ctrl->Canvas->TextRect(R, R.Left + (((R.Right - R.Left) - Ctrl->Canvas->TextWidth(Str)) / 2), R.Top, Str);
  568.  
  569.   R.Left = R.Right;
  570.   R.Right = Rect.Right;
  571.   Ctrl->Canvas->TextRect(R, R.Left + 2, R.Top, ExtractFilePath(FileName));
  572. }
  573.  
  574. void __fastcall TMainFormFm::FilesLbMeasureItem(TWinControl *Control, int Index,    int &Height)
  575. {
  576.   Height = FilesLb->Canvas->TextHeight("W");
  577. }
  578.  
  579. //
  580. // MainXz events
  581. //
  582.  
  583. //
  584. // See the note for the MainXzDeleting procedure/handler, because this handler is
  585. // identical except for replacing Deleting with Fixing.
  586. //
  587. void __fastcall TMainFormFm::FastestcompressionClick(TObject *Sender)
  588. {
  589.   MainXz->CompressionLevel = 1;
  590. }
  591.  
  592. void __fastcall TMainFormFm::NormalcompressionClick(TObject *Sender)
  593. {
  594.   MainXz->CompressionLevel = 6;
  595. }
  596.  
  597. void __fastcall TMainFormFm::BestcompressionClick(TObject *Sender)
  598. {
  599.   MainXz->CompressionLevel = 9;
  600. }
  601.  
  602. void __fastcall TMainFormFm::NoCompressionClick(TObject *Sender)
  603. {
  604.   MainXz->CompressionLevel = 0;
  605. }
  606.  
  607. void __fastcall TMainFormFm::FilesHdSectionResize(THeaderControl *HeaderControl, THeaderSection *Section)
  608. {
  609.     FilesLb->Refresh();
  610. }
  611.  
  612. void __fastcall TMainFormFm::SetSfxConfiguration ()
  613. {
  614.   /* The SfxExtractDirectory property should contain the path where files
  615.      will be extracted to by default.
  616.  
  617.      The following variables are available when specifying
  618.      a value for SfxExtractDirectory:
  619.  
  620.       %W = The location of the Windows Directory
  621.       %S = The location of the Windows System directory
  622.       %e = The directory where the self-extractor is being run from.
  623.       %% = The '%' symbol. */
  624.  
  625.   MainXz->SfxDefaultUnzipToFolder = "%e";
  626.  
  627.   /* The SfxReadmePath should contain the path and filename of a text file
  628.      to display after extracting files. */
  629.  
  630.   MainXz->SfxReadmeFile = "";
  631.  
  632.   /* The SfxRunExePath property should contain the path and filename of an
  633.      executable to run after succesfully extracting all the files. This
  634.      property also should contain the parameters the executable.
  635.  
  636.      The following variables are available when specifying
  637.      a value for RunExePath:
  638.  
  639.       %d = The DefaultExtractDir, or the user-selected
  640.            directory where files were extracted.
  641.       %W = The location of the Windoes Directory
  642.       %S = The location of the Windows System directory
  643.       %e = The directory where the self-extractor is
  644.            being run from.
  645.       %% = The '%' symbol. */
  646.  
  647.   MainXz->SfxExecuteAfter = "";
  648.  
  649.   /* Default password to be used by self-extractor to extract files */
  650.   MainXz->SfxDefaultPassword = "";
  651.  
  652.   /* Default overwrite behavior (Ask, Never, Always) */
  653.   MainXz->SfxExistingFileBehavior = xseAsk;
  654. }
  655.  
  656. //
  657. // The MainXzFileStatus procedure is a handler for the OnFileStatus event
  658. // generated by the TXceedZip component whenever a new file is going to be
  659. // added to an archive. This particular handler simply displays which file is
  660. // being added into the demo's status label, and resets the progress bar to
  661. // 0%.
  662. //
  663. void __fastcall TMainFormFm::MainXzFileStatus(TObject *Sender,
  664.       BSTR sFilename, long lSize, long lCompressedSize,
  665.       long lBytesProcessed, short nBytesPercent, short nCompressionRatio,
  666.       VARIANT_BOOL bFileCompleted)
  667. {
  668.   if( MainXz->CurrentOperation == xcoZipping )
  669.   {
  670.     StatusLb->Caption = WideString( "Adding '" ) + sFilename + "'.";
  671.     ProgressBar1->Position = 0;
  672.   }
  673.   if (MainXz->CurrentOperation == xcoUnzipping)
  674.   {
  675.     StatusLb->Caption = WideString( "Extracting '" ) + sFilename + "'.";
  676.     ProgressBar1->Position = 0;
  677.   }
  678.   if (MainXz->CurrentOperation == xcoTestingZipFile)
  679.   {
  680.     StatusLb->Caption = WideString( "Testing '" ) + sFilename + "'.";
  681.     ProgressBar1->Position = 0;
  682.   }
  683. }
  684.  
  685. //
  686. // The MainXzRemovingFile procedure is a handler for the OnRemovingFile event
  687. // generated by the TXceedZipProxy component whenever a file is being deleted
  688. // from an archive. This particular handler simply displays which file is
  689. // being deleted into the demo's status label, and resets the progress bar to
  690. // 0%. Note: The progress bar will not be updated beyond 0% during the delete
  691. // operation because the delete operation does not generate OnStatus events.*/
  692. //
  693. void __fastcall TMainFormFm::MainXzRemovingFile(TObject *Sender,
  694.       BSTR sFilename, BSTR sComment, long lSize, long lCompressedSize,
  695.       xcdFileAttributes xAttributes, long lCRC, DATE dtLastModified,
  696.       DATE dtLastAccessed, DATE dtCreated, xcdCompressionMethod xMethod,
  697.       VARIANT_BOOL bEncrypted)
  698. {
  699.  
  700.   StatusLb->Caption = WideString("Deleting '")+ sFilename + "'.";
  701.   ProgressBar1->Position = 0;
  702. }
  703.  
  704. //
  705. // The MainXzListingFile procedure is an event handler for the OnListingFile
  706. // event generated by the TXceedZipProxy component because the ListZipContents
  707. // method was called to list files in an archive. This particular handler here
  708. // takes information of each file and adds it to the demo's main listbox.
  709. // No more than 64000 bytes of files and file information will be added to the
  710. // listbox.
  711. //
  712. void __fastcall TMainFormFm::MainXzListingFile(TObject *Sender,
  713.       BSTR sFilename, BSTR sComment, long lSize, long lCompressedSize,
  714.       short nCompressionRatio, xcdFileAttributes xAttributes, long lCRC,
  715.       DATE dtLastModified, DATE dtLastAccessed, DATE dtCreated,
  716.       xcdCompressionMethod xMethod, VARIANT_BOOL bEncrypted,
  717.       long lDiskNumber, VARIANT_BOOL bExcluded, xcdSkippingReason xReason)
  718. {
  719.   AnsiString NewListBoxData;
  720.  
  721.   if( xAttributes & xfaFolder )
  722.   {
  723.     NewListBoxData = "<Folder>\t" +
  724.                      TDateTime(dtLastModified).DateString() + "\t" +
  725.                      TDateTime(dtLastModified).TimeString() + "\t" +
  726.                      FloatToStrF(lSize, ffNumber, 10, 0) + "\t" +
  727.                      FloatToStrF(lCompressedSize, ffNumber, 10, 0) + "\t" +
  728.                      IntToStr(nCompressionRatio) + "%";
  729.   }
  730.   else
  731.   {
  732.     NewListBoxData = WideString(sFilename) + "\t" +
  733.                      TDateTime(dtLastModified).DateString() + "\t" +
  734.                      TDateTime(dtLastModified).TimeString() + "\t" +
  735.                      FloatToStrF(lSize, ffNumber, 10, 0) + "\t" +
  736.                      FloatToStrF(lCompressedSize, ffNumber, 10, 0) + "\t" +
  737.                      IntToStr(nCompressionRatio) + "%";
  738.   }
  739.  
  740.   if (FilesLbBytes < 64000)
  741.   {
  742.     FilesLb->Items->Add(NewListBoxData);
  743.     FilesLbBytes = FilesLbBytes + NewListBoxData.Length();
  744.   }
  745.  
  746.   if (ProgressBar1->Max > 100)
  747.   {
  748.     ProgressBar1->Position++;
  749.   }
  750.  
  751.   TotalSize = TotalSize + lCompressedSize;
  752.   TotalZipSize = TotalZipSize + nCompressionRatio;
  753. }
  754.  
  755. //
  756. // The following procedure handles the OnInsertdisk event, which occurs when
  757. // multidisk mode is activated and the component requires another disk to
  758. // be inserted. This procedure simply informs the user to insert the right
  759. // disk (depending on the lDisknumber parameter, and waits for the user to
  760. // press OK...
  761. //
  762. void __fastcall TMainFormFm::MainXzInsertDisk(TObject *Sender,
  763.       long lDiskNumber, VARIANT_BOOL *bDiskInserted)
  764. {
  765.  
  766.   int response;
  767.   AnsiString msg;
  768.  
  769.   if (lDiskNumber == 0)
  770.   {
  771.       msg = "Please insert the last disk of the set.";
  772.   }
  773.   else
  774.   {
  775.       msg = "Please insert disk #" + AnsiString(lDiskNumber) + " of the set.";
  776.   }
  777.   response = Application->MessageBox(msg.c_str(), "Confirmation", MB_OKCANCEL + MB_ICONQUESTION);
  778.  
  779.   if (response == IDOK)
  780.   {
  781.     *bDiskInserted = VARIANT_TRUE;
  782.   }
  783. }
  784.  
  785. //
  786. // The MainXzReplace procedure is an event handler for the OnReplace event
  787. // generated by the TXceedZip component whenever a file that is being extracted
  788. // may overwrite an already existing file. This procedure displays a message box
  789. // to allow the user to decide to skip the file or not. Notes: The Overwrite
  790. // property must be set to xowAsk for the OnReplace event to occur. Also, the
  791. // choice to rename the file could also be given, as well as the choice of always
  792. // overwriting or never overwriting. See 'OnReplace' in the online help.
  793. //
  794. void __fastcall TMainFormFm::MainXzReplacingFile(TObject *Sender,
  795.       BSTR sFilename, BSTR sComment, long lSize,
  796.       xcdFileAttributes xAttributes, DATE dtLastModified,
  797.       DATE dtLastAccessed, DATE dtCreated, BSTR sOrigFilename,
  798.       long lOrigSize, xcdFileAttributes xOrigAttributes,
  799.       DATE dtOrigLastModified, DATE dtOrigLastAccessed, DATE dtOrigCreated,
  800.       VARIANT_BOOL *bReplaceFile)
  801. {
  802.   int UserAnswer;
  803.   AnsiString msg;
  804.  
  805.   msg = WideString("The file '") + sFilename + "' already exists. Do you want to replace this file?";
  806.   UserAnswer = Application->MessageBox(msg.c_str(), "Confirmation", MB_YESNOCANCEL + MB_ICONWARNING);
  807.  
  808.   switch( UserAnswer )
  809.   {
  810.     case IDYES:
  811.       // Tell the TXceedZipProxy component to replace this file.
  812.       *bReplaceFile = VARIANT_TRUE;
  813.       break;
  814.  
  815.     case IDNO:
  816.       // Tell the TXceedZipProxy component to skip this file.
  817.       *bReplaceFile = VARIANT_FALSE;
  818.       break;
  819.  
  820.     default:
  821.       // Tell the XceedZip component to stop the entire operation. }
  822.       MainXz->Abort = true;
  823.   }
  824. }
  825.  
  826. //
  827. // The MainXzSkipping procedure is an event handler for the TXceedZip component's
  828. // OnSkippingFile event. A message box is displayed to inform the user that a
  829. // file is being skipped. The reason why is also indicated.
  830. //
  831. void __fastcall TMainFormFm::MainXzSkippingFile(TObject *Sender,
  832.       BSTR sFilename, BSTR sComment, BSTR sFilenameOnDisk, long lSize,
  833.       long lCompressedSize, xcdFileAttributes xAttributes, long lCRC,
  834.       DATE dtLastModified, DATE dtLastAccessed, DATE dtCreated,
  835.       xcdCompressionMethod xMethod, VARIANT_BOOL bEncrypted,
  836.       xcdSkippingReason xReason)
  837. {
  838.   AnsiString SkipMsg;
  839.  
  840.   if (!Testing)
  841.   {
  842.     SkipMsg = WideString("Skipping '") + sFilename + "', ";
  843.   }
  844.   else
  845.   {
  846.     SkipMsg = WideString("File '") + sFilename + "' failed test: ";
  847.   }
  848.  
  849.   switch (xcdSkippingReason(xReason))
  850.   {
  851.       case xsrInvalidCRC:
  852.       SkipMsg = SkipMsg + "CRC does not check out.";
  853.       break;
  854.       case xsrSkipOlderDate:
  855.       SkipMsg = SkipMsg + "file is already up to date.";
  856.       break;
  857.       case xsrInvalidPassword:
  858.       SkipMsg = SkipMsg + "invalid or no password to decrypt file.";
  859.       break;
  860.       case xsrSkipExisting:
  861.       SkipMsg = SkipMsg + "instructed not to overwrite.";
  862.       break;
  863.   }
  864.   Application->MessageBox(SkipMsg.c_str(), "Warning", MB_OK + MB_ICONWARNING);
  865.  
  866.   ProgressBar1->Position = 0;
  867. }
  868.  
  869. void __fastcall TMainFormFm::MainXzGlobalStatus(TObject *Sender,
  870.       long lFilesTotal, long lFilesProcessed, long lFilesSkipped,
  871.       short nFilesPercent, long lBytesTotal, long lBytesProcessed,
  872.       long lBytesSkipped, short nBytesPercent, long lBytesOutput,
  873.       short nCompressionRatio)
  874. {
  875.     ProgressBar1->Position = nBytesPercent;
  876. }
  877.  
  878. void __fastcall TMainFormFm::FileFixMnClick(TObject *Sender)
  879. {
  880.   xcdError Err;
  881.  
  882.   MainFormFm->OpenZipDg->Title = "Fix Archive";
  883.   MainFormFm->OpenZipDg->FileName = "";
  884.  
  885.     EnableInterface(false);
  886.  
  887.   if (MainFormFm->OpenZipDg->Execute())
  888.   {
  889.       // Tell the TXceedZip component which archive file to work with. }
  890.     MainFormFm->MainXz->ZipFilename = MainFormFm->OpenZipDg->FileName;
  891.  
  892.     // Call the Fix method (aggressive = True, set Err to the return value. }
  893.     Err = MainFormFm->MainXz->Convert(MainXz->ZipFilename);
  894.  
  895.     // Since we are fixing, Err=XcdSuccess means the archive has been fixed. }
  896.     if (Err == xerSuccess)
  897.     {
  898.          Application->MessageBox("The specified Zip file has been fixed.", "Information", MB_OK + MB_ICONINFORMATION);
  899.     }
  900.     else
  901.     {
  902.         if (Err == xerNotAZipFile)
  903.         {
  904.              Application->MessageBox("The specified Zip file is too corrupted to be fixed.", "Information", MB_OK + MB_ICONINFORMATION);
  905.         }
  906.       else
  907.         {
  908.           // Some other error, pass it to the error handling routine.
  909.         HandleError(Err, "fixing", MainXz);
  910.  
  911.         MainFormFm->MainXz->ZipFilename = "";
  912.         }
  913.     }
  914.   }
  915.   EnableInterface(true);
  916. }
  917.  
  918.