UserForm zentrieren (2 Bildschirme)? / Inventor VBA
mb-ing 24. Mrz. 2020, 09:59

Hallo zusammen,

theoretisch sollte man mit folgenden Code eine UserForm zentrieren können:
(https://ww3.cad.de/foren/ubb/Forum258/HTML/001853.shtml)

Sub Test2()
With UserForm
  .StartUpPosition = 0
  .Left = ThisApplication.Left + (0.5 * ThisApplication.Width) - (0.5 * .Width)
  .Top = ThisApplication.Top + (0.5 * ThisApplication.Height) - (0.5 * .Height)
  .Show vbModeless
End With
Unload UserForm
End Sub

Aber bei mir klappt das leider nicht 

Ich würde gerne die UserForm immer im Zentrum des aktuellen IV-Fenster anzeigen, egal auf welchem Bildschirm sich dieses Fenster befindet.

Application.Left, ThisApplication.Left & ThisApplication.ActiveView.Left (Analog füt Top) liefern mir unterschiedliche Werte.

UserForm1.StartUpPosition = 3 geht immer vom VBA-Fenster aus...

Habt Ihr eine Idee warum es bei mir nicht klappt?

Autodesk schafft es ja anscheinend mit dem Befehl 
ThisApplication.CreateProgressBar()
Ihr Hinweisfenster ist immer schön in der Mitte des entsprechenden IV-Fensters.

Danke im Voraus für Eure Bemühungen.

Danke und Grüße
MB-Ing.

Meierjo 24. Mrz. 2020, 13:29

Hallo

Schon mal probiert, das StartUpPosition auszukommentieren / wegzulassen, oder auf 1 zu setzen?

Gruss

[Diese Nachricht wurde von Meierjo am 24. Mrz. 2020 editiert.]

mb-ing 24. Mrz. 2020, 16:39

Zitat:
Original erstellt von Meierjo:
Hallo

Schon mal probiert, das StartUpPosition auszukommentieren / wegzulassen, oder auf 1 zu setzen?

Gruss

[Diese Nachricht wurde von Meierjo am 24. Mrz. 2020 editiert.]



@Meierjo:

Vielen Dank für Deine Antwort.
Ja das habe ich davor und zur Sicherheit nochmals probiert, aber es hat auch keinen Erfolg gebracht.

Klappt der Code bei Euch?

Danke und Grüße
MB-Ing.

Meierjo 24. Mrz. 2020, 17:43

Hallo

Ja, wenn ich StartUpPosition auf 1 stelle, wird die Userform zentriert auf dem jeweiligen Bildschirm, wo der Inventor läuft, zentriert geöffnet

Gruss

mb-ing 25. Mrz. 2020, 09:12

Zitat:
Original erstellt von Meierjo:
Hallo

Ja, wenn ich StartUpPosition auf 1 stelle, wird die Userform zentriert auf dem jeweiligen Bildschirm, wo der Inventor läuft, zentriert geöffnet

Gruss



@Meierjo:

Vielen herzlichen Dank für Deine Antwort.

Ist das Inventor-Fenster auf dem linken Bildschirm klappt es tadellos.
Aber befindet sich Inventor auf dem rechten Monitor dann wird die UserForm zu weit links (Nahe dem linken Rand des rechten Screens) dargestellt.
Kurzzeitig hat ich Remote im Verdacht, aber auch auf meinem normalen Desktop-Rechner verhält es sich wie oben beschrieben.
Habe aktuell Inventor 2020 Service-Pack 2 zum Testen...

Danke und Grüße
MB-Ing.

Meierjo 25. Mrz. 2020, 09:26

Hallo

Zitat:
Original erstellt von mb-ing:

Habe aktuell Inventor 2020 Service-Pack 2 zum Testen...

Bei mir funktioniert's in Inventor 2019, mit aktuellen Servicepack.
In Inventor 2020 funktioniert's bei mir übrigens auch nicht (habe ich eben erst ausprobiert) 

EDIT: Sorry, wenn man den richtigen Code verwendet, funktionierts auch. Also: bei mir funktionierts in Inventor 2019 und in Inventor 2020, beide mit aktuellem Servicepack


Gruss

[Diese Nachricht wurde von Meierjo am 25. Mrz. 2020 editiert.]

mb-ing 25. Mrz. 2020, 10:08

Zitat:
Original erstellt von Meierjo:
Hallo

Bei mir funktioniert's in Inventor 2019, mit aktuellen Servicepack.
In Inventor 2020 funktioniert's bei mir übrigens auch nicht (habe ich eben erst ausprobiert) 

EDIT: Sorry, wenn man den richtigen Code verwendet, funktionierts auch. Also: bei mir funktionierts in Inventor 2019 und in Inventor 2020, beide mit aktuellem Servicepack


Gruss

[Diese Nachricht wurde von Meierjo am 25. Mrz. 2020 editiert.]


@Meierjo:
Merci für Deine Antwort.

Den richtigen Code?
Also den Code von oben?

Sub Test2()
With UserForm
  .StartUpPosition = 0
  .Left = ThisApplication.Left + (0.5 * ThisApplication.Width) - (0.5 * .Width)
  .Top = ThisApplication.Top + (0.5 * ThisApplication.Height) - (0.5 * .Height)
  .Show vbModeless
End With
Unload UserForm
End Sub

Danke und Grüße
MB-Ing.

Meierjo 27. Mrz. 2020, 18:10

Hallo

sorry, erst jetzt gesehen.
Ich habe .StartUpPosition auf 1 gesetzt
Ansonsten den Code so belassen

Gruss

mb-ing 01. Apr. 2020, 07:19

Zitat:
Original erstellt von Meierjo:
Hallo

sorry, erst jetzt gesehen.
Ich habe .StartUpPosition auf 1 gesetzt
Ansonsten den Code so belassen

Gruss



Hi Meierjo,

Danke für Deine Antwort, aber auch mit .StartUpPosition = 1 klappt es bei mir nicht 
Was für einen Inventor hast Du drauf bzw. welches Service-Pack?

Danke und Grüße
MB-Ing.

Meierjo 01. Apr. 2020, 07:32

Hallo

Ich hab's mit Inventor 2019 und Inventor 2020 probiert, jeweils mit akutellem Servicepack-Stand

Gruss

rkauskh 01. Apr. 2020, 12:00

Hallo

Die StartUpPosition kann zur Laufzeit nicht mehr verändert werden bzw. das hat keine Auswirkungen mehr. Das geht nur in der Initialisierung.
Die StartUpPosition=1 funktioniert mit zwei Monitoren nach meiner Erfahrung nur gelegentlich.
Ich empfehle das ganze weniger zufällig zu machen. Der Code zentriert immer im Inventorfenster, auch wenn das Fenster nicht maximiert ist. Ist der Inventor minimiert, wird das Inventorfenster vorher maximiert.

In die Initialize-Sub der Form:

Code:
Private Sub UserForm_Initialize()
Dim sngLeft As Single
Dim sngTop As Single

    Call ReturnPosition_CenterScreen(Me.Height, Me.Width, sngLeft, sngTop)
    Me.Left = sngLeft
    Me.Top = sngTop
End Sub


Und in ein beliebiges anderes Modul:

Code:

Option Explicit

    Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long
    Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
    Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
    Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal Index As Long) As Long
    Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As udtRECT) As Long

