Показаны сообщения с ярлыком Delphi 7. Показать все сообщения
Показаны сообщения с ярлыком Delphi 7. Показать все сообщения

среда, 18 января 2017 г.

Delphi TWebBrowser Получить HTML

Сценарий

Использую в Delphi 7 компонент TWebBrowser для редактирования HTML.
В моем сценарии редактируется HTML-вариант почтового уведомления

Задача

получить отредактированный HTML

Перед решением

Сразу дам ссылки на вспомогательные материалы:

Варианты решения

Варианты - самые разнообразные. Не все у меня получились. Ссылки привожу. То, что сработало в моем случае - опишу отдельно ниже.



Какое решение подошло мне

Двухфазный способ:

1. при передаче значений в TWebBrowser добавлять теги <body> и </body>. У меня сработало, т.к. в шаблонах сообщений из не было

код:
'<body>'+AHtml+'</body>'

2. Получение результата делать таким кодом

(FWebBrowser.Document as IHTMLDocument2).body.innerHTML; 

Примечание: без первого этапа TWebBrowser обрезал стили, которые были в письме. 


вторник, 17 января 2017 г.

Delphi TWebBrowser - загрузить Html из строки

Окружение: Delphi 7

Задача

загрузить в компонент TWebBrowser Html из строки

Решение


procedure THTMLEdit.EditText(CONST HTMLCode: string);
var
  Doc: Variant;
begin
  if NOT Assigned(wbBrowser.Document) then
    wbBrowser.Navigate('about:blank');

  Doc := wbBrowser.Document;
  Doc.Clear;
  Doc.Write(HTMLCode);
  Doc.Close;
end;

Взял отсюда:
http://stackoverflow.com/questions/39773033/which-is-the-best-way-to-load-a-string-html-code-in-twebbrowser


Доп. информация

Еси Вы хотите узнать, как получить Html из TWebBrowser, Вам сюда:
Как получить отредактированный HTML из TWebBrowser 

пятница, 6 января 2017 г.

Delphi 7 Визуальный Html редактор

Понадобился визуальный Html-редактор для Delphi

Перерыл кучу ссылок. для моих нужд сгодился редактор на основе TWebBrowser.
Его можно переводить в режим редактирования

вот ссылка
http://www.samum2000.narod.ru/articles.html

автору - большое спасибо,

Но пришлось еще повозиться с загрузкой и выгрузкой Html в TWebBrowser.

Этим вопросам посвятил 2 отдельные статьи:
Delphi TWebBrowser - загрузить Html из строки
Delphi TWebBrowser Получить HTML


Ссылки по теме

Визуальный HTML редактор своими руками
http://www.interface.ru/home.asp?artId=2778

Простой HTML редактор
http://www.sql.ru/forum/995008/http://prostoy-html-redaktor

Fooling around with TWebbrowser
http://beensoft.blogspot.com/2006/01/fooling-around-with-twebbrowser.html


A Professional HTML Renderer You Will Use
https://www.codeproject.com/articles/32376/a-professional-html-renderer-you-will-use

WYSIWYG HTML Editor Component for Delphi [closed]
http://stackoverflow.com/questions/2146116/wysiwyg-html-editor-component-for-delphi

четверг, 21 января 2016 г.

FastReport формат числа с ведущими нулями (FastReport VCL)

Ситуация

Есть прилодение на Delphi 7 с FastReport 4. Клиент запросил, чтобы в печтаной форме документа выводились ведущие нули.
Задача словами клиента: Номер документа должен быть шестизначным.

Решение

Использовать внутри FastReport функцию формат в стиле Delphi

Пример Delphi 

str := Format('%.*d',[length, number]);
str := Format('%.*d',[3, 7]);
//str is '007'


Пример FastReport

[Format('%.*d',[6,<frxDBDataset1Order."NUMBER">])]

FastReport Number Format with Leading Zeros (FastReport VCL)

Problem


Delphi 7 Application with FastReport 4. I need field "document number" to be with leading zero in FastReport report.

Solution

Use FastReport Format Function in Delphi-style manner.

Delphi Example

str := Format('%.*d',[length, number]);
str := Format('%.*d',[3, 7]);
//str is '007'


FastReport Example

[Format('%.*d',[6,<frxDBDataset1Order."NUMBER">])]


пятница, 12 сентября 2014 г.

