ＢＳＭＴＰ ＤＬＬ
2003.02.11 更新

BSMTP DLLは、メール送信APIとメール受信APIを提供します。これをあなたのVisual Basic/C++ソースから呼出せばメール送受信が簡単にできます。メール受信時にコールバック関数を指定することにより、受信バイト数確認やキャンセルができます。 Visual C++とDelphiから使えます。１つのAPIを呼出すだけでメール送信ＯＫ。 Visual Basic/VBAからも使えます。
FlushMail API追加しました。2003/02/11 Update!
Java環境でSMTP/POP3などのメールをテストするには、 Jamesをどうぞ。
ダウンロードファイル一覧

    * bsmtp.dll　　本体
    * bsmtp.h　　 ヘッダファイル
    * bsmtp.lib　　Visual C++ 6.0 用LIBファイル 

Visual Basicからの使い方
Declareステートメントを次のように使ってください。

Private Declare Function SendMail Lib "bsmtp" _
      (szServer As String, szTo As String, szFrom As String, _
      szSubject As String, szBody As String, szFile As String) As String

Private Declare Function SendMailEx Lib "bsmtp" _
      (szLogfile As String, szServer As String, szTo As String, _
       szFrom As String, szSubject As String, szBody As String, szFile As String) As String

Private Declare Function RcvMail Lib "bsmtp" _
      (szServer As String, szUser As String, szPass As String, _
      szCommand As String, szDir As String) As Variant

Private Declare Function RcvMail2 Lib "bsmtp" _
      (szServer As String, szUser As String, szPass As String, _
      szCommand As String, szDir As String, callback As Long) As Variant

Private Declare Function ReadMail Lib "bsmtp" _
      (szFilename As String, szPara As String, szDir As String) As Variant

Private Declare Function SortMail Lib "bsmtp" _
      (szDir As String, szHeader As String, opt As Long, _
       szFilter As String,delflag As Long) As Variant

Private Declare Function FlushMail Lib "bsmtp" _
      (szServer As String, szDir As String, szLogfile As String) As Long


メール送信APIの使い方(Visual C++ 6.0/5.0)

    * bsmtp.dll をsystem32ディレクトリにコピー。BASP21 DLLを既にインストールしてあれば不要。
    * C++ 6.0 :bsmtp.lib を適当なディレクトリにコピー(例：c:\babaq\bsmtp.lib)
    * C++ 5.0 :bsmtp50.lib を適当なディレクトリにコピー(例：c:\babaq\bsmtp50.lib)
    * 関数プロトタイプを次のように定義

// Bsmtp DLL
extern "C"
__declspec(dllimport) 
int BSendMail( LPCSTR szServer,   // smtp server name
           LPCSTR szTo,       // to  （最大文字数は８１９２バイトです）
           LPCSTR szFrom,     // from
           LPCSTR szSubject,  // subject
           LPCSTR szBody,     // body
           LPCSTR szFile,     // Attach Files （フルパスでタブで区切って複数指定可）
           LPSTR msg);        // error message

    * 次のようにBSendMail関数を呼出す

    char msg[80];
    int ok = BSendMail(server,   // サーバー名。タブで区切ってポート番号を
                             // 指定できます。
                             // サーバ名の代わりにディレクトリ名（メールキュー）を指定すると
                             // メールファイルを作成します。2003/2/6 Update! 
                             // 戻り値は、メールキュー内のメールファイル数になります。
                             // 作成したメールファイルは、FlushMail APIファイルでサーバに送信します。
            to,       // to mail address (e.g., who@who.com\twho2...)
            from,     // from e-mail address
            subj,     // Message subject
            body,     // Message body
            files,    // Attach Files
            msg);     // error message
    if (!ok) {
            sprintf(buffer,"送信エラー (%s) %s %s %s %s",
                                          msg,server,to,from,subj);
    }
    // メールファイル指定の場合2003/2/6 Update! 
    if (ok <= 9) { // エラー
    }

    * リンクライブラリに　c:\babaq\bsmtp.lib（C++ 6.0の場合） c:\babaq\bsmtp50.lib（C++ 5.0の場合）を指定してリンク。
      bsmtp50.libは、リンクオプション /LINK50COMPATで作成しました。THNX!福嶋さん。 

メール送信APIの使い方(Visual C++ 4.2の場合)
Visual C++ 4.2 ではbsmtp50.libのリンク時にエラーが出るようです。この場合は、bsmtp50.lib を使えません。 LoadLibrary/GetProcAddressを使って関数をコールしてください。

// 関数のプロトタイプをtypedefを使って定義します。
typedef int  (*pBSendMail)( LPCSTR szServer,
               LPCSTR szTo,
               LPCSTR szFrom,
               LPCSTR szSubject,
               LPCSTR szBody,
               LPCSTR szFile,
               LPSTR msg);

// ライブラリをロードします
HINSTANCE hInst = ::LoadLibrary("bsmtp.dll");
if (hInst == NULL)
    return false;
