Kirjautuminen

Haku

Tehtävät

Opasarkisto: Visual Basic -opas: Osa 9 - WinAPIn käyttö

  1. Osa 1 - Johdanto
  2. Osa 2 - Käyttöliittymä
  3. Osa 3 - Muuttujat ja taulukot
  4. Osa 4 - Ehdot ja silmukat
  5. Osa 5 - Aliohjelmat ja funktiot
  6. Osa 6 - Hiiri ja näppäimistö
  7. Osa 7 - VB:n grafiikkakomennot
  8. Osa 8 - Tiedostot
  9. Osa 9 - WinAPIn käyttö

Kirjoittaja: Antti Laaksonen

Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi.

Tämän VB-opassarjan päättävän osan oli alunperin tarkoitus käsitellä ainoastaan WinApia, mutta sitten muistinkin, etten ollut maininnut virheenkäsittelystä halaistua sanaa aiemmissa osissa. Tästä johtuen osa alkaakin virheenkäsittelyllä, jatkuen sitten WinApiin.

Virheenkäsittely

Miksi tarvitaan virheenkäsittelyä? Eikö ohjelmat pidä ensin tehdä virheettömiksi, ja sitten vasta julkaista? Kyllä, mutta on olemassa myös sellaisia virheitä joita ei ohjelmaa tehdessä voi ennakoida.

Otetaanpa esimerkiksi seuraava yksinkertainen koodinpätkä joka luo levykkeelle yksirivisen tekstitiedoston.

Private Sub Form_Click()
    Open "a:\testi.dat" For Output As #1
    Print #1, "Testirivi"
    Close #1
End Sub

Mitäpä jos levykettä ei ole asemassa? Silloin VB ilmoittaa tylysti "Run-time error '71': Disk not ready" ja ohjelman suoritus loppuu välittömästi. Jos näin tapahtuu lopullisessa ohjelmassa, kaikki siihen asti tehty työ katoaa. Jos kyseessä oli parin tunnin työn tulos, saattaapa olla, että ohjelman käyttö katkeaa siihen.

Tällaiset tilanteet voi estää rakentamalla kaikkiin ohjelman virhealttiisiin osiin virheenkäsittelysysteemi. Tämä tehdään Visual Basicissa On Error Goto -lauseella ja nimiöillä. Opassarjan alussa vannotin, ettei Goto-käskyä ja nimiöitä saisi käyttää, mutta tässä erikoistapauksessa se on ainoa vaihtoehto.

Virhetilanteen tutkiminen

Kun On Error Goto -lause ja nimiö on määritelty, nimiöön rakennetaan tavallisesti joku virheen tunnistava järjestelmä, virheen koodi löytyy Err-erikoismuuttujasta. Edellinen esimerkki voisi olla toimivalla virheenkäsittelyllä varustettuna seuraava:

Private Sub Form_Click()
    On Error GoTo virhe

    Open "a:\testi.dat" For Input As #1
    Print #1, "Testirivi"
    Close #1

    Exit Sub
virhe:
    Select Case Err
    Case 71 'asemassa ei ole levykettä
        Dim a As Integer
        a = MsgBox("Asemassa ei ole levykettä!", vbAbortRetryIgnore)
        If a = vbRetry Then
            Resume
        Else
            Exit Sub
        End If
    Case Else 'joku muu virhe
        MsgBox "Tiedostovirhe: " & Error(Err)
        Exit Sub
    End Select
    Resume
End Sub

Jos virhe on jokin muu kuin 71 (asemassa ei ole levykettä), esimerkiksi kirjoitussuojattu tiedosto, näytetään vakiomuotoinen virheilmoitus. Error(Err) palauttaa virheilmoituksen sellaisena kuin VB sen antaa (tässä "Disk not ready"). Resume yrittää suorittaa virherivin uudestaan (käyttäjä on laittanut levykkeen).

Virhetilanteen ohittaminen

