Criando funções de retorno de chamada de status
Este tutorial descreve como criar uma função de retorno de chamada status usada para monitorar o status de uma solicitação da Internet.
As funções de retorno de chamada de status recebem status retornos de chamada em todas as solicitações da Internet originadas de qualquer função WinINet que tenha sido passada um valor de contexto diferente de zero.
As etapas a seguir são necessárias para criar uma função de retorno de chamada status:
Definindo o valor de contexto
O valor de contexto pode ser qualquer valor inteiro longo sem sinal. O ideal é que o valor de contexto identifique qual solicitação acabou de ser concluída e o local de todos os 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 em um DWORD_PTR. A estrutura pode ser usada para armazenar informações sobre a solicitação, de modo que ela seja passada para a função de retorno de chamada 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 status teria acesso ao identificador de janela, o que permitiria exibir uma interface do 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 atender às necessidades de um aplicativo específico, portanto, não se sintam restritos por este exemplo.
Criando a função de retorno de chamada de status
A função de retorno de chamada status deve seguir o formato de InternetStatusCallback. Para fazer isso:
Escreva uma declaração de função para sua função de retorno de chamada status.
O exemplo a seguir mostra uma declaração de exemplo.
void CALLBACK CallMaster( HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD );
Determine o que a função de retorno de chamada status fará. Para aplicativos que estão fazendo chamadas assíncronas, a função de retorno de chamada status deve lidar com o valor INTERNET_STATUS_REQUEST_COMPLETE, o que indica que uma solicitação assíncrona está concluída. A função de retorno de chamada status também pode ser usada para acompanhar o progresso de uma solicitação da Internet.
Em geral, funciona melhor para usar uma instrução switch com dwInternetStatus como o valor da opção e os valores status para as instruções case. Dependendo dos tipos de funções que seu aplicativo está chamando, você pode ignorar alguns dos valores 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 status retornos de chamada.
switch (dwInternetStatus) { case INTERNET_STATUS_REQUEST_COMPLETE: // Add code break; default: // Add code break; }
Crie o código para lidar com 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 status. Para aplicativos que estão apenas acompanhando o progresso de uma solicitação, gravar 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 alguns dos dados retornados no retorno de chamada.
A função de retorno de chamada status a seguir usa uma função switch para determinar qual é o valor status e cria uma cadeia de caracteres que inclui o nome do valor 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 ); }
Use a função InternetSetStatusCallback para definir a função de retorno de chamada status no identificador HINTERNET para o qual você deseja receber status retornos de chamada.
O exemplo a seguir demonstra como definir uma função de retorno de chamada 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
O WinINet não dá suporte a implementações de servidor. Além disso, ele não deve ser usado de um serviço. Para implementações ou serviços de servidor, use Os Serviços HTTP do Microsoft Windows (WinHTTP).
Tópicos relacionados