PÄÄTTÖTYÖ YKSINKERTAISEN C-KIELISEN GRAAFISEN KÄYTTÖLIITTYMÄN LUONTI

Samankaltaiset tiedostot
Windowsin sanomanvälitys. Juha Järvensivu 2007

Windowsin sanomanvälitys. Juha Järvensivu 2008

Winapi. Juha Järvensivu 2007

1 of

Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot. Tiedostot

OpenGL:n perusteet - Osa 1: Ikkunan luominen

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2008

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2007

Modulaarisessa ohjelmoinnissa jaetaan ohjelma osiin (moduuleihin), jotka ovat yksinkertaisia ja lyhyitä.

Graafisen käyttöliittymän ohjelmointi

Sen jälkeen Microsoft Office ja sen alta löytyy ohjelmat. Ensin käynnistä-valikosta kaikki ohjelmat

Loppukurssin järjestelyt

Loppukurssin järjestelyt C:n edistyneet piirteet

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Moduli 5: Kehittyneitä piirteitä

Jypelin käyttöohjeet» Ruutukentän luominen

// // whiledemov1.c // #include <stdio.h> int main(void){ int luku1 = -1; int luku2 = -1;

HELIA 1 (1) Outi Virkki Käyttöliittymät ja ohjelmiston suunnittelu :04

Ohjelmointiharjoituksia Arduino-ympäristössä

Toinen harjoitustyö. ASCII-grafiikkaa 2017

Tutoriaaliläsnäoloista

Pika-asennusohjeet Suomeksi

Toinen harjoitustyö. ASCII-grafiikkaa

int puts(char *buff) Kirjoittaa puskurissa buff \0 :lla päätetyn merkkijonon standarditulostukseen. Formatoitu konsoli-i/o Tiedostot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

Binäärioperaatiot Tiedostot ja I/O

Binäärioperaatiot Tiedostot ja I/O

Tekstinkäsittelyn jatko. KSAO Liiketalous 1

Java-kielen perusteet

TIETOKANNAT: MYSQL & POSTGRESQL Seminaarityö

Canva CV NÄIN PÄÄSET ALKUUN CANVA CV:N TEOSSA: Canva on graafisen suunnittelun

Ohjelmoinnin perusteet Y Python

Tiedosto on yhteenkuuluvien tietojen joukko, joka tavallisimmin sijaitsee kiintolevyllä, muistitikulla tai jollakin muulla fyysisellä tietovälineellä.

Ohjeet. AS C-ohjelmoinnin peruskurssi Aalto-yliopiston sahkotekniikan korkeakoulu Tentti , Raimo Nikkila

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

TIEA341 Funktio-ohjelmointi 1, kevät 2008

C-ohjelmointi, syksy 2006

C-ohjelmointi, syksy Yksiulotteiset taulukot Moniulotteiset taulukot Dynaamiset taulukot. Binääritiedostot. Luento

Tärkeimmät toiminnot. Kertausta ja uusia toimintoja Wordistä sekä tiedostonhallinnasta. Tärkeimmät toiminnot jatkuu...

C-kielessä taulukko on joukko peräkkäisiä muistipaikkoja, jotka kaikki pystyvät tallettamaan samaa tyyppiä olevaa tietoa.

MicroStation V8i-käyttöympäristö

IDL - proseduurit. ATK tähtitieteessä. IDL - proseduurit

Ohjelmassa henkilön etunimi ja sukunimi luetaan kahteen muuttujaan seuraavasti:

TAMK Ohjelmistotekniikka G Graafisten käyttöliittymien ohjelmointi Herkko Noponen Osmo Someroja. Harjoitustehtävä 2: Karttasovellus Kartta

ATK tähtitieteessä. Osa 3 - IDL proseduurit ja rakenteet. 18. syyskuuta 2014

Peliohjelmointirajapinnoista

Luennon sisältö. Taulukot (arrays) (Müldnerin kirjan luku 10) Yksiulotteiset taulukot. Mikä taulukko on? Taulukko-osoitin. tavallinen osoitin

Tietueet. Tietueiden määrittely

erasmartcard-kortinlukijaohjelmiston käyttöohje

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

ELM GROUP 04. Teemu Laakso Henrik Talarmo

Sonera Viestintäpalvelu VIP VIP Laajennettu raportointi Ohje

tään painetussa ja käsin kirjoitetussa materiaalissa usein pienillä kreikkalaisilla

Android ohjelmointi Tunti 5. SQLite, Cursor, Intent ja ADB

Käyttöliittymän muokkaus

Ensin klikkaa käynnistä-valikkoa ja sieltä Kaikki ohjelmat valikosta kaikki ohjelmat

Tietosuoja-portaali. päivittäjän ohje

Operaattoreiden ylikuormitus. Operaattoreiden kuormitus. Operaattoreiden kuormitus. Operaattoreista. Kuormituksesta


