How to use ActivX FtpFile component in C++ Builder 6

I want to use ActiveX FtpFile component from ActivExperts. They have manual to show how to use it but sample code is written in VBscript only :

Set objFtpServer = CreateObject ( "ActiveXperts.FtpServer" )

objFtpServer.Connect "","anonymous","" ' Connect to the FTP server 
                                                                ' using the anonymous account 
Wscript.Echo "Connect, result: " & objFtpServer.LastError
If( objFtpServer.LastError <> 0 ) Then                          ' If connect failed then quit
End If

objFtpServer.ChangeDir "samples/ASocket/Visual Basic/Telnet"    ' Change directory
Wscript.Echo "ChangeDir, result: " & _
If( objFtpServer.LastError <> 0 ) Then                          ' If ChangeDir fails then 
                                                                ' disconnect and quit
End If

Set objFtpFile = objFtpServer.FindFirstFile()                   ' Iterate over all files in dir 
                                                                ' Start with first file
While( objFtpServer.LastError = 0 )
   WScript.Echo "Name: " & objFtpFile.Name                      ' Display file name
   WScript.Echo "IsDirectory: " & objFtpFile.IsDirectory        ' Display directory or file
   WScript.Echo "Size: " & objFtpFile.Size                      ' Display file size
   WScript.Echo "Date: " & objFtpFile.Date                      ' Display file date
   ' To save the file, call the GetFile function. 
   ' strSaveAs = "C:\temp\" & objFtpFile.Name
   ' objFtpServer.GetFile objFtpFile.Name, strSaveAs
   ' Wscript.Echo "Save file, result: " & objFtpServer.LastError

   ' To delete a file, call the DeleteFile function. 
   ' objFtpServer.DeleteFile objFtpFile.Name
   ' Wscript.Echo "Delete, result: " & objFtpServer.LastError

   Set objFtpFile = objFtpServer.FindNextFile()                 ' Next file


Open in new window

I made the following declarations in my code :

 TCOMIFtpServer m_objFtpServer;     
 TCOMIFtpFile m_objFtpFile;

  m_objFtpServer =  CoFtpServer::Create();
  m_objFtpFile = CoFtpFile::Create();


  m_objFtpServer->set_LogFile(WideString (ftplog_filename));

  m_objFtpServer->Connect(WideString ("xxx"), WideString ("Admin"), WideString ("yyy"));

   if( m_objFtpServer->LastError == 0 )
       m_objFtpFile = m_objFtpServer->FindFirstFile();

Open in new window

Connection to server is working properly, but when I was trying to read first file name it come the error ( in last line ) :

[C++ Error] rj1.cpp(26141): E2285 Could not find a match for 'TCOMIFtpFile::operator =(tagVARIANT)'

What is wrong in my code?
Anybody can help me?
Who is Participating?
ssnkumarConnect With a Mentor Commented:
So, that means you are not following proper steps to create the Ftp object.
Go thru the examples from the link that I gave.
That will give you more clues.
You have declared an object: TCOMIFtpFile m_objFtpFile;
Now, the class TCOMIFtpFile doesn't define '=' operator.
So, the compiler is not able to decide what to do, at the code:
m_objFtpFile = m_objFtpServer->FindFirstFile();

So, look at the class definition and see is there any other way to assign the value from  m_objFtpServer->FindFirstFile() to m_objFtpFile.
Leo01010101Author Commented:
FindFirstFile() returns an FtpFile object. This is ActiveX VARIANT type object. I didn't see any method to assign this object to a new declared FtpFile object.  
Never miss a deadline with

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

> I didn't see any method to assign this object to a new declared FtpFile object.  
If there is no way to assign, then you will have to create a new inherited class and define the = operator.
Leo01010101Author Commented:
When I'm trying to assign :

         TCOMIFtpFile m_objFtpFile;
         m_objFtpFile = CoFtpFile::Create();
         m_objFtpFile = m_objFtpServer->FindFirstFile();

In a last line I have an errror :

[C++ Error] rj1.cpp(26182): E2285 Could not find a match for 'TCOMIFtpFile::operator =(tagVARIANT)'

Open in new window

Class TCMIFtpFile is declared in following way :

