MFC tehtäviä syventävät vastaus3
Mureakuha
Tehtävä:
Kirjoita kello. Piirrä kellotaulu ja viisarit LineTo()-funktiolla. Varaa kerran sekunnissa toimiva Timer-kontrolli ja kutsu sieltä WM_PAINT sanomaa, jolloin Windows itse pyyhkii vanhat viisarit pois. Ohjelman täytyy osata skaalata viisarit oikean kokoisiksi riippumatta ikkunan koosta. Kellotaulun ympyrämuodon kaava voidaan laskea sin()- ja cos()-funktioilla. Kun origo on vasemmassa yläkulmassa, kaavan koordinaatit ovat muotoa,
- Keskipiste: ikkunan_leveys/2-ikkunan_korkeus/2
- X-koordinaatti: ikkunan_leveys/2+sin(x)*haluttu_etäisyys_keskipisteestä
- Y-koordinaatti: ikkunan_korkeus/2-cos(x)*haluttu_etäisyys_keskipisteestä
jossa x on haluttu kulma radiaaneissa (00:00 on nolla ja 12:00 on 2*PII radiaania).
[muokkaa]
CPP
//*********************************************************************** // // kello.cpp // //*********************************************************************** #include <afxwin.h> #include <math.h> // sin() ja cos() #include "kello.h" CMyApp myApp; ///////////////////////////////////////////////////////////////////////// // CMyApp luokan aliohjelmien toteutus BOOL CMyApp::InitInstance () { m_pMainWnd = new CMainWindow; m_pMainWnd->ShowWindow (m_nCmdShow); m_pMainWnd->UpdateWindow (); return TRUE; } ///////////////////////////////////////////////////////////////////////// // CMainWindow luokan aliohjelmien toteutus BEGIN_MESSAGE_MAP (CMainWindow, CWnd) ON_WM_CREATE () // lomakkeen luominen ON_WM_PAINT () // lomakkeen piirtäminen ON_WM_SIZE () // lomakkeen koon muutos ON_WM_TIMER () // ajastintapahtuma ON_WM_CLOSE () // lopetustapahtuma END_MESSAGE_MAP () CMainWindow::CMainWindow () { CString strWndClass = AfxRegisterWndClass ( NULL, // ikkunan tyyli myApp.LoadStandardCursor (IDC_ARROW), // ikkunan kursori (HBRUSH) COLOR_WINDOW, // ikkunan taustan väri myApp.LoadStandardIcon (IDI_APPLICATION) // ikkunan ikoni ); // rekisteröi oman ikkunaluokan CreateEx ( NULL, // lomakkeen lisätyyli strWndClass, // lomakkeen ikkunaluokka "Kello", // lomakkeen otsikko WS_OVERLAPPEDWINDOW, // ikkunan tyyli CW_USEDEFAULT, // aloitus x-positio CW_USEDEFAULT, // aloitus y-positio 300, // alkuleveys 300, // alkukorkeus NULL, // emoikkunan kahva NULL, // lomakkeen valikon kahva NULL // lisätietoja ); // lomakkeen luominen } int CMainWindow::OnCreate () // lomakkeen luomistapahtuma { if (!SetTimer (1, 1000, NULL)) // Ajastimen varaus, toimii kerran sekunnissa { MessageBox ("Ei vapaita ajastimia!", "Virhe", MB_ICONEXCLAMATION | MB_OK) ; return -1 ; // ajastimet loppu, ohjelma keskeytyy } return 0; // kaikki hyvin, 0 palautuu } void CMainWindow::OnPaint () // lomakkeen piirtotapahtuma { CTime aika = CTime::GetCurrentTime (); // hakee systeemin kellonajan CPen sininenkyna (PS_SOLID, 2, RGB(0, 0, 128)); // luo tummansinisen kynän CRect rect; GetClientRect (&rect); // lomakkeen koko tallentuu rect-olioon CPaintDC dc (this); // luo piirtopintaolion dc.SelectStockObject (BLACK_PEN); //BLACK_PEN on musta varastokynä, ohjelma piirtää sillä kellotaulun for (double x=0; x<6.2832; x=x+0.5236) // sin() ja cos() käyttävät radiaaneja, 6.2832 == 2*PI { dc.MoveTo (rect.right/2+int(sin(x)*rect.right*0.45), rect.bottom/2-int(cos(x)*rect.bottom*0.45)); // piirtää kellotaulun dc.LineTo (rect.right/2+int(sin(x)*rect.right*0.4), rect.bottom/2-int(cos(x)*rect.bottom*0.4)); } dc.SelectObject (sininenkyna) ; //sininenkyna on paksumpi kuin BLACK_PEN, ohjelma piirtää sillä viisarit dc.MoveTo (rect.right/2, rect.bottom/2); // määrittää LineTo()-funktiota varten alkupisteen dc.LineTo (rect.right/2+int(sin(6.2832*aika.GetSecond ()/60)*rect.right*0.34), rect.bottom/2-int(cos(6.2832*aika.GetSecond ()/60)*rect.bottom*0.34)); // sekunnit dc.MoveTo (rect.right/2, rect.bottom/2); dc.LineTo (rect.right/2+int(sin(6.2832*aika.GetMinute ()/60)*rect.right*0.3), rect.bottom/2-int(cos(6.2832*aika.GetMinute ()/60)*rect.bottom*0.3)); // minuutit dc.MoveTo (rect.right/2, rect.bottom/2); dc.LineTo (rect.right/2+int(sin(6.2832*aika.GetHour ()/12)*rect.right*0.25), rect.bottom/2-int(cos(6.2832*aika.GetHour ()/12)*rect.bottom*0.25)); // tunnit } void CMainWindow::OnSize () // lomakkeen koonmuutostapahtuma { InvalidateRgn (NULL, TRUE); // asettaa koko ikkunan epäkelvoksi, Windows generoi WM_PAINT sanoman } void CMainWindow::OnTimer () // ajastintapahtuma { InvalidateRgn (NULL, TRUE); // asettaa koko ikkunan epäkelvoksi, Windows generoi WM_PAINT sanoman } void CMainWindow::OnClose () // lopetustapahtuma { KillTimer (1); // poistaa Timer:n käytöstä ennen lopetusta, ei tuhlaa resursseja CWnd::OnClose (); // lopettaa ohjeman }
[muokkaa]
H
//*********************************************************************** // // kello.h // //*********************************************************************** class CMyApp : public CWinApp // CMyApp periytetään MFC:n ohjelma-yliluokasta { public: // aliohjelmajäsenten esittely virtual BOOL InitInstance (); // ohjelman instanssin initialisaatio }; class CMainWindow : public CWnd // CMainWindow periytetään MFC:n ikkuna-yliluokasta { public: // aliohjelmajäsenten esittely CMainWindow (); // ikkunan luontialiohjelma protected: // aliohjelmajäsenten esittely afx_msg int OnCreate (); // luomisaliohjelma afx_msg void OnPaint (); // piirtoaliohjelma afx_msg void OnTimer (); // ajastintapahtuma afx_msg void OnClose (); // lopetustapahtuma afx_msg void OnSize (); // lomakkeen koon muutos DECLARE_MESSAGE_MAP () // MESSAGE MAP:n esittely };
Tämän dokumentin kopiointi, levittäminen sekä muokkaaminen on sallittua GNU Free Documentation Licensen version 1.2 tai uudemman Free Software Foundationin julkaiseman version mukaisesti, ilman muuttumattomuuslauseketta tai kansitekstejä. Tätä koskee vastuuvapaus.
Kopio lisenssistä (englanniksi) löytyy täältä.
Kopio lisenssistä (englanniksi) löytyy täältä.
Alkuperäinen (c) Petteri Hämäläinen
