• No results found

Putting Shopper to Work

FTPCLI, a basic FTP application created using the Shopper component, is shown in Figure 5.3. To create this application, start a new project, FTPCLI, call the main form MainForm, and store this in MAIN.PAS, shown in Listing 5.1. Be sure to install the WSock and Shopper components in the palette, and then pluck the Shopper component from the palette onto the main form. Add a button for each FTP command to the form. For example, the Open button calls up Shopper1.Start as shown here:

Go!

Keyword

---Go!

procedure TMainForm.ConnectBtnClick(Sender: TObject);

var

Counter : Integer;

begin

Shopper1.HostName := HostInput.Text;{RemoteHostName;}

{ rest of code } Shopper1.Start;

{ more code not shown here } end;

FIGURE 5.3 The finished FTP client application, FTPCLI Listing 5.1 The FTP client demo main program unit

(*

Developed for KickAss Delphi Programming by John Penman

Ftp Client demo program

Copyright (c) 1996 The Coriolis Group, Inc.

Last Updated 7/5/96

*)

unit Main;

interface uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, About, MakeDir, StdCtrls, Wsock, Shopper, ExtCtrls, FileCtrl;

type

TMainForm = class(TForm) ConnectBtn: TButton;

AboutBtn: TButton;

DisConBtn: TButton;

ExitBtn: TButton;

RemFilesList: TListBox;

ViewBtn: TButton;

MkDirBtn: TButton;

CancelBtn: TButton;

DelBtn: TButton;

StatusMemo: TMemo;

RefreshBtn: TButton;

Progress: TEdit;

Label1: TLabel;

HelpBtn: TButton;

BinaryRBtn: TRadioButton;

AsciiRBtn: TRadioButton;

LocalFileList: TFileListBox;

LocalDirList: TDirectoryListBox;

LocalDrive: TDriveComboBox;

RemoteHostP: TPanel;

PassWordInput: TEdit;

Label2: TLabel;

Label3: TLabel;

Label4: TLabel;

SiteBtn: TButton;

procedure ConnectBtnClick(Sender: TObject);

procedure AboutBtnClick(Sender: TObject);

procedure DisConBtnClick(Sender: TObject);

