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