Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: VBA: Ikkunan skaalaus ja ActiveX

Sivun loppuun

kisahalo [17.11.2010 11:26:11]

#

Ongelmiani on kaksi: Ohjelmani sisältää paljon pictureboxeja, joihin on piirretty perustyökaluilla aika paljon kaikenlaista. Nyt huomasin, että eri resoluutioissa koko formi vääristyy ikkunan koon muuttuessa. Napit menevät outoihin paikkoihin, picturebox ei näy oikein jne. Miten formin saisi skaalautumaan nätisti eri resoluutioissa?

Toinen koskee .exen tekemistä: Miksi kääntämisen jälkeen jos ohjelmaa yrittää käynnistää toisella koneella tulee "Error: ActiveX can't create component"?

neau33 [17.11.2010 13:41:57]

#

Moi kisahalo!

kisahalo kirjoitti:

...huomasin, että eri resoluutioissa koko formi vääristyy ikkunan koon muuttuessa. Napit menevät outoihin paikkoihin, picturebox ei näy oikein jne. Miten formin saisi skaalautumaan nätisti eri resoluutioissa?

Ainoa varma tapa pitää kontrollien suhteet on selvittää resoluutio heti ohjelman alussa + rakentaa kontroll-map systeemi johon tallennetaan kontrollien mittasuhteet prosentteina verattuna kulloiseenkin näytön resoluutioon. Riittää jos systeemi liitetään Form_Resize tapahtumaan mikäli resoluutiota ei muuteta kesken ohjelman ajon. Mikäli resoluutiota muutetaan kesken ajon on ohjelmaan sisällytettävä toiminto, joka haistelee resoluutiota jne.

kisahalo kirjoitti:

...koskee .exen tekemistä: Miksi kääntämisen jälkeen jos ohjelmaa yrittää käynnistää toisella koneella tulee "Error: ActiveX can't create component"?

Johtuu siitä, ettei sille toiselle koneelle ole asennettu ko. ActiveX-komponenttia tai ko. ActiveX-komponenttia ei ole rekisteröity. Rekisteröinti voidaan suorittaa regsvr32.exe -ohjelmalla
Käynnistä -> Suorita -> regsvr32 asema\polku\tiedostonimi.ocx - OK
(tai tiedostonimi .dll)
.ocx kontrollit ja VB6-runtime .dll kirjastot sijaitsevat yleensä C:\WINDOWS\System32 -hakemistossa

kisahalo [17.11.2010 13:49:04]

#

neau33: Kiitos vastauksesta. Onko tuollainen virheilmoitus poikkeus vai sääntö? Tarkoitukseni olisi saada ohjelmasta sellainen, että se toimisi moitteitta koneessa kuin koneessa.

neau33 [17.11.2010 16:44:40]

#

Moi taas kisahalo!

Tuollainen virheilmoitus on sääntö silloin, kun kohdekoneelle ei ole asennettu ao. AxctiveX-komponenttia ja todella harvinainen poikkeus silloin, kun ao. AxctiveX-komponentti on asennettu ja asianmukaisesti rekisteröity.

Kaikki riippuu paljolti VB6-editiosta (standard/pro/enterprise). Esim Standard-versiosta pitäisi löytymän SP5 & SP6-pakettien asentamisen jälkeen lähes kaikki .ocx'ät mutta Standard-versiolla et pysty liittäämään läheskään kaikki haluamiasi ActiveX-komponentteja asennusohjelmaasi, johtuen julkaisuoikeuksista. Sen sijaan esim. Enterprise-versiolla pääsee julkaisemaan kaikki komponentit (julkaisuoikeuksista maksettiin suoraan VB6 Enterprise-version hinnassa).
Nyt on vielä niin, että esim. VB6:lla tehty asennusohjelma tekee asennusohjelmaan liitetyistä lisenssin vaativista ActiveX-komponentteista runtime-version joka asentuu asiakkaan koneelle automaattisesti asennusohjelman suorittamisen yhteydessä. Näitä runtime-versioita ei voi ladat esim. VBA-projektehin (tai voi, mutta ne eivät toimi).
Koska siitä on jo lähes valovuosi, kun koneellani oli viimeksi VB6 Enterprise Edition (en asenna sitä enään) en pysty kuvailemaan sinulle suoraan mitä valintoja asennusohjelman tekemisen alussa piti suorittaa, että halutut komponentit sisällytettiin asennuspakettiin ja miten määriteltiin se mihin hakemistoon ne kulloinkin asentuivat kohdejärjestelmässä. Muistan kuitenkin että myös Pro-versiossa on samat ominaisuudet asennuspakettien tekemiselle, Standard versiosta minulla ei ole juurikaan kokemusta. Lisäongelmia tuottavat usein myös ns. third party-komponentit.