// 関数ポインタを定義
pBSendMail pBs;
// BSendMail関数アドレスを設定
pBs = (pBSendMail)::GetProcAddress(hInst,"BSendMail");
if (pBs == NULL) {
   FreeLibrary(hInst);
   return false;
}
// ポインタを使ってBSendMailをコール
int ok = pBs(Server,To,From,Sub,Body,"",msg);

// 最後にライブラリをアンロード
FreeLibrary(hInst);

メール送信APIの使い方(Delphi)
Delphiでも動くようです。Delphiの場合は、libファイルは使えません。平野＠ラネックスさん、サンプルをありがとうございます。

Function BSendMail( 
		szServer,   // smtp server name
		szTo,       // to
	        szFrom,     // from
		szSubject,  // subject
		szBody,     // body
		szFile:LPCSTR;     // Attach Files  split by tab char
                msg:LPSTR):Integer;        // error message
		cdecl  external 'Bsmtp.dll';

procedure TForm1.Button1Click(Sender: TObject);
var
  wkstr : array[0..80]of Char;
begin
  if (BSendMail( PChar(Edit1.Text),  // smtp server name
                 PChar(Edit2.Text),  // to
                 PChar(Edit3.Text),  // from
                 PChar(Edit4.Text),  // subject
                 PChar(''), 	     // body
                 PChar(Edit5.Text),  // Attach Files  split by tab char
                 wkstr) <> 0 )Then
    begin
      Showmessage('出力しました');
    end
  else
    begin
      Showmessage(wkstr);
    end;
end;


Delphiでのメール受信のサンプルです。Thanks です北畑さん。

unit BSMTP;

interface

uses Windows;

type
  TBSMTPStatus = record
    Counter: integer;
    Status : array[0..255] of LPSTR;
  end;

  TPBSMTPStatus = ^TBSMTPStatus;


  function BSendMail(
      szServer,       // smtp server name
      szTo,           // to
      szFrom,         // from
      szSubject,      // subject
      szBody,         // body
      szFile:LPCSTR;  // Attach Files  split by tab char
      msg:LPSTR       // error message
  ):Integer;	cdecl  external 'Bsmtp.dll';

  procedure BFreeArray(Status:TPBSMTPStatus);  cdecl  external 'Bsmtp.dll';

  function BPOP3(
      szServer,       // pop3 server name
      szName,         // NAME
      szPass,         // PASSWORD
      szCommand,      // COMMAND
      szPath:LPCSTR;  // directory
      Status:TPBSMTPStatus;   // return ARRAY LIST
      msg:LPSTR	      // 80 bytes length message area
  ):Integer;	cdecl  external 'Bsmtp.dll';

  function BMIME(
      szCommand,      // command name
      szFileName,     // Target Name
      szPath:LPCSTR;  // Target Name
      Status:TPBSMTPStatus;   // return ARRAY LIST
      msg:LPSTR	      // 80 bytes length message area
  ):Integer;	cdecl  external 'Bsmtp.dll';


implementation

end.

FlushMail APIの使い方2003/02/11 New !
BSendMail API関数でメールキューに作成したメールファイルをSMTPプロトコルでメール送信します。複数メールファイルを一度のTCPコネクションで送信するので効率よくメールが送れます。バックグラウンド（別プロセスでbsendm.exeがFlushMailメソッドを実行）モードでの送信も可能です。
メールファイルは以下のようなテキスト形式です。

１行目：宛先メールアドレス
２行目：送信元メールアドレス
３行目：件名
４行目：添付ファイル名
５行目以降：本文

    * 関数プロトタイプを次のように定義

extern "C"
__declspec(dllimport) 
int BFlushMail(LPCSTR szServer,	// smtp server name
               LPCSTR szDir,	// メールキュー名
               LPCSTR szLogfile); // ログファイル名PASSWORD


char svr[] = "smtp-server";   // バックグラウンド指定は "&smtp-server"
char mdir[] = "c:\\temp\\maildir";
char logfile[] = "c:\\temp\\log.txt";
int rc = BFlushMail(svr,mdir,logfile);



cc/bcc/reply-toや任意のヘッダーの使い方
宛先メールIDパラメータの中にタブで区切ってcc/bcc/reply-to キーワードを指定します。任意のヘッダーは、">"文字をつけてそのまま指定します。

使用例:
●宛先が　id1　、CC に　id2、Message-IDヘッダーの例
szTo = "id1\tcc\tid2\t>Message-ID: 12345"

●宛先が　id1とid2　、CC に　id3の例
szTo = "id1\tid2\tcc\tid2"

●宛先が　id1とid2　、CC に　id3 id4 の例
szTo = "id1\tid2\tcc\tid3\tid4"

●宛先が　id1　、BCC に　id2の例
szTo = "id1\tbcc\tid2"

●宛先が　id1　、CC に　id2、BCCに id3の例
szTo = "id1\tcc\tid2\tbcc\tid3"

●宛先が　id1　、Reply-To に　id2の例
szTo = "id1\treply-to\tid2"

●CC に　id2の例
szTo = "cc\tid2"

●BCC に　id2の例
szTo = "bcc\tid2"