Joissain tapauksissa virhetilante on mahdollinen, mutta harmiton, esimerkiksi seuraavassa esimerkissä, jossa lasketaan 50 sattumanvaraisen kokonaislukuparin osamäärä:

Private Sub Form_Click()
    Dim i As Integer, x As Integer
    Randomize Timer
    For i = 1 To 50
        x = Int(Rnd * 50) / Int(Rnd * 50)
    Next
End Sub

Välillä, muttei aina, jakajaksi sattuu nolla, jolla jakaminen on tietenkin mahdotonta. Jos näin käy, VB tuottaa virheilmoituksen "Run-time error 11: Division by zero". Tämän ohjelman suorituksen kannalta ei kuitenkaan ole oleellista, että jokainen lasku saadaan päätökseen. Tällöin voidaan käyttää erilaista On Error -lausetta joka aina ohittaa mahdollisen virhetilanteen seuraavaan tapaan:

Private Sub Form_Click()
    On Error Resume Next
    Dim i As Integer, x As Integer
    Randomize Timer
    For i = 1 To 50
        x = Int(Rnd * 50) / Int(Rnd * 50)
        If Err = 11 Then Err = 0
    Next
End Sub

Nyt virhetilanteen sattuessa siirrytään seuraavalle riville. Potentiaalista virhepaikkaa seuraavalla riville kannattaa laittaa Err-muuttujan tarkastus, ja tarvittaessa nollata se. Tällä tavoin ohjelma ei keskeydy vaikka toiseksi numeroksi tulisikin nolla - ja koodia tarvittiin paljon vähemmän kuin On Error Goto -tavalla.

Virhetilanteet - tutkiako vai eikö?

Kuten edellisistä esimerkeistä näkyy, virhetilanteiden huomioon ottaminen lisää koodin määrää ja aiheuttaa aina lisämietittävää ohjelmoijalle. Monesti tekisikin mieli unohtaa tämä osuus ohjelman teossa, voiko näin tehdä?

Se riippuu aika paljon siitä, mihin ohjelma tulee. Jos ohjelman tekee itselleen apuohjelmaksi johonkin erikoistarkoitukseen, tällöin virhetilanteista ei kannata liikaa huolehtia, itse osaa kuitenkin pysyä erossa virhetilanteissa, kun tietää ohjelman rajoitukset. Tai jos ei osaa, sitten täytyy vain syyttää itseään.

Jos ohjelmaa rupeaa jakamaan muillekin esimerkiksi Internetissä, virhetilanteiden käsittelyn pitäisi kuitenkin olla kunnossa. Missään tilanteessa ei pitäisi olla mahdollisuutta ohjelman täydelliselle kaatumiselle. Yksikin hallitsematon virhetilanne voi antaa ohjelmasta epäluotettavan vaikutelman.

Windows Api

Vaikka Visual Basic aikoinaan kehitettiinkin vaikeakäyttöisen WinApi:n korvaajaksi, WinApi-funktiot ovat todella tarpeellisia kehittyneemmässä VB-ohjelmoinnissa. Funktioilla voi monesti tehdä sellaista, mikä pelkällä VB:llä olisi todella vaikeaa ellei mahdotonta.

WinApi:n kautta pääsee käsiksi moniin Windowsin ominaisuuksiin, jotka Visual Basicista puuttuvat tai ovat mukana yksinkertaistettuna. Lisäksi funktiot ovat poikkeuksetta nopeampia kuin VB:n omat - tämä on tärkeää etenkin grafiikkaohjelmien kanssa.

Funktioiden määritteleminen

Funktiot määritellään formin/moduulin (Declarations)-osassa Declare-lauseella. Jos funktiota halutaan kutsua sen formin/moduulin alueella, jossa se on määritelty, lauseen eteen kirjoitetaan Private-avainsana. Jos funktio määritellään moduulissa, se voi myös olla voimassa ohjelman kaikissa osissa. Tällöin käytetään avainsanaa Public.

Tekstin tulostamiseen tarkoitetun TextOut-funktion määrittely näyttää esimerkiksi seuraavalta:

Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal lpString As String, ByVal nCount As Long) As Long"

