다음을 통해 공유


시간 간격으로 그리기

SetTimer 함수를 사용하여 타이머를 만들어 시간 간격으로 그릴 수 있습니다. 타이머를 사용하여 일정한 간격으로 프로시저에 WM_TIMER 메시지를 보내면 애플리케이션은 다른 애플리케이션이 계속 실행되는 동안 클라이언트 영역에서 간단한 애니메이션을 수행할 수 있습니다.

다음 예제에서 애플리케이션은 클라이언트 영역에서 star 좌우로 반송합니다. 창 프로시저가 WM_TIMER 메시지를 받을 때마다 프로시저는 현재 위치에서 star 지우고, 새 위치를 계산하고, 새 위치 내에 star 그립니다. 프로시저는 WM_CREATE 메시지를 처리하는 동안 SetTimer를 호출하여 타이머를 시작합니다.

RECT rcCurrent = {0,0,20,20}; 
POINT aptStar[6] = {10,1, 1,19, 19,6, 1,6, 19,19, 10,1}; 
int X = 2, Y = -1, idTimer = -1; 
BOOL fVisible = FALSE; 
HDC hdc; 
 
LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    RECT rc; 
 
    switch (message) 
    { 
        case WM_CREATE: 
 
            // Calculate the starting point.  
 
            GetClientRect(hwnd, &rc); 
            OffsetRect(&rcCurrent, rc.right / 2, rc.bottom / 2); 
 
            // Initialize the private DC.  
 
            hdc = GetDC(hwnd); 
            SetViewportOrgEx(hdc, rcCurrent.left, 
                rcCurrent.top, NULL); 
            SetROP2(hdc, R2_NOT); 
 
            // Start the timer.  
 
            SetTimer(hwnd, idTimer = 1, 10, NULL); 
            return 0L; 
 
        case WM_DESTROY: 
            KillTimer(hwnd, 1); 
            PostQuitMessage(0); 
            return 0L; 
 
        case WM_SIZE: 
            switch (wParam) 
            { 
                case SIZE_MINIMIZED: 
 
                    // Stop the timer if the window is minimized. 
 
                    KillTimer(hwnd, 1); 
                    idTimer = -1; 
                    break; 
 
                case SIZE_RESTORED: 
 
                    // Move the star back into the client area  
                    // if necessary.  
 
                    if (rcCurrent.right > (int) LOWORD(lParam)) 
                    {
                        rcCurrent.left = 
                            (rcCurrent.right = 
                                (int) LOWORD(lParam)) - 20; 
                    }
                    if (rcCurrent.bottom > (int) HIWORD(lParam)) 
                    {
                        rcCurrent.top = 
                            (rcCurrent.bottom = 
                                (int) HIWORD(lParam)) - 20; 
                    }
 
                    // Fall through to the next case.  
 
                case SIZE_MAXIMIZED: 
 
                    // Start the timer if it had been stopped.  
 
                    if (idTimer == -1) 
                        SetTimer(hwnd, idTimer = 1, 10, NULL); 
                    break; 
            } 
            return 0L; 
 
        case WM_TIMER: 
 
            // Hide the star if it is visible.  
 
            if (fVisible) 
                Polyline(hdc, aptStar, 6); 
 
            // Bounce the star off a side if necessary.  
 
            GetClientRect(hwnd, &rc); 
            if (rcCurrent.left + X < rc.left || 
                rcCurrent.right + X > rc.right) 
                X = -X; 
            if (rcCurrent.top + Y < rc.top || 
                rcCurrent.bottom + Y > rc.bottom) 
                Y = -Y; 
 
            // Show the star in its new position.  
 
            OffsetRect(&rcCurrent, X, Y); 
            SetViewportOrgEx(hdc, rcCurrent.left, 
                rcCurrent.top, NULL); 
            fVisible = Polyline(hdc, aptStar, 6); 
 
            return 0L; 
 
        case WM_ERASEBKGND: 
 
            // Erase the star.  
 
            fVisible = FALSE; 
            return DefWindowProc(hwnd, message, wParam, lParam); 
 
        case WM_PAINT: 
 
            // Show the star if it is not visible. Use BeginPaint  
            // to clear the update region.  
 
            BeginPaint(hwnd, &ps); 
            if (!fVisible) 
                fVisible = Polyline(hdc, aptStar, 6); 
            EndPaint(hwnd, &ps); 
            return 0L; 
    } 
    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

이 애플리케이션은 프라이빗 디바이스 컨텍스트를 사용하여 그리기 위해 디바이스 컨텍스트를 준비하는 데 필요한 시간을 최소화합니다. 창 프로시저는 WM_CREATE 메시지를 처리할 때 개인 디바이스 컨텍스트를 검색하고 초기화하여 Polyline 함수에 대한 동일한 호출을 사용하여 star 지우고 그릴 수 있도록 이진 래스터 작업 모드를 설정합니다. 또한 창 프로시저는 클라이언트 영역에서 star 위치에 관계없이 동일한 점 집합을 사용하여 star 그릴 수 있도록 뷰포트 원본을 설정합니다.

애플리케이션은 WM_PAINT 메시지를 사용하여 창을 업데이트해야 할 때마다 star 그립니다. 창 프로시저는 표시되지 않는 경우에만 star 그립니다. 즉, WM_ERASEBKGND 메시지에 의해 지워진 경우에만 그려집니다. 창 프로시저는 WM_ERASEBKGND 메시지를 가로채 fVisible 변수를 설정하지만 시스템에서 창 배경을 그릴 수 있도록 메시지를 DefWindowProc 에 전달합니다.

애플리케이션은 WM_SIZE 메시지를 사용하여 창이 최소화될 때 타이머를 중지하고 최소화된 창이 복원될 때 타이머를 다시 시작합니다. 창 프로시저는 또한 메시지를 사용하여 star 더 이상 클라이언트 영역에 있지 않도록 창 크기가 줄어드는 경우 star 현재 위치를 업데이트합니다. 애플리케이션은 star 경계 사각형을 정의하는 rcCurrent에 지정된 구조를 사용하여 star 현재 위치를 추적합니다. 클라이언트 영역에 사각형의 모든 모서리를 유지하면 영역에 star 유지됩니다. 창 프로시저는 처음에 WM_CREATE 메시지를 처리할 때 클라이언트 영역의 star 가운데에 옵니다.