/****************************************************************************/ /* ** Aliohjelmakirjasto nappuloiden ja laskureiden piirtämiseksi näytölle. ** ** Kutsuvassa ohjelmassa määritellään taulukko näppäimistä ja ** taulukko laskureista. ** ** Näppäimen painamista joko näppäimistöltä tai hiireltä odotetaan ** aliohjelmalla 'lue_komento'. Aliohjelma palauttaa valittua ** komentoa vastaavan tunnuksen. Tunnukset on määritelty ** käyttäjän ohjelmassa. Negatiiviset tunnukset on varattu ** systeemikäyttöön ja käyttäjän ohjelman on reagoitava myös niihin. ** Esim. mikäli palautetaan komento PIIRRA, pitää käyttäjän piirtää ** koko näyttö uudelleen (koska joku on sen sotkenut). ** ** Nappulan tai laskurin vasenpaan yläkulmaan tarttumalla voidaan ** laatikon paikkaa näytöllä siirtää. ** Oikeasta alakulmasta voidaan laatikon kokoa muuttaa. */ /****************************************************************************/ #include #include #include #include #include #include #include "nappula3.h" /****************************************************************************/ #define SKAALAA_XY \ x = (int)(((long int)x - MIN_H_X) * ( MAX_X - MIN_X + 1) /\ ( MAX_H_X - MIN_H_X +1 ) + MIN_X);\ y = (int)(((long int)y - MIN_H_Y) * ( MAX_Y - MIN_Y + 1) /\ ( MAX_H_Y - MIN_H_Y +1 ) + MIN_Y); #define scale_x(x) ((int)(((long int)x - MIN_X) * SCALE_FACTOR_X + MIN_H_X)) #define scale_y(y) ((int)(((long int)y - MIN_Y) * SCALE_FACTOR_Y + MIN_H_Y)) #define R4(r,dr) r.left-dr,r.top-dr,r.right+dr,r.bottom+dr #define MainWClass "CounterClass" static int lisaviesti = 0; static int paaviesti = EI_KOMENTOA; static HWND hWnd; static HANDLE Hinstance; static MSG msg; static nappain_tyyppi *nappaimet = NULL; static laskuri_tyyppi *laskurit = NULL; static SCALE_FACTOR_X = ( MAX_H_X - MIN_H_X + 1) / ( MAX_X - MIN_X +1 ); static SCALE_FACTOR_Y = ( MAX_H_Y - MIN_H_Y + 1) / ( MAX_Y - MIN_Y +1 ); static XW_MIN = 0; #define BLACK RGB(0,0,0) #define BLUE RGB(0,0,255) #define CYAN RGB(0,255,255) #define YELLOW RGB(255,255,0) /****************************************************************************/ int /* 0 koord. ei laatikossa */ laatikossa( /* 1 koord on laatikossa */ laatikko_tyyppi *tila, int x, int y ) { if ( tila->vasen_yla.x > x ) return 0; if ( tila->vasen_yla.y > y ) return 0; if ( tila->vasen_yla.x + tila->koko.x <= x ) return 0; if ( tila->vasen_yla.y + tila->koko.y <= y ) return 0; return 1; } /****************************************************************************/ int /* -1 jollei hiiri minkään napin koh */ tutki_hiiri( /* napin numero, jonka kohdalla hiiri*/ nappain_tyyppi *nappaimet, laskuri_tyyppi *laskurit, int x, int y ) { int i; if ( laskurit ); for (i=0; nappaimet[i].valinta_kirjain; i++) { if ( laatikossa(&nappaimet[i].nappain,x,y) ) return i; #if 0 if ( siirtokulmassa(&nappaimet[i].nappain,x,y) ) { piirra_nappula(&nappaimet[i]); return siirra_laatikkoa(&nappaimet[i].nappain); } if ( muutoskulmassa(&nappaimet[i].nappain,x,y) ) { piirra_nappula(&nappaimet[i]); return muuta_laatikkoa(&nappaimet[i].nappain); } #endif } #if 0 for (i=0; laskurit[i].tunnus; i++) { if ( siirtokulmassa(&laskurit[i].tila,x,y) ) { piirra_laskuri(&laskurit[i]); return siirra_laatikkoa(&laskurit[i].tila); } if ( muutoskulmassa(&laskurit[i].tila,x,y) ) { piirra_laskuri(&laskurit[i]); return muuta_laatikkoa(&laskurit[i].tila); } } #endif return -1; } /****************************************************************************/ int lue_komento( /* */ nappain_tyyppi *pnappaimet, laskuri_tyyppi *plaskurit, int *lisa ) /* ** Funktio palauttaa valitun komennon tunnuksen ja mahdollisen lisäviestin. ** Funktiosta palataan vasta kun oikeata näppäintä on painettu. ** Mikäli näppäintä ei ole painettu, tutkitaan onko hiirikursori jonkin ** näppäimen kuvan päällä. Jos on, palautetaan tämä tieto. ** Tämä aliohjelma sytyttää ja sammuttaa hiirikursorin, joten muualla ** ohjelmassa hiirestä ei tarvitse tietää muutakuin alustaa se kerran. */ { /* Seuraava toimii mm. Turbo C:ssä: */ char c; int i; *lisa = 0; nappaimet = pnappaimet; laskurit = plaskurit; paaviesti = EI_KOMENTOA; while ( paaviesti == EI_KOMENTOA ) { if (!GetMessage(&msg,NULL,NULL,NULL)) return SYS_EXIT; TranslateMessage(&msg); /* Tulkitaan virtuaaliset näp. koodit */ DispatchMessage(&msg); /* Lähetetään viesti ikkunalle */ } palauta: if ( i < 0 ) return i; /* Systeemikomento! */ *lisa = lisaviesti; return paaviesti; } /****************************************************************************/ void piirra_laatikko(laatikko_tyyppi *tila, char *st, COLORREF color) { HDC hDC; DWORD dw; RECT nelio; HBRUSH hbrOld; HBRUSH hbr; int i,x,y,x_lev,y_kork; if ( ( hDC = GetDC(hWnd) ) == NULL ) return; /* x = tila->vasen_yla.x; y = tila->vasen_yla.y; */ x_lev = tila->koko.x; y_kork = tila->koko.y; if ( !tila->muutettu ) { /* Muutetaan tilan tiedot laitekoordinaatteihin */ dw = GetTextExtent(hDC,st,strlen(st)); if ( x_lev == 0 ) { x_lev = max(LOWORD(dw),XW_MIN); tila->koko.x = x_lev; } else tila->koko.x = ( x_lev *= SCALE_FACTOR_X ); if ( y_kork == 0 ) { y_kork = HIWORD(dw); tila->koko.y = y_kork; } else tila->koko.y = ( y_kork *= SCALE_FACTOR_Y ); tila->vasen_yla.x = scale_x(tila->vasen_yla.x); tila->vasen_yla.y = scale_y(tila->vasen_yla.y); tila->muutettu = 1; } if ( ( x_lev < 0 ) || ( y_kork < 0 ) ) return; /*----------------------------------------------------------------*/ /* Maalataan ikkunan sisus taustavärillä: */ nelio.left = tila->vasen_yla.x; nelio.top = tila->vasen_yla.y; nelio.right = tila->vasen_yla.x+x_lev; nelio.bottom = tila->vasen_yla.y+y_kork; hbr = CreateSolidBrush(color); hbrOld = SelectObject(hDC, hbr); Rectangle(hDC,R4(nelio,4)); Rectangle(hDC,R4(nelio,2)); /* FillRect(hDC,&nelio,hbr); */ SelectObject(hDC,hbrOld); DeleteObject(hbr); ReleaseDC(hWnd,hDC); } /****************************************************************************/ void tulosta_jono_laatikkoon( laatikko_tyyppi *tila, char *st, COLORREF tcolor, COLORREF bcolor, UINT textalign ) { HDC hDC; char s[200]; int kork,x,y; kork = tila->koko.y; x = tila->vasen_yla.x; /* Keskitetään y-suunta: */ y = tila->vasen_yla.y; if ( kork > SCALE_FACTOR_Y ) y += kork/2 - SCALE_FACTOR_Y; if ( ( hDC = GetDC(hWnd) ) == NULL ) return; SetTextColor(hDC,tcolor); SetBkColor(hDC,bcolor); SetTextAlign(hDC, textalign); if ( textalign == TA_CENTER ) x += tila->koko.x/2; if ( textalign == TA_RIGHT ) x += tila->koko.x; TextOut(hDC,x,y,st,strlen(st)); ReleaseDC(hWnd,hDC); } /****************************************************************************/ void nayta_laskuri(laskuri_tyyppi *laskuri) { char s[200]; sprintf(s,laskuri->format,laskuri->arvo); tulosta_jono_laatikkoon(&laskuri->tila,s,BLACK,CYAN,TA_RIGHT); } /****************************************************************************/ void piirra_nappula(nappain_tyyppi *nappula) { piirra_laatikko(&nappula->nappain,nappula->teksti,YELLOW); tulosta_jono_laatikkoon(&nappula->nappain,nappula->teksti,BLACK,YELLOW,TA_CENTER); } /****************************************************************************/ void piirra_laskuri(laskuri_tyyppi *laskuri) { piirra_laatikko(&laskuri->tila,"X",CYAN); nayta_laskuri(laskuri); } /****************************************************************************/ void nollaa_laskurit(laskuri_tyyppi *laskurit) { int i; for (i=0; laskurit[i].tunnus; i++) { laskurit[i].arvo=0; piirra_laskuri(&laskurit[i]); } } /****************************************************************************/ void lisaa_laskuria(laskuri_tyyppi *laskurit,int tunnus) { int i; for (i=0; laskurit[i].tunnus; i++) { /* Ets. laskuri */ if ( laskurit[i].tunnus == tunnus ) { laskurit[i].arvo++; nayta_laskuri(&laskurit[i]); return; } } } /****************************************************************************/ void alusta_nappulat(nappain_tyyppi *pnappulat) { HDC hDC; DWORD dw; if ( ( hDC = GetDC(hWnd) ) == NULL ) return; dw = GetTextExtent(hDC,"X",1); SCALE_FACTOR_X = LOWORD(dw); SCALE_FACTOR_Y = HIWORD(dw); dw = GetTextExtent(hDC,"M",1); XW_MIN = LOWORD(dw); ReleaseDC(hWnd,hDC); nappaimet = pnappulat; } /****************************************************************************/ void tyhjenna_ruutu(void) { /* UpdateWindow(hWnd); */ } /****************************************************************************/ LONG FAR PASCAL MainWndProc(HWND hWnd, unsigned message, WORD wParam, LONG lParam) { HDC hDC; char c; int i; switch (message) { case WM_CHAR: /*KEYDOWN: */ c = toupper(wParam); for (i=0; nappaimet[i].valinta_kirjain; i++) if ( nappaimet[i].valinta_kirjain == c ) { paaviesti = nappaimet[i].komento; lisaviesti = nappaimet[i].lisa_viesti; break; } return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_LBUTTONDOWN: if ( ( i = tutki_hiiri(nappaimet,laskurit,LOWORD(lParam),HIWORD(lParam)) ) != EI_KOMENTOA ) { paaviesti = nappaimet[i].komento; lisaviesti = nappaimet[i].lisa_viesti; } return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_PAINT: /* Viesti: Piirrä ikkuna uudelleen */ paaviesti = PIIRRA; return (DefWindowProc(hWnd, message, wParam, lParam)); case WM_DESTROY: /* Viesti: ikkuna hävitetään */ PostQuitMessage(0); break; default: /* Antaa Windowsin käsitellä muut */ return (DefWindowProc(hWnd, message, wParam, lParam)); } return (NULL); } int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; /* Ikkunaluokka */ if (lpCmdLine); /* Hämäystä, jottei valitusta param. käytt. */ if (!hPrevInstance) { /* Onko muita esiintymiä käynnisssä? */ wc.style = NULL; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = MainWClass; if (!RegisterClass(&wc)) return (FALSE); } hWnd = CreateWindow(MainWClass,"Windows Laskuri",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); if (!hWnd) return (FALSE); ShowWindow(hWnd, nCmdShow); /* Näytetään ikkuna */ laskin_main(); return (msg.wParam); /* Palautetaan PostQuitMessage-funktion arvo */ }