●メール送信の拡張オプション
2000/01/23 のバージョンから次のオプションがサポートされます。


   1. 代表宛先名 "@to-header" 先頭が"@" ならば 先頭の "@" を削除して To: ヘッダーとして送信します。メールアドレス以外の名前を使えます。日本語も使えます。メーリングリストに最適。必ず、bccあるいはcc と共に使うこと。例： mailto = "@Centerfolds-ML-User\tbcc\twho@hoge.com"; 次のように送信します。 To: Centerfolds-ML-User
   2. 転送モード ">#xfr file-name" 指定されたファイルを転送します。RcvMail メソッドで作成されたファイルを指定します。 To: ヘッダーは、削除されますので宛先を指定してください。サブジェクトは、上書きされます。サブジェクトが"" なら元のサブジェクトをそのまま送信します。パラメータとして指定された本文と添付ファイルは、無視されます。次のヘッダーは、ファイルから削除されます。 X-Mailer: X-Mail-Agent: Status: To: Return-Path: Delivered-To: 例１： mailto = "who@hoge.com\t>#xfr c:\\mail\\b21xxx.tmp"; 例２： mailto = "@ML-user\t>#xfr c:\\mail\\b21xxx.tmp\tbcc\twho@hoge.com";
   3. 転送モード時のヘッダー削除 ">#d" 転送するメールの該当ヘッダーを削除したいときに指定します。例： mailto = "@ML-user\t>#xfr c:\\mail\\b21xxx.tmp\t>#dcc:\tbcc\twho@hoge.com";
   4. Bcc ファイル入力モード ">#bcc file-name" メールアドレスをファイルから１行ずつ入力して メールを送信します。送信アドレスは、ヘッダーとして送信しない Bcc として処理しますメールアドレスは、メールIDのみを指定してください。例： mailto = "@ML-user\t>#xfr c:\\mail\\b21xxx.tmp\t>#bcc c:\\mai\\mailto.txt"; mailto.txt の内容： # comment １桁目が "#" の行はコメントとして無視されます who@hoge.com who1@hoge.com who2@hoge.com 




SMTPサーバ名の確認方法
SMTPサーバ名は、telnet コマンドで確認できます。次のようにポート番号２５を使って telnet コマンドを打って応答が返ってくるサーバ名がSMTPサーバです。 > telnet サーバ名 25
メール受信APIの使い方
POP3プロトコルでメールを受信します。

    * 関数プロトタイプを次のように定義

struct RetArray	{     
   int   counter;
   char* array[256];
};

extern "C"
__declspec(dllimport) 
void BFreeArray(RetArray* parray);


extern "C"
__declspec(dllimport) 
int BPOP3( LPCSTR szServer,	// pop3 server name
               LPCSTR szName,	// NAME
               LPCSTR szPass,	// PASSWORD
               LPCSTR szCommand,// COMMAND
               LPCSTR szPath,   // directory
               RetArray* RetArray,	// return ARRAY LIST
               LPSTR msg		// 80 bytes length message area
                );

extern "C"
__declspec(dllimport) 
int BMIME( LPCSTR szCommand,    // command name
               LPCSTR szFileName,   // Target Name
               LPCSTR szPath,   // Target Name
               RetArray* RetArray,	// return ARRAY LIST
               LPSTR msg		// 80 bytes length message area
                );


    * BPOP3関数

BPOP3関数は、メールサーバからメールを受信してファイルに書込みます。
パラメータの説明：
szServer　* POP3サーバ名を指定。IPアドレスでも可。タブで区切ってポート番号を
            指定できます。
szName　　* メールアカウントのユーザ名
szPass    * メールアカウントのパスワード名
      2000/05/20 APOPをサポート
      APOP 認証をするには、パスワードの前に "a" または "A" に １個の
      ブランクをつけます。
      "a xxxx" : サーバがAPOP 未対応なら通常のUSER/PASS 処理をします。
      "A xxxx" : サーバがAPOP 未対応ならエラーになります。
szCommand * 処理コマンド。大文字小文字どちらでも可。
          STAT ...... メール数と総バイト数のみを返します
          LIST ...... すべてのメールのSubject、From、Dateヘッダーの内容のみを
                      返します。
          SAVE n .... n番目のメールを受信します
          SAVD n .... n番目のメールを受信し、サーバのメールボックスから
                      削除します
          SAVEALL ... 全てのメールを受信します
          SAVEALLD .. 全てのメールを受信し、サーバのメールボックスから
                      削除します
szPath    * 受信したメールを保存するディレクトリ名を指定します。
RetArray  * メール受信の結果を配列で返します。配列内容はコマンドによって
                  次のようになります。エラーが発生した場合は、配列を返しません。
          SAVExxx - 受信ファイル名。
          STAT - メール数と総バイト数。
          LIST - タブで区切られたSubject、From、Dateヘッダーの内容
msg       * メッセージ領域（８０バイト）
戻り値    * 1以上だと正常終了。

    * BMIME関数

