Een gebruikersformulier centreren op een scherm

Hallo
We hebben allemaal PC's met 2 schermen en in een macro heb ik een userform die de vervelende neiging heeft om op het verkeerde scherm te openen (Solidworks op het linkerscherm bijvoorbeeld en userform op het rechterscherm)
Op Excel had ik deze code die heel goed werkt:

Private Sub UserForm_Initialize()
    '-------------------------------------------------------- Positionnement UserForm
    Me.StartUpPosition = 0                                                  'Déclarer position MANUAL
    Me.Left = Application.Left + Application.Width / 2 - Me.Width / 2
    Me.Top = Application.Top + Application.Height / 2 - Me.Height / 2
End Sub

Maar deze code veroorzaakt een 438-fout
Het enige gevonden onderwerp dat hier in de buurt komt, is dit en de antwoordpagina is niet meer toegankelijk. (Prb Userform - #7 door jfaradon)
Als iemand weet hoe dit probleem op te lossen.

1 like

Hallo

StartUpPosition u wijzigt het rechtstreeks in het eigenschappenvenster, u hoeft het niet in VBA te doen

voorbeeld

UserForm1.Move 100, 100 'Uniquement pour déplacer à gauche et en haut.
UserForm1.left = 100 'pour déplacer latéralement
UserForm1.Top = 100 ' pour déplacer verticalement
UserForm1.Move 100, 100, 250, 190 'pour tout modifier


Private Sub UserForm_Initialize()
UserForm1.Move 100, 100, 250, 190
End Sub
2 likes

Ja op . Move is wat ik nu heb, maar is een probleem met 2 schermen.
Huidige code:

Private Sub UserForm_Initialize()
    With Me
        .StartUpPosition = 3
        .Move 100, 100
    End With
End Sub

Maar het probleem is dat als het solidworks-venster op het linkerscherm staat (2 schermen), geen zorgen dat de userform ruim boven SW staat.
Maar als de gebruiker Solidworks op zijn rechterscherm heeft gezet, komt de userform op het linkerscherm terecht, tegenover SW.
Daarom ben ik op zoek naar een alternatief zoals in Excel (code van het 1e bericht, maar niet functioneel in SW.

Ik zie 1 probleem
de USF met startupositie op 1-centerowner zou de USF in het midden moeten plaatsen van de applicatie die het heeft gelanceerd, wat niet het geval is

" application.something " werkt niet

zie dit onderwerp waar ik de applicatie moest vervangen, ik denk dat het hetzelfde principe is, op dit moment heb ik het niet gevonden

2 likes

Hallo @sbadenis
Probeer dit eens

Public swapp as sldworks.Sldworks

En

Private Sub UserForm_Initialize()
    '-------------------------------------------------------- Positionnement UserForm
    Me.StartUpPosition = 0                                                  'Déclarer position MANUAL
    Me.Left = swapp.Frameleft + swapp.Framewidth / 2 - Me.Width / 2
    Me.Top = swapp.Frametop + swapp.Frameheight / 2 - Me.Height / 2
End Sub
2 likes

Hallo
Het antwoord van @Lynkoa15 lijkt goed, aan de andere kant heb ik getest en de geretourneerde waarden zijn nogal vreemd.
Het geeft me de volgende waarden voor een dubbel scherm ingesteld op het scherm waar SW open is in 1680x1050:
Links = 897
Breedte = 1024
Boven = 0
Hoogte = 768
Dit heeft tot gevolg dat het UserForm in het midden van de twee schermen wordt geplaatst.
Om het op het linkerscherm te houden (voor mij staat SW aan de linkerkant op het hoofdscherm) heb ik Swapp.FramLeft verwijderd uit de berekening voor Me.Left.
Het plaatste de UserForm op het linkerscherm, niet echt gecentreerd in het venster in de breedte, de hoogte is goed, zelfs als de hoogte niets te maken heeft met mijn schermresolutie.

1 like

Cyrille, het is vreemd, ik heb geen dubbel scherm en ik heb het niet getest, maar als je hiermee het venster naar het tweede scherm kunt schakelen, moet een analyse van de discrepantie met de afmetingen van het laatste mogelijk zijn, misschien een verschil tussen de schermresolutie en de schermresolutie van Windows

1 like

Ik heb niet dezelfde resolutie tussen het linkerscherm en het rechterscherm. Misschien komt het daar vandaan, ik zal nog een keer een test doen met een enkel scherm om te zien.

1 like

Voor mij niet helemaal gecentreerd op het linkerscherm en op het rechterscherm volledig uit het midden.
Door iets uit het midden haakjes toe te voegen op de 2 schermen (dezelfde grootte), kom ik dichter bij de waarheid, maar er is nog steeds een beetje raar gedrag en anders dan de oplossing in excel.

    Me.Left = ((swapp.FrameLeft + swapp.FrameWidth) / 2) - (Me.Width / 2)
    Me.Top = ((swapp.FrameTop + swapp.FrameHeight) / 2) - (Me.Height / 2)

Geen tijd om de komende 2-3 dagen te graven, het werk haalt me in.
Ik neem zo snel mogelijk contact met je op.
In ieder geval, @Lynkoa15 , is uw oplossing de dichtstbijzijnde en meest functionele tot nu toe!

Hallo @sbadenis ,

Inderdaad, Windows beheert de twee schermen als één door pixels in de breedte te verzamelen.
Dit wordt bevestigd door de bijgevoegde macro, die in stukken van het net is opgepikt en is aangepast om de afmetingen van de twee schermen en de positie van het SolidWorks-venster terug te geven.

De discrepantie die is waargenomen bij het gebruik van het voorstel van @Lynkoa15 lijkt mij verband te houden met een verwarring van eenheden voor de schermcoördinaten:

  • De afmetingen en positie van het UserForm-formulier (. Links. Boven. Widt en . Hoogte) worden gedefinieerd door VBA in schermpunten.
  • De afmetingen en positie van het SolidWorks-venster geretourneerd door . Kader Links, . FrameBreedte, . FrameTop en . FrameHeights worden door Windows gedefinieerd in pixels.
    De verhouding tussen de twee units is afhankelijk van het scherm zelf, maar is meestal 4/3.

Ik heb een correcte positie van het formulier in het midden van het SolidWorks-venster met de volgende uitdrukkingen, ongeacht het gebruikte scherm:

With UserForm1
   .Left = (swApp.FrameLeft + swApp.FrameWidth / 2) * 3 / 4 - (.Width / 2)
   .Top = (swApp.FrameTop + swApp.FrameHeight / 2) * 3 / 4 - (.Height / 2)
End With

Vriendelijke groeten.
DoubleEcran.swp (115.5 KB)

1 like

@m_blt ik snel heb getest, gecentreerd op mijn linkerscherm, als ik SW naar het rechterscherm schakel, is het niet gecentreerd.
Ik zal morgen nog een test doen als ik tijd heb.

1 like

Hetzelfde als @Cyril_f , @m_blt niet echt gecentreerd en verschuiven naar de hoogte, de verhouding corrigeert de fout niet, en op meer dan 20 infoberichten ben ik bang dat het helaas erg willekeurig zal zijn.

Ik denk dat we de juiste verhouding zullen moeten meten
3/4 werkt niet op mijn basisscherm (geen tweede scherm)
Ik heb geprobeerd de technische fiche te zien


Ik denk dat we het moeten berekenen
(145/25.4/(1920/210.24))=0.62 (de juiste verhouding voor mij)
Ik denk dat dit hetzelfde is voor een tweede scherm, alleen als ze dezelfde ppi hebben
Vanuit dit oogpunt stel ik voor om met twee verhoudingen te werken, bijvoorbeeld als het aantal pixels groter is dan 1920 (bijvoorbeeld) de eerste (of tweede) pixels berekenen met de eerste verhouding en de rest optellen met een berekening van de andere verhouding

1 like

Hoi allemaal

Het is waar dat het gebruik van " schermpunten " door VBA vaak problematisch is, te oordelen naar de discussies op verschillende forums (vaak gewijd aan Excel of Access).
De oplossing is om er vanaf te komen door Windows API-functies te gebruiken die alleen pixels gebruiken.
De bijgevoegde macro is een aanpassing van de vorige, die zijn werk doet op mijn pc met twee schermen. Het formulier UserForm1 is gecentreerd op het SolidWorks-venster.
Snelle test: Als het SolidWorks-venster wordt verplaatst, wordt het gebruikersformulier opnieuw ingesteld door op de knop " Midden " te klikken.

Vriendelijke groeten.
DoubleEcran.swp (171.5 KB)

1 like

Hallo @tous
@m_blt je macro overtreft :sweat_smile:me.
Dus probeerde ik de functie die ik eerder noemde te ontwikkelen, rekening houdend met je opmerking over eenheden.

Ik heb je een klein eenvoudig hulpmiddel ter beschikking gesteld waarmee je de verhoudingen kunt berekenen (ik hoop dat het zal werken :roll_eyes:)
Macro1.swp (76 kB)
Macro2.swp (56 kB)
Doc1.pdf (237.9 KB)

2 likes

Allereerst hartelijk dank voor de tijd die ik eraan heb besteed, ik had niet gedacht dat het centreren van een userform op het SW-venster zo ingewikkeld zou zijn!
@Lynkoa15 oplossing is eenvoudig, maar aangezien deze macro op meer dan 20 werkstations zal worden gebruikt met een aantal scherm(en) van 1 tot 2, meestal 2, en van totaal verschillende grootte en verhouding.
Daarnaast bestaat het rantsoenprobleem ook op de hoogte. Daarom denk ik erover om me te wenden tot de @m_blt oplossing die perfect werkt.
@m_blt aan de andere kant heb ik een beetje moeite om je macro te begrijpen omdat het zo compleet is.
Ik geef toe dat ik mijn grenzen bereik als autodidactische ontwikkelaar.
Ik nam uw code in een vereenvoudigde macro met een userform zonder iets edt Ik kan het niet aan te passen.
Is het nodig om in de aanroep de 2 argumenten (tekstvak 1 en 2) te hebben:
CoincidentsCtresWindows UserForm1.TextBox1, UserForm1.TextBox2, Waar
En niet alleen
CoincidentsCtresWindows UserForm1 , Waar
Ik heb geprobeerd uw code te wijzigen zonder te bereiken wat ik wilde (gecentreerd het venster alleen met de naam van het gebruikersformulier)

Hallo @sbadenis ,

Sorry, ik ben een fan van het gezegde " Waarom maak je het simpel als je het ook ingewikkeld kunt maken? ".
image

Bijgevoegd is de centrerende macro van het VBA-venster op het SolidWorks-venster, ontdaan van alle TextBox, ListBox en andere knoppen. De enige functie is om de UserForm VBA in het midden van het SolidWorks-venster te plaatsen wanneer deze voor het eerst wordt weergegeven.
Het werkt op mijn pc, met één of twee schermen. Ik heb het niet met drie geprobeerd...

De voorwaarden zijn als volgt:

  • SolidWorks is ingeschakeld (wat in principe het geval is sinds de macro is gelanceerd);
  • de hoofdmodule heet CentrageUsrFrm en bevat alleen de hoofdprocedure;
  • In de hoofdprocedure is de eerste parameter die wordt doorgegeven aan de functie CoincidentsCtresWindows het bijschrift van het SolidWorks-venster, hardgecodeerd: " SOLIDWORKS ".
    De tweede parameter is die van de UserForm, die wordt opgehaald via de caption-eigenschap;
  • De IdentFenetres module bevat de twee functies die gebruik maken van de Windows API's om de afmetingen van de vensters op te halen en de positie van het UserForm te berekenen. Deze module behoeft in principe geen wijzigingen.

Vriendelijke groeten.
CentrerenUsrFrm.swp (102 kB)

2 likes

Het werkt perfect zoals voor de vorige, maar het is nu veel gemakkelijker te begrijpen! :crazy_face:
Bedankt voor de uitleg en de vereenvoudigde macro!
Ook al blijft het ingewikkeld om door de Windows-API's te gaan om een eenvoudig venster te centreren, het blijft in ieder geval de enige haalbare oplossing (meerdere werkstations en verschillende schermen)

Hallo @sbadenis ,

Tevreden om te zien dat dit bij je past...

Wat het gebruik van Windows-API's betreft, zijn er geen andere oplossingen, aangezien Windows de vensters van de verschillende applicaties beheert. SolidWorks zelf, wanneer het de posities en afmetingen van zijn eigen venster (FrameLeft, FrameWidth, enz.) retourneert, gebruikt waarschijnlijk Windows-API's.

We zouden waarschijnlijk de twee functies van de IdentFenetres-module kunnen " verbergen " in een dll, waardoor de module kan worden verwijderd en er slechts twee regels in de macro overblijven om de UserForm te centreren.
Maar het is de installatie op verschillende werkstations die lastig zou worden: locatie van de dll, registratie in het Windows-register). Het voordeel van de macro is dat hij volledig autonoom is vanuit het oogpunt van installatie.

Vriendelijke groeten.

2 likes

Ja inderdaad, het is heel goed mogelijk, het is alleen raar dat solidworks niet iets heeft geïmplementeerd om deze functie te vereenvoudigen, bijvoorbeeld via een dll!
En het zal me gewoon nog een andere module in mijn macro maken die al goed is voorzien, niets om me zorgen over te maken.
En nogmaals bedankt.

1 like