template <class T /* IFtpFile */ >
class TCOMIFtpFileT : public TComInterface<IFtpFile>, public TComInterfaceBase<IUnknown>
  TCOMIFtpFileT() {}
  TCOMIFtpFileT(IFtpFile *intf, bool addRef = false) : TComInterface<IFtpFile>(intf, addRef) {}
  TCOMIFtpFileT(const TCOMIFtpFileT& src) : TComInterface<IFtpFile>(src) {}
  TCOMIFtpFileT& operator=(const TCOMIFtpFileT& src) { Bind(src, true); return *this;}

  HRESULT         __fastcall Clear(void);
  HRESULT         __fastcall get_Size(long* pVal/*[out,retval]*/);
  long            __fastcall get_Size(void);
  HRESULT         __fastcall set_Size(long pVal/*[in]*/);
  HRESULT         __fastcall get_Name(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_Name(void);
  HRESULT         __fastcall set_Name(BSTR pVal/*[in]*/);
  HRESULT         __fastcall get_DateSeconds(long* pVal/*[out,retval]*/);
  long            __fastcall get_DateSeconds(void);
  HRESULT         __fastcall set_DateSeconds(long pVal/*[in]*/);
  HRESULT         __fastcall get_Date(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_Date(void);
  HRESULT         __fastcall set_Date(BSTR pVal/*[in]*/);
  HRESULT         __fastcall get_IsDirectory(long* pVal/*[out,retval]*/);
  long            __fastcall get_IsDirectory(void);
  HRESULT         __fastcall set_IsDirectory(long pVal/*[in]*/);

  __property   long            Size = {read = get_Size, write = set_Size};
  __property   BSTR            Name = {read = get_Name};
  __property   long            DateSeconds = {read = get_DateSeconds, write = set_DateSeconds};
  __property   BSTR            Date = {read = get_Date};
  __property   long            IsDirectory = {read = get_IsDirectory, write = set_IsDirectory};
typedef TCOMIFtpFileT<IFtpFile> TCOMIFtpFile;

Open in new window

I need advace, can I make changes in this and what I should change?
Are you defining TCOMIFtpFileT class?
If so, then you can try to overload the = operator.
But, you will have to add a method which does the operation of = operator.
Leo01010101Author Commented:
No, I took this class definition from _TLB.h of ActiveExperts SOCKET component. I'm not a 'big expert' on this field. Maybe you see they way how to assign objects to make working existing  = operator?  
From the class definition, I see that the class defines = operator.
So, you don't have to define it again.

But, you are getting an error at:
m_objFtpFile = m_objFtpServer->FindFirstFile();

You had told that FindFirstFile() returns an FTP object.
Most probably, this FTP object is not of the type TCOMIFtpFileT.

From the definition, = operator is defined as:
TCOMIFtpFileT& operator=(const TCOMIFtpFileT& src) { Bind(src, true); return *this;}
So, you need to have same kind of objects on both left hand side and right hand side.
See, if you can get FTP object of the same type as TCOMIFtpFileT
try to typecast the FTP object to TCOMIFtpFileT.
Leo01010101Author Commented:

FindFirstFille retiurns an FtpFile object. The is an ActiveX VARIANT type of object.

I made a cast ( I'm not sure if correct way )
 m_objFtpFile = (TCOMIFtpFileT)m_objFtpServer->FindFirstFile();

Open in new window

it comes error:

[C++ Error] rj1.cpp(26182): E2102 Cannot use template 'TCOMIFtpFileT<T>' without specifying specialization parameters
[C++ Error] rj1.cpp(26182): E2293 ) expected
Leo01010101Author Commented:
I tryed,

comes error :

[C++ Error] rj1.cpp(26184): E2314 Call of nonfunction
OK. The reason for the error is, you can make that call only during variable definition.

So, you can do this:
TCOMIFtpFile m_objFtpFile(m_objFtpServer->FindFirstFile());
Can you show the definition of TCOMIFtpServer class?
Leo01010101Author Commented:
I tryed this

TCOMIFtpFile m_objFtpFile(m_objFtpServer->FindFirstFile()); 

Open in new window

and have following error :

[C++ Error] rj1.cpp(26184): E2285 Could not find a match for 'TCOMIFtpFile::TCOMIFtpFileT(tagVARIANT)'

Definition of FtpServer :

// *********************************************************************//
// SmartIntf: TCOMIFtpServer
// Interface: IFtpServer
// *********************************************************************//
template <class T /* IFtpServer */ >
class TCOMIFtpServerT : public TComInterface<IFtpServer>, public TComInterfaceBase<IUnknown>
  TCOMIFtpServerT() {}
  TCOMIFtpServerT(IFtpServer *intf, bool addRef = false) : TComInterface<IFtpServer>(intf, addRef) {}
  TCOMIFtpServerT(const TCOMIFtpServerT& src) : TComInterface<IFtpServer>(src) {}
  TCOMIFtpServerT& operator=(const TCOMIFtpServerT& src) { Bind(src, true); return *this;}

  HRESULT         __fastcall get_Version(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_Version(void);
  HRESULT         __fastcall get_Build(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_Build(void);
  HRESULT         __fastcall get_Module(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_Module(void);
  HRESULT         __fastcall get_ExpirationDate(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_ExpirationDate(void);
  HRESULT         __fastcall set_Reserved(long Param1/*[in]*/);
  HRESULT         __fastcall get_LastError(long* pVal/*[out,retval]*/);
  long            __fastcall get_LastError(void);
  HRESULT         __fastcall get_LogFile(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_LogFile(void);
  HRESULT         __fastcall set_LogFile(BSTR pVal/*[in]*/);
  HRESULT         __fastcall Clear(void);
  HRESULT         __fastcall GetErrorDescription(long newVal, BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall GetErrorDescription(long newVal);
  HRESULT         __fastcall Activate(BSTR bstrRegKey, long bPersistent/*[in,def,opt]*/);
  HRESULT         __fastcall Sleep(long lMilliSeconds);
  HRESULT         __fastcall get_HostPort(long* pVal/*[out,retval]*/);
  long            __fastcall get_HostPort(void);
  HRESULT         __fastcall set_HostPort(long pVal/*[in]*/);
  HRESULT         __fastcall get_BinaryTransfer(long* pVal/*[out,retval]*/);
  long            __fastcall get_BinaryTransfer(void);
  HRESULT         __fastcall set_BinaryTransfer(long pVal/*[in]*/);
  HRESULT         __fastcall get_PassiveMode(long* pVal/*[out,retval]*/);
  long            __fastcall get_PassiveMode(void);
  HRESULT         __fastcall set_PassiveMode(long pVal/*[in]*/);
  HRESULT         __fastcall get_LastResponse(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall get_LastResponse(void);
  HRESULT         __fastcall Connect(BSTR bstrHost, BSTR bstrAccount, BSTR bstrPassword);
  HRESULT         __fastcall Disconnect(void);
  HRESULT         __fastcall FindFirstFile(VARIANT* pVal/*[out,retval]*/);
  VARIANT         __fastcall FindFirstFile(void);
  HRESULT         __fastcall FindNextFile(VARIANT* pVal/*[out,retval]*/);
  VARIANT         __fastcall FindNextFile(void);
  HRESULT         __fastcall GetCurrentDir(BSTR* pVal/*[out,retval]*/);
  BSTR            __fastcall GetCurrentDir(void);
  HRESULT         __fastcall ChangeDir(BSTR bstrDir);
  HRESULT         __fastcall CreateDir(BSTR bstrDir);
  HRESULT         __fastcall RenameDir(BSTR bstrOld, BSTR bstrNew);
  HRESULT         __fastcall DeleteDir(BSTR bstrDir);
  HRESULT         __fastcall GetFile(BSTR bstrRemote, BSTR bstrLocal);
  HRESULT         __fastcall PutFile(BSTR bstrLocal, BSTR bstrRemote/*[in,def,opt]*/);
  HRESULT         __fastcall FindFile(BSTR bstrSearch, VARIANT* pVal/*[out,retval]*/);
  VARIANT         __fastcall FindFile(BSTR bstrSearch);
  HRESULT         __fastcall RenameFile(BSTR bstrOld, BSTR bstrNew);
  HRESULT         __fastcall DeleteFile(BSTR bstrFile);

  __property   BSTR            Version = {read = get_Version};
  __property   BSTR            Build = {read = get_Build};
  __property   BSTR            Module = {read = get_Module};
  __property   BSTR            ExpirationDate = {read = get_ExpirationDate};
  __property   long            Reserved = {write = set_Reserved};
  __property   long            LastError = {read = get_LastError};
  __property   BSTR            LogFile = {read = get_LogFile};
  __property   long            HostPort = {read = get_HostPort, write = set_HostPort};
  __property   long            BinaryTransfer = {read = get_BinaryTransfer, write = set_BinaryTransfer};
  __property   long            PassiveMode = {read = get_PassiveMode, write = set_PassiveMode};
  __property   BSTR            LastResponse = {read = get_LastResponse};
typedef TCOMIFtpServerT<IFtpServer> TCOMIFtpServer;

Open in new window

From the class definition, I see the definition of FindFirstFile() as:
HRESULT         __fastcall FindFirstFile(VARIANT* pVal/*[out,retval]*/);
VARIANT         __fastcall FindFirstFile(void);

And in your case, you are using the 2nd call and it returns a VARIANT.
So, there is a type mismatch.

I see the following constructor has a closer match:
TCOMIFtpFileT(IFtpFile *intf, bool addRef = false) : TComInterface<IFtpFile>(intf, addRef) {}

So, can you try this:
TCOMIFtpFile m_objFtpFile((IFtpFile *)m_objFtpServer->FindFirstFile(), false);
Leo01010101Author Commented:
I tryed this :

 TCOMIFtpFile m_objFtpFile((IFtpFile *)m_objFtpServer->FindFirstFile(), false);

Open in new window

and have an error :

[C++ Error] rj1.cpp(26184): E2031 Cannot cast from 'tagVARIANT' to 'IFtpFile *'
[C++ Error] rj1.cpp(26184): E2285 Could not find a match for 'TCOMIFtpFile::TCOMIFtpFileT(undefined,bool)'
So, from all these experiments, we have have exhausted all possibilities.
So, I think, the way you are assigning the value is wrong.
You will have to find a method to convert the value from one form to another and use it.
There must be some way to do it - just study everything once again and see if you find something new.
Did you check these sample programs:

They may give you some clue.
Look at this sample code:

Here, they are also calling m_pFtpServer->FindFirstFile ( &vtVar );
But, they are not assigning it to object of another type.

This is what they are doing to assign the value:
IFtpServer      *m_pFtpServer;
IFtpFile             *pFile            = NULL;
VARIANT               vtVar;
m_pFtpServer->FindFirstFile ( &vtVar );
pFile = ( IFtpFile* ) vtVar.pdispVal;
VariantClear ( &vtVar );

So, you have to change your code like this:
TCOMIFtpServer *m_objFtpServer;
TCOMIFtpFile *m_objFtpFile;
VARIANT            vtVar;
/* Add the code to create the server object and client object */

m_objFtpFile = (TCOMIFtpFile *)vtVar.pdispVal;
Leo01010101Author Commented:
I tryed code you propose, I can compile this without errors. But during executing this after reading first file from FTP server I can't see properties of m_objFtpFile  object.

I want to check it:

          WideString file_name = m_objFtpFile->get_Name();
          long file_size = m_objFtpFile->get_Size();
          long IsDirectory = m_objFtpFile->get_IsDirectory();
          WideString file_date = m_objFtpFile->get_Date();

Open in new window

but executing first line comes error ( see included image )

Error is in this code:

template <class T> BSTR __fastcall
  BSTR pVal = 0;
  return pVal;

Open in new window

I'm not sure what could be wrong.
Leo01010101Author Commented:
Finally thank to your remarks I find solution :

bool __fastcall TForm1::readFtpFirstFile(void)

  bool ret = false;

  ftp_file_name = "";
  ftp_file_ext = "";
  ftp_file_size = "";
  ftp_file_date = "";
  ftp_file_isDir = false;

  short dlugosc = 0;

   IFtpFile *m_objFtpFile;
   VARIANT vtVar;

   long	lResult	= 0;
   BSTR	bstrVa	= NULL;
   IFtpFile *	pFile	= NULL;
   long	lSize	= 0;
   long	bDirectory	= 0;


   if( m_objFtpServer->LastError == 0 )

          m_objFtpFile = (IFtpFile* )vtVar.pdispVal;

          if( m_objFtpFile )
           m_objFtpFile->get_IsDirectory ( &bDirectory );
           m_objFtpFile->get_Name ( &bstrVal );
           ftp_file_name = bstrVal;
           SysFreeString ( bstrVal );
           m_objFtpFile->get_Size ( &lSize );
           ftp_file_size = IntToStr( lSize );
           m_objFtpFile->get_Date ( &bstrVal );
           ftp_file_date = bstrVal;
           SysFreeString ( bstrVal );

           if ( bDirectory )
            ftp_file_size = "<DIR>";
            ftp_file_isDir = true;
             dlugosc = ftp_file_name.Length();

             ftp_file_ext = ftp_file_name[dlugosc - 2];
             ftp_file_ext += ftp_file_name[dlugosc - 1];
             ftp_file_ext += ftp_file_name[dlugosc];

           ret = true;



 return ret;


Open in new window

Thank you for support
Leo01010101Author Commented:
Thank tou very much for your support and big patience for me.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.