home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedEncoding.Cab / F112897_unManager.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-05-11  |  40.5 KB  |  1,051 lines

  1. {* Xceed Binary Encoding Library - Encoding Manager sample
  2.    Copyright (c) 2001 Xceed Software Inc.
  3.  
  4.    [unManager.pas]
  5.  
  6.    This sample demonstrates how to encode a file using different kinds
  7.    of encoding methods, and decode an encoded file. It specifically uses:
  8.       - The ProcessFile method.
  9.       - The EndOfLineType, MaxLineLength, ContinueOnInvalidData,
  10.         HeaderDataForkLen, HeaderResourceForkLen, HeaderFilename, EncodingFormat
  11.         and DataFormating propeties.
  12.  
  13.    This file is part of the Xceed Binary Encoding Library sample applications.
  14.    The source code in this file is only intended as a supplement to Xceed
  15.    Binary Encoding Library's documentation, and is provided "as is", without
  16.    warranty of any kind, either expressed or implied. *}
  17.  
  18. unit unManager;
  19.  
  20. interface
  21.  
  22. uses
  23.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  24.   StdCtrls, ComCtrls, ExtCtrls, OleCtrls, FileCtrl, ShlObj, ActiveX,
  25.   XCEEDBINARYENCODINGLib_TLB;
  26.  
  27.  
  28. {* The different encoding methods corresponding to the option buttons (the same
  29.    for the Decode and Encode tabs) *}
  30. type TEncodingMethod = ( emUUEncode,        //0
  31.                          emXXEncode,        //1
  32.                          emBase64,          //2
  33.                          emHexaDecimal,     //3
  34.                          emQuotedPrintable, //4
  35.                          emBinHex );        //5
  36.  
  37. type
  38.   TfrmManager = class(TForm)
  39.     xBinEncode          : TXceedBinaryEncoding;
  40.     pgMain              : TPageControl;
  41.     tabEncode           : TTabSheet;
  42.     tabDecode           : TTabSheet;
  43.     Label1              : TLabel;
  44.     Label2              : TLabel;
  45.     Label3              : TLabel;
  46.     Label4              : TLabel;
  47.     Label5              : TLabel;
  48.     Label6              : TLabel;
  49.     Label7              : TLabel;
  50.     edtEncSourceFile    : TEdit;
  51.     edtEncDestFile      : TEdit;
  52.     edtDecDestination   : TEdit;
  53.     edtDecFilename      : TEdit;
  54.     edtMaxLen           : TEdit;
  55.     btBrowseForSource   : TButton;
  56.     btBrowseForDest     : TButton;
  57.     btEncode            : TButton;
  58.     btAddFile           : TButton;
  59.     btRemoveFile        : TButton;
  60.     btClear             : TButton;
  61.     btBrowseForDecDest  : TButton;
  62.     btDecode            : TButton;
  63.     rgMethod            : TRadioGroup;
  64.     rgLineTypeOptions   : TRadioGroup;
  65.     grpDecode           : TGroupBox;
  66.     grpEncOptions       : TGroupBox;
  67.     lstEncodedFile      : TListBox;
  68.     lstMessages         : TListBox;
  69.     chkInvalidData      : TCheckBox;
  70.     xOpenDialog         : TOpenDialog;
  71.  
  72.     procedure FormCreate              (Sender: TObject);
  73.     procedure btBrowseForSourceClick  (Sender: TObject);
  74.     procedure btBrowseForDestClick    (Sender: TObject);
  75.     procedure rgMethodClick           (Sender: TObject);
  76.     procedure btEncodeClick           (Sender: TObject);
  77.     procedure rgLineTypeOptionsClick  (Sender: TObject);
  78.     procedure edtMaxLenChange         (Sender: TObject);
  79.     procedure chkInvalidDataClick     (Sender: TObject);
  80.     procedure btClearClick            (Sender: TObject);
  81.     procedure btBrowseForDecDestClick (Sender: TObject);
  82.     procedure btRemoveFileClick       (Sender: TObject);
  83.     procedure btDecodeClick           (Sender: TObject);
  84.     procedure btAddFileClick          (Sender: TObject);
  85.     procedure edtEncSourceFileExit    (Sender: TObject);
  86.   private
  87.     //The values chosen by the user that will be used throughout this sample
  88.     m_lMaxLineLength         : longint;
  89.     m_eEndOfLineType         : EXBEndOfLineType;
  90.     m_bContinueOnInvalidData : boolean;
  91.  
  92.     //The Encoding and Decoding method that will be used
  93.     m_eEncodingMethod        : TEncodingMethod;
  94.     m_eDecodingMethod        : TEncodingMethod;
  95.  
  96.     procedure SetDestinationFileExtension( eOldEncodingMethod : TEncodingMethod;
  97.                                            eNewEncodingMethod : TEncodingMethod );
  98.     procedure SetDestinationFilename();
  99.     procedure AddEncodedFileToList( sFilename : string );
  100.  
  101.     function ExtractFilename     ( sFilename : string ) : string;
  102.     function ExtractFolder       ( sFilename : string ) : string;
  103.     function ExtractFileExtension( sFilename : string ) : string;
  104.     function RemoveFileExtension ( sFilename : string ) : string;
  105.     function StdFileExtension    ( eMethod   : TEncodingMethod ) : string;
  106.  
  107.     function EncodeFile ( sSourceFilename  : string;
  108.                           eMethod          : TEncodingMethod;
  109.                           eEndOfLineType   : EXBEndOfLineType;
  110.                           lMaxLineLength   : longint;
  111.                           sEncodedFilename : string ) : boolean;
  112.  
  113.     function DecodeFile ( var slEncodedFile      : TStringList;
  114.                           nNbEncodedFile         : integer;
  115.                           eMethod                : TEncodingMethod;
  116.                           bContinueOnInvalidData : boolean;
  117.                           sDecodeFolder          : string;
  118.                           sDecodedFilename       : string ) : boolean;
  119.  
  120.     function BrowseFolder  ( hWnd : integer; var sFolder : string;
  121.                              const sDesc : string ) : boolean;
  122.  
  123.  
  124.   public
  125.     { Public declarations }
  126.   end;
  127.  
  128. var
  129.   frmManager: TfrmManager;
  130.  
  131. implementation
  132.  
  133. {$R *.DFM}
  134. {***************************************************************}
  135. {             ***** XCEED PRIVATE PROCEDURES *****              }
  136. {***************************************************************}
  137.  
  138. {---------------------------------------------------------------}
  139. { If a destination file name already exists for encoding,       }
  140. { change it's extension for a new one appropriate  to the new   }
  141. { encoding method.                                              }
  142. {---------------------------------------------------------------}
  143. procedure TFrmManager.SetDestinationFileExtension( eOldEncodingMethod : TEncodingMethod;
  144.                                                    eNewEncodingMethod : TEncodingMethod );
  145. var
  146.   sDestinationFile          : string;
  147.   sDestinationFileExtension : string;
  148.   bChangedExtension         : boolean;
  149. begin
  150.   bChangedExtension := false;
  151.   sDestinationFile := edtEncDestFile.Text;
  152.   sDestinationFileExtension := UpperCase( ExtractFileExtension( sDestinationFile ) );
  153.  
  154.   // If there is a destination file, we verify if its extension corresponds to the
  155.   // old encoding method. If it corresponds or if there is no extension, we set
  156.   // the flag that will do the change of extension below
  157.   if ( Length( sDestinationFile ) <> 0 ) then
  158.   begin
  159.     case eOldEncodingMethod of
  160.       emUUEncode         : if ( sDestinationFileExtension = 'UUE' ) or
  161.                               ( Length( sDestinationFileExtension ) = 0 ) then
  162.                                bChangedExtension := true;
  163.  
  164.       emXXEncode         : if ( sDestinationFileExtension = 'XXE' ) or
  165.                               ( Length( sDestinationFileExtension ) = 0 ) then
  166.                                bChangedExtension := true;
  167.  
  168.       emBase64           : if ( sDestinationFileExtension = 'B64' ) or
  169.                               ( Length( sDestinationFileExtension ) = 0 ) then
  170.                                bChangedExtension := true;
  171.  
  172.       emHexadecimal      : if ( sDestinationFileExtension = 'HEX' ) or
  173.                               ( Length( sDestinationFileExtension ) = 0 ) then
  174.                                bChangedExtension := true;
  175.  
  176.       emQuotedPrintable  : if ( sDestinationFileExtension = 'QPR' ) or
  177.                               ( Length( sDestinationFileExtension ) = 0 ) then
  178.                                bChangedExtension := true;
  179.  
  180.       emBinHex           : if ( sDestinationFileExtension = 'HQX' ) or
  181.                               ( Length( sDestinationFileExtension ) = 0 ) then
  182.                                bChangedExtension := true;
  183.     end;
  184.  
  185.     // If we determined above that a change of extension is in order. Do it
  186.     if bChangedExtension then
  187.     begin
  188.       sDestinationFile := RemoveFileExtension( sDestinationFile ) +
  189.                           StdFileExtension( eNewEncodingMethod );
  190.       edtEncDestFile.Text := sDestinationFile;
  191.     end;
  192.   end;
  193. end;
  194.  
  195. {---------------------------------------------------------------}
  196. { Set a default destination file name used for the encoding     }
  197. { process. This file name is derived from the source file name  }
  198. { If a destination file name is already specified, do nothing.  }
  199. {---------------------------------------------------------------}
  200. procedure TFrmManager.SetDestinationFilename();
  201. var
  202.   sEncodedFilename : string;
  203. begin
  204.   sEncodedFilename := edtEncDestFile.Text;
  205.   if ( Length( sEncodedFilename ) = 0 ) then
  206.   begin
  207.     sEncodedFilename := RemoveFileExtension( edtEncSourceFile.Text );
  208.  
  209.     if ( Length( sEncodedFilename ) <> 0 ) then
  210.     begin
  211.       edtEncDestFile.Text := sEncodedFilename;
  212.       SetDestinationFileExtension( m_eEncodingMethod, m_eEncodingMethod );
  213.     end;
  214.   end;
  215. end;
  216.  
  217. {---------------------------------------------------------------}
  218. { Add the specified file name to the list box of the file names }
  219. { to decode                                                     }
  220. {---------------------------------------------------------------}
  221. procedure TFrmManager.AddEncodedFileToList( sFilename : string );
  222. var
  223.   i             : integer;
  224.   bFound        : boolean;
  225.   nNbItem       : integer;
  226.   sDecodeFolder : string;
  227.   sExtension    : string;
  228. begin
  229.   nNbItem := lstEncodedFile.Items.Count;
  230.   bFound := false;
  231.  
  232.   // Do not allow more than 1000 files to be decoded at one time
  233.   if ( nNbItem < 1000 ) then
  234.   begin
  235.     for i := 0 to ( nNbItem - 1 ) do
  236.     begin
  237.       // Check if the file is already in the list of files
  238.       if ( lstEncodedFile.Items.Strings[ i ] = sFilename ) then
  239.       begin
  240.         bFound := true;
  241.         break;
  242.       end;
  243.     end;
  244.  
  245.     if not bFound then
  246.     begin
  247.       // add the file name to the list
  248.       lstEncodedFile.Items.Add( sFilename );
  249.  
  250.       // if no decode folder is specified, set one to the folder name of the added file name.
  251.       sDecodeFolder := edtDecDestination.Text;
  252.  
  253.       if ( Length( sDecodeFolder ) = 0 ) then
  254.       begin
  255.         sDecodeFolder := ExtractFolder( sFilename );
  256.  
  257.         if ( Length( sDecodeFolder ) <> 0 ) then
  258.           edtDecDestination.Text := sDecodeFolder;
  259.       end;
  260.  
  261.       // If it's the first file added to the list, select it in the list
  262.       if ( nNbItem = 0 ) then
  263.         lstEncodedFile.ItemIndex := 0;
  264.  
  265.       / /Set the decoding method according to the file name extension
  266.       sExtension :=  UpperCase( Copy( sFilename, Length( sFilename ) - 3, 4 ) );
  267.  
  268.       if ( sExtension = '.UUE' ) then
  269.       begin
  270.         m_eDecodingMethod := emUUEncode;
  271.         rgMethod.ItemIndex := 0;
  272.       end;
  273.  
  274.       if ( sExtension = '.XXE' ) then
  275.       begin
  276.         m_eDecodingMethod := emXXEncode;
  277.         rgMethod.ItemIndex := 1;
  278.       end;
  279.  
  280.       if ( sExtension = '.B64' ) then
  281.       begin
  282.         m_eDecodingMethod := emBase64;
  283.         rgMethod.ItemIndex := 2;
  284.       end;
  285.  
  286.       if ( sExtension = '.HEX' ) then
  287.       begin
  288.         m_eDecodingMethod := emHexaDecimal;
  289.         rgMethod.ItemIndex := 3;
  290.       end;
  291.  
  292.       if ( sExtension = '.QPR' ) then
  293.       begin
  294.         m_eDecodingMethod := emQuotedPrintable;
  295.         rgMethod.ItemIndex := 4;
  296.       end;
  297.  
  298.       if ( sExtension = '.HQX' ) then
  299.       begin
  300.         m_eDecodingMethod := emBinHex;
  301.         rgMethod.ItemIndex := 5;
  302.       end;
  303.     end;
  304.   end;
  305. end;
  306.  
  307. {***************************************************************}
  308. {             ***** XCEED PRIVATE FUNCTIONS *****               }
  309. {***************************************************************}
  310.  
  311. {---------------------------------------------------------------}
  312. { Return the file name part from a "path and file name" string  }
  313. {---------------------------------------------------------------}
  314. function TFrmManager.ExtractFilename( sFilename : string ) : string;
  315. var
  316.   i            : integer;
  317.   nFilenameLen : integer;
  318.   nLenToRemove : integer;
  319. begin
  320.   nFilenameLen := Length( sFilename );
  321.   i := nFilenameLen;
  322.   nLenToRemove := -1;
  323.  
  324.   // Starting from the end of the string, we check each character and stop
  325.   // at the first occurence of \ or :
  326.   while ( i > 0 ) and ( nLenToRemove = -1 ) do
  327.   begin
  328.     // The length of the file name part is the length of the string
  329.     // minus the position of the \ or :
  330.     if ( copy( sFilename, i, 1 ) =  '\' )  or ( copy( sFilename, i, 1 ) = ':' ) then
  331.       nLenToRemove := nFilenameLen - i;
  332.     i := i - 1
  333.   end;
  334.  
  335.   // No \ or : were present. We assume that the string was a file name and
  336.   // we return it
  337.   if ( nLenToRemove = -1 ) then
  338.     ExtractFilename := sFilename
  339.   else
  340.     // We return the right part of the string corresponding to the file name
  341.     ExtractFilename := copy( sFilename, Length( sFilename ) - nLenToRemove + 1,
  342.                              nLenToRemove );
  343. end;
  344.  
  345. {---------------------------------------------------------------}
  346. { Return the folder part from a "path and file name" string     }
  347. { excluding any terminating \                                   }
  348. {---------------------------------------------------------------}
  349. function TFrmManager.ExtractFolder( sFilename : string ) : string;
  350. var
  351.   i            : integer;
  352.   nFilenameLen : integer;
  353.   nLenToRemove : integer;
  354. begin
  355.   nFilenameLen := Length( sFilename );
  356.   i := nFilenameLen;
  357.   nlenToRemove := -1;
  358.  
  359.   // Starting from the end of the string, we check each character and stop
  360.   // at the first occurence of \ or :
  361.   while ( i > 0 ) and ( nLenToRemove = -1 ) do
  362.   begin
  363.     // The length of the folder name part is the position of the \ minus 1
  364.     // (to exclude the \)
  365.     if ( copy( sFilename, i, 1 ) = '\' ) then
  366.       nLenToRemove := i - 1;
  367.     // The length of the folder name part is the same as the position of the :
  368.     if ( copy( sFilename, i, 1 ) = ':' ) then
  369.       nLenToRemove := i;
  370.  
  371.     i := i - 1;
  372.   end;
  373.  
  374.   if ( nLenToRemove = -1 ) then
  375.     // The string contains no folder. We return an empty string
  376.     ExtractFolder := ''
  377.   else
  378.     // Return the left part of the string corresponding to the folder name
  379.     ExtractFolder := copy( sFilename, 1, nLenToRemove )
  380. end;
  381.  
  382. {---------------------------------------------------------------}
  383. { Return the extension part of a specified file name            }
  384. {---------------------------------------------------------------}
  385. function TFrmManager.ExtractFileExtension( sFilename : string ) : string;
  386. var
  387.   i            : integer;
  388.   nFilenameLen : integer;
  389.   nLenToRemove : integer;
  390. begin
  391.   nFilenameLen := Length( sFilename );
  392.   i := nFilenameLen;
  393.   nLenToRemove := -1;
  394.  
  395.   // Starting from the end of the string, we check each character and stop
  396.   // at the first occurence of . or \
  397.   while ( i > 0 ) and ( nLenToRemove = -1 ) do
  398.   begin
  399.     // The length of the extension part is the length of the string
  400.     // minus the position of the .
  401.     if ( copy( sFilename, i, 1 ) = '.' ) then
  402.       nLenToRemove := nFilenameLen - i;
  403.  
  404.     // No extension was found. We will return an empty string
  405.     if ( copy( sFilename, i, 1 ) = '\' ) then
  406.       nLenToRemove := 0;
  407.  
  408.     i := i - 1;
  409.   end;
  410.  
  411.   // No extension was found. We return an empty string
  412.   if ( nLenToRemove = -1 ) then
  413.     ExtractFileExtension := ''
  414.   else
  415.     ExtractFileExtension := copy( sFilename, Length( sFilename ) - nLenToRemove + 1,
  416.                                   nLenToRemove )
  417. end;
  418.  
  419. {---------------------------------------------------------------}
  420. { Return the specified file name WITHOUT its extension, if any  }
  421. {---------------------------------------------------------------}
  422. function TFrmManager.RemoveFileExtension( sFilename : string ) : string;
  423. var
  424.   i            : integer;
  425.   nFilenameLen : integer;
  426.   nLenToRemove : integer;
  427. begin
  428.   nFilenameLen := Length( sFilename );
  429.   i := nFilenameLen;
  430.   nLenToRemove := -1;
  431.  
  432.   // Starting from the end of the string, we check each character and stop
  433.   // at the first occurence of . or \
  434.   while ( i > 0 ) and ( nLenToRemove = -1 ) do
  435.   begin
  436.     // The length of the filename name part is the position of the . minus 1
  437.     // (to exclude the .)
  438.     if ( copy( sFilename, i, 1 ) = '.' ) then
  439.       nLenToRemove := i - 1;
  440.     // The file name contains a path. Returns all the string
  441.     if ( copy( sFilename, i, 1 ) = '\' ) then
  442.       nLenToRemove := nFilenameLen;
  443.  
  444.     i := i - 1;
  445.   end;
  446.  
  447.   // No extension was found return an empty string
  448.   if ( nLenToRemove = -1 ) then
  449.     RemoveFileExtension := ''
  450.   else
  451.     RemoveFileExtension := copy( sFilename, 1, nLenToRemove );
  452. end;
  453.  
  454. {---------------------------------------------------------------}
  455. { Return the extension associated with the specified encoding   }
  456. { method                                                        }
  457. {---------------------------------------------------------------}
  458. function TFrmManager.StdFileExtension( eMethod : TEncodingMethod ) : string;
  459. begin
  460.   StdFileExtension := '';
  461.  
  462.   case eMethod of
  463.     emUUEncode         : StdFileExtension := '.uue';
  464.     emXXEncode         : StdFileExtension := '.xxe';
  465.     emBase64           : StdFileExtension := '.b64';
  466.     emHexadecimal      : StdFileExtension := '.hex';
  467.     emQuotedPrintable  : StdFileExtension := '.qpr';
  468.     emBinHex           : StdFileExtension := '.hqx';
  469.   end;
  470. end;
  471.  
  472. {---------------------------------------------------------------}
  473. { Encode the File!                                              }
  474. {---------------------------------------------------------------}
  475. function TFrmManager.EncodeFile( sSourceFilename  : string;
  476.                                  eMethod          : TEncodingMethod;
  477.                                  eEndOfLineType   : EXBEndOfLineType;
  478.                                  lMaxLineLength   : longint;
  479.                                  sEncodedFilename : string ) : boolean;
  480. var
  481.   vaBytesRead  : OleVariant;
  482.   hFileHandle  : hFile;
  483.  
  484.   xUUEncoding              : XceedUUEncodingFormat;
  485.   xXXEncoding              : XceedXXEncodingFormat;
  486.   xBase64Encoding          : XceedBase64EncodingFormat;
  487.   xHexaEncoding            : XceedHexaEncodingFormat;
  488.   xQuotedPrintableEncoding : XceedQuotedPrintableEncodingFormat;
  489.   xBinHexEncoding          : XceedBinHexEncodingFormat;
  490. begin
  491.   EncodeFile := false;
  492.   Screen.Cursor := crHourGlass;
  493.  
  494.   // Create and prepare the encoding format (XX, UU, BinHex, ...) we also
  495.   // Set the End of line type and the Maximum line length of the chosen
  496.   // encoding format
  497.   //
  498.   case eMethod of
  499.     emUUEncode        : begin
  500.                           xUUEncoding := CoXceedUUEncodingFormat.Create();
  501.                           xUUEncoding.IncludeHeaderFooter := true;
  502.                           xUUEncoding.EndOfLineType := eEndOfLineType;
  503.                           xUUEncoding.MaxLineLength := lMaxLineLength;
  504.  
  505.                           xBinEncode.EncodingFormat := xUUEncoding;
  506.                         end;
  507.     emXXEncode        : begin
  508.                           xXXEncoding := CoXceedXXEncodingFormat.Create();
  509.                           xXXEncoding.IncludeHeaderFooter := true;
  510.                           xXXEncoding.EndOfLineType := eEndOfLineType;
  511.                           xXXEncoding.MaxLineLength := lMaxLineLength;
  512.  
  513.                           xBinEncode.EncodingFormat := xXXEncoding;
  514.                         end;
  515.     emBase64          : begin
  516.                           xBase64Encoding := CoXceedBase64EncodingFormat.Create();
  517.                           xBase64Encoding.EndOfLineType := eEndOfLineType;
  518.                           xBase64Encoding.MaxLineLength := lMaxLineLength;
  519.  
  520.                           xBinEncode.EncodingFormat := xBase64Encoding;
  521.                         end;
  522.     emHexaDecimal     : begin
  523.                           xHexaEncoding := CoXceedHexaEncodingFormat.Create();
  524.                           xHexaEncoding.EndOfLineType := eEndOfLineType;
  525.                           xHexaEncoding.MaxLineLength := lMaxLineLength;
  526.  
  527.                           xBinEncode.EncodingFormat := xHexaEncoding;
  528.                         end;
  529.     emQuotedPrintable : begin
  530.                           xQuotedPrintableEncoding := CoXceedQuotedPrintableEncodingFormat.Create();
  531.                           xQuotedPrintableEncoding.EndOfLineType := eEndOfLineType;
  532.                           xQuotedPrintableEncoding.MaxLineLength := lMaxLineLength;
  533.  
  534.                           xBinEncode.EncodingFormat := xQuotedPrintableEncoding;
  535.                         end;
  536.     emBinHex          : begin
  537.                           xBinHexEncoding := CoXceedBinHexEncodingFormat.Create();
  538.                           xBinHexEncoding.IncludeHeaderFooter := true;
  539.                           xBinHexEncoding.EndOfLineType := eEndOfLineType;
  540.                           xBinHexEncoding.MaxLineLength := lMaxLineLength;
  541.  
  542.                           // For the BinHex format, we must specify the data fork length and the
  543.                           // resource fork length
  544.                           hFileHandle := CreateFile( PChar( sSourceFilename ), GENERIC_READ,
  545.                                          FILE_SHARE_READ, nil, OPEN_EXISTING,
  546.                                          FILE_ATTRIBUTE_NORMAL, 0 );
  547.  
  548.                           xBinHexEncoding.HeaderDataForkLength := GetFileSize( hFileHandle, nil );
  549.                           CloseHandle( hFileHandle );
  550.                           xBinHexEncoding.HeaderResourceForkLength := 0;
  551.  
  552.                           xBinEncode.EncodingFormat := xBinHexEncoding;
  553.                         end;
  554.   end;
  555.  
  556.   // If no extension for the destination file name was provided by the user,
  557.   // we set a default one (according the the encoding method)
  558.   if ( Length( ExtractFileExtension( sEncodedFilename ) ) = 0 ) then
  559.     sEncodedFilename := sEncodedFilename + StdFileExtension( eMethod );
  560.  
  561.   // encode the file
  562.   lstMessages.Clear();
  563.  
  564.   try
  565.     // Encode the file, specifying that :
  566.     // We want to encode all the source file name (0,0 parameters)
  567.     // This is the end of data, no more file to encode will follow (True parameter)
  568.     // We want to overwrite a possibly existing destination file (False parameter)
  569.     xBinEncode.ProcessFile( sSourceFilename, 0, 0, bfpEncode,
  570.                             true, sEncodedFilename, false, vaBytesRead );
  571.  
  572.     // Display a message of success
  573.     lstMessages.Items.Add( sSourceFilename + ' successfully encoded in ' +
  574.                            sEncodedFilename );
  575.     EncodeFile := true;
  576.   except
  577.     on xErr : Exception do
  578.       // Display the error that occured
  579.       lstMessages.Items.Add( xErr.Message );
  580.   end;
  581.   
  582.   Screen.Cursor := crDefault;
  583. end;
  584.  
  585. {---------------------------------------------------------------}
  586. { Decode file(s)!                                               }
  587. { If more than one source file was specified by the user; they  }
  588. { will be decoded in the same destination file (showing an      }
  589. { example of the bAppend parameter).                            }
  590. {---------------------------------------------------------------}
  591. function TFrmManager.DecodeFile ( var slEncodedFile      : TStringList;
  592.                                   nNbEncodedFile         : integer;
  593.                                   eMethod                : TEncodingMethod;
  594.                                   bContinueOnInvalidData : boolean;
  595.                                   sDecodeFolder          : string;
  596.                                   sDecodedFilename       : string ) : boolean;
  597. var
  598.   i           : integer;
  599.   vaBytesRead : OleVariant;
  600.  
  601.   xUUEncoding              : XceedUUEncodingFormat;
  602.   xXXEncoding              : XceedXXEncodingFormat;
  603.   xBase64Encoding          : XceedBase64EncodingFormat;
  604.   xHexaEncoding            : XceedHexaEncodingFormat;
  605.   xQuotedPrintableEncoding : XceedQuotedPrintableEncodingFormat;
  606.   xBinHexEncoding          : XceedBinHexEncodingFormat;
  607. begin
  608.   DecodeFile := false;
  609.   Self.Cursor := crHourGlass;
  610.  
  611.   if ( copy( sDecodeFolder, Length( sDecodeFolder ) - 1, 1 ) <> '\' ) then
  612.     // The decode folder must end with a \
  613.     sDecodeFolder := sDecodeFolder + '\';
  614.  
  615.   // Create and prepare the encoding format (XX, UU, BinHex, ...) and
  616.   // tell whether or not we want to ignore invalid character in the file(s)
  617.   // to decode. If no file name was specified by the user. Read the one used by default
  618.   // by the encoding library (set at the first call).
  619.   case eMethod of
  620.   emUUEncode        : begin
  621.                         xUUEncoding := CoXceedUUEncodingFormat.Create();
  622.                         xUUEncoding.IncludeHeaderFooter := true;
  623.                         xUUEncoding.ContinueOnInvalidData := bContinueOnInvalidData;
  624.  
  625.                         if ( Length( sDecodedFilename ) = 0 ) then
  626.                           sDecodedFilename := xUUEncoding.HeaderFilename;
  627.  
  628.                         xBinEncode.EncodingFormat := xUUEncoding;
  629.                       end;
  630.   emXXEncode        : begin
  631.                         xXXEncoding := CoXceedXXEncodingFormat.Create();
  632.                         xXXEncoding.IncludeHeaderFooter := true;
  633.                         xXXEncoding.ContinueOnInvalidData := bContinueOnInvalidData;
  634.  
  635.                         if ( Length( sDecodedFilename ) = 0 ) then
  636.                           sDecodedFilename := xXXEncoding.HeaderFilename;
  637.  
  638.                         xBinEncode.EncodingFormat := xXXEncoding;
  639.                       end;
  640.   emBase64          : begin
  641.                         xBase64Encoding := CoXceedBase64EncodingFormat.Create();
  642.                         xBase64Encoding.ContinueOnInvalidData := bContinueOnInvalidData;
  643.  
  644.                         xBinEncode.EncodingFormat := xBase64Encoding;
  645.                       end;
  646.   emHexaDecimal     : begin
  647.                         xHexaEncoding := CoXceedHexaEncodingFormat.Create();
  648.                         xHexaEncoding.ContinueOnInvalidData := bContinueOnInvalidData;
  649.  
  650.                         xBinEncode.EncodingFormat := xHexaEncoding;
  651.                       end;
  652.   emQuotedPrintable : begin
  653.                         xQuotedPrintableEncoding := CoXceedQuotedPrintableEncodingFormat.Create();
  654.                         xQuotedPrintableEncoding.ContinueOnInvalidData := bContinueOnInvalidData;
  655.  
  656.                         xBinEncode.EncodingFormat := xQuotedPrintableEncoding;
  657.                       end;
  658.   emBinHex          : begin
  659.                         xBinHexEncoding := CoXceedBinHexEncodingFormat.Create();
  660.                         xBinHexEncoding.IncludeHeaderFooter := true;
  661.                         xBinHexEncoding.ContinueOnInvalidData := bContinueOnInvalidData;
  662.  
  663.                         if ( Length( sDecodedFilename ) = 0 ) then
  664.                           sDecodedFilename := xBinHexEncoding.HeaderFilename;
  665.  
  666.                         xBinEncode.EncodingFormat := xBinHexEncoding;
  667.                       end;
  668.   end;
  669.  
  670.   lstMessages.Clear();
  671.  
  672.   try
  673.     for i := 0 to nNbEncodedFile-1 do
  674.     begin
  675.       // Decode a source file, providing:
  676.       //  - The source filename, without an offset or size (since we want to
  677.       //    decode all the file).
  678.       //  - True in the bEndOfdata for the last file only.
  679.       //  - The processing we want to perform, in this case bfpDecode.
  680.       //  - The destination filename we want to decode to. For the BinHex, UUEncode,
  681.       //    and XXEncode formats, the first call can contain only a folder. The
  682.       //    filename stored in the format will be used (the FileName property of the 
  683.       //    format object).
  684.       //  - True in the bAppend parameter for all but the first file.
  685.       //  - A Variant that will receive the number of bytes read on return.
  686.       xBinEncode.ProcessFile( slEncodedFile.Strings[ i ], 0, 0, 
  687.                               bfpDecode, ( i = nNbEncodedFile - 1 ), 
  688.                               sDecodeFolder + sDecodedFilename,
  689.                               ( i > 0 ), vaBytesRead );
  690.  
  691.       //Display a message of success
  692.       lstMessages.Items.Add( slEncodedFile.Strings[ i ] + ' successfully decoded in ' +
  693.                              sDecodeFolder + sDecodedFilename );
  694.       DecodeFile := True;
  695.  
  696.     end;
  697.  
  698.   except
  699.     on xErr: Exception do
  700.       //Display the error that occured
  701.       lstMessages.Items.Add( xErr.Message );
  702.   end;
  703.  
  704.   Self.Cursor := crDefault;
  705. end;
  706.  
  707. {---------------------------------------------------------------}
  708. { Initialize folder browsing window                             }
  709. {---------------------------------------------------------------}
  710. function BrowseCallbackProc ( hWnd : HWND; nMsg : Cardinal; nParam : integer;
  711.                               pData : integer ) : integer; stdcall;
  712. var
  713.   szDir : array[0..300] of char;
  714. begin
  715.   if nMsg = BFFM_INITIALIZED then
  716.     SendMessage (hWnd, BFFM_SETSELECTION, 1, pData)
  717.   else if nMsg = BFFM_SELCHANGED then
  718.   begin
  719.     { Change the current folder label }
  720.     if (SHGetPathFromIDList (PItemIDList (nParam), szDir)) then
  721.       SendMessage (hWnd, BFFM_SETSTATUSTEXT, 0, integer (@(szDir[0])));
  722.   end;
  723.  
  724.   result := 0;
  725. end;
  726.  
  727. {---------------------------------------------------------------}
  728. { Browse for a destination folder                               }
  729. {---------------------------------------------------------------}
  730. function TFrmManager.BrowseFolder ( hWnd : integer; var sFolder : string;
  731.                                     const sDesc : string ) : boolean;
  732. var
  733.   bi      : TBrowseInfoA;
  734.   pIDList : PItemIDList;
  735.   pszBuffer : PChar;
  736. begin
  737.   pszBuffer := StrAlloc (300);
  738.  
  739.   bi.hwndOwner      := hWnd;
  740.   bi.pidlRoot       := nil;
  741.   bi.pszDisplayName := pszBuffer;
  742.   bi.lpszTitle      := PChar(sDesc);
  743.   bi.ulFlags        := BIF_RETURNONLYFSDIRS;
  744.   bi.lpfn           := BrowseCallbackProc;
  745.   bi.lParam         := LongInt(PChar(sFolder));
  746.   bi.iImage         := 0;
  747.  
  748.   result := false;
  749.   pIDList := SHBrowseForFolder (bi);
  750.  
  751.   if Assigned (pIDList) then
  752.   begin
  753.     if SHGetPathFromIDList (pIDList, pszBuffer) then
  754.     begin
  755.       sFolder := pszBuffer;
  756.       result  := true;
  757.     end;
  758.  
  759.     CoTaskMemFree (pIDList);
  760.   end;
  761.  
  762.   StrDispose (pszBuffer);
  763. end;
  764.  
  765. {***************************************************************}
  766. { PROCEDURES AND EVENTS TRIGGERED BY THE FORM AND ITS CONTROLS  }
  767. {***************************************************************}
  768.  
  769. {---------------------------------------------------------------}
  770. { Select the source folder and file name that will be encoded   }
  771. { by the encode action                                          }
  772. {---------------------------------------------------------------}
  773. procedure TfrmManager.btBrowseForSourceClick(Sender: TObject);
  774. begin
  775.   xOpenDialog.Files.Clear();
  776.   xOpenDialog.Title       := 'Source file';
  777.   xOpenDialog.Filter      := 'All type (*.*)|*.*';
  778.   xOpenDialog.FilterIndex := 0;
  779.  
  780.   // Show an Open common dialog to let the user select a file
  781.   if xOpenDialog.Execute then
  782.   begin
  783.     edtEncSourceFile.Text := trim( xOpenDialog.Files.Text );
  784.     SetDestinationFileName();
  785.   end;
  786. end;
  787.  
  788. {---------------------------------------------------------------}
  789. { Select the destination and name of the file that will be      }
  790. { created by the encode action                                  }
  791. {---------------------------------------------------------------}
  792. procedure TfrmManager.btBrowseForDestClick(Sender: TObject);
  793. begin
  794.   xOpenDialog.Files.Clear();
  795.   xOpenDialog.Title  := 'Destination file';
  796.   xOpenDialog.Filter := 'Encoded (*.uue;*.xxe;*.b64;*.hex)|' +
  797.                         '*.uue;*.xxe;*.b64;*.hex|UU encoded (*.uue)|' +
  798.                         '*.uue|XX Encoded (*.xxe)|*.xxe|Base 64 (*.b64)|' +
  799.                         '*.b64|Hexadecimal (*.hex)|*.hex|BinHex (*.hqz)|' +
  800.                         '*.hqx|Quoted Printable (*.qpr)|All Type (*.*)|*.*';
  801.   xOpenDialog.FilterIndex := 0;
  802.  
  803.   // Show an Open common dialog to let the user select the destination file name
  804.   if xOpenDialog.Execute then
  805.     edtEncDestFile.Text := xOpenDialog.Files.Text;
  806. end;
  807.  
  808. {---------------------------------------------------------------}
  809. { The user changed the selected encoding or decoding method     }
  810. {---------------------------------------------------------------}
  811. procedure TfrmManager.rgMethodClick(Sender: TObject);
  812. begin
  813.   if ( pgMain.ActivePage = tabEncode ) then
  814.   begin
  815.     // Change the extension of the destination (encoded) file name to be
  816.     // consistent with the newly selected encoding method
  817.     SetDestinationFileExtension( m_eEncodingMethod, TEncodingMethod( rgMethod.ItemIndex ) );
  818.     m_eEncodingMethod := TEncodingMethod( rgMethod.ItemIndex );
  819.   end;
  820.  
  821.   if ( pgMain.ActivePage = tabDecode ) then
  822.     // The user changed the selected Decoding method
  823.     m_eDecodingMethod := TEncodingMethod( rgMethod.ItemIndex );
  824. end;
  825.  
  826. {---------------------------------------------------------------}
  827. { Do the encoding of the selected source file name to the       }
  828. { destination file                                              }
  829. {---------------------------------------------------------------}
  830. procedure TfrmManager.btEncodeClick(Sender: TObject);
  831. begin
  832.   if ( Length( Trim( edtEncSourceFile.Text ) ) <> 0 ) then
  833.   begin
  834.     // There is something to Encode! Do the encoding
  835.     if ( EncodeFile( edtEncSourceFile.Text, m_eEncodingMethod, m_eEndOfLineType,
  836.                      m_lMaxLineLength, edtEncDestFile.Text ) ) then
  837.     begin
  838.       // The encoding was successful, we clear the source and destination text boxes.
  839.       edtEncSourceFile.Text := '';
  840.       edtEncDestFile.Text   := '';
  841.     end;
  842.   end;
  843. end;
  844.  
  845. {---------------------------------------------------------------}
  846. { Prepare the main window by assigning default values           }
  847. {---------------------------------------------------------------}
  848. procedure TfrmManager.FormCreate(Sender: TObject);
  849. begin
  850.   m_eEncodingMethod  := emUUEncode;
  851.   m_eDecodingMethod  := emUUEncode;
  852.   m_lMaxLineLength   := StrToInt( edtMaxLen.Text );
  853.   m_eEndOfLineType   := bltCrLf;
  854.  
  855.   // decoding option
  856.   m_bContinueOnInvalidData := chkInvalidData.Checked;
  857.   rgMethod.ItemIndex := 0;
  858.   lstEncodedFile.Clear();
  859. end;
  860.  
  861. {---------------------------------------------------------------}
  862. procedure TfrmManager.rgLineTypeOptionsClick(Sender: TObject);
  863. begin
  864.   case rgLineTypeOptions.ItemIndex of
  865.     0 : m_eEndOfLineType := bltCrLf;
  866.     1 : m_eEndOfLineType := bltLf;
  867.   end;
  868. end;
  869.  
  870. {---------------------------------------------------------------}
  871. procedure TfrmManager.edtMaxLenChange(Sender: TObject);
  872. begin
  873.   m_lMaxLineLength := StrToInt( edtMaxLen.Text );
  874. end;
  875.  
  876. {---------------------------------------------------------------}
  877. procedure TfrmManager.chkInvalidDataClick(Sender: TObject);
  878. begin
  879.   m_bContinueOnInvalidData := chkInvalidData.Checked;
  880. end;
  881.  
  882. {---------------------------------------------------------------}
  883. { Remove all items from the Encoded file(s) list box            }
  884. {---------------------------------------------------------------}
  885. procedure TfrmManager.btClearClick(Sender: TObject);
  886. begin
  887.   lstEncodedFile.Clear();
  888. end;
  889.  
  890. {---------------------------------------------------------------}
  891. { Select a folder that will contain the decoded files           }
  892. {---------------------------------------------------------------}
  893. procedure TfrmManager.btBrowseForDecDestClick(Sender: TObject);
  894. var
  895.   sFolder : string;
  896. begin
  897.   // By default the browse folder window will be positionned in the currently
  898.   // selected Decode folder
  899.   sFolder := edtDecDestination.Text;
  900.  
  901.   if BrowseFolder( self.Handle, sFolder, 'DecodeFolder' ) then
  902.     edtDecDestination.Text := sFolder;
  903. end;
  904.  
  905. {---------------------------------------------------------------}
  906. { Remove the selected file from the list of files to decode     }
  907. {---------------------------------------------------------------}
  908. procedure TfrmManager.btRemoveFileClick(Sender: TObject);
  909. var
  910.   nFirstItem       : integer;
  911.   nNbItemRemoved   : integer;
  912.   nNbItemsToRemove : integer;
  913.   nNbItem          : integer;
  914.   i                : integer;
  915. begin
  916.   nNbItemsToRemove := lstEncodedFile.SelCount;
  917.   nNbItemRemoved := 0;
  918.   nFirstItem := 0;
  919.  
  920.   if ( nNbItemsToRemove <> 0 ) then
  921.   begin
  922.     // Check each file in the list of files to decode and remove it if it is selected
  923.     nNbItem := lstEncodedFile.Items.Count;
  924.  
  925.     for i := nNbItem - 1 downto 0 do
  926.     begin
  927.       if ( lstEncodedFile.Selected[ i ] ) then
  928.       begin
  929.         lstEncodedFile.Items.Delete( i );
  930.         nNbItemRemoved := nNbItemRemoved + 1;
  931.         nNbItem := nNbItem - 1;
  932.  
  933.         if ( nNbItemRemoved = nNbItemsToRemove ) then
  934.         begin
  935.           // We removed the original number of files selected. We set the new item
  936.           // to select in the file list (the file that follows the last selected
  937.           // item) amd exit the loop
  938.           nFirstItem := i;
  939.           break;
  940.         end;
  941.       end;
  942.     end;
  943.  
  944.     if ( nNbItem <> 0 ) then
  945.     begin
  946.       // There is at least 1 file left in the list
  947.       if ( nFirstItem >= nNbItem ) then
  948.         // There was no file after the last one that was removed. We select the
  949.         // last file of the list
  950.         lstEncodedFile.ItemIndex := nNbItem - 1
  951.       else
  952.         lstEncodedFile.ItemIndex := nFirstItem;
  953.  
  954.     end;
  955.   end;
  956. end;
  957.  
  958. {---------------------------------------------------------------}
  959. { Do the decoding of the selected source file(s) to the         }
  960. { selected destination folder                                   }
  961. {---------------------------------------------------------------}
  962. procedure TfrmManager.btDecodeClick(Sender: TObject);
  963. var
  964.   sDecodedFilename : string;
  965.   slEncodedFile    : TStringList;
  966.   nNbEncodedFile   : integer;
  967.   i                : integer;
  968. begin
  969.   sDecodedFilename := edtDecFilename.Text;
  970.  
  971.   if ( ( Length( sDecodedFilename ) = 0 ) and ( m_eDecodingMethod <> emUUEncode )
  972.                                           and ( m_eDecodingMethod <> emXXEncode ) ) then
  973.   begin
  974.     // No decode file namw was entered by the user. Use the file name of the
  975.     // first item in the Encoded File(s) list box.
  976.     sDecodedFilename := RemoveFileExtension( ExtractFilename
  977.                                            ( lstEncodedFile.Items.Strings[ 0 ] ) ) +
  978.                                            '.bin';
  979.     if ( Length( sDecodedFilename ) <> 0 ) then
  980.       edtDecFilename.Text := sDecodedFilename;
  981.   end;
  982.  
  983.   nNbEncodedFile := lstEncodedFile.Items.Count;
  984.  
  985.   if ( nNbEncodedFile <> 0 ) then
  986.   begin
  987.     // Fill a TStringList with all the encoded file names from the listbox
  988.     slEncodedFile := TStringList.Create();
  989.  
  990.     nNbEncodedFile := nNbEncodedFile - 1;
  991.  
  992.     for i := 0 to nNbEncodedFile do
  993.       slEncodedFile.Add( lstEncodedFile.Items.Strings[ i ] );
  994.  
  995.     // Do the decoding
  996.     if ( DecodeFile( slEncodedFile, nNbEncodedFile, m_eDecodingMethod,
  997.                      m_bContinueOnInvalidData, edtDecDestination.Text,
  998.                      sDecodedFilename ) ) then
  999.     begin
  1000.       // The decoding was successfully. We clear the file source list box
  1001.       // and the destination text box
  1002.       edtDecDestination.Text := '';
  1003.       edtDecFilename.Text := '';
  1004.       lstEncodedFile.Clear();
  1005.     end;
  1006.     slEncodedFile.Free();
  1007.   end;
  1008. end;
  1009.  
  1010. {---------------------------------------------------------------}
  1011. { Add file(s) to the list of files to decode
  1012. {---------------------------------------------------------------}
  1013. procedure TfrmManager.btAddFileClick(Sender: TObject);
  1014. var
  1015.   slFilenames : TStringList;
  1016.   i           : integer;
  1017. begin
  1018.   xOpenDialog.Files.Clear();
  1019.   xOpenDialog.Title       := 'Encoded file';
  1020.   xOpenDialog.Filter      := 'Encoded (*.uue;*.xxe;*.b64;*.hex)|' +
  1021.                              '*.uue;*.xxe;*.b64;*.hex|UU encoded (*.uue)|' +
  1022.                              '*.uue|XX Encoded (*.xxe)|*.xxe|Base 64 (*.b64)|' +
  1023.                              '*.b64|Hexadecimal (*.hex)|*.hex|BinHex (*.hqz)|' +
  1024.                              '*.hqx|Quoted Printable (*.qpr)|All Type (*.*)|*.*';
  1025.   xOpenDialog.FilterIndex := 0;
  1026.   xOpenDialog.Options := [ ofAllowMultiSelect ];
  1027.  
  1028.   // Show an Open common dialog to let the user select files
  1029.   if xOpenDialog.Execute then
  1030.   begin
  1031.     slFilenames := TStringList.Create();
  1032.     slFilenames.AddStrings( xOpenDialog.Files );
  1033.  
  1034.     for i := 0 to ( slFilenames.Count - 1 ) do
  1035.       // Add the extracted file name to the list box of file names
  1036.       AddEncodedFileToList( slFilenames.Strings[ i ] );
  1037.  
  1038.     slFilenames.Free();
  1039.   end;
  1040. end;
  1041.  
  1042. {---------------------------------------------------------------}
  1043. { Fill the destination file name to the default value           }
  1044. {---------------------------------------------------------------}
  1045. procedure TfrmManager.edtEncSourceFileExit(Sender: TObject);
  1046. begin
  1047.   SetDestinationFilename();
  1048. end;
  1049.  
  1050. end.
  1051.