c++ builder XE4 > POP before SMTP を使ってからメール送信 | 10.2 Tokyoの場合

```txt:動作確認
C++ Builder XE4
```

POP before SMTPを使ってからメール送信をする。

参考1: http://www.amunsnet.com/delphi/2847.html
参考2: http://ht-deko.com/tech057.html

参考1のコードで実行した時、以下のエラーがでたのでTLSの対応をした。

```
command is not valid in this state
```

コードは以下の通り。

```cpp
// メール送信用
#include <Idglobal.hpp>
#include <IdSMTP.hpp>
#include <IdSSLOpenSSL.hpp>
// POP before SMTP
#include <IdPOP3.hpp>

// メール本文の文字化けの対応
#include <IdHeaderCoder2022JP.hpp>
#pragma link "IdHeaderCoder2022JP"
...

void __fastcall TForm1::IdMessage1InitializeISO(System::WideChar &VHeaderEncoding,
		  UnicodeString &VCharSet)
{
	VHeaderEncoding = L'B';
	VCharSet = "ISO-2022-JP";
}
...
void __fastcall TForm1::sendTestMailSMTP()
{
	// 1. POP before SMTP
	TIdPOP3 *idPop3 = new TIdPOP3();
	idPop3->Host = kPopServerAdr;
	idPop3->Port = kPopPort; // int
	idPop3->Username = kMyUserName;
	idPop3->Password = kMyPassword;

	// command is not valid in this state
	TIdSSLIOHandlerSocketOpenSSL *idSSL = new TIdSSLIOHandlerSocketOpenSSL();
	if (useTLS) {
		idSSL->Host = kPopServerAdr;
		idSSL->Port = kPopPort;
		idSSL->Destination = idSSL->Host + L":" + IntToStr(kPopPort);
		idPop3->IOHandler = idSSL;
		idPop3->UseTLS = utUseImplicitTLS;
	}

	try {
		idPop3->Connect();
		idPop3->Disconnect();
	} catch (const Exception &e) {
		String msg = e.Message;
		delete idPop3;
		delete idSSL;
		return; // fail
	}
	delete idSSL;
	delete idPop3;

	// 2. sending e-mail using SMTP

	TIdSMTP* smtp = new TIdSMTP(NULL);
	TIdSSLIOHandlerSocketOpenSSL * sslHandler = new TIdSSLIOHandlerSocketOpenSSL(NULL);

    smtp->Host = kSmtpHost;
//  sslHandler->Host = smtp->Host;
//  sslHandler->Port = smtp->Port;
//  sslHandler->Destination = sslHandler->Host + L":"
//      + IntToStr(sslHandler->Port);
    smtp->IOHandler = sslHandler;
	smtp->Username = kMyUserName;
	smtp->Password = kMyPassword;
    smtp->Port = 587;
    smtp->UseTLS = utUseExplicitTLS;

    try {
        smtp->Connect();
	} catch (const Exception &e) {
		String msg = e.Message;
	}

    TIdMessage* msg = new TIdMessage(NULL);
    msg->OnInitializeISO = IdMessage1InitializeISO;
	msg->ContentType = "text/plain";
    msg->CharSet = "ISO-2022-JP";
    msg->ContentTransferEncoding = "BASE64";
    msg->From->Name = kFromName;
	msg->From->Address = kFromAddr;
	msg->Recipients->EMailAddresses = kRecipients;

	// TODO: 件名は日本語だと文字化けする
	msg->Subject = "test mail from XE4 on " + Now().FormatString(L"hh:nn:ss");

	msg->Body->Text = "テストメールの本文です";

    try {
        smtp->Send(msg);
    } catch (const Exception &e) {
        String msg = e.Message;
    }

    smtp->Disconnect();
    delete msg;
    delete smtp;
}
```

また、上記において以下を定義しておく必要あり。

```
String kMyUserName; // POP, SMTP接続ユーザ名
String kSmtpHost; // SMTPサーバー
String kPopServerAdr; // POPサーバー
int kPopPort; // 995 or 110 or ?
bool useTLS;
String kFromName; // e.g. yamada
String kFromAddr; // e.g. yamada@testmail.com
String kRecipients; // 送信先メールアドレス
```

ただし、パスワード(下記)に関してはコード埋め込みしないように。

```
String kMyPassword; // パスワード
```

### 10.2 Tokyo対応
(追記 2018/01/10)

10.2 Tokyoの場合は以下の方法で送信できた。

- [C++ Builder 10.2 Tokyo > Indy > OpenSSL > Error: Could not load SSL library > libeay32.dllとssleay32.dllが関連](https://qiita.com/7of9/items/ac616e9bc593c270b5f2)