Repository: AvaloniaUI/Avalonia
File: src/Windows/Avalonia.Win32/TrayIconImpl.cs (C#)

Code before:
using Avalonia.Platform;
using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods;

namespace Avalonia.Win32
{
    internal class TrayIconImpl : ITrayIconImpl
    {
        private static readonly Win32Icon s_emptyIcon;
        private readonly int _uniqueId;
        private static int s_nextUniqueId;
        private static nint s_taskBarMonitor;

        private bool _iconAdded;
        private IconImpl? _iconImpl;
        private bool _iconStale;
        private Win32Icon? _icon;
        private string? _tooltipText;
        private readonly Win32NativeToManagedMenuExporter _exporter;
        private static readonly Dictionary<int, TrayIconImpl> s_trayIcons = new();
        private bool _disposedValue;
        private static readonly uint WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");

        static TrayIconImpl()
        {
            ChangeWindowMessageFilter(WM_TASKBARCREATED, MessageFilterFlag.MSGFLT_ADD);
            using var bitmap = new WriteableBitmap(
                new PixelSize(32, 32), new Vector(96, 96), PixelFormats.Bgra8888, AlphaFormat.Unpremul);
            s_emptyIcon = new Win32Icon(bitmap);
        }
        
        public TrayIconImpl()
        {
            FindTaskBarMonitor();

            _exporter = new Win32NativeToManagedMenuExporter();

            _uniqueId = ++s_nextUniqueId;

            s_trayIcons.Add(_uniqueId, this);
        }

        public Action? OnClicked { get; set; }

        public INativeMenuExporter MenuExporter => _exporter;

        internal static void ProcWnd(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
        {
            switch (msg)
            {
                case (uint)CustomWindowsMessage.WM_TRAYMOUSE:

Review comment (suggestion):
[`ChangeWindowMessageFilter`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changewindowmessagefilter) is deprecated: [`ChangeWindowMessageFilterEx`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-changewindowmessagefilterex) is recommended instead. Please use it in `Win32Platform.CreateMessageWindow`.

Code after:
using Avalonia.Platform;
using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods;

namespace Avalonia.Win32
{
    internal class TrayIconImpl : ITrayIconImpl
    {
        private static readonly Win32Icon s_emptyIcon;
        private readonly int _uniqueId;
        private static int s_nextUniqueId;
        private static nint s_taskBarMonitor;

        private bool _iconAdded;
        private IconImpl? _iconImpl;
        private bool _iconStale;
        private Win32Icon? _icon;
        private string? _tooltipText;
        private readonly Win32NativeToManagedMenuExporter _exporter;
        private static readonly Dictionary<int, TrayIconImpl> s_trayIcons = new();
        private bool _disposedValue;
        private static readonly uint WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");

        static TrayIconImpl()
        {
            using var bitmap = new WriteableBitmap(
                new PixelSize(32, 32), new Vector(96, 96), PixelFormats.Bgra8888, AlphaFormat.Unpremul);
            s_emptyIcon = new Win32Icon(bitmap);
        }

        internal static void ChangeWindowMessageFilter(IntPtr hWnd)
        {
            ChangeWindowMessageFilterEx(hWnd, WM_TASKBARCREATED, MessageFilterFlag.MSGFLT_ALLOW, IntPtr.Zero);
        }

        public TrayIconImpl()
        {
            FindTaskBarMonitor();

            _exporter = new Win32NativeToManagedMenuExporter();

            _uniqueId = ++s_nextUniqueId;

            s_trayIcons.Add(_uniqueId, this);
        }

        public Action? OnClicked { get; set; }

        public INativeMenuExporter MenuExporter => _exporter;

        internal static void ProcWnd(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)