Sisällys. 1. Omat operaatiot. Yleistä operaatioista. Yleistä operaatioista

Symbol for Windows Blisskoostaja ( Versio 2.3 )

Java-kielen perusteet

Graafisen käyttöliittymän ohjelmointi

OpenGL:n perusteet - Osa 2: 3D grafiikka

12 Mallit (Templates)

Funktionimien kuormitus. TIES341 Funktio ohjelmointi 2 Kevät 2006

OHJE Jos Kelaimeen kirjautuminen ei onnistu Mac-koneella Sisällys

ICS-C2000 Tietojenkäsittelyteoria Kevät 2016

Ohjelmoinnin jatkokurssi, kurssikoe

Osoittimet ja taulukot

Sähköposti ja uutisryhmät

Ohjelmoinnin peruskurssien laaja oppimäärä

TYYLIT. Word Tyylit

GeoGebra-harjoituksia malu-opettajille

1 (14) Ohje. Ohje. GTK-wiki. Geologian tutkimuskeskus, Verkkosivustopalvelut

Matopeli C#:lla. Aram Abdulla Hassan. Ammattiopisto Tavastia. Opinnäytetyö

3. Binääripuu, Java-toteutus

Condes. Quick Start opas. Suunnistuksen ratamestariohjelmisto. Versio 7. Quick Start - opas Condes 7. olfellows 1.

1. HARJOITUS harjoitus3_korjaus.doc

C# Windows ohjelmointi perusopas

Tähtitieteen käytännön menetelmiä Kevät 2009 Luento 4: Ohjelmointi, skriptaus ja Python

Lyhyt kertaus osoittimista

Harjoitus 2: Oppijan aktivointi ( )

Koottu lause; { ja } -merkkien väliin kirjoitetut lauseet muodostavat lohkon, jonka sisällä lauseet suoritetaan peräkkäin.

Harjoitustyö: virtuaalikone

Harjoitus 3: Flash-komponenttiarkkitehtuuri ( )

Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö. Muistin käyttö C-ohjelmassa

Sisällys. 12. Näppäimistöltä lukeminen. Yleistä. Yleistä

1. Omat operaatiot 1.1

Verkkojulkaiseminen Minna Väisänen. HTML5-tehtävä

12. Näppäimistöltä lukeminen 12.1

UpdateIT 2010: Editorin käyttöohje

Ohjelmointi 1 Taulukot ja merkkijonot

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Integroidun maksupäätteen lisääminen käyttöönotossa

Muistitikun liittäminen tietokoneeseen

17. Javan omat luokat 17.1

Written by Administrator Monday, 05 September :14 - Last Updated Thursday, 23 February :36

Taulukot. Jukka Harju, Jukka Juslin

JAVA on ohjelmointikieli, mikä on kieliopiltaan hyvin samankaltainen, jopa identtinen mm. C++

Transkriptio:

OMNIA AMMATTIOPISTO PÄÄTTÖTYÖ YKSINKERTAISEN C-KIELISEN GRAAFISEN KÄYTTÖLIITTYMÄN LUONTI Nro 2010-SLE06L OMNIAN AMMATTIOPISTO KOULUTUSALA Sähkö, elektroniikka- ja tietoliikennetekniikka OPISKELIJA Riki Uusoksa OHJAAJA Erkki Viiala VUOSI 2010

3 OMNIAN AMMATTIOPISTO TIIVISTELMÄ Ala Sähköala Tekijä Riki Uusoksa Koulutusohjelma Elektroniikka ja tietoliikennetekniikka Työn nimi Yksinkertaisen C-kielisen graafisen käyttöliittymän luonti Sivumäärä 21 Työn nro 2010-SLE06L Vuosi 2010 Ohjaaja Erkki Viiala Työ sisältää johdannot C-kieleen ja graafisiin ympäristöihin, joiden jälkeen selvitän tavan luoda yksinkertaisen graafisen käyttöliittymän C-kielellä. Hakusana Ohjelmointi, C, grafiikka

4 SISÄLLYSLUETTELO Johdanto...4 1 Johdanto C-kieleen...5 1.1 C-kielen vaikuttajat ja mihin C-kieli on vaikuttanut...5 1.2 C-kielen toiminta...5-6 1.3 C-kielen standardikirjastot...6-7 2 Johdanto graafiseen ulkoasuun...7-8 2.1 Graafisen käyttöliittymän historia...8 3 Yksinkertaisen graafisen käyttöliittymän ohjelmointi C-kielellä WIN32 API-pohjalta...8 3.1 Ikkunan luominen...8-10 3.1.1 Window Classin rekisteröinti...10-11 3.1.2 Ikkunan luominen...11-12 3.1.3 Viesti-loop...12 3.1.4 Ikkunan ohjausprosessit...13 3.2 Ajonaikaisen menun luominen...13-15 3.3 Dialogi-ikkunat...15-18 3.3.1 Mooditon dialogi-ikkuna...18-19 3.4 Muokattava tekstikenttä...20 4 Lähteet...21

