/**************/ /* kolmio.c */ /****************************************************************************/ /* ** Malliohjelma kauan kestävästä piirtämisestä. ** Piirretään rekursiivisesti joukko kolmioita. ** ** Vesa Lappalainen 16.8.1992 & 14.6.1994 ** ** Kääntäminen: ** Tee projekti kolmio.prj: ** kolmio.c ** simplet.def ** ALI\timer.c ** ALI\tabhand.c ** ** Tehtäviä 1) Kokeile piirtämisen aikana valita ikkunan suurennus tms. tai ** paina vaikkapa kahdesti (molemmat välillä irti) ALT-TAB. ** Säädä ohjelman suoritusaikaa muuttelemalla vakiota ** PIENIN_KOLMIO (pieni->kauan, iso-> nopea). ** Mikä vika on ohjelmassa? ** ** Käynnistä samanaikaisesti jokin toinen ohjelma ja säädä sen ** ikkunan niin pieneksi, ettei se peitä kuin osaksi "Kolmiot" ** ikkunaa. Laita sitten ikkunoiden järjestys siten, että ** "Kolmiot"-ikkuna on toiseksi ylin ja avaamasi pikku-ikkuna ** on ylimpänä. Siirtele pikkuikkunaa kolmiot ikkunan päällä! ** ** 2) Ohjelmaikkunan otsikkoksi muuttuu aika, jonka ikkunan uudelleen ** piirtäminen vei. Kokeile peittää ikkunaa eri tavoin toisella ** ikkunalla ja koeta keksiä syy, miksi uudelleen piirto vie ** eri ajan peiton suuruudesta riippuen. ** ** 3) Ohjelmaan liittyy myös "höpö-höpö"-piirtäminen. Miten luulet ** piirtämisen toimivan? Käy välillä toisessa ikkunassa ja ** palaa takaisin ohjelmaan. Mitä käy piirroksille? ** ** 4) Muuta "piirtäminen" sellaiseksi, että kun hiiren nappi ** painetaan alas, aletaan piirtämään viivaa kunnes ** nappi päästetään ylös. Mitä tapahtuu kun nappi ** päästetäänkin ylös "Kolmiot"-ikkunan ulkopuolella ja ** sitten tuodaan hiiri takaisin ikkunan sisälle nappi ** ylhäällä? ** ** 5) Miten "Piirtäminen" pitäisi muuttaa, jotta kuva korjautuisi ** toisessa ikkunassa käymisen jälkeen? ** ----------------------------------------------------------------------------*/ #include #include #include #include "timer.h" #include "tabhand.h" /***************************************************************************/ TblClassSWindowMAIN("TriangleClass",0,"Kolmio",MsgTbl,0); /***************************************************************************/ #define PIENIN_KOLMIO 20 /* Säädä tällä kauanko koko kuvan piirt. kest. */ #define I(x,y) hdc,((int)(x)),((int)(y)) /****************************************************************************/ void kolmio(HDC hdc, double x, double y, double h) { double s2 = h / (sqrt(3)); MoveToEx(I(x,y),NULL); LineTo(I(x-s2,y-h)); LineTo(I(x+s2,y-h)); LineTo(I(x,y)); if ( h < PIENIN_KOLMIO ) return; kolmio(hdc,x-s2,y,h/2); /* Pienempi kolmio vasemmalle */ kolmio(hdc,x+s2,y,h/2); /* Pienempi kolmio oikealle */ kolmio(hdc,x,y-h,h/2); /* Pienempi kolmio yläpuolelle*/ } /****************************************************************************/ static EVENT WM_paint(tMSGParam *msg) /* # MAKE_DC # */ { char s[100]; SetWindowText(msg->hWnd,"Kolmio: Piirretään..."); start_timer(1); kolmio(msg->hDC,300,400,200); sprintf(s,"Kolmio: %5.2lf s.",stop_timer(1)); SetWindowText(msg->hWnd,s); return NULL; } /****************************************************************************/ /* ** Seuraavissa aliohjelmissa on seuraavat parametrit: ** ** hWnd - ikkunan kahva ** wParam - SHIFT, CTRL ja ALT -näppäimen tile, voidaan testata esim. ** if ( wParam && MK_CONTROL ) ... hommat jos CTRL alhaalla ** lParam - x = LOWORD(lParam) ja y = HIWORD(lParam) ** kätevämpi on kuitenkin selvittää hiren paikka: ** POINTS pt = MAKEPOINTS(lParam) ** ----------------------------------------------------------------------------*/ static POINTS old = {0,0}; static pen_down = 0; /****************************************************************************/ static EVENT WM_lbuttondown(tMSGParam *msg) /* Aliohjelmaa kutsutaan kun hiiren nappa on painettu alas */ { old = MAKEPOINTS(msg->lParam); pen_down = 1; return 0; } /****************************************************************************/ static EVENT WM_lbuttonup(tMSGParam *msg) /* Aliohjelmaa kutsutaan kun hiiren nappi on päästetty ylös */ { #pragma argsused pen_down = 0; return 0; } /****************************************************************************/ static EVENT WM_mousemove(tMSGParam *msg) /* # MAKE_DC # */ /* Aliohjelmaa kutsutaan kun hiiri on liikkunut */ { POINTS pt = MAKEPOINTS(msg->lParam); if ( !pen_down ) return 0; MoveToEx(msg->hDC,old.x,old.y,NULL); LineTo(msg->hDC,pt.x,pt.y); return 0; } /****************************************************************************/ static EVENT WM_create(tMSGParam *msg) /* Aliohjelmaa kutsutaan kun ikkuna on luotu, muttei vielä näytössä. */ { MoveWindow(msg->hWnd,10,10,600,500,FALSE); return 0; } /****************************************************************************/ /* Viestien käsittelytaulukko */ /****************************************************************************/ tMSGEntry MsgTbl[] = { EV_HANDLE_WM_DESTROY, { WM_PAINT , DoC , DoC , WM_paint, MAKE_DC }, /*a*/ { WM_LBUTTONDOWN , DoC , DoC , WM_lbuttondown }, /*a*/ { WM_LBUTTONUP , DoC , DoC , WM_lbuttonup }, /*a*/ { WM_MOUSEMOVE , DoC , DoC , WM_mousemove, MAKE_DC }, /*a*/ { WM_CREATE , DoC , DoC , WM_create }, /*a*/ { 0 } }; /****************************************************************************/