Usean näkymän luominen



Samankaltaiset tiedostot
MDI-sovellusten kehittäminen

Dokumentit, näkymät ja kehykset

Jypelin käyttöohjeet» Ruutukentän luominen

Tekstikontrollit LUKU. Tekstin ja sanomien esittäminen valintaikkunoissa. Tekstin muokkaaminen suorituksen aikana. Tiedon tarkistaminen syötön aikana

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

Luettelo-, puu-, parannetun tekstiruutu- sekä HTML-näkymän käyttö

ActiveX-kontrollien käyttö

OHJE EXCEL-MAKRON LUOMISEKSI JA MAKRON KÄYTÖSTÄ

Valintanauhan komennot Valintanauhan kussakin välilehdessä on ryhmiä ja kussakin ryhmässä on toisiinsa liittyviä komentoja.

Kehitysympäristö LUKU. Developer Studio kehitysympäristön alkeet. Liikkuminen projektin työtilassa ja sen eri näkymissä

KESKUSTANUORTEN NETTISIVUT- OHJEITA PIIRIYLLÄPITÄJÄLLE 1. KIRJAUTUMINEN

Taulukot Päivi Vartiainen 1

Avaa ohjelma ja tarvittaessa Tiedosto -> Uusi kilpailutiedosto

Haaga-Helia/IltaTiko ict2tcd005: Ohjelmiston suunnittelutaito 1/7 Anne Benson. Tällä opintojaksolla käytämme VS:n kolmen kokonaisuuden luomiseen:

Visual C++ -ohjelman tekeminen ja suunnittelu

TIETOKONEEN ASETUKSILLA PARANNAT KÄYTETTÄVYYTTÄ

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

Muuttujien määrittely

1 Funktiot, suurin (max), pienin (min) ja keskiarvo

4.1 Frekvenssijakauman muodostaminen tietokoneohjelmilla

Hiirisanomiin vastaaminen

Näkymien vierittäminen ja koon muuttaminen

Nspire CAS - koulutus Ohjelmiston käytön alkeet Pekka Vienonen

Web Services tietokantaohjelmoinnin perusteet

Google-dokumentit. Opetusteknologiakeskus Mediamylly

OpenOffice.org Impress 3.1.0

Mainosankkuri.fi-palvelun käyttöohjeita

Kaakkois-Suomen Ammattikorkeakoulu Oy Mikkelin Ammattikorkeakoulu Oy Kymenlaakson Ammattikorkeakoulu Oy

Tulosta yrityksesi tuloslaskelma ja tase myöhempää tarkastusta varten. Ota varmuuskopio tilanteesta ennen tilimuunnosta.

1 eportfolio Kyvyt.fi - palvelun käytön aloittaminen

Tekstinkäsittelyn jatko Error! Use the Home tab to apply Otsikko 1 to the text that you want to appear here. KSAO Liiketalous 1

GEOS 1. Ilmastodiagrammi Libre Office Calc ohjelmalla

TAULUKOINTI. Word Taulukot

Siirtyminen Outlook versioon

Fonttien käyttö LUKU. Tekstin esittäminen värein ja tyylein. Fonttien käyttö sovelluksen viimeistelyyn OSA IV LUKU 17.

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

CISS Base Excel raporttien määritys Käyttäjän käsikirja. CISS Base Käyttäjän Käsikirja Econocap Engineering Oy 1

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

Osaamispassin luominen Google Sites palveluun

GeoGebra-harjoituksia malu-opettajille

Valintaikkunoiden luonti ja suunnittelu

2. PPPoE YHTEYDEN POISTAMINEN BAANA-CLIENT Windows 2000 / XP

TAMPEREEN TEKNILLINEN YLIOPISTO KÄYTTÖOHJE TIETOVARASTON KUUTIOT

Graafisen käyttöliittymän ohjelmointi

Kansion asetusten muuttaminen Windows 2000 käyttöjärjestelmässä Resurssienhallinnan kautta

Tulostaminen ja esikatselu

Sähköposti ja uutisryhmät

Harjoitus Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

TAULUKKO, KAAVIO, SMARTART-KUVIOT

Facebook-sivun luominen

Aktivoi dokumentin rakenteen tarkistamiseksi piilomerkkien näyttäminen valitsemalla valintanauhasta Kappale-kohdasta painike Näytä kaikki.

NetMeetingiä voi käyttää esimerkiksi Internet puheluissa, kokouksissa, etätyössä, etäopiskelussa ja teknisessä tuessa.

CLOUDBACKUP TSM varmistusohjelmiston asennus

815338A Ohjelmointikielten periaatteet Harjoitus 5 Vastaukset

FOTONETTI BOOK CREATOR

GPRS-lisäpalvelu INTERNET-ASETUKSET

Sonera Viestintäpalvelu VIP VIP Laajennettu raportointi Ohje

E s i t y s g r a f i i k k a a s e l k o k i e l e l l ä MICROSOFT. PowerPoint. P e t r i V a i n i o P e t r i I l m o n e n TIKAS-SARJA

Posterin teko MS Publisherilla

Sovelluksen toimintojen toteuttaminen

Ohjelmoinnin perusteet Y Python

Webmailin käyttöohje. Ohjeen sisältö. Sähköpostin peruskäyttö. Lomavastaajan asettaminen sähköpostiin. Sähköpostin salasanan vaihtaminen

ETAPPI ry JOOMLA 2.5 Mediapaja. Artikkeleiden hallinta ja julkaisu

Muistitikun liittäminen tietokoneeseen

FrontPage Näkymät

Jypelin käyttöohjeet» Ruutukentän luominen

Olion elinikä. Olion luominen. Olion tuhoutuminen. Olion tuhoutuminen. Kissa rontti = null; rontti = new Kissa();

Sisällys. Metodien kuormittaminen. Luokkametodit ja -attribuutit. Rakentajat. Metodien ja muun luokan sisällön järjestäminen. 6.2

WINDOWS MICROSOFT OUTLOOK 2010:N UUDET OMINAISUUDET...

TEHTÄVÄ 1.1 RATKAISUOHJEET

T Olio-ohjelmointi Osa 5: Periytyminen ja polymorfismi Jukka Jauhiainen OAMK Tekniikan yksikkö 2010

RATKAISUT SIVU 1 / 15. Väriteemaan pääset käsiksi hieman eri tavoilla PowerPointin eri versioissa.

Ajokorttimoduuli Moduuli 2. - Laitteenkäyttö ja tiedonhallinta. Harjoitus 1

Asiakastukiryhmä Kesä- ja talviaika

Oppilaan pikaopas. Project 2013 käyttöliittymä ja näkymät

