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 |
댓글