5 JOHDANTO Työn tarkoitus on johdattaa lukija C-kieleen ja graafisiin käyttöympäristöihin, jonka jälkeen esitän tavan jolla voit C-kielellä luoda yksinkertaisen graafisen käyttöliittymän.

6 1 JOHDANTO C-KIELEEN C on perustavanlaatuinen ohjelmointikieli joka kehitettiin vuonna 1972 Dennis Ritchien toimesta käytettäväksi Unix-käyttöjärjestelmässä. Vaikka C kehitettiin järjestelmäohjelmointiin, sitä käytetään usein myös sovellusohjelmointiin. C on yksi yleisimmin käytetyistä ohjelmointikielistä ja on hyvin vähän järjestelmiä, joista C-kääntäjää ei löydy. 1.1 C-KIELEN VAIKUTTAJAT JA MIHIN C-KIELI ON VAIKUTTANUT C-kieli on ottanut vaikutteita esimerkiksi semmoisista ohjelmointikielistä kuin B (BCPL, CPL), ALGOL 68, Assembly, PL/I, FORTRAN ja itse vaikuttanut senkaltaisten ohjelmointikielien syntyyn kuin AWK, csh, C++, C--, C#, Objective-C, BitC, D, Go, Java, JavaScript, Limbo, Perl, PHP, Pike, Processing ja Python. 1.2 C-KIELEN TOIMINTA C on proseduraalinen järjestelmätoteutuksiin tarkoitettu kieli. Se luotiin käännettäväksi suhteellisen yksinkertaisella kääntäjällä, jolla mahdollistetaan matalan tason muistinkäyttö, kielirakenteet jotka kartoittavat tehokkaasti laitteen antamat ohjeet ja joka vaatii minimaalisen määrän suoritustukea. (kts. ohjelman kirjoittamisen jälkeistä tukea c-kääntäjältä) Huolimatta sen matalan tason mahdollisuuksista, kieli tarkoitettiin rohkaisemaan järjestelmäriippumatonta ohjelmointia. C-kielen standardisoidut kirjastot mahdollistavat käytön laajassa valikoimassa laitteistoja ja käyttöjärjestelmiä vaatien vähän tai olemattoman määrän muutoksia sen lähdekoodiin. Kieltä käytetään nykyään melkein kaikkialla, sulautetuista mikrokontrollereista supertietokoneisiin. C-kieli mahdollistaa osoitettujen objektien (kts. esim. muistiin tallennettujen laitehallintarekisterien) helpon ja suoran käytön. C-kieli myös mahdollistaa argumenttien osoittamisen (esim. int p; joka tekee argumentista p int-tyyppisen muuttujan.) C-kieli tukee suurta määrää operaattoreita, jotka ovat symboleja joita käytetään lausekkeessa määrittelemään suoritteet arvioidessa kyseistä lauseketta. C käsittää operaattorit: * aritmaattiset (+, -, *, /, %)

7 * samanarvoisuuden testaus (==,!=) * arvosuhteet (<, <=, >, >=) * Boolean loogiset (!, &&, ) * bittiloogiset (~, &,, ^) * bittien siirrot (<<, >>) * tehtävät (=, +=, -=, *=, /=, %=, &=, =, ^=, <<=, >>=) * lisäys ja vähennys (++, --) * suhteellisuus ja vertaus (&, *, [ ]) * määrittelyn arviointi (? :) * jäsenvalinta (., ->) * tyyppimuunnos (( )) * objektin koko (sizeof) * function argumenttien kokoelma (( )) * listaaminen (,) * lausekkeen jäsentely (( )) C:llä on muodolline C-standardin mukainen kielirakenne. 1.3 C-KIELEN STANDARDIKIRJASTOT, SEKÄ YLEISIMMIN KÄYTETYT EI-STANDARDIT KIRJASTOT JA NIIDEN SISÄLTÄMÄT FUNKTIOT assert.h assert-makro complex.h cabs, cacos, cacosh, carg, casin, casinh, catan, catanh, ccos, ccosh, cexp, cimag, cis, clog, conj, cpow, cproj, creal, csin, csinh, csqrt, ctan, ctanh ctype.h digittoint, isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, toascii, tolower, toupper errno.h, float.h, iso646.h, limits.h ei funktioita inttypes.h imaxabs, imaxdiv, strtoimax, strtoumax, wcstoimax, wcstoumax locale.h localeconv, setlocale math.h acos, asin, atan, atan2, atof, ceil, cos, cosh, exp, fabs, floor, frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh netdb.h getaddrinfo, getnameinfo