Tapahtumapohjainen ohjelmointi. Juha Järvensivu 2007

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

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

Omien raporttien tekeminen Qlikviewissä

Pedacode Pikaopas. Java-kehitysympäristön pystyttäminen

Tietokantojen ja tietuenäkymien käyttö

2020 Fusion. What s New in Version 6? What s New in Version 6? 1 of Fusion

Piirtopinnalle piirtäminen

AUTOCAD-TULOSTUSOHJE. Tällä ohjeella selitetään Autocadin mittakaavatulostuksen perusasiat (mallin mittayksikkönä millimetrit)

1 Yleistä Web-editorista Web-editori -dokumentin luominen Pikatoimintopainikkeet Tallenna... 3

Yksityiskohtaiset ohjeet. TwinSpacen käyttäminen

Pikaopas. Valintanauhan näyttäminen tai piilottaminen Avaa valintanauha napsauttamalla välilehteä, tai kiinnitä se pysyvästi näkyviin.

MultiSave - käyttö ja käyttöönotto

Olio-ohjelmointi Javalla

PERUSTEET. Sisällysluettelo

Tällä harjoituskerralla on tarkoituksena harjoitella käyttötapaus-, luokka- ja tapahtumasekvenssikaavioiden luontia.

Ohjelmoinnin perusteet Y Python

Kynien ja siveltimien käyttö

Monikielinen verkkokauppa

BaseMidlet. KÄYTTÖOHJE v. 1.00

Opiskelijalistojen tulostaminen, opiskelijoiden hallinta ja sähköpostin lähettäminen

Ohjeita LINDOn ja LINGOn käyttöön

C# Windows ohjelmointi perusopas

Ohjeisto Trimble Pro 6H yhdistämisestä Juno 5:een

OpeOodi Opiskelijalistojen tulostaminen, opiskelijoiden hallinta ja sähköpostin lähettäminen

Transkriptio:

OSA V 471 LUKU 20 20 LUKU Dynaamisten ja staattisten jakajaikkunoiden käyttö Resurssienhallinnan kaltaisen käyttöliittymän tekeminen sovelluksiin ja hallinta ilman ikkunan jakamista

472 Kehittyneet dokumentti/näkymä -tekniikat Usean näkymän ymmärtäminen Dokumentti/näkymä arkkitehtuuri tuo ohjelmankehitystyöhön useita etuja. Suurimpia näistä ovat MFC-kirjastoon sisältyvät dokumentti/ näkymää tukevat toiminnot, jotka helpottavat ohjelmointityötä huomattavasti. Kuten olet aiemmista luvuista saanut havaita, nämä luokat hoitavat dokumentin, näkymän ja ikkunan kehyksien luomisen ja hallinnan. Ne käsittelevät myös valikosta käytettäviä komentosanomia, kiinnittyviä työkalurivejä, tilarivin näyttöä ja paljon muuta. Datan (eli dokumentin) käsittelykoodin erottaminen käyttöliittymästä (näkymä) on myös joustava rakenneratkaisu. Samasta näkymästä voidaan esimerkiksi esittää erilaisia näkymiä. Näin voidaan esimerkiksi näyttää laajasta dokumentista tai teknisestä piirustuksesta kaksi eri osaa yhtä aikaa ja vieläpä näytetyistä tiedoista muodostettu kaaviokuva. Yhteen dokumenttiin liitettyjä näkymiä voi toki olla kahta enemmänkin. Usean näkymän luomiseen on eri tapoja. Ikkuna voidaan jakaa ruuduiksi (pane), joissa kussakin on oma näkymänsä. Tätä käytetäänkin useissa sovelluksissa. Windowsin Resurssienhallinnassa (Explorer) jaetaan ikkuna levyasemat ja kansiot esittävään puunäkymään vasempaan ruutuun ja oikean ruudun tiedostoluetteloon. Näkymiä voidaan esittää myös osin päällekkäin eri välilehdillä (tab), kuten Excelin laskentataulukot on esitetty. Ikkunoiden jakaminen Jakamalla ikkuna kahtia saadaan yhteen kehysikkunaan kaksi tai neljä ruutua. Ikkunan jakaminen ruutuihin tehdään kehykseen upotetun jakoikkunan (splitter) avulla. Kukin ruutu sisältää oman näkymänsä, jotka voivat olla samaa tai eri näkymäluokkaa. Monidokumenttisovelluksessa (MDI) kukin MDI-näkymä sisältyy kehysikkunaan ja nämä MDI-lapsi-ikkunat voidaan vielä jakaa ruutuihin. Kehysikkuna voidaan jakaa vaaka- tai pystysuunnassa tai molemmissa. Käyttäjä saa muutettua ruutujen kokoa siirtämällä hiirellä jakopalkkia (splitter bar). Jaettuja ikkunoita on sekä staattisina että dynaamisina; molemmat on toteutettu CSplitterWnd-luokassa.

OSA V LUKU 20 473 Dynaamisten jakoikkunoiden luominen Kehysikkuna, joka voidaan jakaa ruutuihin, näyttää aivan tavalliselta ikkunalta, kunnes käyttäjä valitsee vierityspalkista jakoruudun (splitter box). Aluksi ensimmäinen (vasemman yläkulman) ruutu täyttää koko ikkunan ja vasta käyttäjän raahattua jakoruudun näkymän alueelle ikkuna jaetaan kahteen tai useampaan ruutuun. Kehysikkunaa jaettaessa ruutuihin luodaan vastaavat näkymäoliot. Ylimääräiset ruudut saadaan poistettua viemällä jakopalkki vierityspalkin jompaankumpaan päähän. Kun ruutu poistetaan, myös sen näkymäolio tuhotaan. Dynaamisia jakoikkunoita käytetään yleensä saman dokumentin eri osien näyttämiseen eli ruutujen näkymäoliot edustavat yleensä samaa näkymäluokkaa. Esimerkiksi Developer Studion tekstieditorissa voit käyttää vaaka- ja pystysuunnassa jaettuja ikkunoita. Voit lisätä dynaamisen ikkunan jakamisen sovellukseesi kolmella eri tavalla. Jos suunnittelet jaettujen ikkunoiden käytön sovellukseen alusta alkaen, voit käyttää AppWizardia. Valmiiseen sovellukseen ikkunoiden jakaminen voidaan koodata käsin tai ne saadaan lisäämällä sovellukseen Component and Controls Galleryn komponentti Splitter Bar. AppWizardin käyttö on näistä helpoin. Tämä tuo lisäksi automaattisesti View-valikkoon Split-komennon (Jaa), jolloin käyttäjä pääsee sijoittamaan jakopalkin näkymää jakamaan. Tee siis AppWizardilla uusi SDI-sovellus DSplit. Napauta Step 4 ikkunassa Advanced-painiketta ja valitse Window Styles välilehti. Rastita Use Split Window valinta, kuten kuvassa 20.1 on esitetty. Muista valita myös Step 6 ikkunassa näkymän kantaluokaksi CScrollView. AppWizard lisää Splitkomennon valikkoon Jos valitset AppWizardissa Use Split Window -asetuksen, lisätään Window-valikkoon Splitkomento. Jos lisäät olemassa olevaan sovellukseen jakoikkunan, tämän ID-tunnus on ID_WINDOW_SPLIT. KUVA 20.1 AppWizardin Advanced Options ikkuna.

