Problem mit GetMonitorInfo/MonitorFromWindow

  • WPF

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Problem mit GetMonitorInfo/MonitorFromWindow

    Moin,
    ich möchte mein WPF-Programm mit eigener Titelleiste maximieren können.
    Da cih WindowsStyle=none habe, ist das maximierte Fenster über der Taskleiste.
    Ich habe jetzt diese Lösung gefunden
    blogs.msdn.com/b/llobo/archive…-considering-taskbar.aspx
    Da das C# ist, ich aber VB.Net verwende, habe ich mir das ganze übersetzt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Declare Function MonitorFromWindow Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal dwFlags As Integer) As IntPtr
    2. Friend Declare Function GetMonitorInfo Lib "user32.dll" (ByVal hMonitor As IntPtr, ByRef lpmi As MonitorInfo) As Boolean
    3. Public Const MONITOR_DEFAULTTONEAREST As Integer = &H2
    4. Private Sub MainWindow_SourceInitialized(sender As Object, e As EventArgs) Handles Me.SourceInitialized
    5. Dim handle As IntPtr = (New WindowInteropHelper(Me)).Handle
    6. HwndSource.FromHwnd(handle).AddHook(New HwndSourceHook(AddressOf WindowProc))
    7. End Sub
    8. Private Function WindowProc(ByVal hwnd As IntPtr, msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr
    9. Select Case msg
    10. Case Is = &H24
    11. wmGetMinMaxInfo(hwnd, lParam)
    12. handled = True
    13. End Select
    14. Return New IntPtr(0)
    15. End Function
    16. Private Sub wmGetMinMaxInfo(hwnd As IntPtr, lParam As IntPtr)
    17. Dim mmi As MinMaxInfo = DirectCast(Marshal.PtrToStructure(lParam, GetType(MinMaxInfo)), MinMaxInfo)
    18. Dim monitor As IntPtr = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)
    19. If Not monitor = IntPtr.Zero Then
    20. Dim monitorInfo As MonitorInfo = New MonitorInfo
    21. GetMonitorInfo(monitor, monitorInfo)
    22. Dim rcWorkArea As Rect = monitorInfo.rcWork
    23. Dim rcMonitorArea As Rect = monitorInfo.rcMonitor
    24. mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left)
    25. mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top)
    26. mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left)
    27. mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top)
    28. End If
    29. Marshal.StructureToPtr(mmi, lParam, True)
    30. End Sub
    31. <StructLayout(LayoutKind.Sequential)>
    32. Public Structure MinMaxInfo
    33. Public ptReserved As Point
    34. Public ptMaxSize As Point
    35. Public ptMaxPosition As Point
    36. Public ptMinTrackSize As Point
    37. Public ptMaxTrackSize As Point
    38. End Structure
    39. <StructLayout(LayoutKind.Sequential)>
    40. Public Structure Rect
    41. Public Left As Integer
    42. Public Right As Integer
    43. Public Top As Integer
    44. Public Bottom As Integer
    45. End Structure
    46. <StructLayout(LayoutKind.Sequential)>
    47. Public Class MonitorInfo
    48. Public cbSize As Integer = Marshal.SizeOf(GetType(MinMaxInfo))
    49. Public rcMonitor As New Rect()
    50. Public rcWork As New Rect()
    51. Public dwFlags As Integer = 0
    52. End Class

    Nach dem Übersetzten funktioniert das ganze aber nicht mehr. D.h. das Window bekommt eine Größe von 0x0 und eine Position von 0;0. Außerdem bekomme ich den Fehler, dass die Funktion "GetMonitorInfo" nicht in User32.dll gefunden werden konnte, die Meldung verschwindet, wenn ich einen Alias "GetMonitorInfoA" verwende.

    Ich hoffe ihr könnt mir helfen.

    Gruß
    HamburgerJungeJr
    Screen.FromHandle(IntPtr) gibt dir den Bildschirm zurück, auf dem sich das Fenster mit dem angegebenen Handle zum größten Teil befindet. Screen.FromControl kannst du leider nicht verwenden, da ein WPF-Window kein gültiges Control ist, du musst also den Umweg über das Fensterhandle gehen (ist aber auch in einer Zeile erledigt).