case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps); //출력하기 위한 도구
//텍스트 출력 (x좌표,y좌표,텍스트,크기)
TextOut(hdc, 50, 50, TEXT("win32"), 5);
//사각형 출력 (왼쪽위좌표,오른쪽아래좌표)
Rectangle(hdc, 100, 100, 200, 200);
//원 출력 (왼쪽위좌표,오른쪽아래좌표)
Ellipse(hdc, 100, 100, 200, 200);
//선 그리기
MoveToEx(hdc, 300, 100, NULL); //시작좌표
LineTo(hdc, 400, 150); //끝좌표
MoveToEx(hdc, 100, 400, NULL);//다른 선을 그릴 때마다 시작좌표 새로 설정해야 함
LineTo(hdc, 200, 500);
EndPaint(hWnd, &ps);
}
break;
WM_PAINT는 화면을 그릴 때 호출된다. hdc에 출력할 윈도우 핸들을 설정한다. 그리고 텍스트, 사각형, 원, 선을 출력한다. 그 다음은 스타크래프트처럼 마우스를 드래그 할 때 사각형을 출력하도록 해보자.
struct _tagArea
{
bool bStart;
POINT ptStart;
POINT ptEnd;
};
_tagArea g_tArea;
먼저 출력할 사각형의 시작점과 끝점, 그리고 드래그 중인지 확인하기 위한 bool변수를 가진 구조체를 하나 만들고
전역으로 구조체 타입의 객체를 선언한다.
case WM_LBUTTONDOWN:
//마우스 위치는 lParam에 들어오는데 32비트에 16비트씩 쪼개서 x,y값이 들어옴
//LOWORD, HIWORD 매크로로 상위, 하위 16비트 값을 얻어올 수 있다.
if (!g_tArea.bStart)
{
g_tArea.bStart = true;
// 만약 lParam이 0x12345678
g_tArea.ptStart.x = lParam & 0x0000ffff; // 설명 참고
g_tArea.ptStart.y = lParam >> 16;
//강제로 WM_PAINT 메시지를 호출해주는 함수
//두번째 인수는 갱신할 영역,NULL일 경우 전체화면 대상 갱신
//3번 인자는 TRUE일경우 현재 화면 지우고 갱신, FALSE일 경우 안지움
InvalidateRect(hWnd, NULL, TRUE);
}
break;
WM_LBUTTONDOWN은 마우스 왼쪽 버튼을 누를 때 호출된다. 누르면 드래그가 시작되는 것이므로 bStart를 true로 설정한다. 그리고 드래그의 시작점 좌표를 설정한다. 마우스 위치는 lParam에 들어온다. 32비트에 16비트씩 쪼개서 x,y 값이 들어오는데 먼저 lParam과 0x0000ffff를 &연산한다. 16진수 1비트는 이진수 4비트이기 때문에 16진수 0000ffff는
0 16비트와 1 16비트로 이루어져있다. 그래서 0x12345678과 0000ffff를 &연산하면 5678이 된다. (마스크 오프)
그리고 lParam>>16은 16비트만큼 오른쪽으로 미는 것이므로 0x12345678 >> 16하면 1234가 된다. 그리고 InvalidateRect 함수를 이용해 WM_PAINT를 강제로 호출하고 화면을 갱신한다.
case WM_MOUSEMOVE:
if (g_tArea.bStart)
{
g_tArea.ptEnd.x = lParam & 0x0000ffff;
g_tArea.ptEnd.y = lParam >> 16;
InvalidateRect(hWnd, NULL, TRUE);
}
break;
case WM_LBUTTONUP:
if (g_tArea.bStart)
{
g_tArea.bStart = false;
g_tArea.ptStart.x = lParam & 0x0000ffff;
g_tArea.ptStart.y = lParam >> 16;
InvalidateRect(hWnd, NULL, TRUE);
}
break;
그리고 마우스 왼쪽 버튼을 누른 상태에서 움직일 시 끝좌표가 갱신되고 화면에 출력한다. 마우스 왼쪽 버튼을 떼면 드래그를 중지하고 마지막 마우스 좌표를 화면에 출력한다.
case WM_KEYDOWN:
//wParam에 어떤 키를 눌렀는지 들어옴
switch (wParam)
{
case VK_ESCAPE:
DestroyWindow(hWnd);
break;
}
break;
WM_KEYDOWN은 키보드에 키를 입력할 때 호출된다. 입력한 키 값은 wParam에 저장된다.
'WinAPI' 카테고리의 다른 글
| [WinAPI] 더블 버퍼링 (0) | 2022.01.20 |
|---|---|
| [WinAPI] 삼각함수 (0) | 2022.01.16 |
| [WinAPI] 델타 타임 (0) | 2022.01.16 |
| [WinAPI] PeekMessage와 윈도우 창 크기 설정 (0) | 2022.01.15 |
| [WinAPI] 기본 윈도우 창 (0) | 2022.01.15 |