/**************/ /* timeman.c */ /****************************************************************************/ /* ** Malliohjelma "animaatiosta": ** Tikku-ukko osoittaa oikealla kädellään missä hiiri menee. ** ** Käyttö: Tee projekti time_man.prj jossa on: ** show_man.c ** simplet.def ** ALI\tabhand.h ** ja aja. ** ** Vesa Lappalainen 15.8.1992 & 3.9.1994 ** ** Animaation idea: ** 1. kuva on piirretty valmiiksi ** 2. kun jotakin osaa kuvasta pitää siirtää, pyyhitään vanha osa pois ** 3. lasketaan osan uusi paikka ja/tai muoto ** 4. piirretään uudistettu osa ** ** "Rautalankamallissa" pyyhkiminen käy siten, että piirretään ** kuvan osa kynällä, joka muuttaa kaikki pisteet päinvastaisen ** värisiksi (mm. musta piste muuttuu valkoiseksi ja päinvastoin). ** Kun tällaisella kynällä piirretään kaksi kertaa sama kuva, ei ** tuloksena olekaan mitään, siis joka toisella kerralla kuva häviää. ** ** Monimutkaisemmassa tapauksessa kuvan osan alla oleva taustakuva ** pitää ensin tallettaa ja sitten piirtää vasta kuvan osa. ** Siirrossa tausta palautetaan ja luetaan uusi tausta uudesta ** paikasta ja sitten piirretään uusi osa. ** ** Animaatio: ** ========== ** Tehtäviä: 1) Ukolla on seuraava vika: ** - käynnistä ukko-ohjelma ** - aktivoi jokin pieni ikkuna, esim. WinCD ** - siirrä ko. pieni ikkuna ukon vartalon oikealle puolelle ** - odota kunnes kellon mukana liikkuva käsi kiertyy ** tämän pikkuikkunan alle ** - aktivoi ukkoikkuna ennenkuin käsi tulee pikkuikkunan ** takaa näkyviin ** Mistä vika johtuu? Miten vika voitaisiin korjata? ** (Vian syytä voit tutkia asettamalla vakion TUTKI_VIESTIT ** 1:ksi, jolloin näet viestien saapumisjärjestyksen.) ----------------------------------------------------------------------------*/ #include #include #include #include "tabhand.h" /***************************************************************************/ TblClassSWindowMAIN("ShowmanClass",0,"Näyttäjä-ukko",MsgTbl,0); /***************************************************************************/ typedef struct { int pituus; double suunta; POINT alku; } kasi_tyyppi; #define RAD(d) ((d)*M_PI/180.0) static kasi_tyyppi Oikea = { 80, 0.0, {60,90} }; /****************************************************************************/ #define POINT_TO_2(pt) pt.x,pt.y /* Pisteestä 2 erillistä lukua */ #define POINT_PLUS_RA(pt,r,a) \ pt.x+r*cos(a)+0.5,pt.y-r*sin(a)+0.5 /* Piste + r*suunta */ /****************************************************************************/ static void PiirraKasi(HDC hdc,kasi_tyyppi *kasi) /* Piirretään ukon kasi. */ { MoveToEx(hdc,POINT_TO_2(kasi->alku),NULL); LineTo(hdc,POINT_PLUS_RA(kasi->alku,kasi->pituus,kasi->suunta)); } /****************************************************************************/ static void PiirraNotKasi(HDC hdc,kasi_tyyppi *kasi) /* Piirretään ukon kasi NOT-kynällä. */ { int oldROP = SetROP2(hdc,R2_NOT); PiirraKasi(hdc,kasi); SetROP2(hdc,oldROP); } /****************************************************************************/ static int muuta_kaden_suunta(HDC hDC, LONG lParam, kasi_tyyppi *kasi) { int dx,dy; POINTS pt = MAKEPOINTS(lParam); PiirraNotKasi(hDC,kasi); /* Pyyhitään vanha kasi pois */ dx = pt.x - kasi->alku.x; dy = pt.y - kasi->alku.y; if ( dx || dy ) kasi->suunta = atan2(-dy,dx); else kasi->suunta=0; PiirraNotKasi(hDC,kasi); /* Piirretään uusi kasi tilalle */ return 1; } /****************************************************************************/ static EVENT WM_paint(tMSGParam *msg) /* # MAKE_DC # */ { HBRUSH hBrRed,vanha; hBrRed = CreateSolidBrush(RGB(255,0,0)); vanha = SelectObject(msg->hDC,hBrRed); Ellipse(msg->hDC,40,40,80,80); /* Pää */ SelectObject(msg->hDC,vanha); DeleteObject(hBrRed); MoveToEx(msg->hDC, 60, 80,NULL); LineTo( msg->hDC, 60,180); /* Keskivartalo */ LineTo( msg->hDC, 20,260); /* Vasen jalka */ MoveToEx(msg->hDC, 60,180,NULL); LineTo( msg->hDC,100,260); /* Oikea jalka */ MoveToEx(msg->hDC, 20,170,NULL); LineTo( msg->hDC, 60, 90); /* Vasen käsi */ PiirraNotKasi(msg->hDC,&Oikea); /* Oikea käsi */ return 0; } /****************************************************************************/ static EVENT WM_mousemove(tMSGParam *msg) /* # MAKE_DC # */ /* Aliohjelmaa kutsutaan kun hiiri on liikkunut */ { muuta_kaden_suunta(msg->hDC,msg->lParam,&Oikea); 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_MOUSEMOVE , DoC , DoC , WM_mousemove, MAKE_DC }, /*a*/ { WM_CREATE , DoC , DoC , WM_create }, /*a*/ { 0 } }; /****************************************************************************/