• C# 任务栏的相关信息


    问题提出:对于普通应用程序,我们很多时候会将窗口最小化到系统托盘。当我们点击这个托盘图标时,可能会弹出一些友好的提示界面,可以恰当的进行一些操作。
    一般情况下,我们可能粗暴的将这个友好提示界面放置在桌面的右下角,对于XP,这是OK的,因为XP不允许我们将任务栏拖动到桌面的上、左、右三个方向,
    只允许停靠下桌面的最下方,但是对于win7,我们便需要考虑到其它三个方向,再根据这个方向确定好提示界面放的位置。那么,如何获得任务栏的位置及相关信息?
    windows提供了相关和API进行操作。

    UINT_PTR SHAppBarMessage(
    DWORD dwMessage,
    PAPPBARDATA pData
    );
    其中
    dwMessage为发送给system的消息。
    pData为一个APPBARDATA结构体,用于存储发送或者返回的数据。

    dwMessage只能为以下的其中一个值。
    ABM_ACTIVATE:告知系统任务栏被激活。
    ABM_GETAUTOHIDEBAR:查询任务栏是否是自动隐藏(前提是要给出任务栏停靠的位置)。
    ABM_GETSTATE:查询任务栏自动隐藏和总是牌处于顶层的状态。
    ABM_GETTASKBARPOS:获取任务栏的边界矩形位置。
    ABM_QUERYPOS:请求任务栏的位置。(上、下、左、右)
    其它状态略。
    ABM_NEW、ABM_REMOVE、ABM_SETAUTOHIDEBAR、ABM_SETPOS、ABM_SETSTATE、ABM_WINDOWPOSCHANGED

    [csharp] view plaincopy
     
    1. typedef struct _AppBarData {  
    2.     DWORD cbSize;             // The size of the structure, in bytes.   
    3.     HWND hWnd;                // The handle to the appbar window.   
    4.     UINT uCallbackMessage;    // An application-defined message identifier.This member is used when sending the ABM_NEW message.   
    5.     UINT uEdge;               // 边界位置,有4种:ABE_BOTTOM、ABE_LEFT、ABE_RIGHT、ABE_TOP  
    6.     RECT rc;                  // 任务栏的边界矩形位置。  
    7.     LPARAM lParam;            // This member is used with the ABM_SETAUTOHIDEBAR and ABM_SETSTATE messages.   
    8. } APPBARDATA, *PAPPBARDATA;  

    一个简单的C++代码:
    [csharp] view plaincopy
     
    1. HWND hwnd = FindWindow(L"Shell_TrayWnd", L"");  
    2.     if (hwnd != NULL)  
    3.     {  
    4.         APPBARDATA abd = { sizeof(APPBARDATA) };  
    5.         abd.hWnd = hwnd;  
    6.         BOOL bRt = SHAppBarMessage(ABM_GETTASKBARPOS, &abd);    // 此处能够获取位置和矩形  
    7.         UINT uState = (UINT) SHAppBarMessage(ABM_GETSTATE, &abd);   // 此处也可以使用ABM_GETAUTOHIDEBAR来获取  
    8.         if (0 == uState)  
    9.         {  
    10.             // 0: Taskbar is neither in the auto-hide nor always-on-top state.  
    11.             // 1: ABS_AUTOHIDE The taskbar is in the auto-hide state.   
    12.             // 2: ABS_ALWAYSONTOP The taskbar is in the always-on-top state.   
    13.         }  
    14.         ...  
    15.     }  

    C#代码:

    功能:
    1. 获取taskbar的位置
    2. 计算出所放窗口的位置

    [csharp] view plaincopy
     
    1. 首先需要引入API及相关宏和结构体:  
    2.         [DllImport("shell32.dll")]  
    3.         public static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);  
    4.   
    5.         public enum AppBarMessages  
    6.         {  
    7.             New              = 0x00000000,  
    8.             Remove           = 0x00000001,  
    9.             QueryPos         = 0x00000002,  
    10.             SetPos           = 0x00000003,  
    11.             GetState         = 0x00000004,  
    12.             GetTaskBarPos    = 0x00000005,  
    13.             Activate         = 0x00000006,  
    14.             GetAutoHideBar   = 0x00000007,  
    15.             SetAutoHideBar   = 0x00000008,  
    16.             WindowPosChanged = 0x00000009,  
    17.             SetState         = 0x0000000a  
    18.         }  
    19.   
    20.         [StructLayout(LayoutKind.Sequential)]  
    21.         public struct RECT  
    22.         {  
    23.             public int _Left;  
    24.             public int _Top;  
    25.             public int _Right;  
    26.             public int _Bottom;  
    27.         }  
    28.   
    29.         [StructLayout(LayoutKind.Sequential)]  
    30.         public struct APPBARDATA  
    31.         {  
    32.             public int    cbSize;  
    33.             public IntPtr hWnd;  
    34.             public uint   uCallbackMessage;  
    35.             public uint   uEdge;  
    36.             public RECT   rc;  
    37.             public int    lParam;  
    38.         }  
    39.   
    40.         public enum AppBarStates  
    41.         {  
    42.             AutoHide    = 0x00000001,  
    43.             AlwaysOnTop = 0x00000002  
    44.         }  
    45.   
    46.         public enum AppBarEdge  
    47.         {  
    48.             ABE_LEFT    = 0,  
    49.             ABE_TOP     = 1,  
    50.             ABE_RIGHT   = 2,  
    51.             ABE_BOTTOM  = 3  
    52.         }  
    53.   
    54.         /// <summary>  
    55.         /// Retrieve current task bar's position info.  
    56.         /// </summary>  
    57.         /// <param name="taskbarRect">Current task bar's rectangle.</param>  
    58.         /// <param name="eTaskbarEdge">Current task bar's edge.</param>  
    59.         /// <param name="eTaskbarState">Current task bar's state.</param>  
    60.         public void GetTaskbarPosInfo(  
    61.             ref Rectangle taskbarRect,   
    62.             ref Win32API.AppBarEdge eTaskbarEdge,  
    63.             ref Win32API.AppBarStates eTaskbarState)  
    64.         {  
    65.             eTaskbarState = Win32API.AppBarStates.AlwaysOnTop;  // Init default state  
    66.   
    67.             IntPtr hTaskBarWnd = Win32API.FindWindow("Shell_TrayWnd""");  
    68.             if (hTaskBarWnd != null)  
    69.             {  
    70.                 Win32API.APPBARDATA abd = new Win32API.APPBARDATA();  
    71.                 abd.cbSize = Marshal.SizeOf(typeof(Win32API.APPBARDATA));  
    72.                 Win32API.SHAppBarMessage((uint)(Win32API.AppBarMessages.GetTaskBarPos), ref abd);  
    73.                 eTaskbarEdge = (Win32API.AppBarEdge)(abd.uEdge);  
    74.   
    75.                 IntPtr hTmpWnd = Win32API.SHAppBarMessage((uint)(Win32API.AppBarMessages.GetAutoHideBar), ref abd);  
    76.                 if (0 != hTmpWnd.ToInt64())  
    77.                 {  
    78.                     eTaskbarState = Win32API.AppBarStates.AutoHide;  
    79.                 }  
    80.   
    81.                 taskbarRect = Rectangle.FromLTRB(abd.rc._Left, abd.rc._Top, abd.rc._Right, abd.rc._Bottom);  
    82.             }  
    83.         }  
    84.   
    85.         /// <summary>  
    86.         /// Initialize the popup window's position.   
    87.         /// </summary>  
    88.         /// <returns></returns>  
    89.         private void InitialPosition()  
    90.         {  
    91.             Rectangle taskbarRect = new Rectangle();  
    92.             Win32API.AppBarEdge eTaskbarEdge = new Win32API.AppBarEdge();  
    93.             Win32API.AppBarStates eTaskbarState = new Win32API.AppBarStates();  
    94.             Win32API.GetTaskbarPosInfo(ref taskbarRect, ref eTaskbarEdge, ref eTaskbarState);  
    95.   
    96.             int nSceenWidth = (int)Math.Ceiling(SystemParameters.VirtualScreenWidth);  
    97.             int nSceenHeight = (int)Math.Ceiling(SystemParameters.VirtualScreenHeight);  
    98.   
    99.             // Whether current UI language is Middle East country language.  
    100.             // Because the Middle East country' user is right handed, so the popup window's position   
    101.             // is different with normal when task bar is in TOP and BOTTOM status.  
    102.             bool isMiddleEastLanguage = IsMiddleEastLanguage();  
    103.             bool isTaskBarHide = (Win32API.AppBarStates.AutoHide == eTaskbarState) ? true : false;  
    104.   
    105.             switch (eTaskbarEdge)  
    106.             {  
    107.                 case Win32API.AppBarEdge.ABE_LEFT:  
    108.                     this.Left = isTaskBarHide ? taskbarRect.Left : (taskbarRect.Right);  
    109.                     this.Top = nSceenHeight - this.Height;  
    110.                     break;  
    111.                 case Win32API.AppBarEdge.ABE_TOP:  
    112.                     this.Left = !isMiddleEastLanguage ? (taskbarRect.Right - this.Width) : taskbarRect.Left;  
    113.                     this.Top = isTaskBarHide ? taskbarRect.Top : (taskbarRect.Bottom);  
    114.                     break;  
    115.                 case Win32API.AppBarEdge.ABE_RIGHT:  
    116.                     this.Left = isTaskBarHide ? (taskbarRect.Right - this.Width) : (taskbarRect.Left - this.Width);  
    117.                     this.Top = (nSceenHeight - this.Height)/*(1 == rightHanded) ? (nSceenHeight - this.Height) : (0)*/;  
    118.                     break;  
    119.                 default:  
    120.                     this.Left = !isMiddleEastLanguage ? (taskbarRect.Right - this.Width) : taskbarRect.Left;  
    121.                     this.Top = isTaskBarHide ? (taskbarRect.Bottom - this.Height) : (taskbarRect.Top - this.Height);  
    122.                     break;  
    123.             }  
    124.         }  
    125.   
    126.         /// <summary>  
    127.         /// Whether the current UI culture is middle country or not.  
    128.         /// </summary>  
    129.         /// <returns>Return true or false.</returns>  
    130.         private bool IsMiddleEastLanguage()  
    131.         {  
    132.             string cultureName = System.Globalization.CultureInfo.CurrentUICulture.Name;  
    133.             string mainLanguage = cultureName.Substring(0, 2);  
    134.             if (mainLanguage.Equals("ar") || mainLanguage.Equals("he"))  
    135.             {  
    136.                 return true;  
    137.             }  
    138.             return false;  
    139.         }  


     

     

     
  • 相关阅读:
    pycharm试用版过期问题解决方法(仅能再使用30天)
    使用postmancli工具管理Postman数据
    使用Postman持续更新同步Collection
    ES6的解构赋值
    DOTween添加Sequance回调
    unity升级项目的时候注意不要忽略过程中的报错
    Java 如何实现各进制之间的相互转换
    使用 ohmyposh 美化 windows terminal,让其接近ohmyzsh
    configure: error: cannot find MySQL header files under /usr/local/mysql/lib/
    CentOS 7 释放内存
  • 原文地址:https://www.cnblogs.com/qingtianhua/p/3480816.html
Copyright © 2020-2023  润新知