Zentrieren eines Benutzerformulars auf einem Bildschirm

Hallo
Wir alle haben PCs mit 2 Bildschirmen und in einem Makro habe ich ein Benutzerformular, das die lästige Tendenz hat, auf dem falschen Bildschirm zu öffnen (Solidworks auf dem linken Bildschirm zum Beispiel und Benutzerformular auf dem rechten Bildschirm)
In Excel hatte ich diesen Code, der sehr gut funktioniert:

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

Dieser Code verursacht jedoch einen 438-Fehler
Das einzige gefundene Thema, das dem nahe kommt, ist dieses und die Antwortseite ist nicht mehr zugänglich. (Prb Userform - #7 von jfaradon)
Wenn jemand weiß, wie man dieses Problem beheben kann.

1 „Gefällt mir“

Hallo

StartUpPosition Sie ändern es direkt im Eigenschaftenfenster, es ist nicht erforderlich, dies in VBA zu tun

Beispiel

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 „Gefällt mir“

Ja auf . Move ist das, was ich jetzt habe, aber ist ein Problem mit 2 Bildschirmen.
Aktueller Code:

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

Das Problem ist jedoch, dass, wenn sich das SOLIDWORKS-Fenster auf dem linken Bildschirm (2 Bildschirme) befindet, keine Sorge, das Benutzerformular weit über SW liegt.
Wenn der Benutzer jedoch Solidworks auf seinen rechten Bildschirm gelegt hat, landet das Benutzerformular auf dem linken Bildschirm, gegenüber der SW.
Deswegen suche ich nach einer Alternative wie in Excel (Code der 1. Nachricht, aber in SW nicht funktionsfähig.

Ich sehe 1 Problem
Die USF mit Startuposition auf 1-centerowner sollte die USF in den Mittelpunkt der Anwendung stellen, die sie gestartet hat, was nicht der Fall ist

" application.something " funktioniert nicht

Sehen Sie sich dieses Thema an, wo ich die Anwendung ersetzen musste, ich denke, es ist das gleiche Prinzip, im Moment habe ich nicht gefunden

2 „Gefällt mir“

Hallo @sbadenis
Versuchen Sie dies

Public swapp as sldworks.Sldworks

Und

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 „Gefällt mir“

Hallo
Die Antwort von @Lynkoa15 scheint gut zu sein, andererseits habe ich getestet und die zurückgegebenen Werte sind ziemlich seltsam.
Es gibt mir die folgenden Werte für einen Doppelbildschirm, der auf denjenigen eingestellt ist, auf dem SW in 1680x1050 geöffnet ist:
Links = 897
Breite = 1024
Oben = 0
Höhe = 768
Dies hat zur Folge, dass das UserForm in der Mitte der beiden Bildschirme positioniert wird.
Um es auf dem linken Bildschirm zu halten (bei mir ist SW links auf dem Hauptbildschirm), habe ich Swapp.FramLeft aus der Berechnung für Me.Left entfernt.
Es positionierte das UserForm auf dem linken Bildschirm, nicht wirklich zentriert im Fenster in der Breite, die Höhe ist gut, auch wenn die Höhe nichts mit meiner Bildschirmauflösung zu tun hat.

1 „Gefällt mir“

Cyrille, es ist seltsam, ich habe keinen Dual-Screen und ich habe nicht getestet, aber wenn es Ihnen ermöglicht, das Fenster auf den zweiten Bildschirm umzuschalten, muss eine Analyse der Diskrepanz mit den Abmessungen des letzteren möglich sein, vielleicht ein Unterschied zwischen der Bildschirmauflösung und der Bildschirmauflösung von Windows

1 „Gefällt mir“

Ich habe nicht die gleiche Auflösung zwischen dem linken und dem rechten Bildschirm. Vielleicht kommt es daher, ich mache noch einmal einen Test mit einem einzigen Bildschirm, um zu sehen.

1 „Gefällt mir“

Für mich nicht ganz zentriert auf dem linken Bildschirm und auf dem rechten Bildschirm völlig dezentriert.
Durch das Hinzufügen einer leicht dezentrierten Klammer auf den 2 Bildschirmen (gleiche Größe) komme ich der Wahrheit näher, aber es gibt immer noch ein etwas seltsames Verhalten und unterscheidet sich von der Lösung in Excel.

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

In den nächsten 2-3 Tagen habe ich keine Zeit zum Graben, die Arbeit holt mich ein.
Ich melde mich so schnell wie möglich bei Ihnen.
In jedem Fall ist Ihre Lösung @Lynkoa15 die bisher engste und funktionalste!

Hallo @sbadenis ,

In der Tat verwaltet Windows die beiden Bildschirme als einen, indem es Pixel in der Breite anhäuft.
Dies wird durch das angehängte Makro bestätigt, das in Stücken aus dem Netz aufgenommen und angepasst wurde, um die Abmessungen der beiden Bildschirme und die Position des SolidWorks Fensters zurückzugeben.

Die Diskrepanz, die bei der Verwendung des @Lynkoa15 Vorschlags beobachtet wurde , scheint mir mit einer Verwechslung der Einheiten für die Bildschirmkoordinaten zusammenzuhängen:

  • Die Abmessungen und die Position des UserForm-Formulars (. Links. Nach oben. Widt und . Höhe) werden von VBA in Bildschirmpunkten definiert.
  • Die Abmessungen und die Position des SolidWorks Fensters, die von zurückgegeben werden. FrameLeft, . Rahmenbreite, . FrameTop und . FrameHeights werden von Windows in Pixel definiert.
    Das Verhältnis zwischen den beiden Einheiten hängt vom Display selbst ab, beträgt aber in der Regel 4/3.

Ich habe eine korrekte Position des Formulars in der Mitte des SolidWorks Fensters mit den folgenden Ausdrücken, unabhängig vom verwendeten Bildschirm:

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

Herzliche Grüße.
DoubleEcran.swp (115.5 KB)

1 „Gefällt mir“

@m.blt habe ich schnell getestet, zentriert auf meinem linken Bildschirm, wenn ich SW auf den rechten Bildschirm umschalte, ist es nicht zentriert.
Ich werde morgen einen weiteren Test machen, wenn ich Zeit habe.

1 „Gefällt mir“

Das Gleiche wie @Cyril.f , @m.blt nicht wirklich zentriert und verschiebt sich auf die Höhe, das Verhältnis korrigiert den Fehler nicht, und bei mehr als 20 Infobeiträgen fürchte ich, dass es leider sehr zufällig ist.

Ich denke, wir werden das richtige Verhältnis messen müssen
3/4 funktioniert nicht auf meinem Basisbildschirm (kein zweiter Bildschirm)
Ich habe versucht, das technische Datenblatt zu sehen


Ich denke, wir müssen es berechnen
(145/25,4/(1920/210,24))=0,62 (das richtige Verhältnis für mich)
Ich denke, das ist für einen zweiten Bildschirm nur dann dasselbe, wenn sie die gleichen ppi haben
Unter diesem Gesichtspunkt schlage ich vor, mit zwei Verhältnissen zu arbeiten, z. B. wenn die Anzahl der Pixel 1920 übersteigt, die ersten (oder zweiten) Pixel mit dem ersten Verhältnis zu berechnen und den Rest mit einer Berechnung des anderen Verhältnisses zu addieren

1 „Gefällt mir“

Hallo ihr alle

Es ist wahr, dass die Verwendung von " Bildschirmpunkten " durch VBA oft problematisch ist, wenn man die Diskussionen in verschiedenen Foren (oft Excel oder Access) betrachtet.
Die Lösung besteht darin, es loszuwerden, indem Sie Windows-API-Funktionen verwenden, die nur Pixel verwenden.
Das beigefügte Makro ist eine Adaption des vorherigen, das auf meinem PC mit zwei Bildschirmen die Arbeit erledigt. Das Formular UserForm1 ist zentriert auf dem SolidWorks Fenster.
Schnelltest: Wenn das SolidWorks Fenster verschoben wird, wird durch Klicken auf die Schaltfläche " Zentrieren " das Benutzerformular zurückgesetzt.

Herzliche Grüße.
DoubleEcran.swp (171.5 KB)

1 „Gefällt mir“

Hallo @tous
@m.blt Ihr Makro übertrifft :sweat_smile:mich.
Also habe ich versucht, die Funktion zu entwickeln, die ich vorhin erwähnt habe, unter Berücksichtigung Ihrer Bemerkung über die Einheiten.

Ich stelle Ihnen ein kleines einfaches Tool zur Verfügung, mit dem Sie die Verhältnisse berechnen können (ich hoffe, es wird funktionieren :roll_eyes:)
Makro1.swp (76 KB)
Macro2.swp (56 KB)
Doc1.pdf (237.9 KB)

2 „Gefällt mir“

Zunächst einmal vielen Dank für die aufgewendete Zeit, ich hätte mir nicht vorstellen können, dass das Zentrieren eines Benutzerformulars auf dem SW-Fenster so kompliziert sein würde!
@Lynkoa15 Lösung ist einfach, aber da dieses Makro auf mehr als 20 Workstations mit einer Anzahl von Bildschirmen von 1 bis 2, meistens 2, und mit völlig unterschiedlicher Größe und Verhältnis, verwendet wird.
Darüber hinaus besteht das Rationsproblem auch bei der Höhe. Deshalb denke ich darüber nach, mich an die @m.blt-Lösung zu wenden, die perfekt funktioniert.
@m.blt auf der anderen Seite habe ich ein wenig Schwierigkeiten, Ihr Makro zu verstehen, weil es so vollständig ist.
Ich gebe zu, dass ich als autodidaktischer Entwickler an meine Grenzen stoße.
Ich habe Ihren Code in einem vereinfachten Makro mit einem Benutzerformular ohne irgendetwas EDT genommen, ich kann es nicht anpassen.
Ist es notwendig, im Aufruf die 2 Argumente (Textbox1 und 2) zu haben:
CoincidentsCtresWindows UserForm1.TextBox1, UserForm1.TextBox2, True
und nicht nur
CoincidentsCtresWindows UserForm1 , True
Ich habe versucht, Ihren Code zu ändern, ohne das zu erreichen, was ich wollte (zentrierte das Fenster nur mit dem Namen des Benutzerformulars)

Hallo @sbadenis ,

Entschuldigung, ich bin ein Fan des Sprichworts " Warum es einfach machen, wenn man es kompliziert machen kann? ".
image

Angehängt ist das Zentrierungsmakro des VBA-Fensters am SolidWorks Fenster, das von allen TextBox-, ListBox- und anderen Schaltflächen entfernt wurde. Seine einzige Funktion besteht darin, die UserForm-VBA in der Mitte des SolidWorks Fensters zu positionieren, wenn sie zum ersten Mal angezeigt wird.
Es funktioniert auf meinem PC, mit einem oder zwei Bildschirmen. Ich habe es nicht mit dreien versucht...

Die Bedingungen sind wie folgt:

  • SolidWorks ist aktiviert (was im Prinzip der Fall ist, da das Makro gestartet wird);
  • Das Hauptmodul heißt CentrageUsrFrm und enthält nur die Hauptprozedur.
  • In der Hauptprozedur ist der erste Parameter, der an die Funktion CoincidentsCtresWindows übergeben wird, die Beschriftung des SolidWorks Fensters, die fest codiert ist: " SOLIDWORKS ".
    Der zweite Parameter ist der des UserForm, der über seine caption-Eigenschaft abgerufen wird.
  • Das IdentFenetres-Modul enthält die beiden Funktionen, die die Windows-APIs verwenden, um die Abmessungen der Fenster abzurufen und die Position des UserForm zu berechnen. Prinzipiell sind für dieses Modul keine Änderungen erforderlich.

Herzliche Grüße.
ZentrierungUsrFrm.swp (102 KB)

2 „Gefällt mir“

Es funktioniert perfekt wie das vorherige, aber es ist jetzt viel einfacher zu verstehen! :crazy_face:
Danke für die Erklärungen und das vereinfachte Makro!
Auch wenn das Durchlaufen der Windows-APIs kompliziert bleibt, um ein einfaches Fenster zu zentrieren, bleibt es in jedem Fall die einzig praktikable Lösung (mehrere Workstations und verschiedene Bildschirme)

Hallo @sbadenis ,

Zufrieden zu sehen, dass das zu Ihnen passt...

Was die Verwendung von Windows-APIs betrifft, so gibt es keine anderen Lösungen, da Windows die Fenster der verschiedenen Anwendungen verwaltet. Wenn SolidWorks selbst die Positionen und Abmessungen seines eigenen Fensters (FrameLeft, FrameWidth usw.) zurückgibt, verwendet es wahrscheinlich Windows-APIs.

Wir könnten wahrscheinlich die beiden Funktionen des IdentFenetres-Moduls in einer DLL " verstecken ", was es ermöglichen würde, das Modul zu entfernen und nur zwei Zeilen im Makro zu lassen, um das UserForm zu zentrieren.
Aber es ist die Installation auf verschiedenen Workstations, die knifflig werden würde: Standort der DLL, Registrierung in der Windows-Registrierung). Der Vorteil des Makros besteht darin, dass es aus Sicht der Installation völlig autonom ist.

Herzliche Grüße.

2 „Gefällt mir“

Ja, in der Tat ist es durchaus möglich, es ist nur seltsam, dass SolidWorks nichts implementiert hat, um diese Funktion zu vereinfachen, zum Beispiel über eine DLL!
Und es wird mich nur zu einem weiteren Modul in meinem Makro machen, das bereits gut versorgt ist, ohne dass ich mir Sorgen machen müsste.
Und nochmals vielen Dank.

1 „Gefällt mir“