Browse Source

Merge pull request #6982 from rmbadmin/master

fixes: TrayIcon should be re-added when the Explorer is restarted
Max Katz 3 years ago
parent
commit
95c8fa2eaa

+ 39 - 36
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@@ -914,9 +914,9 @@ namespace Avalonia.Win32.Interop
         [DllImport("user32.dll")]
         public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip,
                                                       MonitorEnumDelegate lpfnEnum, IntPtr dwData);
-        
+
         public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref Rect lprcMonitor, IntPtr dwData);
-        
+
         [DllImport("user32.dll", SetLastError = true)]
         public static extern IntPtr GetDC(IntPtr hWnd);
 
@@ -1007,7 +1007,7 @@ namespace Avalonia.Win32.Interop
 
         public static uint GetWindowLong(IntPtr hWnd, int nIndex)
         {
-            if(IntPtr.Size == 4)
+            if (IntPtr.Size == 4)
             {
                 return GetWindowLong32b(hWnd, nIndex);
             }
@@ -1034,7 +1034,7 @@ namespace Avalonia.Win32.Interop
                 return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr((uint)value)).ToInt32();
             }
         }
-        
+
         public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr handle)
         {
             if (IntPtr.Size == 4)
@@ -1068,14 +1068,14 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("user32.dll")]
         public static extern bool InvalidateRect(IntPtr hWnd, RECT* lpRect, bool bErase);
-        
-        
+
+
         [DllImport("user32.dll")]
         public static extern bool ValidateRect(IntPtr hWnd, IntPtr lpRect);
 
         [DllImport("user32.dll")]
         public static extern bool IsWindow(IntPtr hWnd);
-        
+
         [DllImport("user32.dll")]
         public static extern bool IsWindowEnabled(IntPtr hWnd);
 
@@ -1102,22 +1102,25 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("user32")]
         public static extern IntPtr GetMessageExtraInfo();
-        
+
         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RegisterClassExW")]
         public static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx);
 
         [DllImport("user32.dll")]
         public static extern void RegisterTouchWindow(IntPtr hWnd, int flags);
-        
+
         [DllImport("user32.dll")]
         public static extern bool ReleaseCapture();
 
+        [DllImport("user32.dll", SetLastError = true)]
+        public static extern uint RegisterWindowMessage(string lpString);
+
         [DllImport("user32.dll")]
         public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
 
         [DllImport("user32.dll", SetLastError = true)]
         public static extern IntPtr GetActiveWindow();
-        
+
         [DllImport("user32.dll", SetLastError = true)]
         public static extern IntPtr SetActiveWindow(IntPtr hWnd);
 
@@ -1304,7 +1307,7 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("kernel32.dll", SetLastError = true)]
         public static extern IntPtr LoadLibrary(string fileName);
-        
+
         [DllImport("kernel32.dll", SetLastError = true)]
         public static extern IntPtr LoadLibraryEx(string fileName, IntPtr hFile, int flags);
 
@@ -1348,7 +1351,7 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("user32.dll")]
         public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags);
-        
+
         [DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
         [return: MarshalAs(UnmanagedType.Bool)]
         public static extern bool GetMonitorInfo([In] IntPtr hMonitor, ref MONITORINFO lpmi);
@@ -1356,14 +1359,14 @@ namespace Avalonia.Win32.Interop
         [DllImport("user32")]
         public static extern unsafe bool GetTouchInputInfo(
             IntPtr hTouchInput,
-            uint        cInputs,
+            uint cInputs,
             TOUCHINPUT* pInputs,
-            int         cbSize
+            int cbSize
         );
-        
+
         [DllImport("user32")]
         public static extern bool CloseTouchInputHandle(IntPtr hTouchInput);
-        
+
         [return: MarshalAs(UnmanagedType.Bool)]
         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")]
         public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
@@ -1372,7 +1375,7 @@ namespace Avalonia.Win32.Interop
         public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, uint
                 dwWidth, uint dwHeight, int XSrc, int YSrc, uint uStartScan, uint cScanLines,
             IntPtr lpvBits, [In] ref BITMAPINFOHEADER lpbmi, uint fuColorUse);
-        
+
         [DllImport("kernel32.dll", SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
         public static extern bool CloseHandle(IntPtr hObject);
@@ -1387,27 +1390,27 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("gdi32.dll")]
         public static extern int ChoosePixelFormat(IntPtr hdc, ref PixelFormatDescriptor pfd);
-        
+
         [DllImport("gdi32.dll")]
         public static extern int DescribePixelFormat(IntPtr hdc, ref PixelFormatDescriptor pfd);
 
         [DllImport("gdi32.dll")]
         public static extern int SetPixelFormat(IntPtr hdc, int iPixelFormat, ref PixelFormatDescriptor pfd);
-        
-        
+
+
         [DllImport("gdi32.dll")]
         public static extern int DescribePixelFormat(IntPtr hdc, int iPixelFormat, int bytes, ref PixelFormatDescriptor pfd);
-        
+
         [DllImport("gdi32.dll")]
         public static extern bool SwapBuffers(IntPtr hdc);
 
         [DllImport("opengl32.dll")]
         public static extern IntPtr wglCreateContext(IntPtr hdc);
-        
+
         [DllImport("opengl32.dll")]
         public static extern bool wglDeleteContext(IntPtr context);
 
-        
+
         [DllImport("opengl32.dll")]
         public static extern bool wglMakeCurrent(IntPtr hdc, IntPtr context);
 
@@ -1428,9 +1431,9 @@ namespace Avalonia.Win32.Interop
             uint dwMaximumSizeLow,
             string lpName);
 
