WinInet の基礎
WinInet を使用すると、FTP サポートを追加して、ご自身のアプリケーション内からファイルをダウンロードできます。 OnStatusCallback をオーバーライドし、dwContext パラメーターを使用して、ファイルを検索してダウンロードするときに、進行状況に関する情報をユーザーに提供することができます。
この記事では、次のトピックを取り上げます。
次のコード (抜粋) は、シンプルなブラウザーを作成する方法、Web ページをダウンロードする方法、ファイルを FTP 転送する方法、gopher ファイルを検索する方法を示しています。 これらは完全な例として示すものではなく、一部には例外処理が含まれていません。
WinInet の詳細については、「Win32 インターネット拡張機能 (WinInet)」を参照してください。
非常にシンプルなブラウザーを作成する
#include <afxinet.h>
void DisplayPage(LPCTSTR pszURL)
{
CInternetSession session(_T("My Session"));
CStdioFile *pFile = NULL;
CHAR szBuff[1024];
//use a URL and print a Web page to the console
pFile = session.OpenURL(pszURL);
while (pFile->Read(szBuff, 1024) > 0)
{
printf_s("%1023s", szBuff);
}
delete pFile;
session.Close();
}
Web ページをダウンロードする
//this code excerpt also demonstrates try/catch exception handling
#include <afxinet.h>
void DisplayHttpPage(LPCTSTR pszServerName, LPCTSTR pszFileName)
{
CInternetSession session(_T("My Session"));
CHttpConnection *pServer = NULL;
CHttpFile *pFile = NULL;
try
{
CString strServerName;
INTERNET_PORT nPort = 80;
DWORD dwRet = 0;
pServer = session.GetHttpConnection(pszServerName, nPort);
pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, pszFileName);
pFile->SendRequest();
pFile->QueryInfoStatusCode(dwRet);
if (dwRet == HTTP_STATUS_OK)
{
CHAR szBuff[1024];
while (pFile->Read(szBuff, 1024) > 0)
{
printf_s("%1023s", szBuff);
}
}
delete pFile;
delete pServer;
}
catch (CInternetException *pEx)
{
//catch errors from WinInet
TCHAR pszError[64];
pEx->GetErrorMessage(pszError, 64);
_tprintf_s(_T("%63s"), pszError);
}
session.Close();
}
ファイルを FTP 転送する
#include <afxinet.h>
void GetFtpFile(LPCTSTR pszServerName, LPCTSTR pszRemoteFile, LPCTSTR pszLocalFile)
{
CInternetSession session(_T("My FTP Session"));
CFtpConnection *pConn = NULL;
pConn = session.GetFtpConnection(pszServerName);
//get the file
if (!pConn->GetFile(pszRemoteFile, pszLocalFile))
{
//display an error
}
delete pConn;
session.Close();
}
Gopher ディレクトリを取得する
#include <afxinet.h>
void RetrieveGopherFile(LPCTSTR pszGopherSite, LPCTSTR pszFile)
{
CInternetSession session(_T("My Gopher Session"));
CGopherConnection *pConn = NULL;
CGopherFileFind *pFile;
pConn = session.GetGopherConnection(pszGopherSite);
pFile = new CGopherFileFind(pConn);
BOOL bFound = pFile->FindFile(pszFile);
while (bFound)
{
//retrieve attributes of found file
bFound = pFile->FindNextFile();
}
delete pFile;
delete pConn;
session.Close();
}
OnStatusCallback を使用する
WinInet クラスを使用するとき、アプリケーションの CInternetSession オブジェクトの OnStatusCallback メンバーを使用して、状態情報を取得できます。 独自の CInternetSession
オブジェクトを派生させて、OnStatusCallback
をオーバーライドし、状態のコールバックスを有効にすると、MFC によって、OnStatusCallback
関数と、そのインターネット セッション内のすべてのアクティビティに関する進行状況が呼び出されます。
1 つのセッションによって複数の接続がサポートされる可能性があるため (その有効期間中、さまざまな操作が多数実行される可能性があり)、OnStatusCallback
には、各状態変更を、特定の接続やトランザクションでを使用して特定するためのメカニズムが必要です。 そのメカニズムは、WinInet サポート クラス内の多くのメンバー関数に付与されているコンテキスト ID パラメーターによって提供されます。 このパラメーターは常に DWORD 型で、必ず dwContext という名前になります。
特定のインターネット オブジェクトに割り当てられたコンテキストは、CInternetSession
オブジェクトの OnStatusCallback
メンバー内でオブジェクトによって引き起こされたアクティビティを特定するためにのみ使用されます。 OnStatusCallback
の呼び出しは複数のパラメーターを取ります。これらのパラメーターが連携することで、トランザクションと接続の進行状況がアプリケーションに通知されます。
CInternetSession
オブジェクトを作成するとき、コンストラクターに dwContext パラメーターを指定できます。 CInternetSession
自体はコンテキスト ID を使用せず、代わりにコンテキスト ID を、自分ではコンテキスト ID を明示的に取得しない任意の InternetConnection 派生オブジェクトに渡します。 そして、そのコンテキスト ID は、ユーザーが別のコンテキスト ID を明示的に指定しなければ、これらの CInternetConnection
オブジェクトによって作成済み CInternetFile
オブジェクトに渡されます。 一方、ユーザーが特定のコンテキスト ID を指定した場合、オブジェクトとその作業は、指定したコンテキスト ID に関連付けられます。 コンテキスト ID を使用すると、OnStatusCallback
関数内で提供されている状態情報を特定できます。
ファイルの転送中に進行状況を表示する
たとえば、ファイルを読み取るために FTP サーバーとの接続を確立し、Web ページを取得するために HTTP サーバーに接続するアプリケーションを書く場合、1 つの CInternetSession
オブジェクト、2 つの CInternetConnection
オブジェクト (1 つはCFtpSession
、もう 1 つは CHttpSession
)、2 つの CInternetFile
オブジェクト (各接続に 1 つずつ) を持つことになります。 dwContext パラメーターに既定値を使用した場合、FTP 接続の進行状況を示す OnStatusCallback
呼び出しと、HTTP 接続の進行状況を示す呼び出しを区別できません。 OnStatusCallback
で後でテストできる dwContext ID を指定すると、どの操作でコールバックが発生したのかがわかります。