mirror of
https://github.com/ckaczor/wpf-notifyicon.git
synced 2026-01-14 01:25:45 -05:00
Merge remote-tracking branch 'Reshetnikov/develop'
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Windows.Interop;
|
||||
|
||||
namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
{
|
||||
public static class SystemInfo
|
||||
{
|
||||
private static Tuple<double, double> dpiFactors;
|
||||
|
||||
private static Tuple<double, double> DpiFactors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dpiFactors == null)
|
||||
using (var source = new HwndSource(new HwndSourceParameters()))
|
||||
dpiFactors = Tuple.Create(source.CompositionTarget.TransformToDevice.M11, source.CompositionTarget.TransformToDevice.M22);
|
||||
return dpiFactors;
|
||||
}
|
||||
}
|
||||
|
||||
public static double DpiXFactor
|
||||
{
|
||||
get
|
||||
{
|
||||
var factors = DpiFactors;
|
||||
return factors != null ? factors.Item1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static double DpiYFactor
|
||||
{
|
||||
get
|
||||
{
|
||||
var factors = DpiFactors;
|
||||
return factors != null ? factors.Item2 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
|
||||
namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
@@ -18,6 +19,7 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
/// <returns>Tray coordinates.</returns>
|
||||
public static Point GetTrayLocation()
|
||||
{
|
||||
int space = 2;
|
||||
var info = new AppBarInfo();
|
||||
info.GetSystemTaskBarPosition();
|
||||
|
||||
@@ -26,31 +28,42 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
int x = 0, y = 0;
|
||||
if (info.Edge == AppBarInfo.ScreenEdge.Left)
|
||||
{
|
||||
x = rcWorkArea.Left + 2;
|
||||
x = rcWorkArea.Right + space;
|
||||
y = rcWorkArea.Bottom;
|
||||
}
|
||||
else if (info.Edge == AppBarInfo.ScreenEdge.Bottom)
|
||||
{
|
||||
x = rcWorkArea.Right;
|
||||
y = rcWorkArea.Bottom;
|
||||
y = rcWorkArea.Bottom - rcWorkArea.Height - space;
|
||||
}
|
||||
else if (info.Edge == AppBarInfo.ScreenEdge.Top)
|
||||
{
|
||||
x = rcWorkArea.Right;
|
||||
y = rcWorkArea.Top;
|
||||
y = rcWorkArea.Top + rcWorkArea.Height + space;
|
||||
}
|
||||
else if (info.Edge == AppBarInfo.ScreenEdge.Right)
|
||||
{
|
||||
x = rcWorkArea.Right;
|
||||
x = rcWorkArea.Right - rcWorkArea.Width - space;
|
||||
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")]
|
||||
private static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
|
||||
@@ -80,27 +93,15 @@ namespace Hardcodet.Wpf.TaskbarNotification.Interop
|
||||
get { return (ScreenEdge) m_data.uEdge; }
|
||||
}
|
||||
|
||||
|
||||
public Rectangle WorkArea
|
||||
{
|
||||
get
|
||||
{
|
||||
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);
|
||||
}
|
||||
get { return GetRectangle(m_data.rc); }
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BalloonIcon.cs" />
|
||||
<Compile Include="Interop\SystemInfo.cs" />
|
||||
<Compile Include="Interop\TrayInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -153,6 +153,14 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
#endregion
|
||||
|
||||
#region Custom Balloons
|
||||
public delegate Point GetCustomPopupPosition();
|
||||
|
||||
public GetCustomPopupPosition CustomPopupPosition;
|
||||
|
||||
public Point GetPopupTrayPosition()
|
||||
{
|
||||
return TrayInfo.GetTrayLocation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows a custom control as a tooltip in the tray location.
|
||||
@@ -225,8 +233,8 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
popup.Placement = PlacementMode.AbsolutePoint;
|
||||
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.VerticalOffset = position.Y - 1;
|
||||
|
||||
@@ -402,7 +410,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
WinApi.GetCursorPos(ref cursorPosition);
|
||||
}
|
||||
|
||||
cursorPosition = GetDeviceCoordinates(cursorPosition);
|
||||
cursorPosition = TrayInfo.GetDeviceCoordinates(cursorPosition);
|
||||
|
||||
bool isLeftClickCommandInvoked = false;
|
||||
|
||||
@@ -962,34 +970,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#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)
|
||||
{
|
||||
if (double.IsNaN(scalingFactor))
|
||||
{
|
||||
//calculate scaling factor in order to support non-standard DPIs
|
||||
var presentationSource = PresentationSource.FromVisual(this);
|
||||
if (presentationSource == null)
|
||||
{
|
||||
scalingFactor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var transform = presentationSource.CompositionTarget.TransformToDevice;
|
||||
scalingFactor = 1/transform.M11;
|
||||
}
|
||||
}
|
||||
|
||||
//on standard DPI settings, just return the point
|
||||
if (scalingFactor == 1.0) return point;
|
||||
|
||||
return new Point() {X = (int) (point.X*scalingFactor), Y = (int) (point.Y*scalingFactor)};
|
||||
}
|
||||
|
||||
#region Dispose / Exit
|
||||
|
||||
|
||||
Reference in New Issue
Block a user