BMIME関数は、BPOP3関数で受信したRFC822形式のファイルを読込みます。
パラメータの説明：
szCommand　* コマンド。大文字小文字どちらでも可。
          GET  ...... メールをヘッダー、本文、添付ファイルを読込みます。
          GETNOF  ... メールをヘッダー、本文のみ読込みます。
          HEAD ...... メールのヘッダーのみ読込みます。
szFileName * BPOP3で書込まれたRFC822形式のファイル名
szPath    * 添付ファイルを保存するディレクトリ名を指定します。
RetArray  * メール受信の結果を配列で返します。配列内容はコマンドによって
                  次のようになります。エラーが発生した場合は、配列を返しません。
          HEAD - ヘッダー。
          GET  - ヘッダー、本文、添付ファイル名。
          GETNOF  - ヘッダー、本文。
msg       * メッセージ領域（８０バイト）
戻り値    * 1以上だと正常終了。

    * BFreeArray関数

BFreeArray関数は、BPOP3関数とBMIME関数で使用した配列メモリを開放します。
パラメータの説明：
parray    * RetArray構造体のアドレス

# BPOP3関数とBMIME関数の使い方

	char msgx[80];
	RetArray ret1,ret2;
	int rc = BPOP3( "server1","user1","pass1",
               "save 1","c:\\mail",&ret1,msgx);
	if (rc <= 0)
		return false;
	rc = BMIME("get",ret1.array[0],"c:\\mail",&ret2,msgx);
	if (rc > 0) {
		FILE *fp = ::fopen("c:\\mail\\mail.txt","wb");
		for (int i= 0;i < rc ;i++) {
			::fwrite(ret2.array[i],1,strlen(ret2.array[i]),fp);
			::fwrite("\015\012",1,2,fp); // put CRLF
		}
		::fclose(fp);
	}

	DeleteFile(ret1.array[0]);
	BFreeArray(&ret1);
	BFreeArray(&ret2);

# BPOP3関数でのコールバック関数の使い方

typedef BOOL (APIENTRY *pcallback)(int itemno,int len);

static BOOL APIENTRY CallBack(int itemno,int len)
{
	return 0;	// 1 でキャンセルできます
}


	char msgx[80];
	RetArray ret1;
	char name[200];			// ユーザ名 [tab] コールバック関数アドレス
	wsprintf(name,"user1\t%ld",(long)CallBack);
	int rc = BPOP3( "server1",name,"pass1",
               "saveall","c:\\mail",&ret1,msgx);

ご注意
Visual C++以外のコンパイラでの動作確認を行っておりません。
babaqフリーソフトのご使用上の注意
●プログラムを使って発生した損害に関しては、一切の責任を負いません。
●使用、配布に制限はありません。自由にお使いください。
●動作の保証はありません。
●動作を確認したＯＳは、Windows NT 4.0 とWindows 95/98/Me/XP/2000のみです。


==========================================================================================
==========================================================================================

Ｖｉｓｕａｌ Ｂａｓｉｃ Ｔｉｐｓ
2003.02.11 更新

Visual BasicやVBAならBASP21コンポーネントを使わなくてもメール送受信や正規表現処理が簡単にできます。 BSMTP DLLやBREGEXP DLLを直接Visual Basicから呼出せばいいのです。
Excelでのメール送信サンプルは、 http://homepage1.nifty.com/gak/MSTips/multimail.htmをどうぞ。






メールを送信する
SendMail関数を呼んでメールを送信するサンプルです。 BSMTP.DLLをWindowsのsystemディレクトリかVBアプリケーションを置くディレクトリにコピーします。

Option Explicit
Private Declare Function SendMail Lib "bsmtp" _
      (szServer As String, szTo As String, szFrom As String, _
      szSubject As String, szBody As String, szFile As String) As String

Private Declare Function FlushMail Lib "bsmtp" _  2003/02/11 New !
      (szServer As String, szDir As String, szLogfile As String) As Long

Private Sub Form_Load()
Dim ret As String
Dim szServer As String, szTo As String, szFrom As String
Dim szSubject As String, szBody As String, szFile As String

szServer = "your smtp"   ' SMTPサーバ名。
                         'タブで区切ってポート番号を指定できます。
szTo = "who@who.com"     ' 宛先
' 複数の宛先に送付するときは、アドレスをタブで区切って
' いくらでも指定できます。
szTo = "who1@who1.com" & vbTab & "who2@who2.com" ' 複数宛先
' CCを指定するには次のようにします。
szTo = "who@who.com" & vbTab & "cc" & vbTab & "who2@who2.com" & _
       vbTab & "who3@who3.com"
' BCCを指定するには次のようにします。
szTo = "who@who.com" & vbTab & "bcc" & vbTab & "who2@who2.com" & _
       vbTab & "who3@who3.com"
