#include #include // sin() ja cos() HINSTANCE hInstance ; // käynnistyvän ohjelman kahva LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static char szAppName[] = "Kello" ; // 'ohjelman nimi' HWND hwnd ; MSG msg ; WNDCLASSEX wndclass ; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) COLOR_WINDOW ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ; hwnd = CreateWindow (szAppName, "Kello", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, hInstance, NULL) ; if (!SetTimer (hwnd, 1, 1000, NULL)) // Ajastimen varaus, toimii kerran sekunnissa { MessageBox (hwnd, "Ei vapaita ajastimia!", "Virhe", MB_ICONEXCLAMATION | MB_OK) ; return FALSE ; // ajastimet loppu, ohjelma lopetetaan } ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; // ikkunan päivitys while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HPEN hPen ; // luotavan kynän kahva static SYSTEMTIME aika ; // aika-struktuuriin tallennetaan kellonaika HDC hdc ; // piirtopinnan kahva PAINTSTRUCT ps ; // PAINTSTRUCT-struktuuria käytetään BeginPaint()-funktiossa RECT rect; // RECT-struktuuria käytetään GetClientRect()-funktiossa POINT pt ; // POINT-struktuuria käytetään LineTo()-funktiossa switch (iMsg) // sanomien käsittelyrakenne { case WM_CREATE : // initialisaatiosanoman käsittely hPen = CreatePen (PS_SOLID, 2, RGB(0, 0, 0)); // luodaan 2 pistettä paksu musta kynä return 0 ; // pois ikkunaproseduurista case WM_PAINT : { hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect); // kysytään ruudun koko ja talletetaan se rect-struktuuriin SelectObject (hdc, GetStockObject(BLACK_PEN)) ; //BLACK_PEN on musta varastokynä, piirretään sillä kellotaulu for (double x=0; x<6.2832; x=x+0.5236) // sin() ja cos() käyttävät radiaaneja, 6.2832 == 2*PI { MoveToEx (hdc, rect.right/2+int(sin(x)*rect.right*0.45), rect.bottom/2-int(cos(x)*rect.bottom*0.45), &pt) ; // Piirretään kellotaulu LineTo (hdc, rect.right/2+int(sin(x)*rect.right*0.4), rect.bottom/2-int(cos(x)*rect.bottom*0.4)) ; } SelectObject (hdc, hPen) ; //hPen on paksumpi kuin BLACK_PEN, piirretään sillä viisarit MoveToEx (hdc, rect.right/2, rect.bottom/2, &pt) ; // LineTo() vaatii pt-struuriin viivan alkupisteen LineTo (hdc, rect.right/2+int(sin(6.2832*aika.wSecond/60)*rect.right*0.34), rect.bottom/2-int(cos(6.2832*aika.wSecond/60)*rect.bottom*0.34)) ; // Sekunnit MoveToEx (hdc, rect.right/2, rect.bottom/2, &pt) ; LineTo (hdc, rect.right/2+int(sin(6.2832*aika.wMinute/60)*rect.right*0.3), rect.bottom/2-int(cos(6.2832*aika.wMinute/60)*rect.bottom*0.3)) ; // Minuutit MoveToEx (hdc, rect.right/2, rect.bottom/2, &pt) ; LineTo (hdc, rect.right/2+int(sin(6.2832*aika.wHour/12)*rect.right*0.25), rect.bottom/2-int(cos(6.2832*aika.wHour/12)*rect.bottom*0.25)) ; // Tunnit EndPaint (hwnd, &ps) ; return 0; } case WM_TIMER : GetLocalTime (&aika) ; // haetaan kellonaika aika-struktuuriin InvalidateRect(hwnd, NULL, TRUE); // asetetaan koko ikkuna epäkelvoksi, Windows generoi WM_PAINT sanoman return 0 ; case WM_DESTROY : // lopetussanoman käsittely KillTimer (hwnd, 1) ; // poistetaan Timer käytöstä ennen lopetusta, ei tuhlaa resursseja DeleteObject (hPen) ; // poistetaan luotu kynä, ei tuhlata resursseja PostQuitMessage (0) ; // lopetusviesti Windowsille return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; // sanomien oletuskäsittely }