受信したデータをファイル化するには?

解決


みけにゃん  URL  2002-10-28 17:36:21  No: 1816

前回の書込みの時に書いたメールクライアントでPOP3受信の時に
データをファイル化していちいちPOP3サーバからメールのデータを
受信したくないのですがどうやって行えば良いのでしょうか?


にしの  2002-10-28 23:10:19  No: 1817

TMemoryStreamなどに書き込んで、SaveToFileで保存するだけです。


みけにゃん  URL  2002-10-28 23:26:42  No: 1818

いまいち分からないので今作っているプログラムのソースを
http://isweb11.infoseek.co.jp/play/knekodo/new.htmlに
置くのでソースを見て教えていただけるとありがたいです。
なお都合でアップは17時以降でないと無理なのでごめんなさいです。


みけにゃん  URL  2002-10-29 17:58:00  No: 1819

ソースの方はアップしましたのでできるだけ早くお願いします。
http://isweb11.infoseek.co.jp/play/knekodo/file/nme_dev.lzh


にしの  2002-10-29 18:16:13  No: 1820

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;
になります。


みけにゃん  URL  2002-10-29 20:27:04  No: 1821

Delphi6 Personalで作っています。
多分それで開けないんだと思います。
POP3受信の時のタイミングで保存するのかなと思っているのですが・・・


みけにゃん  URL  2002-10-29 20:47:18  No: 1822

追加なのですがnMail.DLLのSDKも入れないと動かないので
http://www.nanshiki.co.jp/よりダウンロードをお願いします


にしの  2002-10-29 21:27:50  No: 1823

Delphi6を持っていないのでプロジェクトに対してコメントできません。

NMailPop3GetMailを呼び出した後、TMemoryStreamのオブジェクトを作成し、
Subject, Date, From, Header, Bodyなど必要なデータを整形しWriteBufferで出力。
SaveToFileで保存です。
オブジェクトの解放も忘れずに。


みけにゃん  URL  2002-10-29 23:11:13  No: 1824

えっとDelphi6 Personal(無料で利用できる)を使ってやっているので
Borlandさんのホームページからダウンロードすれば使えると思います。
ちなみにこのプログラムはnMail.dllのSDKのサンプル(PDS)を参考に
しながら作っています。(サンプル自体はDelphi3で開けるそうです。)
サンプルは圧縮ファイルの中のDpmail.lzhに入っています。

POP3の受信のあたりはいじっていないのでチェックしてもらえるとうれしいです。


にしの  2002-10-29 23:17:05  No: 1825

いや、前に入れたことがあるんですが、Delphi6をアンインストールしたときDelphi5の設定まで消されまして。
わざわざDelphi6を入れたくないのです。

2つ上の、僕の発言では、わからなかったんでしょうか。


みけにゃん  URL  2002-10-29 23:34:05  No: 1826

そうなんですかぁ・・・。

それならその下に書いたDPMailのサンプルをDelphi5で開いてみてください。
それにも同じコードがあるのでそこで試していただけませんか?
サンプルはDelphi3以上の環境なら動くとかいてあります
>同梱のreadme.txt?に書いてありました。


みけにゃん  URL  2002-10-29 23:39:55  No: 1827

連続書き込みでごめんなさい。

一応MemoryStreamを試してみて出来たファイルを開いてみたのですが
中身がぐちゃぐちゃのファイルでちょっと困りました。

また、ちゃんとしたメーラとして作っているのでこの出来た
データを元のリストビューに読み込ませて件名などを
表示したり、リストビューをクリックしたら本文を
BodyMemoに出力したりしたいのですが・・・


にしの  2002-10-30 00:16:46  No: 1828

もしかして、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にはそういう関数がないようなので、自前で戻さねばなりません。


みけにゃん  URL  2002-10-30 00:37:44  No: 1829

これだと一件クリックしたごとにファイルが上書きされてしまい
後で困るのですが・・・どうすればよいでしょうか?

ちなみにBeckey!やAL-Mailは日付+時刻+拡張子のファイル名で保存していて
このリストビューをクリックした時の受信の動作ではなくてメールメニューの
受信をクリックした時にファイルとして保存しないといけないような気がします。
このメーラも同じように受信をクリックした時にファイルをメールのヘッダと
本文をFileStreamで出力してリストビューをクリックした時にはHDDに
保存したメールのファイルを読み出すようにすれば良いと思うのですが
どうでしょうか?


にしの  2002-10-30 00:47:03  No: 1830

> 受信をクリックした時にファイルとして保存しないといけないような気がします。
> このメーラも同じように受信をクリックした時にファイルをメールのヘッダと
> 本文をFileStreamで出力してリストビューをクリックした時にはHDDに
> 保存したメールのファイルを読み出すようにすれば良いと思うのですが
> どうでしょうか?
そうですね。

メール受信時は、
・->「受信」ボタンを押す<メニューでも何でもいいです
・POP3接続開始
・サーバにあるメッセージの数を取得
・サーバにあるメッセージの全てのUIDLを取得
・現在ローカルに保存してあるメッセージに、サーバ側メッセージのUIDLがあれば、ダウンロードしないようにするチェック
・サーバにあるメッセージで、ローカルにないメッセージを1つずつ読み込む
==ここ
・ローカルのファイルに保存
==ここ
・サーバ側メッセージを削除する設定なら、メッセージを削除
・サーバ切断

という処理になると思います。
日本語で書くと難しくなりますが、処理的には難しくないと思います。