8 setjmp.h longjmp, setjmp signal.h raise stdarg.h va_arg, va_copy, va_end, va_start-makrot stddef.h offsetof-makro stdio.h clearer, fclose, feof, ferror, fflush, fgetc, fgetpos, fgets, fopen (myös freopen, fdopen), printf (myös fprintf, sprintf, snprintf), fputc, fputs, fread, fscanf, fseek, fsetpos, ftell, fwrite, getc-makro, getchar-makro, gets, perror, putc-makro, putchar ja fputchar-makrot, puts, remove, rename, rewind, scanf (myös fscanf, sscanf, vfscanf, vscanf, vsscanf), setbuf, setvbuf, tmpfile, tmpnam, ungetc, vprintf (myös vfprintf, vsprintf) stdlib.h abort, abs (myös labs), atexit, atof, atoi, atol, bsearch, div (myös ldiv), exit, free, itoa, getenv, ltoa, malloc (myös calloc, realloc), qsort, rand, srand, strtod, strtol, strtoul, system string.h memchr, memcmp, memcpy, memmove, memset, strcat (myös strncat), strchr, strcmp (myös strncmp), strcoll, strcpy (myös strncopy), strcspn, sterror, strlen, strpbrk, strrchar, strspn, strstr, strtok, strxfrm time.h asctime, clock, ctime, difftime, gmtime, localtime, mktime, strftime, time alloc.h farmalloc conio.h getch, getche, gotoxy 2 JOHDANTO GRAAFISEEN ULKOASUUN Graafisella ulkoasulla viitataan käyttöliittymään, joka antaa käyttäjälleen mahdollisuuden ohjata sovelluksia muillakin tavoin kuin tekstikomennoilla kuten tietokoneissa, mp3-soittimissa, pelikonsoleissa ja kodinkoneissa. Informaation ja käyttömahdollisuuksien ilmoittamiseen graafinen käyttöliittymä tarjoaa graafisia ikoneita ja visuaalisia ohjastuksia (painikkeita yms.) tekstipohjaisen

9 liittymän komento-ohjauksien ja tekstipohjaisen navigoinnin sijaan. Tapahtumat suoritetaan yleensä graafisten elementtien suoralla manipuloinnilla. 2.1 GRAAFISEN KÄYTTÖLIITTYMÄN HISTORIA Graafisten käyttöliittymien edeltäjä kehitettiin Stanford Research Instituutin tutkijoiden toimesta, joita johti Douglas Engelbart. He kehittivät tekstipohjaisten hyperlinkkien käytön hiirellä ohjattavaksi NLS:ää varten. Hyperlinkkien käsite jalostettiin ja laajennettiin käsittämään grafiikoita Xerox PARCin tutkijoiden toimesta, jotka tekstipohjaisten hyperlinkkien sijaan käyttivät graafista pohjaa pääasiallisena käyttöliittymänä Xerox Alto tietokoneessa. Useimmat nykyiset peruskäyttöön tarkoitetut graafiset käyttöliittymät perustuvat tähän systeemiin. Tästä johtuen jotkut kutsuvat tämäntyylistä käyttöliittymää PARC User Interfaceksi (PUI) yleisemmin käytetyn Graphical User Interface (GUI) sijaan. Ivan Sutherland kehitti Sketchpadiksi kutsutun osoitinpohjaisen systeemin 1963. Se käytti valokynää ohjaamaan rakennuspiirrosten objektien luomista ja manipulaatiota. Xerox Star Workstation esitteli ensimmäisen GUI-käyttöliittymän vuonna 1981. 3 YKSINKERTAISEN GRAAFISEN KÄYTTÖLIITTYMÄN OHJELMOINTI C- KIELELLÄ WIN32 API-POHJALTA 3.1 IKKUNAN LUOMINEN #include <windows.h>

const char g_szclassname[] = "mywindowclass"; (tallettaa Window Class nimen) //3.1.4: Ikkunan ohjausprosessit LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) switch(msg) case WM_CLOSE: DestroyWindow(hwnd); case WM_DESTROY: PostQuitMessage(0); default: return DefWindowProc(hwnd, msg, wparam, lparam); return 0; int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) WNDCLASSEX wc; HWND hwnd; MSG Msg; //3.1.1: Window Classin rekisteröinti wc.cbsize = sizeof(wndclassex); wc.style = 0; wc.lpfnwndproc = WndProc; wc.cbclsextra = 0; wc.cbwndextra = 0; wc.hinstance = hinstance; wc.hicon = LoadIcon(NULL, IDI_APPLICATION); wc.hcursor = LoadCursor(NULL, IDC_ARROW); wc.hbrbackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszmenuname = NULL; wc.lpszclassname = g_szclassname; wc.hiconsm = LoadIcon(NULL, IDI_APPLICATION); if(!registerclassex(&wc)) MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION MB_OK); return 0; //3.1.2: Ikkunan luominen 10

