Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: [VB6] Control Array Indexin laskeminen (VB.NET)

Sivun loppuun

rautamiekka [20.10.2008 18:15:04]

#

Softassa, jossa on kontrolleja ohjaustaulukossa, ei varmaan kannata käyttää Select Case tai If selvittämään mitä kunkin kontrollin kohdalla pitäisi tehdä ? Puhumattakaan jos kaikille samassa CAI:ssa oleville kontrolleille pitäisi tehdä täsmälleen sama koodi, hirveää toistoa, eikö ? Mitä tehdä ?

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    lblButton(Index).BorderStyle = 0
End Sub

Private Sub frame_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    lblButton(Index).BorderStyle = 0
End Sub

Private Sub lblButton_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
    lblButton(Index).BorderStyle = 1
End Sub

Ylläoleva koodi toimii lblButton(0) kohdalla, mutta ei seuraavien kohdalla, siis ensiksi mainittu käyttäytyy kuin kuuluu mutta muut ei. Lisäksi lblButton(1) pitää BorderStyle:n samana vaikka mitä tekisi. Mitä kannattaisi tehdä ?

sqwiik [20.10.2008 18:21:24]

#

Kannattaa pitää päällä VB:n kanssa Option Explicit... Index-muuttujalla on oikea arvo vain tuolla lblButton_MouseMove-aliohjelmassa, frame_MouseMove-aliohjelmassa sen arvo on aina 0. Tuollaisessa systeemissä kannattaisi käyttää ylimääräistä muuttujaa jossa pidät muistissa viimeisintä indeksiä.

' Jossain tämä:
Public Viimeisin As Integer

Private Sub frame_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    lblButton(Viimeisin).BorderStyle = 0
End Sub

Private Sub lblButton_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
    lblButton(Index).BorderStyle = 1
    Viimeisin = Index
End Sub

Siitä on kauan kun VB:n päälle viimeksi mulkaisin, saatan olla väärässäkin.

Merri [20.10.2008 19:17:50]

#

Pitää myös huomata, että myös lblButton_MouseMovessa pitää tehdä viimeisimmälle nollaus, mikäli Viimeisin ei ole sama kuin Index.

Private Sub lblButton_MouseMove(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
    If (Index <> Viimeisin) Or (lblButton(Index).BorderStyle = 0) Then
        lblButton(Viimeisin).BorderStyle = 0
        lblButton(Index).BorderStyle = 1
        Viimeisin = Index
    End If
End Sub

Eli nyt jos indeksi on eri tai jos BorderStyle ei ole tämänhetkisellä päällä, niin sitten nollataan edellinen kytketään päälle nykyinen.

rautamiekka [20.10.2008 19:38:56]

#

Sqwiikin ja Merrin koodit toimivat kun käyttää molempia :)

Ihmettelen vain, miten alussa BorderStyle:n vaihto voi yleensäkään toimia frame_- ja Form_MouseMovessa kun se kerran on nolla ?

Merri [20.10.2008 19:49:42]

#

Kun sinulla ei ole Option Explicit käytössä, niin Index-muuttuja luodaan automaattisesti ja sen arvo on nolla, koska sitä ei muuallakaan ole asetettu. Tällöin framen ja Formin MouseMovet pelittävät aina vain nollaindeksille.

rautamiekka [20.10.2008 20:28:43]

#

Nyt on Option Explicit käytössä. Miten koodi pitäisi muuttua nyt ?

(Mod. huom: turhien viestien lähettäminen ei auta asiaa.)

Grez [21.10.2008 17:51:12]

#

Ei se koodi mitenkään siitä muutu, mutta kääntäjä antaa virheilmoituksen, jos yrität käyttää muuttujaa jota ei ole määritelty (kuten tuo index tuossa alkuerpäisessä frame_MouseMove:ssasi). Eli et turhaan ihmettele miksi saat johonkin arvon 0 kun kehitysympäristö kertoo sinulle suoraan että "hei, et oo määritellyt tällaista muuttujaa, mitä oikein luulet tekeväsi?"

Varsinaiset muutoksethan jos tuossa kerrottiinkin, tuo Option Explicit oli lähinnä kommentti tuohon ihmettelyysi 20.10. 19:17

Ja se Option Explicit kannattaa tosiaan aina olla käytössä. Itse asiassa idioottimaista Microsoftilta, että se on oletuksena pois päältä. (muistaakseni)

Eli Optionsiin vaan Editor välilehdelle ruksi siihen kohtaan "Require Variable Declaration" niin se läpsii aina uusiin tiedostoihin automaagisesti sen Option Explicit:n alkuun.

Metabolix [21.10.2008 17:56:29]

#