Type udtRECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Public Sub ReturnPosition_CenterScreen(ByVal sngHeight As Single, _
                                      ByVal sngWidth As Single, _
                                      ByRef sngLeft As Single, _
                                      ByRef sngTop As Single)
Dim sngAppWidth As Single
Dim sngAppHeight As Single
Dim hWnd As Long
Dim lreturn As Long
Dim lpRect As udtRECT
   
    If ThisApplication.WindowState = kMinimize Then
        ThisApplication.WindowState = kMaximize
    End If
   
    hWnd = ThisApplication.MainFrameHWND
   
    lreturn = GetWindowRect(hWnd, lpRect)
    sngAppWidth = ConvertPixelsToPoints(lpRect.Right - lpRect.Left, "X")
    sngAppHeight = ConvertPixelsToPoints(lpRect.Bottom - lpRect.Top, "Y")
    sngLeft = ConvertPixelsToPoints(lpRect.Left, "X") + ((sngAppWidth - sngWidth) / 2)
    sngTop = ConvertPixelsToPoints(lpRect.Top, "Y") + ((sngAppHeight - sngHeight) / 2)
End Sub

Public Function ConvertPixelsToPoints(ByVal sngPixels As Single, _
                                      ByVal sXorY As String) As Single
Dim hDC As Long

  hDC = GetDC(0)
  If sXorY = "X" Then
      ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 88))
  End If
  If sXorY = "Y" Then
      ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 90))
  End If
  Call ReleaseDC(0, hDC)