-        [DllImport("msvcrt.dll", EntryPoint="memcpy", SetLastError = false, CallingConvention=CallingConvention.Cdecl)]
-        public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count); 
-        
+        [DllImport("msvcrt.dll", EntryPoint = "memcpy", SetLastError = false, CallingConvention = CallingConvention.Cdecl)]
+        public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count);
+
         [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
         public static extern HRESULT RegisterDragDrop(IntPtr hwnd, IntPtr target);
 
@@ -1472,10 +1475,10 @@ namespace Avalonia.Win32.Interop
 
         [DllImport("dwmapi.dll")]
         public static extern void DwmFlush();
-        
+
         [DllImport("dwmapi.dll")]
         public static extern bool DwmDefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam, ref IntPtr plResult);
-        
+
         [DllImport("dwmapi.dll")]
         public static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
         
@@ -1542,8 +1545,8 @@ namespace Avalonia.Win32.Interop
                 throw new Exception("RtlGetVersion failed!");
             }
         }
-        
-        [DllImport("kernel32", EntryPoint="WaitForMultipleObjectsEx", SetLastError = true, CharSet = CharSet.Auto)]
+
+        [DllImport("kernel32", EntryPoint = "WaitForMultipleObjectsEx", SetLastError = true, CharSet = CharSet.Auto)]
         private static extern int IntWaitForMultipleObjectsEx(int nCount, IntPtr[] pHandles, bool bWaitAll, int dwMilliseconds, bool bAlertable);
 
         public const int WAIT_FAILED = unchecked((int)0xFFFFFFFF);
@@ -1551,7 +1554,7 @@ namespace Avalonia.Win32.Interop
         internal static int WaitForMultipleObjectsEx(int nCount, IntPtr[] pHandles, bool bWaitAll, int dwMilliseconds, bool bAlertable)
         {
             int result = IntWaitForMultipleObjectsEx(nCount, pHandles, bWaitAll, dwMilliseconds, bAlertable);
-            if(result ==  WAIT_FAILED)
+            if (result == WAIT_FAILED)
             {
                 throw new Win32Exception();
             }
@@ -1699,7 +1702,7 @@ namespace Avalonia.Win32.Interop
             DrawLeftBorder = 0x20,
             DrawTopBorder = 0x40,
             DrawRightBorder = 0x80,
-            DrawBottomBorder = 0x100,            
+            DrawBottomBorder = 0x100,
         }
 
         [StructLayout(LayoutKind.Sequential)]
@@ -1767,9 +1770,9 @@ namespace Avalonia.Win32.Interop
             MDT_ANGULAR_DPI = 1,
             MDT_RAW_DPI = 2,
             MDT_DEFAULT = MDT_EFFECTIVE_DPI
-        } 
+        }
 
-        public enum ClipboardFormat 
+        public enum ClipboardFormat
         {
             /// <summary>
             /// Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text.
@@ -1820,7 +1823,7 @@ namespace Avalonia.Win32.Interop
             public int X;
             public int Y;
         }
-        
+
         public struct SIZE
         {
             public int X;
@@ -2021,7 +2024,7 @@ namespace Avalonia.Win32.Interop
             OFN_NOREADONLYRETURN = 0x00008000,
             OFN_OVERWRITEPROMPT = 0x00000002
         }
-        
+
         public enum HRESULT : uint
         {
             S_FALSE = 0x0001,

+ 14 - 1
src/Windows/Avalonia.Win32/TrayIconImpl.cs

@@ -24,6 +24,7 @@ namespace Avalonia.Win32
         private readonly Win32NativeToManagedMenuExporter _exporter;
         private static readonly Dictionary<int, TrayIconImpl> s_trayIcons = new Dictionary<int, TrayIconImpl>();
         private bool _disposedValue;
+        private static readonly uint WM_TASKBARCREATED = UnmanagedMethods.RegisterWindowMessage("TaskbarCreated");
 
         public TrayIconImpl()
         {
@@ -44,6 +45,18 @@ namespace Avalonia.Win32
             {
                 s_trayIcons[wParam.ToInt32()].WndProc(hWnd, msg, wParam, lParam);
             }
+
+            if (msg == WM_TASKBARCREATED)
+            {
+                foreach (var tray in s_trayIcons.Values)
+                {
+                    if (tray._iconAdded)
+                    {
+                        tray.UpdateIcon(true);
+                        tray.UpdateIcon();
+                    }
+                }
+            }
         }
 
         public void SetIcon(IWindowIconImpl? icon)
@@ -145,7 +158,7 @@ namespace Avalonia.Win32
         private enum CustomWindowsMessage : uint
         {
             WM_TRAYICON = WindowsMessage.WM_APP + 1024,
-            WM_TRAYMOUSE = WindowsMessage.WM_USER + 1024
+            WM_TRAYMOUSE = WindowsMessage.WM_USER + 1024,
         }
 
         private class TrayIconMenuFlyoutPresenter : MenuFlyoutPresenter, IStyleable