From 9aa6df87cb10f22511e5931598aceb6d0ed04132 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 20 Apr 2019 00:51:54 +0800 Subject: [PATCH 1/6] update readme --- Resources/TabControl.png | Bin 13018 -> 16447 bytes .../Themes/Styles/Base/TreeViewBaseStyle.xaml | 15 --------------- 2 files changed, 15 deletions(-) diff --git a/Resources/TabControl.png b/Resources/TabControl.png index f0fb2287cd5a3ca087c1d5c20b9806b3c62afdab..cfc6e8f931bb58e9d880c39d7410a8fde6ffe40e 100644 GIT binary patch literal 16447 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 Hdw={7bjG+E diff --git a/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/TreeViewBaseStyle.xaml b/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/TreeViewBaseStyle.xaml index 0e3018a6..0c8880ef 100644 --- a/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/TreeViewBaseStyle.xaml +++ b/src/Net_40/HandyControl_Net_40/Themes/Styles/Base/TreeViewBaseStyle.xaml @@ -106,7 +106,6 @@ - @@ -119,24 +118,10 @@ - - \ No newline at end of file From 3aa0f09d3991d88eaef12373123ce9b7eca95237 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 20 Apr 2019 23:36:44 +0800 Subject: [PATCH 2/6] improved notifyicon added mouseenter and mouseleave events --- .../Tools/Helper/AssemblyHelper.cs | 18 +- .../Controls/NotifyIconDemoCtl.xaml.cs | 7 + .../Controls/NotifyIconDemoViewModel.cs | 29 +++ .../ViewModel/Main/MainViewModel.cs | 5 +- .../Controls/Other/NotifyIcon.cs | 188 ++++++++++++++++-- .../Tools/Interop/NativeMethods.cs | 157 ++++++++++++++- 6 files changed, 388 insertions(+), 16 deletions(-) diff --git a/src/Shared/HandyControlDemo_Shared/Tools/Helper/AssemblyHelper.cs b/src/Shared/HandyControlDemo_Shared/Tools/Helper/AssemblyHelper.cs index ae55a7ee..da778226 100644 --- a/src/Shared/HandyControlDemo_Shared/Tools/Helper/AssemblyHelper.cs +++ b/src/Shared/HandyControlDemo_Shared/Tools/Helper/AssemblyHelper.cs @@ -1,15 +1,31 @@ using System; +using System.Collections.Generic; namespace HandyControlDemo.Tools { - public class AssemblyHelper + internal class AssemblyHelper { private static readonly string NameSpaceStr = typeof(AssemblyHelper).Assembly.GetName().Name; + private static readonly Dictionary CacheDic = new Dictionary(); + + public static void Register(string name, object instance) => CacheDic[name] = instance; + + public static object ResolveByKey(string key) + { + if (CacheDic.TryGetValue(key, out var value)) + { + return value; + } + + return null; + } + public static object CreateInternalInstance(string className) { try { + var type = Type.GetType($"{NameSpaceStr}.{className}"); return type == null ? null : Activator.CreateInstance(type); } diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml.cs b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml.cs index 4efd472c..402408dd 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml.cs +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/NotifyIconDemoCtl.xaml.cs @@ -1,4 +1,6 @@ using System.Windows; +using HandyControlDemo.Tools; +using HandyControlDemo.ViewModel; namespace HandyControlDemo.UserControl { @@ -7,8 +9,13 @@ namespace HandyControlDemo.UserControl public NotifyIconDemoCtl() { InitializeComponent(); + + AssemblyHelper.Register(nameof(NotifyIconDemoCtl), this); + Unloaded += NotifyIconDemoCtl_Unloaded; } + private void NotifyIconDemoCtl_Unloaded(object sender, RoutedEventArgs e) => ViewModelLocator.Instance.NotifyIconDemo.Cleanup(); + private void ButtonPush_OnClick(object sender, RoutedEventArgs e) => NotifyIconContextContent.CloseContextControl(); } } diff --git a/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/NotifyIconDemoViewModel.cs b/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/NotifyIconDemoViewModel.cs index 72ae46b6..9b7750d1 100644 --- a/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/NotifyIconDemoViewModel.cs +++ b/src/Shared/HandyControlDemo_Shared/ViewModel/Controls/NotifyIconDemoViewModel.cs @@ -12,6 +12,10 @@ namespace HandyControlDemo.ViewModel { public class NotifyIconDemoViewModel : ViewModelBase { + private bool _isCleanup; + + private bool _reversed; + private bool _contextMenuIsShow; public bool ContextMenuIsShow @@ -25,6 +29,12 @@ namespace HandyControlDemo.ViewModel Set(ref _contextMenuIsShow, value); #endif GlobalData.NotifyIconIsShow = ContextMenuIsShow || ContextContentIsShow; + if (!_isCleanup && !_reversed) + { + _reversed = true; + ContextContentIsShow = !value; + _reversed = false; + } } } @@ -53,6 +63,12 @@ namespace HandyControlDemo.ViewModel Set(ref _contextContentIsShow, value); #endif GlobalData.NotifyIconIsShow = ContextMenuIsShow || ContextContentIsShow; + if (!_isCleanup && !_reversed) + { + _reversed = true; + ContextMenuIsShow = !value; + _reversed = false; + } } } @@ -70,5 +86,18 @@ namespace HandyControlDemo.ViewModel public RelayCommand MouseCmd => new Lazy>(() => new RelayCommand(str=> Growl.Info(str.ToString()))).Value; + + public override void Cleanup() + { + base.Cleanup(); + + _isCleanup = true; + ContextMenuIsShow = false; + ContextMenuIsBlink = false; + ContextContentIsShow = false; + ContextContentIsBlink = false; + GlobalData.NotifyIconIsShow = false; + _isCleanup = false; + } } } \ No newline at end of file diff --git a/src/Shared/HandyControlDemo_Shared/ViewModel/Main/MainViewModel.cs b/src/Shared/HandyControlDemo_Shared/ViewModel/Main/MainViewModel.cs index d3a3d1bc..535fd329 100644 --- a/src/Shared/HandyControlDemo_Shared/ViewModel/Main/MainViewModel.cs +++ b/src/Shared/HandyControlDemo_Shared/ViewModel/Main/MainViewModel.cs @@ -82,7 +82,7 @@ namespace HandyControlDemo.ViewModel #endregion - #region 命令 +#region 命令 /// /// 切换例子命令 @@ -109,7 +109,8 @@ namespace HandyControlDemo.ViewModel _listBoxItemCurrent = item; ContentTitle = item.Content; Messenger.Default.Send(false, MessageToken.FullSwitch); - Messenger.Default.Send(AssemblyHelper.CreateInternalInstance($"UserControl.{tag}"), MessageToken.LoadShowContent); + var obj = AssemblyHelper.ResolveByKey(tag); + Messenger.Default.Send(obj ?? AssemblyHelper.CreateInternalInstance($"UserControl.{tag}"), MessageToken.LoadShowContent); } else { diff --git a/src/Shared/HandyControl_Shared/Controls/Other/NotifyIcon.cs b/src/Shared/HandyControl_Shared/Controls/Other/NotifyIcon.cs index badb1c40..fc87cbb4 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/NotifyIcon.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/NotifyIcon.cs @@ -1,4 +1,6 @@ using System; +using System.Diagnostics; +using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; @@ -14,6 +16,8 @@ namespace HandyControl.Controls { public class NotifyIcon : FrameworkElement, IDisposable { + private bool _isMouseOver; + private bool _added; private readonly object _syncObj = new object(); @@ -44,7 +48,9 @@ namespace HandyControl.Controls private bool _doubleClick; - private DispatcherTimer _dispatcherTimer; + private DispatcherTimer _dispatcherTimerBlink; + + private DispatcherTimer _dispatcherTimerPos; private bool _isTransparent; @@ -87,6 +93,12 @@ namespace HandyControl.Controls OnIconChanged(); UpdateIcon(true); } + + _dispatcherTimerPos = new DispatcherTimer + { + Interval = TimeSpan.FromMilliseconds(200) + }; + _dispatcherTimerPos.Tick += DispatcherTimerPos_Tick; }; if (Application.Current != null) Application.Current.Exit += (s, e) => Dispose(); @@ -137,9 +149,9 @@ namespace HandyControl.Controls private static void OnBlinkIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctl = (NotifyIcon)d; - if (ctl._dispatcherTimer != null) + if (ctl._dispatcherTimerBlink != null) { - ctl._dispatcherTimer.Interval = (TimeSpan) e.NewValue; + ctl._dispatcherTimerBlink.Interval = (TimeSpan) e.NewValue; } } @@ -158,30 +170,175 @@ namespace HandyControl.Controls if (ctl.Visibility != Visibility.Visible) return; if ((bool) e.NewValue) { - if (ctl._dispatcherTimer == null) + if (ctl._dispatcherTimerBlink == null) { - ctl._dispatcherTimer = new DispatcherTimer + ctl._dispatcherTimerBlink = new DispatcherTimer { Interval = ctl.BlinkInterval }; - ctl._dispatcherTimer.Tick += ctl.DispatcherTimer_Tick; + ctl._dispatcherTimerBlink.Tick += ctl.DispatcherTimerBlinkTick; } - ctl._dispatcherTimer.Start(); + ctl._dispatcherTimerBlink.Start(); } else { - ctl._dispatcherTimer?.Stop(); - ctl._dispatcherTimer = null; + ctl._dispatcherTimerBlink?.Stop(); + ctl._dispatcherTimerBlink = null; ctl.UpdateIcon(true); } } - private void DispatcherTimer_Tick(object sender, EventArgs e) + private void DispatcherTimerBlinkTick(object sender, EventArgs e) { if (Visibility != Visibility.Visible || _iconCurrentHandle == IntPtr.Zero) return; UpdateIcon(true, !_isTransparent); } + private bool CheckMouseIsEnter() + { + var isTrue = FindNotifyIcon(out var rectNotify); + if (!isTrue) return false; + NativeMethods.GetCursorPos(out var point); + if (point.X >= rectNotify.Left && point.X <= rectNotify.Right && + point.Y >= rectNotify.Top && point.Y <= rectNotify.Bottom) + { + return true; + } + + return false; + } + + private void DispatcherTimerPos_Tick(object sender, EventArgs e) + { + if (CheckMouseIsEnter()) + { + if (!_isMouseOver) + { + _isMouseOver = true; + RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount) + { + RoutedEvent = MouseEnterEvent + }); + _dispatcherTimerPos.Interval = TimeSpan.FromMilliseconds(500); + } + } + else + { + _dispatcherTimerPos.Stop(); + _isMouseOver = false; + RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount) + { + RoutedEvent = MouseLeaveEvent + }); + } + } + + //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html + private IntPtr FindTrayToolbarWindow() + { + var hWnd = NativeMethods.FindWindow("Shell_TrayWnd", null); + if (hWnd != IntPtr.Zero) + { + hWnd = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "TrayNotifyWnd", null); + if (hWnd != IntPtr.Zero) + { + + hWnd = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "SysPager", null); + if (hWnd != IntPtr.Zero) + { + hWnd = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null); + + } + } + } + return hWnd; + } + + //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html + private IntPtr FindTrayToolbarOverFlowWindow() + { + var hWnd = NativeMethods.FindWindow("NotifyIconOverflowWindow", null); + if (hWnd != IntPtr.Zero) + { + hWnd = NativeMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null); + } + return hWnd; + } + + private bool FindNotifyIcon(out NativeMethods.RECT rect) + { + var rectNotify = new NativeMethods.RECT(); + var hTrayWnd = FindTrayToolbarWindow(); + var isTrue = FindNotifyIcon(hTrayWnd, ref rectNotify); + if (!isTrue) + { + hTrayWnd = FindTrayToolbarOverFlowWindow(); + isTrue = FindNotifyIcon(hTrayWnd, ref rectNotify); + } + rect = rectNotify; + return isTrue; + } + + //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html + private bool FindNotifyIcon(IntPtr hTrayWnd, ref NativeMethods.RECT rectNotify) + { + NativeMethods.GetWindowRect(hTrayWnd, out var rectTray); + var count = (int)NativeMethods.SendMessage(hTrayWnd, NativeMethods.TB_BUTTONCOUNT, 0, IntPtr.Zero); + + var isFind = false; + if (count > 0) + { + NativeMethods.GetWindowThreadProcessId(hTrayWnd, out var trayPid); + var hProcess = NativeMethods.OpenProcess(NativeMethods.ProcessAccess.VMOperation | NativeMethods.ProcessAccess.VMRead | NativeMethods.ProcessAccess.VMWrite, false, trayPid); + var address = NativeMethods.VirtualAllocEx(hProcess, IntPtr.Zero, 1024, NativeMethods.AllocationType.Commit, NativeMethods.MemoryProtection.ReadWrite); + + var btnData = new NativeMethods.TBBUTTON(); + var trayData = new NativeMethods.TRAYDATA(); + var handel = Process.GetCurrentProcess().Id; + + for (uint i = 0; i < count; i++) + { + NativeMethods.SendMessage(hTrayWnd, NativeMethods.TB_GETBUTTON, i, address); + var isTrue = NativeMethods.ReadProcessMemory(hProcess, address, out btnData, Marshal.SizeOf(btnData), out _); + if (!isTrue) continue; + if (btnData.dwData == IntPtr.Zero) + { + btnData.dwData = btnData.iString; + } + NativeMethods.ReadProcessMemory(hProcess, btnData.dwData, out trayData, Marshal.SizeOf(trayData), out _); + NativeMethods.GetWindowThreadProcessId(trayData.hwnd, out var dwProcessId); + if (dwProcessId == (uint)handel) + { + var rect = new NativeMethods.RECT(); + var lngRect = NativeMethods.VirtualAllocEx(hProcess, IntPtr.Zero, Marshal.SizeOf(typeof(Rect)), NativeMethods.AllocationType.Commit, NativeMethods.MemoryProtection.ReadWrite); + NativeMethods.SendMessage(hTrayWnd, NativeMethods.TB_GETITEMRECT, i, lngRect); + NativeMethods.ReadProcessMemory(hProcess, lngRect, out rect, Marshal.SizeOf(rect), out _); + + NativeMethods.VirtualFreeEx(hProcess, lngRect, Marshal.SizeOf(rect), NativeMethods.FreeType.Decommit); + NativeMethods.VirtualFreeEx(hProcess, lngRect, 0, NativeMethods.FreeType.Release); + + var left = rectTray.Left + rect.Left; + var top = rectTray.Top + rect.Top; + var botton = rectTray.Top + rect.Bottom; + var right = rectTray.Left + rect.Right; + rectNotify = new NativeMethods.RECT + { + Left = left, + Right = right, + Top = top, + Bottom = botton + }; + isFind = true; + break; + } + } + NativeMethods.VirtualFreeEx(hProcess, address, 0x4096, NativeMethods.FreeType.Decommit); + NativeMethods.VirtualFreeEx(hProcess, address, 0, NativeMethods.FreeType.Release); + NativeMethods.CloseHandle(hProcess); + } + return isFind; + } + public bool IsBlink { get => (bool) GetValue(IsBlinkProperty); @@ -289,6 +446,13 @@ namespace HandyControl.Controls ShowContextMenu(); WmMouseUp(MouseButton.Right); break; + case NativeMethods.WM_MOUSEMOVE: + if (!_dispatcherTimerPos.IsEnabled) + { + _dispatcherTimerPos.Interval = TimeSpan.FromMilliseconds(200); + _dispatcherTimerPos.Start(); + } + break; } } } @@ -390,9 +554,9 @@ namespace HandyControl.Controls if (_isDisposed) return; if (disposing) { - if (_dispatcherTimer != null && IsBlink) + if (_dispatcherTimerBlink != null && IsBlink) { - _dispatcherTimer.Stop(); + _dispatcherTimerBlink.Stop(); } UpdateIcon(false); } diff --git a/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs b/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs index b5a01f22..dcff9ac8 100644 --- a/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs +++ b/src/Shared/HandyControl_Shared/Tools/Interop/NativeMethods.cs @@ -41,10 +41,165 @@ namespace HandyControl.Tools.Interop WM_MBUTTONDOWN = 0x0207, WM_MBUTTONUP = 0x0208, WM_MBUTTONDBLCLK = 0x0209, - WM_USER = 0x0400; + WM_USER = 0x0400, + TB_GETBUTTON = WM_USER + 23, + TB_BUTTONCOUNT = WM_USER + 24, + TB_GETITEMRECT = WM_USER + 29, + STANDARD_RIGHTS_REQUIRED = 0x000F0000, + SYNCHRONIZE = 0x00100000, + PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, + MEM_COMMIT = 0x1000, + MEM_RELEASE = 0x8000, + PAGE_READWRITE = 0x04, + TBSTATE_HIDDEN = 0x08; + + [Flags] + public enum ProcessAccess + { + AllAccess = CreateThread | DuplicateHandle | QueryInformation | SetInformation | Terminate | VMOperation | VMRead | VMWrite | Synchronize, + CreateThread = 0x2, + DuplicateHandle = 0x40, + QueryInformation = 0x400, + SetInformation = 0x200, + Terminate = 0x1, + VMOperation = 0x8, + VMRead = 0x10, + VMWrite = 0x20, + Synchronize = 0x100000 + } + + [Serializable, StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct RECT + { + public int Left; + public int Top; + public int Right; + public int Bottom; + + public RECT(int left, int top, int right, int bottom) + { + Left = left; + Top = top; + Right = right; + Bottom = bottom; + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct TBBUTTON + { + public int iBitmap; + public int idCommand; + public IntPtr fsStateStylePadding; + public IntPtr dwData; + public IntPtr iString; + } + + [Flags] + public enum AllocationType + { + Commit = 0x1000, + Reserve = 0x2000, + Decommit = 0x4000, + Release = 0x8000, + Reset = 0x80000, + Physical = 0x400000, + TopDown = 0x100000, + WriteWatch = 0x200000, + LargePages = 0x20000000 + } + + [Flags] + public enum MemoryProtection + { + Execute = 0x10, + ExecuteRead = 0x20, + ExecuteReadWrite = 0x40, + ExecuteWriteCopy = 0x80, + NoAccess = 0x01, + ReadOnly = 0x02, + ReadWrite = 0x04, + WriteCopy = 0x08, + GuardModifierflag = 0x100, + NoCacheModifierflag = 0x200, + WriteCombineModifierflag = 0x400 + } + + [StructLayout(LayoutKind.Sequential)] + public struct TRAYDATA + { + public IntPtr hwnd; + public uint uID; + public uint uCallbackMessage; + public uint bReserved0; + public uint bReserved1; + public IntPtr hIcon; + } + + [Flags] + public enum FreeType + { + Decommit = 0x4000, + Release = 0x8000, + } + + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public int X; + public int Y; + + public POINT(int x, int y) + { + X = x; + Y = y; + } + } [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] [ResourceExposure(ResourceScope.None)] public static extern int RegisterWindowMessage(string msg); + + [DllImport(ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern int MapWindowPoints(IntPtr hWndFrom, IntPtr hWndTo, ref RECT lpPoints, uint cPoints); + + [DllImport(ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out TBBUTTON lpBuffer, int dwSize, out int lpNumberOfBytesRead); + + [DllImport(ExternDll.Kernel32, SetLastError = true)] + public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out RECT lpBuffer, int dwSize, out int lpNumberOfBytesRead); + + [DllImport(ExternDll.Kernel32, SetLastError = true)] + public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, out TRAYDATA lpBuffer, int dwSize, out int lpNumberOfBytesRead); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern uint SendMessage(IntPtr hWnd, uint Msg, uint wParam, IntPtr lParam); + + [DllImport(ExternDll.User32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); + + [DllImport(ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern IntPtr OpenProcess(ProcessAccess dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId); + + [DllImport(ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, AllocationType flAllocationType, MemoryProtection flProtect); + + [DllImport(ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern int CloseHandle(IntPtr hObject); + + [DllImport(ExternDll.Kernel32, SetLastError = true, CharSet = CharSet.Auto)] + public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, FreeType dwFreeType); + + [DllImport(ExternDll.User32, SetLastError = true)] + public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport(ExternDll.User32, SetLastError = true)] + public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); + + [DllImport(ExternDll.User32)] + public static extern int GetWindowRect(IntPtr hwnd, out RECT lpRect); + + [DllImport(ExternDll.User32, CharSet = CharSet.Auto)] + public static extern bool GetCursorPos(out POINT pt); } } \ No newline at end of file From 89319eadee2e4081307e974d0b6696d20e0f18c4 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sun, 21 Apr 2019 00:26:30 +0800 Subject: [PATCH 3/6] Update MessageBox.xaml --- .../Themes/Styles/MessageBox.xaml | 122 ++++++++++++++---- 1 file changed, 100 insertions(+), 22 deletions(-) diff --git a/src/Net_40/HandyControl_Net_40/Themes/Styles/MessageBox.xaml b/src/Net_40/HandyControl_Net_40/Themes/Styles/MessageBox.xaml index f2f30ce0..f4006904 100644 --- a/src/Net_40/HandyControl_Net_40/Themes/Styles/MessageBox.xaml +++ b/src/Net_40/HandyControl_Net_40/Themes/Styles/MessageBox.xaml @@ -2,7 +2,8 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:HandyControl.Controls" xmlns:langs="clr-namespace:HandyControl.Properties.Langs" - xmlns:interactivity="clr-namespace:HandyControl.Interactivity"> + xmlns:interactivity="clr-namespace:HandyControl.Interactivity" + xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"> @@ -17,28 +18,105 @@ - + - - - - - - - - - - - - - - -