' ============================================================================
' QFTPCLIENT              EXTENDED  COMPONENT              By Jacques Philippe
'
' HTML DOCUMENTATION                               Version February 12th, 2003                    
' ============================================================================
'
'   INCLUDE :    $INCLUDE "QFTPCLIENT.INC"
'   -------
'
'   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", "Zorro_007", "TopSecretPw")
'           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", "Zorro_007", "TopSecretPw")
'               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", "Zorro_007", "TopSecretPw") 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", "Zorro_007", "TopSecretPw") 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)
'
' =============================================================================