Revision 7fcbf914 trunk/NotifyIconWpf/Interop/TrayInfo.cs

b/trunk/NotifyIconWpf/Interop/TrayInfo.cs
7 7

  
8 8
namespace Hardcodet.Wpf.TaskbarNotification.Interop
9 9
{
10
  /// <summary>
11
  /// Resolves the current tray position.
12
  /// </summary>
13
  public static class TrayInfo
14
  {
15 10
    /// <summary>
16
    /// Gets the position of the system tray.
11
    /// Resolves the current tray position.
17 12
    /// </summary>
18
    /// <returns>Tray coordinates.</returns>
19
    public static Point GetTrayLocation()
13
    public static class TrayInfo
20 14
    {
21
      var info = new AppBarInfo();
22
      info.GetSystemTaskBarPosition();
23

  
24
      Rectangle rcWorkArea = info.WorkArea;
25

  
26
      int x = 0, y = 0;
27
      if (info.Edge == AppBarInfo.ScreenEdge.Left)
28
      {
29
        x = rcWorkArea.Left + 2;
30
        y = rcWorkArea.Bottom;
31
      }
32
      else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
33
      {
34
        x = rcWorkArea.Right;
35
        y = rcWorkArea.Bottom;
36
      }
37
      else if (info.Edge == AppBarInfo.ScreenEdge.Top)
38
      {
39
        x = rcWorkArea.Right;
40
        y = rcWorkArea.Top;
41
      }
42
      else if (info.Edge == AppBarInfo.ScreenEdge.Right)
43
      {
44
        x = rcWorkArea.Right;
45
        y = rcWorkArea.Bottom;
46
      }
47

  
48
      return new Point { X = x, Y = y};
15
        /// <summary>
16
        /// Gets the position of the system tray.
17
        /// </summary>
18
        /// <returns>Tray coordinates.</returns>
19
        public static Point GetTrayLocation()
20
        {
21
            var info = new AppBarInfo();
22
            info.GetSystemTaskBarPosition();
23

  
24
            Rectangle rcWorkArea = info.WorkArea;
25

  
26
            int x = 0, y = 0;
27
            if (info.Edge == AppBarInfo.ScreenEdge.Left)
28
            {
29
                x = rcWorkArea.Left + 2;
30
                y = rcWorkArea.Bottom;
31
            }
32
            else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
33
            {
34
                x = rcWorkArea.Right;
35
                y = rcWorkArea.Bottom;
36
            }
37
            else if (info.Edge == AppBarInfo.ScreenEdge.Top)
38
            {
39
                x = rcWorkArea.Right;
40
                y = rcWorkArea.Top;
41
            }
42
            else if (info.Edge == AppBarInfo.ScreenEdge.Right)
43
            {
44
                x = rcWorkArea.Right;
45
                y = rcWorkArea.Bottom;
46
            }
47

  
48
            return new Point {X = x, Y = y};
49
        }
49 50
    }
50
  }
51

  
52

  
53

  
54 51

  
55
  internal class AppBarInfo
56
  {
57 52

  
58
    [DllImport("user32.dll")]
59
    private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
60

  
61
    [DllImport("shell32.dll")]
62
    private static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA data);
63

  
64
    [DllImport("user32.dll")]
65
    private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam,
66
                                                     IntPtr pvParam, UInt32 fWinIni);
53
    internal class AppBarInfo
54
    {
55
        [DllImport("user32.dll")]
56
        private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
67 57

  
58
        [DllImport("shell32.dll")]
59
        private static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA data);
68 60

  
69
    private const int ABE_BOTTOM = 3;
70
    private const int ABE_LEFT = 0;
71
    private const int ABE_RIGHT = 2;
72
    private const int ABE_TOP = 1;
61
        [DllImport("user32.dll")]
62
        private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam,
63
            IntPtr pvParam, UInt32 fWinIni);
73 64

  
74
    private const int ABM_GETTASKBARPOS = 0x00000005;
75 65

  
76
    // SystemParametersInfo constants
77
    private const UInt32 SPI_GETWORKAREA = 0x0030;
66
        private const int ABE_BOTTOM = 3;
67
        private const int ABE_LEFT = 0;
68
        private const int ABE_RIGHT = 2;
69
        private const int ABE_TOP = 1;
78 70

  
79
    private APPBARDATA m_data;
71
        private const int ABM_GETTASKBARPOS = 0x00000005;
80 72

  
81
    public ScreenEdge Edge
82
    {
83
      get { return (ScreenEdge) m_data.uEdge; }
84
    }
73
        // SystemParametersInfo constants
74
        private const UInt32 SPI_GETWORKAREA = 0x0030;
85 75

  
76
        private APPBARDATA m_data;
86 77

  
87
    public Rectangle WorkArea
