欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WPF實(shí)現(xiàn)基礎(chǔ)控件之托盤的示例代碼

 更新時(shí)間:2022年10月17日 10:08:13   作者:驚鏵  
這篇文章主要為大家詳細(xì)介紹了如何利用WPF實(shí)現(xiàn)托盤這一基礎(chǔ)控件,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,感興趣的小伙伴可以了解一下

WPF 基礎(chǔ)控件之托盤

框架使用大于等于.NET40。

Visual Studio 2022

項(xiàng)目使用 MIT 開源許可協(xié)議。

新建NotifyIcon自定義控件繼承自FrameworkElement。

創(chuàng)建托盤程序主要借助與 Win32API:

  • 注冊(cè)窗體對(duì)象RegisterClassEx
  • 注冊(cè)消息獲取對(duì)應(yīng)消息標(biāo)識(shí)Id RegisterWindowMessage。
  • 創(chuàng)建窗體(本質(zhì)上托盤在創(chuàng)建時(shí)需要一個(gè)窗口句柄,完全可以將主窗體的句柄給進(jìn)去,但是為了更好的管理消息以及托盤的生命周期,通常會(huì)創(chuàng)建一個(gè)獨(dú)立不可見的窗口)CreateWindowEx

以下2點(diǎn)需要注意:

  • 托盤控件的ContextMenu菜單MenuItem 在使用binding時(shí)無效,是因?yàn)?code>DataContext沒有帶過去,需要重新賦值一次。
  • 托盤控件發(fā)送ShowBalloonTip消息通知時(shí)候需新建Shell_NotifyIcon。
  • Nuget 最新 Install-Package WPFDevelopers 1.0.9.1-preview

示例代碼

1) NotifyIcon.cs 代碼如下:

using?System;
using?System.IO;
using?System.Runtime.InteropServices;
using?System.Threading;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Controls.Primitives;
using?System.Windows.Data;
using?System.Windows.Input;
using?System.Windows.Media;
using?System.Windows.Media.Imaging;
using?WPFDevelopers.Controls.Runtimes;
using?WPFDevelopers.Controls.Runtimes.Interop;
using?WPFDevelopers.Controls.Runtimes.Shell32;
using?WPFDevelopers.Controls.Runtimes.User32;