procedure ExitBtnClick(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure ViewBtnClick(Sender: TObject);

procedure MkDirBtnClick(Sender: TObject);

procedure Shopper1Change(Sender: TObject);

procedure RemFilesListClick(Sender: TObject);

procedure RemFilesListDblClick(Sender: TObject);

procedure RefreshBtnClick(Sender: TObject);

procedure Shopper1UpDateProgress(Sender: TObject);

procedure Shopper1UpDateList(Sender: TObject);

procedure HelpBtnClick(Sender: TObject);

procedure LocalFileListChange(Sender: TObject);

procedure LocalDriveChange(Sender: TObject);

procedure LocalFileListDblClick(Sender: TObject);

procedure LocalDirListChange(Sender: TObject);

procedure Shopper1UpdateFileType(Sender: TObject);

procedure Shopper1UpDateTimeTaken(Sender: TObject);

procedure Shopper1UpDateBusyFlag(Sender: TObject);

procedure DelBtnClick(Sender: TObject);

procedure AbortBtnClick(Sender: TObject);

procedure CancelBtnClick(Sender: TObject);

procedure Shopper1ChangeInfo(Sender: TObject);

procedure SiteBtnClick(Sender: TObject);

private

procedure TMainForm.ConnectBtnClick(Sender: TObject);

var

Counter : Integer;

begin

Shopper1.HostName := HostInput.Text;{RemoteHostName;}

if Shopper1.Status = Success then begin

RemoteHostP.Caption :=

Concat('Remote host : ',HostInput.Text);

RemoteIPP.Caption :=

Concat('Remote IP : ',Shopper1.HostName);

with Shopper1 do begin

UserName := UserInput.Text;

Password := PasswordInput.Text;

end;

Shopper1.Start;

if Shopper1.Status = Success then begin

ConnectBtn.Enabled := FALSE;

DisConBtn.Enabled := TRUE;

if Shopper1.Connected then begin

RemFilesList.Clear;{951030JCP}

{populate the remote files list box}

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

{Now enable buttons}

RefreshBtn.Enabled := TRUE;

ExitBtn.Enabled := FALSE;

DisConBtn.Enabled := FALSE;

ViewBtn.Enabled := FALSE;

HelpBtn.Enabled := FALSE;

DelBtn.Enabled := FALSE;

CancelBtn.Enabled := FALSE;

MkDirBtn.Enabled := FALSE;

RefreshBtn.Enabled := FALSE;

ConnectBtn.Enabled := TRUE;

ExitBtn.Enabled := TRUE;

RemFilesList.Clear;

RemoteHostP.Caption := 'Remote host : ';

RemoteIPP.Caption := 'Remote IP : ';

{Output name of local machine}

LocalHostP.Caption :=

Concat('Local host : ',Shopper1.LocalName);

{assign default login info from published properties}

HostInput.Text := Shopper1.HomeServer;

UserInput.Text := Shopper1.UserName;

PasswordInput.Text := Shopper1.Password;

{Disable certain controls}

AbortBtn.Enabled := FALSE;

SiteBtn.Enabled := FALSE;

ConnectBtn.Enabled := TRUE;

DisConBtn.Enabled := FALSE;

ViewBtn.Enabled := FALSE;

HelpBtn.Enabled := FALSE;

DelBtn.Enabled := FALSE;

CancelBtn.Enabled := FALSE;

MkDirBtn.Enabled := FALSE;

RefreshBtn.Enabled := FALSE;

begin

MkDirDlg := TMkDirDlg.Create(Application);

try

if MkDirDlg.ShowModal = IDOK then;

if NewDirName <> '' then begin

Shopper1.FilesList;

RemFilesList.Clear;

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

RemFilesList.UpDate;

if RemFilesList.ItemIndex = -1 then Exit;

Shopper1.Selection := RemFilesList.ItemIndex;

end;

procedure TMainForm.RemFilesListDblClick(Sender: TObject);

var

Counter : Integer;

begin

if RemFilesList.ItemIndex = -1 then Exit;

Shopper1.Get :=

RemFilesList.Items.Strings[RemFilesList.ItemIndex];

RemFilesList.Clear;

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

RemFilesList.UpDate;

end;

procedure TMainForm.Shopper1UpDateProgress(Sender: TObject);

begin

Progress.Text := Concat(IntToStr(Shopper1.Progress),'%');

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

LocalFileList.Drive := LocalDirList.Drive;

LocalFileList.Directory := LocalDirList.Directory;

end;

procedure TMainForm.LocalDriveChange(Sender: TObject);

begin

LocalDirList.Drive := LocalDrive.Drive;

LocalFileList.Drive := LocalDirList.Drive;

end;

procedure TMainForm.LocalFileListDblClick(Sender: TObject);

var

Counter : Integer;

begin

if LocalFileList.ItemIndex = -1 then Exit;

Shopper1.Put := LocalFileList.Items[LocalFileList.ItemIndex];

LocalFileList.Clear;

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

LocalFileList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

LocalFileList.UpDate;

Shopper1.FilesList;

RemFilesList.Clear;

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

if Shopper1.FType = IMAGE then

begin

BinaryRBtn.Checked := TRUE;

AsciiRBtn.Checked := FALSE;

end;

if Shopper1.FType = ASCII then begin

BinaryRBtn.Checked := FALSE;

AsciiRBtn.Checked := TRUE;

end;

if Shopper1.Busy = TRUE then begin

MkDirBtn.Enabled := FALSE;

DelBtn.Enabled := FALSE;

RefreshBtn.Enabled := FALSE;

HelpBtn.Enabled := FALSE;

DisConBtn.Enabled := FALSE;

RemFilesList.Enabled := FALSE;

end else begin

MkDirBtn.Enabled := TRUE;

DelBtn.Enabled := TRUE;

RefreshBtn.Enabled := TRUE;

HelpBtn.Enabled := TRUE;

DisConBtn.Enabled := TRUE;

RemFilesList.Enabled := TRUE;

end;

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

RemFilesList.UpDate;

end;

procedure TMainForm.AbortBtnClick(Sender: TObject);

begin

Shopper1.Abort;

end;

procedure TMainForm.CancelBtnClick(Sender: TObject);

begin

Shopper1.Cancel;

end;

procedure TMainForm.Shopper1ChangeInfo(Sender: TObject);

begin

StatusMemo.Lines.Add(Shopper1.Info);

end;

procedure TMainForm.SiteBtnClick(Sender: TObject);

begin

Shopper1.SiteFtp;

end;

end.

Previous Table of Contents Next

Products | Contact Us | About Us | Privacy | Ad Info | Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.

All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

Brief Full Advanced Search

Search Tips

To access the contents, click the chapter and section titles.

Kick Ass Delphi Programming

(Publisher: The Coriolis Group)

Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin ISBN: 1576100448

Publication Date: 09/01/96

Search this book:

Previous Table of Contents Next

Before you connect to an FTP server, FTPCLI requires that you enter the name of the FTP server, your user name, and your password into the HostInput, UserInput, and

PasswordInput editboxes, respectively. In the case of anonymous login, enter “anonymous” in the UserInput editbox and your email address into the PasswordInput editbox. If you want to access a site that requires an account name, you’ll have to add an extra editbox and modify Shopper to send the ACCT command. To avoid having to type in the same information repeatedly, use the published properties to set the login information as shown previously in Figure 5.2.

Using the information you enter, the Shopper1.Start method calls GetHost to open the connection to the remote host. If this fails, WSAErrorMsg displays the possible cause of the problem, and Status is set to Failure. Otherwise, Status is set to Success. If the connection succeeds, Start calls FTPCommand to send USER, PASS, SYST, and PWD commands—in that sequence—with their appropriate arguments. Start then starts a data connection to transfer the listing of the remote host’s directories and files, using GetPort to set up the data port for the connection.

To retrieve the directory listing, Start sends the LIST command through FTPCommand. The result is stored for a later call to Decode to parse for directories and files. The mechanics of parsing are simple, but the mapping of the directories and files varies between systems. The parser in FTPCLI works well with servers that run on Unix and look-alikes. For other systems, the parser may occasionally return garbled directory listings.

Decode checks the first character of each line in FTPFILE.TMP for a ‘d’, which denotes a directory, or the first 2 characters ‘-’ and ‘r’ which denote a file. When a ‘d’ character is found, it is stripped, and the line is scanned for the directory name and then converted to the familiar

\ddd format. The backslash tells FTPCLI that this is a directory. Likewise, in the case of a file, the ‘-’ and ‘r’ characters are removed, and the line is scanned for the name, time, date, and file size, which are chopped into substrings. These substrings are rearranged to form an acceptable string for viewing in FTPCLI’s listbox, as shown in Figure 5.4.

Go!

Keyword

---Go!

FIGURE 5.4 FTPCLI application with the directory listing of files from the remote FTP host.

The FRemFiles.Add method in Decode reads each line, formats it into a string, and adds it to the FRemFiles property. FRemFiles is a string list, derived from the TStringList class, created by the TShopper.Create constructor. FTPCLI accesses this string list through the RemoteFiles public property. After Shopper1.Start has executed successfully, FTPCLI calls the following code to add the list of directories and files to RemFilesList listbox:

for Counter := 0 to Shopper1.RemoteFiles.Count-1 do

RemFilesList.Items.Add(Shopper1.RemoteFiles.Strings[Counter]);

To end our business with the FTP server, we need to kill the connection by sending a QUIT command. Clicking on the Close button calls Shopper1.Quit and terminates the session as shown here:

procedure TMainForm.DisConBtnClick(Sender: TObject);

begin try

Shopper1.Finish; {Quit server}

finally

AbortBtn.Enabled := FALSE;

SiteBtn.Enabled := FALSE;

DisConBtn.Enabled := FALSE;

ViewBtn.Enabled := FALSE;

HelpBtn.Enabled := FALSE;

DelBtn.Enabled := FALSE;

CancelBtn.Enabled := FALSE;

MkDirBtn.Enabled := FALSE;

RefreshBtn.Enabled := FALSE;

ConnectBtn.Enabled := TRUE;

ExitBtn.Enabled := TRUE;

RemFilesList.Clear;

RemoteHostP.Caption := 'Remote host : ';

RemoteIPP.Caption := 'Remote IP : ';

end;

end;

Previous Table of Contents Next

Products | Contact Us | About Us | Privacy | Ad Info | Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.

All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

Brief Full Advanced Search

Search Tips

To access the contents, click the chapter and section titles.

Kick Ass Delphi Programming

(Publisher: The Coriolis Group)

Author(s): Don Taylor, Jim Mischel, John Penman, Terence Goggin ISBN: 1576100448

Publication Date: 09/01/96

Search this book:

Previous Table of Contents Next

To keep Shopper’s methods direct and simple, I’ve chosen not to use buttons for downloading and uploading files. To download a file, for example, simply click on the desired file. The key to making this technique work is to create a new event. When you add the RemFilesList listbox to the main form, define a new OnDblClick event using the Events page in the Object Inspector. This event is handled by the

TMainForm.Rem FilesListDblClick procedure. The code fragment shows that in response to the event, Shopper1.Get is assigned a file name.

procedure TMainForm.RemFilesListDblClick(Sender: TObject);

begin

if RemFilesList.ItemIndex = -1 then Exit;

Shopper1.Get :=

RemFilesList.Items.Strings[RemFilesList.ItemIndex];

end;

Inside the Shopper component, the Get property passes the file name as Name to Retrieve. To ensure that the file is sent and stored correctly, SetUpFileTransfer checks the file’s extension. For a binary file (such as .EXE, .DLL, and ZIP), SetUpFileTransfer tells FTPCommand to send the TYPE IMAGE command, instructing the server to send the file as a stream of contiguous bytes. For non-binary files, SetUpFileTransfer employs the TYPE A command. After the FTP server acknowledges the TYPE command, SetUpFileTransfer sends the RETR file name command through FTPCommand.

When you double click on a directory name such as ‘\DELPHI’, no download occurs.

Instead, SetUpFileTransfer calls ChangeDir to handle a directory change.

ChangeDir then calls FTPCommand, sending the CWD command, followed by the

‘\DELPHI’ string to the FTP server. If the server accepts the command, it returns a reply code of 250. ChangeDir next sends the LIST command, via FTPCommand, to update the remote files directory listbox. Finally, Decode creates a new directory listing for the changed directory.

Go!

Keyword

---Go!

Internally, the process of uploading a file is similar to downloading, and the

Shopper1.Put property accomplishes this task using its PutFile method. On the main form, to facilitate uploading a file from the client to the server, I derived the following listboxes: LocalDrive from TDriveComboBox, LocalDirList from

TDirectoryListBox, and LocalFileList from TFileListBox. Each of these listboxes are synchronized. When you select a different drive in LocalDrive, the contents of LocalDirList and LocalFileList are updated transparently. As with the RemFilesList listbox, I used the Events page in the Object Inspector to create a new OnDblClick event handler, TMainForm.LocalFileListDblClick, to handle a double click on a file in the LocalFileList listbox. A double click on the file you wish to upload tells

TMainForm.LocalFileListDblClick to call the Shopper1.Put method.

As written, FTPCLI uploads or downloads only a single file at a time. However, you can remedy this shortcoming by enabling the listboxes to handle multiple selections in the Object Inspector, and modifying the TShopper.SetUpFileTransfer and

TShopper.PutFile methods.