2011년8월31일_winAPI_두 개의 타이머, 백그라운드 작업, 콜백함수(CALLBACK)
● 두 개의 타이머 (windows API정복 page.103)
SetTimer()로 현재 윈도우에 타이머 ID 1번과 2번을 설정함.
ID 1번은 1000ms(1초)마다,
ID 2번은 5000ms(5초)마다 WM_TIMRE 메시지가 발생한다.
SendMessage()로 타이머 ID 1번만 최초실행시(WM_CREATE) 메시지를 강제로 발생시켜 ID 1번에 해당하는 기능을 수행하도록함.
추가로 2번 타이머도 실행시 바로 메시지가 발생할 수 있도록함.
WM_TIMER메시지가 발생한 후 wParam에 들어 있는 값을 확인해 보면 어느 타이머가 알려 왔는지 알 수 있다.
MessageBeep()는 사운드코덱(사운드카드)를 통해 소리를 발생시키는 함수로 0을 인자로 넣으면 띵~ 하는 소리가 난다.
이어폰이 없으면 확인하기 어려우니 아래와 같이,
wsprintf()로 정수형 변수의 값을 서식화해 SetWindowText()로 윈도우의 타이틀바에 그 값이 표시되도록 한다.
★ Win32환경에서 만들 수 있는 타이머의 게수에는 제한이 없지만 그렇다고 많이 만들면 느려진다.
● 백그라운드 작업 (windows API page.105)
지속적인 작업을 하기 위해 보통 무한루프를 돌린다.
그러나 윈도우즈와 같은 멀티태스킹환경에서는 이런 방식을 사용해서는 안 된다. 왜냐하면 한 프로그램이 제어권을 독점하고 있어서는 안 되며 다른 프로그램도 실행시간을 가져야 하기 때문이다.
CPU를 독점하는 이런 무한 루프를 작성해서는 안 되며 반드시 메시지가 전달되었을 때 에 한해 필요한 작업을 해야 한다.
<예제코드>
<실행화면>
타이머를 돌려 WM_TIMER메시지를 받아 50ms마다 랜덤좌표에 알록달록 점을 1000개 그린다.
타이머는 항상 돌아 화면 점을 뿌린다. 점을 뿌리는 도중에 마우스메시지를 받아 다른 일도 처리할 수 있다.
스타크래프투게임에서 SVC가 미네랄을 계속 채집하여 나르는 일은 타이머메시지에 넣으면 되겠다.
● 콜백함수
SetTimer()의 네 번째 인수는 TIMERPROC lpTimerFunc이라고 되어 있는데 이 인수는 타이머 프로시저 함수의 포인터를 가리킨다.
이 인수가 NULL로 되어 있을 경우 첫 번째 인수로 지정된 hWnd로 WM_TIMER메시지가 전달되지만 이 인수에 타이머 함수가 지정되었을 경우는 매 시간마다 이 함수가 대신 호출된다.
골백함수의 원형은 아래와 같다.
void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime); |
콜백함수의 이름은 상기와 같이 TimerProc가 아니어도 되나 SetTimer() 호출 시 네 번째 인수에 이름과는 같아야 한다.
그리고 인자들의 type은 꼭 같아야 한다.
hWnd는 타이머를 소유한 윈도우의 핸들이고,
uMsg는 WM_TIMER,
idEvent는 타이머 ID,
dwTIme은 윈도우즈가 실행된 후의 경과시간이다.
이 함수의 인수들은 잘 사용되지 않으므로 구체적으로 알 필요는 없다. 알고 싶어~
<예제코드>
<실행화면>
WM_CREATE메시지로 최초실행시 SetTimer()로 타이머를 돌리는데 4번째 인수로 NULL이 아닌,
TImerProc()의 이름을 넣어 콜백함수로 등록하였다.
콜백함수가 등록되면 운영체제는 윈도우로 WM_TIMER 메시지로 보내는 대신 이 함수를 주기적으로 호출한다.
콜백함수 내부에서는 RandGrp.cpp와 같이 (0~499, 0~399)의 좌표에 알록달록 점을 1000개 찍는 일을 한다.
이와 같이 콜백함수로 처리하는 방법과 RandGrp.cpp와 같이 WM_TIMER에서 처리는 방법의 차이점은,
WM_TIMER메시지는 다른 메시지가 있을 경우 실행 순서에 밀려 늦게 호출되는 경우가 있지만,
콜백함수를 사용하면 정확한 시간에 호출된다는 점이다. 그래서 정확도를 요하는 작업은 타이머 메시지보다는 콜백함수를 사용하는 것이 더 좋다고 되어 있다. 하지만 Win32 환경에서는 사실상 별 차이가 없다.
콜백함수는 어떻게 하면 WM_CREATE메시지에서 호출되게 할 수 있을까? 궁금하네…
★ 콜백함수란?
일반적으로 API함수들은 운영체제가 제공하며 프로그램에서는 이 함수들을 호출해서 운영체제의 서비스를 받는다.
예를 들어 도스의 시스템 콜 함수를 호출하여 디스크 입출력을 한다든가 윈도우즈의 TextOut()를 호출하여 문자열을 출력하는 경우가 이에 해당한다. 응용 프로그램이 운영체제에 내장도니 함수를 호출하여 원하는 작업을 하는 것이다.
반면 콜백함수는 응용 프로그램이 제공하며 운영체제가 필요할 때 호출하는 함수이다.
호출되는 방향이 거꾸로 되었기 때문에 콜백(CALLBACK)이라고 부르는 것이다.