=================== fup.html ================
<HTML><BODY>
<FORM ACTION="fup.asp" ENCTYPE="multipart/form-data" METHOD=POST>
氏名: <INPUT TYPE=TEXT NAME="yourname"><BR>
ファイル1: <INPUT TYPE=file NAME="file1"><BR>
ファイル2: <INPUT TYPE=file NAME="file2"><BR>
<INPUT TYPE=SUBMIT NAME=UPLOAD>
</FORM></BODY></HTML>
=================== fup.html end ============
=================== fup.asp =================
<%
set obj=server.createobject("fileup")
name=obj.FormData("yourname")
f1=obj.FileName("file1")
newf1="d:\temp\fup" & Mid(f1,InstrRev(f1,"\"))
fsize1=obj.SaveAs("file1",newf1)
%>
<HTML><HEAD><TITLE>File Upload Test</TITLE>
<BODY>
<H1>Testing</H1>
<BR>
<%= name %>さん、<%= newf1 %>にアップロードされました<BR>
ファイルサイズ= <%= fsize1 %><BR>
=================== fup.asp end =============
ここでは次のことが学習できます。


クライアントからデータを受取るのにIRequestインタフェースを使うので、
[ActiveXサーバコンポーネント]をクリックして選択して、[次へ]を押します。

[ATL Object Wizardのプロパティ]ダイアログが開きます。
[名前]ページの[C++ ショート]に名前を入れると自動的に
すべてのテキストボックスにデフォルトの名前が入ります。
.H ファイルと.CPPファイルの名前とProg IDの名前を変更します。

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

[ASP]ページでは次をチェックします。要求とはASPのIRequestオブジェクトのことです。


SaveAsメソッドを次のように指定します。 [in] BSTR name,[in] BSTR fpath,[out,retval] long *pVal

同じように次のメソッドも追加します。
FormData [in] BSTR name,[out,retval] BSTR *pVal
FileName [in] BSTR fname,[out,retval] BSTR *pVal
fileupx.cpp (置換します) fileupx.h (置換します) brfc1867.h brfc1867.cpp その他すべてのプロジェクトファイルが含まれてますがコピーするのは、 上の4つのファイルだけにします。 ========================================================================= すぐ試したい人や手順どおりやってもうまくいかない場合は、 解凍した全てのファイルをfileupディレクトリにコピーして fileup.dswをクリックすればプロジェクトが開きますのですぐビルドできます。 但し、このfileup.dswファイルはVisual C++ 6.0対応です。 Visual C++ 5.0ではビルドできません。 ========================================================================= 2. プロジェクトにファイルを追加
[プロジェクト]-[プロジェクトに追加]-[ファイル]で追加します。 brfc1867.h brfc1867.cpp 3. Fileupx.cppファイル
FileUpx.cppは、次のようになります。 // FileUpx.cpp : CFileUp のインプリメンテーション #include "stdafx.h" #include "FileUp.h" #include "FileUpx.h" ///////////////////////////////////////////////////////////////////////////// // CFileUp STDMETHODIMP CFileUp::OnStartPage (IUnknown* pUnk) { if(!pUnk) return E_POINTER; CComPtr<IScriptingContext> spContext; HRESULT hr; // IScriptingContext インターフェイスの取得 hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&spContext); if(FAILED(hr)) return hr; // Request オブジェクトのポインタを取得 hr = spContext->get_Request(&m_piRequest); if(FAILED(hr)) { spContext.Release(); return hr; } // アップロードデータをRequest.BinaryReadで保存 m_rfc1867.Open(m_piRequest); m_bOnStartPageCalled = TRUE; return S_OK; } STDMETHODIMP CFileUp::OnEndPage () { m_rfc1867.Close(); // バッファを開放 m_bOnStartPageCalled = FALSE; // すべてのインターフェイスを解放します m_piRequest.Release(); return S_OK; } STDMETHODIMP CFileUp::SaveAs(BSTR name, BSTR fpath, long *pVal) { USES_CONVERSION; LPCSTR szName = OLE2T(name); LPCSTR szFileName = OLE2T(fpath); int flen; char *tf = m_rfc1867.FileData(szName,&flen); if(tf == NULL || flen < 1) { *pVal = -2; return S_OK; } HANDLE hFile = CreateFile((const char*)szFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) { *pVal = -3; return S_OK; } DWORD dwAmt; if(!WriteFile(hFile, tf, flen, &dwAmt, NULL)) { CloseHandle(hFile); *pVal = -4; return S_OK; } CloseHandle(hFile); *pVal = dwAmt; return S_OK; } STDMETHODIMP CFileUp::FormData(BSTR fname, BSTR *pVal) { USES_CONVERSION; LPCSTR szName = OLE2T(fname); int dlen; char *name = m_rfc1867.FormData(szName,&dlen); if(name == NULL) { *pVal = A2BSTR(""); return S_OK; } int mlen = dlen + 4096; char *tp = new char[mlen]; if (tp == NULL) { delete [] name; return ResultFromScode(E_OUTOFMEMORY); } memcpy(tp,name,dlen); tp[dlen] = 0; int clen = dlen; delete [] name; name = m_rfc1867.FormData(szName,&dlen); while (name) { tp[clen++] = '\t'; if (mlen < (clen + dlen + 1)) { char *tp2 = new char[mlen+dlen + 4096]; if (tp2 == NULL) { delete [] tp; delete [] name; return ResultFromScode(E_OUTOFMEMORY); } memcpy(tp2,tp,clen); delete [] tp; tp = tp2; mlen += dlen + 4096; } memcpy(tp+clen,name,dlen); clen += dlen; tp[clen] = 0; delete [] name; name = m_rfc1867.FormData(szName,&dlen); } *pVal = A2BSTR(tp); delete [] tp; return S_OK; } STDMETHODIMP CFileUp::FileName(BSTR fname, BSTR *pVal) { USES_CONVERSION; LPCSTR szName = OLE2T(fname); char *name = m_rfc1867.FileName(szName); if(name == NULL) { *pVal = A2BSTR(""); return S_OK; } *pVal = A2BSTR(name); delete [] name; return S_OK; }
LIBCMT.lib(crt0.obj) : error LNK2001: 外部シンボル "_main" は未解決です ReleaseMinDependency/FileUp.dll : fatal error LNK1120: 外部参照 1 が未解決です。 link.exe の実行エラー FileUp.dll - エラー 2、警告 0 このエラーは、Cランタイム関数がリンクされていないときに発生します。 Cのランタイム関数をプロジェクト内で使っていると発生します。 ReleaseビルドのデフォルトではATL COM AppWizardは、Cランタイムをリンクしません。 これは、_ATL_MIN_CRTプリプロセッサ文字が指定されているためです。 対策としては: ●[プロジェクトの設定] -[C/C++]-[プリプロセッサの定義]で_ATL_MIN_CRTを削除 こうするとCのランタイムがリンクされてエラーが消えます。 これだけでOKです。 もう一つの方法は: ●Cのランタイム関数を使うのをやめる strlen などの関数を lstrlen などに変更します。 今回は、_ATL_MIN_CRTはそのままにして、Cのランタイム関数を使うのをやめて この問題に対処します。 brfc1867.cpp ファイルのstrnicmp関数がその犯人です。 if (strnicmp(disp,(char*)tp+offset,dlen) != 0) break; // if (CompareString(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE, // disp,dlen,(char*)tp+offset,dlen) != CSTR_EQUAL) // break; これを次のようにstrnicmp関数の代わりにCompareString関数を 使うように修正します。コメントを付け替えるだけです。 // if (strnicmp(disp,(char*)tp+offset,dlen) != 0) // break; if (CompareString(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE, disp,dlen,(char*)tp+offset,dlen) != CSTR_EQUAL) break; ビルドしてエラーが消えればOKです。
[!ProgID] = s '[!TypeName]'
{
CLSID = s '{[!ObjectGUID]}'
[!if=(InsertableEnabled, "TRUE")]
'Insertable'
[!endif]
}
[!VersionIndependentProgID] = s '[!TypeName]'
{
CLSID = s '{[!ObjectGUID]}' <=== この行を追加
CurVer = s '[!ProgID]'
}
これで次回からビルドするときに正しく登録されるようになります。
プロジェクトのFileUp.rgsファイルを手で編集してもかまいません。
CurVerの行の前にCLSIDの行を次のようにコピーしてください。
FileUp.1 = s 'FileUp Class'
{
CLSID = s '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'
}
FileUp = s 'FileUp Class'
{
CLSID = s '{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'
CurVer = s 'FileUp.1'
}