Création de fonctions de rappel d’état
Ce tutoriel explique comment créer une fonction de rappel status utilisée pour surveiller la status d’une requête Internet.
Les fonctions de rappel d’état reçoivent status rappels sur toutes les requêtes Internet provenant de toute fonction WinINet qui a reçu une valeur de contexte différente de zéro.
Les étapes suivantes sont nécessaires pour créer une fonction de rappel status :
Définition de la valeur de contexte
La valeur de contexte peut être n’importe quelle valeur entière longue non signée. Dans l’idéal, la valeur de contexte doit identifier la demande qui vient d’être effectuée et l’emplacement des ressources associées, si nécessaire.
L’une des méthodes les plus utiles pour utiliser la valeur de contexte consiste à passer l’adresse d’une structure et à la caster vers un DWORD_PTR. La structure peut être utilisée pour stocker des informations sur la demande, afin qu’elles soient transmises à la fonction de rappel status.
La structure suivante est un exemple de valeur de contexte possible. Les membres de la structure sont choisis en tenant compte de la fonction InternetOpenUrl .
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;
Dans cet exemple, la fonction de rappel status aurait accès au handle de fenêtre, ce qui lui permettrait d’afficher une interface utilisateur. Le handle HINTERNET créé par InternetOpenUrl peut être passé à une autre fonction qui peut télécharger la ressource et un tableau de caractères qui peuvent être utilisés pour transmettre des informations sur la demande.
Les membres de la structure peuvent être modifiés pour répondre aux besoins d’une application particulière. Par conséquent, ne vous sentez pas contraint par cet exemple.
Création de la fonction de rappel d’état
La fonction de rappel status doit suivre le format InternetStatusCallback. Pour ce faire :
Écrivez une déclaration de fonction pour votre fonction de rappel status.
L’exemple suivant montre un exemple de déclaration.
void CALLBACK CallMaster( HINTERNET, DWORD_PTR, DWORD, LPVOID, DWORD );
Déterminez ce que fera votre fonction de rappel status. Pour les applications qui effectuent des appels asynchrones, la fonction de rappel status doit gérer la valeur INTERNET_STATUS_REQUEST_COMPLETE, ce qui indique qu’une demande asynchrone est terminée. La fonction de rappel status peut également être utilisée pour suivre la progression d’une requête Internet.
En général, il est préférable d’utiliser une instruction switch avec dwInternetStatus comme valeur de commutateur et les valeurs status pour les instructions case. Selon les types de fonctions que votre application appelle, vous pouvez ignorer certaines des valeurs status. Pour obtenir une définition des différentes valeurs status, consultez la liste sous le paramètre dwInternetStatus d’InternetStatusCallback.
L’instruction switch suivante est un exemple de gestion des rappels status.
switch (dwInternetStatus) { case INTERNET_STATUS_REQUEST_COMPLETE: // Add code break; default: // Add code break; }
Créez le code pour gérer les valeurs status.
Le code pour gérer chacune des valeurs status dépend fortement de l’utilisation prévue de la fonction de rappel status. Pour les applications qui suivent simplement la progression d’une requête, l’écriture d’une chaîne dans une zone de liste peut être tout ce dont vous avez besoin. Pour les opérations asynchrones, le code doit gérer certaines des données retournées dans le rappel.
La fonction de rappel status suivante utilise une fonction switch pour déterminer quelle est la valeur status et crée une chaîne qui inclut le nom de la valeur status et la fonction précédente appelée, qui est stockée dans le membre szMemo de la structure 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 ); }
Utilisez la fonction InternetSetStatusCallback pour définir la fonction de rappel status sur le handle HINTERNET pour lequel vous souhaitez recevoir status rappels.
L’exemple suivant montre comment définir une fonction de rappel 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 );
Notes
WinINet ne prend pas en charge les implémentations de serveur. En outre, il ne doit pas être utilisé à partir d’un service. Pour les implémentations de serveur ou les services, utilisez Microsoft Windows HTTP Services (WinHTTP).
Rubriques connexes