kisahalo [22.11.2010 10:06:44]

#

Kiitos. :) Osaisitko vielä auttaa tuon ikkunan skaalauksen kanssa?

Olen nyt googlannut aika paljon, mutten löydä mitään järkevää tapaa skaalata ikkuna resoluutioon sopivaksi. Ainoa minkä löysin, oli neuvo vaihtaa SSTab TabStripiin, koska SSTab on erityisen ongelmallinen skaalauksessa. Yritän välttää viimeiseen saakka screen.widht- ja screen.height-kikkailua, koska minulla on paljon Line-toiminnolla piirrettyä grafiikkaa.

neau33 [22.11.2010 14:21:35]

#

Moi taas kisahalo!


Jos aiot saada jotain toimivaa aikaiseksi niin opiskele tämä kunnolla!!!

kisahalo [23.11.2010 09:43:14]

#

Kiitos jälleen, tuo auttaa eteenpäin jo huomattavasti. :)

Ainoa (suuri) ongelma, joka jää, on se, että skaalattaessa SSTabia se hävittää kaikki pictureboxit sisemmillä välilehdillään. Juuri nuo pictureboxit ovat suurin ongelma, sillä niissä on suurin määrä dataa.

Luin netistä jotain juttuja, joiden mukaan ongelma on SSTabissa ja että pitäisi käyttää TabStripia, mutta TabStripin välilehdille ei tunnu saavan mitään liitetyksi. Multipagessa sama juttu. :/

groovyb [23.11.2010 09:48:41]

#

itse varmaan ensin skaalaisin formin resoluutioon sopivaksi, jonka jälkeen loisin dynaamisesti pictureboxit ja muut kontrollit.

kisahalo [23.11.2010 10:05:28]

#

groovyb kirjoitti:

itse varmaan ensin skaalaisin formin resoluutioon sopivaksi, jonka jälkeen loisin dynaamisesti pictureboxit ja muut kontrollit.

Hyvä idea, mutta ei välttämättä poista SSTabin ongelmaa. Käytin tosiaan tuota neau33:n linkin koodia ja siinä käy niin, että kaikki kontrollit katoavat muilta välilehdiltä. Löysin sitten tällaisen: http://support.microsoft.com/kb/187562
mutta sekään ei auta kontrollien katoamiseen (ellen sitten evota :/).

neau33 [23.11.2010 11:59:24]

#

Moi taas kisahalo!

Kokeile käyttää indeksoituja groupboxeja Tab-kontrollin sijaan siten, että asetat indeksoituja nappeja riiviin aivan groupboxien yläpuolelle. Älä aseta groupboxeja design tilassa päällekkäin (etteivät mene sisäkkäin). GroupBoxit esim. GroupBox1(0), GroupBox1(1), jne. Napit esim. btnGroupShow1(0), btnGroupShow1(1), jne. (voit myös korvata indeksoidut GroupBoxit indeksoiduilla Frame-objekteilla).

Private Sub Form_Load()

   For Each Control In Me Controls
      If InStr(Control.Name, "GroupBox1") > 0 Then
         Dim gbx As GroupBox
         Set gbx = Control
         If gbx.Index > 0 Then
            gbx.Left =  GroupBox1(0).Left
            gbx.Top =  GroupBox1(0).Top
            gbx.Width =  GroupBox1(0).Width
            gbx.Height =  GroupBox1(0).Height
            gbx.Visible = False
         End If
         Set gbx = Nothing
      End If
   Next

   '...
   '...
   '...

