Ikkunat ja viestit Windowsissa

Ikkuna on Windowsin keskeisimpiä käsitteitä sillä useimmat käyttöliittymäoliot "perinteisistä" ikkunoista painikkeisiin ja tekstikenttiin ovat ikkunoita. Ikkuna on Windowsin viestiliikenteen perusta, koska esimerkiksi konsolisovellus, jolla ei ole ikkunaa, ei voi vastaanottaa viestejä lainkaan.

Viesti on suhteellisen yksinkertainen tietue, joka on MSDN:ssä määritelty seuraavasti (Microsoft, 1999, MSG):

typedef struct tagMSG {
    HWND   hwnd;
    UINT   message;
    WPARAM wParam;
    LPARAM lParam;
    DWORD  time;
    POINT  pt;
} MSG;
HWND on ikkunan kahva (engl. window handle) eli numeerinen vastaanottavan ikkunan tunniste. Samoin message on etumerkitön kokonaisluku, joka määrittää viestin tyypin. Kahden seuraavan kokonaislukuparametrin wparam ja lparam tulkinta riippuu täysin viestistä ja niillä välitetään vastaanottajalle varsinainen tilatieto tai osoite suurempaan tietorakenteeseen. Kaksi viimeistä kenttää ovat aika ja hiiren koordinaatit viestin lähetyshetkellä.

Ikkunoilla on viestisilmukka (engl. message loop), joka välittää useimmat vastaanotetut viestit sovelluskohtaisesta viestijonosta (engl. message queue) ikkunan viestinkäsittelijälle, ikkunaproseduurille (engl. window procedure. Tosin Petzoldin mukaan jotkin kiireisimmistä viesteistä ohjataan suoraan ikkunaproseduurille ilman odottelua viestijonossa (Petzold, 1998, A Window of One's Own). Seuraavassa on esimerkki viestisilmukasta:

while(GetMessage(&msg, NULL, 0, 0))
{
	TranslateMessage (&msg) ;
	DispatchMessage (&msg) ;
} // while

GetMessage hakee viestin viestijonosta ja DispatchMessage toimittaa sen perille vastaanottajan ikkunaproseduurille. TranslateMessage kääntää raa'at näppäinkoodit (engl. key code) merkkikoodeiksi (engl. character code).

Kullakin ikkunalla on tyyppi eli ikkunan luokka (engl. window class), joita ovat esimerkiksi button ja edit. Luokka määrittelee ikkunan oletustietojäsenet ja tapahtumankäsittelijän. Ikkunaproseduuri puolestaan on sovelluksen määrittelemä takaisinkutsufunktio, jolle Windows välittää ikkunalle saapuneet viestit. Ohjelmoija käsittelee viestit ikkunakohtaisesti niiden tyypin mukaan mutta kutsuu useimmille viesteille luokan oletuskäsittelijää (DefWindowProc). Alla on esimerkki ikkunaproseduurin yleisrakenteesta:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case viestityyppi1:
			// käsittely.
			return 0;
			break;
		case viestityyppi2:
			// käsittely.
			return 0;
			break;
	} // switch
	return DefWindowProc (hwnd, message, wParam, lParam);
} // windowProcedure

Viestit ovat keskeisiä ruudunlukijan toiminnassa. Ruudunlukijan täytyy päästä käsiksi kaikkien ikkunoiden viestiliikenteeseen ja sen on kyettävä tulkitsemaan viestit oikein ikkunakohtaisesti lukeakseen graafista käyttöliittymää luotettavasti ja tehokkaasti.

takaisin sisällysluetteloon