dev 19-3-28
This commit is contained in:
1 parent
2cd021d34c
commit
67dc02ae83
4 files changed
+154
-102
No files matched your search
@@ -4,13 +4,14 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Controls.Primitives;
|
using System.Windows.Controls.Primitives;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using HandyControl.Tools;
|
using HandyControl.Tools;
|
||||||
using HandyControl.Tools.Interop;
|
using HandyControl.Tools.Interop;
|
||||||
|
|
||||||
namespace HandyControl.Controls
|
namespace HandyControl.Controls
|
||||||
{
|
{
|
||||||
public class NotifyIcon : FrameworkElement
|
public class NotifyIcon : FrameworkElement, IDisposable
|
||||||
{
|
{
|
||||||
private bool _added;
|
private bool _added;
|
||||||
|
|
||||||
@@ -50,10 +51,30 @@ namespace HandyControl.Controls
|
|||||||
{
|
{
|
||||||
_id = ++NextId;
|
_id = ++NextId;
|
||||||
_callback = Callback;
|
_callback = Callback;
|
||||||
CreateToolTip();
|
|
||||||
RegisterClass();
|
Loaded += (s, e) =>
|
||||||
OnIconChanged();
|
{
|
||||||
UpdateIcon(true);
|
CreateToolTip();
|
||||||
|
RegisterClass();
|
||||||
|
OnIconChanged();
|
||||||
|
UpdateIcon(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Application.Current != null) Application.Current.Exit += (s, e) => Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
~NotifyIcon()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
|
||||||
|
"Text", typeof(string), typeof(NotifyIcon), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public string Text
|
||||||
|
{
|
||||||
|
get => (string) GetValue(TextProperty);
|
||||||
|
set => SetValue(TextProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
|
public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
|
||||||
@@ -121,9 +142,11 @@ namespace HandyControl.Controls
|
|||||||
uCallbackMessage = WmTrayMouseMessage,
|
uCallbackMessage = WmTrayMouseMessage,
|
||||||
uFlags = NativeMethods.NIF_MESSAGE | NativeMethods.NIF_ICON | NativeMethods.NIF_TIP,
|
uFlags = NativeMethods.NIF_MESSAGE | NativeMethods.NIF_ICON | NativeMethods.NIF_TIP,
|
||||||
hWnd = _messageWindowHandle,
|
hWnd = _messageWindowHandle,
|
||||||
|
uTimeoutOrVersion = 10,
|
||||||
uID = _id,
|
uID = _id,
|
||||||
dwInfoFlags = NativeMethods.NIIF_INFO,
|
dwInfoFlags = NativeMethods.NIF_TIP,
|
||||||
hIcon = _currentSmallIconHandle.CriticalGetHandle()
|
hIcon = _currentSmallIconHandle.DangerousGetHandle(),
|
||||||
|
szTip = Text
|
||||||
};
|
};
|
||||||
|
|
||||||
if (showIconInTray)
|
if (showIconInTray)
|
||||||
@@ -177,81 +200,92 @@ namespace HandyControl.Controls
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//switch (lparam.ToInt32())
|
Console.WriteLine(lparam);
|
||||||
//{
|
switch (lparam.ToInt32())
|
||||||
// case NativeMethods.WM_LBUTTONDBLCLK:
|
{
|
||||||
// WmMouseDown(MouseButton.Left, 2);
|
case NativeMethods.WM_LBUTTONDBLCLK:
|
||||||
// break;
|
WmMouseDown(MouseButton.Left, 2);
|
||||||
// case NativeMethods.WM_LBUTTONDOWN:
|
break;
|
||||||
// WmMouseDown(MouseButton.Left, 1);
|
case NativeMethods.WM_LBUTTONDOWN:
|
||||||
// break;
|
WmMouseDown(MouseButton.Left, 1);
|
||||||
// case NativeMethods.WM_LBUTTONUP:
|
break;
|
||||||
// WmMouseUp(MouseButton.Left);
|
case NativeMethods.WM_LBUTTONUP:
|
||||||
// break;
|
WmMouseUp(MouseButton.Left);
|
||||||
// case NativeMethods.WM_MBUTTONDBLCLK:
|
break;
|
||||||
// WmMouseDown(MouseButton.Middle, 2);
|
case NativeMethods.WM_MBUTTONDBLCLK:
|
||||||
// break;
|
WmMouseDown(MouseButton.Middle, 2);
|
||||||
// case NativeMethods.WM_MBUTTONDOWN:
|
break;
|
||||||
// WmMouseDown(MouseButton.Middle, 1);
|
case NativeMethods.WM_MBUTTONDOWN:
|
||||||
// break;
|
WmMouseDown(MouseButton.Middle, 1);
|
||||||
// case NativeMethods.WM_MBUTTONUP:
|
break;
|
||||||
// WmMouseUp(MouseButton.Middle);
|
case NativeMethods.WM_MBUTTONUP:
|
||||||
// break;
|
WmMouseUp(MouseButton.Middle);
|
||||||
// case NativeMethods.WM_MOUSEMOVE:
|
break;
|
||||||
// WmMouseMove();
|
case NativeMethods.WM_MOUSEMOVE:
|
||||||
// break;
|
WmMouseMove();
|
||||||
// case NativeMethods.WM_RBUTTONDBLCLK:
|
break;
|
||||||
// WmMouseDown(MouseButton.Right, 2);
|
case NativeMethods.WM_RBUTTONDBLCLK:
|
||||||
// break;
|
WmMouseDown(MouseButton.Right, 2);
|
||||||
// case NativeMethods.WM_RBUTTONDOWN:
|
break;
|
||||||
// WmMouseDown(MouseButton.Right, 1);
|
case NativeMethods.WM_RBUTTONDOWN:
|
||||||
// break;
|
WmMouseDown(MouseButton.Right, 1);
|
||||||
// case NativeMethods.WM_RBUTTONUP:
|
break;
|
||||||
// ShowContextMenu();
|
case NativeMethods.WM_RBUTTONUP:
|
||||||
// WmMouseUp(MouseButton.Right);
|
ShowContextMenu();
|
||||||
// break;
|
WmMouseUp(MouseButton.Right);
|
||||||
//}
|
break;
|
||||||
|
case 0x406:
|
||||||
|
OnBalloonTipShown();
|
||||||
|
break;
|
||||||
|
case 0x407:
|
||||||
|
OnBalloonTipClosed();
|
||||||
|
break;
|
||||||
|
case NativeMethods.NIN_BALLOONTIMEOUT:
|
||||||
|
OnBalloonTipClosed();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var point = new POINT();
|
|
||||||
UnsafeNativeMethods.GetCursorPos(point);
|
|
||||||
ShowToolTip(point);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wparam, lparam);
|
return UnsafeNativeMethods.DefWindowProc(hWnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnBalloonTipShown()
|
||||||
|
{
|
||||||
|
var point = new POINT();
|
||||||
|
UnsafeNativeMethods.GetCursorPos(point);
|
||||||
|
ShowToolTip(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnBalloonTipClosed() => _toolTip.IsOpen = false;
|
||||||
|
|
||||||
private void WmMouseDown(MouseButton button, int clicks)
|
private void WmMouseDown(MouseButton button, int clicks)
|
||||||
{
|
{
|
||||||
if (clicks == 2)
|
if (clicks == 2)
|
||||||
{
|
{
|
||||||
OnMouseDoubleClick(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
||||||
{
|
{
|
||||||
Source = this,
|
|
||||||
RoutedEvent = MouseDoubleClickEvent
|
RoutedEvent = MouseDoubleClickEvent
|
||||||
});
|
});
|
||||||
_doubleClick = true;
|
_doubleClick = true;
|
||||||
}
|
}
|
||||||
OnMouseDown(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
||||||
{
|
{
|
||||||
Source = this,
|
|
||||||
RoutedEvent = MouseDownEvent
|
RoutedEvent = MouseDownEvent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WmMouseUp(MouseButton button)
|
private void WmMouseUp(MouseButton button)
|
||||||
{
|
{
|
||||||
OnMouseUp(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
||||||
{
|
{
|
||||||
Source = this,
|
|
||||||
RoutedEvent = MouseUpEvent
|
RoutedEvent = MouseUpEvent
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_doubleClick)
|
if (!_doubleClick)
|
||||||
{
|
{
|
||||||
OnClick(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
|
||||||
{
|
{
|
||||||
Source = this,
|
|
||||||
RoutedEvent = ClickEvent
|
RoutedEvent = ClickEvent
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -260,16 +294,32 @@ namespace HandyControl.Controls
|
|||||||
|
|
||||||
private void WmMouseMove()
|
private void WmMouseMove()
|
||||||
{
|
{
|
||||||
OnMouseMove(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount)
|
RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount)
|
||||||
{
|
{
|
||||||
RoutedEvent = MouseMoveEvent,
|
RoutedEvent = MouseMoveEvent
|
||||||
Source = this,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowContextMenu()
|
private void ShowContextMenu()
|
||||||
{
|
{
|
||||||
if (ContextMenu != null) ContextMenu.IsOpen = true;
|
if (ContextMenu != null)
|
||||||
|
{
|
||||||
|
var point = new POINT();
|
||||||
|
UnsafeNativeMethods.GetCursorPos(point);
|
||||||
|
|
||||||
|
ContextMenu.Placement = PlacementMode.AbsolutePoint;
|
||||||
|
ContextMenu.HorizontalOffset = point.x;
|
||||||
|
ContextMenu.VerticalOffset = point.y;
|
||||||
|
ContextMenu.IsOpen = true;
|
||||||
|
|
||||||
|
var handle = IntPtr.Zero;
|
||||||
|
var hwndSource = (HwndSource)PresentationSource.FromVisual(ContextMenu);
|
||||||
|
if (hwndSource != null)
|
||||||
|
{
|
||||||
|
handle = hwndSource.Handle;
|
||||||
|
}
|
||||||
|
UnsafeNativeMethods.SetForegroundWindow(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowToolTip(POINT point)
|
private void ShowToolTip(POINT point)
|
||||||
@@ -287,9 +337,7 @@ namespace HandyControl.Controls
|
|||||||
_toolTip = new ToolTip
|
_toolTip = new ToolTip
|
||||||
{
|
{
|
||||||
Placement = PlacementMode.AbsolutePoint,
|
Placement = PlacementMode.AbsolutePoint,
|
||||||
HasDropShadow = false,
|
Style = null
|
||||||
BorderThickness = new Thickness(0),
|
|
||||||
Background = Brushes.Transparent
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_toolTip.SetBinding(ContentControl.ContentProperty, new Binding(ToolTipProperty.Name) { Source = this });
|
_toolTip.SetBinding(ContentControl.ContentProperty, new Binding(ToolTipProperty.Name) { Source = this });
|
||||||
@@ -316,48 +364,42 @@ namespace HandyControl.Controls
|
|||||||
remove => RemoveHandler(MouseDoubleClickEvent, value);
|
remove => RemoveHandler(MouseDoubleClickEvent, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly RoutedEvent BalloonTipShownEvent =
|
//public static readonly RoutedEvent BalloonTipShownEvent =
|
||||||
EventManager.RegisterRoutedEvent("BalloonTipShown", RoutingStrategy.Bubble,
|
// EventManager.RegisterRoutedEvent("BalloonTipShown", RoutingStrategy.Bubble,
|
||||||
typeof(RoutedEventHandler), typeof(NotifyIcon));
|
// typeof(RoutedEventHandler), typeof(NotifyIcon));
|
||||||
|
|
||||||
public event RoutedEventHandler BalloonTipShown
|
//public event RoutedEventHandler BalloonTipShown
|
||||||
|
//{
|
||||||
|
// add => AddHandler(BalloonTipShownEvent, value);
|
||||||
|
// remove => RemoveHandler(BalloonTipShownEvent, value);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public static readonly RoutedEvent BalloonTipClosedEvent =
|
||||||
|
// EventManager.RegisterRoutedEvent("BalloonTipClosed", RoutingStrategy.Bubble,
|
||||||
|
// typeof(RoutedEventHandler), typeof(NotifyIcon));
|
||||||
|
|
||||||
|
//public event RoutedEventHandler BalloonTipClosed
|
||||||
|
//{
|
||||||
|
// add => AddHandler(BalloonTipClosedEvent, value);
|
||||||
|
// remove => RemoveHandler(BalloonTipClosedEvent, value);
|
||||||
|
//}
|
||||||
|
|
||||||
|
private void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
add => AddHandler(BalloonTipShownEvent, value);
|
if (disposing)
|
||||||
remove => RemoveHandler(BalloonTipShownEvent, value);
|
{
|
||||||
|
UpdateIcon(false);
|
||||||
|
_defaultLargeIconHandle?.Dispose();
|
||||||
|
_defaultSmallIconHandle?.Dispose();
|
||||||
|
_currentLargeIconHandle?.Dispose();
|
||||||
|
_currentSmallIconHandle?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly RoutedEvent BalloonTipClosedEvent =
|
public void Dispose()
|
||||||
EventManager.RegisterRoutedEvent("BalloonTipClosed", RoutingStrategy.Bubble,
|
|
||||||
typeof(RoutedEventHandler), typeof(NotifyIcon));
|
|
||||||
|
|
||||||
public event RoutedEventHandler BalloonTipClosed
|
|
||||||
{
|
{
|
||||||
add => AddHandler(BalloonTipClosedEvent, value);
|
Dispose(true);
|
||||||
remove => RemoveHandler(BalloonTipClosedEvent, value);
|
GC.SuppressFinalize(this);
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnClick(MouseButtonEventArgs e) => RaiseEvent(e);
|
|
||||||
|
|
||||||
protected virtual void OnDoubleClick(MouseButtonEventArgs e) => RaiseEvent(e);
|
|
||||||
|
|
||||||
protected virtual void OnMouseDoubleClick(MouseButtonEventArgs e) => RaiseEvent(e);
|
|
||||||
|
|
||||||
protected override void OnMouseDown(MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseDown(e);
|
|
||||||
RaiseEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseUp(MouseButtonEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseUp(e);
|
|
||||||
RaiseEvent(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnMouseMove(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.OnMouseMove(e);
|
|
||||||
RaiseEvent(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,9 @@ namespace HandyControl.Tools.Interop
|
|||||||
NIF_ICON = 0x00000002,
|
NIF_ICON = 0x00000002,
|
||||||
NIF_TIP = 0x00000004,
|
NIF_TIP = 0x00000004,
|
||||||
NIF_INFO = 0x00000010,
|
NIF_INFO = 0x00000010,
|
||||||
|
NIN_BALLOONSHOW = WM_USER + 2,
|
||||||
|
NIN_BALLOONHIDE = WM_USER + 3,
|
||||||
|
NIN_BALLOONTIMEOUT = WM_USER + 4,
|
||||||
NIM_ADD = 0x00000000,
|
NIM_ADD = 0x00000000,
|
||||||
NIM_MODIFY = 0x00000001,
|
NIM_MODIFY = 0x00000001,
|
||||||
NIM_DELETE = 0x00000002,
|
NIM_DELETE = 0x00000002,
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ namespace HandyControl.Tools.Interop
|
|||||||
internal static extern int ExtractIconEx(string szExeFileName, int nIconIndex, out IconHandle phiconLarge, out IconHandle phiconSmall, int nIcons);
|
internal static extern int ExtractIconEx(string szExeFileName, int nIconIndex, out IconHandle phiconLarge, out IconHandle phiconSmall, int nIcons);
|
||||||
|
|
||||||
[DllImport(ExternDll.Shell32, CharSet = CharSet.Auto)]
|
[DllImport(ExternDll.Shell32, CharSet = CharSet.Auto)]
|
||||||
[ResourceExposure(ResourceScope.None)]
|
|
||||||
public static extern int Shell_NotifyIcon(int message, NOTIFYICONDATA pnid);
|
public static extern int Shell_NotifyIcon(int message, NOTIFYICONDATA pnid);
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
@@ -167,15 +166,15 @@ namespace HandyControl.Tools.Interop
|
|||||||
IntPtr lpParam);
|
IntPtr lpParam);
|
||||||
|
|
||||||
[DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
[ResourceExposure(ResourceScope.None)]
|
|
||||||
public static extern short RegisterClass(WNDCLASS wc);
|
public static extern short RegisterClass(WNDCLASS wc);
|
||||||
|
|
||||||
[DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
|
[DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
|
||||||
[ResourceExposure(ResourceScope.None)]
|
|
||||||
public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
public static extern IntPtr DefWindowProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
|
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
|
||||||
[ResourceExposure(ResourceScope.None)]
|
|
||||||
public static extern bool GetCursorPos([In, Out] POINT pt);
|
public static extern bool GetCursorPos([In, Out] POINT pt);
|
||||||
|
|
||||||
|
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,14 @@
|
|||||||
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
|
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
|
||||||
Background="{DynamicResource RegionBrush}">
|
Background="{DynamicResource RegionBrush}">
|
||||||
<Grid>
|
<Grid>
|
||||||
<controls:NotifyIcon ToolTip="123"/>
|
<controls:NotifyIcon Text="123">
|
||||||
|
<controls:NotifyIcon.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="123"/>
|
||||||
|
<MenuItem Header="123"/>
|
||||||
|
<MenuItem Header="123"/>
|
||||||
|
</ContextMenu>
|
||||||
|
</controls:NotifyIcon.ContextMenu>
|
||||||
|
</controls:NotifyIcon>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
Reference in new issue
Block a user