FastReport запуск дизайнера в рантайме для ускорения отладки (FastReport Run Designer in Runtime)

Окружение

Delphi 7, FastReport 4

Ситуация

Работаю со сложным проектом и сложными печатными формами (отчетами).
В какой-то момент понял, что при разработке макетов отчетов выполняю по кругу такие действия:
1. правка в дизайн тайме
2. проверка в рантайме

  • запуск программы
  • ввод логина/пароля
  • открытие нужной формы
  • поиск нужного документа
  • вызов пункта меню Печать
  • просмотр отчета, получившегося на выходе 
  • определение что еще нужно править, 
  • возврат к шагу 1

В этой схеме работы львиную долю времени занимают непродуктивные шаги: запуск программы/поиск документа/вызов меню печать. Очень захотелось исключить непродуктивные шаги.

Что захотелось сделать

Я подумал, что было бы классно: открыть в рантайме нужный документ открыть его макет и сразу же его дизайнерить.
и сразу же смотреть, что получается, без перезапуска программы.

По ходу решения задачи нашел 2 решения.


Решение 0. Самое простое

Тут идея проста как 3 копейки: нужно выполнить команду.

Report.DesignReport()

Но для этого нужно как-то эту команду вызвать, например, через кнопку или пункт меню в интерфейсе. А это мне не подходило, т.к. программа уже имела сложную инфраструктуру с динамически формирующимися пунктами меню и динамическим определением нужного макета отчета.

Соответственно, технически решение работающее, но не элегантное, поэтому я его сразу отмел. Но для очень простых задач оно подойдет.

Решение 1. Через событие OnPreview

Это решение удобно, если отчетов не очень много, и не составит труда вписать по одной строчке кода в событие OnPreview отчета. Такое решение подойдет для небольших проектов.

Суть решения

1. делаю вспомогательный юнит (модуль)

-------------------------------------

unit uUtilsFr;

interface
uses
  frxClass, frxPreview;

type
   TFastReportDesignReportButtonOnClickStubClass = class(TObject)
  public
    procedure OnClick(Sender: TObject);
  end;


procedure FastReportAddDesignButtonToPreviewForm(AReport: TfrxReport);

implementation
uses
  Buttons;

var
  lfxDesignReportButtonOnClickStub: TFastReportDesignReportButtonOnClickStubClass;

{ TFastReportDesignReportButtonOnClickStubClass }

procedure FastReportAddDesignButtonToPreviewForm(AReport: TfrxReport);
var
  lfrxPreviewForm: TfrxPreviewForm;
  lbtnDesign: TSpeedButton;
begin
  lfrxPreviewForm := TfrxPreviewForm(AReport.PreviewForm);

  lbtnDesign := TSpeedButton.Create(lfrxPreviewForm);
  lbtnDesign.OnClick := lfxDesignReportButtonOnClickStub.OnClick;
  lbtnDesign.Caption := 'Дизайнер';
  lbtnDesign.Width:= 66;

  lfrxPreviewForm.ToolBar.InsertControl(lbtnDesign);
end;

procedure TFastReportDesignReportButtonOnClickStubClass.OnClick(
  Sender: TObject);
begin
  TfrxPreviewForm(TSpeedButton(Sender).Owner).Report.DesignReport;
end;

initialization
  lfxDesignReportButtonOnClickStub := TFastReportDesignReportButtonOnClickStubClass.Create;

finalization
  lfxDesignReportButtonOnClickStub.Free;
end.

-------------------------------------

2. В компоненте отчета в событие OnPreview добавляю строчку

FastReportAddDesignButtonToPreviewForm(TfrxReport(sender));

(тут по сути вызываю функцию из созданного в пункте 1 модуля)

Что получается на выходе
В окне превью отчета появляется кнопка "Дизайнер", которая открывает дизайнер отчета.

Решение 2. Через собственный компонент Экспорта

Это решение подойдет для крупных проектов, когда вы не хотите заморачиваться с ручной обработкой каждого отчета, а хотите один раз прописать настройку и дизайнер будет доступен из всех отчетов.

Идея решения: делаю свой фиктивный компонент экспорта отчетов. Суть экспорта: открытие дизайнера.

Сложность решения: нужен будет свой компонент (то есть я предполагаю, что понятия создания/регистрации компонентов в Delphi вам знакомы).

Суть решения

1. Делаем компонент


