Как определить высоту панели задач без использования Screen.WorkingArea?

У меня есть форма, которая должна располагаться у дальнего правого края экрана и растягиваться по высоте, чтобы заполнить всю высоту рабочей области.

В этом нет ничего странного, поэтому я написал решение с использованием Screen.WorkingArea.Height, которое отлично работало, пока я работал локально. Загвоздка в том, что в производственной среде форма запускается в среде Citrix, и кажется, что она полностью игнорирует высоту панели задач. В Citrix Screen.WorkingArea.Height возвращает то же самое значение, что и Screen.Bounds.Height, таким образом растягиваясь под панелью задач.

Моя идея состоит в том, чтобы использовать Screen.Bounds.Height (поскольку это кажется правильным) и вычесть высоту панели задач самостоятельно. Единственная проблема заключается в том, что единственные примеры, которые я могу найти о том, как это сделать, включают Screen.Bounds.Height - Screen.WorkingArea.Height.

Итак, как я могу напрямую получить доступ к высоте панели задач? (Конечно, я с удовольствием выслушаю любые другие советы, как обойти эту проблему!)


person Marcus L    schedule 07.09.2011    source источник


Ответы (1)


Вам также придется использовать некоторые нативные методы для доступа к свойствам панели задач.

Использование:

TaskbarInfo.Height

Класс:

Public NotInheritable Class TaskbarInfo

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    <DllImport("shell32.dll", SetLastError:=True)> _
    Public Shared Function SHAppBarMessage(ByVal dwMessage As ABM, <[In]()> ByRef pData As APPBARDATA) As IntPtr
    End Function

    Enum ABM As UInteger
        [New] = &H0
        Remove = &H1
        QueryPos = &H2
        SetPos = &H3
        GetState = &H4
        GetTaskbarPos = &H5
        Activate = &H6
        GetAutoHideBar = &H7
        SetAutoHideBar = &H8
        WindowPosChanged = &H9
        SetState = &HA
    End Enum

    Enum ABE As UInteger
        Left = 0
        Top = 1
        Right = 2
        Bottom = 3
    End Enum

    <StructLayout(LayoutKind.Sequential)> _
    Structure APPBARDATA
        Public cbSize As UInteger
        Public hWnd As IntPtr
        Public uCallbackMessage As UInteger
        Public uEdge As ABE
        Public rc As RECT
        Public lParam As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Structure RECT
        Public left As Integer
        Public top As Integer
        Public right As Integer
        Public bottom As Integer
    End Structure

    Public Shared Function Height() As Integer
        Dim taskbarHandle As IntPtr = FindWindow("Shell_TrayWnd", Nothing)

        Dim data As New APPBARDATA()
        data.cbSize = CUInt(Marshal.SizeOf(GetType(APPBARDATA)))
        data.hWnd = taskbarHandle
        Dim result As IntPtr = SHAppBarMessage(ABM.GetTaskbarPos, data)

        If result = IntPtr.Zero Then
            Throw New InvalidOperationException()
        End If

        Return Rectangle.FromLTRB(data.rc.left, data.rc.top, data.rc.right, data.rc.bottom).Height
    End Function

End Class

Источник: http://winsharp93.wordpress.com/2009/06/29/find-out-size-and-position-of-the-taskbar/

person Matt Hanson    schedule 10.09.2011
comment
Действительно лучшее решение, чем Bounds - WorkingArea. Однако я сомневаюсь, что это все равно решит проблему. Поскольку код выполняется удаленно на машине Citrix, я предполагаю, что загруженная user32.dll будет той же, что и на этой машине Citrix. Я дам вам знать наверняка, когда у меня будет время протестировать его. - person Marcus L; 13.09.2011