Browse Source

Merge pull request #6982 from rmbadmin/master

fixes: TrayIcon should be re-added when the Explorer is restarted
pull/8066/head
Max Katz 4 years ago
committed by GitHub
parent
commit
95c8fa2eaa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 75
      src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
  2. 15
      src/Windows/Avalonia.Win32/TrayIconImpl.cs

75
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

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

15
src/Windows/Avalonia.Win32/TrayIconImpl.cs

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

Loading…
Cancel
Save