/**************/ /* laskinr.c */ /****************************************************************************/ /* ** Windows: Win 3.1 & Win 32 ** ** Alkeellinen taskulaskin. Laskimessa on kakasi 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 ** ** 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. ** ** 7) Muuta ohjelmaa siten, että menossa oleva operaatio ** näkyy näytössä. Voiko operaatiota vaihtaa? ** ** 8) 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" #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 ShowStatic(HWND hWnd, long value, int id) /* Aliohjelmalla tulostetaan Static ikkunaan id */ { char s[20]; HWND hsWnd = GetDlgItem(hWnd,id); wsprintf(s,"%ld ",value); SetWindowText(hsWnd,s); return TRUE; } static int nayta_laskuri(HWND hWnd,int indeksi) { return ShowStatic(hWnd,laskurit[indeksi],indeksi+EKA_LASKURI); } 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,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 TRUE; } /****************************************************************************/ #define DoC DONT_CARE WPARAM op_table[][2] = { /* 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 } }; TDIALOGPROC(MsgTbl,MainWndProc) /****************************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #pragma argsused MSG msg; HACCEL hAccel = LoadAccelerators(hInstance,"PIKA"); FARPROC lProc = MakeProcInstance((FARPROC)MainWndProc,hInstance); HWND hWnd = CreateDialog(hInstance,"LASKIN",NULL,(DLGPROC)lProc); if ( !hWnd ) goto lopetus; while (GetMessage(&msg,NULL,NULL,NULL)) { if ( TranslateAccelerator(hWnd,hAccel,&msg) ) continue; if ( IsDialogMessage(hWnd,&msg) ) continue; TranslateMessage(&msg); /* Tulkitaan virtuaaliset näp. koodit */ DispatchMessage(&msg); /* Lähetetään viesti ikkunalle */ } lopetus: FreeProcInstance(lProc); return 0; }