namespace?WPFDevelopers.Controls
{
????public?class?NotifyIcon?:?FrameworkElement,?IDisposable
????{
????????private?static?NotifyIcon?NotifyIconCache;

????????public?static?readonly?DependencyProperty?ContextContentProperty?=?DependencyProperty.Register(
????????????"ContextContent",?typeof(object),?typeof(NotifyIcon),?new?PropertyMetadata(default));

????????public?static?readonly?DependencyProperty?IconProperty?=
????????????DependencyProperty.Register("Icon",?typeof(ImageSource),?typeof(NotifyIcon),
????????????????new?PropertyMetadata(default,?OnIconPropertyChanged));

????????public?static?readonly?DependencyProperty?TitleProperty?=
????????????DependencyProperty.Register("Title",?typeof(string),?typeof(NotifyIcon),
????????????????new?PropertyMetadata(default,?OnTitlePropertyChanged));

????????public?static?readonly?RoutedEvent?ClickEvent?=
????????????EventManager.RegisterRoutedEvent("Click",?RoutingStrategy.Bubble,
????????????????typeof(RoutedEventHandler),?typeof(NotifyIcon));

????????public?static?readonly?RoutedEvent?MouseDoubleClickEvent?=
????????????EventManager.RegisterRoutedEvent("MouseDoubleClick",?RoutingStrategy.Bubble,
????????????????typeof(RoutedEventHandler),?typeof(NotifyIcon));

????????private?static?bool?s_Loaded?=?false;

????????private?static?NotifyIcon?s_NotifyIcon;

????????//這是窗口名稱
????????private?readonly?string?_TrayWndClassName;

????????//這個(gè)是窗口消息名稱
????????private?readonly?string?_TrayWndMessage;

????????//這個(gè)是窗口消息回調(diào)(窗口消息都需要在此捕獲)
????????private?readonly?WndProc?_TrayWndProc;
????????private?Popup?_contextContent;

????????private?bool?_doubleClick;

????????//圖標(biāo)句柄
????????private?IntPtr?_hIcon?=?IntPtr.Zero;
????????private?ImageSource?_icon;
????????private?IntPtr?_iconHandle;

????????private?int?_IsShowIn;

????????//托盤對(duì)象
????????private?NOTIFYICONDATA?_NOTIFYICONDATA;

????????//這個(gè)是傳遞給托盤的鼠標(biāo)消息id
????????private?int?_TrayMouseMessage;

????????//窗口句柄
????????private?IntPtr?_TrayWindowHandle?=?IntPtr.Zero;

????????//通過注冊(cè)窗口消息可以獲取唯一標(biāo)識(shí)Id
????????private?int?_WmTrayWindowMessage;

????????private?bool?disposedValue;

????????public?NotifyIcon()
????????{
????????????_TrayWndClassName?=?$"WPFDevelopers_{Guid.NewGuid()}";
????????????_TrayWndProc?=?WndProc_CallBack;
????????????_TrayWndMessage?=?"TrayWndMessageName";
????????????_TrayMouseMessage?=?(int)WM.USER?+?1024;
????????????Start();
????????????if?(Application.Current?!=?null)
????????????{
????????????????//Application.Current.MainWindow.Closed?+=?(s,?e)?=>?Dispose();
????????????????Application.Current.Exit?+=?(s,?e)?=>?Dispose();
????????????}
????????????NotifyIconCache?=?this;
????????}
????????static?NotifyIcon()
????????{
????????????DataContextProperty.OverrideMetadata(typeof(NotifyIcon),?new?FrameworkPropertyMetadata(DataContextPropertyChanged));
????????????ContextMenuProperty.OverrideMetadata(typeof(NotifyIcon),?new?FrameworkPropertyMetadata(ContextMenuPropertyChanged));
????????}
????????private?static?void?DataContextPropertyChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)?=>
????????????((NotifyIcon)d).OnDataContextPropertyChanged(e);
????????private?void?OnDataContextPropertyChanged(DependencyPropertyChangedEventArgs?e)
????????{
????????????UpdateDataContext(_contextContent,?e.OldValue,?e.NewValue);
????????????UpdateDataContext(ContextMenu,?e.OldValue,?e.NewValue);
????????}
????????private?void?UpdateDataContext(FrameworkElement?target,?object?oldValue,?object?newValue)
????????{
????????????if?(target?==?null?||?BindingOperations.GetBindingExpression(target,?DataContextProperty)?!=?null)?return;
????????????if?(ReferenceEquals(this,?target.DataContext)?||?Equals(oldValue,?target.DataContext))
????????????{
????????????????target.DataContext?=?newValue????this;
????????????}
????????}
????????private?static?void?ContextMenuPropertyChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????var?ctl?=?(NotifyIcon)d;
????????????ctl.OnContextMenuPropertyChanged(e);
????????}

????????private?void?OnContextMenuPropertyChanged(DependencyPropertyChangedEventArgs?e)?=>
????????????UpdateDataContext((ContextMenu)e.NewValue,?null,?DataContext);
????????public?object?ContextContent
????????{
????????????get?=>?GetValue(ContextContentProperty);
????????????set?=>?SetValue(ContextContentProperty,?value);
????????}

????????public?ImageSource?Icon
????????{
????????????get?=>?(ImageSource)GetValue(IconProperty);
????????????set?=>?SetValue(IconProperty,?value);
????????}


????????public?string?Title
????????{
????????????get?=>?(string)GetValue(TitleProperty);
????????????set?=>?SetValue(TitleProperty,?value);
????????}

????????public?void?Dispose()
????????{
????????????Dispose(true);
????????????GC.SuppressFinalize(this);
????????}

????????private?static?void?OnTitlePropertyChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????if?(d?is?NotifyIcon?trayService)
????????????????trayService.ChangeTitle(e.NewValue?.ToString());
????????}