Option Explicit ei vaikuta siihen, miten tuo toiminto pitää toteuttaa, vaan vain siihen, että määrittelemättömän muuttujan käyttö aiheuttaa virheen. Kokeilepa sen kanssa esimerkiksi alkuperäistä koodiasi, niin huomaat, miksei se toiminut. Syy on tuo, jonka Merri juuri selitti.

Grez kirjoitti:

Itse asiassa idioottimaista Microsoftilta, että se on oletuksena pois päältä.

Käsittääkseni VB.Net on kuitenkin tehnyt parannuksen.

Merri [21.10.2008 18:03:53]

#

Vain sillä, että kaikki käytettävät muuttujat täytyy määrittää — käytännössä siis Dim jokaista muuttujaa kohden. Muuta muutosta ei tapahdu. Jos muuttujaa ei ole määritetty, niin ilman Option Explicitiä se luodaan lennosta Variant-tyyppisenä; Option Explicitin kanssa tulee virhe. Yleensä on järkevä määrittää sopivin mahdollinen muuttujatyyppi: jos teet merkkijonoa, määritä merkkijonoksi, jos käsittelet valuuttoja, käytä Currencyä, jos vaan tarvitsee laskea isoja lukuja tai tarvitse desimaaleja, eikä tietyn tason pyöristäminen haittaa, käytä Doublea ja niin edelleen. Yksi huomattava muuttujien määrittämisen hyöty on se, että se paljastaa monta helposti huomaamattomaksi jäävää bugia, kuten kirjoitusvirheen tai muuttujan käyttämisen sellaisessa paikassa, jossa sitä ei ole.


Sitten yksi asia, jota et varmaan vieläkään ole täysin tajunnut, jolla ei ole mitään tekemistä Option Explicitin kanssa:

' Form1.frm
Option Explicit

' Tämä muuttuja on käytettävissä kaikkialla Form1:ssä, mutta ei ole käytettävissä sen ulkopuolella.
Dim YksityinenMuuttuja As String

' Sama kuin edellinen, mutta selvemmin tarkoitusperän esille tuoden (suosittelen tätä tapaa, parantaa koodin luettavuutta).
Private YksityinenMuuttuja2 As String

' Tämä muuttuja on käytettävissä myös Form1:n ulkopuolella, kutsuminen onnistuu muodossa Form1.JulkinenMuuttuja
Public JulkinenMuuttuja As String

' Tämä Index on käytettävissä vain Command1_Click:ssä! Se on tarjottu parametrinä proseduuriin, joten muualla siitä ei ole tietoa.
Private Sub Command1_Click(Index As Integer)
    ' Ongelma: meillä on jo YksityinenMuuttuja Form1:ssä! Miten käy?
    Dim YksityinenMuuttuja As String

    ' Vastaus: tämä on eri YksityinenMuuttuja, joka on paikallinen vain Command1_Click:lle. Muutokset siinä eivät tallennu muualle tai seuraavaan kutsuun.
End Sub

Private Sub Command2_Click()
    ' Proseduuriin määritetty static-muuttuja muistaa arvonsa kutsusta toiseen. Paikallinen vain Command2_Click:lle.
    Static PysyväMuuttuja As String
    PysyväMuuttuja = PysyväMuuttuja & "."
    MsgBox PysyväMuuttuja
End Sub
' Module1.bas
Option Explicit

' Mitä mitä mitä? Tämä muuttuja onkin julkinen? Kyllä vain, tätä muuttujaa voi käyttää missä tahansa päin projektia.
' Paikallisemmat muuttujat kuitenkin ovat tärkeämpiä. Tähän muuttujaan voi kuitenkin viitata suoraan myös käyttäen Module1.JulkinenMuuttuja
Dim JulkinenMuuttuja As String

' Kuten äskeinen Dim, mutta selvemmin ymmärrettävissä.
Public JulkinenMuuttuja2 As String

' Tämä muuttuja onkin sitten paikallinen, eli käytettävissä vain Module1:ssä.
Private YksityinenMuuttuja As String

Tämä toivottavasti selventää tilannetta.

rautamiekka [03.11.2008 02:53:51]

#

Merri on mukavan pitkäpinnainen kun jaksaa selventää pilkun viilaamista tälläiselle aloittelijantapaiselle :)

[Oma edit]
Miten tässä tredissä sovellettua koodia voi soveltaa myös samassa softassa, jossa on tarkoitus saada klikattaessa kyseisen klikatun painikkeen tekstin menemään ISOILLE kirjaimille ? Kun on klikattu ja teksti muuttunut isoksi, pitäisi erikseen formille tehty erillinen Frame liusua esiin, paljastaen klikatun painikkeen alivalinnat.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta