Partilhar via


Criando funções de retorno de chamada de status

Este tutorial descreve como criar uma função de retorno de chamada de status usada para monitorar o status de uma solicitação da Internet.

As funções de retorno de chamada de status obtêm retornos de chamada de status em quaisquer pedidos de Internet originados em qualquer função WinINet à qual foi passado um valor de contexto não zero.

As seguintes etapas são necessárias para criar uma função de retorno de chamada de status:

  1. Defina o valor de contexto.
  2. Crie a função de callback de status.

Definindo o valor de contexto

O valor de contexto pode ser qualquer valor inteiro longo não assinado. Idealmente, o valor de contexto deve identificar qual solicitação acabou de ser concluída e a localização de quaisquer recursos associados, se necessário.

Uma das maneiras mais úteis de usar o valor de contexto é passar o endereço de uma estrutura e convertê-lo para um DWORD_PTR. A estrutura pode ser usada para armazenar informações sobre o pedido, para que sejam passadas para a função callback de status.

A estrutura a seguir é um exemplo de um possível valor de contexto. Os membros da estrutura são escolhidos com a função InternetOpenUrl em mente.

typedef struct{
    HWND       hWindow;      // Window handle
    int        nStatusList;  // List box control to hold callbacks
    HINTERNET  hResource;    // HINTERNET handle created by InternetOpenUrl
    char       szMemo[512];  // String to store status memo
} REQUEST_CONTEXT;

Neste exemplo, a função de retorno de chamada de status teria acesso ao identificador de janela, o que permitiria exibir uma interface de usuário. O identificador HINTERNET criado por InternetOpenUrl pode ser passado para outra função que pode baixar o recurso e uma matriz de caracteres que podem ser usados para passar informações sobre a solicitação.

Os membros da estrutura podem ser alterados para se adequarem às necessidades de uma determinada aplicação, por isso não se sinta constrangido por este exemplo.

Criando a função de callback de status

A função de chamada de retorno de status deve seguir o formato de InternetStatusCallback. Para fazer isso:

  1. Escreva uma declaração de função para sua função de retorno de chamada de status.

    O exemplo a seguir mostra uma declaração de exemplo.

    void CALLBACK CallMaster( HINTERNET,
                              DWORD_PTR,
                              DWORD,
                              LPVOID,
                              DWORD );
    
  2. Determine o que sua função de retorno de chamada de status fará. Para aplicativos que estão fazendo chamadas assíncronas, a função de retorno de chamada de status deve manipular o valor INTERNET_STATUS_REQUEST_COMPLETE, que indica que uma solicitação assíncrona está concluída. A função de retorno de chamada de status também pode ser usada para acompanhar o progresso de uma solicitação da Internet.

    Em geral, funciona melhor usar uma instrução switch com dwInternetStatus como o valor do switch e os valores de status para as instruções de caso. Dependendo dos tipos de funções que seu aplicativo está chamando, você pode ignorar alguns dos valores de status. Para obter uma definição dos diferentes valores de status, consulte a listagem sob o parâmetro dwInternetStatus de InternetStatusCallback.

    A instrução switch a seguir é um exemplo de como lidar com retornos de chamada de status.

    switch (dwInternetStatus)
    {
        case INTERNET_STATUS_REQUEST_COMPLETE:
            // Add code
            break;
        default:
            // Add code
            break;
    }
    
  3. Crie o código para manipular os valores de status.

    O código para lidar com cada um dos valores de status depende muito do uso pretendido da função de retorno de chamada de status. Para aplicativos que estão apenas acompanhando o progresso de uma solicitação, escrever uma cadeia de caracteres em uma caixa de listagem pode ser tudo o que você precisa. Para operações assíncronas, o código deve manipular parte dos dados retornados no callback.

    A função de retorno de chamada de status a seguir usa uma função switch para determinar qual é o valor de status e cria uma cadeia de caracteres que inclui o nome do valor de status e a função anterior chamada, que é armazenada no membro szMemo da estrutura REQUEST_CONTEXT.

    void __stdcall CallMaster(
        HINTERNET hInternet,
        DWORD_PTR dwContext,
        DWORD dwInternetStatus,
        LPVOID lpvStatusInformation,
        DWORD dwStatusInformationLength
    )
    {
        UNREFERENCED_PARAMETER(hInternet);
        UNREFERENCED_PARAMETER(lpvStatusInformation);
        UNREFERENCED_PARAMETER(dwStatusInformationLength);
    
        REQUEST_CONTEXT *cpContext;
        cpContext = (REQUEST_CONTEXT*)dwContext;
        char szStatusText[80];
    
        switch (dwInternetStatus)
        {
            case INTERNET_STATUS_CLOSING_CONNECTION:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s CLOSING_CONNECTION",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_CONNECTED_TO_SERVER:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s CONNECTED_TO_SERVER",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_CONNECTING_TO_SERVER:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s CONNECTING_TO_SERVER",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_CONNECTION_CLOSED:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s CONNECTION_CLOSED",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_HANDLE_CLOSING:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s HANDLE_CLOSING",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_HANDLE_CREATED:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s HANDLE_CREATED",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s INTERMEDIATE_RESPONSE",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_NAME_RESOLVED:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s NAME_RESOLVED",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_RECEIVING_RESPONSE:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s RECEIVING_RESPONSE",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_RESPONSE_RECEIVED:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s RESPONSE_RECEIVED",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_REDIRECT:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s REDIRECT",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_REQUEST_COMPLETE:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s REQUEST_COMPLETE",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_REQUEST_SENT:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s REQUEST_SENT",
                                  cpContext->szMemo);
                break;
            case INTERNET_STATUS_RESOLVING_NAME:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s RESOLVING_NAME",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_SENDING_REQUEST:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s SENDING_REQUEST",
                                  cpContext->szMemo );
                break;
            case INTERNET_STATUS_STATE_CHANGE:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s STATE_CHANGE",
                                  cpContext->szMemo );
                break;
            default:
                StringCchPrintfA( szStatusText,
                                  80,
                                  "%s Unknown Status %d Given",
                                  cpContext->szMemo,
                                  dwInternetStatus);
                break;
        }
    
        SendDlgItemMessage( cpContext->hWindow,
                          cpContext->nStatusList,
                          LB_ADDSTRING,
                          0, (LPARAM)szStatusText );
    
    }
    
  4. Use a função InternetSetStatusCallback para definir a função de retorno de chamada de status no identificador HINTERNET para o qual se deseja receber notificações de status.

    O exemplo a seguir demonstra como definir uma função de retorno de chamada de status.

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

Observação

WinINet não suporta implementações de servidor. Além disso, não deve ser usado em um serviço. Para implementações ou serviços de servidor, use Microsoft Windows HTTP Services (WinHTTP).

 

Criando Funções de Callback de Status

InternetSetStatusCallback

InternetStatusCallback