Internet First Steps: WinInet

OverviewHow Do I

You can use WinInet to add FTP support to download and upload files from within your application. You can override and use the dwContext parameter to provide progress information to users as you search for and download files.

This article contains the following topics:

  • Create a Very Simple Browser

  • Download a Web Page

  • FTP a File

  • Retrieve a Gopher Directory

  • Display Progress Information While Transferring Files

The code excerpts below demonstrate how to create a simple browser, download a Web page, FTP a file, and search for a gopher file. They are not meant as complete examples and they do not contain exception handling. See the Internet samples, such as , for more complete examples.

Create a Very Simple Browser

#include <afxinet.h>
//assumes URL names have been initialized
CInternetSession session("My Session");
CStdioFile* pFile = NULL;
//use a URL and display a Web page
while (lpszURL = DisplayPage(...))
{
   pFile = session.OpenURL(lpszURL);
   while (pFile->Read(szBuff,1024) > 0)
   {
      //read file...
   }
   delete pFile;
}
session.Close();

Download a Web Page

//this code excerpt also demonstrates how to use //try/catch exception handling
#include <afxinet.h>
//assumes server, port and URL names have been initialized
CInternetSession session("My Session");
CHttpConnection* pServer = NULL;
CHttpFile* pFile = NULL;
try
{
   CString strServerName;
   INTERNET_PORT nPort;

   pServer = session.GetHttpConnection(strServerName, nPort);
   pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
   pFile->AddRequestHeaders(szHeaders);
   pFile->SendRequest();
   pFile->QueryInfoStatusCode(dwRet);

   if (dwRet == HTTP_STATUS_OK)
   {
       UINT nRead = pFile->Read(szBuff, 1023);
       while (nRead > 0)
       {
           //read file...
       }
   }
   delete pFile;
   delete pServer;
}
catch (CInternetException* pEx)
{
   //catch errors from WinInet
}
session.Close();

FTP a File

#include <afxinet.h>
//assumes server and file names have been initialized
CInternetSession session("My FTP Session");
CFtpConnection* pConn = NULL;

pConn = session.GetFtpConnection(lpszServerName);
//get the file
if (!pConn->GetFile(pstrRemoteFile, pstrLocalFile))
   //display an error
delete pConn;
session.Close();

Retrieve a Gopher Directory

#include <afxinet.h>
//assumes file name has been initialized
CInternetSession session("My Gopher Session");
CGopherConnection* pConn = NULL;
CGopherFileFind* pFile;

pConn = session.GetGopherConnection("gopher.yoursite.com");
pFile = new CGopherFileFind(pConn);
BOOL bFound = pFile->FindFile(lpszFileToFind);
while (bFound)
{
   bFound = pFile->FindNextFile();
   //retrieve attributes of found file
}
delete pFile;
delete pConn;
session.Close();

Use OnStatusCallback

When using the WinInet classes, you can use the member of your application's object to retrieve status information. If you derive your own CInternetSession object, override OnStatusCallback, and enable status callbacks, MFC will call your OnStatusCallback function with progress information about all the activity in that Internet session.

Because a single session might support several connections (which, over their lifetime, might perform many different distinct operations), OnStatusCallback needs a mechanism to identify each status change with a particular connection or transaction. That mechanism is provided by the context ID parameter given to many of the member functions in the WinInet support classes. This parameter is always of type DWORD and is always named dwContext.

The context assigned to a particular Internet object is used only to identify the activity the object causes in the OnStatusCallback member of the CInternetSession object. The call to OnStatusCallback receives several parameters; these parameters work together to tell your application what progress has been made for which transaction and connection.

When you create a CInternetSession object, you can specify a dwContext parameter to the constructor. CInternetSession itself doesn't use the context ID; instead, it passes the context ID on to any InternetConnection-derived objects that don't explicitly get a context ID of their own. In turn, those CInternetConnection objects will pass the context ID along to CInternetFile objects they create if you don't explicitly specify a different context ID. If, on the other hand, you do specify a specific context ID of your own, the object and any work it does will be associated with that context ID. You can use the context IDs to identify what status information is being given to you in your OnStatusCallback function.

Display Progress Information While Transferring Files

For example, if you write an application that creates a connection with an FTP server to read a file and also connects to an HTTP server to get a Web page, you'll have a CInternetSession object, two CInternetConnection objects (one would be a CFtpSession and the other would be a CHttpSession), and two CInternetFile objects (one for each connection). If you used default values for the dwContext parameters, you would not be able to distinguish between the OnStatusCallback invocations that indicate progress for the FTP connection and the invocations that indicate progress for the HTTP connection. If you specify a dwContext ID, which you can later test for in OnStatusCallback, you will know which operation generated the callback.

See Also   Internet: Where Is..., Internet Programming with WinInet, WinInet (HTTP, FTP, gopher)