Building a Web Client with the MFC WinInet Classes

There are two ways to build a Web client with WinInet. The first method, using the CHttpConnection class, is similar to the simplified WinInet client on the preceding page. The second method, using CInternetSession::OpenURL, is even easier. We'll start with the CHttpConnection version.

The EX34A WinInet Client #1—Using CHttpConnection

The EX34A program implements a WinInet client in the file \vcpp32\ex34a\ClientInetThread.cpp on the CD-ROM. Besides allowing the use of an IP address as well as a host name, the program uses a status callback function. That function, CCallbackInternetSession::OnStatusCallback in the file \vcpp32\ex34a\utility.cpp, puts a text string in a global variable g_pchStatus, using a critical section for synchronization. The function then posts a user-defined message to the application's main window. The message triggers an Update Command UI handler (called by CWinApp::OnIdle), which displays the text in the second status bar text pane.

Testing the WinInet Client #1

To test the WinInet client #1, you can follow the same procedure you used to test the Winsock client. Note the status bar messages as the connection is made. Note that the file appears more quickly the second time you request it.

The EX34A WinInet Client #2—Using OpenURL

The EX34A program implements a different WinInet client in the file ClientUrlThread.cpp on the companion CD-ROM. This client uses the "Address" URL (that you type to access the Internet site). Here's the actual code:

CString g_strURL = "http:// ";

UINT ClientUrlThreadProc(LPVOID pParam)
{
    char* buffer = new char[MAXBUF];
    UINT nBytesRead = 0;

    CInternetSession session; // can't get status callbacks for OpenURL
    CStdioFile* pFile1 = NULL; // could call ReadString to get 1 line
    try {
        pFile1 = session.OpenURL(g_strURL, 0, INTERNET_FLAG_TRANSFER_BINARY
            |INTERNET_FLAG_KEEP_CONNECTION);
         // If OpenURL fails, we won't get past here
        nBytesRead = pFile1->Read(buffer, MAXBUF - 1);
        buffer[nBytesRead] = `\0'; // necessary for message box
        char temp[100];
        if(pFile1->Read(temp, 100) != 0) { 
            // makes caching work if read complete
            AfxMessageBox("File overran buffer — not cached");
        }
        ::MessageBox(::GetTopWindow(::GetDesktopWindow()), buffer, 
            "URL CLIENT", MB_OK);
    }
    catch(CInternetException* e) {
        LogInternetException(pParam, e);
        e->Delete();
    }
    if(pFile1) delete pFile1;
    delete [] buffer;
    return 0;
}

Note that OpenURL returns a pointer to a CStdioFile object. You can use that pointer to call Read as shown, or you can call ReadString to get a single line. The file class does all the buffering. As in the previous WinInet client, it's necessary to call Read a second time to cache the file. The OpenURL INTERNET_FLAG_KEEP_CONNECTION parameter is necessary for Windows NT challenge/response authentication, which is described in Chapter 35. If you added the flag INTERNET_FLAG_RELOAD, the program would bypass the cache just as the browser does when you click the Refresh button.

Testing the WinInet Client #2

You can test the WinInet client #2 against any HTTP server. You run this client by typing in the URL address, not by using the menu. You must include the protocol (http:// or ftp://) in the URL address. Type http://localhost. You should see the same HTML code in a message box. No status messages appear here because the status callback doesn't work with OpenURL.