Click to return to the Networking, Protocols     
Microsoft Win32 Internet ...     Implementing Win32 Intern...     Microsoft Win32 Internet ...    
Web Workshop  |  Networking, Protocols & Data Formats

Creating Status Callback Functions


This tutorial describes how to create a status callback function that can be used to monitor the status of an Internet request that was initiated using the Microsoft® Win32® Internet functions.

Status callback functions receive status callbacks on any Internet requests that originated from any Win32 Internet function that was passed a nonzero context value.

Requirements and Dependencies

Application developers who want to create a status callback function must have an understanding of C/C++ programming, a familiarity with Win32 programming, and a familiarity with the Win32 Internet functions.

To compile programs using any of the Win32 Internet functions, make sure the Wininet.h header file is in the include directory and the Wininet.lib library file is in the library directory of the C/C++ compiler you are using.

Implementation Steps

The following steps are necessary for creating a status callback function:

  1. Define the context value.
  2. Create the status callback function.

Defining the Context Value

The context value can be any unsigned long integer value. Ideally, the context value should identify what request has just been completed and the location of any associated resources (if needed).

One of the most useful ways to use the context value is to pass the address of a structure and cast it as a DWORD. The structure can be used to store information about the request, so that it will be passed to the status callback function.

The following structure is an example of a possible context value. The members of the structure have been chosen with the InternetOpenUrl function in mind.

typedef struct{
    HWND        hWindow;     // window handle
    int         nStatusList  // ID of the list box control to hold the callbacks
    HINTERNET   hResource;   // HINTERNET handle created by InternetOpenUrl
    char        szMemo[512]; // string to store status memo
} REQUEST_CONTEXT;

In this example, the status callback function would have access to the window handle, which would allow it to display a user interface; the HINTERNET handle created by InternetOpenUrl, which could be passed to another function that can download the resource; and an array of characters that can be used to pass information about the request.

The members of the structure can be changed to fit the needs of a particular application, so do not feel constrained by this example.

Creating the Status Callback Function

