Indyでメールを送信する自作関数を作成しようと思っています
下記のURLを参考に作成しているのですが、
TIdMessageのOnInitializeISOイベントの割り当て方法が分からなくて悩んでいます
https://ht-deko.com/tech040.html#tech085
ちなみにメール送信関数は1つのユニットに記述しており、
TIdMessageコンポーネントも関数内部で動的にCreateしています
他のアプリからそのユニットをusesする形で再利用することを考えています
上記のURLでの例のようにフォーム上にTIdMessageコンポーネントが配置できれば
いいのですが・・・
// メール送信関数
function ComSendMailWithCC(Host, Subject, Name, From, Mailto, Text: String; Cc: String = ''): Boolean;
const
//*=== メール設定情報 ===*/
MAIL_CHARSET = 'UTF-8'; // 文字コード
MAIL_CONTENTTYPE = 'text/plain'; // コンテンツ種別
MAIL_ENCODING = 'BASE64'; // エンコーディング
var
smtp: TIdSMTP;
msg : TIdMessage;
begin
//*** 復帰値の初期値を設定する ***/
Result := True; // 正常終了
//*** 変数を初期化する ***/
smtp := nil;
msg := nil;
//*** メールを送信する ***/
try
try
//*=== SMTPサーバの接続 ===*/
smtp := TIdSMTP.Create(nil);
smtp.Host := Host;
smtp.Connect;
//*=== メッセージオブジェクトの作成 ===*/
msg := TIdMessage.Create(smtp);
msg.OnInitializeISO := ; // ←???
msg.ContentType := MAIL_CONTENTTYPE;
msg.CharSet := MAIL_CHARSET;
msg.ContentTransferEncoding := MAIL_ENCODING;
msg.Subject := Subject;
msg.From.Name := Name;
msg.From.Address := From;
msg.Recipients.EMailAddresses := Mailto;
msg.CCList.EMailAddresses := Cc;
msg.Body.Text := Text;
//*=== メール送信 ===*/
smtp.Send(msg);
except
Result := False; // 異常終了
end;
finally
//*=== メッセージオブジェクトの破棄 ===*/
if msg <> nil then msg.Free;
//*=== SMTPサーバの切断 ===*/
if smtp <> nil then
begin
smtp.Disconnect;
smtp.Free;
end;
end;
end;
自己レスです
下記のようなやり方でとりあえずイベントは動いたようです
ネット上の色々なサイトのコードを参考にして継ぎはぎしたコードなので全く自信がありません
type
TIdMessage1 = class(TIdMessage)
private
FOnInitializeISO: TIdInitializeISOEvent;
public
procedure DoInitializeISO(var VHeaderEncoding: Char; var VCharSet: String); override;
published
property OnInitializeISO: TIdInitializeISOEvent read FOnInitializeISO write FOnInitializeISO;
end;
procedure TIdMessage1.DoInitializeISO(var VHeaderEncoding: Char; var VCharSet: String);
begin
inherited;
if Assigned(FOnInitializeISO) then
begin
VHeaderEncoding := 'B';
VCharSet := 'UTF-8';
end;
end;
function ComSendMailWithCC(Host, Subject, Name, From, Mailto, Text: String; Cc: String = ''): Boolean;
const
//*=== メール設定情報 ===*/
MAIL_CHARSET = 'UTF-8'; // 文字コード
MAIL_CONTENTTYPE = 'text/plain'; // コンテンツ種別
MAIL_ENCODING = 'BASE64'; // エンコーディング
var
smtp: TIdSMTP;
msg : TIdMessage1;
begin
//*** 復帰値の初期値を設定する ***/
Result := True; // 正常終了
//*** 変数を初期化する ***/
smtp := nil;
msg := nil;
//*** メールを送信する ***/
try
try
//*=== SMTPサーバの接続 ===*/
smtp := TIdSMTP.Create(nil);
smtp.Host := Host;
smtp.Connect;
//*=== メッセージオブジェクトの作成 ===*/
msg := TIdMessage1.Create(smtp);
msg.ContentType := MAIL_CONTENTTYPE;
msg.CharSet := MAIL_CHARSET;
msg.ContentTransferEncoding := MAIL_ENCODING;
msg.Subject := Subject;
msg.From.Name := Name;
msg.From.Address := From;
msg.Recipients.EMailAddresses := Mailto;
msg.CCList.EMailAddresses := Cc;
msg.Body.Text := Text;
//*=== メール送信 ===*/
smtp.Send(msg);
except
Result := False; // 異常終了
end;
finally
//*=== メッセージオブジェクトの破棄 ===*/
if msg <> nil then msg.Free;
//*=== SMTPサーバの切断 ===*/
if smtp <> nil then
begin
smtp.Disconnect;
smtp.Free;
end;
end;
end;
プログラム自体に問題は無さそうですがプログラムの記述にいくつか疑問が残ります。
smtp := nil;
try
smtp := TIdSMTP.Create(nil);
finally
if smtp <> nil then
begin
smtp.Disconnect;
smtp.Free;
end;
end;
となっていますが
クラスの生成と try の関係は
smtp := TIdSMTP.Create(nil);
try
finally
smtp.Free;
end;
このように記述すべきで
そのように書いていないので代入文やifが増えていってますね。
元の書き方だとクラス生成前にエラーになると finallyに飛んで
freeでエラーになるので free前にわざわざ生成されたか判断しているかと
Connectで接続先が見つからなくてもそのまま処理が進むのが不安です。
あとエラーにはなりませんが、
Connectされる前にエラーでfinallyに飛ぶとDisconnectされるみたいですね。