11 hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szclassname, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hinstance, NULL); if(hwnd == NULL) MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION MB_OK); return 0; ShowWindow(hwnd, ncmdshow); UpdateWindow(hwnd); //3.1.3: Viesti-loop while(getmessage(&msg, NULL, 0, 0) > 0) TranslateMessage(&Msg); DispatchMessage(&Msg); return Msg.wParam; 3.1.1 WINDOW CLASSIN REKISTERÖINTI Window Class säilyttää tiedot ikkunan tyypistä, sisältäen sen ohjausprosessit jotka kontrolloivat ikkunaa, pienet ja suuret ikonit ikkunalle ja taustavärin. Tällä tavoin voit rekisteröidä classin kerran, ja luoda niin monta samanlaista ikkunaa kuin vain haluat, ilman että sinun tarvitsee eritellä nämä attribuutit uudelleen ja uudelleen. Ne voi myös vaihtaa ikkunakohtaisesti jos näin haluat. Rakenteen jäsenet jotka vaikuttavat Window Classiin ovat seuraavat: cbsize Rakenteen koko. style

12 Class Styles (CS_*), ei tule sekoittaa Window Styles (WS_*) kanssa. Voi yleensä asettaa arvon 0. lpfnwndproc Ikkunan ohjausprosessin osoitin tälle Window Classille. cbclsextra Määrä ekstradataa, joka muistista asetetaan sivuun tätä Classia varten. Yleensä 0 cbwndextra Määrä ekstradataa, joka muistista asetetaan sivuun tämän tyyppistä ikkunaa varten. Yleensä 0. hinstance Handle (älykäs osoitin, abstrakti referenssi jota toinen systeemi ohjaa) toiseen ohjelmaan, jonka saimme WinMain()ensimmäisessä parametrissa. hicon Suuri, yleensä 32x32 ikoni, joka näytetään käyttäjän painaessa Alt+Tab. hcursor Kursori, joka näytetään ikkunamme yllä. hbrbackground Asettaa ikkunamme taustavärin. lpszmenuname Menu-resurssin nimi jota käytetään tämän Classin ikkunoille. lpszclassname Nimi, jolla Classimme tunnistetaan hiconsm Pieni, yleensä 16x16 ikoni, joka näytetään tehtäväpalkissa ja ikkunamme vasemmassa ylänurkassa. 3.1.2 IKKUNAN LUOMINEN Kun Class on rekisteröity, voimme luoda sillä ikkunan. Ensimmäinen parametric (WS_EX_CLIENTEDGE) on jatkettu ikkunan tyyli. Tässä esimerkissä se on asetettu antamaan upotettu sisempi reunus ikkunalle. Seuraavaksi meillä on Classin nimi (g_szclassname). Tämä kertoo systeemille minkäkaltaisen ikkunan haluamme luoda. Koska halusimme luoda ikkunan

13 rekisteröimästämme tyylistä, käytimme sen Classin nimeä. Tämän jälkeen meillä tulee ikkunan nimi ( the title of my window ) WS_OVERLAPPEDWINDOW on Window Style parametri. Näitä on monia erilaisia. Seuraavat neljä parametria (CW_USEDEFAULT, CW_USEDEFAULT, 320,240) ovat X ja Y koordinaatit ikkunamme vasemmalle ylänurkalle sekä ikkunamme leveys ja korkeus. CW_USEDEFAULT sallii Windowsin määrätä mihin se asettaa ikkunan. Ikkunan leveys kasvaa vasemmalta oikealle ja korkeus ylhäältä alas. Yksiköt ovat pikseleitä. Seuraavaksi (NULL, NULL, g_hinst, NULL) meillä on isäntäikkunan Handle, menun Handle, toisen ohjelman Handle ja osoitin ikkunan luomisen dataan. Windowsissa ikkunat ovat järjestetty Isäntä- ja lapsi-ikkuna hierarkiaan. Kun näet ikkunassa nappulan, se on Lapsi ja se on asetettu sen Isäntäikkunan sisään. Esimerkissämme Isäntä-handle on NULL, sillä ikkunalla ei ole isäntää, vaan tämä on pääikkunamme. Menu on asetettu NULL, sillä meillä ei vielä ole sitä. Toisen ohjelman handle on asetettu siihen, jonka saamme WinMain() ensimmäisestä parametrista. Kun olemme luoneet ikkunan ja tarkistaneet että meillä on oikea Handle, näytämme ikkunan käyttämällä WinMain() viimeistä parametria ja sitten päivitämme sen varmistaaksemme että ikkuna on kunnolla piirtänyt itsensä näytölle. (ShowWindow(hwnd, ncmdshow); UpdateWindow(hwnd);) 3.1.3 VIESTI-LOOP Tämä on ohjelmasi sydän. Periaatteessa kaikki mitä ohjelmasi tekee käy tämän tarkistuspisteen kautta. GetMessage() ottaa viestin ohjelmasi viestijonosta. Joka kerran kun käyttäjä siirtää hiirtä, näppäilee näppäimistöä, klikkaa ikkunasi menua tai tekee mitä tahansa, systeemi luo viestejä ohjelmasi viestijonoon. Kutsumalla GetMessage(), pyydät seuraavan mahdollisen viestin poistettavaksi viestijonosta ja siirrettäväksi ohjelmallesi käsiteltäväksi. Jos viestejä ei ole jonossa, ohjelma odottaa GetMessage() funktiossa. TranslateMessage() suorittaa ylimääräistä prosessointia näppäimistön tapahtumista kuten mahdollistamalla WM_CHAR viestien toimimista WM_KEYDOWN viestien kanssa. Viimeiseksi, DispatchMessage() lähettää viestin ikkunalle jolle se lähettiin. Se voi olla pääikkunamme, joku toinen ikkuna, ohjain tai jossain tapauksissa ikkuna jonka systeemi tai toinen ohjelma loi kulissien taakse. Systeemi huolehtii viestien menemisestä perille oikeaan osoitteeseen.

