Шаг 41.
Пример использования компонента TNMFTP

    На этом шаге мы рассмотрим пример использования компонента TNMFTP.

    Как всегда создаем пустое приложение Delphi и помещаем в него компонент TPageControl. Оставляем место в нижней части формы для компонента ТМеmо, который мы будем использовать для ведения протокола. Сразу добавим компонент TNMFTP и компонент TOpenDialog, которые нам понадобятся позже. Зададим значение True для свойства ParseList компонента TNMFTP1. И не забудем добавить строку состояния, у которой свойству SimplePanel дадим значение True. В строке состояния будем отображать процесс загрузки или выгрузки файлов. Теперь перейдем к компоненту TPageControl и щелкнем на нем правой кнопкой мыши. Из появившегося контекстного меню выбираем команду New Page. Создаем три страницы (объекты TTabSheet), закладкам которых даем имена Соединение, Каталог и Передача файлов. На странице Каталог будут собраны все возможности работы с файлами и каталогами на удаленном компьютере. Передавать и получать файлы можно будет на странице Передача файлов. На странице Соединение, естественно, можно будет подключиться к FTP-ceрверу или разорвать соединение. Давайте начнем оформление со страницы Соединение. Добавим в нее три окна редактирования и к ним три метки с надписями FTP сервер, Имя пользователя и Пароль, обозначающих назначение каждого из трех окон. Зададим для свойства Text этих окон адрес FTP-сервера, например, ftp.demos.su, имя пользователя - anonymous и вымышленный пароль, например, user@host.ru. Правилом хорошего тона считается скрытие вводимых в качестве пароля символов, поэтому зададим свойству PasswordChar последнего окна редактирования значение "*", чтобы вводимые символы пароля отображались символом "звездочка".Теперь добавим две командные кнопки с надписями Подключиться и Отключиться и добавим в них следующие обработчики событий OnClick:

procedure TForm1.Button1Click(Sender: TObject);
//Подключиться
begin
  if not(NMFTP1.Connected) then
    begin
      NMFTP1.Vendor := NMOS_AUTO;
      NMFTP1.Host := Edit1.Text;
      NMFTP1.Timeout := 30000;
      NMFTP1.UserID := Edit2.Text;
      NMFTP1.Password := Edit3.Text;
      NMFTP1.Connect;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
//Отключиться
begin
  if NMFTP1.Connected then NMFTP1.Disconnect;
end;

    Когда вы щелкаете на первой кнопке, то сначала программа проверяет, не установлено ли уже соединение. Если соединения нет, то далее устанавливается значение NMOS_AUTO для свойства Vendor, что позволит автоматически определить при соединении производителя FTP-сервера, - если удастся. Величину свойства Timeout возможно придется подбирать опытным путем. Для начала можно задать этому свойству значение 30000 - 30 секунд, Свойству Host присваивается имя сервера или его IP-адрес из поля редактирования Edit1. Свойство UserID получает значение из второго поля редактирования - это имя пользователя и, наконец, из компонента Edit3 берется значение пароля и присваивается свойству Password.

    Вторая кнопка, названная Отключиться, разрывает установленное соединение. Третья кнопка, названная Инициализация соединения, вызывает метод Reinitialize. В обработчик события OnClick этой кнопки добавляем следующий код:

procedure TForm1.Button3Click(Sender: TObject);
//Инициализация соединения
begin
  ShowMessage('После  инициализации нажмите кнопку "Регистрация"');
  NMFTP1.Reinitialize;
end;

    Окно сообщения, вызываемое в этом обработчике, напоминает вам, что после инициализации соединения необходимо зарегистрироваться. Поэтому после нажатия на эту кнопку вам нужно нажать на следующую кнопку под названием Регистрация. В обработчик события OnClick этой кнопки добавляем следующий код:

procedure TForm1.Button4Click(Sender: TObject);
//Регистрация
var
  AnID, APass: String;
begin
  if InputQuery('Зарегистрируйтесь', 'Введите имя пользователя', AnID) then
    if  InputQuery('Зарегистрируйтесь', 'Введите  пароль', APass)   then
    begin
      NMFTP1.DoCommand('USER '+AnID);
      NMFTP1.DoCommand('PASS '+APass);
    end;