????????private?static?void?OnIconPropertyChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e)
????????{
????????????if?(d?is?NotifyIcon?trayService)
????????????{
????????????????var?notifyIcon?=?(NotifyIcon)d;
????????????????notifyIcon._icon?=?(ImageSource)e.NewValue;
????????????????trayService.ChangeIcon();
????????????}
????????}

????????public?event?RoutedEventHandler?Click
????????{
????????????add?=>?AddHandler(ClickEvent,?value);
????????????remove?=>?RemoveHandler(ClickEvent,?value);
????????}

????????public?event?RoutedEventHandler?MouseDoubleClick
????????{
????????????add?=>?AddHandler(MouseDoubleClickEvent,?value);
????????????remove?=>?RemoveHandler(MouseDoubleClickEvent,?value);
????????}

????????private?static?void?Current_Exit(object?sender,?ExitEventArgs?e)
????????{
????????????s_NotifyIcon?.Dispose();
????????????s_NotifyIcon?=?default;
????????}


????????public?bool?Start()
????????{
????????????RegisterClass(_TrayWndClassName,?_TrayWndProc,?_TrayWndMessage);
????????????LoadNotifyIconData(string.Empty);
????????????Show();

????????????return?true;
????????}

????????public?bool?Stop()
????????{
????????????//銷毀窗體
????????????if?(_TrayWindowHandle?!=?IntPtr.Zero)
????????????????if?(User32Interop.IsWindow(_TrayWindowHandle))
????????????????????User32Interop.DestroyWindow(_TrayWindowHandle);

????????????//反注冊(cè)窗口類
????????????if?(!string.IsNullOrWhiteSpace(_TrayWndClassName))
????????????????User32Interop.UnregisterClassName(_TrayWndClassName,?Kernel32Interop.GetModuleHandle(default));

????????????//銷毀Icon
????????????if?(_hIcon?!=?IntPtr.Zero)
????????????????User32Interop.DestroyIcon(_hIcon);

????????????Hide();

????????????return?true;
????????}

????????///?<summary>
????????///?????注冊(cè)并創(chuàng)建窗口對(duì)象
????????///?</summary>
????????///?<param?name="className">窗口名稱</param>
????????///?<param?name="messageName">窗口消息名稱</param>
????????///?<returns></returns>
????????private?bool?RegisterClass(string?className,?WndProc?wndproccallback,?string?messageName)
????????{
????????????var?wndClass?=?new?WNDCLASSEX
????????????{
????????????????cbSize?=?Marshal.SizeOf(typeof(WNDCLASSEX)),
????????????????style?=?0,
????????????????lpfnWndProc?=?wndproccallback,
????????????????cbClsExtra?=?0,
????????????????cbWndExtra?=?0,
????????????????hInstance?=?IntPtr.Zero,
????????????????hCursor?=?IntPtr.Zero,
????????????????hbrBackground?=?IntPtr.Zero,
????????????????lpszMenuName?=?string.Empty,
????????????????lpszClassName?=?className
????????????};

????????????//注冊(cè)窗體對(duì)象
????????????User32Interop.RegisterClassEx(ref?wndClass);
????????????//注冊(cè)消息獲取對(duì)應(yīng)消息標(biāo)識(shí)id
????????????_WmTrayWindowMessage?=?User32Interop.RegisterWindowMessage(messageName);
????????????//創(chuàng)建窗體(本質(zhì)上托盤在創(chuàng)建時(shí)需要一個(gè)窗口句柄,完全可以將主窗體的句柄給進(jìn)去,但是為了更好的管理消息以及托盤的生命周期,通常會(huì)創(chuàng)建一個(gè)獨(dú)立不可見的窗口)
????????????_TrayWindowHandle?=?User32Interop.CreateWindowEx(0,?className,?"",?0,?0,?0,?1,?1,?IntPtr.Zero,?IntPtr.Zero,
????????????????IntPtr.Zero,?IntPtr.Zero);

????????????return?true;
????????}

