Solved

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

Posted on 2011-09-29
22
500 Views
Last Modified: 2012-05-12
Hi,
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 "ftp.activexperts-labs.com","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
   WScript.Quit
End If

objFtpServer.ChangeDir "samples/ASocket/Visual Basic/Telnet"    ' Change directory
Wscript.Echo "ChangeDir, result: " & _
 objFtpServer.LastError
If( objFtpServer.LastError <> 0 ) Then                          ' If ChangeDir fails then 
                                                                ' disconnect and quit
   objFtpServer.Disconnect
   WScript.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
Wend

objFtpServer.Disconnect              

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->Clear();

  m_objFtpServer->set_LogFile(WideString (ftplog_filename));
  m_objFtpServer->set_HostPort(21);
  m_objFtpServer->set_BinaryTransfer(0);
  m_objFtpServer->set_PassiveMode(0);

  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?
 
0
Comment
Question by:Leo01010101
  • 12
  • 10
22 Comments
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36889977
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.
0
 

Author Comment

by:Leo01010101
ID: 36891262
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.  
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36892472
> 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.
0
 

Author Comment

by:Leo01010101
ID: 36908592
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>
{
public:
  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?
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36908727
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.
0
 

Author Comment

by:Leo01010101
ID: 36908842
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?  
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36908871
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
or
try to typecast the FTP object to TCOMIFtpFileT.
0
 

Author Comment

by:Leo01010101
ID: 36909007


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
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36909027
Try:
m_objFtpFile(m_objFtpServer->FindFirstFile());
0
 

Author Comment

by:Leo01010101
ID: 36909053
I tryed,

comes error :

[C++ Error] rj1.cpp(26184): E2314 Call of nonfunction
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36909226
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());
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 8

Expert Comment

by:ssnkumar
ID: 36909233
Can you show the definition of TCOMIFtpServer class?
0
 

Author Comment

by:Leo01010101
ID: 36909269
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>
{
public:
  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

0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36909301
From the class definition, I see the definition of FindFirstFile() as:
HRESULT         __fastcall FindFirstFile(VARIANT* pVal/*[out,retval]*/);
and
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);
0
 

Author Comment

by:Leo01010101
ID: 36909327
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)'
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36914900
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.
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36914911
Did you check these sample programs: ftp://ftp.activexperts-labs.com/samples/network-component

They may give you some clue.
0
 
LVL 8

Expert Comment

by:ssnkumar
ID: 36914962
Look at this sample code: ftp://ftp.activexperts-labs.com/samples/network-component/Visual%20C++/Windows%20Applications/Demo/DialogFtp.cpp

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_objFtpServer->FindFirstFile(&vtVar);
m_objFtpFile = (TCOMIFtpFile *)vtVar.pdispVal;
0
 

Author Comment

by:Leo01010101
ID: 36915192
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
TCOMIFtpFileT<T>::get_Name(void)
{
  BSTR pVal = 0;
  OLECHECK(this->get_Name((BSTR*)&pVal));
  return pVal;
}

Open in new window


I'm not sure what could be wrong.
eee-1.PNG
0
 
LVL 8

Accepted Solution

by:
ssnkumar earned 500 total points
ID: 36915286
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.
0
 

Author Comment

by:Leo01010101
ID: 36916051
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;

   m_objFtpServer->FindFirstFile(&vtVar);

   if( m_objFtpServer->LastError == 0 )
   {

     try{
          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;
           }
           else
           {
            //extend
             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;
          }
        }

     catch(...){;}

  }

 return ret;

}

Open in new window


Thank you for support
0
 

Author Closing Comment

by:Leo01010101
ID: 36916086
Thank tou very much for your support and big patience for me.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now