88
    {
89
      get
90
      {
91
        Int32 bResult = 0;
92
        var rc = new RECT();
93
        IntPtr rawRect = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
94
        bResult = SystemParametersInfo(SPI_GETWORKAREA, 0, rawRect, 0);
95
        rc = (RECT) Marshal.PtrToStructure(rawRect, rc.GetType());
96

  
97
        if (bResult == 1)
78
        public ScreenEdge Edge
98 79
        {
99
          Marshal.FreeHGlobal(rawRect);
100
          return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
80
            get { return (ScreenEdge) m_data.uEdge; }
101 81
        }
102 82

  
103
        return new Rectangle(0, 0, 0, 0);
104
      }
105
    }
106

  
107 83

  
108

  
109
    public void GetPosition(string strClassName, string strWindowName)
110
    {
111
      m_data = new APPBARDATA();
112
      m_data.cbSize = (UInt32) Marshal.SizeOf(m_data.GetType());
113

  
114
      IntPtr hWnd = FindWindow(strClassName, strWindowName);
115

  
116
      if (hWnd != IntPtr.Zero)
117
      {
118
        UInt32 uResult = SHAppBarMessage(ABM_GETTASKBARPOS, ref m_data);
119

  
120
        if (uResult != 1)
84
        public Rectangle WorkArea
121 85
        {
122
          throw new Exception("Failed to communicate with the given AppBar");
86
            get
87
            {
88
                Int32 bResult = 0;
89
                var rc = new RECT();
90
                IntPtr rawRect = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
91
                bResult = SystemParametersInfo(SPI_GETWORKAREA, 0, rawRect, 0);
92
                rc = (RECT) Marshal.PtrToStructure(rawRect, rc.GetType());
93

  
94
                if (bResult == 1)
95
                {
96
                    Marshal.FreeHGlobal(rawRect);
97
                    return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
98
                }
99

  
100
                return new Rectangle(0, 0, 0, 0);
101
            }
123 102
        }
124
      }
125
      else
126
      {
127
        throw new Exception("Failed to find an AppBar that matched the given criteria");
128
      }
129
    }
130 103

  
131 104

  
132
    public void GetSystemTaskBarPosition()
133
    {
134
      GetPosition("Shell_TrayWnd", null);
135
    }
105
        public void GetPosition(string strClassName, string strWindowName)
106
        {
107
            m_data = new APPBARDATA();
108
            m_data.cbSize = (UInt32) Marshal.SizeOf(m_data.GetType());
109

  
110
            IntPtr hWnd = FindWindow(strClassName, strWindowName);
111

  
112
            if (hWnd != IntPtr.Zero)
113
            {
114
                UInt32 uResult = SHAppBarMessage(ABM_GETTASKBARPOS, ref m_data);
115

  
116
                if (uResult != 1)
117
                {
118
                    throw new Exception("Failed to communicate with the given AppBar");
119
                }
120
            }
121
            else
122
            {
123
                throw new Exception("Failed to find an AppBar that matched the given criteria");
124
            }
125
        }
136 126

  
137 127

  
128
        public void GetSystemTaskBarPosition()
129
        {
130
            GetPosition("Shell_TrayWnd", null);
131
        }
138 132

  
139 133

  
140
    public enum ScreenEdge
141
    {
142
      Undefined = -1,
143
      Left = ABE_LEFT,
144
      Top = ABE_TOP,
145
      Right = ABE_RIGHT,
146
      Bottom = ABE_BOTTOM
147
    }
134
        public enum ScreenEdge
135
        {
136
            Undefined = -1,
137
            Left = ABE_LEFT,
138
            Top = ABE_TOP,
139
            Right = ABE_RIGHT,
140
            Bottom = ABE_BOTTOM
141
        }
148 142

  
149 143

  
150
    [StructLayout(LayoutKind.Sequential)]
151
    private struct APPBARDATA
152
    {
153
      public UInt32 cbSize;
154
      public IntPtr hWnd;
155
      public UInt32 uCallbackMessage;
156
      public UInt32 uEdge;
157
      public RECT rc;
158
      public Int32 lParam;
159
    }
144
        [StructLayout(LayoutKind.Sequential)]
145
        private struct APPBARDATA
146
        {
147
            public UInt32 cbSize;
148
            public IntPtr hWnd;
149
            public UInt32 uCallbackMessage;
150
            public UInt32 uEdge;
151
            public RECT rc;
152
            public Int32 lParam;
153
        }
160 154

  
161
    [StructLayout(LayoutKind.Sequential)]
162
    private struct RECT
163
    {
164
      public Int32 left;
165
      public Int32 top;
166
      public Int32 right;
167
      public Int32 bottom;
155
        [StructLayout(LayoutKind.Sequential)]
156
        private struct RECT
157
        {
158
            public Int32 left;
159
            public Int32 top;
160
            public Int32 right;
161
            public Int32 bottom;
162
        }
168 163
    }
169

  
170
  }
171 164
}

Also available in: Unified diff