상태 콜백 함수 만들기

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

상태 콜백 함수는 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 문을 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