/**************/ /* laskurm5.c */ /**************************************************************************** ** PROGRAM: laskurm5.c ** PURPOSE: Autolaskuri tehtynä mahd. pitkälle Windowsin resursseilla. ** Kuten laskurm4 mutta: ** ** Yritys tehdä dialogista tavallinen ikkuna. ** Onnistuu, mutta dialogin ominaisuudet menevät, eli ** alleviivatut näppäimet eivät enää toimi eikä TAB. ** Jos viestisilmukassa on IsDialogMessage ** niin ominaisuudet toimivat TAB-näppäimen painamisen ** jälkeen(?). Kuitenkin tällöin menujakaan ei voi ** valita ennenkuin TAB on painettu! ** Vian korjaamiseksi tarvitaan ikkunafunktioon muutos! ** TAI: Ikkunafunktio lopetetaan oletustapauksessa ** kutsuun DefDlgProg, niin kaikki näyttäisi toimivan ** Lisäys VL/29.7.1994 ** Paitsi ei tule WM_INITDIALOG-viestiä!!! ** Kaikeihn paras: ** Luodaan ikkunaluokka ja sen funktioksi laitetaan ** DefDlgProc ja dialogille annetaan tämä luokka ja ** dialogille tehdään normaali dialogin funktio. ** Tällöin kaikki toimii normaalisti! ** Lisäys VL/20.8.1994 ** ** Editor: Vesa Lappalainen ** Projektiin tarvitaan ** laskurm5.c - tämä tiedosto ** laskurm5.def - moduulin määrittely ** laskurm5.rc - resurssit dialogissa luokka "Laskuriluokka" ** ..\menu4\tiedleik.c - tiedostot ja leikekirjan käsittely ** ..\menu4\kieli.c - eri kielisten menujen käyttö ** ALI\autot.c - autojen liikuttelu näytöllä ** ALI\filename.c - tiedoston nimen yms. käsittely ** ALI\clipboard.c - leikekirjan käsittely ** ALI\tausta.c - ikonin ja taustan piirto ** ALI\mjonot.c - merkkijonojen käsittely ** ** Tehtäviä: 1) Kokeile eri ehdollisia käännöksiä kommentoimalla ** #define-lauseita. Katso onko tulos sama kuin ** alla olevassa taulukossa. ** ** ****************************************************************************/ /* Ehdolliset käännökset: */ #define LUOKKA /* rekist. laskuriluokka, muuten luominen ei onnistu */ #define DEFDLG /* käytetään ikkunafuktiossa DefDlgProc-kutsua */ //#define IKKUNA /* ikkuna luodaan ikkuna, ei dialogina -> ei nappuloita */ //#define DLGMSG /* viestisilmukkaan tulee IsDialogMessage */ #define DLGMSG2 /* viestisilmukkaan tulee IsDialogMessage Accel jälk. */ //#define FOCUS /* Käytetään kutsua muuttuuko focus */ #define DLGPRO /* Tehdään myös DialogProc */ #define JUSTDEF /* Pääfunktio tekee vain oletuskäsittelyn */ /**************************************************************************** ** Tutkimus: ** FOC = toimii kun jollekin nappulalle saatu focus ** eli 1. TAB-painamisen jälkeen tai 1. hiirellä napin ** painamisen jälkeen ** lakkaa toimimasta jos millään nappulalla ei ole ** focusta eli vaikkapa jonkin dialogin jälkeen. ** x = vastaava #define käytössä L = #define LUOKKA jne... ** Accel = toimiiko Acceleraattorit ** Hiiri = toimiiko kaikki näkyvissä olevat toiminnot hiirellä ** esim. Menut toimii aina hiirellä ** Menut = toimiiko Menut näppäimistöltä ** Alt- = Toimiiko nappuloiden Alt- lyhenteet ** ESC = Lopettaako ESC dialogin ** ** L D I D D2 F D J ** u e k L L o p u ** o f k G G c o s Näyttö Accel Hiiri Menut Alt- ESC muuta ** --------------------------------------------------------------------------------- ** ? ? ? ? ei ? ? ? ? ? ei mitään näyt. ** x dialogi OK OK OK EI EI ** x x dialogi FOC OK FOC FOC OK ** x x dialogi OK OK FOC FOC OK ** x x ikkuna OK OK OK EI EI ei nappuloita ** x x x ikkuna EI OK FOC EI OK - " - ** x x x ikkuna OK OK FOC EI OK - " - ** x x x dialogi OK OK OK OK OK ** x x x dialogi OK OK OK OK OK ** x x dialogi OK OK OK EI EI ** x x x dialogi OK OK OK OK OK ei INIT_DLG ** x x x x dialogi OK OK OK OK OK kaikki OK ** --------------------------------------------------------------------------------- ** ** Päätelmät: ** Ilman lisähommia ei Alt-näppäimiä ja menuja saada luottettavasti ** toimimaan. Ongelma on siinä, että jos Focus on dialogilla, eikä ** millään sen nappulalla, jää Alt-käsittelemättä. Homma voidaan ** korjata siten, ettei dialogille huolita focusta, vaan se ** työnnetään aina jollekin dialogin lapselle. ** TAI kutsutaan ikkunafunktion lopuksi DefDlgProc ** ** ( Tämä homma on kasattu aliohjelmaan "MuuttuukoFocus" ** Tällöin ei ole väliä kummallako puolella lyhenteiden käsittelyä ** IsDialogMessage-on. ) ** ** "Oikea yhditelmä" jos halutaan Alt-lyhenteet: ** 0. Tee .RC-tiedostoon dialogi, jolle ilmoitat haluamasi luokan ** 1. rekisteröi luokka, joka mainittu .RC -tiedostossa, luokan ** funktioksi DefDlgProc ** 2. luo ikkuna CreateDialog-kutsulla ** 3. laita IsDialogMessage ennen kutsua TranslateAccelerator ** 4. kirjoita dialogin funktio ** ** ** ** Mielipiteet: ** + ikoni saadaan hoidettua automaattisesti ** + taustan väri voidaan hoitaa luokan luonnin yhteydessä ** + kursori voidaan muuttaa luokan luonnin yhteydessä ** + luokan ikkunoille voidaan laittaa lisätavuja ja kuljettaa ** tietoa niissä. ** (-) Alt-lyhennettä ei saa oikein toimimaan automaattisesti ** jollei käytä DefDlgProc ** ****************************************************************************/ #include /* Tarvitaan kaikissa Windows C-ohjelmissa */ #include #include #include "filename.h" #include "autot.h" #include "..\menu4\kieli.h" #include "tausta.h" #include "..\menu4\laskurm4.h" int laskurit[LASKUREITA] = {0,0}; static FileType File={ "", /* Tiedoston nimi, aluksi "" */ WTITLE, /* Ikkunan otsikko, jonka perään tied.nimi */ 1, /* Luetun funktion tyyppi, ks. szFilter */ "Laskuri (*.las)\0*.las\0Teksti (*.txt)\0*.txt\0Kaikki (*.*)\0*.*\0", 0, /* Onko tiedostoa muutettu. */ MySave, /* Osoitin talletusfunktioon */ MyRead, /* Osoitin lukufunktioon */ MyNew, /* Osoitin tiedon nollausfunktioon */ laskurit /* Osoitin varsinaiseen dataan. */ }; #ifdef FOCUS /***************************************************************************/ BOOL MuuttuukoFocus(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) /* Tutkitaan onko focus muuttumassa. Näin voidaan korjata dialogi */ /* toimimaan kun annetaan aina focus jollekin nappulalle. */ { #pragma argsused static HWND Focus = 0; switch (message) { case WM_SETFOCUS: /* Jos dialogi meinaa saada focuksen, annetaan pois */ if ( !Focus ) Focus=GetWindow(hWnd,GW_CHILD); SetFocus(Focus); return TRUE; case WM_ACTIVATE: /* Kun dialogi men. aktiivisuutensa jemmataan kellä */ if ( wParam == WA_INACTIVE ) Focus = GetFocus(); /* oli focus ennen */ return TRUE; } return FALSE; } #endif /***************************************************************************/ LRESULT GDlgWndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) /* Dialogin funktio on muutettu tavalliseksi funktioksi, jota kutsutaan */ /* tarpeen mukaan joko ikkunafunktiosta tai dialogin funktiosta. */ { #pragma argsused static int suunta = 1; HMENU hMenu; static char s[128]; if ( language_message(hWnd,message,wParam,lParam) ) return TRUE; # ifdef FOCUS MuuttuukoFocus(hWnd,message,wParam,lParam); /* Dialogi toimimaan! */ # endif /* FOCUS */ #include "lasswi5.c" /* Sama osa kuin switch-lause laskurm4.c:ssä, paitsi */ /* WM_PAINT -viestin käsittely puuttuu */ return FALSE; } /***************************************************************************/ BOOL CALLBACK_E DlgWndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) /* Välittäjäfunktio dialogin funktioksi */ { LRESULT ret = GDlgWndProc(hWnd,message,wParam,lParam); if ( ret ) return TRUE; return FALSE; } /***************************************************************************/ LRESULT CALLBACK_E MainWndProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam) /* Välittäjäfunkntio ikkunafunktioksi */ { #ifdef JUSTDEF LRESULT ret = GDlgWndProc(hWnd,message,wParam,lParam); if ( ret ) if ( ret == TRUE ) return NULL; else return ret; #endif #ifndef DEFDLG return DefWindowProc(hWnd,message,wParam,lParam); #else return DefDlgProc(hWnd,message,wParam,lParam); #endif } /***************************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #pragma argsused MSG msg; HWND hWndL; FARPROC lProc = MakeProcInstance((FARPROC)DlgWndProc,hInstance); /* Ei tarvi */ HACCEL hAccel = LoadAccelerators(hInstance,"PIKA"); AlustaTausta(hInstance,"TAUSTA"); #ifdef LUOKKA if (!hPrevInstance) { /* Onko muita esiintymiä käynnisssä? */ WNDCLASS wc; /* Ikkunaluokka */ wc.style = NULL; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, "Ikoni"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_GRAYTEXT; // wc.lpszMenuName = "kieli_0"; wc.lpszClassName = "Laskuriluokka"; // Laskuriluokka etsitään resursseista! wc.lpszMenuName = NULL; if (!RegisterClass(&wc)) return (FALSE); } #endif /* LUOKKA */ #ifdef IKKUNA hWndL = CreateWindow("Laskuriluokka","Windows Hello",WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,hInstance,NULL); #else /* EI IKKUNA, siis DIALOGI */ # ifdef DLGPRO hWndL = CreateDialog(hInstance,"Laskuri",NULL,(DLGPROC)lProc); # else hWndL = CreateDialog(hInstance,"Laskuri",NULL,NULL); # endif /* Jos edellä lProcin tilalla NULL, niin toimii koska käyttää */ /* aina luokan funktiota. Tämä oli väärä päätelmä: 20.8.94/vl*/ #endif /* IKKUNA */ if ( !hWndL ) goto lopetus; ShowWindow(hWndL,nCmdShow); AlustaMenut(hInstance,hWndL); while ( GetMessage(&msg,NULL,NULL,NULL) ) { # ifdef DLGMSG if ( IsDialogMessage(hWndL,&msg) ) continue; # endif if ( TranslateAccelerator(hWndL,hAccel,&msg) ) continue; # ifdef DLGMSG2 if ( IsDialogMessage(hWndL,&msg) ) continue; # endif TranslateMessage(&msg); /* Tulkitaan virtuaaliset näp. koodit */ DispatchMessage(&msg); /* Lähetetään viesti ikkunalle */ } PoistaMenut(); lopetus: PoistaTausta(); (void)FreeProcInstance(lProc); return 0; }