end;

    Здесь нужно заметить, что не на всяком сервере вам удастся выполнить метод DoCommand. Внешний вид этой страницы смотрите на рисунке 1.


Рис.1. Первая страница приложения клиента FTP

    Теперь перейдем ко второй странице, изображенной на рисунке 2, названной нами именем Каталог.


Рис.2. Вторая страница приложения клиента FTP

    Добавим сюда семь командных кнопок и один компонент TStringGrid. В компонент TStringGrid будем выводить содержимое текущего каталога. Командные кнопки озаглавим следующим образом: Содержимое каталога, Сменить каталог, Создать каталог, Удалить каталог, Текущий каталог, Переименовать файл и Удалить файл. Все эти кнопки выполняют возможные в сервисе FTP операции над файлами и каталогами на удаленном компьютере. Назначение кнопок понятно из названия. Нажатие на кнопку Текущий каталог вызывает окно, в котором показывается имя текущего каталога на удаленной машине. Обработчики событий OnClick для этих кнопок смотрите в листинге примера.

    Компонент TStringGrid заполняется из обработчика события OnSucces, вызываемого при успешном завершении любой команды. В обработчике этого события используется оператор Case, в котором есть соответствующий командный блок для команды List (см. листинг). В компоненте TStringGrid заполняются четыре столбца, которым даются названия Имя файла, Размер файла, Дата изменения, Атрибуты. В эти столбцы выводятся значения свойств Name, Size, ModifDate и Attribute объекта TFTPDirectoryList. После этого в поле мемо добавляется строка об успешном выполнении метода List.

    Перейдем теперь к третьей странице. Добавим на нее шесть командных кнопок и группу из трех радиокнопок, соответствующих методам передачи файлов. Внешний вид этой страницы приведен на рисунке 3.