ファイル名は、yyyymmddhhmiss_seqという記述ならいいと思います。
# 年月日時分秒_シーケンス番号
シーケンスが必要な理由は、同じ時分秒に複数のメールがあるかもしれないからです。


みけにゃん  URL  2002-10-30 01:04:27  No: 1831

と言うことはprocedure TMainForm.AddMailListの部分に書くのですね?
→上で書いた事

でもDelphiはからっきしの初心者なのであんまり分からないです。
本当にこんなこと書いちゃってごめんなさいです。

ファイル名に数字(日付+シーケンス番号)を入れるのも分からないです。


にしの  2002-10-30 01:54:55  No: 1832

> と言うことは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);
などとして、シーケンスまで決定します。


みけにゃん  URL  2002-10-30 02:27:14  No: 1833

ちょっと書いて実行してみたのですが、不正な処理(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;


みけにゃん  URL  2002-10-30 18:14:06  No: 1834

家に帰ってから考えていたのですがやっぱり上のソース以降
進めなくて困っています(追加した部分は現在コメントにしてあります。)
こんな感じでよいのでしょうか?

// メール読み込み
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;


にしの  2002-10-30 18:37:42  No: 1835

ファイルに格納するので、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)をファイル名としてファイルを読み込み、それをメールデータとして扱ってください。
# ヘッダと本文は空行で分かれているはず

添付ファイルは、自前で変換する必要が出ると思います。


みけにゃん  URL  2002-10-30 20:02:21  No: 1836

今試していたのですがやっぱり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;


にしの  2002-10-30 20:10:05  No: 1837

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'くらい設定しておいてくれれば楽なんですがね


みけにゃん  URL  2002-10-30 20:24:12  No: 1838

上の書き込みに書いてあった処理を追加して実行したのですが
やはり不正な処理で終了してしまいます(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;


にしの  2002-10-30 20:28:39  No: 1839

そういうときはデバッグしてみましょう。
Dateの値は何になっています?
ちゃんと日付は入っていますか?


みけにゃん  URL  2002-10-30 20:51:47  No: 1840

今Dateの値を調べたのですが空白または#0,#0がたくさん出てくる
値しか出ないで、Fs := TFileStream.Createの部分で以下の文が表示されます。

プロジェクト nmail.exe がEAccessViolationクラスの例外を生成しました。
'モジュール' 'nMail.DLL' のアドレス 10002E98 でアドレス 00000000に
対する書き込み違反がおきました。


みけにゃん  URL  2002-10-30 20:58:19  No: 1841

どうしてそういう風になったのかが分かりました。
それは以下の2行までコメントにしてしまったからみたいです。

GetMem(Header, HEADER_MAX);
NMailPop3GetMailStatus(S, Count, Subject, Date, From, Header, False);

あとファイルの事なのですが、EXEのある場所に生成されてしまうので
EXEのあるフォルダの下のRcvMail(Inbox)等のフォルダの中に入れたいのですが
どうすればよろしいでしょうか?(あとでツリービューとも関連付けたいのです)


にしの  2002-10-30 21:04:09  No: 1842

EXEのあるフォルダは、ExtractFilePath(Application.ExeName)で取得できます。
TFileStream.Create時に指定すれば良いかと。

ツリービューと関連づけとはどのことでしょう。
メールのフォルダツリーと、フォルダに入ったメッセージ一覧の関連づけならば、フォルダ構造をそのまま使用すれば簡単です。
ツリービューのDataに、フォルダのパスを入れておき、OnChangeなどでリストビューに、ツリービューのDataに入ったフォルダ内部のnmlファイルを一覧すれば良いです。
リストビューがクリックされたときにも、リストビューのDataからファイル名を取得し、そのファイルをプレビューさせればよいです。


みけにゃん  URL  2002-10-30 21:29:20  No: 1843

今それを使って作成しようとしたのですが今度は以下のエラーが出ます。

ソースファイルが見つかりません:classes.pas
無視を押すと次のメッセージが表示されます。

プロジェクト nmail.exe がEFCreateErrorクラスの例外を生成しました。
'ファイル' 'D:\Borland\Delphi6\Projects\NyantaMail\RcvMail\NML20021029162354_0.nml' を
作成できません。

多分フォルダがないために作れないのだと思うのですがその場合
フォルダを作るにはどうすればよいのでしょうか?


にしの  2002-10-30 21:48:03  No: 1844

CreateDirかForceDirectoriesで作成できます。
ディレクトリが深いのであれば、ForceDirectoriesのほうが便利です。

classes.pasはなくとも、classes.dcuがあれば動くと思うんですが。
環境オプションのライブラリを変更しましたか?ライブラリパスに、
$(DELPHI)\Lib
があれば動くと思います。
指定してなかったら追加してみてください。


みけにゃん  URL  2002-10-30 22:23:49  No: 1845

// ディレクトリがない場合は作成する(EXEのあるディレクトリ+RcvMail)
if(!DirectoryExists(RcvFolder + 'RcvMail')) then
begin
  ForceDirectories(RcvFolder + 'RcvMail');
end;

上のコードでコンパイルしようとすると
不正な文字が入力ファイルにありますす:!($(21))と出るのですが
どうしてでしょうか?


にしの  2002-10-30 22:31:42  No: 1846

!でなくnotです。


みけにゃん  URL  2002-10-30 23:06:53  No: 1847

やっとファイル化までこぎつけれました。
でもまだこのファイルをリストと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;

長くなってきたのでファイル化についてはここで解決です。
次はファイル読み込みで書き直します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加