이번에는 원을 그리고 키보드로 원을 움직이는 것을 해보겠다

 

먼저 원을 그려야 하는데 

 

원을 그려주는 Ellipse 함수를 이용한다.

 

좌표 2개를 입력으로 받는다 (X1,Y1) , (X2, Y2) 이 두 좌표를 이용하여 사각형을 만들었을때 

 

그 안을 내접하는 원을 만들어준다.

 

예를들어 (0,0)    (40,40) 이라면

 

중심이 (20,20)인 원

 

 

 

1
2
3
4
5
6
7
Bool Ellipse(
    HDC hdc,
    int X1,
    int Y1,
    int X2,
    int Y2
    );
cs

 

ex)

 

 

 

 

1
2
hdc = BeginPaint(hwnd,&ps);
Ellipse(hdc,x-20,y-20,x+20,y+20);
cs

 

 

 

이제 이를 이용하여

 

 

dd

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
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;
            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)
            {
    
                x+=40;
            
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            break;
        case WM_KEYUP:
            
            InvalidateRgn(hwnd,NULL,TRUE);
            break;
        case WM_DESTROY: {
            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

 

 

이 코드의 경우

 

오른쪽 방향키를 누르면 x가 40만큼 증가하여 원이 오른쪽으로 이동하는 것 처럼 보이게 만들 수 있다.

 

하지만 계속 누르는 경우 윈도우 밖으로 나가버린다.

 

이를 막기 위해 윈도우 크기를 알아내어 해당 윈도우 크기만큼만 이동시킬 수 있는데 

 

GetClientRect()함수로 윈도우 크기를 알아낼 수 있다.

 

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
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)
            {
                
                x+=40;
                if(x+20>rectView.right)
                {
                    x-=40;
                }
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            break;
        case WM_KEYUP:
            
            InvalidateRgn(hwnd,NULL,TRUE);
            break;
        case WM_DESTROY: {
            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

 

 

 

 

 

 

 

실행 하면 현재 윈도우 크기 만큼만 원이 이동함을 알 수 있다.

 

하지만 예상대로 윈도우를 최대화로 늘려도 그 이상 이동되진 않았다.

 

이경우는 윈도우의 크기가 변하면 발생하는 WM_SIZE 메세지를 이용한다.

 

 

 

출처 :

 

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

+ Recent posts