End Sub

Private Sub btnGroupShow1_Click(Index As Integer)

   If GroupBox1(Index).Visible Then
     Exit Sub
   End If

   For Each Control In Me Controls
      If InStr(Control.Name, "GroupBox1") > 0 Then
         Dim gbx As GroupBox
         Set gbx = Control
         If gbx.Index = Index Then
             gbx.Visible = True
         Else
             gbx.Visible = False
         End If
         Set gbx = Nothing
      End If
   Next

End Sub

'Koska koneellani ei ole enään VB6:sta (enkä sitä asenna) niin en voi antaa VB6:lla testattua esimerkkiä, mutta tässä VBA:lla testattu jutska, joka valottaa ehkä hieman Frame & MultiPage-kontrollien skaalautumista (esimerkillä ei sinällään ole mitään tekemistä näytön resoluutiomuutosten kanssa).

'testattu Excel/VBA:lla
'Formille 3 nappia, frame & multipage
'(1. nappi formille, 2. framen sisällä & 3. TabPage1 sisälle)
Private ButtonScaleFactoryX As Integer
Private ButtonScaleFactoryY As Integer
Private ButtonLocationFactoryX As Integer
Private ButtonLocationFactoryY As Integer

Private Type ControlMap
   Ctl As Control
   SizeFactoryX As Integer
   SizeFactoryY As Integer
   LocationFactoryX As Integer
   LocationFactoryY As Integer
End Type

Private FormControlsMap() As ControlMap

Private Sub UserForm_Activate()

   ReDim FormControlsMap(Me.Controls.Count)
   Dim i As Integer: i = -1

   For Each Control In Me.Controls
      i = i + 1
      Set FormControlsMap(i).Ctl = Control
      FormControlsMap(i).LocationFactoryX = Me.Width / Control.Left
      FormControlsMap(i).LocationFactoryY = Me.Height / Control.Top
      FormControlsMap(i).SizeFactoryX = Me.Width / Control.Width
      FormControlsMap(i).SizeFactoryY = Me.Height / Control.Height
   Next

End Sub

Private Sub UserForm_Resize()

   For Each Control In Me.Controls

      Dim i As Integer

      For i = LBound(FormControlsMap) To UBound(FormControlsMap)

         If Control Is FormControlsMap(i).Ctl Then
            FormControlsMap(i).Ctl.Left = (Me.Width _
            / FormControlsMap(i).LocationFactoryX)
           FormControlsMap(i).Ctl.Top = (Me.Height _
           / FormControlsMap(i).LocationFactoryY)

            If TypeName(Control) = "Frame" Then
                FormControlsMap(i).Ctl.Width = (Me.Width _
                / (FormControlsMap(i).SizeFactoryX * 1.075))
                FormControlsMap(i).Ctl.Height = _
                (Me.Width / (FormControlsMap(i).SizeFactoryY * 1.075))
            ElseIf TypeName(Control) = "MultiPage" Then
                FormControlsMap(i).Ctl.Width = (Me.Width _
                / (FormControlsMap(i).SizeFactoryX * 1.075))
                FormControlsMap(i).Ctl.Height = _
                (Me.Width / FormControlsMap(i).SizeFactoryY)
            Else
                FormControlsMap(i).Ctl.Width = (Me.Width _
                / FormControlsMap(i).SizeFactoryX)
                FormControlsMap(i).Ctl.Height = _
                (Me.Height / FormControlsMap(i).SizeFactoryY)
            End If

         End If

      Next i

   Next Control

End Sub

Private Sub CommandButton1_Click()

   'Testi...
   Me.Width = Me.Width + 150
   Me.Height = Me.Height + 100

End Sub

kisahalo [23.11.2010 15:01:07]

#

Oi, toimii. Kiitos paljon vastauksesta! :)


Sivun alkuun

Vastaus

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

Tietoa sivustosta