' ヘッダを指定するには次のようにタブで区切り、>をヘッダの前に
' つけます。
szTo = "who@who.com" & vbTab & ">Message-ID: 12345"
szFrom = "my@my.com"     ' 送信元
szSubject = "はじめまして"     ' 件名
' 本文内で改行するには、vbCrLfを使います。
szBody = "こんにちは。" & vbCrLf & "さようなら"   ' 本文
' ファイルを添付するときは、ファイル名をフルパスで指定します。
' ファイルを複数指定するときは、タブで区切ってください。
szFile = "c:\a1.gif" & vbTab & "c:\a2.jpeg" ' ファイル２個
' ファイルを添付しないときは次のようにします。
szFile = ""   ' ファイル添付なし

ret = SendMail(szServer, szTo, szFrom, szSubject, szBody, szFile)

' 送信エラーのときは、戻り値にエラーメッセージが返ります。
If Len(ret) <> 0 Then
   msgbox "エラー" & ret
End If

' メールキューにメールファイルを作成2003/02/11 New !
Dim mdir As String, szLogfile As String
Dim rcnt As Long
mdir= "c:\temp\mdir"  ' メールファイルを作成するフォルダ（メールキュー）

rcnt = SendMail(mdir, szTo, szFrom, szSubject, szBody, szFile)

' rcnt にはメールキュー内のメールファイル数が返ります。
'
szLogfile = "c:\temp\log.txt"   ' ログファイル名

rcnt = FlushMail(szServer, szTo, mdir, szLogfile)

' rcnt には送信ＯＫのメール数が返ります。

End Sub


SMTPサーバ名って何でしょう
サーバ名とはSMTPプロトコルをサポートしたメールサーバソフトが動作しているマシン名です。インターネットメールサーバ名ともいいます。 Outlookなどのメールソフトでインターネットメールの設定プロパティの [メールボックス情報]-[インターネットメールサーバー]に指定する名前です。 次に名前が正しいかどうか確認する方法を説明します。

メール送信するＰＣでコマンドプロンプトに入ります。
telnet コマンドをSMTPサーバ名とポート番号２５で実行します。
> telnet server 25
これで次のような応答が返ってくれば正しいサーバ名です。
220 xxxxxxxxxxxxxxxxxx ESMTP Sendmail 8.8.7/xxxxx ready at Sat, 29 Nov 1997
10:21:26 +0900

SMTPコネクションを切断するには quit コマンドを打ちます。
> quit


SendMail関数が遅いんです
SendMail関数を呼出すとメールサーバにメールデータを送信し終わるまで待ちます。
次に紹介するSendMailEx関数を使えばすぐに処理が戻ります。 SendMailEx関数は、メール送信処理を別プロセス（Bsendm.exe）に任せてさっさと終了します。 SendMailEx関数を使うにはBsendm.exeをWindowsのsystemディレクトリにコピーしておく必要があります。

Option Explicit
Private Declare Function SendMailEx Lib "bsmtp" _
      (szLogfile As String, szServer As String, szTo As String, _
       szFrom As String, szSubject As String, szBody As String, szFile As String) As String

Private Sub Form_Load()
Dim ret As String
Dim szLogfile As String
Dim szServer As String, szTo As String, szFrom As String
Dim szSubject As String, szBody As String, szFile As String

' メール送信結果を記録するファイル名を指定します。
szLogfile = "c:\log.txt" 
szServer = "your smtp"   ' SMTPサーバ名
                         'タブで区切ってポート番号を指定できます。
szTo = "who@who.com"     ' 宛先
szFrom = "my@my.com"     ' 送信元
szSubject = "はじめまして"     ' 件名
szBody = "こんにちは。" & vbCrLf & "さようなら"   ' 本文
szFile = "c:\a1.gif" & vbTab & "c:\a2.jpeg" ' ファイル２個

ret = SendMailEx(szLogfile,szServer, szTo, szFrom, szSubject, szBody, szFile)

' パラメータエラーのときは、戻り値にエラーメッセージが返ります。
If Len(ret) <> 0 Then
   msgbox "エラー" & ret
End If

End Sub


メールを受信したい
メールを受信するにはRcvMail関数を使います。RcvMail関数でメールボックスからメールを取出してみましょう。

Option Explicit
Private Declare Function RcvMail Lib "bsmtp" _
      (szServer As String, szUser As String, szPass As String, _
      szCommand As String, szDir As String) As Variant

Private Sub Form_Load()
Dim szServer As String, szUser As String, szPass As String
Dim szCommand As String, szDir As String
Dim ar As Variant, v As Variant

szServer = "your pop3 server"  'SMTPサーバ名と同じでよい。
                               'タブで区切ってポート番号を指定できます。
szUser = "your-name"  'メールアカウント名
szPass = "pass"       'パスワード
      2000/05/20 APOPをサポート
      APOP 認証をするには、パスワードの前に "a" または "A" に １個の
      ブランクをつけます。
      "a xxxx" : サーバがAPOP 未対応なら通常のUSER/PASS 処理をします。
      "A xxxx" : サーバがAPOP 未対応ならエラーになります。
szCommand = "SAVE 1-3"  'コマンド　メールの１件目から３件目までを受信
szDir = "c:\maildata" '受信したメールを保存するディレクトリ

ar = RcvMail(szServer, szUser, szPass, szCommand, szDir)

