/**************/ /* laskinr.c */ /****************************************************************************/ /* ** Windows: Win 3.1 & Win 32 ** ** Alkeellinen taskulaskin. Laskimessa on kaksi näyttöä: ** - välitulos, johon näppäiltävä numero tulee ** - tulosl , johon tulee lskutoimituksen tähänastinen tulos ** "Oikeissa" ainoa näyttö toimii vuoronperään kumpanakin tämän laskimen ** näytöistä. ** ** Ohjelman kääntämiseksi tarvitaan projekti, jossa on: ** laskinr.c ** laskinr.def ** laskinr.rc ** ALI\tabhand.c ** ALI\mdialog.c ** ** Vesa Lappalainen ** 18.9.1992 & 11.7.1994 (taulukkoversio) ** ** Tehtäviä: 1) Laita jakolasku toimimaan. Mitä pitää myös muistaa? ** ** 2) Tee etumerkin vaihtonäppäin ja tarvittavat toiminnot. ** ** 3) Lisää esim. toiminto, jolla tulos-ikkunan arvo voidaan ** siirtää lisäysmääräksi ja lisäys (+1) nappulan painaminen ** lisää sitten välituloslaskuria aina tällä määrällä. ** ** 4) Lisää muita laskintoimintoja. ** ** 5) Muuta ohjelma sellaiseksi, ettei enumia operaatio_tyyppi ** tarvita lainkaan. ** ** 6) Muuta ohjelma sellaiseksi, ettei taulukkoa op_table ** tarvita lainkaan. Kerro ratkaisun hyvät ja huonot puolet! ** ** 7) Muuta ohjelmaa siten, että menossa oleva operaatio ** näkyy näytössä. Voiko operaatiota vaihtaa? ** ** 8) Muuta laskinta siten, että myös reaalilukuja voidaan ** laskea ja lisää näppäimistöön desimaalipiste. ** ** 9) Kirjoita ohjelmasta HP-laskinten tyylinen pinolaskin ** jossa näytössä näkyy 4 tulosta ja näytöt ** käyttäytyvät seuraavasti: ** ** näppäily: näytöt: X, Y , Z , T ** [clear all] 0 0 0 0 ** 1 1 0 0 0 ** 23 123 0 0 0 ** [Enter] 123 123 0 0 ** 1 1 123 0 0 ** 0 10 123 0 0 ** [+] 133 0 0 0 ** 4 4 133 0 0 ** ** Eli [Enter] pyöräyttää koko pinoa pykälän oikealle ** monistaen X rekisterin Y rekisteriin. ** ja operaatiot laskevat aina X ja Y rekisterin välillä ** pudottaen samalla pinoa se: X = XopY, Y = Z, Z = T ** Operaation jälkeen ensimmäinen numeron painallus ** kopioi T = Z, Z = Y, Y = X, ja rupeaa täyttämään uutta ** numero X:ään... ** */ /****************************************************************************/ #include /* Tarvitaan kaikissa Windows C-ohjelmissa */ #include "laskinr.h" #include "tabhand.h" #include "mdialog.h" /****************************************************************************/ TblDlgMAIN("PIKA","LASKIN",MsgTbl); /****************************************************************************/ #define LASKUREITA 2 #define EKA_LASKURI TULOS typedef enum { /* Tunnetut operaattorit: */ EI_OPER, PLUS, MIINUS, KERTO, JAKO, LASKE, TYHJENNA } operaatio_tyyppi; static long laskurit[LASKUREITA] = {0,0}; #define TULOSL 0 #define VALITULOSL 1 /****************************************************************************/ /* Apualiohjelmat: */ static int ShowStaticL(HWND hWnd, int id, long value) /* Aliohjelmalla tulostetaan Static ikkunaan id */ { char s[20]; wsprintf(s,"%ld ",value); SetDlgItemText(hWnd,id,s); return 0; } static int nayta_laskuri(HWND hWnd,int indeksi) { return ShowStaticL(hWnd,indeksi+EKA_LASKURI,laskurit[indeksi]); } static int lisaa_numero(HWND hWnd,int laskurin_indeksi, int nro) { laskurit[laskurin_indeksi] *= 10; laskurit[laskurin_indeksi] += nro; return nayta_laskuri(hWnd,laskurin_indeksi); } static int bs_numero(HWND hWnd,int laskurin_indeksi) { laskurit[laskurin_indeksi] /= 10; return nayta_laskuri(hWnd,laskurin_indeksi); } /****************************************************************************/ static int oper(HWND hWnd, int valitulos, int tulos, operaatio_tyyppi operaatio) { static operaatio_tyyppi edel_oper = EI_OPER; if ( operaatio == TYHJENNA ) edel_oper = TYHJENNA; switch (edel_oper) { case LASKE: if ( laskurit[valitulos] == 0 ) break; /* Ei aina break!*/ case EI_OPER: laskurit[tulos] = laskurit[valitulos]; break; case PLUS: laskurit[tulos] += laskurit[valitulos]; break; case KERTO: laskurit[tulos] *= laskurit[valitulos]; break; case MIINUS: laskurit[tulos] -= laskurit[valitulos]; break; case TYHJENNA: laskurit[tulos] = 0; operaatio = EI_OPER; break; } edel_oper = operaatio; laskurit[valitulos] = 0; nayta_laskuri(hWnd,valitulos); return nayta_laskuri(hWnd,tulos); } /****************************************************************************/ /* Käsittelyfunktiot: */ static LONG operaatio(tMSGParam *msg) { return oper(msg->hWnd,VALITULOSL,TULOSL,(operaatio_tyyppi)msg->extra); } static LONG lisaa_num(tMSGParam *msg) { return lisaa_numero(msg->hWnd,VALITULOSL,msg->id-N0); } static LONG lisaa_laskuria(tMSGParam *msg) { laskurit[VALITULOSL]++; return nayta_laskuri(msg->hWnd,VALITULOSL); } static LONG bs_num(tMSGParam *msg) { return bs_numero(msg->hWnd,VALITULOSL); } static LONG lopeta(tMSGParam *msg) { PostQuitMessage(msg->id); return 0; } /****************************************************************************/ static tMsgTTable op_table[] = { /* wParam -> extra */ { YNNAA , PLUS }, { VAHENNA , MIINUS }, { KERRO , KERTO }, { LASKETULOS , LASKE }, { NOLLAA , TYHJENNA }, { DoC,DoC } }; static tMSGEntry MsgTbl[] = { { WM_COMMAND , TRANGE , DoC, lisaa_num , 0 , 0, N0,N9}, { WM_COMMAND , P1 , DoC, lisaa_laskuria, 0 }, { WM_COMMAND , BS , DoC, bs_num , 0 }, { WM_COMMAND , TTABLE , DoC, operaatio , 0 , FROM_TBL, (LONG)op_table }, { WM_COMMAND , IDCANCEL, DoC, lopeta , 0 , 0}, { WM_COMMAND , EXIT , DoC, lopeta , 0 , 0}, { 0 } };