/**************/ /* vaihtaj3.c */ /**************************************************************************** PROGRAM: vaihtaj3.c PURPOSE: Vaihtaa rahaa ja matkoja Ohjelmalla esitellään omatekoisten dialog boxien käyttöä. Pääikkuna tekee vain menun, jolla voidaan valita mikä dialog box tulee aktiiviseksi Skaalausvaihtajan oletusikkunana on luonnosta mitattu matka. Painamalla ENTER (IDOK) päästään aina tähän ikkunaan. Kun ikkunaan tullaan, valitaan koko ikkunassa oleva teksti, jotta uuden syöttäminen olisi helpompaa. Ikkunoiden toimintajärjestys on valittu Resource Workshopissa toiminnolla Options - Set order. Ikkunat ovat käytettävissä yhtäaikaa jos ne on luotu Modeless. Modeless-dialogien on käyttöön omat aliohjelmat, jotka tallettavat kaikki käyttöön otetut modeless dialogit. Modeless tai Modal dialogi valitaan kutsun perusteella DoModelessDialog tai DoModalDialog. Itse dialogit voivat olla samoja, mikäli ne lopetetaan kutsuun DestroyDialog. Scaling dialogista on hukattu pois staattiset muuttujat, ja näin sitä voidaan käyttää useita esiintymiä yhtäaikaa. Tähän malliin on lisätty myös esimerkki ohjelman kääntämisestä kieleltä toiselle (lisäykset merkitty t ) PROJECT: vaihtaj3.c vaihtaja.rc vaihtaja.def mdialog.c transdlg.c language.c mjonot.c TEHTÄVIÄ: 1) Täydennä rahanvaihto-toiminto valmiiksi. 2) Muuta ohjelmaa siten, että aina kun mittakaavadialogi käynnistetään, käytetään sen edelliseltä kerralta jääneitä arvoja (mittakaava, muunnos, map-matka, yksiköt) 3) Kielen vaihtaminen ei ulotu yksiköihin. Miten korjaisit asian? 4) Muuta muunnos-ohjelma yleiseksi siten, että sitä ohjataan seuraavan näköisellä VAIHTAJA.INI-tiedostolla. Tiedoston lukemisen jälkeen menu muuttuu sen mukaan montako [Change?] sektiota saatiin luettua. ;------------------------------------------------------------------------------ [Change0] title = Mittakaavamuunnos menu = &Scaling help = Muuta mittakaavaksi 1:1 jos haluat tehdä yksikkömuunnoksia from = &Kartalla to = &Luonnossa scale = &Mittakaava ; yksikkö kerroin lisäys do0 = mm, 1.0 , 0 do1 = cm, 10.0 , 0 ...jne.. do17= lentopinta, 30400.8 , 0 [Change1] title = Rahanvaihto menu = &Money Change from = &Mistä to = M&ihin do0 = mk, 1.0 , 0 do1 = $ , 4.68 , 0 ...jne... [Change2] title = Lämpötilan muunnos menu = &Temperature from = &Mistä to = M&ihin do0 = C , 1.0 , 0 do1 = K , 1.0 , -273.1 ...jne... ;------------------------------------------------------------------------------ Editor: Vesa Lappalainen 13.7.1993 ****************************************************************************/ #include /* Tarvitaan kaikissa Windows C-ohjelmissa */ #include #include #include #include "vaihtaja.h" #include "mdialog.h" #include "transdlg.h" /* t */ #define WCLASSNAME "WMultiWClass" /***************************************************************************/ BOOL CALLBACK_E About(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam) { #pragma argsused switch (message) { case WM_INITDIALOG: TranslateDialog(hDlg,0); /* t */ return (TRUE); case WM_COMMAND: if ( wParam == IDOK || wParam == IDCANCEL ) { DestroyDialog(hDlg,TRUE); return (TRUE); } break; } return (FALSE); } static char s[100]; /***************************************************************************/ double GetDouble(HWND hDlg,WPARAM id) { double d=0; GetDlgItemText(hDlg,id,s,sizeof(s)); sscanf(s,"%lf",&d); return d; } /***************************************************************************/ void ShowDouble(HWND hDlg,WPARAM id,double d) { double ad,old_d = GetDouble(hDlg,id); ad = fabs(d); if ( fabs(old_d) > ad ) ad = fabs(old_d); if ( fabs(d -old_d) <= ad*0.0000001 ) return; /* Suht virhe isompaan */ sprintf(s,"%-0.9lg",d); SetDlgItemText(hDlg,id,s); } /***************************************************************************/ double dmax(double a, double b) /* Ei makrona, koska tällöin laskut tulee moneen kertaan! */ { return ( a > b ? a : b ); } /***************************************************************************/ typedef struct { char *unit; double mm; } unit_type; static unit_type units[] = { { "mm", 1.0 }, { "cm", 10.0 }, { "dm", 100.0 }, { "m", 1000.0 }, { "km", 1000000.0 }, { "inch", 25.4 }, { "ft", 304.8 }, { "yard", 914.4 }, { "mile", 1609300.0 }, { "NM", 1853200.0 }, { "tuuma(s)", 24.742 }, { "kortteli", 148.45 }, { "jalka(s)", 296.9 }, { "kyynärä", 593.8 }, { "syli", 1781.4 }, { "virsta", 1068800.0 }, { "peninkulma", 10688000.0 }, { "lentopinta", 30400.8 }, { NULL , 0.0 } }; #define MM 0 #define KM 4 #define DO_SHOW_OUT 1991 #define DO_SHOW_MAP 1992 /***************************************************************************/ BOOL do_command(HWND hDlg,WPARAM wParam) { SendMessage(hDlg,WM_COMMAND,wParam,0); return TRUE; } /***************************************************************************/ BOOL CALLBACK_E Scaling(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam) { #pragma argsused #define map_unit ( (int)SendDlgItemMessage(hDlg,ID_MAP_UNIT,CB_GETCURSEL,0,0) ) #define map_dist GetDouble(hDlg,ID_MAP_DIST) #define out_unit ( (int)SendDlgItemMessage(hDlg,ID_OUT_UNIT,CB_GETCURSEL,0,0) ) #define out_dist GetDouble(hDlg,ID_OUT_DIST) #define scale dmax(GetDouble(hDlg,ID_SCALE),1) #define change_other SendDlgItemMessage(hDlg,IDR_OTHER,BM_GETCHECK,0,0) int i; switch (message) { case WM_PAINT: return FALSE; case WM_INITDIALOG: for (i=0; units[i].unit; i++) { /* Täytetään combo-listat */ SendDlgItemMessage(hDlg,ID_MAP_UNIT,CB_INSERTSTRING,i, (LPARAM) ((LPSTR)units[i].unit)); SendDlgItemMessage(hDlg,ID_OUT_UNIT,CB_INSERTSTRING,i, (LPARAM) ((LPSTR)units[i].unit)); } TranslateDialog(hDlg,0); SendDlgItemMessage(hDlg,ID_MAP_UNIT,CB_SETCURSEL,MM,0); /* oletus yks */ SendDlgItemMessage(hDlg,ID_OUT_UNIT,CB_SETCURSEL,KM,0); /* oletus yks */ SendDlgItemMessage(hDlg,IDR_OTHER,BM_SETCHECK,TRUE,0); /* oletus muut */ ShowDouble(hDlg,ID_SCALE,200000.0); ShowDouble(hDlg,ID_MAP_DIST,10.0); ShowDouble(hDlg,ID_OUT_DIST,2.0); return (TRUE); case WM_COMMAND: switch ( wParam ) { case DO_SHOW_OUT: ShowDouble(hDlg,ID_OUT_DIST, map_dist*units[map_unit].mm*scale/units[out_unit].mm); return TRUE; case DO_SHOW_MAP: ShowDouble(hDlg,ID_MAP_DIST, out_dist/(units[map_unit].mm*scale/units[out_unit].mm)); return TRUE; case ID_SCALE: if ( HIWORD(lParam) == EN_CHANGE ) { ShowDouble(hDlg,ID_SCALE,scale); return do_command(hDlg,DO_SHOW_OUT); } break; case ID_MAP_DIST: if ( HIWORD(lParam) == EN_CHANGE ) return do_command(hDlg,DO_SHOW_OUT); break; case ID_OUT_DIST: if ( HIWORD(lParam) == EN_CHANGE ) return do_command(hDlg,DO_SHOW_MAP); break; case ID_MAP_UNIT: if ( HIWORD(lParam) == CBN_SELCHANGE ) { if ( change_other ) return do_command(hDlg,DO_SHOW_OUT); return do_command(hDlg,DO_SHOW_MAP); } break; case ID_OUT_UNIT: if ( HIWORD(lParam) == CBN_SELCHANGE ) { if ( change_other ) return do_command(hDlg,DO_SHOW_MAP); return do_command(hDlg,DO_SHOW_OUT); } break; case IDR_THIS: return TRUE; case IDR_OTHER: return FALSE; case IDOK: SetFocus(GetDlgItem(hDlg,ID_MAP_DIST)); SendDlgItemMessage(hDlg,ID_MAP_DIST,EM_SETSEL,0,MAKELONG(0,-1)); return TRUE; case IDCANCEL: DestroyDialog(hDlg,1); return (TRUE); default: break; } break; } return (FALSE); } /***************************************************************************/ BOOL CALLBACK_E Money(HWND hDlg,unsigned message,WPARAM wParam,LPARAM lParam) { #pragma argsused switch (message) { case WM_INITDIALOG: TranslateDialog(hDlg,0); /* t */ return (TRUE); case WM_COMMAND: if ( wParam == IDOK || wParam == IDCANCEL ) { DestroyDialog(hDlg,1); return (TRUE); } break; } return (FALSE); } /***************************************************************************/ LRESULT CALLBACK_E MainWndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) { char *viesti = T("Valitse menusta ohjelma!"); PAINTSTRUCT ps; switch (message) { case WM_PAINT: /* Viesti: Piirrä ikkuna uudelleen */ if ( BeginPaint(hWnd,&ps) ) TextOut(ps.hdc, 10, 10, viesti,strlen(viesti)); EndPaint(hWnd,&ps); return (NULL); case WM_DESTROY: /* Viesti: ikkuna hävitetään */ free_translate(); /* t */ PostQuitMessage(0); return (NULL); case WM_COMMAND: switch (wParam) { case IDM_FILE_EXIT: SendMessage(hWnd,WM_DESTROY,0,0); return NULL; case IDM_APP_SCALING: return (LRESULT)DoMultiModelessDialog(hWnd,"SCALING",Scaling); case IDM_APP_MONEY: return (LRESULT)DoModelessDialog(hWnd,"CHANGE",Money); case IDM_HELP_ABOUT: return (LRESULT)DoModalDialog(hWnd,"About",About); case IDM_ENGLISH: /* t */ if ( language() == 1 ) return NULL; read_translate("vaihtaja.tra",1); TranslateDialog(hWnd,0); set_language(1); InvalidateRect(hWnd,NULL,TRUE); return NULL; case IDM_FINNISH: /* t */ TranslateDialog(hWnd,1); set_language(0); InvalidateRect(hWnd,NULL,TRUE); return NULL; default: break; } break; default: /* Antaa Windowsin käsitellä muut */ break; } return (DefWindowProc(hWnd, message, wParam, lParam)); } /***************************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow) { #pragma argsused WNDCLASS wc; /* Ikkunaluokka */ HWND hWnd; /* Pääikkunan kahva */ MSG msg; /* Viesti */ 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(hInstance, "Ikoni"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(GRAY_BRUSH); wc.lpszMenuName = "MAINMENU"; wc.lpszClassName = WCLASSNAME; if (!RegisterClass(&wc)) return (FALSE); } hWnd = CreateWindow(WCLASSNAME,"Vaihtaja",WS_OVERLAPPEDWINDOW, 20,20,400,400, NULL,NULL,hInstance,NULL); if (!hWnd) return (FALSE); ShowWindow(hWnd, nCmdShow); /* Näytetään ikkuna */ UpdateWindow(hWnd); /* Lähetetään WM_PAINT viesti */ while (GetMessage(&msg,NULL,NULL,NULL)) { if ( IsModelessMessage(&msg) ) continue; TranslateMessage(&msg); /* Tulkitaan virtuaaliset näp. koodit */ DispatchMessage(&msg); /* Lähetetään viesti ikkunalle */ } FreeAllModeless(); return (msg.wParam); /* Palautetaan PostQuitMessage-funktion arvo */ }