GetTrayLocation now return with GetDeviceCoordinates. Fix in the case of multi-monitor.

Add extension point CustomPopupPosition to show Balloon on custom position.
AppBarInfo.WorkArea now return appbar workarea. Before it returns screen workarea.
This commit is contained in:
hemn.still
2015-02-02 18:45:16 +04:00
parent 0f7f9778c1
commit 111b48153e
2 changed files with 36 additions and 36 deletions

View File

@@ -3,6 +3,7 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows;
namespace Hardcodet.Wpf.TaskbarNotification.Interop namespace Hardcodet.Wpf.TaskbarNotification.Interop
@@ -18,6 +19,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
/// <returns>Tray coordinates.</returns> /// <returns>Tray coordinates.</returns>
public static Point GetTrayLocation() public static Point GetTrayLocation()
{ {
int space = 2;
var info = new AppBarInfo(); var info = new AppBarInfo();
info.GetSystemTaskBarPosition(); info.GetSystemTaskBarPosition();
@@ -26,31 +28,42 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
int x = 0, y = 0; int x = 0, y = 0;
if (info.Edge == AppBarInfo.ScreenEdge.Left) if (info.Edge == AppBarInfo.ScreenEdge.Left)
{ {
x = rcWorkArea.Left + 2; x = rcWorkArea.Right + space;
y = rcWorkArea.Bottom; y = rcWorkArea.Bottom;
} }
else if (info.Edge == AppBarInfo.ScreenEdge.Bottom) else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
{ {
x = rcWorkArea.Right; x = rcWorkArea.Right;
y = rcWorkArea.Bottom; y = rcWorkArea.Bottom - rcWorkArea.Height - space;
} }
else if (info.Edge == AppBarInfo.ScreenEdge.Top) else if (info.Edge == AppBarInfo.ScreenEdge.Top)
{ {
x = rcWorkArea.Right; x = rcWorkArea.Right;
y = rcWorkArea.Top; y = rcWorkArea.Top + rcWorkArea.Height + space;
} }
else if (info.Edge == AppBarInfo.ScreenEdge.Right) else if (info.Edge == AppBarInfo.ScreenEdge.Right)
{ {
x = rcWorkArea.Right; x = rcWorkArea.Right - rcWorkArea.Width - space;
y = rcWorkArea.Bottom; y = rcWorkArea.Bottom;
} }
return new Point {X = x, Y = y}; return GetDeviceCoordinates(new Point {X = x, Y = y});
}
/// <summary>
/// Recalculates OS coordinates in order to support WPFs coordinate
/// system if OS scaling (DPIs) is not 100%.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
public static Point GetDeviceCoordinates(Point point)
{
return new Point() { X = (int)(point.X / SystemInfo.DpiXFactor), Y = (int)(point.Y / SystemInfo.DpiYFactor) };
} }
} }
internal class AppBarInfo public class AppBarInfo
{ {
[DllImport("user32.dll")] [DllImport("user32.dll")]
private static extern IntPtr FindWindow(String lpClassName, String lpWindowName); private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
@@ -80,27 +93,15 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
get { return (ScreenEdge) m_data.uEdge; } get { return (ScreenEdge) m_data.uEdge; }
} }
public Rectangle WorkArea public Rectangle WorkArea
{ {
get get { return GetRectangle(m_data.rc); }
{
Int32 bResult = 0;
var rc = new RECT();
IntPtr rawRect = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
bResult = SystemParametersInfo(SPI_GETWORKAREA, 0, rawRect, 0);
rc = (RECT) Marshal.PtrToStructure(rawRect, rc.GetType());
if (bResult == 1)
{
Marshal.FreeHGlobal(rawRect);
return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
return new Rectangle(0, 0, 0, 0);
}
} }
private Rectangle GetRectangle(RECT rc)
{
return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
}
public void GetPosition(string strClassName, string strWindowName) public void GetPosition(string strClassName, string strWindowName)
{ {

View File

@@ -145,6 +145,14 @@ namespace Hardcodet.Wpf.TaskbarNotification
#endregion #endregion
#region Custom Balloons #region Custom Balloons
public delegate Point GetCustomPopupPosition();
public GetCustomPopupPosition CustomPopupPosition;
public Point GetPopupTrayPosition()
{
return TrayInfo.GetTrayLocation();
}
/// <summary> /// <summary>
/// Shows a custom control as a tooltip in the tray location. /// Shows a custom control as a tooltip in the tray location.
@@ -217,8 +225,8 @@ namespace Hardcodet.Wpf.TaskbarNotification
popup.Placement = PlacementMode.AbsolutePoint; popup.Placement = PlacementMode.AbsolutePoint;
popup.StaysOpen = true; popup.StaysOpen = true;
Point position = TrayInfo.GetTrayLocation();
position = GetDeviceCoordinates(position); Point position = this.CustomPopupPosition != null ? this.CustomPopupPosition() : this.GetPopupTrayPosition();
popup.HorizontalOffset = position.X - 1; popup.HorizontalOffset = position.X - 1;
popup.VerticalOffset = position.Y - 1; popup.VerticalOffset = position.Y - 1;
@@ -394,7 +402,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
WinApi.GetCursorPos(ref cursorPosition); WinApi.GetCursorPos(ref cursorPosition);
} }
cursorPosition = GetDeviceCoordinates(cursorPosition); cursorPosition = TrayInfo.GetDeviceCoordinates(cursorPosition);
bool isLeftClickCommandInvoked = false; bool isLeftClickCommandInvoked = false;
@@ -954,16 +962,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
#endregion #endregion
/// <summary>
/// Recalculates OS coordinates in order to support WPFs coordinate
/// system if OS scaling (DPIs) is not 100%.
/// </summary>
/// <param name="point"></param>
/// <returns></returns>
private Point GetDeviceCoordinates(Point point)
{
return new Point() { X = (int)(point.X / SystemInfo.DpiXFactor), Y = (int)(point.Y / SystemInfo.DpiYFactor) };
}
#region Dispose / Exit #region Dispose / Exit