????????///?<summary>
????????///?????創(chuàng)建托盤對(duì)象
????????///?</summary>
????????///?<param?name="icon">圖標(biāo)路徑,可以修改托盤圖標(biāo)(本質(zhì)上是可以接受用戶傳入一個(gè)圖片對(duì)象,然后將圖片轉(zhuǎn)成Icon,但是算了這個(gè)有點(diǎn)復(fù)雜)</param>
????????///?<param?name="title">托盤的tooltip</param>
????????///?<returns></returns>
????????private?bool?LoadNotifyIconData(string?title)
????????{
????????????lock?(this)
????????????{
????????????????_NOTIFYICONDATA?=?NOTIFYICONDATA.GetDefaultNotifyData(_TrayWindowHandle);

????????????????if?(_TrayMouseMessage?!=?0)
????????????????????_NOTIFYICONDATA.uCallbackMessage?=?(uint)_TrayMouseMessage;
????????????????else
????????????????????_TrayMouseMessage?=?(int)_NOTIFYICONDATA.uCallbackMessage;

????????????????if?(_iconHandle?==?IntPtr.Zero)
????????????????{
????????????????????var?processPath?=?Kernel32Interop.GetModuleFileName(new?HandleRef());
????????????????????if?(!string.IsNullOrWhiteSpace(processPath))
????????????????????{
????????????????????????var?index?=?IntPtr.Zero;
????????????????????????var?hIcon?=?Shell32Interop.ExtractAssociatedIcon(IntPtr.Zero,?processPath,?ref?index);
????????????????????????_NOTIFYICONDATA.hIcon?=?hIcon;
????????????????????????_hIcon?=?hIcon;
????????????????????}
????????????????}

????????????????if?(!string.IsNullOrWhiteSpace(title))
????????????????????_NOTIFYICONDATA.szTip?=?title;
????????????}

????????????return?true;
????????}

????????private?bool?Show()
????????{
????????????var?command?=?NotifyCommand.NIM_Add;
????????????if?(Thread.VolatileRead(ref?_IsShowIn)?==?1)
????????????????command?=?NotifyCommand.NIM_Modify;
????????????else
????????????????Thread.VolatileWrite(ref?_IsShowIn,?1);

????????????lock?(this)
????????????{
????????????????return?Shell32Interop.Shell_NotifyIcon(command,?ref?_NOTIFYICONDATA);
????????????}
????????}

????????internal?static?int?AlignToBytes(double?original,?int?nBytesCount)
????????{
????????????var?nBitsCount?=?8?<<?(nBytesCount?-?1);
????????????return?((int)Math.Ceiling(original)?+?(nBitsCount?-?1))?/?nBitsCount?*?nBitsCount;
????????}

????????private?static?byte[]?GenerateMaskArray(int?width,?int?height,?byte[]?colorArray)
????????{
????????????var?nCount?=?width?*?height;
????????????var?bytesPerScanLine?=?AlignToBytes(width,?2)?/?8;
????????????var?bitsMask?=?new?byte[bytesPerScanLine?*?height];

????????????for?(var?i?=?0;?i?<?nCount;?i++)
????????????{
????????????????var?hPos?=?i?%?width;
????????????????var?vPos?=?i?/?width;
????????????????var?byteIndex?=?hPos?/?8;
????????????????var?offsetBit?=?(byte)(0x80?>>?(hPos?%?8));

????????????????if?(colorArray[i?*?4?+?3]?==?0x00)
????????????????????bitsMask[byteIndex?+?bytesPerScanLine?*?vPos]?|=?offsetBit;
????????????????else
????????????????????bitsMask[byteIndex?+?bytesPerScanLine?*?vPos]?&=?(byte)~offsetBit;

????????????????if?(hPos?==?width?-?1?&&?width?==?8)?bitsMask[1?+?bytesPerScanLine?*?vPos]?=?0xff;
????????????}

????????????return?bitsMask;
????????}

