Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1724to1728
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

StartUpPosition bei zwei Bildschirmen

StartUpPosition bei zwei Bildschirmen
06.12.2019 13:18:37
Sven
Moin zusammen,
wir haben neuerdingsden Luxus zweier Bildschirme und damit folgendes Problem:
Verschiebt man das Haupt-Userform, welches auf dem linken geöffnet wurde, nach rechts auf den zweiten, so wird das "Unter-Userform" (ein selbstgebauter Druckdialog) dennoch weiterhin auf den linken Bildschirm geöffnet. Änderungen an der StartUpPosition-Eigenschaft des Userforms zeigen keine Wirkung. Das betrifft auch Msgboxen, die dann bei den Kollegen irgendwo aufpoppen, aber nicht immer über dem Haupt-Dialog liegen.
Kann man die Fenster/Boxen bspw. immer an der Mausposition anzeigen lassen?
Danke und Grüße
Sven

5
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: StartUpPosition bei zwei Bildschirmen
06.12.2019 13:51:03
Nepumuk
Hallo Sven,
ein Userform kannst du beeinflussen. Eine MsgBox im Prinzip auch, ist aber aufwendig.
Im Modul des Userforms:
Option Explicit

Private Declare Function GetCursorPos Lib "user32.dll" ( _
    lpPoint As POINTAPI) As Long
Private Declare Function GetSystemMetrics Lib "user32.dll" ( _
    ByVal nIndex As Long) As Long
Private Declare Function FindWindowA Lib "user32.dll" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long
Private Declare Function GetWindowRect Lib "user32.dll" ( _
    ByVal hWnd As Long, _
    ByRef lpRect As RECT) As Long

Private Const SM_CXSCREEN As Long = 0&
Private Const SM_CYSCREEN As Long = 1&

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Sub CommandButton1_Click()
    Call Unload(Object:=Me)
End Sub

Private Sub UserForm_Initialize()
    
    Const CONVERSION_FACTOR As Single = 0.75 'Um Pixel in Point umzurechnen
    
    Dim udtCursorPos As POINTAPI, udtRectangle As RECT
    Dim lnghWnd As Long
    
    'Position der Maus auslesen
    Call GetCursorPos(udtCursorPos)
    
    'Zugriffsnummer der Taskleiste auslesen
    lnghWnd = FindWindowA("Shell_traywnd", vbNullString)
    
    'Position der Taskleise auslesen
    Call GetWindowRect(lnghWnd, udtRectangle)
    
    'Startposition des Userforms auf manuell setzen
    StartUpPosition = 0
    
    'Linke Position des Userforms berechnen
    If udtCursorPos.X * CONVERSION_FACTOR + Width > _
        GetSystemMetrics(SM_CXSCREEN) * CONVERSION_FACTOR Then
        
        'Links der Maus anzeigen
        Left = udtCursorPos.X * CONVERSION_FACTOR - Width
        
    Else
        
        'Rechts der Maus anzeigen
        Left = udtCursorPos.X * CONVERSION_FACTOR
        
    End If
    
    'Oben-Position des Userforms berechnen
    If udtCursorPos.Y * CONVERSION_FACTOR + Height > _
        GetSystemMetrics(SM_CYSCREEN) * CONVERSION_FACTOR - _
        (udtRectangle.Bottom - udtRectangle.Top) Then
        
        'Über der Maus anzeigen
        Top = udtCursorPos.Y * CONVERSION_FACTOR - Height
        
    Else
        
        'Unter der Maus anzeigen
        Top = udtCursorPos.Y * CONVERSION_FACTOR
        
    End If
End Sub

Gruß
Nepumuk
Anzeige
AW: StartUpPosition bei zwei Bildschirmen
09.12.2019 10:08:53
Sven
Boa, super. Danke, Nepumuk!
Das klappt prima. Ob das Fenster modal angezeigt wird oder nicht erscheint unerheblich, oder?
Bei MsgBoxen ist das deutlich aufwändiger, sagst Du?
Grüße
AW: StartUpPosition bei zwei Bildschirmen
09.12.2019 10:17:04
Nepumuk
Hallo Sven,
1. Ja es ist unerheblich ob Modal oder nicht.
2. Um eine MsgBox zu platzieren muss ich vor der Box einen Timer starten der das Fenster abfängt und dieses dann verschiebt. Ich versuche dir mal ein Beispiel zu erstellen.
Gruß
Nepumuk
AW: StartUpPosition bei zwei Bildschirmen
09.12.2019 19:11:24
Nepumuk
Hallo Sven,
das angekündigte Beispiel:
Option Explicit
Option Private Module