unit ufrxExportDesign;

interface

uses
  Classes, Controls, Dialogs, frxClass;

type
  TfrxExportDesign = class(TfrxCustomExportFilter)
  public
    constructor Create(AOwner: TComponent); override;

    class function GetDescription: String; override;
    function ShowModal: TModalResult; override;


  end;

implementation

{ TfrxPDFExport }

constructor TfrxExportDesign.Create(AOwner: TComponent);
begin
  inherited;
  ShowDialog:= true;
end;

class function TfrxExportDesign.GetDescription: String;
begin
  Result := 'Run Designer';
end;

function TfrxExportDesign.ShowModal: TModalResult;
begin
  Report.DesignReport();
  Result:= mrCancel;
end;

end.



2. регистрируем компонент. 

Тут код я не привожу, т.к. это будет зависеть от вашей инфраструктуры проектов

3. Кидаем компонент на форму с отчетами
(по сути достаточно одного компонента на приложение)

Что получается на выходе 
в подменю "Экспорт" окна предпросмотра отчета у вас появятся кнопка "Run Designer"

Примечание

Если Вы хотите посмотреть, что получилось, Вам все таки придется переоткрыть основное окно предпросмотра отчета, Но это, в любом случае, быстрее, чем перезапуск программы.

Самое главное: Как сохранить изменения

После того, как в рантайме вас все устраивает, в окне дизайнера вызовите команду "Соханить в файл".
Потом в дизайн-тайме открываете дизайнер этого же отчета и загружаете из файла.
В самом простом варианте этого достаточно

воскресенье, 27 июля 2014 г.

Windows пипетка

Понадобилась экранная пипетка снимать цвет изображения windows, в частности для программирования в Delphi.

Воспользовался программой
http://www.ant-karlov.ru/colours-ekrannaya-pipetka.html

В Windows 8 работает.
Спасибо автору. 

пятница, 4 июля 2014 г.

Delphi 7 Модуль данных (datamodule) не виден на экране

Ситуация
Работаю над проектом в Delphi 7
Перед этим проектом занимался другой разработчик

Проблема
Не отображается визуальное представление датамодуля (datamodule)

Код вижу, но при нажатии на F12 визуальное представление не отображается


Причина
Причину выяснил по косвенным признакам + дедуктивный метод.

У предыдущего разработчика было большое разрешение экрана и он сдвинул модуль данных подальше, но на его экране он был видим, а на моем - нет.

Решение
Открыл через проводник файл dfm модуля данных и поправил на 1 свойства Top и Left
(через делфи до них не добраться)

пятница, 31 мая 2013 г.

Delphi TDateTimePicker редактирование даты и времени одновременно

Проблемы: стандратный компонент Delphi TDateTimePicker позволяет редактировать или дату или время.
Одновременное редактирование даты и времени в стандартном варианте невозможно.

Погуглил  - выручила статья
http://www.foxbase.ru/delphi/redaktirovanie-daty-i-vremeni-odnovremenno.htm

вторник, 26 марта 2013 г.

FastReport 4 font reading and huge file size workaround solution

Information for Russian-speakingсDevelopers is in Russian version of this article

Environment:
Delphi 7 application, Fast Report 4 VCL


Problem 1:
Export files from FastReport to PDF is unreadable on Android-devices, iOS-devices and web mailers.


Solution 1 - PDF is unreadable on Android-devices, iOS-devices and web mailers
embed fonts in the report file.
In export component set this property to "true":
TfrxPDFExport.EmbeddedFonts

With embedded font report became readable on any client OS and Web Mailers.


Problem 2 (a consequence of the solution of the problem 1)
The report file is huge: approximately 1MB


Reason: embedded font (which we embed in pdf file to solve problem 1)

Particular Solution 2 -
The huge file-size of FastReport export to PDF with embedded fonts:

I must say that the general solution I have not found. Tried to use third-party filters, but they have bugs. Virtual pdf printer - is not suited for me as a solution, because it's hard to maintain. But I found a partial solution that work in my environment, hope it may be useful to someone:

The Main Idea of the solution: use a font with small file-size. Naturally this font you need to install on your development computer and on the client computer (only to computer of pdf-exporter customer).

Disadvantages solutions: font need to be installed on client computer.

Small in size (57KB) Arial-like font with Cyrillic Charset I've found here:
http://weblast.ru/fonts-493.html
direct link: http://weblast.ru/fonts/ukrainian/ARICYR.ttf

I've set Font property of all  labels and bands in a report to new font, and (BINGO!) export file reduced from 1MB to 120KB.

Please note that labels did not pickup new font when their CharSet property was setted to RUSSIAN_CHARSET, I had to change down all charsets to DEFAULT_CHARSET

Case history

The problem must be solved in 5 FastReport VCL (it includes only used font-characters in exported file), but there is stil not FastReport 5 VCL on developer's site, and who knows when it will be. Wrote to support - no answer.

Related Links

http://www.fast-report.com/en/forum/index.php?showtopic=7265

http://stackoverflow.com/questions/6844831/any-good-pdf-export-filter-that-works-with-fast-report



FastReport 4 экспорт в PDF шрифты и большой размер файла: обходное решение

Окружение:
Программа на Delphi 7, FastReport 4 (VCL)

проблема 1: 
экспорт из FastReport в PDF не читается на андроид-устройствах, iOS-устройствах и веб-почтовиках.

решение проблемы 1 - PDF из FastReport не читается на Android, iOS, веб-почтовиках:
внедряем шрифт в файл.
в компоненте-экспорте свойство: TfrxPDFExport.EmbeddedFonts устанавливаем в true

и отчет нормально читается на всех клиентских машинах.

Проблема 2 (вытекает из решения проблемы 1)
Файл отчета становится большим: примерно 1Мб

Причина: внедренный шрифт (который мы внедрили для решения проблемы 1)

Частное Решение проблемы 2 - 
Большой размер файла экспорта из FastReport в PDF с внедренными шрифтами:

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

Суть решения: использовать маленький по размеру шрифт. Естественно шрифт нужно установить и на компьютере разработчика и на компьютере клиента.

Недостатки решения: на компьютер клиента нужно установить используемый шрифт.

Маленький по размеру (57Кб) Arial-подобный шрифт с кириллицей нашел здесь:
http://weblast.ru/fonts-493.html
прямая ссылка: http://weblast.ru/fonts/ukrainian/ARICYR.ttf

перевел все надписи и банды в отчете на новый шрифт, и экспортный файл уменьшился с 1Мб до 120Кб.

Обратите внимание: шрифт не хотел подхватываться если у надписей в отчете стоял RUSSIAN_CHARSET, нужно было все надписи сбить в DEFAULT_CHARSET


История вопроса

Проблема должна была решиться в FastReport 5 VCL (типа там из всего шрифта в экспортный файл должны внедряться только реально используемые символы), но пятой версии нет, и неизвестно когда будет. Писал в поддержку - ответа не получил.

Ссылки по теме

http://www.fast-report.com/en/forum/index.php?showtopic=7265

http://stackoverflow.com/questions/6844831/any-good-pdf-export-filter-that-works-with-fast-report


четверг, 7 февраля 2013 г.

Delphi отправить сообщение с уведомлением о доставке Indy-компоненты

Задача
Отправить сообщение с уведомлением о доставке

Средства реализации
Delphi 7, компоненты Indy 10

Решение

В сообщении TIdMessage устанавливает поле ReceiptRecipient

 lMessage.ReceiptRecipient.Text:= 'a@b.com';


Что происходит на фоне: устанавливается заголовок  в письме Read-Receipt-To


Продолжение темы
Если вы захотите автоматически разбирать подтверждения о доставке, смотрите статью
Delphi Indy 10 POP3 пример


UPD
Возникла проблема, которую пока не знаю как решить. Веб-интерфейс mail.ru игнорирует адрес из заголовка ReceiptRecipient. Уведомления о доставке он отправляет на адрес отправителя.

Вопросы/пожелания/предложения оставляйте кв комментариях

см. также

Общие вопросы отправки почты через Indy 10
http://dev-doc.blogspot.com/2012/08/delphi-indy-10.html

заголовки почтовых сообщений
http://www.activexperts.com/smtp-pop3-component/headers/


тут еще есть ссылка на заголовок X-Confirm-Reading-To
я его не использовал
http://delphimaster.net/view/6-25490

обсуждение вопросов гарантированной доставки
http://stackoverflow.com/questions/3525145/email-open-notification-ruby-on-rails/3525199#3525199

описание класса TIDMessage
http://kumanov.com/docs/prog/indy/007544.html