The status callback function must follow the format of INTERNET_STATUS_CALLBACK. To do this:

  1. Write a function declaration for your status callback function.

    The following example shows a sample declaration.

    void __stdcall CallMaster(HINTERNET, DWORD, DWORD, LPVOID, DWORD);
    
  2. Determine what your status callback function will do. For applications that are using the Win32 Internet functions asynchronously, the status callback function must handle the INTERNET_STATUS_REQUEST_COMPLETE value, which indicates an asynchronous request is complete. The status callback function can also be used to track the progress of an Internet request.

    In general, using a switch function using dwInternetStatus as the switch value and the status values for the case statements works the best. Depending on the types of functions your application is calling, you can ignore some of the status values. For a definition of the different status values, see the listing under the dwInternetStatus parameter of INTERNET_STATUS_CALLBACK.

    The following switch statement is an example of how to handle status callbacks.

    switch (dwInternetStatus)
    {
        case INTERNET_STATUS_REQUEST_COMPLETE:
            // Some code.
            break;
        default:
            // Some code.
            break;
    }
    
  3. Create the code to handle the status values.

    The code to handle each of the status values depends heavily on what you are using the status callback function for. For applications that are just tracking the progress of a request, writing a string to a list box might be all you need. For asynchronous operations, the code must handle some of the data returned in the callback. For details on asynchronous operations, see the Calling Win32 Functions Asynchronously article.

    The following status callback function uses a switch function to determine what the status value is and creates a string that includes the name of the status value and the previous function called (which is stored in the szMemo member of the REQUEST_CONTEXT structure).

    void __stdcall CallMaster(
        HINTERNET hInternet,
        DWORD dwContext,
        DWORD dwInternetStatus,
        LPVOID lpvStatusInformation,
        DWORD dwStatusInformationLength
    )
    {
    
        // Copy that context value to a pointer so I don't have to keep
        // casting the context value as a REQUEST_CONTEXT pointer.
        REQUEST_CONTEXT *cpContext;
        cpContext = (REQUEST_CONTEXT*)dwContext;
        char szStatusText[80];
    
        switch (dwInternetStatus)
    {
            case INTERNET_STATUS_CLOSING_CONNECTION:
                sprintf(szStatusText,"%s CLOSING_CONNECTION", cpContext->szMemo);
                break;
            case INTERNET_STATUS_CONNECTED_TO_SERVER:
                sprintf(szStatusText,"%s CONNECTED_TO_SERVER", cpContext->szMemo);
                break;
            case INTERNET_STATUS_CONNECTING_TO_SERVER:
                sprintf(szStatusText,"%s CONNECTING_TO_SERVER", cpContext->szMemo);
                break;
            case INTERNET_STATUS_CONNECTION_CLOSED:
                sprintf(szStatusText,"%s CONNECTION_CLOSED", cpContext->szMemo);
                break;
            case INTERNET_STATUS_HANDLE_CLOSING:
                sprintf(szStatusText,"%s HANDLE_CLOSING", cpContext->szMemo);
                break;
            case INTERNET_STATUS_HANDLE_CREATED:
                sprintf(szStatusText,"%s HANDLE_CREATED", cpContext->szMemo);
                break;
    case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
                sprintf(szStatusText,"%s INTERMEDIATE_RESPONSE", cpContext->szMemo);
                break;
    case INTERNET_STATUS_NAME_RESOLVED:
                sprintf(szStatusText,"%s NAME_RESOLVED", cpContext->szMemo);
                break;
            case INTERNET_STATUS_RECEIVING_RESPONSE:
                sprintf(szStatusText,"%s RECEIVING_RESPONSE", cpContext->szMemo);
                break;
            case INTERNET_STATUS_RESPONSE_RECEIVED:
                sprintf(szStatusText,"%s RESPONSE_RECEIVED", cpContext->szMemo);
                break;
            case INTERNET_STATUS_REDIRECT:
                sprintf(szStatusText,"%s REDIRECT", cpContext->szMemo);
                break;
            case INTERNET_STATUS_REQUEST_COMPLETE:
                sprintf(szStatusText,"%s REQUEST_COMPLETE", cpContext->szMemo);
                break;
            case INTERNET_STATUS_REQUEST_SENT:
                sprintf(szStatusText,"%s REQUEST_SENT", cpContext->szMemo);
                break;
            case INTERNET_STATUS_RESOLVING_NAME:
                sprintf(szStatusText,"%s RESOLVING_NAME", cpContext->szMemo);
                break;
    case INTERNET_STATUS_SENDING_REQUEST:
                sprintf(szStatusText,"%s SENDING_REQUEST", cpContext->szMemo);
                break;
            case INTERNET_STATUS_STATE_CHANGE:
                sprintf(szStatusText,"%s STATE_CHANGE", cpContext->szMemo);
                break;
            default:
                sprintf(szStatusText,"%s Unknown Status %d Given",
                        cpContext->szMemo, dwInternetStatus);
                break;
    }
    
    SendDlgItemMessage(cpContext->hWindow,cpContext->nStatusList,
                           LB_ADDSTRING,0,(LPARAM)szStatusText);
    
    }
    
  4. Use the InternetSetStatusCallback function to set the status callback function on the HINTERNET handle for which you want to receive status callbacks.

    The following example demonstrates how to set a status callback function.

    HINTERNET hOpen;                       // root HINTERNET handle
    INTERNET_STATUS_CALLBACK iscCallback;  // holder for the callback function
    
    // Create the root HINTERNET handle.
    hOpen = InternetOpen("Test Application", INTERNET_OPEN_TYPE_PRECONFIG,
                        NULL, NULL, 0);
    
    // Set the status callback function.
    iscCallback = InternetSetStatusCallback(hOpen,
                                           (INTERNET_STATUS_CALLBACK)CallMaster);
    

Related Information

The following tutorial covers one use of a status callback function:

The following references are related to status callback functions:



Back to topBack to top

Did you find this topic useful? Suggestions for other topics? Write us!

© 1999 Microsoft Corporation. All rights reserved. Terms of use.