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 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.
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.