Programming Language/Windows API

마우스로 도형 옮기기

D4tai1 2018. 9. 30.

1. 마우스로 드래그해서 원 옮기기

[1] 마우스가 클릭되었을 때의 좌표가 원 내에 있는지 확인

[2] 원 내에 있다면 WM_MOUSEMOVE 메세지가 발생했을 때 원의 좌표를 마우스 좌표로 변경

[3] 마우스 드래그 중일 때는 원의 색상을 빨간색으로 변경

 

2. 소스

1) 윈도우 메세지 처리함수

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
		PAINTSTRUCT ps;
		HDC hdc;
		
		static int x, y;
		//원의 좌표
		int mx, my;
		//마우스의 좌표

		static BOOL flag;
		//마우스가 원의 영역안에 있는지 상태

	case WM_CREATE:
	{
		x = 250;
		y = 250;
		//처음 원의 위치
		flag = FALSE;
		//처음 상태는 클릭되어있지 않으므로 FALSE
	}
	break;

	case WM_LBUTTONDOWN:
	{
		mx = LOWORD(lParam);
		//마우스의 x좌표를 mx에 저장
		my = HIWORD(lParam);
		//마우스의 y좌표를 my에 저장

		if (InCircle(x, y, mx, my)) {
			//원의 영역내에 있다면
			flag = TRUE;
		}
		InvalidateRgn(hWnd, NULL, TRUE);
	}
	break;

	case WM_LBUTTONUP:
	{
		flag = FALSE;
		//마우스버튼을 떼면 FALSE로 변경
		InvalidateRgn(hWnd, NULL, TRUE);
	}
	break;

	case WM_MOUSEMOVE: 
	{
		mx = LOWORD(lParam);
		//마우스의 x좌표를 mx에 저장
		my = HIWORD(lParam);
		//마우스의 y좌표를 my에 저장

		if (flag) {
			x = mx;
			y = my;
			//마우스 좌표를 원의 좌표로 변경

			InvalidateRgn(hWnd, NULL, TRUE);
			//해당 창번호의 영역전체를 무효화 후 다시 그리기
		}
	}
	break;

    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 메뉴 선택을 구문 분석합니다:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
			hdc = BeginPaint(hWnd, &ps);
			my_paint(hdc, &flag, &x, &y);
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

 

2) 사용자 정의함수

 

#include<math.h>
#define BSIZE 50
//반지름

double LengthPts(int x1, int y1, int x2, int y2) {
	return sqrt((float)((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)));
	//피타고라스 정의를 이용하여 원의 중심으로부터 마우스포인터까지 거리를 반환
}

BOOL InCircle(int x, int y, int mx, int my) {
	if (LengthPts(x, y, mx, my) < BSIZE) {
		//원의 중심으로부터 반지름 내 거리에 있다면
		return TRUE;
	}
	else {
		return FALSE;
	}
}

void my_paint(HDC hdc, BOOL *flag, int *x, int *y) {
	HBRUSH hBrush;
	if (*flag) {
		//Rectangle(hdc, *x - 50, *y - 50, *x + 50, *y + 50);
		hBrush = CreateSolidBrush(RGB(255, 0, 0));
		//빨간색을 얻어와 HBRUSH 타입의 hBrush에 저장
		SelectObject(hdc, hBrush);
		//창의 속성 중 BRUSH를 hBrush로 변경
	}
	else {
		SelectObject(hdc, GetStockObject(WHITE_BRUSH));
		//창의 속성 중 BRUSH를 흰색으로 변경
	}
	Ellipse(hdc, *x - 50, *y - 50, *x + 50, *y + 50);
	//원 그리기
}

 

 

3. 시연

- 마우스로 드래그하여 원을 이동할 수 있다.

'Programming Language > Windows API' 카테고리의 다른 글

사각형 그리기  (0) 2018.09.30
도형 자동이동  (0) 2018.09.30
keyboard[마지막]  (0) 2018.09.10
shape  (0) 2018.08.27
caret  (0) 2018.08.27

댓글