2014년 4월 10일 목요일

WIN32 API기반으로 간단히 구현해 본 StopWatch

API를 이용하여 간단하게 교육용 소스로 스톱워치를 만들어 보았다.

타이머를 하나 생성해서 돌려주면

타이머 이벤트가 발생할 때 마다 undercomma (1/100초)가 하나씩 증가하고

이넘들이 100개 모이면 1초 , 1초가 60개 모이면 다시 1분이 증가하는 순서이다.

소스는 간단함..

문제점이 있다면 실제 시간하고 맞지 않는다는것이다.
(실제시간 1초보다 타이머상의 1초가 증가하는데 더 오래걸린다)



//============================================================================================
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=TEXT("StopWatch");
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)(COLOR_WINDOW+1);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW | CS_VREDRAW;
 RegisterClass(&WndClass);
 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,CW_USEDEFAULT,300,220,
  NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 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;
   HFONT font, oldfont;
   static int min, sec, undercomma; // 분, 초, 0.01초
   switch (iMessage) {
     case WM_CREATE:
      hWndMain=hWnd;
      CreateWindow(TEXT("button"),TEXT("START"),WS_CHILD|WS_VISIBLE|
       BS_PUSHBUTTON,20,150,80,30,hWnd,(HMENU)0,g_hInst,NULL);
      CreateWindow(TEXT("button"),TEXT("STOP"),WS_CHILD|WS_VISIBLE|
       BS_PUSHBUTTON,105,150,80,30,hWnd,(HMENU)1,g_hInst,NULL);
      CreateWindow(TEXT("button"),TEXT("EXIT"),WS_CHILD|WS_VISIBLE|
       BS_PUSHBUTTON,190,150,80,30,hWnd,(HMENU)2,g_hInst,NULL);
    return 0;
 
   case WM_TIMER:
      undercomma+=5;
      if(undercomma >= 100) { sec++; undercomma=0; }
      if(sec >= 60) { min++; sec=0; }
      InvalidateRect(hWnd, NULL, TRUE);
    return 0;
   case WM_PAINT:
      char szTxt[16];
      hdc=BeginPaint(hWnd, &ps);
      font=CreateFont(60,0,0,0,0,0,0,0,HANGEUL_CHARSET,0,0,0,0,"돋움");
      oldfont=(HFONT)SelectObject(hdc,font);
      sprintf(szTxt, "%02d:%02d.%02d",min, sec, undercomma);
      TextOut(hdc, 20, 40, szTxt, strlen(szTxt));
      SelectObject(hdc,oldfont);
      DeleteObject(font);
      EndPaint(hWnd, &ps);
    return 0;
   case WM_COMMAND:
    switch(LOWORD(wParam)) {
    case 0:  // START button clicked
       min = 0;
       sec = 0;
     undercomma = 0;
       SetTimer(hWnd, 3355, 50, NULL);
       break;
    case 1:  // STOP button clicked
       KillTimer(hWnd, 3355);
       break;
    case 2:  // EXIT button clicked
       PostQuitMessage(0);
       break;
    }
    return 0;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   }
   return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}

댓글 없음:

댓글 쓰기