Рис.3. Третья страница приложения клиента FTP

    Назначение командных кнопок видно из их названий: две кнопки используют два метода загрузки файлов, и четыре кнопки - четыре метода выгрузки файлов на сервер. Обработчики событий OnClick для этих кнопок смотрите в тексте программы. Во всех обработчиках вызывается метод Execute компонента OpenDialog. В случае его успешного завершения, т.е. когда выбрано имя файла, выполнение метода продолжается. В соответствии с выбранной радиокнопкой вызывается метод Mode, определяющий способ передач файлов. После этого вызывается соответствующий метод загрузки или выгрузки файлов.

    В тексте программы остались нерассмотренными обработчики событий OnAuthenticationFailed, OnAuthenticationNeeded, OnConnect, OnDisconnect, OnFailure, OnPacketSent, OnPacketRecvd, OnSuccess, OnTransactionStart, OnTransactionStop, OnUnSupportedFunction компонента TNMFTP.

    Событие OnAuthenticationFailed вызывается при неудачной попытке регистрации, когда заданы неверные имя пользователя или пароль, или эти значения не соответствуют друг другу. В нашем случае, после неудачной регистрации программа, вызвав функцию MessageDlg, выдает окно диалога, в котором спрашивается, будете вы повторять попытку регистрации или нет. В случае положительного ответа последовательно, два раза вызывается функция InputQuery для ввода имени пользователя и пароля. Введенные значения присваиваются соответствующим свойствам компонента TNMFTP, после этого параметру Handled присваивается значение True, что позволит компоненту повторить попытку регистрации.

    Событие OnAuthenticationNeeded происходит, если не задано имя пользователя или пароль. В этом случае пользователю дается возможность в окне диалога функции InputQuery ввести недостающие значения. Если пользователь их вводит, то параметр Handled получает значение True, и компонент выполнит попытку регистрации. Если пользователь откажется ввести данные, то указанному параметру будет присвоено значение False, будет возбуждена исключительная ситуация, и соединение будет оборвано.

    Обработчик события OnConnect вызывается после успешного установления связи с удаленным компьютером, OnDisconnect - после разрыва соединения. Методы OnTransactionStart и OnTransactionStop вызывают методами List, NList и методами загрузки и выгрузки файлов при начале и окончании процесса.

    Событие OnFailure происходит, когда в процессе выполнения одной из команд FTP происходит ошибка. Обработчик этого события устроен просто: в операторе Case производится определение команды, вызвавшей ошибку, и в поле мемо выводится соответствующее сообщение об ошибке.

    Обработчики событий OnPacketSent и OnPacketRecvd вызываются при выгрузке или загрузке данных. В нашем примере обработчики этих событий выводят в строку состояния количество переданных данных в байтах, используя для этого свойства BytesSent, BytesRecvd и BytesTotal.

    Событие OnSuccess генерируется в случае успешного выполнения команды. Аналогично обработчику события OnFailure эта процедура выводит сообщения об успешном завершении команды. Только в случае команды List заполняется информацией о каталоге компонент TStringGrid.

    Последний из рассматриваемых обработчиков - OnUnSupportedFunction. Вызывается он при попытке выполнить команду, которая не поддерживается данным FTP-сервером. Эта процедура просто информирует пользователя о невозможности выполнить команду.

    Текст программы приводится ниже.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Psock, NMFtp, Grids, ExtCtrls;

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    Memo1: TMemo;
    NMFTP1: TNMFTP;
    OpenDialog1: TOpenDialog;
    StatusBar1: TStatusBar;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Button10: TButton;
    Button11: TButton;
    StringGrid1: TStringGrid;
    Button12: TButton;
    Button13: TButton;
    Button14: TButton;
    Button15: TButton;
    Button16: TButton;
    Button17: TButton;
    RadioGroup1: TRadioGroup;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure NMFTP1Success(Trans_Type: TCmdType);
    procedure Button12Click(Sender: TObject);
    procedure Button13Click(Sender: TObject);
    procedure Button14Click(Sender: TObject);
    procedure Button15Click(Sender: TObject);
    procedure Button16Click(Sender: TObject);
    procedure Button17Click(Sender: TObject);
    procedure NMFTP1Failure(var Handled: Boolean; Trans_Type: TCmdType);
    procedure NMFTP1AuthenticationFailed(var Handled: Boolean);
    procedure NMFTP1AuthenticationNeeded(var Handled: Boolean);
    procedure NMFTP1Connect(Sender: TObject);
    procedure NMFTP1PacketSent(Sender: TObject);
    procedure NMFTP1TransactionStart(Sender: TObject);
    procedure NMFTP1TransactionStop(Sender: TObject);
    procedure NMFTP1UnSupportedFunction(Trans_Type: TCmdType);
    procedure NMFTP1Disconnect(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
//Подключиться
begin
  if not(NMFTP1.Connected) then
    begin
      NMFTP1.Vendor := NMOS_AUTO;
      NMFTP1.Host := Edit1.Text;
      NMFTP1.Timeout := 30000;
      NMFTP1.UserID := Edit2.Text;
      NMFTP1.Password := Edit3.Text;
      NMFTP1.Connect;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);
//Отключиться
begin
  if NMFTP1.Connected then NMFTP1.Disconnect;
end;

procedure TForm1.Button3Click(Sender: TObject);
//Инициализация соединения
begin
  ShowMessage('После  инициализации нажмите кнопку "Регистрация"');
  NMFTP1.Reinitialize;
end;

procedure TForm1.Button4Click(Sender: TObject);
//Регистрация
var
  AnID, APass: String;
begin
  if InputQuery('Зарегистрируйтесь', 'Введите имя пользователя', AnID) then
    if  InputQuery('Зарегистрируйтесь', 'Введите  пароль', APass)   then
    begin
      NMFTP1.DoCommand('USER '+AnID);
      NMFTP1.DoCommand('PASS '+APass);
    end;
end;

procedure TForm1.Button5Click(Sender: TObject);
//Содержимое каталога
begin
  NMFTP1.List;
end;

procedure TForm1.Button6Click(Sender: TObject);
//Сменить каталог
var
  TheDir: String;
begin
  if InputQuery('Сменить каталог', 'Введите имя каталога', TheDir) then
    NMFTP1.ChangeDir(TheDir);
end;

procedure TForm1.Button7Click(Sender: TObject);
//Создать каталог
var
  TheDir: String;
begin
  if InputQuery('Создание каталога', 'Введите имя каталога',TheDir) then
    NMFTP1.MakeDirectory(TheDir);
end;

procedure TForm1.Button8Click(Sender: TObject);
//Удаление каталога
var
  TheDir: String;
begin
  if InputQuery('Удаление каталога', 'Введите имя каталога', TheDir) then
    NMFTP1.RemoveDir(TheDir);