'戻り値が返る変数は、Variantタイプを指定すること。
'受信したメール１通ごとにファイルが作成されます。
'メールに添付されたファイルは、本文と共に１つのファイルに含まれます。
'ReadMail関数で添付ファイルを取出します。
If IsArray(ar) Then   '正常終了時のSAVEコマンドの戻り値は、配列になります。 
   For Each v In ar
    Debug.Print v     'メールデータが保存されたファイル名がフルパスで戻ります。 
                      'このファイル名をReadMailのパラメータとして渡します。 
   Next
Else
  Debug.Print ar      'エラー発生時は、配列でなくメッセージが戻ります。
End If

End Sub

コマンドは、次のように指定します。
　STAT ...... メールボックスに到着しているメール数と総バイト数のみを返します
　LIST [n[-n2]] ...... メールのSubject、From、Dateヘッダーの内容のみを
      　      返します。範囲も指定できます。
　SAVE n[-n2] .... n番目のメールを受信します。範囲も指定できます。
　SAVD n[-n2] .... n番目のメールを受信し、サーバのメールボックスから
    　        削除します。範囲も指定できます。
　SAVEALL ... 全てのメールを受信します
　SAVEALLD .. 全てのメールを受信し、サーバのメールボックスから
  　          削除します
　DELE n[-n2] .... n番目のメールをメールボックスから削除します。
　　　　　　　範囲も指定できます。

RcvMail関数の戻り値は、Variantタイプで指定します。正常に処理が終了したとき
配列で値が返されます。エラーが発生した場合は、配列を返しません。
配列内容はコマンドによって次のようになります。
　STAT - メール数と総バイト数。例：output(0) -> 2 4011
　LIST - タブで区切られたSubject、From、Dateヘッダーの内容
　例：output(0) -> こんにちは\txxxx@xxxx.xxx\t1998/09/15 11:11:30
　    output(1) -> こんにちは2\txxxx@xxxx.xxx\t1998/09/15 12:11:30
　SAVE/SAVED/SAVEALL/SAVEALLD - 受信したメールを保存したファイル名。
  DELE - メッセージが返ります。
　例："3 message(s) deleted"

メールが保存されるファイルの内容は、RFC822タイプの形式です。
添付ファイルも同じファイルに含まれています。
このRFC822タイプのファイルを読んでヘッダーや本文、添付ファイルを取出したりするには
次に説明するReadMail関数を使います。


メールの受信状態を知りたい
メールを受信状態を知るにはRcvMail2関数を使います。RcvMail2関数でコールバック関数を指定すると受信中のメールごとに受信バイト数が通知されます。コールバック関数でメールの受信処理をキャンセルすることもできます。

Option Explicit
Private Declare Function RcvMail2 Lib "bsmtp" _
      (szServer As String, szUser As String, szPass As String, _
      szCommand As String, szDir As String, callback As Long) As Variant

Private Sub Form_Load()
Dim szServer As String, szUser As String, szPass As String
Dim szCommand As String, szDir As String
Dim ar As Variant, v As Variant

szServer = "your pop3 server"  'SMTPサーバ名と同じでよい。
szUser = "your-name"  'メールアカウント名
szPass = "pass"       'パスワード
szCommand = "SAVE 1-3"  'コマンド　メールの１件目から３件目までを受信
szDir = "c:\maildata" '受信したメールを保存するディレクトリ

ar = RcvMail2(szServer, szUser, szPass, szCommand, szDir, AddressOf RcvMailCallBack)

End Sub

' コールバック関数は、モジュールに配置すること
Public Function RcvMailCallBack(ByVal item As Long, ByVal totlen As Long) As Long
    Debug.Print item     ' 受信数
    Debug.Print totlen   ' 受信バイト数
    RcvMailCallBack = 0  ' キャンセルするとき 戻り値に 1 を指定
End Function

パラメータや戻り値は、RcvMail関数と同じです。
コールバック関数が有効になるのは、次のSAVE 系のコマンドのみです。
　SAVE n[-n2] .... n番目のメールを受信します。範囲も指定できます。
　SAVD n[-n2] .... n番目のメールを受信し、サーバのメールボックスから
    　        削除します。範囲も指定できます。
　SAVEALL ... 全てのメールを受信します
　SAVEALLD .. 全てのメールを受信し、サーバのメールボックスから
  　          削除します

その他の LIST コマンドなどでは、コールバック関数の呼出しは行いません。


ReadMail関数を使ってメールの内容を読む
RcvMail関数でメールボックスから取出したメールを読むには、ReadMail関数を使います。

Option Explicit
Private Declare Function ReadMail Lib "bsmtp" _
      (szFilename As String, szPara As String, szDir As String) As Variant

Private Sub Form_Load()
Dim szFilename As String, szPara As String, szDir As String
Dim retv As Variant, v As Variant

szFilename = ar(0)  ' ファイル名にはRcvMailの戻り値の配列からファイル名を設定
szDir = "c:\mail"   ' 添付ファイルが保存されるディレクトリ
szPara = "subject:from:date:"  ' ヘッダーの指定
                               ' nofile: とすると添付ファイルを保存しません。