????????private?byte[]?BitmapImageToByteArray(BitmapImage?bmp)
????????{
????????????byte[]?bytearray?=?null;
????????????try
????????????{
????????????????var?smarket?=?bmp.StreamSource;
????????????????if?(smarket?!=?null?&&?smarket.Length?>?0)
????????????????{
????????????????????//設(shè)置當(dāng)前位置
????????????????????smarket.Position?=?0;
????????????????????using?(var?br?=?new?BinaryReader(smarket))
????????????????????{
????????????????????????bytearray?=?br.ReadBytes((int)smarket.Length);
????????????????????}
????????????????}
????????????}
????????????catch?(Exception?ex)
????????????{
????????????}

????????????return?bytearray;
????????}

????????private?byte[]?ConvertBitmapSourceToBitmapImage(
????????????BitmapSource?bitmapSource)
????????{
????????????byte[]?imgByte?=?default;
????????????if?(!(bitmapSource?is?BitmapImage?bitmapImage))
????????????{
????????????????bitmapImage?=?new?BitmapImage();

????????????????var?encoder?=?new?BmpBitmapEncoder();
????????????????encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

????????????????using?(var?memoryStream?=?new?MemoryStream())
????????????????{
????????????????????encoder.Save(memoryStream);
????????????????????memoryStream.Position?=?0;

????????????????????bitmapImage.BeginInit();
????????????????????bitmapImage.CacheOption?=?BitmapCacheOption.OnLoad;
????????????????????bitmapImage.StreamSource?=?memoryStream;
????????????????????bitmapImage.EndInit();
????????????????????imgByte?=?BitmapImageToByteArray(bitmapImage);
????????????????}
????????????}

????????????return?imgByte;
????????}

????????internal?static?IconHandle?CreateIconCursor(byte[]?xor,?int?width,?int?height,?int?xHotspot,
????????????int?yHotspot,?bool?isIcon)
????????{
????????????var?bits?=?IntPtr.Zero;

????????????BitmapHandle?colorBitmap?=?null;
????????????var?bi?=?new?BITMAPINFO(width,?-height,?32)
????????????{
????????????????bmiHeader_biCompression?=?0
????????????};

????????????colorBitmap?=?Gdi32Interop.CreateDIBSection(new?HandleRef(null,?IntPtr.Zero),?ref?bi,?0,?ref?bits,?null,?0);

????????????if?(colorBitmap.IsInvalid?||?bits?==?IntPtr.Zero)?return?IconHandle.GetInvalidIcon();
????????????Marshal.Copy(xor,?0,?bits,?xor.Length);
????????????var?maskArray?=?GenerateMaskArray(width,?height,?xor);
????????????var?maskBitmap?=?Gdi32Interop.CreateBitmap(width,?height,?1,?1,?maskArray);
????????????if?(maskBitmap.IsInvalid)?return?IconHandle.GetInvalidIcon();
????????????var?iconInfo?=?new?Gdi32Interop.ICONINFO
????????????{
????????????????fIcon?=?isIcon,
????????????????xHotspot?=?xHotspot,
????????????????yHotspot?=?yHotspot,
????????????????hbmMask?=?maskBitmap,
????????????????hbmColor?=?colorBitmap
????????????};

????????????return?User32Interop.CreateIconIndirect(iconInfo);
????????}


