На этом шаге мы рассмотрим пример использования компонента TNMNNTP.
Как всегда создаем новое приложение Delphi. Поскольку в этом сервисе возможностей достаточно много, и все они могут не поместиться на одной странице, то добавим на форму компонент TPageControl и создадим на нем три страницы с закладками Подключение, Просмотр и Отправка. Первая страница будет посвящена подключению к серверу новостей, на второй мы будем заниматься просмотром, а с третьей страницы отправлять сообщения в текущую группу новостей. Сразу поместим на форму компонент TNMNNTP, TOpenDialog и TStatusBar. Рассмотрим первую страницу. Добавим в нее три окна редактирования, командную кнопку и несколько меток. Изображение первой страницы приведено на рисунке 1.
Рис.1. Первая страница приложения
В первом окне редактирования будем вводить имя сервера новостей. Два оставшихся окна предназначаются для ввода имени пользователя и пароля, если в этом есть необходимость. Ниже приводится обработчик события OnClick единственной командной кнопки на этой странице, в котором происходит подключение к серверу новостей или отключение от него.
procedure TForm1.Button1Click(Sender: TObject); begin if NMNNTP1.Connected then NMNNTP1.Disconnect else begin if Edit1.Text <> '' then begin NMNNTP1.UserID := Edit2.Text; NMNNTP1.Password := Edit3.Text; end; NMNNTP1.Host := Edit1.Text; NMNNTP1.Connect; end; end;
Перейдем ко второй странице, приведенной на рисунке 2.
Рис.2. Вторая страница приложения
Для списка групп и списка сообщений группы заготовим два компонента списка. В нижней части страницы разместим три компонента мемо, в которые будем выводить заголовок сообщения, текст сообщения и имена вложенных в сообщение файлов. В трех компонентах TEdit, расположенных выше, будем помещать данные об электронном адресе отправителя, теме сообщения, дате и времени отправки. Три командные кнопки Получить сообщение, Получить заголовок и Получить тело будут выполнять работу, соответствующую своим названиям. Обработчики событий OnClick этих кнопок приводятся ниже.
procedure TForm1.Button3Click(Sender: TObject); //Получить сообщение var S: String; I: Integer; begin if InputQuery('Загрузка сообщения', 'Укажите номер сообщения', S) then begin I := StrToIntDef (S, -1); if I <> -1 then NMNNTP1.GetArticle(I); end; end; procedure TForm1.Button4Click(Sender: TObject); //Загрузка заголовка сообщения var S: String; I: Integer; begin if InputQuery('Загрузка заголовка сообщения', 'Укажите номер сообщения', S) then begin I := StrToIntDef(S, -1); if I <> -1 then NMNNTP1.GetArticleHeader(I); end; end; procedure TForm1.Button5Click(Sender: TObject); //Текст сообщения var S: String; I: Integer; begin if InputQuery('Загрузка текста сообщения', 'Задайте номер сообщения', S) then begin I := StrToIntDef(S, -1); if I <> -1 then NMNNTP1.GetArticleBody(I); end; end;
Во всех трех процедурах выводится окно диалога, в котором вы должны ввести номер интересующей вас статьи, далее введенное значение приводится к целому типу и вызывается соответствующий метод компонента TNMNNTP.
Но перед тем, как загружать текст сообщения, нам нужно выбрать группу и загрузить список сообщений этой группы. Эти действия выполняет обработчик события OnClick компонента TListBox, который приводится ниже.
procedure TForm1.ListBox1Click(Sender: TObject); begin if ListBox1.ItemIndex <> -1 then begin ListBox2.Clear; NMNNTP1.SetGroup(ListBox1.Items[ListBox1.ItemIndex]); Label14.Caption := 'Сообщения отправляются в текущую группу новостей: '+ NMNNTP1.SelectedGroup; end; if NMNNTP1.Posting then Label15.Caption := 'Отправлять сообщения в эту группу разрешено' else Label15.Caption := 'Отправлять сообщения в эту группу запрещено'; end;
Эта процедура очищает содержимое компонента ListBox2, т.е. список сообщений текущей группы новостей. Затем для задания текущей группы вызывается метод SetGroup. Далее присваиваются надписи двум меткам с третьей страницы нашего приложения. Первая строка напоминает нам имя текущей группы, во второй сообщается о возможности или невозможности отправки сообщений в группу.
На форме еще имеется командная кнопка Сменить каталог. При нажатии на эту кнопку вызывается следующая процедура:
procedure TForm1.Button6Click(Sender: TObject); //Сменить каталог var S: String; begin if SelectDirectory (S, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then begin Label7.Caption:='Каталог для выгрузки присоединенных файлов:'+S; NMNNTP1.AttachFilePath := S; end; end;
В ней вы можете изменить имя каталога, в который будут помещаться вложенные файлы. После успешного выбора каталога имя нового каталога будет выводиться в соседнюю метку, в данном случае метку Label7. Однако вложенные в сообщение файлы будут извлекаться только в том случае, если будет отмечен флажок с именем Извлекать присоединенные файлы?. Обработчик события OnClick этого компонента выглядит следующим образом:
procedure TForm1.CheckBox1Click(Sender: TObject); //Разрешение извлекать присоединенные файлы begin if CheckBox1.Checked then NMNNTP1.ParseAttachments := true else NMNNTP1.ParseAttachments := false; end;
У нас остались не рассмотренными на этой странице две кнопки с надписями Получить список сообщений группы и Отменить операцию. Первая попросту вызывает метод GetArticleList со значением первого параметра равным True, который загружает полный список статей выбранной группы. Мы сами должны позаботиться о том, чтобы заголовки этих статей "не пропали" и были выведены в отведенное для них место, а именно в список ListBox2. Для этого нужно воспользоваться обработчиком события ОnНеаderList, который вызывается в процессе выполнения метода GetArticleList каждый раз при загрузке очередной статьи. Обработчик этот состоит из одной строки и приведен ниже.
procedure TForm1.NMNNTP1HeaderList(Sender: TObject); begin ListBox2.Items.Add('['+IntToStr(NMNNTP1.HeaderRecord.PrArticleID)+'] Subject: '+ NMNNTP1.HeaderRecord.PrSubject); end;
Обработчик нажатия на кнопку Получить список сообщений группы выглядит следующим образом:
procedure TForm1.Button2Click(Sender: TObject); //Получить список сообщений группы begin NMNNTP1.GetArticleList (true, 0); Label6.Caption := 'Читаем сообщения группы '+NMNNTP1.SelectedGroup+' с № '+ IntToStr(NMNNTP1.LoMessage)+' no № '+IntToStr(NMNNTP1.HiMessage); end;
И, наконец, последняя кнопка на этой странице вызывает метод Abort, отменяющий текущую операцию.
Перейдем теперь на третью страницу нашего приложения.
Рис.3. Третья страница приложения
Здесь приводится напоминание о том, что отправлять сообщения можно только в текущую группу, сообщается, разрешено или нет посылать сообщения в текущую группу, и выводится имя текущей группы. Кроме того на форме имеются два окна редактирования, мемо-поле, список, две командные кнопки и метки, поясняющие назначение перечисленных компонентов. В окнах редактирования указываем свой e-mail и тему сообщения. В поле мемо набираем текст письма. С помощью кнопки Присоединить файл вызываем окно диалога и добавляем необходимое количество файлов, имена которых отображаются в соседнем с кнопкой списке. Когда поля ввода данных на этой странице заполнены, можно нажимать кнопку Отправить, что приведет к вызову следующей процедуры:
procedure TForm1.Button9Click(Sender: TObject); //Отправить begin NMNNTP1.PostAttachments.Text := ListBox3.Items.Text; NMNNTP1.PostBody.Text := Memo4.Text; with NMNNTP1.PostRecord do begin PrFromAddress := Edit7.Text; PrReplyTo := Edit7.Text; PrSubject := Edit8.Text; PrNewsGroups := NMNNTP1.SelectedGroup; end; NMNNTP1.PostHeader.Values['Organization' ]:= 'Клуб любителей Delphi'; NMNNTP1.PostArticle; end;
Мы видим, что здесь заполняются данными необходимые свойства компонента TNMNNTP и вызывается метод PostArticle.
Нам осталось обсудить обработчики нескольких событий компонента TNMNNTP, и можно приступать к изготовлению программы. Рассмотрим процедуры обработки событий в алфавитном порядке.
Обработчик события OnAbort, которое происходит при вызове метода Abort, выводит соответствующее сообщение в строку состояния.
procedure TForm1.NMNNTP1Abort(Sender: TObject); begin StatusBar1.SimpleText := 'Текущее действие отменяется'; end;
Следующая процедура обрабатывает событие OnArticle, что происходит в случае успешного выполнения метода GetArticle. Видно, что в процедуре попросту расписываются соответствующие компоненты полученной от сервера новостей информации по заказанной статье: выводится текст сообщения, его заголовок, список присоединенных файлов, адрес отправителя, тема сообщения, время и дата публикации сообщения на сервере. И, кроме того, в двух метках, поясняющих назначение соседних компонентов, выводится номер текущего сообщения.
procedure TForm1.NMNNTP1Article(Sender: TObject); begin Memo2.Text:=NMNNTP1.Body.Text; Memo1.Text:=NMNNTP1.Header.Text; Memo3.Text:=NMNNTP1.Attachments.Text; Edit4.Text:=NMNNTP1.HeaderRecord.PrFromAddress; Edit5.Text:=NMNNTP1.HeaderRecord.PrSubject; Edit6.Text:=NMNNTP1.HeaderRecord.PrTimeDate; Label11.Caption := 'Заголовок сообщения №'+IntToStr(NMNNTP1.CurrentArticle); Label12.Caption := 'Текст сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end;
Событие OnAuthenticationFailed происходит при ошибке регистрации, о чем вы получите сообщение:
procedure TForm1.NMNNTP1AuthenticationFailed(Sender: TObject); begin ShowMessage('Ошибка регистрации'); end;
Событие OnAuthenticationNeeded генерируется в том случае, когда для работы с сервером новостей требуется регистрация, а одно из свойств UserID или Password оказалось не заданным, т.е. пустым. Очевидно, что обработчик этого события можно и нужно использовать для повторной регистрации. В приведенном ниже обработчике пользователю предлагается ввести имя или пароль, в зависимости от того, чего не хватает. Далее введенное значение присваивается соответствующему свойству компонента, а параметру Handled присваивается значение True, чтобы повторить попытку регистрации.
procedure TForm1.NMNNTP1AuthenticationNeeded(var Handled: Boolean); var AnID, APass: String; begin if NMNNTP1.UserID = '' then begin if InputQuery('Нужно зарегистрироваться','Введите имя пользователя', AnID) then begin NMNNTP1.UserID := AnID; Handled := true; end; end; if NMNNTP1.Password = '' then begin if InputQuery('Нужно зарегистрироваться', 'Введите пароль', APass) then begin NMNNTP1.Password := APass; Handled := true; end; end; end;
Следующая процедура обрабатывает событие OnBody, которое происходит в случае успешного выполнения метода GetArticleBody. Этот обработчик аналогичен обработчику события OnArticle, приведенному выше. Похожим на эти процедуры будет и обработчик события OnHeader, вызываемого после успешного выполнения метода GetArticleHeader. Поэтому мы приведем его следом за обработчиком события OnBody.
procedure TForm1.NMNNTP1Body(Sender: TObject); begin Memo2.Text := NMNNTP1.Body.Text; Memo3.Text := NMNNTP1.Attachments.Text; Label12.Caption := 'Текст сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end; procedure TForm1.NMNNTP1Header(Sender: TObject); begin Memo1.Text := NMNNTP1.Header.Text; Edit4.Text := NMNNTP1.HeaderRecord.PrFromAddress; Edit5.Text := NMNNTP1.HeaderRecord.PrSubject; Edit6.Text := NMNNTP1.HeaderRecord.PrTimeDate; Label11.Caption := 'Заголовок сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end;
Следующая процедура - обработчик события OnConnect. Событие наступает при успешном установлении связи с сервером новостей. В этой процедуре выполняются естественные для этой ситуации действия: выводится текст "Соединились" в строку состояния, вызывается метод GetGroupList. Поскольку загружается список групп новостей долго, то пользователю перед вызовом этого метода выводится сообщение "Начинаем загрузку имен групп новостей. Ждите". После загрузки списка групп их имена в цикле for записываются в список ListBox1.
procedure TForm1.NMNNTP1Connect(Sender: TObject); var I: Integer; begin StatusBar1.SimpleText := 'Соединились'; ShowMessage('Начинаем загрузку имен групп новостей. Ждите'); NMNNTP1.GetGroupList; for I := 0 to (NMNNTP1.GroupList.Count - 1) do ListBox1.Items.Add(NthWord(NMNNTP1.GroupList[I], ' ', 1)); end;
Когда происходит событие OnDisconnect, т.е., когда произошел разрыв связи с сервером, выводится соответствующее сообщение в строку состояния.
procedure TForm1.NMNNTP1Disconnect(Sender: TObject); begin StatusBar1.SimpleText := 'Отключились'; end;
Событие OnGroupSelectRequired генерируется в случае, когда делается попытка выполнить метод, для работы которого должна быть установлена текущая группа, а этого сделано не было. Эти методы включают в себя методы GetArticle, GetArticleBody, GetArticleHeader, GetArticleList и PostArticle. Будет естественно в процедуре обработки этого события дать возможность пользователю ввести имя нужной группы, установить ее в качестве текущей и повторить вызов потерпевшего неудачу метода. Текст процедуры приводится ниже.
procedure TForm1.NMNNTP1GroupSelectRequired(var Handled: Boolean); var S: String; begin if InputQuery('He выбрана группа новостей', 'Выбрать следующую группу: ', S) then begin NMNNTP1.SetGroup (S); Handled := true; end; end;
Обработчик события OnHeaderList мы рассматривали выше. Следующее событие происходит, когда делается попытка загрузки данных несуществующего сообщения. Процедура выводит сообщение об ошибке:
procedure TForm1.NMNNTP1InvalidArticle(Sender: TObject); begin ShowMessage('Указан неверный номер статьи'); end;
События OnPosted и OnPostFailed, наступающие при успешной отправке сообщения и в случае неудачи, только выводят соответствующие сообщения.
procedure TForm1.NMNNTP1Posted(Sender: TObject); begin StatusBar1.SimpleText := 'Сообщение успешно отослано'; end; procedure TForm1.NMNNTP1PostFailed(Sender: TComponent; Errno: Word; Errmsg: String); begin ShowMessage('Ошибка при отправке сообщения: '+Errmsg+' код ошибки '+ IntToStr (Errno)); end;
Листинг примера приводится ниже.
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls, Psock, NMNNTP, QDialogs, FileCtrl; type TForm1 = class(TForm) PageControl1: TPageControl; TabSheet1: TTabSheet; TabSheet2: TTabSheet; TabSheet3: TTabSheet; NMNNTP1: TNMNNTP; OpenDialog1: TOpenDialog; StatusBar1: TStatusBar; Edit1: TEdit; Panel1: TPanel; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Button1: TButton; Label5: TLabel; ListBox1: TListBox; Button2: TButton; Label6: TLabel; ListBox2: TListBox; Button3: TButton; Button4: TButton; Button5: TButton; Label7: TLabel; Button6: TButton; CheckBox1: TCheckBox; Label8: TLabel; Label9: TLabel; Label10: TLabel; Edit4: TEdit; Edit5: TEdit; Edit6: TEdit; Label11: TLabel; Memo1: TMemo; Label12: TLabel; Memo2: TMemo; Label13: TLabel; Memo3: TMemo; Button7: TButton; Label15: TLabel; Panel2: TPanel; Label14: TLabel; Label16: TLabel; Edit7: TEdit; Label17: TLabel; Edit8: TEdit; Label18: TLabel; Label19: TLabel; Memo4: TMemo; Label20: TLabel; Button8: TButton; Button9: TButton; ListBox3: TListBox; procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure ListBox1Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure CheckBox1Click(Sender: TObject); procedure NMNNTP1HeaderList(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Button9Click(Sender: TObject); procedure NMNNTP1Abort(Sender: TObject); procedure NMNNTP1Article(Sender: TObject); procedure NMNNTP1AuthenticationFailed(Sender: TObject); procedure NMNNTP1AuthenticationNeeded(var Handled: Boolean); procedure NMNNTP1Body(Sender: TObject); procedure NMNNTP1Header(Sender: TObject); procedure NMNNTP1Connect(Sender: TObject); procedure NMNNTP1Disconnect(Sender: TObject); procedure NMNNTP1GroupSelectRequired(var Handled: Boolean); procedure NMNNTP1InvalidArticle(Sender: TObject); procedure NMNNTP1Posted(Sender: TObject); procedure NMNNTP1PostFailed(Sender: TComponent; Errno: Word; Errmsg: String); procedure FormActivate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin if NMNNTP1.Connected then NMNNTP1.Disconnect else begin if Edit1.Text <> '' then begin NMNNTP1.UserID := Edit2.Text; NMNNTP1.Password := Edit3.Text; end; NMNNTP1.Host := Edit1.Text; NMNNTP1.Connect; end; end; procedure TForm1.Button3Click(Sender: TObject); //Получить сообщение var S: String; I: Integer; begin if InputQuery('Загрузка сообщения', 'Укажите номер сообщения', S) then begin I := StrToIntDef (S, -1); if I <> -1 then NMNNTP1.GetArticle(I); end; end; procedure TForm1.Button4Click(Sender: TObject); //Загрузка заголовка сообщения var S: String; I: Integer; begin if InputQuery('Загрузка заголовка сообщения', 'Укажите номер сообщения', S) then begin I := StrToIntDef(S, -1); if I <> -1 then NMNNTP1.GetArticleHeader(I); end; end; procedure TForm1.Button5Click(Sender: TObject); //Текст сообщения var S: String; I: Integer; begin if InputQuery('Загрузка текста сообщения', 'Задайте номер сообщения', S) then begin I := StrToIntDef(S, -1); if I <> -1 then NMNNTP1.GetArticleBody(I); end; end; procedure TForm1.ListBox1Click(Sender: TObject); begin if ListBox1.ItemIndex <> -1 then begin ListBox2.Clear; NMNNTP1.SetGroup(ListBox1.Items[ListBox1.ItemIndex]); Label14.Caption := 'Сообщения отправляются в текущую группу новостей: '+ NMNNTP1.SelectedGroup; end; if NMNNTP1.Posting then Label15.Caption := 'Отправлять сообщения в эту группу разрешено' else Label15.Caption := 'Отправлять сообщения в эту группу запрещено'; end; procedure TForm1.Button6Click(Sender: TObject); //Сменить каталог var S: String; begin if SelectDirectory (S, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then begin Label7.Caption:='Каталог для выгрузки присоединенных файлов:'+S; NMNNTP1.AttachFilePath := S; end; end; procedure TForm1.CheckBox1Click(Sender: TObject); //Разрешение извлекать присоединенные файлы begin if CheckBox1.Checked then NMNNTP1.ParseAttachments := true else NMNNTP1.ParseAttachments := false; end; procedure TForm1.NMNNTP1HeaderList(Sender: TObject); begin ListBox2.Items.Add('['+IntToStr(NMNNTP1.HeaderRecord.PrArticleID)+'] Subject: '+ NMNNTP1.HeaderRecord.PrSubject); end; procedure TForm1.Button2Click(Sender: TObject); //Получить список сообщений группы begin NMNNTP1.GetArticleList (true, 0); Label6.Caption := 'Читаем сообщения группы '+NMNNTP1.SelectedGroup+' с № '+ IntToStr(NMNNTP1.LoMessage)+' no № '+IntToStr(NMNNTP1.HiMessage); end; procedure TForm1.Button7Click(Sender: TObject); //Отменить операцию begin NMNNTP1.Abort; end; procedure TForm1.Button9Click(Sender: TObject); //Отправить begin NMNNTP1.PostAttachments.Text := ListBox3.Items.Text; NMNNTP1.PostBody.Text := Memo4.Text; with NMNNTP1.PostRecord do begin PrFromAddress := Edit7.Text; PrReplyTo := Edit7.Text; PrSubject := Edit8.Text; PrNewsGroups := NMNNTP1.SelectedGroup; end; NMNNTP1.PostHeader.Values['Organization' ]:= 'Клуб любителей Delphi'; NMNNTP1.PostArticle; end; procedure TForm1.NMNNTP1Abort(Sender: TObject); begin StatusBar1.SimpleText := 'Текущее действие отменяется'; end; procedure TForm1.NMNNTP1Article(Sender: TObject); begin Memo2.Text:=NMNNTP1.Body.Text; Memo1.Text:=NMNNTP1.Header.Text; Memo3.Text:=NMNNTP1.Attachments.Text; Edit4.Text:=NMNNTP1.HeaderRecord.PrFromAddress; Edit5.Text:=NMNNTP1.HeaderRecord.PrSubject; Edit6.Text:=NMNNTP1.HeaderRecord.PrTimeDate; Label11.Caption := 'Заголовок сообщения №'+IntToStr(NMNNTP1.CurrentArticle); Label12.Caption := 'Текст сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end; procedure TForm1.NMNNTP1AuthenticationFailed(Sender: TObject); begin ShowMessage('Ошибка регистрации'); end; procedure TForm1.NMNNTP1AuthenticationNeeded(var Handled: Boolean); var AnID, APass: String; begin if NMNNTP1.UserID = '' then begin if InputQuery('Нужно зарегистрироваться','Введите имя пользователя', AnID) then begin NMNNTP1.UserID := AnID; Handled := true; end; end; if NMNNTP1.Password = '' then begin if InputQuery('Нужно зарегистрироваться', 'Введите пароль', APass) then begin NMNNTP1.Password := APass; Handled := true; end; end; end; procedure TForm1.NMNNTP1Body(Sender: TObject); begin Memo2.Text := NMNNTP1.Body.Text; Memo3.Text := NMNNTP1.Attachments.Text; Label12.Caption := 'Текст сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end; procedure TForm1.NMNNTP1Header(Sender: TObject); begin Memo1.Text := NMNNTP1.Header.Text; Edit4.Text := NMNNTP1.HeaderRecord.PrFromAddress; Edit5.Text := NMNNTP1.HeaderRecord.PrSubject; Edit6.Text := NMNNTP1.HeaderRecord.PrTimeDate; Label11.Caption := 'Заголовок сообщения №'+IntToStr(NMNNTP1.CurrentArticle); end; procedure TForm1.NMNNTP1Connect(Sender: TObject); var I: Integer; begin StatusBar1.SimpleText := 'Соединились'; ShowMessage('Начинаем загрузку имен групп новостей. Ждите'); NMNNTP1.GetGroupList; for I := 0 to (NMNNTP1.GroupList.Count - 1) do ListBox1.Items.Add(NthWord(NMNNTP1.GroupList[I], ' ', 1)); end; procedure TForm1.NMNNTP1Disconnect(Sender: TObject); begin StatusBar1.SimpleText := 'Отключились'; end; procedure TForm1.NMNNTP1GroupSelectRequired(var Handled: Boolean); var S: String; begin if InputQuery('He выбрана группа новостей', 'Выбрать следующую группу: ', S) then begin NMNNTP1.SetGroup (S); Handled := true; end; end; procedure TForm1.NMNNTP1InvalidArticle(Sender: TObject); begin ShowMessage('Указан неверный номер статьи'); end; procedure TForm1.NMNNTP1Posted(Sender: TObject); begin StatusBar1.SimpleText := 'Сообщение успешно отослано'; end; procedure TForm1.NMNNTP1PostFailed(Sender: TComponent; Errno: Word; Errmsg: String); begin ShowMessage('Ошибка при отправке сообщения: '+Errmsg+' код ошибки '+ IntToStr (Errno)); end; procedure TForm1.FormActivate(Sender: TObject); begin Label7.Caption := 'Каталог для выгрузки присоединенных файлов: ' + NMNNTP1.AttachFilePath; if NMNNTP1.ParseAttachments = true then CheckBox1.Checked := true else CheckBox1.Checked := false; end; end.
На следующем шаге мы рассмотрим компонент TNMPOP3.