先ほどのIndyの文字化けの件は大変ありがとうございました。
WinXP、C++BuilderXE2スターターです。
山本隆の開発日誌さんの、
C++Builder2010とIndy10でメールを送信する
http://www.gesource.jp/programming/bcb/97.html
と、
Mr.XRAYさんの、
776_TIdPOP3を使用してメール受信
http://mrxray.on.coocan.jp/Delphi/plSamples/776_IdPOP3MailClient.htm
を参考にしながら書いています。
添付ファイルを参照することまでは出来たのですが、
添付ファイルを保存する所までが辿りつけません。
色々試行錯誤してみたのですが、Header情報を保存してしまうのみで、
添付ファイルを保存できません。
こちらの環境には、TIdAttachmentFileコンポーネントが無いようで、検索でも余り情報が引っかからず、お手上げ状態です。
IndyをTIdAttachmentFileがある、古いバージョンにしてしまう事も考えてます。
どなたか、お知恵を拝借いただけると助かりますm(__)m。
以下ソースです。
//テスト受信
bool result = IdPOP31->Retrieve(5049, msg); //メールの番号は1から
if (result)
{
StringGrid1->Cells[1][1] = msg->Subject;
StringGrid1->Cells[2][1] = msg->Body->Text;
StringGrid1->Cells[3][1] = msg->Date;
StringGrid1->Cells[4][1] = msg->From->Text;
StringGrid1->Cells[5][1] = item->Address;
StringGrid1->Cells[6][1] = msg->Headers->Text;
int i = 1;
while ("" != msg->MessageParts->Items[i]->FileName)
{
try
{
StringGrid1->Cells[7][1] = StringGrid1->Cells[7][1] + msg->MessageParts->Items[i]->FileName;
//↓ここが問題の部分です。
msg->SaveToFile("d:\\aaa.txt",msg->MessageParts->Items[i]->Headers);
}
catch (int)
{
}
}
}
else
{
MessageDlg("メールの受信に失敗しました。", mtError, TMsgDlgButtons() << mbOK, 0);
}
}
こんにちは.Mr.XRAYです.
>IndyをTIdAttachmentFileがある、古いバージョンにしてしまう事も考えてます。
古いバージョンにあるかどうかは知りませんが,Indyのインストール先にIdAttachmentFileという名前の
ファイルが,もしあったら,usseに追加して見てください.
ない場合は,分かりません.
ゴメンなさい.C++だから #include ですね.
Mr.XRAYさんありがとうございます。
探してみたところ、そのファイルはCBuilderXE2に入っていました。
しかし、今度は「system.Classes.pas」というファイルが必要だと、
コンパイラから怒られました。
そこでそのファイルを探してみたのですが、PC上にありませんでした。
コードの書き方が間違っているのでしょうか?
以下がサイトを参考にしながら書いてみたコードです。
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//メールを受信する
UnicodeString AFileName = "d:\\aaa.txt";
TIdMessage* msg = new TIdMessage(NULL);
TIdEMailAddressItem* item = msg->Recipients->Add();
TIdAttachmentFile* attached = new TIdAttachmentFile(
msg->MessageParts,
msg->MessageParts->Items[1]->FileName); //ファイルのパス
bool result = IdPOP31->Retrieve(5049, msg); //メールの番号は1から
if (result)
{
StringGrid1->Cells[1][1] = msg->Subject;
StringGrid1->Cells[2][1] = msg->Body->Text;
StringGrid1->Cells[3][1] = msg->Date;
StringGrid1->Cells[4][1] = msg->From->Text;
StringGrid1->Cells[5][1] = item->Address;
StringGrid1->Cells[6][1] = msg->Headers->Text;
int i = 1;
while ("" != msg->MessageParts->Items[i]->FileName)
{
try
{
StringGrid1->Cells[7][1] = StringGrid1->Cells[7][1] + msg->MessageParts->Items[i]->FileName;
//↓この部分が自分が書いた部分で、最も怪しい部分です。
attached->SaveToFile(AFileName);
}
catch (int)
{
}
}
}
else
{
MessageDlg("メールの受信に失敗しました。", mtError, TMsgDlgButtons() << mbOK, 0);
}
}
コードを整理したところ、初歩的バグが多数あったので、
直しましたが、まだダウンロードに失敗します。
少しずつ原因が見えてきて、自分の技量不足が、
最大の要因っぽいです。
以下、現在のコードです。
どなたかお知恵をお貸しいただけると助かりますm(__)m。
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//メールを受信する
TIdMessage* msg = new TIdMessage(NULL);
TIdEMailAddressItem* item = msg->Recipients->Add();
//1件だけ試し受信
bool result = IdPOP31->Retrieve(5049, msg); //メールの番号は1から
if (result)
{
StringGrid1->Cells[1][1] = msg->Subject;
StringGrid1->Cells[2][1] = msg->Body->Text;
StringGrid1->Cells[3][1] = msg->Date;
StringGrid1->Cells[4][1] = msg->From->Text;
StringGrid1->Cells[5][1] = item->Address;
StringGrid1->Cells[6][1] = msg->Headers->Text;
int i = 1;
while ("" != msg->MessageParts->Items[i]->FileName)
{
try
{
TIdAttachmentFile* attached = new TIdAttachmentFile(
msg->MessageParts,
msg->MessageParts->Items[i]->FileName); //ファイルのパス
StringGrid1->Cells[7][1] = StringGrid1->Cells[7][1] + msg->MessageParts->Items[i]->FileName;
attached->SaveToFile("d:\\" + msg->MessageParts->Items[i]->FileName);
}
catch (int)
{
}
i += 1;
}
}
else
{
MessageDlg("メールの受信に失敗しました。", mtError, TMsgDlgButtons() << mbOK, 0);
}
}
コードを見せられても....
>しかし、今度は「system.Classes.pas」というファイルが必要だと、
ではなかったんでしたっけ.
Delphiの場合ですが,新規でVCLフォームアプリケーションを作句すると.usesが
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
となります.新規のユニット作成の場合は何もありません.
Delphiでは,これらのファイルの拡張子は.pas(パスカルのパス)です.
このファイルにいろいろなクラスやメソッド,関数類が書いてあり,それらを使用するするわけです.
コンポーネントをフォームに配置した時は,自動で,必要なものが追加されます.
そうでない場合は,今回のように,自分が追加することになります.
おそらく,C++BuilderXE2 も同様に #include があるのではないかと思われます.
この中で,System.Classes にはかなり基本的なコード類が収めてあります.
もし,これがないとすると,相当値切って購入したか,その C++BuilderXE2 のファイル構成やら,
何かの設定が壊れているではないかと思います.
一度,新規のプロジェクトを作成して,その動作を確認してみてはいかがでしょうか.
残念ですが,私には,これ以上のことは分かりません.
C++Builder XEで添付ファイルを保存するソースコードです。
参考になれば。
for (int i = 0; i < IdMessage1->MessageParts->Count; ++i)
{
TIdMessagePart* part = IdMessage1->MessageParts->Items[i];
if (part->PartType() == mptAttachment)
{
TIdAttachmentFile* attached = dynamic_cast<TIdAttachmentFile*>(part);
if (attached != 0)
{
//TODO:ファイル名はデコードする必要がある
attached->SaveToFile(attached->FileName);
}
}
}
>Mr.XRAYさん
ご指摘ありがとうございます、原因のひとつが判りました。
プロジェクトファイルが壊れていました(笑)。
それに気づかず、Builderを3回ほどクリーンインストールしてしまいました・・・。
Indy10を無理やり古いバージョンと交換したところ、BuilderのIndyが再インストール不能となり、
またインストール、それでもIndyが正常に認識されず、駄目元でプロジェクトを新規作成してみたら、
あっさりと動きました^^;。
system.Classesというのは、Builderのプロジェクトファイルの一番先頭に記述されていて、
Indy10使用時にエラーを起こすと、そのメッセージが出るみたいです。
バグをつぶしていったところ、そのエラーは出なくなりました。
お騒がせしました^^;。
>山本隆さん
ありがとうございます!!m(__)m
サイト参考にさせてもらっています。
DelphiからC++Builderに移ってまだ日が浅いので、大変参考になります。
早速実装したところ、きれいに動きました(!)
C++で組むのを諦めて、Delphiで組みなおしている最中でした。
助かりました、皆さん本当にありがとうございますm(__)m。
以下、完成したメール読み込み部です。
折角Delphiでも作ったので、(自身の勉強の為にも)後ほどDelphiで組んだものも載せておきます。
環境
WinXP C++BuilderXE2スターター
メール読み込み部分
void __fastcall TForm1::Button3Click(TObject *Sender)
{
chekcount = IdPOP31->CheckMessages();
Button5Click(Sender);
//メールを受信する
TIdMessage* msg = new TIdMessage(NULL);
TIdEMailAddressItem* item = msg->Recipients->Add();
//int i1 = 1;
//1件だけ試し受信
int mailcount = 1;
int message = 2;//IdPOP31->CheckMessages();
StringGrid1->RowCount = IdPOP31->CheckMessages();
while (message > mailcount)
{
bool result = IdPOP31->Retrieve(5049, msg); //メールの番号は1から
if (result)
{
StringGrid1->Cells[1][mailcount] = msg->Subject;
StringGrid1->Cells[2][mailcount] = msg->Body->Text;
StringGrid1->Cells[3][mailcount] = msg->Date;
StringGrid1->Cells[4][mailcount] = msg->From->Text;
int Ritems = 0;
int Rcount = msg->Recipients->Count;
while ( Ritems < Rcount + 1)
{
StringGrid1->Cells[5][mailcount] = StringGrid1->Cells[5][mailcount] + msg->Recipients->Items[Ritems]->Text + char(13);
Ritems += 1;
if (Ritems == Rcount)
{
Ritems += 2;
}
}
StringGrid1->Cells[6][mailcount] = msg->Headers->Text;
for (int i = 0; i < msg->MessageParts->Count; ++i)
{
TIdMessagePart* part = msg->MessageParts->Items[i];
if (part->PartType() == mptAttachment)
{
TIdAttachmentFile* attached = dynamic_cast<TIdAttachmentFile*>(part);
if (attached != 0)
{
//TODO:ファイル名はデコードする必要がある
StringGrid1->Cells[7][mailcount] = StringGrid1->Cells[7][mailcount] + attached->FileName;
attached->SaveToFile("d:\\" + attached->FileName);
}
}
}
ツイート | ![]() |