end;

procedure TForm1.Button9Click(Sender: TObject);
//Текущий каталог
begin
  ShowMessage(NMFTP1.CurrentDir); 
end;

procedure TForm1.Button10Click(Sender: TObject);
//Переименовать файл
var
  OldFile,NewFile: String;
begin
  if InputQuery('Переименование файла', 'Введите имя файла', OldFile) then
    if InputQuery ('Переименование файла', 'Ведите новое имя', NewFile) then
         NMFTP1.Rename(OldFile, NewFile);
end;

procedure TForm1.Button11Click(Sender: TObject);
//Удалить файл
var
  TheFile: String;
begin
  if InputQuery('Удаление файла', 'Введите имя файла', TheFile) then
      NMFTP1.Delete(TheFile);
end;

procedure TForm1.NMFTP1Success(Trans_Type: TCmdType);
var
  I: Integer;
begin
  case Trans_Type of
  cmdList:
    begin
     for I := 0 to (StringGrid1.ColCount - 1) do
         StringGrid1.Cols[I].Clear;
     StringGrid1.RowCount := NMFTP1.FTPDirectoryList.Name.Count;
     StringGrid1.ColCount := 4;
     StringGrid1.Cells[0, 0] := 'Имя файла';
     StringGrid1.Cells[1, 0] := 'Размер файла';
     StringGrid1.Cells[2, 0] := 'Дата изменения';
     StringGrid1.Cells[3, 0] := 'Атрибуты';
     for I := 0 to (NMFTP1.FTPDirectoryList.Name.Count - 1) do
        with NMFTP1.FTPDirectoryList do
        begin
          StringGrid1.Cells [0, I+1] := name[I];
          StringGrid1.Cells[1, I+1] := Size[I];
          StringGrid1.Cells[2, I+1] := ModifDate[I];
          StringGrid1.Cells [3, I+1] := Attribute[I];
        end;
     Memo1.Lines.Add('Вывод содержимого каталога - успешно');
    end;
  cmdChangeDir:
    begin
       Memo1.Lines.Add('Смена каталога - успешно');
       NMFTP1.List;
    end;
  cmdMakeDir:
    Memo1.Lines.Add('Создание каталога - успешно');
  cmdRemoveDir:
    Memo1.Lines.Add('Удаление каталога - успешно');
  cmdDelete:
    Memo1.Lines.Add('Удаление файла - успешно');
  cmdRename:
    Memo1.Lines.Add('Переименование файла - успешно');
  cmdReInit:
    Memo1.Lines.Add('Инициализация - успешно');
  cmdCurrentDir:
    Memo1.Lines.Add('Показать текущий каталог - успешно');
  end;
end;

procedure TForm1.Button12Click(Sender: TObject);
//Загрузить
var
  RemoteFile,LocalFile: String;
begin
  if InputQuery('Загрузка файла', 'Загрузить файл: ', RemoteFile) then
    if OpenDialog1.Execute then
     begin
       LocalFile := OpenDialog1.FileName;
       case RadioGroup1.ItemIndex of
         0: NMFTP1.Mode(MODE_ASCII);
         1: NMFTP1.Mode(MODE_IMAGE);
         2: NMFTP1.Mode(MODE_BYTE);
       end;
       NMFTP1.Download(RemoteFile, LocalFile);
     end;
end;

procedure TForm1.Button13Click(Sender: TObject);
//Загрузить (продолжить)
var
  RemoteFile, LocalFile: String;
begin
  if InputQuery('Продолжение загрузки файла', 
         'Загрузить файл: ',RemoteFile) then
    if OpenDialog1.Execute then
    begin
      LocalFile := OpenDialog1.FileName;
      case RadioGroup1.ItemIndex of
        0: NMFTP1.Mode(MODE_ASCII);
        1: NMFTP1.Mode(MODE_IMAGE);
        2: NMFTP1.Mode(MODE_BYTE);
      end;
      NMFTP1.DownloadRestore(RemoteFile, LocalFile);
    end;
end;

procedure TForm1.Button14Click(Sender: TObject);
//Выгрузить
var
  LocalFile, RemoteFile: String;
  F: File of Byte;
  FSize: Integer;
begin
  if OpenDialog1.Execute then
     if InputQuery('Выгрузка файла на сервер', 
         'Укажите имя файла на сервере', RemoteFile) then
     begin
        LocalFile := OpenDialog1.FileName;
        case RadioGroup1.ItemIndex of
          0: NMFTP1.Mode(MODE_ASCII);
          1: NMFTP1.Mode(MODE_IMAGE);
          2: NMFTP1.Mode(MODE_BYTE);
        end;
        AssignFile(F, LocalFile);
        Reset(F);
        FSize := FileSize(F);
        CloseFile(F);
        NMFTP1.Allocate(FSize);
        NMFTP1.Upload(LocalFile, RemoteFile);
     end;
end;

procedure TForm1.Button15Click(Sender: TObject);
//Выгрузить (продолжить)
var
  LocalFile, RemoteFile: String;
  FPosition: Integer;
  FPos: String;
begin
  if OpenDialog1.Execute then
  if InputQuery('Продолжение выгрузки файла на сервер', 
              'Введите имя файла на сервере', RemoteFile) then
    if InputQuery('Задание начальной позиции', 
           'Укажите начальную позицию в байтах: ', FPos) then
      begin
       FPosition := StrToInt(FPos);
       LocalFile := OpenDialog1.FileName;
       case RadioGroup1.ItemIndex of
         0: NMFTP1.Mode(MODE_ASCII);
         1: NMFTP1.Mode(MODE_IMAGE);
         2: NMFTP1.Mode(MODE_BYTE);
       end;
       NMFTP1.UploadRestore(LocalFile, RemoteFile, FPosition);
      end;
end;

procedure TForm1.Button16Click(Sender: TObject);
//Выгрузить (добавить)
var
 LocalFile, RemoteFile: String;
begin
  if OpenDialog1.Execute then
    if InputQuery('Выгрузка с добавлением файла на сервер', 
          'Укажите имя файла на сервере', RemoteFile) then
    begin
      LocalFile := OpenDialog1.FileName;
      case RadioGroup1.ItemIndex of
        0: NMFTP1.Mode(MODE_ASCII);
        1: NMFTP1.Mode(MODE_IMAGE);
        2: NMFTP1.Mode (MODE_BYTE);
      end;
      NMFTP1.UploadAppend(LocalFile, RemoteFile);
    end;
end;

procedure TForm1.Button17Click(Sender: TObject);
//Выгрузить (уникальное имя)
var
  LocalFile: String;
begin
  if OpenDialog1.Execute then
  begin
   LocalFile := OpenDialog1.FileName;
   case RadioGroup1.ItemIndex of
     0: NMFTP1.Mode(MODE_ASCII);
     1: NMFTP1.Mode(MODE_IMAGE);
     2: NMFTP1.Mode (MODE_BYTE);
   end;
   NMFTP1.UploadUnique(LocalFile);
  end;
end;

procedure TForm1.NMFTP1Failure(var Handled: Boolean; Trans_Type: TCmdType);
begin
case Trans_Type of
  cmdChangeDir: Memo1.Lines.Add('Ошибка смены каталога');
  cmdMakeDir: Memo1.Lines.Add('Ошибка создания каталога');
  cmdDelete: Memo1.Lines.Add('Ошибка удаления файла');
  cmdRemoveDir: Memo1.Lines.Add('Ошибка удаления каталога');
  cmdList: Memo1.Lines.Add('Ошибка просмотра каталога');
  cmdRename: Memo1.Lines.Add('Ошибка переименования файла');
  cmdUpRestore: Memo1.Lines.Add('Ошибка метода UploadRestore');
  cmdDownRestore: Memo1.Lines.Add('Ошибка метода DownloadRestore');
  cmdDownload: Memo1.Lines.Add('Ошибка метода Download');
  cmdUpload: Memo1.Lines.Add('Ошибка метода Upload');
  cmdAppend: Memo1.Lines.Add('Ошибка метода UploadAppend');
  cmdReInit: Memo1.Lines.Add('Ошибка метода Reinitialize');
  cmdAllocate: Memo1.Lines.Add('Ошибка метода Allocate');
  cmdNList: Memo1.Lines.Add('Ошибка метода NList');
  cmdDoCommand: Memo1.Lines.Add('Ошибка метода DoCommand');
  cmdCurrentDir: Memo1.Lines.Add('Ошибка метода CurrentDir');
end;

end;

procedure TForm1.NMFTP1AuthenticationFailed(var Handled: Boolean);
var
  ThePass, TheID: String;
begin
 if MessageDlg('Ошибка регистрации. Повторить попытку', 
       mtConfirmation, [mbYes, mbNo], 0) = mrYes then
 begin
   ThePass := NMFTP1.Password;
   TheID := NMFTP1.UserID;
   InputQuery ('Вторая попытка', 'Введите имя пользователя', TheID);
   InputQuery ('Вторая попытка', 'Введите пароль', ThePass);
   NMFTP1. Password := ThePass;
   NMFTP1.UserID := TheID;
   Handled := true;
 end;
end;

procedure TForm1.NMFTP1AuthenticationNeeded(var Handled: Boolean);
var
  APass,AnID: String;
begin
  if NMFTP1.Password = '' then
  begin
   if InputQuery('Ввод пароля', 'Введите пароль: ', APass) then
   begin
     NMFTP1.Password := APass;
     Handled := true;
   end
   else
     Handled := false;
  end;
  if NMFTP1.UserID ='' then
  begin
   if InputQuery('Ввод имени пользователя', 
         'Введите имя пользователя: ', AnID) then
   begin
      NMFTP1.UserID := AnID;
      Handled := true;
   end
   else
      Handled := false;
  end;
end;

procedure TForm1.NMFTP1Connect(Sender: TObject);
begin
  Memo1.Lines.Add('Соединились...');
end;

procedure TForm1.NMFTP1PacketSent(Sender: TObject);
begin
  StatusBar1.SimpleText := 'Отослано '+IntToStr(NMFTP1.BytesSent)+
   ' байт из '+IntToStr (NMFTP1.BytesTotal);
end;

procedure TForm1.NMFTP1TransactionStart(Sender: TObject);
begin
  Memo1.Lines.Add('Начинаем передачу данных.');
end;

procedure TForm1.NMFTP1TransactionStop(Sender: TObject);
begin
  Memo1.Lines.Add('Передача данных закончена.');
end;

procedure TForm1.NMFTP1UnSupportedFunction(Trans_Type: TCmdType);
begin
  case Trans_Type of
      cmdChangeDir: Memo1.Lines.Add('Команда ChangeDir не 
           поддерживается этим сервером');
      cmdMakeDir: Memo1.Lines.Add('Команда MakeDir не 
           поддерживается этим сервером');
      cmdDelete: Memo1.Lines.Add('Команда Delete не 
           поддерживается этим сервером');
      cmdRemoveDir: Memo1.Lines.Add('Команда RemoveDir не 
           поддерживается этим сервером');
      cmdList: Memo1.Lines.Add('Команда List не 
           поддерживается этим сервером');
      cmdRename: Memo1.Lines.Add('Команда Rename не 
           поддерживается этим сервером');
      cmdUpRestore: Memo1.Lines.Add('Команда UploadRestore не 
           поддерживается этим сервером');
      cmdDownRestore: Memo1.Lines.Add('Команда DownloadRestore не 
           поддерживается этим сервером');
      cmdDownload: Memo1.Lines.Add('Команда Download не 
           поддерживается этим сервером');
      cmdUpload: Memo1.Lines.Add('Команда Upload не 
           поддерживается этим сервером');
      cmdAppend: Memo1.Lines.Add('Команда UploadAppend не 
           поддерживается этим сервером');
      cmdReInit: Memo1.Lines.Add('Команда Reinitialize не 
           поддерживается этим сервером');
      cmdAllocate: Memo1.Lines.Add('Команда Allocate не 
           поддерживается этим сервером');
      cmdNList: Memo1.Lines.Add('Команда NList не 
           поддерживается этим сервером');
      cmdDoCommand: Memo1.Lines.Add('Команда DoCommand не 
           поддерживается этим сервером');
      cmdCurrentDir: Memo1.Lines.Add('Команда CurrentDir не 
           поддерживается этим сервером');
  end;
end;

procedure TForm1.NMFTP1Disconnect(Sender: TObject);
begin
   Memo1.Lines.Add('Соединение завершено...');
end;

end. 
Текст этого приложения можно взять здесь.

    На следующем шаге мы рассмотрим компонент TNMHTTP.




Предыдущий шаг Содержание Следующий шаг