Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VB6: MDI Formi

Lumi-ukkeli [07.12.2005 20:41:05]

#

Mitenhän kannattaa luoda uusia MDIChild-formeja niin, että niihin säilyy joku osoite tms.? Formilla ei näy olevan index-ominaisuutta ainakaan suunnittelun aikana.

Miten saa formin objektit pienenemään ja suurenemaan niin että ne täyttävät formin kun formi suurennetaan/pienennetään?

Blaze [07.12.2005 21:01:41]

#

Lumi-ukkeli kirjoitti:

Mitenhän kannattaa luoda uusia MDIChild-formeja niin, että niihin säilyy joku osoite tms.? Formilla ei näy olevan index-ominaisuutta ainakaan suunnittelun aikana.

Tee taulukko, jossa säilöt niitä formeja.

Dim MunFormit(10) As MdiForm1
Set MunFormit(0) = New MdiForm1
MunFormit(0).Show
'jne.

Lumi-ukkeli kirjoitti:

Miten saa formin objektit pienenemään ja suurenemaan niin että ne täyttävät formin kun formi suurennetaan/pienennetään?

Tuohon ei ole mitään taikakeinoa, joudut kirjoittamaan koonmuutoskoodin jokaiselle formilla olevalle kontrollille Formin Resize-eventtiin.

Merri [08.12.2005 06:55:38]

#

Taikakeinot löytyy:

' keino #1: kun formien kokoa saa muuttaa vapaasti
Private Sub MDIForm_Resize()
    If Me.WindowState = vbMinimized Then Exit Sub
    Me.Arrange vbTileHorizontal
End Sub
' keino #2: formeille on asetettu BorderStyle = 0 None
Private Sub MDIForm_Resize()
    If Me.WindowState = vbMinimized Then Exit Sub
    If Me.ActiveForm Is Nothing Then Exit Sub
    Me.ActiveForm.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
End Sub

Lisäksi jos nämä lapsiformit ovat kaikki samanlaisia, kannattaa ne ottaa käyttöön erillisen julkisen arrayn avulla. Yksinkertainen esimerkki, jonka avulla voi käsitellä ties kuinka montaa lapsiformia ja joille on annettu lisäominaisuus Filename:

' moduulissa
Public Const NO_FILENAME As String = "Nimetön"

Public Child() As frmChild

Public Function AddChild(ByVal Filename As String) As Integer
    Dim intNewIndex As Integer
    ' tarkista onko meillä yhtään formeja ennestään
    If Not ((Not Child) = True) Then
        ' tarkista onko joku lapsista poistettu käytöstä
        For intNewIndex = 0 To UBound(Child)
            ' poistetut lapset on asetettu olemattomiksi
            If Child(intNewIndex) Is Nothing Then Exit For
            ' jos poistettuja ei löytynyt, lisätään uusi
            If intNewIndex > UBound(Child) Then ReDim Preserve Child(intNewIndex)
        Next intNewIndex
    Else
        ' ei ollut formeja ei
        ReDim Child(0)
    End If
    ' sitten lapsi eloon
    Set Child(intNewIndex) = New frmChild
    ' ja asetetaan ominaisuudet
    With Child(intNewIndex)
        ' talletetaan indeksi tagiin
        .Tag = intNewIndex
        ' asetetaan tiedostonimi itse luotuun ominaisuuteen
        .Filename = Filename
        ' näkyville!
        .Visible = True
    End With
End Sub
Public Sub RemoveChild(ByVal Index As Integer)
    ' tarkista ensin onko poistettavaa
    If (Not Child) = True Then Exit Sub
    ' validi indeksi?
    If Index < 0 Then Exit Sub
    If Index > UBound(Child) Then Exit Sub
    ' poista se
    Set Child(Index) = Nothing
End Sub


' frmChildissa:

Dim m_Filename As String

Public Property Get Filename() As String
    Filename = m_Filename
End Property
Public Property Let Filename(ByVal NewValue As String)
    m_Filename = NewValue
    ' tällainen on ihan hyvä tehdä, sitä voi sitten säätää haluamallaan tavalla
    UpdateCaption
End Property
Public Sub UpdateCaption()
    ' tarkista onko tiedostonimeä
    If LenB(m_Filename) > 0 Then
        Me.Caption = m_Filename
    Else
        Me.Caption = NO_FILENAME
    End If
End Sub


' käyttötapoja:
AddChild Tiedostonimi
Indeksi = AddChild(Tiedostonimi)
RemoveChild Indeksi
Child(Indeksi).Filename = Tiedostonimi

Järkevää olisi tietysti koodata tiedostonlatausrutiini ja niin pois päin. Eiköhän tällä tietovyöryllä kuitenkin pääse vauhtiin.

Ai joo... sitten vielä semmoinen asia, että tuo arrayn olemassaolon tarkistaminen (eli (Not Array) = True) aiheuttaa outoja ongelmia IDE:n alla: seuraavan kerran kun käsitellään liukulukuja, nousee IDE:ssä virhe (käännetyssä ohjelmassa ongelmaa ei ole). Olen itse ratkaissut ongelman yksinkertaisesti teettämällä virhelaukaisun joka kerta sen jälkeen, kun IDE:ssä tarkistetaan arrayn koko. Tässäpä sekin moduuli samaan syssyyn:

' modFloatingPointError.bas

' this module has only one purpose: to get rid of the floating point error under IDE
' this error happens each time when floating point calculation is done after (Not Array) = True is used
Option Explicit

Private Function InDebug(ByRef blnResult As Boolean) As Boolean
    blnResult = True
End Function
' you can use this to detect if you are under IDE
Private Function InIDE() As Boolean
    Debug.Assert True Xor InDebug(InIDE)
End Function
' KAFPE = Kill the Annoying Floating Point Error
Public Sub KAFPE()
    If Not InIDE Then Exit Sub
    Dim lngTemp As Long
    On Error Resume Next
    lngTemp = CLng(0.1)
    Err.Clear
    On Error GoTo 0
End Sub

Naatiskelkaa. Tuo KAFPE siis kutsutaan ennemmin tai myöhemmin (Not Array) = True jälkeen.

Merri [08.12.2005 12:07:44]

#

Jaahas, jäi tuossa aamusella välistä sana "objektit" ja nyt ei voi enää korjata viestiään. Kunnon "taikakeinoa" siihen ei ole, mutta netistä löytyy joitakin automaattisesti kontrollien kokoa muuttavia ActiveX-kontrolleja. Ne kuitenkin noin pääpiirteittäin tuottavat huonon lopputuloksen, joten Form_Resize on se ainoa järkevä vaihtoehto.

Vastaus

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

Tietoa sivustosta