????????private?bool?ChangeIcon()
????????{
????????????var?bitmapFrame?=?_icon?as?BitmapFrame;
????????????if?(bitmapFrame?!=?null?&&?bitmapFrame.Decoder?!=?null)
????????????????if?(bitmapFrame.Decoder?is?IconBitmapDecoder)
????????????????{
????????????????????//var?iconBitmapDecoder?=?new?Rect(0,?0,?_icon.Width,?_icon.Height);
????????????????????//var?dv?=?new?DrawingVisual();
????????????????????//var?dc?=?dv.RenderOpen();
????????????????????//dc.DrawImage(_icon,?iconBitmapDecoder);
????????????????????//dc.Close();

????????????????????//var?bmp?=?new?RenderTargetBitmap((int)_icon.Width,?(int)_icon.Height,?96,?96,
????????????????????//????PixelFormats.Pbgra32);
????????????????????//bmp.Render(dv);


????????????????????//BitmapSource?bitmapSource?=?bmp;

????????????????????//if?(bitmapSource.Format?!=?PixelFormats.Bgra32?&&?bitmapSource.Format?!=?PixelFormats.Pbgra32)
????????????????????//????bitmapSource?=?new?FormatConvertedBitmap(bitmapSource,?PixelFormats.Bgra32,?null,?0.0);
????????????????????var?w?=?bitmapFrame.PixelWidth;
????????????????????var?h?=?bitmapFrame.PixelHeight;
????????????????????var?bpp?=?bitmapFrame.Format.BitsPerPixel;
????????????????????var?stride?=?(bpp?*?w?+?31)?/?32?*?4;
????????????????????var?sizeCopyPixels?=?stride?*?h;
????????????????????var?xor?=?new?byte[sizeCopyPixels];
????????????????????bitmapFrame.CopyPixels(xor,?stride,?0);

????????????????????var?iconHandle?=?CreateIconCursor(xor,?w,?h,?0,?0,?true);
????????????????????_iconHandle?=?iconHandle.CriticalGetHandle();
????????????????}


????????????if?(Thread.VolatileRead(ref?_IsShowIn)?!=?1)
????????????????return?false;

????????????if?(_hIcon?!=?IntPtr.Zero)
????????????{
????????????????User32Interop.DestroyIcon(_hIcon);
????????????????_hIcon?=?IntPtr.Zero;
????????????}

????????????lock?(this)
????????????{
????????????????if?(_iconHandle?!=?IntPtr.Zero)
????????????????{
????????????????????var?hIcon?=?_iconHandle;
????????????????????_NOTIFYICONDATA.hIcon?=?hIcon;
????????????????????_hIcon?=?hIcon;
????????????????}
????????????????else
????????????????{
????????????????????_NOTIFYICONDATA.hIcon?=?IntPtr.Zero;
????????????????}

????????????????return?Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Modify,?ref?_NOTIFYICONDATA);
????????????}
????????}

????????private?bool?ChangeTitle(string?title)
????????{
????????????if?(Thread.VolatileRead(ref?_IsShowIn)?!=?1)
????????????????return?false;

????????????lock?(this)
????????????{
????????????????_NOTIFYICONDATA.szTip?=?title;
????????????????return?Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Modify,?ref?_NOTIFYICONDATA);
????????????}
????????}

????????public?static?void?ShowBalloonTip(string?title,?string?content,?NotifyIconInfoType?infoType)
????????{
????????????if?(NotifyIconCache?!=?null)
????????????????NotifyIconCache.ShowBalloonTips(title,?content,?infoType);
????????}

????????public?void?ShowBalloonTips(string?title,?string?content,?NotifyIconInfoType?infoType)
????????{
????????????if?(Thread.VolatileRead(ref?_IsShowIn)?!=?1)
????????????????return;
????????????var?_ShowNOTIFYICONDATA?=?NOTIFYICONDATA.GetDefaultNotifyData(_TrayWindowHandle);
????????????_ShowNOTIFYICONDATA.uFlags?=?NIFFlags.NIF_INFO;
????????????_ShowNOTIFYICONDATA.szInfoTitle?=?title????string.Empty;
????????????_ShowNOTIFYICONDATA.szInfo?=?content????string.Empty;

????????????switch?(infoType)
????????????{
????????????????case?NotifyIconInfoType.Info:
????????????????????_ShowNOTIFYICONDATA.dwInfoFlags?=?NIIFFlags.NIIF_INFO;
????????????????????break;
????????????????case?NotifyIconInfoType.Warning:
????????????????????_ShowNOTIFYICONDATA.dwInfoFlags?=?NIIFFlags.NIIF_WARNING;
????????????????????break;
????????????????case?NotifyIconInfoType.Error:
????????????????????_ShowNOTIFYICONDATA.dwInfoFlags?=?NIIFFlags.NIIF_ERROR;
????????????????????break;
????????????????case?NotifyIconInfoType.None:
????????????????????_ShowNOTIFYICONDATA.dwInfoFlags?=?NIIFFlags.NIIF_NONE;
????????????????????break;
????????????}

????????????Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Modify,?ref?_ShowNOTIFYICONDATA);
????????}

????????private?bool?Hide()
????????{
????????????var?isShow?=?Thread.VolatileRead(ref?_IsShowIn);
????????????if?(isShow?!=?1)
????????????????return?true;

????????????Thread.VolatileWrite(ref?_IsShowIn,?0);

????????????lock?(this)
????????????{
????????????????return?Shell32Interop.Shell_NotifyIcon(NotifyCommand.NIM_Delete,?ref?_NOTIFYICONDATA);
????????????}
????????}

????????private?IntPtr?WndProc_CallBack(IntPtr?hwnd,?WM?msg,?IntPtr?wParam,?IntPtr?lParam)
????????{
????????????//這是窗口相關(guān)的消息
????????????if?((int)msg?==?_WmTrayWindowMessage)
????????????{
????????????}
????????????else?if?((int)msg?==?_TrayMouseMessage)?//這是托盤上鼠標(biāo)相關(guān)的消息
????????????{
????????????????switch?((WM)(long)lParam)
????????????????{
????????????????????case?WM.LBUTTONDOWN:
????????????????????????break;
????????????????????case?WM.LBUTTONUP:
????????????????????????WMMouseUp(MouseButton.Left);
????????????????????????break;
????????????????????case?WM.LBUTTONDBLCLK:
????????????????????????WMMouseDown(MouseButton.Left,?2);
????????????????????????break;
????????????????????case?WM.RBUTTONDOWN:
????????????????????????break;
????????????????????case?WM.RBUTTONUP:
????????????????????????OpenMenu();
????????????????????????break;
????????????????????case?WM.MOUSEMOVE:
????????????????????????break;
????????????????????case?WM.MOUSEWHEEL:
????????????????????????break;
????????????????}
????????????}
????????????else?if?(msg?==?WM.COMMAND)
????????????{
????????????}


????????????return?User32Interop.DefWindowProc(hwnd,?msg,?wParam,?lParam);
????????}

????????private?void?WMMouseUp(MouseButton?button)
????????{
????????????if?(!_doubleClick?&&?button?==?MouseButton.Left)
????????????????RaiseEvent(new?MouseButtonEventArgs(
????????????????????Mouse.PrimaryDevice,
????????????????????Environment.TickCount,?button)
????????????????{
????????????????????RoutedEvent?=?ClickEvent
????????????????});
????????????_doubleClick?=?false;
????????}

????????private?void?WMMouseDown(MouseButton?button,?int?clicks)
????????{
????????????if?(clicks?==?2)
????????????{
????????????????RaiseEvent(new?MouseButtonEventArgs(
????????????????????Mouse.PrimaryDevice,
????????????????????Environment.TickCount,?button)
????????????????{
????????????????????RoutedEvent?=?MouseDoubleClickEvent
????????????????});
????????????????_doubleClick?=?true;
????????????}
????????}

????????private?void?OpenMenu()
????????{
????????????if?(ContextContent?!=?null)
????????????{
????????????????_contextContent?=?new?Popup
????????????????{
????????????????????Placement?=?PlacementMode.Mouse,
????????????????????AllowsTransparency?=?true,
????????????????????StaysOpen?=?false,
????????????????????UseLayoutRounding?=?true,
????????????????????SnapsToDevicePixels?=?true
????????????????};

????????????????_contextContent.Child?=?new?ContentControl
????????????????{
????????????????????Content?=?ContextContent
????????????????};
????????????????UpdateDataContext(_contextContent,?null,?DataContext);
????????????????_contextContent.IsOpen?=?true;
????????????????User32Interop.SetForegroundWindow(_contextContent.Child.GetHandle());
????????????}
????????????else?if?(ContextMenu?!=?null)
????????????{
????????????????if?(ContextMenu.Items.Count?==?0)?return;

????????????????ContextMenu.InvalidateProperty(StyleProperty);
????????????????foreach?(var?item?in?ContextMenu.Items)
????????????????????if?(item?is?MenuItem?menuItem)
????????????????????{
????????????????????????menuItem.InvalidateProperty(StyleProperty);
????????????????????}
????????????????????else
????????????????????{
????????????????????????var?container?=?ContextMenu.ItemContainerGenerator.ContainerFromItem(item)?as?MenuItem;
????????????????????????container?.InvalidateProperty(StyleProperty);
????????????????????}
????????????????ContextMenu.Placement?=?PlacementMode.Mouse;
????????????????ContextMenu.IsOpen?=?true;

????????????????User32Interop.SetForegroundWindow(ContextMenu.GetHandle());
????????????}
????????}

????????protected?virtual?void?Dispose(bool?disposing)
????????{
????????????if?(!disposedValue)
????????????{
????????????????if?(disposing)
????????????????????Stop();

????????????????disposedValue?=?true;
????????????}
????????}
????}

????public?enum?NotifyIconInfoType
????{
????????///?<summary>
????????///?????No?Icon.
????????///?</summary>
????????None,

????????///?<summary>
????????///?????A?Information?Icon.
????????///?</summary>
????????Info,

????????///?<summary>
????????///?????A?Warning?Icon.
????????///?</summary>
????????Warning,

????????///?<summary>
????????///?????A?Error?Icon.
????????///?</summary>
????????Error
????}
}

2) NotifyIconExample.xaml 代碼如下:

ContextMenu 使用如下:

<wpfdev:NotifyIcon?Title="WPF開發(fā)者">
????????????<wpfdev:NotifyIcon.ContextMenu>
????????????????<ContextMenu>
????????????????????<MenuItem?Header="托盤消息"?Click="SendMessage_Click"/>
????????????????????<MenuItem?Header="退出"?Click="Quit_Click"/>
????????????????</ContextMenu>
????????????</wpfdev:NotifyIcon.ContextMenu>
????????</wpfdev:NotifyIcon>

ContextContent 使用如下:

<wpfdev:NotifyIcon?Title="WPF開發(fā)者">
????<wpfdev:NotifyIcon.ContextContent>
??????????<Border?CornerRadius="3"?Margin="10"?
??????????????????Background="{DynamicResource?BackgroundSolidColorBrush}"?
??????????Effect="{StaticResource?NormalShadowDepth}">
??????????<StackPanel?VerticalAlignment="Center"?Margin="16">
????????????<Rectangle?Width="100"?Height="100">
??????????????<Rectangle.Fill>
??????????????????<ImageBrush?ImageSource="pack://application:,,,/Logo.ico"/>
??????????????</Rectangle.Fill>
????????????</Rectangle>
????????????????<StackPanel?Margin="0,16,0,0"?HorizontalAlignment="Center"?Orientation="Horizontal">
??????????????????<Button?MinWidth="100"?Content="關(guān)于"?
??????????????????????????Style="{DynamicResource?PrimaryButton}"?
??????????????????????????Command="{Binding?GithubCommand}"?/>
??????????????????<Button?Margin="16,0,0,0"?MinWidth="100"?Content="退出"?Click="Quit_Click"/>
????????????????</StackPanel>
??????????????</StackPanel>
??????????</Border>
?????</wpfdev:NotifyIcon.ContextContent>
?</wpfdev:NotifyIcon>

3) NotifyIconExample.cs 代碼如下:

ContextMenu 使用如下:

?private?void?Quit_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????Application.Current.Shutdown();
????????}
????????private?void?SendMessage_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????NotifyIcon.ShowBalloonTip("Message",?"?Welcome?to?WPFDevelopers.Minimal?",?NotifyIconInfoType.None);
????????}

ContextContent 使用如下:

?private?void?Quit_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????Application.Current.Shutdown();
????????}
????????private?void?SendMessage_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????NotifyIcon.ShowBalloonTip("Message",?"?Welcome?to?WPFDevelopers.Minimal?",?NotifyIconInfoType.None);
????????}

實(shí)現(xiàn)效果

以上就是WPF實(shí)現(xiàn)基礎(chǔ)控件之托盤的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于WPF托盤的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論