Hacking Arts
타이머 본문
- 타이머 메시지란 알람과 같이 1초, 1분 등의 일정 시간이 되었을 때마다 임의의 어떤 작업을 수행하도록 해준다.
[ 그림 1 SetTimer 정의 ]
- 인자 값으로 윈도우 핸들 , 그리고 타이머 식별 번호가 들어가게 되는데 여러개의 타이머를 사용 할 수 있기 때문이다. 그 다음 인자값이 시간 주기이다. msec 단위라서 10000 값이 1분을 뜻한다. 그리고 그다음 콜백 함수 인자 값이 들어가게 된다. 아래 그림 과 같은 과정을 거친다.
[ 그림 2 타이머 단계 ]
[ 그림 3 타이머 구현 ]
- 아래 소스를 이용해서 위 타이머를 구현 할 수 있다
#include- 이런식으로 생성하면 타이머를 2개도 사용가능 하다.#include #include #pragma warning(disable:4996) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); HINSTANCE g_hInst; LPWSTR lpszClass = (LPWSTR)"OutPut"; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst = hInstance; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = (WNDPROC)WndProc; WndClass.lpszClassName = (LPCSTR)lpszClass; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&WndClass); hWnd = CreateWindow((LPCSTR)lpszClass, (LPCSTR)lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); while (GetMessage(&Message, 0, 0, 0)){ TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { static char curTime[10]; static RECT rt = { 100, 100, 400, 120 }; HDC hdc; PAINTSTRUCT ps; switch (iMessage) { case WM_CREATE: SetTimer(hWnd, 1, 1000, NULL); return 0; case WM_TIMER: _strtime(curTime); InvalidateRect(hWnd, &rt, TRUE); return 0; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); TextOut(hdc, 100, 100, curTime, strlen(curTime)); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: KillTimer(hWnd, 1); PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); }
-콜백 함수란? 응용 프로그램에 정의 되어 있는 함수를 운영체제가 필요할 때 호출하는 함수이다. 콜백 함수는 응용 프로그램 내에서 호출할 수 없고, 반드시 운영체제만이 호출할 수 있다. 그렇다면 왜 운영체제가 호출해야만 하는가? 자원의 독점을 막기 위해서라고 할 수 있다. 즉 콜백 함수의 사용 효과는 자원의 독점을 막고 수행 처리 속도의 향상을 가져온다.
[ 그림 4 콜백 함수 ]
- 왜 타이머는 콜백 함수를 사용하는가? 만약 타이머가 0.1초 분기마다 실행되고 여러개가 실행된다면 타이머도 메시지가 발생하기때문에 메시지 큐에 병목현상이 일어날 수 있다. 즉 여러개의 짧은 주기의 타이머를 정확하게 동작시키기 위해 콜백함수를 사용하게 된 것이다.
[ 그림 5 콜백 함수 구현]
- 아래 소스를 통해서 그림 5를 구현할 수 있다. 랜덤한 크기의 사각형과 원을 출력시키고 있다.
#include#include #include #pragma warning(disable:4996) LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime); HINSTANCE g_hInst; LPWSTR lpszClass = (LPWSTR)"OutPut"; int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst = hInstance; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hInstance = hInstance; WndClass.lpfnWndProc = (WNDPROC)WndProc; WndClass.lpszClassName = (LPCSTR)lpszClass; WndClass.lpszMenuName = NULL; WndClass.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&WndClass); hWnd = CreateWindow((LPCSTR)lpszClass, (LPCSTR)lpszClass, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, (HMENU)NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); while (GetMessage(&Message, 0, 0, 0)){ TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { static char curTime[10]; static RECT rt = { 100, 100, 400, 120 }; HDC hdc; PAINTSTRUCT ps; switch (iMessage) { case WM_CREATE: SetTimer(hWnd, 1, 1000, (TIMERPROC)TimerProc); return 0; case WM_DESTROY: KillTimer(hWnd, 1); PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); } void CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) { HDC hdc; hdc = GetDC(hWnd); Rectangle(hdc, rand() % 500, rand() % 500, rand() % 500, rand() % 500); Ellipse(hdc, rand() % 500, rand() % 500, rand() % 500, rand() % 500); ReleaseDC(hWnd,hdc); }
-참고 자료
API Programing / 이창현 / 혜지원
'Programing > API Programing' 카테고리의 다른 글
resource (icon/cursor) (0) | 2014.11.04 |
---|---|
키보드 입력 (0) | 2014.10.10 |
마우스 입력 (0) | 2014.10.10 |
문자열 / 점 / 선 / 사각형 / 원 / 다각형 / 메시지 박스 (0) | 2014.10.10 |
출력 / GDI / DC (0) | 2014.10.10 |