retv = ReadMail(szFilename,szPara,szDir)

If IsArray(retv) Then
   For Each v In retv
    Debug.Print v
   Next
Else
  Debug.Print retv
End If
End SUb

ReadMail関数は、読込んだメールの内容を配列で返します。
入力となるファイル名は、RcvMailで作成されたファイルを指定します。
ヘッダー、本文、添付ファイル名の順番に設定されます。
エラーが発生した場合は、配列を返しません。
例：output(0) -> To: xxxx@xxxx.xxx
    output(1) -> From: who@who.com
    output(2) -> Date: 1998/09/15 12:30:31
    output(3) -> .....
    output(4) -> Body: 本文
    output(5) -> File: ファイル名１
    output(6) -> File: ファイル名２


SortMail関数を使ってメールの内容をソート
SortMail関数を使えば　RcvMail関数で保存したメールをソートしたり選択したりできます。

Option Explicit
Private Declare Function SortMail Lib "bsmtp" _
      (szDir As String, szHeader As String, opt As Long, _
       szFilter As String,delflag As Long) As Variant

Private Sub Form_Load()
Dim szDir As String, szHeader As String, opt As Long
Dim szFilter As String, delflag As Long
Dim retv As Variant, v As Variant

szDir = "c:\mail"   ' メールファイルのディレクトリ
szFilter = "date:"  ' ソートヘッダーの指定
opt = 1             ' 逆順ソート
szFilter = "from:=babaq" ' 送信元が babaq 
delflag = 0         ' 削除しない

retv = SortMail(szDir,szHeader,opt,szFilter,delflag)

If IsArray(retv) Then
   For Each v In retv
    Debug.Print v
   Next
Else
  Debug.Print retv
End If
End Sub

szDir    : メールファイルのディレクトリ名。
szHeader : ソート対象のヘッダ名。ソートしない場合（選択や削除のみ）は、""。
               * で総称名が使えます。
               例：
               "From:"    - 送信元でソート
               "Date:"    - 送信日付でソート
               "Subject:" - 件名でソート
               "X-Mail*"  - X-Mailer または X-Mail-Agent ヘッダでソート。
opt       : ソートオプションを数字で指定。デフォルト値は、0。
               0 - 順ソート
               1 - 逆順ソート
               2 - 大文字小文字無視
szFilter  : 選択オプション。デフォルトは、"" ですべて選択します。
               ヘッダ名 + 条件 + 文字列で指定します。
               ヘッダ名は、*: で総称指定できます。
               文字列は、大文字小文字を無視します。
               文字列を指定しないと、ヘッダが存在するしないで選択できます。
               本文("Body:")や添付ファイル("File:")も指定可能。
               条件:　= 後続の文字列を含むものを選択
                      ! 後続の文字列を含まないものを選択
               例：
               "From:=babaq"   - 送信元にbabaq を含むメール
               "To:!hoge"      - 宛先に hoge を含まないメール
               "Body:=babaq"   - 本文に babaq を含むメール
               "References:="  - References ヘッダを含むメール
               "References:!"  - References ヘッダを含まないメール
               "X-Mail*:=outlook"   - Microsoft OutLook で送信したメール
                                      X-Mailer または X-Mail-Agent: ヘッダが該当します。
delflag    : 削除オプション。選択オプションと共に使います。デフォルトは、0。
               0 - 削除しません。
               1 - 選択条件に一致したものを削除します。
outarray   : ソート（あるいは選択、削除）されたファイル名を配列で返します。
                  エラーや該当するメールファイルがないときは配列でなく文字列が返ります。

使用例：
Dim dirx As String, outarray As Variant
dirx = "d:\mail" 
outarray = SortMail(dirx,"date:",1,"",0)  ' 最新日付の順にソート
' 古い日付の順にソート。Fromヘッダに hoge が含まれているメールのみ
outarray = SortMail(dirx,"date:",0,"from:==hoge",0)
' Fromヘッダに hoge が含まれているメールのみ削除
outarray = SortMail(dirx,"",0,"from:==hoge",1)
' 添付ファイルがあるメールのみ削除
outarray = SortMail(dirx,"",0,"File:=",1)
' Beckyで送信されたメールのみ取出す
outarray = SortMail(dirx,"",0,"X-Mailer:=becky",0)



正規表現を使ってみたい
正規表現は、文字列をパターンとして処理することができます。ここではBREGEXP DLLが提供するMatch/MatchEx/Replace/Translate/Split関数を紹介します。はじめに、BREGEXP.DLLをWindowsのsystemディレクトリかVBアプリケーションを置くディレクトリにコピーします。

Private Declare Function Match Lib "bregexp" _
      (szRegstr As String, szTarget As String) As String

Private Declare Function MatchEx Lib "bregexp" _
      (szRegstr As String, szTarget As String, mode As Long) As Variant

Private Declare Function Replace Lib "bregexp" _
      (szRegstr As String, szTarget As String) As String