Delphi Indy 10 POP3 Пример

Простой пример обработки входящей почты с использованием POP3 компонент Indy10 для Delphi 7

(практическая задача была: обработать уведомления о доставке)

на форме компоненты:

  IdPOP3: TIdPOP3;
  IdMessage: TIdMessage;


Ниже: текст процедуры


...
var
  msgs: integer;
  i: integer;
  flag: boolean;

  msgcnt: integer;
begin
  IdPOP3.Host:= 'XXXX';
  IdPOP3.Username:= 'XXXX';
  IdPOP3.Password:= 'XXXX';
  IdPOP3.Port:= 110;

  IdPOP3.Connect;
  try
    msgcnt:= IdPOP3.CheckMessages;
    
    for I:= msgcnt to 1 do
    begin
      IdMessage.Clear;
      flag:= false;

      if (IdPOP3.Retrieve(i, IdMessage)) then
      begin
        ProcessMessage(IdMessage.From.Address, IdMessage.Subject);        
        flag:= true;        
      end;
      if flag then
      begin
        IdPOP3.Delete(i); //удаление письма
      end;
    end;    
  finally
    IdPOP3.Disconnect;
  end;
end;


UPD если нужно извлечь текст сообщения, может помочь такой код

var
  locBody: string;
...

        if (locBody = '') then
        begin
          for j:= 0 to IdMessage.MessageParts.Count - 1 do
          begin
            if (IdMessage.MessageParts[j] is TidText) then
            begin
              locBody:= (IdMessage.MessageParts[j] as TidText).Body.Text;
              if locBody <> '' then break;
            end;
          end;
        end;
...


Вопросы/пожелания/предложения оставляйте в комментариях.

см. также

Отправка почты через Smtp компоненты Indy10 в Delphi7
http://dev-doc.blogspot.com/2012/08/delphi-indy-10.html


За основу взял код на стековерфлоу
http://stackoverflow.com/questions/5336984/how-to-receive-emails-using-indy-10-and-delphi-7-with-the-file-attachment

Еще один простой пример
http://www.lazarus.freepascal.org/index.php?topic=17626.0

пятница, 14 декабря 2012 г.

Хеш-таблица HashTable вида ключ-значение в Delphi 7


Задача
использовать хеш-таблицу вида ключ-значение (где значение может быть integer, string или TObject)

Среда: Delphi 7

Решение
Код взял отюда
http://read.pudn.com/downloads76/sourcecode/p2p/289231/Hashes.pas__.htm

на код навела статья из stackoverflow
http://stackoverflow.com/questions/2866144/is-there-anything-like-a-map-or-a-hashtable-in-delphi-6

Вставил модуль в проект. Скомпилировалось сразу. Методы работы легко посмотреть в коде.


Альтернативное решение
преимущество: использует только стандартные библиотеки Delphi без необходимости использования сторонних библиотек
недостаток: решение только частного случая: хэш-таблица integer->string

Модуль: IniFiles
классы: TStringHash, THashedStringList

спасибо за совет xen2:
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=113797&msg=13631299


Еще одно решение
(похоже на подходящее, но сам пока не попробовал)
Использовать ...Hash... из AcedUtils

http://acedutils.narod.ru/AcedUtils.htm

опять спасибо за совет  xen2
http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=113797&msg=13631895




вторник, 21 августа 2012 г.

Delphi Indy 10 SSL and Encoding Issues


When sending mail through Indy components in Delphi 7 encountered periodically on different issues.
Variants of problems:


  • sending emails from machines that - there are Russian letters in the names
  • email using SSL
  • problems with encoding in the subject and body of the message


I didn't find common solution in internet - only scattered pieces.

All solutions brought here. May be it will be useful for someone (tested on russian charsets)

System configuration:

  • Delphi 7, 
  • Indy components version: 10.5.9.4797 (installed manually by article http://conferences.embarcadero.com/article/32160
    file: Indy10_4798.zip)
  • SSL Library: openssl-1.0.0d-i386-win32.zip
    from http://indy.fulgan.com/SSL/
    (files libeay32.dll and ssleay32.dll are copied to project output directory)

main procedure is - SendEmail
Main pieces of code are commented.

uses
...

IdCoderMIME , IdMessage, IdSMTP,
IdSSLOpenSSL , IdIOHandler, IdAttachmentFile, IdExplicitTLSClientServerBase, idCharSets, idText
...

