다음을 통해 공유


상태 콜백 함수 만들기

이 자습서에서는 인터넷 요청의 상태를 모니터링하는 데 사용되는 상태 콜백 함수를 만드는 방법을 설명합니다.

상태 콜백 함수는 0이 아닌 컨텍스트 값을 전달한 WinINet 함수에서 시작된 모든 인터넷 요청에서 상태 콜백을 받습니다.

상태 콜백 함수를 만드는 데 필요한 단계는 다음과 같습니다.

  1. 컨텍스트 값을 정의합니다.
  2. 상태 콜백 함수를 만듭니다.

컨텍스트 값 정의

컨텍스트 값은 부호 없는 긴 정수 값일 수 있습니다. 이상적으로 컨텍스트 값은 방금 완료된 요청과 연결된 리소스의 위치(필요한 경우)를 식별해야 합니다.

컨텍스트 값을 사용하는 가장 유용한 방법 중 하나는 구조체의 주소를 전달하고 이를 DWORD_PTR로 변환하는 것입니다. 구조체를 사용하여 요청에 대한 정보를 저장하여 상태 콜백 함수에 전달할 수 있습니다.

다음 구조체는 가능한 컨텍스트 값의 예입니다. 구조체의 멤버는 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;

이 예제에서 상태 콜백 함수는 창 핸들에 액세스할 수 있으므로 사용자 인터페이스를 표시할 수 있습니다. InternetOpenUrl 만든 HINTERNET 핸들은 리소스 및 요청에 대한 정보를 전달하는 데 사용할 수 있는 문자 배열을 다운로드할 수 있는 다른 함수에 전달될 수 있습니다.

구조체의 멤버는 특정 애플리케이션의 요구에 맞게 변경할 수 있으므로 이 예제에서는 제약을 받지 않습니다.

상태 콜백 함수 만들기

상태 콜백 함수는 InternetStatusCallback형식을 따라야 합니다. 이렇게 하려면 다음을 수행합니다.

  1. 상태 콜백 함수에 대한 함수 선언을 작성합니다.

    다음 예제에서는 샘플 선언을 보여줍니다.

    void CALLBACK CallMaster( HINTERNET,
                              DWORD_PTR,
                              DWORD,
                              LPVOID,
                              DWORD );
    
  2. 상태 콜백 함수가 수행할 작업을 결정합니다. 비동기 호출을 하는 애플리케이션의 경우 상태 콜백 함수는 비동기 요청이 완료되었음을 나타내는 INTERNET_STATUS_REQUEST_COMPLETE 값을 처리해야 합니다. 상태 콜백 함수를 사용하여 인터넷 요청의 진행률을 추적할 수도 있습니다.

    일반적으로 dwInternetStatus를 스위치 값으로 하고 상태 값을 사례 문의 값으로 사용하는 switch 문을 사용하는 것이 최상의 방법입니다. 애플리케이션에서 호출하는 함수 유형에 따라 일부 상태 값을 무시할 수 있습니다. 다른 상태 값에 대한 정의는 InternetStatusCallbackdwInternetStatus 매개 변수 아래의 목록을 참조하세요.

    다음 switch 문은 상태 콜백을 처리하는 방법의 예입니다.

    switch (dwInternetStatus)
    {
        case INTERNET_STATUS_REQUEST_COMPLETE:
            // Add code
            break;
        default:
            // Add code
            break;
    }
    
  3. 상태 값을 처리하는 코드를 만듭니다.

    각 상태 값을 처리하는 코드는 상태 콜백 함수를 의도한 용도에 따라 크게 달라집니다. 요청 진행률만 추적하는 애플리케이션의 경우 목록 상자에 문자열을 쓰는 것이 필요할 수 있습니다. 비동기 작업의 경우 코드는 콜백에서 반환된 일부 데이터를 처리해야 합니다.

    다음 상태 콜백 함수는 switch 함수를 사용하여 상태 값이 무엇인지 확인하고 상태 값의 이름과 호출된 이전 함수를 포함하는 문자열을 만듭니다. 이 문자열은 REQUEST_CONTEXT 구조의 szMemo 멤버에 저장됩니다.

    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. InternetSetStatusCallback 함수를 사용하여 상태 콜백을 수신하려는 HINTERNET 핸들에서 상태 콜백 함수를 설정합니다.

    다음 예제에서는 상태 콜백 함수를 설정하는 방법을 보여 줍니다.

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

메모

WinINet은 서버 구현을 지원하지 않습니다. 또한 서비스에서 사용하면 안 됩니다. 서버 구현 또는 서비스의 경우 WinHTTP(Microsoft Windows HTTP 서비스) 사용합니다.

 

상태 콜백 함수 만들기

InternetSetStatusCallback

InternetStatusCallback