474 Kehittyneet dokumentti/näkymä -tekniikat Jos haluat lisätä ikkunoiden jakamisen jo olemassa olevaan SDI- tai MDI-sovellukseen, toimi seuraavien ohjeiden mukaan. Huomaa, että et tarvitse näitä vaiheita DSplit-esimerkissämme. SplitterBar-komponentin lisääminen 1. Avaa Developer Studiossa projekti, johon haluat lisätä jakopalkit. 2. Valitse Project-valikosta Add to Project ja alavalikosta Components and Controls. Saat esiin Components and Controls Gallery ikkunan. 3. Kaksoisnapauta Visual C++ Components kansiota. 4. Valitse komponenttiluettelosta Splitter Bar, kuten kuvassa 20.2 tehdään. Saat tässä vaiheessa lisätietoja lisättävästä komponentista More Info painikkeella. KUVA 20.2 Components and Controls Gallery ikkuna. 5. Napauta Insert-painiketta. Hyväksy komponentin lisääminen napauttamalla Insert the Splitter Bar Component sanomaruudussa OK-painiketta. Saat esiin kuvan 20.3 esittämän Splitter Bar asetusikkunan. KUVA 20.3 Splitter Bar komponentin asetusikkuna.

6. Valitse haluamasi jakopalkit ja napauta OK. 7. Sulje Components and Controls Gallery ikkuna. OSA V LUKU 20 475 KATSO MYÖS Yksityiskohtia SDI-sovelluksen luomisesta luvussa 12. Lisätietoja CScrollView-luokasta luvusta 18. Lisätietoja komponenttigalleriasta luvusta 9. Dynaamisten jakoikkunoiden alustaminen Joko AppWizardilla tai komponenttigalleriasta lisätty jakoikkuna generoi samanlaisen koodin. CSplitterWnd-luokan olio on upotettu CMainFrame-luokan jäseneksi (MDI-sovelluksessa CChildFramen). Tämä splitter-olio ottaa haltuunsa kehysikkunan työalueen ja ohjaa näkymäikkunoiden luomista ja tuhoamista. DSplit-esimerkissä löydät olion CMainFrame-luokan protected-tyyppisistä muuttujista: CSplitterWnd m_wndsplitter; Jakoikkuna luodaan korvaajafunktiossa CMainFrame::OnCreateClient, kuten listauksessa 20.1 on esitetty. Tätä funktiota kutsutaan kehysikkunan luomisen aikana CFrameWnd::OnCreate-funktiosta. Oletustoteutuksessa luodaan näkymäolio ja sen työalue asetetaan kehysikkunan kokoiseksi. Korvaajafunktiossa luodaan ensin itse jakoikkuna, joka alustaa itsensä luomalla View-olion. Muut näkymät luodaan käyttäjän jakaessa ikkunan. LISTAUS 20.1 LST20_1.CPP Dynaamisten jakoikkunoiden luominen OnCreateClient-funktiossa 1 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/, 2 CCreateContext* pcontext) 1 3 { 4 return m_wndsplitter.create(this, 5 2, 2, // TODO: adjust rows and columns 6 CSize(10, 10), // TODO: adjust minimum pane size 7 pcontext); 2 8 } 1 Jakoikkunat luodaan korvaamalla OnCreateClientfunktio. 2 Luodaan jakoikkuna syöttämällä parametreinä tiedot rivien ja sarakkeiden määrästä. Jakoikkunan Create-funktiolle (rivillä 4) voidaan syöttää jopa seitsemän parametriä. Ensimmäinen on osoitin isäikkunaan, joka tässä on this. Toinen parametri on rivien enimmäismäärä, kolmas sarakkeiden (rivi 5). CSplitterWnd-luokka tukee ainoastaan yhden vaaka- ja yhden

476 Ikkunoiden luominen ajon aikana Kontrollien lisääminen valintaikkunamalliin resurssieditorissa on helppoa, mutta esimerkiksi tekstiruudun lisääminen valintaikkunaan ajonaikana ehdollisesti tehdään CEdit::Create-funktiolla. Createfunktiota käyttämällä voidaan luoda ajon aikana millaisia ikkunoita tahansa. Ajonaikainen ikkunoiden luominen on aina kaksivaiheinen prosessi. Aluksi muodostetaan ikkunaluokan olio (esimerkiksi CEdit tai CComboBox) ja sitten kutsutaan Create-funktiota välittäen sille parametreinä ikkunan tyyli, koko, isäikkuna ja kontrollin IDnumero. Kehittyneet dokumentti/näkymä -tekniikat pystysuuntaisen jakopalkin luomista, joten arvo voi olla 1 tai 2. Esimerkiksi 1 rivi ja 2 saraketta saa aikaan ainoastaan pystysuuntaisen jakopalkin. Neljäs parametri on CSize-tyyppiä, se määrää rivin vähimmäiskorkeuden ja sarakkeen vähimmäisleveyden (rivi 6). Näkymä luodaan ainoastaan, kun vähimmäiskorkeus ja leveys ylitetään ja näkymä tuhotaan, mikäli ruudun koko on annettuja arvoja pienempi. Näitä asetuksia voit muuttaa ohjelman suorituksen aikana SetRowInfo- ja SetColumnInfo-funktioilla. Viides parametri on osoitin CCreateContext -olioon, joka sisältää dokumentti-, näkymä- ja kehysikkunaluokkien ajonaikaiset tiedot. Tämä pcontexttietorakenne on jo valmiiksi alustettu ja se vain välitetään Createfunktiolle (rivi 7). Kaksi viimeistä parametriä ovat valinnaisia. Kuudentena parametrinä voidaan syöttää ikkunan tyyliasetuksia. Oletusarvo tälle on WS_CHILD WS_VISIBLE WS_HSCROLL WS_VSCROLL SPLS_DYNAMIC_SPLIT. Viimeinen parametri on lapsi-ikkunan IDtunnus ja ellet upota jaettuja ikkunoita toisiinsa, tulee käyttää oletusarvoa AFX_IDW_PANE_FIRST. Saat esimerkin ikkunan jakamisesta muokkaamalla kahta CDSplitView-luokan funktiota listauksen 20.2 mukaisesti. LISTAUS 20.2 LST20_2.CPP 50 tekstiriviä sisältävän ikkunan dynaaminen jakaminen 1 Laskee korkeuden tekstiriville nykyisellä fontilla. 2 Tulostaa tekstin näytölle. 1 void CDSplitView::OnDraw(CDC* pdc) 2 { 3 CDSplitDoc* pdoc = GetDocument(); 4 ASSERT_VALID(pDoc); 5 6 // TODO: add draw code for native data here 7 TEXTMETRIC tm; 8 int nlineheight; 9 10 // ** Get metrics of the current font & calculate the line height 11 pdc->gettextmetrics(&tm); 12 nlineheight = tm.tmheight + tm.tmexternalleading; 1 13 14 // ** Output 50 lines of text 15 CString str; 16 for(int nline = 1; nline < 51; nline++) 17 { 18 str.format("line %d - I must NOT feed my homework to my dog.", nline); 19 pdc->textout(5, nline * nlineheight, str); 2 20 } 21 } 22

OSA V LUKU 20 477 23 void CDSplitView::OnInitialUpdate() 24 { 25 CScrollView::OnInitialUpdate(); 26 27 CSize sizetotal; 28 // TODO: calculate the total size of this view 29 30 // Initialize the total scroll size to 1000 x 1000 31 sizetotal.cx = sizetotal.cy = 1000; 32 SetScrollSizes(MM_TEXT, sizetotal); 3 33 } 3 Vierityskoon asettaminen 1000 x 1000 pisteeseen pakottaa vierityspalkit käyttöön. Joudut muokkaamaan tässä ainoastaan CDSPlitView::OnInitialUpdate -funktiota muuttamalla rivillä 31 arvon 100 paikalle 1000. Näin looginen näkymän koko tulee fyysistä kokoa suuremmaksi ja ikkuna saa vierityspalkit. Korvattu OnDrawfunktio esittää 50 tekstiriviä. Voit laskea piirtopinnalle valitun fontin korkeuden rivillä 7 määritellyn TEXTMETRIC-tietorakenteen avulla, kun alustat tietorakenteen rivin 11 CDC::GetTextMetric-funktiolla. Käännä ja suorita sovellus. Valitse jakoruudut ja kokeile näkymien vieritystä. Huomaa, että vierityspalkit toimivat sekä vaaka- että pystynäkymille. DSplit-esimerkki on esitetty kuvassa 20.4. KUVA 20.4 DSplit-esimerkki. KATSO MYÖS Lisätietoja MDI-luokista luvusta 21. Tietoja piirtopinnasta luvusta 15.

478 Kehittyneet dokumentti/näkymä -tekniikat Staattisten jakoikkunoiden luominen Kehysikkuna, jossa käytetään staattisia jakoikkunoita, näyttää ikkunan jaettuna ruutuihin heti sen kehysikkunan luomisen jälkeen. Ruutujen määrä, sijainti ja näkymäluokka määrätään kehyksen luomisen aikana. Myös näkymäoliot luodaan tässä vaiheessa. Dynaamisista jakoikkunoista poiketen staattisia jakoikkunoita ei voida poistaa, joten näkymäolioita ei käytön aikana muodosteta eikä tuhota. Jakopalkki on aina esillä ja se pysähtyy, jos ruutu pienenee vähimmäiskokoonsa. Jos haluat luoda Resurssienhallinnan kaltaisia sovelluksia, jossa on kaksi staattista ikkunaa - vasemman puunäkymä ja oikean ikkunan luettelonäkymä, saat tähän apua jo AppWizardilta. Resurssienhallinnan näköisten sovelluksien luomista on käsitelty myöhemmin tässä luvussa. Ainoa erilainen tapa luoda staattisia jakoikkunoita on koodin kirjoittaminen. Tätä pääsemme kokeilemaan, kun teet AppWizardilla uuden SDI-projektin SSplit. Valitse näkymän kantaluokaksi Step 6 ikkunassa CEditView. Jakopalkkinäytön räätälöinti Voit muokata jakopalkkinäyttöä johtamalla oman aliluokan CSplitterWnd-luokasta ja korvaamalla virtuaalifunktion OnDrawSplitter(). Funktio saa parametrinä enum-vakioarvon, joka määrittää, mitä jakoikkunan osia piirretään. Mahdolliset arvot ovat splitbox, splitbar, splitintersection ja splitborder. Staattisten jakoikkunoiden alustaminen Sovelluksesta riippuen staattisissa jakoikkunoissa saatetaan esittää erilaisia näkymiä ja näin näkymät saattavat olla eri luokista. Tässä projektissa lisäät koodaamalla staattisen jakoikkunan sekä toisen näkymän. Staattinen jakoikkuna on pystysuuntainen ja sen CEditView-luokasta peritty näkymä esitetään ikkunan vasemmassa osassa ja CView-luokasta peritty näkymä oikeassa. Tehtyäsi projektin valmiiksi seuraa seuraavia ohjeita. Oman näkymäluokan johtaminen ClassWizardilla 1. Käynnistä ClassWizard näppäilemällä Ctrl+W tai valitsemalla View-valikosta ClassWizard. 2. Napauta Add Class painiketta ja valitse saamastasi luettelosta New. Saat esiin New Class ikkunan. 3. Anna uudelle luokalle nimi Name-ruutuun. Tässä esimerkissä käytämme nimeä CArtView. 4. Valitse Base Class yhdistelmäruudussa CView. Lisää luokka napauttamalla OK-painiketta. 5. Sulje ClassWizard OK:lla.

Uusi näkymäluokka on luotu, joten voit kirjoittaa staattisen jakoikkunakoodin. Lisää ensin CMainFrame-luokkaan protected-tyyppinen CSplitterWnd-luokan jäsenmuuttuja. Käytän muuttujalle nimeä m_wndsplitter. Toimi nyt seuraavien ohjeiden mukaan ja muokkaa sitten CMainFrame::OnCreateClient-funktiota listauksen 20.3 mukaan. OSA V LUKU 20 479 Staattisen jakoikkunan toteutus 1. Käynnistä ClassWizard näppäilemällä Ctrl+W tai valitsemalla View-valikosta ClassWizard. 2. Valitse Message Maps välilehti. 3. Valitse Class Name yhdistelmäruudussa CMainFrame. 4. Valitse Object IDs luettelosta CMainFrame. 5. Valitse Messages-luettelosta OnCreateClient ja napauta Add Function painiketta. 6. Napauta Edit Code painiketta. LISTAUS 20.3 LST20_3.CPP Staattisten jakoikkunoiden luominen OnCreateClient-funktiossa 1 BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pcontext) 2 { 3 // TODO: Add your specialized code here and/or call the base class 4 // ** Create the static splitter window 5 if (!m_wndsplitter.createstatic(this, 1, 2)) 1 6 return FALSE; 7 8 // ** Create two views and insert in to the splitter panes 9 if (!m_wndsplitter.createview(0, 0, RUNTIME_CLASS (CSSplitView), CSize(150, 100), pcontext) 10!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS (CArtView),CSize(100, 100), pcontext)) 2 11 { 12 m_wndsplitter.destroywindow(); 3 13 return FALSE; 14 } 15 16 // ** Return successful 17 return TRUE; 18 } 1 Luo staattisen jakoikkunan, jossa on 1 rivi ja 2 saraketta (pystyjako). 2 Luo näkymän jaetun ikkunan kullekin ruudulle. 3 Siivotaan jäljet, ellei luominen onnistu. Huomaa, että joudut lisäämään seuraavat #include-lauseet

480 Kehittyneet dokumentti/näkymä -tekniikat MainFrm.cpp-tiedoston alkuun: #include SSplitView.h #include ArtView.h Joudut lisäämään myös dokumenttiluokan määrittelyn SSplitView.htiedostoon. Tämä liittyy otsikkotiedostojen lisäämisjärjestykseen käännettäessä. Lisää siis seuraava rivi: class CSSplitDoc; ennen riviä: class CSSplitView : public CEditView Staattinen jakoikkuna luodaan CreateStatic-funktiolla dynaamisten jakoikkunoiden kanssa käytetyn Create-funktion sijaan. Staattisten jakojen rajoitukset Dynaamisesta jaosta, jossa ikkunassa voi olla korkeintaan 2 riviä ja 2 saraketta, poiketen staattisesti jaetussa ikkunassa voi olla 16 riviä ja 16 saraketta. Näin monen ikkunan käyttö saattaa kuitenkin olla varsin käyttökelvoton käyttöliittymä. Jakoikkunan CreateStatic-funktiolle voidaan syöttää enimmillään viisi parametriä. Ensimmäinen osoittaa isäikkunaan eli tässä tapauksessa funktiota kutsuvaan luokkaan this. Toinen ja kolmas parametri ovat rivien ja sarakkeiden enimmäismäärät. Rivillä 5 annetut arvot yksi rivi ja kaksi saraketta jakavat ikkunan pystysuunnassa keskeltä kahtia. Kaksi viimeistä parametriä ovat valinnaisia: neljäs on ikkunan tyyli ja viides lapsi-ikkuna ID-tunnus. Ellei ikkunaluokkia upoteta toisiinsa, tulee tunnuksena käyttää oletusarvoa AFX_IDW_PANE_FIRST. Kullekin ruudulle tulee luoda näkymäolio rivien 9 ja 10 CreateViewfunktiolla. Ensimmäisen kaksi parametriä ovat näkymän paikan rivi ja sarake. Kolmas parametri osoittaa näkymäluokan ajonaikaisiin tietoihin. Tämän luokan tulee olla johdettu CWnd-luokasta, mutta yleensä se johdetaan CView:stä. Neljäs CSize-tyyppinen parametri asettaa rivin vähimmäiskorkeuden ja sarakkeen vähimmäisleveyden. Näitä arvoja voidaan muuttaa ohjelman ajon aikana SetRowInfo- ja SetColumnInfo-funktioilla. Viides parametri on osoitin CCreateContext-olioon, jossa on dokumentti- ja kehysluokan ajonaikaiset tiedot. pcontext-parametri saadaan CFrameWnd::OnCreateClient-funktion syötteestä, joten sen välittäminen CreateView-funktiolle riittää. Funktion lopusta on poistettu kantaluokan kutsuminen ja funktio palauttaakin yksinkertaisesti TRUE (rivi 17), jos jakoikkunan ja näkymien luominen on onnistunut.

Esimerkki eri näkymäluokista staattisissa jakoikkunoissa saadaan muokkaamalla CArtView::OnDraw-funktio listauksen 20.4 mukaiseksi. LISTAUS 20.4 LST20_4.CPP OnDraw-funktion korvaaminen OSA V LUKU 20 481 1 void CArtView::OnDraw(CDC* pdc) 2 { 3 CDocument* pdoc = GetDocument(); 1 4 5 // TODO: add draw code here 6 // ** Save the current brush 7 CBrush* poldbrush = pdc->getcurrentbrush(); 2 8 9 // ** Create a solid yellow brush 10 CBrush br; 11 br.createsolidbrush(rgb(0,0,255)); 3 12 13 // ** Select the blue brush in to the device context 14 pdc->selectobject(&br); 4 15 pdc->ellipse(1, 1, 300, 300); 5 16 br.detach(); 6 17 18 br.createhatchbrush(hs_fdiagonal,rgb(255,255,0));7 19 pdc->selectobject(&br); 20 pdc->ellipse(50, 50, 200, 200); 8 21 22 // ** Restore the current brush 23 pdc->selectobject(poldbrush); 9 24 } 1 Haetaan osoitin sovelluksen dokumenttiluokkaan näkymän GetDocument()-funktiolla. 2 Haetaan osoitin pdcpiirtopinnalla valittuna olevaan siveltimeen. 3 Luodaan sininen sivellin. 4 Valitaan uusi sivellin piirtopinnalle. 5 Piirretään suuri ellipsi. 6 Irrotetaan sivellin piirtopinnalta. 7 Luodaan keltainen sivellin, joka piirtää vinon kuvion 45 asteen kulmassa. 8 Piirretään pieni ellipsi. 9 Valitaan piirtopinnalle takaisin alkuperäinen sivellin. CArtView::OnDraw-funktiota kutsutaan, kun oikea jakoikkuna kaipaa uudelleenpiirtämistä. Koodi piirtää ikkunaan kaksi ellipsiä, toisen värillä ja toisen kuviolla. Piirtofunktiolle syötetty paikka (kuten CDC::Ellipselle riveillä 15 ja 20) esitetään suhteessa näkymän työalueeseen. Käännä ja suorita sovelluksesi. Sen pitäisi näyttää kuvan 20.5 mukaiselta.

482 Kehittyneet dokumentti/näkymä -tekniikat KUVA 20.5 SSplit-esimerkki. Resurssienhallinnan näköisten sovelluksien luominen Resurssienhallinta (Windows Explorer) on hyvä esimerkki moninäkymäsovelluksesta. Kaksi erityyppistä näkymää on erotettu staattisella jakoikkunalla. Vasemmassa ruudussa esitetään puunäkymä ja oikeassa luettelo. Tämä asettelu sopii hyvin moniin tarkoituksiin. Itse olemme käyttäneet Resurssienhallinnan näköistä ikkunaa tuotannonajoitusjärjestelmässä. Tällöin puussa esitetään työntekijöiden ja koneiden nimet ja luettelossa tehtävien yksityiskohdat. AppWizard osaa luoda suoraan projektin Resurssienhallinnan näköisellä näkymällä. Tarvittavat toimet on esitetty seuraavissa ohjeissa. Resurssienhallinnan näköisen projektin luominen 1. Luo uusi MFC AppWizard (exe) projekti. 2. Valitse AppWizardin Step 1 ikkunassa joko Single Documenttai Multiple Documents valintapainike. 3. Varmista, että Document/View Architecture Support? on valittuna. 4. Valitse Step 4 ikkunassa Windows Explorer valintapainike. Kun AppWizardissa valitaan Windows Explorer tyyli, AppWizard luo sovellusrungon, jossa on kaksi näkymäluokkaa: CLeftView, joka on johdettu luokasta CTreeView, ja CListView-luokasta johdettu

OSA V LUKU 20 483 sovellusnäkymä. Staattinen jakoikkuna on automaattisesti upotettu kehykseen ja näkymän luontikoodi OnCreateClientkorvaajafunktioon. Molemmat näkymäluokat liitetään samaan dokumenttiin ja niissä on käytettävissä GetDocument-funktiot. AppWizard lisää myös työkaluriviin neljä kuvaketta, jotka vaihtavat luettelonäkymän tyypin pieniksi tai suuriksi kuvakkeiksi, tavalliseksi tai yksityiskohtaiseksi luetteloksi. Sovellukseen lisätään myös valintarivi työkalurivin alle. Resurssienhallinta esittää näkymien otsikot valinnaisella valintarivillä, mutta itse voit käyttää sitä valitsemaasi tarkoitukseen. Saat poistettua valintarivin poistamalla CMainFrameluokasta m_wnddlgbar-jäsenmuuttujan ja siihen viittaavan koodin CMainFrame::OnCreate-funktiosta. Vasemman ruudun näkymäluokka CLeftView periytyy aina CTreeView-luokasta eikä sitä voi AppWizardilla muuttaa, mutta oikean näkymäluokan voi. Voit valita AppWizardin Step 6 ikkunassa sovelluksen ikkunan oikeanpuoleisen ruudun näkymän kantaluokan Base Class yhdistelmäruudusta. Funktiorunkojen koodin tekemisen jälkeen joudut täyttämään puukontrollin alkiot ja toteuttamaan oikeanpuoleisen ruudun näkymäluokan. Puunäkymän ytimessä on puukontrolli CTreeView-luokka on paketoi sisäänsä valintaikkunoissa käytettävän CTreeCtrl-luokan. Kontrollin näkymäversio on tehty ikkunan työalueen kokoiseksi ja kehysikkunan mukaan skaalautuvaksi. Voit lisäksi lisätä CTreeCtrl-luokkaan valikon ja työkalurivin käsittelijät. Näkymään kuuluvaan puukontroliin pääsee käsiksi GetTreeCtrl()-funktiolla. KATSO MYÖS Lisätietoja CTreeView-luokasta luvusta 19. Lisätietoja CListView-luokasta luvusta 19. Näkymien lisääminen sovellukseen ajon aikana Dokumentti/näkymä-arkkitehtuuri on hyvin joustava siinä, kuinka sovelluksen tiedot esitetään käyttäjälle. Olet jo saanut kokemusta jakoikkunoiden käytöstä, mutta ne eivät aina ole paras tapa esittää tietoa etenkään, jos samaa tietoa halutaan esittää hyvin eri tavoin. MFC:n sovellusrunko tukee näkymien luomista ajon aikana ja niiden liittämistä dokumenttiin. Liittämisen jälkeen näkymä toimii dokumentin kanssa aivan samoin kuin dokumenttimallinäkymäkin (document template view). Näkymien lisääminen ja poistaminen Näkymä voidaan muodostaa milloin vain ohjelman suorituksen aikana. Näkymä kuuluu vain yhteen dokumenttiin Näkymä voidaan liittää dokumenttiin vain kerran; toisen AddView-toiminnon yritys samalla näkymäosoittimella aiheuttaa MFC-koodista ASSERTvirhetilanteen.

484 Kehittyneet dokumentti/näkymä -tekniikat Dokumentti saadaan liitettyä muodostettuun näkymäolioon välittämällä näkymäosoitin CDocument::AddView-funktiolle. Näkymä saadaan puolestaan irrotettua näkymästä kutsumalla CDocument::RemoveViewfunktiota ja syöttämällä sille osoitin irrotettavaan näkymään. Nämä funktiot eivät kuitenkaan alusta tai tuhoa itse näkymäoliota. Näkymän tulee olla olemassa jo ennen AddView-funktion kutsumista ja se voidaan tuhota vasta RemoveView-funktion kutsumisen jälkeen. Dokumentissa pidetään yllä luetteloa siihen liittyvistä näkymistä ja nämä funktiot ainoastaan muokkaavat tuota luetteloa. AddView- ja RemoveView-funktioita kutsutaan myös CView::OnCreate- ja CView::~CView-funktioista, kun näkymät on luotu dokumenttimalleista. Molemmat funktiot kutsuvat OnChangedViewList-virtuaalifunktiota omien tehtäviensä jälkeen. CDocument::OnChangedViewList puolestaan tarkistaa, onko dokumentin näkymäluettelo tyhjä ja jos on, sulkee dokumentin OnCloseDocument-funktiolla. Voit halutessasi korvata OnChangedDocument-funktion ellet tahdo näin käyvän esimerkiksi halutessasi dokumentin pysyvän auki, vaikkei siihen liittyviä näkymiä olekaan. Näkymän luomisen ja aktivoinnin ohjaaminen Oikeiden näkymien näyttäminen oikeaan aikaan käyttäjille saadaan tehtyä helposti käyttämällä sovelluksen muodostavan dokumentin/ näkymien funktioita. Näillä voit lisätä ja poistaa näkymiä käyttäjän toimien mukaan omasta käyttöliittymästäsi. Tässä kappaleessa teemme sovelluksen, jossa käyttäjä voi vaihdella kahta koko työalueen täyttävää näkymää. Aluksi saat luoda AppWizardilla SDI-projektin VPick, jonka näkymän kantaluokaksi valitaan Step 6 ikkunassa CEditView. VPick perustuu edelliseen SSplit-esimerkkiin ja esittää jakoikkunoista poikkeavan usean näkymän käytön. Generoituasi projektin lisää edellisen esimerkin ohjein projektiisi toinen näkymä, CArtView. Käyttäjä valitsee haluamansa näkymän valikosta. Lisää siis valikkoon molemmille näkymille oma sopivan niminen komento. Anna komentojen ID-tunnuksiksi ID_SHOW_ARTVIEW ja ID_SHOW_EDITVIEW. Lisää nyt näille valikon komennoille käsittelijäfunktiot. Tässä SDIesimerkissä komennot toteutetaan CMainFrame-luokassa, MDIsovelluksessa ne olisivat tulleet CChildFrame-luokkaan. Valikon komentojen käsittelijöiden lisääminen

1. Käynnistä ClassWizard näppäilemällä Ctrl+W tai valitsemalla Viewvalikosta ClassWizard. Valitse ikkunassa Message Maps välilehti. 2. Valitse Class Name yhdistelmäruudussa CMainFrame. 3. Valitse Object IDs luettelossa ID_SHOW_EDIT. 4. Valitse Messages-luettelosta COMMAND ja napauta Add Function painiketta. Napauta Add Member Function ikkunassa OKpainiketta. 5. Valitse Messages-luettelosta UPDATE_COMMAND_UI ja napauta Add Function painiketta. Napauta Add Member Function ikkunassa OK-painiketta. 6. Valitse Object IDs luettelossa ID_SHOW_ART. 7. Valitse Messages-luettelosta COMMAND ja napauta Add Function painiketta. Napauta Add Member Function ikkunassa OKpainiketta. 8. Valitse Messages-luettelosta UPDATE_COMMAND_UI ja napauta Add Function painiketta. Napauta Add Member Function ikkunassa OK-painiketta. 9. Sulje ClassWizard OK-painikkeella. Suuri osa OnShowEdit ja OnShowArt -funktioiden koodista on yhteistä. Koodin turhan kopioinnin sijaan luo apufunktio, jota molemmat funktiot kutsuvat. Seuraavaksi lisättävän funktion parametrit selitetään myöhemmin tässä kappaleessa. OSA V LUKU 20 485 Apufunktion luominen 1. Valitse ClassView-ruudussa CMainFrame-luokka ja sen pikavalikosta Add Member Function. 2. Anna funktion tyypiksi (Function Type ruutuun) void. 3. Syötä funktion määrittelyksi Function Declaration tekstiruutuun CreateActivateView(CRuntimeClass *pnewview, UINT nid). 4. Valitse Private Access valintapainike ja napauta OK. Nyt vain lisäät koodin ja sovellus on valmis. Käyttäjän tulee valita valikosta näkymäkseen joko tekstinäkymä (edit view) tai kuva (art view). Valittu näkymä näytetään koko ikkunassa ja toinen näkymä jätetään näyttämättä. Myös valikon komennot sallitaan ja poistetaan käytöstä

486 Kehittyneet dokumentti/näkymä -tekniikat näkymän valinnan mukaan. Muokkaa siis CArtView::OnDraw -funktio listauksen 20.4 mukaiseksi (esitetty aiempana tässä luvussa). Koodi on sama kuin SSplit-esimerkissä ja on tarkoitettu ainoastaan esittämään erilaista näkymäluokkaa. Muokkaa CMainFrame-luokan jäsenfunktiot listauksen 20.5 mukaisiksi. Huomaa, että joudut lisäämään MainFrm.cpp-tiedoston alkuun seuraavat #include-lauseet: #include VPickView.h #include ArtView.h Joudut myös lisäämään luokan määrittelyn dokumenttiluokalle VPickView.h tiedostoon. Tällä vaikutetaan otsikkotiedostojen (.h) järjestyksen käännettäessä. Lisää siis seuraava rivi: class CVPickDoc; Ennen riviä: class CVPickView : public CEditView Listaus 20.5 LST20_5.CPP Valikoiden komentojen toteutus näkymien luomiseksi ja sallimiseksi 1 Valikon komennon käsittelijä. 2 Poistaa valikon komennon käytöstä, jos CEditView on aktiivinen; sallii muutoin. 3 Valikon komennon käsittelijä. 4 Poistaa valikon komennon käytöstä, jos CArtView on aktiivinen; sallii muutoin. 1 void CMainFrame::OnShowEdit() 1 2 { 3 // ** Call helper function passing a pointer to the 4 // ** views runtime class and a unique ID 5 CreateActivateView(RUNTIME_CLASS(CEditView), 1); 6 } 7 8 void CMainFrame::OnUpdateShowEdit(CCmdUI* pcmdui) 9 { 10 // ** Enable/Disable the menu option according to 11 // ** the active view's class 12 pcmdui->enable(!getactiveview()-> 13 IsKindOf(RUNTIME_CLASS(CEditView))); 2 14 } 15 16 void CMainFrame::OnShowArt() 3 17 { 18 // ** Call helper function passing a pointer to the 19 // ** views runtime class and a unique ID 20 CreateActivateView(RUNTIME_CLASS(CArtView), 2); 21 } 22 23 void CMainFrame::OnUpdateShowArt(CCmdUI* pcmdui) 24 { 25 // ** Enable/Disable the menu option according to 26 // ** the active view's class 27 pcmdui->enable(!getactiveview()-> 28 IsKindOf(RUNTIME_CLASS(CArtView))); 4 29 } 30

OSA V LUKU 20 487 31 void CMainFrame::CreateActivateView( 32 CRuntimeClass *pnewviewclass, 33 UINT nid) 34 { 35 // ** Retrieve a pointer the active view 36 CView* poldview = GetActiveView(); 37 CView* pnewview = NULL; 38 39 // ** Retrieve a pointer to the active document then 40 // ** iterate the document's views looking for a view 41 // ** object of the same runtime class that was passed 42 // ** to the function 43 CDocument* pdoc = GetActiveDocument(); 44 POSITION pos = pdoc->getfirstviewposition(); 45 while(pos &&!pnewview) 46 { 47 CView* pview = pdoc->getnextview(pos); 5 48 if(pview->iskindof(pnewviewclass)) 49 pnewview = pview; 50 } 51 // ** Check to see if a view object was found. 52 // ** If not construct, create and initialize one. 53 if(pnewview == NULL) 54 { 55 // ** Initialize a CCreateContext variable 56 // ** with a pointer to the document 57 CCreateContext context; 58 context.m_pcurrentdoc = pdoc; 59 60 // ** Construct the view object using the 61 // ** runtime class and create the view window. 62 pnewview = (CView*)pNewViewClass->CreateObject(); 6 63 pnewview->create(null, NULL, 0, 64 CFrameWnd::rectDefault, 65 this, nid, &context); 7 66 pnewview->oninitialupdate(); 67 } 68 // ** Set the new view as the active viewand show 69 // ** it's window. Hide the window of the old view. 70 SetActiveView(pNewView); 71 pnewview->showwindow(sw_show); 72 poldview->showwindow(sw_hide); 8 73 74 // ** Swap the two window IDs because the ID of the active 75 // ** view window must be set to AFX_IDW_PANE_FIRST. 76 poldview->setdlgctrlid(pnewview->getdlgctrlid());9 77 pnewview->setdlgctrlid(afx_idw_pane_first); 78 79 // ** Reposition control bars and size the view window. 80 RecalcLayout(); 81 } 5 Käy läpi kaikki dokumentin näkyvät löytääkseen haluamansa. 6 Ajonaikaisen olion dynaamisnen muodostaminen. 7 Luo näkymän ja kutsuu OnInitialUpdate()-funktiota. 8 Näyttää uuden näkymän ja piilottaa korvatun. 9 Vaihtaa ikkunatunnukset keskenään. Näet listauksessa kaksi valikonkäsittelijää: OnShowEdit (rivi 1) ja

488 ASSERT_KINDOF()-makro IsKindOf()-funktion lisäksi myös ASSERT_KINDOF()-makrolle voidaan syöttää CObject-luokasta johdetun luokan olio. Makron parametrit ovat luokan nimi ja osoitin luokan olioon. Makro tarkistaa, onko olio oikeasta luokasta; ellei, siitä ilmoitetaan MFC Assert -valintaikkunalla. Tämä makro suoritetaan ainoaan projektin Debug-versiossa - Release-versiossa sitä ei edes käännetä. Kehittyneet dokumentti/näkymä -tekniikat OnShowArt (rivi 16), jotka siirtävät tehtävänsä välittömästi CreateActivateView-apufunktiolle (esitetty rivillä 31). Funktio saa kaksi parametriä: osoittimen näkymäluokan ajonaikaisiin tietoihin ja oman ID-tunnuksen. Ensimmäistä m_pnewviewclass-parametriä käytetään erottamaan valittava näkymä ja toinen on näkymäikkunan tunnisteena. Funktioita OnUpdateShowEdit (rivi 8) ja OnUpdateShowArt (rivi 23) kutsutaan, kun valikon alkiot piirretään. Funktiot tarkistavat aktiivisen näkymäluokan CObject::IsKindOf-funktiolla. Mikäli aktiivinen näkymäluokka on sama kuin IsKindOf-funktiolle syötetty ajossa oleva, CCmdUI::Enable-funktio saa parametrin FALSE ja poistaa tämän valikon komennon käytöstä. Näin piilossa olevan näkymän komento on valikossa aina sallittu ja esillä olevan näkymän komento poistettu käytöstä. Rivin 31 CreateActivateView-funktio kutsuu aluksi GetActiveView-funktiota näkymän osoittimen poldview-muuttujaan kyseessähän on korvattava näkymä. Uuden tehtävän on sitten päätettävä, onko aktiiviseen dokumenttiin liitetty pnewviewclasstyyppistä näkymää. Dokumentin kaikki näkymät tutkitaan GetFirstViewPosition- ja GetNextView-funktioiden avulla (rivit 44 50). Jos pnewviewclass-tyyppinen näkymä löydetään, asetetaan pnewview osoittamaan siihen (rivi 49). Rivin 53 if-lause tarkistaa, löytyikö näkymää ja jos löytyi, se aktivoidaan uudelleen, muuten se muodostetaan ensin ja aktivoidaan sitten. Uusien näkymäolioiden muodostaminen ja luominen tehdään riveillä 57 67. CCreateContext-tyyppinen muuttuja context on tietorakenne, joka alustetaan osoittimella dokumenttiin. Tämä tietorakenne välitetään myöhemmin Create-funktiolle (rivi 65) dokumentin ja näkymän liittämiseksi toisiinsa. Näkymäolio alustetaan rivillä 62; tässä pnewviewclassvoi olla joko CEditView tai CArtView. Koska näitä luokkia voidaan luoda dynaamisesti, tulee CreateObject-funktio kutsumaan sopivaa muodostinta ja palauttamaan osoittimen uuteen olioon. Rivin 63 Create-funktio luo näkymäikkunan ja liittää sen CView-luokasta johdettuun olioon. Kun näkymä on saatu luotua, kutsutaan virtuaalifunktiota OnInitialUpdate() itsealustuksen suorittamiseksi. Vaadittiinpa muodostamista tai ei, valittu näkymä syötetään SetActiveView-funktiolle (rivi 70), joka aktivoi näkymän ja asettaa sen syötteen saavaksi ikkunaksi. Huomaa, että näkymiä aktivoitaessa tai aktivointi poistettaessa ne saavat OnActivateView-sanoman, jossa

bactivate-parametri kertoo tilan (aktiiviseksi vai ei?). Rivillä 71 valittu näkymä näytetään ja rivillä 72 toinen näkymä piilotetaan. Aktiivisen näkymän ID-tunnus tulee aina olla AFX_IDW_PANE_FIRST, koska tämä on kiinteästi koodattu RecalcLayout-funktiossa, mutta tämä ID-tunnus voi olla vain yhdellä ikkunalla. Tästä syystä rivillä 76 asetetaan ikkunan poldview-tunnuksen pnewview-arvon mukaiseksi ennen kuin pnewviewsaa ID:n arvoksi AFX_IDW_PANE_FIRST (rivi 77). Rivillä 80 kutsuttu RecalcLayoutvastaa näkymäikkunan oikeasta koosta ja työkalurivien paikasta kehysikkunassa. Käännä ja aja sovelluksesi. Kokeile näkymien valitsemista. Kuva 20.6 esittää valmiin VPick-sovelluksen. OSA V LUKU 20 489 KUVA 20.6 VPick-sovellus. KATSO MYÖS Lisätietoja valikoista luvusta 13. Lisätietoja MDI-luokista luvusta 21. Lisätietoja ajonaikaisista luokkatiedoista luvusta 23.

490 Kehittyneet dokumentti/näkymä -tekniikat