FTP example for C++ 5.0 and later

Take the following steps to use FTP features, including Directory Browsing, to your application:

1.

Start with a copy of the project that you created in Loading and Displaying an Image

 

Note: This example changes the initialization of the window; so using a copy of the original project prevents problems with later reuse of the original project.

2.

From the Project menu choose "Settings...". In the "General" tab, select "Use MFC in a Shared DLL".

3.

A sink interface must be added to receive FtpBrowse event from the LEADRasterFTP COM object. Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

Click the Add Class button.

 

b.

Click New....

 

c.

Type CRasterFTPSink for the name of the class

 

d.

Select CCmdTarget for the base class of the new class.

 

e.

Under Automation, click the Automation radio button.

 

f.

Click OK to create the class.

 

g.

In the RasterFTPSink.h file, move the destructor so that it is public:

// Implementation
   virtual ~CRasterFTPSink();
protected:

h.

In the RasterFTPSink.h file, add the following to the top of the file:

class CTutorDlg;

i.

In the RasterFTPSink.cpp file, add the following to the top of the file (after #include "RasterFTPSink.h")

#include "tutorDlg.h"

4.

Add #import and #include statements to your program so you can access the LEAD COM constants and classes:

 

a.

In the Project Workspace, click the FileView tab.

 

b.

Double-click the tutor files folder to open it.

 

c.

Double-click the Header Files folder to open it.

 

d.

Double-click the StdAfx.h file to edit it.

 

e.

Add the following line to the end of the file (keep in mind, you may have to change the path to where the DLL resides):

#import "c:\\winnt\\system32\\LTRVR14N.dll" no_namespace, named_guids
#import "c:\\winnt\\system32\\LTRFT14N.dll" no_namespace, named_guids
#include "RasterFTPSink.h"

5.

Edit the TUTORDLG.H file and change the definition of CTutorDlg : CDialog by inserting the following lines after DECLARE_MESSAGE_MAP:

public:
   ILEADRasterFTP *m_pRasterFTP;
   CRasterFTPSink *m_pRasterFTPSink;
   DWORD m_dwFTPCookie;

6.

Edit the TutorDlg.cpp file and add the following code to the end of the OnInitDialog function (just before return TRUE):

//Instantiate the sink class and hold a pointer to it.
m_pRasterFTPSink = new CRasterFTPSink;
//Create the RasterFTP object
CoCreateInstance(CLSID_LEADRasterFTP, NULL, CLSCTX_ALL, IID_ILEADRasterFTP, (void**)&m_pRasterFTP);
//Establish a connection between source and sink.
LPUNKNOWN pUnkSink = m_pRasterFTPSink->GetIDispatch(FALSE);
AfxConnectionAdvise(m_pRasterFTP, DIID__LEADRasterFTPEvents, pUnkSink, FALSE, &m_dwFTPCookie); 

7.

Add the following line near the top of TutorDlg.cpp (just after #include "tutorDlg.h")

#include <afxctl.h>

8.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

In the Class name combo box, select CTutorDlg.

 

b.

In the Object IDs list box, select CTutorDlg.

 

c.

In the Messages list box, select WM_DESTROY.

 

d.

Click the Add function button. Choose OK for the default function name (OnDestroy).

 

e.

Click the Edit Code button to start entering the code.

9.

Enter new code as follows (just before the CDialog::OnDestroy call):

void CTutorDlg::OnDestroy()
{
   //Terminate a connection between source and sink.
   LPUNKNOWN pUnkSink = m_pRasterFTPSink->GetIDispatch(FALSE);
   AfxConnectionUnadvise(m_pRasterFTP, DIID__LEADRasterFTPEvents, pUnkSink, FALSE, m_dwFTPCookie);
   delete m_pRasterFTPSink;
   m_pRasterFTP->Release();
   CDialog::OnDestroy();
}

10.

Add a command button to the Tutor dialog and name it as follows:

 

ID

Caption

 

IDC_FTP

FTP Test

11.

Press Ctrl-W to go to the MFC Class Wizard; then do the following:

 

a.

Click the Message Maps tab.

 

b.

In the Class Name combo box, select CTutorDlg.

 

c.

In the Object IDs list box, select IDC_FTP.

 

d.

In the Messages list box, select BN_CLICKED.

 

e.

Click the Add function button. Choose OK for the default function name (OnFtp).

 

f.

Click the Edit Code button and enter the following code: (you will have to change the file names to existing file names on your computer)

BOOL SavedSetting = m_pRasterFTP->EnableMethodErrors;
m_pRasterFTP->EnableMethodErrors = FALSE;
if(m_pRasterFTP->InetFtpConnect ("10.1.1.113", 21, "anonymous", "user@domain.com"))
{
   AfxMessageBox(TEXT("Error connecting to FTP server"));
   return;
}
// Change working directory on the server
m_pRasterFTP->InetFtpChangeDir ("/pub/TestFolder");
// Check that the change took effect
TCHAR s[1000];
wsprintf(s, TEXT("Current Directory is: %s"), (TCHAR*)( m_pRasterFTP->InetFtpGetCurrentDir ()));
AfxMessageBox(s);
// get directory contents
m_pRasterFTP->InetFtpBrowseDir("*.*");
// Send a file to the server
m_pRasterFTP->InetFtpSendFile("c:\\local.txt", "remote.txt", SENDAS_BINARY);
// rename a file on the server
m_pRasterFTP->InetFtpRenameFile ("remote.txt", "remote2.txt");
// get a file from the server
m_pRasterFTP->InetFtpGetFile ("remote2.txt", "c:\\local2.txt", TRUE, SENDAS_BINARY);
// create a new directory on the server
m_pRasterFTP->InetFtpCreateDir ("/pub/TestFolder/SubFolder");
// send a LEAD image to a file on the server
// load the image first by clicking the "LEAD Load" button
m_pRasterFTP->InetFtpSendBitmap(m_LEADRasView1.GetRaster(), FILE_BMP, 4, 0, "SubFolder/test.bmp", SENDAS_BINARY);
// delete a file on the server
m_pRasterFTP->InetFtpDeleteFile("SubFolder/test.bmp");
// remove a directory from the server
m_pRasterFTP->InetFtpDeleteDir("SubFolder");
// end the connection with the server
m_pRasterFTP->InetFtpDisconnect();
m_pRasterFTP->EnableMethodErrors = SavedSetting;

12.

Add code to handle the FtpBrowse Event.

 

a.

Start the OLE VIEW (OLE/COM object viewer) tool that ships with Visual Studio.

 

b.

Click to open the "Type Libraries" branch (if it is not displayed, choose "Expert Mode" from the View menu).

 

c.

Double-click the "LEAD RasterFTP Object Library" item.

 

d.

Click to open the dispinterface _LEADRasterFTPEvents branch.

 

e.

Click to open the "Methods" branch.

 

f.

Select the "FtpBrowse" method. See that the Dispatch ID is 1, and the FtpBrowse() event takes 7 arguments.

 

g.

Add the following code to RasterFTPSink.cpp immediately before the END_DISPATCH_MAP() macro. The VT_EMPTY argument indicates that the FtpBrowse Event returns NULL. The VTS_xxx arguments indicate the types and order of the FtpBrowse Event arguments:

DISP_FUNCTION_ID(CRasterFTPSink, "FtpBrowse", 1, OnFtpBrowse, VT_EMPTY, VTS_BSTR VTS_I4 VTS_DATE VTS_DATE VTS_DATE VTS_I4 VTS_PBOOL) 

h.

In RasterFTPSink.cpp, modify the second parameter of the INTERFACE_PART macro to become as follows:

i.

INTERFACE_PART(CRasterFTPSink, DIID__LEADRasterFTPEvents, Dispatch)

j.

Click on the "Class View" tab in the project workspace.

k.

Right-click the "CRasterFTPSink" branch, and choose "Add Member Function".

l.

For "Function Type" enter "void".

m.

For "Function Declaration" enter the following and click the "OK" button:

OnFtpBrowse(TCHAR * pszFile, long FileAttrib, DATE CreateTime, DATE AccessTime, DATE LastWriteTime, long uFileSize)

n.

Add the following code to the OnFtpBrowse() method:

void CRasterFTPSink::OnFtpBrowse(TCHAR * pszFile, long FileAttrib, DATE CreateTime, DATE AccessTime, DATE LastWriteTime, long uFileSize)
{
   CString s(TEXT("File name: "));

   m_pRasterFTP->PutStopFtpBrowseEvent( FALSE);

   s = s + pszFile + TEXT("\n");
   s = s + TEXT("File Attributies:") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_ARCHIVE) s = s + TEXT("\t") + TEXT("Archive") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_COMPRESSED) s = s + TEXT("\t") + TEXT("Compressed") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_DIRECTORY) s = s + TEXT("\t") + TEXT("Directory") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_ENCRYPTED) s = s + TEXT("\t") + TEXT("Encrypted") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_HIDDEN) s = s + TEXT("\t") + TEXT("Hidden") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_NORMAL) s = s + TEXT("\t") + TEXT("Normal") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_OFFLINE) s = s + TEXT("\t") + TEXT("Offline") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_READONLY) s = s + TEXT("\t") + TEXT("Read-only") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_REPARSE_POINT) s = s + TEXT("\t") + TEXT("Reparse point") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_SPARSE_FILE) s = s + TEXT("\t") + TEXT("Sparse file") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_SYSTEM) s = s + TEXT("\t") + TEXT("System") + TEXT("\n");
   if (FileAttrib & FTP_FILE_ATTRIB_TEMPORARY) s = s + TEXT("\t") + TEXT("Temporary") + TEXT("\n");
   s = s + TEXT("Create Time:") + TEXT("\t") + COleDateTime(CreateTime).Format() + TEXT("\n");
   s = s + TEXT("Access Time:") + TEXT("\t") + COleDateTime(AccessTime).Format() + TEXT("\n");
   s = s + TEXT("Write Time: ") + TEXT("\t") + COleDateTime(LastWriteTime).Format() + TEXT("\n");
   CString sFileSize;
   sFileSize.Format(TEXT("%ld"), uFileSize);
   s = s + TEXT("File Size: ") + TEXT("\t") + sFileSize + TEXT("\n");
   AfxMessageBox(s);
};

13.

Rebuild and run the application.