Erstellen von Statusrückruffunktionen

In diesem Tutorial wird beschrieben, wie Sie eine status Rückruffunktion erstellen, die zum Überwachen der status einer Internetanforderung verwendet wird.

Statusrückruffunktionen empfangen status Rückrufe für Alle Internetanforderungen, die von einer WinINet-Funktion stammen, die einen nichtzero-Kontextwert übergeben hat.

Die folgenden Schritte sind erforderlich, um eine status Rückruffunktion zu erstellen:

  1. Definieren Sie den Kontextwert.
  2. Erstellen Sie die status Rückruffunktion.

Definieren des Kontextwerts

Der Kontextwert kann ein beliebiger ganzzahliger Wert ohne Vorzeichen sein. Im Idealfall sollte der Kontextwert angeben, welche Anforderung gerade abgeschlossen wurde, und den Speicherort aller zugeordneten Ressourcen, falls erforderlich.

Eine der nützlichsten Möglichkeiten, den Kontextwert zu verwenden, besteht darin, die Adresse einer Struktur zu übergeben und an eine DWORD_PTR zu übergeben. Die Struktur kann verwendet werden, um Informationen zur Anforderung zu speichern, sodass sie an die status Rückruffunktion übergeben werden.

Die folgende Struktur ist ein Beispiel für einen möglichen Kontextwert. Die Elemente der Struktur werden unter Berücksichtigung der InternetOpenUrl-Funktion ausgewählt.

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;

In diesem Beispiel hätte die status Rückruffunktion Zugriff auf das Fensterhandle, wodurch eine Benutzeroberfläche angezeigt werden kann. Das von InternetOpenUrl erstellte HINTERNET-Handle kann an eine andere Funktion übergeben werden, die die Ressource herunterladen kann, und an ein Array von Zeichen, die verwendet werden können, um Informationen zur Anforderung zu übergeben.

Die Elemente der Struktur können so geändert werden, dass sie den Anforderungen einer bestimmten Anwendung entsprechen, sodass Sie sich durch dieses Beispiel nicht eingeschränkt fühlen.

Erstellen der Statusrückruffunktion

Die status Rückruffunktion muss das Format InternetStatusCallback aufweisen. Gehen Sie dazu folgendermaßen vor:

  1. Schreiben Sie eine Funktionsdeklaration für Ihre status Rückruffunktion.

    Das folgende Beispiel zeigt eine Beispieldeklaration.

    void CALLBACK CallMaster( HINTERNET,
                              DWORD_PTR,
                              DWORD,
                              LPVOID,
                              DWORD );
    
  2. Bestimmen Sie, was Ihre status Rückruffunktion bewirkt. Für Anwendungen, die asynchrone Aufrufe ausführen, muss die status Rückruffunktion den INTERNET_STATUS_REQUEST_COMPLETE-Wert verarbeiten, was angibt, dass eine asynchrone Anforderung abgeschlossen ist. Die status Rückruffunktion kann auch verwendet werden, um den Fortschritt einer Internetanforderung nachzuverfolgen.

    Im Allgemeinen funktioniert es am besten, eine Switch-Anweisung mit dwInternetStatus als Switchwert und die status-Werte für die Fallanweisungen zu verwenden. Abhängig von den Funktionstypen, die ihre Anwendung aufruft, können Sie einige der status Werte ignorieren. Eine Definition der verschiedenen status Werte finden Sie in der Auflistung unter dem dwInternetStatus-Parameter von InternetStatusCallback.

    Die folgende Switch-Anweisung ist ein Beispiel für die Behandlung status Rückrufe.

    switch (dwInternetStatus)
    {
        case INTERNET_STATUS_REQUEST_COMPLETE:
            // Add code
            break;
        default:
            // Add code
            break;
    }
    
  3. Erstellen Sie den Code, um die status-Werte zu behandeln.

    Der Code zum Behandeln der einzelnen status-Werte hängt stark von Der beabsichtigten Verwendung der status Rückruffunktion ab. Für Anwendungen, die nur den Fortschritt einer Anforderung nachverfolgen, ist das Schreiben einer Zeichenfolge in ein Listenfeld möglicherweise alles, was Sie benötigen. Bei asynchronen Vorgängen muss der Code einige der im Rückruf zurückgegebenen Daten verarbeiten.

    Die folgende status Rückruffunktion verwendet eine Switchfunktion, um zu bestimmen, was der status Wert ist, und erstellt eine Zeichenfolge, die den Namen des status-Werts und die vorherige Funktion namens enthält, die im szMemo-Member der REQUEST_CONTEXT-Struktur gespeichert ist.

    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. Verwenden Sie die InternetSetStatusCallback-Funktion, um die status Rückruffunktion für das HINTERNET-Handle festzulegen, für das Sie status Rückrufe empfangen möchten.

    Im folgenden Beispiel wird veranschaulicht, wie eine status Rückruffunktion festgelegt wird.

    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 );
    

Hinweis

WinINet unterstützt keine Serverimplementierungen. Darüber hinaus sollte es nicht von einem Dienst aus verwendet werden. Verwenden Sie für Serverimplementierungen oder Dienste Microsoft Windows HTTP Services (WinHTTP).

 

Erstellen von Statusrückruffunktionen

InternetSetStatusCallback

InternetStatusCallback