type

  //-- helper stub-class for TidMessage.OnInitializeISO event  handling
  Tindystub = class(tobject)
  public
    procedure OnInitISO(var VHeaderEncoding: Char; var VCharSet: string);
  end;

procedure Tindystub.OnInitISO(var VHeaderEncoding: Char;
  var VCharSet: string);
begin
  VCharSet := IdCharsetNames[ idcs_UTF_8 ];
end;


procedure SendEmail(
    aSmtpServer: string;
    aSmtpPort: integer;
    aSmtpLogin: string;
    aSmtpPassword: string;
    aFromAddress: string;
    aFromName: string;
    aToAddress: string;
    aMessageSubject: string;
    aMessageText: string;
    aAttachmentFileFullName: string;
    aUseSSL: boolean = false
    );
var
  lMessage : TIDMessage;
  lSMTP    : TIdSMTP;
  attach   : TIdAttachmentFile;
  sslHandler: TIdSSLIOHandlerSocketOpenSSL;
  lindystub: Tindystub;
  idtTextPart: TIdText;
begin
  lMessage:= TIDMessage.Create(nil);
  lSmtp:= TIDSmtp.Create(nil);
  sslHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  lindystub:= Tindystub.Create();
  try
    lSMTP.AuthType:= satDefault;

    lSMTP.Host     := aSmtpServer;   //Хост
    lSMTP.Port     := aSmtpPort;     //Порт (25 - по умолчанию)

    lSMTP.Username := aSmtpLogin;
    lSMTP.Password := aSmtpPassword;

    //-- solving "non-english computer name" problem
    lSMTP.HeloName := 'tfo';

    //-- using SSL
    if (aUseSSL) then
    begin
      SSLHandler.Destination := aSmtpServer+':'+IntToStr(aSmtpPort);
      SSLHandler.Host := aSmtpServer;
      SSLHandler.Port := aSmtpPort;
      SSLHandler.DefaultPort := 0;
      SSLHandler.SSLOptions.Method := sslvSSLv23;
      SSLHandler.SSLOptions.Mode := sslmUnassigned;
      lSMTP.IOHandler := SSLHandler;
      lSMTP.UseTLS := utUseImplicitTLS;
    end;

    //-- subject encoding
    lMessage.OnInitializeISO := lindystub.OnInitISO;

    lMessage.Subject      := aMessageSubject;
    lMessage.From.Address := aFromAddress;
    lMessage.From.Name    := aFromName;
    lMessage.Recipients.EMailAddresses:= aToAddress;

    //-- message body encoding
    idtTextPart := TIdText.Create(lMessage.MessageParts, nil);
    idtTextPart.ContentType := 'text/plain';
    idtTextPart.CharSet := 'Windows-1251';

    idtTextPart.Body.Text:= aMessageText;

    //-- work with attached files
    if (aAttachmentFileFullName <> '') then
    begin
      attach:=TIdAttachmentFile.Create(lMessage.MessageParts, aAttachmentFileFullName); //Вложение
    end;

    //-- sending email
    lSMTP.Connect;
    try
      lSMTP.Send(lMessage);
    finally
      lSMTP.Disconnect;
    end;

  finally
    sslHandler.Free;
    lMessage.Free;
    lSmtp.Free;
    lindystub.Free;
  end;
end;

Delphi Indy 10 SMTP Кодировки и SSL Решение все в одном


При отправке писем через SMTP компоненты Indy в Delphi 7 наталкивался периодически на разные проблемы.
Варианты проблем:

  • отправка писем от машин, у которых - есть русские буквы в названиях
  • отправка писем через SSL
  • проблемы с кодировками в теме и теле письма

В интернете общего решения не находил - только разрозненные части.

Все решения свел здесь. может кому-то пригодится

