이번에는 입력에 의한 제어가 아닌

 

일정 시간 간격으로 메세지를 보내는 타이머 메세지이다.

 

1
2
3
4
5
6
UINT_PTR SetTimer(
    HWND hWnd,
    UINT_PTR nIDEvent,
    UINT uElapse,
    TIMERPROC lpTimerFunc
    );
cs

 

SetTimer() 함수를 이용한다.

 

nIDEvent : 타이머의 ID로 정수값 (여러개의 타이머를 쓸 경우 구분하기위함)

uElapse : 시간 간격으로 단위는 밀리초 ex) 1000 이 1초

lpTimerFunc : 타이머가 보내는 WM_TIMER 메세지를 받을 함수 이름 NULL 이면 WndProc() 가 WM_TIMER 메세지를 받는다.

 

 

 

 

타이머의 동작을 중간에 정지시킬 떄는 KillTimer() 함수를 사용한다. KillTimer() 함수로 정지시킨 타이머는 SetTimer() 로 다시 동작시킬 수 있다.

 

 

 

1
2
3
4
BOOL KiLLTimer(
    HWND hWnd,
    UINT_PTR nIDEvent,
    );
cs

 

nIDEvent : 동작 중인 타이머의 ID

 

 

 

이제 이를 이용하여 타이머를 설정하고 

 

타이머를 이용하여 원이 자동으로 움직이게 만들어보면

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    
    HDC hdc;
    PAINTSTRUCT ps;
    static int x,y;
    static RECT rectView;
    
    switch(Message) {
        
        /* Upon destruction, tell the main thread to stop */
        case WM_CREATE:
            x=20; y=20;
            GetClientRect(hwnd,&rectView);
            break
            
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            
            Ellipse(hdc,x-20,y-20,x+20,y+20);
            EndPaint(hwnd,&ps);
            break;
        case WM_KEYDOWN:
            if(wParam == VK_RIGHT)
            {
                SetTimer(hwnd,1,70,NULL);
                
            }
            
            break;
        case WM_TIMER:
            x+=40;
            if(x+20>rectView.right)
            {
                x-=40;
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            
            break;
        case WM_DESTROY: {
            KillTimer(hwnd,1);
            PostQuitMessage(0);
            break;
        }
    
        /* All other messages (a lot of them) are processed using default procedures */
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}
cs

 

이렇게 만들어서 실행해보면 오른쪽 방향키를 누르는 순간 원이 자동으로 오른쪽으로 이동한다.

 

하지만 오른쪽방향키를 꾹 누르고 있는 경우 공이 멈춰버리는데 

 

정확한것은 아니지만

 

내 예상으로는 SetTimer가 설정되고 그 타이머가 WM_TIMER 메세지를 보내기전에 또다시  SetTimer가 만들어져서(오른쪽 방향키를 계속 누르고있으니 WM_KEYDOWN 메세지가 엄청빨리 보내짐) WM_TIMER가 메세지가 발생하지 않았을 것이라 생각된다(SetTimer가 덮어써지는 현상일듯?)

 

 

출처 :

 

핵심 API로 배우는 윈도우 프로그래밍,   강경우 지음   출판사 : 한빛아카데미

+ Recent posts