Bagikan melalui


Membuat Fungsi Panggilan Balik Status

Tutorial ini menjelaskan cara membuat fungsi panggilan balik status yang digunakan untuk memantau status permintaan Internet.

Fungsi panggilan balik status menerima panggilan balik status pada permintaan Internet apa pun yang berasal dari fungsi WinINet apa pun yang melewati nilai konteks bukan nol.

Langkah-langkah berikut diperlukan untuk membuat fungsi panggilan balik status:

  1. Tentukan nilai konteks.
  2. Buat fungsi panggilan balik status.

Menentukan Nilai Konteks

Nilai konteks dapat berupa nilai bilangan bulat panjang yang tidak ditandatangani. Idealnya, nilai konteks harus mengidentifikasi permintaan apa yang baru saja selesai dan lokasi sumber daya terkait, jika diperlukan.

Salah satu cara paling berguna untuk menggunakan nilai konteks adalah dengan meneruskan alamat struktur dan mentransmisikannya ke DWORD_PTR. Struktur dapat digunakan untuk menyimpan informasi tentang permintaan, sehingga diteruskan ke fungsi panggilan balik status.

Struktur berikut adalah contoh kemungkinan nilai konteks. Anggota struktur dipilih dengan ingat fungsi 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;

Dalam contoh ini, fungsi panggilan balik status akan memiliki akses ke handel jendela, yang akan memungkinkannya menampilkan antarmuka pengguna. Handel HINTERNET yang dibuat oleh InternetOpenUrl dapat diteruskan ke fungsi lain yang dapat mengunduh sumber daya dan array karakter yang dapat digunakan untuk meneruskan informasi tentang permintaan.

Anggota struktur dapat diubah agar sesuai dengan kebutuhan aplikasi tertentu, jadi jangan merasa dibatasi oleh contoh ini.

Membuat Fungsi Panggilan Balik Status

Fungsi panggilan balik status harus mengikuti format InternetStatusCallback. Untuk melakukan ini:

  1. Tulis deklarasi fungsi untuk fungsi panggilan balik status Anda.

    Contoh berikut menunjukkan deklarasi sampel.

    void CALLBACK CallMaster( HINTERNET,
                              DWORD_PTR,
                              DWORD,
                              LPVOID,
                              DWORD );
    
  2. Tentukan apa yang akan dilakukan fungsi panggilan balik status Anda. Untuk aplikasi yang melakukan panggilan asinkron, fungsi panggilan balik status harus menangani nilai INTERNET_STATUS_REQUEST_COMPLETE, yang menunjukkan permintaan asinkron selesai. Fungsi panggilan balik status juga dapat digunakan untuk melacak kemajuan permintaan Internet.

    Secara umum, cara terbaik adalah menggunakan pernyataan pengalih dengan dwInternetStatus sebagai nilai sakelar dan nilai status untuk pernyataan kasus. Bergantung pada jenis fungsi yang dipanggil aplikasi Anda, Anda dapat mengabaikan beberapa nilai status. Untuk definisi nilai status yang berbeda, lihat daftar di bawah parameter dwInternetStatus dari InternetStatusCallback.

    Pernyataan sakelar berikut adalah contoh cara menangani panggilan balik status.

    switch (dwInternetStatus)
    {
        case INTERNET_STATUS_REQUEST_COMPLETE:
            // Add code
            break;
        default:
            // Add code
            break;
    }
    
  3. Buat kode untuk menangani nilai status.

    Kode untuk menangani setiap nilai status sangat bergantung pada penggunaan fungsi panggilan balik status yang Anda maksudkan. Untuk aplikasi yang hanya melacak kemajuan permintaan, menulis string ke kotak daftar mungkin semua yang Anda butuhkan. Untuk operasi asinkron, kode harus menangani beberapa data yang dikembalikan dalam panggilan balik.

    Fungsi panggilan balik status berikut menggunakan fungsi switch untuk menentukan nilai status dan membuat string yang menyertakan nama nilai status dan fungsi sebelumnya yang disebut, yang disimpan dalam anggota szMemo dari struktur 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. Gunakan fungsi InternetSetStatusCallback untuk mengatur fungsi panggilan balik status pada handel HINTERNET yang ingin Anda terima panggilan balik statusnya.

    Contoh berikut menunjukkan cara mengatur fungsi panggilan balik 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 );
    

Catatan

WinINet tidak mendukung implementasi server. Selain itu, itu tidak boleh digunakan dari layanan. Untuk implementasi atau layanan server, gunakan Microsoft Windows HTTP Services (WinHTTP).

 

Membuat Fungsi Panggilan Balik Status

InternetSetStatusCallback

InternetStatusCallback