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.         }  


 

 

 

 
posted @ 2013-12-18 18:02  青田  阅读(614)  评论(0编辑  收藏  举报