如何在不使用Screen.WorkingArea的情况下找出任务栏高度?

时间:2011-09-07 13:04:23

标签: vb.net winforms citrix

我有一个表格应该将自己定位在屏幕的最右边缘,并在高度上拉伸以填充整个工作区域的高度。

没有什么太奇怪的,因此我使用Screen.WorkingArea.Height编写了一个解决方案,只要我在本地运行就可以正常工作。问题在于生产中表单是在 Citrix 环境中运行的,它似乎完全忽略了任务栏的高度。在Citrix Screen.WorkingArea.Height中返回与Screen.Bounds.Height完全相同的值 - 因此在任务栏下方展开。

我的想法是使用Screen.Bounds.Height(因为它似乎正确返回)并自行减去任务栏高度。唯一的问题是我能找到的关于如何执行此操作的唯一示例Screen.Bounds.Height - Screen.WorkingArea.Height

那么如何直接访问任务栏的高度? (当然,我很乐意听取有关如何解决这个问题的任何其他建议!)

1 个答案:

答案 0 :(得分: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/