Programming Language/Windows API
도형 자동이동
1. 상하좌우버튼으로 원 자동이동
[1] 상하좌우 중 하나의 버튼이 한 번 눌렸을 때 그 방향으로 1초마다 20씩 이동한다.
[2] 이동할 때마다 원의 색상이 랜덤하게 변경된다.
[3] 동작 시 버튼을 누르면 원이 멈추고, 멈춘상태에서 버튼을 누르면 다시 이동한다.
2. 소스
1) 사용자 정의함수
#include<time.h> void my_init(HDC hdc, HBRUSH *hBrush, int *x, int *y) { srand(time(NULL)); int a = (rand() % 1000 + *x*100) % 256; int b = (rand() % 10000 + *x * 100) % 256; int c = (rand() % 5000 + *x * 100) % 256; SelectObject(hdc, CreateSolidBrush(RGB(a, b, c))); //원의 색상을 부여하기 위해 랜덤값 사용. //RGB는 0~255사이의 3개의 숫자값을 입력하면 해당하는 색상을 반환 Ellipse(hdc, *x - 30, *y - 30, *x + 30, *y + 30); //원 그리기 }
2) 윈도우 메세지 처리함수
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static int x; static int y; //원의 좌표 static RECT rect; //화면 전체 영역의 좌표를 저장하는 구조체 static RECT rt; static BOOL flag[5]; //1~4의 인덱스를 사용하여 방향키를 지정 static HBRUSH hBrush; //원의 색상을 저장 switch (message) { case WM_CREATE: { x = 100; y = 100; //초기 원의 좌표. GetClientRect(hWnd, &rect); //프로그램 실행시 실행창의 영역의 좌표를 rect구조체에 저장한다. for (int i = 0; i < sizeof(flag); i++) { flag[i] = FALSE; } //상하좌우 4개의 방향키 모두 FALSE } break; case WM_KEYDOWN: //입력된 키 중에 { if (wParam == VK_UP) { //위 방향키가 입력되었다면? if (!flag[1]) { //동작하지 않는상태면? SetTimer(hWnd, 1 1000, NULL); //타이머번호 1번 = 1초에 1번씩 WM_TIMER발생 flag[1] = TRUE; //눌렸다. } else { //이미 동작하고 있는 상태면? KillTimer(hWnd, 1); //타이머번호 1번 = 삭제 flag[1] = FALSE; //동작하지 않는 상태로 변경 } } else if (wParam == VK_DOWN) { if (!flag[2]) { SetTimer(hWnd, 2, 1000, NULL); flag[2] = TRUE; } else { KillTimer(hWnd, 2); flag[2] = FALSE; } } else if (wParam == VK_LEFT) { if (!flag[3]) { SetTimer(hWnd, 3, 1000, NULL); flag[3] = TRUE; } else { KillTimer(hWnd, 3); flag[3] = FALSE; } } else if (wParam == VK_RIGHT) { if (!flag[4]) { SetTimer(hWnd, 4, 1000, NULL); flag[4] = TRUE; } else { KillTimer(hWnd, 4); flag[4] = FALSE; } } } break; case WM_TIMER: { rt.left = x - 50; rt.right = x + 50; rt.top = y - 50; rt.bottom = y + 50; //rt구조체 영역 표시 switch (wParam) { case 1: y -= 20; //위 키가 눌렸다면 위로 20 증가 InvalidateRect(hWnd, &rt, TRUE); break; case 2: y += 20; //아래 키가 눌렸다면 아래로 20 증가 InvalidateRect(hWnd, &rt, TRUE); break; case 3: x -= 20; //왼쪽 키가 눌렸다면 좌측으로 20 증가 InvalidateRect(hWnd, &rt, TRUE); break; case 4 : x += 20; //오른쪽 키가 눌렸다면 우측으로 20 증가 //InvalidateRgn(hWnd, NULL, TRUE); 인발리업데이트리전 InvalidateRect(hWnd, &rt, TRUE); // &rt 사각형구조체 영역만 무효화 } break; } 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: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); my_init(hdc, &hBrush, &x, &y); //처음 초기화한 함수와 비슷하므로 같이 사용 //PAINT메세지 발생 시 색상에 따른 원 그리기 EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
3. 시연
- 아래버튼과 우측버튼을 동시에 누르면 대각선으로 이동하는 것도 확인할 수 있다.
'Programming Language > Windows API' 카테고리의 다른 글
입력된 방향키 확인 (0) | 2018.09.30 |
---|---|
사각형 그리기 (0) | 2018.09.30 |
마우스로 도형 옮기기 (0) | 2018.09.30 |
keyboard[마지막] (0) | 2018.09.10 |
shape (0) | 2018.08.27 |
댓글