Private Declare Function Translate Lib "bregexp" _
      (szRegstr As String, szTarget As String, ret As String) As Long

Private Declare Function Split Lib "bregexp" _
      (szRegstr As String, szTarget As String, limit As Long) As Variant



'◆Match
' Match関数は、パターンマッチで文字列検索を行ない、"1" または偽 ("0") を返します。
' グループメタ文字"()"を使った場合は、マッチした文字列を返します。
' szRegstr : パターン。
' szTarget : 対象文字列。
' 戻り値   : "1"または"0"またはマッチした文字列。
' パターンは、次のように指定します。パターンの詳細は、Perlのマニュアルを参照。
'  /PATTERN/gik
'       g   グローバルにマッチ、つまり、すべてを探し出す
'       i   大文字、小文字を区別しない
'       k   日本語を処理する。日本語をシングル文字として処理しない。
'       m   文字列を複数行として扱う。
'
ret = Match("/\d{3}/", szTarget)
If ret then
  '数字が３桁含まれている
End If
' 連続している３桁の数字を取出す
ret = Match("m/(\d{3})/", szTarget)
'
'
'◆MatchEx
' MatchEx関数は、パターンマッチの拡張版です。正規表現メモリ（Perl の $1 $2 に対応）や
' すべてのマッチ文字を' を返します。グループメタ文字"()"は、マッチした文字を記憶します。
' szRegstr : パターン。
' szTarget : 対象文字列。
' mode     : マッチモードを数字で指定します。
'            0 : 正規表現メモリモード
'            1 : すべてのマッチ文字を返します
' 戻り値   : マッチ結果を配列で返します。
'          正規表現メモリモード：
'          out(0) : マッチした文字列そのもの。Perl では $& 。
'          out(1) : マッチ文字列の前の文字列。Perl では $` 。 
'          out(2) : マッチ文字列の後の文字列。Perl では $' 。
'          out(3) : メモリ１の文字列。Perl では $1 。
'          out(4) : メモリ２の文字列。Perl では $2 。
'          out(n) : メモリｎの文字列。Perl では $n 。
'          すべてのマッチ：
'          out(0) : マッチした文字列１。
'          out(1) : マッチした文字列２。
'          out(2) : マッチした文字列３。
'          out(n) : マッチした文字列ｎ。
'
'
ret = MatchEx("/\d{3}/", szTarget,1)  ' すべての３桁の数字を求める
If IsArray(ret) then   ' 配列のとき、マッチ
   Dim v As Variant
   For Each v In ret
    Debug.Print v
   Next
End If
'
'
'◆Replace
' Replace関数は、文字列中でパターンを検索し、もし見つかれば、置換テキストで置き換えた
' 文字列を返します。
' szRegstr : パターン。
' szTarget : 対象文字列。
' 戻り値   : 置換後の文字。
' パターンは、次のように指定します。パターンの詳細は、Perlのマニュアルを参照。
'   s/PATTERN/REPLACEMENT/gikm
'
' 数字をすべてxに変更する例。
ret = Replace("s/\d/x/g", szTarget)
'
' Perlのマニュアルに出てた最初の 2 語を入替える例。なんの意味があるのでしょうか（笑）
ret = Replace("s/^([^ ]*) *([^ ]*)/$2 $1/",szTarget)
'
'
'◆Translate
' Translate関数は、検索リスト (SEARCHLIST) に含まれる文字を、対応する置換リスト
' (REPLACEMENTLIST) の文字に変換します。また、置換または削除が行なわれた、文字数を返します。
' szRegstr : パターン。
' szTarget : 対象文字列。
' ret      : 置換後の文字列。
' 戻り値   : 文字数。
' パターンは、次のように指定します。パターンの詳細は、Perlのマニュアルを参照。
'     tr/SEARCHLIST/REPLACEMENTLIST/cds
'
'        オプションには、
'          c   SEARCHLIST を補集合にする
'          d   見つかったが置換されなかった文字を削除する
'          s   置換された文字が重なったときに圧縮する
'          k   日本語を処理する。日本語をシングル文字として処理しない。
'
' 小文字を大文字に変更する例。
Dim ctr as Long
ctr = Translate("tr/a-z/A-Z/", szTarget, ret)
'
'
'◆Split
' Split関数は   文字列を文字列の配列に分割して、それを返します。
' szRegstr : パターン。Match関数と同じ。
' szTarget : 対象文字列。
' limit    : 配列数の制限値。0を指定すると無制限。
' 戻り値   : 配列。
Dim retv as Variant,v as Variant
retv = Split("/\d/k", "5,4,6,c", 30)
If IsArray(retv) Then
   For Each v In retv
    
    Debug.Print v
   Next
Else
  Debug.Print retv
End If



プログラムコードのご使用上の注意
●プログラムコードを使って発生した損害に関しては、一切の責任を負いません。
●使用、配布に制限はありません。自由にお使いください。
●動作の保証はありません。
●動作を確認したＯＳは、Windows NT 4.0 とWindows 95/98/Me/XP/2000のみです。

