COM プログラミング

ASP(Active Server Pages)から呼出すプログラムは、スタンドアローンの プログラムの形式ではなくCOMサーバを作成します。 ここでは Visual C++ 5.0 の ATLベースのCOMサーバの作り方を説明します。 あなたのコンポーネントにSendMailメソッドを実装してみましょう。

ATL COM AppWizardプロジェクトの作成

[ファイル]-[新規作成]で[プロジェクト]ページの[ATL COM AppWizard]を 選択して[OK]を押します。次をチェックして[終了]を押します。

ATLオブジェクトの新規作成

[挿入]-[ATLオブジェクトの新規作成]で[ATLオブジェクト ウィザード]ダイアログを 開きます。[シンプルオブジェクト]をクリックして選択して、[次へ]を押します。
[ATL Object Wizardのプロパティ]ダイアログが開きます。
[名前]ページの[C++ ショート]に名前を入れると自動的に すべてのテキストボックスにデフォルトの名前が入ります。

[COM Prog ID]が外部からこのコンポーネントをアクセスするときに指定する名前となります。 ASPのVBScriptのServer.CreateObjectメソッドでオブジェクトを作成するときに使います。 この例では、Set obj = Server.CreateObject("Test.Test")になります。
[属性]ページでは次をチェックします。


インタフェースにメソッドを追加

クラスビューの中のインタフェース(ここでは ITest )を右クリックして [メソッドの追加]を選択します。

SendMailメソッドを次のように指定してみましょう。パラメータは、次のようにします。 [in] BSTR server,[in] BSTR to,[in] BSTR from,[in] BSTR subj,[in] BSTR body, [in] BSTR file,[out,retval] BSTR *pVal

メソッドのインプリメント

ファイルビューの中のcppファイル(ここでは test.cpp )をクリックして開きます。


次のコードをコピーしてください。コードは、たったこれだけです。 BSMTP DLL が面倒なメール送信処理をすべて行います。
// Bsmtp DLL
extern "C"
__declspec(dllimport) 
int BSendMail( LPCSTR szServer,	// smtp server name
               LPCSTR szTo,		// split by tab char
               LPCSTR szFrom,
               LPCSTR szSubject,
               LPCSTR szBody,
               LPCSTR szFile,    // Attach Files  split by tab char
               LPSTR msg);    // error message

STDMETHODIMP Ctest::SendMail(BSTR server, BSTR to, BSTR from, BSTR subj, BSTR body, BSTR file, BSTR * pVal)
{

	USES_CONVERSION;
	LPCSTR szServer = OLE2T(server);
	LPCSTR szTo = OLE2T(to);
	LPCSTR szFrom = OLE2T(from);
	LPCSTR szSubject = OLE2T(subj);
//	LPCSTR szBody = OLE2T(body);
	int bodylen = (lstrlenW(body)+1)*2;
	char *szBody = 
		ATLW2AHELPER((LPSTR) new char[bodylen], body, bodylen);

	LPCSTR szFile = OLE2T(file);

	char msg[128];

	if (szBody == NULL) {
		*pVal = A2BSTR("Body too large");
		return S_OK;
	}

	if (*szServer == '\0') {
		*pVal = A2BSTR("Server name invalid");
		delete [] szBody;
		return S_OK;
	}
	
	if (strchr(szTo,'@') == NULL) {
		*pVal = A2BSTR("To field invalid");
		delete [] szBody;
		return S_OK;
	}

	if (*szFrom == '\0') {
		*pVal = A2BSTR("From field invalid");
		delete [] szBody;
		return S_OK;
	}

	// file exist check is ready in BSendMail

	// call Bsmtp.dll
	int ok = BSendMail(szServer,   // SMTP サーバ名
            szTo,       // 宛先メールアドレス
            szFrom,     // 送信元メールアドレス
            szSubject,  // 件名
            szBody,     // 本文
            szFile,     // 添付ファイル
            msg);     // エラーメッセージ域

	delete [] szBody;

	if (ok) {	// success ?
		*pVal = A2BSTR("");
	}
	else {
		*pVal = A2BSTR(msg);
	}

	return S_OK;
}


ビルド

BSMTP DLLを使っているので[プロジェクト設定]の[オブジェクト/ライブラリモジュール]に bsmtp.libファイルを指定します。これで後は[F7]を押してビルドするだけ。


ATLビルド環境の不具合(rgsファイルの修正)

VC++5.0のATLビルド環境の不具合のため、CreateObjectメソッドで 失敗することがあります。
Set obj = Server.CreateObject("Test.Test.1")だとうまくいきますが、 Set obj = Server.CreateObject("Test.Test")だと失敗します。 ATL のレジストリの登録でversion-independent ProgIDのCLSIDが 登録されないことが原因です。 DevStudio\SharedIDE\Template\atlの中の*.rgs ファイルの中を 次のように編集してください。

	[!ProgID] = s '[!TypeName]'
	{
		CLSID = s '{[!ObjectGUID]}'
[!if=(InsertableEnabled, "TRUE")]
		'Insertable'
[!endif]
	}
	[!VersionIndependentProgID] = s '[!TypeName]'
	{
		CLSID = s '{[!ObjectGUID]}'      <=== この行を追加
		CurVer = s '[!ProgID]'
	}


これで次回からビルドするときに正しく登録されるようになります。

Home


Copyright 1997 Tatsuo Baba,All rights reserved.