posted by nsakura 2010. 7. 18. 18:39

바로 전 타이머 포스팅을 보면 약간의 문제가 있다.

프로그램이 실행되면 바로 약간 갭이 있는후에 시계가 뜬다

이유가 뭘까?

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