【问题标题】:Programatically get Windows Taskbar Info: AutoHidden State, Taskbar Coordinates, which Screen Edge it's on and Taskbar Thickness以编程方式获取 Windows 任务栏信息:自动隐藏状态、任务栏坐标、它所在的屏幕边缘和任务栏厚度
【发布时间】:2017-06-25 12:09:36
【问题描述】:

我花了一段时间才找到这个答案,所以我想我会在这里作为问答分享。

我想让我的 Visual Basic 程序程序检索以下信息:

  1. 任务栏顶部、底部、左侧和右侧边缘的位置。底部 和 Top 表示这些边缘和顶部任何点的 y 值 left 表示这些边缘上任何点的 x 值。
  2. 它所在的屏幕边缘:底部、顶部、左侧或右侧屏幕 边缘
  3. Windows 任务栏的自动隐藏状态
  4. 任务栏的厚度(请记住,厚度会因 DPI 和屏幕边缘位置而异,其中左右边缘可能会导致任务栏比顶部和底部更厚)。

【问题讨论】:

    标签: vb.net pinvoke taskbar


    【解决方案1】:

    此代码由我编写,但基于我从this post on CodeGuru 获得的信息。我要感谢 Visual Vincent,他在评论部分提出的更正建议使得在 x64 中运行此代码成为可能。

    准备:共享常量、变量和函数:

    Const ABS_AUTOHIDE As Int32 = 1
    Const ABS_ONTOP As Int32 = 2
    Const ABM_NEW As Int32 = 0
    Const ABM_REMOVE As Int32 = 1
    Const ABM_QUERYPOS As Int32 = 2
    Const ABM_SETPOS As Int32 = 3
    Const ABM_GETSTATE As Int32 = 4
    Const ABM_GETTASKBARPOS As Int32 = 5
    Const ABM_ACTIVATE As Int32 = 6
    Const ABM_GETAUTOHIDEBAR As Int32 = 7
    Const ABM_SETAUTOHIDEBAR As Int32 = 8
    Const ABM_WINDOWPOSCHANGED As Int32 = 9
    
    Const TB_POS_BOTTOM As Integer = 1
    Const TB_POS_TOP As Integer = 2
    Const TB_POS_LEFT As Integer = 3
    Const TB_POS_RIGHT As Integer = 4
    
    Private Declare Function apiSHAppBarMessage Lib "shell32" Alias "SHAppBarMessage" (ByVal dwMessage As UInt32, ByRef pData As APPBARDATA) As UIntPtr
    
    Private Structure RECT
        Public rLeft, rTop, rRight, rBottom As Int32
    End Structure
    
    Private Structure APPBARDATA
        Public cbSize As UInt32, hwnd As IntPtr, uCallbackMessage, uEdge As UInt32, rc As RECT, lParam As IntPtr
    End Structure
    
    Dim ABD As New APPBARDATA
    Dim Autohide_State As Int32
    Dim taskbar_left, taskbar_right, taskbar_top, taskbar_bottom, taskbar_edge, taskbar_thickness As Integer    
    

    第 1 部分和第 2 部分:下面的 Sub 可用于查找任务栏的顶部、底部、左侧和右侧边缘的位置以及它所在的屏幕边缘。

        Private Sub GetTaskBarEdge_and_Coordinates()
        apiSHAppBarMessage(ABM_GETTASKBARPOS, ABD)
        taskbar_left = ABD.rc.rLeft
        taskbar_right = ABD.rc.rRight
        taskbar_top = ABD.rc.rTop
        taskbar_bottom = ABD.rc.rBottom
    
        'Figure out if it's located on the buttom, top, left or right edge of screen 
        If (taskbar_left < 5) And (taskbar_top > 5) Then
            taskbar_edge = TB_POS_BOTTOM
        ElseIf (taskbar_left < 5) And (taskbar_top < 5) And (taskbar_right > taskbar_bottom) Then
            taskbar_edge = TB_POS_TOP
        ElseIf (taskbar_left < 5) And (taskbar_top < 5) And (taskbar_right < taskbar_bottom) Then
            taskbar_edge = TB_POS_LEFT
        ElseIf (taskbar_left > 5) And (taskbar_top < 5) Then
            taskbar_edge = TB_POS_RIGHT
        Else
            MsgBox("Something went wrong while I was trying to find the taskbar edge. Please contact the develloper. Defaulting Edge to bottom.")
            taskbar_edge = TB_POS_BOTTOM
        End If
    End Sub
    

    第 3 部分:下面的函数将为您提供自动隐藏状态的整数值。

    0 Means AH is off, Always on top is off.  
    1 means AH is on and Always on Top is off. 
    2 means AH is off and AoT is on. 
    3 means AH and AoT are on. 
    

    注意我在第 1 部分中设置的常量:ABS_AUTOHIDE = 1 , ABS_ONTOP = 2。

    Private Function GetTaskBarAHState() As Integer
        Return CInt(apiSHAppBarMessage(ABM_GETSTATE, Nothing))
    End Function
    

    第 4 部分:任务栏厚度可以从 taskbar_bottom - taskbar_top 或 taskbar_right - taskbar_left 计算(取决于任务栏的边缘)。

    Private Sub GetTaskBar_Thickness()
    
        GetTaskBarEdge_and_Coordinates()
    
        Select Case taskbar_edge
            Case TB_POS_BOTTOM
                taskbar_thickness = Math.Abs(taskbar_bottom - taskbar_top)
            Case TB_POS_TOP
                taskbar_thickness = Math.Abs(taskbar_bottom - taskbar_top)
            Case Case TB_POS_LEFT
                taskbar_thickness = Math.Abs(taskbar_right - taskbar_left)
            Case TB_POS_RIGHT
                taskbar_thickness = Math.Abs(taskbar_right - taskbar_left)
            Case Else
                MsgBox("Something went wrong while I tried to find Taskbar thickness. Please contact the develloper. Default to taskbar thickness of 39 [4]")
                taskbar_thickness = 39
        End Select
    
    End Sub     
    

    【讨论】:

    • 很好,但是APPBARDATA 结构中的字段类型不正确。 cbSize 应为UInt32hWnd 应为IntPtruCallbackMessageuEdge 应为UInt32lParam 应为IntPtr
    • 另外apiSHAppBarMessage函数中的dwMessage参数应该是UInt32,函数的返回值应该是UIntPtr
    • 太棒了!我想您会在验证代码仍然有效后更新答案? -- 供参考,以下是文档:APPBARDATA structureWindows Data Types
    • 数据类型转换其实很简单。假设您应该转换cbSize 字段(数据类型DWORD):在Windows 数据类型 列表中查找DWORD,您将看到声明typedef unsigned long DWORD;(在C++ 中@987654348 @ = int = int32),因此您应该有一个 unsigned Int32,即 UInt32。 -- 任何未知和*_PTR 数据类型通常映射到IntPtrUIntPtr
    • 很高兴我能帮上忙!目前我的时间有点短,但稍后我可以为您提供有关数据类型的更多详细信息。 -- Do I simply use CInt(UIntPtr return value) - 不完全是。 UIntPtr 可以映射到 UIntegerULong(取决于它是 32 位还是 64 位系统),因此您应该更改返回类型:GetTaskBarAHState() As ULong,然后:@987654361 @.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2011-05-06
    • 2013-10-26
    • 2011-01-05
    • 2011-01-03
    • 2012-11-23
    相关资源
    最近更新 更多