교내 전공과목인 윈도우즈 API수업을 정리합니다
1. Timer을 알아보자.
(1) 코드소스
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
SYSTEMTIME st;
static TCHAR sTime[128];
static RECT rt={100,100,400,120};
switch (iMessage) {
case WM_CREATE: //window를 켰을 때 한 번 나타남. (p.99)
SetTimer(hWnd,1,1000,NULL); // (1) SetTime(윈도우핸들, 타이머 번호, 메시지 생성간격, 보통 NULL지정)
// SendMessage(hWnd, WM_TIMER, 1, 0);
return 0;
case WM_TIMER:
GetLocalTime(&st); //시스템에서 현재시간 알아오기, &왜 붙이는지 알아오기
wsprintf(sTime,TEXT("지금 시간은 %d:%d:%d입니다"), //sTime = buffer, %d= format(정수),
st.wHour,st.wMinute,st.wSecond);
InvalidateRect(hWnd,NULL,FALSE); // TRUE를 FALSE로 바꿔보는 것도 괜츈
// InvalidateRect(hWnd,&rt,TRUE);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,100,100,sTime,lstrlen(sTime));
EndPaint(hWnd,&ps);
return 0;
case WM_DESTROY:
KillTimer(hWnd,1);
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}
- SetTimer(HWND hWnd, int nIDEvent,WORD wElapse,FARPROC lpTimerFunc)
hWnd: 메시지를 받을 윈도우 핸들
nIDEvent: 타이머의 번호(여러개 생길 수도 있는 타이머의 구분)
wElapse: 메시지가 생성될 시간 간격(1/1000초 단위)
lpTimerFunc: 보통 NULL값으로 지정, WM_TIMER메시지를 WndProc에 전달되도록 함 - SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
Msg: 전달할 메시지
wParam: 메시지 추가 정보, 메시지에 따라 의미 달라짐
lParam: 메시지 추가 정보 - GetLocalTime(LPSYSTEMTIME lpSystemTime);
lpSystemTime: 현재 로컬 시간을 대입받을 SYSTEMTIME 구조체 - InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase)
lpRect: 무효화할 영역, NULL이면 작업 영역 전체가 무효화 됨
bErase: 무효 영역의 배경을 먼저 지울 것인가를 지정, True면 함수가 배경은 먼저 지우고 작업 영역을 그림)
* 무효화영역: 윈도우의 화면의 일부가 변경되어 다시 그려져야 할 부분 - TextOut(HDC hdc, int nXStart, int nYStart, LPCTSTR lpString, int cbString);
nXStart: X좌표
nYStart: Y좌표
lpString: 출력할 문자열
cbString: 문자열의 길이, 반들시 길이를 밝혀 주어야 함 (null인식 불가) - KillTimer(HWND hWnd, UINT_PTR uIDEvent);
uIDEvent: 삭제할 타이머의 ID, SetTimer의 ID와 일치해야 함. - PostQuitMessage(int nExitCode);
nExitCode: 종료코드, 보통 0으로 전달함.메인 윈도우 파괴시 응용 프로그램 종료 역할
(2) 실행모습
1초단위로 현재 시간을 출력하는 윈도우가 만들어진다.
2. TIMER을 이용하여 문자열이 (수직방향) 움직이도록 만들자
(1) 코드소스
int x, y;
TCHAR str[26];
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
SYSTEMTIME st;
static RECT rect;
switch (iMessage) {
case WM_CREATE:
srand((unsigned int)time(NULL)); // 랜덤 위치 설정
GetClientRect(hWnd, &rect); // (hWnd, Rect구조체포인터), 윈도우의 작업영역 크기를 계산함
SetTimer(hWnd, 1, 100, NULL); // 0.1초 단위로 수직방향의 위치 변환
// SendMessage(hWnd, WM_TIMER, 1, 0);
str[0] = rand() % 26 + 97; // 출력할 알파벳 코드 얻기
y = rand() % (rect.right - 40) + 20; // 출력위치의 랜덤 x좌표 얻기
return 0;
case WM_SIZE:
GetClientRect(hWnd, &rect);
return 0;
case WM_TIMER:
if (y >= rect.bottom){ //문자가 바닥 위치를 넘으면
str[0] = rand() % 26 + 97; //새로운 문자 지정
x = rand() % (rect.right - 40) + 20; // x축(시작위치) . 40은 양 끝의 총 길이, 시작점은 20보다 커야 함.
y = 0; // y축(시작위치)
}
y += 60; // 위치 하향
InvalidateRect(hWnd, NULL, TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, x, y, str, lstrlen(str)); // (hdc, x좌표, y좌표, 문자열, 문자열길이)
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
- GetClientRect(HWND hWnd, LPRECT lpRect);
lpRect: 리턴값을 돌려받기 위한 RECT 구조체의 포인터
윈도우의 작업영역 크기를 계산해준다. 좌상단값은 항상 (0, 0) 이고 우하단좌표는 (right, bottom)이 곧 윈도우의 크기가 된다.
(2) 실행모습
랜덤위치에서 랜덤알파벳이 수직낙하함.
내일은 3주차-2로 타이핑 맞추기만들기.