Välillä funktion parametrit sisältävät erikoismuuttujatyyppejä, jotka on määriteltävä funktiomäärityksiä ennen Type-käskyllä. Funktio voi saada myös parametreikseen tai palauttaa vakioita, jotka määritetään niin ikään (Declarations)-osassa.

Funktioiden kutsuminen ohjelmasta

WinApi-funktioita kutsutaan ohjelmasta kuin mitä tahansa muita funktioita. Esimerkiksi seuraava koodinpätkä tulostaisi äsken määritellyllä TextOut-funktiolla tekstiä formille:

x = TextOut(Me.hdc, 0, 0, "Moikka!", 7)

Kahvat

Kahvat ('handles', parempaa suomennosta en tiedä) ovat suuressa roolissa WinApi:ssa. Ne ovat lukuja, jotka yksilöivät käyttöjärjestelmän oliot, esimerkiksi ikkunat, valikot ja kuvakkeet. Kahvojen nimet parametreina alkavat yleensä h-kirjaimella.

Kaksi tärkeintä kahvaa, joita monet funktiot vaativat parametreikseen, ovat hdc ja hwnd. Hdc esiintyy tavallisesti piirtokomennoissa, ja se kuvaa piirtoaluetta. VB:ssä formilla ja PictureBox-komponentilla on automaattisesti oma hdc.

Jokaisella ikkunalla taas on hwnd-kahva, joita tarvitaan useimmissa ikkunankäsittelyfunktioissa. Tämäkin löytyy VB:stä formin attribuuttina. Näiden lisäksi on lukuisia muita kahvoja, esimerkiksi hMenu, hIcon, hCursor ja hPalette, joita käytetään samalla periaatteella.

Viimeiset loppusanat

Yhdeksän osan ja neljän kuukauden jälkeen on aika lopettaa tämä opassarja. Paljon on tullut käsiteltyä, mutta paljon on jäänyt käsittelemättäkin. Visual Basicin hyviä puolia on sen loogisuus, monet asiat oppii kokeilemalla kun perusasiat on hoidossa.

Ongelmatilanteissa ja jatkokysymyksissä auttaa usein keskustelualue, minua voi myöskin lähestyä sähköpostilla - palaute on aina tervetullutta.

Kaikki ei kuitenkaan lopu tähän - tästä eteenpäin on Ohjelmointiputkassa tarkoitus ilmestyä pienempiä eri aiheita käsitteleviä oppaita VB:lle, mukaanlukien tietokannat, resurssitiedostot ja grafiikkaa WinApi:lla.


Kommentit

progo [17.02.2003 08:25:20]

Lainaa #

Olisi voinut olla enemmänkin esimerkkejä esim. kahvoista jne..

hunajavohveli [18.04.2004 12:18:32]

Lainaa #

Mahtaisiko netistä löytyä mitään listaa WinAPI:n kaikista funktioista? Tässä kun oli mainittu vain yksi. Muuten hyvä opas, selittää hyvin, mikä WinAPI on ja miten sitä käytetään.

Waltsu [03.06.2004 21:40:50]

Lainaa #

Mistä löytäis ton ohjelman???
(visual basic 5)

jv_windy [16.06.2004 21:30:03]

Lainaa #

Meitsi [26.10.2004 15:55:03]

Lainaa #

hunajavohveli: www.msdn.com

Tatti [11.01.2008 10:08:12]

Lainaa #

Ajattelin vain tässä viimeisessä osassa kiittää oppaan kirjoittajaa. Oppaasta on ollut tosi paljon hyötyä ja alkaa tuo VB olemaankin jo jotenkin päin hanskassa, tosin vielä on paljon opittavaa. ;)

black cat [04.01.2010 17:01:45]

Lainaa #

voisko olla esimerkkejä enemmän

black cat [04.01.2010 17:02:19]

Lainaa #

siis WinAPi;sta

Kirjoita kommentti

Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta