Statistics
| Branch: | Revision:

root / trunk / NotifyIconWpf / Interop / TrayInfo.cs @ 049333d2

History | View | Annotate | Download (3.9 kB)

1
// Some interop code taken from Mike Marshall's AnyForm
2

    
3
using System;
4
using System.Drawing;
5
using System.Runtime.InteropServices;
6

    
7

    
8
namespace Hardcodet.Wpf.TaskbarNotification.Interop
9
{
10
  /// <summary>
11
  /// Resolves the current tray position.
12
  /// </summary>
13
  public static class TrayInfo
14
  {
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
    }
50
  }
51

    
52

    
53

    
54

    
55
  internal class AppBarInfo
56
  {
57

    
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);
67

    
68

    
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;
73

    
74
    private const int ABM_GETTASKBARPOS = 0x00000005;
75

    
76
    // SystemParametersInfo constants
77
    private const UInt32 SPI_GETWORKAREA = 0x0030;
78

    
79
    private APPBARDATA m_data;
80

    
81
    public ScreenEdge Edge
82
    {
83
      get { return (ScreenEdge) m_data.uEdge; }
84
    }
85

    
86

    
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)
98
        {
99
          Marshal.FreeHGlobal(rawRect);
100
          return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
101
        }
102

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

    
107

    
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)
121
        {
122
          throw new Exception("Failed to communicate with the given AppBar");
123
        }
124
      }
125
      else
126
      {
127
        throw new Exception("Failed to find an AppBar that matched the given criteria");
128
      }
129
    }
130

    
131

    
132
    public void GetSystemTaskBarPosition()
133
    {
134
      GetPosition("Shell_TrayWnd", null);
135
    }
136

    
137

    
138

    
139

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

    
149

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

    
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;
168
    }
169

    
170
  }
171
}