Конфигурация системы:

  • Delphi 7, 
  • Версия компонентов Indy:10.5.9.4797 (переустанавливал вручную по статье http://conferences.embarcadero.com/article/32160  файл: Indy10_4798.zip)
  • ssl - библиотеки: openssl-1.0.0d-i386-win32.zip
    брал отсюда http://indy.fulgan.com/SSL/
    (в директорию с exe-файлом подложил libeay32.dll и ssleay32.dll)


Ключевая процедура в коде - SendEmail
Важные места подкомментировал.

uses
...

IdCoderMIME , IdMessage, IdSMTP,
IdSSLOpenSSL , IdIOHandler, IdAttachmentFile, IdExplicitTLSClientServerBase, idCharSets, idText
...

type

  //-- вспомогательный класс-заглушка для подвязки события компонента indy
  Tindystub = class(tobject)
  public
    procedure OnInitISO(var VHeaderEncoding: Char; var VCharSet: string);
  end;

procedure Tindystub.OnInitISO(var VHeaderEncoding: Char;
  var VCharSet: string);
begin
  VCharSet := IdCharsetNames[ idcs_UTF_8 ];
end;


procedure SendEmail(
    aSmtpServer: string;
    aSmtpPort: integer;
    aSmtpLogin: string;
    aSmtpPassword: string;
    aFromAddress: string;
    aFromName: string;
    aToAddress: string;
    aMessageSubject: string;
    aMessageText: string;
    aAttachmentFileFullName: string;
    aUseSSL: boolean = false
    );
var
  lMessage : TIDMessage;
  lSMTP    : TIdSMTP;
  attach   : TIdAttachmentFile;
  sslHandler: TIdSSLIOHandlerSocketOpenSSL;
  lindystub: Tindystub;
  idtTextPart: TIdText;
begin
  lMessage:= TIDMessage.Create(nil);
  lSmtp:= TIDSmtp.Create(nil);
  sslHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  lindystub:= Tindystub.Create();
  try
    lSMTP.AuthType:= satDefault;

    lSMTP.Host     := aSmtpServer;   //Хост
    lSMTP.Port     := aSmtpPort;     //Порт (25 - по умолчанию)

    lSMTP.Username := aSmtpLogin;
    lSMTP.Password := aSmtpPassword;

    //-- решаем проблему отправки писем, если у компьютера руссоке имя
    lSMTP.HeloName := 'tfo';

    //-- отправляем почту через SSL, если надо (пока тестировал только на ukr.net)
    if (aUseSSL) then
    begin
      SSLHandler.Destination := aSmtpServer+':'+IntToStr(aSmtpPort);
      SSLHandler.Host := aSmtpServer;
      SSLHandler.Port := aSmtpPort;
      SSLHandler.DefaultPort := 0;
      SSLHandler.SSLOptions.Method := sslvSSLv23;
      SSLHandler.SSLOptions.Mode := sslmUnassigned;
      lSMTP.IOHandler := SSLHandler;
      lSMTP.UseTLS := utUseImplicitTLS;
    end;

    //-- решаем вопрос кодировки темы письма
    lMessage.OnInitializeISO := lindystub.OnInitISO;

    lMessage.Subject      := aMessageSubject;
    lMessage.From.Address := aFromAddress;
    lMessage.From.Name    := aFromName;
    lMessage.Recipients.EMailAddresses:= aToAddress;

    //-- решаем вопрос кодировки тела письма
    idtTextPart := TIdText.Create(lMessage.MessageParts, nil);
    idtTextPart.ContentType := 'text/plain';
    idtTextPart.CharSet := 'Windows-1251';

    idtTextPart.Body.Text:= aMessageText;

    //-- работа со вложенными файлами
    if (aAttachmentFileFullName <> '') then
    begin
      attach:=TIdAttachmentFile.Create(lMessage.MessageParts, aAttachmentFileFullName); //Вложение
    end;

    //-- собственно отправка
    lSMTP.Connect;
    try
      lSMTP.Send(lMessage);
    finally
      lSMTP.Disconnect;
    end;

  finally
    sslHandler.Free;
    lMessage.Free;
    lSmtp.Free;
    lindystub.Free;
  end;
end;


Вопросы/пожелания/предложения оставляйте в комментариях

см. также

Обработка почты через POP3 компоненты Indy10 в Delphi 7
http://dev-doc.blogspot.com/2013/02/delphi-indy-10-pop3.html

EMAIL MESSAGES FROM DELPHI. USING INDY TO SEND E-MAILS
https://community.embarcadero.com/article/technical-articles/162-programming/5913-email-messages-from-delphi-using-indy-to-send-emails
---------------------------------
UPD
Если хотите отправить почту через ukr.net
проверьте чтобы были включен параметр "POP3 и SMTP" согласно статье
http://www.qdpro.com.ua/node/17758
(если не сделать, будет выскакивать ошибка SYSERR 417)