    '
    ' ============================================================================
    ' QFTPCLIENT              EXTENDED  COMPONENT              By Jacques Philippe
    '
    ' HTML DOCUMENTATION                               Version February 12th, 2003
    ' ============================================================================
    '
    '   INCLUDE :    $INCLUDE "QFTPCLIENT.INC"      On Top Of Your Code
    '   -------
    '
    '   DIM :        DIM myFtp As QFtpClient
    '   ---
    '
    '   METHODS :    DIRECTORY :  GetDir, MkDir, SetDir, RemoveDir,
    '   -------           FILE :  PutFile, GetFile, Rename, Delete
    '                     FIND :  FindFirstFile, FindNextFile
    '                    OTHER :  ReadMessage
    '
    '   PROPERTIES :   GENERAL :  ErrorMsg, Agent
    '   ----------   FILE_FIND :  FileName, FileSize, FileTime, FileDate, FileAttributes
    '                             FileAttributesAsString
    '
    ' =============================================================================
    '
    '   Examples Assume    $ECAPECHARS ON
    '
    '   EXAMPLES 1    no FTP directory scanning, just PutFile, GetFile
    '   --------
    '       Dim myFtp As QFtpClient
    '       myFtp.Connect ("www.bigftp.com", "MyLogin", "MyPassword")
    '           myFtp.PutFile ("c:\\MyDir\\myFile.lkj", "d:\\hostDir\\newName.lkj")
    '           myFtp.GetFile ("d:\\hostFir\\newName.lkj", "C:\\myDir\\newFile.lkj", True)
    '       myFtp.Close
    '
    '   ' Note : Relative and absolute path are allowed
    '
    '   EXAMPLE 2     FTP scanning a Directory
    '   ---------
    '       Dim myFtp As QFtpClient
    '       With myFtp
    '          DefStr sFile
    '          .Connect ("www.bigftp.com", "MyLogin", "MyPassword")
    '               sFile = .FindFirstFile ("c:\\ExistingDirAtRemoteHost\\*.bas")
    '               While sFile <> ""
    '                   If Instr(.fileAttributesAsString, "D") = 0 Then  ' reject directories
    '                       Print "FileName : ";.fileName
    '                       Print "                 Dos FileName : ";.dosFileName
    '                       Print "                    File Size : ";.fileSize
    '                       Print "                    File Date : ";.fileDate
    '                       Print "                    File Time : ";.fileTime
    '                       Print "               File Attributes: ";.fileAttributes
    '                       Print "    File Attributes As String : ";.fileAttributesAsString
    '                   End If
    '                   sFile = .FindNextFile
    '               Wend
    '               Print "End Of Directory"
    '           .Close
    '       End With
    '
    '
    '   EXAMPLE 3   Tracking Errors and FTP Scanning a Directory
    '   ---------
    '       Dim myFtp As QFtpClient
    '       With myFtp
    '           DefStr sFile
    '           If .Connect ("www.bigftp.com", "MyLogin", "MyPassword") Then
    '               sFile = .FindFirstFile ("c:\\ExistingDirAtRemoteHost\\*.bas")
    '               While sFile <> ""
    '                   If Instr(.fileAttributesAsString, "D") = 0 Then  ' reject directories
    '                       Print "FileName : ";.fileName
    '                       Print "                 Dos FileName : ";.dosFileName
    '                       Print "                    File Size : ";.fileSize
    '                       Print "                    File Date : ";.fileDate
    '                       Print "                    File Time : ";.fileTime
    '                       Print "               File Attributes: ";.fileAttributes
    '                       Print "    File Attributes As String : ";.fileAttributesAsString
    '                   End If
    '                   sFile = .FindNextFile
    '               Wend
    '               Print .errorMsg
    '               Print "End Of Directory"
    '           .Close
    '           Else
    '               Print .errorMsg
    '               .Close
    '           End If
    '       End With
    '
    '
    '   EXAMPLE 4  Using FTP Prompt Messages To Monitor Communication
    '   ---------
    '       Dim myFtp As QFtpClient
    '       With myFtp
    '           DefStr sFile
    '           If .Connect ("www.bigftp.com", "MyLogin", "MyPassword") Then
    '               Print .ReadMessage
    '               Sleep 1
    '               sFile = .FindFirstFile ("c:\\ExistingDirAtRemoteHost\\*.bas")
    '               While sFile <> ""
    '                   If Instr(.fileAttributesAsString, "D") = 0 Then  ' reject directories
    '                       Print "FileName : ";.fileName
    '                       Print "                 Dos FileName : ";.dosFileName
    '                       Print "                    File Size : ";.fileSize
    '                       Print "                    File Date : ";.fileDate
    '                       Print "                    File Time : ";.fileTime
    '                       Print "               File Attributes: ";.fileAttributes
    '                       Print "    File Attributes As String : ";.fileAttributesAsString
    '                       Sleep 1
    '                   End If
    '                   sFile = .FindNextFile
    '               Wend
    '               Print .ReadMessage
    '               Print "End Of Directory"
    '               .Close
    '           Else
    '               Print .ReadMessage
    '           End If
    '       End With
    '
    ' =============================================================================
    '
    '   METHODS  detailed
    '   -------
    '
    '   - Function CONNECT (remoteServer$, login$, password$) As Long
    '                Returns a valid handle to the FTP session if the connection is
    '                successfull, or NULL otherwise.
    '
    '   - Function GETDIR As String
    '                Returns the current Directory at Remote Host
    '
    '   - Function MAKEDIR (newDirectory As String) As Long
    '                Create A New Directory At Remote Host
    '                Overwrite = Error
    '                Return True/False
    '
    '   - Function SETDIR (newDirectory As String) As Long
    '               Set, Change Directory at Remote Host
    '               Return True/False
    '
    '   - Function REMOVEDIR (delDirectory As String) As Long
    '               Delete a Directory at Remote Host
    '               Return True/False
    '
    '   - Function PUTFILE (localFileName$, remoteFileName$) As Long
    '               Upload, Copy a File from Local Host To Remote Host
    '               Relative and Absolute Path are allowed
    '               Return True/False
    '
    '   - Function GETFILE (remoteFileName$, localFileName$, flagOverwrite%) As Long
    '               DownLoad, Copy a File from Remote Host to Local Host
    '               Relative and Absolute Path are allowed
    '               Return True/False
    '
    '   - Function RENAME (oldName as String, newName as String) as Long
    '               Rename a File at Remote Host
    '               Return True/False
    '
    '   - Function DELETE (remoteFileName As String) As Long
    '               Delete a file at Remote Host
    '               Return True/False
    '
    '   - Function FINDFIRSTFILE (filter As String) As String
    '               Search the First File Matching the filter in Remote Host Current
    '               Directory. Return the filename or an Empty string if no matching
    '               File is found. To be used with FINDNEXTFILE.
    '
    '   - Function FINDNEXTFILE As String
    '               Search the Next File matching the filter (set in FINDFIRSTFILE)
    '               in the Remote Host Directory. Return the filename or an Empty
    '               String if no file match the filter anymore.
    '
    '   - Function READMESSAGE As String
    '               returns an the FTP Message generated by the remote server or
    '               ?local API call? (some kind of ftp monitoring)
    '
    '   - Function CLOSE As Long
    '               ****  The FTP Session must be Closed !  ****
    '               returns 1 if both FTP SESSION and "ALL" have Been Closed
    '
    ' =============================================================================
    '   PROPERTIES I    detailled
    '   ------------
    '     UseFull Properties General
    '     --------------------------
    '      -  ERRORMSG As String       report string after each Method Call    Read Only
    '      -  AGENT As String          default : "FTP Object for RAPIDQ"
    '
    '     Usefull Properties Updated By FindFirstFile and FindNextFile
    '     ------------------------------------------------------------
    '      -  FILENAME As string
    '      -  DOSFILENAME As string
    '      -  FILESIZE As Double
    '      -  FILEDATE As String       Format  MM/DD/YYYY   US Format
    '      -  FILEDATEEU As String     Format  DD/MM/YYYY   European Format
    '      -  FILETIMEMS As String     Format  HH:MM:SS.mmm  (mmm = milliseconds)
    '      -  FILETIME As String       Format  HH:MM:SS
    '      -  FILEDATETIME As Double   DateTime in 1/100 seconds since ??1-1-1900??
    '                           use this to sort by datetime
    '      -  fileAttributes As Long   Combination of Set Attributes As Attribute
    '                           Contantes Show Here Under.
    '      -  fileAttributesAsString As String   "ADHNRSTC" if all the file attributes
    '                           are set
    '
    ' =============================================================================
    '   PROPERTIES II
    '   -------------
    '     Less UseFull Properties (harder to Use :)
    '     -----------------------
    '     General Properties
    '     ------------------
    '      - ftpHandle As Long     the handle of the FTP Socket              Read Only
    '      - errorMsg As String    report string after each function call    Read Only
    '
    '     Open Properties      see the doc of API "InternetOpen" at ??www.allapi.net
    '     ---------------      dont really know either :)
    '      - Agent As String         default : "FTP Object for RAPIDQ"
    '      - OpenType As Long        default : CONST INTERNET_OPEN_TYPE_PRECONFIG
    '      - ProxyName As String     default : ""
    '      - ProxyByPass As String   default : ""
    '      - Open_dwFlags As Long    default : 0
    '
    '     Connect Properties   see the doc of API "InternetConnect" at ??www.allapi.net
    '     ------------------   dont really know either :)
    '      - FtpPort As Long            default : CONST INTERNET_DEFAULT_FTP_PORT
    '      - InternetService As Long    default : CONST INTERNET_SERVICE_FTP
    '      - InternetFlag As Long       a function of Internet Service (computed in code)
    '      - Connect_dwContext As Long  default : 0
    '
    '     PutFile Properties       see the doc of API "FtpPutFile" at ??www.allapi.net
    '     ------------------       dont really know either :)
    '      -  FtpTransferType As Long   default : CONST FTP_TRANSFER_TYPE_UNKNOWN
    '      -  Put_dwContext As Long     default : 0
    '
    '     GetFile Properties       see the doc of API "FtpGetFile" at ??www.allapi.net
    '     ------------------       dont really know either :)
    '      -  FlagsAndAttributes As Long      default : 0
    '      -  Get_dwContext As Long           default : 0
    '
    '     FindFirstFile & FindNextFile Properties  see the API docs at ??www.allapi.net
    '     ---------------------------------------
    '      -  findfirst_dwFlags As Long       default : 0    API FindFirstFile
    '      -  findFirst_dwContext As Long     default : 0    API FindFirstFile
    '      -  WIN32_FIND_DATA As QFTP_WIN32_FIND_DATA      the WIN32 File Structure
    '           Type QFTP_FILETIME
    '               LowDateTime As Long
    '               HighDateTime As Long
    '           End Type
    '
    '           Type QFTP_WIN32_FIND_DATA             ' variables about the last find file
    '               FileAttributes As Long         ' See CONSTANTES here under
    '               'ftCreationTime As FILETIME    ' replaced by (1) & (2)
    '               'ftLastAccessTime As FILETIME  ' replaced by (3) & (4)
    '               'ftLastWriteTime As FILETIME   ' replaced by (5) & (6)
    '               'RAPIDQ BUGS WITH NESTED TYPES so REPLACED BY The Six Following Lines
    '               CreationTimeLow As Long        ' (1) low dw = unsigned long
    '               CreationTimeHigh As Long       ' (2) high dw = unsigned long
    '               LastAccessTimeLow As Long      ' (3) low dw = unsigned long
    '               LastAccessTimeHigh As Long     ' (4) high dw = unsigned long
    '               LastWriteTimeLow As Long       ' (5) low dw = unsigned long
    '               LastWriteTimeHigh As Long      ' (6) high dw = unsigned long
    '               nFileSizeHigh As Long          ' low dw = unsigned long
    '               nFileSizeLow As Long           ' high dw = unsigned long
    '               dwReserved0 As Long
    '               dwReserved1 As Long
    '               cFileName As String * xxFTP_MAX_PATH  ' The FileName
    '               cAlternate As String * 14             ' The Dos FileName
    '           End Type
    '
    '           Const QFTP_FILE_ATTRIBUTE_ARCHIVE = &H20        ' "A"
    '           Const QFTP_FILE_ATTRIBUTE_DIRECTORY = &H10      ' "D"
    '           Const QFTP_FILE_ATTRIBUTE_HIDDEN = &H2          ' "H"
    '           Const QFTP_FILE_ATTRIBUTE_NORMAL = &H80         ' "N"
    '           Const QFTP_FILE_ATTRIBUTE_READONLY = &H1        ' "R"
    '           Const QFTP_FILE_ATTRIBUTE_SYSTEM = &H4          ' "S"
    '           Const QFTP_FILE_ATTRIBUTE_TEMPORARY = &H100     ' "T"
    '           Const QFTP_FILE_ATTRIBUTE_COMPRESSED = &H800    ' "C"
    '
    '      -  hFind As Long   the Handle used by the FindFirstFile And FindNextFile
    '                         allows recursive FIND in sub directory too (=work)
    '
    ' =============================================================================