바로 전 타이머 포스팅을 보면 약간의 문제가 있다.
프로그램이 실행되면 바로 약간 갭이 있는후에 시계가 뜬다
이유가 뭘까?
WM_PAINT가 문제일까 WM_TIMER가 문제일까?
자세히 살펴보자
WM_PAINT는 단지 화면에 글씨를 출력시켜주는 일밖에 안한다.
그러니 문제가 없다고 본다.
그렇다면 WM_TIMER에서 문제일까?
그렇다 WM_TIMER의문제 인데. 이유는 간단!
WM_TIMER에서 현 시간을 조사하는데 걸리는 시간이 1초라는것이다.
간단하게 말하면 WM_TIMER가 프로그램이 실행되고 1초후라는거다.
그러니 1초라는 갭이있는데 이 갭을 없애고 싶다는것이다.
그러기 위해서 사용하는 함수가 SendMessage함수이다.
원형을 보자.
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
즉 이 함수는 강제적으로 메시지가 발생한 것처럼 만들어주는 함수라고 보면 된다.
첫 번째 인수 윈도우를 말하는것
두 번째 인수 보내고자하는 메세지
세 번째 네 번째 인수는 메세지의 추가 정보인 wParam,lParam이며 보내는 메세지에따라 달라진다.
wParam은 타이머 Id를 보내도록 되어있다.
타이머 포스트의 소스의 일부를
case WM_CREATE:
SetTimer(hWnd,1,1000,NULL);
SendMessage(hWnd,WM_TIMER,1,0);
return 0;
이렇게 추가하자.
본인이 프로그램을 짤때는 문제는 없으니 책을 보니 두번째 문제가 있다고 하는데.
바로 시간을 갱신할때 화면이 껌뻑거릴수있다고 하는데. 이것에 대한 문재는.
InvalidateRect(hWnd,NULL,true);
두번째 인자가 null이다 즉 전체 화면에 대해 다시 그린다 인데 이게 문제가되어서 화면이 깜빡거릴수있다고 한다.
두번째 인자는 앞 포스팅에서 말했듯 다시그릴 영역 즉 범위를 설정한다고 했다.
코드 전체를 보면
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_Inst;
LPCTSTR wndname=TEXT("GFP TIME");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nShowCmd){
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
g_Inst=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;
WndClass.lpszClassName=wndname;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(wndname,wndname,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nShowCmd);
while(GetMessage(&Message,NULL,0,0)){
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam){
HDC hdc;
PAINTSTRUCT ps;
SYSTEMTIME st;
static RECT table={100,100,400,120};
static TCHAR sTime[128];
switch(iMessage){
case WM_DESTROY:
KillTimer(hWnd,1);
PostQuitMessage(0);
return 0;
case WM_CREATE:
SetTimer(hWnd,1,1000,NULL);
SendMessage(hWnd,WM_TIMER,1,0);
return 0;
case WM_TIMER:
GetLocalTime(&st);
wsprintf(sTime,TEXT("%d : %d: %d"),st.wHour,st.wMinute,st.wSecond);
InvalidateRect(hWnd,&table,true);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,100,100,sTime,lstrlen(sTime));
EndPaint(hWnd,&ps);
return 0;
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
이런식이 되겠다.
'Computer > Win API' 카테고리의 다른 글
WinApi 두개의 타이머 (0) | 2010.07.18 |
---|---|
WinApi 타이머 확장 문제. (0) | 2010.07.18 |
WinApi 타이머 (0) | 2010.07.18 |
WinApi 마우스 입력. (0) | 2010.07.18 |
WinApi WM_KEYDOWN (0) | 2010.07.18 |