End Function


mb-ing 15. Apr. 2020, 07:32

Zitat:
Original erstellt von rkauskh:
Hallo

Die StartUpPosition kann zur Laufzeit nicht mehr verändert werden bzw. das hat keine Auswirkungen mehr. Das geht nur in der Initialisierung.
Die StartUpPosition=1 funktioniert mit zwei Monitoren nach meiner Erfahrung nur gelegentlich.
Ich empfehle das ganze weniger zufällig zu machen. Der Code zentriert immer im Inventorfenster, auch wenn das Fenster nicht maximiert ist. Ist der Inventor minimiert, wird das Inventorfenster vorher maximiert.

In die Initialize-Sub der Form:

Code:
Private Sub UserForm_Initialize()
Dim sngLeft As Single
Dim sngTop As Single

Call ReturnPosition_CenterScreen(Me.Height, Me.Width, sngLeft, sngTop)
Me.Left = sngLeft
Me.Top = sngTop
End Sub


Und in ein beliebiges anderes Modul:

Code:

Option Explicit

Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long
Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal Index As Long) As Long
Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As Long, ByRef lpRect As udtRECT) As Long

Type udtRECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Sub ReturnPosition_CenterScreen(ByVal sngHeight As Single, _
  ByVal sngWidth As Single, _
  ByRef sngLeft As Single, _
  ByRef sngTop As Single)
Dim sngAppWidth As Single
Dim sngAppHeight As Single
Dim hWnd As Long
Dim lreturn As Long
Dim lpRect As udtRECT

If ThisApplication.WindowState = kMinimize Then
ThisApplication.WindowState = kMaximize
End If

hWnd = ThisApplication.MainFrameHWND

lreturn = GetWindowRect(hWnd, lpRect)
sngAppWidth = ConvertPixelsToPoints(lpRect.Right - lpRect.Left, "X")
sngAppHeight = ConvertPixelsToPoints(lpRect.Bottom - lpRect.Top, "Y")
sngLeft = ConvertPixelsToPoints(lpRect.Left, "X") + ((sngAppWidth - sngWidth) / 2)
sngTop = ConvertPixelsToPoints(lpRect.Top, "Y") + ((sngAppHeight - sngHeight) / 2)
End Sub

Public Function ConvertPixelsToPoints(ByVal sngPixels As Single, _
ByVal sXorY As String) As Single
Dim hDC As Long

  hDC = GetDC(0)
  If sXorY = "X" Then
ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 88))
  End If
  If sXorY = "Y" Then
ConvertPixelsToPoints = sngPixels * (72 / GetDeviceCaps(hDC, 90))
  End If
  Call ReleaseDC(0, hDC)
End Function



Hi Ralf,

vielen herzlichen Dank.
Der Code funktioniert super und positioniert das Hinweisfenster immer in der Mitte des Bildschirms, auf dem sich Inventor befindet 

Wie kann man es umbauen, dass es immer in der Mitte des aktiven Inventors ist?
Dann wäre es für mich perfekt...

Danke und Grüße
MB-Ing.

rkauskh 17. Apr. 2020, 06:10

Moin

Dann hast du in den Eigenschaften deiner Form die StartUpPosition vermutlich nicht auf "0-manuell" gestellt. Dadurch wird der gesamte Code faktisch ignoriert.
Entweder in den Eigenschaften der Form umstellen oder an den Anfang der Initialize-Sub noch einfügen:

Code:
Me.StartUpPosition = 0

mb-ing 20. Apr. 2020, 13:40

Zitat:
Original erstellt von rkauskh:
Moin

Dann hast du in den Eigenschaften deiner Form die StartUpPosition vermutlich nicht auf "0-manuell" gestellt. Dadurch wird der gesamte Code faktisch ignoriert.
Entweder in den Eigenschaften der Form umstellen oder an den Anfang der Initialize-Sub noch einfügen:

Code:
Me.StartUpPosition = 0


@Ralf:

Vielen herzlichen Dank!
Genau daran hat es gelegen 

Jetzt funktioniert alles perfekt.

Danke und Grüße
MB-Ing.