작업 표시 줄 (taskbar) 에 대한 정 보 를 가 져 오 는 방법

문 제 는 일반 응용 프로그램 에 대해 서 는 시스템 트 레이 로 창 을 최소 화 하 는 경우 가 많다.우리 가 이 트 레이 아이콘 을 클릭 하면 우호 적 인 알림 인터페이스 가 나타 날 수 있 고 적당 한 조작 을 할 수 있 습 니 다.일반적인 상황 에서 우 리 는 이 우호 적 인 알림 인 터 페 이 스 를 데스크 톱 의 오른쪽 아래 에 굵게 놓 을 수 있 습 니 다. XP 에 대해 서 는 OK 입 니 다. XP 는 작업 표시 줄 을 데스크 톱 의 위, 왼쪽, 오른쪽 세 방향 으로 끌 어 올 리 는 것 을 허용 하지 않 기 때문에 아래 데스크 톱 의 맨 아래 에 만 멈 출 수 있 습 니 다. 그러나 win 7 에 대해 서 는 다른 세 방향 을 고려 해 야 합 니 다.이 방향 에 따라 제시 인터페이스 가 놓 인 위 치 를 확인 하 세 요.그렇다면 작업 표시 줄 의 위치 와 관련 정 보 를 어떻게 얻 습 니까?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
typedef struct _AppBarData {
    DWORD cbSize;             // The size of the structure, in bytes. 
    HWND hWnd;                // The handle to the appbar window. 
    UINT uCallbackMessage;    // An application-defined message identifier.This member is used when sending the ABM_NEW message. 
    UINT uEdge;               //     , 4 :ABE_BOTTOM、ABE_LEFT、ABE_RIGHT、ABE_TOP
    RECT rc;                  //           。
    LPARAM lParam;            // This member is used with the ABM_SETAUTOHIDEBAR and ABM_SETSTATE messages. 
} APPBARDATA, *PAPPBARDATA;

간단 한 C++ 코드:
HWND hwnd = FindWindow(L"Shell_TrayWnd", L"");
    if (hwnd != NULL)
    {
        APPBARDATA abd = { sizeof(APPBARDATA) };
        abd.hWnd = hwnd;
        BOOL bRt = SHAppBarMessage(ABM_GETTASKBARPOS, &abd);    //            
        UINT uState = (UINT) SHAppBarMessage(ABM_GETSTATE, &abd);   //        ABM_GETAUTOHIDEBAR   
        if (0 == uState)
        {
            // 0: Taskbar is neither in the auto-hide nor always-on-top state.
            // 1: ABS_AUTOHIDE The taskbar is in the auto-hide state. 
            // 2: ABS_ALWAYSONTOP The taskbar is in the always-on-top state. 
        }
        ...
    }

C\# 코드:
기능: 1. taskbar 의 위 치 를 가 져 옵 니 다. 2. 놓 인 창의 위 치 를 계산 합 니 다.
      API        :
        [DllImport("shell32.dll")]
        public static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);

        public enum AppBarMessages
        {
            New              = 0x00000000,
            Remove           = 0x00000001,
            QueryPos         = 0x00000002,
            SetPos           = 0x00000003,
            GetState         = 0x00000004,
            GetTaskBarPos    = 0x00000005,
            Activate         = 0x00000006,
            GetAutoHideBar   = 0x00000007,
            SetAutoHideBar   = 0x00000008,
            WindowPosChanged = 0x00000009,
            SetState         = 0x0000000a
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int _Left;
            public int _Top;
            public int _Right;
            public int _Bottom;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct APPBARDATA
        {
            public int    cbSize;
            public IntPtr hWnd;
            public uint   uCallbackMessage;
            public uint   uEdge;
            public RECT   rc;
            public int    lParam;
        }

        public enum AppBarStates
        {
            AutoHide    = 0x00000001,
            AlwaysOnTop = 0x00000002
        }

        public enum AppBarEdge
        {
            ABE_LEFT    = 0,
            ABE_TOP     = 1,
            ABE_RIGHT   = 2,
            ABE_BOTTOM  = 3
        }

        /// <summary>
        /// Retrieve current task bar's position info.
        /// </summary>
        /// <param name="taskbarRect">Current task bar's rectangle.</param>
        /// <param name="eTaskbarEdge">Current task bar's edge.</param>
        /// <param name="eTaskbarState">Current task bar's state.</param>
        public void GetTaskbarPosInfo(
            ref Rectangle taskbarRect, 
            ref Win32API.AppBarEdge eTaskbarEdge,
            ref Win32API.AppBarStates eTaskbarState)
        {
            eTaskbarState = Win32API.AppBarStates.AlwaysOnTop;  // Init default state

            IntPtr hTaskBarWnd = Win32API.FindWindow("Shell_TrayWnd", "");
            if (hTaskBarWnd != null)
            {
                Win32API.APPBARDATA abd = new Win32API.APPBARDATA();
                abd.cbSize = Marshal.SizeOf(typeof(Win32API.APPBARDATA));
                Win32API.SHAppBarMessage((uint)(Win32API.AppBarMessages.GetTaskBarPos), ref abd);
                eTaskbarEdge = (Win32API.AppBarEdge)(abd.uEdge);

                IntPtr hTmpWnd = Win32API.SHAppBarMessage((uint)(Win32API.AppBarMessages.GetAutoHideBar), ref abd);
                if (0 != hTmpWnd.ToInt64())
                {
                    eTaskbarState = Win32API.AppBarStates.AutoHide;
                }

                taskbarRect = Rectangle.FromLTRB(abd.rc._Left, abd.rc._Top, abd.rc._Right, abd.rc._Bottom);
            }
        }

        /// <summary>
        /// Initialize the popup window's position. 
        /// </summary>
        /// <returns></returns>
        private void InitialPosition()
        {
            Rectangle taskbarRect = new Rectangle();
            Win32API.AppBarEdge eTaskbarEdge = new Win32API.AppBarEdge();
            Win32API.AppBarStates eTaskbarState = new Win32API.AppBarStates();
            Win32API.GetTaskbarPosInfo(ref taskbarRect, ref eTaskbarEdge, ref eTaskbarState);

            int nSceenWidth = (int)Math.Ceiling(SystemParameters.VirtualScreenWidth);
            int nSceenHeight = (int)Math.Ceiling(SystemParameters.VirtualScreenHeight);

            // Whether current UI language is Middle East country language.
            // Because the Middle East country' user is right handed, so the popup window's position 
            // is different with normal when task bar is in TOP and BOTTOM status.
            bool isMiddleEastLanguage = IsMiddleEastLanguage();
            bool isTaskBarHide = (Win32API.AppBarStates.AutoHide == eTaskbarState) ? true : false;

            switch (eTaskbarEdge)
            {
                case Win32API.AppBarEdge.ABE_LEFT:
                    this.Left = isTaskBarHide ? taskbarRect.Left : (taskbarRect.Right);
                    this.Top = nSceenHeight - this.Height;
                    break;
                case Win32API.AppBarEdge.ABE_TOP:
                    this.Left = !isMiddleEastLanguage ? (taskbarRect.Right - this.Width) : taskbarRect.Left;
                    this.Top = isTaskBarHide ? taskbarRect.Top : (taskbarRect.Bottom);
                    break;
                case Win32API.AppBarEdge.ABE_RIGHT:
                    this.Left = isTaskBarHide ? (taskbarRect.Right - this.Width) : (taskbarRect.Left - this.Width);
                    this.Top = (nSceenHeight - this.Height)/*(1 == rightHanded) ? (nSceenHeight - this.Height) : (0)*/;
                    break;
                default:
                    this.Left = !isMiddleEastLanguage ? (taskbarRect.Right - this.Width) : taskbarRect.Left;
                    this.Top = isTaskBarHide ? (taskbarRect.Bottom - this.Height) : (taskbarRect.Top - this.Height);
                    break;
            }
        }

        /// <summary>
        /// Whether the current UI culture is middle country or not.
        /// </summary>
        /// <returns>Return true or false.</returns>
        private bool IsMiddleEastLanguage()
        {
            string cultureName = System.Globalization.CultureInfo.CurrentUICulture.Name;
            string mainLanguage = cultureName.Substring(0, 2);
            if (mainLanguage.Equals("ar") || mainLanguage.Equals("he"))
            {
                return true;
            }
            return false;
        }

 

좋은 웹페이지 즐겨찾기