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?
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.
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 SubLisä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 = TiedostonimiJä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 SubNaatiskelkaa. Tuo KAFPE siis kutsutaan ennemmin tai myöhemmin (Not Array) = True jälkeen.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.