14 3.1.4 IKKUNAN OHJAUSPROSESSIT Ohjausprosessit ovat ohjelmamme aivot. Täällä kaikki lähetetyt viestit prosessoituvat. Ohjausprosessit kutsutaan jokaiselle viestille erikseen. HWND parametri on kyseisen viestin kohdeikkunan handle. Tämä on tärkeä, sillä sinulla saattaa olla useita saman Classin ikkunoita jotka käyttävät samaa ohjausprosessia (WndProc()). Ero on siinä että parametri HWND on eri joka ikkunalle. Esimerkiksi lähettäessämme WM_CLOSE viestin, suljemme ikkunan. Koska käytämme ikkunan handlea, jonka saimme ensimmäisenä parametrina, muut ikkunat eivät sulkeudu, vaan vain se johon tarkoitimme WM_CLOSEn. WM_CLOSE lähetetään kun käyttäjä painaa Sulje-nappulaa tai näppäilee Alt-F4 Kutsuessamme DestroyWindow() systeemi lähettää viestin WM_DESTROY kyseiselle ikkunalle sulkien samalla kaikki jäljelle jääneet lapsi-ikkunat. Koska tämä on ohjelmamme ainoa ikkuna, olemme tämän jälkeen valmiit ja kutsumme PostQuitMessage(). Tämä lähettää WM_QUIT viestin viesti-looppiin ja lopettaa ohjelman. 3.2 AJONAIKAISEN MENUN LUOMINEN Voit koodiisi sisällyttää menun resursseista vaihtamalla Window Class määrittelyyn wc.lpszmenuname = MAKEINTRESOURCE(IDR_MYMENU); jossa IDR_MYMENU on kyseisen menuresurssin nimi. (.rc pääte) Tässä sen sijaan käsittelen ajonaikasta menua. Näin annamme WM_CREATE viestille Handlen ja lisäämme menun ikkunaamme #define ID_FILE_EXIT 9001 #define ID_STUFF_GO 9002 Aseta nämä kaksi IDtä.c-filesi huipulle, #include rivien alle. Seuraavaksi lisäämme WM_CREATE Handleemme seuraavan koodin: case WM_CREATE: HMENU hmenu, hsubmenu; HICON hicon, hiconsm; hmenu = CreateMenu(); hsubmenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit"); AppendMenu(hMenu, MF_STRING MF_POPUP, (UINT)hSubMenu, "&File"); hsubmenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&Go");

15 AppendMenu(hMenu, MF_STRING MF_POPUP, (UINT)hSubMenu, "&Stuff"); SetMenu(hwnd, hmenu); Tämä lisää yllä näkyvän kaltaisen menun ikkunaamme, ilman ikonia. Kyseinen menu on ajonaikainen, joten se lopetetaan automaattisesti kun ohjelma sulkeutuu. Nyt, kun meillä on menu, meidän tulee laittaa se tekemään jotain. Tämä on suhteellisen yksinkertaista, sillä meidän tulee vain asettaa WM_COMMAND viestille Handle ja tarkistaa mitä komentoja saamme menusta ja toimia sen mukaan. Tällä hetkellä WndProc() tulisi näyttää seuraavalta: LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) switch(message) case WM_CREATE: HMENU hmenu, hsubmenu; hmenu = CreateMenu(); hsubmenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_FILE_EXIT, "E&xit"); AppendMenu(hMenu, MF_STRING MF_POPUP, (UINT)hSubMenu, "&File"); hsubmenu = CreatePopupMenu(); AppendMenu(hSubMenu, MF_STRING, ID_STUFF_GO, "&Go"); AppendMenu(hMenu, MF_STRING MF_POPUP, (UINT)hSubMenu, "&Stuff"); SetMenu(hwnd, hmenu); case WM_COMMAND: switch(loword(wparam)) case ID_FILE_EXIT: case ID_STUFF_GO:

16 case WM_CLOSE: DestroyWindow(hwnd); case WM_DESTROY: PostQuitMessage(0); default: return DefWindowProc(hwnd, Message, wparam, lparam); return 0; Oletettavasti haluamme Exit valikon sulkevan ohjelman, joten WM_COMMAND,ID_FILE_EXIT Handlerissa voit seuraavalla koodilla saada sen aikaiseksi: PostMessage(hwnd, WM_CLOSE, 0, 0); WM_COMMAND Handlerisi tulisi nyt näyttää tältä: case WM_COMMAND: switch(loword(wparam)) case ID_FILE_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0); case ID_STUFF_GO: Tällä hetkellä ID_STUFF_GO ei tee mitään. 3.3 DIALOGI-IKKUNAT Ensimmäinen askel dialogi-ikkunoiden luomiseen on luoda dialogille resurssitiedosto. (.rc pääte) Tässä esimerkki sen sisällöstä: IDD_ABOUT DIALOG DISCARDABLE 0, 0, 239, 66 STYLE DS_MODALFRAME WS_POPUP WS_CAPTION WS_SYSMENU CAPTION "My About Box" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "&OK",IDOK,174,18,50,14 PUSHBUTTON "&Cancel",IDCANCEL,174,35,50,14 GROUPBOX "About this program...",idc_static,7,7,225,52 CTEXT "An example program showing how to use Dialog Boxes\r\n\r\nby theforger", IDC_STATIC,16,18,144,33 END

17 Ensimmäisellä rivillä IDD_ABOUTDLG on resurssin ID, DIALOG on resurssin tyyppi ja neljä seuraavaa numeroa (0, 0, 239, 66) ovat jo-käsitellyt koordinaatit ja koko, mutta dialogeissa ne ovat pikselien sijaan dialogi-yksiköitä, joiden koko perustuu käytettyyn fonttiin. Käyttäessäsi suurta fonttia, on dialogi-ikkuna suuri ja pientä fonttia käyttäessäsi on dialogi-ikkuna sen verran pienempi. Tämä on tärkeää, sillä se varmistaa, että kontrollisii ovat oikean kokoiset esittämään niiden sisältämän tekstin. DISCARDABLE kertoo systeemille, että se voi siirtää resurssimuistia levylle kun ohjelma ei ole käytössä, säästäen systeemin resursseja Toinen rivi alkaa STYLE ja sitä seuraa ikkunatyylit joita käytetään dialogin luomisessa. Käyttääksesi valmiiksi asetettuja tyylejä, joudut ehkä lisäämään #include "windows.h".rc tiedostoosi. Seuraavaksi meillä on lista kontrolleista, jotka luodaan dialogi-ikkunaan. DEFPUSHBUTTON "&OK",IDOK,174,18,50,14 Tämä rivi määrittelee OK-painikkeen. IDOK on painikkeen tunnistin. IDOK on valmiiksi määritelty, joten meidän ei tarvitse #define sitä itse. Neljä seuraavaa numeroa ovat taas koordinaatit, sekä leveys että pituus. Kaikki taas dialogiyksiköissä. Seuraavaksi meidän pitää kirjoittaa dialogille ohjausprosessi. Se on periaatteessa samankaltainen kuin ikkunan ohjausprosessi. BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) switch(message) case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch(loword(wparam)) case IDOK: EndDialog(hwnd, IDOK); case IDCANCEL: EndDialog(hwnd, IDCANCEL);

18 default: return FALSE; return TRUE; Dialogin ohjausprosessissa ja ikkunan ohjausprosessissa on muutamia tärkeitä eroavaisuuksia jotka tulee tietää. Ensimmäiseksi, et kutsu DefWindowProc() viesteille, joita et käsittele. Dialogeissa tämä tapahtuu automaattisesti. Toiseksi, yleensä palautat FALSE viesteille joita et prosessoi ja TRUE viesteille jotka prosessoit, ellei viesti erittele, että palautat jotain muuta. Kolmanneksi, et kutsu DestroyWindow()sulkemaan dialogia, vaan sen sijaan EndDialog(). Toinen parametri on arvo, joka palautetaan DialogBox() kutsuttuun koodiin. Viimeiseksi, WM_CREATEn käsittelyn sijaan käsittelet WM_INITDIALOG tekemään prosessit joita vaaditaan ennen dialogin ilmestymistä, joka sitten palauttaa TRUE arvon keskittämään näppäimistön ensiarvoiseen painikkeeseen. Seuraavaksi dialogi-ikkunan luomiseen: case WM_COMMAND: switch(loword(wparam)) case ID_HELP_ABOUT: int ret = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc); if(ret == IDOK) MessageBox(hwnd, "Dialog exited with IDOK.", "Notice", MB_OK MB_ICONINFORMATION); else if(ret == IDCANCEL) MessageBox(hwnd, "Dialog exited with IDCANCEL.", "Notice", MB_OK MB_ICONINFORMATION); else if(ret == -1) MessageBox(hwnd, "Dialog failed!", "Error", MB_OK MB_ICONINFORMATION); // Muita menun valintoja..

19 Tämä tulee sijoittaa WM_COMMAND Handleriin. Koska haluamme pääikkunamme menun luovan dialogin, tulee koodi sijoittaa pääikkunamme WndProc()iin. IDD_ABOUT on dialogiresurssin ID. Hwnd on dialogin isäntäikkunan Handle. AboutDlgProc() on dialogin kontrolloimiseen tarkoitettu dialogiproseduuri. DialogBoxia käytettäessä pääikkunasi käyttö on evätty ennenkuin dialogi on päätetty. 3.3.1 MOODITON DIALOGI-IKKUNA Seuraavaksi käsittelemme CreateDialog() function. Erona näissä on se, että kun DialogBox() käsittää oman viesti-looppinsa eikä palaa pääikkunan viesti-looppiin ennenkuin dialogi suljetaan, käyttäytyy CreateDialog() ennemmin kuin ikkuna joka on luotu CreateWindowEx() siinä mielessä, että se palaa automaattisesti alkuperäiseen, odottaen viestiä aivan kuten pääikkunakin. Täten Mooditon, kun taas DialogBox() luo Modaalisia dialogeja IDD_TOOLBAR DIALOGEX 0, 0, 98, 52 STYLE DS_MODALFRAME WS_POPUP WS_CAPTION EXSTYLE WS_EX_TOOLWINDOW CAPTION "My Dialog Toolbar" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "&Press This Button",IDC_PRESS,7,7,84,14 PUSHBUTTON "&Or This One",IDC_OTHER,7,31,84,14 END Seuraavaksi haluamme luoda dialogin sillä aikaa kun ohjelmamme on käynnissä. Haluamme myös asettaa globaalin muuttujan pitämään ikkunan Handlea palautumaan CreateDialog()ista, jotta voimme käyttää sitä myöhemmin. HWND g_htoolbar = NULL; case WM_CREATE: g_htoolbar = CreateDialog(GetModuleHandle(NULL),

20 MAKEINTRESOURCE(IDD_TOOLBAR), hwnd, ToolDlgProc); if(g_htoolbar!= NULL) ShowWindow(g_hToolbar, SW_SHOW); else MessageBox(hwnd, "CreateDialog returned NULL", "Warning!", MB_OK MB_ICONINFORMATION); Tarkistamme palautusarvon ja jos se on erisuuri kuin NULL, näytämme ikkunan ShowWindow() funktiolla. Seuraavaksi tarvitsemme dialogiproseduurin työkalupalkkiimme: BOOL CALLBACK ToolDlgProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) switch(message) case WM_COMMAND: switch(loword(wparam)) case IDC_PRESS: MessageBox(hwnd, "Hi!", "This is a message", MB_OK MB_ICONEXCLAMATION); case IDC_OTHER: MessageBox(hwnd, "Bye!", "This is also a message", MB_OK MB_ICONEXCLAMATION); default: return FALSE; return TRUE;

21 3.4 MUOKATTAVA TEKSTIKENTTÄ Yksi yleisimmin käytetyistä kontrolleista Windows-ympäristössä on EDIT, kontrolli joka sallii käyttäjän syöttää, muokata, kopioida jne. tekstiä. Esim. Windows Notepad. SetDlgItemText(hwnd, IDC_TEXT, "This is a string"); Näin saat muokattua kontrollin sisältämää tekstiä. Tekstin palauttaminen kontrollista vaatii hieman enemmän työtä. int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT)); if(len > 0) int i; char* buf; buf = (char*)globalalloc(gptr, len + 1); GetDlgItemText(hwnd, IDC_TEXT, buf, len + 1); //... do stuff with text... GlobalFree((HANDLE)buf); Ensiksikin meidän tulee laittaa syrjään muistia tekstin tallettamista varten. Tätä varten meidän tulee tietää kuinka paljon muistia siirtää syrjään GetWindowTextLength()tekee tämän, joten meidän täytyy saada Handle kontrollille käyttämällä GetDlgItem(). Nyt kun meillä on pituus, voimme siirtää syrjään muistia. Tähän käytämme GlobalAlloc() GetWindowTextLength()palauttaa syötettyjen kirjaimien määrän, jotka kontrolli sisältää. Viimeiseksi kutsumme GetDlgItemText() noutamaan kontrollin sisällön muistibufferiin jonka juuri varasimme Tämän jälkeen käytämme GlobalFree() vapauttamaan varaamamme muistin. Siinä muutama yksinkertainen graafinen elementti c-kieliseen ohjelmaan.

22 4 LÄHTEET http://en.wikipedia.org/wiki/list_of_c_functions http://en.wikipedia.org/wiki/c_%28programming_language%29 http://en.wikipedia.org/wiki/graphical_user_interface http://www.fanboy.com/wp-content/uploads/2009/02/xerox-star-interface.jpg http://www.winprog.org/tutorial/ (theforger s WIN32 API tutorial)