前回の書込みの時に書いたメールクライアントでPOP3受信の時に
データをファイル化していちいちPOP3サーバからメールのデータを
受信したくないのですがどうやって行えば良いのでしょうか?
TMemoryStreamなどに書き込んで、SaveToFileで保存するだけです。
いまいち分からないので今作っているプログラムのソースを
http://isweb11.infoseek.co.jp/play/knekodo/new.htmlに
置くのでソースを見て教えていただけるとありがたいです。
なお都合でアップは17時以降でないと無理なのでごめんなさいです。
ソースの方はアップしましたのでできるだけ早くお願いします。
http://isweb11.infoseek.co.jp/play/knekodo/file/nme_dev.lzh
Delphiのバージョンは何ですか?
Delphi5では開けませんでした。
受信したデータはどういう風に保持しているんでしょうか。
TMemoryStreamに、WriteかWriteBufferで書き出すだけです。
MemStream := TMemoryStream.Create;
try
MemStream.WriteBuffer(保持している変数, 保持内容の大きさ);
MemStream.SaveToFile(保存したいファイル名);
finally
MemStream.Free;
end;
こんな感じです。
読み込みながらファイルに保存ならば、tryの次の行が
while(読み込み終えるまで) do
begin
{ 読み込み }
MemStream.WriteBuffer(保持している変数, 保持内容の大きさ); { MemoryStreamに書き出し }
end;
になります。
Delphi6 Personalで作っています。
多分それで開けないんだと思います。
POP3受信の時のタイミングで保存するのかなと思っているのですが・・・
追加なのですがnMail.DLLのSDKも入れないと動かないので
http://www.nanshiki.co.jp/よりダウンロードをお願いします。
Delphi6を持っていないのでプロジェクトに対してコメントできません。
NMailPop3GetMailを呼び出した後、TMemoryStreamのオブジェクトを作成し、
Subject, Date, From, Header, Bodyなど必要なデータを整形しWriteBufferで出力。
SaveToFileで保存です。
オブジェクトの解放も忘れずに。
えっとDelphi6 Personal(無料で利用できる)を使ってやっているので
Borlandさんのホームページからダウンロードすれば使えると思います。
ちなみにこのプログラムはnMail.dllのSDKのサンプル(PDS)を参考に
しながら作っています。(サンプル自体はDelphi3で開けるそうです。)
サンプルは圧縮ファイルの中のDpmail.lzhに入っています。
POP3の受信のあたりはいじっていないのでチェックしてもらえるとうれしいです。
いや、前に入れたことがあるんですが、Delphi6をアンインストールしたときDelphi5の設定まで消されまして。
わざわざDelphi6を入れたくないのです。
2つ上の、僕の発言では、わからなかったんでしょうか。
そうなんですかぁ・・・。
それならその下に書いたDPMailのサンプルをDelphi5で開いてみてください。
それにも同じコードがあるのでそこで試していただけませんか?
サンプルはDelphi3以上の環境なら動くとかいてあります
>同梱のreadme.txt?に書いてありました。
連続書き込みでごめんなさい。
一応MemoryStreamを試してみて出来たファイルを開いてみたのですが
中身がぐちゃぐちゃのファイルでちょっと困りました。
また、ちゃんとしたメーラとして作っているのでこの出来た
データを元のリストビューに読み込ませて件名などを
表示したり、リストビューをクリックしたら本文を
BodyMemoに出力したりしたいのですが・・・
もしかして、WriteBufferの第一引数に、Bodyとか入れています?
Body^にして見てください。
# ポインタでなく、実体を渡すようにしてください
僕もはまりましたから、ここの部分。
このdpmailのメニュー「保存」の処理が、ほぼそのまま使えます。
MemoryStreamと言いましたが、この場合ならTFileStreamの方が適切でしたね。
混乱させて済みません。
TFileStreamも、TMemoryStreamと同じように使います。違うのは、最初にファイルを指定するところです。
// メールを読み込む
NMailPop3GetMail(S, MailIndex, subject, date, from, header, Body, nil, nil); // 変数は違うかもしれません。
try
Fs := TFileStream.Create(MailSaveFile, fmCreate); // ヘッダ部分を保存。MailSaveFileに保存したいファイル名を設定しておくこと
Fs.WriteBuffer(header^, StrLen(header)); // メールヘッダを保存
Fs.WriteBuffer(body^, StrLen(body)); // メール本文を保存
finally
Fs.Free;
end;
こんな形です。
保存したデータを元に戻す場合、DLLにはそういう関数がないようなので、自前で戻さねばなりません。
これだと一件クリックしたごとにファイルが上書きされてしまい
後で困るのですが・・・どうすればよいでしょうか?
ちなみにBeckey!やAL-Mailは日付+時刻+拡張子のファイル名で保存していて
このリストビューをクリックした時の受信の動作ではなくてメールメニューの
受信をクリックした時にファイルとして保存しないといけないような気がします。
このメーラも同じように受信をクリックした時にファイルをメールのヘッダと
本文をFileStreamで出力してリストビューをクリックした時にはHDDに
保存したメールのファイルを読み出すようにすれば良いと思うのですが
どうでしょうか?
> 受信をクリックした時にファイルとして保存しないといけないような気がします。
> このメーラも同じように受信をクリックした時にファイルをメールのヘッダと
> 本文をFileStreamで出力してリストビューをクリックした時にはHDDに
> 保存したメールのファイルを読み出すようにすれば良いと思うのですが
> どうでしょうか?
そうですね。
メール受信時は、
・->「受信」ボタンを押す<メニューでも何でもいいです
・POP3接続開始
・サーバにあるメッセージの数を取得
・サーバにあるメッセージの全てのUIDLを取得
・現在ローカルに保存してあるメッセージに、サーバ側メッセージのUIDLがあれば、ダウンロードしないようにするチェック
・サーバにあるメッセージで、ローカルにないメッセージを1つずつ読み込む
==ここ
・ローカルのファイルに保存
==ここ
・サーバ側メッセージを削除する設定なら、メッセージを削除
・サーバ切断
という処理になると思います。
日本語で書くと難しくなりますが、処理的には難しくないと思います。
ファイル名は、yyyymmddhhmiss_seqという記述ならいいと思います。
# 年月日時分秒_シーケンス番号
シーケンスが必要な理由は、同じ時分秒に複数のメールがあるかもしれないからです。
と言うことはprocedure TMainForm.AddMailListの部分に書くのですね?
→上で書いた事
でもDelphiはからっきしの初心者なのであんまり分からないです。
本当にこんなこと書いちゃってごめんなさいです。
ファイル名に数字(日付+シーケンス番号)を入れるのも分からないです。
> と言うことはprocedure TMainForm.AddMailListの部分に書くのですね?
> →上で書いた事
そういうことですね。
NMailPop3GetMailStatusでメールの情報を取得した後、本文もNMailPop3GetMailで取得します。
ひとまとめにしたものを、ファイルに保存し、そのファイル名をListItem.Dataに入れておけば、後で使えます。
dateに、yyyy/mm/dd hh:mm:ddで入ってくるので、
filename := 'mail' + Copy(date, 1, 4) // yyyy
+ Copy(date, 6, 2) // mm
+ Copy(date, 9, 2) // dd
+ Copy(date, 12, 2) // hh
+ Copy(date, 15, 2) // mm
+ Copy(Date, 18, 2); // ss
でファイル名の頭を確定し、
seq := 0;
while FileExists(filename + '_' + IntToStr(Seq) + '.txt') do Inc(seq);
などとして、シーケンスまで決定します。
ちょっと書いて実行してみたのですが、不正な処理(Accsess Vioration)で
停止してしまいました。この中に記述すれば良いのは大分わかったのですが
FileStreamでの保存のタイミングやファイル読み込みのいろいろな部分が
まだ分からない状態です。(>_<)
procedure TMainForm.AddMailList(S: TSocket);
var
No, Count: integer;
Subject: array [0..HEADER_MAX] of Char;
Date: array [0..HEADER_MAX] of Char;
From: array [0..HEADER_MAX] of Char;
Header: PChar;
I: TListItem;
DataName: String;
Seq: Integer;
Body: PChar;
begin
// メール本文表示をクリア
BodyMemo.Lines.Clear;
// ListView もクリア
HeaderDataClear;
MailListView.Items.Clear;
// POP3 サーバに接続する
S := NMailPop3Connect(PChar(Pop3Name));
if S <> INVALID_SOCKET then
begin
if (Id = '') or (Password = '') then
begin
// ID とパスワード入力
if InputForm.ShowModal = mrOk then
begin
Id := InputForm.IdEdit.Text;
Password := InputForm.PasswordEdit.Text;
end;
end;
// メールの数を得る
No := NMailPop3Authenticate(S, PChar(Id), PChar(Password), ApopFlag);
if No >= 0 then
begin
for Count := 1 to No do
begin
GetMem(Header, HEADER_MAX);
// 順番にヘッダの内容を読み、ListView に追加
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);
NMailPop3GetMail(S, Count, Subject, Date, From, Header, Body, nil, nil);
DataName := 'NML' + Copy(date, 1, 4) // yyyy
+ Copy(date, 6, 2) // mm
+ Copy(date, 9, 2) // dd
+ Copy(date, 12, 2) // hh
+ Copy(date, 15, 2) // mm
+ Copy(Date, 18, 2); // ss
Seq := 0;
while FileExists(DataName + '_' + IntToStr(Seq) + '.nml') do Inc(Seq);
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
I.Data := Header;
StrLCat(Header, #13#10, HEADER_MAX - 1);
end;
end
else
begin
// サーバーからのエラーメッセージを取得
NMailGetMessage(NMAIL_GET_ERROR_MESSAGE, Subject, HEADER_MAX);
MessageDlg('ログインエラー:' + StrPas(Subject), mtError, [mbOK], 0);
end;
NMailPop3Close(S);
S := INVALID_SOCKET;
end;
end;
家に帰ってから考えていたのですがやっぱり上のソース以降
進めなくて困っています(追加した部分は現在コメントにしてあります。)
こんな感じでよいのでしょうか?
// メール読み込み
NMailPop3GetMail(S, Count, Subject, Date, From, Header, Body, nil, nil);
DataName := 'NML' + Copy(date, 1, 4) // yyyy
+ Copy(date, 6, 2) // mm
+ Copy(date, 9, 2) // dd
+ Copy(date, 12, 2) // hh
+ Copy(date, 15, 2) // mm
+ Copy(Date, 18, 2); // ss
Seq := 0;
while FileExists(DataName + '_' + IntToStr(Seq) + '.nml') do Inc(Seq);
try
Fs: = TFileStream.Create(DataName, fmCreate);
Fs.WriteBuffer(header^, StrLen(header)); // メールヘッダを保存
Fs.WriteBuffer(body^, StrLen(body)); // メール本文を保存
finally
Fs.Free;
end;
ファイルに格納するので、Headerを動的に確保する必要はありません。
静的に用意して、Subjectなどと同じように使います。
同じく、I.Dataに、Headerを持つ意味はありません。
ファイルに格納したメールを読み直すだけです。毎回ログインしてメールを取得するのであれば、ファイルに格納する意味がなくなります。
> I := MailListView.Items.Add;
> I.Caption := StrPas(Subject);
> I.SubItems.Add(StrPas(Date));
> I.SubItems.Add(StrPas(From));
> I.Data := Header;
> StrLCat(Header, #13#10, HEADER_MAX - 1);
の部分が、
DataName := DataName + '_' + IntToStr(Seq) + '.nml'; // ファイル名を設定
Body := nil;
Fs := nil;
try
BodySize := NMailPop3GetMailSize(S, Count);
GetMem(Body, BodySize);
NMailPop3GetMail(S, Count, subject, date, from, header, Body, nil, nil);
Fs := TFileStream.Create(DataName + '_' + IntToStr(Seq) + '.nml', fmCreate);
Fs.WriteBuffer(Header^, StrLen(Header));
Fs.WriteBuffer(Header^, StrLen(Body));
finally
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
if Fs <> nil then Fs.Free;
if Body <> nil then FreeMem(Body);
end;
GetMem(I.Data, StrLen(DataName)); // ファイル名を保持するメモリを確保。OnDeletionで解放すること。
CopyMemory(I.Data, PChar(DataName), StrLen(DataName)); // ファイル名をコピー
というようになります。
# 動作確認はしていません。
ただし、これだと保持データが変わるので、データ管理部分の大部分が変更になると思います。
思い当たるのは2点。
1.MailListViewのOnDeletionで、Item.Dataを解放するようにしてください。
2.OnClickで、String(MailListView.Selected.Data)をファイル名としてファイルを読み込み、それをメールデータとして扱ってください。
# ヘッダと本文は空行で分かれているはず
添付ファイルは、自前で変換する必要が出ると思います。
今試していたのですがやっぱりDataNameの作成のところで不正な処理を
起こしてしまうようです。一応現在のプロシージャのリストを載せます。
原因なのかな?と疑っているのはDateの値が参照できない値ですと
出ることなのですが、どうでしょうか?
procedure TMainForm.AddMailList(S: TSocket);
var
No, Count: integer;
Subject: array [0..HEADER_MAX] of Char;
Date: array [0..HEADER_MAX] of Char;
From: array [0..HEADER_MAX] of Char;
Header: PChar;
I: TListItem;
DataName: String; // NMLファイルのファイル名
Seq: Integer; // シーケンス番号
Body: PChar; // Bodyのデータ用
BodySize: Integer; // Bodyのファイルサイズ
Fs: TFileStream; // ファイルストリーム
begin
// メール本文表示をクリア
BodyMemo.Lines.Clear;
// ListView もクリア
HeaderDataClear;
MailListView.Items.Clear;
// POP3 サーバに接続する
S := NMailPop3Connect(PChar(Pop3Name));
if S <> INVALID_SOCKET then
begin
if (Id = '') or (Password = '') then
begin
// ID とパスワード入力
if InputForm.ShowModal = mrOk then
begin
Id := InputForm.IdEdit.Text;
Password := InputForm.PasswordEdit.Text;
end;
end;
// メールの数を得る
No := NMailPop3Authenticate(S, PChar(Id), PChar(Password), ApopFlag);
if No >= 0 then
begin
for Count := 1 to No do
begin
// 順番にヘッダの内容を読み、ListView に追加
{GetMem(Header, HEADER_MAX);
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
I.Data := Header;
StrLCat(Header, #13#10, HEADER_MAX - 1);}
DataName := 'NML' + Copy(date, 1, 4) // yyyy
+ Copy(date, 6, 2) // mm
+ Copy(date, 9, 2) // dd
+ Copy(date, 12, 2) // hh
+ Copy(date, 15, 2) // mm
+ Copy(Date, 18, 2); // ss
Seq := 0;
while FileExists(DataName + '_' + IntToStr(Seq) + '.nml') do Inc(Seq);
try
BodySize := NMailPop3GetMailSize(S, Count);
GetMem(Body, BodySize);
NMailPop3GetMail(S, Count, subject, date, from, header, Body, nil, nil);
Fs := TFileStream.Create(DataName + '_' + IntToStr(Seq) + '.nml', fmCreate);
Fs.WriteBuffer(Header^, StrLen(Header));
Fs.WriteBuffer(Header^, StrLen(Body));
finally
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
if Fs <> nil then Fs.Free;
if Body <> nil then FreeMem(Body);
end;
end;
end
else
begin
// サーバーからのエラーメッセージを取得
NMailGetMessage(NMAIL_GET_ERROR_MESSAGE, Subject, HEADER_MAX);
MessageDlg('ログインエラー:' + StrPas(Subject), mtError, [mbOK], 0);
end;
NMailPop3Close(S);
S := INVALID_SOCKET;
end;
end;
dateはPChar(array of char)でしたね。忘れていました。
strDate: String;をvarに用意して、strDate := StrPas(Date);とし、
DataName := 'NML' + Copy(strDate, 1, 4) // yyyy
+ Copy(strDate, 6, 2) // mm
+ Copy(strDate, 9, 2) // dd
+ Copy(strDate, 12, 2) // hh
+ Copy(strDate, 15, 2) // mm
+ Copy(strDate, 18, 2); // ss
Dateの書式は、DLLの説明から、'yyyy/mm/dd hh:mi:ss'であるとして作ってあります。dateが取得できなかった場合があるならば、その判断も必要になります。
# DLL側で、Dateがなければ'1900/01/01 00:00:00'くらい設定しておいてくれれば楽なんですがね
上の書き込みに書いてあった処理を追加して実行したのですが
やはり不正な処理で終了してしまいます(Date:参照できない値ですが出ます)
procedure TMainForm.AddMailList(S: TSocket);
var
No, Count: integer;
Subject: array [0..HEADER_MAX] of Char;
Date: array [0..HEADER_MAX] of Char;
From: array [0..HEADER_MAX] of Char;
Header: PChar;
I: TListItem;
DataName: String; // NMLファイルのファイル名
Seq: Integer; // シーケンス番号
Body: PChar; // Bodyのデータ用
BodySize: Integer; // Bodyのファイルサイズ
Fs: TFileStream; // ファイルストリーム
strDate: String; // 日付の取得
begin
// メール本文表示をクリア
BodyMemo.Lines.Clear;
// ListView もクリア
HeaderDataClear;
MailListView.Items.Clear;
// POP3 サーバに接続する
S := NMailPop3Connect(PChar(Pop3Name));
if S <> INVALID_SOCKET then
begin
if (Id = '') or (Password = '') then
begin
// ID とパスワード入力
if InputForm.ShowModal = mrOk then
begin
Id := InputForm.IdEdit.Text;
Password := InputForm.PasswordEdit.Text;
end;
end;
// メールの数を得る
No := NMailPop3Authenticate(S, PChar(Id), PChar(Password), ApopFlag);
if No >= 0 then
begin
for Count := 1 to No do
begin
// 順番にヘッダの内容を読み、ListView に追加
{GetMem(Header, HEADER_MAX);
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
I.Data := Header;
StrLCat(Header, #13#10, HEADER_MAX - 1);}
strDate := StrPas(Date);
DataName := 'NML' + Copy(strDate, 1, 4) // yyyy
+ Copy(strDate, 6, 2) // mm
+ Copy(strDate, 9, 2) // dd
+ Copy(strDate, 12, 2) // hh
+ Copy(strDate, 15, 2) // mm
+ Copy(strDate, 18, 2); // ss
Seq := 0;
while FileExists(DataName + '_' + IntToStr(Seq) + '.nml') do Inc(Seq);
try
BodySize := NMailPop3GetMailSize(S, Count);
GetMem(Body, BodySize);
NMailPop3GetMail(S, Count, Subject, Date, From, Header, Body, nil, nil);
Fs := TFileStream.Create(DataName + '_' + IntToStr(Seq) + '.nml', fmCreate);
Fs.WriteBuffer(Header^, StrLen(Header));
Fs.WriteBuffer(Header^, StrLen(Body));
finally
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
if Fs <> nil then Fs.Free;
if Body <> nil then FreeMem(Body);
end;
end;
end
else
begin
// サーバーからのエラーメッセージを取得
NMailGetMessage(NMAIL_GET_ERROR_MESSAGE, Subject, HEADER_MAX);
MessageDlg('ログインエラー:' + StrPas(Subject), mtError, [mbOK], 0);
end;
NMailPop3Close(S);
S := INVALID_SOCKET;
end;
end;
そういうときはデバッグしてみましょう。
Dateの値は何になっています?
ちゃんと日付は入っていますか?
今Dateの値を調べたのですが空白または#0,#0がたくさん出てくる
値しか出ないで、Fs := TFileStream.Createの部分で以下の文が表示されます。
プロジェクト nmail.exe がEAccessViolationクラスの例外を生成しました。
'モジュール' 'nMail.DLL' のアドレス 10002E98 でアドレス 00000000に
対する書き込み違反がおきました。
どうしてそういう風になったのかが分かりました。
それは以下の2行までコメントにしてしまったからみたいです。
GetMem(Header, HEADER_MAX);
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);
あとファイルの事なのですが、EXEのある場所に生成されてしまうので
EXEのあるフォルダの下のRcvMail(Inbox)等のフォルダの中に入れたいのですが
どうすればよろしいでしょうか?(あとでツリービューとも関連付けたいのです)
EXEのあるフォルダは、ExtractFilePath(Application.ExeName)で取得できます。
TFileStream.Create時に指定すれば良いかと。
ツリービューと関連づけとはどのことでしょう。
メールのフォルダツリーと、フォルダに入ったメッセージ一覧の関連づけならば、フォルダ構造をそのまま使用すれば簡単です。
ツリービューのDataに、フォルダのパスを入れておき、OnChangeなどでリストビューに、ツリービューのDataに入ったフォルダ内部のnmlファイルを一覧すれば良いです。
リストビューがクリックされたときにも、リストビューのDataからファイル名を取得し、そのファイルをプレビューさせればよいです。
今それを使って作成しようとしたのですが今度は以下のエラーが出ます。
ソースファイルが見つかりません:classes.pas
無視を押すと次のメッセージが表示されます。
プロジェクト nmail.exe がEFCreateErrorクラスの例外を生成しました。
'ファイル' 'D:\Borland\Delphi6\Projects\NyantaMail\RcvMail\NML20021029162354_0.nml' を
作成できません。
多分フォルダがないために作れないのだと思うのですがその場合
フォルダを作るにはどうすればよいのでしょうか?
CreateDirかForceDirectoriesで作成できます。
ディレクトリが深いのであれば、ForceDirectoriesのほうが便利です。
classes.pasはなくとも、classes.dcuがあれば動くと思うんですが。
環境オプションのライブラリを変更しましたか?ライブラリパスに、
$(DELPHI)\Lib
があれば動くと思います。
指定してなかったら追加してみてください。
// ディレクトリがない場合は作成する(EXEのあるディレクトリ+RcvMail)
if(!DirectoryExists(RcvFolder + 'RcvMail')) then
begin
ForceDirectories(RcvFolder + 'RcvMail');
end;
上のコードでコンパイルしようとすると
不正な文字が入力ファイルにありますす:!($(21))と出るのですが
どうしてでしょうか?
!でなくnotです。
やっとファイル化までこぎつけれました。
でもまだこのファイルをリストとBodyMemoに読み込ませる作業と
UIDが同じメールをファイル化しないというのをつけなくては
いけないのですが、どうやれば良いでしょうか?
現在のリストを載せます。
procedure TMainForm.AddMailList(S: TSocket);
var
No, Count: integer;
Subject: array [0..HEADER_MAX] of Char;
Date: array [0..HEADER_MAX] of Char;
From: array [0..HEADER_MAX] of Char;
Header: PChar;
I: TListItem;
DataName: String; // NMLファイルのファイル名
Seq: Integer; // シーケンス番号
Body: PChar; // Bodyのデータ用
BodySize: Integer; // Bodyのファイルサイズ
Fs: TFileStream; // ファイルストリーム
strDate: String; // 日付の取得
begin
// メール本文表示をクリア
BodyMemo.Lines.Clear;
// ListView もクリア
HeaderDataClear;
MailListView.Items.Clear;
// POP3 サーバに接続する
S := NMailPop3Connect(PChar(Pop3Name));
if S <> INVALID_SOCKET then
begin
if (Id = '') or (Password = '') then
begin
// ID とパスワード入力
if InputForm.ShowModal = mrOk then
begin
Id := InputForm.IdEdit.Text;
Password := InputForm.PasswordEdit.Text;
end;
end;
// メールの数を得る
No := NMailPop3Authenticate(S, PChar(Id), PChar(Password), ApopFlag);
if No >= 0 then
begin
for Count := 1 to No do
begin
// 順番にヘッダの内容を読み、ListView に追加
GetMem(Header, HEADER_MAX);
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);
{I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
I.Data := Header;
StrLCat(Header, #13#10, HEADER_MAX - 1);}
strDate := StrPas(Date);
DataName := 'NML' + Copy(strDate, 1, 4) // yyyy
+ Copy(strDate, 6, 2) // mm
+ Copy(strDate, 9, 2) // dd
+ Copy(strDate, 12, 2) // hh
+ Copy(strDate, 15, 2) // mm
+ Copy(strDate, 18, 2); // ss
Seq := 0;
while FileExists(RcvFolder + 'RcvMail\' + DataName + '_' + IntToStr(Seq) + '.nml') do Inc(Seq);
try
BodySize := NMailPop3GetMailSize(S, Count);
GetMem(Body, BodySize);
NMailPop3GetMail(S, Count, Subject, Date, From, Header, Body, nil, nil);
RcvFolder := ExtractFilePath(Application.ExeName);
Fs := TFileStream.Create(RcvFolder + 'RcvMail\' + DataName + '_' + IntToStr(Seq) + '.nml', fmCreate);
Fs.WriteBuffer(Header^, StrLen(Header));
Fs.WriteBuffer(#13#10, StrLen(#13#10));
Fs.WriteBuffer(Body^, StrLen(Body));
finally
I := MailListView.Items.Add;
I.Caption := StrPas(Subject);
I.SubItems.Add(StrPas(Date));
I.SubItems.Add(StrPas(From));
if Fs <> nil then Fs.Free;
if Body <> nil then FreeMem(Body);
end;
end;
end
else
begin
// サーバーからのエラーメッセージを取得
NMailGetMessage(NMAIL_GET_ERROR_MESSAGE, Subject, HEADER_MAX);
MessageDlg('ログインエラー:' + StrPas(Subject), mtError, [mbOK], 0);
end;
NMailPop3Close(S);
S := INVALID_SOCKET;
end;
end;
長くなってきたのでファイル化についてはここで解決です。
次はファイル読み込みで書き直します。
ツイート | ![]() |