Private Declare PtrSafe Function GetWindowPlacement Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByRef lpwndpl As WINDOWPLACEMENT) As Long
Private Declare PtrSafe Function GetCursorPos Lib "user32.dll" ( _
    ByRef lpPoint As POINTAPI) As Long
Private Declare Function GetSystemMetrics Lib "user32.dll" ( _
    ByVal nIndex As Long) As Long
Private Declare PtrSafe Function MoveWindow Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal x As Long, _
    ByVal y As Long, _
    ByVal nWidth As Long, _
    ByVal nHeight As Long, _
    ByVal bRepaint As Long) As Long
Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function SetTimer Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal nIDEvent As LongPtr, _
    ByVal uElapse As Long, _
    ByVal lpTimerFunc As LongPtr) As LongPtr
Private Declare PtrSafe Function KillTimer Lib "user32.dll" ( _
    ByVal hwnd As LongPtr, _
    ByVal nIDEvent As LongPtr) As Long

Private Type POINTAPI
    x As Long
    y As Long
End Type

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type WINDOWPLACEMENT
    Length As Long
    flags As Long
    showCmd As Long
    ptMinPosition As POINTAPI
    ptMaxPosition As POINTAPI
    rcNormalPosition As RECT
End Type

Private Const GC_CLASSNAMEMSDIALOG As String = "#32770"

Private Const WM_PAINT As Long = &HF

Private Const SM_CXSCREEN As Long = 0&
Private Const SM_CYSCREEN As Long = 1&

Public gstrBoxTitle As String

Public Sub Test()
    
    gstrBoxTitle = "Information"
    
    Call SetTimer(Application.hwnd, 0, 1, AddressOf StartTimer)
    
    Select Case MsgBox("Test", vbInformation, gstrBoxTitle)
        Case vbOK
            Debug.Print "Ok"
        Case vbCancel
            Debug.Print "Cancel"
        Case vbAbort
            Debug.Print "Abbruch"
        Case vbRetry
            Debug.Print "Wiederholen"
        Case vbIgnore
            Debug.Print "Ignorieren"
        Case vbYes
            Debug.Print "Ja"
        Case vbNo
            Debug.Print "Nein"
    End Select
End Sub

Private Sub StartTimer(ByVal hwnd As Long, ByVal nIDEvent As Long, _
        ByVal uElapse As Long, ByVal lpTimerFunc As Long)

    
    Call StopTimer
    
    Call SetWindowPos
    
End Sub

Private Sub StopTimer()
    Call KillTimer(Application.hwnd, 0)
End Sub

Private Sub SetWindowPos()
    
    Dim lngLeft As Long, lngTop As Long
    
    Dim lngptrBoxHwnd As LongPtr
    Dim udtWindowPlacemet As WINDOWPLACEMENT
    Dim udtCursorPos As POINTAPI
    
    lngptrBoxHwnd = FindWindowA(GC_CLASSNAMEMSDIALOG, gstrBoxTitle)
    
    Call GetWindowPlacement(lngptrBoxHwnd, udtWindowPlacemet)
    
    Call GetCursorPos(udtCursorPos)
    
    udtWindowPlacemet.Length = Len(udtWindowPlacemet)
    
    With udtWindowPlacemet.rcNormalPosition
        
        If udtCursorPos.x + (.Right - .Left) > GetSystemMetrics(SM_CXSCREEN) Then
            
            lngLeft = udtCursorPos.x - (.Right - .Left)
            
        Else
            
            lngLeft = udtCursorPos.x
            
        End If
        
        If udtCursorPos.y + (.Bottom - .Top) > GetSystemMetrics(SM_CYSCREEN) Then
            
            lngTop = udtCursorPos.y - (.Bottom - .Top)
            
        Else
            
            lngTop = udtCursorPos.y
            
        End If
        
        Call MoveWindow(lngptrBoxHwnd, lngLeft, lngTop, .Right - .Left, .Bottom - .Top, WM_PAINT)
        
    End With
End Sub

Gruß
Nepumuk
Anzeige
AW: StartUpPosition bei zwei Bildschirmen
10.12.2019 08:52:40
Sven
Hallo Nepumuk,
wow, auch danke hierfür.
Der Aufwand ist aber ja wirklich enorm.
Grüße

Links zu Excel-Dialogen

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige